|
|
1.1 ! root 1: /* D.L.Buck and Associates, Inc. - %H% ! 2: * ! 3: * COPYRIGHT NOTICE: ! 4: * Copyright c %H% - An unpublished work by ! 5: * D.L.Buck and Associates, Inc. ! 6: * ! 7: * PROPRIETARY RIGHTS NOTICE: ! 8: * All rights reserved. This document and program contains ! 9: * proprietary information of D.L.Buck and Associates,Inc. ! 10: * of San Jose, California, U.S.A., embodying confidential ! 11: * information, ideas, and expressions, no part of which ! 12: * may be reproduced, or transmitted in any form or by any ! 13: * means, electronic, mechanical, or otherwise, without ! 14: * the written permission of D.L.Buck and Associates, Inc. ! 15: * NAME ! 16: * bscd - BISYNC communications daemon ! 17: * ! 18: * SYNOPSIS ! 19: * bscd ! 20: * ! 21: * DESCRIPTION ! 22: * bscd submits files queued by bscbatch to the BISYNC driver (bsc), ! 23: * which sends them to a specified remote host via 3780 or 2780 ! 24: * protocol over telephone lines. It is started by an entry in ! 25: * /usr/lib/crontab. ! 26: * ! 27: * ALGORITHM ! 28: * 0. try to create the bsclock file ! 29: * a. if already there, another bscd is running; exit ! 30: * 1. search all host queues for work ! 31: * 2. for each host having file(s) queued to send: ! 32: * a. call installation exit "connect" ! 33: * b. open bsc device ! 34: * c. set bsc device parameters via ioctl call ! 35: * d. while there's another queue control file: ! 36: * i. open control file ! 37: * ii. get control parameters ! 38: * iii. set bsc device parameters as directed by ! 39: * control file via ioctl call ! 40: * iv. close control file ! 41: * v. open actual file to be sent ! 42: * vi. while not eof: ! 43: * format a block ! 44: * submit it to the bsc driver via write ! 45: * if an error is encountered: ! 46: * close file (host is probably trying ! 47: * to send to you) ! 48: * goto 'e.' ! 49: * ! 50: * vii. close file ! 51: * viii. call installation exit "notefile" if requested by ! 52: * control file mail flag ! 53: * ix. remove control file if send successful ! 54: * e. try to receive files: ! 55: * i. while not eof: ! 56: * read a block from bsc device ! 57: * unformat the block ! 58: * write it either to a PR or PU file somehow ! 59: * ii. call installation exit "asgnfile" ! 60: * iii. repeat from 'i.' until read times out ! 61: * f. if another queue control file appeared, go back to step 'd' ! 62: * g. close device ! 63: * h. call installation exit "disconnect" ! 64: * i. unlink bsc lock file ! 65: * ! 66: * make note in the AUDIT file of host spool directory of each action ! 67: * as processing occurs ! 68: */ ! 69: ! 70: #include <stdio.h> ! 71: #include <sys/types.h> ! 72: #include <sys/dir.h> ! 73: #include <sys/ioctl.h> ! 74: #include <sys/stat.h> ! 75: #include <signal.h> ! 76: #include <errno.h> ! 77: #include "local.h" ! 78: #include <bsc/bscio.h> ! 79: #if defined BSD42 ! 80: #include <sys/time.h> ! 81: #else ! 82: #include <time.h> ! 83: #endif ! 84: ! 85: #define libpath "/usr/lib/bscbatch/" ! 86: #define spoolpath "/usr/spool/bscbatch/" ! 87: #define YES 1 ! 88: #define NO 0 ! 89: #define OK 2 ! 90: #define GS 0x1d /* group separator */ ! 91: ! 92: #ifndef lint ! 93: static char sccsid[] = "%W% %Q%"; ! 94: #endif ! 95: extern int errno; /* system error numbers get put in here */ ! 96: extern char *sys_errlist[]; /* Explanatory strings for error numbers */ ! 97: ! 98: char hostname[20]; /* contains host name */ ! 99: char audname[80]; /* temp audit pathname goes here */ ! 100: char auditlock[80]; /* audit lockfile pathname goes here */ ! 101: char new_audnm[80]; /* real audit name goes here */ ! 102: char spool[50]; /* contains host spool directory path */ ! 103: char hostid[20]; /* host id to check for */ ! 104: char signon[50]; /* host signon file */ ! 105: char signoff[50]; /* host signoff file */ ! 106: char lockfile[50]; /* bsc lock file name */ ! 107: char emsg[40]; /* contains error message for AUDIT */ ! 108: char delfile[50]; /* file to delete when through transmitting */ ! 109: char user[20]; /* user name */ ! 110: char sys_admin[20] = "/dev/console"; /* system administrator name ! 111: for problem mail */ ! 112: char df_string[40]; /* minspace check command */ ! 113: char sendfile[50]; /* full name of file to send */ ! 114: char note[100]; /* mail to system administrator goes in here */ ! 115: char dname[15]; /* contains name of device to check if ! 116: MINSPACE parameter set */ ! 117: ! 118: char *strcpy(); /* function copies one string to another */ ! 119: char *strcat(); /* function appends one string to another */ ! 120: char *index(); /* function looks for one string in another */ ! 121: ! 122: int chk_hostid; ! 123: int chk_termid; ! 124: int blksize; ! 125: int primary = BSCPRIM; ! 126: int recsize; ! 127: int recblk; ! 128: int recsep; ! 129: int rviab; ! 130: int ius; /* unit separator for 2780 used? */ ! 131: int pt_to_pt; ! 132: int son_file; /* is there a signon file to send? */ ! 133: int soff_file; /* is there a signoff file to send? */ ! 134: int mail = NO; /* send mail no matter what? */ ! 135: int trnsp = NO; /* force a file to be sent transparent? */ ! 136: int transp_ok = YES; /* transparent transmission ok for this host? */ ! 137: int blocks; /* tracks number of blocks written to bsc device */ ! 138: int ascii; /* ascii or ebcdic data? */ ! 139: int compress = YES; /* compress data ? */ ! 140: int devfd; /* bsc device file descriptor */ ! 141: int total_bl = 0; /* total blocks sent or received */ ! 142: int ctr = 0; /* used to supply unique names to received files */ ! 143: int set_trnsp = NO; /* have any of sendfile's blocks been sent in ! 144: transparent mode, if this is a normal file? */ ! 145: ! 146: int sigint(); /* signal interrupt routine */ ! 147: long maxfsize = 0; /* max size a receive file can be before it must ! 148: be truncated */ ! 149: long minspace = 0; /* minimum space required to receive files from a ! 150: host */ ! 151: long atol(); /* converts ascii to long */ ! 152: char devname[20]; ! 153: char ctlfile[50]; /* queue control file name */ ! 154: ! 155: FILE *fopen(); /* function opens files */ ! 156: FILE *popen(); /* initiate I/O to form a process */ ! 157: FILE *aud; /* host AUDIT file pointer */ ! 158: ! 159: struct tm *localtime(); /* function returns current time */ ! 160: struct tm *t; /* localtime returns time into here */ ! 161: ! 162: struct bscio c_params; /* current bsc driver parameters */ ! 163: struct bscio s_params; /* parameters bsc driver was set with */ ! 164: long time(); ! 165: long currtime; ! 166: void exit(); ! 167: #if defined BSD42 ! 168: DIR *libfd; /* Host Configuration directory fd */ ! 169: DIR *spoolfd; /* Spool directory fd */ ! 170: #else ! 171: int libfd; /* host config directory file descriptor */ ! 172: int spoolfd; /* spool directory file descriptor */ ! 173: #endif ! 174: ! 175: main() ! 176: { ! 177: int more = YES; ! 178: int contention = NO; /*contention error encountered? */ ! 179: int err; /* get_err or connect error code */ ! 180: int almost_done; /* are we almost done communicating with ! 181: this host? */ ! 182: ! 183: long lseek(); ! 184: #if defined BSD42 ! 185: struct direct *dir; /* points to libpath directory entry */ ! 186: struct direct *hdir; /* points to spoolpath directory entry */ ! 187: #else ! 188: struct direct dir; /* libpath directory entry */ ! 189: struct direct hdir; /* spoolpath directory entry */ ! 190: #endif ! 191: struct stat s; /* points to file status structure */ ! 192: ! 193: char cfg_name[50]; /* contains host configuration file name */ ! 194: char line[100]; /* line of file to be sent read in here */ ! 195: int lockfd; /* bsc lock file file descriptor */ ! 196: ! 197: FILE *pptr; /* stream ptr to be used with popen */ ! 198: ! 199: /* catch signals -- if bscd spawned as background process, ! 200: allow kill -15 (SIGTERM) to nicely make it go away. */ ! 201: if (isatty(0)) ! 202: signal(SIGINT,sigint); ! 203: else ! 204: signal(SIGTERM,sigint); ! 205: ! 206: /* 1. search all host queues for work */ ! 207: #if defined BSD42 ! 208: if ((libfd = opendir(libpath)) == NULL) { ! 209: #else ! 210: if ((libfd = open(libpath,0)) == -1) { ! 211: #endif ! 212: fprintf(stderr, ! 213: "bscd: can't open <%s> configuration directory\n", ! 214: libpath); ! 215: exit(1); ! 216: } ! 217: ! 218: #if defined BSD42 ! 219: while ((dir = readdir(libfd)) != NULL) { ! 220: if (dir->d_name[0] == '.') ! 221: continue; ! 222: strcpy(hostname,dir->d_name); ! 223: #else ! 224: while (read(libfd,&dir,sizeof dir) == sizeof dir) { ! 225: if (dir.d_name[0] == '.' || dir.d_ino == 0) ! 226: continue; ! 227: strcpy(hostname,dir.d_name); ! 228: #endif ! 229: sprintf(spool,"%s%s",spoolpath,hostname); ! 230: ! 231: /* try to access spool directory; if not there, continue */ ! 232: #if defined BSD42 ! 233: if ((spoolfd = opendir(spool)) == NULL) { ! 234: #else ! 235: if ((spoolfd = open(spool,0)) == -1) { ! 236: #endif ! 237: sprintf(note, ! 238: "bscd <%s>: directory <%s> not readable", ! 239: hostname,spool); ! 240: fputs(note,stderr); ! 241: /* send mail about the problem */ ! 242: post(); ! 243: continue; ! 244: } ! 245: ! 246: /* try to access the lock file -- if okay, another bscd is running; ! 247: abort. */ ! 248: sprintf(lockfile,"%s/%s",spool,"bsclock"); ! 249: if (access(lockfile,0) == 0) { ! 250: fprintf(stderr, ! 251: "bscd <%s>: another bscd process is currently running\n", ! 252: hostname); ! 253: lockfile[0] = '\0'; ! 254: continue; ! 255: } ! 256: /* Create the lock file */ ! 257: if ( (lockfd = creat(lockfile,0)) < 0) { ! 258: fprintf(stderr, ! 259: "bscd <%s>: can't create %s\n",hostname,lockfile); ! 260: exit(1); ! 261: } else ! 262: close(lockfd); ! 263: /* open the host directory and search for work */ ! 264: if (searchq(spoolfd) == NO) { ! 265: quithost(); ! 266: continue; ! 267: } ! 268: ! 269: /* get host configuration parameters */ ! 270: sprintf(cfg_name,"%s%s",libpath,hostname); ! 271: get_cnfg(cfg_name); ! 272: ! 273: /* construct AUDIT pathname, open AUDIT file */ ! 274: open_audit(); ! 275: ! 276: /* write "ready for connect" msg to AUDIT */ ! 277: sprintf (note,"Ready for connect via <%s>", ! 278: devname); ! 279: write_aud("C",note); ! 280: ! 281: /* call connect installation exit */ ! 282: if (err = connect (hostname, devname)) { ! 283: /* skip this host if there were problems */ ! 284: sprintf(note, "Connection failed, <%s>",emsg); ! 285: write_aud("C",note); ! 286: ! 287: /* send mail about it */ ! 288: post(); ! 289: quithost(); ! 290: continue; ! 291: } ! 292: ! 293: /* open bsc device */ ! 294: if ((devfd = open(devname,2)) == -1) { ! 295: if (errno == EBUSY) { ! 296: fprintf(stderr, ! 297: "bscd <%s>: <%s> being used.\n", ! 298: hostname, devname); ! 299: sprintf(note, ! 300: "Open failed, device <%s> busy.", devname); ! 301: write_aud("C", note); ! 302: ! 303: /* send mail about problem */ ! 304: post(); ! 305: quithost(); ! 306: goto Disconnect; ! 307: } ! 308: ! 309: sprintf(note, ! 310: "Connection failed, %s cannot be opened: %s", ! 311: devname,sys_errlist[errno]); ! 312: ! 313: fprintf(stderr, "bscd <%s>: %s\n", hostname, note); ! 314: ! 315: /* update AUDIT file with the news */ ! 316: write_aud("C",note); ! 317: ! 318: /* send mail about problem */ ! 319: post(); ! 320: quithost(); ! 321: goto Disconnect; ! 322: } ! 323: ! 324: /* write "connected" message to AUDIT file */ ! 325: strcpy(note,"Connected"); ! 326: if (chk_hostid) ! 327: sprintf(note,"%s - host id is %s",note,hostid); ! 328: ! 329: write_aud("C",note); ! 330: ! 331: /* set device parameters */ ! 332: ioctl(devfd,BSCSET,&s_params); ! 333: ! 334: /* if a signon file was specified, send it via send_son ! 335: (send_son.c) */ ! 336: if (son_file) { ! 337: if ((more = send_son(signon)) == NO) { ! 338: sprintf(note,"Disconnected, <%s>", ! 339: emsg); ! 340: write_aud("D",note); ! 341: goto Disconnect; ! 342: } ! 343: /* if there's a contention problem, abort sending */ ! 344: if (c_params.b_flags == BSCONTND) { ! 345: contention = YES; ! 346: goto Receive_Files; ! 347: } ! 348: ! 349: sprintf(note, ! 350: "Transmission of SIGNON file <%s> completed (%d blocks)", ! 351: signon,blocks); ! 352: write_aud("T",note); ! 353: total_bl += blocks; ! 354: blocks = 0; ! 355: } ! 356: ! 357: almost_done = NO; ! 358: Send_Files: /* get another queue control file while there is one */ ! 359: #if defined BSD42 ! 360: rewinddir(spoolfd); ! 361: while ((hdir = readdir(spoolfd)) != NULL) { ! 362: if (hdir->d_name[0] != 'C') ! 363: continue; ! 364: sprintf(ctlfile,"%s/%s",spool,hdir->d_name); ! 365: #else ! 366: lseek(spoolfd,0L,0); ! 367: while (read(spoolfd,&hdir,sizeof hdir) == sizeof hdir) { ! 368: if (hdir.d_ino == 0 || hdir.d_name[0] != 'C') ! 369: continue; ! 370: sprintf(ctlfile,"%s/%s",spool,hdir.d_name); ! 371: #endif ! 372: ! 373: /* get queue control parameters */ ! 374: if (get_params()) /* error */ ! 375: continue; ! 376: ! 377: /* if no sendfile, look for control file w/sendfile */ ! 378: if (!sendfile[0]) ! 379: continue; ! 380: ! 381: /* found something to send; just in case we were sent back ! 382: here after getting a receive timeout from the host and ! 383: almost_done is YES, we shall set almost_done back to NO. */ ! 384: almost_done = NO; ! 385: ! 386: /* set secondary ioctl parameters */ ! 387: if (trnsp) ! 388: ioctl(devfd,BSCTRNSP,0); ! 389: ! 390: /* send file */ ! 391: if (sendf(sendfile) == -1) { ! 392: /* get_errors determines error msg */ ! 393: more = get_errors(); ! 394: ! 395: if (!transp_ok && trnsp) { ! 396: sprintf(emsg, ! 397: "Attempt to send transparent to non-transparent host <%s>", ! 398: hostname); ! 399: more = NO; ! 400: } ! 401: ! 402: sprintf(note, ! 403: "bscd <%s> :Transmission of <%s> aborted, <%s>", ! 404: hostname,sendfile,emsg); ! 405: write_aud("S",note); ! 406: ! 407: /* if we got an rvi abort, remove queue control file ! 408: (and delfile, if any), and go down to receive */ ! 409: if (c_params.b_flags == BSCRVI) { ! 410: unlink(ctlfile); ! 411: if (delfile) ! 412: unlink(delfile); ! 413: contention = YES; ! 414: goto Receive_Files; ! 415: } ! 416: ! 417: /* if there's a contention problem, abort sending */ ! 418: if (c_params.b_flags == BSCONTND) { ! 419: contention = YES; ! 420: goto Receive_Files; ! 421: } ! 422: ! 423: /* send mail about problem */ ! 424: post(); ! 425: ! 426: if (more == NO) { ! 427: sprintf(note,"Disconnected, <%s>", ! 428: emsg); ! 429: write_aud("D",note); ! 430: goto Disconnect; ! 431: } else ! 432: continue; ! 433: } ! 434: ! 435: /* if send successful and q_ctl mail flag set, ! 436: call installation exit notefile */ ! 437: sprintf(note,"bscd: File <%s> sent successfully",sendfile); ! 438: notefile(user,sendfile,note); ! 439: ! 440: /* unlink q_ctl and delfile */ ! 441: unlink(ctlfile); ! 442: if (delfile) ! 443: unlink(delfile); ! 444: ! 445: /* tell the AUDIT file this file's all done */ ! 446: sprintf(note,set_trnsp? ! 447: "Transmission of <%s> completed (transparent,%d blocks)": ! 448: "Transmission of <%s> completed (%d blocks)", ! 449: sendfile,blocks); ! 450: ! 451: write_aud("S",note); ! 452: ! 453: total_bl += blocks; ! 454: blocks = 0; ! 455: set_trnsp = NO; ! 456: } /* End of while read hdir (host spool directory) */ ! 457: ! 458: /* if this isn't the first time we've been to Send_Files, ! 459: we got a receive timeout the last time we were in Receive_Files, ! 460: and there was nothing else to send, then almost_done will ! 461: be set. That means it's time to disconnect; write disconnect message ! 462: and goto Disconnect. */ ! 463: if (almost_done == 1) { ! 464: sprintf(note,"Disconnected, <Receive idle timeout>"); ! 465: write_aud("D",note); ! 466: goto Send_Signoff; ! 467: } ! 468: ! 469: /* get transmit status and write to AUDIT */ ! 470: ioctl(devfd,BSCGET,&c_params); ! 471: sprintf(note, ! 472: "EOT, sent %d blocks, did %d TTDs, had %d NAKs, %d timeouts, %d WACKs", ! 473: total_bl,c_params.b_nttd,c_params.b_nnak,c_params.b_nor, ! 474: c_params.b_nwack); ! 475: ! 476: write_aud("T",note); ! 477: ! 478: Receive_Files: ! 479: /* try to receive something (rcvf is receive function) */ ! 480: /* first check minimum space in user area if minspace set */ ! 481: if (minspace) { ! 482: pptr = popen(df_string,"r"); ! 483: fgets(line,sizeof line,pptr); ! 484: if (atol(&line[25]) < minspace) { ! 485: sprintf(note, ! 486: "bscd <%s>: file system <%s> has less than minimum blocks available. Processing aborted.", ! 487: hostname,dname); ! 488: ! 489: write_aud("D",note); ! 490: /* send mail about it all */ ! 491: post(); ! 492: ! 493: /* and now, do the disconnect stuff */ ! 494: goto Send_Signoff; ! 495: } ! 496: } ! 497: ! 498: total_bl = 0; ! 499: /* rcvf returns OK (2) if a file was received successfully; ! 500: NO (0) if nothing was received; ! 501: YES (1) if an error was encountered */ ! 502: while ((err = rcvf()) == OK || err == NO) { ! 503: if (minspace) { ! 504: pptr = popen(df_string,"r"); ! 505: fgets(line,sizeof line,pptr); ! 506: if (atol(&line[25]) < minspace) { ! 507: strcpy(note, ! 508: "Receiving aborted - minimum space unavailable"); ! 509: write_aud("D",note); ! 510: ! 511: /* send mail about it all */ ! 512: post(); ! 513: ! 514: } ! 515: } ! 516: if (contention) ! 517: break; ! 518: } ! 519: ! 520: /* if contention on the line, go back and try to send file again */ ! 521: if (contention) { ! 522: contention = NO; ! 523: goto Send_Files; ! 524: } ! 525: ! 526: if (err == YES) { /* rcvf reported problem */ ! 527: get_errors(); ! 528: ! 529: /* if receive timeout, go back to send to check if there's ! 530: anything else to transmit */ ! 531: if (c_params.b_flags == BSCRXTO) { ! 532: almost_done = 1; ! 533: /* update AUDIT with status of receive */ ! 534: ioctl(devfd,BSCGET,&c_params); ! 535: sprintf(note, ! 536: "EOT, received %d blocks, did %d WACKs and %d NAKs, had %d TTDs, %d overruns", ! 537: total_bl,c_params.b_nwack,c_params.b_nnak, ! 538: c_params.b_nttd,c_params.b_nor); ! 539: write_aud("T",note); ! 540: ! 541: goto Send_Files; ! 542: } ! 543: ! 544: sprintf(note,"Receiving aborted, <%s>",emsg); ! 545: write_aud("R",note); ! 546: sprintf(note,"Disconnected, <%s>",emsg); ! 547: write_aud("D",note); ! 548: goto Disconnect; ! 549: } ! 550: ! 551: /* update AUDIT with status of receive */ ! 552: ioctl(devfd,BSCGET,&c_params); ! 553: sprintf(note, ! 554: "EOT, received %d blocks, did %d WACKs and %d NAKs, had %d TTDs, %d overruns", ! 555: total_bl,c_params.b_nwack,c_params.b_nnak,c_params.b_nttd, ! 556: c_params.b_nor); ! 557: write_aud("T",note); ! 558: ! 559: /* if a new queue control file appeared, go back and send it */ ! 560: #if defined BSD42 ! 561: rewinddir(spoolfd); ! 562: #else ! 563: lseek(spoolfd,0L,0); /* rewind host directory */ ! 564: #endif ! 565: if (searchq(spoolfd) == YES) ! 566: { stat(ctlfile,&s); ! 567: if (s.st_size > 0) ! 568: goto Send_Files; ! 569: } ! 570: ! 571: Send_Signoff: ! 572: /* if there's a signoff file, send it (soff_send.c) */ ! 573: if (soff_file) { ! 574: total_bl = 0; ! 575: if ((more = soff_send(signoff)) == NO) { ! 576: sprintf(note,"Disconnected, <%s>", ! 577: emsg); ! 578: write_aud("D",note); ! 579: goto Disconnect; ! 580: } ! 581: sprintf(note, ! 582: "Transmission of SIGNOFF file <%s> completed (%d blocks)", ! 583: signoff,blocks); ! 584: write_aud("D",note); ! 585: total_bl += blocks; ! 586: ! 587: ioctl(devfd,BSCGET,&c_params); ! 588: sprintf(note, ! 589: "EOT, sent %d blocks, did %d TTDs, had %d NAKs, %d timeouts, %d WACKs", ! 590: total_bl,c_params.b_nttd,c_params.b_nnak, ! 591: c_params.b_nor,c_params.b_nwack); ! 592: ! 593: write_aud("T",note); ! 594: blocks = 0; ! 595: } ! 596: Disconnect: ! 597: quithost(); ! 598: } ! 599: } ! 600: ! 601: /* search the host directory for files queued to send */ ! 602: searchq(wfd) ! 603: #if defined BSD42 ! 604: DIR *wfd; ! 605: #else ! 606: int wfd; ! 607: #endif ! 608: { ! 609: int work = NO; ! 610: #if defined BSD42 ! 611: struct direct *d; ! 612: ! 613: while ((d = readdir(wfd)) != NULL) ! 614: if (d->d_name[0] == 'C') ! 615: { work = YES; ! 616: sprintf(ctlfile,"%s/%s",spool,d->d_name); ! 617: break; } ! 618: #else ! 619: struct direct d; ! 620: ! 621: while (read(wfd,&d,sizeof d) == sizeof d) ! 622: if (d.d_ino != 0 && d.d_name[0] == 'C') ! 623: { work = YES; ! 624: sprintf(ctlfile,"%s/%s",spool,d.d_name); ! 625: break; } ! 626: #endif ! 627: ! 628: return (work); ! 629: } ! 630: ! 631: /* quithost -- cleanup at end of host processing */ ! 632: quithost() ! 633: { ! 634: if (devfd > 0) { ! 635: close(devfd); ! 636: devfd = -1; ! 637: /* do any necessary disconnect cleanup */ ! 638: disconnect(hostname,devname); ! 639: } ! 640: ! 641: if (lockfile[0]) { ! 642: unlink(lockfile); ! 643: lockfile[0] = '\0'; ! 644: } ! 645: if (auditlock[0]) { ! 646: unlink(auditlock); ! 647: auditlock[0] = '\0'; ! 648: } ! 649: if (aud) { ! 650: fclose(aud); ! 651: aud = (FILE *)0; ! 652: if (link(audname,new_audnm) >= 0) { ! 653: unlink(audname); ! 654: } ! 655: } ! 656: #if defined BSD42 ! 657: if (spoolfd) { ! 658: closedir(spoolfd); ! 659: spoolfd = (DIR *)0; ! 660: } ! 661: #else ! 662: if (spoolfd > 0) { ! 663: close(spoolfd); ! 664: spoolfd = -1; ! 665: } ! 666: #endif ! 667: } ! 668: ! 669: /* sigint -- do signal interrupt processing */ ! 670: sigint(sig) ! 671: int sig; ! 672: { ! 673: char msg[80]; ! 674: sprintf(msg,"Signal %d received",sig); ! 675: /* update the audit file */ ! 676: write_aud("D",msg); ! 677: ! 678: quithost(); ! 679: exit(0); ! 680: } ! 681: ! 682: /* param_err - invalid keyword parameter error */ ! 683: param_err(kword,fname) ! 684: char *kword; ! 685: char *fname; ! 686: { ! 687: /* send mail about problem */ ! 688: sprintf(note,"Invalid parameter for keyword <%s>\n in <%s>\n", ! 689: kword,fname); ! 690: post(); ! 691: ! 692: fputs(note,stderr); ! 693: quithost(); ! 694: exit(1); ! 695: } ! 696: ! 697: /* post - post mail to the system administrator about problems encountered */ ! 698: post() ! 699: { ! 700: FILE *popen(),*pptr; ! 701: char address[50]; ! 702: ! 703: sprintf(address,"mail %s",sys_admin); ! 704: if (sys_admin[0] == '/') { ! 705: pptr = fopen(sys_admin,"a"); ! 706: fputs(note,pptr); ! 707: fclose(pptr); ! 708: } else { ! 709: pptr = popen(address,"w"); ! 710: fputs(note,pptr); ! 711: pclose(pptr); ! 712: } ! 713: } ! 714: ! 715: /* get_cnfg - get host configuration parameters ! 716: The function bcopy used herein does the same thing as strncpy, only ! 717: it actually does copy n characters, and doesn't stop at NULL. Very ! 718: convenient for binary or transparent data which contains NULLs... ! 719: bcopy(to,from,nbytes) */ ! 720: ! 721: get_cnfg(config_file) ! 722: char config_file[]; ! 723: { ! 724: FILE *fptr; /* file pointer returned by fopen */ ! 725: ! 726: int counter = 0; /* tracks line of config file being read */ ! 727: int i = 0; /* convenient index */ ! 728: ! 729: /* default b_flags parameter values */ ! 730: int halfdup = 0; ! 731: int irs = 0; ! 732: ! 733: char *index(); ! 734: char *pos; /* general buffer position pointer */ ! 735: char *dptr; /* dname position pointer */ ! 736: char cline[50]; /* contains one configuration line */ ! 737: ! 738: s_params.b_blks = 508; /* default block size */ ! 739: blksize = 508; /* as above */ ! 740: recsize = 503; ! 741: recblk = 503; ! 742: recsep = 0x1e; ! 743: rviab = BSCRVIABT; /* abort on receiving rvi */ ! 744: maxfsize = 0L; ! 745: minspace = 0L; ! 746: s_params.b_nbid = 0; /* default number of bids limit */ ! 747: s_params.b_nnak = 16; /* default number of naks allowed */ ! 748: s_params.b_nretry = 15; /* default number of retrys allowed */ ! 749: s_params.b_nttd = 120; /* default number of temp. txt delays */ ! 750: s_params.b_nwack = 120; /* default number of wacks allowed */ ! 751: s_params.b_nor = 60; /* default timeout */ ! 752: pt_to_pt = 0; ! 753: chk_hostid = NO; ! 754: son_file = NO; ! 755: soff_file = NO; ! 756: chk_termid = NO; ! 757: ! 758: strcpy(devname,"/dev/bsc"); /* default device name */ ! 759: strcpy(sys_admin,"/dev/console"); /* default system administrator ! 760: name for problem mail */ ! 761: ascii = NO; ! 762: compress = YES; ! 763: ! 764: /* read host configuration file for actual parameters */ ! 765: if ((fptr = fopen(config_file,"r")) == NULL) { ! 766: fprintf(stderr, ! 767: "bscd: can't open <%s> configuration file \n",hostname); ! 768: quithost(); ! 769: exit(1); ! 770: } ! 771: ! 772: while ((fgets(cline,sizeof cline,fptr)) != NULL) { ! 773: ++counter; ! 774: ! 775: if (strncmp(cline,"BLKSIZE=",8) == 0) { ! 776: pos = &cline[8]; ! 777: s_params.b_blks = atoi(pos); ! 778: blksize = s_params.b_blks; ! 779: if (s_params.b_blks < 32 || s_params.b_blks > 512) ! 780: param_err("BLKSIZE",config_file); ! 781: continue; ! 782: } ! 783: ! 784: if (strncmp(cline,"CODE=",5) == 0) { ! 785: pos = &cline[5]; ! 786: if(strncmp(pos,"ASCII",5) != 0 && ! 787: strncmp(pos,"EBCDIC",6) != 0) ! 788: param_err("CODE",config_file); ! 789: ascii = strncmp(pos,"ASCII",5) == 0?BSCASCII:NO; ! 790: continue; ! 791: } ! 792: ! 793: if (strncmp(cline,"COMPRESS=",9) == 0) { ! 794: pos = &cline[9]; ! 795: if (strncmp(pos,"YES",3) != 0 && ! 796: strncmp(pos,"NO",2) != 0) ! 797: param_err("COMPRESS",config_file); ! 798: compress =strncmp(pos,"YES",3)==0?YES:NO; ! 799: continue; ! 800: } ! 801: ! 802: if (strncmp(cline,"DEVICE=",7) == 0) { ! 803: pos = &cline[7]; ! 804: strcpy(devname,pos); ! 805: devname[strlen(devname)-1] = '\0'; ! 806: continue; ! 807: } ! 808: ! 809: if(strncmp(cline,"DUPLEX=",7) == 0) { ! 810: pos = &cline[7]; ! 811: if (strncmp(pos,"HALF",4) != 0 && ! 812: strncmp(pos,"FULL",4) != 0) ! 813: param_err("DUPLEX",config_file); ! 814: halfdup =strncmp(pos,"HALF",4)==0?0:BSCFDX; ! 815: continue; ! 816: } ! 817: ! 818: if (strncmp(cline,"IDCHECK=",8) ==0) { ! 819: pos = &cline[8]; ! 820: strcpy(s_params.b_hostid,pos); ! 821: chk_hostid = BSCCKHOST; ! 822: continue; ! 823: } ! 824: ! 825: if (strncmp(cline,"MAIL=",5) == 0) { ! 826: pos = &cline[5]; ! 827: strcpy(sys_admin,pos); ! 828: continue; ! 829: } ! 830: ! 831: if (strncmp(cline,"MAXFSIZE=",9) == 0) { ! 832: pos = &cline[9]; ! 833: maxfsize = atol(pos); ! 834: if (maxfsize > 1000000000L) ! 835: param_err("MAXFSIZE",config_file); ! 836: continue; ! 837: } ! 838: ! 839: if (strncmp(cline,"MINSPACE=",9) == 0) { ! 840: if ((pos = index(cline,',')) == NULL) ! 841: param_err("MINSPACE",config_file); ! 842: ++pos; ! 843: minspace = atol(pos); ! 844: if (minspace > 1000000000L) ! 845: param_err("MINSPACE",config_file); ! 846: pos = &cline[9]; ! 847: dptr = &dname[0]; ! 848: while(*pos != ',') ! 849: *dptr++ = *pos++; ! 850: *dptr = '\0'; ! 851: sprintf(df_string,"df -f %s\n",dname); ! 852: continue; ! 853: } ! 854: ! 855: if (strncmp(cline,"MPTADDR=",8) == 0) { ! 856: pos = &cline[8]; ! 857: strcpy(s_params.b_termid,pos); ! 858: pt_to_pt = BSCMPT; ! 859: continue; ! 860: } ! 861: ! 862: if (strncmp(cline,"NBID=",5) == 0) { ! 863: pos = &cline[5]; ! 864: s_params.b_nbid = atoi(pos); ! 865: if (s_params.b_nbid > 127 || s_params.b_nbid < 0) ! 866: param_err("NBID",config_file); ! 867: continue; ! 868: } ! 869: ! 870: if (strncmp(cline,"NNAK=",5) == 0) { ! 871: pos = &cline[5]; ! 872: s_params.b_nnak = atoi(pos); ! 873: if (s_params.b_nnak > 127 || s_params.b_nnak < 0) ! 874: param_err("NNAK",config_file); ! 875: continue; ! 876: } ! 877: ! 878: if (strncmp(cline,"NRETRY=",7) == 0) { ! 879: pos = &cline[7]; ! 880: s_params.b_nretry = atoi(pos); ! 881: if (s_params.b_nretry > 127 || s_params.b_nretry < 0) ! 882: param_err("NRETRY",config_file); ! 883: continue; ! 884: } ! 885: ! 886: if (strncmp(cline,"NTTD=",5) == 0) { ! 887: pos = &cline[5]; ! 888: s_params.b_nttd = atoi(pos); ! 889: if (s_params.b_nttd > 127 || s_params.b_nttd < 0) ! 890: param_err("NTTD",config_file); ! 891: continue; ! 892: } ! 893: ! 894: if (strncmp(cline,"NWACK=",6) == 0) { ! 895: pos = &cline[6]; ! 896: s_params.b_nwack = atoi(pos); ! 897: if (s_params.b_nwack > 127 || s_params.b_nwack < 0) ! 898: param_err("NWACK",config_file); ! 899: continue; ! 900: } ! 901: ! 902: if (strncmp(cline,"RECBLK=",7) == 0) { ! 903: pos = &cline[7]; ! 904: recblk = atoi(pos); ! 905: if (recblk > 507) ! 906: param_err("RECBLK",config_file); ! 907: continue; ! 908: } ! 909: ! 910: if (strncmp(cline,"RECSEP=",7) == 0) { ! 911: pos = &cline[7]; ! 912: irs =strncmp(pos,"IRS",3)==0?0:BSCIUS; ! 913: recsep = (irs == 0)?0x1e:0x19; ! 914: continue; ! 915: } ! 916: ! 917: if (strncmp(cline,"RECSIZE=",8) == 0) { ! 918: pos = &cline[8]; ! 919: recsize = atoi(pos); ! 920: if (recsize > 507) ! 921: recsize = 507; ! 922: continue; ! 923: } ! 924: ! 925: if (strncmp(cline,"RVIMODE=",8) == 0) { ! 926: pos = &cline[8]; ! 927: if (strncmp(pos,"ABORT",5) != 0 && ! 928: strncmp(pos,"IGNORE",6) != 0) ! 929: param_err("RVIMODE",config_file); ! 930: rviab =strncmp(pos,"ABORT",5)==0?BSCRVIABT:NO; ! 931: continue; ! 932: } ! 933: ! 934: if (strncmp(cline,"SIGNON=",7) == 0) { ! 935: strcpy(signon,&cline[7]); ! 936: signon[strlen(signon)-1] = '\0'; ! 937: son_file = YES; ! 938: continue; ! 939: } ! 940: ! 941: if (strncmp(cline,"SIGNOFF=",8) == 0) { ! 942: strcpy(signoff,&cline[8]); ! 943: signoff[strlen(signoff)-1] = '\0'; ! 944: soff_file = YES; ! 945: continue; ! 946: } ! 947: ! 948: if (strncmp(cline,"STATION=",8) == 0) { ! 949: pos = &cline[8]; ! 950: if (strncmp(pos,"PRIMARY",7) != 0 && ! 951: strncmp(pos,"SECONDARY",9) != 0) ! 952: param_err("STATION",config_file); ! 953: primary =strncmp(pos,"PRIMARY",7)==0?BSCPRIM:NO; ! 954: continue; ! 955: } ! 956: ! 957: if (strncmp(cline,"TERMID=",7) == 0) { ! 958: pos = &cline[7]; ! 959: bcopy(s_params.b_termid,pos,strlen(pos)-1); ! 960: chk_termid = YES; ! 961: continue; ! 962: } ! 963: ! 964: if (strncmp(cline,"TIMEOUT=",8) == 0) { ! 965: pos = &cline[8]; ! 966: i = atoi(pos); ! 967: if (i > 0 && i <= 3000) ! 968: s_params.b_nor = atoi(pos); ! 969: else ! 970: param_err("TIMEOUT",config_file); ! 971: continue; ! 972: } ! 973: ! 974: ! 975: if (strncmp(cline,"TRANSPARENT=",12) == 0) { ! 976: pos = &cline[12]; ! 977: if (strncmp(pos,"YES",3) != 0 && ! 978: strncmp(pos,"NO",2) != 0) ! 979: param_err("TRANSPARENT",config_file); ! 980: transp_ok =strncmp(pos,"YES",3)==0?YES:NO; ! 981: continue; ! 982: } ! 983: ! 984: if (strncmp(cline,"UNITSEP=",8) == 0) { ! 985: pos = &cline[8]; ! 986: ius = (strncmp(pos,"YES",3) == 0)? BSCIUS:NO; ! 987: continue; ! 988: } ! 989: ! 990: /* invalid keyword parameter error */ ! 991: sprintf(note, ! 992: "bscd <%s>: Unrecognized keyword, line %d in <%s>\n", ! 993: hostname,counter,config_file); ! 994: ! 995: fputs(note,stderr); ! 996: post(); ! 997: quithost(); ! 998: exit(1); ! 999: } ! 1000: ! 1001: /* insure that the record size is smaller than the block size */ ! 1002: if (recsize > blksize - 5) ! 1003: recsize = blksize - 5; ! 1004: ! 1005: s_params.b_flags = ascii | halfdup | ius | rviab | ! 1006: primary | chk_hostid | pt_to_pt; ! 1007: /* translate termid if one given and ebcdic */ ! 1008: if (!ascii && chk_termid) ! 1009: ascebc(s_params.b_termid,strlen(s_params.b_termid)); ! 1010: /* close configuration file */ ! 1011: fclose(fptr); ! 1012: } ! 1013: ! 1014: /* open_audit - open the host's AUDIT file */ ! 1015: open_audit() ! 1016: { ! 1017: int audfd; ! 1018: ! 1019: /* construct AUDIT file pathname */ ! 1020: sprintf(audname,"%s/%s",spool,"AUDIT"); ! 1021: sprintf(new_audnm,"%s/%s",spool,"AUDIT"); ! 1022: ! 1023: if (access(audname,0) == 0) { ! 1024: sprintf(auditlock,"%s/%s",spool,"auditlock"); ! 1025: if ((audfd = creat(auditlock,0)) < 0) { ! 1026: auditlock[0] = '\0'; ! 1027: bsc_audnm(); ! 1028: } else { ! 1029: close(audfd); ! 1030: aud = fopen(audname,"a"); ! 1031: } ! 1032: } ! 1033: } ! 1034: ! 1035: char *usr_name; /* ptr returned by getlogin */ ! 1036: /* write_aud - write message to audit file */ ! 1037: write_aud(type,msg) ! 1038: char *type; ! 1039: char *msg; ! 1040: { ! 1041: char *getlogin(); /* returns ptr to login name for this ! 1042: process */ ! 1043: ! 1044: if (aud == NULL) ! 1045: return; ! 1046: ! 1047: /* if first time, get login name */ ! 1048: if (usr_name == NULL) ! 1049: if ((usr_name=getlogin()) == NULL) ! 1050: usr_name="unknown"; ! 1051: ! 1052: /* get current time */ ! 1053: currtime = time((long*)0); ! 1054: t = localtime(&currtime); ! 1055: ! 1056: fprintf (aud, "%s %s %02d%02d%02d%02d%02d %s\n", ! 1057: usr_name, type, t->tm_year, (t->tm_mon) + 1, ! 1058: t->tm_mday, t->tm_hour, t->tm_min, msg); ! 1059: fflush(aud); ! 1060: } ! 1061: ! 1062: /* do_compress - replace blanks with group separator and count of blanks */ ! 1063: do_compress(string,llen) ! 1064: char *string; ! 1065: register int llen; /* line length */ ! 1066: { ! 1067: register int blanks; /* count of blanks */ ! 1068: ! 1069: register char *s, *r; ! 1070: char blank; ! 1071: ! 1072: blank = ascii?' ':0x40; ! 1073: ! 1074: r = s = string; ! 1075: ! 1076: while (1) { ! 1077: /* "copy" characters into string as long as they aren't blank */ ! 1078: while (llen > 0 && *s != blank) { ! 1079: --llen; ! 1080: *r++ = *s++; ! 1081: } ! 1082: ! 1083: if (llen == 0) /* no blanks were found */ ! 1084: break; ! 1085: ! 1086: /* skip over blanks in string, keep count to encode as group separator ! 1087: (GS) followed by number of blanks -- encode only if more than ! 1088: two blanks are found */ ! 1089: blanks = 0; ! 1090: while (llen > 0 && *s == blank){ ! 1091: ++blanks; ! 1092: --llen; ! 1093: ++s; ! 1094: } ! 1095: ! 1096: if (blanks > 2) ! 1097: { *r++ = GS; ! 1098: if (blanks <= 63) ! 1099: *r++ = 0x40 + blanks; ! 1100: else { ! 1101: *r++ = 0x40 + 63; ! 1102: *r++ = GS; ! 1103: *r++ = 0x40 + (blanks - 63); ! 1104: } ! 1105: continue; ! 1106: } ! 1107: else if (blanks == 2) ! 1108: *r++ = blank; ! 1109: ! 1110: *r++ = blank; ! 1111: } ! 1112: *r = '\0'; ! 1113: return(r-string); ! 1114: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.