|
|
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, User, _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, User, *_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: gwd(Wrkdir);
204: if(fopt){
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: setbuf(fpc, CNULL);
289:
290: /* set Jobid -- C.jobid */
291: (void) strncpy(Jobid, BASENAME(cfile, '.'), NAMESIZE);
292: Jobid[NAMESIZE-1] = '\0';
293:
294: /*
295: * rxfile is the X. file for the job, fprx is its stream ptr.
296: * if the command is to be executed locally, rxfile becomes
297: * a local X. file, otherwise we send it as a D. file to the
298: * remote site.
299: */
300:
301: gename(DATAPRE, xsys, 'X', rxfile);
302: DEBUG(9, "rxfile = %s\n", rxfile);
303: ASSERT(access(rxfile, 0) != 0, Fl_EXISTS, rxfile, errno);
304: fprx = fdopen(ret = creat(rxfile, DFILEMODE), "w");
305: ASSERT(ret >= 0 && fprx != NULL, Ct_WRITE, rxfile, errno);
306: setbuf(fprx, CNULL);
307: clearerr(fprx);
308:
309: (void) fprintf(fprx,"%c %s %s\n", X_USER, User, Myname);
310: if (zflag) {
311: (void) fprintf(fprx, "%c return status on success\n",
312: X_COMMENT);
313: (void) fprintf(fprx,"%c\n", X_SENDZERO);
314: }
315:
316: if (nflag) {
317: (void) fprintf(fprx, "%c don't return status on failure\n",
318: X_COMMENT);
319: (void) fprintf(fprx,"%c\n", X_SENDNOTHING);
320: } else {
321: (void) fprintf(fprx, "%c return status on failure\n",
322: X_COMMENT);
323: fprintf(fprx,"%c\n", X_NONZERO);
324: }
325:
326: if (bringback) {
327: (void) fprintf(fprx, "%c return input on abnormal exit\n",
328: X_COMMENT);
329: (void) fprintf(fprx,"%c\n", X_BRINGBACK);
330: }
331: if (_Statop)
332: (void) fprintf(fprx,"%c %s\n", X_MAILF, _Sfile);
333:
334: if (retaddr != NULL) {
335: (void) fprintf(fprx, "%c return address for status or input return\n",
336: X_COMMENT);
337: (void) fprintf(fprx,"%c %s\n", X_RETADDR, retaddr);
338: }
339:
340: /*
341: * create a JCL file to spool pipe input into
342: */
343: if (pipein) {
344: /*
345: * fpd is the D. file into which we now read
346: * input from stdin
347: */
348:
349: gename(DATAPRE, Myname, 'B', dfile);
350:
351: ASSERT(access(dfile, 0) != 0, Fl_EXISTS, dfile, errno);
352: fpd = fdopen(ret = creat(dfile, DFILEMODE), "w");
353: ASSERT(ret >= 0 && fpd != NULL, Ct_OPEN, dfile, errno);
354:
355: /*
356: * read pipe to EOF
357: */
358: while (!feof(stdin)) {
359: ret = fread(buf, 1, BUFSIZ, stdin);
360: ASSERT(fwrite(buf, 1, ret, fpd) == ret, Ct_WRITE,
361: dfile, errno);
362: }
363: ASSERT(ferror(fpd) == 0, Ct_WRITE, dfile, errno);
364: (void) fclose(fpd);
365:
366: /*
367: * if command is to be executed on remote
368: * create extra JCL
369: */
370: if (!EQUALSN(Myname, xsys, SYSNSIZE)) {
371: GENSEND(fpc, dfile, dfile, dfile);
372: }
373:
374: /*
375: * create file for X_ commands
376: */
377: (void) fprintf(fprx, "%c %s\n", X_RQDFILE, dfile);
378: (void) fprintf(fprx, "%c %s\n", X_STDIN, dfile);
379:
380: wfcommit(dfile, dfile, xsys);
381:
382: }
383: /*
384: * parse command
385: */
386: ap = inargs;
387: while ((ap = getprm(ap, prm)) != NULL) {
388: DEBUG(4, "prm - %s\n", prm);
389:
390: /*
391: * redirection of I/O
392: */
393: if (prm[0] == '>' || prm[0] == '<') {
394: redir = prm[0];
395: continue;
396: }
397:
398: /*
399: * some terminator
400: */
401: if ( prm[0] == '|' || prm[0] == '^'
402: || prm[0] == '&' || prm[0] == ';') {
403: if (*cmd != '\0') /* not 1st thing on line */
404: APPCMD(prm);
405: command = TRUE;
406: continue;
407: }
408:
409: /*
410: * process command or file or option
411: * break out system and file name and
412: * use default if necessary
413: */
414: ret = split(prm, syspart, rest);
415: DEBUG(4, "syspart -> %s, ", syspart);
416: DEBUG(4, "rest -> %s, ", rest);
417: DEBUG(4, "ret -> %d\n", ret);
418:
419: if (command && redir == '\0') {
420: /*
421: * command
422: */
423: APPCMD(rest);
424: command = FALSE;
425: continue;
426: }
427:
428: if (syspart[0] == '\0') {
429: (void) strcpy(syspart, Myname);
430: DEBUG(6, "syspart -> %s\n", syspart);
431: } else if (versys(syspart, 0) != 0) {
432: /*
433: * bad system name
434: */
435: fprintf(stderr, "bad system name: %s\n", syspart);
436: if (fprx != NULL)
437: (void) fclose(fprx);
438: if (fpc != NULL)
439: (void) fclose(fpc);
440: cleanup(11);
441: }
442:
443: /*
444: * process file or option
445: */
446:
447: /*
448: * process file argument
449: * expand filename and create JCL card for
450: * redirected output
451: * e.g., X file sys
452: */
453: if (redir == '>') {
454: if (rest[0] != '~')
455: if (ckexpf(rest))
456: cleanup(6);
457: ASSERT(fprintf(fprx, "%c %s %s\n", X_STDOUT, rest,
458: syspart) >= 0, Ct_WRITE, rxfile, errno);
459: redir = '\0';
460: continue;
461: }
462:
463: /*
464: * if no system specified, then being
465: * processed locally
466: */
467: if (ret == NOSYSPART && redir == '\0') {
468:
469: /*
470: * option
471: */
472: APPCMD(rest);
473: continue;
474: }
475:
476:
477: /* local xeqn + local file (!x !f) */
478: if ((EQUALSN(xsys, Myname, SYSNSIZE))
479: && (EQUALSN(xsys, syspart, SYSNSIZE))) {
480: /*
481: * create JCL card
482: */
483: if (ckexpf(rest))
484: cleanup(7);
485: /*
486: * JCL card for local input
487: * e.g., I file
488: */
489: if (redir == '<') {
490: (void) fprintf(fprx, "%c %s\n", X_STDIN, rest);
491: } else
492: APPCMD(rest);
493: ASSERT(fprx != NULL, Ct_WRITE, rxfile, errno);
494: redir = '\0';
495: continue;
496: }
497:
498: /* remote xeqn + local file (sys!x !f) */
499: if (EQUALSN(syspart, Myname, SYSNSIZE)) {
500: /*
501: * check access to local file
502: * if cflag is set, copy to spool directory
503: * otherwise, just mention it in the X. file
504: */
505: if (ckexpf(rest))
506: cleanup(6);
507: DEBUG(4, "rest %s\n", rest);
508:
509: /* see if I can read this file as read uid, gid */
510: if (uidstat(rest, &stbuf) != 0) {
511: (void) fprintf(stderr,
512: "can't get file status %s\n", rest);
513: cleanup(8);
514: }
515: if ( !(stbuf.st_mode & ANYREAD)
516: && !(stbuf.st_uid == Uid && stbuf.st_mode & 0400)
517: && !(stbuf.st_gid ==getgid() && stbuf.st_mode & 0040)
518: ) {
519: fprintf(stderr,"permission denied %s\n", rest);
520: cleanup(1);
521: }
522:
523: /* D. file for sending local file */
524: gename(DATAPRE, xsys, 'A', dfile);
525:
526: if (cflag || !(stbuf.st_mode & ANYREAD)) {
527: /* make local copy */
528: if (uidxcp(rest, dfile) != 0) {
529: fprintf(stderr,"can't copy %s\n", rest);
530: cleanup(5);
531: }
532: (void) chmod(dfile, DFILEMODE);
533: /* generate 'send' entry in command file */
534: GENSEND(fpc, rest, dfile, dfile);
535: wfcommit(dfile, dfile, xsys); /* commit input */
536: } else /* don't make local copy */
537: GENSEND(fpc, rest, dfile, "D.0");
538:
539: /*
540: * JCL cards for redirected input in X. file,
541: * e.g.
542: * I D.xxx
543: * F D.xxx
544: */
545: if (redir == '<') {
546: /*
547: * don't bother making a X_RQDFILE line that
548: * renames stdin on the remote side, since the
549: * remote command can't know its name anyway
550: */
551: (void) fprintf(fprx, "%c %s\n", X_STDIN, dfile);
552: (void) fprintf(fprx, "%c %s\n", X_RQDFILE, dfile);
553: } else {
554: APPCMD(BASENAME(rest, '/'));;
555: /*
556: * generate X. JCL card that specifies
557: * F file
558: */
559: (void) fprintf(fprx, "%c %s %s\n", X_RQDFILE,
560: dfile, BASENAME(rest, '/'));
561: }
562: redir = '\0';
563:
564: continue;
565: }
566:
567: /* local xeqn + remote file (!x sys!f ) */
568: if (EQUALS(Myname, xsys)) {
569: /*
570: * expand receive file name
571: */
572: if (ckexpf(rest))
573: cleanup(6);
574: /*
575: * tfile is command file for receive from remote.
576: * we defer commiting until later so
577: * that only one C. file is created per site.
578: *
579: * dfile is name of data file to receive into;
580: * we don't use it, just name it.
581: *
582: * the name of the remote is appended to the
583: * X_RQDFILE line to help uuxqt in finding the
584: * D. file when it arrives.
585: */
586: if (gtcfile(tfile, syspart) != SUCCESS) {
587: gename(CMDPRE, syspart, 'R', tfile);
588:
589: ASSERT(access(tfile, 0) != 0,
590: Fl_EXISTS, tfile, errno);
591: svcfile(tfile, syspart);
592: (void) close(creat(tfile, CFILEMODE));
593: }
594: fp = fopen(tfile, "a");
595: ASSERT(fp != NULL, Ct_OPEN, tfile, errno);
596: setbuf(fp, CNULL);
597: gename(DATAPRE, syspart, 'R', dfile);
598:
599: /* prepare JCL card to receive file */
600: GENRCV(fp, rest, dfile);
601: ASSERT(ferror(fp) == 0, Ct_WRITE, dfile, errno);
602: (void) fclose(fp);
603: rflag++;
604: if (rest[0] != '~')
605: if (ckexpf(rest))
606: cleanup(7);
607:
608: /*
609: * generate receive entries
610: */
611: if (redir == '<') {
612: (void) fprintf(fprx,
613: "%c %s/%s/%s\n", X_RQDFILE, Spool,
614: syspart, dfile);
615: (void) fprintf(fprx, "%c %s\n", X_STDIN, dfile);
616: } else {
617: (void) fprintf(fprx, "%c %s/%s/%s %s\n",
618: X_RQDFILE, Spool, syspart, dfile,
619: BASENAME(rest, '/'));
620: APPCMD(BASENAME(rest, '/'));
621: }
622:
623: redir = '\0';
624: continue;
625: }
626:
627: /* remote xeqn/file, different remotes (xsys!cmd syspart!rest) */
628: if (!EQUALS(syspart, xsys)) {
629: /*
630: * strategy:
631: * request rest from syspart.
632: *
633: * set up a local X. file that will send rest to xsys,
634: * once it arrives from syspart.
635: *
636: * arrange so that the xsys D. file (fated to become
637: * an X. file on xsys), rest is required and named.
638: *
639: * pictorially:
640: *
641: * ===== syspart/C.syspartR.... ===== (tfile)
642: * R rest D.syspart... (dfile)
643: *
644: *
645: * ===== local/X.local... ===== (t2file)
646: * F Spool/syspart/D.syspart... rest (dfile)
647: * C uucp -C rest D.syspart... (dfile)
648: *
649: * ===== xsys/D.xsysG.... (fprx)
650: * F D.syspart... rest (dfile)
651: * or, in the case of redir == '<'
652: * F D.syspart... (dfile)
653: * I D.syspart... (dfile)
654: *
655: * while we do push rest around a bunch,
656: * we use the protection scheme to good effect.
657: *
658: * we must rely on uucp's treatment of requests
659: * form XQTDIR to get the data file to the right
660: * place ultimately.
661: */
662:
663: /* build (or append to) C.syspartR... */
664: if (gtcfile(tfile, syspart) != SUCCESS) {
665: gename(CMDPRE, syspart, 'R', tfile);
666:
667: ASSERT(access(tfile, 0) != 0,
668: Fl_EXISTS, tfile, errno);
669: svcfile(tfile, syspart);
670: (void) close(creat(tfile, CFILEMODE));
671: }
672: fp = fopen(tfile, "a");
673: ASSERT(fp != NULL, Ct_OPEN, tfile, errno);
674: setbuf(fp, CNULL);
675: gename(DATAPRE, syspart, 'R', dfile);
676: GENRCV(fp, rest, dfile);
677: ASSERT(ferror(fp) == 0, Ct_WRITE, dfile, errno);
678: (void) fclose(fp);
679:
680: /* build local/X.localG... */
681: gename(XQTPRE, Myname, _Grade, t2file);
682: ASSERT(access(t2file, 0)!=0, Fl_EXISTS, t2file, errno);
683: (void) close(creat(t2file, CFILEMODE));
684: fp = fopen(t2file, "w");
685: ASSERT(fp != NULL, Ct_OPEN, t2file, errno);
686: setbuf(fp, CNULL);
687: (void) fprintf(fp, "%c %s/%s/%s %s\n", X_RQDFILE,
688: Spool, syspart, dfile, BASENAME(rest, '/'));
689: (void) fprintf(fp, "%c uucp -C %s %s!%s\n",
690: X_CMD, BASENAME(rest, '/'), xsys, dfile);
691: ASSERT(ferror(fp) == 0, Ct_WRITE, t2file, errno);
692: (void) fclose(fp);
693:
694: /* put t2file where uuxqt can get at it */
695: wfcommit(t2file, t2file, Myname);
696:
697: /* generate xsys/X.sysG... cards */
698: if (redir == '<') {
699: (void) fprintf(fprx, "%c %s\n",
700: X_RQDFILE, dfile);
701: (void) fprintf(fprx, "%c %s\n", X_STDIN, dfile);
702: } else {
703: (void) fprintf(fprx, "%c %s %s\n", X_RQDFILE,
704: dfile, BASENAME(rest, '/'));
705: APPCMD(BASENAME(rest, '/'));
706: }
707: redir = '\0';
708: continue;
709: }
710:
711: /* remote xeqn + remote file, same remote (sys!x sys!f) */
712: if (rest[0] != '~') /* expand '~' on remote */
713: if (ckexpf(rest))
714: cleanup(7);
715: if (redir == '<') {
716: (void) fprintf(fprx, "%c %s\n", X_STDIN, rest);
717: }
718: else
719: APPCMD(rest);
720: redir = '\0';
721: continue;
722:
723: }
724:
725: /*
726: * place command to be executed in JCL file
727: */
728: (void) fprintf(fprx, "%c %s\n", X_CMD, cmd);
729: ASSERT(ferror(fprx) == 0, Ct_WRITE, rxfile, errno);
730: (void) fclose(fprx); /* rxfile is ready for commit */
731: logent(cmd, "QUEUED");
732:
733: /* the X. name must have the X.Jobid so status reporting is by jobid */
734: (void) sprintf(tfile, "X.%s", Jobid);
735: if (EQUALS(xsys, Myname)) {
736: /* local xeqn -- use X_ file here */
737: wfcommit(rxfile, tfile, xsys);
738:
739: /*
740: * see if -r option requested JCL to be queued only
741: */
742: if (startjob)
743: xuuxqt(Myname);
744: } else {
745: /* remote xeqn -- send rxfile to remote */
746: /* put it in a place where cico can get at it */
747: wfcommit(rxfile, rxfile, xsys);
748:
749: GENSEND(fpc, rxfile, tfile, rxfile);
750: }
751:
752: cfileUsed = (ftell(fpc) != 0L); /* was cfile used? */
753: ASSERT(ferror(fpc) == 0, Ct_WRITE, cfile, errno);
754: (void) fclose(fpc);
755:
756: /*
757: * has any command been placed in command JCL file
758: */
759: if (cfileUsed) {
760: wfcommit(cfile, cfile, xsys);
761: /*
762: * see if -r option requested JCL to be queued only
763: */
764: if (startjob)
765: xuucico(xsys);
766: } else
767: unlink(cfile);
768:
769: /* commit any leftover C. files for remote receive */
770: commitall();
771: if (jflag) /* print Jobid */
772: printf("%s\n", Jobid);
773:
774: cleanup(0);
775: }
776:
777:
778: /*
779: * cleanup and unlink if error
780: * code -> exit code
781: * return:
782: * none
783: */
784: cleanup(code)
785: register int code;
786: {
787: rmlock(CNULL);
788: if (code) {
789: wfabort();
790: fprintf(stderr, "uux failed ( %d )\n", code);
791: fflush(stderr);
792: if (code < 0) {
793: setuid(getuid());
794: signal(SIGIOT, SIG_DFL);
795: abort();
796: }
797: }
798: DEBUG(1, "exit code %d\n", code);
799: if (code < 0)
800: exit(-code);
801: else
802: exit(code);
803: }
804:
805: /*
806: * catch signal then cleanup and exit
807: */
808: onintr(inter)
809: register int inter;
810: {
811: char str[30];
812: (void) signal(inter, SIG_IGN);
813: (void) sprintf(str, "XSIGNAL %d", inter);
814: logent(str, "XCAUGHT");
815: cleanup(-inter);
816: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.