|
|
1.1 root 1: /*
2: * uux.c
3: *
4: * Execute commands on a remote system.
5: *
6: * Peter S. Housel ([email protected])
7: * changes copyright (c) 1989-1991 by Mark Williams Company
8: */
9:
10: #include <stdio.h>
11: #include <signal.h>
12: #include <ctype.h>
13: #include "dcp.h"
14:
15: #define DEFGRADE 'a' /* or whatever */
16:
17: extern int getopt();
18: extern int optind;
19: extern char *optarg;
20: extern char *index(/* char *string, char c */);
21: extern char *rindex(/* char *string, char c */);
22: extern char *mktemp(/* char *template */);
23: extern char *strtok();
24: extern FILE *fopen();
25:
26: void usage(), dostdin(), doarg();
27: char *uucpname(), *whoami();
28: char *filesite(/* char *filename */), *filepath(/* char *filename */);
29: char *basename(/* char *filename */);
30: extern int getseq();
31: int debug = 0;
32:
33: char tempname[] = "/usr/spool/uucp/TM.XXXXXX";
34: char luser[512]; /* local user name */
35: char mysite[SITELEN]; /* this host's uucpname */
36: char cmdsite[SITELEN]; /* site where command is run */
37: char cmd[64]; /* remote command name */
38: char arglist[2048] = ""; /* remote argument list */
39: FILE *commandfile; /* the "C." spool command file */
40: FILE *execfile; /* the "X." remote spool execute file */
41: char grade = DEFGRADE; /* transfer grade */
42: int local = 0;
43: int nocico = 0; /* "don't run uucico" flag */
44: int trylink = 0; /* try spoolfile links before copying */
45: int readstdin = 0; /* read standard input ("-" or "-p") */
46: int notifyfail = 1;
47: int notifysucceed = 0; /* notify succeed */
48: char directory [40] = SPOOLDIR;
49: char subdirectory [60];
50: int output = 0;
51: int input = 0;
52: #define ARGBUFSZ 1024
53: char argbuf[ARGBUFSZ];
54: char onearg[ARGBUFSZ];
55: char *rmtname = NULL;
56:
57: main(argc, argv)
58: int argc;
59: char *argv[];
60: {
61: int c; /* option character */
62: int seq; /* 'seq number' of X. file */
63: static char scratch[256]; /* ubiquitous scratch buffer */
64: char *p; /* equally ubiquitous scratch pointer */
65: char *arg;
66: register int (*intfun)(), (*quitfun)();
67:
68: strcpy(mysite, uucpname());
69: if (strlen(mysite) == 0) {
70: fprintf(stderr, "uux: can't get my own uucpname\n");
71: exit(1);
72: }
73: strcpy(luser, whoami());
74: while( (c=getopt(argc, argv, "a:bcCg:jnprS:s:vVx:z")) != EOF ) {
75: switch(c) {
76: case 'a':
77: strcpy(luser, optarg);
78: break;
79: case 'b':
80: case 'c':
81: case 'C':
82: notsup(c);
83: break;
84: case 'g':
85: if (isalnum(optarg[0]) && '\0' == optarg[1])
86: grade = optarg[0];
87: else
88: fprintf(stderr,
89: "uux: %s: illegal grade\n", optarg);
90: break;
91: case 'j':
92: notsup(c);
93: break;
94: case 'r':
95: nocico = 1;
96: break;
97: case 'n':
98: notifyfail = 0;
99: break;
100: case 'p':
101: readstdin = 1;
102: break;
103: case 's':
104: notsup(c);
105: break;
106: case 'S':
107: strcpy(directory, optarg);
108: fprintf(stderr, "Debug directory is %s\n", directory);
109: break;
110: case 'x':
111: debug = atoi (optarg);
112: fprintf (stderr, "debug is %d\n", debug);
113: fprintf(stderr, "uux version %s\n", VERSION);
114: break;
115: case 'v':
116: case 'V':
117: fatal("uux: Version %s", VERSION);
118: case 'z':
119: notifysucceed = 1;
120: break;
121: default:
122: usage();
123: exit(1);
124: }
125: }
126: if (optind < argc && strcmp(argv[optind], "-") == 0) {
127: ++optind;
128: readstdin = 1;
129: }
130: if (optind >= argc) {
131: usage();
132: exit(1);
133: }
134: if (NULL == (p = filesite(argv[optind]))) {
135: fprintf(stderr, "uux: illegal command\n");
136: exit(1);
137: }
138: strcpy(cmdsite, p);
139: if (NULL == (p = filepath(argv[optind]))) {
140: fprintf(stderr, "uux: illegal command\n");
141: exit(1);
142: }
143: strcpy(cmd, p);
144: ++optind;
145: local = 0;
146: if (strlen(cmdsite) == 0) {
147: local = 1;
148: } else if (!knowhost(cmdsite)) {
149: fprintf(stderr, "uux: site %s unknown\n", cmdsite);
150: exit(1);
151: }
152: if (local == 0) {
153: if (NULL == (commandfile = fopen(mktemp(tempname), "w"))) {
154: fprintf(stderr, "uux: can't open ");
155: perror(tempname);
156: exit(1);
157: }
158: }
159: sprintf(subdirectory, "%s/%s", directory, cmdsite);
160: if (!ckdir(subdirectory)) {
161: fprintf(stderr, "Unable to create directory %s\n",
162: subdirectory);
163: exit (1);
164: }
165: intfun = signal(SIGINT, SIG_IGN);
166: quitfun = signal(SIGQUIT, SIG_IGN);
167: seq = getseq(cmdsite);
168: if (local == 0)
169: sprintf(scratch, "%s/%s/D.%.*s%c%04d", directory,
170: cmdsite, SITESIG, mysite, 'X', seq);
171: else
172: sprintf(scratch, "%s/%s/X.%.*s%c%04d", directory,
173: mysite, SITESIG, mysite, 'X', seq);
174: if (debug > 1)
175: fprintf(stderr, "command path is %s\n", scratch);
176: if ((execfile = fopen(scratch, "w")) == NULL) {
177: fprintf(stderr, "uux: can't open execfile for output: ");
178: perror(scratch);
179: exit(1);
180: }
181: rmtname = &cmdsite[0];
182: open_the_logfile("uux");
183: if (readstdin)
184: dostdin();
185: strcpy(argbuf, "");
186: while (optind < argc) {
187: arg = argv[optind++];
188: if ((strlen(arg) + strlen(argbuf) + 2) > ARGBUFSZ) {
189: fprintf(stderr, "Argument list too long\n");
190: exit(1);
191: }
192: strcat(argbuf, " ");
193: strcat(argbuf, arg);
194: }
195: plog(M_INFO, "%s!%s %s", cmdsite, cmd, argbuf);
196: processargs();
197:
198: if (local == 0) {
199: fprintf(commandfile,
200: "S D.%.*s%c%04d X.%.*s%c%04d %s - D.%.*s%c%04d 0666\n",
201: SITESIG, mysite, 'X', seq, SITESIG, mysite, 'X', seq, luser,
202: SITESIG, mysite, 'X', seq);
203: }
204: plog(M_INFO, "user: %s site %s %s", luser, mysite,
205: notifyfail ? "notifyfail" : "");
206: fprintf(execfile, "U %s %s\nR %s\n", luser, mysite, luser);
207: if (notifyfail)
208: fprintf(execfile, "Z \n");
209: if (notifysucceed)
210: fprintf(execfile, "n \n");
211:
212: fprintf(execfile, "C %s %s\n", cmd, arglist);
213: fclose(execfile);
214: if (local == 0) {
215: fclose(commandfile);
216: sprintf(scratch, "%s/%s/C.%.*s%c%04d",
217: directory, cmdsite, SITESIG, cmdsite, grade, seq);
218: if (link(tempname, scratch) == 0)
219: unlink(tempname);
220: else {
221: fprintf(stderr, "uux: couldn't rename commandfile\n");
222: exit(1);
223: }
224: }
225: if (nocico)
226: exit(0);
227: else {
228: exec_cico(cmdsite);
229: }
230: exit (0);
231:
232: }
233:
234: processargs()
235: {
236: char *ap, *arg;
237: char append [2];
238: ap = argbuf;
239:
240: strcpy(append, "");
241: while ((arg = strtok(ap, " \t\n")) != NULL) {
242: ap = NULL;
243: if ((strcmp(arg, ">") == 0) || (strcmp(arg, "<") == 0) ||
244: strcmp(arg, "|") == 0)
245: strcpy(append, arg);
246: else {
247: strcpy(onearg, append);
248: strcat(onearg, arg);
249: strcpy(append, "");
250: doarg(onearg);
251: }
252: }
253: }
254:
255: notsup(c)
256: int c;
257: {
258: fprintf(stderr, "Option %c not supported yet\n", c);
259: }
260:
261: void usage()
262: {
263: fprintf(stderr,
264: "usage: uux [-plrv] [-g grade] [-a user] [-] host!cmd arg ...\n");
265: exit (1);
266: }
267:
268: void
269: dostdin()
270: {
271: static char name[128], spoolname[128]; /* spool data filename */
272: FILE *data; /* spool data file */
273: int seq; /* spool sequence number */
274: int c; /* char from stdin */
275:
276: seq = getseq(cmdsite);
277: sprintf(subdirectory, "%s/%s", directory, cmdsite);
278: if (!ckdir(subdirectory)) {
279: fprintf(stderr, "Unable to create directory %s\n",
280: subdirectory);
281: exit (1);
282: }
283: sprintf(name, "D.%.*s%c%04d", SITESIG, mysite, grade, seq);
284: sprintf(spoolname, "%s/%s/%s", directory, cmdsite, name);
285: if ((data = fopen(spoolname, "w")) == NULL) {
286: fprintf(stderr, "uux: can't copy stdin\n");
287: return;
288: }
289: while(EOF != (c = getc(stdin)))
290: putc(c, data);
291: fclose(data);
292:
293: fprintf(execfile, "F %s\nI %s\n", name, name);
294: if (local == 0)
295: fprintf(commandfile,
296: "S %s %s %s - %s 0666\n", name, name, luser, name);
297: }
298:
299: void doarg(arg)
300: char *arg;
301: {
302: char name[128], spoolname[128]; /* spool data filename */
303: FILE *data; /* spool data file */
304: FILE *source; /* source data file */
305: int seq; /* spool sequence number */
306: int c; /* char from input */
307:
308: if (debug > 2)
309: fprintf(stderr, "doarg argument: [%s]\n", arg);
310: output = 0;
311: input = 0;
312: if ('(' == arg[0] && ')' == arg[strlen(arg) - 1]) {
313: strcat(arglist, arg + 1);
314: arglist[strlen(arglist) - 1] = '\0';
315: } else if (NULL == index(arg, '!'))
316: strcat(arglist, arg);
317: else if (strcmp(filesite(arg), cmdsite) == 0) {
318: strcat(arglist, filepath(arg));
319: } else if (strlen(filesite(arg)) == 0) {
320: seq = getseq(cmdsite);
321: if (debug)
322: fprintf(stderr, "seq is %s\n", seq);
323: sprintf(subdirectory, "%s/%s", directory, cmdsite);
324: if (!ckdir(subdirectory)) {
325: fprintf(stderr, "Unable to create directory %s\n",
326: subdirectory);
327: exit (1);
328: }
329: sprintf(name, "D.%.*s%c%04d", SITESIG, mysite, grade, seq);
330: sprintf(spoolname, "%s/%s/%s", directory, cmdsite, name);
331: if (!trylink || link(filepath(arg), spoolname) < 0) {
332: if (NULL == (data = fopen(spoolname, "w"))
333: || NULL == (source = fopen(filepath(arg), "r"))) {
334: fprintf(stderr,
335: "uux: can't copy %s to spool directory\n",
336: filepath(arg));
337: exit(1);
338: }
339: while(EOF != (c = getc(source)))
340: putc(c, data);
341: fclose(data);
342: fclose(source);
343: }
344: if (local == 0) {
345: fprintf(commandfile,
346: "S %s %s %s - %s 0666\n", filepath(arg), name,
347: luser, name);
348: }
349: fprintf(execfile, "F %s %s\n", name, basename(filepath(arg)));
350: strcat(arglist, basename(filepath(arg)));
351: } else {
352: char *fs, *fp;
353: if (arg[0] == '>') {
354: fprintf(stderr, "Argument is an output argument\n");
355: output = 1;
356: arg++;
357: } else if (arg[0] == '<') {
358: fprintf(stderr, "Argument is an input argument\n");
359: input = 1;
360: arg++;
361: }
362: fs = filesite(arg);
363: fp = filepath(arg);
364: fprintf(stderr, "To handle transfer for site %s, file %s\n",
365: fs, fp);
366: }
367: strcat(arglist, " ");
368: }
369:
370: char *filesite(name)
371: char *name;
372: {
373: static char site[SITELEN];
374: char *oname;
375: char *p;
376: char *q;
377:
378: oname = name;
379: if (NULL == (p = index(name, '!')))
380: p = NULL;
381: else {
382: q = site;
383: while(name < p)
384: *q++ = *name++;
385: *q = '\0';
386: p = site;
387: }
388: if (debug)
389: fprintf(stderr, "filesite(%s) : %s.\n", oname, p);
390: return p;
391:
392: }
393:
394: char *filepath(name)
395: char *name;
396: {
397: char *p;
398:
399: if (NULL == (p = rindex(name, '!')))
400: p = NULL;
401: else
402: p = p + 1;
403: if (debug)
404: fprintf(stderr, "filepath(%s) : %s\n", name, p);
405: return p;
406: }
407:
408: char *basename(name)
409: char *name;
410: {
411: char *p;
412: if (NULL == (p = rindex(name, '/')))
413: return name;
414: else
415: return p + 1;
416: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.