BSD 3 development
[unix-history] / usr / src / cmd / uucp / uucp.c
CommitLineData
1b4660f8
BJ
1 /* uucp 2.7 5/24/79 19:40:13 */
2#include "uucp.h"
3#include "uucpdefs.h"
4#include <sys/types.h>
5#include <sys/stat.h>
6
7static char SiD[] = "@(#)uucp 2.7";
8
9/*
10 * uucp
11 */
12
13int Uid;
14char *Ropt = " ";
15char Path[100], Optns[10], Ename[8];
16char Grade = 'n';
17int Copy = 1;
18
19#define MAXCOUNT 20 /* maximun number of commands per C. file */
20
21main(argc, argv)
22char *argv[];
23{
24 int ret;
25 char *sysfile1, *sysfile2, *cp;
26 char file1[MAXFULLNAME], file2[MAXFULLNAME];
27 extern char *index();
28
29 uucpname(Myname);
30 Optns[0] = '-';
31 Ename[0] = Optns[1] = '\0';
32 while(argc>1 && argv[1][0] == '-'){
33 switch(argv[1][1]){
34 case 'c':
35 Copy = 0;
36 strcat(Optns, "c");
37 break;
38 case 'd':
39 strcat(Optns, "d");
40 break;
41 case 'e':
42 sprintf(Ename, "%.7s", &argv[1][2]);
43 break;
44 case 'g':
45 Grade = argv[1][2]; break;
46 case 'm':
47 strcat(Optns, "m");
48 break;
49 case 'r':
50 Ropt = argv[1];
51 break;
52 case 's':
53 Spool = &argv[1][2]; break;
54 case 'x':
55 Debug = atoi(&argv[1][2]);
56 if (Debug <= 0)
57 Debug = 1;
58 break;
59 default:
60 printf("unknown flag %s\n", argv[1]); break;
61 }
62 --argc; argv++;
63 }
64 DEBUG(4, "\n\n** %s **\n", "START");
65 ret = gwd(Wrkdir);
66 if (ret != 0) {
67 fprintf(stderr, "can't get working directory; will try to continue\n");
68 strcpy(Wrkdir, "/UNKNOWN");
69 }
70 chdir(Spool);
71
72 Uid = getuid();
73 ret = guinfo(Uid, User, Path);
74 ASSERT(ret == 0, "CAN NOT FIND UID %d\n", Uid);
75 DEBUG(4, "UID %d, ", Uid);
76 DEBUG(4, "User %s,", User);
77 DEBUG(4, "Ename (%s) ", Ename);
78 DEBUG(4, "PATH %s\n", Path);
79 if (argc < 3) {
80 fprintf(stderr, "usage uucp from ... to\n");
81 cleanup(0);
82 }
83
84
85 /* set up "to" system and file names */
86 if ((cp = index(argv[argc - 1], '!')) != NULL) {
87 sysfile2 = argv[argc - 1];
88 *cp = '\0';
89 if (*sysfile2 == '\0')
90 sysfile2 = Myname;
91 else
92 sprintf(Rmtname, "%.7s", sysfile2);
93 if (versys(sysfile2) != 0) {
94 fprintf(stderr, "bad system name: %s\n", sysfile2);
95 cleanup(0);
96 }
97 strcpy(file2, cp + 1);
98 }
99 else {
100 sysfile2 = Myname;
101 strcpy(file2, argv[argc - 1]);
102 }
103 if (strlen(sysfile2) > 7)
104 *(sysfile2 + 7) = '\0';
105
106
107 /* do each from argument */
108 while (argc > 2) {
109 if ((cp = index(argv[1], '!')) != NULL) {
110 sysfile1 = argv[1];
111 *cp = '\0';
112 if (strlen(sysfile1) > 7)
113 *(sysfile1 + 7) = '\0';
114 if (*sysfile1 == '\0')
115 sysfile1 = Myname;
116 else
117 sprintf(Rmtname, "%.7s", sysfile1);
118 if (versys(sysfile1) != 0) {
119 fprintf(stderr, "bad system name: %s\n", sysfile1);
120 cleanup(0);
121 }
122 strcpy(file1, cp + 1);
123 }
124 else {
125 sysfile1 = Myname;
126 strcpy(file1, argv[1]);
127 }
128 DEBUG(4, "file1 - %s\n", file1);
129 copy(sysfile1, file1, sysfile2, file2);
130 --argc;
131 argv++;
132 }
133
134 clscfile();
135 if (*Ropt != '-')
136 xuucico("");
137 cleanup(0);
138}
139
140cleanup(code)
141int code;
142{
143 logcls();
144 rmlock(NULL);
145 exit(code);
146}
147
148
149/***
150 * copy(s1, f1, s2, f2) generate copy files
151 * char *s1, *f1, *s2, *f2;
152 *
153 * return codes 0 | FAIL
154 */
155
156copy(s1, f1, s2, f2)
157char *s1, *f1, *s2, *f2;
158{
159 int ret, type, statret;
160 struct stat stbuf, stbuf1;
161 char dfile[NAMESIZE];
162 char file1[MAXFULLNAME], file2[MAXFULLNAME];
163 FILE *cfp;
164 extern char *index();
165 extern FILE *gtcfile();
166
167 type = 0;
168 strcpy(file1, f1);
169 strcpy(file2, f2);
170 if (strcmp(s1, Myname) != SAME)
171 type = 1;
172 if (strcmp(s2, Myname) != SAME)
173 type += 2;
174 if (type & 01)
175 if ((index(file1, '*') != NULL
176 || index(file1, '?') != NULL
177 || index(file1, '[') != NULL))
178 type = 4;
179
180 switch (type) {
181 case 0:
182 /* all work here */
183 DEBUG(4, "all work here %d\n", type);
184 expfile(file1);
185 expfile(file2);
186 if (stat(file1, &stbuf) != 0) {
187 fprintf(stderr, "can't get file status %s \n copy failed\n",
188 file1);
189 return(0);
190 }
191 statret = stat(file2, &stbuf1);
192 if (statret == 0
193 && stbuf.st_ino == stbuf1.st_ino
194 && stbuf.st_dev == stbuf1.st_dev) {
195 fprintf(stderr, "%s %s - same file; can't copy\n", file1, file2);
196 return(0);
197 }
198 if (chkpth(User, "", file1) != 0
199 || chkpth(User, "", file2) != 0) {
200 fprintf(stderr, "permission denied\n");
201 cleanup(1);
202 }
203 if ((stbuf.st_mode & ANYREAD) == 0) {
204 fprintf(stderr, "can't read file (%s) mode (%o)\n",
205 file1, stbuf.st_mode);
206 return(FAIL);
207 }
208 if (statret == 0 && (stbuf1.st_mode & ANYWRITE) == 0) {
209 fprintf(stderr, "can't write file (%s) mode (%o)\n",
210 file2, stbuf.st_mode);
211 return(FAIL);
212 }
213 xcp(file1, file2);
214 logent("WORK HERE", "DONE");
215 return(0);
216 case 1:
217 /* receive file */
218 DEBUG(4, "receive file - %d\n", type);
219 if (file1[0] != '~')
220 expfile(file1);
221 expfile(file2);
222 if (chkpth(User, "", file2) != 0) {
223 fprintf(stderr, "permission denied\n");
224 return(FAIL);
225 }
226 if (Ename[0] != '\0') {
227 /* execute uux - remote uucp */
228 xuux(Ename, s1, file1, s2, file2);
229 return(0);
230 }
231
232 cfp = gtcfile(s1);
233 fprintf(cfp, "R %s %s %s %s\n", file1, file2, User, Optns);
234 break;
235 case 2:
236 /* send file */
237 expfile(file1);
238 if (file2[0] != '~')
239 expfile(file2);
240 DEBUG(4, "send file - %d\n", type);
241
242 if (chkpth(User, "", file1) != 0) {
243 fprintf(stderr, "permission denied %s\n", file1);
244 return(FAIL);
245 }
246 if (stat(file1, &stbuf) != 0) {
247 fprintf(stderr, "can't get status for file %s\n", file1);
248 return(FAIL);
249 }
250 if ((stbuf.st_mode & S_IFMT) == S_IFDIR) {
251 fprintf(stderr, "directory name illegal - %s\n",
252 file1);
253 return(FAIL);
254 }
255 if ((stbuf.st_mode & ANYREAD) == 0) {
256 fprintf(stderr, "can't read file (%s) mode (%o)\n",
257 file1, stbuf.st_mode);
258 return(FAIL);
259 }
260 if (Ename[0] != '\0') {
261 /* execute uux - remote uucp */
262 xuux(Ename, s1, file1, s2, file2);
263 return(0);
264 }
265 if (Copy) {
266 gename(DATAPRE, s2, Grade, dfile);
267 if (xcp(file1, dfile) != 0) {
268 fprintf(stderr, "can't copy %s\n", file1);
269 return(FAIL);
270 }
271 chmod(dfile, 0666);
272 }
273 else {
274 /* make a dummy D. name */
275 /* cntrl.c knows names < 6 chars are dummy D. files */
276 strcpy(dfile, "D.0");
277 }
278 cfp = gtcfile(s2);
279 fprintf(cfp, "S %s %s %s %s %s %o\n", file1, file2,
280 User, Optns, dfile, stbuf.st_mode & 0777);
281 break;
282 case 3:
283 case 4:
284 /* send uucp command for execution on s1 */
285 DEBUG(4, "send uucp command - %d\n", type);
286 if (strcmp(s2, Myname) == SAME) {
287 expfile(file2);
288 if (chkpth(User, "", file2) != 0) {
289 fprintf(stderr, "permission denied\n");
290 return(FAIL);
291 }
292 }
293 if (Ename[0] != '\0') {
294 /* execute uux - remote uucp */
295 xuux(Ename, s1, file1, s2, file2);
296 return(0);
297 }
298 cfp = gtcfile(s1);
299 fprintf(cfp, "X %s %s!%s\n", file1, s2, file2);
300 break;
301 }
302 return(0);
303}
304
305/***
306 * xuux(ename, s1, s2, f1, f2) execute uux for remote uucp
307 *
308 * return code - none
309 */
310
311xuux(ename, s1, f1, s2, f2)
312char *ename, *s1, *s2, *f1, *f2;
313{
314 char cmd[200];
315
316 DEBUG(4, "Ropt(%s) ", Ropt);
317 DEBUG(4, "ename(%s) ", ename);
318 DEBUG(4, "s1(%s) ", s1);
319 DEBUG(4, "f1(%s) ", f1);
320 DEBUG(4, "s2(%s) ", s2);
321 DEBUG(4, "f2(%s)\n", f2);
322 sprintf(cmd, "uux %s %s!uucp %s!%s \\(%s!%s\\)",
323 Ropt, ename, s1, f1, s2, f2);
324 DEBUG(4, "cmd (%s)\n", cmd);
325 system(cmd);
326 return;
327}
328
329FILE *Cfp = NULL;
330char Cfile[NAMESIZE];
331
332/***
333 * gtcfile(sys) - get a Cfile descriptor
334 *
335 * return an open file descriptor
336 */
337
338FILE *
339gtcfile(sys)
340char *sys;
341{
342 static char presys[8] = "";
343 static int cmdcount = 0;
344
345 if (strcmp(presys, sys) != SAME /* this is !SAME on first call */
346 || ++cmdcount > MAXCOUNT) {
347
348 cmdcount = 1;
349 if (presys[0] != '\0') {
350 clscfile();
351 }
352 gename(CMDPRE, sys, Grade, Cfile);
353 Cfp = fopen(Cfile, "w");
354 ASSERT(Cfp != NULL, "CAN'T OPEN %s", Cfile);
355 chmod(0200, Cfile);
356 strcpy(presys, sys);
357 }
358 return(Cfp);
359}
360
361/***
362 * clscfile() - close cfile
363 *
364 * return code - none
365 */
366
367clscfile()
368{
369 if (Cfp == NULL)
370 return;
371 fclose(Cfp);
372 chmod(0666, Cfile);
373 logent(Cfile, "QUE'D");
374 Cfp = NULL;
375 return;
376}