# 2.11BSD#431 - /usr/src/usr.bin/uucp/cntrl.c

##### Functions

    arrived           X
    blptcl            X
    cntrl             X
    fptcl             X
    lnotify           X
    notify            X
    nullf             X
    putinpub          X
    rmesg             X
    startup           X
    stptcl            X
    unlinkdf          X
    wmesg             X

##### Variables

    Dfile             X
    Em_msg            X
    HaveSentHup       X
    LastCheckedNoLoginX
    LastTurned        X
    Now               X
    Ptbl              X
    TransferSucceeded X
    Wfile             X
    stbuf             X
    willturn          X

##### Macros

    EM_BADUUCP        X
    EM_LOCACC         X
    EM_LOCCP          X
    EM_MAX            X
    EM_NOTMP          X
    EM_RMTACC         X
    EM_RMTCP          X
    HUP               X
    RAMESG            X
    RCVFILE           X
    RESET             X
    RMESG             X
    RQSTCMPT          X
    SLTPTCL           X
    SNDFILE           X
    USEPTCL           X
    WMESG             X
    W_DFILE           X
    W_FILE1           X
    W_FILE2           X
    W_MODE            X
    W_NUSER           X
    W_OPTNS           X
    W_TYPE            X
    W_USER            X
    XFRRATE           X
    XUUCP             X

