Address sonar complaints about the listener
[ric-app/mc.git] / sidecars / listener / src / mc_listener.c
1 // vim: ts=4 sw=4 noet:
2 /*
3 --------------------------------------------------------------------------------
4         Copyright (c) 2018-2019 AT&T Intellectual Property.
5
6    Licensed under the Apache License, Version 2.0 (the "License");
7    you may not use this file except in compliance with the License.
8    You may obtain a copy of the License at
9
10            http://www.apache.org/licenses/LICENSE-2.0
11
12    Unless required by applicable law or agreed to in writing, software
13    distributed under the License is distributed on an "AS IS" BASIS,
14    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15    See the License for the specific language governing permissions and
16    limitations under the License.
17 --------------------------------------------------------------------------------
18 */
19
20 /*
21         Mnemonic:       mc_listener.c
22         Abstract:       This application (management campaign listener) will listen for
23                                 RMR based messages and write the payloads into FIFOs which
24                                 correspond to the message type.
25                 
26                                 Defaults:
27                                         /var/lib/mc/listener  -- directory for FIFOs
28
29                                 Command line options:
30                                         -d <path>   FIFO directory (default is /tmp/mcl/fifos)
31                                         -p <port>       The port to set RMR listener on (default is 4560)
32                                         -r <seconds>  The frequency that count reports are written to
33                                                                         stderr. 0 == 0ff; default is 60.
34
35
36                                 RMR based environment variables which might be needed:
37                                         RMR_SEED_RT -- path to the static routing table
38                                         RMR_RTG_SVC -- port to listen for RTG connections
39
40         Date:           22 August 2019
41         Author:         E. Scott Daniels
42 */
43
44 #include <unistd.h>
45 #include <errno.h>
46 #include <stdio.h>
47 #include <stdlib.h>
48 #include <time.h>
49 #include <string.h>
50 #include <signal.h>
51
52
53 #include "mcl.h"
54
55 //---- support -----------------------------------------------------------------------------
56
57 static void bad_arg( char* what ) {
58         fprintf( stderr, "[ERR] option is unrecognised or isn't followed by meaningful data: %s\n", what );
59 }
60
61 static void usage( char* argv0 ) {
62         fprintf( stderr, "usage: %s [-d fifo-dir] [-e] [-p listen-port] [-q | -r report-freq]\n", argv0 );
63         fprintf( stderr, "  -e  disable extended header in buffers written to FIFOs\n" );
64         fprintf( stderr, "\n" );
65         fprintf( stderr, "The following environment variables may be set to affect operation:\n" );
66         fprintf( stderr, "  MCL_RDC_STAGE: the directory where raw data capture files are staged. (/tmp/rdc/stage)\n" );
67         fprintf( stderr, "  MCL_RDC_FINAL: the directory where raw data capture files are placed for export. (/tmp/rdc/final)\n" );
68         fprintf( stderr, "  MCL_RDC_SUFFIX: the suffix written on each raw data capture file; must include '.'. (.rdc)\n" );
69         fprintf( stderr, "  MCL_RDC_SOURCE: a short string used as source identification in rdc file names.\n" );
70         fprintf( stderr, "  MCL_RDC_FREQ: the amount of time (seconds) that raw capture files are rolled. (300)\n" );
71         fprintf( stderr, "\nIf either final or staging directories are defined by environment vars, they MUST exist.\n" );
72         fprintf( stderr, "\n" );
73 }
74
75 /*
76         We exit on any trapped signal so that we can kill  -15 the proecss
77         and still get gcoverage information to keep sonar happy.
78 */
79 static void sigh( int sig ) {
80         fprintf( stderr, "\n[INFO] exiting on signal %d\n", sig );
81         exit( 0 );
82 }
83
84 //------------------------------------------------------------------------------------------
85 int main( int argc,  char** argv ) {
86         void*   ctx;                                                    // the mc listener library context
87         char*   dname = NULL;                                   // default directory where we open fifos
88         char*   port = "4560";                                  // default rmr port
89         char*   siphon_dir = "/tmp/mci/siphon"; // where siphon files are placed
90         int             siphon = 0;                                             // percentage of messages to siphone off
91         int             report_freq = 60;                               // report stats every n seconds
92         int             pidx = 1;                                               // parameter index
93         int             error = 0;
94         int             long_hdrs = 1;                                  // -e sets and causes extended headers to be written
95
96         signal( SIGINT, sigh );
97         signal( SIGTERM, sigh );
98
99         dname = strdup( "/tmp/mcl/fifos" );                                     // so we can always free
100
101         while( pidx < argc && argv[pidx][0] == '-' ) {                  // simple argument parsing (-x  or -x value)
102                 switch( argv[pidx][1] ) {
103                         case 'd':
104                                 if( pidx+1 < argc ) {
105                                         dname = strdup( argv[pidx+1] );
106                                         pidx++;
107                                 } else {
108                                         bad_arg( argv[pidx] );
109                                         error = 1;
110                                 }
111                                 break;
112
113                         case 'e':
114                                 long_hdrs = 0;
115                                 break;
116
117                         case 'p':
118                                 if( pidx+1 < argc ) {
119                                         port = strdup( argv[pidx+1] );
120                                         pidx++;
121                                 } else {
122                                         bad_arg( argv[pidx] );
123                                         error = 1;
124                                 }
125                                 break;
126
127                         case 'q':
128                                 report_freq = 0;
129                                 break;
130
131                         case 'r':
132                                 if( pidx+1 < argc ) {
133                                         report_freq = atoi( argv[pidx+1] );
134                                         pidx++;
135                                 } else {
136                                         bad_arg( argv[pidx] );
137                                         error = 1;
138                                 }
139                                 break;
140
141                         case 'h':
142                         case '?':
143                                 usage( argv[0] );
144                                 exit( 0 );
145
146                         default:
147                                 bad_arg( argv[pidx] );
148                                 error = 1;
149                                 break;
150                 }
151
152                 pidx++;
153         }
154
155         if( error ) {
156                 free( dname );
157                 usage( argv[0] );
158                 exit( 1 );
159         }
160
161         ctx = mcl_mk_context( dname );                  // initialise the library context
162         if( ctx == NULL ) {
163                 fprintf( stderr, "[FAIL] couldn't initialise the mc listener environment\n" );
164                 free( dname );
165                 exit( 1 );
166         }
167         mcl_set_sigh();                                                                 // set signal handler(s)
168
169         mcl_start_listening( ctx,  port, MCL_NOWAIT );          // start the listener, no waiting for rt since we don't send
170         mcl_fifo_fanout( ctx, report_freq, long_hdrs );         // listen and fanout messages to fifo; report to stdout every ~2sec
171
172         fprintf( stderr, "[INFO] mc listener is finished.\n" );
173
174         free( port );                   // uneeded, but these keep sonar from twisting it's knickers about leaks
175         free( dname );
176 }
177