113697Ssam #ifndef lint 2*25147Sbloom static char sccsid[] = "@(#)uuxqt.c 5.7 (Berkeley) 10/09/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 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 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; 3417846Sralph 3518628Sralph int TransferSucceeded = 1; 3613697Ssam int notiok = 1; 3713697Ssam int nonzero = 0; 3813697Ssam 39*25147Sbloom struct timeb Now; 40*25147Sbloom 4118628Sralph char PATH[MAXFULLNAME] = "PATH=/bin:/usr/bin:/usr/ucb"; 4218628Sralph char Shell[MAXFULLNAME]; 4318628Sralph char HOME[MAXFULLNAME]; 4417846Sralph 4518628Sralph extern char **environ; 4618628Sralph char *nenv[] = { 4718628Sralph PATH, 4818628Sralph Shell, 4918628Sralph HOME, 5018628Sralph 0 5118628Sralph }; 5217846Sralph 5313697Ssam /* to remove restrictions from uuxqt 5413697Ssam * define ALLOK 1 5513697Ssam * 5613697Ssam * to add allowable commands, add to the file CMDFILE 5713697Ssam * A line of form "PATH=..." changes the search path 5813697Ssam */ 5913697Ssam main(argc, argv) 6013697Ssam char *argv[]; 6113697Ssam { 6213697Ssam char xcmd[MAXFULLNAME]; 6313697Ssam int argnok; 6417846Sralph int notiflg; 6517846Sralph char xfile[MAXFULLNAME], user[MAXFULLNAME], buf[BUFSIZ]; 6617846Sralph char lbuf[MAXFULLNAME]; 6713697Ssam char cfile[NAMESIZE], dfile[MAXFULLNAME]; 6813697Ssam char file[NAMESIZE]; 6913697Ssam char fin[MAXFULLNAME], sysout[NAMESIZE], fout[MAXFULLNAME]; 7013697Ssam register FILE *xfp, *fp; 7113697Ssam FILE *dfp; 7213697Ssam char path[MAXFULLNAME]; 7313697Ssam char cmd[BUFSIZ]; 7413697Ssam char *cmdp, prm[1000], *ptr; 7513697Ssam char *getprm(), *lastpart(); 7617846Sralph int uid, ret, ret2, badfiles; 7713697Ssam register int i; 7813697Ssam int stcico = 0; 7918628Sralph time_t xstart, xnow; 8013697Ssam char retstat[30]; 8118628Sralph char **ep; 8213697Ssam 8313697Ssam strcpy(Progname, "uuxqt"); 8413697Ssam uucpname(Myname); 8513697Ssam 8613697Ssam umask(WFMASK); 8713697Ssam Ofn = 1; 8813697Ssam Ifn = 0; 8913697Ssam while (argc>1 && argv[1][0] == '-') { 9013697Ssam switch(argv[1][1]){ 9113697Ssam case 'x': 9217846Sralph chkdebug(); 9313697Ssam Debug = atoi(&argv[1][2]); 9413697Ssam if (Debug <= 0) 9513697Ssam Debug = 1; 9613697Ssam break; 9713697Ssam default: 9813697Ssam fprintf(stderr, "unknown flag %s\n", argv[1]); 9913697Ssam break; 10013697Ssam } 10113697Ssam --argc; argv++; 10213697Ssam } 10313697Ssam 10418628Sralph DEBUG(4, "\n\n** START **\n", CNULL); 10517846Sralph ret = subchdir(Spool); 10617846Sralph ASSERT(ret >= 0, "CHDIR FAILED", Spool, ret); 10713697Ssam strcpy(Wrkdir, Spool); 10813697Ssam uid = getuid(); 10913697Ssam guinfo(uid, User, path); 11017846Sralph setgid(getegid()); 11117846Sralph setuid(geteuid()); 11217846Sralph 11313697Ssam DEBUG(4, "User - %s\n", User); 11423692Sbloom if (ulockf(X_LOCK, X_LOCKTIME) != 0) 11513697Ssam exit(0); 11613697Ssam 11713697Ssam fp = fopen(CMDFILE, "r"); 11813697Ssam if (fp == NULL) { 11917846Sralph logent(CANTOPEN, CMDFILE); 12013697Ssam Cmds[0] = "rmail"; 12113697Ssam Cmds[1] = "rnews"; 12213697Ssam Cmds[2] = "ruusend"; 12313697Ssam Cmds[3] = NULL; 12413697Ssam goto doprocess; 12513697Ssam } 12613697Ssam DEBUG(5, "%s opened\n", CMDFILE); 12717846Sralph for (i=0; i<NCMDS && cfgets(xcmd, sizeof(xcmd), fp) != NULL; i++) { 12817846Sralph int j; 12917846Sralph /* strip trailing whitespace */ 13017846Sralph for (j = strlen(xcmd)-1; j >= 0; --j) 13117846Sralph if (xcmd[j] == '\n' || xcmd[j] == ' ' || xcmd[j] == '\t') 13217846Sralph xcmd[j] = '\0'; 13317846Sralph else 13417846Sralph break; 13517846Sralph /* look for imbedded whitespace */ 13617846Sralph for (; j >= 0; --j) 13717846Sralph if (xcmd[j] == '\n' || xcmd[j] == ' ' || xcmd[j] == '\t') 13817846Sralph break; 13917846Sralph /* skip this entry if it has embedded whitespace */ 14017846Sralph /* This defends against a bad PATH=, for example */ 14117846Sralph if (j >= 0) { 14217846Sralph logent(xcmd, "BAD WHITESPACE"); 14317846Sralph continue; 14417846Sralph } 14513697Ssam if (strncmp(xcmd, "PATH=", 5) == 0) { 14613697Ssam strcpy(PATH, xcmd); 14717846Sralph i--; /*kludge */ 14813697Ssam continue; 14913697Ssam } 15013697Ssam DEBUG(5, "xcmd = %s\n", xcmd); 15117846Sralph 15217846Sralph if ((ptr = index(xcmd, ',')) != NULL) { 15317846Sralph *ptr++ = '\0'; 15417846Sralph if (strncmp(ptr, "Err", 3) == SAME) 15517846Sralph Notify[i] = NT_ERR; 15617846Sralph else if (strcmp(ptr, "No") == SAME) 15717846Sralph Notify[i] = NT_NO; 15817846Sralph else 15917846Sralph Notify[i] = NT_YES; 16017846Sralph } else 16117846Sralph Notify[i] = NT_YES; 16217846Sralph if ((Cmds[i] = malloc((unsigned)(strlen(xcmd)+1))) == NULL) { 16317846Sralph DEBUG(1, "MALLOC FAILED", CNULL); 16417846Sralph break; 16517846Sralph } 16613697Ssam strcpy(Cmds[i], xcmd); 16713697Ssam } 16817846Sralph Cmds[i] = CNULL; 16913697Ssam fclose(fp); 17013697Ssam 17113697Ssam doprocess: 17218628Sralph 17318628Sralph (void) sprintf(HOME, "HOME=%s", Spool); 17418628Sralph (void) sprintf(Shell, "SHELL=%s", SHELL); 17518628Sralph environ = nenv; /* force use if our environment */ 17618628Sralph 17718628Sralph DEBUG(11,"path = %s\n", getenv("PATH")); 17818628Sralph 17917846Sralph DEBUG(4, "process %s\n", CNULL); 18018628Sralph time(&xstart); 18113697Ssam while (gtxfile(xfile) > 0) { 182*25147Sbloom /* if /etc/nologin exists, exit cleanly */ 183*25147Sbloom #if defined(BSD4_2) || defined(USG) 184*25147Sbloom if (access(NOLOGIN) == 0) { 185*25147Sbloom #else !BSD4_2 && ! USG 18617846Sralph ultouch(); 18717846Sralph if (nologinflag) { 188*25147Sbloom #endif !BSD4_2 && !USG 18917846Sralph logent(NOLOGIN, "UUXQT SHUTDOWN"); 19017846Sralph if (Debug) 19117846Sralph logent("debugging", "continuing anyway"); 19217846Sralph else 19317846Sralph break; 19417846Sralph } 19513697Ssam DEBUG(4, "xfile - %s\n", xfile); 19613697Ssam 19713697Ssam xfp = fopen(subfile(xfile), "r"); 19817846Sralph ASSERT(xfp != NULL, CANTOPEN, xfile, 0); 19913697Ssam 20013697Ssam /* initialize to default */ 20113697Ssam strcpy(user, User); 20217846Sralph strcpy(fin, DEVNULL); 20317846Sralph strcpy(fout, DEVNULL); 20423692Sbloom strcpy(sysout, Myname); 20517846Sralph badfiles = 0; 20613697Ssam while (fgets(buf, BUFSIZ, xfp) != NULL) { 20713697Ssam switch (buf[0]) { 20813697Ssam case X_USER: 20917846Sralph sscanf(&buf[1], "%s %s", user, Rmtname); 21013697Ssam break; 21117846Sralph case X_RETURNTO: 21217846Sralph sscanf(&buf[1], "%s", user); 21317846Sralph break; 21413697Ssam case X_STDIN: 21513697Ssam sscanf(&buf[1], "%s", fin); 21613697Ssam i = expfile(fin); 21713697Ssam /* rti!trt: do not check permissions of 21813697Ssam * vanilla spool file */ 21913697Ssam if (i != 0 22013697Ssam && (chkpth("", "", fin) || anyread(fin) != 0)) 22113697Ssam badfiles = 1; 22213697Ssam break; 22313697Ssam case X_STDOUT: 22413697Ssam sscanf(&buf[1], "%s%s", fout, sysout); 22523692Sbloom sysout[MAXBASENAME] = '\0'; 22613697Ssam /* rti!trt: do not check permissions of 22713697Ssam * vanilla spool file. DO check permissions 22813697Ssam * of writing on a non-vanilla file */ 22913697Ssam i = 1; 23013697Ssam if (fout[0] != '~' || prefix(sysout, Myname)) 23113697Ssam i = expfile(fout); 23213697Ssam if (i != 0 23313697Ssam && (chkpth("", "", fout) 23413697Ssam || chkperm(fout, (char *)1))) 23513697Ssam badfiles = 1; 23613697Ssam break; 23713697Ssam case X_CMD: 23813697Ssam strcpy(cmd, &buf[2]); 23913697Ssam if (*(cmd + strlen(cmd) - 1) == '\n') 24013697Ssam *(cmd + strlen(cmd) - 1) = '\0'; 24113697Ssam break; 24213697Ssam case X_NONOTI: 24313697Ssam notiok = 0; 24413697Ssam break; 24513697Ssam case X_NONZERO: 24613697Ssam nonzero = 1; 24713697Ssam break; 24813697Ssam default: 24913697Ssam break; 25013697Ssam } 25113697Ssam } 25213697Ssam 25313697Ssam fclose(xfp); 25413697Ssam DEBUG(4, "fin - %s, ", fin); 25513697Ssam DEBUG(4, "fout - %s, ", fout); 25613697Ssam DEBUG(4, "sysout - %s, ", sysout); 25713697Ssam DEBUG(4, "user - %s\n", user); 25813697Ssam DEBUG(4, "cmd - %s\n", cmd); 25913697Ssam 26013697Ssam /* command execution */ 26117846Sralph if (strcmp(fout, DEVNULL) == SAME) 26217846Sralph strcpy(dfile,DEVNULL); 26313697Ssam else 26413697Ssam gename(DATAPRE, sysout, 'O', dfile); 26513697Ssam 26613697Ssam /* expand file names where necessary */ 26713697Ssam expfile(dfile); 26818628Sralph cmdp = buf; 26913697Ssam ptr = cmd; 27013697Ssam xcmd[0] = '\0'; 27113697Ssam argnok = 0; 27213697Ssam while ((ptr = getprm(ptr, prm)) != NULL) { 27313697Ssam if (prm[0] == ';' || prm[0] == '^' 27413697Ssam || prm[0] == '&' || prm[0] == '|') { 27513697Ssam xcmd[0] = '\0'; 27613697Ssam APPCMD(prm); 27713697Ssam continue; 27813697Ssam } 27913697Ssam 28017846Sralph if ((argnok = argok(xcmd, prm)) != SUCCESS) 28113697Ssam /* command not valid */ 28213697Ssam break; 28313697Ssam 28413697Ssam if (prm[0] == '~') 28513697Ssam expfile(prm); 28613697Ssam APPCMD(prm); 28713697Ssam } 28817846Sralph /* 28917846Sralph * clean up trailing ' ' in command. 29017846Sralph */ 29117846Sralph if (cmdp > buf && cmdp[0] == '\0' && cmdp[-1] == ' ') 29217846Sralph *--cmdp = '\0'; 29318628Sralph if (strpbrk(user, BADCHARS) != NULL) { 29417870Sralph sprintf(lbuf, "%s INVALID CHARACTER IN USERNAME", user); 29517870Sralph logent(cmd, lbuf); 29617870Sralph strcpy(user, "postmaster"); 29717870Sralph } 29813697Ssam if (argnok || badfiles) { 29913697Ssam sprintf(lbuf, "%s XQT DENIED", user); 30013697Ssam logent(cmd, lbuf); 30113697Ssam DEBUG(4, "bad command %s\n", prm); 30213697Ssam notify(user, Rmtname, cmd, "DENIED"); 30313697Ssam goto rmfiles; 30413697Ssam } 30513697Ssam sprintf(lbuf, "%s XQT", user); 30613697Ssam logent(buf, lbuf); 30713697Ssam DEBUG(4, "cmd %s\n", buf); 30813697Ssam 30913697Ssam mvxfiles(xfile); 31017846Sralph ret = subchdir(XQTDIR); 31117846Sralph ASSERT(ret >= 0, "CHDIR FAILED", XQTDIR, ret); 31218628Sralph ret = shio(buf, fin, dfile); 31313697Ssam sprintf(retstat, "signal %d, exit %d", ret & 0377, 31413697Ssam (ret>>8) & 0377); 31513697Ssam if (strcmp(xcmd, "rmail") == SAME) 31613697Ssam notiok = 0; 31713697Ssam if (strcmp(xcmd, "rnews") == SAME) 31813697Ssam nonzero = 1; 31917846Sralph notiflg = chknotify(xcmd); 32017846Sralph if (notiok && notiflg != NT_NO && 32117846Sralph (ret != 0 || (!nonzero && notiflg == NT_YES))) 32213697Ssam notify(user, Rmtname, cmd, retstat); 32313697Ssam else if (ret != 0 && strcmp(xcmd, "rmail") == SAME) { 32413697Ssam /* mail failed - return letter to sender */ 32517846Sralph #ifdef DANGEROUS 32617846Sralph /* NOT GUARANTEED SAFE!!! */ 32717846Sralph if (!nonzero) 32817846Sralph retosndr(user, Rmtname, fin); 32917846Sralph #else 33017846Sralph notify(user, Rmtname, cmd, retstat); 33117846Sralph #endif 33217846Sralph sprintf(buf, "%s (%s) from %s!%s", buf, retstat, Rmtname, user); 33313697Ssam logent("MAIL FAIL", buf); 33413697Ssam } 33513697Ssam DEBUG(4, "exit cmd - %d\n", ret); 33617846Sralph ret2 = subchdir(Spool); 33717846Sralph ASSERT(ret2 >= 0, "CHDIR FAILED", Spool, ret); 33813697Ssam rmxfiles(xfile); 33913697Ssam if (ret != 0) { 34013697Ssam /* exit status not zero */ 34113697Ssam dfp = fopen(subfile(dfile), "a"); 34217846Sralph ASSERT(dfp != NULL, CANTOPEN, dfile, 0); 34313697Ssam fprintf(dfp, "exit status %d", ret); 34413697Ssam fclose(dfp); 34513697Ssam } 34617846Sralph if (strcmp(fout, DEVNULL) != SAME) { 34713697Ssam if (prefix(sysout, Myname)) { 34813697Ssam xmv(dfile, fout); 34913697Ssam chmod(fout, BASEMODE); 35018628Sralph } else { 35117846Sralph char *cp = rindex(user, '!'); 35213697Ssam gename(CMDPRE, sysout, 'O', cfile); 35313697Ssam fp = fopen(subfile(cfile), "w"); 35413697Ssam ASSERT(fp != NULL, "OPEN", cfile, 0); 35517846Sralph fprintf(fp, "S %s %s %s - %s 0666\n", dfile, 35617846Sralph fout, cp ? cp : user, lastpart(dfile)); 35713697Ssam fclose(fp); 35813697Ssam } 35913697Ssam } 36013697Ssam rmfiles: 36113697Ssam xfp = fopen(subfile(xfile), "r"); 36217846Sralph ASSERT(xfp != NULL, CANTOPEN, xfile, 0); 36313697Ssam while (fgets(buf, BUFSIZ, xfp) != NULL) { 36413697Ssam if (buf[0] != X_RQDFILE) 36513697Ssam continue; 36613697Ssam sscanf(&buf[1], "%s", file); 36713697Ssam unlink(subfile(file)); 36813697Ssam } 36913697Ssam unlink(subfile(xfile)); 37013697Ssam fclose(xfp); 37118628Sralph 37218628Sralph /* rescan X. for new work every RECHECKTIME seconds */ 37318628Sralph time(&xnow); 37418628Sralph if (xnow > (xstart + RECHECKTIME)) { 37518628Sralph extern int Nfiles; 37618628Sralph Nfiles = 0; /*force rescan for new work */ 37718628Sralph } 37818628Sralph xstart = xnow; 37913697Ssam } 38013697Ssam 38113697Ssam if (stcico) 38213697Ssam xuucico(""); 38313697Ssam cleanup(0); 38413697Ssam } 38513697Ssam 38613697Ssam 38713697Ssam cleanup(code) 38813697Ssam int code; 38913697Ssam { 39013697Ssam logcls(); 39113697Ssam rmlock(CNULL); 39217846Sralph #ifdef VMS 39317846Sralph /* 39417846Sralph * Since we run as a BATCH job we must wait for all processes to 39517846Sralph * to finish 39617846Sralph */ 39718628Sralph while(wait(0) != -1) 39818628Sralph ; 39917846Sralph #endif VMS 40013697Ssam exit(code); 40113697Ssam } 40213697Ssam 40313697Ssam 40418628Sralph /* 40518628Sralph * get a file to execute 40613697Ssam * 40713697Ssam * return codes: 0 - no file | 1 - file to execute 40813697Ssam */ 40913697Ssam 41013697Ssam gtxfile(file) 41113697Ssam register char *file; 41213697Ssam { 41313697Ssam char pre[3]; 41417846Sralph int rechecked; 41517846Sralph time_t ystrdy; /* yesterday */ 41617846Sralph struct stat stbuf; /* for X file age */ 41713697Ssam 41813697Ssam pre[0] = XQTPRE; 41913697Ssam pre[1] = '.'; 42013697Ssam pre[2] = '\0'; 42113697Ssam rechecked = 0; 42213697Ssam retry: 42313697Ssam if (!gtwrkf(Spool, file)) { 42413697Ssam if (rechecked) 42517846Sralph return 0; 42613697Ssam rechecked = 1; 42717846Sralph DEBUG(4, "iswrk\n", CNULL); 42813697Ssam if (!iswrk(file, "get", Spool, pre)) 42917846Sralph return 0; 43013697Ssam } 43113697Ssam DEBUG(4, "file - %s\n", file); 43213697Ssam /* skip spurious subdirectories */ 43313697Ssam if (strcmp(pre, file) == SAME) 43413697Ssam goto retry; 43513697Ssam if (gotfiles(file)) 43617846Sralph return 1; 43717846Sralph /* check for old X. file with no work files and remove them. */ 43817846Sralph if (Nfiles > LLEN/2) { 43917846Sralph time(&ystrdy); 44017846Sralph ystrdy -= (4 * 3600L); /* 4 hours ago */ 44117846Sralph DEBUG(4, "gtxfile: Nfiles > LLEN/2\n", CNULL); 44217846Sralph while (gtwrkf(Spool, file) && !gotfiles(file)) { 44317846Sralph if (stat(subfile(file), &stbuf) == 0) 44417846Sralph if (stbuf.st_mtime <= ystrdy) { 44517846Sralph char *bnp, cfilename[NAMESIZE]; 44617846Sralph DEBUG(4, "gtxfile: move %s to CORRUPT \n", file); 44717846Sralph unlink(subfile(file)); 44817846Sralph bnp = rindex(subfile(file), '/'); 44917846Sralph sprintf(cfilename, "%s/%s", CORRUPT, 45017846Sralph bnp ? bnp + 1 : subfile(file)); 45117846Sralph xmv(subfile(file), cfilename); 45217846Sralph logent(file, "X. FILE CORRUPTED"); 45317846Sralph } 45417846Sralph } 45517846Sralph DEBUG(4, "iswrk\n", CNULL); 45617846Sralph if (!iswrk(file, "get", Spool, pre)) 45717846Sralph return 0; 45817846Sralph } 45913697Ssam goto retry; 46013697Ssam } 46113697Ssam 46218628Sralph /* 46318628Sralph * check for needed files 46413697Ssam * 46513697Ssam * return codes: 0 - not ready | 1 - all files ready 46613697Ssam */ 46713697Ssam 46813697Ssam gotfiles(file) 46913697Ssam register char *file; 47013697Ssam { 47113697Ssam struct stat stbuf; 47213697Ssam register FILE *fp; 47313697Ssam char buf[BUFSIZ], rqfile[MAXFULLNAME]; 47413697Ssam 47513697Ssam fp = fopen(subfile(file), "r"); 47613697Ssam if (fp == NULL) 47717846Sralph return 0; 47813697Ssam 47913697Ssam while (fgets(buf, BUFSIZ, fp) != NULL) { 48013697Ssam DEBUG(4, "%s\n", buf); 48113697Ssam if (buf[0] != X_RQDFILE) 48213697Ssam continue; 48313697Ssam sscanf(&buf[1], "%s", rqfile); 48413697Ssam expfile(rqfile); 48513697Ssam if (stat(subfile(rqfile), &stbuf) == -1) { 48613697Ssam fclose(fp); 48717846Sralph return 0; 48813697Ssam } 48913697Ssam } 49013697Ssam 49113697Ssam fclose(fp); 49217846Sralph return 1; 49313697Ssam } 49413697Ssam 49513697Ssam 49618628Sralph /* 49718628Sralph * remove execute files to x-directory 49813697Ssam */ 49913697Ssam 50013697Ssam rmxfiles(xfile) 50113697Ssam register char *xfile; 50213697Ssam { 50313697Ssam register FILE *fp; 50413697Ssam char buf[BUFSIZ], file[NAMESIZE], tfile[NAMESIZE]; 50513697Ssam char tfull[MAXFULLNAME]; 50613697Ssam 50713697Ssam if((fp = fopen(subfile(xfile), "r")) == NULL) 50813697Ssam return; 50913697Ssam 51013697Ssam while (fgets(buf, BUFSIZ, fp) != NULL) { 51113697Ssam if (buf[0] != X_RQDFILE) 51213697Ssam continue; 51313697Ssam if (sscanf(&buf[1], "%s%s", file, tfile) < 2) 51413697Ssam continue; 51513697Ssam sprintf(tfull, "%s/%s", XQTDIR, tfile); 51613697Ssam unlink(subfile(tfull)); 51713697Ssam } 51813697Ssam fclose(fp); 51913697Ssam return; 52013697Ssam } 52113697Ssam 52213697Ssam 52318628Sralph /* 52418628Sralph * move execute files to x-directory 52513697Ssam */ 52613697Ssam 52713697Ssam mvxfiles(xfile) 52813697Ssam char *xfile; 52913697Ssam { 53013697Ssam register FILE *fp; 53113697Ssam char buf[BUFSIZ], ffile[MAXFULLNAME], tfile[NAMESIZE]; 53213697Ssam char tfull[MAXFULLNAME]; 53313697Ssam int ret; 53413697Ssam 53513697Ssam if((fp = fopen(subfile(xfile), "r")) == NULL) 53613697Ssam return; 53713697Ssam 53813697Ssam while (fgets(buf, BUFSIZ, fp) != NULL) { 53913697Ssam if (buf[0] != X_RQDFILE) 54013697Ssam continue; 54113697Ssam if (sscanf(&buf[1], "%s%s", ffile, tfile) < 2) 54213697Ssam continue; 54313697Ssam expfile(ffile); 54413697Ssam sprintf(tfull, "%s/%s", XQTDIR, tfile); 54513697Ssam unlink(subfile(tfull)); 54613697Ssam ret = xmv(ffile, tfull); 54717846Sralph ASSERT(ret == 0, "XQTDIR ERROR", CNULL, ret); 54813697Ssam } 54913697Ssam fclose(fp); 55013697Ssam } 55113697Ssam 55218628Sralph /* 55318628Sralph * check for valid command/argument 55418628Sralph * *NOTE - side effect is to set xc to the command to be executed. 55513697Ssam * 55613697Ssam * return 0 - ok | 1 nok 55713697Ssam */ 55813697Ssam 55913697Ssam argok(xc, cmd) 56013697Ssam register char *xc, *cmd; 56113697Ssam { 56213697Ssam register char **ptr; 56313697Ssam 56413697Ssam #ifndef ALLOK 56518628Sralph if (strpbrk(cmd, BADCHARS) != NULL) { 56617846Sralph DEBUG(1,"MAGIC CHARACTER FOUND\n", CNULL); 56718628Sralph logent(cmd, "NASTY MAGIC CHARACTER FOUND"); 56817846Sralph return FAIL; 56917846Sralph } 57017846Sralph #endif !ALLOK 57113697Ssam 57213697Ssam if (xc[0] != '\0') 57317846Sralph return SUCCESS; 57413697Ssam 57513697Ssam #ifndef ALLOK 57613697Ssam ptr = Cmds; 57717846Sralph DEBUG(9, "Compare %s and\n", cmd); 57813697Ssam while(*ptr != NULL) { 57917846Sralph DEBUG(9, "\t%s\n", *ptr); 58013697Ssam if (strcmp(cmd, *ptr) == SAME) 58113697Ssam break; 58217846Sralph ptr++; 58313697Ssam } 58417846Sralph if (*ptr == NULL) { 58517846Sralph DEBUG(1,"COMMAND NOT FOUND\n", CNULL); 58617846Sralph return FAIL; 58717846Sralph } 58813697Ssam #endif 58913697Ssam strcpy(xc, cmd); 59017846Sralph DEBUG(9, "MATCHED %s\n", xc); 59117846Sralph return SUCCESS; 59213697Ssam } 59313697Ssam 59413697Ssam 59518628Sralph /* 59618628Sralph * if notification should be sent for successful execution of cmd 59717846Sralph * 59817846Sralph * return NT_YES - do notification 59917846Sralph * NT_ERR - do notification if exit status != 0 60017846Sralph * NT_NO - don't do notification ever 60117846Sralph */ 60217846Sralph 60317846Sralph chknotify(cmd) 60417846Sralph char *cmd; 60517846Sralph { 60617846Sralph register char **ptr; 60717846Sralph register int *nptr; 60817846Sralph 60917846Sralph ptr = Cmds; 61017846Sralph nptr = Notify; 61117846Sralph while (*ptr != NULL) { 61217846Sralph if (strcmp(cmd, *ptr) == SAME) 61317846Sralph return *nptr; 61417846Sralph ptr++; 61517846Sralph nptr++; 61617846Sralph } 61717846Sralph return NT_YES; /* "shouldn't happen" */ 61817846Sralph } 61917846Sralph 62017846Sralph 62117846Sralph 62218628Sralph /* 62318628Sralph * send mail to user giving execution results 62413697Ssam */ 62513697Ssam 62613697Ssam notify(user, rmt, cmd, str) 62713697Ssam char *user, *rmt, *cmd, *str; 62813697Ssam { 62913697Ssam char text[MAXFULLNAME]; 63013697Ssam char ruser[MAXFULLNAME]; 63113697Ssam 63217846Sralph sprintf(text, "uuxqt cmd (%s) status (%s)", cmd, str); 63313697Ssam if (prefix(rmt, Myname)) 63413697Ssam strcpy(ruser, user); 63513697Ssam else 63613697Ssam sprintf(ruser, "%s!%s", rmt, user); 63717846Sralph mailst(ruser, text, CNULL); 63813697Ssam return; 63913697Ssam } 64013697Ssam 64118628Sralph /* 64218628Sralph * return mail to sender 64313697Ssam * 64413697Ssam */ 64513697Ssam 64613697Ssam retosndr(user, rmt, file) 64713697Ssam char *user, *rmt, *file; 64813697Ssam { 64917846Sralph char ruser[MAXFULLNAME]; 65013697Ssam 65113697Ssam if (strcmp(rmt, Myname) == SAME) 65213697Ssam strcpy(ruser, user); 65313697Ssam else 65413697Ssam sprintf(ruser, "%s!%s", rmt, user); 65513697Ssam 65613697Ssam if (anyread(file) == 0) 65713697Ssam mailst(ruser, "Mail failed. Letter returned to sender.\n", file); 65813697Ssam else 65917846Sralph mailst(ruser, "Mail failed. Letter returned to sender.\n", CNULL); 66013697Ssam return; 66113697Ssam } 66217870Sralph 66317870Sralph /* 66418628Sralph * execute shell of command with fi and fo as standard input/output 66518628Sralph */ 66618628Sralph 66718628Sralph shio(cmd, fi, fo) 66818628Sralph char *cmd, *fi, *fo; 66918628Sralph { 67018628Sralph int status, f; 67118628Sralph int uid, pid, ret; 67218628Sralph char path[MAXFULLNAME]; 67318628Sralph char *args[20]; 67418628Sralph extern int errno; 67518628Sralph 67618628Sralph if (fi == NULL) 67718628Sralph fi = DEVNULL; 67818628Sralph if (fo == NULL) 67918628Sralph fo = DEVNULL; 68018628Sralph 68118628Sralph getargs(cmd, args, 20); 68218628Sralph DEBUG(3, "shio - %s\n", cmd); 68318628Sralph #ifdef SIGCHLD 68418628Sralph signal(SIGCHLD, SIG_IGN); 68518628Sralph #endif SIGCHLD 68618628Sralph if ((pid = fork()) == 0) { 68718628Sralph signal(SIGINT, SIG_IGN); 68818628Sralph signal(SIGHUP, SIG_IGN); 68918628Sralph signal(SIGQUIT, SIG_IGN); 69018628Sralph close(Ifn); 69118628Sralph close(Ofn); 69218628Sralph close(0); 69318628Sralph setuid(getuid()); 69418628Sralph f = open(subfile(fi), 0); 69518628Sralph if (f != 0) { 69618628Sralph logent(fi, "CAN'T READ"); 69718628Sralph exit(-errno); 69818628Sralph } 69918628Sralph close(1); 70018628Sralph f = creat(subfile(fo), 0666); 70118628Sralph if (f != 1) { 70218628Sralph logent(fo, "CAN'T WRITE"); 70318628Sralph exit(-errno); 70418628Sralph } 70518628Sralph execvp(args[0], args); 70618628Sralph exit(100+errno); 70718628Sralph } 70818628Sralph while ((ret = wait(&status)) != pid && ret != -1) 70918628Sralph ; 71018628Sralph DEBUG(3, "status %d\n", status); 71118628Sralph return status; 71218628Sralph } 713