xref: /titanic_53/usr/src/cmd/bnu/uucp.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
23*7c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
24*7c478bd9Sstevel@tonic-gate 
25*7c478bd9Sstevel@tonic-gate /*
26*7c478bd9Sstevel@tonic-gate  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
27*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
28*7c478bd9Sstevel@tonic-gate  */
29*7c478bd9Sstevel@tonic-gate 
30*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
31*7c478bd9Sstevel@tonic-gate 
32*7c478bd9Sstevel@tonic-gate #include "uucp.h"
33*7c478bd9Sstevel@tonic-gate 
34*7c478bd9Sstevel@tonic-gate /*
35*7c478bd9Sstevel@tonic-gate  * uucp
36*7c478bd9Sstevel@tonic-gate  * user id
37*7c478bd9Sstevel@tonic-gate  * make a copy in spool directory
38*7c478bd9Sstevel@tonic-gate  */
39*7c478bd9Sstevel@tonic-gate int Copy = 0;
40*7c478bd9Sstevel@tonic-gate static int _Transfer = 0;
41*7c478bd9Sstevel@tonic-gate char Nuser[32];
42*7c478bd9Sstevel@tonic-gate char *Ropt = " ";
43*7c478bd9Sstevel@tonic-gate char Optns[10];
44*7c478bd9Sstevel@tonic-gate char Uopts[BUFSIZ];
45*7c478bd9Sstevel@tonic-gate char Xopts[BUFSIZ];
46*7c478bd9Sstevel@tonic-gate char Sgrade[NAMESIZE];
47*7c478bd9Sstevel@tonic-gate int Mail = 0;
48*7c478bd9Sstevel@tonic-gate int Notify = 0;
49*7c478bd9Sstevel@tonic-gate 
50*7c478bd9Sstevel@tonic-gate void cleanup(), ruux(), usage();
51*7c478bd9Sstevel@tonic-gate int eaccess(), guinfo(), vergrd(), gwd(), ckexpf(), uidstat(), uidxcp(),
52*7c478bd9Sstevel@tonic-gate 	copy(), gtcfile();
53*7c478bd9Sstevel@tonic-gate void commitall(), wfabort(), mailst(), gename(), svcfile();
54*7c478bd9Sstevel@tonic-gate 
55*7c478bd9Sstevel@tonic-gate char	Sfile[MAXFULLNAME];
56*7c478bd9Sstevel@tonic-gate 
57*7c478bd9Sstevel@tonic-gate main(argc, argv, envp)
58*7c478bd9Sstevel@tonic-gate char *argv[];
59*7c478bd9Sstevel@tonic-gate char	**envp;
60*7c478bd9Sstevel@tonic-gate {
61*7c478bd9Sstevel@tonic-gate 	char *jid();
62*7c478bd9Sstevel@tonic-gate 	int	ret;
63*7c478bd9Sstevel@tonic-gate 	int	errors = 0;
64*7c478bd9Sstevel@tonic-gate 	char	*fopt, *sys2p;
65*7c478bd9Sstevel@tonic-gate 	char	sys1[MAXFULLNAME], sys2[MAXFULLNAME];
66*7c478bd9Sstevel@tonic-gate 	char	fwd1[MAXFULLNAME], fwd2[MAXFULLNAME];
67*7c478bd9Sstevel@tonic-gate 	char	file1[MAXFULLNAME], file2[MAXFULLNAME];
68*7c478bd9Sstevel@tonic-gate 	short	jflag = 0;	/* -j flag  Jobid printout */
69*7c478bd9Sstevel@tonic-gate 	extern int	split();
70*7c478bd9Sstevel@tonic-gate 
71*7c478bd9Sstevel@tonic-gate 
72*7c478bd9Sstevel@tonic-gate 	/* Set locale environment variables local definitions */
73*7c478bd9Sstevel@tonic-gate 	(void) setlocale(LC_ALL, "");
74*7c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN)	/* Should be defined by cc -D */
75*7c478bd9Sstevel@tonic-gate #define	TEXT_DOMAIN "SYS_TEST"	/* Use this only if it wasn't */
76*7c478bd9Sstevel@tonic-gate #endif
77*7c478bd9Sstevel@tonic-gate 	(void) textdomain(TEXT_DOMAIN);
78*7c478bd9Sstevel@tonic-gate 
79*7c478bd9Sstevel@tonic-gate 	/* this fails in some versions, but it doesn't hurt */
80*7c478bd9Sstevel@tonic-gate 	Uid = getuid();
81*7c478bd9Sstevel@tonic-gate 	Euid = geteuid();
82*7c478bd9Sstevel@tonic-gate 	if (Uid == 0)
83*7c478bd9Sstevel@tonic-gate 		(void) setuid(UUCPUID);
84*7c478bd9Sstevel@tonic-gate 
85*7c478bd9Sstevel@tonic-gate 	/* choose LOGFILE */
86*7c478bd9Sstevel@tonic-gate 	(void) strcpy(Logfile, LOGUUCP);
87*7c478bd9Sstevel@tonic-gate 
88*7c478bd9Sstevel@tonic-gate 	Env = envp;
89*7c478bd9Sstevel@tonic-gate 	fopt = NULL;
90*7c478bd9Sstevel@tonic-gate 	(void) strcpy(Progname, "uucp");
91*7c478bd9Sstevel@tonic-gate 	Pchar = 'U';
92*7c478bd9Sstevel@tonic-gate 	*Uopts = NULLCHAR;
93*7c478bd9Sstevel@tonic-gate 	*Xopts = NULLCHAR;
94*7c478bd9Sstevel@tonic-gate 	*Sgrade = NULLCHAR;
95*7c478bd9Sstevel@tonic-gate 
96*7c478bd9Sstevel@tonic-gate 	if (eaccess(GRADES, 0) != -1) {
97*7c478bd9Sstevel@tonic-gate 		Grade = 'A';
98*7c478bd9Sstevel@tonic-gate 		Sgrades = TRUE;
99*7c478bd9Sstevel@tonic-gate 		sprintf(Sgrade, "%s", "default");
100*7c478bd9Sstevel@tonic-gate 	}
101*7c478bd9Sstevel@tonic-gate 
102*7c478bd9Sstevel@tonic-gate 	/*
103*7c478bd9Sstevel@tonic-gate 	 * find name of local system
104*7c478bd9Sstevel@tonic-gate 	 */
105*7c478bd9Sstevel@tonic-gate 	uucpname(Myname);
106*7c478bd9Sstevel@tonic-gate 	Optns[0] = '-';
107*7c478bd9Sstevel@tonic-gate 	Optns[1] = 'd';
108*7c478bd9Sstevel@tonic-gate 	Optns[2] = 'c';
109*7c478bd9Sstevel@tonic-gate 	Optns[3] = Nuser[0] = Sfile[0] = NULLCHAR;
110*7c478bd9Sstevel@tonic-gate 
111*7c478bd9Sstevel@tonic-gate 	/*
112*7c478bd9Sstevel@tonic-gate 	 * find id of user who spawned command to
113*7c478bd9Sstevel@tonic-gate 	 * determine
114*7c478bd9Sstevel@tonic-gate 	 */
115*7c478bd9Sstevel@tonic-gate 	(void) guinfo(Uid, User);
116*7c478bd9Sstevel@tonic-gate 
117*7c478bd9Sstevel@tonic-gate 	/*
118*7c478bd9Sstevel@tonic-gate 	 * create/append command log
119*7c478bd9Sstevel@tonic-gate 	 */
120*7c478bd9Sstevel@tonic-gate 	commandlog(argc,argv);
121*7c478bd9Sstevel@tonic-gate 
122*7c478bd9Sstevel@tonic-gate 	while ((ret = getopt(argc, argv, "Ccdfg:jmn:rs:x:")) != EOF) {
123*7c478bd9Sstevel@tonic-gate 		switch (ret) {
124*7c478bd9Sstevel@tonic-gate 
125*7c478bd9Sstevel@tonic-gate 		/*
126*7c478bd9Sstevel@tonic-gate 		 * make a copy of the file in the spool
127*7c478bd9Sstevel@tonic-gate 		 * directory.
128*7c478bd9Sstevel@tonic-gate 		 */
129*7c478bd9Sstevel@tonic-gate 		case 'C':
130*7c478bd9Sstevel@tonic-gate 			Copy = 1;
131*7c478bd9Sstevel@tonic-gate 			Optns[2] = 'C';
132*7c478bd9Sstevel@tonic-gate 			break;
133*7c478bd9Sstevel@tonic-gate 
134*7c478bd9Sstevel@tonic-gate 		/*
135*7c478bd9Sstevel@tonic-gate 		 * not used (default)
136*7c478bd9Sstevel@tonic-gate 		 */
137*7c478bd9Sstevel@tonic-gate 		case 'c':
138*7c478bd9Sstevel@tonic-gate 			break;
139*7c478bd9Sstevel@tonic-gate 
140*7c478bd9Sstevel@tonic-gate 		/*
141*7c478bd9Sstevel@tonic-gate 		 * not used (default)
142*7c478bd9Sstevel@tonic-gate 		 */
143*7c478bd9Sstevel@tonic-gate 		case 'd':
144*7c478bd9Sstevel@tonic-gate 			break;
145*7c478bd9Sstevel@tonic-gate 		case 'f':
146*7c478bd9Sstevel@tonic-gate 			Optns[1] = 'f';
147*7c478bd9Sstevel@tonic-gate 			break;
148*7c478bd9Sstevel@tonic-gate 
149*7c478bd9Sstevel@tonic-gate 		/*
150*7c478bd9Sstevel@tonic-gate 		 * set service grade
151*7c478bd9Sstevel@tonic-gate 		 */
152*7c478bd9Sstevel@tonic-gate 		case 'g':
153*7c478bd9Sstevel@tonic-gate 			snprintf(Xopts, sizeof (Xopts), "-g%s", optarg);
154*7c478bd9Sstevel@tonic-gate 			if (!Sgrades) {
155*7c478bd9Sstevel@tonic-gate 				if (strlen(optarg) < (size_t)2 && isalnum(*optarg))
156*7c478bd9Sstevel@tonic-gate 					Grade = *optarg;
157*7c478bd9Sstevel@tonic-gate 				else {
158*7c478bd9Sstevel@tonic-gate 					(void) fprintf(stderr, gettext("No"
159*7c478bd9Sstevel@tonic-gate 					    " administrator defined service"
160*7c478bd9Sstevel@tonic-gate 					    " grades available on this"
161*7c478bd9Sstevel@tonic-gate 					    " machine.\n"));
162*7c478bd9Sstevel@tonic-gate 					(void) fprintf(stderr, gettext("UUCP"
163*7c478bd9Sstevel@tonic-gate 					    " service grades range from"
164*7c478bd9Sstevel@tonic-gate 					    " [A-Z][a-z] only.\n"));
165*7c478bd9Sstevel@tonic-gate 					cleanup(-1);
166*7c478bd9Sstevel@tonic-gate 				}
167*7c478bd9Sstevel@tonic-gate 			}
168*7c478bd9Sstevel@tonic-gate 			else {
169*7c478bd9Sstevel@tonic-gate 				(void) strncpy(Sgrade, optarg, NAMESIZE-1);
170*7c478bd9Sstevel@tonic-gate 				Sgrade[NAMESIZE-1] = NULLCHAR;
171*7c478bd9Sstevel@tonic-gate 				if (vergrd(Sgrade) != SUCCESS)
172*7c478bd9Sstevel@tonic-gate 					cleanup(FAIL);
173*7c478bd9Sstevel@tonic-gate 			}
174*7c478bd9Sstevel@tonic-gate 			break;
175*7c478bd9Sstevel@tonic-gate 
176*7c478bd9Sstevel@tonic-gate 		case 'j':	/* job id */
177*7c478bd9Sstevel@tonic-gate 			jflag = 1;
178*7c478bd9Sstevel@tonic-gate 			break;
179*7c478bd9Sstevel@tonic-gate 
180*7c478bd9Sstevel@tonic-gate 		/*
181*7c478bd9Sstevel@tonic-gate 		 * send notification to local user
182*7c478bd9Sstevel@tonic-gate 		 */
183*7c478bd9Sstevel@tonic-gate 		case 'm':
184*7c478bd9Sstevel@tonic-gate 			Mail = 1;
185*7c478bd9Sstevel@tonic-gate 			(void) strcat(Optns, "m");
186*7c478bd9Sstevel@tonic-gate 			break;
187*7c478bd9Sstevel@tonic-gate 
188*7c478bd9Sstevel@tonic-gate 		/*
189*7c478bd9Sstevel@tonic-gate 		 * send notification to user on remote
190*7c478bd9Sstevel@tonic-gate 		 * if no user specified do not send notification
191*7c478bd9Sstevel@tonic-gate 		 */
192*7c478bd9Sstevel@tonic-gate 		case 'n':
193*7c478bd9Sstevel@tonic-gate 			/*
194*7c478bd9Sstevel@tonic-gate 			 * We should add "n" option to Optns only once,
195*7c478bd9Sstevel@tonic-gate 			 * even if multiple -n option are passed to uucp
196*7c478bd9Sstevel@tonic-gate 			 */
197*7c478bd9Sstevel@tonic-gate 			if (!Notify) {
198*7c478bd9Sstevel@tonic-gate 				(void) strlcat(Optns, "n", sizeof (Optns));
199*7c478bd9Sstevel@tonic-gate 				Notify = 1;
200*7c478bd9Sstevel@tonic-gate 			}
201*7c478bd9Sstevel@tonic-gate 			(void) sprintf(Nuser, "%.8s", optarg);
202*7c478bd9Sstevel@tonic-gate 
203*7c478bd9Sstevel@tonic-gate 			/*
204*7c478bd9Sstevel@tonic-gate 			 * We do the copy multiple times when multiple
205*7c478bd9Sstevel@tonic-gate 			 * -n options are specified, but
206*7c478bd9Sstevel@tonic-gate 			 * only the last -n value is used.
207*7c478bd9Sstevel@tonic-gate 	 		 */
208*7c478bd9Sstevel@tonic-gate 			(void) snprintf(Uopts, sizeof (Uopts), "-n%s ", Nuser);
209*7c478bd9Sstevel@tonic-gate 
210*7c478bd9Sstevel@tonic-gate 			break;
211*7c478bd9Sstevel@tonic-gate 
212*7c478bd9Sstevel@tonic-gate 		/*
213*7c478bd9Sstevel@tonic-gate 		 * create JCL files but do not start uucico
214*7c478bd9Sstevel@tonic-gate 		 */
215*7c478bd9Sstevel@tonic-gate 		case 'r':
216*7c478bd9Sstevel@tonic-gate 			Ropt = "-r";
217*7c478bd9Sstevel@tonic-gate 			break;
218*7c478bd9Sstevel@tonic-gate 
219*7c478bd9Sstevel@tonic-gate 		/*
220*7c478bd9Sstevel@tonic-gate 		 * return status file
221*7c478bd9Sstevel@tonic-gate 		 */
222*7c478bd9Sstevel@tonic-gate 		case 's':
223*7c478bd9Sstevel@tonic-gate 			fopt = optarg;
224*7c478bd9Sstevel@tonic-gate 			/* "m" needed for compatability */
225*7c478bd9Sstevel@tonic-gate 			(void) strcat(Optns, "mo");
226*7c478bd9Sstevel@tonic-gate 			break;
227*7c478bd9Sstevel@tonic-gate 
228*7c478bd9Sstevel@tonic-gate 		/*
229*7c478bd9Sstevel@tonic-gate 		 * turn on debugging
230*7c478bd9Sstevel@tonic-gate 		 */
231*7c478bd9Sstevel@tonic-gate 		case 'x':
232*7c478bd9Sstevel@tonic-gate 			Debug = atoi(optarg);
233*7c478bd9Sstevel@tonic-gate 			if (Debug <= 0)
234*7c478bd9Sstevel@tonic-gate 				Debug = 1;
235*7c478bd9Sstevel@tonic-gate #ifdef SMALL
236*7c478bd9Sstevel@tonic-gate 			fprintf(stderr, gettext("WARNING: uucp built with SMALL"
237*7c478bd9Sstevel@tonic-gate 			    " flag defined -- no debug info available\n"));
238*7c478bd9Sstevel@tonic-gate #endif /* SMALL */
239*7c478bd9Sstevel@tonic-gate 			break;
240*7c478bd9Sstevel@tonic-gate 
241*7c478bd9Sstevel@tonic-gate 		default:
242*7c478bd9Sstevel@tonic-gate 			usage();
243*7c478bd9Sstevel@tonic-gate 			break;
244*7c478bd9Sstevel@tonic-gate 		}
245*7c478bd9Sstevel@tonic-gate 	}
246*7c478bd9Sstevel@tonic-gate 	DEBUG(4, "\n\n** %s **\n", "START");
247*7c478bd9Sstevel@tonic-gate 	gwd(Wrkdir);
248*7c478bd9Sstevel@tonic-gate 	if (fopt) {
249*7c478bd9Sstevel@tonic-gate 		if (*fopt != '/')
250*7c478bd9Sstevel@tonic-gate 			(void) snprintf(Sfile, MAXFULLNAME, "%s/%s",
251*7c478bd9Sstevel@tonic-gate 					Wrkdir, fopt);
252*7c478bd9Sstevel@tonic-gate 		else
253*7c478bd9Sstevel@tonic-gate 			(void) snprintf(Sfile, MAXFULLNAME, "%s", fopt);
254*7c478bd9Sstevel@tonic-gate 
255*7c478bd9Sstevel@tonic-gate 	}
256*7c478bd9Sstevel@tonic-gate 	else
257*7c478bd9Sstevel@tonic-gate 		if (strlcpy(Sfile, "dummy", sizeof (Sfile)) >= sizeof (Sfile))
258*7c478bd9Sstevel@tonic-gate 			return (2);
259*7c478bd9Sstevel@tonic-gate 
260*7c478bd9Sstevel@tonic-gate 	/*
261*7c478bd9Sstevel@tonic-gate 	 * work in WORKSPACE directory
262*7c478bd9Sstevel@tonic-gate 	 */
263*7c478bd9Sstevel@tonic-gate 	ret = chdir(WORKSPACE);
264*7c478bd9Sstevel@tonic-gate 	if (ret != 0) {
265*7c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("No work directory - %s -"
266*7c478bd9Sstevel@tonic-gate 		    " get help\n"), WORKSPACE);
267*7c478bd9Sstevel@tonic-gate 		cleanup(-12);
268*7c478bd9Sstevel@tonic-gate 	}
269*7c478bd9Sstevel@tonic-gate 
270*7c478bd9Sstevel@tonic-gate 	if (Nuser[0] == NULLCHAR)
271*7c478bd9Sstevel@tonic-gate 		(void) strcpy(Nuser, User);
272*7c478bd9Sstevel@tonic-gate 	(void) strcpy(Loginuser, User);
273*7c478bd9Sstevel@tonic-gate 	DEBUG(4, "UID %ld, ", (long) Uid);
274*7c478bd9Sstevel@tonic-gate 	DEBUG(4, "User %s\n", User);
275*7c478bd9Sstevel@tonic-gate 	if (argc - optind < 2) {
276*7c478bd9Sstevel@tonic-gate 		usage();
277*7c478bd9Sstevel@tonic-gate 	}
278*7c478bd9Sstevel@tonic-gate 
279*7c478bd9Sstevel@tonic-gate 	/*
280*7c478bd9Sstevel@tonic-gate 	 * set up "to" system and file names
281*7c478bd9Sstevel@tonic-gate 	 */
282*7c478bd9Sstevel@tonic-gate 
283*7c478bd9Sstevel@tonic-gate 	(void) split(argv[argc - 1], sys2, fwd2, file2);
284*7c478bd9Sstevel@tonic-gate 	if (*sys2 != NULLCHAR) {
285*7c478bd9Sstevel@tonic-gate 		(void) strncpy(Rmtname, sys2, MAXBASENAME);
286*7c478bd9Sstevel@tonic-gate 		Rmtname[MAXBASENAME] = NULLCHAR;
287*7c478bd9Sstevel@tonic-gate 
288*7c478bd9Sstevel@tonic-gate 		/* get real Myname - it depends on who I'm calling--Rmtname */
289*7c478bd9Sstevel@tonic-gate 		(void) mchFind(Rmtname);
290*7c478bd9Sstevel@tonic-gate 		myName(Myname);
291*7c478bd9Sstevel@tonic-gate 
292*7c478bd9Sstevel@tonic-gate 		if (versys(sys2) != 0) {
293*7c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr,
294*7c478bd9Sstevel@tonic-gate 			    gettext("bad system: %s\n"), sys2);
295*7c478bd9Sstevel@tonic-gate 			cleanup(-EX_NOHOST);
296*7c478bd9Sstevel@tonic-gate 		}
297*7c478bd9Sstevel@tonic-gate 	}
298*7c478bd9Sstevel@tonic-gate 
299*7c478bd9Sstevel@tonic-gate 	DEBUG(9, "sys2: %s, ", sys2);
300*7c478bd9Sstevel@tonic-gate 	DEBUG(9, "fwd2: %s, ", fwd2);
301*7c478bd9Sstevel@tonic-gate 	DEBUG(9, "file2: %s\n", file2);
302*7c478bd9Sstevel@tonic-gate 
303*7c478bd9Sstevel@tonic-gate 	/*
304*7c478bd9Sstevel@tonic-gate 	 * if there are more than 2 argsc, file2 is a directory
305*7c478bd9Sstevel@tonic-gate 	 */
306*7c478bd9Sstevel@tonic-gate 	if (argc - optind > 2)
307*7c478bd9Sstevel@tonic-gate 		(void) strcat(file2, "/");
308*7c478bd9Sstevel@tonic-gate 
309*7c478bd9Sstevel@tonic-gate 	/*
310*7c478bd9Sstevel@tonic-gate 	 * do each from argument
311*7c478bd9Sstevel@tonic-gate 	 */
312*7c478bd9Sstevel@tonic-gate 
313*7c478bd9Sstevel@tonic-gate 	for ( ; optind < argc - 1; optind++) {
314*7c478bd9Sstevel@tonic-gate 	    (void) split(argv[optind], sys1, fwd1, file1);
315*7c478bd9Sstevel@tonic-gate 	    if (*sys1 != NULLCHAR) {
316*7c478bd9Sstevel@tonic-gate 		if (versys(sys1) != 0) {
317*7c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr,
318*7c478bd9Sstevel@tonic-gate 			    gettext("bad system: %s\n"), sys1);
319*7c478bd9Sstevel@tonic-gate 			cleanup(-EX_NOHOST);
320*7c478bd9Sstevel@tonic-gate 		}
321*7c478bd9Sstevel@tonic-gate 	    }
322*7c478bd9Sstevel@tonic-gate 
323*7c478bd9Sstevel@tonic-gate 	    /*  source files can have at most one ! */
324*7c478bd9Sstevel@tonic-gate 	    if (*fwd1 != NULLCHAR) {
325*7c478bd9Sstevel@tonic-gate 		/* syntax error */
326*7c478bd9Sstevel@tonic-gate 	        (void) fprintf(stderr,
327*7c478bd9Sstevel@tonic-gate 		    gettext("illegal  syntax %s\n"), argv[optind]);
328*7c478bd9Sstevel@tonic-gate 	        exit(2);
329*7c478bd9Sstevel@tonic-gate 	    }
330*7c478bd9Sstevel@tonic-gate 
331*7c478bd9Sstevel@tonic-gate 	    /*
332*7c478bd9Sstevel@tonic-gate 	     * check for required remote expansion of file names -- generate
333*7c478bd9Sstevel@tonic-gate 	     *	and execute a uux command
334*7c478bd9Sstevel@tonic-gate 	     * e.g.
335*7c478bd9Sstevel@tonic-gate 	     *		uucp   owl!~/dan/..  ~/dan/
336*7c478bd9Sstevel@tonic-gate 	     *
337*7c478bd9Sstevel@tonic-gate 	     * NOTE: The source file part must be full path name.
338*7c478bd9Sstevel@tonic-gate 	     *  If ~ it will be expanded locally - it assumes the remote
339*7c478bd9Sstevel@tonic-gate 	     *  names are the same.
340*7c478bd9Sstevel@tonic-gate 	     */
341*7c478bd9Sstevel@tonic-gate 
342*7c478bd9Sstevel@tonic-gate 	    if (*sys1 != NULLCHAR)
343*7c478bd9Sstevel@tonic-gate 		if ((strchr(file1, '*') != NULL
344*7c478bd9Sstevel@tonic-gate 		      || strchr(file1, '?') != NULL
345*7c478bd9Sstevel@tonic-gate 		      || strchr(file1, '[') != NULL)) {
346*7c478bd9Sstevel@tonic-gate 		        /* do a uux command */
347*7c478bd9Sstevel@tonic-gate 		        if (ckexpf(file1) == FAIL)
348*7c478bd9Sstevel@tonic-gate 			    exit(6);
349*7c478bd9Sstevel@tonic-gate 			(void) strncpy(Rmtname, sys1, MAXBASENAME);
350*7c478bd9Sstevel@tonic-gate 			Rmtname[MAXBASENAME] = NULLCHAR;
351*7c478bd9Sstevel@tonic-gate 			/* get real Myname - it depends on who I'm calling--Rmtname */
352*7c478bd9Sstevel@tonic-gate 			(void) mchFind(Rmtname);
353*7c478bd9Sstevel@tonic-gate 			myName(Myname);
354*7c478bd9Sstevel@tonic-gate 			if (*sys2 == NULLCHAR)
355*7c478bd9Sstevel@tonic-gate 			    sys2p = Myname;
356*7c478bd9Sstevel@tonic-gate 		        ruux(sys1, sys1, file1, sys2p, fwd2, file2);
357*7c478bd9Sstevel@tonic-gate 		        continue;
358*7c478bd9Sstevel@tonic-gate 		}
359*7c478bd9Sstevel@tonic-gate 
360*7c478bd9Sstevel@tonic-gate 	    /*
361*7c478bd9Sstevel@tonic-gate 	     * check for forwarding -- generate and execute a uux command
362*7c478bd9Sstevel@tonic-gate 	     * e.g.
363*7c478bd9Sstevel@tonic-gate 	     *		uucp uucp.c raven!owl!~/dan/
364*7c478bd9Sstevel@tonic-gate 	     */
365*7c478bd9Sstevel@tonic-gate 
366*7c478bd9Sstevel@tonic-gate 	    if (*fwd2 != NULLCHAR) {
367*7c478bd9Sstevel@tonic-gate 	        ruux(sys2, sys1, file1, "", fwd2, file2);
368*7c478bd9Sstevel@tonic-gate 	        continue;
369*7c478bd9Sstevel@tonic-gate 	    }
370*7c478bd9Sstevel@tonic-gate 
371*7c478bd9Sstevel@tonic-gate 	    /*
372*7c478bd9Sstevel@tonic-gate 	     * check for both source and destination on other systems --
373*7c478bd9Sstevel@tonic-gate 	     *  generate and execute a uux command
374*7c478bd9Sstevel@tonic-gate 	     */
375*7c478bd9Sstevel@tonic-gate 
376*7c478bd9Sstevel@tonic-gate 	    if (*sys1 != NULLCHAR )
377*7c478bd9Sstevel@tonic-gate 		if ( (!EQUALS(Myname, sys1))
378*7c478bd9Sstevel@tonic-gate 	    	  && *sys2 != NULLCHAR
379*7c478bd9Sstevel@tonic-gate 	    	  && (!EQUALS(sys2, Myname)) ) {
380*7c478bd9Sstevel@tonic-gate 		    ruux(sys2, sys1, file1, "", fwd2, file2);
381*7c478bd9Sstevel@tonic-gate 	            continue;
382*7c478bd9Sstevel@tonic-gate 	        }
383*7c478bd9Sstevel@tonic-gate 
384*7c478bd9Sstevel@tonic-gate 
385*7c478bd9Sstevel@tonic-gate 	    sys2p = sys2;
386*7c478bd9Sstevel@tonic-gate 	    if (*sys1 == NULLCHAR) {
387*7c478bd9Sstevel@tonic-gate 		if (*sys2 == NULLCHAR)
388*7c478bd9Sstevel@tonic-gate 		    sys2p = Myname;
389*7c478bd9Sstevel@tonic-gate 		(void) strcpy(sys1, Myname);
390*7c478bd9Sstevel@tonic-gate 	    } else {
391*7c478bd9Sstevel@tonic-gate 		(void) strncpy(Rmtname, sys1, MAXBASENAME);
392*7c478bd9Sstevel@tonic-gate 		Rmtname[MAXBASENAME] = NULLCHAR;
393*7c478bd9Sstevel@tonic-gate 		/* get real Myname - it depends on who I'm calling--Rmtname */
394*7c478bd9Sstevel@tonic-gate 		(void) mchFind(Rmtname);
395*7c478bd9Sstevel@tonic-gate 		myName(Myname);
396*7c478bd9Sstevel@tonic-gate 		if (*sys2 == NULLCHAR)
397*7c478bd9Sstevel@tonic-gate 		    sys2p = Myname;
398*7c478bd9Sstevel@tonic-gate 	    }
399*7c478bd9Sstevel@tonic-gate 
400*7c478bd9Sstevel@tonic-gate 	    DEBUG(4, "sys1 - %s, ", sys1);
401*7c478bd9Sstevel@tonic-gate 	    DEBUG(4, "file1 - %s, ", file1);
402*7c478bd9Sstevel@tonic-gate 	    DEBUG(4, "Rmtname - %s\n", Rmtname);
403*7c478bd9Sstevel@tonic-gate 	    if (copy(sys1, file1, sys2p, file2))
404*7c478bd9Sstevel@tonic-gate 	    	errors++;
405*7c478bd9Sstevel@tonic-gate 	}
406*7c478bd9Sstevel@tonic-gate 
407*7c478bd9Sstevel@tonic-gate 	/* move the work files to their proper places */
408*7c478bd9Sstevel@tonic-gate 	commitall();
409*7c478bd9Sstevel@tonic-gate 
410*7c478bd9Sstevel@tonic-gate 	/*
411*7c478bd9Sstevel@tonic-gate 	 * Wait for all background uux processes to finish so
412*7c478bd9Sstevel@tonic-gate 	 * that our caller will know that we're done with all
413*7c478bd9Sstevel@tonic-gate 	 * input files and it's safe to remove them.
414*7c478bd9Sstevel@tonic-gate 	 */
415*7c478bd9Sstevel@tonic-gate 	while (wait(NULL) != -1)
416*7c478bd9Sstevel@tonic-gate 		;
417*7c478bd9Sstevel@tonic-gate 
418*7c478bd9Sstevel@tonic-gate 	/*
419*7c478bd9Sstevel@tonic-gate 	 * do not spawn daemon if -r option specified
420*7c478bd9Sstevel@tonic-gate 	 */
421*7c478bd9Sstevel@tonic-gate 	if (*Ropt != '-') {
422*7c478bd9Sstevel@tonic-gate #ifndef	V7
423*7c478bd9Sstevel@tonic-gate 		long	limit;
424*7c478bd9Sstevel@tonic-gate 		char	msg[100];
425*7c478bd9Sstevel@tonic-gate 		limit = ulimit(1, (long) 0);
426*7c478bd9Sstevel@tonic-gate 		if (limit < MINULIMIT)  {
427*7c478bd9Sstevel@tonic-gate 			(void) sprintf(msg,
428*7c478bd9Sstevel@tonic-gate 			    "ULIMIT (%ld) < MINULIMIT (%ld)", limit, MINULIMIT);
429*7c478bd9Sstevel@tonic-gate 			logent(msg, "Low-ULIMIT");
430*7c478bd9Sstevel@tonic-gate 		}
431*7c478bd9Sstevel@tonic-gate 		else
432*7c478bd9Sstevel@tonic-gate #endif
433*7c478bd9Sstevel@tonic-gate 			xuucico(Rmtname);
434*7c478bd9Sstevel@tonic-gate 	}
435*7c478bd9Sstevel@tonic-gate 	if (jflag) {
436*7c478bd9Sstevel@tonic-gate 		(void) strncpy(Jobid, jid(), NAMESIZE);
437*7c478bd9Sstevel@tonic-gate 		printf("%s\n", Jobid);
438*7c478bd9Sstevel@tonic-gate 	}
439*7c478bd9Sstevel@tonic-gate 	cleanup(errors);
440*7c478bd9Sstevel@tonic-gate 	/*NOTREACHED*/
441*7c478bd9Sstevel@tonic-gate }
442*7c478bd9Sstevel@tonic-gate 
443*7c478bd9Sstevel@tonic-gate /*
444*7c478bd9Sstevel@tonic-gate  * cleanup lock files before exiting
445*7c478bd9Sstevel@tonic-gate  */
446*7c478bd9Sstevel@tonic-gate void
447*7c478bd9Sstevel@tonic-gate cleanup(code)
448*7c478bd9Sstevel@tonic-gate register int	code;
449*7c478bd9Sstevel@tonic-gate {
450*7c478bd9Sstevel@tonic-gate 	static int first = 1;
451*7c478bd9Sstevel@tonic-gate 
452*7c478bd9Sstevel@tonic-gate 	if (first) {
453*7c478bd9Sstevel@tonic-gate 		first = 0;
454*7c478bd9Sstevel@tonic-gate 		rmlock(CNULL);
455*7c478bd9Sstevel@tonic-gate 		if (code != 0)
456*7c478bd9Sstevel@tonic-gate 			wfabort();  /* this may be extreme -- abort all work */
457*7c478bd9Sstevel@tonic-gate 	}
458*7c478bd9Sstevel@tonic-gate 	if (code < 0) {
459*7c478bd9Sstevel@tonic-gate 	       (void) fprintf(stderr,
460*7c478bd9Sstevel@tonic-gate 		   gettext("uucp failed completely (%d)\n"), (-code));
461*7c478bd9Sstevel@tonic-gate 		exit(-code);
462*7c478bd9Sstevel@tonic-gate 	}
463*7c478bd9Sstevel@tonic-gate 	else if (code > 0) {
464*7c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, gettext(
465*7c478bd9Sstevel@tonic-gate 		    "uucp failed partially: %d file(s) sent; %d error(s)\n"),
466*7c478bd9Sstevel@tonic-gate 		 _Transfer, code);
467*7c478bd9Sstevel@tonic-gate 		exit(code);
468*7c478bd9Sstevel@tonic-gate 	}
469*7c478bd9Sstevel@tonic-gate 	exit(code);
470*7c478bd9Sstevel@tonic-gate }
471*7c478bd9Sstevel@tonic-gate 
472*7c478bd9Sstevel@tonic-gate /*
473*7c478bd9Sstevel@tonic-gate  * generate copy files for s1!f1 -> s2!f2
474*7c478bd9Sstevel@tonic-gate  *	Note: only one remote machine, other situations
475*7c478bd9Sstevel@tonic-gate  *	have been taken care of in main.
476*7c478bd9Sstevel@tonic-gate  * return:
477*7c478bd9Sstevel@tonic-gate  *	0	-> success
478*7c478bd9Sstevel@tonic-gate  * Non-zero     -> failure
479*7c478bd9Sstevel@tonic-gate  */
480*7c478bd9Sstevel@tonic-gate int
481*7c478bd9Sstevel@tonic-gate copy(s1, f1, s2, f2)
482*7c478bd9Sstevel@tonic-gate char *s1, *f1, *s2, *f2;
483*7c478bd9Sstevel@tonic-gate {
484*7c478bd9Sstevel@tonic-gate 	FILE *cfp;
485*7c478bd9Sstevel@tonic-gate 	static FILE *syscfile();
486*7c478bd9Sstevel@tonic-gate 	struct stat stbuf, stbuf1;
487*7c478bd9Sstevel@tonic-gate 	int type, statret;
488*7c478bd9Sstevel@tonic-gate 	char dfile[NAMESIZE];
489*7c478bd9Sstevel@tonic-gate 	char cfile[NAMESIZE];
490*7c478bd9Sstevel@tonic-gate 	char command[10+(2*MAXFULLNAME)];
491*7c478bd9Sstevel@tonic-gate 	char file1[MAXFULLNAME], file2[MAXFULLNAME];
492*7c478bd9Sstevel@tonic-gate 	char msg[BUFSIZ];
493*7c478bd9Sstevel@tonic-gate 
494*7c478bd9Sstevel@tonic-gate 	type = 0;
495*7c478bd9Sstevel@tonic-gate 	(void) strcpy(file1, f1);
496*7c478bd9Sstevel@tonic-gate 	(void) strcpy(file2, f2);
497*7c478bd9Sstevel@tonic-gate 	if (!EQUALS(s1, Myname))
498*7c478bd9Sstevel@tonic-gate 		type = 1;
499*7c478bd9Sstevel@tonic-gate 	if (!EQUALS(s2, Myname))
500*7c478bd9Sstevel@tonic-gate 		type = 2;
501*7c478bd9Sstevel@tonic-gate 
502*7c478bd9Sstevel@tonic-gate 	DEBUG(4, "copy: file1=<%s> ", file1);
503*7c478bd9Sstevel@tonic-gate 	DEBUG(4, "file2=<%s>\n", file2);
504*7c478bd9Sstevel@tonic-gate 	switch (type) {
505*7c478bd9Sstevel@tonic-gate 	case 0:
506*7c478bd9Sstevel@tonic-gate 
507*7c478bd9Sstevel@tonic-gate 		/*
508*7c478bd9Sstevel@tonic-gate 		 * all work here
509*7c478bd9Sstevel@tonic-gate 		 */
510*7c478bd9Sstevel@tonic-gate 		DEBUG(4, "all work here %d\n", type);
511*7c478bd9Sstevel@tonic-gate 
512*7c478bd9Sstevel@tonic-gate 		/*
513*7c478bd9Sstevel@tonic-gate 		 * check access control permissions
514*7c478bd9Sstevel@tonic-gate 		 */
515*7c478bd9Sstevel@tonic-gate 		if (ckexpf(file1))
516*7c478bd9Sstevel@tonic-gate 			 return(-6);
517*7c478bd9Sstevel@tonic-gate 		if (ckexpf(file2))
518*7c478bd9Sstevel@tonic-gate 			 return(-7);
519*7c478bd9Sstevel@tonic-gate 
520*7c478bd9Sstevel@tonic-gate 		setuid(Uid);
521*7c478bd9Sstevel@tonic-gate 		if (chkperm(file1, file2, strchr(Optns, 'd')) &&
522*7c478bd9Sstevel@tonic-gate 		    (access(file2, W_OK) == -1)) {
523*7c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, gettext("permission denied\n"));
524*7c478bd9Sstevel@tonic-gate 			cleanup(1);
525*7c478bd9Sstevel@tonic-gate 		}
526*7c478bd9Sstevel@tonic-gate 
527*7c478bd9Sstevel@tonic-gate 		/*
528*7c478bd9Sstevel@tonic-gate 		 * copy file locally
529*7c478bd9Sstevel@tonic-gate 		 *
530*7c478bd9Sstevel@tonic-gate 		 * Changed from uidxcp() to fic file made and owner
531*7c478bd9Sstevel@tonic-gate 		 * being modified for existing files, and local file
532*7c478bd9Sstevel@tonic-gate 		 * name expansion.
533*7c478bd9Sstevel@tonic-gate 		 */
534*7c478bd9Sstevel@tonic-gate 		DEBUG(2, "local copy: %s -> ", file1);
535*7c478bd9Sstevel@tonic-gate 		DEBUG(2, "%s\n", file2);
536*7c478bd9Sstevel@tonic-gate 
537*7c478bd9Sstevel@tonic-gate 		sprintf(command, "cp %s %s", file1, file2);
538*7c478bd9Sstevel@tonic-gate 		if ((cfp = popen(command, "r")) == NULL) {
539*7c478bd9Sstevel@tonic-gate 			perror("popen");
540*7c478bd9Sstevel@tonic-gate 			DEBUG(5, "popen failed - errno %d\n", errno);
541*7c478bd9Sstevel@tonic-gate 			setuid(Euid);
542*7c478bd9Sstevel@tonic-gate 			return (FAIL);
543*7c478bd9Sstevel@tonic-gate 		}
544*7c478bd9Sstevel@tonic-gate 		if (pclose(cfp) != 0) {
545*7c478bd9Sstevel@tonic-gate 			DEBUG(5, "Copy failed - errno %d\n", errno);
546*7c478bd9Sstevel@tonic-gate 			return (FAIL);
547*7c478bd9Sstevel@tonic-gate 		}
548*7c478bd9Sstevel@tonic-gate 		setuid(Euid);
549*7c478bd9Sstevel@tonic-gate 
550*7c478bd9Sstevel@tonic-gate 		/*
551*7c478bd9Sstevel@tonic-gate 		 * if user specified -m, notify "local" user
552*7c478bd9Sstevel@tonic-gate 		 */
553*7c478bd9Sstevel@tonic-gate 		 if ( Mail ) {
554*7c478bd9Sstevel@tonic-gate 		 	sprintf(msg,
555*7c478bd9Sstevel@tonic-gate 		 	"REQUEST: %s!%s --> %s!%s (%s)\n(SYSTEM %s) copy succeeded\n",
556*7c478bd9Sstevel@tonic-gate 		 	s1, file1, s2, file2, User, s2 );
557*7c478bd9Sstevel@tonic-gate 		 	mailst(User, "copy succeeded", msg, "", "");
558*7c478bd9Sstevel@tonic-gate 		}
559*7c478bd9Sstevel@tonic-gate 		/*
560*7c478bd9Sstevel@tonic-gate 		 * if user specified -n, notify "remote" user
561*7c478bd9Sstevel@tonic-gate 		 */
562*7c478bd9Sstevel@tonic-gate 		if ( Notify ) {
563*7c478bd9Sstevel@tonic-gate 			sprintf(msg, "%s from %s!%s arrived\n",
564*7c478bd9Sstevel@tonic-gate 				file2, s1, User );
565*7c478bd9Sstevel@tonic-gate 			mailst(Nuser, msg, msg, "", "");
566*7c478bd9Sstevel@tonic-gate 		}
567*7c478bd9Sstevel@tonic-gate 		return(0);
568*7c478bd9Sstevel@tonic-gate 	case 1:
569*7c478bd9Sstevel@tonic-gate 
570*7c478bd9Sstevel@tonic-gate 		/*
571*7c478bd9Sstevel@tonic-gate 		 * receive file
572*7c478bd9Sstevel@tonic-gate 		 */
573*7c478bd9Sstevel@tonic-gate 		DEBUG(4, "receive file - %d\n", type);
574*7c478bd9Sstevel@tonic-gate 
575*7c478bd9Sstevel@tonic-gate 		/*
576*7c478bd9Sstevel@tonic-gate 		 * expand source and destination file names
577*7c478bd9Sstevel@tonic-gate 		 * and check access permissions
578*7c478bd9Sstevel@tonic-gate 		 */
579*7c478bd9Sstevel@tonic-gate 		if (file1[0] != '~')
580*7c478bd9Sstevel@tonic-gate 			if (ckexpf(file1))
581*7c478bd9Sstevel@tonic-gate 				 return(6);
582*7c478bd9Sstevel@tonic-gate 		if (ckexpf(file2))
583*7c478bd9Sstevel@tonic-gate 			 return(7);
584*7c478bd9Sstevel@tonic-gate 
585*7c478bd9Sstevel@tonic-gate 
586*7c478bd9Sstevel@tonic-gate 		gename(DATAPRE, s2, Grade, dfile);
587*7c478bd9Sstevel@tonic-gate 
588*7c478bd9Sstevel@tonic-gate 		/*
589*7c478bd9Sstevel@tonic-gate 		 * insert JCL card in file
590*7c478bd9Sstevel@tonic-gate 		 */
591*7c478bd9Sstevel@tonic-gate 		cfp = syscfile(cfile, s1);
592*7c478bd9Sstevel@tonic-gate 		(void) fprintf(cfp,
593*7c478bd9Sstevel@tonic-gate 	       	"R %s %s %s %s %s %o %s %s\n", file1, file2,
594*7c478bd9Sstevel@tonic-gate 			User, Optns,
595*7c478bd9Sstevel@tonic-gate 			*Sfile ? Sfile : "dummy",
596*7c478bd9Sstevel@tonic-gate 			0777, Nuser, dfile);
597*7c478bd9Sstevel@tonic-gate 		(void) fclose(cfp);
598*7c478bd9Sstevel@tonic-gate 		(void) sprintf(msg, "%s!%s --> %s!%s", Rmtname, file1,
599*7c478bd9Sstevel@tonic-gate 		    Myname, file2);
600*7c478bd9Sstevel@tonic-gate 		logent(msg, "QUEUED");
601*7c478bd9Sstevel@tonic-gate 		break;
602*7c478bd9Sstevel@tonic-gate 	case 2:
603*7c478bd9Sstevel@tonic-gate 
604*7c478bd9Sstevel@tonic-gate 		/*
605*7c478bd9Sstevel@tonic-gate 		 * send file
606*7c478bd9Sstevel@tonic-gate 		 */
607*7c478bd9Sstevel@tonic-gate 		if (ckexpf(file1))
608*7c478bd9Sstevel@tonic-gate 			 return(6);
609*7c478bd9Sstevel@tonic-gate 		/* XQTDIR hook enables 3rd party uux requests (cough) */
610*7c478bd9Sstevel@tonic-gate 		DEBUG(4, "Workdir = <%s>\n", Wrkdir);
611*7c478bd9Sstevel@tonic-gate 		if (file2[0] != '~' && !EQUALS(Wrkdir, XQTDIR))
612*7c478bd9Sstevel@tonic-gate 			if (ckexpf(file2))
613*7c478bd9Sstevel@tonic-gate 				 return(7);
614*7c478bd9Sstevel@tonic-gate 		DEBUG(4, "send file - %d\n", type);
615*7c478bd9Sstevel@tonic-gate 
616*7c478bd9Sstevel@tonic-gate 		if (uidstat(file1, &stbuf) != 0) {
617*7c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr,
618*7c478bd9Sstevel@tonic-gate 			    gettext("can't get status for file %s\n"), file1);
619*7c478bd9Sstevel@tonic-gate 			return(8);
620*7c478bd9Sstevel@tonic-gate 		}
621*7c478bd9Sstevel@tonic-gate 		if ((stbuf.st_mode & S_IFMT) == S_IFDIR) {
622*7c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr,
623*7c478bd9Sstevel@tonic-gate 			    gettext("directory name illegal - %s\n"), file1);
624*7c478bd9Sstevel@tonic-gate 			return(9);
625*7c478bd9Sstevel@tonic-gate 		}
626*7c478bd9Sstevel@tonic-gate 		/* see if I can read this file as read uid, gid */
627*7c478bd9Sstevel@tonic-gate 		if (access(file1, R_OK) != 0) {
628*7c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr,
629*7c478bd9Sstevel@tonic-gate 			    gettext("uucp can't read (%s) mode (%o)\n"),
630*7c478bd9Sstevel@tonic-gate 			    file1, stbuf.st_mode&0777);
631*7c478bd9Sstevel@tonic-gate 			return(3);
632*7c478bd9Sstevel@tonic-gate 		}
633*7c478bd9Sstevel@tonic-gate 
634*7c478bd9Sstevel@tonic-gate 		/*
635*7c478bd9Sstevel@tonic-gate 		 * make a copy of file in spool directory
636*7c478bd9Sstevel@tonic-gate 		 */
637*7c478bd9Sstevel@tonic-gate 
638*7c478bd9Sstevel@tonic-gate 		gename(DATAPRE, s2, Grade, dfile);
639*7c478bd9Sstevel@tonic-gate 
640*7c478bd9Sstevel@tonic-gate 		if (Copy || !READANY(file1) ) {
641*7c478bd9Sstevel@tonic-gate 
642*7c478bd9Sstevel@tonic-gate 			if (uidxcp(file1, dfile))
643*7c478bd9Sstevel@tonic-gate 			    return(5);
644*7c478bd9Sstevel@tonic-gate 
645*7c478bd9Sstevel@tonic-gate 			(void) chmod(dfile, DFILEMODE);
646*7c478bd9Sstevel@tonic-gate 		}
647*7c478bd9Sstevel@tonic-gate 
648*7c478bd9Sstevel@tonic-gate 		cfp = syscfile(cfile, s2);
649*7c478bd9Sstevel@tonic-gate 		(void) fprintf(cfp, "S %s %s %s %s %s %lo %s %s\n",
650*7c478bd9Sstevel@tonic-gate 		    file1, file2, User, Optns, dfile,
651*7c478bd9Sstevel@tonic-gate 		    (long) stbuf.st_mode & LEGALMODE, Nuser, Sfile);
652*7c478bd9Sstevel@tonic-gate 		(void) fclose(cfp);
653*7c478bd9Sstevel@tonic-gate 		(void) sprintf(msg, "%s!%s --> %s!%s", Myname, file1,
654*7c478bd9Sstevel@tonic-gate 		    Rmtname, file2);
655*7c478bd9Sstevel@tonic-gate 		logent(msg, "QUEUED");
656*7c478bd9Sstevel@tonic-gate 		break;
657*7c478bd9Sstevel@tonic-gate 	}
658*7c478bd9Sstevel@tonic-gate 	_Transfer++;
659*7c478bd9Sstevel@tonic-gate 	return(0);
660*7c478bd9Sstevel@tonic-gate }
661*7c478bd9Sstevel@tonic-gate 
662*7c478bd9Sstevel@tonic-gate 
663*7c478bd9Sstevel@tonic-gate /*
664*7c478bd9Sstevel@tonic-gate  *	syscfile(file, sys)
665*7c478bd9Sstevel@tonic-gate  *	char	*file, *sys;
666*7c478bd9Sstevel@tonic-gate  *
667*7c478bd9Sstevel@tonic-gate  *	get the cfile for system sys (creat if need be)
668*7c478bd9Sstevel@tonic-gate  *	return stream pointer
669*7c478bd9Sstevel@tonic-gate  *
670*7c478bd9Sstevel@tonic-gate  *	returns
671*7c478bd9Sstevel@tonic-gate  *		stream pointer to open cfile
672*7c478bd9Sstevel@tonic-gate  *
673*7c478bd9Sstevel@tonic-gate  */
674*7c478bd9Sstevel@tonic-gate 
675*7c478bd9Sstevel@tonic-gate static FILE	*
676*7c478bd9Sstevel@tonic-gate syscfile(file, sys)
677*7c478bd9Sstevel@tonic-gate char	*file, *sys;
678*7c478bd9Sstevel@tonic-gate {
679*7c478bd9Sstevel@tonic-gate 	FILE	*cfp;
680*7c478bd9Sstevel@tonic-gate 
681*7c478bd9Sstevel@tonic-gate 	if (gtcfile(file, sys) == FAIL) {
682*7c478bd9Sstevel@tonic-gate 		gename(CMDPRE, sys, Grade, file);
683*7c478bd9Sstevel@tonic-gate 		ASSERT(access(file, 0) != 0, Fl_EXISTS, file, errno);
684*7c478bd9Sstevel@tonic-gate 		cfp = fdopen(creat(file, CFILEMODE), "w");
685*7c478bd9Sstevel@tonic-gate 		svcfile(file, sys, Sgrade);
686*7c478bd9Sstevel@tonic-gate 	} else
687*7c478bd9Sstevel@tonic-gate 		cfp = fopen(file, "a");
688*7c478bd9Sstevel@tonic-gate 	ASSERT(cfp != NULL, Ct_OPEN, file, errno);
689*7c478bd9Sstevel@tonic-gate 	return(cfp);
690*7c478bd9Sstevel@tonic-gate }
691*7c478bd9Sstevel@tonic-gate 
692*7c478bd9Sstevel@tonic-gate 
693*7c478bd9Sstevel@tonic-gate /*
694*7c478bd9Sstevel@tonic-gate  * generate and execute a uux command
695*7c478bd9Sstevel@tonic-gate  */
696*7c478bd9Sstevel@tonic-gate 
697*7c478bd9Sstevel@tonic-gate void
698*7c478bd9Sstevel@tonic-gate ruux(rmt, sys1, file1, sys2, fwd2, file2)
699*7c478bd9Sstevel@tonic-gate char *rmt, *sys1, *file1, *sys2, *fwd2, *file2;
700*7c478bd9Sstevel@tonic-gate {
701*7c478bd9Sstevel@tonic-gate     char cmd[BUFSIZ];
702*7c478bd9Sstevel@tonic-gate     char xcmd[BUFSIZ];
703*7c478bd9Sstevel@tonic-gate     char * xarg[6];
704*7c478bd9Sstevel@tonic-gate     int narg = 0;
705*7c478bd9Sstevel@tonic-gate     int i;
706*7c478bd9Sstevel@tonic-gate 
707*7c478bd9Sstevel@tonic-gate     /* get real Myname - it depends on who I'm calling--rmt */
708*7c478bd9Sstevel@tonic-gate     (void) mchFind(rmt);
709*7c478bd9Sstevel@tonic-gate     myName(Myname);
710*7c478bd9Sstevel@tonic-gate 
711*7c478bd9Sstevel@tonic-gate     xarg[narg++] = UUX;
712*7c478bd9Sstevel@tonic-gate     xarg[narg++] = "-C";
713*7c478bd9Sstevel@tonic-gate     if (*Xopts != NULLCHAR)
714*7c478bd9Sstevel@tonic-gate 	xarg[narg++] = Xopts;
715*7c478bd9Sstevel@tonic-gate     if (*Ropt  != ' ')
716*7c478bd9Sstevel@tonic-gate 	xarg[narg++] = Ropt;
717*7c478bd9Sstevel@tonic-gate 
718*7c478bd9Sstevel@tonic-gate     (void) sprintf(cmd, "%s!uucp -C", rmt);
719*7c478bd9Sstevel@tonic-gate 
720*7c478bd9Sstevel@tonic-gate     if (*Uopts != NULLCHAR)
721*7c478bd9Sstevel@tonic-gate 	(void) sprintf(cmd+strlen(cmd), " (%s) ", Uopts);
722*7c478bd9Sstevel@tonic-gate 
723*7c478bd9Sstevel@tonic-gate     if (*sys1 == NULLCHAR || EQUALS(sys1, Myname)) {
724*7c478bd9Sstevel@tonic-gate         if (ckexpf(file1))
725*7c478bd9Sstevel@tonic-gate   	    exit(6);
726*7c478bd9Sstevel@tonic-gate 	(void) sprintf(cmd+strlen(cmd), " %s!%s ", sys1, file1);
727*7c478bd9Sstevel@tonic-gate     }
728*7c478bd9Sstevel@tonic-gate     else
729*7c478bd9Sstevel@tonic-gate 	if (!EQUALS(rmt, sys1))
730*7c478bd9Sstevel@tonic-gate 	    (void) sprintf(cmd+strlen(cmd), " (%s!%s) ", sys1, file1);
731*7c478bd9Sstevel@tonic-gate 	else
732*7c478bd9Sstevel@tonic-gate 	    (void) sprintf(cmd+strlen(cmd), " (%s) ", file1);
733*7c478bd9Sstevel@tonic-gate 
734*7c478bd9Sstevel@tonic-gate     if (*fwd2 != NULLCHAR) {
735*7c478bd9Sstevel@tonic-gate 	if (*sys2 != NULLCHAR)
736*7c478bd9Sstevel@tonic-gate 	    (void) sprintf(cmd+strlen(cmd),
737*7c478bd9Sstevel@tonic-gate 		" (%s!%s!%s) ", sys2, fwd2, file2);
738*7c478bd9Sstevel@tonic-gate 	else
739*7c478bd9Sstevel@tonic-gate 	    (void) sprintf(cmd+strlen(cmd), " (%s!%s) ", fwd2, file2);
740*7c478bd9Sstevel@tonic-gate     }
741*7c478bd9Sstevel@tonic-gate     else {
742*7c478bd9Sstevel@tonic-gate 	if (*sys2 == NULLCHAR || EQUALS(sys2, Myname))
743*7c478bd9Sstevel@tonic-gate 	    if (ckexpf(file2))
744*7c478bd9Sstevel@tonic-gate 		exit(7);
745*7c478bd9Sstevel@tonic-gate 	(void) sprintf(cmd+strlen(cmd), " (%s!%s) ", sys2, file2);
746*7c478bd9Sstevel@tonic-gate     }
747*7c478bd9Sstevel@tonic-gate 
748*7c478bd9Sstevel@tonic-gate     xarg[narg++] = cmd;
749*7c478bd9Sstevel@tonic-gate     xarg[narg] = (char *) 0;
750*7c478bd9Sstevel@tonic-gate 
751*7c478bd9Sstevel@tonic-gate     xcmd[0] = NULLCHAR;
752*7c478bd9Sstevel@tonic-gate     for (i=0; i < narg; i++) {
753*7c478bd9Sstevel@tonic-gate 	strcat(xcmd, xarg[i]);
754*7c478bd9Sstevel@tonic-gate 	strcat(xcmd, " ");
755*7c478bd9Sstevel@tonic-gate     }
756*7c478bd9Sstevel@tonic-gate     DEBUG(2, "cmd: %s\n", xcmd);
757*7c478bd9Sstevel@tonic-gate     logent(xcmd, "QUEUED");
758*7c478bd9Sstevel@tonic-gate 
759*7c478bd9Sstevel@tonic-gate     if (fork() == 0) {
760*7c478bd9Sstevel@tonic-gate 	ASSERT(setuid(getuid()) == 0, "setuid", "failed", 99);
761*7c478bd9Sstevel@tonic-gate 	execv(UUX, xarg);
762*7c478bd9Sstevel@tonic-gate 	exit(0);
763*7c478bd9Sstevel@tonic-gate     }
764*7c478bd9Sstevel@tonic-gate     return;
765*7c478bd9Sstevel@tonic-gate }
766*7c478bd9Sstevel@tonic-gate 
767*7c478bd9Sstevel@tonic-gate void
768*7c478bd9Sstevel@tonic-gate usage()
769*7c478bd9Sstevel@tonic-gate {
770*7c478bd9Sstevel@tonic-gate 
771*7c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr, gettext(
772*7c478bd9Sstevel@tonic-gate 	"Usage:  %s [-c|-C] [-d|-f] [-g GRADE] [-jm] [-n USER]\\\n"
773*7c478bd9Sstevel@tonic-gate 	"[-r] [-s FILE] [-x DEBUG_LEVEL] source-files destination-file\n"),
774*7c478bd9Sstevel@tonic-gate 	Progname);
775*7c478bd9Sstevel@tonic-gate 	cleanup(-2);
776*7c478bd9Sstevel@tonic-gate }
777