##### struct's

    Proto             X

       1: #ifndef lint
       2: static char sccsid[] = "@(#)cntrl.c	5.8 (Berkeley) 1/24/86";
       3: #endif
       4:
       5: #include "uucp.h"
       6: #include <sys/stat.h>
       7: #include "uust.h"
       8:
       9: extern int errno;
      10: extern int turntime;
      11: int willturn;
      12: int HaveSentHup = 0;
      13:
      14: struct Proto {
      15:     char P_id;
      16:     int (*P_turnon)();
      17:     int (*P_rdmsg)();
      18:     int (*P_wrmsg)();
      19:     int (*P_rddata)();
      20:     int (*P_wrdata)();
      21:     int (*P_turnoff)();
      22: };
      23:
      24: extern int gturnon(), gturnoff();
      25: extern int grdmsg(), grddata();
      26: extern int gwrmsg(), gwrdata();
      27: extern int imsg(), omsg(), nullf();
      28: #ifdef TCPIP
      29: extern int twrmsg(), trdmsg();
      30: extern int twrdata(), trddata();
      31: #endif TCPIP
      32: #ifdef PAD
      33: extern int fturnon(), fturnoff();
      34: extern int frdmsg(), frddata();
      35: extern int fwrmsg(), fwrdata();
      36: #endif PAD
      37:
      38: struct Proto Ptbl[]={
      39: #ifdef TCPIP
      40:     't', nullf, trdmsg, twrmsg, trddata, twrdata, nullf,
      41: #endif TCPIP
      42: #ifdef PAD
      43:     'f', fturnon, frdmsg, fwrmsg, frddata, fwrdata, fturnoff,
      44: #endif PAD
      45:     'g', gturnon, grdmsg, gwrmsg, grddata, gwrdata, gturnoff,
      46:     '\0'
      47: };
      48:
      49: int (*Imsg)() = imsg, (*Omsg)() = omsg;
      50:
      51: int (*Rdmsg)()=imsg, (*Rddata)();
      52: int (*Wrmsg)()=omsg, (*Wrdata)();
      53: int (*Turnon)()=nullf, (*Turnoff)() = nullf;
      54:
      55: struct timeb Now, LastTurned, LastCheckedNoLogin;
      56:
      57: static char *YES = "Y";
      58: static char *NO = "N";
      59:
      60: int TransferSucceeded = 1;
      61:
      62: /*  failure messages  */
      63: #define EM_MAX      6
      64: #define EM_LOCACC   "N1"    /* local access to file denied */
      65: #define EM_RMTACC   "N2"    /* remote access to file/path denied */
      66: #define EM_BADUUCP  "N3"    /* a bad uucp command was generated */
      67: #define EM_NOTMP    "N4"    /* remote error - can't create temp */
      68: #define EM_RMTCP    "N5"    /* can't copy to remote directory - file in public */
      69: #define EM_LOCCP    "N6"    /* can't copy on local system */
      70:
      71: char *Em_msg[] = {
      72:     "COPY FAILED (reason not given by remote)",
      73:     "local access to file denied",
      74:     "remote access to path/file denied",
      75:     "system error - bad uucp command generated",
      76:     "remote system can't create temp file",
      77:     "can't copy to file/directory - file left in PUBDIR/user/file",
      78:     "can't copy to file/directory on local system  - file left in PUBDIR/user/file"
      79: };
      80:
      81:
      82: #define XUUCP 'X'   /* execute uucp (string) */
      83: #define SLTPTCL 'P' /* select protocol  (string)  */
      84: #define USEPTCL 'U' /* use protocol (character) */
      85: #define RCVFILE 'R' /* receive file (string) */
      86: #define SNDFILE 'S' /* send file (string) */
      87: #define RQSTCMPT 'C'    /* request complete (string - yes | no) */
      88: #define HUP     'H' /* ready to hangup (string - yes | no) */
      89: #define RESET   'X' /* reset line modes */
      90:
      91: #define W_TYPE      wrkvec[0]
      92: #define W_FILE1     wrkvec[1]
      93: #define W_FILE2     wrkvec[2]
      94: #define W_USER      wrkvec[3]
      95: #define W_OPTNS     wrkvec[4]
      96: #define W_DFILE     wrkvec[5]
      97: #define W_MODE      wrkvec[6]
      98: #define W_NUSER     wrkvec[7]
      99:
     100: #define XFRRATE 35000L
     101: #define RMESG(m, s, n) if (rmesg(m, s, n) != 0) {(*Turnoff)(); return FAIL;} else
     102: #define RAMESG(s, n) if (rmesg('\0', s, n) != 0) {(*Turnoff)(); return FAIL;} else
     103: #define WMESG(m, s) if(wmesg(m, s) != 0) {(*Turnoff)(); return FAIL;} else
     104:
     105: char Wfile[MAXFULLNAME] = {'\0'};
     106: char Dfile[MAXFULLNAME];
     107:
     108: /*
     109:  * To avoid a huge backlog of X. files, start uuxqt every so often.
     110:  */
     111: static int nXfiles = 0; /* number of X files since last uuxqt start */
     112: static char send_or_receive;
     113: struct stat stbuf;
     114:
     115: /*
     116:  *	cntrl  -  this routine will execute the conversation
     117:  *	between the two machines after both programs are
     118:  *	running.
     119:  *
     120:  *	return codes
     121:  *		SUCCESS - ok
     122:  *		FAIL - failed
     123:  */
     124:
     125: cntrl(role, wkpre)
     126: int role;
     127: char *wkpre;
     128: {
     129:     char msg[BUFSIZ], rqstr[BUFSIZ];
     130:     register FILE *fp;
     131:     int filemode;
     132:     char filename[MAXFULLNAME], wrktype, *wrkvec[20];
     133:     extern (*Rdmsg)(), (*Wrmsg)();
     134:     extern char *index(), *lastpart();
     135:     int status = 1;
     136:     register int i, narg;
     137:     int mailopt, ntfyopt;
     138:     int ret;
     139:     static int pnum, tmpnum = 0;
     140:     extern int ReverseRole;
     141:
     142:     pnum = getpid();
     143:     Wfile[0] = '\0';
     144:     willturn = turntime > 0;
     145: remaster:
     146: #ifdef USG
     147:     time(&LastTurned.time);
     148:     LastTurned.millitm = 0;
     149: #else !USG
     150:     ftime(&LastTurned);
     151: #endif !USG
     152:     send_or_receive = RESET;
     153:     HaveSentHup = 0;
     154: top:
     155:     for (i = 0; i < sizeof wrkvec / sizeof wrkvec[0]; i++)
     156:         wrkvec[i] = 0;
     157:     DEBUG(4, "*** TOP ***  -  role=%s\n", role ? "MASTER" : "SLAVE");
     158:     setupline(RESET);
     159:     if (Now.time > (LastCheckedNoLogin.time+60)) {
     160:         LastCheckedNoLogin = Now;
     161:         if (access(NOLOGIN, 0) == 0) {
     162:             logent(NOLOGIN, "UUCICO SHUTDOWN");
     163:             if (Debug > 4)
     164:                 logent("DEBUGGING", "continuing anyway");
     165:             else {
     166:                 WMESG(HUP, YES);
     167:                 RMESG(HUP, msg, 1);
     168:                 goto process;
     169:             }
     170:         }
     171:     }
     172:     if (role == MASTER) {
     173:         /* get work */
     174:         if (ReverseRole || (narg = gtwvec(Wfile, Spool, wkpre, wrkvec)) == 0) {
     175:             ReverseRole = 0;
     176:             WMESG(HUP, "");
     177:             RMESG(HUP, msg, 1);
     178:             goto process;
     179:         }
     180:         wrktype = W_TYPE[0];
     181:
     182:         msg[0] = '\0';
     183:         for (i = 1; i < narg; i++) {
     184:             strcat(msg, " ");
     185:             strcat(msg, wrkvec[i]);
     186:         }
     187:
     188:         if (wrktype == XUUCP) {
     189:             sprintf(rqstr, "X %s", msg);
     190:             logent(rqstr, "REQUEST");
     191:             goto sendmsg;
     192:         }
     193:         mailopt = index(W_OPTNS, 'm') != NULL;
     194:         ntfyopt = index(W_OPTNS, 'n') != NULL;
     195:
     196:         if (narg < 5) {
     197:             char *bnp;
     198:             bnp = rindex(Wfile, '/');
     199:             sprintf(rqstr, "%s/%s", CORRUPT, bnp ? bnp + 1 : Wfile);
     200:             xmv(Wfile, rqstr);
     201:             logent(Wfile, "CMD FILE CORRUPTED");
     202:             Wfile[0] = '\0';
     203:             goto top;
     204:         }
     205:         sprintf(User, "%.9s", W_USER);
     206:         sprintf(rqstr, "%s %s %s %s", W_TYPE, W_FILE1,
     207:           W_FILE2, W_USER);
     208:         logent(rqstr, "REQUEST");
     209:         if (wrktype == SNDFILE ) {
     210:             strcpy(filename, W_FILE1);
     211:             i = expfile(filename);
     212:             DEBUG(4, "expfile type - %d, ", i);
     213:             if (i != 0 && chkpth(User, "", filename))
     214:                 goto e_access;
     215:             strcpy(Dfile, W_DFILE);
     216:             fp = NULL;
     217:             if (index(W_OPTNS, 'c') == NULL) {
     218:                 fp = fopen(subfile(Dfile), "r");
     219:                 if (fp != NULL)
     220:                     i = 0;
     221:             }
     222:             if (fp == NULL &&
     223:                (fp = fopen(subfile(filename), "r")) == NULL) {
     224:                 /*  can not read data file  */
     225:                 logent("CAN'T READ DATA", _FAILED);
     226:                 TransferSucceeded = 1; /* else will keep sending */
     227:                 USRF(USR_LOCACC);
     228:                 unlinkdf(Dfile);
     229:                 lnotify(User, filename, "can't access");
     230:                 goto top;
     231:             }
     232:             /* if file exists but is not generally readable... */
     233:             if (i != 0 && fstat(fileno(fp), &stbuf) == 0
     234:             &&  (stbuf.st_mode & ANYREAD) == 0) {
     235:         e_access:;
     236:                 /*  access denied  */
     237:                 fclose(fp);
     238:                 fp = NULL;
     239:                 TransferSucceeded = 1; /* else will keep sending */
     240:                 logent("DENIED", "ACCESS");
     241:                 USRF(USR_LOCACC);
     242:                 unlinkdf(W_DFILE);
     243:                 lnotify(User, filename, "access denied");
     244:                 goto top;
     245:             }
     246:
     247:             setupline(SNDFILE);
     248:         }
     249:
     250:         if (wrktype == RCVFILE) {
     251:             strcpy(filename, W_FILE2);
     252:             expfile(filename);
     253:             if (chkpth(User, "", filename)
     254:              || chkperm(filename, index(W_OPTNS, 'd'))) {
     255:                 /*  access denied  */
     256:                 logent("DENIED", "ACCESS");
     257:                 TransferSucceeded = 1; /* else will keep trying */
     258:                 USRF(USR_LOCACC);
     259:                 lnotify(User, filename, "access denied");
     260:                 goto top;
     261:             }
     262:             sprintf(Dfile, "%s/TM.%05d.%03d", Spool, pnum, tmpnum++);
     263:             if ((fp = fopen(subfile(Dfile), "w")) == NULL) {
     264:                 /*  can not create temp  */
     265:                 logent("CAN'T CREATE TM", _FAILED);
     266:                 USRF(USR_LNOTMP);
     267:                 unlinkdf(Dfile);
     268:                 goto top;
     269:             }
     270:             setupline(RCVFILE);
     271:         }
     272: sendmsg:
     273:         DEBUG(4, "wrktype - %c\n", wrktype);
     274:         WMESG(wrktype, msg);
     275:         RMESG(wrktype, msg, 1);
     276:         goto process;
     277:     }
     278:
     279:     /* role is slave */
     280:     RAMESG(msg, 1);
     281:     if (willturn < 0)
     282:         willturn = msg[0] == HUP;
     283:
     284: process:
     285:     DEBUG(4, "PROCESS: msg - %s\n", msg);
     286:     switch (msg[0]) {
     287:
     288:     case RQSTCMPT:
     289:         DEBUG(4, "RQSTCMPT:\n", CNULL);
     290:         if (msg[1] == 'N') {
     291:             i = atoi(&msg[2]);
     292:             if (i<0 || i>EM_MAX)
     293:                 i = 0;
     294:             USRF( 1 << i );
     295:             logent(Em_msg[i], "REQUEST FAILED");
     296:             TransferSucceeded = 1; /* He had his chance */
     297:         }
     298:         if (msg[1] == 'Y') {
     299:             USRF(USR_COK);
     300:             TransferSucceeded = 1;
     301:         }
     302:         if (role == MASTER) {
     303:             notify(mailopt, W_USER, W_FILE1, Rmtname, &msg[1]);
     304:         }
     305:         if (msg[2] == 'M') {
     306:             extern int Nfiles;
     307:             WMESG(HUP, "");
     308:             RMESG(HUP, msg, 1);
     309:             logent(Rmtname, "TURNAROUND");
     310: #ifdef USG
     311:                 time(&LastTurned.time);
     312:                 LastTurned.millitm = 0;
     313: #else !USG
     314:                 ftime(&LastTurned);
     315: #endif !USG
     316:             Nfiles = 0; /* force rescan of queue for work */
     317:             goto process;
     318:         }
     319:         goto top;
     320:
     321:     case HUP:
     322:         DEBUG(4, "HUP:\n", CNULL);
     323:         HaveSentHup = 1;
     324:         if (msg[1] == 'Y') {
     325:             if (role == MASTER)
     326:                 WMESG(HUP, YES);
     327:             (*Turnoff)();
     328:             Rdmsg = Imsg;
     329:             Wrmsg = Omsg;
     330:             return SUCCESS;
     331:         }
     332:
     333:         if (msg[1] == 'N') {
     334:             ASSERT(role == MASTER, "WRONG ROLE - HUP", CNULL, role);
     335:             role = SLAVE;
     336:             goto remaster;
     337:         }
     338:
     339:         /* get work */
     340:         if (!iswrk(Wfile, "chk", Spool, wkpre)) {
     341:             WMESG(HUP, YES);
     342:             RMESG(HUP, msg, 1);
     343:             goto process;
     344:         }
     345:
     346:         WMESG(HUP, NO);
     347:         role = MASTER;
     348:         goto remaster;
     349:
     350:     case XUUCP:
     351:         if (role == MASTER) {
     352:             goto top;
     353:         }
     354:
     355:         /*  slave part  */
     356:         i = getargs(msg, wrkvec, 20);
     357:         strcpy(filename, W_FILE1);
     358:         if (index(filename, ';') != NULL || index(W_FILE2, ';') != NULL
     359:             || i < 3) {
     360:             WMESG(XUUCP, NO);
     361:             goto top;
     362:         }
     363:         expfile(filename);
     364:         if (chkpth("", Rmtname, filename)) {
     365:             WMESG(XUUCP, NO);
     366:             logent("XUUCP DENIED", filename);
     367:                 USRF(USR_XUUCP);
     368:             goto top;
     369:         }
     370:         sprintf(rqstr, "%s %s", filename, W_FILE2);
     371:         xuucp(rqstr);
     372:         WMESG(XUUCP, YES);
     373:         goto top;
     374:
     375:     case SNDFILE:
     376:         /*  MASTER section of SNDFILE  */
     377:
     378:         DEBUG(4, "%s\n", "SNDFILE:");
     379:         if (msg[1] == 'N') {
     380:             i = atoi(&msg[2]);
     381:             if (i < 0 || i > EM_MAX)
     382:                 i = 0;
     383:             logent(Em_msg[i], "REQUEST FAILED");
     384:             USRF( 1 << i );
     385:             fclose(fp);
     386:             fp = NULL;
     387:             /* dont send him files he can't save */
     388:             if (strcmp(&msg[1], EM_NOTMP) == 0) {
     389:                 WMESG(HUP, "");
     390:                 RMESG(HUP, msg, 1);
     391:                 goto process;
     392:             }
     393:             notify(mailopt, W_USER, W_FILE1, Rmtname, &msg[1]);
     394:             ASSERT(role == MASTER, "WRONG ROLE - SN", CNULL, role);
     395:             if (msg[1] != '4')
     396:                 unlinkdf(W_DFILE);
     397:             goto top;
     398:         }
     399:
     400:         if (msg[1] == 'Y') {
     401:             /* send file */
     402:             ASSERT(role == MASTER, "WRONG ROLE - SY", CNULL, role);
     403:             ret = fstat(fileno(fp), &stbuf);
     404:             ASSERT(ret != -1, "STAT FAILED", filename, 0);
     405:             i = 1 + (int)(stbuf.st_size / XFRRATE);
     406:             if (send_or_receive != SNDFILE) {
     407:                 send_or_receive = SNDFILE;
     408:                 systat(Rmtname, SS_INPROGRESS, "SENDING");
     409:             }
     410:             ret = (*Wrdata)(fp, Ofn);
     411:             fclose(fp);
     412:             fp = NULL;
     413:             if (ret != SUCCESS) {
     414:                 (*Turnoff)();
     415:                 USRF(USR_CFAIL);
     416:                 return FAIL;
     417:             }
     418:             RMESG(RQSTCMPT, msg, i);
     419:             unlinkdf(W_DFILE);
     420:             goto process;
     421:         }
     422:
     423:         /*  SLAVE section of SNDFILE  */
     424:         ASSERT(role == SLAVE, "WRONG ROLE - SLAVE", CNULL, role);
     425:
     426:         /* request to receive file */
     427:         /* check permissions */
     428:         i = getargs(msg, wrkvec, 20);
     429:         if (i < 5) {
     430:             char *bnp;
     431:             bnp = rindex(Wfile, '/');
     432:             sprintf(rqstr, "%s/%s", CORRUPT, bnp ? bnp + 1 : Wfile);
     433:             xmv(Wfile, rqstr);
     434:             logent(Wfile, "CMD FILE CORRUPTED");
     435:             Wfile[0] = '\0';
     436:             goto top;
     437:         }
     438:         sprintf(rqstr, "%s %s %s %s", W_TYPE, W_FILE1, W_FILE2, W_USER);
     439:         logent(rqstr, "REQUESTED");
     440:         DEBUG(4, "msg - %s\n", msg);
     441:         strcpy(filename, W_FILE2);
     442:         /* Run uuxqt occasionally */
     443:         if (filename[0] == XQTPRE) {
     444:             if (++nXfiles > 10) {
     445:                 nXfiles = 0;
     446:                 /*
     447: 				 * want to create an orphan uuxqt,
     448: 				 * so a double-fork is needed.
     449: 				 */
     450:                 if (fork() == 0) {
     451:                     xuuxqt();
     452:                     _exit(0);
     453:                 }
     454:                 wait((int *)0);
     455:             }
     456:         }
     457:         /* expand filename, i is set to 0 if this is
     458: 		 * is a vanilla spool file, so no stat(II)s are needed */
     459:         i = expfile(filename);
     460:         DEBUG(4, "expfile type - %d\n", i);
     461:         if (i != 0) {
     462:             if (chkpth("", Rmtname, filename)
     463:              || chkperm(filename, index(W_OPTNS, 'd'))) {
     464:                 WMESG(SNDFILE, EM_RMTACC);
     465:                 logent("DENIED", "PERMISSION");
     466:                 goto top;
     467:             }
     468:             if (isdir(filename)) {
     469:                 strcat(filename, "/");
     470:                 strcat(filename, lastpart(W_FILE1));
     471:             }
     472:         }
     473:         sprintf(User, "%.9s", W_USER);
     474:
     475:         DEBUG(4, "chkpth ok Rmtname - %s\n", Rmtname);
     476:         /* speed things up by OKing file before
     477: 		 * creating TM file.  If the TM file cannot be created,
     478: 		 * then the conversation bombs, but that seems reasonable,
     479: 		 * as there are probably serious problems then.
     480: 		 */
     481:         WMESG(SNDFILE, YES);
     482:         sprintf(Dfile, "%s/TM.%05d.%03d", Spool, pnum, tmpnum++);
     483:         if((fp = fopen(subfile(Dfile), "w")) == NULL) {
     484: /*			WMESG(SNDFILE, EM_NOTMP);*/
     485:             logent("CAN'T OPEN", "TM FILE");
     486:             unlinkdf(Dfile);
     487:             (*Turnoff)();
     488:             return FAIL;
     489:         }
     490:
     491:         if (send_or_receive != RCVFILE) {
     492:             send_or_receive = RCVFILE;
     493:             systat(Rmtname, SS_INPROGRESS, "RECEIVING");
     494:         }
     495:         ret = (*Rddata)(Ifn, fp);
     496:         fflush(fp);
     497:         if (ferror(fp) || fclose(fp))
     498:             ret = FAIL;
     499:
     500:         if (ret != SUCCESS) {
     501:             (void) unlinkdf(Dfile);
     502:             (*Turnoff)();
     503:             return FAIL;
     504:         }
     505:         /* copy to user directory */
     506:         ntfyopt = index(W_OPTNS, 'n') != NULL;
     507:         status = xmv(Dfile, filename);
     508:
     509:         if (willturn && Now.time > (LastTurned.time+turntime)
     510:             && iswrk(Wfile, "chk", Spool, wkpre)) {
     511:                 WMESG(RQSTCMPT, status ? EM_RMTCP : "YM");
     512:                 willturn = -1;
     513:         } else
     514:             WMESG(RQSTCMPT, status ? EM_RMTCP : YES);
     515:         if (i == 0)
     516:             ;   /* vanilla file, nothing to do */
     517:         else if (status == 0) {
     518:             if (W_MODE == 0 || sscanf(W_MODE, "%o", &filemode) != 1)
     519:                 filemode = BASEMODE;
     520:             chmod(subfile(filename), (filemode|BASEMODE)&0777);
     521:             arrived(ntfyopt, filename, W_NUSER, Rmtname, User);
     522:         } else {
     523:             logent(_FAILED, "COPY");
     524:             status = putinpub(filename, Dfile, W_USER);
     525:             DEBUG(4, "->PUBDIR %d\n", status);
     526:             if (status == 0)
     527:                 arrived(ntfyopt, filename, W_NUSER, Rmtname, User);
     528:         }
     529:
     530:         goto top;
     531:
     532:     case RCVFILE:
     533:         /*  MASTER section of RCVFILE  */
     534:
     535:         DEBUG(4, "%s\n", "RCVFILE:");
     536:         if (msg[1] == 'N') {
     537:             i = atoi(&msg[2]);
     538:             if (i < 0 || i > EM_MAX)
     539:                 i = 0;
     540:             logent(Em_msg[i], "REQUEST FAILED");
     541:             USRF( 1 << i );
     542:             fclose(fp);
     543:             fp = NULL;
     544:             notify(mailopt, W_USER, W_FILE1, Rmtname, &msg[1]);
     545:             ASSERT(role == MASTER, "WRONG ROLE - RN", CNULL, role);
     546:             unlinkdf(Dfile);
     547:             goto top;
     548:         }
     549:
     550:         if (msg[1] == 'Y') {
     551:             /* receive file */
     552:             ASSERT(role == MASTER, "WRONG ROLE - RY", CNULL, role);
     553:             if (send_or_receive != RCVFILE) {
     554:                 send_or_receive = RCVFILE;
     555:                 systat(Rmtname, SS_INPROGRESS, "RECEIVING");
     556:             }
     557:             ret = (*Rddata)(Ifn, fp);
     558:             fflush(fp);
     559:             if (ferror(fp) || fclose(fp))
     560:                 ret = FAIL;
     561:             if (ret != SUCCESS) {
     562:                 unlinkdf(Dfile);
     563:                 (*Turnoff)();
     564:                 USRF(USR_CFAIL);
     565:                 return FAIL;
     566:             }
     567:             /* copy to user directory */
     568:             if (isdir(filename)) {
     569:                 strcat(filename, "/");
     570:                 strcat(filename, lastpart(W_FILE1));
     571:             }
     572:             status = xmv(Dfile, filename);
     573:             if (willturn && Now.time > (LastTurned.time+turntime)
     574:                 && iswrk(Wfile, "chk", Spool, wkpre)) {
     575:                     WMESG(RQSTCMPT, status ? EM_RMTCP : "YM");
     576:                     willturn = -1;
     577:             } else
     578:                 WMESG(RQSTCMPT, status ? EM_RMTCP : YES);
     579:             notify(mailopt, W_USER, filename, Rmtname,
     580:                 status ? EM_LOCCP : YES);
     581:             if (status == 0) {
     582:                 sscanf(&msg[2], "%o", &filemode);
     583:                 if (filemode <= 0)
     584:                     filemode = BASEMODE;
     585:                 chmod(subfile(filename), (filemode|BASEMODE)&0777);
     586:                 USRF(USR_COK);
     587:             } else {
     588:                 logent(_FAILED, "COPY");
     589:                 putinpub(filename, Dfile, W_USER);
     590:                 USRF(USR_LOCCP);
     591:             }
     592:             goto top;
     593:         }
     594:
     595:         /*  SLAVE section of RCVFILE  */
     596:         ASSERT(role == SLAVE, "WRONG ROLE - SLAVE RCV", CNULL, role);
     597:
     598:         /* request to send file */
     599:         strcpy(rqstr, msg);
     600:         logent(rqstr, "REQUESTED");
     601:
     602:         /* check permissions */
     603:         i = getargs(msg, wrkvec, 20);
     604:         if (i < 4) {
     605:             char *bnp;
     606:             bnp = rindex(Wfile, '/');
     607:             sprintf(rqstr, "%s/%s", CORRUPT, bnp ? bnp + 1 : Wfile);
     608:             xmv(Wfile, rqstr);
     609:             logent(Wfile, "CMD FILE CORRUPTED");
     610:             Wfile[0] = '\0';
     611:             goto top;
     612:         }
     613:         DEBUG(4, "msg - %s\n", msg);
     614:         DEBUG(4, "W_FILE1 - %s\n", W_FILE1);
     615:         strcpy(filename, W_FILE1);
     616:         expfile(filename);
     617:         if (isdir(filename)) {
     618:             strcat(filename, "/");
     619:             strcat(filename, lastpart(W_FILE2));
     620:         }
     621:         sprintf(User, "%.9s", W_USER);
     622:         if (chkpth("", Rmtname, filename) || anyread(filename)) {
     623:             WMESG(RCVFILE, EM_RMTACC);
     624:             logent("DENIED", "PERMISSION");
     625:             goto top;
     626:         }
     627:         DEBUG(4, "chkpth ok Rmtname - %s\n", Rmtname);
     628:
     629:         if ((fp = fopen(subfile(filename), "r")) == NULL) {
     630:             WMESG(RCVFILE, EM_RMTACC);
     631:             logent("CAN'T OPEN", "DENIED");
     632:             goto top;
     633:         }
     634:
     635:         /*  ok to send file */
     636:         ret = fstat(fileno(fp), &stbuf);
     637:         ASSERT(ret != -1, "STAT FAILED", filename, 0);
     638:         i = 1 + (int)(stbuf.st_size / XFRRATE);
     639:         sprintf(msg, "%s %o", YES, (int)stbuf.st_mode & 0777);
     640:         WMESG(RCVFILE, msg);
     641:         if (send_or_receive != SNDFILE) {
     642:             send_or_receive = SNDFILE;
     643:             systat(Rmtname, SS_INPROGRESS, "SENDING");
     644:         }
     645:         ret = (*Wrdata)(fp, Ofn);
     646:         fclose(fp);
     647:         if (ret != SUCCESS) {
     648:             (*Turnoff)();
     649:             return FAIL;
     650:         }
     651:         RMESG(RQSTCMPT, msg, i);
     652:         goto process;
     653:     }
     654:     (*Turnoff)();
     655:     return FAIL;
     656: }
     657:
     658:
     659: /*
     660:  *	read message 'c'. try 'n' times
     661:  *
     662:  *	return code:  SUCCESS  |  FAIL
     663:  */
     664: rmesg(c, msg, n)
     665: register char *msg, c;
     666: register int n;
     667: {
     668:     char str[MAXFULLNAME];
     669:
     670:     DEBUG(4, "rmesg - '%c' ", c);
     671:     while ((*Rdmsg)(msg, Ifn) != SUCCESS) {
     672:         if (--n > 0) {
     673:             sprintf(str, "%d", n);
     674:             logent(str, "PATIENCE");
     675:             continue;
     676:         }
     677:         DEBUG(4, "got FAIL\n", CNULL);
     678:         if (c != '\0')
     679:             sprintf(str, "expected '%c' got FAIL (%d)", c, errno);
     680:         else
     681:             sprintf(str, "expected ANY got FAIL (%d)", errno);
     682:         logent(str, "BAD READ");
     683:         return FAIL;
     684:     }
     685:     if (c != '\0' && msg[0] != c) {
     686:         DEBUG(4, "got %s\n", msg);
     687:         sprintf(str, "expected '%c' got %s", c, msg);
     688:         logent(str, "BAD READ");
     689:         return FAIL;
     690:     }
     691:     DEBUG(4, "got %s\n", msg);
     692:     return SUCCESS;
     693: }
     694:
     695:
     696: /*
     697:  *	write a message (type m)
     698:  *
     699:  *	return codes: SUCCESS - ok | FAIL - ng
     700:  */
     701: wmesg(m, s)
     702: register char *s, m;
     703: {
     704:     DEBUG(4, "wmesg '%c' ", m);
     705:     DEBUG(4, "%s\n", s);
     706:     return (*Wrmsg)(m, s, Ofn);
     707: }
     708:
     709: /*
     710:  *	mail results of command
     711:  *
     712:  *	return codes:  none
     713:  */
     714: notify(mailopt, user, file, sys, msgcode)
     715: char *user, *file, *sys, *msgcode;
     716: {
     717:     char str[BUFSIZ];
     718:     int i;
     719:     char *msg;
     720:
     721:     if (!mailopt && *msgcode == 'Y')
     722:         return;
     723:     if (*msgcode == 'Y')
     724:         msg = "copy succeeded";
     725:     else {
     726:         i = atoi(msgcode + 1);
     727:         if (i < 1 || i > EM_MAX)
     728:             i = 0;
     729:         msg = Em_msg[i];
     730:     }
     731:     sprintf(str, "file %s!%s -- %s\n",
     732:         sys,file, msg);
     733:     mailst(user, str, CNULL);
     734:     return;
     735: }
     736:
     737: /*
     738:  *	local notify
     739:  *
     740:  *	return code - none
     741:  */
     742: lnotify(user, file, mesg)
     743: char *user, *file, *mesg;
     744: {
     745:     char mbuf[200];
     746:     sprintf(mbuf, "file %s!%s -- %s\n", Myname, file, mesg);
     747:     mailst(user, mbuf, CNULL);
     748:     return;
     749: }
     750:
     751: /*
     752:  *	converse with the remote machine, agree upon a protocol (if possible)
     753:  *	and start the protocol.
     754:  *
     755:  *	return codes:
     756:  *		SUCCESS - successful protocol selection
     757:  *		FAIL - can't find common or open failed
     758:  */
     759: startup(role)
     760: int role;
     761: {
     762:     extern (*Rdmsg)(), (*Wrmsg)();
     763:     extern char *blptcl(), fptcl();
     764:     char msg[BUFSIZ], str[MAXFULLNAME];
     765:
     766:     Rdmsg = Imsg;
     767:     Wrmsg = Omsg;
     768:     if (role == MASTER) {
     769:         RMESG(SLTPTCL, msg, 1);
     770:         if ((str[0] = fptcl(&msg[1])) == NULL) {
     771:             /* no protocol match */
     772:             WMESG(USEPTCL, NO);
     773:             return FAIL;
     774:         }
     775:         str[1] = '\0';
     776:         WMESG(USEPTCL, str);
     777:         if (stptcl(str) != 0)
     778:             return FAIL;
     779:         DEBUG(4, "protocol %s\n", str);
     780:         return SUCCESS;
     781:     }
     782:     else {
     783:         WMESG(SLTPTCL, blptcl(str));
     784:         RMESG(USEPTCL, msg, 1);
     785:         if (msg[1] == 'N') {
     786:             return FAIL;
     787:         }
     788:
     789:         if (stptcl(&msg[1]) != 0)
     790:             return FAIL;
     791:         DEBUG(4, "Protocol %s\n", msg);
     792:         return SUCCESS;
     793:     }
     794: }
     795:
     796: /*
     797:  *	choose a protocol from the input string (str) and return the it
     798:  *
     799:  *	return codes:
     800:  *		'\0'  -  no acceptable protocol
     801:  *		any character  -  the chosen protocol
     802:  */
     803: char
     804: fptcl(str)
     805: register char *str;
     806: {
     807:     register struct Proto *p;
     808:     extern char LineType[];
     809:
     810:     for (p = Ptbl; p->P_id != '\0'; p++) {
     811: #ifdef TCPIP
     812:         /* Only use 't' on TCP/IP */
     813:         if (p->P_id == 't' && strcmp("TCP", LineType))
     814:             continue;
     815: #endif TCPIP
     816: #ifdef PAD
     817:         /* only use 'f' protocol on PAD */
     818:         if (p->P_id == 'f' && strcmp("PAD", LineType))
     819:             continue;
     820: #endif PAD
     821:         if (index(str, p->P_id) != NULL) {
     822:             return p->P_id;
     823:         }
     824:     }
     825:
     826:     return '\0';
     827: }
     828:
     829: /*
     830:  *	build a string of the letters of the available protocols
     831:  */
     832: char *
     833: blptcl(str)
     834: register char *str;
     835: {
     836:     register struct Proto *p;
     837:     register char *s;
     838:
     839:     for (p = Ptbl, s = str; (*s++ = p->P_id) != '\0'; p++)
     840:         ;
     841:     *s = '\0';
     842:     return str;
     843: }
     844:
     845: /*
     846:  *	this routine will set up the six routines
     847:  *	(Rdmsg, Wrmsg, Rddata, Wrdata, Turnon, Turnoff) for the
     848:  *	desired protocol.
     849:  *
     850:  *	return codes:
     851:  *		SUCCESS - ok
     852:  *		FAIL - no find or failed to open
     853:  *
     854:  */
     855: stptcl(c)
     856: register char *c;
     857: {
     858:     register struct Proto *p;
     859:
     860:     for (p = Ptbl; p->P_id != '\0'; p++) {
     861:         if (*c == p->P_id) {
     862:             /* found protocol - set routines */
     863:             Rdmsg = p->P_rdmsg;
     864:             Wrmsg = p->P_wrmsg;
     865:             Rddata = p->P_rddata;
     866:             Wrdata = p->P_wrdata;
     867:             Turnon = p->P_turnon;
     868:             Turnoff = p->P_turnoff;
     869:             if ((*Turnon)() != SUCCESS)
     870:                 return FAIL;
     871:             DEBUG(4, "Proto started %c\n", *c);
     872:             return SUCCESS;
     873:         }
     874:     }
     875:     DEBUG(4, "Proto start-fail %c\n", *c);
     876:     return FAIL;
     877: }
     878:
     879: /*
     880:  *	put file in public place. if successful, filename is modified
     881:  *
     882:  *	return code  SUCCESS | FAIL
     883:  */
     884:
     885: putinpub(file, tmp, user)
     886: register char *file, *tmp, *user;
     887: {
     888:     char fullname[MAXFULLNAME];
     889:     char *lastpart();
     890:     int status;
     891:
     892:     sprintf(fullname, "%s/%s/", PUBDIR, user);
     893:     if (mkdirs(fullname) != 0) {
     894:         /* can not make directories */
     895:         DEBUG(1, "Cannot mkdirs(%s)\n", fullname);
     896:         return FAIL;
     897:     }
     898:     strcat(fullname, lastpart(file));
     899:     status = xmv(tmp, fullname);
     900:     if (status == 0) {
     901:         strcpy(file, fullname);
     902:         chmod(subfile(fullname), BASEMODE);
     903:     }
     904:     return status;
     905: }
     906:
     907: /*
     908:  *	unlink D. file
     909:  *
     910:  *	return code - none
     911:  */
     912:
     913: unlinkdf(file)
     914: register char *file;
     915: {
     916:     if (strlen(file) > 6)
     917:         unlink(subfile(file));
     918:     return;
     919: }
     920:
     921: /*
     922:  *	notify receiver of arrived file
     923:  *
     924:  *	return code - none
     925:  */
     926: arrived(opt, file, nuser, rmtsys, rmtuser)
     927: char *file, *nuser, *rmtsys, *rmtuser;
     928: {
     929:     char mbuf[200];
     930:
     931:     if (!opt)
     932:         return;
     933:     sprintf(mbuf, "%s from %s!%s arrived\n", file, rmtsys, rmtuser);
     934:     mailst(nuser, mbuf, CNULL);
     935:     return;
     936: }
     937:
     938: nullf()
     939: {
     940:     return SUCCESS;
     941: }

