Annotation of embedtools/src/upd.c, revision 1.2
1.2 ! misho 1: /*************************************************************************
! 2: * (C) 2010 AITNET - Sofia/Bulgaria - <office@aitbg.com>
! 3: * by Michael Pounov <misho@aitbg.com>
! 4: *
! 5: * $Author: misho $
! 6: * $Id: upd.c,v 1.1.2.10 2011/06/08 09:15:32 misho Exp $
! 7: *
! 8: *************************************************************************/
! 9: #include "global.h"
! 10: #include "upd.h"
! 11:
! 12:
! 13: int Kill;
! 14:
! 15:
! 16: static inline int ChkImg(const char *csImg, char *psDir)
! 17: {
! 18: int res = 0;
! 19:
! 20: getcwd(psDir, MAXPATHLEN);
! 21: if (access(csImg, R_OK) == -1) {
! 22: printf("Error:: Unable to find new image %s #%d - %s\n",
! 23: csImg, errno, strerror(errno));
! 24: res = -1;
! 25: } else {
! 26: strlcat(psDir, "/", MAXPATHLEN);
! 27: strlcat(psDir, csImg, MAXPATHLEN);
! 28: }
! 29:
! 30: return res;
! 31: }
! 32:
! 33: // -------------------------------
! 34:
! 35: int Activate(const char *csImg)
! 36: {
! 37: char szDir[MAXPATHLEN];
! 38:
! 39: if (ChkImg(csImg, szDir) == -1)
! 40: return -1;
! 41:
! 42: VERB(3) printf("Activate procedure for %s\n", szDir);
! 43:
! 44: unlink(FIRMWARE_IMG);
! 45: if (symlink(szDir, FIRMWARE_IMG) == -1) {
! 46: printf("Error:: Unable to activate new image %s #%d - %s\n",
! 47: csImg, errno, strerror(errno));
! 48: return -2;
! 49: }
! 50:
! 51: syslog(LOG_NOTICE, "Activate new image %s", csImg);
! 52: VERB(1) printf("Activate new image %s\n", csImg);
! 53: return 0;
! 54: }
! 55:
! 56: int Install(const char *csImg, const char *psDir)
! 57: {
! 58: int src, dst, len;
! 59: u_char buf[BUFSIZ];
! 60: char szDir[MAXPATHLEN], szFile[MAXPATHLEN];
! 61: struct stat ss, ds;
! 62:
! 63: strlcpy(szFile, psDir, MAXPATHLEN);
! 64: strlcat(szFile, "/", MAXPATHLEN);
! 65: strlcat(szFile, csImg, MAXPATHLEN);
! 66: if (access(szFile, R_OK) == -1) {
! 67: printf("Error:: Unable to find new image %s #%d - %s\n",
! 68: csImg, errno, strerror(errno));
! 69: return -1;
! 70: } else {
! 71: memset(&ss, 0, sizeof ss);
! 72: if (stat(szFile, &ss) == -1) {
! 73: printf("Error:: Unable to find new image %s #%d - %s\n",
! 74: csImg, errno, strerror(errno));
! 75: return -1;
! 76: }
! 77: }
! 78:
! 79: getcwd(szDir, MAXPATHLEN);
! 80: VERB(3) printf("Install procedure from %s to %s\n", szFile, szDir);
! 81: strlcat(szDir, "/", MAXPATHLEN);
! 82: strlcat(szDir, csImg, MAXPATHLEN);
! 83: memset(&ds, 0, sizeof ds);
! 84: if (stat(szDir, &ds) == -1 && ENOENT != errno) {
! 85: printf("Error:: Unable to stat target #%d - %s\n",
! 86: errno, strerror(errno));
! 87: return -1;
! 88: }
! 89:
! 90: if (ss.st_dev == ds.st_dev && ss.st_ino == ds.st_ino) {
! 91: printf("Error:: Unable to install into self ...\n");
! 92: return -1;
! 93: }
! 94:
! 95: dst = open(szDir, O_WRONLY | O_CREAT | O_TRUNC, 0644);
! 96: if (dst == -1) {
! 97: printf("Error:: in create image %s #%d - %s\n",
! 98: szDir, errno, strerror(errno));
! 99: return -1;
! 100: }
! 101: src = open(szFile, O_RDONLY);
! 102: if (src == -1) {
! 103: printf("Error:: in open image %s #%d - %s\n",
! 104: szFile, errno, strerror(errno));
! 105: close(dst);
! 106: unlink(szDir);
! 107: return -1;
! 108: }
! 109:
! 110: while ((len = read(src, buf, BUFSIZ)) > 0)
! 111: if (write(dst, buf, len) == -1) {
! 112: printf("Error:: in write image #%d - %s\n",
! 113: errno, strerror(errno));
! 114: close(src);
! 115: close(dst);
! 116: unlink(szDir);
! 117:
! 118: len = -1;
! 119: break;
! 120: }
! 121:
! 122: close(src);
! 123: close(dst);
! 124:
! 125: if (!len) {
! 126: syslog(LOG_NOTICE, "Install image %s to %s", csImg, szDir);
! 127: VERB(1) printf("Install image %s to %s\n", csImg, szDir);
! 128: }
! 129: return len;
! 130: }
! 131:
! 132: int Rollback(const char *csImg)
! 133: {
! 134: int src, dst, len;
! 135: u_char buf[BUFSIZ];
! 136: char szDir[MAXPATHLEN], szFile[MAXPATHLEN];
! 137: struct stat ss, ds;
! 138:
! 139: getcwd(szFile, MAXPATHLEN);
! 140: strlcat(szFile, "/", MAXPATHLEN);
! 141: strlcat(szFile, FIRMWARE_BAK, MAXPATHLEN);
! 142: if (access(szFile, R_OK) == -1) {
! 143: printf("Error:: Unable to find backup image #%d - %s\n",
! 144: errno, strerror(errno));
! 145: return -1;
! 146: } else {
! 147: memset(&ss, 0, sizeof ss);
! 148: if (stat(szFile, &ss) == -1) {
! 149: printf("Error:: Unable to find backup image #%d - %s\n",
! 150: errno, strerror(errno));
! 151: return -1;
! 152: }
! 153: }
! 154:
! 155: getcwd(szDir, MAXPATHLEN);
! 156: strlcat(szDir, "/", MAXPATHLEN);
! 157: strlcat(szDir, csImg, MAXPATHLEN);
! 158: VERB(3) printf("Rollback procedure for image %s from backup!\n", csImg);
! 159: memset(&ds, 0, sizeof ds);
! 160: if (stat(szDir, &ds) == -1 && ENOENT != errno) {
! 161: printf("Error:: Unable to stat target #%d - %s\n",
! 162: errno, strerror(errno));
! 163: return -1;
! 164: }
! 165:
! 166: if (ss.st_dev == ds.st_dev && ss.st_ino == ds.st_ino) {
! 167: printf("Error:: Unable to rollback into self ...\n");
! 168: return -1;
! 169: }
! 170:
! 171: src = open(szFile, O_RDONLY);
! 172: if (src == -1) {
! 173: printf("Error:: in open backup %s #%d - %s\n",
! 174: szFile, errno, strerror(errno));
! 175: return -1;
! 176: }
! 177: dst = open(szDir, O_WRONLY | O_CREAT | O_TRUNC, 0644);
! 178: if (dst == -1) {
! 179: printf("Error:: in create image %s #%d - %s\n",
! 180: szDir, errno, strerror(errno));
! 181: close(src);
! 182: return -1;
! 183: }
! 184:
! 185: while ((len = read(src, buf, BUFSIZ)) > 0)
! 186: if (write(dst, buf, len) == -1) {
! 187: printf("Error:: in write image #%d - %s\n",
! 188: errno, strerror(errno));
! 189: close(dst);
! 190: close(src);
! 191: unlink(szDir);
! 192:
! 193: len = -1;
! 194: break;
! 195: }
! 196:
! 197: close(dst);
! 198: close(src);
! 199:
! 200: if (!len) {
! 201: syslog(LOG_NOTICE, "Rollback image %s to %s", csImg, szDir);
! 202: VERB(1) printf("Rollback image %s to %s\n", csImg, szDir);
! 203: }
! 204: return len;
! 205:
! 206: return 0;
! 207: }
! 208:
! 209: int tFTP(const char *csImg, const char *psDir)
! 210: {
! 211: int src, dst, len;
! 212: u_char buf[BUFSIZ];
! 213: char szDir[MAXPATHLEN], szFile[MAXPATHLEN];
! 214: struct stat ss, ds;
! 215:
! 216: if (ChkImg(csImg, szDir) == -1)
! 217: return -1;
! 218: else {
! 219: memset(&ss, 0, sizeof ss);
! 220: if (stat(szDir, &ss) == -1) {
! 221: printf("Error:: Unable to find image %s #%d - %s\n",
! 222: szDir, errno, strerror(errno));
! 223: return -1;
! 224: }
! 225: }
! 226:
! 227: VERB(3) printf("tFTP procedure for %s to %s\n", szDir, psDir);
! 228: strlcpy(szFile, psDir, MAXPATHLEN);
! 229: strlcat(szFile, "/", MAXPATHLEN);
! 230: strlcat(szFile, csImg, MAXPATHLEN);
! 231: memset(&ds, 0, sizeof ds);
! 232: if (stat(szFile, &ds) == -1 && ENOENT != errno) {
! 233: printf("Error:: Unable to stat target %s #%d - %s\n",
! 234: szFile, errno, strerror(errno));
! 235: return -1;
! 236: }
! 237:
! 238: if (ss.st_dev == ds.st_dev && ss.st_ino == ds.st_ino) {
! 239: printf("Error:: Unable to copy into self ...\n");
! 240: return -1;
! 241: }
! 242:
! 243: dst = open(szFile, O_WRONLY | O_CREAT | O_TRUNC, 0644);
! 244: if (dst == -1) {
! 245: printf("Error:: in create backup %s #%d - %s\n",
! 246: szFile, errno, strerror(errno));
! 247: return -1;
! 248: }
! 249: src = open(szDir, O_RDONLY);
! 250: if (src == -1) {
! 251: printf("Error:: in open image %s #%d - %s\n",
! 252: szDir, errno, strerror(errno));
! 253: close(dst);
! 254: unlink(szFile);
! 255: return -1;
! 256: }
! 257:
! 258: while ((len = read(src, buf, BUFSIZ)) > 0)
! 259: if (write(dst, buf, len) == -1) {
! 260: printf("Error:: in write backup #%d - %s\n",
! 261: errno, strerror(errno));
! 262: close(src);
! 263: close(dst);
! 264: unlink(szFile);
! 265:
! 266: len = -1;
! 267: break;
! 268: }
! 269:
! 270: close(src);
! 271: close(dst);
! 272:
! 273: if (!len) {
! 274: syslog(LOG_NOTICE, "Export tFTP image %s to %s", csImg, psDir);
! 275: VERB(1) printf("Export tFTP image %s to %s\n", csImg, psDir);
! 276: }
! 277: return len;
! 278: }
! 279:
! 280: int Backup(const char *csImg)
! 281: {
! 282: int src, dst, len;
! 283: u_char buf[BUFSIZ];
! 284: char szDir[MAXPATHLEN], szFile[MAXPATHLEN];
! 285:
! 286: if (ChkImg(csImg, szDir) == -1)
! 287: return -1;
! 288:
! 289: getcwd(szFile, MAXPATHLEN);
! 290: strlcat(szFile, "/", MAXPATHLEN);
! 291: strlcat(szFile, FIRMWARE_BAK, MAXPATHLEN);
! 292: VERB(3) printf("Backup procedure for %s\n", szDir);
! 293:
! 294: dst = open(szFile, O_WRONLY | O_CREAT | O_TRUNC, 0644);
! 295: if (dst == -1) {
! 296: printf("Error:: in create backup %s #%d - %s\n",
! 297: szFile, errno, strerror(errno));
! 298: return -1;
! 299: }
! 300: src = open(szDir, O_RDONLY);
! 301: if (src == -1) {
! 302: printf("Error:: in open image %s #%d - %s\n",
! 303: szDir, errno, strerror(errno));
! 304: close(dst);
! 305: unlink(szFile);
! 306: return -1;
! 307: }
! 308:
! 309: while ((len = read(src, buf, BUFSIZ)) > 0)
! 310: if (write(dst, buf, len) == -1) {
! 311: printf("Error:: in write backup #%d - %s\n",
! 312: errno, strerror(errno));
! 313: close(src);
! 314: close(dst);
! 315: unlink(szFile);
! 316:
! 317: len = -1;
! 318: break;
! 319: }
! 320:
! 321: close(src);
! 322: close(dst);
! 323:
! 324: if (!len) {
! 325: syslog(LOG_NOTICE, "Backup image %s", csImg);
! 326: VERB(1) printf("Backup image %s\n", csImg);
! 327: }
! 328: return len;
! 329: }
! 330:
! 331: int Clean(const char *csImg)
! 332: {
! 333: char szDir[MAXPATHLEN], szFile[MAXPATHLEN];
! 334:
! 335: if (ChkImg(csImg, szDir) == -1)
! 336: return -1;
! 337:
! 338: getcwd(szFile, MAXPATHLEN);
! 339: strlcat(szFile, "/", MAXPATHLEN);
! 340: strlcat(szFile, FIRMWARE_BAK, MAXPATHLEN);
! 341:
! 342: VERB(3) printf("Clean procedure for %s\n", szDir);
! 343:
! 344: if (unlink(szFile) == -1) {
! 345: printf("Error:: in clean backup #%d - %s\n", errno, strerror(errno));
! 346: return -1;
! 347: }
! 348:
! 349: syslog(LOG_NOTICE, "Clean backup for image %s", csImg);
! 350: VERB(1) printf("Clean backup for image %s\n", csImg);
! 351: return 0;
! 352: }
! 353:
! 354: // ----------------------------------
! 355:
! 356: static void Signal(int sig)
! 357: {
! 358: int stat;
! 359:
! 360: switch (sig) {
! 361: case SIGHUP:
! 362: VERB(5) printf("Info(5):: Signal arrived #%d\n", sig);
! 363: break;
! 364: case SIGCHLD:
! 365: while (waitpid(-1, &stat, WNOHANG) > 0);
! 366: break;
! 367: case SIGTERM:
! 368: Kill = 1;
! 369: VERB(5) printf("Info(5):: Signal arrived #%d\n", sig);
! 370: break;
! 371: }
! 372: }
! 373:
! 374: int Daemonize(struct sockaddr_in sin, const char *csTFTP)
! 375: {
! 376: int s, n = 1;
! 377: pid_t pid;
! 378: fd_set rfd;
! 379: u_short seq = 0xffff;
! 380: int clilen, len, f, retry;
! 381: struct sockaddr_in cli, rcv;
! 382: struct sigaction sa;
! 383: u_char buf[TFTP_BUF], *pos;
! 384: char szFName[MAX_STR];
! 385: struct tftphdr *tftp = (struct tftphdr*) buf;
! 386: struct timeval tv = { TFTP_TIMEOUT, 0 };
! 387:
! 388: VERB(3) printf("Daemonize procedure for %s:%d to %s\n",
! 389: inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), csTFTP);
! 390:
! 391: memset(&sa, 0, sizeof sa);
! 392: sigemptyset(&sa.sa_mask);
! 393: sa.sa_handler = Signal;
! 394: sigaction(SIGCHLD, &sa, NULL);
! 395: sigaction(SIGTERM, &sa, NULL);
! 396: sigaction(SIGHUP, &sa, NULL);
! 397:
! 398: s = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
! 399: if (s == -1) {
! 400: printf("Error:: in create socket #%d - %s\n", errno, strerror(errno));
! 401: return -1;
! 402: }
! 403: if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &n, sizeof n) == -1) {
! 404: printf("Error:: in socket options #%d - %s\n", errno, strerror(errno));
! 405: close(s);
! 406: return -1;
! 407: }
! 408: if (bind(s, (struct sockaddr*) &sin, sizeof sin) == -1) {
! 409: printf("Error:: in bind #%d - %s\n", errno, strerror(errno));
! 410: close(s);
! 411: return -1;
! 412: }
! 413:
! 414: switch ((pid = fork())) {
! 415: case -1:
! 416: printf("Error:: in socket options #%d - %s\n", errno, strerror(errno));
! 417: close(s);
! 418: return -1;
! 419: case 0:
! 420: setsid();
! 421:
! 422: while (!Kill) {
! 423: FD_ZERO(&rfd);
! 424: FD_SET(s, &rfd);
! 425: if (select(s + 1, &rfd, NULL, NULL, NULL) == -1)
! 426: continue;
! 427:
! 428: memset(buf, 0, TFTP_BUF);
! 429: clilen = sizeof cli;
! 430: len = recvfrom(s, buf, TFTP_BUF, 0, (struct sockaddr*) &cli,
! 431: (socklen_t*) &clilen);
! 432: if (len == -1) {
! 433: VERB(5) printf("Error:: in recvfrom #%d - %s\n",
! 434: errno, strerror(errno));
! 435: continue;
! 436: }
! 437:
! 438: tftp = (struct tftphdr*) (pos = buf);
! 439: VERB(5) printf("Info(5):: Received packet from %s len %d with opcode=%hd\n",
! 440: inet_ntoa(cli.sin_addr), len, ntohs(tftp->th_opcode));
! 441: switch (ntohs(tftp->th_opcode)) {
! 442: case WRQ:
! 443: len -= 2;
! 444: pos += 2;
! 445: strlcpy(szFName, (char*) pos, MAX_STR);
! 446: VERB(5) printf("Info(5):: Get filename %s\n", szFName);
! 447: len -= strlen((char*) pos) + 1;
! 448: pos += strlen((char*) pos) + 1;
! 449: VERB(5) printf("Info(5):: Get mode %s len=%d\n", pos, len);
! 450: if (strncmp((char*) pos, "octet", len)) {
! 451: memset(buf, 0, TFTP_BUF);
! 452: tftp->th_opcode = htons(ERROR);
! 453: tftp->th_code = htons(EBADOP);
! 454: strncpy(tftp->th_data, "Error:: mode not supported", 27);
! 455: sendto(s, buf, 31, 0, (struct sockaddr*) &cli, sizeof cli);
! 456: continue;
! 457: }
! 458: VERB(2) printf("Info(2):: Receive file %s from %s\n",
! 459: szFName, inet_ntoa(cli.sin_addr));
! 460:
! 461: f = open(szFName, O_WRONLY | O_CREAT | O_EXCL, 0644);
! 462: if (f == -1) {
! 463: memset(buf, 0, TFTP_BUF);
! 464: tftp->th_opcode = htons(ERROR);
! 465: switch (errno) {
! 466: case EACCES:
! 467: case EPERM:
! 468: tftp->th_code = htons(EACCESS);
! 469: break;
! 470: case EEXIST:
! 471: tftp->th_code = htons(EEXISTS);
! 472: break;
! 473: default:
! 474: tftp->th_code = htons(ENOSPACE);
! 475: }
! 476: snprintf(tftp->th_data, STRSIZ, "Error:: in file %s",
! 477: strerror(errno));
! 478: sendto(s, buf, strlen(tftp->th_data) + 4, 0,
! 479: (struct sockaddr*) &cli, sizeof cli);
! 480: continue;
! 481: }
! 482:
! 483: memset(buf, 0, TFTP_BUF);
! 484: tftp->th_opcode = htons(ACK);
! 485: tftp->th_block = seq = 0;
! 486: sendto(s, tftp, 4, 0, (struct sockaddr*) &cli, sizeof cli);
! 487:
! 488: for (retry = TFTP_RETRY; retry;) {
! 489: FD_ZERO(&rfd);
! 490: FD_SET(s, &rfd);
! 491: if (select(s + 1, &rfd, NULL, NULL, &tv) < 1) {
! 492: retry--;
! 493: continue;
! 494: }
! 495: memset(buf, 0, TFTP_BUF);
! 496: clilen = sizeof sin;
! 497: if ((len = recvfrom(s, buf, TFTP_BUF, 0,
! 498: (struct sockaddr*) &rcv,
! 499: (socklen_t*) &clilen)) == -1) {
! 500: VERB(5) printf("Error:: in recvfrom #%d - %s\n",
! 501: errno, strerror(errno));
! 502: retry--;
! 503: continue;
! 504: } else
! 505: if (cli.sin_addr.s_addr != rcv.sin_addr.s_addr)
! 506: continue;
! 507:
! 508: VERB(5) printf("Info(5):: received opcode=%d block=%d seq=%d\n",
! 509: ntohs(tftp->th_opcode), ntohs(tftp->th_block), seq);
! 510: if (ERROR == ntohs(tftp->th_opcode)) {
! 511: syslog(LOG_ERR, "Error:: in tftp receiving #%d - %s",
! 512: tftp->th_code, tftp->th_data);
! 513: close(f);
! 514: unlink(szFName);
! 515: break;
! 516: }
! 517: if (DATA == ntohs(tftp->th_opcode) &&
! 518: ++seq == ntohs(tftp->th_block)) {
! 519: if (write(f, tftp->th_data, len - 4) == -1) {
! 520: syslog(LOG_ERR, "Error:: Can`t write to file %s\n",
! 521: szFName);
! 522: close(f);
! 523: unlink(szFName);
! 524: break;
! 525: }
! 526:
! 527: memset(buf, 0, TFTP_BUF);
! 528: tftp->th_opcode = htons(ACK);
! 529: tftp->th_block = htons(seq);
! 530: sendto(s, tftp, 4, 0, (struct sockaddr*) &rcv, sizeof rcv);
! 531: VERB(5) printf("Info(5):: Send ACK for %s block=%d\n",
! 532: inet_ntoa(cli.sin_addr), seq);
! 533:
! 534: if (SEGSIZE > len - 4) {
! 535: close(f);
! 536: syslog(LOG_INFO, "TFTP transfer complete to %s",
! 537: szFName);
! 538: break;
! 539: }
! 540: } else {
! 541: memset(buf, 0, TFTP_BUF);
! 542: tftp->th_opcode = htons(ERROR);
! 543: tftp->th_code = htons(EBADID);
! 544: snprintf(tftp->th_data, STRSIZ, "Error:: in transfer #%d",
! 545: seq);
! 546: sendto(s, buf, strlen(tftp->th_data) + 4, 0,
! 547: (struct sockaddr*) &cli, sizeof cli);
! 548: retry--;
! 549: }
! 550: }
! 551: if (!retry) {
! 552: close(f);
! 553: unlink(szFName);
! 554: syslog(LOG_ERR, "Error:: transfer aborted - timeout!");
! 555: }
! 556:
! 557: break;
! 558: case RRQ:
! 559: len -= 2;
! 560: pos += 2;
! 561: strlcpy(szFName, (char*) pos, MAX_STR);
! 562: VERB(5) printf("Info(5):: Get filename %s\n", szFName);
! 563: len -= strlen((char*) pos) + 1;
! 564: pos += strlen((char*) pos) + 1;
! 565: VERB(5) printf("Info(5):: Get mode %s len=%d\n", pos, len);
! 566: if (strncmp((char*) pos, "octet", len)) {
! 567: memset(buf, 0, TFTP_BUF);
! 568: tftp->th_opcode = htons(ERROR);
! 569: tftp->th_code = htons(EBADOP);
! 570: strncpy(tftp->th_data, "Error:: mode not supported", 27);
! 571: sendto(s, buf, 31, 0, (struct sockaddr*) &cli, sizeof cli);
! 572: continue;
! 573: }
! 574: VERB(2) printf("Info(2):: Send file %s to %s\n",
! 575: szFName, inet_ntoa(cli.sin_addr));
! 576:
! 577: f = open(szFName, O_RDONLY);
! 578: if (f == -1) {
! 579: memset(buf, 0, TFTP_BUF);
! 580: tftp->th_opcode = htons(ERROR);
! 581: switch (errno) {
! 582: case EACCES:
! 583: case EPERM:
! 584: tftp->th_code = htons(EACCESS);
! 585: break;
! 586: case ENOENT:
! 587: tftp->th_code = htons(ENOTFOUND);
! 588: break;
! 589: default:
! 590: tftp->th_code = htons(ENOSPACE);
! 591: }
! 592: snprintf(tftp->th_data, STRSIZ, "Error:: in file %s",
! 593: strerror(errno));
! 594: sendto(s, buf, strlen(tftp->th_data) + 4, 0,
! 595: (struct sockaddr*) &cli, sizeof cli);
! 596: continue;
! 597: } else
! 598: seq = 1;
! 599:
! 600: for (retry = TFTP_RETRY; retry;) {
! 601: tftp->th_opcode = htons(DATA);
! 602: tftp->th_block = htons(seq);
! 603: if ((len = read(f, tftp->th_data, SEGSIZE)) == -1) {
! 604: syslog(LOG_ERR, "Error:: Can`t read from file %s\n",
! 605: szFName);
! 606: close(f);
! 607: break;
! 608: } else
! 609: sendto(s, buf, len + 4, 0,
! 610: (struct sockaddr*) &cli, sizeof cli);
! 611:
! 612: FD_ZERO(&rfd);
! 613: FD_SET(s, &rfd);
! 614: if (select(s + 1, &rfd, NULL, NULL, &tv) < 1) {
! 615: retry--;
! 616: continue;
! 617: }
! 618: memset(buf, 0, TFTP_BUF);
! 619: clilen = sizeof sin;
! 620: if (recvfrom(s, buf, TFTP_BUF, 0, (struct sockaddr*) &rcv,
! 621: (socklen_t*) &clilen) == -1) {
! 622: VERB(5) printf("Error:: in recvfrom #%d - %s\n",
! 623: errno, strerror(errno));
! 624: retry--;
! 625: continue;
! 626: } else
! 627: if (cli.sin_addr.s_addr != rcv.sin_addr.s_addr)
! 628: continue;
! 629:
! 630: VERB(5) printf("Info(5):: received opcode=%d block=%d seq=%d\n",
! 631: ntohs(tftp->th_opcode), ntohs(tftp->th_block), seq);
! 632: if (ERROR == ntohs(tftp->th_opcode)) {
! 633: syslog(LOG_ERR, "Error:: in tftp sending #%d - %s",
! 634: tftp->th_code, tftp->th_data);
! 635: if (lseek(f, len * -1, SEEK_CUR) == -1) {
! 636: syslog(LOG_ERR, "Error:: revert sending #%d - %s",
! 637: errno, strerror(errno));
! 638: close(f);
! 639: break;
! 640: }
! 641: retry--;
! 642: continue;
! 643: }
! 644: if (ACK == ntohs(tftp->th_opcode) &&
! 645: seq == ntohs(tftp->th_block)) {
! 646: seq++;
! 647: if (SEGSIZE > len) {
! 648: close(f);
! 649: syslog(LOG_INFO, "TFTP transfer complete to %s",
! 650: szFName);
! 651: break;
! 652: }
! 653: } else {
! 654: memset(buf, 0, TFTP_BUF);
! 655: tftp->th_opcode = htons(ERROR);
! 656: tftp->th_code = htons(EBADID);
! 657: snprintf(tftp->th_data, STRSIZ, "Error:: in transfer #%d",
! 658: seq);
! 659: sendto(s, buf, strlen(tftp->th_data) + 4, 0,
! 660: (struct sockaddr*) &cli, sizeof cli);
! 661: retry--;
! 662: }
! 663: }
! 664: if (!retry) {
! 665: close(f);
! 666: syslog(LOG_ERR, "Error:: transfer aborted - timeout!");
! 667: }
! 668:
! 669: break;
! 670: case DATA:
! 671: if (seq == 0xffff)
! 672: VERB(5) printf("Error:: not specified operation!\n");
! 673: break;
! 674: }
! 675: }
! 676:
! 677: break;
! 678: }
! 679:
! 680:
! 681: close(s);
! 682: return 0;
! 683: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>