Annotation of cci/usr/src/usr.bin/bsc/cmd/batch/bscd.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.