Add the DragonFly cvs id and perform general cleanups on cvs/rcs/sccs ids. Most
[dragonfly.git] / usr.sbin / i4b / isdntrace / trace.c
1 /*
2  *   Copyright (c) 1996, 2000 Hellmuth Michaelis.  All rights reserved.
3  *
4  *   Copyright (c) 1996 Gary Jennejohn.  All rights reserved. 
5  *
6  *   Redistribution and use in source and binary forms, with or without
7  *   modification, are permitted provided that the following conditions
8  *   are met:
9  *
10  *   1. Redistributions of source code must retain the above copyright
11  *      notice, this list of conditions and the following disclaimer.
12  *   2. Redistributions in binary form must reproduce the above copyright
13  *      notice, this list of conditions and the following disclaimer in the
14  *      documentation and/or other materials provided with the distribution.
15  *   3. Neither the name of the author nor the names of any co-contributors
16  *      may be used to endorse or promote products derived from this software
17  *      without specific prior written permission.
18  *   4. Altered versions must be plainly marked as such, and must not be
19  *      misrepresented as being the original software and/or documentation.
20  *   
21  *   THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
22  *   ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  *   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  *   ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
25  *   FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  *   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  *   OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  *   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  *   LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  *   OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  *   SUCH DAMAGE.
32  *
33  *---------------------------------------------------------------------------*
34  *
35  *      trace.c - print traces of D (B) channel activity for isdn4bsd
36  *      -------------------------------------------------------------
37  *
38  *      $Id: trace.c,v 1.19 2000/08/28 07:06:42 hm Exp $ 
39  *
40  * $FreeBSD: src/usr.sbin/i4b/isdntrace/trace.c,v 1.8.2.1 2001/08/01 17:45:08 obrien Exp $
41  * $DragonFly: src/usr.sbin/i4b/isdntrace/trace.c,v 1.2 2003/06/17 04:29:55 dillon Exp $
42  *
43  *      last edit-date: [Mon Aug 28 09:03:46 2000]
44  *
45  *---------------------------------------------------------------------------*/
46
47 #include "trace.h"
48
49 unsigned char buf[BSIZE];
50 FILE *Fout = NULL;
51 FILE *BP = NULL;
52 int outflag = 1;
53 int header = 1;
54 int print_q921 = 1;
55 int unit = 0;
56 int dchan = 0;
57 int bchan = 0;
58 int traceon = 0;
59 int analyze = 0;
60 int Rx = RxUDEF;
61 int Tx = TxUDEF;
62 int f;
63 int Bopt = 0;
64 int Popt = 0;
65 int bpopt = 0;
66 int info = 0;
67 int Fopt = 0;
68 int xopt = 1;
69
70 int enable_trace = TRACE_D_RX | TRACE_D_TX;
71         
72 static char outfilename[MAXPATHLEN];
73 static char routfilename[MAXPATHLEN];
74 static char BPfilename[MAXPATHLEN];
75 static char rBPfilename[MAXPATHLEN];
76
77 static struct stat fst;
78
79 static void dumpbuf( int n, unsigned char *buf, i4b_trace_hdr_t *hdr, int raw );
80 static int switch_driver( int value, int rx, int tx );
81 static void usage( void );
82 static void exit_hdl( void );
83 static void reopenfiles( int );
84 void add_datetime(char *filename, char *rfilename);
85
86 /*---------------------------------------------------------------------------*
87  *      usage instructions
88  *---------------------------------------------------------------------------*/
89 void
90 usage(void)
91 {
92         fprintf(stderr,"\n");
93         fprintf(stderr,"isdntrace - i4b package ISDN trace facility for passive cards (%02d.%02d.%d)\n", VERSION, REL, STEP);
94         fprintf(stderr,"usage: isdntrace -a -b -d -f <file> -h -i -l -n <val> -o -p <file> -r -u <unit>\n");
95         fprintf(stderr,"                 -x -B -F -P -R <unit> -T <unit>\n");
96         fprintf(stderr,"       -a        analyzer mode ................................... (default off)\n");
97         fprintf(stderr,"       -b        switch B channel trace on ....................... (default off)\n");
98         fprintf(stderr,"       -d        switch D channel trace off ....................... (default on)\n");
99         fprintf(stderr,"       -f <file> write output to file filename ............ (default %s0)\n", TRACE_FILE_NAME);
100         fprintf(stderr,"       -h        don't print header for each message ............. (default off)\n");
101         fprintf(stderr,"       -i        print I.430 (layer 1) INFO signals .............. (default off)\n");   
102         fprintf(stderr,"       -l        don't decode low layer Q.921 messages ........... (default off)\n");
103         fprintf(stderr,"       -n <val>  process packet if it is longer than <val> octetts . (default 0)\n");
104         fprintf(stderr,"       -o        don't write output to a file .................... (default off)\n");
105         fprintf(stderr,"       -p <file> specify filename for -B and -P ........ (default %s0)\n", BIN_FILE_NAME);
106         fprintf(stderr,"       -r        don't print raw hex/ASCII dump of protocol ...... (default off)\n");
107         fprintf(stderr,"       -u <unit> specify controller unit number ............... (default unit 0)\n");
108         fprintf(stderr,"       -x        show packets with unknown protocol discriminator  (default off)\n");
109         fprintf(stderr,"       -B        write binary trace data to file filename ........ (default off)\n");
110         fprintf(stderr,"       -F        with -P and -p: wait for more data at EOF ....... (default off)\n");
111         fprintf(stderr,"       -P        playback from binary trace data file ............ (default off)\n");
112         fprintf(stderr,"       -R <unit> analyze Rx controller unit number (for -a) ... (default unit %d)\n", RxUDEF);
113         fprintf(stderr,"       -T <unit> analyze Tx controller unit number (for -a) ... (default unit %d)\n", TxUDEF);
114         fprintf(stderr,"\n");
115         exit(1);
116 }
117
118 /*---------------------------------------------------------------------------*
119  *      main
120  *---------------------------------------------------------------------------*/
121 int
122 main(int argc, char *argv[])
123 {
124         extern int optind;
125         extern int opterr;
126         extern char *optarg;
127         char devicename[80];
128         char headerbuf[256];
129                 
130         int n;
131         int c;
132         char *b;
133
134         char *outfile = TRACE_FILE_NAME;
135         char *binfile = BIN_FILE_NAME;
136         int outfileset = 0;
137         int raw = 1;
138         int noct = -1;
139         time_t tm;
140         i4b_trace_hdr_t *ithp = NULL;
141         int l;
142         static struct stat fstnew;      
143
144         b = &buf[sizeof(i4b_trace_hdr_t)];
145         
146         while( (c = getopt(argc, argv, "abdf:hiln:op:ru:xBFPR:T:")) != -1)
147         {
148                 switch(c)
149                 {
150                         case 'a':
151                                 analyze = 1;
152                                 break;
153                                 
154                         case 'b':
155                                 enable_trace |= (TRACE_B_RX | TRACE_B_TX);
156                                 break;
157
158                         case 'd':
159                                 enable_trace &= (~(TRACE_D_TX | TRACE_D_RX));
160                                 break;
161
162                         case 'o':
163                                 outflag = 0;
164                                 break;
165
166                         case 'f':
167                                 outfile = optarg;
168                                 outfileset = 1;
169                                 break;
170                         
171                         case 'n':
172                                 noct = atoi(optarg);
173                                 break;
174
175                         case 'h':
176                                 header = 0;
177                                 break;
178
179                         case 'i':
180                                 enable_trace |= TRACE_I;
181                                 info = 1;
182                                 break;
183
184                         case 'l':
185                                 print_q921 = 0;
186                                 break;
187
188                         case 'p':
189                                 binfile = optarg;
190                                 bpopt = 1;
191                                 break;
192                         
193                         case 'r':
194                                 raw = 0;
195                                 break;
196
197                         case 'u':
198                                 unit = atoi(optarg);
199                                 if(unit < 0 || unit >= MAX_CONTROLLERS)
200                                         usage();
201                                 break;
202
203                         case 'x':
204                                 xopt = 0;
205                                 break;
206
207                         case 'B':
208                                 Bopt = 1;
209                                 break;
210                         
211                         case 'F':
212                                 Fopt = 1;
213                                 break;
214                         
215                         case 'P':
216                                 Popt = 1;
217                                 break;
218                         
219                         case 'R':
220                                 Rx = atoi(optarg);
221                                 if(Rx < 0 || Rx >= MAX_CONTROLLERS)
222                                         usage();
223                                 break;
224
225                         case 'T':
226                                 Tx = atoi(optarg);
227                                 if(Tx < 0 || Tx >= MAX_CONTROLLERS)
228                                         usage();
229                                 break;
230
231                         case '?':
232                         default:
233                                 usage();
234                                 break;
235                 }
236         }
237
238         if(enable_trace == 0)
239                 usage();
240
241         if(Bopt && Popt)
242                 usage();
243                 
244         atexit(exit_hdl);
245
246         if(Bopt)
247         {
248                 if(bpopt)
249                         sprintf(BPfilename, "%s", binfile);
250                 else
251                         sprintf(BPfilename, "%s%d", BIN_FILE_NAME, unit);
252                         
253                 add_datetime(BPfilename, rBPfilename);
254
255                 if((BP = fopen(rBPfilename, "w")) == NULL)
256                 {
257                         char buffer[80];
258
259                         sprintf(buffer, "Error opening file [%s]", rBPfilename);
260                         perror(buffer);
261                         exit(1);
262                 }
263                 
264                 if((setvbuf(BP, (char *)NULL, _IONBF, 0)) != 0)
265                 {
266                         char buffer[80];
267
268                         sprintf(buffer, "Error setting file [%s] to unbuffered", rBPfilename);
269                         perror(buffer);
270                         exit(1);
271                 }
272         }               
273
274         if(Popt)
275         {
276                 if(bpopt)
277                         sprintf(BPfilename, "%s", binfile);
278                 else
279                         sprintf(BPfilename, "%s%d", BIN_FILE_NAME, unit);
280                         
281                 strcpy(rBPfilename, BPfilename);
282                 
283                 if((BP = fopen(BPfilename, "r")) == NULL)
284                 {
285                         char buffer[80];
286
287                         sprintf(buffer, "Error opening file [%s]", BPfilename);
288                         perror(buffer);
289                         exit(1);
290                 }
291                 if(Fopt)
292                 {
293                         if(fstat(fileno(BP), &fst))
294                         {
295                                 char buffer[80];
296                                 sprintf(buffer, "Error fstat file [%s]", BPfilename);
297                                 perror(buffer);
298                                 exit(1);
299                         }
300                 }
301         }
302         else
303         {               
304                 sprintf(devicename, "%s%d", I4BTRC_DEVICE, unit);
305         
306                 if((f = open(devicename, O_RDWR)) < 0)
307                 {
308                         char buffer[80];
309         
310                         sprintf(buffer, "Error opening trace device [%s]", devicename);
311                         perror(buffer);
312                         exit(1);
313                 }
314         }
315         
316         if(outflag)
317         {
318                 if(outfileset == 0)
319                         sprintf(outfilename, "%s%d", TRACE_FILE_NAME, unit);
320                 else
321                         strcpy(outfilename, outfile);
322                         
323                 add_datetime(outfilename, routfilename);
324                         
325                 if((Fout = fopen(routfilename, "w")) == NULL)
326                 {
327                         char buffer[80];
328
329                         sprintf(buffer, "Error opening file [%s]", routfilename);
330                         perror(buffer);
331                         exit(1);
332                 }
333                 
334                 if((setvbuf(Fout, (char *)NULL, _IONBF, 0)) != 0)
335                 {
336                         char buffer[80];
337
338                         sprintf(buffer, "Error setting file [%s] to unbuffered", routfilename);
339                         perror(buffer);
340                         exit(1);
341                 }
342         }
343
344         if((setvbuf(stdout, (char *)NULL, _IOLBF, 0)) != 0)
345         {
346                 char buffer[80];
347
348                 sprintf(buffer, "Error setting stdout to line-buffered");
349                 perror(buffer);
350                 exit(1);
351         }
352
353         if(!Popt)
354         {
355                 if((switch_driver(enable_trace, Rx, Tx)) == -1)
356                         exit(1);
357                 else
358                         traceon = 1;
359         }
360                 
361         signal(SIGHUP, SIG_IGN);        /* ignore hangup signal */
362         signal(SIGUSR1, reopenfiles);   /* rotate logfile(s)    */      
363
364         time(&tm);
365         
366         if(analyze)
367         {
368                 sprintf(headerbuf, "\n==== isdnanalyze controller rx #%d - tx #%d ==== started %s",
369                                 Rx, Tx, ctime(&tm));
370         }
371         else
372         {
373                 sprintf(headerbuf, "\n=========== isdntrace controller #%d =========== started %s",
374                                 unit, ctime(&tm));
375         }
376         
377         printf("%s", headerbuf);
378         
379         if(outflag)
380                 fprintf(Fout, "%s", headerbuf);
381
382         for (;;)
383         {
384                 if(Popt == 0)
385                 {
386                         n = read(f, buf, BSIZE);
387
388                         if(Bopt)
389                         {
390                                 if((fwrite(buf, 1, n, BP)) != n)
391                                 {
392                                         char buffer[80];
393                                         sprintf(buffer, "Error writing file [%s]", rBPfilename);
394                                         perror(buffer);
395                                         exit(1);
396                                 }
397                         }
398
399                         n -= sizeof(i4b_trace_hdr_t);                   
400                 }
401                 else
402                 {                       
403 again:
404                         if((fread(buf, 1, sizeof(i4b_trace_hdr_t), BP)) != sizeof(i4b_trace_hdr_t))
405                         {
406                                 if(feof(BP))
407                                 {
408                                         if(Fopt)
409                                         {
410                                                 if(ferror(BP))
411                                                 {
412                                                         char buffer[80];
413                                                         sprintf(buffer, "Error reading hdr from file [%s]", rBPfilename);
414                                                         perror(buffer);
415                                                         exit(1);
416                                                 }
417
418                                                 usleep(250000);
419                                                 clearerr(BP);
420
421                                                 if(stat(rBPfilename, &fstnew) != -1)
422                                                 {
423                                                         if((fst.st_ino != fstnew.st_ino) ||
424                                                            (fstnew.st_nlink == 0))
425                                                         {
426                                                                 if((BP = freopen(rBPfilename, "r", BP)) == NULL)
427                                                                 {
428                                                                         char buffer[80];
429                                                                         sprintf(buffer, "Error reopening file [%s]", rBPfilename);
430                                                                         perror(buffer);
431                                                                         exit(1);
432                                                                 }
433                                                                 stat(rBPfilename, &fst);
434                                                         }
435                                                 }
436                                                 goto again;
437                                         }
438                                         else
439                                         {
440                                                 printf("\nEnd of playback input file reached.\n");
441                                                 exit(0);
442                                         }
443                                 }
444                                 else
445                                 {
446                                         char buffer[80];
447                                         sprintf(buffer, "Error reading hdr from file [%s]", rBPfilename);
448                                         perror(buffer);
449                                         exit(1);
450                                 }
451                         }
452
453                         ithp = (i4b_trace_hdr_t *)buf;
454                         l = ithp->length - sizeof(i4b_trace_hdr_t);
455                         
456                         if((n = fread(buf+sizeof(i4b_trace_hdr_t), 1, l , BP)) != l)
457                         {
458                                 char buffer[80];
459                                 sprintf(buffer, "Error reading data from file [%s]", rBPfilename);
460                                 perror(buffer);
461                                 exit(1);
462                         }
463
464                 }
465
466                 if((n > 0) && (n > noct))
467                 {
468                         dumpbuf(n, b, (i4b_trace_hdr_t *)buf, raw);
469                 }
470         }
471 }
472
473 /*---------------------------------------------------------------------------*
474  *      format header into static buffer, return buffer address
475  *---------------------------------------------------------------------------*/
476 char *
477 fmt_hdr(i4b_trace_hdr_t *hdr, int frm_len)
478 {
479         struct tm *s;
480         static char hbuf[256];
481         int i = 0;
482
483         s = localtime((time_t *)&(hdr->time.tv_sec));
484
485         if(hdr->type == TRC_CH_I)               /* Layer 1 INFO's */
486         {
487                 sprintf(hbuf,"\n-- %s - unit:%d ---------------- time:%2.2d.%2.2d %2.2d:%2.2d:%2.2d.%06u ",
488                         ((hdr->dir) ? "NT->TE" : "TE->NT"),
489                         hdr->unit,
490                         s->tm_mday,
491                         s->tm_mon + 1,
492                         s->tm_hour,
493                         s->tm_min,
494                         s->tm_sec,
495                         (u_int32_t)hdr->time.tv_usec);
496         }
497         else
498         {
499                 if(hdr->trunc > 0)
500                 {
501                         sprintf(hbuf,"\n-- %s - unit:%d - frame:%6.6u - time:%2.2d.%2.2d %2.2d:%2.2d:%2.2d.%06u - length:%d (%d) ",
502                                 ((hdr->dir) ? "NT->TE" : "TE->NT"),
503                                 hdr->unit,
504                                 hdr->count,
505                                 s->tm_mday,
506                                 s->tm_mon + 1,
507                                 s->tm_hour,
508                                 s->tm_min,
509                                 s->tm_sec,
510                                 (u_int32_t)hdr->time.tv_usec,
511                                 frm_len,
512                                 hdr->trunc);
513                 }
514                 else
515                 {
516                         sprintf(hbuf,"\n-- %s - unit:%d - frame:%6.6u - time:%2.2d.%2.2d %2.2d:%2.2d:%2.2d.%06u - length:%d ",
517                                 ((hdr->dir) ? "NT->TE" : "TE->NT"),
518                                 hdr->unit,
519                                 hdr->count,
520                                 s->tm_mday,
521                                 s->tm_mon + 1,
522                                 s->tm_hour,
523                                 s->tm_min,
524                                 s->tm_sec,
525                                 (u_int32_t)hdr->time.tv_usec,
526                                 frm_len);
527                 }
528         }
529         
530         for(i=strlen(hbuf); i <= NCOLS;)
531                 hbuf[i++] = '-';
532
533         hbuf[i++] = '\n';
534         hbuf[i] = '\0';
535         
536         return(hbuf);
537 }
538
539 /*---------------------------------------------------------------------------*
540  *      decode protocol and output to file(s)
541  *---------------------------------------------------------------------------*/
542 static void
543 dumpbuf(int n, unsigned char *buf, i4b_trace_hdr_t *hdr, int raw)
544 {
545         static char l1buf[128];
546         static unsigned char l2buf[32000];
547         static unsigned char l3buf[32000];
548         int cnt;
549         int nsave = n;
550         char *pbuf;
551         int i, j;
552
553         l1buf[0] = '\0';
554         l2buf[0] = '\0';
555         l3buf[0] = '\0';
556
557         switch(hdr->type)
558         {
559                 case TRC_CH_I:          /* Layer 1 INFO's */
560
561                         /* on playback, don't display layer 1 if -i ! */
562                         if(!(enable_trace & TRACE_I))
563                                 break;
564                                 
565                         pbuf = &l1buf[0];
566
567                         switch(buf[0])
568                         {
569                                 case INFO0:
570                                         sprintf((pbuf+strlen(pbuf)),"I430: INFO0 (No Signal)\n");
571                                         break;
572         
573                                 case INFO1_8:
574                                         sprintf((pbuf+strlen(pbuf)),"I430: INFO1 (Activation Request, Priority = 8, from TE)\n");
575                                         break;
576         
577                                 case INFO1_10:
578                                         sprintf((pbuf+strlen(pbuf)),"I430: INFO1 (Activation Request, Priority = 10, from TE)\n");
579                                         break;
580         
581                                 case INFO2:
582                                         sprintf((pbuf+strlen(pbuf)),"I430: INFO2 (Pending Activation, from NT)\n");
583                                         break;
584         
585                                 case INFO3:
586                                         sprintf((pbuf+strlen(pbuf)),"I430: INFO3 (Synchronized, from TE)\n");
587                                         break;
588         
589                                 case INFO4_8:
590                                         sprintf((pbuf+strlen(pbuf)),"I430: INFO4 (Activated, Priority = 8/9, from NT)\n");
591                                         break;
592         
593                                 case INFO4_10:
594                                         sprintf((pbuf+strlen(pbuf)),"I430: INFO4 (Activated, Priority = 10/11, from NT)\n");
595                                         break;
596         
597                                 default:
598                                         sprintf((pbuf+strlen(pbuf)),"I430: ERROR, invalid INFO value 0x%x!\n", buf[0]);
599                                         break;
600                         }
601                         break;
602                         
603                 case TRC_CH_D:          /* D-channel data */
604
605                         cnt = decode_lapd(l2buf, n, buf, hdr->dir, raw, print_q921);
606                 
607                         n -= cnt;
608                         buf += cnt;
609                 
610                         if(n)
611                         {
612                                 switch(*buf)
613                                 {
614                                         case 0x40:
615                                         case 0x41:
616                                                 decode_1tr6(l3buf, n, cnt, buf, raw);
617                                                 break;
618                                                 
619                                         case 0x08:
620                                                 decode_q931(l3buf, n, cnt, buf, raw);
621                                                 break;
622
623                                         default:
624                                                 if(xopt)
625                                                 {
626                                                         l2buf[0] = '\0';
627                                                         l3buf[0] = '\0';
628                                                 }
629                                                 else
630                                                 {       
631                                                         decode_unknownl3(l3buf, n, cnt, buf, raw);
632                                                 }
633                                                 break;
634                                 }
635                         }
636                         break;
637
638                 default:        /* B-channel data */
639         
640                         pbuf = &l2buf[0];
641         
642                         for (i = 0; i < n; i += 16)
643                         {
644                                 sprintf((pbuf+strlen(pbuf)),"B%d:%.3x  ", hdr->type, i);
645         
646                                 for (j = 0; j < 16; j++)
647                                         if (i + j < n)
648                                                 sprintf((pbuf+strlen(pbuf)),"%02x ", buf[i + j]);
649                                         else
650                                                 sprintf((pbuf+strlen(pbuf)),"   ");
651         
652                                 sprintf((pbuf+strlen(pbuf)),"      ");
653         
654                                 for (j = 0; j < 16 && i + j < n; j++)
655                                         if (isprint(buf[i + j]))
656                                                 sprintf((pbuf+strlen(pbuf)),"%c", buf[i + j]);
657                                         else
658                                                 sprintf((pbuf+strlen(pbuf)),".");
659         
660                                 sprintf((pbuf+strlen(pbuf)),"\n");
661                         }
662                         break;
663         }
664         
665         if(header && ((l1buf[0] != '\0' || l2buf[0] != '\0') || (l3buf[0] != 0)))
666         {
667                 char *p;
668                 p = fmt_hdr(hdr, nsave);
669                 printf("%s", p);
670                 if(outflag)
671                         fprintf(Fout, "%s", p);
672         }
673
674         if(l1buf[0] != '\0')
675         {       
676                 printf("%s", l1buf);
677                 if(outflag)
678                         fprintf(Fout, "%s", l1buf);
679         }
680
681         if(l2buf[0] != '\0')
682         {       
683                 printf("%s", l2buf);
684                 if(outflag)
685                         fprintf(Fout, "%s", l2buf);
686         }
687
688         if(l3buf[0] != '\0')
689         {
690                 printf("%s", l3buf);
691                 if(outflag)
692                         fprintf(Fout, "%s", l3buf);
693         }
694 }
695
696 /*---------------------------------------------------------------------------*
697  *      exit handler function to be called at program exit
698  *---------------------------------------------------------------------------*/
699 void
700 exit_hdl()
701 {
702         if(traceon)
703                 switch_driver(TRACE_OFF, Rx, Tx);
704 }
705
706 /*---------------------------------------------------------------------------*
707  *      switch driver debugging output on/off
708  *---------------------------------------------------------------------------*/
709 static int
710 switch_driver(int value, int rx, int tx)
711 {
712         char buffer[80];
713         int v = value;
714
715         if(analyze == 0)
716         {
717                 if(ioctl(f, I4B_TRC_SET, &v) < 0)
718                 {
719                         sprintf(buffer, "Error ioctl I4B_TRC_SET, val = %d", v);
720                         perror(buffer);
721                         return(-1);
722                 }
723         }
724         else
725         {
726                 if(value == TRACE_OFF)
727                 {
728                         if(ioctl(f, I4B_TRC_RESETA, &v) < 0)
729                         {
730                                 sprintf(buffer, "Error ioctl I4B_TRC_RESETA - ");
731                                 perror(buffer);
732                                 return(-1);
733                         }
734                 }
735                 else
736                 {
737                         i4b_trace_setupa_t tsa;
738                         
739                         tsa.rxunit = rx;
740                         tsa.rxflags = value;
741                         tsa.txunit = tx;
742                         tsa.txflags = value;
743                         
744                         if(ioctl(f, I4B_TRC_SETA, &tsa) < 0)
745                         {
746                                 sprintf(buffer, "Error ioctl I4B_TRC_SETA, val = %d", v);
747                                 perror(buffer);
748                                 return(-1);
749                         }
750                 }
751         }
752         return(0);
753 }
754
755 /*---------------------------------------------------------------------------*
756  *      reopen files to support rotating logfile(s) on SIGUSR1
757  *
758  *      based on an idea from Ripley (ripley@nostromo.in-berlin.de)
759  *
760  *      close file and reopen it for append. this will be a nop
761  *      if the previously opened file hasn't moved but will open
762  *      a new one otherwise, thus enabling a rotation...
763  * 
764  *---------------------------------------------------------------------------*/
765 static void
766 reopenfiles(int dummy)
767 {
768         if(outflag)
769         {
770                 fclose(Fout);
771
772                 add_datetime(outfilename, routfilename);
773                 
774                 if((Fout = fopen(routfilename, "a")) == NULL)
775                 {
776                         char buffer[80];
777
778                         sprintf(buffer, "Error re-opening file [%s]", routfilename);
779                         perror(buffer);
780                         exit(1);
781                 }
782
783                 if((setvbuf(Fout, (char *)NULL, _IONBF, 0)) != 0)
784                 {
785                         char buffer[80];
786
787                         sprintf(buffer, "Error re-setting file [%s] to unbuffered", routfilename);
788                         perror(buffer);
789                         exit(1);
790                 }
791         }
792
793         if(Bopt)
794         {
795                 
796                 fclose(BP);
797
798                 add_datetime(BPfilename, rBPfilename);
799                 
800                 if((BP = fopen(rBPfilename, "a")) == NULL)
801                 {
802                         char buffer[80];
803
804                         sprintf(buffer, "Error re-opening file [%s]", rBPfilename);
805                         perror(buffer);
806                         exit(1);
807                 }
808
809                 if((setvbuf(BP, (char *)NULL, _IONBF, 0)) != 0)
810                 {
811                         char buffer[80];
812
813                         sprintf(buffer, "Error re-setting file [%s] to unbuffered", rBPfilename);
814                         perror(buffer);
815                         exit(1);
816                 }
817         }
818 }
819
820 void
821 add_datetime(char *filename, char *rfilename)
822 {
823         time_t timeb;
824         struct tm *tmp;
825         FILE *fx;
826
827         time(&timeb);
828         tmp = localtime(&timeb);
829         
830         sprintf(rfilename, "%s-", filename);
831
832         strftime(rfilename+strlen(rfilename), MAXPATHLEN-strlen(rfilename)-1,
833                 "%Y%m%d-%H%M%S", tmp);
834                 
835         if((fx = fopen(rfilename, "r")) != NULL)
836         {
837                 fclose(fx);
838
839                 sleep(1);
840
841                 time(&timeb);
842                 tmp = localtime(&timeb);
843         
844                 sprintf(rfilename, "%s-", filename);
845
846                 strftime(rfilename+strlen(rfilename), MAXPATHLEN-strlen(rfilename)-1,
847                         "%Y%m%d-%H%M%S", tmp);
848         }
849 }
850         
851 /* EOF */