Annotation of cci/usr/src/usr.bin/bsc/cmd/batch/bsclog.c, revision 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.