Annotation of coherent/d/usr/bin/uucpstuff/dcp/dcpxfer.c, revision 1.1.1.1

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: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.