|
|
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.