|
|
1.1 ! root 1: /* ! 2: * dcpxfer.c ! 3: * ! 4: * Revised edition of dcp ! 5: * ! 6: * Stuart Lynne May/87 ! 7: * ! 8: * Copyright (c) Richard H. Lamb 1985, 1986, 1987 Changes Copyright (c) Stuart ! 9: * Lynne 1987 ! 10: * ! 11: * "DCP" a uucp clone. Copyright Richard H. Lamb 1985,1986,1987 ! 12: * file send routines ! 13: */ ! 14: ! 15: #include "dcp.h" ! 16: #include <signal.h> ! 17: #include <ctype.h> ! 18: #include <sys/timeb.h> ! 19: #include <sys/stat.h> ! 20: #include <access.h> ! 21: #include "perm.h" ! 22: ! 23: extern int (*getpkt)(), (*sendpkt)(), (*openpk)(), (*closepk)(); ! 24: ! 25: extern int errno; ! 26: extern char *sys_errlist[]; ! 27: extern char *strtok(); ! 28: extern char *rebuildfn(); ! 29: static char tempname[] = "/usr/spool/uucp/TM.XXXXXX"; ! 30: static unsigned char rpacket[MAXPACK]; ! 31: static unsigned char spacket[MAXPACK]; ! 32: char reason [80]; ! 33: static char S_record [BUFSIZ]; ! 34: static int lstat; ! 35: extern int canwrite(); ! 36: #define BIGBUFSZ (BUFSIZ * 20) ! 37: static char bigreadbuf [BIGBUFSZ]; ! 38: ! 39: struct timeb transferstart; /* transfer start time */ ! 40: struct timeb transferstop; /* transfer stop time */ ! 41: ! 42: /* ! 43: * s d a t a ! 44: * ! 45: * Send File Data ! 46: */ ! 47: sdata() ! 48: { ! 49: for (;;) { ! 50: if ((size = read(fpfd, spacket, pktsize)) <= 0) /* Get data */ ! 51: return 'Z'; /* If EOF set state to that */ ! 52: bytecount += size; ! 53: if ((*sendpkt) (spacket, size, 0)) ! 54: return cantsend(); /* send data */ ! 55: } ! 56: } ! 57: ! 58: /* ! 59: * s b r e a k ! 60: * ! 61: */ ! 62: sbreak() ! 63: { ! 64: if (sendmsg("H") < 0) ! 65: return cantsend(); ! 66: if (getmsg(spacket) < 0) { ! 67: plog(M_CONVERSE, "Cannot get reply to H (sbreak)"); ! 68: terminatelevel++; ! 69: return 'Y'; /* was return 0 */ ! 70: } ! 71: printmsg(M_CONVERSE, "Switch modes: %s", spacket); ! 72: if (spacket[1] == 'N') ! 73: return 'G'; ! 74: return 'Y'; ! 75: } ! 76: ! 77: /* ! 78: * s e o f ! 79: * ! 80: * Send End-Of-File. ! 81: */ ! 82: seof() ! 83: { ! 84: double elapsed; ! 85: ! 86: close(fpfd); ! 87: fpfd = -1; ! 88: printmsg(M_TRANSFER, "seof"); ! 89: if ((*sendpkt) (spacket, 0, 0) < 0) ! 90: return cantsend(); /* length zero packet indicates EOF */ ! 91: if (getmsg(spacket) < 0) ! 92: return cantread(); /* was plog; termlev++, no ret*/ ! 93: printmsg(M_TRANSFER, "seof: spacket is %s.", spacket); ! 94: if (strncmp(spacket, "CY", 2) != 0) { ! 95: sprintf(reason, "Remote would not accept file %s", fromfilep); ! 96: plog(M_TRANSFER, reason); ! 97: notifystatus(fromfilep, tofilep, 1, 0, lstat); ! 98: return 'F'; ! 99: } ! 100: if (lstat && (index(optionp, 'c') == NULL)) { ! 101: unlink(xfromfile); ! 102: /* plog("unlinking %s", xfromfile); */ ! 103: printmsg(M_TRANSFER, "unlinking %s.", xfromfile); ! 104: } ! 105: printmsg(M_TRANSFER, "seof: Transfer of %s completed.", ! 106: fromfilep); ! 107: ftime(&transferstop); ! 108: printmsg(M_TRANSFER, "Stop time is %ld.%03d\n", ! 109: transferstop.time, transferstop.millitm); ! 110: elapsed = ! 111: (double)transferstop.time - (double)transferstart.time; ! 112: elapsed += ! 113: ((double)transferstop.millitm - ! 114: (double)transferstart.millitm) / 1000.0; ! 115: if (total_errors > 0) ! 116: plog(M_TRANSFER, ! 117: "S (OK) %ld bytes, %5.2f seconds, %5.1f Bps, %d error%c", ! 118: bytecount, elapsed, (double) bytecount / elapsed, ! 119: total_errors, total_errors == 1 ? ' ' : 's'); ! 120: else ! 121: plog(M_TRANSFER, "S (OK) %ld bytes, %5.2f seconds, %5.1f Bps", ! 122: bytecount, elapsed, (double) bytecount / elapsed); ! 123: notifystatus(fromfilep, tofilep, 1, 1, lstat); ! 124: return 'F'; /* go get the next file to send */ ! 125: } ! 126: ! 127: /* ! 128: * s f i l e ! 129: * ! 130: * Send File Header. ! 131: * This needs to respond to: ! 132: * 1) commands from a C. file ! 133: * 2) requests from remote. ! 134: */ ! 135: sfile() ! 136: { ! 137: printmsg(M_SPOOL, "Sending %s as %s,\n\tspool %s", ! 138: fromfilep, tofilep, xfromfile); ! 139: plog(M_SPOOL, "S (%s)->(%s)", fromfilep, tofilep); ! 140: bytecount = 0; ! 141: total_errors = 0; ! 142: ftime(&transferstart); ! 143: printmsg(M_TRANSFER, "Start time is %ld.%03d\n", ! 144: transferstart.time, transferstart.millitm); ! 145: return 'D'; ! 146: } ! 147: ! 148: /* ! 149: * s i n i t ! 150: * ! 151: * Send Initiate: send this host's parameters and get other side's back. ! 152: */ ! 153: sinit() ! 154: { ! 155: if ((*openpk) ()) ! 156: return 'A'; ! 157: return ('B'); ! 158: } ! 159: ! 160: /* ! 161: * cdotcmd ! 162: * read commands from C. file, and dispatch accordingly. ! 163: * This routine and the corresponding routine rmtcmd need to set up ! 164: * the following global variables. ! 165: * fromfilep pointer to file name that is source. ! 166: * tofilep pointer to file name that is destination. ! 167: * xfromfile file name that is actual source, eg, spool file. ! 168: * optionp pointer to option string. ! 169: * modep pointer to octal mode string. ! 170: * notifyp pointer to user to be notified ! 171: * These control the action of sendf, sfile and seof. ! 172: * ! 173: */ ! 174: cdotcmd() ! 175: { ! 176: char *cp; ! 177: ! 178: lstat = 1; ! 179: printmsg(M_SPOOL, "cdotcmd enter"); ! 180: if (fpfd != -1) { /* If not already open, */ ! 181: plog(M_SPOOL, "File already open"); ! 182: terminatelevel++; ! 183: return 'A'; /* If something's already open, we' trouble */ ! 184: } ! 185: printmsg(M_SPOOL, "looking for next file..."); ! 186: if (getcline()) { /* get next file from current work */ ! 187: fclose(cfp); ! 188: printmsg(M_SPOOL, "unlinking %s", cfile); ! 189: unlink(cfile); /* close and delete completed workfile */ ! 190: cfp = NULL; ! 191: return 'B'; /* end controlling session */ ! 192: } ! 193: if (*clinep [1] == 'R') { /* ask for file */ ! 194: int permerr = 0; ! 195: printmsg(M_SPOOL, "getcline gave us an 'R' rec"); ! 196: if ((cp = rebuildfn(tofilep)) == NULL) { ! 197: sprintf(reason, "No such user as referenced in \"%s\"", ! 198: tofilep); ! 199: permerr = 1; ! 200: } else ! 201: strcpy(xtofile, cp); ! 202: if (!permerr && !perm_write(xtofile)) { ! 203: sprintf(reason, "No permission to write file \"%s\"", ! 204: xtofile); ! 205: permerr = 1; ! 206: } ! 207: if (!permerr && !canwrite(xtofile)) { ! 208: sprintf(reason, "Unable to create \"%s\"; %s", ! 209: xtofile, sys_errlist[errno]); ! 210: permerr = 1; ! 211: } ! 212: if (permerr) { ! 213: plog(M_SPOOL, reason); ! 214: notifystatus(fromfilep, xtofile, 0, 0, lstat); ! 215: return 'F'; /* Give up if can't */ ! 216: } ! 217: if (sendmsg(S_record) < 0) /* really S&R_record */ ! 218: return cantsend(); ! 219: if (getmsg(spacket) < 0) ! 220: return cantread(); ! 221: printmsg(M_SPOOL, "spacket is %s", spacket); ! 222: if ((spacket [0] != 'R') || (spacket [1] != 'Y')) { ! 223: sprintf(reason, "Remote won't send file \"%s\".", ! 224: fromfilep); ! 225: plog(M_SPOOL, reason); ! 226: notifystatus(fromfilep, xtofile, 0, 0, lstat); ! 227: return 'F'; /* was return 'A' */ ! 228: } ! 229: return rfile(); ! 230: } ! 231: if (strcmp(clinep [1], "S") == 0) { ! 232: int noperm; ! 233: noperm = 0; ! 234: printmsg(M_SPOOL, "Opening \"%s\" for sending.", xfromfile); ! 235: if ((strcmp(perm_value(sendfiles_e), "call") == 0) || ! 236: !perm_read(xfromfile)) { ! 237: if (role != MASTER) { ! 238: sprintf(reason, ! 239: "No permission to send as remote \"%s\"", ! 240: xfromfile); ! 241: noperm = 1; ! 242: } ! 243: } else if ((strcmp(perm_value(sendfiles_e), "yes") != 0) || ! 244: !perm_read(xfromfile)) { ! 245: sprintf(reason,"No permission to send file\"%s\"", ! 246: xfromfile); ! 247: noperm = 1; ! 248: } ! 249: if (noperm) { ! 250: plog(M_TRANSFER, reason); ! 251: notifystatus(xfromfile, xtofile, 0, 0, lstat); ! 252: return 'F'; ! 253: } ! 254: fpfd = open(xfromfile, 0); /* open the file to be sent */ ! 255: if (fpfd == -1) { ! 256: sprintf(reason, "Unable to read \"%s\"; %s", ! 257: xfromfile, sys_errlist[errno]); ! 258: plog(M_TRANSFER, reason); ! 259: notifystatus(xfromfile, xtofile, 0, 0, lstat); ! 260: return 'F'; ! 261: } ! 262: /* send 'S fromfile tofile user - tofile <perms>'. */ ! 263: if (sendmsg(S_record) < 0) ! 264: return cantsend(); /* was return 0 */ ! 265: if (getmsg(spacket) < 0) ! 266: return cantread(); /* was return 0 */ ! 267: printmsg(M_SPOOL, "spacket is %s", spacket); ! 268: if (spacket[1] != 'Y') { ! 269: sprintf(reason, "Remote won't accept file \"%s\"", ! 270: xfromfile); ! 271: plog(M_TRANSFER, reason); ! 272: notifystatus(xfromfile, xtofile, 1, 0, lstat); ! 273: close(fpfd); ! 274: fpfd = -1; ! 275: return 'F'; ! 276: } ! 277: return sfile(); ! 278: } ! 279: plog(M_SPOOL, "unknown record in \"%s\" of \"%s\"", cfile, clinep[1]); ! 280: return 'Y'; ! 281: } ! 282: ! 283: /* ! 284: * getcline() ! 285: * get one line from the C. file and split it apart. ! 286: */ ! 287: getcline() ! 288: { ! 289: char *p; ! 290: static char line[BUFSIZ]; ! 291: if (fgets(line, BUFSIZ, cfp) == (char *) NULL) ! 292: return 1; ! 293: if ((p = index(line, '\n')) != NULL) ! 294: *p = '\0'; ! 295: strcpy(cline, line); ! 296: return sepcline(); ! 297: ! 298: } ! 299: ! 300: sepcline() ! 301: { ! 302: char *sp; ! 303: int i; ! 304: ! 305: printmsg(M_SPOOL, "sepcline: line is %s", cline); ! 306: strcpy(S_record, cline); ! 307: sp = cline; ! 308: for (i=0; i<10; i++) ! 309: clinep[i] = NULL; ! 310: for (i=1; i<10; i++) { ! 311: if ( (clinep[i]=strtok(sp, " \t\n")) == NULL ){ ! 312: break; ! 313: } ! 314: printmsg(M_SPOOL, "cline[%d]:\t%\"%s\"", i, clinep[i]); ! 315: sp = NULL; ! 316: } ! 317: ! 318: printmsg(M_SPOOL,"PERMISSIONS WATCH: cline[%d] is %o",i, clinep[i]); ! 319: ! 320: /* If the last field of a parsed command line is NOT null, then ! 321: * there is something wrong with the line parsed. Leave a message ! 322: * to this affect in the logs, and print the offending line there ! 323: * as well. Abort processing this file. ! 324: ! 325: * It has not yet been determined what affects this will have. ! 326: * It may keep other requests from the site which is expecting to ! 327: * receive files from receving all of the files it expects. ! 328: ! 329: * the following is a short description of how this was called: ! 330: ! 331: sendf() -> calls cdotcmd() until 'complete' (dcp.c) ! 332: cdotcmd() -> calls getcline() until a non-zero ! 333: value is returned. When a non zero ! 334: value is returned, the C. file being ! 335: read is closed and deleted. A 'B' is ! 336: then returned back to sendf() ! 337: getcline() -> calls sepcline (breaks out the C. fields) ! 338: ! 339: * Bob Hemedinger 01/27/92 ! 340: */ ! 341: ! 342: /* 01/30/92: removed the return statement. We WANT to continue ! 343: * if we don't see the NULL terminator for compatibility with ! 344: * other variants. ! 345: */ ! 346: ! 347: if (clinep[9] != NULL) { ! 348: plog(M_SPOOL, "Error parsing command 'C.' file"); ! 349: plog(M_SPOOL, "last sepcline field not null"); ! 350: plog(M_SPOOL, "Actually parsed: "); ! 351: plog(M_SPOOL, " %s %s %s %s %s %s %s %s %s", ! 352: clinep[1], clinep[2], clinep[3], ! 353: clinep[4], clinep[5], clinep[6], ! 354: clinep[7], clinep[8], clinep[9]); ! 355: } ! 356: nclinep = i; ! 357: fromfilep = clinep[2]; ! 358: tofilep = clinep[3]; ! 359: usernamep = clinep[4]; ! 360: optionp = clinep[5]; ! 361: spoolfilep = clinep[6]; ! 362: modep = clinep[7]; ! 363: notifyp = clinep[8]; ! 364: ! 365: if (strcmp(clinep[1], "S") == 0) { ! 366: sprintf(xfromfile, "%s/%s/%s", SPOOLDIR, rmtname, spoolfilep); ! 367: if (index(optionp, 'c') != NULL) /* this looks weak */ ! 368: strcpy(xfromfile, fromfilep); ! 369: } else if (strcmp(clinep[1], "R") == 0) { ! 370: strcpy(xfromfile, fromfilep); ! 371: } else if (*clinep[1] == 'H') { ! 372: ; ! 373: } else { ! 374: plog(M_SPOOL, "Unrecog record type %s", cline); ! 375: printmsg(M_SPOOL, "Unrecog type %s %s %s", cline[1], ! 376: cline[2], cline[3]); ! 377: return 1; ! 378: } ! 379: return 0; ! 380: } ! 381: ! 382: /*********************** MISC SUB SUB PROTOCOL *************************/ ! 383: ! 384: /* ! 385: * ! 386: * schkdir ! 387: * scan the dir ! 388: */ ! 389: schkdir() ! 390: { ! 391: char c; ! 392: ! 393: c = scandir(); ! 394: ! 395: if (c == 'Q') { ! 396: return ('Y'); ! 397: } ! 398: if (c == 'S') { ! 399: sprintf(rpacket, "HN"); ! 400: if ((*sendpkt) (rpacket, 0, 1)) ! 401: return cantsend(); ! 402: } ! 403: return ('B'); ! 404: } ! 405: ! 406: /* ! 407: * endp() end protocol ! 408: * ! 409: */ ! 410: endp() ! 411: { ! 412: ! 413: (void) sendmsg("HY"); ! 414: (*closepk) (); ! 415: return 'P'; ! 416: } ! 417: ! 418: ! 419: ! 420: /***********************RECEIVE PROTOCOL**********************/ ! 421: ! 422: /* ! 423: * r d a t a ! 424: * ! 425: * Receive Data ! 426: */ ! 427: rdata() ! 428: { ! 429: int len; ! 430: ! 431: if ((*getpkt) (rpacket, &len)) ! 432: return cantread(); ! 433: if (len == 0) ! 434: return reof(); ! 435: if (write(fpfd, rpacket, len) != len) /* Write the data to the file */ ! 436: return 'Y'; ! 437: bytecount += len; ! 438: return 'J'; /* Remain in data state */ ! 439: /* changed to J */ ! 440: } ! 441: ! 442: /* ! 443: * reof ! 444: * handle eof on read. ! 445: * try to link the temp file to the new name; ! 446: * if not successful, then copy it. ! 447: */ ! 448: reof() ! 449: { ! 450: int tfpfd; ! 451: int noperm; ! 452: double elapsed; ! 453: int mode; ! 454: int bytes; ! 455: ! 456: noperm = 0; ! 457: tfpfd = -1; ! 458: close(fpfd); ! 459: fpfd = -1; ! 460: unlink(xtofile); ! 461: if (link(tempname, xtofile) == -1) { ! 462: if ((tfpfd = open(tempname, 0)) == -1) { ! 463: sprintf(reason, "Unable to reread \"%s\"; %s", ! 464: tempname, sys_errlist[errno]); ! 465: noperm = 1; ! 466: } else if ((fpfd = creat(xtofile, 0644)) == -1) { ! 467: sprintf(reason, "Unable to create \"%s\"; %s (rdata)", ! 468: xtofile, sys_errlist[errno]); ! 469: noperm = 1; ! 470: } ! 471: if (noperm) { ! 472: plog(M_TRANSFER, reason); ! 473: notifystatus(fromfilep, tempname, 0, 0, lstat); ! 474: if (sendmsg("CN") < 0) { ! 475: plog(M_SPOOL, "Message CN refused"); ! 476: return cantsend(); ! 477: } ! 478: if (tfpfd != -1) ! 479: close(tfpfd); ! 480: if (fpfd != -1) ! 481: close(fpfd); ! 482: return 'F'; ! 483: } ! 484: while ((bytes = read(tfpfd, bigreadbuf, BIGBUFSZ)) > 0) ! 485: write(fpfd, bigreadbuf, bytes); ! 486: close(tfpfd); ! 487: close(fpfd); ! 488: fpfd = -1; ! 489: } ! 490: unlink(tempname); ! 491: ! 492: /* this problem showed up in 4.0. When we request a file, nothing specifies ! 493: the file permissions. This little ditty will take care of the problem. ! 494: Now we check the value of nclinep, as it holds the place where we ! 495: exitted the loop which parses the command received. If we broke out at 7, ! 496: which is where the file permissions are stored, then we end up with garbage ! 497: permissions in modep (which is clinep[7]). For these cases, we will default ! 498: to permissions of 0644 and pray that the customers can live with it. ! 499: ! 500: Bob H. 08/26/92 */ ! 501: ! 502: if ((strlen(modep) > 0) && (mode = getoct(modep)) != 0 && ! 503: (chmod(xtofile, (nclinep == 7 ? 0644:getoct(modep)) ) == -1)) { ! 504: printmsg(M_TRANSFER, "Unable to change permission"); ! 505: plog(M_TRANSFER, ! 506: "Unable to change permission to \"%s\" on file \"%s\"", ! 507: modep, xtofile); ! 508: } ! 509: /* now, do the copy. rewind the above file and reread it */ ! 510: /* we ought to do the copy in a temp file, and move it here */ ! 511: printmsg(M_TRANSFER, "transfer complete"); ! 512: ftime(&transferstop); ! 513: printmsg(M_TRANSFER, "Stop time is %ld.%03d\n", ! 514: transferstop.time, transferstop.millitm); ! 515: elapsed = ! 516: (double)transferstop.time - ! 517: (double)transferstart.time; ! 518: elapsed += ! 519: ((double)transferstop.millitm - ! 520: (double)transferstart.millitm) / 1000.0; ! 521: if (total_errors > 0) ! 522: plog(M_TRANSFER, ! 523: "R (OK) %ld bytes, %5.2f seconds, %5.1f Bps, %d error%c", ! 524: bytecount, (double)elapsed, bytecount / elapsed, ! 525: total_errors, total_errors == 1 ? ' ' : 's'); ! 526: else ! 527: plog(M_TRANSFER, "R (OK) %ld bytes, %5.2f seconds, %5.1f Bps", ! 528: bytecount, (double)elapsed, bytecount / elapsed); ! 529: notifystatus(fromfilep, xtofile, 0, 1, lstat); ! 530: printmsg(M_TRANSFER, "returning from rdata"); ! 531: if (sendmsg("CY") < 0) { ! 532: strcpy(reason, "Message CY refused."); ! 533: plog(M_TRANSFER, reason); ! 534: return cantsend(); ! 535: } ! 536: return 'F'; ! 537: } ! 538: ! 539: /* ! 540: * Analog of cdotcmd. This takes 'S' records or 'R' records ! 541: * from the other end and dispatches them properly. ! 542: */ ! 543: rmtcmd() ! 544: { ! 545: static char buf[256]; ! 546: char *cp; ! 547: int noperm; ! 548: ! 549: lstat = 0; ! 550: if (getmsg(buf) < 0) { ! 551: printmsg(M_LOWPROTO, "in rmtcmd, getmsg says -1"); ! 552: return cantread(); /* was return 0 */ ! 553: } ! 554: printmsg(M_TRANSFER, "buf[0] is %c", buf[0]); ! 555: strcpy(cline, buf); ! 556: sepcline(); ! 557: if (*clinep [1] == 'H') { /* used to be buf [0] */ ! 558: printmsg(M_TRANSFER, "rmtcmd got H, returning C"); ! 559: return 'C'; ! 560: } ! 561: printmsg(M_TRANSFER, "rmtcmd: buf %d \"%s\"", strlen(S_record), ! 562: S_record); ! 563: if (strcmp (clinep [1], "R") == 0) { ! 564: printmsg(M_INFO, "rmdcmd: send file R"); ! 565: printmsg(M_SPOOL, "Opening %s for sending.", xfromfile); ! 566: if ((strcmp(perm_value(request_e), "yes") != 0) || ! 567: !perm_read(xfromfile)) { ! 568: sprintf(reason, "Request permission denied: \"%s\"", ! 569: xfromfile); ! 570: plog(M_TRANSFER, reason); ! 571: sendmsg("RN"); ! 572: notifystatus(fromfilep, xtofile, 0, 0, lstat); ! 573: return 'F'; ! 574: } else { ! 575: fpfd = open(xfromfile, 0); ! 576: /* open the file to be sent */ ! 577: if (fpfd == -1) { /* If bad file pointer, give up */ ! 578: sprintf(reason, ! 579: "Cannot open file \"%s\".", xfromfile); ! 580: plog(M_TRANSFER, reason); ! 581: sendmsg("RN"); ! 582: notifystatus(fromfilep, xtofile, 0, 0, lstat); ! 583: return 'F'; /* was return 'A' */ ! 584: } ! 585: sendmsg("RY"); ! 586: return sfile(); ! 587: } ! 588: } ! 589: printmsg(M_INFO, "rmtcmd: receive file \"%s\"", tofilep); ! 590: if ((cp = index(optionp, 'c')) != NULL) /* oops, not allowd*/ ! 591: *cp = ' '; ! 592: noperm = 0; ! 593: if ((cp = rebuildfn(tofilep)) == NULL) { ! 594: noperm = 1; ! 595: sprintf(reason, "No such user as referenced in \"%s\"", ! 596: tofilep); ! 597: } else ! 598: strcpy(xtofile, rebuildfn(tofilep)); ! 599: if (!noperm && !perm_write(xtofile)) { ! 600: sprintf(reason, "No permission to write file \"%s\"", xtofile); ! 601: noperm = 1; ! 602: } ! 603: if (!noperm && !canwrite(xtofile)) { ! 604: sprintf(reason, "rmtcmd: Unable to create file \"%s\": %s", ! 605: xtofile, sys_errlist[errno]); ! 606: noperm = 1; ! 607: } ! 608: if (noperm) { ! 609: plog(M_TRANSFER, reason); ! 610: notifystatus(fromfilep, xtofile, 0, 0, lstat); ! 611: if (sendmsg("SN") < 0) ! 612: return cantsend(); ! 613: return 'F'; ! 614: } ! 615: if (sendmsg("SY") < 0) { ! 616: plog(M_TRANSFER, "Can't send SY"); ! 617: return 'Y'; ! 618: } ! 619: return rfile(); ! 620: } ! 621: ! 622: /* ! 623: * r f i l e ! 624: * ! 625: * Receive File Header ! 626: */ ! 627: rfile() ! 628: { ! 629: printmsg(M_TRANSFER, "Receiving %s as %s", fromfilep, xtofile); ! 630: /* create temp file name, open it for output */ ! 631: if ((fpfd = creat(mktemp(tempname), 0644)) == -1) { ! 632: sprintf(reason, "Unable to create \"%s\"; %s", ! 633: tempname, sys_errlist[errno]); ! 634: plog(M_TRANSFER, reason); ! 635: notifystatus(fromfilep, xtofile, 0, 0, lstat); ! 636: return 'F'; /* Give up if can't */ ! 637: } ! 638: plog(M_TRANSFER, "R (%s)<-(%s)", xtofile, fromfilep); ! 639: bytecount = 0; ! 640: total_errors = 0; ! 641: ftime(&transferstart); ! 642: printmsg(M_TRANSFER, "Start time is %ld.%03d\n", ! 643: transferstart.time, transferstart.millitm); ! 644: return 'J'; /* Switch to data state */ ! 645: } ! 646: ! 647: /* ! 648: * r i n i t ! 649: * ! 650: * Receive Initialization ! 651: */ ! 652: rinit() ! 653: { ! 654: if ((*openpk) ()) { ! 655: plog(M_TRANSFER, "Unable to get opening packet"); ! 656: return 'Y'; ! 657: } ! 658: return ('F'); ! 659: } ! 660: ! 661: /* ! 662: * |getmsg()| recieves a null-terminated "conversation-level" message ! 663: * from the communications channel. This may require one or more packets, ! 664: * but all of them will be "long-data" packets containing a full 64 bytes. ! 665: */ ! 666: int getmsg(dest) ! 667: char *dest; ! 668: { ! 669: int len; ! 670: ! 671: while(1) { ! 672: if ((*getpkt)(dest, &len) < 0) ! 673: return(-1); ! 674: *(dest + len) = '\0'; /* make sure it's terminated */ ! 675: if (strlen(dest) != len) ! 676: break; /* we reached the terminator */ ! 677: dest += len; ! 678: } ! 679: return( 0 ); ! 680: } ! 681: ! 682: /* ! 683: * |sendmsg(message)| sends a null-terminated "conversation-level" message. ! 684: */ ! 685: int sendmsg(message) ! 686: char *message; ! 687: { ! 688: int len; ! 689: len = strlen(message) + 1; /* total length including '\0' */ ! 690: ! 691: while(1) { ! 692: if ((*sendpkt)(message, 0, 1) < 0) /* send with padding */ ! 693: return -1; ! 694: if ((len -= pktsize) <= 0) ! 695: break; ! 696: message += pktsize; ! 697: } ! 698: return 0; ! 699: } ! 700:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.