/* ** Copyright (C) 2003-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@ */ /* * rwswapbytes * * Read any rw file (rwpacked file, rwfilter output, etc) and output a * file in the specified byte order. * */ #include "silk.h" RCSIDENT("$SiLK: rwswapbytes.c 8844 2007-09-06 17:38:29Z mthomas $"); #include "rwpack.h" #include "sksite.h" #include "utils.h" /* MACROS AND TYPEDEFS */ /* File handle for --help output */ #define USAGE_FH stdout typedef enum _rwswapOptions { RWSW_BIG = 128, RWSW_LITTLE, RWSW_NATIVE, RWSW_SWAP, RWSW_COPY } rwswapOptions_t; /* LOCAL FUNCTIONS */ static void appUsageLong(void); /* never returns */ static void appTeardown(void); static void appSetup(int argc, char **argv); /* never returns on failure */ static int appOptionsHandler(clientData, int, const char *); /* LOCAL VARIABLES */ static rwswapOptions_t outEndian; static const char *inFName; static const char *outFName; /* OPTIONS */ static struct option appOptions[] = { {"big-endian", NO_ARG, 0, RWSW_BIG}, {"little-endian", NO_ARG, 0, RWSW_LITTLE}, {"native-endian", NO_ARG, 0, RWSW_NATIVE}, {"swap-endian", NO_ARG, 0, RWSW_SWAP}, {0,0,0,0} /* sentinel entry */ }; static char *appHelp[] = { /* add help strings here for the applications options */ "write output in big-endian format", "write output in little-endian format", "write output in this machine's native format", "unconditionally swap the byte-order of the input", (char *)NULL }; /* FUNCTION DEFINITIONS */ /* * appUsageLong(); * * Print complete usage information to USAGE_FH. Pass this * function to skOptionsSetUsageCallback(); optionsParse() will * call this funciton and then exit the program when the --help * option is given. */ static void appUsageLong(void) { #define USAGE_MSG \ ("[SWITCHES] \n" \ "\tChange the byte-order of as specified\n" \ "\tby and write result to .\n" \ "\tYou may use \"stdin\" for and \"stdout\"\n" \ "\tfor . Gzipped files are o.k.\n") FILE *fh = USAGE_FH; int i; fprintf(fh, "%s %s", skAppName(), USAGE_MSG); fprintf(fh, "\nSWITCHES:\n"); skOptionsDefaultUsage(fh); fprintf(fh, "\nENDIAN_SWITCH:\n"); for (i = 0; appOptions[i].name; i++ ) { fprintf(fh, "--%s: %s\n", appOptions[i].name, appHelp[i]); } } /* * appTeardown() * * Teardown all modules, close all files, and tidy up all * application state. * * This function is idempotent. */ static void appTeardown(void) { static int teardownFlag = 0; if (teardownFlag) { return; } teardownFlag = 1; skAppUnregister(); } /* * appSetup(argc, argv); * * Perform all the setup for this application include setting up * required modules, parsing options, etc. This function should be * passed the same arguments that were passed into main(). * * Returns to the caller if all setup succeeds. If anything fails, * this function will cause the application to exit with a FAILURE * exit status. */ static void appSetup(int argc, char **argv) { int arg_index; /* register the application */ skAppRegister(argv[0]); skOptionsSetUsageCallback(&appUsageLong); /* verify same number of options and help strings */ assert((sizeof(appHelp)/sizeof(char *)) == (sizeof(appOptions)/sizeof(struct option))); /* register the options */ if (optionsRegister(appOptions, (optHandler)appOptionsHandler, NULL)) { skAppPrintErr("unable to register options"); exit(EXIT_FAILURE); } /* parse options */ arg_index = optionsParse(argc, argv); if (arg_index < 0) { skAppUsage(); /* never returns */ } /* try to load site config file; if it fails, we will not be able * to resolve flowtype and sensor from input file names */ sksiteConfigure(0); /* Check that a swapping option was given */ if (0 == outEndian) { skAppPrintErr("You must specify the output byte order."); skAppUsage(); } /* Check that we have input */ if (arg_index >= argc) { skAppPrintErr("Expecting input file name"); skAppUsage(); /* never returns */ } inFName = argv[arg_index]; ++arg_index; /* check that we have an output location */ if (arg_index >= argc) { skAppPrintErr("Expecting output file name"); skAppUsage(); /* never returns */ } outFName = argv[arg_index]; ++arg_index; /* check for extra options */ if (argc != arg_index) { skAppPrintErr("Got extra options"); skAppUsage(); /* never returns */ } if (atexit(appTeardown) < 0) { skAppPrintErr("unable to register appTeardown() with atexit()"); appTeardown(); exit(EXIT_FAILURE); } return; /* OK */ } /* * status = appOptionsHandler(cData, opt_index, opt_arg); * * This function is passed to optionsRegister(); it will be called * by optionsParse() for each user-specified switch that the * application has registered; it should handle the switch as * required---typically by setting global variables---and return 1 * if the switch processing failed or 0 if it succeeded. Returning * a non-zero from from the handler causes optionsParse() to return * a negative value. * * The clientData in 'cData' is typically ignored; 'opt_index' is * the index number that was specified as the last value for each * struct option in appOptions[]; 'opt_arg' is the user's argument * to the switch for options that have a REQUIRED_ARG or an * OPTIONAL_ARG. */ static int appOptionsHandler( clientData UNUSED(cData), int opt_index, const char UNUSED(*opt_arg)) { switch (opt_index) { #if !IS_LITTLE_ENDIAN case RWSW_NATIVE: #endif case RWSW_BIG: if ((0 != outEndian) && (RWSW_BIG != outEndian)) { skAppPrintErr("conflicting endian options given"); return 1; } outEndian = RWSW_BIG; break; #if IS_LITTLE_ENDIAN case RWSW_NATIVE: #endif case RWSW_LITTLE: if ((0 != outEndian) && (RWSW_LITTLE != outEndian)) { skAppPrintErr("conflicting endian options given"); return 1; } outEndian = RWSW_LITTLE; break; case RWSW_SWAP: if ((0 != outEndian) && (RWSW_SWAP != outEndian)) { skAppPrintErr("conflicting endian options given"); return 1; } outEndian = RWSW_SWAP; break; default: skAppPrintErr("Unhandled option %d in options handler at %s:%d", opt_index, __FILE__, __LINE__); abort(); } return 0; /* OK */ } /* * is_ok = rwswap_file(input_file, output_file); * * Byte swap the file named 'input_file' and write it to * 'output_file' using the 'out_endian' to determine the byte-order * of 'output_file'. */ static int rwswap_file( const char *input_file, const char *output_file, rwswapOptions_t out_endian) { silk_endian_t byte_order; rwIOStruct_t *input_ios; rwIOStruct_t *output_ios; rwRec rwrec; int rv = 0; input_ios = rwOpenFile(input_file, NULL); if (!input_ios) { return 1; } switch (out_endian) { case RWSW_BIG: byte_order = SILK_ENDIAN_BIG; break; case RWSW_LITTLE: byte_order = SILK_ENDIAN_LITTLE; break; case RWSW_NATIVE: byte_order = SILK_ENDIAN_NATIVE; break; case RWSW_SWAP: if (rwGetIsBigEndian(input_ios)) { byte_order = SILK_ENDIAN_LITTLE; } else { byte_order = SILK_ENDIAN_BIG; } break; default: skAppPrintErr("Case %d not handled in byte-order handler at %s:%d", out_endian, __FILE__, __LINE__); abort(); } /* Open the output file and copy the headers from the source file, * but modify the byte order */ if ((rv = rwioCreate(&output_ios, output_file, SK_RWIO_WRITE)) || (rv = rwioSetHeaderFromFile(output_ios, input_ios)) || (rv = rwioSetFileByteorder(output_ios, byte_order)) || (rv = rwioOpen(output_ios)) || (rv = rwioWriteHeader(output_ios))) { goto END; } while (!LIBRW_ERROR_IS_FATAL(rv) && rwRead(input_ios, &rwrec)) { rv = rwWrite(output_ios, &rwrec); } END: if (rv) { rwioPrintLastErr(output_ios, rv, &skAppPrintErr); } if (output_ios) { rwCloseFile(output_ios); } if (input_ios) { rwCloseFile(input_ios); } return rv; } int main(int argc, char **argv) { int rv; appSetup(argc, argv); rv = rwswap_file(inFName, outFName, outEndian); /* done */ appTeardown(); return rv; } /* ** Local variables: ** mode:c ** indent-tabs-mode:nil ** c-basic-offset:4 ** End: */