]> mj.ucw.cz Git - libucw.git/blob - lib/log-file.c
backport patch from head
[libucw.git] / lib / log-file.c
1 /*
2  *      UCW Library -- Keeping of Log Files
3  *
4  *      (c) 1997--2005 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 #include "lib/lfs.h"
12
13 #include <stdio.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 volatile int log_switch_nest;
23
24 static int
25 do_log_switch(struct tm *tm)
26 {
27   int fd, l;
28   char name[log_filename_size];
29   int switched = 0;
30
31   if (!log_name_patt ||
32       log_filename[0] && !log_params)
33     return 0;
34   log_switch_nest++;
35   l = strftime(name, log_filename_size, log_name_patt, tm);
36   if (l < 0 || l >= log_filename_size)
37     die("Error formatting log file name: %m");
38   if (strcmp(name, log_filename))
39     {
40       strcpy(log_filename, name);
41       fd = sh_open(name, O_WRONLY | O_CREAT | O_APPEND, 0666);
42       if (fd < 0)
43         die("Unable to open log file %s: %m", name);
44       close(2);
45       dup(fd);
46       close(fd);
47       close(1);
48       dup(2);
49       switched = 1;
50     }
51   log_switch_nest--;
52   return switched;
53 }
54
55 int
56 log_switch(void)
57 {
58   time_t tim = time(NULL);
59   return do_log_switch(localtime(&tim));
60 }
61
62 static void
63 internal_log_switch(struct tm *tm)
64 {
65   if (!log_switch_nest)
66     do_log_switch(tm);
67 }
68
69 void
70 log_file(byte *name)
71 {
72   if (name)
73     {
74       if (log_name_patt)
75         xfree(log_name_patt);
76       if (log_filename)
77         {
78           xfree(log_filename);
79           log_filename = NULL;
80         }
81       log_name_patt = xstrdup(name);
82       log_params = !!strchr(name, '%');
83       log_filename_size = strlen(name) + 64;    /* 63 is an upper bound on expansion of % escapes */
84       log_filename = xmalloc(log_filename_size);
85       log_filename[0] = 0;
86       log_switch();
87       log_switch_hook = internal_log_switch;
88     }
89 }
90
91 void
92 log_fork(void)
93 {
94   log_pid = getpid();
95 }
96
97 #ifdef TEST
98
99 int main(int argc, char **argv)
100 {
101   log_init(argv[0]);
102   log_file("/proc/self/fd/1");
103   for (int i=1; i<argc; i++)
104     log(L_INFO, argv[i]);
105   return 0;
106 }
107
108 #endif