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
blptcl defined in line 832; used 2 times
cntrl defined in line 125; used 1 times
fptcl defined in line 803; used 2 times
lnotify defined in line 742; used 3 times
notify defined in line 714; used 4 times
nullf defined in line 938; used 5 times
putinpub defined in line 885; used 2 times
rmesg defined in line 664; used 2 times
startup defined in line 759; used 1 times
stptcl defined in line 855; used 2 times
unlinkdf defined in line 913; used 9 times
wmesg defined in line 701; used 1 times

Defined variables

Dfile defined in line 106; used 16 times
Em_msg defined in line 71; used 4 times
HaveSentHup defined in line 12; used 2 times
LastCheckedNoLogin defined in line 55; used 2 times
LastTurned defined in line 55; used 8 times
NO defined in line 58; used 4 times
Now defined in line 55; used 4 times
Ptbl defined in line 38; used 3 times
TransferSucceeded defined in line 60; used 7 times
Wfile defined in line 105; used 20 times
YES defined in line 57; used 9 times
nXfiles defined in line 111; used 2 times
sccsid defined in line 2; never used
send_or_receive defined in line 112; used 9 times
stbuf defined in line 113; used 7 times
willturn defined in line 11; used 7 times

Defined struct's

Proto defined in line 14; used 8 times

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
EM_MAX defined in line 63; used 4 times
EM_NOTMP defined in line 67; used 1 times
EM_RMTACC defined in line 65; used 3 times
EM_RMTCP defined in line 68; used 4 times
HUP defined in line 88; used 13 times
RAMESG defined in line 102; used 1 times
RCVFILE defined in line 85; used 9 times
RESET defined in line 89; used 2 times
RMESG defined in line 101; used 10 times
RQSTCMPT defined in line 87; used 6 times
SLTPTCL defined in line 83; used 2 times
SNDFILE defined in line 86; used 8 times
USEPTCL defined in line 84; used 3 times
WMESG defined in line 103; used 23 times
W_DFILE defined in line 96; used 4 times
W_FILE1 defined in line 92; used 11 times
W_FILE2 defined in line 93; used 7 times
W_MODE defined in line 97; used 2 times
  • in line 518(2)
W_NUSER defined in line 98; used 2 times
W_OPTNS defined in line 95; used 6 times
W_TYPE defined in line 91; used 3 times
W_USER defined in line 94; used 11 times
XFRRATE defined in line 100; used 2 times
XUUCP defined in line 82; used 4 times
Last modified: 1986-02-01
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3369
Valid CSS Valid XHTML 1.0 Strict