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