|
|
1.1 root 1: /* /sccs/src/cmd/uucp/s.uux.c
2: uux.c 1.12 8/30/84 17:38:15
3: */
4: #include "uucp.h"
5: VERSION(@(#)uux.c 1.12);
6:
7: #define NOSYSPART 0
8: #define HASSYSPART 1
9:
10: #define GENSEND(f, a, b, c) {\
11: ASSERT(fprintf(f, "S %s %s %s -%s %s 0666 %s %s\n", a, b, retaddr, _Statop?"o":"", c, User, _Sfile) >= 0, Ct_WRITE, "", errno);\
12: }
13: #define GENRCV(f, a, b) {\
14: ASSERT(fprintf(f, "R %s %s %s - %s 0666 %s\n", a, b, retaddr, *_Sfile ? _Sfile : "dummy", User) >= 0, \
15: Ct_WRITE, "", errno);\
16: }
17:
18: #define USAGE "[-aNAME] [-b] [-c] [-C] [-j] [-gGRADE] [-n] [-p] [-r] [-sFILE] [-xNUM] [-z] command-string"
19: #define APPCMD(p) {(void) strcat(cmd, p); (void) strcat(cmd, " ");}
20:
21: static char _Sfile[MAXFULLNAME];
22: static int _Statop;
23:
24: char _Grade = 'N';
25: /*
26: * uux
27: */
28: main(argc, argv)
29: char *argv[];
30: {
31: FILE *fprx = NULL, *fpc = NULL, *fpd = NULL, *fp = NULL;
32: extern onintr();
33: int cfileUsed = 0; /* >0 if commands put in C. file flag */
34: int rflag = 0; /* C. files for receiving flag */
35: int cflag = 0; /* if > 0 make local copy of files to be sent */
36: int nflag = 0; /* if != 0, do not request error notification */
37: int zflag = 0; /* if != 0, request success notification */
38: int pipein = 0;
39: int startjob = 1;
40: short jflag = 0; /* -j flag output Jobid */
41: int bringback = 0; /* return stdin to invoker on error */
42: int ret, i;
43: char *getprm();
44: char redir = '\0';
45: char command = TRUE;
46: char cfile[NAMESIZE]; /* send commands for files from here */
47: char dfile[NAMESIZE]; /* used for all data files from here */
48: char rxfile[NAMESIZE]; /* file for X_ commands */
49: char tfile[NAMESIZE]; /* temporary file name */
50: char t2file[NAMESIZE]; /* temporary file name */
51: char buf[BUFSIZ];
52: char inargs[BUFSIZ];
53: char cmd[BUFSIZ];
54: char *ap;
55: char prm[BUFSIZ];
56: char syspart[NAMEBUF], rest[BUFSIZ];
57: char xsys[NAMEBUF];
58: char *fopt = NULL;
59: char *retaddr = NULL;
60:
61: struct stat stbuf;
62:
63: /* we want this to run as uucp, even if the kernel doesn't */
64: Uid = getuid();
65: Euid = geteuid(); /* this should be UUCPUID */
66: if (Uid == 0)
67: setuid(UUCPUID);
68:
69: /* choose LOGFILE */
70: (void) strcpy(Logfile, LOGUUX);
71:
72: /*
73: * determine local system name
74: */
75: (void) strcpy(Progname, "uux");
76: Pchar = 'X';
77: (void) signal(SIGILL, onintr);
78: (void) signal(SIGTRAP, onintr);
79: (void) signal(SIGIOT, onintr);
80: (void) signal(SIGEMT, onintr);
81: (void) signal(SIGFPE, onintr);
82: (void) signal(SIGBUS, onintr);
83: (void) signal(SIGSEGV, onintr);
84: (void) signal(SIGSYS, onintr);
85: (void) signal(SIGTERM, SIG_IGN);
86: uucpname(Myname);
87: Ofn = 1;
88: Ifn = 0;
89: *_Sfile = '\0';
90: /*
91: * since getopt() can't handle the pipe input option '-'
92: * I'll change it to "-p"
93: */
94: for (i=0; i<argc; i++)
95: if (EQUALS(argv[i], "-"))
96: argv[i] = "-p";
97:
98: while ((i = getopt(argc, argv, "a:bcCjg:nprs:x:z")) != EOF) {
99: switch(i){
100:
101: /*
102: * use this name in the U line
103: */
104: case 'a':
105: retaddr = optarg;
106: break;
107:
108: /*
109: * if return code non-zero, return command's input
110: */
111: case 'b':
112: bringback = 1;
113: break;
114:
115: /* do not make local copies of files to be sent (default) */
116: case 'c':
117: cflag = 0;
118: break;
119:
120: /* make local copies of files to be sent */
121: case 'C':
122: cflag = 1;
123: break;
124: /*
125: * set priority of request
126: */
127: case 'g':
128: _Grade = *optarg;
129: break;
130:
131:
132: case 'j': /* job id */
133: jflag = 1;
134: break;
135:
136:
137: /*
138: * do not send failure notification to user
139: */
140: case 'n':
141: nflag++;
142: break;
143:
144: /*
145: * send success notification to user
146: */
147: case 'z':
148: zflag++;
149: break;
150:
151: /*
152: * -p or - option specifies input from pipe
153: */
154: case 'p':
155: pipein = 1;
156: break;
157:
158: /*
159: * do not start transfer
160: */
161: case 'r':
162: startjob = 0;
163: break;
164:
165: case 's':
166: fopt = optarg;
167: _Statop++;
168: break;
169:
170: /*
171: * debugging level
172: */
173: case 'x':
174: Debug = atoi(optarg);
175: if (Debug <= 0)
176: Debug = 1;
177: break;
178:
179: default:
180: (void) fprintf(stderr, "\tusage: %s %s\n", Progname, USAGE);
181: exit(2);
182: }
183: }
184:
185: DEBUG(4, "\n\n** %s **\n", "START");
186:
187: /*
188: * copy arguments into a buffer for later
189: * processing
190: */
191: inargs[0] = '\0';
192: for (; optind < argc; optind++) {
193: DEBUG(4, "arg - %s:", argv[optind]);
194: (void) strcat(inargs, " ");
195: (void) strcat(inargs, argv[optind]);
196: }
197:
198: /*
199: * get working directory and change
200: * to spool directory
201: */
202: DEBUG(4, "arg - %s\n", inargs);
203: if(fopt){
204: gwd(Wrkdir);
205: if(*fopt != '/')
206: (void) sprintf(_Sfile, "%s/%s", Wrkdir, fopt);
207: else
208: (void) sprintf(_Sfile, "%s", fopt);
209:
210: }
211: if (chdir(WORKSPACE) != 0) {
212: (void) fprintf(stderr, "No spool directory - %s - get help\n", WORKSPACE);
213: cleanup(12);
214: }
215: /*
216: * find remote system name
217: * remote name is first to know that
218: * is not > or <
219: */
220: ap = inargs;
221: xsys[0] = '\0';
222: while ((ap = getprm(ap, prm)) != NULL) {
223: if (prm[0] == '>' || prm[0] == '<') {
224: ap = getprm(ap, prm);
225: continue;
226: }
227:
228: /*
229: * split name into system name
230: * and command name
231: */
232: split(prm, xsys, rest);
233: break;
234: }
235: if (xsys[0] == '\0')
236: (void) strcpy(xsys, Myname);
237: strncpy(Rmtname, xsys, MAXBASENAME);
238: Rmtname[MAXBASENAME] = '\0';
239: DEBUG(4, "xsys %s\n", xsys);
240:
241: /*
242: * check to see if system name is valid
243: */
244: if (versys(xsys, 0) != 0) {
245: /*
246: * bad system name
247: */
248: fprintf(stderr, "bad system name: %s\n", xsys);
249: if (fprx != NULL)
250: (void) fclose(fprx);
251: if (fpc != NULL)
252: (void) fclose(fpc);
253: cleanup(11);
254: }
255:
256: /*
257: * determine id of user starting remote
258: * execution
259: */
260: guinfo(Uid, User);
261: (void) strcpy(Loginuser,User);
262:
263: DEBUG(6, "User %s\n", User);
264: if (retaddr == NULL)
265: retaddr = User;
266:
267: /*
268: * initialize command buffer
269: */
270: *cmd = '\0';
271:
272: /*
273: * generate JCL files to work from
274: */
275:
276: /*
277: * fpc is the C. file for the local site.
278: * collect commands into cfile.
279: * commit if not empty (at end).
280: *
281: * the appropriate C. file.
282: */
283: gename(CMDPRE, xsys, _Grade, cfile);
284: DEBUG(9, "cfile = %s\n", cfile);
285: ASSERT(access(cfile, 0) != 0, Fl_EXISTS, cfile, errno);
286: fpc = fdopen(ret = creat(cfile, CFILEMODE), "w");
287: ASSERT(ret >= 0 && fpc != NULL, Ct_OPEN, cfile, errno);
288:
289: /* set Jobid -- C.jobid */
290: (void) strncpy(Jobid, BASENAME(cfile, '.'), NAMESIZE);
291: Jobid[NAMESIZE-1] = '\0';
292:
293: /*
294: * rxfile is the X. file for the job, fprx is its stream ptr.
295: * if the command is to be executed locally, rxfile becomes
296: * a local X. file, otherwise we send it as a D. file to the
297: * remote site.
298: */
299:
300: gename(DATAPRE, xsys, 'X', rxfile);
301: DEBUG(9, "rxfile = %s\n", rxfile);
302: ASSERT(access(rxfile, 0) != 0, Fl_EXISTS, rxfile, errno);
303: fprx = fdopen(ret = creat(rxfile, DFILEMODE), "w");
304: ASSERT(ret >= 0 && fprx != NULL, Ct_WRITE, rxfile, errno);
305: clearerr(fprx);
306:
307: (void) fprintf(fprx,"%c %s %s\n", X_USER, User, Myname);
308: if (zflag) {
309: (void) fprintf(fprx, "%c return status on success\n",
310: X_COMMENT);
311: (void) fprintf(fprx,"%c\n", X_SENDZERO);
312: }
313:
314: if (nflag) {
315: (void) fprintf(fprx, "%c don't return status on failure\n",
316: X_COMMENT);
317: (void) fprintf(fprx,"%c\n", X_SENDNOTHING);
318: } else {
319: (void) fprintf(fprx, "%c return status on failure\n",
320: X_COMMENT);
321: fprintf(fprx,"%c\n", X_NONZERO);
322: }
323:
324: if (bringback) {
325: (void) fprintf(fprx, "%c return input on abnormal exit\n",
326: X_COMMENT);
327: (void) fprintf(fprx,"%c\n", X_BRINGBACK);
328: }
329: if (_Statop)
330: (void) fprintf(fprx,"%c %s\n", X_MAILF, _Sfile);
331:
332: if (retaddr != NULL) {
333: (void) fprintf(fprx, "%c return address for status or input return\n",
334: X_COMMENT);
335: (void) fprintf(fprx,"%c %s\n", X_RETADDR, retaddr);
336: }
337:
338: /*
339: * create a JCL file to spool pipe input into
340: */
341: if (pipein) {
342: /*
343: * fpd is the D. file into which we now read
344: * input from stdin
345: */
346:
347: gename(DATAPRE, Myname, 'B', dfile);
348:
349: ASSERT(access(dfile, 0) != 0, Fl_EXISTS, dfile, errno);
350: i = creat(dfile, DFILEMODE);
351: ASSERT(i >= 0, Ct_OPEN, dfile, errno);
352: while ((ret = read(0, buf, BUFSIZ)) > 0)
353: ASSERT(write(i, buf, ret) == ret, Ct_WRITE, dfile, errno);
354: (void) close(i);
355: /*
356: * if command is to be executed on remote
357: * create extra JCL
358: */
359: if (!EQUALSN(Myname, xsys, SYSNSIZE)) {
360: GENSEND(fpc, dfile, dfile, dfile);
361: }
362:
363: /*
364: * create file for X_ commands
365: */
366: (void) fprintf(fprx, "%c %s\n", X_RQDFILE, dfile);
367: (void) fprintf(fprx, "%c %s\n", X_STDIN, dfile);
368:
369: wfcommit(dfile, dfile, xsys);
370:
371: }
372: /*
373: * parse command
374: */
375: ap = inargs;
376: while ((ap = getprm(ap, prm)) != NULL) {
377: DEBUG(4, "prm - %s\n", prm);
378:
379: /*
380: * redirection of I/O
381: */
382: if (prm[0] == '>' || prm[0] == '<') {
383: redir = prm[0];
384: continue;
385: }
386:
387: /*
388: * some terminator
389: */
390: if ( prm[0] == '|' || prm[0] == '^'
391: || prm[0] == '&' || prm[0] == ';') {
392: if (*cmd != '\0') /* not 1st thing on line */
393: APPCMD(prm);
394: command = TRUE;
395: continue;
396: }
397:
398: /*
399: * process command or file or option
400: * break out system and file name and
401: * use default if necessary
402: */
403: ret = split(prm, syspart, rest);
404: DEBUG(4, "syspart -> %s, ", syspart);
405: DEBUG(4, "rest -> %s, ", rest);
406: DEBUG(4, "ret -> %d\n", ret);
407:
408: if (command && redir == '\0') {
409: /*
410: * command
411: */
412: APPCMD(rest);
413: command = FALSE;
414: continue;
415: }
416:
417: if (syspart[0] == '\0') {
418: (void) strcpy(syspart, Myname);
419: DEBUG(6, "syspart -> %s\n", syspart);
420: } else if (versys(syspart, 0) != 0) {
421: /*
422: * bad system name
423: */
424: fprintf(stderr, "bad system name: %s\n", syspart);
425: if (fprx != NULL)
426: (void) fclose(fprx);
427: if (fpc != NULL)
428: (void) fclose(fpc);
429: cleanup(11);
430: }
431:
432: /*
433: * process file or option
434: */
435:
436: /*
437: * process file argument
438: * expand filename and create JCL card for
439: * redirected output
440: * e.g., X file sys
441: */
442: if (redir == '>') {
443: if (rest[0] != '~')
444: if (ckexpf(rest))
445: cleanup(6);
446: ASSERT(fprintf(fprx, "%c %s %s\n", X_STDOUT, rest,
447: syspart) >= 0, Ct_WRITE, rxfile, errno);
448: redir = '\0';
449: continue;
450: }
451:
452: /*
453: * if no system specified, then being
454: * processed locally
455: */
456: if (ret == NOSYSPART && redir == '\0') {
457:
458: /*
459: * option
460: */
461: APPCMD(rest);
462: continue;
463: }
464:
465:
466: /* local xeqn + local file (!x !f) */
467: if ((EQUALSN(xsys, Myname, SYSNSIZE))
468: && (EQUALSN(xsys, syspart, SYSNSIZE))) {
469: /*
470: * create JCL card
471: */
472: if (ckexpf(rest))
473: cleanup(7);
474: /*
475: * JCL card for local input
476: * e.g., I file
477: */
478: if (redir == '<') {
479: (void) fprintf(fprx, "%c %s\n", X_STDIN, rest);
480: } else
481: APPCMD(rest);
482: ASSERT(fprx != NULL, Ct_WRITE, rxfile, errno);
483: redir = '\0';
484: continue;
485: }
486:
487: /* remote xeqn + local file (sys!x !f) */
488: if (EQUALSN(syspart, Myname, SYSNSIZE)) {
489: /*
490: * check access to local file
491: * if cflag is set, copy to spool directory
492: * otherwise, just mention it in the X. file
493: */
494: if (ckexpf(rest))
495: cleanup(6);
496: DEBUG(4, "rest %s\n", rest);
497:
498: /* see if I can read this file as read uid, gid */
499: if (uidstat(rest, &stbuf) != 0) {
500: (void) fprintf(stderr,
501: "can't get file status %s\n", rest);
502: cleanup(8);
503: }
504: if ( !(stbuf.st_mode & ANYREAD)
505: && !(stbuf.st_uid == Uid && stbuf.st_mode & 0400)
506: && !(stbuf.st_gid ==getgid() && stbuf.st_mode & 0040)
507: ) {
508: fprintf(stderr,"permission denied %s\n", rest);
509: cleanup(1);
510: }
511:
512: /* D. file for sending local file */
513: gename(DATAPRE, xsys, 'A', dfile);
514:
515: if (cflag || !(stbuf.st_mode & ANYREAD)) {
516: /* make local copy */
517: if (uidxcp(rest, dfile) != 0) {
518: fprintf(stderr,"can't copy %s\n", rest);
519: cleanup(5);
520: }
521: (void) chmod(dfile, DFILEMODE);
522: /* generate 'send' entry in command file */
523: GENSEND(fpc, rest, dfile, dfile);
524: wfcommit(dfile, dfile, xsys); /* commit input */
525: } else /* don't make local copy */
526: GENSEND(fpc, rest, dfile, "D.0");
527:
528: /*
529: * JCL cards for redirected input in X. file,
530: * e.g.
531: * I D.xxx
532: * F D.xxx
533: */
534: if (redir == '<') {
535: /*
536: * don't bother making a X_RQDFILE line that
537: * renames stdin on the remote side, since the
538: * remote command can't know its name anyway
539: */
540: (void) fprintf(fprx, "%c %s\n", X_STDIN, dfile);
541: (void) fprintf(fprx, "%c %s\n", X_RQDFILE, dfile);
542: } else {
543: APPCMD(BASENAME(rest, '/'));;
544: /*
545: * generate X. JCL card that specifies
546: * F file
547: */
548: (void) fprintf(fprx, "%c %s %s\n", X_RQDFILE,
549: dfile, BASENAME(rest, '/'));
550: }
551: redir = '\0';
552:
553: continue;
554: }
555:
556: /* local xeqn + remote file (!x sys!f ) */
557: if (EQUALS(Myname, xsys)) {
558: /*
559: * expand receive file name
560: */
561: if (ckexpf(rest))
562: cleanup(6);
563: /*
564: * tfile is command file for receive from remote.
565: * we defer commiting until later so
566: * that only one C. file is created per site.
567: *
568: * dfile is name of data file to receive into;
569: * we don't use it, just name it.
570: *
571: * the name of the remote is appended to the
572: * X_RQDFILE line to help uuxqt in finding the
573: * D. file when it arrives.
574: */
575: if (gtcfile(tfile, syspart) != SUCCESS) {
576: gename(CMDPRE, syspart, 'R', tfile);
577:
578: ASSERT(access(tfile, 0) != 0,
579: Fl_EXISTS, tfile, errno);
580: svcfile(tfile, syspart);
581: (void) close(creat(tfile, CFILEMODE));
582: }
583: fp = fopen(tfile, "a");
584: ASSERT(fp != NULL, Ct_OPEN, tfile, errno);
585: setbuf(fp, CNULL);
586: gename(DATAPRE, syspart, 'R', dfile);
587:
588: /* prepare JCL card to receive file */
589: GENRCV(fp, rest, dfile);
590: ASSERT(ferror(fp) == 0, Ct_WRITE, dfile, errno);
591: (void) fclose(fp);
592: rflag++;
593: if (rest[0] != '~')
594: if (ckexpf(rest))
595: cleanup(7);
596:
597: /*
598: * generate receive entries
599: */
600: if (redir == '<') {
601: (void) fprintf(fprx,
602: "%c %s/%s/%s\n", X_RQDFILE, Spool,
603: syspart, dfile);
604: (void) fprintf(fprx, "%c %s\n", X_STDIN, dfile);
605: } else {
606: (void) fprintf(fprx, "%c %s/%s/%s %s\n",
607: X_RQDFILE, Spool, syspart, dfile,
608: BASENAME(rest, '/'));
609: APPCMD(BASENAME(rest, '/'));
610: }
611:
612: redir = '\0';
613: continue;
614: }
615:
616: /* remote xeqn/file, different remotes (xsys!cmd syspart!rest) */
617: if (!EQUALS(syspart, xsys)) {
618: /*
619: * strategy:
620: * request rest from syspart.
621: *
622: * set up a local X. file that will send rest to xsys,
623: * once it arrives from syspart.
624: *
625: * arrange so that the xsys D. file (fated to become
626: * an X. file on xsys), rest is required and named.
627: *
628: * pictorially:
629: *
630: * ===== syspart/C.syspartR.... ===== (tfile)
631: * R rest D.syspart... (dfile)
632: *
633: *
634: * ===== local/X.local... ===== (t2file)
635: * F Spool/syspart/D.syspart... rest (dfile)
636: * C uucp -C rest D.syspart... (dfile)
637: *
638: * ===== xsys/D.xsysG.... (fprx)
639: * F D.syspart... rest (dfile)
640: * or, in the case of redir == '<'
641: * F D.syspart... (dfile)
642: * I D.syspart... (dfile)
643: *
644: * while we do push rest around a bunch,
645: * we use the protection scheme to good effect.
646: *
647: * we must rely on uucp's treatment of requests
648: * form XQTDIR to get the data file to the right
649: * place ultimately.
650: */
651:
652: /* build (or append to) C.syspartR... */
653: if (gtcfile(tfile, syspart) != SUCCESS) {
654: gename(CMDPRE, syspart, 'R', tfile);
655:
656: ASSERT(access(tfile, 0) != 0,
657: Fl_EXISTS, tfile, errno);
658: svcfile(tfile, syspart);
659: (void) close(creat(tfile, CFILEMODE));
660: }
661: fp = fopen(tfile, "a");
662: ASSERT(fp != NULL, Ct_OPEN, tfile, errno);
663: setbuf(fp, CNULL);
664: gename(DATAPRE, syspart, 'R', dfile);
665: GENRCV(fp, rest, dfile);
666: ASSERT(ferror(fp) == 0, Ct_WRITE, dfile, errno);
667: (void) fclose(fp);
668:
669: /* build local/X.localG... */
670: gename(XQTPRE, Myname, _Grade, t2file);
671: ASSERT(access(t2file, 0)!=0, Fl_EXISTS, t2file, errno);
672: (void) close(creat(t2file, CFILEMODE));
673: fp = fopen(t2file, "w");
674: ASSERT(fp != NULL, Ct_OPEN, t2file, errno);
675: setbuf(fp, CNULL);
676: (void) fprintf(fp, "%c %s/%s/%s %s\n", X_RQDFILE,
677: Spool, syspart, dfile, BASENAME(rest, '/'));
678: (void) fprintf(fp, "%c uucp -C %s %s!%s\n",
679: X_CMD, BASENAME(rest, '/'), xsys, dfile);
680: ASSERT(ferror(fp) == 0, Ct_WRITE, t2file, errno);
681: (void) fclose(fp);
682:
683: /* put t2file where uuxqt can get at it */
684: wfcommit(t2file, t2file, Myname);
685:
686: /* generate xsys/X.sysG... cards */
687: if (redir == '<') {
688: (void) fprintf(fprx, "%c %s\n",
689: X_RQDFILE, dfile);
690: (void) fprintf(fprx, "%c %s\n", X_STDIN, dfile);
691: } else {
692: (void) fprintf(fprx, "%c %s %s\n", X_RQDFILE,
693: dfile, BASENAME(rest, '/'));
694: APPCMD(BASENAME(rest, '/'));
695: }
696: redir = '\0';
697: continue;
698: }
699:
700: /* remote xeqn + remote file, same remote (sys!x sys!f) */
701: if (rest[0] != '~') /* expand '~' on remote */
702: if (ckexpf(rest))
703: cleanup(7);
704: if (redir == '<') {
705: (void) fprintf(fprx, "%c %s\n", X_STDIN, rest);
706: }
707: else
708: APPCMD(rest);
709: redir = '\0';
710: continue;
711:
712: }
713:
714: /*
715: * place command to be executed in JCL file
716: */
717: (void) fprintf(fprx, "%c %s\n", X_CMD, cmd);
718: ASSERT(ferror(fprx) == 0, Ct_WRITE, rxfile, errno);
719: (void) fclose(fprx); /* rxfile is ready for commit */
720: logent(cmd, "QUEUED");
721:
722: /* the X. name must have the X.Jobid so status reporting is by jobid */
723: (void) sprintf(tfile, "X.%s", Jobid);
724: if (EQUALS(xsys, Myname)) {
725: /* local xeqn -- use X_ file here */
726: wfcommit(rxfile, tfile, xsys);
727:
728: /*
729: * see if -r option requested JCL to be queued only
730: */
731: if (startjob)
732: xuuxqt(Myname);
733: } else {
734: /* remote xeqn -- send rxfile to remote */
735: /* put it in a place where cico can get at it */
736: wfcommit(rxfile, rxfile, xsys);
737:
738: GENSEND(fpc, rxfile, tfile, rxfile);
739: }
740:
741: cfileUsed = (ftell(fpc) != 0L); /* was cfile used? */
742: ASSERT(ferror(fpc) == 0, Ct_WRITE, cfile, errno);
743: (void) fclose(fpc);
744:
745: /*
746: * has any command been placed in command JCL file
747: */
748: if (cfileUsed) {
749: wfcommit(cfile, cfile, xsys);
750: /*
751: * see if -r option requested JCL to be queued only
752: */
753: if (startjob)
754: xuucico(xsys);
755: } else
756: unlink(cfile);
757:
758: /* commit any leftover C. files for remote receive */
759: commitall();
760: if (jflag) /* print Jobid */
761: printf("%s\n", Jobid);
762:
763: cleanup(0);
764: }
765:
766:
767: /*
768: * cleanup and unlink if error
769: * code -> exit code
770: * return:
771: * none
772: */
773: cleanup(code)
774: register int code;
775: {
776: rmlock(CNULL);
777: if (code) {
778: wfabort();
779: fprintf(stderr, "uux failed ( %d )\n", code);
780: fflush(stderr);
781: if (code < 0) {
782: setuid(getuid());
783: signal(SIGIOT, SIG_DFL);
784: abort();
785: }
786: }
787: DEBUG(1, "exit code %d\n", code);
788: if (code < 0)
789: exit(-code);
790: else
791: exit(code);
792: }
793:
794: /*
795: * catch signal then cleanup and exit
796: */
797: onintr(inter)
798: register int inter;
799: {
800: char str[30];
801: (void) signal(inter, SIG_IGN);
802: (void) sprintf(str, "XSIGNAL %d", inter);
803: logent(str, "XCAUGHT");
804: cleanup(-inter);
805: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.