#### Defined functions

arrived defined in line 926; used 2 times

- in line 521, 527

blptcl defined in line 832; used 2 times

- in line 763, 783

cntrl defined in line 125; used 1 times

- in /usr/src/usr.bin/uucp/cico.c line 622

fptcl defined in line 803; used 2 times

- in line 763, 770

lnotify defined in line 742; used 3 times

- in line 229, 243, 259

notify defined in line 714; used 4 times

- in line 303, 393, 544, 579

nullf defined in line 938; used 5 times

- in line 27, 40(2), 53(2)

putinpub defined in line 885; used 2 times

- in line 524, 589

rmesg defined in line 664; used 2 times

- in line 101-102(2)

startup defined in line 759; used 1 times

- in /usr/src/usr.bin/uucp/cico.c line 602

stptcl defined in line 855; used 2 times

- in line 777, 789

unlinkdf defined in line 913; used 9 times

- in line 228, 242, 267, 396, 419, 486, 501, 546, 562

wmesg defined in line 701; used 1 times

- in line 103

#### Defined variables

Dfile defined in line 106; used 16 times

- in line 215-218(2), 228, 262-267(3), 482-486(3), 501, 507, 524, 546, 562, 572, 589

Em_msg defined in line 71; used 4 times

- in line 295, 383, 540, 729

