113697Ssam #ifndef lint 2*18628Sralph static char sccsid[] = "@(#)uuxqt.c 5.5 (Berkeley) 04/10/85"; 313697Ssam #endif 413697Ssam 513697Ssam #include "uucp.h" 613697Ssam #include <sys/stat.h> 713697Ssam #ifdef NDIR 813697Ssam #include "ndir.h" 913697Ssam #else 1013702Ssam #include <sys/dir.h> 1113697Ssam #endif 1217846Sralph #include <signal.h> 1313697Ssam 14*18628Sralph #define BADCHARS "&^|(`\\<>;\"{}\n'" 15*18628Sralph #define RECHECKTIME 60*10 /* 10 minutes */ 1617870Sralph 1713697Ssam #define APPCMD(d) {\ 1813697Ssam char *p;\ 1917846Sralph for (p = d; *p != '\0';) *cmdp++ = *p++; *cmdp++ = ' '; *cmdp = '\0';} 2013697Ssam 2113697Ssam /* 2213697Ssam * uuxqt will execute commands set up by a uux command, 2313697Ssam * usually from a remote machine - set by uucp. 2413697Ssam */ 2513697Ssam 2613697Ssam #define NCMDS 50 2717846Sralph char *Cmds[NCMDS+1]; 2817846Sralph int Notify[NCMDS+1]; 2917846Sralph #define NT_YES 0 /* if should notify on execution */ 3017846Sralph #define NT_ERR 1 /* if should notify if non-zero exit status (-z equivalent) */ 3117846Sralph #define NT_NO 2 /* if should not notify ever (-n equivalent) */ 3213697Ssam 3317846Sralph extern int Nfiles; 34*18628Sralph char *strpbrk(); 3517846Sralph 36*18628Sralph int TransferSucceeded = 1; 3713697Ssam int notiok = 1; 3813697Ssam int nonzero = 0; 3913697Ssam 40*18628Sralph char PATH[MAXFULLNAME] = "PATH=/bin:/usr/bin:/usr/ucb"; 41*18628Sralph char Shell[MAXFULLNAME]; 42*18628Sralph char HOME[MAXFULLNAME]; 4317846Sralph 44*18628Sralph extern char **environ; 45*18628Sralph char *nenv[] = { 46*18628Sralph PATH, 47*18628Sralph Shell, 48*18628Sralph HOME, 49*18628Sralph 0 50*18628Sralph }; 5117846Sralph 5213697Ssam /* to remove restrictions from uuxqt 5313697Ssam * define ALLOK 1 5413697Ssam * 5513697Ssam * to add allowable commands, add to the file CMDFILE 5613697Ssam * A line of form "PATH=..." changes the search path 5713697Ssam */ 5813697Ssam main(argc, argv) 5913697Ssam char *argv[]; 6013697Ssam { 6113697Ssam char xcmd[MAXFULLNAME]; 6213697Ssam int argnok; 6317846Sralph int notiflg; 6417846Sralph char xfile[MAXFULLNAME], user[MAXFULLNAME], buf[BUFSIZ]; 6517846Sralph char lbuf[MAXFULLNAME]; 6613697Ssam char cfile[NAMESIZE], dfile[MAXFULLNAME]; 6713697Ssam char file[NAMESIZE]; 6813697Ssam char fin[MAXFULLNAME], sysout[NAMESIZE], fout[MAXFULLNAME]; 6913697Ssam register FILE *xfp, *fp; 7013697Ssam FILE *dfp; 7113697Ssam char path[MAXFULLNAME]; 7213697Ssam char cmd[BUFSIZ]; 7313697Ssam char *cmdp, prm[1000], *ptr; 7413697Ssam char *getprm(), *lastpart(); 7517846Sralph int uid, ret, ret2, badfiles; 7613697Ssam register int i; 7713697Ssam int stcico = 0; 78*18628Sralph time_t xstart, xnow; 7913697Ssam char retstat[30]; 80*18628Sralph char **ep; 8113697Ssam 8213697Ssam strcpy(Progname, "uuxqt"); 8313697Ssam uucpname(Myname); 8413697Ssam 8513697Ssam umask(WFMASK); 8613697Ssam Ofn = 1; 8713697Ssam Ifn = 0; 8813697Ssam while (argc>1 && argv[1][0] == '-') { 8913697Ssam switch(argv[1][1]){ 9013697Ssam case 'x': 9117846Sralph chkdebug(); 9213697Ssam Debug = atoi(&argv[1][2]); 9313697Ssam if (Debug <= 0) 9413697Ssam Debug = 1; 9513697Ssam break; 9613697Ssam default: 9713697Ssam fprintf(stderr, "unknown flag %s\n", argv[1]); 9813697Ssam break; 9913697Ssam } 10013697Ssam --argc; argv++; 10113697Ssam } 10213697Ssam 103*18628Sralph DEBUG(4, "\n\n** START **\n", CNULL); 10417846Sralph ret = subchdir(Spool); 10517846Sralph ASSERT(ret >= 0, "CHDIR FAILED", Spool, ret); 10613697Ssam strcpy(Wrkdir, Spool); 10713697Ssam uid = getuid(); 10813697Ssam guinfo(uid, User, path); 10917846Sralph setgid(getegid()); 11017846Sralph setuid(geteuid()); 11117846Sralph 11213697Ssam DEBUG(4, "User - %s\n", User); 11313697Ssam if (ulockf(X_LOCK, (time_t) X_LOCKTIME) != 0) 11413697Ssam exit(0); 11513697Ssam 11613697Ssam fp = fopen(CMDFILE, "r"); 11713697Ssam if (fp == NULL) { 11817846Sralph logent(CANTOPEN, CMDFILE); 11913697Ssam Cmds[0] = "rmail"; 12013697Ssam Cmds[1] = "rnews"; 12113697Ssam Cmds[2] = "ruusend"; 12213697Ssam Cmds[3] = NULL; 12313697Ssam goto doprocess; 12413697Ssam } 12513697Ssam DEBUG(5, "%s opened\n", CMDFILE); 12617846Sralph for (i=0; i<NCMDS && cfgets(xcmd, sizeof(xcmd), fp) != NULL; i++) { 12717846Sralph int j; 12817846Sralph /* strip trailing whitespace */ 12917846Sralph for (j = strlen(xcmd)-1; j >= 0; --j) 13017846Sralph if (xcmd[j] == '\n' || xcmd[j] == ' ' || xcmd[j] == '\t') 13117846Sralph xcmd[j] = '\0'; 13217846Sralph else 13317846Sralph break; 13417846Sralph /* look for imbedded whitespace */ 13517846Sralph for (; j >= 0; --j) 13617846Sralph if (xcmd[j] == '\n' || xcmd[j] == ' ' || xcmd[j] == '\t') 13717846Sralph break; 13817846Sralph /* skip this entry if it has embedded whitespace */ 13917846Sralph /* This defends against a bad PATH=, for example */ 14017846Sralph if (j >= 0) { 14117846Sralph logent(xcmd, "BAD WHITESPACE"); 14217846Sralph continue; 14317846Sralph } 14413697Ssam if (strncmp(xcmd, "PATH=", 5) == 0) { 14513697Ssam strcpy(PATH, xcmd); 14617846Sralph i--; /*kludge */ 14713697Ssam continue; 14813697Ssam } 14913697Ssam DEBUG(5, "xcmd = %s\n", xcmd); 15017846Sralph 15117846Sralph if ((ptr = index(xcmd, ',')) != NULL) { 15217846Sralph *ptr++ = '\0'; 15317846Sralph if (strncmp(ptr, "Err", 3) == SAME) 15417846Sralph Notify[i] = NT_ERR; 15517846Sralph else if (strcmp(ptr, "No") == SAME) 15617846Sralph Notify[i] = NT_NO; 15717846Sralph else 15817846Sralph Notify[i] = NT_YES; 15917846Sralph } else 16017846Sralph Notify[i] = NT_YES; 16117846Sralph if ((Cmds[i] = malloc((unsigned)(strlen(xcmd)+1))) == NULL) { 16217846Sralph DEBUG(1, "MALLOC FAILED", CNULL); 16317846Sralph break; 16417846Sralph } 16513697Ssam strcpy(Cmds[i], xcmd); 16613697Ssam } 16717846Sralph Cmds[i] = CNULL; 16813697Ssam fclose(fp); 16913697Ssam 17013697Ssam doprocess: 171*18628Sralph 172*18628Sralph (void) sprintf(HOME, "HOME=%s", Spool); 173*18628Sralph (void) sprintf(Shell, "SHELL=%s", SHELL); 174*18628Sralph environ = nenv; /* force use if our environment */ 175*18628Sralph 176*18628Sralph DEBUG(11,"path = %s\n", getenv("PATH")); 177*18628Sralph 17817846Sralph DEBUG(4, "process %s\n", CNULL); 179*18628Sralph time(&xstart); 18013697Ssam while (gtxfile(xfile) > 0) { 18117846Sralph ultouch(); 18217846Sralph /* if /etc/nologin exists, exit cleanly */ 18317846Sralph if (nologinflag) { 18417846Sralph logent(NOLOGIN, "UUXQT SHUTDOWN"); 18517846Sralph if (Debug) 18617846Sralph logent("debugging", "continuing anyway"); 18717846Sralph else 18817846Sralph break; 18917846Sralph } 19013697Ssam DEBUG(4, "xfile - %s\n", xfile); 19113697Ssam 19213697Ssam xfp = fopen(subfile(xfile), "r"); 19317846Sralph ASSERT(xfp != NULL, CANTOPEN, xfile, 0); 19413697Ssam 19513697Ssam /* initialize to default */ 19613697Ssam strcpy(user, User); 19717846Sralph strcpy(fin, DEVNULL); 19817846Sralph strcpy(fout, DEVNULL); 19913697Ssam sprintf(sysout, "%.7s", Myname); 20017846Sralph badfiles = 0; 20113697Ssam while (fgets(buf, BUFSIZ, xfp) != NULL) { 20213697Ssam switch (buf[0]) { 20313697Ssam case X_USER: 20417846Sralph sscanf(&buf[1], "%s %s", user, Rmtname); 20513697Ssam break; 20617846Sralph case X_RETURNTO: 20717846Sralph sscanf(&buf[1], "%s", user); 20817846Sralph break; 20913697Ssam case X_STDIN: 21013697Ssam sscanf(&buf[1], "%s", fin); 21113697Ssam i = expfile(fin); 21213697Ssam /* rti!trt: do not check permissions of 21313697Ssam * vanilla spool file */ 21413697Ssam if (i != 0 21513697Ssam && (chkpth("", "", fin) || anyread(fin) != 0)) 21613697Ssam badfiles = 1; 21713697Ssam break; 21813697Ssam case X_STDOUT: 21913697Ssam sscanf(&buf[1], "%s%s", fout, sysout); 22013697Ssam sysout[7] = '\0'; 22113697Ssam /* rti!trt: do not check permissions of 22213697Ssam * vanilla spool file. DO check permissions 22313697Ssam * of writing on a non-vanilla file */ 22413697Ssam i = 1; 22513697Ssam if (fout[0] != '~' || prefix(sysout, Myname)) 22613697Ssam i = expfile(fout); 22713697Ssam if (i != 0 22813697Ssam && (chkpth("", "", fout) 22913697Ssam || chkperm(fout, (char *)1))) 23013697Ssam badfiles = 1; 23113697Ssam break; 23213697Ssam case X_CMD: 23313697Ssam strcpy(cmd, &buf[2]); 23413697Ssam if (*(cmd + strlen(cmd) - 1) == '\n') 23513697Ssam *(cmd + strlen(cmd) - 1) = '\0'; 23613697Ssam break; 23713697Ssam case X_NONOTI: 23813697Ssam notiok = 0; 23913697Ssam break; 24013697Ssam case X_NONZERO: 24113697Ssam nonzero = 1; 24213697Ssam break; 24313697Ssam default: 24413697Ssam break; 24513697Ssam } 24613697Ssam } 24713697Ssam 24813697Ssam fclose(xfp); 24913697Ssam DEBUG(4, "fin - %s, ", fin); 25013697Ssam DEBUG(4, "fout - %s, ", fout); 25113697Ssam DEBUG(4, "sysout - %s, ", sysout); 25213697Ssam DEBUG(4, "user - %s\n", user); 25313697Ssam DEBUG(4, "cmd - %s\n", cmd); 25413697Ssam 25513697Ssam /* command execution */ 25617846Sralph if (strcmp(fout, DEVNULL) == SAME) 25717846Sralph strcpy(dfile,DEVNULL); 25813697Ssam else 25913697Ssam gename(DATAPRE, sysout, 'O', dfile); 26013697Ssam 26113697Ssam /* expand file names where necessary */ 26213697Ssam expfile(dfile); 263*18628Sralph cmdp = buf; 26413697Ssam ptr = cmd; 26513697Ssam xcmd[0] = '\0'; 26613697Ssam argnok = 0; 26713697Ssam while ((ptr = getprm(ptr, prm)) != NULL) { 26813697Ssam if (prm[0] == ';' || prm[0] == '^' 26913697Ssam || prm[0] == '&' || prm[0] == '|') { 27013697Ssam xcmd[0] = '\0'; 27113697Ssam APPCMD(prm); 27213697Ssam continue; 27313697Ssam } 27413697Ssam 27517846Sralph if ((argnok = argok(xcmd, prm)) != SUCCESS) 27613697Ssam /* command not valid */ 27713697Ssam break; 27813697Ssam 27913697Ssam if (prm[0] == '~') 28013697Ssam expfile(prm); 28113697Ssam APPCMD(prm); 28213697Ssam } 28317846Sralph /* 28417846Sralph * clean up trailing ' ' in command. 28517846Sralph */ 28617846Sralph if (cmdp > buf && cmdp[0] == '\0' && cmdp[-1] == ' ') 28717846Sralph *--cmdp = '\0'; 288*18628Sralph if (strpbrk(user, BADCHARS) != NULL) { 28917870Sralph sprintf(lbuf, "%s INVALID CHARACTER IN USERNAME", user); 29017870Sralph logent(cmd, lbuf); 29117870Sralph strcpy(user, "postmaster"); 29217870Sralph } 29313697Ssam if (argnok || badfiles) { 29413697Ssam sprintf(lbuf, "%s XQT DENIED", user); 29513697Ssam logent(cmd, lbuf); 29613697Ssam DEBUG(4, "bad command %s\n", prm); 29713697Ssam notify(user, Rmtname, cmd, "DENIED"); 29813697Ssam goto rmfiles; 29913697Ssam } 30013697Ssam sprintf(lbuf, "%s XQT", user); 30113697Ssam logent(buf, lbuf); 30213697Ssam DEBUG(4, "cmd %s\n", buf); 30313697Ssam 30413697Ssam mvxfiles(xfile); 30517846Sralph ret = subchdir(XQTDIR); 30617846Sralph ASSERT(ret >= 0, "CHDIR FAILED", XQTDIR, ret); 307*18628Sralph ret = shio(buf, fin, dfile); 30813697Ssam sprintf(retstat, "signal %d, exit %d", ret & 0377, 30913697Ssam (ret>>8) & 0377); 31013697Ssam if (strcmp(xcmd, "rmail") == SAME) 31113697Ssam notiok = 0; 31213697Ssam if (strcmp(xcmd, "rnews") == SAME) 31313697Ssam nonzero = 1; 31417846Sralph notiflg = chknotify(xcmd); 31517846Sralph if (notiok && notiflg != NT_NO && 31617846Sralph (ret != 0 || (!nonzero && notiflg == NT_YES))) 31713697Ssam notify(user, Rmtname, cmd, retstat); 31813697Ssam else if (ret != 0 && strcmp(xcmd, "rmail") == SAME) { 31913697Ssam /* mail failed - return letter to sender */ 32017846Sralph #ifdef DANGEROUS 32117846Sralph /* NOT GUARANTEED SAFE!!! */ 32217846Sralph if (!nonzero) 32317846Sralph retosndr(user, Rmtname, fin); 32417846Sralph #else 32517846Sralph notify(user, Rmtname, cmd, retstat); 32617846Sralph #endif 32717846Sralph sprintf(buf, "%s (%s) from %s!%s", buf, retstat, Rmtname, user); 32813697Ssam logent("MAIL FAIL", buf); 32913697Ssam } 33013697Ssam DEBUG(4, "exit cmd - %d\n", ret); 33117846Sralph ret2 = subchdir(Spool); 33217846Sralph ASSERT(ret2 >= 0, "CHDIR FAILED", Spool, ret); 33313697Ssam rmxfiles(xfile); 33413697Ssam if (ret != 0) { 33513697Ssam /* exit status not zero */ 33613697Ssam dfp = fopen(subfile(dfile), "a"); 33717846Sralph ASSERT(dfp != NULL, CANTOPEN, dfile, 0); 33813697Ssam fprintf(dfp, "exit status %d", ret); 33913697Ssam fclose(dfp); 34013697Ssam } 34117846Sralph if (strcmp(fout, DEVNULL) != SAME) { 34213697Ssam if (prefix(sysout, Myname)) { 34313697Ssam xmv(dfile, fout); 34413697Ssam chmod(fout, BASEMODE); 345*18628Sralph } else { 34617846Sralph char *cp = rindex(user, '!'); 34713697Ssam gename(CMDPRE, sysout, 'O', cfile); 34813697Ssam fp = fopen(subfile(cfile), "w"); 34913697Ssam ASSERT(fp != NULL, "OPEN", cfile, 0); 35017846Sralph fprintf(fp, "S %s %s %s - %s 0666\n", dfile, 35117846Sralph fout, cp ? cp : user, lastpart(dfile)); 35213697Ssam fclose(fp); 35313697Ssam } 35413697Ssam } 35513697Ssam rmfiles: 35613697Ssam xfp = fopen(subfile(xfile), "r"); 35717846Sralph ASSERT(xfp != NULL, CANTOPEN, xfile, 0); 35813697Ssam while (fgets(buf, BUFSIZ, xfp) != NULL) { 35913697Ssam if (buf[0] != X_RQDFILE) 36013697Ssam continue; 36113697Ssam sscanf(&buf[1], "%s", file); 36213697Ssam unlink(subfile(file)); 36313697Ssam } 36413697Ssam unlink(subfile(xfile)); 36513697Ssam fclose(xfp); 366*18628Sralph 367*18628Sralph /* rescan X. for new work every RECHECKTIME seconds */ 368*18628Sralph time(&xnow); 369*18628Sralph if (xnow > (xstart + RECHECKTIME)) { 370*18628Sralph extern int Nfiles; 371*18628Sralph Nfiles = 0; /*force rescan for new work */ 372*18628Sralph } 373*18628Sralph xstart = xnow; 37413697Ssam } 37513697Ssam 37613697Ssam if (stcico) 37713697Ssam xuucico(""); 37813697Ssam cleanup(0); 37913697Ssam } 38013697Ssam 38113697Ssam 38213697Ssam cleanup(code) 38313697Ssam int code; 38413697Ssam { 38513697Ssam logcls(); 38613697Ssam rmlock(CNULL); 38717846Sralph #ifdef VMS 38817846Sralph /* 38917846Sralph * Since we run as a BATCH job we must wait for all processes to 39017846Sralph * to finish 39117846Sralph */ 392*18628Sralph while(wait(0) != -1) 393*18628Sralph ; 39417846Sralph #endif VMS 39513697Ssam exit(code); 39613697Ssam } 39713697Ssam 39813697Ssam 399*18628Sralph /* 400*18628Sralph * get a file to execute 40113697Ssam * 40213697Ssam * return codes: 0 - no file | 1 - file to execute 40313697Ssam */ 40413697Ssam 40513697Ssam gtxfile(file) 40613697Ssam register char *file; 40713697Ssam { 40813697Ssam char pre[3]; 40917846Sralph int rechecked; 41017846Sralph time_t ystrdy; /* yesterday */ 41117846Sralph extern time_t time(); 41217846Sralph struct stat stbuf; /* for X file age */ 41313697Ssam 41413697Ssam pre[0] = XQTPRE; 41513697Ssam pre[1] = '.'; 41613697Ssam pre[2] = '\0'; 41713697Ssam rechecked = 0; 41813697Ssam retry: 41913697Ssam if (!gtwrkf(Spool, file)) { 42013697Ssam if (rechecked) 42117846Sralph return 0; 42213697Ssam rechecked = 1; 42317846Sralph DEBUG(4, "iswrk\n", CNULL); 42413697Ssam if (!iswrk(file, "get", Spool, pre)) 42517846Sralph return 0; 42613697Ssam } 42713697Ssam DEBUG(4, "file - %s\n", file); 42813697Ssam /* skip spurious subdirectories */ 42913697Ssam if (strcmp(pre, file) == SAME) 43013697Ssam goto retry; 43113697Ssam if (gotfiles(file)) 43217846Sralph return 1; 43317846Sralph /* check for old X. file with no work files and remove them. */ 43417846Sralph if (Nfiles > LLEN/2) { 43517846Sralph time(&ystrdy); 43617846Sralph ystrdy -= (4 * 3600L); /* 4 hours ago */ 43717846Sralph DEBUG(4, "gtxfile: Nfiles > LLEN/2\n", CNULL); 43817846Sralph while (gtwrkf(Spool, file) && !gotfiles(file)) { 43917846Sralph if (stat(subfile(file), &stbuf) == 0) 44017846Sralph if (stbuf.st_mtime <= ystrdy) { 44117846Sralph char *bnp, cfilename[NAMESIZE]; 44217846Sralph DEBUG(4, "gtxfile: move %s to CORRUPT \n", file); 44317846Sralph unlink(subfile(file)); 44417846Sralph bnp = rindex(subfile(file), '/'); 44517846Sralph sprintf(cfilename, "%s/%s", CORRUPT, 44617846Sralph bnp ? bnp + 1 : subfile(file)); 44717846Sralph xmv(subfile(file), cfilename); 44817846Sralph logent(file, "X. FILE CORRUPTED"); 44917846Sralph } 45017846Sralph } 45117846Sralph DEBUG(4, "iswrk\n", CNULL); 45217846Sralph if (!iswrk(file, "get", Spool, pre)) 45317846Sralph return 0; 45417846Sralph } 45513697Ssam goto retry; 45613697Ssam } 45713697Ssam 458*18628Sralph /* 459*18628Sralph * check for needed files 46013697Ssam * 46113697Ssam * return codes: 0 - not ready | 1 - all files ready 46213697Ssam */ 46313697Ssam 46413697Ssam gotfiles(file) 46513697Ssam register char *file; 46613697Ssam { 46713697Ssam struct stat stbuf; 46813697Ssam register FILE *fp; 46913697Ssam char buf[BUFSIZ], rqfile[MAXFULLNAME]; 47013697Ssam 47113697Ssam fp = fopen(subfile(file), "r"); 47213697Ssam if (fp == NULL) 47317846Sralph return 0; 47413697Ssam 47513697Ssam while (fgets(buf, BUFSIZ, fp) != NULL) { 47613697Ssam DEBUG(4, "%s\n", buf); 47713697Ssam if (buf[0] != X_RQDFILE) 47813697Ssam continue; 47913697Ssam sscanf(&buf[1], "%s", rqfile); 48013697Ssam expfile(rqfile); 48113697Ssam if (stat(subfile(rqfile), &stbuf) == -1) { 48213697Ssam fclose(fp); 48317846Sralph return 0; 48413697Ssam } 48513697Ssam } 48613697Ssam 48713697Ssam fclose(fp); 48817846Sralph return 1; 48913697Ssam } 49013697Ssam 49113697Ssam 492*18628Sralph /* 493*18628Sralph * remove execute files to x-directory 49413697Ssam */ 49513697Ssam 49613697Ssam rmxfiles(xfile) 49713697Ssam register char *xfile; 49813697Ssam { 49913697Ssam register FILE *fp; 50013697Ssam char buf[BUFSIZ], file[NAMESIZE], tfile[NAMESIZE]; 50113697Ssam char tfull[MAXFULLNAME]; 50213697Ssam 50313697Ssam if((fp = fopen(subfile(xfile), "r")) == NULL) 50413697Ssam return; 50513697Ssam 50613697Ssam while (fgets(buf, BUFSIZ, fp) != NULL) { 50713697Ssam if (buf[0] != X_RQDFILE) 50813697Ssam continue; 50913697Ssam if (sscanf(&buf[1], "%s%s", file, tfile) < 2) 51013697Ssam continue; 51113697Ssam sprintf(tfull, "%s/%s", XQTDIR, tfile); 51213697Ssam unlink(subfile(tfull)); 51313697Ssam } 51413697Ssam fclose(fp); 51513697Ssam return; 51613697Ssam } 51713697Ssam 51813697Ssam 519*18628Sralph /* 520*18628Sralph * move execute files to x-directory 52113697Ssam */ 52213697Ssam 52313697Ssam mvxfiles(xfile) 52413697Ssam char *xfile; 52513697Ssam { 52613697Ssam register FILE *fp; 52713697Ssam char buf[BUFSIZ], ffile[MAXFULLNAME], tfile[NAMESIZE]; 52813697Ssam char tfull[MAXFULLNAME]; 52913697Ssam int ret; 53013697Ssam 53113697Ssam if((fp = fopen(subfile(xfile), "r")) == NULL) 53213697Ssam return; 53313697Ssam 53413697Ssam while (fgets(buf, BUFSIZ, fp) != NULL) { 53513697Ssam if (buf[0] != X_RQDFILE) 53613697Ssam continue; 53713697Ssam if (sscanf(&buf[1], "%s%s", ffile, tfile) < 2) 53813697Ssam continue; 53913697Ssam expfile(ffile); 54013697Ssam sprintf(tfull, "%s/%s", XQTDIR, tfile); 54113697Ssam unlink(subfile(tfull)); 54213697Ssam ret = xmv(ffile, tfull); 54317846Sralph ASSERT(ret == 0, "XQTDIR ERROR", CNULL, ret); 54413697Ssam } 54513697Ssam fclose(fp); 54613697Ssam } 54713697Ssam 548*18628Sralph /* 549*18628Sralph * check for valid command/argument 550*18628Sralph * *NOTE - side effect is to set xc to the command to be executed. 55113697Ssam * 55213697Ssam * return 0 - ok | 1 nok 55313697Ssam */ 55413697Ssam 55513697Ssam argok(xc, cmd) 55613697Ssam register char *xc, *cmd; 55713697Ssam { 55813697Ssam register char **ptr; 55913697Ssam 56013697Ssam #ifndef ALLOK 561*18628Sralph if (strpbrk(cmd, BADCHARS) != NULL) { 56217846Sralph DEBUG(1,"MAGIC CHARACTER FOUND\n", CNULL); 563*18628Sralph logent(cmd, "NASTY MAGIC CHARACTER FOUND"); 56417846Sralph return FAIL; 56517846Sralph } 56617846Sralph #endif !ALLOK 56713697Ssam 56813697Ssam if (xc[0] != '\0') 56917846Sralph return SUCCESS; 57013697Ssam 57113697Ssam #ifndef ALLOK 57213697Ssam ptr = Cmds; 57317846Sralph DEBUG(9, "Compare %s and\n", cmd); 57413697Ssam while(*ptr != NULL) { 57517846Sralph DEBUG(9, "\t%s\n", *ptr); 57613697Ssam if (strcmp(cmd, *ptr) == SAME) 57713697Ssam break; 57817846Sralph ptr++; 57913697Ssam } 58017846Sralph if (*ptr == NULL) { 58117846Sralph DEBUG(1,"COMMAND NOT FOUND\n", CNULL); 58217846Sralph return FAIL; 58317846Sralph } 58413697Ssam #endif 58513697Ssam strcpy(xc, cmd); 58617846Sralph DEBUG(9, "MATCHED %s\n", xc); 58717846Sralph return SUCCESS; 58813697Ssam } 58913697Ssam 59013697Ssam 591*18628Sralph /* 592*18628Sralph * if notification should be sent for successful execution of cmd 59317846Sralph * 59417846Sralph * return NT_YES - do notification 59517846Sralph * NT_ERR - do notification if exit status != 0 59617846Sralph * NT_NO - don't do notification ever 59717846Sralph */ 59817846Sralph 59917846Sralph chknotify(cmd) 60017846Sralph char *cmd; 60117846Sralph { 60217846Sralph register char **ptr; 60317846Sralph register int *nptr; 60417846Sralph 60517846Sralph ptr = Cmds; 60617846Sralph nptr = Notify; 60717846Sralph while (*ptr != NULL) { 60817846Sralph if (strcmp(cmd, *ptr) == SAME) 60917846Sralph return *nptr; 61017846Sralph ptr++; 61117846Sralph nptr++; 61217846Sralph } 61317846Sralph return NT_YES; /* "shouldn't happen" */ 61417846Sralph } 61517846Sralph 61617846Sralph 61717846Sralph 618*18628Sralph /* 619*18628Sralph * send mail to user giving execution results 62013697Ssam */ 62113697Ssam 62213697Ssam notify(user, rmt, cmd, str) 62313697Ssam char *user, *rmt, *cmd, *str; 62413697Ssam { 62513697Ssam char text[MAXFULLNAME]; 62613697Ssam char ruser[MAXFULLNAME]; 62713697Ssam 62817846Sralph sprintf(text, "uuxqt cmd (%s) status (%s)", cmd, str); 62913697Ssam if (prefix(rmt, Myname)) 63013697Ssam strcpy(ruser, user); 63113697Ssam else 63213697Ssam sprintf(ruser, "%s!%s", rmt, user); 63317846Sralph mailst(ruser, text, CNULL); 63413697Ssam return; 63513697Ssam } 63613697Ssam 637*18628Sralph /* 638*18628Sralph * return mail to sender 63913697Ssam * 64013697Ssam */ 64113697Ssam 64213697Ssam retosndr(user, rmt, file) 64313697Ssam char *user, *rmt, *file; 64413697Ssam { 64517846Sralph char ruser[MAXFULLNAME]; 64613697Ssam 64713697Ssam if (strcmp(rmt, Myname) == SAME) 64813697Ssam strcpy(ruser, user); 64913697Ssam else 65013697Ssam sprintf(ruser, "%s!%s", rmt, user); 65113697Ssam 65213697Ssam if (anyread(file) == 0) 65313697Ssam mailst(ruser, "Mail failed. Letter returned to sender.\n", file); 65413697Ssam else 65517846Sralph mailst(ruser, "Mail failed. Letter returned to sender.\n", CNULL); 65613697Ssam return; 65713697Ssam } 65817870Sralph 65917870Sralph /* 66017870Sralph * this is like index, but takes a string as the second argument 66117870Sralph */ 66217870Sralph char * 663*18628Sralph strpbrk(str, chars) 66417870Sralph register char *str, *chars; 66517870Sralph { 66617870Sralph register char *cp; 66717870Sralph 66817870Sralph do { 66917870Sralph cp = chars - 1; 67017870Sralph while (*++cp) { 67117870Sralph if (*str == *cp) 67217870Sralph return str; 67317870Sralph } 67417870Sralph } while (*str++); 67517870Sralph return NULL; 67617870Sralph } 677*18628Sralph 678*18628Sralph /* 679*18628Sralph * execute shell of command with fi and fo as standard input/output 680*18628Sralph */ 681*18628Sralph 682*18628Sralph shio(cmd, fi, fo) 683*18628Sralph char *cmd, *fi, *fo; 684*18628Sralph { 685*18628Sralph int status, f; 686*18628Sralph int uid, pid, ret; 687*18628Sralph char path[MAXFULLNAME]; 688*18628Sralph char *args[20]; 689*18628Sralph extern int errno; 690*18628Sralph 691*18628Sralph if (fi == NULL) 692*18628Sralph fi = DEVNULL; 693*18628Sralph if (fo == NULL) 694*18628Sralph fo = DEVNULL; 695*18628Sralph 696*18628Sralph getargs(cmd, args, 20); 697*18628Sralph DEBUG(3, "shio - %s\n", cmd); 698*18628Sralph #ifdef SIGCHLD 699*18628Sralph signal(SIGCHLD, SIG_IGN); 700*18628Sralph #endif SIGCHLD 701*18628Sralph if ((pid = fork()) == 0) { 702*18628Sralph signal(SIGINT, SIG_IGN); 703*18628Sralph signal(SIGHUP, SIG_IGN); 704*18628Sralph signal(SIGQUIT, SIG_IGN); 705*18628Sralph signal(SIGKILL, SIG_IGN); 706*18628Sralph close(Ifn); 707*18628Sralph close(Ofn); 708*18628Sralph close(0); 709*18628Sralph setuid(getuid()); 710*18628Sralph f = open(subfile(fi), 0); 711*18628Sralph if (f != 0) { 712*18628Sralph logent(fi, "CAN'T READ"); 713*18628Sralph exit(-errno); 714*18628Sralph } 715*18628Sralph close(1); 716*18628Sralph f = creat(subfile(fo), 0666); 717*18628Sralph if (f != 1) { 718*18628Sralph logent(fo, "CAN'T WRITE"); 719*18628Sralph exit(-errno); 720*18628Sralph } 721*18628Sralph execvp(args[0], args); 722*18628Sralph exit(100+errno); 723*18628Sralph } 724*18628Sralph while ((ret = wait(&status)) != pid && ret != -1) 725*18628Sralph ; 726*18628Sralph DEBUG(3, "status %d\n", status); 727*18628Sralph return status; 728*18628Sralph } 729