4.3BSD beta release manual page
[unix-history] / usr / src / usr.bin / uucp / uux / uux.c
CommitLineData
c63b1805 1#ifndef lint
1a85e9d2 2static char sccsid[] = "@(#)uux.c 5.3 (Berkeley) %G%";
c63b1805
SL
3#endif
4
c63b1805
SL
5#include "uucp.h"
6
7#define NOSYSPART 0
8#define HASSYSPART 1
9
10#define APPCMD(d) {\
46b15d8a 11char *p; for (p = d; *p != '\0';) *cmdp++ = *p++; *cmdp++ = ' '; *cmdp = '\0';}
c63b1805
SL
12
13#define GENSEND(f, a, b, c, d, e) {\
46b15d8a
RC
14fprintf(f, "S %s %s %s -%s %s 0666\n", a, b, c, d, e); }
15#define GENRCV(f, a, b, c) {fprintf(f, "R %s %s %s - \n", a, b, c);}
c63b1805
SL
16
17main(argc, argv)
18char *argv[];
19{
20 char cfile[NAMESIZE]; /* send commands for files from here */
21 char dfile[NAMESIZE]; /* used for all data files from here */
22 char rxfile[NAMESIZE]; /* to be sent to xqt file (X. ...) */
23 char tfile[NAMESIZE]; /* temporary file name */
24 char tcfile[NAMESIZE]; /* temporary file name */
25 char t2file[NAMESIZE]; /* temporary file name */
26 int cflag = 0; /* commands in C. file flag */
27 int rflag = 0; /* C. files for receiving flag */
46b15d8a
RC
28#ifdef DONTCOPY
29 int Copy = 0; /* Don't Copy spool files */
30#else !DONTCOPY
c63b1805 31 int Copy = 1; /* Copy spool files */
46b15d8a
RC
32#endif !DONTCOPY
33 int Linkit = 0; /* Try link before copy */
c63b1805
SL
34 char buf[BUFSIZ];
35 char inargs[BUFSIZ];
36 int pipein = 0;
37 int startjob = 1;
38 char Grade = 'A';
39 char path[MAXFULLNAME];
40 char cmd[BUFSIZ];
41 char *ap, *cmdp;
42 char prm[BUFSIZ];
43 char syspart[8], rest[MAXFULLNAME];
1a85e9d2
RC
44 char Xsys[8], local[8];
45 char *xsys = Xsys;
c63b1805
SL
46 FILE *fprx, *fpc, *fpd, *fp;
47 extern char *getprm(), *lastpart();
48 extern FILE *ufopen();
49 int uid, ret;
50 char redir = '\0';
51 int nonoti = 0;
52 int nonzero = 0;
46b15d8a
RC
53 int link_failed;
54 char *ReturnTo = NULL;
55 extern int LocalOnly;
c63b1805
SL
56
57 strcpy(Progname, "uux");
58 uucpname(Myname);
59 umask(WFMASK);
60 Ofn = 1;
61 Ifn = 0;
46b15d8a
RC
62#ifdef VMS
63 arg_fix(argc, argv);
64#endif
c63b1805
SL
65 while (argc>1 && argv[1][0] == '-') {
66 switch(argv[1][1]){
67 case 'p':
68 case '\0':
69 pipein = 1;
70 break;
71 case 'r':
72 startjob = 0;
73 break;
74 case 'c':
46b15d8a
RC
75 Copy = 0;
76 Linkit = 0;
77 break;
c63b1805
SL
78 case 'l':
79 Copy = 0;
46b15d8a
RC
80 Linkit = 1;
81 break;
82 case 'C':
83 Copy = 1;
84 Linkit = 0;
c63b1805
SL
85 break;
86 case 'g':
87 Grade = argv[1][2];
88 break;
89 case 'x':
46b15d8a 90 chkdebug();
c63b1805
SL
91 Debug = atoi(&argv[1][2]);
92 if (Debug <= 0)
93 Debug = 1;
94 break;
95 case 'n':
96 nonoti = 1;
97 break;
98 case 'z':
99 nonzero = 1;
100 break;
46b15d8a
RC
101 case 'L':
102 LocalOnly++;
103 break;
104 case 'a':
105 ReturnTo = &argv[1][2];
106 break;
c63b1805
SL
107 default:
108 fprintf(stderr, "unknown flag %s\n", argv[1]);
109 break;
110 }
111 --argc; argv++;
112 }
46b15d8a
RC
113 if (argc > 2) {
114 ret = gwd(Wrkdir);
115 if (ret != 0) {
116 fprintf(stderr, "can't get working directory; will try to continue\n");
117 strcpy(Wrkdir, "/UNKNOWN");
118 }
119 }
c63b1805
SL
120
121 DEBUG(4, "\n\n** %s **\n", "START");
122
123 inargs[0] = '\0';
124 for (argv++; argc > 1; argc--) {
125 DEBUG(4, "arg - %s:", *argv);
126 strcat(inargs, " ");
127 strcat(inargs, *argv++);
128 }
129 DEBUG(4, "arg - %s\n", inargs);
46b15d8a
RC
130 ret = subchdir(Spool);
131 ASSERT(ret >= 0, "CHDIR FAILED", Spool, ret);
c63b1805
SL
132 uid = getuid();
133 guinfo(uid, User, path);
134
135 sprintf(local, "%.7s", Myname);
136 cmdp = cmd;
137 *cmdp = '\0';
138 gename(DATAPRE, local, 'X', rxfile);
139 fprx = ufopen(rxfile, "w");
140 ASSERT(fprx != NULL, "CAN'T OPEN", rxfile, 0);
141 gename(DATAPRE, local, 'T', tcfile);
142 fpc = ufopen(tcfile, "w");
143 ASSERT(fpc != NULL, "CAN'T OPEN", tcfile, 0);
144 fprintf(fprx, "%c %s %s\n", X_USER, User, local);
145 if (nonoti)
146 fprintf(fprx, "%c\n", X_NONOTI);
147 if (nonzero)
148 fprintf(fprx, "%c\n", X_NONZERO);
46b15d8a
RC
149 if (ReturnTo == NULL || *ReturnTo == '\0')
150 ReturnTo = User;
151 fprintf(fprx, "%c %s\n", X_RETURNTO, ReturnTo);
c63b1805
SL
152
153 /* find remote system name */
154 ap = inargs;
155 xsys[0] = '\0';
156 while ((ap = getprm(ap, prm)) != NULL) {
157 if (prm[0] == '>' || prm[0] == '<') {
158 ap = getprm(ap, prm);
159 continue;
160 }
161
162
163 split(prm, xsys, rest);
164 break;
165 }
166 if (xsys[0] == '\0')
167 strcpy(xsys, local);
168 sprintf(Rmtname, "%.7s", xsys);
169 DEBUG(4, "xsys %s\n", xsys);
1a85e9d2 170 if (versys(&xsys) != 0) {
c63b1805
SL
171 /* bad system name */
172 fprintf(stderr, "bad system name: %s\n", xsys);
173 fclose(fprx);
174 fclose(fpc);
175 cleanup(EX_NOHOST);
176 }
177
178 if (pipein) {
179 gename(DATAPRE, local, 'B', dfile);
180 fpd = ufopen(dfile, "w");
181 ASSERT(fpd != NULL, "CAN'T OPEN", dfile, 0);
182 while (!feof(stdin)) {
183 ret = fread(buf, 1, BUFSIZ, stdin);
184 fwrite(buf, 1, ret, fpd);
185 }
186 fclose(fpd);
46b15d8a 187 strcpy(tfile, dfile);
c63b1805 188 if (strcmp(local, xsys) != SAME) {
46b15d8a
RC
189 tfile[strlen(local) + 2] = 'S';
190 GENSEND(fpc, dfile, tfile, User, "", dfile);
c63b1805
SL
191 cflag++;
192 }
46b15d8a
RC
193 fprintf(fprx, "%c %s\n", X_RQDFILE, tfile);
194 fprintf(fprx, "%c %s\n", X_STDIN, tfile);
c63b1805
SL
195 }
196 /* parse command */
197 ap = inargs;
198 while ((ap = getprm(ap, prm)) != NULL) {
199 DEBUG(4, "prm - %s\n", prm);
200 if (prm[0] == '>' || prm[0] == '<') {
201 redir = prm[0];
202 continue;
203 }
204
205 if (prm[0] == ';') {
206 APPCMD(prm);
207 continue;
208 }
209
210 if (prm[0] == '|' || prm[0] == '^') {
211 if (cmdp != cmd)
212 APPCMD(prm);
213 continue;
214 }
215
216 /* process command or file or option */
217 ret = split(prm, syspart, rest);
218 DEBUG(4, "s - %s, ", syspart);
219 DEBUG(4, "r - %s, ", rest);
220 DEBUG(4, "ret - %d\n", ret);
221 if (syspart[0] == '\0')
222 strcpy(syspart, local);
223
224 if (cmdp == cmd && redir == '\0') {
225 /* command */
226 APPCMD(rest);
227 continue;
228 }
229
230 /* process file or option */
231 DEBUG(4, "file s- %s, ", syspart);
232 DEBUG(4, "local - %s\n", local);
233 /* process file */
234 if (redir == '>') {
235 if (rest[0] != '~')
236 if (ckexpf(rest))
237 cleanup(EX_CANTCREAT);
238 fprintf(fprx, "%c %s %s\n", X_STDOUT, rest,
239 syspart);
240 redir = '\0';
241 continue;
242 }
243
244 if (ret == NOSYSPART && redir == '\0') {
245 /* option */
246 APPCMD(rest);
247 continue;
248 }
249
250 if (strcmp(xsys, local) == SAME
251 && strcmp(xsys, syspart) == SAME) {
252 if (ckexpf(rest))
253 cleanup(EX_CANTCREAT);
254 if (redir == '<')
255 fprintf(fprx, "%c %s\n", X_STDIN, rest);
256 else
257 APPCMD(rest);
258 redir = '\0';
259 continue;
260 }
261
262 if (strcmp(syspart, local) == SAME) {
263 /* generate send file */
264 if (ckexpf(rest))
265 cleanup(EX_CANTCREAT);
266 gename(DATAPRE, local, 'A', dfile);
267 DEBUG(4, "rest %s\n", rest);
268 if ((chkpth(User, "", rest) || anyread(rest)) != 0) {
269 fprintf(stderr, "permission denied %s\n", rest);
270 cleanup(EX_NOINPUT);
271 }
46b15d8a
RC
272 link_failed = 0;
273 if (Linkit) {
274 if (link(subfile(rest), subfile(dfile)) != 0)
275 link_failed++;
276 else
277 GENSEND(fpc, rest, dfile, User, "", dfile);
278 }
279 if (Copy || link_failed) {
c63b1805
SL
280 if (xcp(rest, dfile) != 0) {
281 fprintf(stderr, "can't copy %s to %s\n", rest, dfile);
282 cleanup(EX_NOINPUT);
283 }
284 GENSEND(fpc, rest, dfile, User, "", dfile);
285 }
46b15d8a 286 if (!Copy && !Linkit) {
c63b1805
SL
287 GENSEND(fpc, rest, dfile, User, "c", "D.0");
288 }
289 cflag++;
290 if (redir == '<') {
291 fprintf(fprx, "%c %s\n", X_STDIN, dfile);
292 fprintf(fprx, "%c %s\n", X_RQDFILE, dfile);
1a85e9d2 293 } else {
c63b1805
SL
294 APPCMD(lastpart(rest));
295 fprintf(fprx, "%c %s %s\n", X_RQDFILE,
296 dfile, lastpart(rest));
297 }
298 redir = '\0';
299 continue;
300 }
301
302 if (strcmp(local, xsys) == SAME) {
303 /* generate local receive */
304 gename(CMDPRE, syspart, 'R', tfile);
305 strcpy(dfile, tfile);
306 dfile[0] = DATAPRE;
307 fp = ufopen(tfile, "w");
308 ASSERT(fp != NULL, "CAN'T OPEN", tfile, 0);
309 if (ckexpf(rest))
310 cleanup(EX_CANTCREAT);
311 GENRCV(fp, rest, dfile, User);
312 fclose(fp);
313 rflag++;
314 if (rest[0] != '~')
315 if (ckexpf(rest))
316 cleanup(EX_CANTCREAT);
317 if (redir == '<') {
318 fprintf(fprx, "%c %s\n", X_RQDFILE, dfile);
319 fprintf(fprx, "%c %s\n", X_STDIN, dfile);
1a85e9d2 320 } else {
c63b1805
SL
321 fprintf(fprx, "%c %s %s\n", X_RQDFILE, dfile,
322 lastpart(rest));
323 APPCMD(lastpart(rest));
324 }
325
326 redir = '\0';
327 continue;
328 }
329
330 if (strcmp(syspart, xsys) != SAME) {
331 /* generate remote receives */
332 gename(DATAPRE, syspart, 'R', dfile);
333 strcpy(tfile, dfile);
334 tfile[0] = CMDPRE;
335 fpd = ufopen(dfile, "w");
336 ASSERT(fpd != NULL, "CAN'T OPEN", dfile, 0);
337 gename(DATAPRE, local, 'T', t2file);
338 GENRCV(fpd, rest, t2file, User);
339 fclose(fpd);
340 GENSEND(fpc, dfile, tfile, User, "", dfile);
341 cflag++;
342 if (redir == '<') {
343 fprintf(fprx, "%c %s\n", X_RQDFILE, t2file);
344 fprintf(fprx, "%c %s\n", X_STDIN, t2file);
1a85e9d2 345 } else {
c63b1805
SL
346 fprintf(fprx, "%c %s %s\n", X_RQDFILE, t2file,
347 lastpart(rest));
348 APPCMD(lastpart(rest));
349 }
350 redir = '\0';
351 continue;
352 }
353
354 /* file on remote system */
355 if (rest[0] != '~')
356 if (ckexpf(rest))
357 cleanup(EX_CANTCREAT);
358 if (redir == '<')
359 fprintf(fprx, "%c %s\n", X_STDIN, rest);
360 else
361 APPCMD(rest);
362 redir = '\0';
363 continue;
364
365 }
46b15d8a
RC
366 /*
367 * clean up trailing ' ' in command.
368 */
369 if (cmdp > cmd && cmdp[0] == '\0' && cmdp[-1] == ' ')
370 *--cmdp = '\0';
371 /* block multi-hop uux, which doesn't work */
372 for (ap = cmd; *ap && *ap != ' '; ap++)
373 if (*ap == '!') {
374 fprintf(stderr, "uux handles only adjacent sites.\n");
375 fprintf(stderr, "Try uusend for multi-hop delivery.\n");
376 cleanup(1);
377 }
c63b1805
SL
378
379 fprintf(fprx, "%c %s\n", X_CMD, cmd);
380 logent(cmd, "XQT QUE'D");
381 fclose(fprx);
382
46b15d8a 383 gename(XQTPRE, local, Grade, tfile);
c63b1805
SL
384 if (strcmp(xsys, local) == SAME) {
385 /* rti!trt: xmv() works across filesystems, link(II) doesnt */
386 xmv(rxfile, tfile);
387 if (startjob)
388 if (rflag)
389 xuucico(xsys);
390 else
391 xuuxqt();
392 }
393 else {
394 GENSEND(fpc, rxfile, tfile, User, "", rxfile);
395 cflag++;
396 }
397
398 fclose(fpc);
399 if (cflag) {
400 gename(CMDPRE, xsys, Grade, cfile);
401 /* rti!trt: use xmv() rather than link(II) */
402 xmv(tcfile, cfile);
403 if (startjob)
404 xuucico(xsys);
405 cleanup(0);
406 }
407 else
408 unlink(subfile(tcfile));
1a85e9d2 409 exit(0);
c63b1805
SL
410}
411
412#define FTABSIZE 30
413char Fname[FTABSIZE][NAMESIZE];
414int Fnamect = 0;
415
46b15d8a
RC
416/*
417 * cleanup and unlink if error
c63b1805
SL
418 *
419 * return - none - do exit()
420 */
421
422cleanup(code)
423int code;
424{
425 int i;
426
427 logcls();
428 rmlock(CNULL);
429 if (code) {
430 for (i = 0; i < Fnamect; i++)
431 unlink(subfile(Fname[i]));
432 fprintf(stderr, "uux failed. code %d\n", code);
433 }
434 DEBUG(1, "exit code %d\n", code);
435 exit(code);
436}
437
46b15d8a
RC
438/*
439 * open file and record name
c63b1805
SL
440 *
441 * return file pointer.
442 */
443
444FILE *ufopen(file, mode)
445char *file, *mode;
446{
447 if (Fnamect < FTABSIZE)
448 strcpy(Fname[Fnamect++], file);
449 else
450 logent("Fname", "TABLE OVERFLOW");
46b15d8a
RC
451 return fopen(subfile(file), mode);
452}
453#ifdef VMS
454/*
455 * EUNICE bug:
456 * quotes are not stripped from DCL. Do it here.
457 * Note if we are running under Unix shell we don't
458 * do the right thing.
459 */
460arg_fix(argc, argv)
461char **argv;
462{
463 register char *cp, *tp;
464
465 for (; argc > 0; --argc, argv++) {
466 cp = *argv;
467 if (cp == (char *)0 || *cp++ != '"')
468 continue;
469 tp = cp;
470 while (*tp++) ;
471 tp -= 2;
472 if (*tp == '"') {
473 *tp = '\0';
474 *argv = cp;
475 }
476 }
c63b1805 477}
46b15d8a 478#endif VMS