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
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 );
118 fprintf( stderr, "usage: %s [-d fifo-dir] [-f input-file] [-t msg-type]\n", argv[0] );
119 fprintf( stderr, "if -f not given, then standard input is read\n" );
124 if( input_file == NULL ) {
127 if( (fd = open( input_file, O_RDONLY )) < 0 ) {
128 fprintf( stderr, "abort: cant open: %s: %s\n", input_file, strerror(errno) );
133 mcl_ctx = mcl_mk_context( fifo_path );
134 mcl_set_sigh(); // ignore pipe related signals
136 remain = read( fd, rbuf, sizeof( rbuf ) );
138 while( remain > 0 ) {
139 if( remain < 20 ) { // not enough stuff
140 memcpy( rbuf, nxt, remain ); // copy remaining up front
142 remain += read( fd, nxt + remain, sizeof( rbuf ) - remain );
145 if( remain < 20 ) { // truncated or a record > rbuf
146 fprintf( stderr, "abort: @header check, truncated file, or record > read buffer size\n" );
150 if( strncmp( nxt, "@RDC", 4 ) == 0 ) {
151 mtype = atoi( nxt+4 );
152 mlen = atoi( nxt+12 );
156 if( remain < mlen ) { // not enough stuff
157 memcpy( rbuf, nxt, remain ); // copy remaining up front
159 remain += read( fd, nxt + remain, sizeof( rbuf ) - remain );
162 if( remain < mlen ) { // truncated or a record > rbuf
163 fprintf( stderr, "abort: truncated file, or record > read buffer size\n" );
167 if( desired < 0 || mtype == desired ) { // all mtypes, or specific
168 state = mcl_fifo_one( mcl_ctx, nxt, mlen, mtype );
179 fprintf( stderr, "abort: didn't find rdc header!?! @ %ld\n", (long) (nxt - rbuf) );
184 fprintf( stderr, "done, captured %ld messages; %ld errors\n", ok_count, err_count );