| 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 | |
| 7 | static char SiD[] = "@(#)uucp 2.7"; |
| 8 | |
| 9 | /* |
| 10 | * uucp |
| 11 | */ |
| 12 | |
| 13 | int Uid; |
| 14 | char *Ropt = " "; |
| 15 | char Path[100], Optns[10], Ename[8]; |
| 16 | char Grade = 'n'; |
| 17 | int Copy = 1; |
| 18 | |
| 19 | #define MAXCOUNT 20 /* maximun number of commands per C. file */ |
| 20 | |
| 21 | main(argc, argv) |
| 22 | char *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 | |
| 140 | cleanup(code) |
| 141 | int 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 | |
| 156 | copy(s1, f1, s2, f2) |
| 157 | char *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 | |
| 311 | xuux(ename, s1, f1, s2, f2) |
| 312 | char *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 | |
| 329 | FILE *Cfp = NULL; |
| 330 | char Cfile[NAMESIZE]; |
| 331 | |
| 332 | /*** |
| 333 | * gtcfile(sys) - get a Cfile descriptor |
| 334 | * |
| 335 | * return an open file descriptor |
| 336 | */ |
| 337 | |
| 338 | FILE * |
| 339 | gtcfile(sys) |
| 340 | char *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 | |
| 367 | clscfile() |
| 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 | } |