#!/usr/bin/awk # IBM_PROLOG_BEGIN_TAG # This is an automatically generated prolog. # # # # Licensed Materials - Property of IBM # # (C) COPYRIGHT International Business Machines Corp. 2000,2019 # All Rights Reserved # # US Government Users Restricted Rights - Use, duplication or # disclosure restricted by GSA ADP Schedule Contract with IBM Corp. # # IBM_PROLOG_END_TAG # sccsid = "@(#)66 1.2 src/rsct/ffdc/bin/fcparse.awk, ffdc, rsct_rady, rady2035a 3/9/15 09:58:14" # ============================================================================= # Module Name: fc_parse.awk # # Component: ffdc # # Description: Script for "awk" command to identify selectors within a Syslog # configuration file (ex: /etc/syslog.conf) whose action is to # record only to a file. # # This "awk" script is to be executed after another facility has # preprocessed the Syslog configuration file to remove comments # and to collapse multiple lined entries. Although this script # could handle basic comments, it cannot handle multiple line # entries, nor comments embedded within multiple line entries. # # Usage: sed -f fc_strip.sed | \ # sed -f fc_join.sed | \ # awk -f fc_parse.awk # # Input: Preprocessed Syslog configuration file, with comments removed # and multiple lined entries collapsed into single lines. # # Output: Zero or more lines in the following format: # \t # where: # A 6-digit base-64 encoding that # indicates the facility and the priority # associated with a specific log file # Was obtained from the action field of # the Syslog configuration file entry for # this selector # # Exit Status: Set by "awk" # ============================================================================= # ------------------------- # # Global value declarations # # ------------------------- # BEGIN { # Used for converting upper case charatecters to lower case upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" lower = "abcdefghijklmnopqrstuvwxyz" # Used to convert decimal values to base-64 values base64 = "./0123456789ABCEDFGHIJKLMNOPQRSTUVWXZYabcdefghijklmnopqrstuvwxyz" # Used to convert facilities and priorities # # ------ The list of facilities and priorities MUST match the # | NOTE | c_name values specified in the /usr/include/sys/syslog.h # ------ header arrays facilitynames[] and prioritynames[] prioritylist[1] = "emerg" ; prioritylist[2] = "alert" prioritylist[3] = "crit" ; prioritylist[4] = "err" prioritylist[5] = "warning" ; prioritylist[6] = "notice" prioritylist[7] = "info" ; prioritylist[8] = "debug" prioritylist[9] = "none" oldprilist[1] = "panic" ; oldprilist[4] = "error" oldprilist[5] = "warn" facilitylist[1] = "kern" ; facilitylist[2] = "user" facilitylist[3] = "mail" ; facilitylist[4] = "daemon" facilitylist[5] = "auth" ; facilitylist[6] = "syslog" facilitylist[7] = "lpr" ; facilitylist[8] = "news" facilitylist[9] = "uucp" ; facilitylist[10] = "cron" facilitylist[11] = "authpriv" ; facilitylist[12] = "ftp" facilitylist[13] = "mark" ; facilitylist[14] = "reserved" facilitylist[15] = "reserved" ; facilitylist[16] = "reserved" facilitylist[17] = "local0" ; facilitylist[18] = "local1" facilitylist[19] = "local2" ; facilitylist[20] = "local3" facilitylist[21] = "local4" ; facilitylist[22] = "local5" facilitylist[23] = "local6" ; facilitylist[24] = "local7" oldfaclist[5] = "security" # Maximum number of logfile array elements entrytable[1,1] = "" ; entrytable[21,8] = "" logfiletable[1,1] = "" ; logfiletable[21,8] = "" maxfacilities = 24 ; maxpriorities = 8 } # -------------------------------------- # # Mainline /etc/syslog.conf Parsing Code # # -------------------------------------- # # Process non-comments in /etc/syslog.conf (should have been removed by now) !/^$/ && !/^#/ { # Work on entries sending messages to files only if ( $2 ~ /-?\/+/ ) { # Strip any "no sync" chars from the log file name logfilestart = index($2, "-") if (0 == logfilestart) { newlogfile = $2 } else { logfilestart++ newlogfile = substr($2, logfilestart) } # Construct temporary array containing list of all selectors # (facility and priority pairs) that apply. The selector # field may have more than one selector within it, and some # subsequent selectors may change the actions taken by previos # ones in the same entry (ex: the "none" and "!" markers). for (h = 1 ; h <= maxfacilities ; h++) { for (i = 1 ; i <= maxpriorities ; i++ ) { entrytable[h,i] = "" } } numsels = split($1, selectors, ";") totalsels = numsels for (i = 1 ; i <= numsels ; i++) { # Each individual selector may have multiple facilities # associated with the same priority. numfacs = split(selectors[i], facilities, ",") if (1 == numfacs) { newselector = lower_selector(selectors[i]) expand_and_list(newselector, newlogfile) } else { totalsels += numfacs - 1 prioritystart = index(selectors[i], ".") priority = substr(selectors[i], prioritystart) for (j = 1 ; j < numfacs ; j++) { newselector = facilities[j] priority newselector = \ lower_selector(newselector) expand_and_list(newselector, \ newlogfile) } numfacs = split(facilities[j], lastfac, ".") newselector = lastfac[1] priority newselector = lower_selector(newselector) expand_and_list(newselector, newlogfile) } } # Now that entry has been fully expanded and the selectors # stored, update the global array with the results. for (h = 1 ; h <= maxfacilities ; h++) { for (i = 1 ; i <= maxpriorities ; i++) { if ( entrytable[h,i] !~ /^$/ ) { record_logfile(logfiletable, h, i, \ entrytable[h,i]) } } } #DEBUG printf("Contents of Log File Array after processing %s:\n", \ #DEBUG $2) #DEBUG dump_array(logfiletable, maxfacilities, maxpriorities) } } # ---------------------------------------- # # Print Out the Results of This Processing # # ---------------------------------------- # END { for (h = 1 ; h <= maxfacilities ; h++) { for (i = 1 ; i <= maxpriorities ; i++) { if ( logfiletable[h,i] !~ /^$/ ) { fac64 = convert_to_base64(h) pri64 = convert_to_base64(i) printf("%s%s....\t%s\n", fac64, pri64, \ logfiletable[h,i]) } } } } # ------------------------------------- # # Function to Dump Contents of An Array # # ------------------------------------- # function dump_array (array, rowlimit, columnlimit) { for (a = 1 ; a <= rowlimit ; a++) { for (b = 1 ; b <= columnlimit ; b++) { if ( array[a,b] !~ /^$/ ) { printf("\tElement [%2d,%2d]: \t Value %s\n", \ a,b, array[a,b]) } else { printf("\tElement [%2d,%2d]: \t [ empty ]\n", \ a, b) } } } } # -------------------------------------------------- # # Function to Convert Selector Strings to Lower Case # # -------------------------------------------------- # function lower_selector (selector) { workselector = selector for (k = 1 ; k <= length(workselector) ; k++) { thischar = substr(selector, k, 1) if (character = index(upper, thischar)) { workselector = substr(workselector, 1, k-1) \ substr(lower, character, 1) \ substr(selector, k+1) } } return workselector } # ----------------------------------------------- # # Function to Locate Selector Name Numeric Values # # ----------------------------------------------- # function get_index (which, codename) { if ("facility" == which) { if (codename == oldfaclist[5]) { return 5 } for (m = 1 ; m <= 21 ; m++) { if (codename == facilitylist[m]) { return m } } } else { for (m = 1 ; m <= 9 ; m++) { if (codename == prioritylist[m]) { return m } } for (m = 1 ; m <= 5 ; m++) { if (codename == oldprilist[m]) { return m } } } return 0 } # -------------------------------------------------------------- # # Function to Store All Identified Selectors and Their Log Files # # -------------------------------------------------------------- # function record_logfile (tableparam, rowindex, columnindex, lfile) { #DEBUG if ( tableparam[rowindex,columnindex] !~ /^$/ ) { #DEBUG printf("\t Overwriting value %s w/ %s at element [%d,%d]\n", \ #DEBUG tableparam[selectorsindex], lfile, \ #DEBUG rowindex, columnindex) #DEBUG } tableparam[rowindex, columnindex] = lfile } # ------------------------------------------------------------ # # Function to Identify All Priorities Affected By the Selector # # ------------------------------------------------------------ # function expand_priority (selectorcode, facilityindex, lfile) { # Obtain priority value from the provided selector selectnum = split(selectorcode, selectcomps, ".") # Find what range of priorities are impacted: all (*), just one (=), # or the normal function of "everything up to..." usefile = lfile if ( selectcomps[2] ~ /^\*/ ) { ylow = 1 yhigh = 8 } else { if ("none" == selectcomps[2]) { ylow = 1 yhigh = 8 usefile = "" } else { onlyone = 0 while (1) { if ( selectcomps[2] ~ /^!/ ) { usefile = "" selectcomps[2] = substr(selectcomps[2],\ 2) continue } if ( selectcomps[2] ~ /^=/ ) { onlyone = 1 selectcomps[2] = substr(selectcomps[2],\ 2) continue } break } yhigh = get_index("priority", selectcomps[2]) if (onlyone) { ylow = yhigh } else { ylow = 1 } } } # Expand the selector into its full list and process it for (y = ylow ; y <= yhigh ; y++) { expandedsel = selectcomps[1] "." prioritylist[y] #DEBUG printf("\t expanded to %s [ code %d, %d ] - file %s\n", \ #DEBUG expandedsel, facilityindex, y, usefile) # Record this selector's log file in the global array record_logfile(entrytable, facilityindex, y, usefile) } } # ------------------------------------------------------------ # # Function to Identify All Facilities Affected By the Selector # # ------------------------------------------------------------ # function expand_and_list (selectcde, lfile) { # Obtain facility value from the provided selector selectno = split(selectcde, selectcmps, ".") # Find out if all facilities or only one are affected, expand the # facility if necessary, and process it if ( selectcmps[1] ~ /^\*/ ) { xlow = 1 xhigh = 21 } else { xlow = get_index("facility", selectcmps[1]) xhigh = xlow } for (x = xlow ; x <= xhigh ; x++ ) { expselector = facilitylist[x] "." selectcmps[2] #DEBUG printf("%s expanded to %s, log file %s\n", selectcde, \ #DEBUG expselector, lfile) expand_priority(expselector, x, lfile) } } #----------------------------------------------------------# # Function to Convert Decimal Values Into Base-64 Notation # # !! NOTE !! Assumes decimal values are 0 >= x >= 63 # #----------------------------------------------------------# function convert_to_base64 (decimalval) { counterpart = substr(base64, decimalval, 1) return counterpart }