libcfe  0.12.1
some useful C-functions
logfile.c
Go to the documentation of this file.
1 #include "config.h"
2 #include "logfile.h"
3 
4 #include <stdlib.h>
5 #include <unistd.h>
6 #include <string.h>
7 #include <errno.h>
8 #include <syslog.h>
9 #include <libintl.h>
10 
11 #include "output.h"
12 #include "len.h"
13 
14 #ifndef TMP_LOGFILE_TEMPLATE
15 # define TMP_LOGFILE_TEMPLATE "logfile.XXXXXX"
16 #endif
17 
18 #ifdef P_tmpdir
19 # define TMPDIR P_tmpdir
20 #else
21 # define TMPDIR "/tmp"
22 #endif
23 
24 static char *_logfile_tmplog;
25 
26 FILE *mk_temp_logfile(void)
27 {
28  if(_logfile_tmplog == NULL)
29  {
30  char *name = malloc(str_len(TMPDIR) + str_len(TMP_LOGFILE_TEMPLATE) + 2);
31  char *ptr = name + str_len(TMPDIR);
32 
33  strcpy(name, TMPDIR);
34  ptr[0] = '/';
35  strcpy(++ptr, TMP_LOGFILE_TEMPLATE);
36 
37  int fd = mkstemp(name);
38  if(fd == -1)
39  {
40  error(_("cannot create temporary log file '%s': %s"), name, strerror(errno));
41  free(name);
42  return NULL;
43  }
44  FILE *fp = fdopen(fd, "w");
45  if(fp != NULL)
46  {
47  _logfile_tmplog = name;
48  return fp;
49  }
50  error(_("cannot create temporary log file '%s': %s"), name, strerror(errno));
51  close(fd);
52  }
53  return NULL;
54 }
55 
56 void remove_temp_logfile(FILE **tmplogfp)
57 {
58  if(*tmplogfp != NULL && _logfile_tmplog != NULL)
59  {
60  fflush(*tmplogfp);
61  close_logfile(tmplogfp);
62  if(remove(_logfile_tmplog) != 0)
63  {
64  output(LOG_WARNING, _("cannot remove temporary log file '%s': %s"), _logfile_tmplog, strerror(errno));
65  }
66  free(_logfile_tmplog);
67  _logfile_tmplog = NULL;
68  }
69  return;
70 }
71 
72 FILE *mk_logfile(FILE *tmplogfp, const char *file)
73 {
74  FILE *fp = NULL;
75  FILE *destfp = fopen(file, "w");
76  if(destfp == NULL)
77  {
78  error(_("cannot create log file '%s': %s"), file, strerror(errno));
79  return NULL;
80  }
81 
82  if(tmplogfp != NULL && _logfile_tmplog != NULL)
83  {
84  fflush(tmplogfp);
85  FILE *srcfp = fopen(_logfile_tmplog, "r");
86 
87  size_t size = 512;
88  size_t read = 0;
89  size_t write = 0;
90 
91  flockfile(srcfp);
92  flockfile(destfp);
93 
94  char *buf = (char *)malloc(size);
95  while(feof(srcfp) == 0)
96  {
97  read = fread_unlocked(buf, 1, size, srcfp);
98  if(read != size && ferror(srcfp) != 0) /* if this is, these are the last blocks read, then all the output until freopen will not be logged. */
99  {
100  error(_("cannot copy log file: %s"), strerror(errno));
101  return NULL;
102  }
103 
104  write = fwrite_unlocked(buf, 1, read, destfp);
105  if(write != read)
106  {
107  error(_("number of bytes read and written are not the same, while coping logfile"));
108  debug(_("bytes read: %d; bytes written: %d"), (int)read, (int)write);
109  return NULL;
110  }
111  }
112  fflush(destfp);
113  funlockfile(srcfp);
114  funlockfile(destfp);
115 
116  fp = freopen(file, "a", tmplogfp); /* from here fp and oldfp points to the same stream to file 'FILE'. */
117  free(buf);
118  buf = NULL;
119 
120  fclose(srcfp);
121  srcfp = NULL;
122  fclose(destfp);
123  destfp = NULL;
124 
125  if(remove(_logfile_tmplog) != 0)
126  {
127  output(LOG_WARNING, _("cannot remove temporary log file '%s': %s"), _logfile_tmplog, strerror(errno));
128  }
129 
130  free(_logfile_tmplog);
131  _logfile_tmplog = NULL;
132  }
133  else
134  fp = destfp;
135 
136  return fp;
137 }
138 
139 void close_logfile(FILE **fd)
140 {
141  fclose(*fd);
142  *fd = NULL;
143 }
#define output
Definition: output.h:25
FILE * mk_temp_logfile(void)
Definition: logfile.c:26
#define str_len(s)
Shorthand for counting '\0' terminating strings. See _len for more info.
Definition: len.h:17
#define _(string)
Definition: output.h:43
void close_logfile(FILE **fd)
Definition: logfile.c:139
void remove_temp_logfile(FILE **tmplogfp)
Definition: logfile.c:56
#define error(...)
Definition: output.h:30
#define debug(...)
Definition: output.h:38
#define TMP_LOGFILE_TEMPLATE
Definition: logfile.c:15
FILE * mk_logfile(FILE *tmplogfp, const char *file)
Definition: logfile.c:72
#define TMPDIR
Definition: logfile.c:21