chiark / gitweb /
*** empty log message ***
[sympathy.git] / src / log.c
1 /*
2  * log.c:
3  *
4  * Copyright (c) 2008 James McKenzie <james@fishsoup.dhs.org>,
5  * All rights reserved.
6  *
7  */
8
9 static char rcsid[] = "$Id$";
10
11 /*
12  * $Log$
13  * Revision 1.5  2008/02/27 01:31:14  james
14  * *** empty log message ***
15  *
16  * Revision 1.4  2008/02/27 00:54:16  james
17  * *** empty log message ***
18  *
19  * Revision 1.3  2008/02/23 11:48:37  james
20  * *** empty log message ***
21  *
22  * Revision 1.2  2008/02/22 14:51:54  james
23  * *** empty log message ***
24  *
25  * Revision 1.1  2008/02/14 12:14:50  james
26  * *** empty log message ***
27  *
28  */
29
30 #include "project.h"
31
32 typedef struct
33 {
34   LOG_SIGNATURE;
35   int do_close;
36   FILE *fp;
37 } File_Log;
38
39 static void
40 flog_log (Log * _l, char *buf)
41 {
42   File_Log *l = (File_Log *) _l;
43   struct timeval tv = { 0 };
44   struct tm *tm;
45   time_t t;
46   static const char *days[] = { "Sun", "Mon", "Tue",
47     "Wed", "Thu", "Fri", "Sat"
48   };
49   static const char *months[] = {
50     "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct",
51     "Nov", "Dec"
52   };
53
54   if (!l->fp)
55     return;
56
57   gettimeofday (&tv, NULL);
58   t = tv.tv_sec;
59   tm = localtime (&t);
60
61   fprintf (l->fp, "%s %2d %02d:%02d:%02d.%06d ", months[tm->tm_mon],
62            tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, tv.tv_usec);
63
64   fputs (buf, l->fp);
65   fputc ('\n', l->fp);
66   fflush (l->fp);
67 }
68
69
70
71
72 static void
73 flog_close (Log * _l)
74 {
75   File_Log *l = (File_Log *) _l;
76   if (l->fp && l->do_close)
77     fclose (l->fp);
78   free (l);
79 }
80
81 Log *
82 file_log_new (char *fn)
83 {
84   File_Log *l;
85   FILE *f;
86   int dc = 1;
87
88   if (fn && strcmp (fn, "-"))
89     {
90       f = fopen (fn, "a+");
91       if (!f)
92         return NULL;
93     }
94   else
95     {
96       f = stderr;
97       dc = 0;
98     }
99
100   l = malloc (sizeof (File_Log));
101
102   l->log = flog_log;
103   l->close = flog_close;
104   l->fp = f;
105   l->do_close = dc;
106
107   fput_cp (f, 0xffef);
108
109   return (Log *) l;
110 }
111
112 void
113 log_f (Log * log, char *fmt, ...)
114 {
115
116   int n;
117   static char *buf;
118   va_list ap;
119   static int size;
120
121   if (!log)
122     return;
123
124   if (!size)
125     {
126       size = 128;
127       buf = malloc (size);
128     }
129
130   if (!buf)
131     return;
132
133   while (1)
134     {
135       va_start (ap, fmt);
136       n = vsnprintf (buf, size, fmt, ap);
137       va_end (ap);
138
139       if (n > -1 && n < size)
140         {
141           log->log (log, buf);
142           return;
143         }
144
145       if (n > -1)               /* glibc 2.1 */
146         size = n + 1;
147       else                      /* glibc 2.0 */
148         size *= 2;              /* twice the old size */
149
150       buf = realloc (buf, size);
151
152       if (!buf)
153         return;
154     }
155 }