/* ** Copyright (C) 2001-2007 by Carnegie Mellon University. ** ** @OPENSOURCE_HEADER_START@ ** ** Use of the SILK system and related source code is subject to the terms ** of the following licenses: ** ** GNU Public License (GPL) Rights pursuant to Version 2, June 1991 ** Government Purpose License Rights (GPLR) pursuant to DFARS 252.225-7013 ** ** NO WARRANTY ** ** ANY INFORMATION, MATERIALS, SERVICES, INTELLECTUAL PROPERTY OR OTHER ** PROPERTY OR RIGHTS GRANTED OR PROVIDED BY CARNEGIE MELLON UNIVERSITY ** PURSUANT TO THIS LICENSE (HEREINAFTER THE "DELIVERABLES") ARE ON AN ** "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY ** KIND, EITHER EXPRESS OR IMPLIED AS TO ANY MATTER INCLUDING, BUT NOT ** LIMITED TO, WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE, ** MERCHANTABILITY, INFORMATIONAL CONTENT, NONINFRINGEMENT, OR ERROR-FREE ** OPERATION. CARNEGIE MELLON UNIVERSITY SHALL NOT BE LIABLE FOR INDIRECT, ** SPECIAL OR CONSEQUENTIAL DAMAGES, SUCH AS LOSS OF PROFITS OR INABILITY ** TO USE SAID INTELLECTUAL PROPERTY, UNDER THIS LICENSE, REGARDLESS OF ** WHETHER SUCH PARTY WAS AWARE OF THE POSSIBILITY OF SUCH DAMAGES. ** LICENSEE AGREES THAT IT WILL NOT MAKE ANY WARRANTY ON BEHALF OF ** CARNEGIE MELLON UNIVERSITY, EXPRESS OR IMPLIED, TO ANY PERSON ** CONCERNING THE APPLICATION OF OR THE RESULTS TO BE OBTAINED WITH THE ** DELIVERABLES UNDER THIS LICENSE. ** ** Licensee hereby agrees to defend, indemnify, and hold harmless Carnegie ** Mellon University, its trustees, officers, employees, and agents from ** all claims or demands made against them (and any related losses, ** expenses, or attorney's fees) arising out of, or relating to Licensee's ** and/or its sub licensees' negligent use or willful misuse of or ** negligent conduct or willful misconduct regarding the Software, ** facilities, or other rights or assistance granted by Carnegie Mellon ** University under this License, including, but not limited to, any ** claims of product liability, personal injury, death, damage to ** property, or violation of any laws or regulations. ** ** Carnegie Mellon University Software Engineering Institute authored ** documents are sponsored by the U.S. Department of Defense under ** Contract F19628-00-C-0003. Carnegie Mellon University retains ** copyrights in all material produced under this contract. The U.S. ** Government retains a non-exclusive, royalty-free license to publish or ** reproduce these documents, or allow others to do so, for U.S. ** Government purposes only pursuant to the copyright license under the ** contract clause at 252.227.7013. ** ** @OPENSOURCE_HEADER_END@ */ /* ** rwcut.c ** ** cut fields/records from the given input file(s) using field ** specifications from here, record filter specifications from ** module libfilter ** ** 1/15/2002 ** ** Suresh L. Konda ** */ #include "silk.h" RCSIDENT("$SiLK: rwcut.c 8269 2007-08-03 18:54:48Z mthomas $"); #include "rwcut.h" /* TYPEDEFS AND MACROS */ /* Where to write filenames if --print-file specified */ #define PRINT_FILENAMES_FH stderr /* EXPORTED VARIABLES */ /* The output stream: where to print the records */ FILE *stream_out; /* rw-file that is currently been read */ rwIOStruct_t *rwIOS; /* interface to the iochecks library */ iochecksInfoStruct_t *ioISP; /* global and file limits and counters */ countersStruct globalCounters; static countersStruct fileCounters; /* user's options */ cut_opt_flags_t cut_opts; /* delimiter between columns */ char delimiter; /* available fields */ sk_stringmap_t *field_map; /* Array of out_stream_t* */ out_stream_t **outputs; /* Count of 'outputs' */ size_t output_count; /* List of dynamic libraries to attempt to open at startup */ const char *app_dynlib_names[] = { "libaddrtype.so", "libccfilter.so", "libpmapfilter.so", NULL /* sentinel */ }; /* Dynamic libraries we actually opened */ app_dynlib_t app_dynlib_list[APP_MAX_DYNLIBS]; /* Number of dynamic libraries actually opened */ int app_dynlib_count; /* LOCAL VARIABLES */ /* global scratch space; contains text to be printed; functions return * a pointer to this space. */ static char pText[RWCUT_MAX_COLUMN_WIDTH]; /* LOCAL FUNCTION DECLARATIONS */ static void setCounters(void); static void dumprec(rwRec *rwrec); static void cutFile(const char *inFName); /* FUNCTION DEFINITIONS */ /* * setCounters: * set fileCounters.numRecs and fileCounters.firstRec based * on user options. * Input: * None. * Output: * None. * Side Effects: * fileCounters.numRecs and fileCounters.firstRec, are set * based globalCounter values. */ static void setCounters(void) { int i; #ifdef FROM_EOF_POSSIBLE /* check if from eof */ if (cut_opts.fromEOF) { fileCounters.firstRec = rwGetRecCount(rwIOS) - rwGetRejectCount(rwIOS) - globalCounters.numRecs; fileCounters.numRecs = globalCounters.numRecs; return; } #endif /* figure out what to dump */ fileCounters.numRecs = globalCounters.numRecs; fileCounters.firstRec = globalCounters.firstRec; if (fileCounters.firstRec) { fileCounters.firstRec--; } if (fileCounters.firstRec) { if (globalCounters.lastRec) { i = globalCounters.lastRec - fileCounters.firstRec; if ( i < 0) { /* bad request. adjust */ fileCounters.numRecs = 0; } else { fileCounters.numRecs = i; } } } else if (globalCounters.lastRec) { /* start not given but end is. */ i = globalCounters.lastRec - fileCounters.numRecs; if (i < 0) { /* more requested than available. Reduce fileCounters.numRecs */ fileCounters.numRecs = globalCounters.lastRec; fileCounters.firstRec = 0; } else { fileCounters.firstRec = i; } } if (fileCounters.numRecs < 1) { skAppPrintErr("requested < 1 records"); exit(EXIT_FAILURE); } return; } /* * writeColTitles: * write out the required column titles. * Input: None * Output: printed col titles * NOTE: this must be idempotent. */ void writeColTitles(void) { static uint8_t wroteColTitles = 0; out_stream_t *ostream; size_t i; /* have we been here before? */ if (wroteColTitles) { return; } wroteColTitles = 1; /* don't do anything when no titles are requested */ if (cut_opts.no_titles) { return; } for (i = 0; i < output_count; ++i) { ostream = outputs[i]; /* use the Ascii Stream if it is non-null */ if (ostream->a_stream) { rwAsciiPrintTitles(ostream->a_stream); } else { /* use the plug-in */ assert(ostream->cutf_wrap.field_width <= (int)sizeof(pText)); ostream->cutf_wrap.cut_fxn(ostream->cutf_wrap.field_id, pText, ostream->cutf_wrap.field_width, NULL); if (cut_opts.no_columns) { fprintf(stream_out, "%s%c", pText, delimiter); } else { fprintf(stream_out, "%*s%c", ostream->cutf_wrap.field_width-1, pText, delimiter); } } } fprintf(stream_out, "\n"); } /* * dumprec: * dump the information the global rwrec according the user * options. * Basically, each desired field is dumped into the global pText * which is pointed to by cp. All called functions must dump * their information into pRec. Then pRec is printed out based * Input: None * Output: None * Side Effects: printed record to stream_out. * pText keeps getting filled etc. */ void dumprec(rwRec *rwrec) { out_stream_t *ostream; size_t i; for (i = 0; i < output_count; ++i) { ostream = outputs[i]; /* use the Ascii Stream if it is non-NULL */ if (ostream->a_stream) { rwAsciiPrintRec(ostream->a_stream, rwrec); } else { ostream->cutf_wrap.cut_fxn(ostream->cutf_wrap.field_id, pText, ostream->cutf_wrap.field_width, rwrec); if (cut_opts.no_columns) { fprintf(stream_out, "%s%c", pText, delimiter); } else { fprintf(stream_out, "%*s%c", ostream->cutf_wrap.field_width-1, pText, delimiter); } } } fprintf(stream_out, "\n"); } /* * cutFile(path); * * Open 'path' and read and print its records. Exits on error. */ static void cutFile(const char *inFName) { rwRec rwrec; rwIOS = rwOpenFile(inFName, ioISP->inputCopyFD); if (rwIOS == NULL) { skAppPrintErr("unable to open %s", inFName); exit(EXIT_FAILURE); } if (cut_opts.printFileName) { fprintf(PRINT_FILENAMES_FH, "%s\n", rwGetFileName(rwIOS)); } /* set the global and file-level counters */ setCounters(); if (fileCounters.numRecs > 0) { writeColTitles(); if (fileCounters.firstRec) { if (rwSkip(rwIOS, fileCounters.firstRec)) { appTeardown(); exit(EXIT_FAILURE); } } while (fileCounters.numRecs-- && rwRead(rwIOS, &rwrec)) { dumprec(&rwrec); } } rwCloseFile(rwIOS); rwIOS = (rwIOStruct_t*)NULL; } int main(int argc, char **argv) { int counter; appSetup(argc, argv); /* never returns on error */ /* Process the files from command line or stdin */ for(counter = ioISP->firstFile; counter < ioISP->fileCount ; counter++) { cutFile(ioISP->fnArray[counter]); } /* done */ appTeardown(); return 0; } /* ** Local Variables: ** mode:c ** indent-tabs-mode:nil ** c-basic-offset:4 ** End: */