Initial revision
[crypto.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.1  2000/06/27 11:36:55  priikone
24  * Initial revision
25  *
26  *
27  */
28
29 #include "silcincludes.h"
30
31 /* SILC Log name strings. These strings are printed to the log file. */
32 const SilcLogTypeName silc_log_types[] =
33 {
34   { "Info", SILC_LOG_INFO },
35   { "Warning", SILC_LOG_WARNING },
36   { "Error", SILC_LOG_ERROR },
37   { "Fatal", SILC_LOG_FATAL },
38
39   { NULL, -1 },
40 };
41
42 char *log_info_file;
43 char *log_warning_file;
44 char *log_error_file;
45 char *log_fatal_file;
46 unsigned int log_info_size;
47 unsigned int log_warning_size;
48 unsigned int log_error_size;
49 unsigned int log_fatal_size;
50
51 /* Formats arguments to a string and returns it after allocating memory
52    for it. It must be remembered to free it later. */
53
54 char *silc_log_format(char *fmt, ...)
55 {
56   va_list args;
57   static char buf[1024];
58
59   va_start(args, fmt);
60   vsprintf(buf, fmt, args);
61   va_end(args);
62
63   return strdup(buf);
64 }
65
66 /* Outputs the log message to what ever log file selected. */
67
68 void silc_log_output(const char *filename, unsigned int maxsize,
69                      SilcLogType type, char *string)
70 {
71   FILE *fp;
72   const SilcLogTypeName *np;
73
74   /* Purge the log file if the max size is defined. */
75   if (maxsize) {
76     fp = fopen(filename, "r");
77     if (fp) {
78       int filelen;
79       
80       filelen = fseek(fp, (off_t)0L, SEEK_END);
81       fseek(fp, (off_t)0L, SEEK_SET);  
82       
83       /* Purge? */
84       if (maxsize >= filelen)
85         unlink(filename);
86     }
87   }
88
89   /* Open the log file */
90   if ((fp = fopen(filename, "a+")) == NULL) {
91     fprintf(stderr, "warning: could not open log file "
92             "%s: %s\n", filename, strerror(errno));
93     fprintf(stderr, "warning: log messages will be displayed on the screen\n");
94     fp = stderr;
95   }
96  
97   /* Get the log type name */
98   for(np = silc_log_types; np->name; np++) {
99     if (np->type == type)
100       break;
101   }
102
103   fprintf(fp, "[%s] [%s] %s\n", silc_get_time(), np->name, string);
104   fflush(fp);
105   fclose(fp);
106   silc_free(string);
107 }
108
109 /* Outputs the debug message to stderr. */
110
111 void silc_log_output_debug(char *file, char *function, 
112                            int line, char *string)
113 {
114   /* fprintf(stderr, "%s:%s:%d: %s\n", file, function, line, string); */
115   fprintf(stderr, "%s:%d: %s\n", function, line, string);
116   fflush(stderr);
117   silc_free(string);
118 }
119
120 /* Hexdumps a message */
121
122 void silc_log_output_hexdump(char *file, char *function, 
123                              int line, void *data_in,
124                              unsigned int len, char *string)
125 {
126   int i, k;
127   int off, pos, count;
128   unsigned char *data = (unsigned char *)data_in;
129
130   /* fprintf(stderr, "%s:%s:%d: %s\n", file, function, line, string); */
131   fprintf(stderr, "%s:%d: %s\n", function, line, string);
132   silc_free(string);
133
134   k = 0;
135   off = len % 16;
136   pos = 0;
137   count = 16;
138   while (1) {
139
140     if (off) {
141       if ((len - pos) < 16 && (len - pos <= len - off))
142         count = off;
143     } else {
144       if (pos == len)
145         count = 0;
146     }
147     if (off == len)
148       count = len;
149
150     if (count)
151       fprintf(stderr, "%08X  ", k++ * 16);
152
153     for (i = 0; i < count; i++) {
154       fprintf(stderr, "%02X ", data[pos + i]);
155       
156       if ((i + 1) % 4 == 0)
157         fprintf(stderr, " ");
158     }
159
160     if (count && count < 16) {
161       int j;
162       
163       for (j = 0; j < 16 - count; j++) {
164         fprintf(stderr, "   ");
165
166         if ((j + count + 1) % 4 == 0)
167           fprintf(stderr, " ");
168       }
169     }
170   
171     for (i = 0; i < count; i++) {
172       char ch;
173       
174       if (data[pos] < 32 || data[pos] >= 127)
175         ch = '.';
176       else
177         ch = data[pos];
178
179       fprintf(stderr, "%c", ch);
180       pos++;
181     }
182
183     if (count)
184       fprintf(stderr, "\n");
185
186     if (count < 16)
187       break;
188   }
189 }
190
191 /* Sets log files */
192
193 void silc_log_set_files(char *info, unsigned int info_size, 
194                         char *warning, unsigned int warning_size,
195                         char *error, unsigned int error_size,
196                         char *fatal, unsigned int fatal_size)
197 {
198   log_info_file = info;
199   log_warning_file = warning;
200   log_error_file = error;
201   log_fatal_file = fatal;
202
203   log_info_size = info_size;
204   log_warning_size = warning_size;
205   log_error_size = error_size;
206   log_fatal_size = fatal_size;
207 }