static void tftp_handle_rrq(struct tftp_t *tp, int pktlen)

{

  struct tftp_session *spt;

  int s, k, n;

  u_int8_t *src, *dst;



  s = tftp_session_allocate(tp);



  if (s < 0) {

    return;

  }



  spt = &tftp_sessions[s];



  src = tp->x.tp_buf;

  dst = spt->filename;

  n = pktlen - ((uint8_t *)&tp->x.tp_buf[0] - (uint8_t *)tp);



  /* get name */



  for (k = 0; k < n; k++) {

    if (k < TFTP_FILENAME_MAX) {

      dst[k] = src[k];

    }

    else {

      return;

    }



    if (src[k] == '\0') {

      break;

    }

  }



  if (k >= n) {

    return;

  }



  k++;



  /* check mode */

  if ((n - k) < 6) {

    return;

  }



  if (memcmp(&src[k], "octet\0", 6) != 0) {

      tftp_send_error(spt, 4, "Unsupported transfer mode", tp);

      return;

  }



  k += 6; /* skipping octet */



  /* do sanity checks on the filename */



  if ((spt->filename[0] != '/')

      || (spt->filename[strlen((char *)spt->filename) - 1] == '/')

      ||  strstr((char *)spt->filename, "/../")) {

      tftp_send_error(spt, 2, "Access violation", tp);

      return;

  }



  /* only allow exported prefixes */



  if (!tftp_prefix) {

      tftp_send_error(spt, 2, "Access violation", tp);

      return;

  }



  /* check if the file exists */



  if (tftp_read_data(spt, 0, spt->filename, 0) < 0) {

      tftp_send_error(spt, 1, "File not found", tp);

      return;

  }



  if (src[n - 1] != 0) {

      tftp_send_error(spt, 2, "Access violation", tp);

      return;

  }



  while (k < n) {

      const char *key, *value;



      key = (char *)src + k;

      k += strlen(key) + 1;



      if (k >= n) {

	  tftp_send_error(spt, 2, "Access violation", tp);

	  return;

      }



      value = (char *)src + k;

      k += strlen(value) + 1;



      if (strcmp(key, "tsize") == 0) {

	  int tsize = atoi(value);

	  struct stat stat_p;



	  if (tsize == 0 && tftp_prefix) {

	      char buffer[1024];

	      int len;



	      len = snprintf(buffer, sizeof(buffer), "%s/%s",

			     tftp_prefix, spt->filename);



	      if (stat(buffer, &stat_p) == 0)

		  tsize = stat_p.st_size;

	      else {

		  tftp_send_error(spt, 1, "File not found", tp);

		  return;

	      }

	  }



	  tftp_send_oack(spt, "tsize", tsize, tp);

      }

  }



  tftp_send_data(spt, 1, tp);

}

static void tftp_handle_rrq(struct tftp_t *tp, int pktlen)

