|
|
1.1 ! root 1: /* ! 2: * dcp.c ! 3: * ! 4: * revised edition of dcp -- "dcp" a uucp clone ! 5: * ! 6: * copyright (c) richard h. lamb 1985, 1986, 1987 ! 7: * changes copyright (c) stuart lynne may/1987 ! 8: * changes copyright (c) peter housel nov/1988 ! 9: * changes (massive) copyright (c) 1989-1991 by Mark Williams Company ! 10: * ! 11: * this program implements a uucico type file transfer and remote execution ! 12: * type protocol. ! 13: * ! 14: * Usage: uucico [-xn] [-r0] slave mode ! 15: * uucico [-xn] [-r1] -{sS}host call host ! 16: * uucico [-xn] [-r1] -{sS}all call all known hosts ! 17: * uucico [-xn] [-r1] -{c}all call all known hosts with queued files ! 18: * uucico [-xn] -r1 call uutouch queued hosts ! 19: */ ! 20: ! 21: #include <sys/types.h> ! 22: #include <time.h> ! 23: #include <signal.h> ! 24: #include "dcp.h" ! 25: #include "perm.h" ! 26: #include "alarm.h" ! 27: ! 28: int pktsize; /* packet size for pro */ ! 29: char xfromfile[BUFSIZ]; /* source of copy */ ! 30: char xtofile[BUFSIZ]; /* destination of copy */ ! 31: char *clinep[10]; /* pointer to fields from line from C. file */ ! 32: char cline [BUFSIZ]; /* line from C. file */ ! 33: ! 34: char *fromfilep, *tofilep, *usernamep, *optionp, *spoolfilep, *modep, *notifyp; ! 35: ! 36: int nclinep; /* number tokens in cline */ ! 37: long bytecount; /* transfer byte count */ ! 38: ! 39: int size; /* nbytes in buff */ ! 40: char proto[5]; /* list of protocols */ ! 41: int bad_count; ! 42: int total_errors; ! 43: unsigned int checksum(); ! 44: ! 45: /* ! 46: * Global Variables ! 47: */ ! 48: ! 49: int checkfirst = 0; /* check spooldir before calling */ ! 50: int abort_cico = 0; /* Indicates Process Abort Signalled */ ! 51: int sysended = 0; /* Indicates sysend() was called */ ! 52: int processid; /* Current Process Id (uucico) */ ! 53: int fpfd = -1; /* File Decriptor used for send&receive */ ! 54: int role = SLAVE; /* Our role, either MASTER or SLAVE */ ! 55: char *sysname = NULL; /* Command line -[sS]sysname argument */ ! 56: char *rmtname = NULL; /* Remote System being processed now */ ! 57: char *logname = NULL; /* In SLAVE mode, the login name */ ! 58: int forcecall = 0; /* Ignore L.sys spec for time to call */ ! 59: int terminatelevel = 0; /* Indicates return code for one call */ ! 60: char cfile[CTLFLEN]; /* Current C.* Control Work File Name */ ! 61: FILE *cfp = NULL; /* FILE Pointer for C.* files */ ! 62: char *nodename; /* UUCP node name (or MYNAME, perhaps) */ ! 63: char *version; /* Version Character String */ ! 64: int stripflg = 0; /* Flag to strip chars to 7bits on read */ ! 65: ! 66: /* ! 67: * Extern Function Declarations ! 68: */ ! 69: ! 70: extern int catchhup(), catchquit(), catchterm(), catchsegv(); ! 71: extern char *getenv(); ! 72: ! 73: /* ! 74: * Local Variables ! 75: */ ! 76: ! 77: static char state; /* system state */ ! 78: ! 79: main(argc, argv) ! 80: int argc; ! 81: char *argv[]; ! 82: { ! 83: time_t now; ! 84: static char buf[16]; ! 85: ! 86: sprintf(buf, "%.14s%s", VERSION, ! 87: #if SGTTY ! 88: "S"); ! 89: #elif TERMIO ! 90: "T"); ! 91: #elif BBS ! 92: "SB"); ! 93: #endif ! 94: version = &buf[0]; ! 95: ! 96: while(--argc) { ! 97: if (**++argv != '-') ! 98: usage(); ! 99: switch(argv[0][1]) { ! 100: case 'x': ! 101: debuglevel = atoi(&argv[0][2]); break; ! 102: case 'c': ! 103: checkfirst = 1; ! 104: role = MASTER; ! 105: sysname = &argv[0][2]; ! 106: break; ! 107: case 'S': ! 108: forcecall = 1; ! 109: case 's': ! 110: role = MASTER; ! 111: sysname = &argv[0][2]; break; ! 112: case 'r': ! 113: role = atoi(&argv[0][2]); break; ! 114: case 'v': ! 115: case 'V': ! 116: fatal("uucico: Version %s", version); ! 117: default: ! 118: usage(); break; ! 119: } ! 120: } ! 121: if ( ((role!=MASTER) && ((role!=SLAVE) || (sysname!=NULL))) || ! 122: ((role==MASTER) && (sysname==NULL)) ) ! 123: usage(); ! 124: ! 125: open_debug("uucico", role==SLAVE); ! 126: if ( debuglevel && !lsys_access() ) { ! 127: printmsg(M_LOG, "unauthorized debuglevel; reset to zero."); ! 128: debuglevel = 0; ! 129: } ! 130: processid = getpid(); ! 131: timedout = 0; ! 132: INITALRM(); ! 133: signal(SIGINT, SIG_IGN); ! 134: signal(SIGHUP, catchhup); ! 135: signal(SIGQUIT, catchquit); ! 136: signal(SIGTERM, catchterm); ! 137: signal(SIGSEGV, catchsegv); ! 138: ! 139: if (role == MASTER) { ! 140: time(&now); ! 141: printmsg(M_CALL, ! 142: "System Name \"%s\", debug=%d (%.24s) (V%s)", ! 143: sysname, debuglevel, ctime(&now), version); ! 144: lsys_open(); ! 145: state = 'I'; ! 146: while(!abort_cico) { ! 147: printmsg(M_DEBUG, "Mstate = %c", state); ! 148: switch(state) { ! 149: case 'I': ! 150: terminatelevel = 0; ! 151: if ( (state=getsystem()) != 'S' ) ! 152: rmtname = NULL; ! 153: break; ! 154: case 'S': ! 155: ! 156: /* If our check first flag is NOT set, then we call regardless ! 157: * of if there files pending for transfer from this site. ! 158: * If our check flag is set, then we only call when a file is ! 159: * pending for transfer. ! 160: */ ! 161: if(checkfirst == 0){ ! 162: state = callup(); ! 163: break; ! 164: } ! 165: if((checkfirst != 0) && (scandir() == 'S')){ ! 166: state = callup(); ! 167: } ! 168: else{ ! 169: state = 'Y'; ! 170: plog(M_CALL,"Attempting to call, checking for queued files."); ! 171: plog(M_CALL,"No Files pending"); ! 172: } ! 173: break; ! 174: ! 175: case 'P': ! 176: perm_get(rmtname, NULL); ! 177: nodename = myname(); ! 178: fixline(); ! 179: state = startup(); ! 180: break; ! 181: case 'D': ! 182: if ( (state=master()) != 'A' ) ! 183: break; ! 184: case 'A': ! 185: terminatelevel++; ! 186: case 'Y': ! 187: state = sysend(); break; ! 188: } ! 189: if (state == 'A') ! 190: break; ! 191: } ! 192: lsys_close(); ! 193: } else { ! 194: state = '0'; ! 195: while(!abort_cico) { ! 196: printmsg(M_DEBUG, "Sstate = %c", state); ! 197: switch(state) { ! 198: case '0': ! 199: state = initline() ? 'I': 'Y'; ! 200: break; ! 201: case 'I': ! 202: if ( (logname=getenv("USER")) == NULL ) ! 203: fatal("Can't getenv USER"); ! 204: time(&now); ! 205: printmsg(M_CALL, ! 206: "Logname \"%s\", debug=%d (%.24s) (V%s)", ! 207: logname, debuglevel, ctime(&now), version); ! 208: perm_get(NULL, logname); ! 209: nodename = myname(); ! 210: state = startup(); ! 211: break; ! 212: case 'R': ! 213: if ( (state=slave()) != 'A' ) ! 214: break; ! 215: case 'A': ! 216: terminatelevel++; ! 217: case 'Y': ! 218: state = sysend(); ! 219: break; ! 220: } ! 221: if (state == 'A') ! 222: break; ! 223: } ! 224: } ! 225: if ( !sysended ) ! 226: sysend(); ! 227: exec_xqt(); ! 228: exit(0); ! 229: } ! 230: ! 231: /* ! 232: * master ! 233: */ ! 234: master() ! 235: { ! 236: state = 'I'; ! 237: while(!abort_cico) { ! 238: printmsg(M_CONVERSE, "Top level state (master mode) %c", state); ! 239: switch(state) { ! 240: case 'I': state = sinit(); break; ! 241: case 'B': state = scandir(); break; ! 242: case 'S': state = sendf(); break; ! 243: case 'Q': state = sbreak(); break; ! 244: case 'G': state = recvf(); break; ! 245: case 'C': state = 'Y'; break; ! 246: case 'Y': state = endp(); break; ! 247: case 'P': return ('Y'); ! 248: case 'A': return ('A'); ! 249: default: return ('A'); ! 250: } ! 251: } ! 252: return('A'); ! 253: } ! 254: ! 255: /* ! 256: * slave ! 257: */ ! 258: slave() ! 259: { ! 260: state = 'I'; ! 261: while(!abort_cico) { ! 262: printmsg(M_CONVERSE, "Top level state (slave mode) %c", state); ! 263: switch(state) { ! 264: case 'I': state = rinit(); break; ! 265: case 'F': state = recvf(); break; ! 266: case 'C': state = schkdir(); break; ! 267: case 'T': state = 'B'; break; ! 268: case 'B': state = scandir(); break; ! 269: case 'S': state = sendf(); break; ! 270: case 'Q': state = sbreak(); break; ! 271: case 'G': return ('Y'); ! 272: case 'Y': state = endp(); break; ! 273: case 'P': return ('Y'); ! 274: case 'A': return ('A'); ! 275: default: return ('A'); ! 276: } ! 277: } ! 278: return('A'); ! 279: } ! 280: ! 281: /* ! 282: * r e c v f ! 283: * ! 284: * This is the state table switcher for receiving files. ! 285: */ ! 286: ! 287: recvf() ! 288: { ! 289: state = 'F'; /* Receive-Init is the start state */ ! 290: while(!abort_cico) { ! 291: printmsg(M_DEBUG, " recvf state: %c", state); ! 292: switch(state) { ! 293: case 'F': state = rmtcmd(); break; /* Rcv File */ ! 294: case 'J': state = rdata(); break; /* Rcv Data */ ! 295: case 'D': state = sdata(); break; ! 296: case 'Z': state = seof(); break; ! 297: case 'C': return ('C'); /* Complete state */ ! 298: case 'A': return ('Y'); /* Abort state */ ! 299: default: return ('Y'); /* Abort state */ ! 300: } ! 301: } ! 302: return('A'); ! 303: } ! 304: ! 305: ! 306: /* ! 307: * s e n d f ! 308: * ! 309: * Sendsw is the state table switcher for sending files. It loops until either ! 310: * it finishes, or an error is encountered. The routines called by sendsw ! 311: * are responsible for changing the state. ! 312: * - ! 313: * This routine is more properly called the command file reader. ! 314: * It needs to dispatch to sfile and rfile based upon decoding of records in ! 315: * the C.<> file. ! 316: * ! 317: */ ! 318: sendf() ! 319: { ! 320: fpfd = -1; /* reset file getter/opener */ ! 321: state = 'F'; /* Send initiate is the start state */ ! 322: while(!abort_cico) { /* Do this as long as necessary */ ! 323: printmsg(M_DEBUG, "sendf state: %c", state); ! 324: switch(state) { ! 325: case 'F': state = cdotcmd(); break; /* Send-File */ ! 326: case 'J': state = rdata(); break; ! 327: case 'D': state = sdata(); break; /* Send-Data */ ! 328: case 'Z': state = seof(); break; /* Send-EoF */ ! 329: case 'B': return ('B'); /* Complete */ ! 330: case 'A': return ('Y'); /* Abort */ ! 331: default: return ('Y'); /* Unknown, fail */ ! 332: } ! 333: } ! 334: return('A'); ! 335: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.