HaveSentHup defined in line 12; used 2 times

- in line 153, 323

LastCheckedNoLogin defined in line 55; used 2 times

- in line 159-160(2)

LastTurned defined in line 55; used 8 times

- in line 147-150(3), 311-314(3), 509, 573

NO defined in line 58; used 4 times

- in line 346, 360-365(2), 772

Now defined in line 55; used 4 times

- in line 159-160(2), 509, 573

Ptbl defined in line 38; used 3 times

- in line 810, 839, 860

TransferSucceeded defined in line 60; used 7 times

- in line 226, 239, 257, 296-300(2)
- in /usr/src/usr.bin/uucp/anlwrk.c line 72, 82

Wfile defined in line 105; used 20 times

- in line 143, 174, 198-202(5), 340, 431-435(5), 510, 574, 606-610(5)

YES defined in line 57; used 9 times

- in line 166, 326, 341, 372, 481, 514, 578-580(2), 639

nXfiles defined in line 111; used 2 times

- in line 444-445(2)

sccsid defined in line 2; never used
send_or_receive defined in line 112; used 9 times

- in line 152, 406-407(2), 491-492(2), 553-554(2), 641-642(2)

stbuf defined in line 113; used 7 times

- in line 233-234(2), 403-405(2), 636-639(3)

