|
|
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.