Print this page
4337 eliminate /etc/TIMEZONE
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/bnu/uucico.c
+++ new/usr/src/cmd/bnu/uucico.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
↓ open down ↓ |
11 lines elided |
↑ open up ↑ |
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 + * Copyright 2014 Garrett D'Amore
23 + */
24 +/*
22 25 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 26 * Use is subject to license terms.
24 27 */
25 28
26 29 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
27 30 /* All Rights Reserved */
28 31
29 32
30 33 /*
31 34
32 35 * uucp file transfer program:
33 36 * to place a call to a remote machine, login, and
34 37 * copy files between the two machines.
35 38
36 39 */
37 40 /*
38 41 * Added check to limit the total number of uucicos as defined
39 42 * in the Limits file.
40 43 *
41 44 * Added -f flag to "force execution", ignoring the limit on the
42 45 * number of uucicos. This will be used when invoking uucico from
43 46 * Uutry.
44 47 */
45 48
46 49 #include "uucp.h"
47 50 #include "log.h"
48 51
49 52 #ifndef V7
50 53 #include <sys/mkdev.h>
51 54 #endif /* V7 */
52 55
53 56 #ifdef TLI
54 57 #include <sys/tiuser.h>
55 58 #endif /* TLI */
56 59
57 60 jmp_buf Sjbuf;
58 61 extern unsigned msgtime;
59 62 char uuxqtarg[MAXBASENAME] = {'\0'};
60 63 int uuxqtflag = 0;
61 64
62 65 extern int (*Setup)(), (*Teardown)(); /* defined in interface.c */
63 66
64 67 #define USAGE "Usage: %s [-x NUM] [-r [0|1]] -s SYSTEM -u USERID -d SPOOL -i INTERFACE [-f]\n"
65 68 extern void closedem();
66 69 void cleanup(), cleanTM();
67 70
68 71 extern int sysaccess(), guinfo(), eaccess(), countProcs(), interface(),
69 72 savline(), omsg(), restline(), imsg(), callok(), gnxseq(),
70 73 cmtseq(), conn(), startup(), cntrl();
71 74 extern void setuucp(), fixline(), gename(), ulkseq(), pfEndfile();
72 75
73 76 #ifdef NOSTRANGERS
74 77 static void checkrmt(); /* See if we want to talk to remote. */
75 78 #endif /* NOSTRANGERS */
76 79
77 80 extern char *Mytype;
78 81
79 82 static char *pskip();
80 83
81 84 int
82 85 main(argc, argv, envp)
83 86 int argc;
84 87 char *argv[];
85 88 char **envp;
86 89 {
87 90
88 91 extern void intrEXIT(), onintr(), timeout();
89 92 extern void setservice();
90 93 #ifndef ATTSVR3
91 94 void setTZ();
92 95 #endif /* ATTSVR3 */
93 96 int ret, seq, exitcode;
94 97 char file[NAMESIZE];
95 98 char msg[BUFSIZ], *p, *q;
96 99 char xflag[6]; /* -xN N is single digit */
97 100 char *ttyn;
98 101 char *iface; /* interface name */
99 102 char cb[128];
100 103 time_t ts, tconv;
101 104 char lockname[MAXFULLNAME];
102 105 struct limits limitval;
103 106 int maxnumb;
104 107 int force = 0; /* set to force execution, ignoring uucico limit */
105 108 char gradedir[2*NAMESIZE];
106 109
107 110 /* Set locale environment variables local definitions */
108 111 (void) setlocale(LC_ALL, "");
109 112 #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
110 113 #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it wasn't */
111 114 #endif
112 115 (void) textdomain(TEXT_DOMAIN);
113 116
114 117 Ulimit = ulimit(1,0L);
115 118 Uid = getuid();
116 119 Euid = geteuid(); /* this should be UUCPUID */
117 120 if (Uid == 0)
118 121 setuid(UUCPUID);
119 122 Env = envp;
120 123 Role = SLAVE;
121 124 strcpy(Logfile, LOGCICO);
122 125 *Rmtname = NULLCHAR;
123 126 Ifn = Ofn = -1; /* must be set before signal handlers */
124 127
125 128 closedem();
126 129 time(&Nstat.t_qtime);
127 130 tconv = Nstat.t_start = Nstat.t_qtime;
128 131 strcpy(Progname, "uucico");
129 132 setservice(Progname);
130 133 ret = sysaccess(EACCESS_SYSTEMS);
131 134 ASSERT(ret == 0, Ct_OPEN, "Systems", ret);
132 135 ret = sysaccess(EACCESS_DEVICES);
133 136 ASSERT(ret == 0, Ct_OPEN, "Devices", ret);
134 137 ret = sysaccess(EACCESS_DIALERS);
135 138 ASSERT(ret == 0, Ct_OPEN, "Dialers", ret);
136 139 Pchar = 'C';
137 140 (void) signal(SIGILL, intrEXIT);
138 141 (void) signal(SIGTRAP, intrEXIT);
139 142 (void) signal(SIGIOT, intrEXIT);
140 143 (void) signal(SIGEMT, intrEXIT);
141 144 (void) signal(SIGFPE, intrEXIT);
142 145 (void) signal(SIGBUS, intrEXIT);
143 146 (void) signal(SIGSEGV, intrEXIT);
144 147 (void) signal(SIGSYS, intrEXIT);
145 148 if (signal(SIGPIPE, SIG_IGN) != SIG_IGN) /* This for sockets */
146 149 (void) signal(SIGPIPE, intrEXIT);
147 150 (void) signal(SIGINT, onintr);
148 151 (void) signal(SIGHUP, onintr);
149 152 (void) signal(SIGQUIT, onintr);
150 153 (void) signal(SIGTERM, onintr);
151 154 #ifdef SIGUSR1
152 155 (void) signal(SIGUSR1, SIG_IGN);
153 156 #endif
154 157 #ifdef SIGUSR2
155 158 (void) signal(SIGUSR2, SIG_IGN);
156 159 #endif
157 160 #ifdef BSD4_2
158 161 (void) sigsetmask(sigblock(0) & ~(1 << (SIGALRM - 1)));
159 162 #endif /*BSD4_2*/
160 163
161 164 pfInit();
162 165 scInit("xfer");
163 166 ret = guinfo(Euid, User);
164 167 ASSERT(ret == 0, "BAD UID ", "", ret);
165 168 strncpy(Uucp, User, NAMESIZE);
166 169
167 170 setuucp(User);
168 171
169 172 *xflag = NULLCHAR;
170 173 iface = "UNIX";
171 174
172 175 while ((ret = getopt(argc, argv, "fd:c:r:s:x:u:i:")) != EOF) {
173 176 switch (ret) {
174 177 case 'd':
175 178 if ( eaccess(optarg, 01) != 0 ) {
176 179 (void) fprintf(stderr, gettext("%s: cannot"
177 180 " access spool directory %s\n"),
178 181 Progname, optarg);
179 182 exit(1);
180 183 }
181 184 Spool = optarg;
182 185 break;
183 186 case 'c':
184 187 Mytype = optarg;
185 188 break;
186 189 case 'f':
187 190 ++force;
188 191 break;
189 192 case 'r':
190 193 if ( (Role = atoi(optarg)) != MASTER && Role != SLAVE ) {
191 194 (void) fprintf(stderr, gettext("%s: bad value"
192 195 " '%s' for -r argument\n" USAGE),
193 196 Progname, optarg, Progname);
194 197 exit(1);
195 198 }
196 199 break;
197 200 case 's':
198 201 strncpy(Rmtname, optarg, MAXFULLNAME-1);
199 202 if (versys(Rmtname)) {
200 203 (void) fprintf(stderr,
201 204 gettext("%s: %s not in Systems file\n"),
202 205 Progname, optarg);
203 206 cleanup(101);
204 207 }
205 208 /* set args for possible xuuxqt call */
206 209 strcpy(uuxqtarg, Rmtname);
207 210 /* if versys put a longer name in, truncate it again */
208 211 Rmtname[MAXBASENAME] = '\0';
209 212 break;
210 213 case 'x':
211 214 Debug = atoi(optarg);
212 215 if (Debug <= 0)
213 216 Debug = 1;
214 217 if (Debug > 9)
215 218 Debug = 9;
216 219 (void) sprintf(xflag, "-x%d", Debug);
217 220 break;
218 221 case 'u':
219 222 DEBUG(4, "Loginuser %s specified\n", optarg);
220 223 strncpy(Loginuser, optarg, NAMESIZE);
221 224 Loginuser[NAMESIZE - 1] = NULLCHAR;
222 225 break;
223 226 case 'i':
224 227 /* interface type */
225 228 iface = optarg;
226 229 break;
227 230 default:
228 231 (void) fprintf(stderr, gettext(USAGE), Progname);
229 232 exit(1);
230 233 }
231 234 }
232 235
233 236 if (Role == MASTER || *Loginuser == NULLCHAR) {
234 237 ret = guinfo(Uid, Loginuser);
235 238 ASSERT(ret == 0, "BAD LOGIN_UID ", "", ret);
236 239 }
237 240
238 241 /* limit the total number of uucicos */
239 242 if (force) {
240 243 DEBUG(4, "force flag set (ignoring uucico limit)\n%s", "");
241 244 } else if (scanlimit("uucico", &limitval) == FAIL) {
242 245 DEBUG(1, "No limits for uucico in %s\n", LIMITS);
243 246 } else {
244 247 maxnumb = limitval.totalmax;
245 248 if (maxnumb < 0) {
246 249 DEBUG(4, "Non-positive limit for uucico in %s\n", LIMITS);
247 250 DEBUG(1, "No limits for uucico\n%s", "");
248 251 } else {
249 252 DEBUG(4, "Uucico limit %d -- ", maxnumb);
250 253 (void) sprintf(lockname, "%s.", LOCKPRE);
251 254 if (countProcs(lockname, (maxnumb-1)) == FALSE) {
252 255 DEBUG(4, "exiting\n%s", "");
253 256 cleanup(101);
254 257 }
255 258 DEBUG(4, "continuing\n%s", "");
256 259 }
257 260 }
258 261
259 262 pfStrtConn((Role == MASTER) ? 'M' : 'S');
260 263 if (Role == MASTER) {
261 264 if (*Rmtname == NULLCHAR) {
262 265 DEBUG(5, "No -s specified\n%s" , "");
263 266 cleanup(101);
264 267 }
265 268 /* get Myname - it depends on who I'm calling--Rmtname */
266 269 (void) mchFind(Rmtname);
267 270 myName(Myname);
268 271 if (EQUALSN(Rmtname, Myname, MAXBASENAME)) {
269 272 DEBUG(5, "This system specified: -sMyname: %s, ", Myname);
270 273 cleanup(101);
271 274 }
272 275 acInit("xfer");
273 276 }
274 277
275 278 ASSERT(chdir(Spool) == 0, Ct_CHDIR, Spool, errno);
276 279 strcpy(Wrkdir, Spool);
277 280
278 281 scReqsys((Role == MASTER) ? Myname : Rmtname); /* log requestor system */
279 282
280 283 if (Role == SLAVE) {
281 284
282 285 #ifndef ATTSVR3
283 286 setTZ();
284 287 #endif /* ATTSVR3 */
285 288
286 289 if (freopen(RMTDEBUG, "a", stderr) == 0) {
287 290 errent(Ct_OPEN, RMTDEBUG, errno, __FILE__, __LINE__);
288 291 freopen("/dev/null", "w", stderr);
289 292 }
290 293 if ( interface(iface) ) {
291 294 (void)fprintf(stderr,
292 295 "%s: invalid interface %s\n", Progname, iface);
293 296 cleanup(101);
294 297 }
295 298 /*master setup will be called from processdev()*/
296 299 if ( (*Setup)( Role, &Ifn, &Ofn ) ) {
297 300 DEBUG(5, "SLAVE Setup failed%s", "");
298 301 cleanup(101);
299 302 }
300 303
301 304 /*
302 305 * initial handshake
303 306 */
304 307 (void) savline();
305 308 fixline(Ifn, 0, D_ACU);
306 309 /* get MyName - use logFind to check PERMISSIONS file */
307 310 (void) logFind(Loginuser, "");
308 311 myName(Myname);
309 312
310 313 DEBUG(4,"cico.c: Myname - %s\n",Myname);
311 314 DEBUG(4,"cico.c: Loginuser - %s\n",Loginuser);
312 315 fflush(stderr);
313 316 Nstat.t_scall = times(&Nstat.t_tga);
314 317 (void) sprintf(msg, "here=%s", Myname);
315 318 omsg('S', msg, Ofn);
316 319 (void) signal(SIGALRM, timeout);
317 320 (void) alarm(msgtime); /* give slow machines a second chance */
318 321 if (setjmp(Sjbuf)) {
319 322
320 323 /*
321 324 * timed out
322 325 */
323 326 (void) restline();
324 327 rmlock(CNULL);
325 328 exit(0);
326 329 }
327 330 for (;;) {
328 331 ret = imsg(msg, Ifn);
329 332 if (ret != 0) {
330 333 (void) alarm(0);
331 334 (void) restline();
332 335 rmlock(CNULL);
333 336 exit(0);
334 337 }
335 338 if (msg[0] == 'S')
336 339 break;
337 340 }
338 341 Nstat.t_ecall = times(&Nstat.t_tga);
339 342 (void) alarm(0);
340 343 q = &msg[1];
341 344 p = pskip(q);
342 345 strncpy(Rmtname, q, MAXBASENAME);
343 346 Rmtname[MAXBASENAME] = '\0';
344 347
345 348 seq = 0;
346 349 while (p && *p == '-') {
347 350 q = pskip(p);
348 351 switch(*(++p)) {
349 352 case 'x':
350 353 Debug = atoi(++p);
351 354 if (Debug <= 0)
352 355 Debug = 1;
353 356 (void) sprintf(xflag, "-x%d", Debug);
354 357 break;
355 358 case 'Q':
356 359 seq = atoi(++p);
357 360 if (seq < 0)
358 361 seq = 0;
359 362 break;
360 363 #ifdef MAXGRADE
361 364 case 'v': /* version -- -vname=val or -vname */
362 365 if (strncmp(++p, "grade=", 6) == 0 &&
363 366 isalnum(p[6]))
364 367 MaxGrade = p[6];
365 368 break;
366 369 #endif /* MAXGRADE */
367 370 case 'R':
368 371 Restart++;
369 372 p++;
370 373 break;
371 374 case 'U':
372 375 SizeCheck++;
373 376 RemUlimit = strtol(++p, (char **) NULL,0);
374 377 break;
375 378 default:
376 379 break;
377 380 }
378 381 p = q;
379 382 }
380 383 DEBUG(4, "sys-%s\n", Rmtname);
381 384 if (strpbrk(Rmtname, Shchar) != NULL) {
382 385 DEBUG(4, "Bad remote system name '%s'\n", Rmtname);
383 386 logent(Rmtname, "BAD REMOTE SYSTEM NAME");
384 387 omsg('R', "Bad remote system name", Ofn);
385 388 cleanup(101);
386 389 }
387 390 if (Restart)
388 391 CDEBUG(1,"Checkpoint Restart enabled\n%s", "");
389 392
390 393 #ifdef NOSTRANGERS
391 394 checkrmt(); /* Do we know the remote system. */
392 395 #else
393 396 (void) versys(Rmtname); /* in case the real name is longer */
394 397 #endif /* NOSTRANGERS */
395 398
396 399 (void) sprintf(lockname, "%ld", (long) getpid());
397 400 if (umlock(LOCKPRE, lockname)) {
398 401 omsg('R', "LCK", Ofn);
399 402 cleanup(101);
400 403 }
401 404
402 405 /* validate login using PERMISSIONS file */
403 406 if (logFind(Loginuser, Rmtname) == FAIL) {
404 407 scWrite(); /* log security violation */
405 408 Uerror = SS_BAD_LOG_MCH;
406 409 logent(UERRORTEXT, "FAILED");
407 410 systat(Rmtname, SS_BAD_LOG_MCH, UERRORTEXT,
408 411 Retrytime);
409 412 omsg('R', "LOGIN", Ofn);
410 413 cleanup(101);
411 414 }
412 415
413 416 ret = callBack();
414 417 DEBUG(4,"return from callcheck: %s",ret ? "TRUE" : "FALSE");
415 418 if (ret==TRUE) {
416 419 (void) signal(SIGINT, SIG_IGN);
417 420 (void) signal(SIGHUP, SIG_IGN);
418 421 omsg('R', "CB", Ofn);
419 422 logent("CALLBACK", "REQUIRED");
420 423 /*
421 424 * set up for call back
422 425 */
423 426 chremdir(Rmtname);
424 427 (void) sprintf(file, "%s/%c", Rmtname, D_QUEUE);
425 428 chremdir(file);
426 429 gename(CMDPRE, Rmtname, 'C', file);
427 430 (void) close(creat(file, CFILEMODE));
428 431 if (callok(Rmtname) == SS_CALLBACK_LOOP) {
429 432 systat(Rmtname, SS_CALLBACK_LOOP, "CALL BACK - LOOP", Retrytime);
430 433 } else {
431 434 systat(Rmtname, SS_CALLBACK, "CALL BACK", Retrytime);
432 435 xuucico(Rmtname);
433 436 }
434 437 cleanup(101);
435 438 }
436 439
437 440 if (callok(Rmtname) == SS_SEQBAD) {
438 441 Uerror = SS_SEQBAD;
439 442 logent(UERRORTEXT, "PREVIOUS");
440 443 omsg('R', "BADSEQ", Ofn);
441 444 cleanup(101);
442 445 }
443 446
444 447 if (gnxseq(Rmtname) == seq) {
445 448 if (Restart) {
446 449 if (SizeCheck)
447 450 (void) sprintf (msg, "OK -R -U0x%lx %s",
448 451 Ulimit, xflag);
449 452 else
450 453 (void) sprintf (msg, "OK -R %s", xflag);
451 454 omsg('R', msg, Ofn);
452 455 } else
453 456 omsg('R', "OK", Ofn);
454 457 (void) cmtseq();
455 458 } else {
456 459 Uerror = SS_SEQBAD;
457 460 systat(Rmtname, SS_SEQBAD, UERRORTEXT, Retrytime);
458 461 logent(UERRORTEXT, "HANDSHAKE FAILED");
459 462 ulkseq();
460 463 omsg('R', "BADSEQ", Ofn);
461 464 cleanup(101);
462 465 }
463 466 ttyn = ttyname(Ifn);
464 467 if (ttyn != CNULL && *ttyn != NULLCHAR) {
465 468 struct stat ttysbuf;
466 469 if ( fstat(Ifn,&ttysbuf) == 0 )
467 470 Dev_mode = ttysbuf.st_mode;
468 471 else
469 472 Dev_mode = R_DEVICEMODE;
470 473 if ( EQUALSN(ttyn,"/dev/",5) )
471 474 strcpy(Dc, ttyn+5);
472 475 else
473 476 strcpy(Dc, ttyn);
474 477 chmod(ttyn, S_DEVICEMODE);
475 478 } else
476 479 strcpy(Dc, "notty");
477 480 /* set args for possible xuuxqt call */
478 481 strcpy(uuxqtarg, Rmtname);
479 482 }
480 483
481 484 strcpy(User, Uucp);
482 485 /*
483 486 * Ensure reasonable ulimit (MINULIMIT)
484 487 */
485 488
486 489 #ifndef V7
487 490 {
488 491 long minulimit;
489 492 minulimit = ulimit(1, (long) 0);
490 493 ASSERT(minulimit >= MINULIMIT, "ULIMIT TOO SMALL",
491 494 Loginuser, (int) minulimit);
492 495 }
493 496 #endif
494 497 if (Role == MASTER && callok(Rmtname) != 0) {
495 498 logent("SYSTEM STATUS", "CAN NOT CALL");
496 499 cleanup(101);
497 500 }
498 501
499 502 chremdir(Rmtname);
500 503
501 504 (void) strcpy(Wrkdir, RemSpool);
502 505 if (Role == MASTER) {
503 506
504 507 /*
505 508 * master part
506 509 */
507 510 (void) signal(SIGINT, SIG_IGN);
508 511 (void) signal(SIGHUP, SIG_IGN);
509 512 (void) signal(SIGQUIT, SIG_IGN);
510 513 if (Ifn != -1 && Role == MASTER) {
511 514 (void) (*Write)(Ofn, EOTMSG, strlen(EOTMSG));
512 515 (void) close(Ofn);
513 516 (void) close(Ifn);
514 517 Ifn = Ofn = -1;
515 518 rmlock(CNULL);
516 519 sleep(3);
517 520 }
518 521
519 522 /*
520 523 * Find the highest priority job grade that has
521 524 * jobs to do. This is needed to form the lock name.
522 525 */
523 526
524 527 findgrade(RemSpool, JobGrade);
525 528 DEBUG(4, "Job grade to process - %s\n", JobGrade);
526 529
527 530 /*
528 531 * Lock the job grade if there is one to process.
529 532 */
530 533
531 534 if (*JobGrade != NULLCHAR) {
532 535 (void) sprintf(gradedir, "%s/%s", Rmtname, JobGrade);
533 536 chremdir(gradedir);
534 537
535 538 (void) sprintf(lockname, "%.*s.%s", SYSNSIZE, Rmtname, JobGrade);
536 539 (void) sprintf(msg, "call to %s - process job grade %s ",
537 540 Rmtname, JobGrade);
538 541 if (umlock(LOCKPRE, lockname) != 0) {
539 542 logent(msg, "LOCKED");
540 543 CDEBUG(1, "Currently Talking With %s\n",
541 544 Rmtname);
542 545 cleanup(100);
543 546 }
544 547 } else {
545 548 (void) sprintf(msg, "call to %s - no work", Rmtname);
546 549 }
547 550
548 551 Nstat.t_scall = times(&Nstat.t_tga);
549 552 Ofn = Ifn = conn(Rmtname);
550 553 Nstat.t_ecall = times(&Nstat.t_tga);
551 554 if (Ofn < 0) {
552 555 delock(LOCKPRE, lockname);
553 556 logent(UERRORTEXT, "CONN FAILED");
554 557 systat(Rmtname, Uerror, UERRORTEXT, Retrytime);
555 558 cleanup(101);
556 559 } else {
557 560 logent(msg, "SUCCEEDED");
558 561 ttyn = ttyname(Ifn);
559 562 if (ttyn != CNULL && *ttyn != NULLCHAR) {
560 563 struct stat ttysbuf;
561 564 if ( fstat(Ifn,&ttysbuf) == 0 )
562 565 Dev_mode = ttysbuf.st_mode;
563 566 else
564 567 Dev_mode = R_DEVICEMODE;
565 568 chmod(ttyn, M_DEVICEMODE);
566 569 }
567 570 }
568 571
569 572 if (setjmp(Sjbuf)) {
570 573 delock(LOCKPRE, lockname);
571 574 Uerror = SS_LOGIN_FAILED;
572 575 logent(Rmtname, UERRORTEXT);
573 576 systat(Rmtname, SS_LOGIN_FAILED,
574 577 UERRORTEXT, Retrytime);
575 578 DEBUG(4, "%s - failed\n", UERRORTEXT);
576 579 cleanup(101);
577 580 }
578 581 (void) signal(SIGALRM, timeout);
579 582 /* give slow guys lots of time to thrash */
580 583 (void) alarm(2 * msgtime);
581 584 for (;;) {
582 585 ret = imsg(msg, Ifn);
583 586 if (ret != 0) {
584 587 continue; /* try again */
585 588 }
586 589 if (msg[0] == 'S')
587 590 break;
588 591 }
589 592 (void) alarm(0);
590 593 if(EQUALSN("here=", &msg[1], 5)){
591 594 /* This may be a problem, we check up to MAXBASENAME
592 595 * characters now. The old comment was:
593 596 * this is a problem. We'd like to compare with an
594 597 * untruncated Rmtname but we fear incompatability.
595 598 * So we'll look at most 6 chars (at most).
596 599 */
597 600 (void) pskip(&msg[6]);
598 601 if (!EQUALSN(&msg[6], Rmtname, MAXBASENAME)) {
599 602 delock(LOCKPRE, lockname);
600 603 Uerror = SS_WRONG_MCH;
601 604 logent(&msg[6], UERRORTEXT);
602 605 systat(Rmtname, SS_WRONG_MCH, UERRORTEXT,
603 606 Retrytime);
604 607 DEBUG(4, "%s - failed\n", UERRORTEXT);
605 608 cleanup(101);
606 609 }
607 610 }
608 611 CDEBUG(1,"Login Successful: System=%s\n",&msg[6]);
609 612 seq = gnxseq(Rmtname);
610 613 (void) sprintf(msg, "%s -Q%d -R -U0x%lx %s",
611 614 Myname, seq, Ulimit, xflag);
612 615 #ifdef MAXGRADE
613 616 if (MaxGrade != NULLCHAR) {
614 617 p = strchr(msg, NULLCHAR);
615 618 sprintf(p, " -vgrade=%c", MaxGrade);
616 619 }
617 620 #endif /* MAXGRADE */
618 621 omsg('S', msg, Ofn);
619 622 (void) alarm(msgtime); /* give slow guys some thrash time */
620 623 for (;;) {
621 624 ret = imsg(msg, Ifn);
622 625 DEBUG(4, "msg-%s\n", msg);
623 626 if (ret != 0) {
624 627 (void) alarm(0);
625 628 delock(LOCKPRE, lockname);
626 629 ulkseq();
627 630 cleanup(101);
628 631 }
629 632 if (msg[0] == 'R')
630 633 break;
631 634 }
632 635 (void) alarm(0);
633 636
634 637 /* check for rejects from remote */
635 638 Uerror = 0;
636 639 if (EQUALS(&msg[1], "LCK"))
637 640 Uerror = SS_RLOCKED;
638 641 else if (EQUALS(&msg[1], "LOGIN"))
639 642 Uerror = SS_RLOGIN;
640 643 else if (EQUALS(&msg[1], "CB"))
641 644 Uerror = (callBack() ? SS_CALLBACK_LOOP : SS_CALLBACK);
642 645 else if (EQUALS(&msg[1], "You are unknown to me"))
643 646 Uerror = SS_RUNKNOWN;
644 647 else if (EQUALS(&msg[1], "BADSEQ"))
645 648 Uerror = SS_SEQBAD;
646 649 else if (!EQUALSN(&msg[1], "OK", 2))
647 650 Uerror = SS_UNKNOWN_RESPONSE;
648 651 if (Uerror) {
649 652 delock(LOCKPRE, lockname);
650 653 systat(Rmtname, Uerror, UERRORTEXT, Retrytime);
651 654 logent(UERRORTEXT, "HANDSHAKE FAILED");
652 655 CDEBUG(1, "HANDSHAKE FAILED: %s\n", UERRORTEXT);
653 656 ulkseq();
654 657 cleanup(101);
655 658 }
656 659 (void) cmtseq();
657 660
658 661 /*
659 662 * See if we have any additional parameters on the OK
660 663 */
661 664
662 665 if (strlen(&msg[3])) {
663 666 p = pskip(&msg[3]);
664 667 while (p && *p == '-') {
665 668 q = pskip(p);
666 669 switch(*(++p)) {
667 670 case 'R':
668 671 Restart++;
669 672 p++;
670 673 break;
671 674 case 'U':
672 675 SizeCheck++;
673 676 RemUlimit = strtol(++p, (char **) NULL, 0);
674 677 break;
675 678 case 'x':
676 679 if (!Debug) {
677 680 Debug = atoi(++p);
678 681 if (Debug <= 0)
679 682 Debug = 1;
680 683 }
681 684 break;
682 685 default:
683 686 break;
684 687 }
685 688 p = q;
686 689 }
687 690 }
688 691
689 692 }
690 693 DEBUG(4, " Rmtname %s, ", Rmtname);
691 694 DEBUG(4, " Restart %s, ", (Restart ? "YES" : "NO"));
692 695 DEBUG(4, "Role %s, ", Role ? "MASTER" : "SLAVE");
693 696 DEBUG(4, "Ifn - %d, ", Ifn);
694 697 DEBUG(4, "Loginuser - %s\n", Loginuser);
695 698
696 699 /* alarm/setjmp added here due to experience with uucico
697 700 * hanging for hours in imsg().
698 701 */
699 702 if (setjmp(Sjbuf)) {
700 703 delock(LOCKPRE, lockname);
701 704 logent("startup", "TIMEOUT");
702 705 DEBUG(4, "%s - timeout\n", "startup");
703 706 cleanup(101);
704 707 }
705 708 (void) alarm(MAXSTART);
706 709 ret = startup();
707 710 (void) alarm(0);
708 711
709 712 if (ret != SUCCESS) {
710 713 delock(LOCKPRE, lockname);
711 714 logent("startup", "FAILED");
712 715 Uerror = SS_STARTUP;
713 716 CDEBUG(1, "%s\n", UERRORTEXT);
714 717 systat(Rmtname, Uerror, UERRORTEXT, Retrytime);
715 718 exitcode = 101;
716 719 } else {
717 720 pfConnected(Rmtname, Dc);
718 721 acConnected(Rmtname, Dc);
719 722 logent("startup", "OK");
720 723 systat(Rmtname, SS_INPROGRESS, UTEXT(SS_INPROGRESS),Retrytime);
721 724 Nstat.t_sftp = times(&Nstat.t_tga);
722 725
723 726 exitcode = cntrl();
724 727 Nstat.t_eftp = times(&Nstat.t_tga);
725 728 DEBUG(4, "cntrl - %d\n", exitcode);
726 729 (void) signal(SIGINT, SIG_IGN);
727 730 (void) signal(SIGHUP, SIG_IGN);
728 731 (void) signal(SIGALRM, timeout);
729 732
730 733 if (exitcode == 0) {
731 734 (void) time(&ts);
732 735 (void) sprintf(cb, "conversation complete %s %ld",
733 736 Dc, ts - tconv);
734 737 logent(cb, "OK");
735 738 systat(Rmtname, SS_OK, UTEXT(SS_OK), Retrytime);
736 739
737 740 } else {
738 741 logent("conversation complete", "FAILED");
739 742 systat(Rmtname, SS_CONVERSATION,
740 743 UTEXT(SS_CONVERSATION), Retrytime);
741 744 }
742 745 (void) alarm(msgtime); /* give slow guys some thrash time */
743 746 omsg('O', "OOOOO", Ofn);
744 747 CDEBUG(4, "send OO %d,", ret);
745 748 if (!setjmp(Sjbuf)) {
746 749 for (;;) {
747 750 omsg('O', "OOOOO", Ofn);
748 751 ret = imsg(msg, Ifn);
749 752 if (ret != 0)
750 753 break;
751 754 if (msg[0] == 'O')
752 755 break;
753 756 }
754 757 }
755 758 (void) alarm(0);
756 759 }
757 760 cleanup(exitcode);
758 761 /*NOTREACHED*/
759 762 return (0);
760 763 }
761 764
762 765 /*
763 766 * clean and exit with "code" status
764 767 */
765 768 void
766 769 cleanup(code)
767 770 int code;
768 771 {
769 772 (void) signal(SIGINT, SIG_IGN);
770 773 (void) signal(SIGHUP, SIG_IGN);
771 774 rmlock(CNULL);
772 775 closedem();
773 776 alarm(msgtime); /* Start timer in case closes hang. */
774 777 if (setjmp(Sjbuf) == 0)
775 778 (*Teardown)( Role, Ifn, Ofn );
776 779 alarm(0); /* Turn off timer. */
777 780 DEBUG(4, "exit code %d\n", code);
778 781 CDEBUG(1, "Conversation Complete: Status %s\n\n",
779 782 code ? "FAILED" : "SUCCEEDED");
780 783
781 784 cleanTM();
782 785 if ((code == 0) && (uuxqtflag == 1))
783 786 xuuxqt(uuxqtarg);
784 787 exit(code);
785 788 }
786 789
787 790 short TM_cnt = 0;
788 791 char TM_name[MAXNAMESIZE];
789 792
790 793 void
791 794 cleanTM()
792 795 {
793 796 int i;
794 797 char tm_name[MAXNAMESIZE];
795 798
796 799 DEBUG(7,"TM_cnt: %d\n",TM_cnt);
797 800 for(i=0; i < TM_cnt; i++) {
798 801 (void) sprintf(tm_name, "%s.%3.3d", TM_name, i);
799 802 DEBUG(7, "tm_name: %s\n", tm_name);
800 803 unlink(tm_name);
801 804 }
802 805 return;
803 806 }
804 807
805 808 void
806 809 TMname(file, pnum)
807 810 char *file;
808 811 pid_t pnum;
809 812 {
810 813
811 814 (void) sprintf(file, "%s/TM.%.5ld.%.3d", RemSpool, (long) pnum, TM_cnt);
812 815 if (TM_cnt == 0)
813 816 (void) sprintf(TM_name, "%s/TM.%.5ld", RemSpool, (long) pnum);
814 817 DEBUG(7, "TMname(%s)\n", file);
815 818 TM_cnt++;
816 819 return;
817 820 }
818 821
819 822 /*
820 823 * intrrupt - remove locks and exit
821 824 */
822 825 void
823 826 onintr(inter)
824 827 int inter;
825 828 {
826 829 char str[30];
827 830 /* I'm putting a test for zero here because I saw it happen
828 831 * and don't know how or why, but it seemed to then loop
829 832 * here for ever?
830 833 */
831 834 if (inter == 0)
832 835 exit(99);
833 836 (void) signal(inter, SIG_IGN);
834 837 (void) sprintf(str, "SIGNAL %d", inter);
835 838 logent(str, "CAUGHT");
836 839 pfEndfile("PARTIAL FILE");
837 840 acEnd(PARTIAL); /*stop collecting accounting log */
838 841 cleanup(inter);
839 842 }
840 843
841 844 void
842 845 intrEXIT(inter)
843 846 int inter;
844 847 {
845 848 char cb[20];
846 849
847 850 (void) sprintf(cb, "SIGNAL %d", inter);
848 851 logent("INTREXIT", cb);
849 852 (void) signal(SIGIOT, SIG_DFL);
850 853 (void) signal(SIGILL, SIG_DFL);
851 854 rmlock(CNULL);
852 855 closedem();
853 856 (void) setuid(Uid);
854 857 abort();
855 858 }
856 859
857 860 /*
858 861 * catch SIGALRM routine
859 862 */
860 863 void
861 864 timeout()
862 865 {
863 866 longjmp(Sjbuf, 1);
864 867 }
865 868
866 869 /* skip to next field */
867 870 static char *
868 871 pskip(p)
869 872 char *p;
870 873 {
871 874 if ((p = strchr(p, ' ')) != CNULL)
872 875 do
873 876 *p++ = NULLCHAR;
874 877 while (*p == ' ');
875 878 return(p);
876 879 }
877 880
878 881 void
879 882 closedem()
880 883 {
881 884 int i, maxfiles;
882 885
883 886 #ifdef ATTSVR3
884 887 maxfiles = ulimit(4,0);
885 888 #else /* !ATTSVR3 */
886 889 #ifdef BSD4_2
887 890 maxfiles = getdtablesize();
888 891 #else /* BSD4_2 */
889 892 maxfiles = _NFILE;
890 893 #endif /* BSD4_2 */
891 894 #endif /* ATTSVR3 */
892 895
893 896 for ( i = 3; i < maxfiles; i++ )
894 897 if ( i != Ifn && i != Ofn && i != fileno(stderr) )
895 898 (void) close(i);
896 899 return;
897 900 }
898 901
899 902 #ifndef ATTSVR3
900 903
901 904 /*
902 905 * setTZ()
903 906 *
904 907 * if login "shell" is uucico (i.e., Role == SLAVE), must set
905 908 * timezone env variable TZ. otherwise will default to EST.
906 909 */
907 910
908 911 #define LINELEN 81
909 912
↓ open down ↓ |
878 lines elided |
↑ open up ↑ |
910 913 void
911 914 setTZ()
912 915 {
913 916 static char buf[LINELEN], *bp;
914 917 extern char *fgets();
915 918 FILE *tzfp;
916 919 extern FILE *fopen();
917 920 int i;
918 921 extern int fclose(), strncmp();
919 922
920 - if ( (tzfp = fopen("/etc/TIMEZONE","r")) == (FILE *)NULL )
923 + if ( (tzfp = fopen("/etc/default/init","r")) == (FILE *)NULL )
921 924 return;
922 925 while ( (bp = fgets(buf,LINELEN,tzfp)) != (char *)NULL ) {
923 926 while ( isspace(*bp) )
924 927 ++bp;
925 928 if ( strncmp(bp, "TZ=", 3) == 0 ) {
926 929 for ( i = strlen(bp) - 1; i > 0 && isspace(*(bp+i)); --i )
927 930 *(bp+i) = '\0';
928 931 putenv(bp);
929 932 (void)fclose(tzfp);
930 933 return;
931 934 }
932 935 }
933 936 (void)fclose(tzfp);
934 937 return;
935 938 }
936 939 #endif /* ATTSVR3 */
937 940
938 941 #ifdef NOSTRANGERS
939 942 /*
940 943 * Function: checkrmt
941 944 *
942 945 * If NOSTRANGERS is defined, see if the remote system is in our systems
943 946 * file. If it is not, execute NOSTRANGERS and then reject the call.
944 947 */
945 948
946 949 static void
947 950 checkrmt ()
948 951
949 952 {
950 953 char ** eVarPtr; /* Pointer to environment variable. */
951 954 char msgbuf[BUFSIZ]; /* Place to build messages. */
952 955 pid_t procid; /* ID of Nostranger process. */
953 956 static char * safePath = PATH;
954 957 int status; /* Exit status of child. */
955 958 pid_t waitrv; /* Return value from wait system call. */
956 959
957 960 /* here's the place to look the remote system up in the Systems file.
958 961 * If the command NOSTRANGERS is executable and
959 962 * If they're not in my file then hang up */
960 963
961 964 if (versys(Rmtname) && (access(NOSTRANGERS, 1) == 0)) {
962 965 sprintf(msgbuf, "Invoking %s for %%s\n", NOSTRANGERS);
963 966 DEBUG(4, msgbuf, Rmtname);
964 967
965 968 /*
966 969 * Ignore hangup in case remote goes away before we can
967 970 * finish logging.
968 971 */
969 972
970 973 (void) signal(SIGHUP, SIG_IGN);
971 974 omsg('R', "You are unknown to me", Ofn);
972 975 scWrite(); /* log unknown remote system */
973 976 procid = fork();
974 977 if ( procid == 0 ) {
975 978 /*
976 979 * Before execing the no strangers program, there is
977 980 * a security aspect to consider. If NOSTRANGERS is
978 981 * not a full path name, then the PATH environment
979 982 * variable will provide places to look for the file.
980 983 * To be safe, we will set the PATH environment
981 984 * variable before we do the exec.
982 985 */
983 986
984 987 /* Find PATH in current environment and change it. */
985 988
986 989 for (eVarPtr = Env; *eVarPtr != CNULL; eVarPtr++) {
987 990 if (PREFIX("PATH=", *eVarPtr))
988 991 *eVarPtr = safePath;
989 992 }
990 993 execlp( NOSTRANGERS, "stranger", Rmtname, (char *) 0);
991 994 sprintf(msgbuf, "Execlp of %s failed with errno=%%d\n",
992 995 NOSTRANGERS);
993 996 DEBUG(4, msgbuf, errno);
994 997 perror(gettext("cico.c: execlp NOSTRANGERS failed"));
995 998 cleanup(errno);
996 999 } else if (procid < 0) {
997 1000 perror(gettext("cico.c: execlp NOSTRANGERS failed"));
998 1001 cleanup(errno);
999 1002 } else {
1000 1003 while ((waitrv = wait(&status)) != procid)
1001 1004 if (waitrv == -1 && errno != EINTR)
1002 1005 cleanup(errno);
1003 1006 sprintf(msgbuf, "%s exit status was %%#x\n",
1004 1007 NOSTRANGERS);
1005 1008 DEBUG(4, msgbuf, status);
1006 1009 }
1007 1010 cleanup(101);
1008 1011 }
1009 1012 }
1010 1013 #endif /* NOSTRANGERS */
↓ open down ↓ |
80 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX