bb63ec22d5e3e3bf73f0e617555c43d63aeba5a6
[lcr.git] / trace.c
1 /*****************************************************************************\
2 **                                                                           **
3 ** Linux Call Router                                                         **
4 **                                                                           **
5 **---------------------------------------------------------------------------**
6 ** Copyright: Andreas Eversberg                                              **
7 **                                                                           **
8 ** trace functions                                                           **
9 **                                                                           **
10 \*****************************************************************************/ 
11
12 #include "main.h"
13
14 struct trace trace;
15 char trace_string[MX_TRACE_ELEMENTS * 100 + 400];
16
17 static char *spaces[11] = {
18         "          ",
19         "         ",
20         "        ",
21         "       ",
22         "      ",
23         "     ",
24         "    ",
25         "   ",
26         "  ",
27         " ",
28         "",
29 };
30
31 /*
32  * initializes a new trace
33  * all values will be reset
34  */
35 void start_trace(int port, char *interface, char *caller, char *dialing, int direction, char *category, char *name);
36 {
37         if (trace.name[0])
38                 PERROR("trace already started (name=%s)\n", trace.name);
39         memset(trace, 0, sizeof(struct trace));
40         trace.port = port;
41         if (interface) if (interface[0])
42                 SCPY(trace.interface, interface);
43         if (caller) if (caller[0])
44                 SCPY(trace.caller, caller);
45         if (dialing) if (dialing[0])
46                 SCPY(trace.dialing, dialing);
47         trace.direction = direction;
48         if (category) if (category[0])
49                 SCPY(trace.category, category);
50         if (name) if (name[0])
51                 SCPY(trace.name, name);
52         trace.sec = now_tv.tv_sec;
53         trace.usec = now_tv.tv_usec;
54 }
55
56
57 /*
58  * adds a new element to the trace
59  * if subelement is given, element will also contain a subelement
60  * if multiple subelements belong to same element, name must be equal for all subelements
61  */
62 void add_trace(char *name, char *sub, const char *fmt, ...);
63 {
64         va_list args;
65
66         if (!trace.name[0])
67                 PERROR("trace not started\n");
68         
69         /* check for required name value */
70         if (!name)
71                 goto nostring;
72         if (!name[0])
73         {
74                 nostring:
75                 PERROR("trace with name=%s gets element with no string\n", trace->name);
76                 return;
77         }
78         
79         /* write name, sub and value */
80         SCPY(trace.element[trace.elements].name, name);
81         if (sub) if (sub[0])
82                 SCPY(trace.element[trace.elements].sub, sub);
83         if (fmt) if (fmt[0])
84         {
85                 va_start(args, fmt);
86                 VUNPRINT(trace.element[trace.element].value, sizeof(trace.element[trace.elements].value)-1, fmt, args);
87                 va_end(args);
88         }
89
90         /* increment elements */
91         trace.elements++;
92 }
93
94
95 /*
96  * trace ends
97  * this function will put the trace to sockets and logfile, if requested
98  */
99 void end_trace(void);
100 {
101         if (!trace.name[0])
102                 PERROR("trace not started\n");
103         
104         /* process log file */
105         if (options.log[0])
106         {
107                 string = print_trace(1, 0, NULL, NULL, NULL, -1, "AP", NULL);
108                 fwrite(string, strlen(string), 1, fp);
109         }
110
111         memset(trace, 0, sizeof(struct trace));
112 }
113
114
115 /*
116  * prints trace to socket or log
117  * detail: 1 = brief, 2=short, 3=long
118  */
119 static char *print_trace(int detail, int port, char *interface, char *caller, char *dialing, char *category);
120 {
121         trace_string[0] = '\0';
122         char buffer[256];
123         struct tm *tm;
124
125         if (detail < 1)
126                 return;
127
128         /* filter trace */
129         if (port && trace.port)
130                 if (port != trace.port) return;
131         if (interface && interface[0] && trace.interface[0])
132                 if (!!strcasecmp(interface, trace.interface)) return;
133         if (caller && caller[0] && trace.caller[0])
134                 if (!!strcasecmp(caller, trace.caller)) return;
135         if (dialing && dialing[0] && trace.dialing[0])
136                 if (!!strcasecmp(dialing, trace.dialing)) return;
137         if (category && category[0] && trace.category[0])
138                 if (!!strcasecmp(category, trace.category)) return;
139
140         /* head */
141         if (detail >= 3)
142         {
143                 /* "Port: 1 (BRI PTMP TE)" */
144                 if (port)
145                 {
146                         mISDNport = mISDNport_first;
147                         while(mISDNport)
148                         {
149                                 if (mISDNport->number == trace.port)
150                                         break;
151                                 mISDNport = mISDNport->next;
152                         }
153                         if (mISDNport)
154                                 SPRINT(buffer, "Port: %d (%s %s %s)", port, (mISDNport->pri)?"PRI":"BRI", (mISDNport->ptp)?"PTP":"PTMP", (mISDNport->nt)?"NT":"TE");
155                         else
156                                 SPRINT(buffer, "Port: %d (does not exist}\n", port);
157                         SCAT(trace_string, buffer);
158                 } else
159                         SCAT(trace_string, "Port: ---");
160
161                 if (trace.interface[0])
162                 {
163                         /* "  Interface: 'Ext'" */
164                         SPRINT(buffer, "  Interface: '%s'", trace.interface);
165                         SCAT(trace_string, buffer);
166                 } else
167                         SCAT(trace_string, "  Interface: ---");
168                         
169                 if (trace.caller[0])
170                 {
171                         /* "  Caller: '021256493'" */
172                         SPRINT(buffer, "  Caller: '%s'\n", trace.caller);
173                         SCAT(trace_string, buffer);
174                 } else
175                         SCAT(trace_string, "  Caller: ---\n");
176
177                 /* "Time: 25.08.73 05:14:39.282" */
178                 tm = localtime(&trace.sec);
179                 SPRINT(buffer, "Time: %02d.%02d.%02d %02d:%02d:%02d.%03d", tm->tm_mday, tm->tm_mon+1, tm->tm_year%100, tm->tm_hour, tm->tm_min, tm->tm_sec, trace->usec/1000);
180                 SCAT(trace_string, buffer);
181
182                 if (trace.direction)
183                 {
184                         /* "  Direction: out" */
185                         SPRINT(buffer, "  Direction: %s", (trace.direction==DIRECTION_OUT)?"OUT":"IN");
186                         SCAT(trace_string, buffer);
187                 } else
188                         SCAT(trace_string, "  Direction: ---");
189
190                 if (trace.dialing[0])
191                 {
192                         /* "  Dialing: '57077'" */
193                         SPRINT(buffer, "  Dialing: '%s'\n", trace.dialing);
194                         SCAT(trace_string, buffer);
195                 } else
196                         SCAT(trace_string, "  Dialing: ---\n");
197
198                 SCAT(trace_string, "------------------------------------------------------------------------------\n");
199         }
200
201         /* "L3: CC_SETUP (net->user)" */
202         SPRINT(buffer, "%s: %s", trace.category[0]?trace.category:"--", trace.name[0]?trace.name:"<unknown>");
203         SCAT(trace_string, buffer);
204
205         /* elements */
206         switch(detail)
207         {
208                 case 1: /* brief */
209                 i = 0;
210                 while(i < trace.elements)
211                 {
212                         SPRINT(buffer, "  %s", trace.element[i].name);
213                         if (i) if (!strcmp(trace.element[i].name, trace.element[i-1].name))
214                                 buffer[0] = '\0';
215                         SCAT(trace_string, buffer);
216                         if (trace.element[i].sub[0])
217                                 SPRINT(buffer, " %s=", trace.element[i].sub, value);
218                         else
219                                 SPRINT(buffer, " ", value);
220                         SCAT(trace_string, buffer);
221                         if (strchr(value, ' '))
222                                 SPRINT(buffer, "'%s'", value);
223                         else
224                                 SPRINT(buffer, "%s", value);
225                         SCAT(trace_string, buffer);
226                         i++;
227                 }
228                 SCAT(trace_string, "\n");
229                 break;
230
231                 case 2: /* short */
232                 case 3: /* long */
233                 SCAT(trace_string, "\n");
234                 i = 0;
235                 while(i < trace.elements)
236                 {
237                         SPRINT(buffer, " %s%s", trace.element[i].name, spaces[strlen(trace.element[i].name)]);
238                         if (i) if (!strcmp(trace.element[i].name, trace.element[i-1].name))
239                                 SPRINT(buffer, "           ");
240                         SCAT(trace_string, buffer);
241                         if (trace.element[i].sub[0])
242                                 SPRINT(buffer, " : %s%s = ", trace.element[i].sub, spaces[strlen(trace.element[i].sub)], value);
243                         else
244                                 SPRINT(buffer, " :              ", value);
245                         SCAT(trace_string, buffer);
246                         if (strchr(value, ' '))
247                                 SPRINT(buffer, "'%s'\n", value);
248                         else
249                                 SPRINT(buffer, "%s\n", value);
250                         SCAT(trace_string, buffer);
251                         i++;
252                 }
253                 break;
254         }
255
256         /* end */
257         if (detail >= 3)
258                 SCAT(trace_string, "\n");
259 }
260
261
262
263 ^todo:
264 socket
265 file open
266
267