|
|
1.1 root 1: /* cntrl 2.7 5/24/79 21:37:36 */
2: #include "uucp.h"
3: #include <sys/types.h>
4: #include <sys/stat.h>
5:
6: static char SiD[] = "@(#)cntrl 2.7";
7:
8:
9: struct Proto {
10: char P_id;
11: int (*P_turnon)();
12: int (*P_rdmsg)();
13: int (*P_wrmsg)();
14: int (*P_rddata)();
15: int (*P_wrdata)();
16: int (*P_turnoff)();
17: };
18:
19:
20: extern int gturnon(), gturnoff();
21: extern int grdmsg(), grddata();
22: extern int gwrmsg(), gwrdata();
23: extern int imsg();
24: extern int omsg();
25:
26: struct Proto Ptbl[]={
27: 'g', gturnon, grdmsg, gwrmsg, grddata, gwrdata, gturnoff,
28: '\0'
29: };
30:
31: int (*Rdmsg)()=imsg, (*Rddata)();
32: int (*Wrmsg)()=omsg, (*Wrdata)();
33: int (*Turnon)(), (*Turnoff)();
34:
35:
36: #define YES "Y"
37: #define NO "N"
38:
39: /* failure messages */
40: #define EM_MAX 6
41: #define EM_LOCACC "N1" /* local access to file denied */
42: #define EM_RMTACC "N2" /* remote access to file/path denied */
43: #define EM_BADUUCP "N3" /* a bad uucp command was generated */
44: #define EM_NOTMP "N4" /* remote error - can't create temp */
45: #define EM_RMTCP "N5" /* can't copy to remote directory - file in public */
46: #define EM_LOCCP "N6" /* can't copy on local system */
47:
48: char *Em_msg[] = {
49: "COPY FAILED (reason not given by remote)",
50: "local access to file denied",
51: "remote access to path/file denied",
52: "system error - bad uucp command generated",
53: "remote system can't create temp file",
54: "can't copy to file/directory - file left in PUBDIR/user/file",
55: "can't copy to file/directory - file left in PUBDIR/user/file"
56: };
57:
58: /* */
59:
60:
61: #define XUUCP 'X' /* execute uucp (string) */
62: #define SLTPTCL 'P' /* select protocol (string) */
63: #define USEPTCL 'U' /* use protocol (character) */
64: #define RCVFILE 'R' /* receive file (string) */
65: #define SNDFILE 'S' /* send file (string) */
66: #define RQSTCMPT 'C' /* request complete (string - yes | no) */
67: #define HUP 'H' /* ready to hangup (string - yes | no) */
68:
69:
70: #define W_TYPE wrkvec[0]
71: #define W_FILE1 wrkvec[1]
72: #define W_FILE2 wrkvec[2]
73: #define W_USER wrkvec[3]
74: #define W_OPTNS wrkvec[4]
75: #define W_DFILE wrkvec[5]
76: #define W_MODE wrkvec[6]
77:
78: #define RMESG(m, s) if (rmesg(m, s) != 0) {(*Turnoff)(); return(FAIL);}
79: #define RAMESG(s) if (rmesg('\0', s) != 0) {(*Turnoff)(); return(FAIL);}
80: #define WMESG(m, s) if(wmesg(m, s) != 0) {(*Turnoff)(); return(FAIL);}
81:
82: char Wfile[MAXFULLNAME] = {'\0'};
83: char Dfile[MAXFULLNAME];
84:
85: /*******
86: * cntrl(role, wkpre)
87: * int role;
88: * char *wkpre;
89: *
90: * cntrl - this routine will execute the conversation
91: * between the two machines after both programs are
92: * running.
93: *
94: * return codes
95: * SUCCESS - ok
96: * FAIL - failed
97: */
98:
99: cntrl(role, wkpre)
100: int role;
101: char *wkpre;
102: {
103: char msg[BUFSIZ], rqstr[BUFSIZ];
104: FILE *fp;
105: int filemode;
106: struct stat stbuf;
107: char filename[MAXFULLNAME], wrktype, *wrkvec[20];
108: extern (*Rdmsg)(), (*Wrmsg)();
109: extern char *index(), *lastpart();
110: int status = 1, i;
111: int mailopt;
112: int ret;
113: static int pnum, tmpnum = 0;
114:
115: pnum = getpid();
116: top:
117: DEBUG(4, "*** TOP *** - role=%d, ", role);
118: if (role == MASTER) {
119: /* get work */
120: if ((i = gtwvec(Wfile, Spool, wkpre, wrkvec)) == 0) {
121: WMESG(HUP, "");
122: RMESG(HUP, msg);
123: goto process;
124: }
125: wrktype = W_TYPE[0];
126: mailopt = index(W_OPTNS, 'm') != NULL;
127:
128: DEBUG(4, "wrktype %c, ", wrktype);
129: if (wrktype == XUUCP) {
130: int n;
131: msg[0] = '\0';
132: for (n = 1; n < i; n++) {
133: strcat(msg, " ");
134: strcat(msg, wrkvec[n]);
135: }
136: sprintf(rqstr, "X %s", msg);
137: logent(rqstr, "REQUEST");
138: goto sendmsg;
139: }
140:
141: ASSERT(i > 4, "ARG COUNT - %d\n", i);
142: sprintf(msg, " %s %s %s %s %s %s",
143: W_FILE1, W_FILE2, W_USER,
144: W_OPTNS, W_DFILE, W_MODE);
145: strcpy(User, W_USER);
146: ASSERT(strlen(User) <= 10, "User - %s\n", User);
147: sprintf(rqstr, "%s %s %s %s", W_TYPE, W_FILE1,
148: W_FILE2, W_USER);
149: logent(rqstr, "REQUEST");
150: DEBUG(4, "User - %s\n", User);
151: if (wrktype == SNDFILE ) {
152: strcpy(filename, W_FILE1);
153: expfile(filename);
154: if (chkpth(User, "", filename) || anyread(filename)) {
155: /* access denied */
156: logent("DENIED", "ACCESS");
157: unlinkdf(W_DFILE);
158: lnotify(User, filename, "access denied");
159: goto top;
160: }
161:
162: strcpy(Dfile, W_DFILE);
163: fp = NULL;
164: if (index(W_OPTNS, 'c') == NULL)
165: fp = fopen(Dfile, "r");
166: if (fp == NULL &&
167: (fp = fopen(filename, "r")) == NULL) {
168: /* can not read data file */
169: logent("CAN'T READ DATA", "FAILED");
170: unlinkdf(Dfile);
171: lnotify(User, filename, "can't access");
172: goto top;
173: }
174: }
175:
176: if (wrktype == RCVFILE) {
177: strcpy(filename, W_FILE2);
178: expfile(filename);
179: if (chkpth(User, "", filename)
180: || chkperm(filename, User, index(W_OPTNS, 'd'))) {
181: /* access denied */
182: logent("DENIED", "ACCESS");
183: lnotify(User, filename, "access denied");
184: goto top;
185: }
186: sprintf(Dfile, "%s/TM.%05d.%03d", Spool, pnum, tmpnum++);
187: if ((fp = fopen(Dfile, "w")) == NULL) {
188: /* can not create temp */
189: logent("CAN'T CREATE TM", "FAILED");
190: unlinkdf(Dfile);
191: goto top;
192: }
193: chmod(Dfile, 0666);
194: }
195: sendmsg:
196: DEBUG(4, "wrktype - %c, ", wrktype);
197: DEBUG(4, " fileno - %d\n", fileno(fp));
198: WMESG(wrktype, msg);
199: RMESG(wrktype, msg);
200: goto process;
201: }
202:
203: /* role is slave */
204: RAMESG(msg);
205: goto process;
206:
207: process:
208: ultouch(); /* touch all lock files */
209: DEBUG(4, " PROCESS: msg - %s\n", msg);
210: switch (msg[0]) {
211:
212: case RQSTCMPT:
213: DEBUG(4, "%s\n", "RQSTCMPT:");
214: logent(msg, "REQUESTED");
215: if (role == MASTER) {
216: notify(mailopt, W_USER, W_FILE1, Rmtname, &msg[1]);
217: }
218: goto top;
219:
220: case HUP:
221: DEBUG(4, "%s\n", "HUP:");
222: if (msg[1] == 'Y') {
223: WMESG(HUP, YES);
224: (*Turnoff)();
225: Rdmsg = imsg;
226: Wrmsg = omsg;
227: return(0);
228: }
229:
230: if (msg[1] == 'N') {
231: ASSERT(role == MASTER,
232: "role - %d", role);
233: role = SLAVE;
234: goto top;
235: }
236:
237: /* get work */
238: if (!iswrk(Wfile, "chk", Spool, wkpre)) {
239: WMESG(HUP, YES);
240: RMESG(HUP, msg);
241: goto process;
242: }
243:
244: WMESG(HUP, NO);
245: role = MASTER;
246: goto top;
247:
248: case XUUCP:
249: if (role == MASTER) {
250: goto top;
251: }
252:
253: /* slave part */
254: i = getargs(msg, wrkvec);
255: strcpy(filename, W_FILE1);
256: if (index(filename, ';') != NULL
257: || index(W_FILE2, ';') != NULL
258: || i < 3) {
259: WMESG(XUUCP, NO);
260: goto top;
261: }
262: expfile(filename);
263: if (chkpth("", Rmtname, filename)) {
264: WMESG(XUUCP, NO);
265: logent("XUUCP DENIED", filename);
266: goto top;
267: }
268: sprintf(rqstr, "%s %s", filename, W_FILE2);
269: xuucp(rqstr);
270: WMESG(XUUCP, YES);
271: goto top;
272:
273: case SNDFILE:
274: /* MASTER section of SNDFILE */
275:
276: DEBUG(4, "%s\n", "SNDFILE:");
277: if (msg[1] == 'N') {
278: i = atoi(&msg[2]);
279: if (i < 0 || i > EM_MAX)
280: i = 0;
281: logent(Em_msg[i], "REQUEST");
282: notify(mailopt, W_USER, W_FILE1, Rmtname, &msg[1]);
283: ASSERT(role == MASTER,
284: "role - %d", role);
285: fclose(fp);
286: unlinkdf(W_DFILE);
287: goto top;
288: }
289:
290: if (msg[1] == 'Y') {
291: /* send file */
292: ASSERT(role == MASTER,
293: "role - %d", role);
294: ret = (*Wrdata)(fp, Ofn);
295: fclose(fp);
296: if (ret != 0) {
297: (*Turnoff)();
298: return(FAIL);
299: }
300: unlinkdf(W_DFILE);
301: RMESG(RQSTCMPT, msg);
302: goto process;
303: }
304:
305: /* SLAVE section of SNDFILE */
306: ASSERT(role == SLAVE,
307: "role - %d", role);
308:
309: /* request to receive file */
310: /* check permissions */
311: i = getargs(msg, wrkvec);
312: ASSERT(i > 4, "ARG COUNT - %d\n", i);
313: sprintf(rqstr, "%s %s %s %s", W_TYPE, W_FILE1,
314: W_FILE2, W_USER);
315: logent(rqstr, "REQUESTED");
316: DEBUG(4, "msg - %s\n", msg);
317: DEBUG(4, "W_FILE2 - %s\n", W_FILE2);
318: strcpy(filename, W_FILE2);
319: expfile(filename);
320: if (chkpth("", Rmtname, filename)
321: || chkperm(filename, Loginuser, index(W_OPTNS, 'd'))) {
322: WMESG(SNDFILE, EM_RMTACC);
323: logent("DENIED", "PERMISSION");
324: goto top;
325: }
326: if (isdir(filename)) {
327: strcat(filename, "/");
328: strcat(filename, lastpart(W_FILE1));
329: }
330: strcpy(User, W_USER);
331: ASSERT(strlen(User) <= 10, "User - %s\n", User);
332:
333: DEBUG(4, "chkpth ok Rmtname - %s\n", Rmtname);
334: sprintf(Dfile, "%s/TM.%05d.%03d", Spool, pnum, tmpnum++);
335: if((fp = fopen(Dfile, "w")) == NULL) {
336: WMESG(SNDFILE, EM_NOTMP);
337: logent("CAN'T OPEN", "DENIED");
338: unlinkdf(Dfile);
339: goto top;
340: }
341: chmod(Dfile, 0666);
342:
343: WMESG(SNDFILE, YES);
344: ret = (*Rddata)(Ifn, fp);
345: fclose(fp);
346: if (ret != 0) {
347: (*Turnoff)();
348: return(FAIL);
349: }
350: /* copy to user directory */
351: status = xmv(Dfile, filename);
352: WMESG(RQSTCMPT, status ? EM_RMTCP : YES);
353: logent(status ? "FAILED" : "SUCCEEDED", "COPY");
354: if (status == 0) {
355: sscanf(W_MODE, "%o", &filemode);
356: DEBUG(4, "mode - %o\n", filemode);
357: if (filemode <= 0)
358: filemode = 0666;
359: chmod(filename, filemode | 0666);
360: }
361: else {
362: putinpub(filename, Dfile, W_USER);
363: }
364:
365: goto top;
366:
367: case RCVFILE:
368: /* MASTER section of RCVFILE */
369:
370: DEBUG(4, "%s\n", "RCVFILE:");
371: if (msg[1] == 'N') {
372: i = atoi(&msg[2]);
373: if (i < 0 || i > EM_MAX)
374: i = 0;
375: logent(Em_msg[i], "REQUEST");
376: notify(mailopt, W_USER, W_FILE1, Rmtname, &msg[1]);
377: ASSERT(role == MASTER,
378: "role - %d", role);
379: fclose(fp);
380: goto top;
381: }
382:
383: if (msg[1] == 'Y') {
384: /* receive file */
385: ASSERT(role == MASTER,
386: "role - %d", role);
387: ret = (*Rddata)(Ifn, fp);
388: fclose(fp);
389: if (ret != 0) {
390: (*Turnoff)();
391: return(FAIL);
392: }
393: /* copy to user directory */
394: if (isdir(filename)) {
395: strcat(filename, "/");
396: strcat(filename, lastpart(W_FILE1));
397: }
398: status = xmv(Dfile, filename);
399: WMESG(RQSTCMPT, status ? EM_RMTCP : YES);
400: logent(status ? "FAILED" : "SUCCEEDED", "COPY");
401: notify(mailopt, W_USER, filename, Rmtname,
402: status ? EM_LOCCP : YES);
403: if (status == 0) {
404: sscanf(&msg[2], "%o", &filemode);
405: DEBUG(4, "mode - %o\n", filemode);
406: if (filemode <= 0)
407: filemode = 0666;
408: chmod(filename, filemode | 0666);
409: }
410: else {
411: putinpub(filename, Dfile, W_USER);
412: }
413: goto top;
414: }
415:
416: /* SLAVE section of RCVFILE */
417: ASSERT(role == SLAVE,
418: "role - %d", role);
419:
420: /* request to send file */
421: strcpy(rqstr, msg);
422: logent(rqstr, "REQUESTED");
423:
424: /* check permissions */
425: i = getargs(msg, wrkvec);
426: ASSERT(i > 3, "ARG COUNT - %d\n", i);
427: DEBUG(4, "msg - %s\n", msg);
428: DEBUG(4, "W_FILE1 - %s\n", W_FILE1);
429: strcpy(filename, W_FILE1);
430: expfile(filename);
431: if (isdir(filename)) {
432: strcat(filename, "/");
433: strcat(filename, lastpart(W_FILE2));
434: }
435: strcpy(User, W_USER);
436: ASSERT(strlen(User) <= 10, "User - %s\n", User);
437: if (chkpth("", Rmtname, filename) || anyread(filename)) {
438: WMESG(RCVFILE, EM_RMTACC);
439: logent("DENIED", "PERMISSION");
440: goto top;
441: }
442: DEBUG(4, "chkpth ok Rmtname - %s\n", Rmtname);
443:
444: if ((fp = fopen(filename, "r")) == NULL) {
445: WMESG(RCVFILE, EM_RMTACC);
446: logent("CAN'T OPEN", "DENIED");
447: goto top;
448: }
449:
450: /* ok to send file */
451: ret = stat(filename, &stbuf);
452: ASSERT(ret != -1, "STAT FAILED %s", filename);
453: sprintf(msg, "%s %o", YES, stbuf.st_mode & 0777);
454: WMESG(RCVFILE, msg);
455: ret = (*Wrdata)(fp, Ofn);
456: fclose(fp);
457: if (ret != 0) {
458: (*Turnoff)();
459: return(FAIL);
460: }
461: RMESG(RQSTCMPT, msg);
462: goto process;
463: }
464: (*Turnoff)();
465: return(FAIL);
466: }
467:
468:
469: /***
470: * rmesg(c, msg) read message 'c'
471: * char *msg, c;
472: *
473: * return code: 0 | FAIL
474: */
475:
476: rmesg(c, msg)
477: char *msg, c;
478: {
479: char str[50];
480:
481: DEBUG(4, "rmesg - '%c' ", c);
482: if ((*Rdmsg)(msg, Ifn) != 0) {
483: DEBUG(4, "got %s\n", "FAIL");
484: sprintf(str, "expected '%c' got FAIL", c);
485: logent(str, "BAD READ");
486: return(FAIL);
487: }
488: if (c != '\0' && msg[0] != c) {
489: DEBUG(4, "got %s\n", msg);
490: sprintf(str, "expected '%c' got %.25s", c, msg);
491: logent(str, "BAD READ");
492: return(FAIL);
493: }
494: DEBUG(4, "got %.25s\n", msg);
495: return(0);
496: }
497:
498:
499: /***
500: * wmesg(m, s) write a message (type m)
501: * char *s, m;
502: *
503: * return codes: 0 - ok | FAIL - ng
504: */
505:
506: wmesg(m, s)
507: char *s, m;
508: {
509: DEBUG(4, "wmesg '%c'", m);
510: DEBUG(4, "%.25s\n", s);
511: return((*Wrmsg)(m, s, Ofn));
512: }
513:
514:
515: /***
516: * notify mail results of command
517: *
518: * return codes: none
519: */
520:
521: notify(mailopt, user, file, sys, msgcode)
522: char *user, *file, *sys, *msgcode;
523: {
524: char str[200];
525: int i;
526: char *msg;
527:
528: if (!mailopt && *msgcode == 'Y')
529: return;
530: if (*msgcode == 'Y')
531: msg = "copy succeeded";
532: else {
533: i = atoi(msgcode + 1);
534: if (i < 1 || i > EM_MAX)
535: i = 0;
536: msg = Em_msg[i];
537: }
538: sprintf(str, "file %s, system %s\n%s\n",
539: file, sys, msg);
540: mailst(user, str);
541: return;
542: }
543:
544: /***
545: * lnotify(user, file, mesg) - local notify
546: *
547: * return code - none
548: */
549:
550: lnotify(user, file, mesg)
551: char *user, *file, *mesg;
552: {
553: char mbuf[200];
554: sprintf(mbuf, "file %s on %s\n%s\n", file, Myname, mesg);
555: mailst(user, mbuf);
556: return;
557: }
558:
559:
560: /***
561: * startup(role)
562: * int role;
563: *
564: * startup - this routine will converse with the remote
565: * machine, agree upon a protocol (if possible) and start the
566: * protocol.
567: *
568: * return codes:
569: * SUCCESS - successful protocol selection
570: * FAIL - can't find common or open failed
571: */
572:
573: startup(role)
574: int role;
575: {
576: extern (*Rdmsg)(), (*Wrmsg)();
577: extern imsg(), omsg();
578: extern char *blptcl(), fptcl();
579: char msg[BUFSIZ], str[BUFSIZ];
580:
581: Rdmsg = imsg;
582: Wrmsg = omsg;
583: if (role == MASTER) {
584: RMESG(SLTPTCL, msg);
585: if ((str[0] = fptcl(&msg[1])) == NULL) {
586: /* no protocol match */
587: WMESG(USEPTCL, NO);
588: return(FAIL);
589: }
590: str[1] = '\0';
591: WMESG(USEPTCL, str);
592: if (stptcl(str) != 0)
593: return(FAIL);
594: DEBUG(4, "protocol %s\n", str);
595: return(SUCCESS);
596: }
597: else {
598: WMESG(SLTPTCL, blptcl(str));
599: RMESG(USEPTCL, msg);
600: if (msg[1] == 'N') {
601: return(FAIL);
602: }
603:
604: if (stptcl(&msg[1]) != 0)
605: return(FAIL);
606: DEBUG(4, "Protocol %s\n", msg);
607: return(SUCCESS);
608: }
609: }
610:
611:
612: /*******
613: * char
614: * fptcl(str)
615: * char *str;
616: *
617: * fptcl - this routine will choose a protocol from
618: * the input string (str) and return the found letter.
619: *
620: * return codes:
621: * '\0' - no acceptable protocol
622: * any character - the chosen protocol
623: */
624:
625: char
626: fptcl(str)
627: char *str;
628: {
629: struct Proto *p;
630: extern char *index();
631:
632: for (p = Ptbl; p->P_id != '\0'; p++) {
633: if (index(str, p->P_id) != NULL) {
634: return(p->P_id);
635: }
636: }
637:
638: return('\0');
639: }
640:
641:
642: /***
643: * char *
644: * blptcl(str)
645: * char *str;
646: *
647: * blptcl - this will build a string of the
648: * letters of the available protocols and return
649: * the string (str).
650: *
651: * return:
652: * a pointer to string (str)
653: */
654:
655: char *
656: blptcl(str)
657: char *str;
658: {
659: struct Proto *p;
660: char *s;
661:
662: for (p = Ptbl, s = str; (*s++ = p->P_id) != '\0'; p++);
663: return(str);
664: }
665:
666: /***
667: * stptcl(c)
668: * char *c;
669: *
670: * stptcl - this routine will set up the six routines
671: * (Rdmsg, Wrmsg, Rddata, Wrdata, Turnon, Turnoff) for the
672: * desired protocol.
673: *
674: * return codes:
675: * SUCCESS - ok
676: * FAIL - no find or failed to open
677: *
678: */
679:
680: stptcl(c)
681: char *c;
682: {
683: struct Proto *p;
684:
685: for (p = Ptbl; p->P_id != '\0'; p++) {
686: if (*c == p->P_id) {
687: /* found protocol - set routines */
688: Rdmsg = p->P_rdmsg;
689: Wrmsg = p->P_wrmsg;
690: Rddata = p->P_rddata;
691: Wrdata = p->P_wrdata;
692: Turnon = p->P_turnon;
693: Turnoff = p->P_turnoff;
694: if ((*Turnon)() != 0)
695: return(FAIL);
696: DEBUG(4, "Proto started %c\n", *c);
697: return(SUCCESS);
698: }
699: }
700: DEBUG(4, "Proto start-fail %c\n", *c);
701: return(FAIL);
702: }
703:
704: /***
705: * putinpub put file in public place
706: *
707: * return code 0 | FAIL
708: */
709:
710: putinpub(file, tmp, user)
711: char *file, *user, *tmp;
712: {
713: char fullname[MAXFULLNAME];
714: char *lastpart();
715:
716: sprintf(fullname, "%s/%s/", PUBDIR, user);
717: if (mkdirs(fullname) != 0) {
718: /* can not make directories */
719: return(FAIL);
720: }
721: strcat(fullname, lastpart(file));
722: xmv(tmp, fullname);
723: return(0);
724: }
725:
726: /***
727: * unlinkdf(file) - unlink D. file
728: *
729: * return code - none
730: */
731:
732: unlinkdf(file)
733: char *file;
734: {
735: if (strlen(file) > 6)
736: unlink(file);
737: return;
738: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.