{

  struct tftp_session *spt;

  int s, k, n;

  u_int8_t *src, *dst;



  s = tftp_session_allocate(tp);



  if (s < 0) {

    return;

  }



  spt = &tftp_sessions[s];



  src = tp->x.tp_buf;

  dst = spt->filename;

  n = pktlen - ((uint8_t *)&tp->x.tp_buf[0] - (uint8_t *)tp);



  



  for (k = 0; k < n; k++) {

    if (k < TFTP_FILENAME_MAX) {

      dst[k] = src[k];

    }

    else {

      return;

    }



    if (src[k] == '\0') {

      break;

    }

  }



  if (k >= n) {

    return;

  }



  k++;



  

  if ((n - k) < 6) {

    return;

  }



  if (memcmp(&src[k], "octet\0", 6) != 0) {

      tftp_send_error(spt, 4, "Unsupported transfer mode", tp);

      return;

  }



  k += 6; 



  



  if ((spt->filename[0] != '/')

      || (spt->filename[strlen((char *)spt->filename) - 1] == '/')

      ||  strstr((char *)spt->filename, "/../")) {

      tftp_send_error(spt, 2, "Access violation", tp);

      return;

  }



  



  if (!tftp_prefix) {

      tftp_send_error(spt, 2, "Access violation", tp);

      return;

  }



  



  if (tftp_read_data(spt, 0, spt->filename, 0) < 0) {

      tftp_send_error(spt, 1, "File not found", tp);

      return;

  }



  if (src[n - 1] != 0) {

      tftp_send_error(spt, 2, "Access violation", tp);

      return;

  }



  while (k < n) {

      const char *key, *value;



      key = (char *)src + k;

      k += strlen(key) + 1;



      if (k >= n) {

	  tftp_send_error(spt, 2, "Access violation", tp);

	  return;

      }



      value = (char *)src + k;

      k += strlen(value) + 1;



      if (strcmp(key, "tsize") == 0) {

	  int tsize = atoi(value);

	  struct stat stat_p;



	  if (tsize == 0 && tftp_prefix) {

	      char buffer[1024];

	      int len;



	      len = snprintf(buffer, sizeof(buffer), "%s/%s",

			     tftp_prefix, spt->filename);



	      if (stat(buffer, &stat_p) == 0)

		  tsize = stat_p.st_size;

	      else {

		  tftp_send_error(spt, 1, "File not found", tp);

		  return;

	      }

	  }



	  tftp_send_oack(spt, "tsize", tsize, tp);

      }

  }



  tftp_send_data(spt, 1, tp);

}

static void FUNC_0(struct tftp_t *VAR_0, int VAR_1)

{

  struct tftp_session *VAR_2;

  int VAR_3, VAR_4, VAR_5;

  u_int8_t *src, *dst;



  VAR_3 = tftp_session_allocate(VAR_0);



  if (VAR_3 < 0) {

    return;

  }



  VAR_2 = &tftp_sessions[VAR_3];



  src = VAR_0->x.tp_buf;

  dst = VAR_2->filename;

  VAR_5 = VAR_1 - ((uint8_t *)&VAR_0->x.tp_buf[0] - (uint8_t *)VAR_0);



  



  for (VAR_4 = 0; VAR_4 < VAR_5; VAR_4++) {

    if (VAR_4 < TFTP_FILENAME_MAX) {

      dst[VAR_4] = src[VAR_4];

    }

    else {

      return;

    }



    if (src[VAR_4] == '\0') {

      break;

    }

  }



  if (VAR_4 >= VAR_5) {

    return;

  }



  VAR_4++;



  

  if ((VAR_5 - VAR_4) < 6) {

    return;

  }



  if (memcmp(&src[VAR_4], "octet\0", 6) != 0) {

      tftp_send_error(VAR_2, 4, "Unsupported transfer mode", VAR_0);

      return;

  }



  VAR_4 += 6; 



  



  if ((VAR_2->filename[0] != '/')

      || (VAR_2->filename[strlen((char *)VAR_2->filename) - 1] == '/')

      ||  strstr((char *)VAR_2->filename, "/../")) {

      tftp_send_error(VAR_2, 2, "Access violation", VAR_0);

      return;

  }



  



  if (!tftp_prefix) {

      tftp_send_error(VAR_2, 2, "Access violation", VAR_0);

      return;

  }



  



  if (tftp_read_data(VAR_2, 0, VAR_2->filename, 0) < 0) {

      tftp_send_error(VAR_2, 1, "File not found", VAR_0);

      return;

  }



  if (src[VAR_5 - 1] != 0) {

      tftp_send_error(VAR_2, 2, "Access violation", VAR_0);

      return;

  }



  while (VAR_4 < VAR_5) {

      const char *VAR_6, *VAR_7;



      VAR_6 = (char *)src + VAR_4;

      VAR_4 += strlen(VAR_6) + 1;



      if (VAR_4 >= VAR_5) {

	  tftp_send_error(VAR_2, 2, "Access violation", VAR_0);

	  return;

      }



      VAR_7 = (char *)src + VAR_4;

      VAR_4 += strlen(VAR_7) + 1;



      if (strcmp(VAR_6, "VAR_8") == 0) {

	  int VAR_8 = atoi(VAR_7);

	  struct stat VAR_9;



	  if (VAR_8 == 0 && tftp_prefix) {

	      char VAR_10[1024];

	      int VAR_11;



	      VAR_11 = snprintf(VAR_10, sizeof(VAR_10), "%VAR_3/%VAR_3",

			     tftp_prefix, VAR_2->filename);



	      if (stat(VAR_10, &VAR_9) == 0)

		  VAR_8 = VAR_9.st_size;

	      else {

		  tftp_send_error(VAR_2, 1, "File not found", VAR_0);

		  return;

	      }

	  }



	  tftp_send_oack(VAR_2, "VAR_8", VAR_8, VAR_0);

      }

  }



  tftp_send_data(VAR_2, 1, VAR_0);

}