willturn defined in line 11; used 7 times

- in line 144, 281-282(2), 509-512(2), 573-576(2)

#### Defined struct's

Proto defined in line 14; used 8 times

- in line 38(2), 807(2), 836(2), 858(2)

#### Defined macros

EM_BADUUCP defined in line 66; never used
EM_LOCACC defined in line 64; never used
EM_LOCCP defined in line 69; used 1 times

- in line 580

EM_MAX defined in line 63; used 4 times

- in line 292, 381, 538, 727

EM_NOTMP defined in line 67; used 1 times

- in line 388

EM_RMTACC defined in line 65; used 3 times

- in line 464, 623, 630

EM_RMTCP defined in line 68; used 4 times

- in line 511-514(2), 575-578(2)

HUP defined in line 88; used 13 times

- in line 166-167(2), 176-177(2), 282, 307-308(2), 326, 341-346(3), 389-390(2)

RAMESG defined in line 102; used 1 times

- in line 280

RCVFILE defined in line 85; used 9 times

- in line 250, 270, 491-492(2), 553-554(2), 623, 630, 640

RESET defined in line 89; used 2 times

- in line 152, 158

RMESG defined in line 101; used 10 times

- in line 167, 177, 275, 308, 342, 390, 418, 651, 769, 784

RQSTCMPT defined in line 87; used 6 times

