Merge branch 'newpc92timings' of /scm/spider into newpc92timings
[spider.git] / src / debug.c
1 /*
2  * debug routines
3  *
4  * Copyright (c) 1998 Dirk Koopman G1TLH
5  *
6  * $Id$
7  */
8
9 #include <stdio.h>
10 #include <stdarg.h>
11 #include <errno.h>
12 #include <time.h>
13 #include <string.h>
14 #include <sys/stat.h>
15 #include <unistd.h>
16
17 #include "debug.h"
18
19 #define LOGDIR "./dbg"
20
21 static char opened = 0;
22 unsigned long dbglevel = 0;
23 static int pid;
24 static char *prog;
25 static FILE *f;
26 static int thisday;
27 static time_t systime;
28
29 void (*dbgproc)();
30 char dbgbuf[1500];
31
32 static int getdayno(time_t t)
33 {
34         struct tm *tm;
35         
36         tm = gmtime(&t);
37         return tm->tm_mday;
38 }
39
40 static char *genlogname(char *dir, char *fn, int day, int readonly)
41 {
42         static char buf[256];
43         struct stat s;
44         
45         sprintf(buf, "%s/%s_%d", dir, fn, day);
46         
47         /* look to see if this is out of date, if it is remove it */
48         if (!readonly && stat(buf, &s) >= 0) {
49                 if (systime - s.st_mtime > (7*24*60*60)) 
50                         unlink(buf);
51         }
52         return buf;
53 }
54
55 static void rotate_log()
56 {
57         int i;
58         char *fn;
59         
60         i = getdayno(systime);
61         if (i != thisday) {
62                 thisday = i;
63                 dbghup();
64         }
65 }
66
67 void dbghup()
68 {
69         char *fn;
70         
71         if (f) {
72                 fclose(f);
73                 f = 0;
74         }
75         if (!f) {
76                 if (!thisday)
77                         thisday = getdayno(systime);
78         fn = genlogname(LOGDIR, "log", thisday, 0);
79                 f = fopen(fn, "a");
80     }
81         
82         if (!f)
83                 die("can't open %s (%d) for debug", fn, errno);
84 }
85
86 char *dbgtime()
87 {
88         time_t t;
89         char *ap;
90         static char buf[30];
91         
92         ap = ctime(&systime);
93         sprintf(buf, "%2.2s%3.3s%4.4s %8.8s", &ap[8], &ap[4], &ap[20], &ap[11]);
94         return buf;
95 }
96
97 void dbginit(char *ident)
98 {
99         pid = getpid();
100         prog = strdup(ident);
101         time(&systime);
102         mkdir(LOGDIR, 01777);
103         dbghup();
104 }
105
106 void dbgadd(unsigned long level)
107 {
108     dbglevel |= level;
109 }
110
111 void dbgsub(unsigned long level)
112 {
113     dbglevel &= ~level;
114 }
115
116 void dbgset(unsigned long level)
117 {
118     dbglevel = level;
119 }
120
121 unsigned long dbgget()
122 {
123         return dbglevel;
124 }
125
126 void dbgread(char *s)
127 {
128     unsigned long level = strtoul(s, 0, 0);
129     dbgset(level);
130 }
131
132 void dbg(unsigned long level, char *format, ...)
133 {
134     if (f && DBGLEVEL(level)) {
135                 char dbuf[100];
136         char buf[1500-100];
137                 int i;
138         va_list ap;
139                 
140                 time(&systime);
141                 
142                 rotate_log();
143                 
144         sprintf(dbuf, "%s %s[%d,%04x] ", dbgtime(), prog, pid, level);
145         va_start(ap, format);
146         vsprintf(buf, format, ap);
147                 i = strlen(buf);
148                 if (i>1 && buf[i-1] == '\n')
149                         buf[i-1] = 0;
150                 fprintf(f, dbuf);
151                 fprintf(f, buf);
152                 fputc('\n', f);
153         va_end(ap);
154                 fflush(f);
155
156                 /* save for later */
157                 if (dbgproc) {
158                         sprintf(dbgbuf, "%s%s", dbuf, buf);
159                         (dbgproc)(dbgbuf);
160                 }
161     }
162 }
163
164 void dbgdump(unsigned long level, char *dir, unsigned char *s, int lth)
165 {
166     if (f && DBGLEVEL(level)) {
167         int c, l;
168         unsigned char *p2, *p1;
169         char *p, buf[120];
170                 
171                 time(&systime);
172
173                 rotate_log();
174                 
175         sprintf(buf, "%s %s[%d,%04x] %s Lth: %d", dbgtime(), prog, pid, level, dir, lth);
176         fprintf(f, "%s\n", buf);
177                 if (dbgproc) {
178                         (dbgproc)(buf);
179                 }
180
181         /* calc how many blocks of 8 I can do */
182         c = 80 / 8;
183         c /= 3;
184
185         for (p = buf, p2 = s; p2 < s + lth; p2 += c * 8, p = buf) {
186             int i, l = c * 8;
187             sprintf(p, "%4d: ", p2 - s);
188             p += strlen(p);
189             for (p1 = p2; p1 < s + lth && p1 < p2 + l; ++p1) {
190                 sprintf(p, "%02X", *p1);
191                 p += strlen(p);
192             }
193             for ( ;p1 < p2 + l; ++p1) {
194                 sprintf(p, "  ");
195                 p += strlen(p);
196             }
197             sprintf(p, " ");
198             p += strlen(p);
199             for (p1 = p2; p1 < s + lth && p1 < p2 + l; ++p1) {
200                 sprintf(p, "%c", (*p1 >= ' ' && *p1 <= 0x7e) ? *p1 : '.'); 
201                 p += strlen(p);
202             }
203             fprintf(f, "%s\n", buf);
204                         if (dbgproc) {
205                                 (dbgproc)(buf);
206                         }
207         }
208     }
209         fflush(f);
210 }
211
212 void dbgclose()
213 {
214     if (f) {
215         fclose(f);
216         opened = 0;
217     }
218 }