BSD 3 development
[unix-history] / usr / src / cmd / uucp / uuxqt.c
CommitLineData
607ab998
BJ
1#include "uucp.h"
2#include "uucpdefs.h"
3#include <sys/types.h>
4#include <sys/stat.h>
5#include <sys/dir.h>
6
7#define APPCMD(d) {\
8char *p;\
9for (p = d; *p != '\0';) *cmdp++ = *p++;\
10*cmdp++ = ' ';\
11*cmdp = '\0';}
12
13/*
14 * uuxqt will execute commands set up by a uux command,
15 * usually from a remote machine - set by uucp.
16 */
17
18char *Cmds[] = {
19 "rmail",
20 "lpr",
21 "opr",
22 "fsend",
23 "fget",
24 NULL
25 };
26#define PATH "PATH=/bin:/usr/bin;"
27/* to remove restrictions from uuxqt
28 * define ALLOK 1
29 *
30 * to add allowable commands, add to the list under Cmds[]
31 */
32
33main(argc, argv)
34char *argv[];
35{
36 char xcmd[100];
37 int cmdnok;
38 char xfile[MAXFULLNAME], user[10], buf[BUFSIZ];
39 char lbuf[30];
40 char cfile[NAMESIZE], dfile[MAXFULLNAME];
41 char file[NAMESIZE];
42 char fin[MAXFULLNAME], sysout[NAMESIZE], fout[MAXFULLNAME];
43 FILE *xfp, *dfp, *fp;
44 char path[MAXFULLNAME];
45 char cmd[BUFSIZ];
46 char *cmdp, prm[MAXFULLNAME], *ptr;
47 char *getprm();
48 int uid, ret;
49 int stcico = 0;
50 char rnum[5];
51
52 uucpname(Myname);
53 Ofn = 1;
54 Ifn = 0;
55 while (argc>1 && argv[1][0] == '-') {
56 switch(argv[1][1]){
57 case 'x':
58 Debug = atoi(&argv[1][2]);
59 if (Debug <= 0)
60 Debug = 1;
61 break;
62 default:
63 sprintf(stderr, "unknown flag %s\n", argv[1]);
64 break;
65 }
66 --argc; argv++;
67 }
68
69 DEBUG(4, "\n\n** %s **\n", "START");
70 chdir(Spool);
71 strcpy(Wrkdir, Spool);
72 uid = getuid();
73 guinfo(uid, User, path);
74 DEBUG(4, "User - %s\n", User);
75 if (ulockf(X_LOCK, X_LOCKTIME) != 0)
76 exit(0);
77
78 DEBUG(4, "process %s\n", "");
79 while (gtxfile(xfile) > 0) {
80 DEBUG(4, "xfile - %s\n", xfile);
81
82 xfp = fopen(xfile, "r");
83 ASSERT(xfp != NULL, "CAN'T OPEN %s", xfile);
84
85 /* initialize to default */
86 strcpy(user, User);
87 strcpy(fin, "/dev/null");
88 strcpy(fout, "/dev/null");
89 sprintf(sysout, "%.7s", Myname);
90 while (fgets(buf, BUFSIZ, xfp) != NULL) {
91 switch (buf[0]) {
92 case X_USER:
93 sscanf(&buf[1], "%s%s", user, Rmtname);
94 break;
95 case X_STDIN:
96 sscanf(&buf[1], "%s", fin);
97 expfile(fin);
98 break;
99 case X_STDOUT:
100 sscanf(&buf[1], "%s%s", fout, sysout);
101 sysout[7] = '\0';
102 if (fout[0] != '~' || prefix(sysout, Myname))
103 expfile(fout);
104 break;
105 case X_CMD:
106 strcpy(cmd, &buf[2]);
107 if (*(cmd + strlen(cmd) - 1) == '\n')
108 *(cmd + strlen(cmd) - 1) = '\0';
109 break;
110 default:
111 break;
112 }
113 }
114
115 fclose(xfp);
116 DEBUG(4, "fin - %s, ", fin);
117 DEBUG(4, "fout - %s, ", fout);
118 DEBUG(4, "sysout - %s, ", sysout);
119 DEBUG(4, "user - %s\n", user);
120 DEBUG(4, "cmd - %s\n", cmd);
121
122 /* command execution */
123 if (strcmp(fout, "/dev/null") == SAME)
124 strcpy(dfile,"/dev/null");
125 else
126 gename(DATAPRE, sysout, 'O', dfile);
127
128 /* expand file names where necessary */
129 expfile(dfile);
130 strcpy(buf, PATH);
131 cmdp = buf + strlen(buf);
132 ptr = cmd;
133 xcmd[0] = '\0';
134 cmdnok = 0;
135 while ((ptr = getprm(ptr, prm)) != NULL) {
136 if (prm[0] == ';' || prm[0] == '^'
137 || prm[0] == '|') {
138 xcmd[0] = '\0';
139 APPCMD(prm);
140 continue;
141 }
142 if ((cmdnok = cmdok(xcmd, prm)) != 0)
143 /* command not valid */
144 break;
145
146 if (prm[0] == '~')
147 expfile(prm);
148 APPCMD(prm);
149 }
150 if (cmdnok) {
151 sprintf(lbuf, "%s XQT DENIED", user);
152 logent(cmd, lbuf);
153 DEBUG(4, "bad command %s\n", prm);
154 notify(user, Rmtname, cmd, "DENIED");
155 goto rmfiles;
156 }
157 sprintf(lbuf, "%s XQT", user);
158 logent(buf, lbuf);
159 DEBUG(4, "cmd %s\n", buf);
160
161 mvxfiles(xfile);
162 chdir(XQTDIR);
163 ret = shio(buf, fin, dfile, user);
164 sprintf(rnum, "%d", ret);
165 if (strcmp(xcmd, "rmail") != SAME
166 && strcmp(xcmd, "mail") != SAME)
167 notify(user, Rmtname, cmd, rnum);
168 DEBUG(4, "exit cmd - %d\n", ret);
169 chdir(Spool);
170 rmxfiles(xfile);
171 if (ret != 0) {
172 /* exit status not zero */
173 dfp = fopen(dfile, "a");
174 ASSERT(dfp != NULL, "CAN'T OPEN %s", dfile);
175 fprintf(dfp, "exit status %d", ret);
176 fclose(dfp);
177 }
178 if (strcmp(fout, "/dev/null") != SAME) {
179 if (prefix(sysout, Myname)) {
180 xmv(dfile, fout);
181 }
182 else {
183 gename(CMDPRE, sysout, 'O', cfile);
184 fp = fopen(cfile, "w");
185 ASSERT(fp != NULL, "OPEN %s", cfile);
186 chmod(cfile, 0666);
187 fprintf(fp, "S %s %s %s - %s 0666\n",
188 dfile, fout, user, lastpart(dfile));
189 fclose(fp);
190 }
191 }
192 rmfiles:
193 xfp = fopen(xfile, "r");
194 ASSERT(xfp != NULL, "CAN'T OPEN %s", xfile);
195 while (fgets(buf, BUFSIZ, xfp) != NULL) {
196 if (buf[0] != X_RQDFILE)
197 continue;
198 sscanf(&buf[1], "%s", file);
199 unlink(file);
200 }
201 unlink(xfile);
202 }
203
204 if (stcico)
205 xuucico("");
206 cleanup(0);
207}
208
209
210cleanup(code)
211int code;
212{
213 logcls();
214 rmlock(NULL);
215 exit(code);
216}
217
218
219/*******
220 * gtxfile(file) get a file to execute
221 * char *file;
222 *
223 * return codes: 0 - no file | 1 - file to execute
224 */
225
226gtxfile(file)
227char *file;
228{
229 static FILE *pdir;
230 char pre[2];
231
232 if (pdir == NULL) {
233 pdir = fopen(Spool, "r");
234 ASSERT(pdir != NULL, "GTXFILE CAN'T OPEN %s", Spool);
235 }
236
237 pre[0] = XQTPRE;
238 pre[1] = '\0';
239 while (gnamef(pdir, file) != 0) {
240 DEBUG(4, "file - %s\n", file);
241 if (!prefix(pre, file))
242 continue;
243 if (gotfiles(file))
244 /* return file to execute */
245 return(1);
246 }
247
248 fclose(pdir);
249 return(0);
250}
251
252
253/***
254 * gotfiles(file) check for needed files
255 * char *file;
256 *
257 * return codes: 0 - not ready | 1 - all files ready
258 */
259
260gotfiles(file)
261char *file;
262{
263 struct stat stbuf;
264 FILE *fp;
265 char buf[BUFSIZ], rqfile[MAXFULLNAME];
266
267 fp = fopen(file, "r");
268 if (fp == NULL)
269 return(0);
270
271 while (fgets(buf, BUFSIZ, fp) != NULL) {
272 DEBUG(4, "%s\n", buf);
273 if (buf[0] != X_RQDFILE)
274 continue;
275 sscanf(&buf[1], "%s", rqfile);
276 expfile(rqfile);
277 if (stat(rqfile, &stbuf) == -1) {
278 fclose(fp);
279 return(0);
280 }
281 }
282
283 fclose(fp);
284 return(1);
285}
286
287
288/***
289 * rmxfiles(xfile) remove execute files to x-directory
290 * char *xfile;
291 *
292 * return codes - none
293 */
294
295rmxfiles(xfile)
296char *xfile;
297{
298 FILE *fp;
299 char buf[BUFSIZ], file[NAMESIZE], tfile[NAMESIZE];
300 char tfull[MAXFULLNAME];
301
302 if((fp = fopen(xfile, "r")) == NULL)
303 return;
304
305 while (fgets(buf, BUFSIZ, fp) != NULL) {
306 if (buf[0] != X_RQDFILE)
307 continue;
308 if (sscanf(&buf[1], "%s%s", file, tfile) < 2)
309 continue;
310 sprintf(tfull, "%s/%s", XQTDIR, tfile);
311 unlink(tfull);
312 }
313 fclose(fp);
314 return;
315}
316
317
318/***
319 * mvxfiles(xfile) move execute files to x-directory
320 * char *xfile;
321 *
322 * return codes - none
323 */
324
325mvxfiles(xfile)
326char *xfile;
327{
328 FILE *fp;
329 char buf[BUFSIZ], ffile[MAXFULLNAME], tfile[NAMESIZE];
330 char tfull[MAXFULLNAME];
331 int ret;
332
333 if((fp = fopen(xfile, "r")) == NULL)
334 return;
335
336 while (fgets(buf, BUFSIZ, fp) != NULL) {
337 if (buf[0] != X_RQDFILE)
338 continue;
339 if (sscanf(&buf[1], "%s%s", ffile, tfile) < 2)
340 continue;
341 expfile(ffile);
342 sprintf(tfull, "%s/%s", XQTDIR, tfile);
343 unlink(tfull);
344 ret = link(ffile, tfull);
345 ASSERT(ret == 0, "LINK RET-%d", ret);
346 unlink(ffile);
347 }
348 fclose(fp);
349 return;
350}
351
352
353/***
354 * cmdok(xc, cmd) check for valid command
355 * *NOTE - side effect is to set xc to the
356 * command to be executed.
357 * char *xc, *cmd;
358 *
359 * return 0 - ok | 1 nok
360 */
361
362cmdok(xc, cmd)
363char *xc, *cmd;
364{
365 char **ptr;
366
367 if (xc[0] != '\0')
368 return(0);
369#ifndef ALLOK
370 ptr = Cmds;
371 while(*ptr != NULL) {
372 if (strcmp(cmd, *ptr) == SAME)
373 break;
374 ptr++;
375 }
376 if (*ptr == NULL)
377 return(1);
378#endif
379 strcpy(xc, cmd);
380 return(0);
381}
382
383
384/***
385 * notify send mail to user giving execution results
386 * return code - none
387 * This program assumes new mail command - send remote mail
388 */
389
390notify(user, rmt, cmd, str)
391char *user, *rmt, *cmd, *str;
392{
393 char text[100];
394 char ruser[100];
395
396 sprintf(text, "uuxqt cmd (%s) status (%s)", cmd, str);
397 if (prefix(rmt, Myname))
398 strcpy(ruser, user);
399 else
400 sprintf(ruser, "%s!%s", rmt, user);
401 mailst(ruser, text);
402 return;
403}