cc74119d5f987fd20fec34cac9e3e73df5ab72da
[silc.git] / lib / silccore / silclog.c
1 /*
2
3   silclog.c
4
5   Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
6
7   Copyright (C) 1997 - 2000 Pekka Riikonen
8
9   This program is free software; you can redistribute it and/or modify
10   it under the terms of the GNU General Public License as published by
11   the Free Software Foundation; either version 2 of the License, or
12   (at your option) any later version.
13   
14   This program is distributed in the hope that it will be useful,
15   but WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   GNU General Public License for more details.
18
19 */
20 /*
21  * $Id$
22  * $Log$
23  * Revision 1.2  2000/07/03 05:53:58  priikone
24  *      Fixed file purging bug.  The purging should work now ok.
25  *
26  * Revision 1.1.1.1  2000/06/27 11:36:55  priikone
27  *      Importet from internal CVS/Added Log headers.
28  *
29  *
30  */
31
32 #include "silcincludes.h"
33
34 /* SILC Log name strings. These strings are printed to the log file. */
35 const SilcLogTypeName silc_log_types[] =
36 {
37   { "Info", SILC_LOG_INFO },
38   { "Warning", SILC_LOG_WARNING },
39   { "Error", SILC_LOG_ERROR },
40   { "Fatal", SILC_LOG_FATAL },
41
42   { NULL, -1 },
43 };
44
45 char *log_info_file;
46 char *log_warning_file;
47 char *log_error_file;
48 char *log_fatal_file;
49 unsigned int log_info_size;
50 unsigned int log_warning_size;
51 unsigned int log_error_size;
52 unsigned int log_fatal_size;
53
54 /* Formats arguments to a string and returns it after allocating memory
55    for it. It must be remembered to free it later. */
56
57 char *silc_log_format(char *fmt, ...)
58 {
59   va_list args;
60   static char buf[1024];
61
62   va_start(args, fmt);
63   vsprintf(buf, fmt, args);
64   va_end(args);
65
66   return strdup(buf);
67 }
68
69 /* Outputs the log message to what ever log file selected. */
70
71 void silc_log_output(const char *filename, unsigned int maxsize,
72                      SilcLogType type, char *string)
73 {
74   FILE *fp;
75   const SilcLogTypeName *np;
76
77   /* Purge the log file if the max size is defined. */
78   if (maxsize) {
79     fp = fopen(filename, "r");
80     if (fp) {
81       int filelen;
82       
83       filelen = fseek(fp, (off_t)0L, SEEK_END);
84       fseek(fp, (off_t)0L, SEEK_SET);  
85       
86       /* Purge? */
87       if (filelen >= maxsize)
88         unlink(filename);
89     }
90   }
91
92   /* Open the log file */
93   if ((fp = fopen(filename, "a+")) == NULL) {
94     fprintf(stderr, "warning: could not open log file "
95             "%s: %s\n", filename, strerror(errno));
96     fprintf(stderr, "warning: log messages will be displayed on the screen\n");
97     fp = stderr;
98   }
99  
100   /* Get the log type name */
101   for(np = silc_log_types; np->name; np++) {
102     if (np->type == type)
103       break;
104   }
105
106   fprintf(fp, "[%s] [%s] %s\n", silc_get_time(), np->name, string);
107   fflush(fp);
108   fclose(fp);
109   silc_free(string);
110 }
111
112 /* Outputs the debug message to stderr. */
113
114 void silc_log_output_debug(char *file, char *function, 
115                            int line, char *string)
116 {
117   /* fprintf(stderr, "%s:%s:%d: %s\n", file, function, line, string); */
118   fprintf(stderr, "%s:%d: %s\n", function, line, string);
119   fflush(stderr);
120   silc_free(string);
121 }
122
123 /* Hexdumps a message */
124
125 void silc_log_output_hexdump(char *file, char *function, 
126                              int line, void *data_in,
127                              unsigned int len, char *string)
128 {
129   int i, k;
130   int off, pos, count;
131   unsigned char *data = (unsigned char *)data_in;
132
133   /* fprintf(stderr, "%s:%s:%d: %s\n", file, function, line, string); */
134   fprintf(stderr, "%s:%d: %s\n", function, line, string);
135   silc_free(string);
136
137   k = 0;
138   off = len % 16;
139   pos = 0;
140   count = 16;
141   while (1) {
142
143     if (off) {
144       if ((len - pos) < 16 && (len - pos <= len - off))
145         count = off;
146     } else {
147       if (pos == len)
148         count = 0;
149     }
150     if (off == len)
151       count = len;
152
153     if (count)
154       fprintf(stderr, "%08X  ", k++ * 16);
155
156     for (i = 0; i < count; i++) {
157       fprintf(stderr, "%02X ", data[pos + i]);
158       
159       if ((i + 1) % 4 == 0)
160         fprintf(stderr, " ");
161     }
162
163     if (count && count < 16) {
164       int j;
165       
166       for (j = 0; j < 16 - count; j++) {
167         fprintf(stderr, "   ");
168
169         if ((j + count + 1) % 4 == 0)
170           fprintf(stderr, " ");
171       }
172     }
173   
174     for (i = 0; i < count; i++) {
175       char ch;
176       
177       if (data[pos] < 32 || data[pos] >= 127)
178         ch = '.';
179       else
180         ch = data[pos];
181
182       fprintf(stderr, "%c", ch);
183       pos++;
184     }
185
186     if (count)
187       fprintf(stderr, "\n");
188
189     if (count < 16)
190       break;
191   }
192 }
193
194 /* Sets log files */
195
196 void silc_log_set_files(char *info, unsigned int info_size, 
197                         char *warning, unsigned int warning_size,
198                         char *error, unsigned int error_size,
199                         char *fatal, unsigned int fatal_size)
200 {
201   log_info_file = info;
202   log_warning_file = warning;
203   log_error_file = error;
204   log_fatal_file = fatal;
205
206   log_info_size = info_size;
207   log_warning_size = warning_size;
208   log_error_size = error_size;
209   log_fatal_size = fatal_size;
210 }