X-Git-Url: http://git.eversberg.eu/gitweb.cgi?p=lcr.git;a=blobdiff_plain;f=trace.c;h=0d6c114a0182b33ba50bc5e7906a7c7ed2c942fd;hp=f2698c1e4b5e89d5932863b66549ac78a2291e5e;hb=refs%2Fheads%2Fbackup2;hpb=d07348811e8517cfaa44a476ab54b5e4a3dc886d diff --git a/trace.c b/trace.c index f2698c1..0d6c114 100644 --- a/trace.c +++ b/trace.c @@ -11,51 +11,39 @@ #include "main.h" -struct trace trace[MAX_NESTED_TRACES]; -int trace_current = -1; -char trace_string[MX_TRACE_ELEMENTS * 100 + 400]; - -static char *spaces[11] = { - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - "", -}; +struct trace trace; +char trace_string[MAX_TRACE_ELEMENTS * 100 + 400]; + +static const char *spaces = " "; /* * initializes a new trace * all values will be reset */ -void start_trace(int port, char *interface, char *caller, char *dialing, int direction, char *category, char *name); +void _start_trace(const char *__file, int __line, int port, struct interface *interface, const char *caller, const char *dialing, int direction, int category, int serial, const char *name) { - if (++trace_current == MAX_NESTED_TRACES) - { - PERROR("maximum nesting level of traces exceeding: %d, exitting!\n", MAX_NESTED_TRACES); - PERROR("last trace=%s\n", trace[MAX_NESTED_TRACE-1].name); - exit(-1); - } - memset(trace[trace_current], 0, sizeof(struct trace)); - trace[trace_current].port = port; - if (interface) if (interface[0]) - SCPY(trace[trace_current].interface, interface); + struct timeval current_time; + + if (trace.name[0]) + PERROR("trace already started (name=%s) in file %s line %d\n", trace.name, __file, __line); + memset(&trace, 0, sizeof(struct trace)); + trace.port = port; + if (interface) + SCPY(trace.interface, interface->name); if (caller) if (caller[0]) - SCPY(trace[trace_current].caller, caller); + SCPY(trace.caller, caller); if (dialing) if (dialing[0]) - SCPY(trace[trace_current].dialing, dialing); - trace[trace_current].direction = direction; - if (category) if (category[0]) - SCPY(trace[trace_current].category, category); + SCPY(trace.dialing, dialing); + trace.direction = direction; + trace.category = category; + trace.serial = serial; if (name) if (name[0]) - SCPY(trace[trace_current].name, name); - trace[trace_current].sec = now_tv.tv_sec; - trace[trace_current].usec = now_tv.tv_usec; + SCPY(trace.name, name); + if (!trace.name[0]) + SCPY(trace.name, ""); + gettimeofday(¤t_time, NULL); + trace.sec = current_time.tv_sec; + trace.usec = current_time.tv_usec; } @@ -64,72 +52,34 @@ void start_trace(int port, char *interface, char *caller, char *dialing, int dir * if subelement is given, element will also contain a subelement * if multiple subelements belong to same element, name must be equal for all subelements */ -void add_trace(char *name, char *sub, const char *fmt, ...); +void _add_trace(const char *__file, int __line, const char *name, const char *sub, const char *fmt, ...) { va_list args; - /* check nesting */ - if (trace_current < 0) - { - PERROR("add_trace called without start_trace, exitting.\n"); - exit(0); - } - - /* check for space */ - if (trace[trace_current].elements == MAX_TRACE_ELEMENTS) - { - PERROR("trace with name=%s exceeds the maximum number of elements (%d)\n", trace.name, MAX_TRACE_ELEMENTS); - return; - } + if (!trace.name[0]) + PERROR("trace not started in file %s line %d\n", __file, __line); /* check for required name value */ if (!name) goto nostring; - if (!name[0]) - { + if (!name[0]) { nostring: - PERROR("trace with name=%s gets element with no string\n", trace->name); + PERROR("trace with name=%s gets element with no string\n", trace.name); return; } /* write name, sub and value */ - SCPY(trace[trace_current].element[trace[trace_current].elements].name, name); + SCPY(trace.element[trace.elements].name, name); if (sub) if (sub[0]) - SCPY(trace[trace_current].element[trace[trace_current].elements].sub, sub); - if (fmt) if (fmt[0]) - { + SCPY(trace.element[trace.elements].sub, sub); + if (fmt) if (fmt[0]) { va_start(args, fmt); - VUNPRINT(trace[trace_current].element[trace[trace_current].element].value, sizeof(trace[trace_current].element[trace[trace_current].elements].value)-1, fmt, args); + VUNPRINT(trace.element[trace.elements].value, sizeof(trace.element[trace.elements].value)-1, fmt, args); va_end(args); } /* increment elements */ - trace[trace_current].elements++; -} - - -/* - * trace ends - * this function will put the trace to sockets and logfile, if requested - */ -void end_trace(void); -{ - /* check nesting */ - if (trace_current < 0) - { - PERROR("end_trace called without start_trace, exitting.\n"); - exit(0); - } - - /* process log file */ - if (options.log[0]) - { - string = print_trace(1, 0, NULL, NULL, NULL, -1, "AP", NULL); - fwrite(string, strlen(string), 1, fp); - } - - /* reduce nesting level */ - trace_current--; + trace.elements++; } @@ -137,60 +87,65 @@ void end_trace(void); * prints trace to socket or log * detail: 1 = brief, 2=short, 3=long */ -static char *print_trace(int detail, int port, char *interface, char *caller, char *dialing, int direction, char *category); +static char *print_trace(int detail, int port, char *interface, char *caller, char *dialing, int category) { - trace_string[0] = '\0'; char buffer[256]; + time_t ti = trace.sec; struct tm *tm; +#ifdef WITH_MISDN + struct mISDNport *mISDNport; +#endif + int i; + + trace_string[0] = '\0'; // always clear string if (detail < 1) - return; + return(NULL); /* filter trace */ - if (port && trace.port) - if (port != trace.port) return; - if (interface && interface[0] && trace.interface[0]) - if (!!strcasecmp(interface, trace.interface)) return; - if (caller && caller[0] && trace.caller[0]) - if (!!strcasecmp(caller, trace.caller)) return; - if (dialing && dialing[0] && trace.dialing[0]) - if (!!strcasecmp(dialing, trace.dialing)) return; - if (direction && trace.direction) - if (direction != trace.direction) return; - if (category && category[0] && trace.category[0]) - if (!!strcasecmp(category, trace.category)) return; + if (port >= 0 && trace.port >= 0) + if (port != trace.port) return(NULL); + if (interface) if (interface[0] && trace.interface[0]) + if (!!strcasecmp(interface, trace.interface)) return(NULL); + if (caller) if (caller[0] && trace.caller[0]) + if (!!strncasecmp(caller, trace.caller, strlen(trace.caller))) return(NULL); + if (dialing) if (dialing[0] && trace.dialing[0]) + if (!!strncasecmp(dialing, trace.dialing, strlen(trace.dialing))) return(NULL); + if (category && trace.category) + if (!(category & trace.category)) return(NULL); /* head */ - if (detail >= 3) - { + if (detail >= 3) { + SCAT(trace_string, "------------------------------------------------------------------------------\n"); +#ifdef WITH_MISDN /* "Port: 1 (BRI PTMP TE)" */ - if (port) - { + if (trace.port >= 0) { mISDNport = mISDNport_first; - while(mISDNport) - { - if (mISDNport->number == trace.port) + while(mISDNport) { + if (mISDNport->portnum == trace.port) break; mISDNport = mISDNport->next; } - if (mISDNport) - SPRINT(buffer, "Port: %d (%s %s %s)", port, (mISDNport->pri)?"PRI":"BRI", (mISDNport->ptp)?"PTP":"PTMP", (mISDNport->nt)?"NT":"TE"); - else - SPRINT(buffer, "Port: %d (does not exist}\n", port); + if (mISDNport) { + SPRINT(buffer, "Port: %d (%s %s %s)", trace.port, (mISDNport->pri)?"PRI":"BRI", (mISDNport->ptp)?"PTP":"PTMP", (mISDNport->ntmode)?"NT":"TE"); + /* copy interface, if we have a port */ + if (mISDNport->ifport) if (mISDNport->ifport->interface) + SCPY(trace.interface, mISDNport->ifport->interface->name); + } else + SPRINT(buffer, "Port: %d (does not exist)\n", trace.port); SCAT(trace_string, buffer); } else +#endif SCAT(trace_string, "Port: ---"); - if (trace.interface[0]) - { + if (trace.interface[0]) { /* " Interface: 'Ext'" */ SPRINT(buffer, " Interface: '%s'", trace.interface); SCAT(trace_string, buffer); } else SCAT(trace_string, " Interface: ---"); - if (trace.caller[0]) - { + if (trace.caller[0]) { /* " Caller: '021256493'" */ SPRINT(buffer, " Caller: '%s'\n", trace.caller); SCAT(trace_string, buffer); @@ -198,20 +153,18 @@ static char *print_trace(int detail, int port, char *interface, char *caller, ch SCAT(trace_string, " Caller: ---\n"); /* "Time: 25.08.73 05:14:39.282" */ - tm = localtime(&trace.sec); - 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); + tm = localtime(&ti); + 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); SCAT(trace_string, buffer); - if (trace.direction) - { + if (trace.direction) { /* " Direction: out" */ SPRINT(buffer, " Direction: %s", (trace.direction==DIRECTION_OUT)?"OUT":"IN"); SCAT(trace_string, buffer); } else SCAT(trace_string, " Direction: ---"); - if (trace.dialing[0]) - { + if (trace.dialing[0]) { /* " Dialing: '57077'" */ SPRINT(buffer, " Dialing: '%s'\n", trace.dialing); SCAT(trace_string, buffer); @@ -221,25 +174,57 @@ static char *print_trace(int detail, int port, char *interface, char *caller, ch SCAT(trace_string, "------------------------------------------------------------------------------\n"); } - /* "L3: CC_SETUP (net->user)" */ - SPRINT(buffer, "%s: %s", trace.category[0]?trace.category:"--", trace.name[0]?trace.name:""); + if (detail < 3) { + tm = localtime(&ti); + SPRINT(buffer, "%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); + SCAT(trace_string, buffer); + } + + /* "CH(45): CC_SETUP (net->user)" */ + switch (trace.category) { + case CATEGORY_CH: + SCAT(trace_string, "CH"); + break; + + case CATEGORY_EP: + SCAT(trace_string, "EP"); + break; + + default: + SCAT(trace_string, "--"); + } + if (trace.serial) + SPRINT(buffer, "(%lu): %s", trace.serial, trace.name[0]?trace.name:""); + else + SPRINT(buffer, ": %s", trace.name[0]?trace.name:""); SCAT(trace_string, buffer); /* elements */ - switch(detail) - { + switch(detail) { case 1: /* brief */ + if (trace.interface[0]) { + SPRINT(buffer, " iface %s", trace.interface); + SCAT(trace_string, buffer); + } + if (trace.port >= 0) { + SPRINT(buffer, " port %d", trace.port); + SCAT(trace_string, buffer); + } i = 0; - while(i < trace.elements) - { + while(i < trace.elements) { SPRINT(buffer, " %s", trace.element[i].name); if (i) if (!strcmp(trace.element[i].name, trace.element[i-1].name)) buffer[0] = '\0'; SCAT(trace_string, buffer); if (trace.element[i].sub[0]) - SPRINT(buffer, " %s=%s", trace.element[i].sub, value); + SPRINT(buffer, " %s=", trace.element[i].sub); + else + SPRINT(buffer, " "); + SCAT(trace_string, buffer); + if (strchr(trace.element[i].value, ' ')) + SPRINT(buffer, "'%s'", trace.element[i].value); else - SPRINT(buffer, " %s", value); + SPRINT(buffer, "%s", trace.element[i].value); SCAT(trace_string, buffer); i++; } @@ -250,16 +235,20 @@ static char *print_trace(int detail, int port, char *interface, char *caller, ch case 3: /* long */ SCAT(trace_string, "\n"); i = 0; - while(i < trace.elements) - { - SPRINT(buffer, " %s%s", trace.element[i].name, spaces[strlen(trace.element[i].name)]); + while(i < trace.elements) { + SPRINT(buffer, " %s%s", trace.element[i].name, &spaces[strlen(trace.element[i].name)]); if (i) if (!strcmp(trace.element[i].name, trace.element[i-1].name)) SPRINT(buffer, " "); SCAT(trace_string, buffer); if (trace.element[i].sub[0]) - SPRINT(buffer, " : %s%s = %s\n", trace.element[i].sub, spaces[strlen(trace.element[i].sub)], value); + SPRINT(buffer, " : %s%s = ", trace.element[i].sub, &spaces[strlen(trace.element[i].sub)]); else - SPRINT(buffer, " : %s\n", value); + SPRINT(buffer, " : "); + SCAT(trace_string, buffer); + if (strchr(trace.element[i].value, ' ')) + SPRINT(buffer, "'%s'\n", trace.element[i].value); + else + SPRINT(buffer, "%s\n", trace.element[i].value); SCAT(trace_string, buffer); i++; } @@ -269,12 +258,77 @@ static char *print_trace(int detail, int port, char *interface, char *caller, ch /* end */ if (detail >= 3) SCAT(trace_string, "\n"); + return(trace_string); } +/* + * trace ends + * this function will put the trace to sockets and logfile, if requested + */ +void _end_trace(const char *__file, int __line) +{ + char *string; + FILE *fp; + struct admin_list *admin; + struct admin_queue *response, **responsep; /* response pointer */ + int __attribute__((__unused__)) ret; + + if (!trace.name[0]) + PERROR("trace not started in file %s line %d\n", __file, __line); + + if (options.deb || options.log[0]) { + string = print_trace(1, -1, NULL, NULL, NULL, 0); + if (string) { + /* process debug */ + if (options.deb) + debug(NULL, NULL, 0, "TRACE", string); + /* process log */ + if (options.log[0]) { + fp = fopen(options.log, "a"); + if (fp) { + ret = fwrite(string, strlen(string), 1, fp); + fclose(fp); + } + } + } + } + + /* process admin */ + admin = admin_first; + while(admin) { + if (admin->trace.detail) { + string = print_trace(admin->trace.detail, admin->trace.port, admin->trace.interface, admin->trace.caller, admin->trace.dialing, admin->trace.category); + if (string) { + /* seek to end of response list */ + response = admin->response; + responsep = &admin->response; + while(response) { + responsep = &response->next; + response = response->next; + } + + /* create state response */ + response = (struct admin_queue *)MALLOC(sizeof(struct admin_queue)+sizeof(admin_message)); + memuse++; + response->num = 1; + /* message */ + response->am[0].message = ADMIN_TRACE_RESPONSE; + SCPY(response->am[0].u.trace_rsp.text, string); + + /* attach to response chain */ + *responsep = response; + responsep = &response->next; + admin->fd.when |= LCR_FD_WRITE; + } + } + admin = admin->next; + } +// fwrite(string, strlen(string), 1, fp); + + memset(&trace, 0, sizeof(struct trace)); +} + -^todo: -socket -file open