]> mj.ucw.cz Git - libucw.git/blob - lib/log-file.c
5916acb5bf648d50575359b209a7a40c31fd5b20
[libucw.git] / lib / log-file.c
1 /*
2  *      Sherlock Library -- Keeping of Log Files
3  *
4  *      (c) 1997--2004 Martin Mares <mj@ucw.cz>
5  *
6  *      This software may be freely distributed and used according to the terms
7  *      of the GNU Lesser General Public License.
8  */
9
10 #include "lib/lib.h"
11
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <fcntl.h>
16 #include <unistd.h>
17 #include <time.h>
18
19 static char *log_name_patt;
20 static int log_params;
21 static int log_filename_size;
22 int log_switch_nest;
23
24 static void
25 do_log_switch(struct tm *tm)
26 {
27   int fd, l;
28   char name[log_filename_size];
29
30   if (!log_name_patt ||
31       log_filename[0] && !log_params)
32     return;
33   log_switch_nest++;
34   l = strftime(name, log_filename_size, log_name_patt, tm);
35   if (l < 0 || l >= log_filename_size)
36     die("Error formatting log file name: %m");
37   if (strcmp(name, log_filename))
38     {
39       strcpy(log_filename, name);
40       fd = open(name, O_WRONLY | O_CREAT | O_APPEND, 0666);
41       if (fd < 0)
42         die("Unable to open log file %s: %m", name);
43       close(2);
44       dup(fd);
45       close(fd);
46       close(1);
47       dup(2);
48     }
49   log_switch_nest--;
50 }
51
52 void
53 log_switch(void)
54 {
55   time_t tim = time(NULL);
56   do_log_switch(localtime(&tim));
57 }
58
59 static void
60 internal_log_switch(struct tm *tm)
61 {
62   if (!log_switch_nest)
63     do_log_switch(tm);
64 }
65
66 void
67 log_file(byte *name)
68 {
69   if (name)
70     {
71       if (log_name_patt)
72         xfree(log_name_patt);
73       if (log_filename)
74         {
75           xfree(log_filename);
76           log_filename = NULL;
77         }
78       log_name_patt = xstrdup(name);
79       log_params = !!strchr(name, '%');
80       log_filename_size = strlen(name) + 64;    /* 63 is an upper bound on expansion of % escapes */
81       log_filename = xmalloc(log_filename_size);
82       log_filename[0] = 0;
83       log_switch();
84       log_switch_hook = internal_log_switch;
85       close(0);
86       open("/dev/null", O_RDWR, 0);
87     }
88 }
89
90 void
91 log_fork(void)
92 {
93   log_pid = getpid();
94 }
95
96 #ifdef TEST
97
98 int main(int argc, char **argv)
99 {
100   log_init(argv[0]);
101   log_file("/proc/self/fd/1");
102   for (int i=1; i<argc; i++)
103     log(L_INFO, argv[i]);
104   return 0;
105 }
106
107 #endif