|
|
1.1 root 1: /* /sccs/src/cmd/uucp/s.cntrl.c
2: cntrl.c 1.9 8/30/84 17:37:09
3: */
4: #include "uucp.h"
5: VERSION(@(#)cntrl.c 1.9);
6:
7: struct Proto {
8: char P_id;
9: int (*P_turnon)();
10: int (*P_rdmsg)();
11: int (*P_wrmsg)();
12: int (*P_rddata)();
13: int (*P_wrdata)();
14: int (*P_turnoff)();
15: };
16:
17: #ifdef PROTO_G
18: extern int gturnon(), gturnoff();
19: extern int errno;
20: extern int grdmsg(), grddata();
21: extern int gwrmsg(), gwrdata();
22: #endif
23: #ifdef PROTO_D
24: extern int dturnon(), dturnoff();
25: extern int drdmsg(), drddata();
26: extern int dwrmsg(), dwrdata();
27: #endif
28: #ifdef PROTO_X
29: extern int xturnon(), xturnoff();
30: extern int xrdmsg(), xrddata();
31: extern int xwrmsg(), xwrdata();
32: #endif
33: #ifdef PROTO_E
34: extern int eturnon(), eturnoff();
35: extern int erdmsg(), erddata();
36: extern int ewrmsg(), ewrdata();
37: #endif
38:
39: extern int imsg();
40: extern int omsg();
41:
42: struct Proto Ptbl[]={
43: #ifdef PROTO_G
44: 'g', gturnon, grdmsg, gwrmsg, grddata, gwrdata, gturnoff,
45: #endif
46: #ifdef PROTO_E
47: 'e', eturnon, erdmsg, ewrmsg, erddata, ewrdata, eturnoff,
48: #endif
49: #ifdef PROTO_D
50: 'd', dturnon, drdmsg, dwrmsg, drddata, dwrdata, dturnoff,
51: #endif
52: #ifdef PROTO_X
53: 'x', xturnon, xrdmsg, xwrmsg, xrddata, xwrdata, xturnoff,
54: #endif
55: '\0'
56: };
57:
58: int (*Rdmsg)()=imsg, (*Rddata)();
59: int (*Wrmsg)()=omsg, (*Wrdata)();
60: int (*Turnon)(), (*Turnoff)();
61:
62:
63: #define YES "Y"
64: #define NO "N"
65:
66: /*
67: * failure messages
68: */
69: #define EM_MAX 7
70: #define EM_LOCACC "N1" /* local access to file denied */
71: #define EM_RMTACC "N2" /* remote access to file/path denied */
72: #define EM_BADUUCP "N3" /* a bad uucp command was generated */
73: #define EM_NOTMP "N4" /* remote error - can't create temp */
74: #define EM_RMTCP "N5" /* can't copy to remote directory - file in public */
75: #define EM_LOCCP "N6" /* can't copy on local system */
76:
77: char *Em_msg[] = {
78: "COPY FAILED (reason not given by remote)",
79: "local access to file denied",
80: "remote access to path/file denied",
81: "system error - bad uucp command generated",
82: "remote system can't create temp file",
83: "can't copy to file/directory - file left in PUBDIR/user/file",
84: "can't copy to file/directory - file left in PUBDIR/user/file",
85: "forwarding error"
86: };
87:
88:
89: #define XUUCP 'X' /* execute uucp (string) */
90: #define SLTPTCL 'P' /* select protocol (string) */
91: #define USEPTCL 'U' /* use protocol (character) */
92: #define RCVFILE 'R' /* receive file (string) */
93: #define SNDFILE 'S' /* send file (string) */
94: #define RQSTCMPT 'C' /* request complete (string - yes | no) */
95: #define HUP 'H' /* ready to hangup (string - yes | no) */
96: #define RESET 'X' /* reset line modes */
97:
98: #define W_MAX 10 /* maximum number of C. files per line */
99: #define W_TYPE wrkvec[0]
100: #define W_FILE1 wrkvec[1]
101: #define W_FILE2 wrkvec[2]
102: #define W_USER wrkvec[3]
103: #define W_OPTNS wrkvec[4]
104: #define W_DFILE wrkvec[5]
105: #define W_MODE wrkvec[6]
106: #define W_NUSER wrkvec[7]
107: #define W_SFILE wrkvec[8]
108: #define W_RFILE wrkvec[5]
109: #define W_XFILE wrkvec[5]
110: char *mf;
111:
112: #define RMESG(m, s) if (rmesg(m, s) != 0) {(*Turnoff)(); return(FAIL);}
113: #define RAMESG(s) if (rmesg('\0', s) != 0) {(*Turnoff)(); return(FAIL);}
114: #define WMESG(m, s) if(wmesg(m, s) != 0) {(*Turnoff)(); return(FAIL);}
115:
116: char Wfile[MAXFULLNAME] = {'\0'};
117: char Dfile[MAXFULLNAME];
118:
119: /*
120: * execute the conversation between the two machines
121: * after both programs are running.
122: * returns:
123: * SUCCESS -> ok
124: * FAIL -> failed
125: */
126: char *wrkvec[W_MAX+1];
127: int statfopt;
128: cntrl(role)
129: register int role;
130: {
131: FILE * fp;
132: struct stat stbuf;
133: extern (*Rdmsg)(), (*Wrmsg)();
134: int filemode;
135: int status = 1;
136: int i, narg;
137: int mailopt, ntfyopt;
138: int ret;
139: char rqstr[BUFSIZ]; /* contains the current request message */
140: char msg[BUFSIZ];
141: char filename[MAXFULLNAME], wrktype;
142: static int pnum;
143:
144: pnum = getpid();
145: Wfile[0] = '\0';
146: top:
147: statfopt = 0;
148: *Jobid = '\0';
149: DEBUG(4, "*** TOP *** - role=%d, ", role);
150: setline(RESET);
151: if (role == MASTER) {
152:
153: /*
154: * get work
155: */
156: if ((narg = gtwvec(Wfile, wrkvec, W_MAX)) == 0) {
157: WMESG(HUP, "");
158: RMESG(HUP, msg);
159: goto process;
160: }
161: DEBUG(7, "Wfile - %s,", Wfile);
162: strncpy(Jobid, BASENAME(Wfile, '/')+2, NAMESIZE);
163: Jobid[NAMESIZE-1] = '\0';
164: DEBUG(7, "Jobid = %s\n", Jobid);
165: wrktype = W_TYPE[0];
166: mailopt = strchr(W_OPTNS, 'm') != NULL;
167: #if NOTDEF /* unsafe */
168: statfopt = strchr(W_OPTNS, 'o') != NULL;
169: #endif
170: ntfyopt = strchr(W_OPTNS, 'n') != NULL;
171:
172: strcpy(User, W_USER);
173: W_USER = Uucp; /* so what we send is short */
174: msg[0] = '\0';
175: for (i = 1; i < narg; i++) {
176: (void) strcat(msg, " ");
177: (void) strcat(msg, wrkvec[i]);
178: }
179:
180: /*
181: * We used to check for corrupt workfiles here (narg < 5),
182: * but we were doing it wrong, and besides, anlwrk.c is the
183: * appropriate place to do it.
184: */
185:
186: if (wrktype == SNDFILE ) {
187: (void) sprintf(rqstr, "%s!%s --> %s!%s (%s)", Myname,
188: W_FILE1, Rmtname, W_FILE2, User);
189: logent(rqstr, "REQUEST");
190: CDEBUG(1, "Request: %s\n", rqstr);
191: mf = W_SFILE;
192: (void) strcpy(filename, W_FILE1);
193: expfile(filename);
194: if ( !READSOME(filename) && !READSOME(W_DFILE)) {
195:
196: /*
197: * access denied
198: */
199: logent("DENIED", "ACCESS");
200: unlinkdf(W_DFILE);
201: lnotify(User, rqstr, "access denied");
202: CDEBUG(1, "Failed: Access Denied\n", 0);
203: goto top;
204: }
205:
206: (void) strcpy(Dfile, W_DFILE);
207: fp = NULL;
208: fp = fopen(Dfile, "r");
209: ASSERT(strlen(Dfile)>0, "Dfile==0", "", role);
210: if (fp == NULL &&
211: (fp = fopen(filename, "r")) == NULL) {
212:
213: /* can not read data file */
214: unlinkdf(Dfile);
215: lnotify(User, rqstr, "can't access");
216:
217: (void) sprintf(msg, "CAN'T READ %s %d",
218: filename, errno);
219: logent(msg, "FAILED");
220: CDEBUG(1, "Failed: Can't Read %s\n", filename);
221: goto top;
222: }
223: Seqn++;
224: setline(SNDFILE);
225: }
226:
227: if (wrktype == RCVFILE) {
228: (void) sprintf(rqstr, "%s!%s --> %s!%s (%s)", Rmtname,
229: W_FILE1, Myname, W_FILE2, User);
230: logent(rqstr, "REQUEST");
231: CDEBUG(1, "Request: %s\n", rqstr);
232: mf = W_RFILE;
233: (void) strcpy(filename, W_FILE2);
234: expfile(filename);
235: if (chkperm(W_FILE1, filename, strchr(W_OPTNS, 'd'))) {
236:
237: /* access denied */
238: logent("DENIED", "ACCESS");
239: lnotify(User, rqstr, "access denied");
240: CDEBUG(1, "Failed: Access Denied--File: $s\n",
241: filename);
242: goto top;
243: }
244: TMname(Dfile, pnum); /* get TM file name */
245:
246: if ( ((fp = fopen(Dfile, "w")) == NULL)
247: || nospace(Dfile)) {
248:
249: /* can not create temp */
250: logent("CAN'T CREATE TM", "FAILED");
251: CDEBUG(1, "Failed: No Space!\n", 0);
252: unlinkdf(Dfile);
253: assert(Ct_CREATE, Dfile, nospace(Dfile),
254: sccsid, __FILE__, __LINE__);
255: cleanup(FAIL);
256: }
257: Seqn++;
258: chmod(Dfile, DFILEMODE); /* no peeking! */
259: setline(RCVFILE);
260: }
261: sendmsg:
262: DEBUG(4, "wrktype - %c\n ", wrktype);
263: WMESG(wrktype, msg);
264: RMESG(wrktype, msg);
265: goto process;
266: }
267:
268: /*
269: * role is slave
270: */
271: RAMESG(msg);
272:
273: process:
274:
275: /*
276: * touch all lock files
277: */
278: ultouch();
279: DEBUG(4, " PROCESS: msg - %s\n", msg);
280: switch (msg[0]) {
281:
282: case RQSTCMPT:
283: DEBUG(4, "%s\n", "RQSTCMPT:");
284: if (msg[1] == 'N') {
285: i = atoi(&msg[2]);
286: if (i < 0 || i > EM_MAX)
287: i = 0;
288: logent(Em_msg[i], "REQUESTED");
289: }
290: if (role == MASTER)
291: notify(mailopt, User, rqstr, Rmtname, &msg[1]);
292: goto top;
293:
294: case HUP:
295: DEBUG(4, "%s\n", "HUP:");
296: if (msg[1] == 'Y') {
297: WMESG(HUP, YES);
298: (*Turnoff)();
299: Rdmsg = imsg;
300: Wrmsg = omsg;
301: return(0);
302: }
303:
304: if (msg[1] == 'N') {
305: ASSERT(role == MASTER, Wr_ROLE, "", role);
306: role = SLAVE;
307: goto top;
308: }
309:
310: /*
311: * get work
312: */
313: if ( (switchRole() == FALSE) || !iswrk(Wfile) ) {
314: DEBUG(5, "SLAVE-switchRole (%s)\n",
315: switchRole() ? "TRUE" : "FALSE");
316: WMESG(HUP, YES);
317: RMESG(HUP, msg);
318: goto process;
319: }
320:
321: /* Note that Wfile is the first C. to process at top
322: * set above by iswrk() call
323: */
324: WMESG(HUP, NO);
325: role = MASTER;
326: goto top;
327:
328: case XUUCP:
329: /*
330: * slave part
331: * No longer accepted
332: */
333:
334: WMESG(XUUCP, NO);
335: goto top;
336:
337: case SNDFILE:
338:
339: /*
340: * MASTER section of SNDFILE
341: */
342: DEBUG(4, "%s\n", "SNDFILE:");
343: if (msg[1] == 'N')
344: {
345: i = atoi(&msg[2]);
346: if (i < 0 || i > EM_MAX)
347: i = 0;
348: logent(Em_msg[i], "REQUEST");
349: notify(mailopt, User, rqstr, Rmtname, &msg[1]);
350: ASSERT(role == MASTER, Wr_ROLE, "", role);
351: (void) fclose(fp);
352: ASSERT(i != 4, Em_msg[4], Rmtname, i); /* EM_NOTMP */
353: unlinkdf(W_DFILE);
354: goto top;
355: }
356:
357: if (msg[1] == 'Y') {
358:
359: /*
360: * send file
361: */
362: ASSERT(role == MASTER, Wr_ROLE, "", role);
363: if (fstat(fileno(fp), &stbuf)) /* never fail but .. */
364: stbuf.st_size = 0; /* for time loop calculation */
365: ret = (*Wrdata)(fp, Ofn);
366: (void) fclose(fp);
367: if (ret != 0) {
368: (*Turnoff)();
369: return(FAIL);
370: }
371:
372: /* loop depending on the size of the file */
373: /* give an extra try for each megabyte */
374: for (i = stbuf.st_size >> 10; i >= 0; --i) {
375: if ((ret = rmesg(RQSTCMPT, msg)) == 0)
376: break; /* got message */
377: }
378: if (ret != 0) {
379: (*Turnoff)();
380: return(FAIL);
381: }
382: unlinkdf(W_DFILE);
383: goto process;
384: }
385:
386: /*
387: * SLAVE section of SNDFILE
388: */
389: ASSERT(role == SLAVE, Wr_ROLE, "", role);
390:
391: /*
392: * request to receive file
393: * check permissions
394: */
395: i = getargs(msg, wrkvec, W_MAX);
396:
397: /* Check for bad request */
398: if (i < 7) {
399: WMESG(SNDFILE, EM_BADUUCP);
400: logent("DENIED", "TOO FEW ARGS IN SLAVE SNDFILE");
401: goto top;
402: }
403:
404: mf = W_SFILE;
405: (void) sprintf(rqstr, "%s!%s --> %s!%s (%s)", Rmtname,
406: W_FILE1, Myname, W_FILE2, W_USER);
407: logent(rqstr, "REMOTE REQUESTED");
408: DEBUG(4, "msg - %s\n", msg);
409: CDEBUG(1, "Remote Requested: %s\n", rqstr);
410: (void) strcpy(filename, W_FILE2);
411: expfile(filename);
412: DEBUG(4, "SLAVE - filename: %s\n", filename);
413: if (chkpth(filename, CK_WRITE)
414: || chkperm(W_FILE1, filename, strchr(W_OPTNS, 'd'))) {
415: WMESG(SNDFILE, EM_RMTACC);
416: logent("DENIED", "PERMISSION");
417: CDEBUG(1, "Failed: Access Denied\n", 0);
418: goto top;
419: }
420: strcpy(User, W_USER);
421:
422: DEBUG(4, "chkpth ok Rmtname - %s\n", Rmtname);
423: TMname(Dfile, pnum); /* get TM file name */
424:
425: if ( ((fp = fopen(Dfile, "w")) == NULL) || nospace(Dfile) ) {
426: WMESG(SNDFILE, EM_NOTMP);
427: logent("CAN'T OPEN", "DENIED");
428: CDEBUG(1, "Failed: Can't Create Temp File\n", 0);
429: unlinkdf(Dfile);
430: goto top;
431: }
432: Seqn++;
433: chmod(Dfile, DFILEMODE); /* no peeking! */
434: WMESG(SNDFILE, YES);
435: ret = (*Rddata)(Ifn, fp);
436: (void) fclose(fp);
437: if (ret != 0) {
438: (*Turnoff)();
439: logent("INPUT FAILURE", "IN SEND/SLAVE MODE");
440: return(FAIL);
441: }
442: /* copy to user directory */
443: ntfyopt = strchr(W_OPTNS, 'n') != NULL;
444: status = xmv(Dfile, filename);
445: WMESG(RQSTCMPT, status ? EM_RMTCP : YES);
446: if (status == 0) {
447: sscanf(W_MODE, "%o", &filemode);
448: if (filemode <= 0)
449: filemode = 0666;
450: if (PREFIX(RemSpool, filename))
451: chmod(filename, 0600);
452: else
453: chmod(filename, (filemode|0666) & 0777);
454: arrived(ntfyopt, filename, W_NUSER, Rmtname, User);
455: } else {
456: logent("FAILED", "COPY");
457: status = putinpub(filename, Dfile,
458: BASENAME(W_USER, '!'));
459: DEBUG(4, "->PUBDIR %d\n", status);
460: if (status == 0)
461: arrived(ntfyopt, filename, W_NUSER,
462: Rmtname, User);
463: }
464: goto top;
465:
466: case RCVFILE:
467:
468: /*
469: * MASTER section of RCVFULE
470: */
471: DEBUG(4, "%s\n", "RCVFILE:");
472: if (msg[1] == 'N') {
473: i = atoi(&msg[2]);
474: if (i < 0 || i > EM_MAX)
475: i = 0;
476: logent(Em_msg[i], "REQUEST");
477: notify(mailopt, User, rqstr, Rmtname, &msg[1]);
478: ASSERT(role == MASTER, Wr_ROLE, "", role);
479: (void) fclose(fp);
480: unlinkdf(Dfile);
481: goto top;
482: }
483:
484: if (msg[1] == 'Y') {
485:
486: /*
487: * receive file
488: */
489: ASSERT(role == MASTER, Wr_ROLE, "", role);
490: ret = (*Rddata)(Ifn, fp);
491: (void) fclose(fp);
492: if (ret != 0) {
493: (*Turnoff)();
494: return(FAIL);
495: }
496:
497: status = xmv(Dfile, filename);
498: WMESG(RQSTCMPT, status ? EM_RMTCP : YES);
499: notify(mailopt, User, rqstr, Rmtname,
500: status ? EM_LOCCP : YES);
501: if (status == 0) {
502: sscanf(&msg[2], "%o", &filemode);
503: if (filemode <= 0)
504: filemode = 0666;
505: if (PREFIX(RemSpool, filename))
506: chmod(filename, 0600);
507: else
508: chmod(filename, (filemode|0666) & 0777);
509: } else {
510: logent("FAILED", "COPY");
511: putinpub(filename, Dfile, W_USER);
512: }
513: goto top;
514: }
515:
516: /*
517: * SLAVE section of RCVFILE
518: * (request to send file)
519: */
520: ASSERT(role == SLAVE, Wr_ROLE, "", role);
521:
522: /* check permissions */
523: i = getargs(msg, wrkvec, W_MAX);
524:
525: /* Check for bad request */
526: if (i < 5) {
527: WMESG(RCVFILE, EM_BADUUCP);
528: logent("DENIED", "TOO FEW ARGS IN SLAVE RCVFILE");
529: goto top;
530: }
531:
532: (void) sprintf(rqstr, "%s!%s --> %s!%s (%s)", Myname,
533: W_FILE1, Rmtname, W_FILE2, W_USER);
534: logent(rqstr, "REMOTE REQUESTED");
535: CDEBUG(1, "Remote Requested: %s\n", rqstr);
536: mf = W_RFILE;
537: DEBUG(4, "msg - %s\n", msg);
538: DEBUG(4, "W_FILE1 - %s\n", W_FILE1);
539: (void) strcpy(filename, W_FILE1);
540: expfile(filename);
541: if (DIRECTORY(filename)) {
542: (void) strcat(filename, "/");
543: (void) strcat(filename, BASENAME(W_FILE2, '/'));
544: }
545: strcpy(User, W_USER);
546: if (requestOK() == FALSE) {
547: WMESG(RCVFILE, EM_RMTACC);
548: logent("DENIED", "REQUESTING");
549: CDEBUG(1, "Failed: Access Denied\n", 0);
550: goto top;
551: }
552: DEBUG(4, "requestOK for Loginuser - %s\n", Loginuser);
553:
554: if (chkpth(filename, CK_READ) || !READANY(filename)) {
555: WMESG(RCVFILE, EM_RMTACC);
556: logent("DENIED", "PERMISSION");
557: CDEBUG(1, "Failed: Access Denied\n", 0);
558: goto top;
559: }
560: DEBUG(4, "chkpth ok Loginuser - %s\n", Loginuser);
561:
562: if ((fp = fopen(filename, "r")) == NULL) {
563: WMESG(RCVFILE, EM_RMTACC);
564: logent("CAN'T OPEN", "DENIED");
565: CDEBUG(1, "Failed: Can't Open %s\n", filename);
566: goto top;
567: }
568:
569: /*
570: * ok to send file
571: */
572:
573: ASSERT(fstat(fileno(fp), &stbuf) == 0, Ct_STAT,
574: filename, errno);
575: (void) sprintf(msg, "%s %o", YES, stbuf.st_mode & 0777);
576: WMESG(RCVFILE, msg);
577: Seqn++;
578: ret = (*Wrdata)(fp, Ofn);
579: (void) fclose(fp);
580: if (ret != 0) {
581: (*Turnoff)();
582: return(FAIL);
583: }
584:
585: /* loop depending on the size of the file */
586: /* give an extra try for each megabyte */
587: /* stbuf set in fstat several lines back */
588: for (i = stbuf.st_size >> 10; i >= 0; --i) {
589: if ((ret = rmesg(RQSTCMPT, msg)) == 0)
590: break; /* got message */
591: }
592: if (ret != 0) {
593: (*Turnoff)();
594: return(FAIL);
595: }
596: goto process;
597: }
598: (*Turnoff)();
599: return(FAIL);
600: }
601:
602:
603:
604: /*
605: * read message
606: * returns:
607: * 0 -> success
608: * FAIL -> failure
609: */
610: rmesg(c, msg)
611: char *msg, c;
612: {
613: char str[50];
614:
615: DEBUG(4, "rmesg - '%c' ", c);
616: if ((*Rdmsg)(msg, Ifn) != 0) {
617: DEBUG(4, "got %s\n", "FAIL");
618: (void) sprintf(str, "expected '%c' got FAIL", c);
619: logent(str, "BAD READ");
620: return(FAIL);
621: }
622: if (c != '\0' && msg[0] != c) {
623: DEBUG(4, "got %s\n", msg);
624: (void) sprintf(str, "expected '%c' got %s", c, msg);
625: logent(str, "BAD READ");
626: return(FAIL);
627: }
628: DEBUG(4, "got %s\n", msg);
629: return(0);
630: }
631:
632:
633: /*
634: * write a message
635: * returns:
636: * 0 -> ok
637: * FAIL -> ng
638: */
639: wmesg(m, s)
640: char *s, m;
641: {
642: CDEBUG(4, "wmesg '%c'", m);
643: CDEBUG(4, "%s\n", s);
644: return((*Wrmsg)(m, s, Ofn));
645: }
646:
647:
648: /*
649: * mail results of command
650: * return:
651: * none
652: */
653: notify(mailopt, user, msgin, sys, msgcode)
654: char *user, *msgin, *sys;
655: register char *msgcode;
656: {
657: register int i;
658: char str[BUFSIZ];
659: register char *msg;
660:
661: DEBUG(4,"mailopt %d, ", mailopt);
662: DEBUG(4,"statfopt %d\n", statfopt);
663: if (statfopt == 0 && mailopt == 0 && *msgcode == 'Y')
664: return;
665: if (*msgcode == 'Y')
666: msg = "copy succeeded";
667: else {
668: i = atoi(msgcode + 1);
669: if (i < 1 || i > EM_MAX)
670: i = 0;
671: msg = Em_msg[i];
672: }
673: if(statfopt){
674: stmesg(msgin, msg);
675: return;
676: }
677: (void) sprintf(str, "REQUEST: %s\n(SYSTEM: %s) %s\n",
678: msgin, sys, msg);
679: mailst(user, str, "", "");
680: return;
681: }
682:
683: /*
684: * local notify
685: * return:
686: * none
687: */
688: lnotify(user, msgin, mesg)
689: char *user, *msgin, *mesg;
690: {
691: char mbuf[BUFSIZ];
692:
693: if(statfopt){
694: stmesg(msgin, mesg);
695: return;
696: }
697: (void) sprintf(mbuf, "REQUEST: %s\n(SYSTEM: %s) %s\n",
698: msgin, Myname, mesg);
699: mailst(user, mbuf, "", "");
700: return;
701: }
702: static
703: stmesg(f, m)
704: char *f, *m;
705: {
706: FILE *Cf;
707: time_t clock;
708: long td, th, tm, ts;
709:
710: ASSERT(1, "stmesg called", "", 0);
711: #if NOTDEF
712: DEBUG(4,"STMES %s\n",mf);
713: if((Cf = fopen(mf, "a+")) == NULL){
714: chmod(mf, 0666);
715: return;
716: }
717: (void) time(&clock);
718: (void) fprintf(Cf, "uucp job: %s (%s) ", Jobid, timeStamp());
719: td = clock - Nstat.t_qtime;
720: ts = td%60;
721: td /= 60;
722: tm = td%60;
723: td /= 60;
724: th = td;
725: (void) fprintf(Cf, "(%ld:%ld:%ld)\n%s\n%s\n\n", th, tm, ts, f, m);
726: (void) fclose(Cf);
727: chmod(mf, 0666);
728: #endif
729:
730: }
731:
732:
733: /*
734: * converse with the remote machine, agree upon a
735: * protocol (if possible) and start the protocol.
736: * return:
737: * SUCCESS -> successful protocol selection
738: * FAIL -> can't find common or open failed
739: */
740: startup(role)
741: register int role;
742: {
743: extern (*Rdmsg)(), (*Wrmsg)();
744: extern imsg(), omsg();
745: extern char *blptcl(), fptcl(), *protoString();
746: char msg[BUFSIZ], str[BUFSIZ];
747:
748: Rdmsg = imsg;
749: Wrmsg = omsg;
750: if (role == MASTER) {
751: RMESG(SLTPTCL, msg);
752: if ((str[0] = fptcl(&msg[1])) == NULL) {
753:
754: /*
755: * no protocol match
756: */
757: WMESG(USEPTCL, NO);
758: return(FAIL);
759: }
760: str[1] = '\0';
761: WMESG(USEPTCL, str);
762: if (stptcl(str) != 0)
763: return(FAIL);
764: return(SUCCESS);
765: } else {
766: WMESG(SLTPTCL, blptcl(str));
767: RMESG(USEPTCL, msg);
768: if (msg[1] == 'N') {
769: return(FAIL);
770: }
771:
772: if (stptcl(&msg[1]) != 0)
773: return(FAIL);
774: return(SUCCESS);
775: }
776: }
777:
778:
779: /*
780: * choose a protocol from the input string (str)
781: * and return the found letter.
782: * Use the MASTER string for order of selection.
783: * If a preferred protocol was named, use that if possible.
784: * return:
785: * '\0' -> no acceptable protocol
786: * any character -> the chosen protocol
787: */
788: char
789: fptcl(str)
790: register char *str;
791: {
792: char *l, list[20]; /* assume less than 20 protocols */
793:
794: if ((l = protoString()) != NULL)
795: for (; *l; l++)
796: if (strchr(str, *l))
797: return (*l);
798: blptcl(list);
799: for (l = list; *l != '\0'; l++)
800: if (strchr(str, *l) != NULL)
801: return(*l);
802: return('\0');
803: }
804:
805: /*
806: * build a string of the letters of the available
807: * protocols and return the string (str).
808: * return:
809: * a pointer to string (str)
810: */
811: char *
812: blptcl(str)
813: register char *str;
814: {
815: register struct Proto *p;
816: char *s;
817:
818: for (p = Ptbl, s = str; (*s++ = p->P_id) != '\0'; p++)
819: ;
820: return(str);
821: }
822:
823: /*
824: * set up the six routines (Rdmg. Wrmsg, Rddata
825: * Wrdata, Turnon, Turnoff) for the desired protocol.
826: * returns:
827: * SUCCESS -> ok
828: * FAIL -> no find or failed to open
829: */
830: stptcl(c)
831: register char *c;
832: {
833: register struct Proto *p;
834:
835: for (p = Ptbl; p->P_id != '\0'; p++) {
836: if (*c == p->P_id) {
837:
838: /*
839: * found protocol
840: * set routine
841: */
842: Rdmsg = p->P_rdmsg;
843: Wrmsg = p->P_wrmsg;
844: Rddata = p->P_rddata;
845: Wrdata = p->P_wrdata;
846: Turnon = p->P_turnon;
847: Turnoff = p->P_turnoff;
848: if ((*Turnon)() != 0)
849: break;
850: CDEBUG(4, "Proto started %c\n", *c);
851: return(SUCCESS);
852: }
853: }
854: CDEBUG(4, "Proto start-fail %c\n", *c);
855: return(FAIL);
856: }
857:
858: /*
859: * put file in public place
860: * if successful, filename is modified
861: * returns:
862: * 0 -> success
863: * FAIL -> failure
864: */
865: putinpub(file, tmp, user)
866: char *file, *user, *tmp;
867: {
868: int status;
869: char fullname[MAXFULLNAME];
870:
871: (void) sprintf(fullname, "%s/%s/", Pubdir, user);
872: if (mkdirs(fullname) != 0) {
873:
874: /*
875: * can not make directories
876: */
877: return(FAIL);
878: }
879: (void) strcat(fullname, BASENAME(file, '/'));
880: status = xmv(tmp, fullname);
881: if (status == 0) {
882: (void) strcpy(file, fullname);
883: (void) chmod(fullname,0666);
884: }
885: return(status);
886: }
887:
888: /*
889: * unlink D. file
890: * returns:
891: * none
892: */
893: unlinkdf(file)
894: register char *file;
895: {
896: if (strlen(file) > 6)
897: (void) unlink(file);
898: return;
899: }
900:
901: /*
902: * notify receiver of arrived file
903: * returns:
904: * none
905: */
906: arrived(opt, file, nuser, rmtsys, rmtuser)
907: char *file, *nuser, *rmtsys, *rmtuser;
908: {
909: char mbuf[200];
910:
911: if (!opt)
912: return;
913: (void) sprintf(mbuf, "%s from %s!%s arrived\n", file, rmtsys, rmtuser);
914: mailst(nuser, mbuf, "", "");
915: return;
916: }
917:
918:
919: /*
920: * Check to see if there is space for file
921: */
922:
923: #define FREESPACE 50 /* Minimum freespace in blocks to permit transfer */
924: #define FREENODES 5 /* Minimum number of inodes to permit transfer */
925:
926: /*ARGSUSED*/
927: static
928: nospace(name)
929: char *name;
930: #ifdef NOUSTAT
931: {return(FALSE);}
932: #else
933: {
934: struct stat statb;
935: struct ustat ustatb;
936:
937: if( stat(name, &statb) < 0 )
938: return(TRUE);
939: #ifdef RT
940: if( (statb.st_mode|S_IFMT) == S_IFREG ||
941: (statb.st_mode|S_IFMT) == S_IFEXT ||
942: (statb.st_mode&S_IFMT) == S_IF1EXT )
943: #else
944: if( (statb.st_mode&S_IFMT) == S_IFREG )
945: #endif
946: {
947: if( ustat(statb.st_dev, &ustatb)<0 )
948: return(TRUE);
949: if( ustatb.f_tfree < FREESPACE ) {
950: logent("FREESPACE IS LOW","REMOTE TRANSFER DENIED - ");
951: return(TRUE);
952: }
953: if( ustatb.f_tinode < FREENODES ) {
954: logent("TOO FEW INODES","REMOTE TRANSFER DENIED - ");
955: return(TRUE);
956: }
957: }
958: return(FALSE);
959: }
960: #endif
961:
962: #ifdef V7USTAT
963: ustat(dev, ustat)
964: int dev;
965: struct ustat *ustat;
966: {
967: FILE *dfp, *popen();
968: struct fstab *fstab = NULL;
969: char *fval, buf[BUFSIZ];
970:
971: sprintf(buf, "%s %d %d 2>&1", V7USTAT, major(dev), minor(dev));
972: if ((dfp = popen(buf, "r")) == NULL)
973: return(-1);
974: fval = fgets(buf, sizeof(buf), dfp);
975: if (pclose(dfp) != 0
976: || fval == NULL
977: || sscanf(buf, "%d %d", &ustat->f_tfree, &ustat->f_tinode) != 2)
978: return(-1);
979: return(0);
980: }
981: #endif V7USTAT
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.