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

1.1       root        1: /*     D.L.Buck and Associates, Inc. - 8/27/84
                      2:  *
                      3:  *     COPYRIGHT NOTICE:
                      4:  *             Copyright c 8/27/84 - 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:  * 
                     16:  * NAME
                     17:  *     bsclog - BISYNC batch audit trail utility
                     18:  *
                     19:  * SYNOPSIS
                     20:  *     bsclog hostname [-purge=dd] [-from=[yymmdd]hhmm] [-to=[yymmdd]hhmm]
                     21:  *                     [-class=cccc] [-user=uuuu]
                     22:  *
                     23:  * DESCRIPTION
                     24:  *     bsclog selectively prints audit trail information gleaned from the
                     25:  *     AUDIT file, and purges old information to keep the AUDIT file within
                     26:  *     reasonable size limits.
                     27:  *
                     28:  * ALGORITHM
                     29:  *     1. Process hostname
                     30:  *      a. check that it was specified, exit if not
                     31:  *      b. construct host's directory pathname
                     32:  *      c. change directory
                     33:  *     2. Open primary audit file, AUDIT
                     34:  *     3. Get options from command line
                     35:  *     4. Sort and merge secondary audit files with primary audit file
                     36:  *     5. If purge:
                     37:  *      a. create and open for writing temp purge file (holds results of purge)
                     38:  *      b. while AUDIT line doesn't meet save criteria, get another AUDIT
                     39:  *         line
                     40:  *      c. write lines to temp purge file
                     41:  *      d. close temp and audit files
                     42:  *      e. unlink audit file, link temp file to it (temp file becomes the new
                     43:  *         AUDIT file)
                     44:  *     6. If report:
                     45:  *      a. set up report headers
                     46:  *      b. while there's another AUDIT entry line, read it and process entries:
                     47:  *             i. format entry date
                     48:  *            ii. check that entry meets sort criteria; continue reading if it
                     49:  *                doesn't
                     50:  *           iii. if at bottom of page, form feed and print headers
                     51:  *            iv. construct report line
                     52:  *             v. print report line
                     53:  *     7. Remove any secondary audit files there may be
                     54:  *
                     55:  */
                     56: 
                     57: #include <sys/types.h>
                     58: #include <sys/dir.h>
                     59: #include <sys/stat.h>
                     60: #include <stdio.h>
                     61: #include <ctype.h>
                     62: #include "local.h"
                     63: #if defined BSD42
                     64: #include <sys/time.h>
                     65: #else
                     66: #include <time.h>
                     67: #endif
                     68: 
                     69: #ifndef lint
                     70: static char sccsid[] = "@(#)bsclog.c   1.10 REL";
                     71: #endif
                     72: char *strncat(), *strncpy(), *strcat(), *strcpy();
                     73: void exit();
                     74: 
                     75: #define YES 1
                     76: #define NO 0
                     77: #define PATH "/usr/spool/bscbatch/"
                     78: #define RCDLN 160
                     79: #define PAGELN 60
                     80: #define PAGEWIDTH 80
                     81: 
                     82: char line[RCDLN];              /* audit trail entry line */
                     83: char *months[] = {"nope","Jan ","Feb ","Mar ","Apr ","May ","Jun ","Jul ",
                     84:                     "Aug ","Sep ","Oct ","Nov ","Dec "};
                     85: 
                     86: char *fields = "   Class   |  Date / Time       |  Message";
                     87: char *underline = "________________________________________";
                     88: char *blankfields =    "           |                    | ";
                     89: char *blanks = "                                         ";
                     90: 
                     91: int age;                       /* age of audit entry; used with purge */
                     92: int purge_age;                 /* purge audit entries older than purge_age */
                     93: int leap;                      /* is this year a leap year? */
                     94: 
                     95: /* day_yr is used to compute the day of the year (1-365) of AUDIT entries.
                     96:    and in turn is used to compute the age of the entry by subtracting it
                     97:    from the current day of the year. day_yr[0] values are for non-leap
                     98:    years. day_yr[1] values are for leap years. */
                     99: static int day_yr[2][13] = {
                    100:        {0,0,32,60,90,120,151,180,211,242,272,303,333},
                    101:        {0,0,32,61,91,121,152,181,212,243,273,304,334}  };
                    102: 
                    103: long from[2];                  /* beginning of time interval for sort */
                    104: long to[2] =                   /* end of time interval for sort */
                    105:        { 991231L,              /* end of time is 12/31/99 */
                    106:        2359L };                /* at 23:59 */
                    107: 
                    108: long time();                   /* function returns current time */
                    109: long currtime;                 /* contains time time() returns */
                    110: struct tm *t,*localtime();
                    111: 
                    112: char class[8] = "CDEQRST";     /* contains class of AUDIT entries wanted */
                    113: char user[20] = "all";         /* contains user id of AUDIT entries wanted */
                    114: char header[3][PAGEWIDTH];     /* contains report header */
                    115: char fromdate[21] =            /* formatted from: MMM DD, YYYY HH:MM */
                    116:         "Earliest Audit Date";
                    117: char todate[21] =              /* formatted to: MMM DD, YYYY HH:MM */
                    118:         "Latest Audit Date";
                    119: 
                    120: FILE *fopen();                 /* function opens a file */
                    121: FILE *audit;                   /* contains audit file path for open */
                    122: FILE *temp;                    /* contains purge temp file path for open */
                    123: 
                    124: main(argc,argv)
                    125: int argc;
                    126: char *argv[];
                    127: {
                    128:        int i,j;                /* friendly, neighborhood indices */
                    129:        int purge = 0;          /* flags whether or not this is a purge */
                    130: 
                    131:        char pathname[50];      /* contains the directory pathname */
                    132:        char hostname[20];      /* contains hostname */
                    133: 
                    134:        long time();            /* function returns current time */
                    135: 
                    136:        /* check whether the hostname was given (in 1st param if it was) */
                    137:        if (argc < 2 || argv[1][0] == '-')
                    138:                strcpy(hostname,"default");
                    139:        else
                    140:                strcpy(hostname,argv[1]);
                    141: 
                    142:        /* process hostname */
                    143:        strcpy(pathname,PATH);
                    144:        strcat(pathname,hostname);
                    145: 
                    146:        if (chdir(pathname) == -1) {
                    147:                fprintf(stderr,
                    148:                        "bsclog: <%s> has no spool directory\n",
                    149:                        hostname);
                    150:                exit(1);
                    151:        }
                    152: 
                    153:        /* open the primary audit file */
                    154:         if ((audit=fopen("AUDIT","r")) == NULL) {
                    155:                 fprintf(stderr,"bsclog: <%s> has no AUDIT file\n",hostname);
                    156:                exit(1);
                    157:        }
                    158: 
                    159:        /* get options from command line */
                    160:        for (i=1;i<argc;++i) {
                    161:                 if (strncmp(argv[i],"-purge=",7) == 0) { /* process purge opt */
                    162:                        if (argc > 3) {
                    163:                                fprintf(stderr,
                    164:                                 "bsclog: too many arguments for purge\n");
                    165:                                exit(1);
                    166:                        }
                    167: 
                    168:                        if (!isdigit(argv[i][7]))       {
                    169:                                fprintf(stderr,
                    170:                                 "bsclog: not a numeric value <%s>\n",argv[i]);
                    171:                                exit(1);
                    172:                        }
                    173:                        if ((purge_age=atoi(&argv[i][7])) == NULL)
                    174:                                purge_age = 0;
                    175:                        purge = YES;
                    176:                        break;
                    177:                }
                    178: 
                    179:                /* get time interval to select entries from */
                    180:                 if (strncmp(argv[i],"-from=",6) == 0) {
                    181:                        if (argv[i][6] < '0' || argv[i][6] > '9') {
                    182:                                fprintf(stderr,
                    183:                                 "bsclog: not a numeric value (%s)\n",argv[i]);
                    184:                                exit(1);
                    185:                        }
                    186: 
                    187:                        /* format from date and time into MMM DD, YYYY HH:MM,
                    188:                           and into long numbers to use to determine whether or
                    189:                           not to print audit entries */
                    190:                        makedate(&argv[i][6],fromdate,from);
                    191: 
                    192:                        continue;
                    193:                }
                    194: 
                    195:                /* get time interval to select entries until */
                    196:                 if (strncmp(argv[i],"-to=",4) == 0) {
                    197:                        if (argv[i][4] < '0' || argv[i][4] > '9') {
                    198:                                fprintf(stderr,
                    199:                                 "bsclog: not a numeric value (%s)\n",argv[i]);
                    200:                                exit(1);
                    201:                        }
                    202: 
                    203:                        /* format to date and time into MMM DD, YYYY HH:MM, and
                    204:                           into long numbers to use in determining whether or
                    205:                           or not to print audit entries */
                    206:                        makedate(&argv[i][4],todate,to);
                    207: 
                    208:                        continue;
                    209:                }
                    210: 
                    211:                /* get class(es) of entries to select */
                    212:                 if (strncmp(argv[i],"-class=",7) == 0) {
                    213:                        strcpy(class,&argv[i][7]);
                    214: 
                    215:                        /* insure that class types are upper case */
                    216:                        for (j=0;j<strlen(class);++j)
                    217:                                class[j] = toupper(class[j]);
                    218: 
                    219:                        continue;
                    220:                }
                    221: 
                    222:                /* get which user entries to select */
                    223:                 if (strncmp(argv[i],"-user=",6) == 0) {
                    224:                        strcpy(user,&argv[i][6]);
                    225:                        continue;
                    226:                }
                    227: 
                    228:                /* check for invalid parameter */
                    229:                if (argv[i][0] == '-' || (i>=2 && argv[i][0] != '-')) {
                    230:                        fprintf(stderr,
                    231:                        "bsclog: unrecognized option <%s>\n",argv[i]);
                    232:                        exit(1);
                    233:                }
                    234: 
                    235:        }
                    236: 
                    237:        /* merge the AUDIT files and sort in ascending date/time order.
                    238:           the 'system' command submits commands to the shell. Here, it's
                    239:           telling the shell to merge all files which begin with AUDIT
                    240:           (AUDIT*) into the file AUDIT, skip the first blank-separated
                    241:           field of each line, and do a numeric sort on the next one. */
                    242: 
                    243:         system("sort -m +2.0n -3 -o AUDIT AUDIT*;rm -f AUDIT.*");
                    244: 
                    245:        purge?do_purge():do_report();   /* if purge=YES, purge; else do audit */
                    246:                                        /* trail report. */
                    247: }
                    248: 
                    249: do_purge()
                    250: {
                    251: /* create and open purge temp file */
                    252:         if ((temp=fopen("TEMPUR","w")) == NULL) {
                    253:                 fprintf(stderr,"bsclog: can't create temporary file\n");
                    254:                exit(1);
                    255:        }
                    256: 
                    257:        /* purge time - loop until reaching audit entries to be kept */
                    258:        while(fgets(line,RCDLN,audit) != NULL)  {
                    259:                if (getage() > purge_age)       continue;
                    260: 
                    261:                fputs(line,temp);       
                    262:        }
                    263:        fclose(audit);
                    264:        fclose(temp);
                    265: 
                    266:        /* unlink the purged audit file and link the temp file (has results of
                    267:           purge) to AUDIT; unlink temp file to get rid of it */
                    268: 
                    269:         unlink("AUDIT");
                    270:         link("TEMPUR","AUDIT");
                    271:         unlink("TEMPUR");
                    272: 
                    273:        return;
                    274: }
                    275: 
                    276: /* print audit trail report */
                    277: int pagecount = 1;
                    278: int linecount = 0;
                    279: do_report()
                    280: {
                    281:        char *index();  /* function returns a pointer to 1st occurance
                    282:                                   of a given string */
                    283:        char *lnptr;            /* points to positions on AUDIT line read in */
                    284:        char reportline[PAGEWIDTH];     /* report lines constructed here */
                    285:        char last_class = ' ';          /* class of last line printed (CDRST) */
                    286:        char audate[21];                /* contains audit entry date */
                    287:        char auduser[20];               /* contains audit entry user id */
                    288:        char msgpart[PAGEWIDTH];        /* contains msg part of audit entry */
                    289:        char tmp[PAGEWIDTH];
                    290: 
                    291:        long date[2];
                    292:        int i = 0;
                    293:        int length;             /* keep track of line length */
                    294:        int counter;            /* an index */
                    295:        int center;             /* used to center headers */
                    296:        /* set up report headers; construct in temp header first to determine
                    297:           length, then pad with blanks to center */
                    298:         strcpy(header[0],"                                Audit Trail Report");
                    299: 
                    300:         sprintf(tmp,"From: %s    To: %s",fromdate,todate);
                    301:        center = (PAGEWIDTH-strlen(tmp))/2;
                    302:        strncpy(header[1],blanks,center);
                    303:        strcat(header[1],tmp);
                    304: 
                    305:         sprintf(tmp,"Classes: %s   Users: %s  ",class,user);
                    306:        center = (PAGEWIDTH-strlen(tmp))/2;
                    307:        strncpy(header[2],blanks,center);
                    308:        strcat(header[2],tmp);
                    309: 
                    310:        while(fgets(line,RCDLN,audit) != NULL) {
                    311:                i = 0;
                    312:                while(line[i] != ' ')   {
                    313:                        auduser[i] = line[i];
                    314:                        i++;
                    315:                }
                    316:                auduser[i] = '\0';
                    317: 
                    318:                makedate(&line[i+3],audate,date);
                    319: 
                    320:                /* check that line meets sort criteria */
                    321:                 if ((strcmp(user,"all") == 0 || strcmp(user,auduser) == 0) &&
                    322:                 index(class,line[i+1]) != '\0' && ((date[0] >= from[0] &&
                    323:                 date[1] >= from[1] && date[0] < to[0]) ||
                    324:                 (date[0]== to[0] && (date[1] >= from[1] && date[1] <= to[1]))))
                    325:                {
                    326:                        /* if at the end of a page, do a formfeed and
                    327:                           print header */
                    328:                        if (linecount == PAGELN || linecount == 0)
                    329:                                disp_header();
                    330: 
                    331:                        /* construct a report line */
                    332:                        /* copy class description onto report line */
                    333:                        if (line[i+1] != last_class) {
                    334:                                strcpy(reportline,blankfields);
                    335:                                 fprintf(stdout,"%s\n",reportline);
                    336:                                if (++linecount >= PAGELN)
                    337:                                        disp_header();
                    338:                                switch (line[i+1]) {
                    339:                                case 'C':{
                    340:                                         strcpy(reportline," Connect   |");
                    341:                                        break; }
                    342:                                case 'D':{
                    343:                                         strcpy(reportline," Disconnect|");
                    344:                                        break;}
                    345:                                case 'E':{
                    346:                                        strcpy(reportline," Error     |");
                    347:                                        break;  }
                    348:                                case 'Q':{
                    349:                                        strcpy(reportline," Queue     |");
                    350:                                        break;  }
                    351:                                case 'R':{
                    352:                                         strcpy(reportline," Receive   |");
                    353:                                        break;}
                    354:                                case 'S':{
                    355:                                         strcpy(reportline," Send      |");
                    356:                                        break;}
                    357:                                case 'T':{
                    358:                                         strcpy(reportline,"Statistics |");
                    359:                                        break;}
                    360:                                }
                    361:                        }
                    362:                        else
                    363:                                 strcpy(reportline,"           |");
                    364: 
                    365:                        /* cat date onto report line */
                    366:                        strcat(reportline,audate);
                    367:                         strcat(reportline,"| ");
                    368: 
                    369:                        /* cat message onto report line */
                    370:                        lnptr = &line[i+14];
                    371:                        strcpy(msgpart,lnptr);
                    372:                        if ((length=strlen(msgpart)) <= 45)
                    373:                                strncat(reportline,msgpart,length-1);
                    374:                        else
                    375:                        {/* break msgpart up into 2 lines & cat to reportline*/
                    376:                                strncat(reportline,msgpart,35);
                    377:                                lnptr = &msgpart[35];
                    378:        break_apart:            counter = 69;
                    379:                        while (*lnptr != ',' && *lnptr != ' ' &&
                    380:                                  *lnptr != '\n' && *lnptr != '/' && 
                    381:                                  counter < 78)
                    382:                                  reportline[counter++] = *lnptr++;
                    383: 
                    384:                                if (*lnptr != '\n')
                    385:                                        reportline[counter++] = *lnptr;
                    386:                                reportline[counter] = '\0';
                    387:                                if (*lnptr != '\n' && *lnptr != '\0') {
                    388:                                         fprintf(stdout,"%s\n",reportline);
                    389:                                        if (++linecount >= PAGELN)
                    390:                                                disp_header();
                    391:                                        ++lnptr;
                    392:                                        if (*lnptr == ' ')
                    393:                                                ++lnptr;
                    394:                                        strcpy(reportline,blankfields);
                    395:                                        if (strlen(lnptr) > 45) {
                    396:                                                strncat(reportline,
                    397:                                                lnptr,35);
                    398:                                                lnptr += 35;
                    399:                                                goto break_apart;
                    400:                                        }
                    401: 
                    402:                                        strncat(reportline,lnptr,
                    403:                                                (strlen(lnptr)-1));
                    404:                                }
                    405:                        }
                    406:                         fprintf(stdout,"%s\n",reportline);
                    407:                        ++linecount;
                    408:                        last_class = line[i+1];
                    409:                }
                    410:        }
                    411: 
                    412:        if (linecount == 0)     {       /* nothing printed */
                    413:                fprintf(stderr,
                    414:                        "bsclog: no data meets selection requirements\n");
                    415:        }
                    416: }
                    417: 
                    418: /* get age of audit trail entry */
                    419: getage()
                    420: {
                    421:        int i = 0;      /* local index */
                    422:        int j;          /* local index */
                    423:        int days;       /* entry's day of the year (1-365) */
                    424:        int today;      /* today's day of the year (1-365) */
                    425:        int year;       /* year pulled out of entry */
                    426:        int month;      /* month pulled out of entry */
                    427:        int day;        /* day pulled out of entry */
                    428:        char lndate[7]; /* the date that gets pulled out of the entry */
                    429: 
                    430: /* look for beginning of date field (user name lengths vary so ...) */
                    431:        while (line[i] != ' ')
                    432:                ++i;
                    433: 
                    434: /* mmdd of entry starts 3 positions after user name */
                    435:        for (j=0;j<6;++j)       
                    436:                lndate[j] = line[j+i+3];
                    437:        lndate[6] = '\0';
                    438:        day = atoi(&lndate[4]);
                    439:        lndate[4] = '\0';
                    440:        month = atoi(&lndate[2]);
                    441:        lndate[2] = '\0';
                    442:        year = atoi(&lndate[0]);
                    443: 
                    444:        leap = year%4==0 && year%100 != 0 || year%400 == 0?YES:NO;
                    445:        days = (day_yr[leap][month]) + day;
                    446: 
                    447:        /* get current date and time */
                    448:        gettime();
                    449: 
                    450:        /* if year < current year, today is the number of days last year +
                    451:           the number of days so far this year; otherwise, it's just the
                    452:           number of days so far this year. */
                    453:        today = (year<t->tm_year)? (day_yr[leap][12]+31)+t->tm_yday :(t->tm_yday+1);
                    454: 
                    455:        age = today - days;
                    456:        return(age);
                    457: }
                    458: /* return structure pointing to current time */
                    459: gettime()
                    460: {
                    461:        currtime = time((long*)0);
                    462:        t = localtime(&currtime);
                    463: }
                    464: 
                    465: /* convert string date and time values to MMM DD, YYYY HH:MM format and to
                    466:    long format: YYMMDD and HHMM. */
                    467: makedate(strptr,formdate,longno)
                    468: char *strptr;
                    469: char formdate[18];
                    470: long longno[2];
                    471: {
                    472:        int month;
                    473:        int day;
                    474:        int year;
                    475:        int hours;
                    476:        int minutes;
                    477: 
                    478:        if (strlen(strptr) >= 10)
                    479:        {       /* YYMMDDHHMM */
                    480:                minutes = atoi(&strptr[8]);
                    481:                strptr[8] = '\0';
                    482:                hours = atoi(&strptr[6]);
                    483:                strptr[6] = '\0';
                    484:                day = atoi(&strptr[4]);
                    485:                strptr[4] = '\0';
                    486:                month = atoi(&strptr[2]);
                    487:                strptr[2] = '\0';
                    488:                year = atoi(&strptr[0]);
                    489:        }
                    490:        else if (strlen(strptr) == 4)
                    491:        {       /* HHMM given; use current YYMMDD */
                    492:                minutes = atoi(&strptr[2]);
                    493:                strptr[2] = '\0';
                    494:                hours = atoi(&strptr[0]);
                    495: 
                    496:                /* set month, day, year to current date */
                    497:                gettime();
                    498:                month = (t->tm_mon) + 1;
                    499:                day = t->tm_mday;
                    500:                year = t->tm_year;
                    501:        }
                    502:        else    /* invalid date/time format */
                    503:        {
                    504:                fprintf(stderr,
                    505:                        "bsclog: date-time format is YYMMDDHHMM or HHMM\n");
                    506:                exit(1);
                    507:        }
                    508: 
                    509:        longno[0] = year * 10000L + month * 100L + day;
                    510:        longno[1] = hours * 100L + minutes;
                    511: 
                    512:         sprintf(formdate," %s%2d, 19%02d %2d:%02d ",
                    513:                months[month],day,year,hours,minutes);
                    514: }
                    515: 
                    516: /* disp_header() - display report header if line count >= page length */
                    517: disp_header()
                    518: {
                    519:        putc('\f',stdout);
                    520:        fprintf(stdout,"%s\n%s\n%s  page %d\n\n",
                    521:               header[0],header[1],header[2],pagecount);
                    522: 
                    523:        /* print field header and underline */
                    524:        fprintf(stdout,"%s\n%s%s\n",
                    525:                fields,underline,underline);
                    526: 
                    527:        ++pagecount;
                    528:        linecount = 7;
                    529: }

unix.superglobalmegacorp.com

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