4 Abstract: This reads raw data from an RDC file generated by the mc_listener
5 builds RMR messages which mimic the original message that the
6 listener received, and then writes those messages. The assumption
7 is that a dummy route table is in place that causes one or more message
8 types to be routed to the mc_listener for "replay" into the mc-core
12 The RDC file format is expected to be:
13 @RDC<mtype><len> or as depicted in hex:
16 0000000 40 52 44 43 << delim == @RDC
17 30 30 31 30 30 35 30 2a << mtype
18 30 30 30 30 << msg len
20 40 4d 43 4c 30 30 30 30 30 34 36 00 << raw message
24 This is a very quick and dirty thing, so it might be flakey.
26 Parms from command line are file to read, and the msg type to extract.
27 If mtype given is 0, then message type of each record is written to
28 stdout (can be sorted -u for a list of messages in the file).
31 Date: 19 November 2019
32 Author: E. Scott Daniels
45 Write a scathing message to let the user know they buggered it!
47 static void invalid_arg( char* arg ) {
48 fprintf( stderr, "%s is not a valid option, or requires an additional parameter which was omitted\n", arg );
51 int main( int argc, char** argv ) {
53 int state; // processing state
54 int fd; // input file des
55 int mtype; // msg type for current buffer
56 int mlen; // len of raw data
57 char* nxt; // pointer at next bytes to process
58 int remain = 0; // number of bytes remaining to parse
59 int need = 20; // number of bytes needed before having enough to work with
60 int desired = -1; // all mtypes; -t overrides and susses out one type
62 void* mcl_ctx; // mcl library context
65 char* fifo_path = "/tmp/mcl_replay/fifos"; // directory where we create fifos; -d overrieds
66 char* input_file = NULL; // -f to set; stdin is default if nil
71 for( i = 1; i < argc; i++ ) {
80 fifo_path = argv[i+1];
90 input_file = argv[i+1];
100 desired = atoi( argv[i+1] );
109 fprintf( stderr, "unrecognised option: %s\n", arg );
116 fprintf( stderr, "usage: %s [-d fifo-dir] [-f input-file] [-t msg-type]\n", argv[0] );
117 fprintf( stderr, "if -f not given, then standard input is read\n" );
122 if( input_file == NULL ) {
125 if( (fd = open( input_file, O_RDONLY )) < 0 ) {
126 fprintf( stderr, "abort: cant open: %s: %s\n", input_file, strerror(errno) );
131 mcl_ctx = mcl_mk_context( fifo_path );
132 mcl_set_sigh(); // ignore pipe related signals
134 remain = read( fd, rbuf, sizeof( rbuf ) );
136 while( remain > 0 ) {
137 if( remain < 20 ) { // not enough stuff
138 memcpy( rbuf, nxt, remain ); // copy remaining up front
140 remain += read( fd, nxt + remain, sizeof( rbuf ) - remain );
143 if( remain < 20 ) { // truncated or a record > rbuf
144 fprintf( stderr, "abort: @header check, truncated file, or record > read buffer size\n" );
148 if( strncmp( nxt, "@RDC", 4 ) == 0 ) {
149 mtype = atoi( nxt+4 );
150 mlen = atoi( nxt+12 );
154 if( remain < mlen ) { // not enough stuff
155 memcpy( rbuf, nxt, remain ); // copy remaining up front
157 remain += read( fd, nxt + remain, sizeof( rbuf ) - remain );
160 if( remain < mlen ) { // truncated or a record > rbuf
161 fprintf( stderr, "abort: truncated file, or record > read buffer size\n" );
165 if( desired < 0 || mtype == desired ) { // all mtypes, or specific
166 state = mcl_fifo_one( mcl_ctx, nxt, mlen, mtype );
177 fprintf( stderr, "abort: didn't find rdc header!?! @ %ld\n", (long) (nxt - rbuf) );
182 fprintf( stderr, "done, captured %ld messages; %ld errors\n", ok_count, err_count );