]> CyberLeo.Net >> Repos - FreeBSD/releng/7.2.git/blob - usr.sbin/i4b/isdntrace/trace.c
Create releng/7.2 from stable/7 in preparation for 7.2-RELEASE.
[FreeBSD/releng/7.2.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$
41  *
42  *      last edit-date: [Mon Aug 28 09:03:46 2000]
43  *
44  *---------------------------------------------------------------------------*/
45
46 #include "trace.h"
47 #include <unistd.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         char devicename[80];
125         char headerbuf[256];
126                 
127         int n;
128         int c;
129         char *b;
130
131         char *outfile = TRACE_FILE_NAME;
132         char *binfile = BIN_FILE_NAME;
133         int outfileset = 0;
134         int raw = 1;
135         int noct = -1;
136         time_t tm;
137         i4b_trace_hdr_t *ithp = NULL;
138         int l;
139         static struct stat fstnew;      
140
141         b = &buf[sizeof(i4b_trace_hdr_t)];
142         
143         while( (c = getopt(argc, argv, "abdf:hiln:op:ru:xBFPR:T:")) != -1)
144         {
145                 switch(c)
146                 {
147                         case 'a':
148                                 analyze = 1;
149                                 break;
150                                 
151                         case 'b':
152                                 enable_trace |= (TRACE_B_RX | TRACE_B_TX);
153                                 break;
154
155                         case 'd':
156                                 enable_trace &= (~(TRACE_D_TX | TRACE_D_RX));
157                                 break;
158
159                         case 'o':
160                                 outflag = 0;
161                                 break;
162
163                         case 'f':
164                                 outfile = optarg;
165                                 outfileset = 1;
166                                 break;
167                         
168                         case 'n':
169                                 noct = atoi(optarg);
170                                 break;
171
172                         case 'h':
173                                 header = 0;
174                                 break;
175
176                         case 'i':
177                                 enable_trace |= TRACE_I;
178                                 info = 1;
179                                 break;
180
181                         case 'l':
182                                 print_q921 = 0;
183                                 break;
184
185                         case 'p':
186                                 binfile = optarg;
187                                 bpopt = 1;
188                                 break;
189                         
190                         case 'r':
191                                 raw = 0;
192                                 break;
193
194                         case 'u':
195                                 unit = atoi(optarg);
196                                 if(unit < 0 || unit >= MAX_CONTROLLERS)
197                                         usage();
198                                 break;
199
200                         case 'x':
201                                 xopt = 0;
202                                 break;
203
204                         case 'B':
205                                 Bopt = 1;
206                                 break;
207                         
208                         case 'F':
209                                 Fopt = 1;
210                                 break;
211                         
212                         case 'P':
213                                 Popt = 1;
214                                 break;
215                         
216                         case 'R':
217                                 Rx = atoi(optarg);
218                                 if(Rx < 0 || Rx >= MAX_CONTROLLERS)
219                                         usage();
220                                 break;
221
222                         case 'T':
223                                 Tx = atoi(optarg);
224                                 if(Tx < 0 || Tx >= MAX_CONTROLLERS)
225                                         usage();
226                                 break;
227
228                         case '?':
229                         default:
230                                 usage();
231                                 break;
232                 }
233         }
234
235         if(enable_trace == 0)
236                 usage();
237
238         if(Bopt && Popt)
239                 usage();
240                 
241         atexit(exit_hdl);
242
243         if(Bopt)
244         {
245                 if(bpopt)
246                         sprintf(BPfilename, "%s", binfile);
247                 else
248                         sprintf(BPfilename, "%s%d", BIN_FILE_NAME, unit);
249                         
250                 add_datetime(BPfilename, rBPfilename);
251
252                 if((BP = fopen(rBPfilename, "w")) == NULL)
253                 {
254                         char buffer[80];
255
256                         sprintf(buffer, "Error opening file [%s]", rBPfilename);
257                         perror(buffer);
258                         exit(1);
259                 }
260                 
261                 if((setvbuf(BP, (char *)NULL, _IONBF, 0)) != 0)
262                 {
263                         char buffer[80];
264
265                         sprintf(buffer, "Error setting file [%s] to unbuffered", rBPfilename);
266                         perror(buffer);
267                         exit(1);
268                 }
269         }               
270
271         if(Popt)
272         {
273                 if(bpopt)
274                         sprintf(BPfilename, "%s", binfile);
275                 else
276                         sprintf(BPfilename, "%s%d", BIN_FILE_NAME, unit);
277                         
278                 strcpy(rBPfilename, BPfilename);
279                 
280                 if((BP = fopen(BPfilename, "r")) == NULL)
281                 {
282                         char buffer[80];
283
284                         sprintf(buffer, "Error opening file [%s]", BPfilename);
285                         perror(buffer);
286                         exit(1);
287                 }
288                 if(Fopt)
289                 {
290                         if(fstat(fileno(BP), &fst))
291                         {
292                                 char buffer[80];
293                                 sprintf(buffer, "Error fstat file [%s]", BPfilename);
294                                 perror(buffer);
295                                 exit(1);
296                         }
297                 }
298         }
299         else
300         {               
301                 sprintf(devicename, "%s%d", I4BTRC_DEVICE, unit);
302         
303                 if((f = open(devicename, O_RDWR)) < 0)
304                 {
305                         char buffer[80];
306         
307                         sprintf(buffer, "Error opening trace device [%s]", devicename);
308                         perror(buffer);
309                         exit(1);
310                 }
311         }
312         
313         if(outflag)
314         {
315                 if(outfileset == 0)
316                         sprintf(outfilename, "%s%d", TRACE_FILE_NAME, unit);
317                 else
318                         strcpy(outfilename, outfile);
319                         
320                 add_datetime(outfilename, routfilename);
321                         
322                 if((Fout = fopen(routfilename, "w")) == NULL)
323                 {
324                         char buffer[80];
325
326                         sprintf(buffer, "Error opening file [%s]", routfilename);
327                         perror(buffer);
328                         exit(1);
329                 }
330                 
331                 if((setvbuf(Fout, (char *)NULL, _IONBF, 0)) != 0)
332                 {
333                         char buffer[80];
334
335                         sprintf(buffer, "Error setting file [%s] to unbuffered", routfilename);
336                         perror(buffer);
337                         exit(1);
338                 }
339         }
340
341         if((setvbuf(stdout, (char *)NULL, _IOLBF, 0)) != 0)
342         {
343                 char buffer[80];
344
345                 sprintf(buffer, "Error setting stdout to line-buffered");
346                 perror(buffer);
347                 exit(1);
348         }
349
350         if(!Popt)
351         {
352                 if((switch_driver(enable_trace, Rx, Tx)) == -1)
353                         exit(1);
354                 else
355                         traceon = 1;
356         }
357                 
358         signal(SIGHUP, SIG_IGN);        /* ignore hangup signal */
359         signal(SIGUSR1, reopenfiles);   /* rotate logfile(s)    */      
360
361         time(&tm);
362         
363         if(analyze)
364         {
365                 sprintf(headerbuf, "\n==== isdnanalyze controller rx #%d - tx #%d ==== started %s",
366                                 Rx, Tx, ctime(&tm));
367         }
368         else
369         {
370                 sprintf(headerbuf, "\n=========== isdntrace controller #%d =========== started %s",
371                                 unit, ctime(&tm));
372         }
373         
374         printf("%s", headerbuf);
375         
376         if(outflag)
377                 fprintf(Fout, "%s", headerbuf);
378
379         for (;;)
380         {
381                 if(Popt == 0)
382                 {
383                         n = read(f, buf, BSIZE);
384
385                         if(Bopt)
386                         {
387                                 if((fwrite(buf, 1, n, BP)) != n)
388                                 {
389                                         char buffer[80];
390                                         sprintf(buffer, "Error writing file [%s]", rBPfilename);
391                                         perror(buffer);
392                                         exit(1);
393                                 }
394                         }
395
396                         n -= sizeof(i4b_trace_hdr_t);                   
397                 }
398                 else
399                 {                       
400 again:
401                         if((fread(buf, 1, sizeof(i4b_trace_hdr_t), BP)) != sizeof(i4b_trace_hdr_t))
402                         {
403                                 if(feof(BP))
404                                 {
405                                         if(Fopt)
406                                         {
407                                                 if(ferror(BP))
408                                                 {
409                                                         char buffer[80];
410                                                         sprintf(buffer, "Error reading hdr from file [%s]", rBPfilename);
411                                                         perror(buffer);
412                                                         exit(1);
413                                                 }
414
415                                                 usleep(250000);
416                                                 clearerr(BP);
417
418                                                 if(stat(rBPfilename, &fstnew) != -1)
419                                                 {
420                                                         if((fst.st_ino != fstnew.st_ino) ||
421                                                            (fstnew.st_nlink == 0))
422                                                         {
423                                                                 if((BP = freopen(rBPfilename, "r", BP)) == NULL)
424                                                                 {
425                                                                         char buffer[80];
426                                                                         sprintf(buffer, "Error reopening file [%s]", rBPfilename);
427                                                                         perror(buffer);
428                                                                         exit(1);
429                                                                 }
430                                                                 stat(rBPfilename, &fst);
431                                                         }
432                                                 }
433                                                 goto again;
434                                         }
435                                         else
436                                         {
437                                                 printf("\nEnd of playback input file reached.\n");
438                                                 exit(0);
439                                         }
440                                 }
441                                 else
442                                 {
443                                         char buffer[80];
444                                         sprintf(buffer, "Error reading hdr from file [%s]", rBPfilename);
445                                         perror(buffer);
446                                         exit(1);
447                                 }
448                         }
449
450                         ithp = (i4b_trace_hdr_t *)buf;
451                         l = ithp->length - sizeof(i4b_trace_hdr_t);
452                         
453                         if((n = fread(buf+sizeof(i4b_trace_hdr_t), 1, l , BP)) != l)
454                         {
455                                 char buffer[80];
456                                 sprintf(buffer, "Error reading data from file [%s]", rBPfilename);
457                                 perror(buffer);
458                                 exit(1);
459                         }
460
461                 }
462
463                 if((n > 0) && (n > noct))
464                 {
465                         dumpbuf(n, b, (i4b_trace_hdr_t *)buf, raw);
466                 }
467         }
468 }
469
470 /*---------------------------------------------------------------------------*
471  *      format header into static buffer, return buffer address
472  *---------------------------------------------------------------------------*/
473 char *
474 fmt_hdr(i4b_trace_hdr_t *hdr, int frm_len)
475 {
476         struct tm *s;
477         static char hbuf[256];
478         int i = 0;
479
480         s = localtime((time_t *)&(hdr->time.tv_sec));
481
482         if(hdr->type == TRC_CH_I)               /* Layer 1 INFO's */
483         {
484                 sprintf(hbuf,"\n-- %s - unit:%d ---------------- time:%2.2d.%2.2d %2.2d:%2.2d:%2.2d.%06u ",
485                         ((hdr->dir) ? "NT->TE" : "TE->NT"),
486                         hdr->unit,
487                         s->tm_mday,
488                         s->tm_mon + 1,
489                         s->tm_hour,
490                         s->tm_min,
491                         s->tm_sec,
492                         (u_int32_t)hdr->time.tv_usec);
493         }
494         else
495         {
496                 if(hdr->trunc > 0)
497                 {
498                         sprintf(hbuf,"\n-- %s - unit:%d - frame:%6.6u - time:%2.2d.%2.2d %2.2d:%2.2d:%2.2d.%06u - length:%d (%d) ",
499                                 ((hdr->dir) ? "NT->TE" : "TE->NT"),
500                                 hdr->unit,
501                                 hdr->count,
502                                 s->tm_mday,
503                                 s->tm_mon + 1,
504                                 s->tm_hour,
505                                 s->tm_min,
506                                 s->tm_sec,
507                                 (u_int32_t)hdr->time.tv_usec,
508                                 frm_len,
509                                 hdr->trunc);
510                 }
511                 else
512                 {
513                         sprintf(hbuf,"\n-- %s - unit:%d - frame:%6.6u - time:%2.2d.%2.2d %2.2d:%2.2d:%2.2d.%06u - length:%d ",
514                                 ((hdr->dir) ? "NT->TE" : "TE->NT"),
515                                 hdr->unit,
516                                 hdr->count,
517                                 s->tm_mday,
518                                 s->tm_mon + 1,
519                                 s->tm_hour,
520                                 s->tm_min,
521                                 s->tm_sec,
522                                 (u_int32_t)hdr->time.tv_usec,
523                                 frm_len);
524                 }
525         }
526         
527         for(i=strlen(hbuf); i <= NCOLS;)
528                 hbuf[i++] = '-';
529
530         hbuf[i++] = '\n';
531         hbuf[i] = '\0';
532         
533         return(hbuf);
534 }
535
536 /*---------------------------------------------------------------------------*
537  *      decode protocol and output to file(s)
538  *---------------------------------------------------------------------------*/
539 static void
540 dumpbuf(int n, unsigned char *buf, i4b_trace_hdr_t *hdr, int raw)
541 {
542         static char l1buf[128];
543         static unsigned char l2buf[32000];
544         static unsigned char l3buf[32000];
545         int cnt;
546         int nsave = n;
547         char *pbuf;
548         int i, j;
549
550         l1buf[0] = '\0';
551         l2buf[0] = '\0';
552         l3buf[0] = '\0';
553
554         switch(hdr->type)
555         {
556                 case TRC_CH_I:          /* Layer 1 INFO's */
557
558                         /* on playback, don't display layer 1 if -i ! */
559                         if(!(enable_trace & TRACE_I))
560                                 break;
561                                 
562                         pbuf = &l1buf[0];
563
564                         switch(buf[0])
565                         {
566                                 case INFO0:
567                                         sprintf((pbuf+strlen(pbuf)),"I430: INFO0 (No Signal)\n");
568                                         break;
569         
570                                 case INFO1_8:
571                                         sprintf((pbuf+strlen(pbuf)),"I430: INFO1 (Activation Request, Priority = 8, from TE)\n");
572                                         break;
573         
574                                 case INFO1_10:
575                                         sprintf((pbuf+strlen(pbuf)),"I430: INFO1 (Activation Request, Priority = 10, from TE)\n");
576                                         break;
577         
578                                 case INFO2:
579                                         sprintf((pbuf+strlen(pbuf)),"I430: INFO2 (Pending Activation, from NT)\n");
580                                         break;
581         
582                                 case INFO3:
583                                         sprintf((pbuf+strlen(pbuf)),"I430: INFO3 (Synchronized, from TE)\n");
584                                         break;
585         
586                                 case INFO4_8:
587                                         sprintf((pbuf+strlen(pbuf)),"I430: INFO4 (Activated, Priority = 8/9, from NT)\n");
588                                         break;
589         
590                                 case INFO4_10:
591                                         sprintf((pbuf+strlen(pbuf)),"I430: INFO4 (Activated, Priority = 10/11, from NT)\n");
592                                         break;
593         
594                                 default:
595                                         sprintf((pbuf+strlen(pbuf)),"I430: ERROR, invalid INFO value 0x%x!\n", buf[0]);
596                                         break;
597                         }
598                         break;
599                         
600                 case TRC_CH_D:          /* D-channel data */
601
602                         cnt = decode_lapd(l2buf, n, buf, hdr->dir, raw, print_q921);
603                 
604                         n -= cnt;
605                         buf += cnt;
606                 
607                         if(n)
608                         {
609                                 switch(*buf)
610                                 {
611                                         case 0x40:
612                                         case 0x41:
613                                                 decode_1tr6(l3buf, n, cnt, buf, raw);
614                                                 break;
615                                                 
616                                         case 0x08:
617                                                 decode_q931(l3buf, n, cnt, buf, raw);
618                                                 break;
619
620                                         default:
621                                                 if(xopt)
622                                                 {
623                                                         l2buf[0] = '\0';
624                                                         l3buf[0] = '\0';
625                                                 }
626                                                 else
627                                                 {       
628                                                         decode_unknownl3(l3buf, n, cnt, buf, raw);
629                                                 }
630                                                 break;
631                                 }
632                         }
633                         break;
634
635                 default:        /* B-channel data */
636         
637                         pbuf = &l2buf[0];
638         
639                         for (i = 0; i < n; i += 16)
640                         {
641                                 sprintf((pbuf+strlen(pbuf)),"B%d:%.3x  ", hdr->type, i);
642         
643                                 for (j = 0; j < 16; j++)
644                                         if (i + j < n)
645                                                 sprintf((pbuf+strlen(pbuf)),"%02x ", buf[i + j]);
646                                         else
647                                                 sprintf((pbuf+strlen(pbuf)),"   ");
648         
649                                 sprintf((pbuf+strlen(pbuf)),"      ");
650         
651                                 for (j = 0; j < 16 && i + j < n; j++)
652                                         if (isprint(buf[i + j]))
653                                                 sprintf((pbuf+strlen(pbuf)),"%c", buf[i + j]);
654                                         else
655                                                 sprintf((pbuf+strlen(pbuf)),".");
656         
657                                 sprintf((pbuf+strlen(pbuf)),"\n");
658                         }
659                         break;
660         }
661         
662         if(header && ((l1buf[0] != '\0' || l2buf[0] != '\0') || (l3buf[0] != 0)))
663         {
664                 char *p;
665                 p = fmt_hdr(hdr, nsave);
666                 printf("%s", p);
667                 if(outflag)
668                         fprintf(Fout, "%s", p);
669         }
670
671         if(l1buf[0] != '\0')
672         {       
673                 printf("%s", l1buf);
674                 if(outflag)
675                         fprintf(Fout, "%s", l1buf);
676         }
677
678         if(l2buf[0] != '\0')
679         {       
680                 printf("%s", l2buf);
681                 if(outflag)
682                         fprintf(Fout, "%s", l2buf);
683         }
684
685         if(l3buf[0] != '\0')
686         {
687                 printf("%s", l3buf);
688                 if(outflag)
689                         fprintf(Fout, "%s", l3buf);
690         }
691 }
692
693 /*---------------------------------------------------------------------------*
694  *      exit handler function to be called at program exit
695  *---------------------------------------------------------------------------*/
696 void
697 exit_hdl()
698 {
699         if(traceon)
700                 switch_driver(TRACE_OFF, Rx, Tx);
701 }
702
703 /*---------------------------------------------------------------------------*
704  *      switch driver debugging output on/off
705  *---------------------------------------------------------------------------*/
706 static int
707 switch_driver(int value, int rx, int tx)
708 {
709         char buffer[80];
710         int v = value;
711
712         if(analyze == 0)
713         {
714                 if(ioctl(f, I4B_TRC_SET, &v) < 0)
715                 {
716                         sprintf(buffer, "Error ioctl I4B_TRC_SET, val = %d", v);
717                         perror(buffer);
718                         return(-1);
719                 }
720         }
721         else
722         {
723                 if(value == TRACE_OFF)
724                 {
725                         if(ioctl(f, I4B_TRC_RESETA, &v) < 0)
726                         {
727                                 sprintf(buffer, "Error ioctl I4B_TRC_RESETA - ");
728                                 perror(buffer);
729                                 return(-1);
730                         }
731                 }
732                 else
733                 {
734                         i4b_trace_setupa_t tsa;
735                         
736                         tsa.rxunit = rx;
737                         tsa.rxflags = value;
738                         tsa.txunit = tx;
739                         tsa.txflags = value;
740                         
741                         if(ioctl(f, I4B_TRC_SETA, &tsa) < 0)
742                         {
743                                 sprintf(buffer, "Error ioctl I4B_TRC_SETA, val = %d", v);
744                                 perror(buffer);
745                                 return(-1);
746                         }
747                 }
748         }
749         return(0);
750 }
751
752 /*---------------------------------------------------------------------------*
753  *      reopen files to support rotating logfile(s) on SIGUSR1
754  *
755  *      based on an idea from Ripley (ripley@nostromo.in-berlin.de)
756  *
757  *      close file and reopen it for append. this will be a nop
758  *      if the previously opened file hasn't moved but will open
759  *      a new one otherwise, thus enabling a rotation...
760  * 
761  *---------------------------------------------------------------------------*/
762 static void
763 reopenfiles(int dummy)
764 {
765         if(outflag)
766         {
767                 fclose(Fout);
768
769                 add_datetime(outfilename, routfilename);
770                 
771                 if((Fout = fopen(routfilename, "a")) == NULL)
772                 {
773                         char buffer[80];
774
775                         sprintf(buffer, "Error re-opening file [%s]", routfilename);
776                         perror(buffer);
777                         exit(1);
778                 }
779
780                 if((setvbuf(Fout, (char *)NULL, _IONBF, 0)) != 0)
781                 {
782                         char buffer[80];
783
784                         sprintf(buffer, "Error re-setting file [%s] to unbuffered", routfilename);
785                         perror(buffer);
786                         exit(1);
787                 }
788         }
789
790         if(Bopt)
791         {
792                 
793                 fclose(BP);
794
795                 add_datetime(BPfilename, rBPfilename);
796                 
797                 if((BP = fopen(rBPfilename, "a")) == NULL)
798                 {
799                         char buffer[80];
800
801                         sprintf(buffer, "Error re-opening file [%s]", rBPfilename);
802                         perror(buffer);
803                         exit(1);
804                 }
805
806                 if((setvbuf(BP, (char *)NULL, _IONBF, 0)) != 0)
807                 {
808                         char buffer[80];
809
810                         sprintf(buffer, "Error re-setting file [%s] to unbuffered", rBPfilename);
811                         perror(buffer);
812                         exit(1);
813                 }
814         }
815 }
816
817 void
818 add_datetime(char *filename, char *rfilename)
819 {
820         time_t timeb;
821         struct tm *tmp;
822         FILE *fx;
823
824         time(&timeb);
825         tmp = localtime(&timeb);
826         
827         sprintf(rfilename, "%s-", filename);
828
829         strftime(rfilename+strlen(rfilename), MAXPATHLEN-strlen(rfilename)-1,
830                 "%Y%m%d-%H%M%S", tmp);
831                 
832         if((fx = fopen(rfilename, "r")) != NULL)
833         {
834                 fclose(fx);
835
836                 sleep(1);
837
838                 time(&timeb);
839                 tmp = localtime(&timeb);
840         
841                 sprintf(rfilename, "%s-", filename);
842
843                 strftime(rfilename+strlen(rfilename), MAXPATHLEN-strlen(rfilename)-1,
844                         "%Y%m%d-%H%M%S", tmp);
845         }
846 }
847         
848 /* EOF */