Diff for /tftpd/src/srv.c between versions 1.2.2.5 and 1.3

version 1.2.2.5, 2014/02/20 14:20:42 version 1.3, 2014/02/18 12:46:39
Line 63  txData(sched_task_t *task) Line 63  txData(sched_task_t *task)
         n = htons(cli.seq);          n = htons(cli.seq);
         rpack_uint16(pkt, &n, 0);          rpack_uint16(pkt, &n, 0);
   
        /* max file size check */        len = pread(cli.fd, RPACK_NEXT(pkt), cli.siz, (cli.seq - 1) * cli.siz);
        if (cli.tsiz && cli.tsiz <= cli.seq * cli.siz) { 
                len = MAX(0, cli.tsiz - (cli.seq - 1) * cli.siz); 
                cli.close = 42; /* last sended packet, should be close! */ 
        } else 
                len = cli.siz; 
 
        len = pread(cli.fd, RPACK_NEXT(pkt), len, (cli.seq - 1) * cli.siz); 
         if (len == -1) {          if (len == -1) {
                 ESYSERR(0);                  ESYSERR(0);
                 code = htole16(3);                  code = htole16(3);
Line 124  txAck(sched_task_t *task) Line 117  txAck(sched_task_t *task)
 }  }
   
 static int  static int
