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