- in line 418, 511-514(2), 575-578(2), 651

SLTPTCL defined in line 83; used 2 times

- in line 769, 783

SNDFILE defined in line 86; used 8 times

- in line 209, 247, 406-407(2), 464, 481, 641-642(2)

USEPTCL defined in line 84; used 3 times

- in line 772-776(2), 784

WMESG defined in line 103; used 23 times

- in line 166, 176, 274, 307, 326, 341-346(2), 360-365(2), 372, 389, 464, 481, 511-514(2), 575-578(2), 623, 630, 640, 772-776(2), 783

W_DFILE defined in line 96; used 4 times

- in line 215, 242, 396, 419

W_FILE1 defined in line 92; used 11 times

- in line 206-210(2), 303, 357, 393, 438, 470, 544, 570, 614-615(2)

W_FILE2 defined in line 93; used 7 times

- in line 207, 251, 358, 370, 438-441(2), 619

W_MODE defined in line 97; used 2 times

- in line 518(2)

W_NUSER defined in line 98; used 2 times

- in line 521, 527

W_OPTNS defined in line 95; used 6 times

- in line 193-194(2), 217, 254, 463, 506

W_TYPE defined in line 91; used 3 times

- in line 180, 206, 438

W_USER defined in line 94; used 11 times

- in line 205-207(2), 303, 393, 438, 473, 524, 544, 579, 589, 621

XFRRATE defined in line 100; used 2 times

- in line 405, 638

XUUCP defined in line 82; used 4 times

- in line 188, 360-365(2), 372

Last modified: 1987-02-17 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 2582 |