getOpts(rpack_t * __restrict pkt)getOpts(const char *opts, int rlen)
 {  {
        char *opt, *val;        if (!opts)
        int len;                return -1;
   
         do {  
                 /* option */  
                 len = str_getString(RPACK_NEXT(pkt), RPACK_REMAIN(pkt), NULL);  
                 if (len == -1)  
                         return -1;  
                 opt = (char*) rpack_rnext(pkt, len);  
                 if (!opt)  
                         return -1;  
                 /* value */  
                 len = str_getString(RPACK_NEXT(pkt), RPACK_REMAIN(pkt), NULL);  
                 if (len == -1)  
                         return -1;  
                 val = (char*) rpack_rnext(pkt, len);  
                 if (!val)  
                         return -1;  
   
                 if (!strcasecmp(opt, TFTP_OPT_BLKSIZE)) {  
                         len = strtol(val, NULL, 10);  
                         if (len > TFTP_LOAD_MAX)  
                                 cli.siz = len;  
                 } else if (!strcasecmp(opt, TFTP_OPT_TSIZE))  
                         cli.tsiz = strtoll(val, NULL, 10);  
                 else if (!strcasecmp(opt, TFTP_OPT_TIMEOUT))  
                         cli.tout = strtol(val, NULL, 10);  
                 else  
                         return -1;  
         } while (!RPACK_ISEND(pkt));  
   
         EVERBOSE(4, "blksize=%u tsize=%llu timeout=%u", cli.siz, cli.tsiz, cli.tout);  
         return 0;          return 0;
 }  }
   
 static void *  static void *
 txOack(sched_task_t *task)  
 {  
         rpack_t *pkt = TASK_DATA(task);  
         u_short n = htons(TFTP_OPC_OACK);  
         struct stat sb;  
         char szStr[STRSIZ];  
   
         ETRACE();  
   
         RPACK_REWIND(pkt);  
         rpack_uint16(pkt, &n, 0);  
   
         /* if opcode is RRQ and tsize is 0 then we must return file size to client */  
         if (cli.opc == TFTP_OPC_RRQ && !cli.tsiz && stat(cli.file, &sb) != -1)  
                 cli.tsiz = sb.st_size;  
   
         if (cli.siz > TFTP_LOAD_MAX) {  
                 memset(szStr, 0, sizeof szStr);  
                 snprintf(szStr, sizeof szStr, "%u", cli.siz);  
                 rpack_rdata(pkt, TFTP_OPT_BLKSIZE, strlen(TFTP_OPT_BLKSIZE) + 1);  
                 rpack_rdata(pkt, szStr, strlen(szStr) + 1);  
         }  
         if (cli.tsiz) {  
                 memset(szStr, 0, sizeof szStr);  
                 snprintf(szStr, sizeof szStr, "%llu", cli.tsiz);  
                 rpack_rdata(pkt, TFTP_OPT_TSIZE, strlen(TFTP_OPT_TSIZE) + 1);  
                 rpack_rdata(pkt, szStr, strlen(szStr) + 1);  
         }  
         if (cli.tout) {  
                 memset(szStr, 0, sizeof szStr);  
                 snprintf(szStr, sizeof szStr, "%u", cli.tout);  
                 rpack_rdata(pkt, TFTP_OPT_TIMEOUT, strlen(TFTP_OPT_TIMEOUT) + 1);  
                 rpack_rdata(pkt, szStr, strlen(szStr) + 1);  
         }  
   
         schedEvent(TASK_ROOT(task), txPkt, NULL, TASK_FD(task),   
                         TASK_DATA(task), RPACK_OFF(pkt));  
         taskExit(task, NULL);  
 }  
   
 static void *  
 RQ(sched_task_t *task)  RQ(sched_task_t *task)
 {  {
         rpack_t *pkt = TASK_DATA(task);          rpack_t *pkt = TASK_DATA(task);
         struct tftp_hdr *tftp = (struct tftp_hdr*) RPACK_BUF(pkt);          struct tftp_hdr *tftp = (struct tftp_hdr*) RPACK_BUF(pkt);
         int len, rlen = TASK_DATLEN(task) - 2;          int len, rlen = TASK_DATLEN(task) - 2;
        char *str;        char *str, *opts;
         u_short code = 0;          u_short code = 0;
   
         ETRACE();          ETRACE();
Line 221  RQ(sched_task_t *task) Line 144  RQ(sched_task_t *task)
                 rlen -= len;                  rlen -= len;
                 strlcpy(cli.file, (char*) tftp->tftp_data, sizeof cli.file);                  strlcpy(cli.file, (char*) tftp->tftp_data, sizeof cli.file);
         }          }
        len = str_getString((const u_char*) str, rlen, NULL);        len = str_getString((const u_char*) str, rlen, &opts);
         if (len == -1)          if (len == -1)
                 goto end;                  goto end;
         else {          else {
Line 240  RQ(sched_task_t *task) Line 163  RQ(sched_task_t *task)
                 }                  }
         }          }
   
           /* tftp extended options */
           if (!RPACK_ISEND(pkt) && !getOpts(opts, rlen))
                   cli.opts = 42;  /* we have options */
   
         cli.opc = ntohs(tftp->tftp_opc);          cli.opc = ntohs(tftp->tftp_opc);
         switch (cli.opc) {          switch (cli.opc) {
                 case TFTP_OPC_RRQ:                  case TFTP_OPC_RRQ:
Line 254  RQ(sched_task_t *task) Line 181  RQ(sched_task_t *task)
                         EVERBOSE(2, "WRQ:: file=%s mode=%s\n", cli.file, cli.mode);                          EVERBOSE(2, "WRQ:: file=%s mode=%s\n", cli.file, cli.mode);
                         break;                          break;
         }          }
   
         if (!RPACK_ISEND(pkt) && !getOpts(pkt))  
                 schedEvent(TASK_ROOT(task), txOack, NULL, TASK_FD(task),   
                                 TASK_DATA(task), 0);  
   
         cli.fd = open(cli.file, code, 0644);          cli.fd = open(cli.file, code, 0644);
         if (cli.fd == -1) {          if (cli.fd == -1) {
                 if (errno == EACCES)                  if (errno == EACCES)
Line 374  DATA(sched_task_t *task) Line 296  DATA(sched_task_t *task)
         } else          } else
                 cli.seq = ntohs(code);                  cli.seq = ntohs(code);
   
         /* max file size check */  
         len = TASK_DATLEN(task) - RPACK_OFF(pkt);          len = TASK_DATLEN(task) - RPACK_OFF(pkt);
         if (cli.tsiz && cli.tsiz <= cli.seq * cli.siz)  
                 len = MIN(len, cli.tsiz - (cli.seq - 1) * cli.siz);  
         if (len < cli.siz)          if (len < cli.siz)
                 cli.close = 42; /* last received packet, should be close! */                  cli.close = 42; /* last received packet, should be close! */
   
Line 460  rxPkt(sched_task_t *task) Line 379  rxPkt(sched_task_t *task)
                                                 TASK_DATA(task), rlen);                                                  TASK_DATA(task), rlen);
                                 break;                                  break;
                         case TFTP_OPC_OACK:                          case TFTP_OPC_OACK:
                                   ELOGGER(LOG_WARNING, "oack");
                                   /*
                                   schedEvent(TASK_ROOT(task), OACK, NULL, TASK_FD(task), 
                                                   TASK_DATA(task), rlen);
                                                   */
                                   break;
                         case TFTP_OPC_ERROR:                          case TFTP_OPC_ERROR:
                         default:                          default:
                                 RPACK_REWIND(pkt);                                  RPACK_REWIND(pkt);

Removed from v.1.2.2.5  
changed lines
  Added in v.1.3


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>