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