static void FUNC_0(struct tftp_t *VAR_0, int VAR_1)
{ struct tftp_session *VAR_2; int VAR_3, VAR_4, VAR_5; u_int8_t *src, *dst; VAR_3 = tftp_session_allocate(VAR_0); if (VAR_3 < 0) { return; } VAR_2 = &tftp_sessions[VAR_3]; src = VAR_0->x.tp_buf; dst = VAR_2->filename; VAR_5 = VAR_1 - ((uint8_t *)&VAR_0->x.tp_buf[0] - (uint8_t *)VAR_0); for (VAR_4 = 0; VAR_4 < VAR_5; VAR_4++) { if (VAR_4 < TFTP_FILENAME_MAX) { dst[VAR_4] = src[VAR_4]; } else { return; } if (src[VAR_4] == '\0') { break; } } if (VAR_4 >= VAR_5) { return; } VAR_4++; if ((VAR_5 - VAR_4) < 6) { return; } if (memcmp(&src[VAR_4], "octet\0", 6) != 0) { tftp_send_error(VAR_2, 4, "Unsupported transfer mode", VAR_0); return; } VAR_4 += 6; if ((VAR_2->filename[0] != '/')
|| (VAR_2->filename[strlen((char *)VAR_2->filename) - 1] == '/')
||  strstr((char *)VAR_2->filename, "/../")) { tftp_send_error(VAR_2, 2, "Access violation", VAR_0); return; } if (!tftp_prefix) { tftp_send_error(VAR_2, 2, "Access violation", VAR_0); return; } if (tftp_read_data(VAR_2, 0, VAR_2->filename, 0) < 0) { tftp_send_error(VAR_2, 1, "File not found", VAR_0); return; } if (src[VAR_5 - 1] != 0) { tftp_send_error(VAR_2, 2, "Access violation", VAR_0); return; } while (VAR_4 < VAR_5) { const char *VAR_6, *VAR_7; VAR_6 = (char *)src + VAR_4; VAR_4 += strlen(VAR_6) + 1; if (VAR_4 >= VAR_5) { tftp_send_error(VAR_2, 2, "Access violation", VAR_0); return; } VAR_7 = (char *)src + VAR_4; VAR_4 += strlen(VAR_7) + 1; if (strcmp(VAR_6, "VAR_8") == 0) { int VAR_8 = atoi(VAR_7); struct stat VAR_9; if (VAR_8 == 0 && tftp_prefix) { char VAR_10[1024]; int VAR_11; VAR_11 = snprintf(VAR_10, sizeof(VAR_10), "%VAR_3/%VAR_3",
tftp_prefix, VAR_2->filename); if (stat(VAR_10, &VAR_9) == 0)
VAR_8 = VAR_9.st_size; else { tftp_send_error(VAR_2, 1, "File not found", VAR_0); return; } } tftp_send_oack(VAR_2, "VAR_8", VAR_8, VAR_0); } } tftp_send_data(VAR_2, 1, VAR_0); }