113697Ssam #ifndef lint 2*33579Srick static char sccsid[] = "@(#)uuxqt.c 5.9 (Berkeley) 02/24/88"; 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 1418628Sralph #define BADCHARS "&^|(`\\<>;\"{}\n'" 1518628Sralph #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 21*33579Srick extern char Filent[LLEN][NAMESIZE]; 22*33579Srick 2313697Ssam /* 2413697Ssam * uuxqt will execute commands set up by a uux command, 2513697Ssam * usually from a remote machine - set by uucp. 2613697Ssam */ 2713697Ssam 2813697Ssam #define NCMDS 50 2917846Sralph char *Cmds[NCMDS+1]; 3017846Sralph int Notify[NCMDS+1]; 3117846Sralph #define NT_YES 0 /* if should notify on execution */ 3217846Sralph #define NT_ERR 1 /* if should notify if non-zero exit status (-z equivalent) */ 3317846Sralph #define NT_NO 2 /* if should not notify ever (-n equivalent) */ 3413697Ssam 3517846Sralph extern int Nfiles; 3617846Sralph 3718628Sralph int TransferSucceeded = 1; 3813697Ssam int notiok = 1; 3913697Ssam int nonzero = 0; 4013697Ssam 4125147Sbloom struct timeb Now; 4225147Sbloom 4318628Sralph char PATH[MAXFULLNAME] = "PATH=/bin:/usr/bin:/usr/ucb"; 4418628Sralph char Shell[MAXFULLNAME]; 4518628Sralph char HOME[MAXFULLNAME]; 4617846Sralph 4718628Sralph extern char **environ; 4818628Sralph char *nenv[] = { 4918628Sralph PATH, 5018628Sralph Shell, 5118628Sralph HOME, 5218628Sralph 0 5318628Sralph }; 5417846Sralph 5513697Ssam /* to remove restrictions from uuxqt 5613697Ssam * define ALLOK 1 5713697Ssam * 5813697Ssam * to add allowable commands, add to the file CMDFILE 5913697Ssam * A line of form "PATH=..." changes the search path 6013697Ssam */ 6113697Ssam main(argc, argv) 6213697Ssam char *argv[]; 6313697Ssam { 64*33579Srick char xcmd[BUFSIZ*2]; 6513697Ssam int argnok; 6617846Sralph int notiflg; 67*33579Srick char xfile[MAXFULLNAME], user[MAXFULLNAME], buf[BUFSIZ*2]; 6817846Sralph char lbuf[MAXFULLNAME]; 6913697Ssam char cfile[NAMESIZE], dfile[MAXFULLNAME]; 7013697Ssam char file[NAMESIZE]; 7113697Ssam char fin[MAXFULLNAME], sysout[NAMESIZE], fout[MAXFULLNAME]; 7213697Ssam register FILE *xfp, *fp; 7313697Ssam FILE *dfp; 7413697Ssam char path[MAXFULLNAME]; 75*33579Srick char cmd[BUFSIZ*2]; 7613697Ssam char *cmdp, prm[1000], *ptr; 7713697Ssam char *getprm(), *lastpart(); 7817846Sralph int uid, ret, ret2, badfiles; 7913697Ssam register int i; 8013697Ssam int stcico = 0; 8118628Sralph time_t xstart, xnow; 8213697Ssam char retstat[30]; 8318628Sralph char **ep; 8413697Ssam 8513697Ssam strcpy(Progname, "uuxqt"); 8613697Ssam uucpname(Myname); 8713697Ssam 8813697Ssam umask(WFMASK); 8913697Ssam Ofn = 1; 9013697Ssam Ifn = 0; 9113697Ssam while (argc>1 && argv[1][0] == '-') { 9213697Ssam switch(argv[1][1]){ 9313697Ssam case 'x': 9417846Sralph chkdebug(); 9513697Ssam Debug = atoi(&argv[1][2]); 9613697Ssam if (Debug <= 0) 9713697Ssam Debug = 1; 9813697Ssam break; 99*33579Srick case 'S': 100*33579Srick Spool = &argv[1][2]; 101*33579Srick DEBUG(1, "Spool set to %s", Spool); 102*33579Srick break; 10313697Ssam default: 10413697Ssam fprintf(stderr, "unknown flag %s\n", argv[1]); 10513697Ssam break; 10613697Ssam } 10713697Ssam --argc; argv++; 10813697Ssam } 10913697Ssam 11018628Sralph DEBUG(4, "\n\n** START **\n", CNULL); 11117846Sralph ret = subchdir(Spool); 11217846Sralph ASSERT(ret >= 0, "CHDIR FAILED", Spool, ret); 11313697Ssam strcpy(Wrkdir, Spool); 11413697Ssam uid = getuid(); 115*33579Srick if (guinfo(uid, User, path) != SUCCESS) { 116*33579Srick assert("Can't find username for ", "uid", uid); 117*33579Srick DEBUG(1, "Using username", "uucp"); 118*33579Srick strcpy(User, "uucp"); 119*33579Srick } 12017846Sralph setgid(getegid()); 12117846Sralph setuid(geteuid()); 12217846Sralph 12313697Ssam DEBUG(4, "User - %s\n", User); 12423692Sbloom if (ulockf(X_LOCK, X_LOCKTIME) != 0) 12513697Ssam exit(0); 12613697Ssam 12713697Ssam fp = fopen(CMDFILE, "r"); 12813697Ssam if (fp == NULL) { 12917846Sralph logent(CANTOPEN, CMDFILE); 13013697Ssam Cmds[0] = "rmail"; 13113697Ssam Cmds[1] = "rnews"; 13213697Ssam Cmds[2] = "ruusend"; 13313697Ssam Cmds[3] = NULL; 13413697Ssam goto doprocess; 13513697Ssam } 13613697Ssam DEBUG(5, "%s opened\n", CMDFILE); 13717846Sralph for (i=0; i<NCMDS && cfgets(xcmd, sizeof(xcmd), fp) != NULL; i++) { 13817846Sralph int j; 13917846Sralph /* strip trailing whitespace */ 14017846Sralph for (j = strlen(xcmd)-1; j >= 0; --j) 14117846Sralph if (xcmd[j] == '\n' || xcmd[j] == ' ' || xcmd[j] == '\t') 14217846Sralph xcmd[j] = '\0'; 14317846Sralph else 14417846Sralph break; 14517846Sralph /* look for imbedded whitespace */ 14617846Sralph for (; j >= 0; --j) 14717846Sralph if (xcmd[j] == '\n' || xcmd[j] == ' ' || xcmd[j] == '\t') 14817846Sralph break; 14917846Sralph /* skip this entry if it has embedded whitespace */ 15017846Sralph /* This defends against a bad PATH=, for example */ 15117846Sralph if (j >= 0) { 15217846Sralph logent(xcmd, "BAD WHITESPACE"); 15317846Sralph continue; 15417846Sralph } 15513697Ssam if (strncmp(xcmd, "PATH=", 5) == 0) { 15613697Ssam strcpy(PATH, xcmd); 15717846Sralph i--; /*kludge */ 15813697Ssam continue; 15913697Ssam } 16013697Ssam DEBUG(5, "xcmd = %s\n", xcmd); 16117846Sralph 16217846Sralph if ((ptr = index(xcmd, ',')) != NULL) { 16317846Sralph *ptr++ = '\0'; 16417846Sralph if (strncmp(ptr, "Err", 3) == SAME) 16517846Sralph Notify[i] = NT_ERR; 16617846Sralph else if (strcmp(ptr, "No") == SAME) 16717846Sralph Notify[i] = NT_NO; 16817846Sralph else 16917846Sralph Notify[i] = NT_YES; 17017846Sralph } else 17117846Sralph Notify[i] = NT_YES; 17217846Sralph if ((Cmds[i] = malloc((unsigned)(strlen(xcmd)+1))) == NULL) { 17317846Sralph DEBUG(1, "MALLOC FAILED", CNULL); 17417846Sralph break; 17517846Sralph } 17613697Ssam strcpy(Cmds[i], xcmd); 17713697Ssam } 17817846Sralph Cmds[i] = CNULL; 17913697Ssam fclose(fp); 18013697Ssam 18113697Ssam doprocess: 18218628Sralph 18318628Sralph (void) sprintf(HOME, "HOME=%s", Spool); 18418628Sralph (void) sprintf(Shell, "SHELL=%s", SHELL); 18518628Sralph environ = nenv; /* force use if our environment */ 18618628Sralph 18718628Sralph DEBUG(11,"path = %s\n", getenv("PATH")); 18818628Sralph 18917846Sralph DEBUG(4, "process %s\n", CNULL); 190*33579Srick 19118628Sralph time(&xstart); 19213697Ssam while (gtxfile(xfile) > 0) { 19325147Sbloom /* if /etc/nologin exists, exit cleanly */ 19425147Sbloom #if defined(BSD4_2) || defined(USG) 19525147Sbloom if (access(NOLOGIN) == 0) { 19625147Sbloom #else !BSD4_2 && ! USG 19717846Sralph ultouch(); 19817846Sralph if (nologinflag) { 19925147Sbloom #endif !BSD4_2 && !USG 20017846Sralph logent(NOLOGIN, "UUXQT SHUTDOWN"); 20117846Sralph if (Debug) 20217846Sralph logent("debugging", "continuing anyway"); 20317846Sralph else 20417846Sralph break; 20517846Sralph } 20613697Ssam DEBUG(4, "xfile - %s\n", xfile); 20713697Ssam 20813697Ssam xfp = fopen(subfile(xfile), "r"); 20917846Sralph ASSERT(xfp != NULL, CANTOPEN, xfile, 0); 21013697Ssam 21113697Ssam /* initialize to default */ 21213697Ssam strcpy(user, User); 21317846Sralph strcpy(fin, DEVNULL); 21417846Sralph strcpy(fout, DEVNULL); 21523692Sbloom strcpy(sysout, Myname); 21617846Sralph badfiles = 0; 21713697Ssam while (fgets(buf, BUFSIZ, xfp) != NULL) { 218*33579Srick if(buf[0] != '\0' && buf[0] != '#' && 219*33579Srick buf[1] != ' ' && buf[1] != '\0' && buf[1] != '\n') { 220*33579Srick char *bnp, cfilename[BUFSIZ]; 221*33579Srick DEBUG(4, "uuxqt: buf = %s\n", buf); 222*33579Srick bnp = rindex(xfile, '/'); 223*33579Srick sprintf(cfilename, "%s/%s", CORRUPT, 224*33579Srick bnp ? bnp + 1 : xfile); 225*33579Srick DEBUG(4, "uuxqt: move %s to ", xfile); 226*33579Srick DEBUG(4, "%s\n", cfilename); 227*33579Srick xmv(xfile, cfilename); 228*33579Srick assert("X. FILE CORRUPTED", xfile, 0); 229*33579Srick fclose(xfp); 230*33579Srick goto doprocess; 231*33579Srick 232*33579Srick } 23313697Ssam switch (buf[0]) { 23413697Ssam case X_USER: 23517846Sralph sscanf(&buf[1], "%s %s", user, Rmtname); 23613697Ssam break; 23717846Sralph case X_RETURNTO: 23817846Sralph sscanf(&buf[1], "%s", user); 23917846Sralph break; 24013697Ssam case X_STDIN: 24113697Ssam sscanf(&buf[1], "%s", fin); 24213697Ssam i = expfile(fin); 24313697Ssam /* rti!trt: do not check permissions of 24413697Ssam * vanilla spool file */ 24513697Ssam if (i != 0 24613697Ssam && (chkpth("", "", fin) || anyread(fin) != 0)) 24713697Ssam badfiles = 1; 24813697Ssam break; 24913697Ssam case X_STDOUT: 25013697Ssam sscanf(&buf[1], "%s%s", fout, sysout); 25123692Sbloom sysout[MAXBASENAME] = '\0'; 25213697Ssam /* rti!trt: do not check permissions of 25313697Ssam * vanilla spool file. DO check permissions 25413697Ssam * of writing on a non-vanilla file */ 25513697Ssam i = 1; 25613697Ssam if (fout[0] != '~' || prefix(sysout, Myname)) 25713697Ssam i = expfile(fout); 25813697Ssam if (i != 0 25913697Ssam && (chkpth("", "", fout) 26013697Ssam || chkperm(fout, (char *)1))) 26113697Ssam badfiles = 1; 26213697Ssam break; 26313697Ssam case X_CMD: 26413697Ssam strcpy(cmd, &buf[2]); 26513697Ssam if (*(cmd + strlen(cmd) - 1) == '\n') 26613697Ssam *(cmd + strlen(cmd) - 1) = '\0'; 26713697Ssam break; 26813697Ssam case X_NONOTI: 26913697Ssam notiok = 0; 27013697Ssam break; 27113697Ssam case X_NONZERO: 27213697Ssam nonzero = 1; 27313697Ssam break; 27413697Ssam default: 27513697Ssam break; 27613697Ssam } 27713697Ssam } 27813697Ssam 27913697Ssam fclose(xfp); 28013697Ssam DEBUG(4, "fin - %s, ", fin); 28113697Ssam DEBUG(4, "fout - %s, ", fout); 28213697Ssam DEBUG(4, "sysout - %s, ", sysout); 28313697Ssam DEBUG(4, "user - %s\n", user); 28413697Ssam DEBUG(4, "cmd - %s\n", cmd); 28513697Ssam 28613697Ssam /* command execution */ 28717846Sralph if (strcmp(fout, DEVNULL) == SAME) 28817846Sralph strcpy(dfile,DEVNULL); 28913697Ssam else 29013697Ssam gename(DATAPRE, sysout, 'O', dfile); 29113697Ssam 29213697Ssam /* expand file names where necessary */ 29313697Ssam expfile(dfile); 29418628Sralph cmdp = buf; 29513697Ssam ptr = cmd; 29613697Ssam xcmd[0] = '\0'; 29713697Ssam argnok = 0; 29813697Ssam while ((ptr = getprm(ptr, prm)) != NULL) { 29913697Ssam if (prm[0] == ';' || prm[0] == '^' 30013697Ssam || prm[0] == '&' || prm[0] == '|') { 30113697Ssam xcmd[0] = '\0'; 30213697Ssam APPCMD(prm); 30313697Ssam continue; 30413697Ssam } 30513697Ssam 30617846Sralph if ((argnok = argok(xcmd, prm)) != SUCCESS) 30713697Ssam /* command not valid */ 30813697Ssam break; 30913697Ssam 31013697Ssam if (prm[0] == '~') 31113697Ssam expfile(prm); 31213697Ssam APPCMD(prm); 31313697Ssam } 31417846Sralph /* 31517846Sralph * clean up trailing ' ' in command. 31617846Sralph */ 31717846Sralph if (cmdp > buf && cmdp[0] == '\0' && cmdp[-1] == ' ') 31817846Sralph *--cmdp = '\0'; 31913697Ssam if (argnok || badfiles) { 32013697Ssam sprintf(lbuf, "%s XQT DENIED", user); 32113697Ssam logent(cmd, lbuf); 32213697Ssam DEBUG(4, "bad command %s\n", prm); 32313697Ssam notify(user, Rmtname, cmd, "DENIED"); 32413697Ssam goto rmfiles; 32513697Ssam } 32613697Ssam sprintf(lbuf, "%s XQT", user); 32713697Ssam logent(buf, lbuf); 32813697Ssam DEBUG(4, "cmd %s\n", buf); 32913697Ssam 33013697Ssam mvxfiles(xfile); 33117846Sralph ret = subchdir(XQTDIR); 33217846Sralph ASSERT(ret >= 0, "CHDIR FAILED", XQTDIR, ret); 33318628Sralph ret = shio(buf, fin, dfile); 33413697Ssam sprintf(retstat, "signal %d, exit %d", ret & 0377, 33513697Ssam (ret>>8) & 0377); 33613697Ssam if (strcmp(xcmd, "rmail") == SAME) 33713697Ssam notiok = 0; 33813697Ssam if (strcmp(xcmd, "rnews") == SAME) 33913697Ssam nonzero = 1; 34017846Sralph notiflg = chknotify(xcmd); 34117846Sralph if (notiok && notiflg != NT_NO && 34217846Sralph (ret != 0 || (!nonzero && notiflg == NT_YES))) 34313697Ssam notify(user, Rmtname, cmd, retstat); 34413697Ssam else if (ret != 0 && strcmp(xcmd, "rmail") == SAME) { 34513697Ssam /* mail failed - return letter to sender */ 34617846Sralph #ifdef DANGEROUS 34717846Sralph /* NOT GUARANTEED SAFE!!! */ 34817846Sralph if (!nonzero) 34917846Sralph retosndr(user, Rmtname, fin); 35017846Sralph #else 35117846Sralph notify(user, Rmtname, cmd, retstat); 35217846Sralph #endif 35317846Sralph sprintf(buf, "%s (%s) from %s!%s", buf, retstat, Rmtname, user); 35413697Ssam logent("MAIL FAIL", buf); 35513697Ssam } 35613697Ssam DEBUG(4, "exit cmd - %d\n", ret); 35717846Sralph ret2 = subchdir(Spool); 35817846Sralph ASSERT(ret2 >= 0, "CHDIR FAILED", Spool, ret); 35913697Ssam rmxfiles(xfile); 36013697Ssam if (ret != 0) { 36113697Ssam /* exit status not zero */ 36213697Ssam dfp = fopen(subfile(dfile), "a"); 36317846Sralph ASSERT(dfp != NULL, CANTOPEN, dfile, 0); 36413697Ssam fprintf(dfp, "exit status %d", ret); 36513697Ssam fclose(dfp); 36613697Ssam } 36717846Sralph if (strcmp(fout, DEVNULL) != SAME) { 36813697Ssam if (prefix(sysout, Myname)) { 36913697Ssam xmv(dfile, fout); 37013697Ssam chmod(fout, BASEMODE); 37118628Sralph } else { 37217846Sralph char *cp = rindex(user, '!'); 37313697Ssam gename(CMDPRE, sysout, 'O', cfile); 37413697Ssam fp = fopen(subfile(cfile), "w"); 37513697Ssam ASSERT(fp != NULL, "OPEN", cfile, 0); 37617846Sralph fprintf(fp, "S %s %s %s - %s 0666\n", dfile, 37717846Sralph fout, cp ? cp : user, lastpart(dfile)); 37813697Ssam fclose(fp); 37913697Ssam } 38013697Ssam } 38113697Ssam rmfiles: 38213697Ssam xfp = fopen(subfile(xfile), "r"); 38317846Sralph ASSERT(xfp != NULL, CANTOPEN, xfile, 0); 38413697Ssam while (fgets(buf, BUFSIZ, xfp) != NULL) { 38513697Ssam if (buf[0] != X_RQDFILE) 38613697Ssam continue; 38713697Ssam sscanf(&buf[1], "%s", file); 38813697Ssam unlink(subfile(file)); 38913697Ssam } 39013697Ssam unlink(subfile(xfile)); 39113697Ssam fclose(xfp); 39218628Sralph 39318628Sralph /* rescan X. for new work every RECHECKTIME seconds */ 39418628Sralph time(&xnow); 39518628Sralph if (xnow > (xstart + RECHECKTIME)) { 39618628Sralph extern int Nfiles; 39718628Sralph Nfiles = 0; /*force rescan for new work */ 39818628Sralph } 39918628Sralph xstart = xnow; 40013697Ssam } 40113697Ssam 40213697Ssam if (stcico) 40313697Ssam xuucico(""); 40413697Ssam cleanup(0); 40513697Ssam } 40613697Ssam 40713697Ssam 40813697Ssam cleanup(code) 40913697Ssam int code; 41013697Ssam { 41113697Ssam logcls(); 41213697Ssam rmlock(CNULL); 41317846Sralph #ifdef VMS 41417846Sralph /* 41517846Sralph * Since we run as a BATCH job we must wait for all processes to 41617846Sralph * to finish 41717846Sralph */ 41818628Sralph while(wait(0) != -1) 41918628Sralph ; 42017846Sralph #endif VMS 42113697Ssam exit(code); 42213697Ssam } 42313697Ssam 42413697Ssam 42518628Sralph /* 42618628Sralph * get a file to execute 42713697Ssam * 42813697Ssam * return codes: 0 - no file | 1 - file to execute 42913697Ssam */ 43013697Ssam 43113697Ssam gtxfile(file) 43213697Ssam register char *file; 43313697Ssam { 43413697Ssam char pre[3]; 435*33579Srick register int rechecked, i; 43617846Sralph time_t ystrdy; /* yesterday */ 43717846Sralph struct stat stbuf; /* for X file age */ 43813697Ssam 43913697Ssam pre[0] = XQTPRE; 44013697Ssam pre[1] = '.'; 44113697Ssam pre[2] = '\0'; 44213697Ssam rechecked = 0; 44313697Ssam retry: 444*33579Srick if (Nfiles-- <= 0) { 445*33579Srick Nfiles = 0; 44613697Ssam if (rechecked) 44717846Sralph return 0; 44813697Ssam rechecked = 1; 44917846Sralph DEBUG(4, "iswrk\n", CNULL); 450*33579Srick return iswrk(file, "get", Spool, pre); 45113697Ssam } 452*33579Srick sprintf(file, "%s/%s", Spool, Filent[0]); 453*33579Srick for (i=0; i<Nfiles;i++) 454*33579Srick strcpy(Filent[i], Filent[i+1]); 455*33579Srick 45613697Ssam DEBUG(4, "file - %s\n", file); 45713697Ssam /* skip spurious subdirectories */ 45813697Ssam if (strcmp(pre, file) == SAME) 45913697Ssam goto retry; 46013697Ssam if (gotfiles(file)) 46117846Sralph return 1; 46217846Sralph /* check for old X. file with no work files and remove them. */ 46317846Sralph if (Nfiles > LLEN/2) { 46417846Sralph time(&ystrdy); 46517846Sralph ystrdy -= (4 * 3600L); /* 4 hours ago */ 46617846Sralph DEBUG(4, "gtxfile: Nfiles > LLEN/2\n", CNULL); 467*33579Srick while (Nfiles-- > 0) { 468*33579Srick sprintf(file, "%s/%s", Spool, Filent[0]); 469*33579Srick for (i=0; i<Nfiles; i++) 470*33579Srick strcpy(Filent[i], Filent[i+1]); 471*33579Srick 472*33579Srick if (gotfiles(file)) 473*33579Srick return 1; 47417846Sralph if (stat(subfile(file), &stbuf) == 0) 47517846Sralph if (stbuf.st_mtime <= ystrdy) { 47617846Sralph char *bnp, cfilename[NAMESIZE]; 47717846Sralph DEBUG(4, "gtxfile: move %s to CORRUPT \n", file); 478*33579Srick bnp = rindex(file, '/'); 47917846Sralph sprintf(cfilename, "%s/%s", CORRUPT, 480*33579Srick bnp ? bnp + 1 : file); 481*33579Srick xmv(file, cfilename); 482*33579Srick assert("X. FILE MISSING FILES", file, 0); 48317846Sralph } 48417846Sralph } 485*33579Srick Nfiles = 0; 48617846Sralph DEBUG(4, "iswrk\n", CNULL); 48717846Sralph if (!iswrk(file, "get", Spool, pre)) 48817846Sralph return 0; 48917846Sralph } 49013697Ssam goto retry; 49113697Ssam } 49213697Ssam 49318628Sralph /* 49418628Sralph * check for needed files 49513697Ssam * 49613697Ssam * return codes: 0 - not ready | 1 - all files ready 49713697Ssam */ 49813697Ssam 49913697Ssam gotfiles(file) 50013697Ssam register char *file; 50113697Ssam { 50213697Ssam struct stat stbuf; 50313697Ssam register FILE *fp; 50413697Ssam char buf[BUFSIZ], rqfile[MAXFULLNAME]; 50513697Ssam 50613697Ssam fp = fopen(subfile(file), "r"); 50713697Ssam if (fp == NULL) 50817846Sralph return 0; 50913697Ssam 51013697Ssam while (fgets(buf, BUFSIZ, fp) != NULL) { 51113697Ssam DEBUG(4, "%s\n", buf); 51213697Ssam if (buf[0] != X_RQDFILE) 51313697Ssam continue; 51413697Ssam sscanf(&buf[1], "%s", rqfile); 51513697Ssam expfile(rqfile); 51613697Ssam if (stat(subfile(rqfile), &stbuf) == -1) { 51713697Ssam fclose(fp); 51817846Sralph return 0; 51913697Ssam } 52013697Ssam } 52113697Ssam 52213697Ssam fclose(fp); 52317846Sralph return 1; 52413697Ssam } 52513697Ssam 52613697Ssam 52718628Sralph /* 52818628Sralph * remove execute files to x-directory 52913697Ssam */ 53013697Ssam 53113697Ssam rmxfiles(xfile) 53213697Ssam register char *xfile; 53313697Ssam { 53413697Ssam register FILE *fp; 53513697Ssam char buf[BUFSIZ], file[NAMESIZE], tfile[NAMESIZE]; 53613697Ssam char tfull[MAXFULLNAME]; 53713697Ssam 53813697Ssam if((fp = fopen(subfile(xfile), "r")) == NULL) 53913697Ssam return; 54013697Ssam 54113697Ssam while (fgets(buf, BUFSIZ, fp) != NULL) { 54213697Ssam if (buf[0] != X_RQDFILE) 54313697Ssam continue; 54413697Ssam if (sscanf(&buf[1], "%s%s", file, tfile) < 2) 54513697Ssam continue; 54613697Ssam sprintf(tfull, "%s/%s", XQTDIR, tfile); 54713697Ssam unlink(subfile(tfull)); 54813697Ssam } 54913697Ssam fclose(fp); 55013697Ssam return; 55113697Ssam } 55213697Ssam 55313697Ssam 55418628Sralph /* 55518628Sralph * move execute files to x-directory 55613697Ssam */ 55713697Ssam 55813697Ssam mvxfiles(xfile) 55913697Ssam char *xfile; 56013697Ssam { 56113697Ssam register FILE *fp; 56213697Ssam char buf[BUFSIZ], ffile[MAXFULLNAME], tfile[NAMESIZE]; 56313697Ssam char tfull[MAXFULLNAME]; 56413697Ssam int ret; 56513697Ssam 56613697Ssam if((fp = fopen(subfile(xfile), "r")) == NULL) 56713697Ssam return; 56813697Ssam 56913697Ssam while (fgets(buf, BUFSIZ, fp) != NULL) { 57013697Ssam if (buf[0] != X_RQDFILE) 57113697Ssam continue; 57213697Ssam if (sscanf(&buf[1], "%s%s", ffile, tfile) < 2) 57313697Ssam continue; 57413697Ssam expfile(ffile); 57513697Ssam sprintf(tfull, "%s/%s", XQTDIR, tfile); 57613697Ssam unlink(subfile(tfull)); 57713697Ssam ret = xmv(ffile, tfull); 57817846Sralph ASSERT(ret == 0, "XQTDIR ERROR", CNULL, ret); 57913697Ssam } 58013697Ssam fclose(fp); 58113697Ssam } 58213697Ssam 58318628Sralph /* 58418628Sralph * check for valid command/argument 58518628Sralph * *NOTE - side effect is to set xc to the command to be executed. 58613697Ssam * 58713697Ssam * return 0 - ok | 1 nok 58813697Ssam */ 58913697Ssam 59013697Ssam argok(xc, cmd) 59113697Ssam register char *xc, *cmd; 59213697Ssam { 59313697Ssam register char **ptr; 59413697Ssam 59513697Ssam #ifndef ALLOK 59618628Sralph if (strpbrk(cmd, BADCHARS) != NULL) { 59717846Sralph DEBUG(1,"MAGIC CHARACTER FOUND\n", CNULL); 59818628Sralph logent(cmd, "NASTY MAGIC CHARACTER FOUND"); 59917846Sralph return FAIL; 60017846Sralph } 60117846Sralph #endif !ALLOK 60213697Ssam 60313697Ssam if (xc[0] != '\0') 60417846Sralph return SUCCESS; 60513697Ssam 60613697Ssam #ifndef ALLOK 60713697Ssam ptr = Cmds; 60817846Sralph DEBUG(9, "Compare %s and\n", cmd); 60913697Ssam while(*ptr != NULL) { 61017846Sralph DEBUG(9, "\t%s\n", *ptr); 61113697Ssam if (strcmp(cmd, *ptr) == SAME) 61213697Ssam break; 61317846Sralph ptr++; 61413697Ssam } 61517846Sralph if (*ptr == NULL) { 61617846Sralph DEBUG(1,"COMMAND NOT FOUND\n", CNULL); 61717846Sralph return FAIL; 61817846Sralph } 61913697Ssam #endif 62013697Ssam strcpy(xc, cmd); 62117846Sralph DEBUG(9, "MATCHED %s\n", xc); 62217846Sralph return SUCCESS; 62313697Ssam } 62413697Ssam 62513697Ssam 62618628Sralph /* 62718628Sralph * if notification should be sent for successful execution of cmd 62817846Sralph * 62917846Sralph * return NT_YES - do notification 63017846Sralph * NT_ERR - do notification if exit status != 0 63117846Sralph * NT_NO - don't do notification ever 63217846Sralph */ 63317846Sralph 63417846Sralph chknotify(cmd) 63517846Sralph char *cmd; 63617846Sralph { 63717846Sralph register char **ptr; 63817846Sralph register int *nptr; 63917846Sralph 64017846Sralph ptr = Cmds; 64117846Sralph nptr = Notify; 64217846Sralph while (*ptr != NULL) { 64317846Sralph if (strcmp(cmd, *ptr) == SAME) 64417846Sralph return *nptr; 64517846Sralph ptr++; 64617846Sralph nptr++; 64717846Sralph } 64817846Sralph return NT_YES; /* "shouldn't happen" */ 64917846Sralph } 65017846Sralph 65117846Sralph 65217846Sralph 65318628Sralph /* 65418628Sralph * send mail to user giving execution results 65513697Ssam */ 65613697Ssam 65713697Ssam notify(user, rmt, cmd, str) 65813697Ssam char *user, *rmt, *cmd, *str; 65913697Ssam { 660*33579Srick char text[BUFSIZ*2]; 66113697Ssam char ruser[MAXFULLNAME]; 66213697Ssam 66325968Sbloom if (strpbrk(user, BADCHARS) != NULL) { 66425968Sbloom char lbuf[MAXFULLNAME]; 66525968Sbloom sprintf(lbuf, "%s INVALID CHARACTER IN USERNAME", user); 66625968Sbloom logent(cmd, lbuf); 66725968Sbloom strcpy(user, "postmaster"); 66825968Sbloom } 66917846Sralph sprintf(text, "uuxqt cmd (%s) status (%s)", cmd, str); 67013697Ssam if (prefix(rmt, Myname)) 67113697Ssam strcpy(ruser, user); 67213697Ssam else 67313697Ssam sprintf(ruser, "%s!%s", rmt, user); 67417846Sralph mailst(ruser, text, CNULL); 67513697Ssam } 67613697Ssam 67718628Sralph /* 67818628Sralph * return mail to sender 67913697Ssam * 68013697Ssam */ 68113697Ssam retosndr(user, rmt, file) 68213697Ssam char *user, *rmt, *file; 68313697Ssam { 68417846Sralph char ruser[MAXFULLNAME]; 68513697Ssam 68625968Sbloom if (strpbrk(user, BADCHARS) != NULL) { 68725968Sbloom char lbuf[MAXFULLNAME]; 68825968Sbloom sprintf(lbuf, "%s INVALID CHARACTER IN USERNAME", user); 68925968Sbloom logent(file, lbuf); 69025968Sbloom strcpy(user, "postmaster"); 69125968Sbloom } 69213697Ssam if (strcmp(rmt, Myname) == SAME) 69313697Ssam strcpy(ruser, user); 69413697Ssam else 69513697Ssam sprintf(ruser, "%s!%s", rmt, user); 69613697Ssam 69713697Ssam if (anyread(file) == 0) 69813697Ssam mailst(ruser, "Mail failed. Letter returned to sender.\n", file); 69913697Ssam else 70017846Sralph mailst(ruser, "Mail failed. Letter returned to sender.\n", CNULL); 70113697Ssam return; 70213697Ssam } 70317870Sralph 70417870Sralph /* 70518628Sralph * execute shell of command with fi and fo as standard input/output 70618628Sralph */ 70718628Sralph 70818628Sralph shio(cmd, fi, fo) 70918628Sralph char *cmd, *fi, *fo; 71018628Sralph { 71118628Sralph int status, f; 71218628Sralph int uid, pid, ret; 71318628Sralph char path[MAXFULLNAME]; 714*33579Srick char *args[256]; 71518628Sralph extern int errno; 71618628Sralph 71718628Sralph if (fi == NULL) 71818628Sralph fi = DEVNULL; 71918628Sralph if (fo == NULL) 72018628Sralph fo = DEVNULL; 72118628Sralph 722*33579Srick getargs(cmd, args, 256); 72318628Sralph DEBUG(3, "shio - %s\n", cmd); 72418628Sralph #ifdef SIGCHLD 72518628Sralph signal(SIGCHLD, SIG_IGN); 72618628Sralph #endif SIGCHLD 72718628Sralph if ((pid = fork()) == 0) { 72818628Sralph signal(SIGINT, SIG_IGN); 72918628Sralph signal(SIGHUP, SIG_IGN); 73018628Sralph signal(SIGQUIT, SIG_IGN); 73118628Sralph close(Ifn); 73218628Sralph close(Ofn); 73318628Sralph close(0); 73418628Sralph setuid(getuid()); 73518628Sralph f = open(subfile(fi), 0); 73618628Sralph if (f != 0) { 73718628Sralph logent(fi, "CAN'T READ"); 73818628Sralph exit(-errno); 73918628Sralph } 74018628Sralph close(1); 74118628Sralph f = creat(subfile(fo), 0666); 74218628Sralph if (f != 1) { 74318628Sralph logent(fo, "CAN'T WRITE"); 74418628Sralph exit(-errno); 74518628Sralph } 74618628Sralph execvp(args[0], args); 74718628Sralph exit(100+errno); 74818628Sralph } 74918628Sralph while ((ret = wait(&status)) != pid && ret != -1) 75018628Sralph ; 75118628Sralph DEBUG(3, "status %d\n", status); 75218628Sralph return status; 75318628Sralph } 754