home *** CD-ROM | disk | FTP | other *** search
- #include "uucp.h"
- #include <sys/types.h>
- #include <sys/stat.h>
-
-
- struct Proto {
- char P_id;
- int (*P_turnon)();
- int (*P_rdmsg)();
- int (*P_wrmsg)();
- int (*P_rddata)();
- int (*P_wrdata)();
- int (*P_turnoff)();
- };
-
-
- extern int gturnon(), gturnoff();
- extern int grdmsg(), grddata();
- extern int gwrmsg(), gwrdata();
- extern int imsg();
- extern int omsg();
-
- struct Proto Ptbl[]={
- 'g', gturnon, grdmsg, gwrmsg, grddata, gwrdata, gturnoff,
- '\0'
- };
-
- int (*Rdmsg)()=imsg, (*Rddata)();
- int (*Wrmsg)()=omsg, (*Wrdata)();
- int (*Turnon)(), (*Turnoff)();
-
-
- #define YES "Y"
- #define NO "N"
- #define Y 'Y'
- #define N 'N'
-
-
- #define XUUCP 'X' /* execute uucp (string) */
- #define SLTPTCL 'P' /* select protocol (string) */
- #define USEPTCL 'U' /* use protocol (character) */
- #define RCVFILE 'R' /* receive file (string) */
- #define SNDFILE 'S' /* send file (string) */
- #define RQSTCMPT 'C' /* request complete (string - yes | no) */
- #define HUP 'H' /* ready to hangup (string - yes | no) */
-
-
- #define W_TYPE wrkvec[0]
- #define W_FILE1 wrkvec[1]
- #define W_FILE2 wrkvec[2]
- #define W_USER wrkvec[3]
- #define W_OPTNS wrkvec[4]
- #define W_DFILE wrkvec[5]
- #define W_MODE wrkvec[6]
-
- #define RMESG(m, s) if (rmesg(m, s) != 0) return(FAIL);
- #define RAMESG(s) if (rmesg('\0', s) != 0) return(FAIL)
- #define WMESG(m, s) if(wmesg(m, s) != 0) return(FAIL)
-
- char Wfile[MAXFULLNAME] = {'\0'};
- char Dfile[MAXFULLNAME];
-
- /*******
- * cntrl(role, wkpre)
- * int role;
- * char *wkpre;
- *
- * cntrl - this routine will execute the conversation
- * between the two machines after both programs are
- * running.
- *
- * return codes
- * SUCCESS - ok
- * FAIL - failed
- */
-
- cntrl(role, wkpre)
- int role;
- char *wkpre;
- {
- char msg[BUFSIZ], rqstr[BUFSIZ];
- FILE *fp;
- int filemode;
- struct stat stbuf;
- char filename[MAXFULLNAME], wrktype, *wrkvec[20];
- extern (*Rdmsg)(), (*Wrmsg)();
- extern char *index(), *lastpart();
- int status = 1, i;
- int ret;
- static int pnum, tmpnum = 0;
-
- pnum = getpid();
- top:
- DEBUG(4, "*** TOP *** - role=%d, ", role);
- if (role == MASTER) {
- /* get work */
- if ((i = gtwvec(Wfile, Spool, wkpre, wrkvec)) == 0) {
- WMESG(HUP, "");
- RMESG(HUP, msg);
- goto process;
- }
- wrktype = W_TYPE[0];
-
- DEBUG(4, "wrktype %c, ", wrktype);
- if (wrktype == XUUCP) {
- int n;
- msg[0] = '\0';
- for (n = 1; n < i; n++) {
- strcat(msg, " ");
- strcat(msg, wrkvec[n]);
- }
- sprintf(rqstr, "X %s", msg);
- logent(rqstr, "REQUEST");
- goto sendmsg;
- }
-
- ASSERT(i > 4, "ARG COUNT - %d\n", i);
- sprintf(msg, " %s %s %s %s %s %s",
- W_FILE1, W_FILE2, W_USER,
- W_OPTNS, W_DFILE, W_MODE);
- strcpy(User, W_USER);
- ASSERT(strlen(User) <= 10, "User - %s\n", User);
- sprintf(rqstr, "%s %s %s %s", W_TYPE, W_FILE1,
- W_FILE2, W_USER);
- logent(rqstr, "REQUEST");
- DEBUG(4, "User - %s\n", User);
- if (wrktype == SNDFILE ) {
- strcpy(filename, W_FILE1);
- expfile(filename);
- if (chkpth(User, "", filename)) {
- /* access denied */
- logent("DENIED", "ACCESS");
- unlink(W_DFILE);
- unlink(Wfile);
- goto top;
- }
-
- strcpy(Dfile, W_DFILE);
- if ((fp = fopen(Dfile, "r")) == NULL
- && (fp = fopen(filename, "r")) == NULL) {
- /* can not read data file */
- logent("CAN'T READ DATA", "FAILED");
- unlink(Wfile);
- unlink(Dfile);
- goto top;
- }
- }
-
- if (wrktype == RCVFILE) {
- strcpy(filename, W_FILE2);
- expfile(filename);
- if (chkpth(User, "", filename)
- || chkperm(filename, User, index(W_OPTNS, 'd'))) {
- /* access denied */
- logent("DENIED", "ACCESS");
- unlink(Wfile);
- goto top;
- }
- sprintf(Dfile, "%s/TM.%05d.%03d", Spool, pnum, tmpnum++);
- if ((fp = fopen(Dfile, "w")) == NULL) {
- /* can not create temp */
- logent("CAN'T CREATE TM", "FAILED");
- unlink(Wfile);
- unlink(Dfile);
- goto top;
- }
- chmod(Dfile, 0666);
- }
- sendmsg:
- DEBUG(4, "wrktype - %c, ", wrktype);
- DEBUG(4, " fileno - %d\n", fileno(fp));
- WMESG(wrktype, msg);
- RMESG(wrktype, msg);
- goto process;
- }
-
- /* role is slave */
- RAMESG(msg);
- goto process;
-
- process:
- DEBUG(4, " PROCESS: msg - %s\n", msg);
- switch (msg[0]) {
-
- case RQSTCMPT:
- DEBUG(4, "%s\n", "RQSTCMPT:");
- logent((msg[1] == 'N') ? "FAILED" : "SUCCEEDED", "REQUEST");
- if (role == MASTER) {
- notify(W_OPTNS, W_USER, W_FILE1, Rmtname,
- (msg[1] == N) ? "failed" : "succeeded");
- }
- goto top;
-
- case HUP:
- DEBUG(4, "%s\n", "HUP:");
- if (msg[1] == Y) {
- WMESG(HUP, YES);
- (*Turnoff)();
- Rdmsg = imsg;
- Wrmsg = omsg;
- return(0);
- }
-
- if (msg[1] == N) {
- ASSERT(role == MASTER,
- "role - %d", role);
- role = SLAVE;
- goto top;
- }
-
- /* get work */
- if (!iswrk(Wfile, "chk", Spool, wkpre)) {
- WMESG(HUP, YES);
- RMESG(HUP, msg);
- goto process;
- }
-
- WMESG(HUP, NO);
- role = MASTER;
- goto top;
-
- case XUUCP:
- if (role == MASTER) {
- unlink(Wfile);
- goto top;
- }
-
- /* slave part */
- i = getargs(msg, wrkvec);
- strcpy(filename, W_FILE1);
- if (index(filename, ';') != NULL
- || index(W_FILE2, ';') != NULL
- || i < 3) {
- WMESG(XUUCP, NO);
- goto top;
- }
- expfile(filename);
- if (chkpth("", Rmtname, filename)) {
- WMESG(XUUCP, NO);
- logent("XUUCP DENIED", filename);
- goto top;
- }
- sprintf(rqstr, "%s %s", filename, W_FILE2);
- xuucp(rqstr);
- WMESG(XUUCP, YES);
- goto top;
-
- case SNDFILE:
- /* MASTER section of SNDFILE */
-
- DEBUG(4, "%s\n", "SNDFILE:");
- if (msg[1] == N) {
- logent("DENIED", "REQUEST");
- ASSERT(role == MASTER,
- "role - %d", role);
- fclose(fp);
- unlink(W_DFILE);
- unlink(Wfile);
- goto top;
- }
-
- if (msg[1] == Y) {
- /* send file */
- ASSERT(role == MASTER,
- "role - %d", role);
- ret = (*Wrdata)(fp, Ofn);
- fclose(fp);
- if (ret != 0)
- return(FAIL);
- unlink(W_DFILE);
- RMESG(RQSTCMPT, msg);
- goto process;
- }
-
- /* SLAVE section of SNDFILE */
- ASSERT(role == SLAVE,
- "role - %d", role);
-
- /* request to receive file */
- /* check permissions */
- i = getargs(msg, wrkvec);
- ASSERT(i > 4, "ARG COUNT - %d\n", i);
- sprintf(rqstr, "%s %s %s %s", W_TYPE, W_FILE1,
- W_FILE2, W_USER);
- logent(rqstr, "REQUESTED");
- DEBUG(4, "msg - %s\n", msg);
- DEBUG(4, "W_FILE2 - %s\n", W_FILE2);
- strcpy(filename, W_FILE2);
- expfile(filename);
- if (chkpth("", Rmtname, filename)
- || chkperm(filename, Loginuser, index(W_OPTNS, 'd'))) {
- WMESG(SNDFILE, NO);
- logent("DENIED", "PERMISSION");
- goto top;
- }
- if (isdir(filename)) {
- strcat(filename, "/");
- strcat(filename, lastpart(W_FILE1));
- }
- strcpy(User, W_USER);
- ASSERT(strlen(User) <= 10, "User - %s\n", User);
-
- DEBUG(4, "chkpth ok Rmtname - %s\n", Rmtname);
- sprintf(Dfile, "%s/TM.%05d.%03d", Spool, pnum, tmpnum++);
- if((fp = fopen(Dfile, "w")) == NULL) {
- WMESG(SNDFILE, NO);
- logent("CAN'T OPEN", "DENIED");
- unlink(Dfile);
- goto top;
- }
- chmod(Dfile, 0666);
-
- WMESG(SNDFILE, YES);
- ret = (*Rddata)(Ifn, fp);
- fclose(fp);
- if (ret != 0)
- return(FAIL);
- /* copy to user directory */
- status = xmv(Dfile, filename);
- WMESG(RQSTCMPT, status ? NO : YES);
- logent(status ? "FAILED" : "SUCCEEDED", "COPY");
- sscanf(W_MODE, "%o", &filemode);
- DEBUG(4, "mode - %o\n", filemode);
- if (filemode <= 0)
- filemode = 0666;
- if (status == 0) {
- filemode |= 0666;
- chmod(filename, filemode | 0666);
- }
- goto top;
-
- case RCVFILE:
- /* MASTER section of RCVFILE */
-
- DEBUG(4, "%s\n", "RCVFILE:");
- if (msg[1] == N) {
- logent("REQUEST", "DENIED");
- ASSERT(role == MASTER,
- "role - %d", role);
- unlink(Wfile);
- fclose(fp);
- goto top;
- }
-
- if (msg[1] == Y) {
- /* receive file */
- ASSERT(role == MASTER,
- "role - %d", role);
- ret = (*Rddata)(Ifn, fp);
- fclose(fp);
- if (ret != 0)
- return(FAIL);
- /* copy to user directory */
- if (isdir(filename)) {
- strcat(filename, "/");
- strcat(filename, lastpart(W_FILE1));
- }
- status = xmv(Dfile, filename);
- WMESG(RQSTCMPT, status ? NO : YES);
- logent(status ? "FAILED" : "SUCCEEDED", "COPY");
- notify(W_OPTNS, W_USER, filename, Rmtname,
- status ? "failed" : "succeeded");
- sscanf(&msg[2], "%o", &filemode);
- DEBUG(4, "mode - %o\n", filemode);
- if (filemode <= 0)
- filemode = 0666;
- if (status == 0) {
- unlink(Dfile);
- filemode |= 0666;
- chmod(filename, filemode | 0666);
- }
- goto top;
- }
-
- /* SLAVE section of RCVFILE */
- ASSERT(role == SLAVE,
- "role - %d", role);
-
- /* request to send file */
- strcpy(rqstr, msg);
- logent(rqstr, "REQUESTED");
-
- /* check permissions */
- i = getargs(msg, wrkvec);
- ASSERT(i > 3, "ARG COUNT - %d\n", i);
- DEBUG(4, "msg - %s\n", msg);
- DEBUG(4, "W_FILE1 - %s\n", W_FILE1);
- strcpy(filename, W_FILE1);
- expfile(filename);
- if (isdir(filename)) {
- strcat(filename, "/");
- strcat(filename, lastpart(W_FILE2));
- }
- strcpy(User, W_USER);
- ASSERT(strlen(User) <= 10, "User - %s\n", User);
- if (chkpth("", Rmtname, filename) != 0) {
- WMESG(RCVFILE, NO);
- logent("DENIED", "PERMISSION");
- goto top;
- }
- DEBUG(4, "chkpth ok Rmtname - %s\n", Rmtname);
-
- if ((fp = fopen(filename, "r")) == NULL) {
- WMESG(RCVFILE, NO);
- logent("CAN'T OPEN", "DENIED");
- goto top;
- }
-
- /* ok to send file */
- ret = stat(filename, &stbuf);
- ASSERT(ret != -1, "STAT FAILED %s", filename);
- sprintf(msg, "%s %o", YES, stbuf.st_mode & 0777);
- WMESG(RCVFILE, msg);
- ret = (*Wrdata)(fp, Ofn);
- fclose(fp);
- if (ret != 0)
- return(FAIL);
- RMESG(RQSTCMPT, msg);
- goto process;
- }
- return(FAIL);
- }
-
-
- /***
- * rmesg(c, msg) read message 'c'
- * char *msg, c;
- *
- * return code: 0 | FAIL
- */
-
- rmesg(c, msg)
- char *msg, c;
- {
- char str[50];
-
- DEBUG(4, "rmesg - '%c' ", c);
- if ((*Rdmsg)(msg, Ifn) != 0) {
- DEBUG(4, "got %s\n", "FAIL");
- sprintf(str, "expected '%c' got FAIL", c);
- logent(str, "BAD READ");
- return(FAIL);
- }
- if (c != '\0' && msg[0] != c) {
- DEBUG(4, "got %s\n", msg);
- sprintf(str, "expected '%c' got %.25s", c, msg);
- logent(str, "BAD READ");
- return(FAIL);
- }
- DEBUG(4, "got %.25s\n", msg);
- return(0);
- }
-
-
- /***
- * wmesg(m, s) write a message (type m)
- * char *s, m;
- *
- * return codes: 0 - ok | FAIL - ng
- */
-
- wmesg(m, s)
- char *s, m;
- {
- DEBUG(4, "wmesg '%c'", m);
- DEBUG(4, "%.25s\n", s);
- return((*Wrmsg)(m, s, Ofn));
- }
-
-
- /***
- * notify(options, user, file, sys, stwork) mail results of copy
- * char *options, *user, *file, *sys, *stword);
- *
- * return codes: none
- */
-
- notify(options, user, file, sys, stword)
- char *options, *user, *file, *sys, *stword;
- {
- char str[200];
- if (index(options, 'm') == NULL)
- return;
- sprintf(str, "file %s, system %s, copy %s\n", file, sys, stword);
- mailst(user, str);
- return;
- }
-
-
- /***
- * startup(role)
- * int role;
- *
- * startup - this routine will converse with the remote
- * machine, agree upon a protocol (if possible) and start the
- * protocol.
- *
- * return codes:
- * SUCCESS - successful protocol selection
- * FAIL - can't find common or open failed
- */
-
- startup(role)
- int role;
- {
- extern (*Rdmsg)(), (*Wrmsg)();
- extern imsg(), omsg();
- extern char *blptcl(), fptcl();
- char msg[BUFSIZ], str[BUFSIZ];
-
- Rdmsg = imsg;
- Wrmsg = omsg;
- if (role == MASTER) {
- RMESG(SLTPTCL, msg);
- if ((str[0] = fptcl(&msg[1])) == NULL) {
- /* no protocol match */
- WMESG(USEPTCL, NO);
- return(FAIL);
- }
- str[1] = '\0';
- WMESG(USEPTCL, str);
- if (stptcl(str) != 0)
- return(FAIL);
- DEBUG(4, "protocol %s\n", str);
- return(SUCCESS);
- }
- else {
- WMESG(SLTPTCL, blptcl(str));
- RMESG(USEPTCL, msg);
- if (msg[1] == N) {
- return(FAIL);
- }
-
- if (stptcl(&msg[1]) != 0)
- return(FAIL);
- DEBUG(4, "Protocol %s\n", msg);
- return(SUCCESS);
- }
- }
-
-
- /*******
- * char
- * fptcl(str)
- * char *str;
- *
- * fptcl - this routine will choose a protocol from
- * the input string (str) and return the found letter.
- *
- * return codes:
- * '\0' - no acceptable protocol
- * any character - the chosen protocol
- */
-
- char
- fptcl(str)
- char *str;
- {
- struct Proto *p;
- extern char *index();
-
- for (p = Ptbl; p->P_id != '\0'; p++) {
- if (index(str, p->P_id) != NULL) {
- return(p->P_id);
- }
- }
-
- return('\0');
- }
-
-
- /***
- * char *
- * blptcl(str)
- * char *str;
- *
- * blptcl - this will build a string of the
- * letters of the available protocols and return
- * the string (str).
- *
- * return:
- * a pointer to string (str)
- */
-
- char *
- blptcl(str)
- char *str;
- {
- struct Proto *p;
- char *s;
-
- for (p = Ptbl, s = str; (*s++ = p->P_id) != '\0'; p++);
- return(str);
- }
-
- /***
- * stptcl(c)
- * char *c;
- *
- * stptcl - this routine will set up the six routines
- * (Rdmsg, Wrmsg, Rddata, Wrdata, Turnon, Turnoff) for the
- * desired protocol.
- *
- * return codes:
- * SUCCESS - ok
- * FAIL - no find or failed to open
- *
- */
-
- stptcl(c)
- char *c;
- {
- struct Proto *p;
-
- for (p = Ptbl; p->P_id != '\0'; p++) {
- if (*c == p->P_id) {
- /* found protocol - set routines */
- Rdmsg = p->P_rdmsg;
- Wrmsg = p->P_wrmsg;
- Rddata = p->P_rddata;
- Wrdata = p->P_wrdata;
- Turnon = p->P_turnon;
- Turnoff = p->P_turnoff;
- if ((*Turnon)() != 0)
- return(FAIL);
- DEBUG(4, "Proto started %c\n", *c);
- return(SUCCESS);
- }
- }
- DEBUG(4, "Proto start-fail %c\n", *c);
- return(FAIL);
- }
-