17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5d0fa49b7STony Nguyen * Common Development and Distribution License (the "License"). 6d0fa49b7STony Nguyen * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 22d0fa49b7STony Nguyen * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate /* 277c478bd9Sstevel@tonic-gate * Main processor for auditreduce. 287c478bd9Sstevel@tonic-gate * Mproc() is the entry point for this module. It is the only visible 297c478bd9Sstevel@tonic-gate * function in this module. 307c478bd9Sstevel@tonic-gate */ 317c478bd9Sstevel@tonic-gate 327c478bd9Sstevel@tonic-gate #include <sys/types.h> 337c478bd9Sstevel@tonic-gate #include <locale.h> 347c478bd9Sstevel@tonic-gate #include <bsm/libbsm.h> 35d0fa49b7STony Nguyen #include <bsm/audit.h> 367c478bd9Sstevel@tonic-gate #include "auditr.h" 377c478bd9Sstevel@tonic-gate 387c478bd9Sstevel@tonic-gate extern int write_header(); 397c478bd9Sstevel@tonic-gate extern int token_processing(); 407c478bd9Sstevel@tonic-gate 417c478bd9Sstevel@tonic-gate static void asort(); 427c478bd9Sstevel@tonic-gate static audit_pcb_t *aget(); 437c478bd9Sstevel@tonic-gate static int get_file(); 447c478bd9Sstevel@tonic-gate static int write_recs(); 457c478bd9Sstevel@tonic-gate static int get_recs(); 467c478bd9Sstevel@tonic-gate static int check_rec(); 477c478bd9Sstevel@tonic-gate static void check_order(); 487c478bd9Sstevel@tonic-gate static int check_header(); 497c478bd9Sstevel@tonic-gate static int get_record(); 507c478bd9Sstevel@tonic-gate 517c478bd9Sstevel@tonic-gate static char empty_file_token[] = { 527c478bd9Sstevel@tonic-gate #ifdef _LP64 537c478bd9Sstevel@tonic-gate AUT_OTHER_FILE64, /* token id */ 547c478bd9Sstevel@tonic-gate 0, 0, 0, 0, 0, 0, 0, 0, /* seconds of time */ 557c478bd9Sstevel@tonic-gate 0, 0, 0, 0, 0, 0, 0, 0, /* microseconds of time */ 567c478bd9Sstevel@tonic-gate #else 577c478bd9Sstevel@tonic-gate AUT_OTHER_FILE32, /* token id */ 587c478bd9Sstevel@tonic-gate 0, 0, 0, 0, /* seconds of time */ 597c478bd9Sstevel@tonic-gate 0, 0, 0, 0, /* microseconds of time */ 607c478bd9Sstevel@tonic-gate #endif 617c478bd9Sstevel@tonic-gate 0, 0, /* length of path name */ 627c478bd9Sstevel@tonic-gate }; 637c478bd9Sstevel@tonic-gate 647c478bd9Sstevel@tonic-gate 657c478bd9Sstevel@tonic-gate /* 667c478bd9Sstevel@tonic-gate * .func mproc - main processor. 677c478bd9Sstevel@tonic-gate * .desc Mproc controls a single process's actions. 687c478bd9Sstevel@tonic-gate * First one record is retreived from each pcb. As they are retreived 697c478bd9Sstevel@tonic-gate * they are placed into a linked list sorted with oldest first. Then 707c478bd9Sstevel@tonic-gate * the first one from the list is written out and another record 717c478bd9Sstevel@tonic-gate * read in to replace it. The new record is placed into the list. 727c478bd9Sstevel@tonic-gate * This continues until the list is empty. 737c478bd9Sstevel@tonic-gate * .call ret = mproc(pcbr). 747c478bd9Sstevel@tonic-gate * .arg pcbr - ptr to pcb for this process. 757c478bd9Sstevel@tonic-gate * .ret 0 - no errors in processing. 767c478bd9Sstevel@tonic-gate * .ret -1 - errors in processing (message already printed). 777c478bd9Sstevel@tonic-gate */ 787c478bd9Sstevel@tonic-gate int 797c478bd9Sstevel@tonic-gate mproc(pcbr) 807c478bd9Sstevel@tonic-gate register audit_pcb_t *pcbr; 817c478bd9Sstevel@tonic-gate { 827c478bd9Sstevel@tonic-gate int i, ret, junk; 837c478bd9Sstevel@tonic-gate int nrecs = 0; /* number of records read from stream */ 847c478bd9Sstevel@tonic-gate int nprecs = 0; /* number of records put to stream */ 857c478bd9Sstevel@tonic-gate register audit_pcb_t *pcb; 867c478bd9Sstevel@tonic-gate audit_pcb_t *aget(); 877c478bd9Sstevel@tonic-gate void asort(); 887c478bd9Sstevel@tonic-gate 897c478bd9Sstevel@tonic-gate #if AUDIT_PROC_TRACE 907c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "mproc: count %d lo %d hi %d\n", 917c478bd9Sstevel@tonic-gate pcbr->pcb_count, pcbr->pcb_lo, pcbr->pcb_hi); 927c478bd9Sstevel@tonic-gate #endif 937c478bd9Sstevel@tonic-gate 947c478bd9Sstevel@tonic-gate /* 957c478bd9Sstevel@tonic-gate * First load up a record from each input group. 967c478bd9Sstevel@tonic-gate */ 977c478bd9Sstevel@tonic-gate for (i = pcbr->pcb_lo; i <= pcbr->pcb_hi; i++) { 987c478bd9Sstevel@tonic-gate pcb = &(pcbr->pcb_below[i]); /* get next PCB */ 997c478bd9Sstevel@tonic-gate while (pcb->pcb_time < 0) { /* while no active record ... */ 1007c478bd9Sstevel@tonic-gate if ((ret = get_file(pcb)) == -1) 1017c478bd9Sstevel@tonic-gate break; /* no files - finished PCB */ 1027c478bd9Sstevel@tonic-gate if (ret == -2) 1037c478bd9Sstevel@tonic-gate return (-1); /* quit processing - failed */ 1047c478bd9Sstevel@tonic-gate if (get_recs(pcb, &nrecs) == 0) 1057c478bd9Sstevel@tonic-gate asort(pcb); /* got a rec - put in list */ 1067c478bd9Sstevel@tonic-gate } 1077c478bd9Sstevel@tonic-gate } 1087c478bd9Sstevel@tonic-gate /* 1097c478bd9Sstevel@tonic-gate * Now process all of the records. 1107c478bd9Sstevel@tonic-gate */ 1117c478bd9Sstevel@tonic-gate while ((pcb = aget()) != NULL) { /* get oldest record */ 1127c478bd9Sstevel@tonic-gate if (write_recs(pcbr, pcb, &nprecs)) 1137c478bd9Sstevel@tonic-gate return (-1); 1147c478bd9Sstevel@tonic-gate while (pcb->pcb_time < 0) { /* while we don't have a rec */ 1157c478bd9Sstevel@tonic-gate if (pcb->pcb_fpr == NULL) { /* no active file ... */ 1167c478bd9Sstevel@tonic-gate if ((ret = get_file(pcb)) == -1) 1177c478bd9Sstevel@tonic-gate break; /* no files - finished pcb */ 1187c478bd9Sstevel@tonic-gate else if (ret == -2) 1197c478bd9Sstevel@tonic-gate return (-1); /* quit - failed */ 1207c478bd9Sstevel@tonic-gate } 1217c478bd9Sstevel@tonic-gate if (get_recs(pcb, &nrecs) == 0) 1227c478bd9Sstevel@tonic-gate asort(pcb); /* put record in list */ 1237c478bd9Sstevel@tonic-gate } 1247c478bd9Sstevel@tonic-gate } 1257c478bd9Sstevel@tonic-gate /* 1267c478bd9Sstevel@tonic-gate * For root: write outfile header if no records were encountered. 1277c478bd9Sstevel@tonic-gate * For non-root: write trailer to pipe and close pipe. 1287c478bd9Sstevel@tonic-gate */ 1297c478bd9Sstevel@tonic-gate if (pcbr->pcb_flags & PF_ROOT) { 1307c478bd9Sstevel@tonic-gate if (nprecs == 0) { 1317c478bd9Sstevel@tonic-gate if (write_header()) /* write header if no records */ 1327c478bd9Sstevel@tonic-gate return (-1); 1337c478bd9Sstevel@tonic-gate } 1347c478bd9Sstevel@tonic-gate } else { 1357c478bd9Sstevel@tonic-gate pcb = &(pcbr->pcb_below[0]); /* any old PCB will do */ 1367c478bd9Sstevel@tonic-gate pcb->pcb_rec = empty_file_token; 1377c478bd9Sstevel@tonic-gate if (write_recs(pcbr, pcb, &junk)) 1387c478bd9Sstevel@tonic-gate return (-1); 1397c478bd9Sstevel@tonic-gate if (fclose(pcbr->pcb_fpw) == EOF) { 1407c478bd9Sstevel@tonic-gate if (!f_quiet) 1417c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1427c478bd9Sstevel@tonic-gate gettext("%s couldn't close pipe.\n"), ar); 1437c478bd9Sstevel@tonic-gate } 1447c478bd9Sstevel@tonic-gate } 1457c478bd9Sstevel@tonic-gate /* 1467c478bd9Sstevel@tonic-gate * For root process tell how many records were written. 1477c478bd9Sstevel@tonic-gate */ 1487c478bd9Sstevel@tonic-gate if (f_verbose && (pcbr->pcb_flags & PF_ROOT)) { 1497c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1507c478bd9Sstevel@tonic-gate gettext("%s %d record(s) total were written out.\n"), 1517c478bd9Sstevel@tonic-gate ar, nprecs); 1527c478bd9Sstevel@tonic-gate } 1537c478bd9Sstevel@tonic-gate return (0); 1547c478bd9Sstevel@tonic-gate } 1557c478bd9Sstevel@tonic-gate 1567c478bd9Sstevel@tonic-gate 1577c478bd9Sstevel@tonic-gate /* 1587c478bd9Sstevel@tonic-gate * Head of linked-list of pcbs - sorted by time - oldest first. 1597c478bd9Sstevel@tonic-gate */ 1607c478bd9Sstevel@tonic-gate static audit_pcb_t *pcbls = NULL; 1617c478bd9Sstevel@tonic-gate 1627c478bd9Sstevel@tonic-gate /* 1637c478bd9Sstevel@tonic-gate * .func asort - audit sort. 1647c478bd9Sstevel@tonic-gate * .desc Place a pcb in the list sorted by time - oldest first. 1657c478bd9Sstevel@tonic-gate * .call asort(pcb); 1667c478bd9Sstevel@tonic-gate * .arg pcb - ptr to pcb to install in list. 1677c478bd9Sstevel@tonic-gate * .ret void. 1687c478bd9Sstevel@tonic-gate */ 1697c478bd9Sstevel@tonic-gate static void 1707c478bd9Sstevel@tonic-gate asort(pcb) 1717c478bd9Sstevel@tonic-gate register audit_pcb_t *pcb; 1727c478bd9Sstevel@tonic-gate { 1737c478bd9Sstevel@tonic-gate register audit_pcb_t *pcbc, *pcbp; 1747c478bd9Sstevel@tonic-gate extern audit_pcb_t *pcbls; /* ptr to start of list */ 1757c478bd9Sstevel@tonic-gate 1767c478bd9Sstevel@tonic-gate pcb->pcb_next = NULL; 1777c478bd9Sstevel@tonic-gate if (pcbls == NULL) { 1787c478bd9Sstevel@tonic-gate pcbls = pcb; /* empty list */ 1797c478bd9Sstevel@tonic-gate return; 1807c478bd9Sstevel@tonic-gate } 1817c478bd9Sstevel@tonic-gate pcbc = pcbls; /* current pcb */ 1827c478bd9Sstevel@tonic-gate pcbp = pcbls; /* previous pcb */ 1837c478bd9Sstevel@tonic-gate while (pcbc != NULL) { 1847c478bd9Sstevel@tonic-gate if (pcb->pcb_time < pcbc->pcb_time) { 1857c478bd9Sstevel@tonic-gate if (pcbp == pcbc) { 1867c478bd9Sstevel@tonic-gate pcb->pcb_next = pcbls; /* new -> 1st in list */ 1877c478bd9Sstevel@tonic-gate pcbls = pcb; 1887c478bd9Sstevel@tonic-gate return; 1897c478bd9Sstevel@tonic-gate } 1907c478bd9Sstevel@tonic-gate pcbp->pcb_next = pcb; 1917c478bd9Sstevel@tonic-gate pcb->pcb_next = pcbc; /* new in the inside */ 1927c478bd9Sstevel@tonic-gate return; 1937c478bd9Sstevel@tonic-gate } 1947c478bd9Sstevel@tonic-gate pcbp = pcbc; 1957c478bd9Sstevel@tonic-gate pcbc = pcbc->pcb_next; 1967c478bd9Sstevel@tonic-gate } 1977c478bd9Sstevel@tonic-gate pcbp->pcb_next = pcb; /* new -> last */ 1987c478bd9Sstevel@tonic-gate } 1997c478bd9Sstevel@tonic-gate 2007c478bd9Sstevel@tonic-gate 2017c478bd9Sstevel@tonic-gate /* 2027c478bd9Sstevel@tonic-gate * .func aget - audit get. 2037c478bd9Sstevel@tonic-gate * .desc Get the first pcb from the list. Pcb is removed from list, too. 2047c478bd9Sstevel@tonic-gate * .call pcb = aget(). 2057c478bd9Sstevel@tonic-gate * .arg none. 2067c478bd9Sstevel@tonic-gate * .ret pcb - ptr to pcb that was the first. 2077c478bd9Sstevel@tonic-gate */ 2087c478bd9Sstevel@tonic-gate static audit_pcb_t * 2097c478bd9Sstevel@tonic-gate aget() 2107c478bd9Sstevel@tonic-gate { 2117c478bd9Sstevel@tonic-gate audit_pcb_t *pcbret; 2127c478bd9Sstevel@tonic-gate extern audit_pcb_t *pcbls; /* ptr to start of list */ 2137c478bd9Sstevel@tonic-gate 2147c478bd9Sstevel@tonic-gate if (pcbls == NULL) 2157c478bd9Sstevel@tonic-gate return (pcbls); /* empty list */ 2167c478bd9Sstevel@tonic-gate pcbret = pcbls; 2177c478bd9Sstevel@tonic-gate pcbls = pcbls->pcb_next; /* 2nd becomes 1st */ 2187c478bd9Sstevel@tonic-gate return (pcbret); 2197c478bd9Sstevel@tonic-gate } 2207c478bd9Sstevel@tonic-gate 2217c478bd9Sstevel@tonic-gate 2227c478bd9Sstevel@tonic-gate /* 2237c478bd9Sstevel@tonic-gate * .func get_file - get a new file. 2247c478bd9Sstevel@tonic-gate * .desc Get the next file from the pcb's list. Check the header to see 2257c478bd9Sstevel@tonic-gate * if the file really is an audit file. If there are no more then 2267c478bd9Sstevel@tonic-gate * quit. If a file open (fopen) fails because the system file table 2277c478bd9Sstevel@tonic-gate * is full or the process file table is full then quit processing 2287c478bd9Sstevel@tonic-gate * altogether. 2297c478bd9Sstevel@tonic-gate * .call ret = get_file(pcb). 2307c478bd9Sstevel@tonic-gate * .arg pcb - pcb holding the fcb's (files). 2317c478bd9Sstevel@tonic-gate * .ret 0 - new file opened for processing. 2327c478bd9Sstevel@tonic-gate * .ret -1 - no more files - pcb finished. 2337c478bd9Sstevel@tonic-gate * .ret -2 - fatal error - quit processing. 2347c478bd9Sstevel@tonic-gate */ 2357c478bd9Sstevel@tonic-gate static int 2367c478bd9Sstevel@tonic-gate get_file(pcb) 2377c478bd9Sstevel@tonic-gate register audit_pcb_t *pcb; 2387c478bd9Sstevel@tonic-gate { 2397c478bd9Sstevel@tonic-gate FILE *fp; 2407c478bd9Sstevel@tonic-gate audit_fcb_t *fcb; 2417c478bd9Sstevel@tonic-gate 2427c478bd9Sstevel@tonic-gate /* 2437c478bd9Sstevel@tonic-gate * Process file list until a good one if found or empty. 2447c478bd9Sstevel@tonic-gate */ 2457c478bd9Sstevel@tonic-gate while (pcb->pcb_fpr == NULL) { 2467c478bd9Sstevel@tonic-gate if ((fcb = pcb->pcb_first) == NULL) { 2477c478bd9Sstevel@tonic-gate pcb->pcb_time = -1; 2487c478bd9Sstevel@tonic-gate return (-1); /* pcb is all done */ 2497c478bd9Sstevel@tonic-gate } else { 2507c478bd9Sstevel@tonic-gate /* 2517c478bd9Sstevel@tonic-gate * If we are reading from files then open the next one. 2527c478bd9Sstevel@tonic-gate */ 2537c478bd9Sstevel@tonic-gate if (!f_stdin) { 2547c478bd9Sstevel@tonic-gate if ((fp = fopen(fcb->fcb_file, "r")) == NULL) { 2557c478bd9Sstevel@tonic-gate if (!f_quiet) { 2567c478bd9Sstevel@tonic-gate (void) sprintf(errbuf, gettext( 2577c478bd9Sstevel@tonic-gate "%s couldn't open:\n %s"), 2587c478bd9Sstevel@tonic-gate ar, fcb->fcb_file); 2597c478bd9Sstevel@tonic-gate perror(errbuf); 2607c478bd9Sstevel@tonic-gate } 2617c478bd9Sstevel@tonic-gate /* 2627c478bd9Sstevel@tonic-gate * See if file space is depleted. 2637c478bd9Sstevel@tonic-gate * If it is then we quit. 2647c478bd9Sstevel@tonic-gate */ 2657c478bd9Sstevel@tonic-gate if (errno == ENFILE || errno == EMFILE) 2667c478bd9Sstevel@tonic-gate { 2677c478bd9Sstevel@tonic-gate return (-2); 2687c478bd9Sstevel@tonic-gate } 2697c478bd9Sstevel@tonic-gate pcb->pcb_first = fcb->fcb_next; 2707c478bd9Sstevel@tonic-gate continue; /* try another file */ 2717c478bd9Sstevel@tonic-gate } 2727c478bd9Sstevel@tonic-gate } else { 2737c478bd9Sstevel@tonic-gate /* 2747c478bd9Sstevel@tonic-gate * Read from standard input. 2757c478bd9Sstevel@tonic-gate */ 2767c478bd9Sstevel@tonic-gate fp = stdin; 2777c478bd9Sstevel@tonic-gate } 2787c478bd9Sstevel@tonic-gate /* 2797c478bd9Sstevel@tonic-gate * Check header of audit file. 2807c478bd9Sstevel@tonic-gate */ 2817c478bd9Sstevel@tonic-gate if (check_header(fp, fcb->fcb_name)) { 2827c478bd9Sstevel@tonic-gate if (!f_quiet) { 2837c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 2847c478bd9Sstevel@tonic-gate "%s %s:\n %s.\n", 2857c478bd9Sstevel@tonic-gate ar, error_str, fcb->fcb_file); 2867c478bd9Sstevel@tonic-gate } 2877c478bd9Sstevel@tonic-gate if (fclose(fp) == EOF) { 2887c478bd9Sstevel@tonic-gate if (!f_quiet) { 2897c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 2907c478bd9Sstevel@tonic-gate "%s couldn't close %s.\n"), 2917c478bd9Sstevel@tonic-gate ar, fcb->fcb_file); 2927c478bd9Sstevel@tonic-gate } 2937c478bd9Sstevel@tonic-gate } 2947c478bd9Sstevel@tonic-gate pcb->pcb_first = fcb->fcb_next; 2957c478bd9Sstevel@tonic-gate continue; /* try another file */ 2967c478bd9Sstevel@tonic-gate } 2977c478bd9Sstevel@tonic-gate /* 2987c478bd9Sstevel@tonic-gate * Found a good audit file. 2997c478bd9Sstevel@tonic-gate * Initalize pcb for processing. 3007c478bd9Sstevel@tonic-gate */ 3017c478bd9Sstevel@tonic-gate pcb->pcb_first = fcb->fcb_next; 3027c478bd9Sstevel@tonic-gate pcb->pcb_cur = fcb; 3037c478bd9Sstevel@tonic-gate pcb->pcb_fpr = fp; 3047c478bd9Sstevel@tonic-gate pcb->pcb_nrecs = 0; 3057c478bd9Sstevel@tonic-gate pcb->pcb_nprecs = 0; 3067c478bd9Sstevel@tonic-gate pcb->pcb_otime = -1; 3077c478bd9Sstevel@tonic-gate } 3087c478bd9Sstevel@tonic-gate } 3097c478bd9Sstevel@tonic-gate return (0); 3107c478bd9Sstevel@tonic-gate } 3117c478bd9Sstevel@tonic-gate 3127c478bd9Sstevel@tonic-gate 3137c478bd9Sstevel@tonic-gate /* 3147c478bd9Sstevel@tonic-gate * .func write_recs - write records. 3157c478bd9Sstevel@tonic-gate * .desc Write record from a buffer to output stream. Keep an eye out 3167c478bd9Sstevel@tonic-gate * for the first and last records of the root's output stream. 3177c478bd9Sstevel@tonic-gate * .call ret = write_recs(pcbr, pcb, nprecs). 3187c478bd9Sstevel@tonic-gate * .arg pcbr - ptr to node pcb. 3197c478bd9Sstevel@tonic-gate * .arg pcb - ptr to pcb holding the stream. 3207c478bd9Sstevel@tonic-gate * .arg nprecs - ptr to the number of put records. Updated here. 3217c478bd9Sstevel@tonic-gate * .ret 0 - no errors detected. 3227c478bd9Sstevel@tonic-gate * .ret -1 - error in writing. Quit processing. 3237c478bd9Sstevel@tonic-gate */ 3247c478bd9Sstevel@tonic-gate static int 3257c478bd9Sstevel@tonic-gate write_recs(pcbr, pcb, nprecs) 3267c478bd9Sstevel@tonic-gate register audit_pcb_t *pcbr, *pcb; 3277c478bd9Sstevel@tonic-gate int *nprecs; 3287c478bd9Sstevel@tonic-gate { 3297c478bd9Sstevel@tonic-gate adr_t adr; 3307c478bd9Sstevel@tonic-gate char id; 3317c478bd9Sstevel@tonic-gate int32_t size; 3327c478bd9Sstevel@tonic-gate 3337c478bd9Sstevel@tonic-gate adrm_start(&adr, pcb->pcb_rec); 3347c478bd9Sstevel@tonic-gate (void) adrm_char(&adr, &id, 1); 3357c478bd9Sstevel@tonic-gate (void) adrm_int32(&adr, &size, 1); 3367c478bd9Sstevel@tonic-gate 3377c478bd9Sstevel@tonic-gate /* 3387c478bd9Sstevel@tonic-gate * Scan for first record to be written to outfile. 3397c478bd9Sstevel@tonic-gate * When we find it then write the header and 3407c478bd9Sstevel@tonic-gate * save the time for the outfile name. 3417c478bd9Sstevel@tonic-gate */ 3427c478bd9Sstevel@tonic-gate if ((*nprecs)++ == 0) { 3437c478bd9Sstevel@tonic-gate if (pcbr->pcb_flags & PF_ROOT) { 3447c478bd9Sstevel@tonic-gate f_start = pcb->pcb_time; /* save start time */ 3457c478bd9Sstevel@tonic-gate if (write_header()) 3467c478bd9Sstevel@tonic-gate return (-1); 3477c478bd9Sstevel@tonic-gate } 3487c478bd9Sstevel@tonic-gate } 3497c478bd9Sstevel@tonic-gate f_end = pcb->pcb_time; /* find last record's time */ 3507c478bd9Sstevel@tonic-gate pcb->pcb_time = -1; /* disable just written rec */ 3517c478bd9Sstevel@tonic-gate 3527c478bd9Sstevel@tonic-gate if ((fwrite(pcb->pcb_rec, sizeof (char), size, pcbr->pcb_fpw)) != 3537c478bd9Sstevel@tonic-gate size) { 3547c478bd9Sstevel@tonic-gate if (pcbr->pcb_flags & PF_ROOT) { 3557c478bd9Sstevel@tonic-gate (void) sprintf(errbuf, gettext( 3567c478bd9Sstevel@tonic-gate "%s write failed to %s"), 3577c478bd9Sstevel@tonic-gate ar, f_outfile ? f_outfile : gettext("stdout")); 3587c478bd9Sstevel@tonic-gate perror(errbuf); 3597c478bd9Sstevel@tonic-gate } else { 3607c478bd9Sstevel@tonic-gate perror(gettext("auditreduce: write failed to pipe")); 3617c478bd9Sstevel@tonic-gate } 3627c478bd9Sstevel@tonic-gate return (-1); 3637c478bd9Sstevel@tonic-gate } 3647c478bd9Sstevel@tonic-gate free(pcb->pcb_rec); 3657c478bd9Sstevel@tonic-gate return (0); 3667c478bd9Sstevel@tonic-gate } 3677c478bd9Sstevel@tonic-gate 3687c478bd9Sstevel@tonic-gate /* 3697c478bd9Sstevel@tonic-gate * .func get_recs - get records. 3707c478bd9Sstevel@tonic-gate * .desc Get records from a stream until one passing the current selection 3717c478bd9Sstevel@tonic-gate * criteria is found or the stream is emptied. 3727c478bd9Sstevel@tonic-gate * .call ret = get_recs(pcb, nr). 3737c478bd9Sstevel@tonic-gate * .arg pcb - ptr to pcb that holds this stream. 3747c478bd9Sstevel@tonic-gate * .arg nr - ptr to number of records read. Updated by this routine. 3757c478bd9Sstevel@tonic-gate * .ret 0 - got a record. 3767c478bd9Sstevel@tonic-gate * .ret -1 - stream is finished. 3777c478bd9Sstevel@tonic-gate */ 3787c478bd9Sstevel@tonic-gate static int 3797c478bd9Sstevel@tonic-gate get_recs(pcb, nr) 3807c478bd9Sstevel@tonic-gate register audit_pcb_t *pcb; 3817c478bd9Sstevel@tonic-gate int *nr; 3827c478bd9Sstevel@tonic-gate { 3837c478bd9Sstevel@tonic-gate adr_t adr; 3847c478bd9Sstevel@tonic-gate time_t secs; 3857c478bd9Sstevel@tonic-gate int tmp; 3867c478bd9Sstevel@tonic-gate int ret, ret2; 3877c478bd9Sstevel@tonic-gate int nrecs = 0; /* count how many records read this call */ 3887c478bd9Sstevel@tonic-gate int getrec = TRUE; 3897c478bd9Sstevel@tonic-gate int alldone = FALSE; 3907c478bd9Sstevel@tonic-gate char header_type; 3917c478bd9Sstevel@tonic-gate short e; 3927c478bd9Sstevel@tonic-gate char *str; 3937c478bd9Sstevel@tonic-gate #if AUDIT_FILE 3947c478bd9Sstevel@tonic-gate static void get_trace(); 3957c478bd9Sstevel@tonic-gate #endif 3967c478bd9Sstevel@tonic-gate 3977c478bd9Sstevel@tonic-gate while (getrec) { 3987c478bd9Sstevel@tonic-gate ret = get_record(pcb->pcb_fpr, &pcb->pcb_rec, 3997c478bd9Sstevel@tonic-gate pcb->pcb_cur->fcb_name); 4007c478bd9Sstevel@tonic-gate if (ret > 0) { 4017c478bd9Sstevel@tonic-gate adrm_start(&adr, pcb->pcb_rec); 4027c478bd9Sstevel@tonic-gate 4037c478bd9Sstevel@tonic-gate /* get token id */ 4047c478bd9Sstevel@tonic-gate (void) adrm_char(&adr, (char *)&header_type, 1); 4057c478bd9Sstevel@tonic-gate /* skip over byte count */ 4067c478bd9Sstevel@tonic-gate (void) adrm_int32(&adr, (int32_t *)&tmp, 1); 4077c478bd9Sstevel@tonic-gate /* skip over version # */ 4087c478bd9Sstevel@tonic-gate (void) adrm_char(&adr, (char *)&tmp, 1); 4097c478bd9Sstevel@tonic-gate /* skip over event id */ 4107c478bd9Sstevel@tonic-gate (void) adrm_short(&adr, (short *)&e, 1); 4117c478bd9Sstevel@tonic-gate /* skip over event id modifier */ 4127c478bd9Sstevel@tonic-gate (void) adrm_short(&adr, (short *)&tmp, 1); 4137c478bd9Sstevel@tonic-gate 4147c478bd9Sstevel@tonic-gate if (header_type == AUT_HEADER32) { 4157c478bd9Sstevel@tonic-gate int32_t s, m; 4167c478bd9Sstevel@tonic-gate 4177c478bd9Sstevel@tonic-gate /* get seconds */ 4187c478bd9Sstevel@tonic-gate (void) adrm_int32(&adr, (int32_t *)&s, 1); 4197c478bd9Sstevel@tonic-gate /* get microseconds */ 4207c478bd9Sstevel@tonic-gate (void) adrm_int32(&adr, (int32_t *)&m, 1); 4217c478bd9Sstevel@tonic-gate secs = (time_t)s; 4227c478bd9Sstevel@tonic-gate } else if (header_type == AUT_HEADER32_EX) { 4237c478bd9Sstevel@tonic-gate int32_t s, m; 4247c478bd9Sstevel@tonic-gate int32_t t, junk[4]; /* at_type + at_addr[4] */ 4257c478bd9Sstevel@tonic-gate 4267c478bd9Sstevel@tonic-gate /* skip type and ip address field */ 4277c478bd9Sstevel@tonic-gate (void) adrm_int32(&adr, (int32_t *)&t, 1); 4287c478bd9Sstevel@tonic-gate (void) adrm_int32(&adr, (int32_t *)&junk[0], t/4); 4297c478bd9Sstevel@tonic-gate 4307c478bd9Sstevel@tonic-gate /* get seconds */ 4317c478bd9Sstevel@tonic-gate (void) adrm_int32(&adr, (int32_t *)&s, 1); 4327c478bd9Sstevel@tonic-gate /* get microseconds */ 4337c478bd9Sstevel@tonic-gate (void) adrm_int32(&adr, (int32_t *)&m, 1); 4347c478bd9Sstevel@tonic-gate secs = (time_t)s; 4357c478bd9Sstevel@tonic-gate } else if (header_type == AUT_HEADER64) { 4367c478bd9Sstevel@tonic-gate int64_t s, m; 4377c478bd9Sstevel@tonic-gate 4387c478bd9Sstevel@tonic-gate /* get seconds */ 4397c478bd9Sstevel@tonic-gate (void) adrm_int64(&adr, (int64_t *)&s, 1); 4407c478bd9Sstevel@tonic-gate /* get microseconds */ 4417c478bd9Sstevel@tonic-gate (void) adrm_int64(&adr, (int64_t *)&m, 1); 4427c478bd9Sstevel@tonic-gate #if ((!defined(_LP64)) || defined(_SYSCALL32)) 4437c478bd9Sstevel@tonic-gate if (s < (time_t)INT32_MIN || 4447c478bd9Sstevel@tonic-gate s > (time_t)INT32_MAX) 4457c478bd9Sstevel@tonic-gate secs = 0; 4467c478bd9Sstevel@tonic-gate else 4477c478bd9Sstevel@tonic-gate secs = (time_t)s; 4487c478bd9Sstevel@tonic-gate #else 4497c478bd9Sstevel@tonic-gate secs = (time_t)s; 4507c478bd9Sstevel@tonic-gate #endif 4517c478bd9Sstevel@tonic-gate } else if (header_type == AUT_HEADER64_EX) { 4527c478bd9Sstevel@tonic-gate int64_t s, m; 4537c478bd9Sstevel@tonic-gate int32_t t, junk[4]; 4547c478bd9Sstevel@tonic-gate 4557c478bd9Sstevel@tonic-gate /* skip type and ip address field */ 4567c478bd9Sstevel@tonic-gate (void) adrm_int32(&adr, (int32_t *)&t, 1); 4577c478bd9Sstevel@tonic-gate (void) adrm_int32(&adr, (int32_t *)&junk[0], t/4); 4587c478bd9Sstevel@tonic-gate 4597c478bd9Sstevel@tonic-gate /* get seconds */ 4607c478bd9Sstevel@tonic-gate (void) adrm_int64(&adr, (int64_t *)&s, 1); 4617c478bd9Sstevel@tonic-gate /* get microseconds */ 4627c478bd9Sstevel@tonic-gate (void) adrm_int64(&adr, (int64_t *)&m, 1); 4637c478bd9Sstevel@tonic-gate #if ((!defined(_LP64)) || defined(_SYSCALL32)) 4647c478bd9Sstevel@tonic-gate if (s < (time_t)INT32_MIN || 4657c478bd9Sstevel@tonic-gate s > (time_t)INT32_MAX) 4667c478bd9Sstevel@tonic-gate secs = 0; 4677c478bd9Sstevel@tonic-gate else 4687c478bd9Sstevel@tonic-gate secs = (time_t)s; 4697c478bd9Sstevel@tonic-gate #else 4707c478bd9Sstevel@tonic-gate secs = (time_t)s; 4717c478bd9Sstevel@tonic-gate #endif 4727c478bd9Sstevel@tonic-gate } 4737c478bd9Sstevel@tonic-gate } 4747c478bd9Sstevel@tonic-gate 4757c478bd9Sstevel@tonic-gate #if AUDIT_REC 4767c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "get_recs: %d ret %d recno %d\n", 4777c478bd9Sstevel@tonic-gate pcb->pcb_procno, ret, pcb->pcb_nrecs + 1); 4787c478bd9Sstevel@tonic-gate #endif 4797c478bd9Sstevel@tonic-gate /* 4807c478bd9Sstevel@tonic-gate * See if entire file is after the time window specified. 4817c478bd9Sstevel@tonic-gate * Must be check here because the start time of the file name 4827c478bd9Sstevel@tonic-gate * may be after the first record(s). 4837c478bd9Sstevel@tonic-gate */ 484*406d6273SPalle Lyckegaard if (pcb->pcb_nrecs == 0 && (pcb->pcb_flags & PF_USEFILE)) { 4857c478bd9Sstevel@tonic-gate /* 4867c478bd9Sstevel@tonic-gate * If the first record read failed then use the time 4877c478bd9Sstevel@tonic-gate * that was in the filename to judge. 4887c478bd9Sstevel@tonic-gate */ 4897c478bd9Sstevel@tonic-gate if (ret > 0) 4907c478bd9Sstevel@tonic-gate (pcb->pcb_cur)->fcb_start = secs; 4917c478bd9Sstevel@tonic-gate if (!f_all && (m_before <= (pcb->pcb_cur)->fcb_start)) { 4927c478bd9Sstevel@tonic-gate (void) fclose(pcb->pcb_fpr); /* ignore file */ 4937c478bd9Sstevel@tonic-gate pcb->pcb_fpr = NULL; 4947c478bd9Sstevel@tonic-gate pcb->pcb_time = -1; 4957c478bd9Sstevel@tonic-gate return (-1); 4967c478bd9Sstevel@tonic-gate } else { 4977c478bd9Sstevel@tonic-gate /* Give belated announcement of file opening. */ 4987c478bd9Sstevel@tonic-gate if (f_verbose) { 4997c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 5007c478bd9Sstevel@tonic-gate gettext("%s opened:\n %s.\n"), 5017c478bd9Sstevel@tonic-gate ar, (pcb->pcb_cur)->fcb_file); 5027c478bd9Sstevel@tonic-gate } 5037c478bd9Sstevel@tonic-gate } 5047c478bd9Sstevel@tonic-gate } 5057c478bd9Sstevel@tonic-gate /* Succesful acquisition of a record. */ 5067c478bd9Sstevel@tonic-gate if (ret > 0) { 5077c478bd9Sstevel@tonic-gate pcb->pcb_time = secs; /* time of record */ 5087c478bd9Sstevel@tonic-gate pcb->pcb_nrecs++; /* # of read recs from stream */ 5097c478bd9Sstevel@tonic-gate nrecs++; /* # of recs read this call */ 5107c478bd9Sstevel@tonic-gate /* Only check record if at bottom of process tree. */ 511*406d6273SPalle Lyckegaard if (pcb->pcb_flags & PF_USEFILE) { 5127c478bd9Sstevel@tonic-gate check_order(pcb); /* check time sequence */ 5137c478bd9Sstevel@tonic-gate if ((ret2 = check_rec(pcb)) == 0) { 5147c478bd9Sstevel@tonic-gate pcb->pcb_nprecs++; 5157c478bd9Sstevel@tonic-gate getrec = FALSE; 5167c478bd9Sstevel@tonic-gate } else if (ret2 == -2) { 5177c478bd9Sstevel@tonic-gate /* error */ 5187c478bd9Sstevel@tonic-gate getrec = FALSE; /* get no more recs */ 5197c478bd9Sstevel@tonic-gate alldone = TRUE; /* quit this file */ 5207c478bd9Sstevel@tonic-gate free(pcb->pcb_rec); 5217c478bd9Sstevel@tonic-gate } else { 5227c478bd9Sstevel@tonic-gate /* -1: record not interesting */ 5237c478bd9Sstevel@tonic-gate free(pcb->pcb_rec); 5247c478bd9Sstevel@tonic-gate } 5257c478bd9Sstevel@tonic-gate } else { 5267c478bd9Sstevel@tonic-gate pcb->pcb_nprecs++; 5277c478bd9Sstevel@tonic-gate getrec = FALSE; 5287c478bd9Sstevel@tonic-gate } 5297c478bd9Sstevel@tonic-gate } else { 5307c478bd9Sstevel@tonic-gate /* Error with record read or all done with stream. */ 5317c478bd9Sstevel@tonic-gate getrec = FALSE; 5327c478bd9Sstevel@tonic-gate alldone = TRUE; 5337c478bd9Sstevel@tonic-gate } 5347c478bd9Sstevel@tonic-gate } 5357c478bd9Sstevel@tonic-gate if (alldone == TRUE) { 5367c478bd9Sstevel@tonic-gate #if AUDIT_FILE 5377c478bd9Sstevel@tonic-gate get_trace(pcb); 5387c478bd9Sstevel@tonic-gate #endif 5397c478bd9Sstevel@tonic-gate /* Error in record read. Display messages. */ 5407c478bd9Sstevel@tonic-gate if (ret < 0 || ret2 == -2) { 5417c478bd9Sstevel@tonic-gate pcb->pcb_nrecs++; /* # of read records */ 5427c478bd9Sstevel@tonic-gate if (!f_quiet) { 543*406d6273SPalle Lyckegaard if (pcb->pcb_flags & PF_USEFILE) { 5447c478bd9Sstevel@tonic-gate /* Ignore if this is not_terminated. */ 5457c478bd9Sstevel@tonic-gate if (!strstr((pcb->pcb_cur)->fcb_file, 5467c478bd9Sstevel@tonic-gate "not_terminated")) { 5477c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("%s read error in %s at record %d.\n"), ar, 5487c478bd9Sstevel@tonic-gate (pcb->pcb_cur)->fcb_file, pcb->pcb_nrecs); 5497c478bd9Sstevel@tonic-gate } 5507c478bd9Sstevel@tonic-gate } else { 5517c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("%s read error in pipe at record %d.\n"), ar, 5527c478bd9Sstevel@tonic-gate pcb->pcb_nrecs); 5537c478bd9Sstevel@tonic-gate } 5547c478bd9Sstevel@tonic-gate } 5557c478bd9Sstevel@tonic-gate } else { 5567c478bd9Sstevel@tonic-gate /* 5577c478bd9Sstevel@tonic-gate * Only mark infile for deleting if we have succesfully 5587c478bd9Sstevel@tonic-gate * processed all of it. 5597c478bd9Sstevel@tonic-gate */ 560*406d6273SPalle Lyckegaard if (pcb->pcb_flags & PF_USEFILE) 5617c478bd9Sstevel@tonic-gate (pcb->pcb_cur)->fcb_flags |= FF_DELETE; 5627c478bd9Sstevel@tonic-gate } 5637c478bd9Sstevel@tonic-gate if (fclose(pcb->pcb_fpr) == EOF) { 5647c478bd9Sstevel@tonic-gate if (!f_quiet) { 565*406d6273SPalle Lyckegaard if (pcb->pcb_flags & PF_USEFILE) { 5667c478bd9Sstevel@tonic-gate str = (pcb->pcb_cur)->fcb_file; 5677c478bd9Sstevel@tonic-gate } else { 5687c478bd9Sstevel@tonic-gate str = "pipe"; 5697c478bd9Sstevel@tonic-gate } 5707c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 5717c478bd9Sstevel@tonic-gate gettext("%s couldn't close %s.\n"), 5727c478bd9Sstevel@tonic-gate ar, str); 5737c478bd9Sstevel@tonic-gate } 5747c478bd9Sstevel@tonic-gate } 5757c478bd9Sstevel@tonic-gate pcb->pcb_fpr = NULL; 5767c478bd9Sstevel@tonic-gate pcb->pcb_time = -1; 5777c478bd9Sstevel@tonic-gate *nr += nrecs; 5787c478bd9Sstevel@tonic-gate return (-1); 5797c478bd9Sstevel@tonic-gate } 5807c478bd9Sstevel@tonic-gate *nr += nrecs; 5817c478bd9Sstevel@tonic-gate return (0); 5827c478bd9Sstevel@tonic-gate } 5837c478bd9Sstevel@tonic-gate 5847c478bd9Sstevel@tonic-gate 5857c478bd9Sstevel@tonic-gate #if AUDIT_FILE 5867c478bd9Sstevel@tonic-gate /* 5877c478bd9Sstevel@tonic-gate * .func get_trace - get trace. 5887c478bd9Sstevel@tonic-gate * .desc If we are tracing file action (AUDIT_FILE is on) then print out 5897c478bd9Sstevel@tonic-gate * a message when the file is closed regarding how many records 5907c478bd9Sstevel@tonic-gate * were handled. 5917c478bd9Sstevel@tonic-gate * .call get_trace(pcb). 5927c478bd9Sstevel@tonic-gate * .arg pcb - ptr to pcb holding file/pipe. 5937c478bd9Sstevel@tonic-gate * .ret void. 5947c478bd9Sstevel@tonic-gate */ 5957c478bd9Sstevel@tonic-gate static void 5967c478bd9Sstevel@tonic-gate get_trace(pcb) 5977c478bd9Sstevel@tonic-gate audit_pcb_t *pcb; 5987c478bd9Sstevel@tonic-gate { 5997c478bd9Sstevel@tonic-gate /* 6007c478bd9Sstevel@tonic-gate * For file give filename, too. 6017c478bd9Sstevel@tonic-gate */ 602*406d6273SPalle Lyckegaard if (pcb->pcb_flags & PF_USEFILE) { 6037c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "%s closed %s: %d records read recs: \ 6047c478bd9Sstevel@tonic-gate %d record written.\n", ar, (pcb->pcb_cur)->fcb_file, 6057c478bd9Sstevel@tonic-gate pcb->pcb_nrecs, pcb->pcb_nprecs); 6067c478bd9Sstevel@tonic-gate } else { 6077c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "%s closed pipe: %d records read: \ 6087c478bd9Sstevel@tonic-gate %d records written .\n", ar, pcb->pcb_nrecs, 6097c478bd9Sstevel@tonic-gate pcb->pcb_nprecs); 6107c478bd9Sstevel@tonic-gate } 6117c478bd9Sstevel@tonic-gate } 6127c478bd9Sstevel@tonic-gate 6137c478bd9Sstevel@tonic-gate #endif 6147c478bd9Sstevel@tonic-gate 6157c478bd9Sstevel@tonic-gate /* 6167c478bd9Sstevel@tonic-gate * .func check_rec - check a record. 6177c478bd9Sstevel@tonic-gate * .desc Check a record against the user's selection criteria. 6187c478bd9Sstevel@tonic-gate * .call ret = check_rec(pcb). 6197c478bd9Sstevel@tonic-gate * .arg pcb - ptr to pcb holding the record. 6207c478bd9Sstevel@tonic-gate * .ret 0 - record accepted. 6217c478bd9Sstevel@tonic-gate * .ret -1 - record rejected - continue processing file. 6227c478bd9Sstevel@tonic-gate * .ret -2 - record rejected - quit processing file. 6237c478bd9Sstevel@tonic-gate */ 6247c478bd9Sstevel@tonic-gate static int 6257c478bd9Sstevel@tonic-gate check_rec(pcb) 6267c478bd9Sstevel@tonic-gate register audit_pcb_t *pcb; 6277c478bd9Sstevel@tonic-gate { 6287c478bd9Sstevel@tonic-gate adr_t adr; 6297c478bd9Sstevel@tonic-gate struct timeval tv; 6307c478bd9Sstevel@tonic-gate uint_t bytes; 631d0fa49b7STony Nguyen au_emod_t id_modifier; 6327c478bd9Sstevel@tonic-gate char version; 633d0fa49b7STony Nguyen au_event_t event_type; 6347c478bd9Sstevel@tonic-gate char tokenid; 6357c478bd9Sstevel@tonic-gate int rc; /* return code */ 6367c478bd9Sstevel@tonic-gate 6377c478bd9Sstevel@tonic-gate adrm_start(&adr, pcb->pcb_rec); 6387c478bd9Sstevel@tonic-gate (void) adrm_char(&adr, &tokenid, 1); 6397c478bd9Sstevel@tonic-gate 6407c478bd9Sstevel@tonic-gate /* 6417c478bd9Sstevel@tonic-gate * checkflags will be my data structure for determining if 6427c478bd9Sstevel@tonic-gate * a record has met ALL the selection criteria. Once 6437c478bd9Sstevel@tonic-gate * checkflags == flags, we have seen all we need to of the 6447c478bd9Sstevel@tonic-gate * record, and can go to the next one. If when we finish 6457c478bd9Sstevel@tonic-gate * processing the record we still have stuff to see, 6467c478bd9Sstevel@tonic-gate * checkflags != flags, and thus we should return a -1 6477c478bd9Sstevel@tonic-gate * from this function meaning reject this record. 6487c478bd9Sstevel@tonic-gate */ 6497c478bd9Sstevel@tonic-gate 6507c478bd9Sstevel@tonic-gate checkflags = 0; 6517c478bd9Sstevel@tonic-gate 6527c478bd9Sstevel@tonic-gate /* must be header token -- sanity check */ 6537c478bd9Sstevel@tonic-gate if (tokenid != AUT_HEADER32 && tokenid != AUT_HEADER64 && 6547c478bd9Sstevel@tonic-gate tokenid != AUT_HEADER32_EX && tokenid != AUT_HEADER64_EX) { 6557c478bd9Sstevel@tonic-gate #if AUDIT_REC 6567c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 6577c478bd9Sstevel@tonic-gate "check_rec: %d recno %d no header %d found\n", 6587c478bd9Sstevel@tonic-gate pcb->pcb_procno, pcb->pcb_nrecs, tokenid); 6597c478bd9Sstevel@tonic-gate #endif 6607c478bd9Sstevel@tonic-gate return (-2); 6617c478bd9Sstevel@tonic-gate } 6627c478bd9Sstevel@tonic-gate 6637c478bd9Sstevel@tonic-gate /* 6647c478bd9Sstevel@tonic-gate * The header token is: 6657c478bd9Sstevel@tonic-gate * attribute id: char 6667c478bd9Sstevel@tonic-gate * byte count: int 6677c478bd9Sstevel@tonic-gate * version #: char 6687c478bd9Sstevel@tonic-gate * event ID: short 6697c478bd9Sstevel@tonic-gate * ID modifier: short 6707c478bd9Sstevel@tonic-gate * seconds (date): int 6717c478bd9Sstevel@tonic-gate * time (microsecs): int 6727c478bd9Sstevel@tonic-gate */ 6737c478bd9Sstevel@tonic-gate (void) adrm_u_int32(&adr, (uint32_t *)&bytes, 1); 6747c478bd9Sstevel@tonic-gate (void) adrm_char(&adr, &version, 1); 6757c478bd9Sstevel@tonic-gate (void) adrm_u_short(&adr, &event_type, 1); 6767c478bd9Sstevel@tonic-gate 6777c478bd9Sstevel@tonic-gate /* 6787c478bd9Sstevel@tonic-gate * Used by s5_IPC_token to set the ipc_type so 6797c478bd9Sstevel@tonic-gate * s5_IPC_perm_token can test. 6807c478bd9Sstevel@tonic-gate */ 6817c478bd9Sstevel@tonic-gate ipc_type = (char)0; 6827c478bd9Sstevel@tonic-gate 6837c478bd9Sstevel@tonic-gate if (flags & M_TYPE) { 6847c478bd9Sstevel@tonic-gate checkflags |= M_TYPE; 6857c478bd9Sstevel@tonic-gate if (m_type != event_type) 6867c478bd9Sstevel@tonic-gate return (-1); 6877c478bd9Sstevel@tonic-gate } 6887c478bd9Sstevel@tonic-gate if (flags & M_CLASS) { 6897c478bd9Sstevel@tonic-gate au_event_ent_t *ev = NULL; 6907c478bd9Sstevel@tonic-gate 6917c478bd9Sstevel@tonic-gate checkflags |= M_CLASS; 6927c478bd9Sstevel@tonic-gate if (cacheauevent(&ev, event_type) <= 0) { 6937c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 6947c478bd9Sstevel@tonic-gate "Warning: invalid event no %d in audit trail."), 6957c478bd9Sstevel@tonic-gate event_type); 6967c478bd9Sstevel@tonic-gate return (-1); 6977c478bd9Sstevel@tonic-gate } 6987c478bd9Sstevel@tonic-gate global_class = ev->ae_class; 6997c478bd9Sstevel@tonic-gate if (!(flags & M_SORF) && !(mask.am_success & global_class)) 7007c478bd9Sstevel@tonic-gate return (-1); 7017c478bd9Sstevel@tonic-gate } 7027c478bd9Sstevel@tonic-gate 7037c478bd9Sstevel@tonic-gate (void) adrm_u_short(&adr, &id_modifier, 1); 7047c478bd9Sstevel@tonic-gate 7057c478bd9Sstevel@tonic-gate /* 7067c478bd9Sstevel@tonic-gate * Check record against time criteria. 7077c478bd9Sstevel@tonic-gate * If the 'A' option was used then no time checking is done. 7087c478bd9Sstevel@tonic-gate * The 'a' parameter is inclusive and the 'b' exclusive. 7097c478bd9Sstevel@tonic-gate */ 7107c478bd9Sstevel@tonic-gate if (tokenid == AUT_HEADER32) { 7117c478bd9Sstevel@tonic-gate int32_t secs, msecs; 7127c478bd9Sstevel@tonic-gate (void) adrm_int32(&adr, (int32_t *)&secs, 1); 7137c478bd9Sstevel@tonic-gate (void) adrm_int32(&adr, (int32_t *)&msecs, 1); 7147c478bd9Sstevel@tonic-gate tv.tv_sec = (time_t)secs; 7157c478bd9Sstevel@tonic-gate tv.tv_usec = (suseconds_t)msecs; 7167c478bd9Sstevel@tonic-gate } else if (tokenid == AUT_HEADER32_EX) { 7177c478bd9Sstevel@tonic-gate int32_t secs, msecs; 7187c478bd9Sstevel@tonic-gate int32_t t, junk[5]; /* at_type + at_addr[4] */ 7197c478bd9Sstevel@tonic-gate /* skip type and ip address field */ 7207c478bd9Sstevel@tonic-gate (void) adrm_int32(&adr, (int32_t *)&t, 1); 7217c478bd9Sstevel@tonic-gate (void) adrm_int32(&adr, (int32_t *)&junk[0], t/4); 7227c478bd9Sstevel@tonic-gate /* get time */ 7237c478bd9Sstevel@tonic-gate (void) adrm_int32(&adr, (int32_t *)&secs, 1); 7247c478bd9Sstevel@tonic-gate (void) adrm_int32(&adr, (int32_t *)&msecs, 1); 7257c478bd9Sstevel@tonic-gate tv.tv_sec = (time_t)secs; 7267c478bd9Sstevel@tonic-gate tv.tv_usec = (suseconds_t)msecs; 7277c478bd9Sstevel@tonic-gate } else if (tokenid == AUT_HEADER64) { 7287c478bd9Sstevel@tonic-gate int64_t secs, msecs; 7297c478bd9Sstevel@tonic-gate (void) adrm_int64(&adr, (int64_t *)&secs, 1); 7307c478bd9Sstevel@tonic-gate (void) adrm_int64(&adr, (int64_t *)&msecs, 1); 7317c478bd9Sstevel@tonic-gate #if ((!defined(_LP64)) || defined(_SYSCALL32)) 7327c478bd9Sstevel@tonic-gate if (secs < (time_t)INT32_MIN || 7337c478bd9Sstevel@tonic-gate secs > (time_t)INT32_MAX) 7347c478bd9Sstevel@tonic-gate tv.tv_sec = 0; 7357c478bd9Sstevel@tonic-gate else 7367c478bd9Sstevel@tonic-gate tv.tv_sec = (time_t)secs; 7377c478bd9Sstevel@tonic-gate if (msecs < (suseconds_t)INT32_MIN || 7387c478bd9Sstevel@tonic-gate msecs > (suseconds_t)INT32_MAX) 7397c478bd9Sstevel@tonic-gate tv.tv_usec = 0; 7407c478bd9Sstevel@tonic-gate else 7417c478bd9Sstevel@tonic-gate tv.tv_usec = (suseconds_t)msecs; 7427c478bd9Sstevel@tonic-gate #else 7437c478bd9Sstevel@tonic-gate tv.tv_sec = (time_t)secs; 7447c478bd9Sstevel@tonic-gate tv.tv_usec = (suseconds_t)msecs; 7457c478bd9Sstevel@tonic-gate #endif 7467c478bd9Sstevel@tonic-gate } else if (tokenid == AUT_HEADER64_EX) { 7477c478bd9Sstevel@tonic-gate int64_t secs, msecs; 7487c478bd9Sstevel@tonic-gate int32_t t, junk[4]; /* at_type + at_addr[4] */ 7497c478bd9Sstevel@tonic-gate /* skip type and ip address field */ 7507c478bd9Sstevel@tonic-gate (void) adrm_int32(&adr, (int32_t *)&t, 1); 7517c478bd9Sstevel@tonic-gate (void) adrm_int32(&adr, (int32_t *)&junk[0], t/4); 7527c478bd9Sstevel@tonic-gate /* get time */ 7537c478bd9Sstevel@tonic-gate (void) adrm_int64(&adr, (int64_t *)&secs, 1); 7547c478bd9Sstevel@tonic-gate (void) adrm_int64(&adr, (int64_t *)&msecs, 1); 7557c478bd9Sstevel@tonic-gate #if ((!defined(_LP64)) || defined(_SYSCALL32)) 7567c478bd9Sstevel@tonic-gate if (secs < (time_t)INT32_MIN || 7577c478bd9Sstevel@tonic-gate secs > (time_t)INT32_MAX) 7587c478bd9Sstevel@tonic-gate tv.tv_sec = 0; 7597c478bd9Sstevel@tonic-gate else 7607c478bd9Sstevel@tonic-gate tv.tv_sec = (time_t)secs; 7617c478bd9Sstevel@tonic-gate if (msecs < (suseconds_t)INT32_MIN || 7627c478bd9Sstevel@tonic-gate msecs > (suseconds_t)INT32_MAX) 7637c478bd9Sstevel@tonic-gate tv.tv_usec = 0; 7647c478bd9Sstevel@tonic-gate else 7657c478bd9Sstevel@tonic-gate tv.tv_usec = (suseconds_t)msecs; 7667c478bd9Sstevel@tonic-gate #else 7677c478bd9Sstevel@tonic-gate tv.tv_sec = (time_t)secs; 7687c478bd9Sstevel@tonic-gate tv.tv_usec = (suseconds_t)msecs; 7697c478bd9Sstevel@tonic-gate #endif 7707c478bd9Sstevel@tonic-gate } 7717c478bd9Sstevel@tonic-gate pcb->pcb_otime = pcb->pcb_time; 7727c478bd9Sstevel@tonic-gate if (!f_all) { 7737c478bd9Sstevel@tonic-gate if (m_after > tv.tv_sec) 7747c478bd9Sstevel@tonic-gate return (-1); 7757c478bd9Sstevel@tonic-gate if (m_before <= tv.tv_sec) 7767c478bd9Sstevel@tonic-gate return (-1); 7777c478bd9Sstevel@tonic-gate } 7787c478bd9Sstevel@tonic-gate 7797c478bd9Sstevel@tonic-gate /* if no selection flags were passed, select everything */ 7807c478bd9Sstevel@tonic-gate if (!flags) 7817c478bd9Sstevel@tonic-gate return (0); 7827c478bd9Sstevel@tonic-gate 7837c478bd9Sstevel@tonic-gate /* 7847c478bd9Sstevel@tonic-gate * If all information can be found in header, 7857c478bd9Sstevel@tonic-gate * there is no need to continue processing the tokens. 7867c478bd9Sstevel@tonic-gate */ 7877c478bd9Sstevel@tonic-gate if (flags == checkflags) 7887c478bd9Sstevel@tonic-gate return (0); 7897c478bd9Sstevel@tonic-gate 7907c478bd9Sstevel@tonic-gate /* 7917c478bd9Sstevel@tonic-gate * Process tokens until we hit the end of the record 7927c478bd9Sstevel@tonic-gate */ 7937c478bd9Sstevel@tonic-gate while ((uint_t)(adr.adr_now - adr.adr_stream) < bytes) { 7947c478bd9Sstevel@tonic-gate adrm_char(&adr, &tokenid, 1); 7957c478bd9Sstevel@tonic-gate rc = token_processing(&adr, tokenid); 7967c478bd9Sstevel@tonic-gate 7977c478bd9Sstevel@tonic-gate /* Any Problems? */ 7987c478bd9Sstevel@tonic-gate if (rc == -2) { 7997c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 8007c478bd9Sstevel@tonic-gate gettext("auditreduce: bad token %u, terminating " 8017c478bd9Sstevel@tonic-gate "file %s\n"), tokenid, (pcb->pcb_cur)->fcb_file); 8027c478bd9Sstevel@tonic-gate return (-2); 8037c478bd9Sstevel@tonic-gate } 8047c478bd9Sstevel@tonic-gate 8057c478bd9Sstevel@tonic-gate /* Are we finished? */ 8067c478bd9Sstevel@tonic-gate if (flags == checkflags) 8077c478bd9Sstevel@tonic-gate return (0); 8087c478bd9Sstevel@tonic-gate } 8097c478bd9Sstevel@tonic-gate 8107c478bd9Sstevel@tonic-gate /* 8117c478bd9Sstevel@tonic-gate * So, we haven't seen all that we need to see. Reject record. 8127c478bd9Sstevel@tonic-gate */ 8137c478bd9Sstevel@tonic-gate 8147c478bd9Sstevel@tonic-gate return (-1); 8157c478bd9Sstevel@tonic-gate } 8167c478bd9Sstevel@tonic-gate 8177c478bd9Sstevel@tonic-gate 8187c478bd9Sstevel@tonic-gate /* 8197c478bd9Sstevel@tonic-gate * .func check_order - Check temporal sequence. 8207c478bd9Sstevel@tonic-gate * .call check_order(pcb). 8217c478bd9Sstevel@tonic-gate * .arg pcb - ptr to audit_pcb_t. 8227c478bd9Sstevel@tonic-gate * .desc Check to see if the records are out of temporal sequence, ie, 8237c478bd9Sstevel@tonic-gate * a record has a time stamp older than its predecessor. 8247c478bd9Sstevel@tonic-gate * Also check to see if the current record is within the bounds of 8257c478bd9Sstevel@tonic-gate * the file itself. 8267c478bd9Sstevel@tonic-gate * This routine prints a diagnostic message, unless the QUIET 8277c478bd9Sstevel@tonic-gate * option was selected. 8287c478bd9Sstevel@tonic-gate * .call check_order(pcb). 8297c478bd9Sstevel@tonic-gate * .arg pcb - ptr to pcb holding the records. 8307c478bd9Sstevel@tonic-gate * .ret void. 8317c478bd9Sstevel@tonic-gate */ 8327c478bd9Sstevel@tonic-gate static void 8337c478bd9Sstevel@tonic-gate check_order(pcb) 8347c478bd9Sstevel@tonic-gate register audit_pcb_t *pcb; 8357c478bd9Sstevel@tonic-gate { 8367c478bd9Sstevel@tonic-gate char cptr1[28], cptr2[28]; /* for error reporting */ 8377c478bd9Sstevel@tonic-gate 8387c478bd9Sstevel@tonic-gate /* 8397c478bd9Sstevel@tonic-gate * If the record-past is not the oldest then say so. 8407c478bd9Sstevel@tonic-gate */ 8417c478bd9Sstevel@tonic-gate if (pcb->pcb_otime > pcb->pcb_time) { 8427c478bd9Sstevel@tonic-gate if (!f_quiet) { 8437c478bd9Sstevel@tonic-gate (void) memcpy((void *)cptr1, 8447c478bd9Sstevel@tonic-gate (void *)ctime(&pcb->pcb_otime), 26); 8457c478bd9Sstevel@tonic-gate cptr1[24] = ' '; 8467c478bd9Sstevel@tonic-gate (void) memcpy((void *)cptr2, 8477c478bd9Sstevel@tonic-gate (void *)ctime(&pcb->pcb_time), 26); 8487c478bd9Sstevel@tonic-gate cptr2[24] = ' '; 8497c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 8507c478bd9Sstevel@tonic-gate gettext("%s %s had records out of order: %s was followed by %s.\n"), 8517c478bd9Sstevel@tonic-gate ar, (pcb->pcb_cur)->fcb_file, cptr1, cptr2); 8527c478bd9Sstevel@tonic-gate } 8537c478bd9Sstevel@tonic-gate } 8547c478bd9Sstevel@tonic-gate } 8557c478bd9Sstevel@tonic-gate 8567c478bd9Sstevel@tonic-gate 8577c478bd9Sstevel@tonic-gate /* 8587c478bd9Sstevel@tonic-gate * .func check_header. 8597c478bd9Sstevel@tonic-gate * .desc Read in and check the header for an audit file. 8607c478bd9Sstevel@tonic-gate * The header must read-in properly and have the magic #. 8617c478bd9Sstevel@tonic-gate * .call err = check_header(fp). 8627c478bd9Sstevel@tonic-gate * .arg fp - file stream. 8637c478bd9Sstevel@tonic-gate * .ret 0 no problems. 8647c478bd9Sstevel@tonic-gate * .ret -1 problems. 8657c478bd9Sstevel@tonic-gate */ 8667c478bd9Sstevel@tonic-gate static int 8677c478bd9Sstevel@tonic-gate check_header(fp, fn) 8687c478bd9Sstevel@tonic-gate FILE *fp; 8697c478bd9Sstevel@tonic-gate char *fn; 8707c478bd9Sstevel@tonic-gate { 8717c478bd9Sstevel@tonic-gate char id; 8727c478bd9Sstevel@tonic-gate char *fname; 8737c478bd9Sstevel@tonic-gate short pathlength; 8747c478bd9Sstevel@tonic-gate adr_t adr; 8757c478bd9Sstevel@tonic-gate adrf_t adrf; 8767c478bd9Sstevel@tonic-gate 8777c478bd9Sstevel@tonic-gate adrf_start(&adrf, &adr, fp); 8787c478bd9Sstevel@tonic-gate 8797c478bd9Sstevel@tonic-gate if (adrf_char(&adrf, &id, 1)) { 8807c478bd9Sstevel@tonic-gate (void) sprintf(errbuf, gettext("%s is empty"), fn); 8817c478bd9Sstevel@tonic-gate error_str = errbuf; 8827c478bd9Sstevel@tonic-gate return (-1); 8837c478bd9Sstevel@tonic-gate } 8847c478bd9Sstevel@tonic-gate if (!(id == AUT_OTHER_FILE32 || id == AUT_OTHER_FILE64)) { 8857c478bd9Sstevel@tonic-gate (void) sprintf(errbuf, gettext("%s not an audit file "), fn); 8867c478bd9Sstevel@tonic-gate error_str = errbuf; 8877c478bd9Sstevel@tonic-gate return (-1); 8887c478bd9Sstevel@tonic-gate } 8897c478bd9Sstevel@tonic-gate 8907c478bd9Sstevel@tonic-gate if (id == AUT_OTHER_FILE32) { 8917c478bd9Sstevel@tonic-gate int32_t secs, msecs; 8927c478bd9Sstevel@tonic-gate (void) adrf_int32(&adrf, (int32_t *)&secs, 1); 8937c478bd9Sstevel@tonic-gate (void) adrf_int32(&adrf, (int32_t *)&msecs, 1); 8947c478bd9Sstevel@tonic-gate } else { 8957c478bd9Sstevel@tonic-gate int64_t secs, msecs; 8967c478bd9Sstevel@tonic-gate (void) adrf_int64(&adrf, (int64_t *)&secs, 1); 8977c478bd9Sstevel@tonic-gate (void) adrf_int64(&adrf, (int64_t *)&msecs, 1); 8987c478bd9Sstevel@tonic-gate #if ((!defined(_LP64)) || defined(_SYSCALL32)) 8997c478bd9Sstevel@tonic-gate if (secs < (time_t)INT32_MIN || 9007c478bd9Sstevel@tonic-gate secs > (time_t)INT32_MAX) { 9017c478bd9Sstevel@tonic-gate error_str = gettext("bad time stamp in file header"); 9027c478bd9Sstevel@tonic-gate return (-1); 9037c478bd9Sstevel@tonic-gate } 9047c478bd9Sstevel@tonic-gate if (msecs < (suseconds_t)INT32_MIN || 9057c478bd9Sstevel@tonic-gate msecs > (suseconds_t)INT32_MAX) { 9067c478bd9Sstevel@tonic-gate error_str = gettext("bad time stamp in file header"); 9077c478bd9Sstevel@tonic-gate return (-1); 9087c478bd9Sstevel@tonic-gate } 9097c478bd9Sstevel@tonic-gate #endif 9107c478bd9Sstevel@tonic-gate } 9117c478bd9Sstevel@tonic-gate 9127c478bd9Sstevel@tonic-gate if (adrf_short(&adrf, &pathlength, 1)) { 9137c478bd9Sstevel@tonic-gate error_str = gettext("incomplete file header"); 9147c478bd9Sstevel@tonic-gate return (-1); 9157c478bd9Sstevel@tonic-gate } 9167c478bd9Sstevel@tonic-gate 9177c478bd9Sstevel@tonic-gate if (pathlength != 0) { 9187c478bd9Sstevel@tonic-gate fname = (char *)a_calloc(1, (size_t)pathlength); 9197c478bd9Sstevel@tonic-gate if ((fread(fname, sizeof (char), pathlength, fp)) != 9207c478bd9Sstevel@tonic-gate pathlength) { 9217c478bd9Sstevel@tonic-gate (void) sprintf(errbuf, 9227c478bd9Sstevel@tonic-gate gettext("error in header/filename read in %s"), 9237c478bd9Sstevel@tonic-gate fn); 9247c478bd9Sstevel@tonic-gate error_str = errbuf; 9257c478bd9Sstevel@tonic-gate return (-1); 9267c478bd9Sstevel@tonic-gate } 9277c478bd9Sstevel@tonic-gate free(fname); 9287c478bd9Sstevel@tonic-gate } 9297c478bd9Sstevel@tonic-gate return (0); 9307c478bd9Sstevel@tonic-gate } 9317c478bd9Sstevel@tonic-gate 9327c478bd9Sstevel@tonic-gate 9337c478bd9Sstevel@tonic-gate /* 9347c478bd9Sstevel@tonic-gate * .func get_record - get a single record. 9357c478bd9Sstevel@tonic-gate * .desc Read a single record from stream fp. If the record to be read 9367c478bd9Sstevel@tonic-gate * is larger than the buffer given to hold it (as determined by 9377c478bd9Sstevel@tonic-gate * cur_size) then free that buffer and allocate a new and bigger 9387c478bd9Sstevel@tonic-gate * one, making sure to store its size. 9397c478bd9Sstevel@tonic-gate * .call ret = get_record(fp, buf, cur_size, flags). 9407c478bd9Sstevel@tonic-gate * .arg fp - stream to read from. 9417c478bd9Sstevel@tonic-gate * .arg buf - ptr to ptr to buffer to place record in. 9427c478bd9Sstevel@tonic-gate * .arg cur_size- ptr to the size of the buffer that *buf points to. 9437c478bd9Sstevel@tonic-gate * .arg flags - flags from fcb (to get FF_NOTTERM). 9447c478bd9Sstevel@tonic-gate * .ret +number - number of chars in the record. 9457c478bd9Sstevel@tonic-gate * .ret 0 - trailer seen - file done. 9467c478bd9Sstevel@tonic-gate * .ret -1 - read error (error_str know what type). 9477c478bd9Sstevel@tonic-gate */ 9487c478bd9Sstevel@tonic-gate static int 9497c478bd9Sstevel@tonic-gate get_record(fp, buf, fn) 9507c478bd9Sstevel@tonic-gate FILE *fp; 9517c478bd9Sstevel@tonic-gate char **buf; 9527c478bd9Sstevel@tonic-gate char *fn; 9537c478bd9Sstevel@tonic-gate { 9547c478bd9Sstevel@tonic-gate adr_t adr; 9557c478bd9Sstevel@tonic-gate adrf_t adrf; 9567c478bd9Sstevel@tonic-gate int leadin; 9577c478bd9Sstevel@tonic-gate char id; 9587c478bd9Sstevel@tonic-gate int lsize; 9597c478bd9Sstevel@tonic-gate short ssize; 9607c478bd9Sstevel@tonic-gate 9617c478bd9Sstevel@tonic-gate /* 9627c478bd9Sstevel@tonic-gate * Get the token type. It will be either a header or a file 9637c478bd9Sstevel@tonic-gate * token. 9647c478bd9Sstevel@tonic-gate */ 9657c478bd9Sstevel@tonic-gate (void) adrf_start(&adrf, &adr, fp); 9667c478bd9Sstevel@tonic-gate if (adrf_char(&adrf, &id, 1)) { 9677c478bd9Sstevel@tonic-gate (void) sprintf(errbuf, gettext( 9687c478bd9Sstevel@tonic-gate "record expected but not found in %s"), 9697c478bd9Sstevel@tonic-gate fn); 9707c478bd9Sstevel@tonic-gate error_str = errbuf; 9717c478bd9Sstevel@tonic-gate return (-1); 9727c478bd9Sstevel@tonic-gate } 9737c478bd9Sstevel@tonic-gate switch (id) { 9747c478bd9Sstevel@tonic-gate case AUT_HEADER32: 9757c478bd9Sstevel@tonic-gate case AUT_HEADER32_EX: 9767c478bd9Sstevel@tonic-gate case AUT_HEADER64: 9777c478bd9Sstevel@tonic-gate case AUT_HEADER64_EX: 9787c478bd9Sstevel@tonic-gate /* 9797c478bd9Sstevel@tonic-gate * The header token is: 9807c478bd9Sstevel@tonic-gate * attribute id: char 9817c478bd9Sstevel@tonic-gate * byte count: int 9827c478bd9Sstevel@tonic-gate * version #: char 9837c478bd9Sstevel@tonic-gate * event ID: short 9847c478bd9Sstevel@tonic-gate * ID modifier: short 9857c478bd9Sstevel@tonic-gate * IP address type int (_EX only) 9867c478bd9Sstevel@tonic-gate * IP address 1/4*int (_EX only) 9877c478bd9Sstevel@tonic-gate * seconds (date): long 9887c478bd9Sstevel@tonic-gate * time (microsecs): long 9897c478bd9Sstevel@tonic-gate */ 9907c478bd9Sstevel@tonic-gate leadin = sizeof (int32_t) + sizeof (char); 9917c478bd9Sstevel@tonic-gate (void) adrf_int32(&adrf, &lsize, 1); 9927c478bd9Sstevel@tonic-gate *buf = (char *)a_calloc(1, (size_t)(lsize + leadin)); 9937c478bd9Sstevel@tonic-gate adr_start(&adr, *buf); 9947c478bd9Sstevel@tonic-gate adr_char(&adr, &id, 1); 9957c478bd9Sstevel@tonic-gate adr_int32(&adr, (int32_t *)&lsize, 1); 9967c478bd9Sstevel@tonic-gate if (fread(*buf + leadin, sizeof (char), lsize - leadin, fp) != 9977c478bd9Sstevel@tonic-gate lsize - leadin) { 9987c478bd9Sstevel@tonic-gate (void) sprintf(errbuf, 9997c478bd9Sstevel@tonic-gate gettext("header token read failure in %s"), fn); 10007c478bd9Sstevel@tonic-gate error_str = errbuf; 10017c478bd9Sstevel@tonic-gate return (-1); 10027c478bd9Sstevel@tonic-gate } 10037c478bd9Sstevel@tonic-gate return (lsize + leadin); 10047c478bd9Sstevel@tonic-gate case AUT_OTHER_FILE32: { 10057c478bd9Sstevel@tonic-gate int32_t secs, msecs; 10067c478bd9Sstevel@tonic-gate leadin = 2 * sizeof (int32_t) + 10077c478bd9Sstevel@tonic-gate sizeof (short) + sizeof (char); 10087c478bd9Sstevel@tonic-gate (void) adrf_int32(&adrf, (int32_t *)&secs, 1); 10097c478bd9Sstevel@tonic-gate (void) adrf_int32(&adrf, (int32_t *)&msecs, 1); 10107c478bd9Sstevel@tonic-gate (void) adrf_short(&adrf, &ssize, 1); 10117c478bd9Sstevel@tonic-gate *buf = (char *)a_calloc(1, (size_t)(ssize + leadin)); 10127c478bd9Sstevel@tonic-gate adr_start(&adr, *buf); 10137c478bd9Sstevel@tonic-gate adr_char(&adr, &id, 1); 10147c478bd9Sstevel@tonic-gate adr_int32(&adr, (int32_t *)&secs, 1); 10157c478bd9Sstevel@tonic-gate adr_int32(&adr, (int32_t *)&msecs, 1); 10167c478bd9Sstevel@tonic-gate adr_short(&adr, &ssize, 1); 10177c478bd9Sstevel@tonic-gate if (fread(*buf + leadin, sizeof (char), ssize, fp) != ssize) { 10187c478bd9Sstevel@tonic-gate error_str = gettext("file token read failure"); 10197c478bd9Sstevel@tonic-gate return (-1); 10207c478bd9Sstevel@tonic-gate } 10217c478bd9Sstevel@tonic-gate return (0); /* done! */ 10227c478bd9Sstevel@tonic-gate } 10237c478bd9Sstevel@tonic-gate case AUT_OTHER_FILE64: { 10247c478bd9Sstevel@tonic-gate int64_t secs, msecs; 10257c478bd9Sstevel@tonic-gate leadin = 2 * sizeof (int64_t) + 10267c478bd9Sstevel@tonic-gate sizeof (short) + sizeof (char); 10277c478bd9Sstevel@tonic-gate (void) adrf_int64(&adrf, (int64_t *)&secs, 1); 10287c478bd9Sstevel@tonic-gate (void) adrf_int64(&adrf, (int64_t *)&msecs, 1); 10297c478bd9Sstevel@tonic-gate (void) adrf_short(&adrf, &ssize, 1); 10307c478bd9Sstevel@tonic-gate *buf = (char *)a_calloc(1, (size_t)(ssize + leadin)); 10317c478bd9Sstevel@tonic-gate adr_start(&adr, *buf); 10327c478bd9Sstevel@tonic-gate adr_char(&adr, &id, 1); 10337c478bd9Sstevel@tonic-gate adr_int64(&adr, (int64_t *)&secs, 1); 10347c478bd9Sstevel@tonic-gate adr_int64(&adr, (int64_t *)&msecs, 1); 10357c478bd9Sstevel@tonic-gate adr_short(&adr, &ssize, 1); 10367c478bd9Sstevel@tonic-gate if (fread(*buf + leadin, sizeof (char), ssize, fp) != ssize) { 10377c478bd9Sstevel@tonic-gate error_str = gettext("file token read failure"); 10387c478bd9Sstevel@tonic-gate return (-1); 10397c478bd9Sstevel@tonic-gate } 10407c478bd9Sstevel@tonic-gate return (0); /* done! */ 10417c478bd9Sstevel@tonic-gate } 10427c478bd9Sstevel@tonic-gate default: 10437c478bd9Sstevel@tonic-gate break; 10447c478bd9Sstevel@tonic-gate } 10457c478bd9Sstevel@tonic-gate error_str = gettext("record begins without proper token"); 10467c478bd9Sstevel@tonic-gate return (-1); 10477c478bd9Sstevel@tonic-gate } 1048