log.c
Go to the documentation of this file.
1 /* ========================================================================== */
2 /*! \file
3  * \brief Server protocol logging
4  *
5  * Copyright (c) 2012-2020 by the developers. See the LICENSE file for details.
6  * If nothing else is specified, functions return zero to indicate success
7  * and a negative value to indicate an error.
8  */
9 
10 
11 /* ========================================================================== */
12 /* Include headers */
13 
14 #include "posix.h" /* Include this first because of feature test macros */
15 
16 #include <stdio.h>
17 #include <string.h>
18 
19 #include "config.h"
20 #include "fileutils.h"
21 #include "log.h"
22 #include "main.h"
23 #include "xdg.h"
24 
25 
26 /* ========================================================================== */
27 /*! \defgroup LOGGING LOG: Logging of NNTP communication
28  *
29  * Location of protocol logfile: \c $XDG_CONFIG_HOME/$CFG_NAME/logfile
30  */
31 /*! @{ */
32 
33 
34 /* ========================================================================== */
35 /* Constants */
36 
37 /*! \brief Message prefix for LOG module */
38 #define MAIN_ERR_PREFIX "LOG: "
39 
40 /*! \brief Permissions for server protocol logfile */
41 #define LOG_PERM (posix_mode_t) (POSIX_S_IRUSR | POSIX_S_IWUSR)
42 
43 
44 /* ========================================================================== */
45 /*! \brief Get logfile pathname
46  *
47  * This function must be thread safe.
48  * The caller is responsible to free the memory for the buffer on success.
49  *
50  * \return
51  * - Pointer to logfile pathname on success
52  * - \c NULL on error
53  */
54 
55 const char* log_get_logpathname(void)
56 {
57  static const char logname[] = "logfile";
58  const char* res = NULL;
59  int rv;
60 
61  /* This requires the UI mutex */
62  res = xdg_get_confdir(CFG_NAME);
63  if(NULL != res)
64  {
65  rv = fu_create_path(res, (posix_mode_t) POSIX_S_IRWXU);
66  if(0 == rv)
67  {
68  /* Store scorefile pathname */
69  rv = xdg_append_to_path(&res, logname);
70  if(0 != rv)
71  {
72  posix_free((void*) res);
73  res = NULL;
74  }
75  }
76  }
77 
78  return(res);
79 }
80 
81 
82 /* ========================================================================== */
83 /*! \brief Delete logfile if present */
84 
86 {
87  const char* lfpn = log_get_logpathname();
88 
89  if(NULL != lfpn)
90  {
91  (void) fu_unlink_file(lfpn);
92  posix_free((void*) lfpn);
93  }
94 }
95 
96 
97 /* ========================================================================== */
98 /*! \brief Open logfile
99  *
100  * \param[out] lfs Pointer to logfile stream
101  * \param[in] logfile Pathname of logfile to open
102  *
103  * A valid stream pointer was written to \e lfs before success is returned.
104  * Otherwise the location pointed to by \e lfs is not changed.
105  *
106  * \note
107  * If \e logfile is \c NULL , the file \c /dev/null is used instead.
108  *
109  * \return
110  * - Zero on success
111  * - -1 on error
112  */
113 
114 int log_open_logfile(FILE** lfs, const char* logfile)
115 {
116  static const char* null = "/dev/null";
117  int res = 0;
118  int fd = -1;
119  FILE* fs = NULL;
120 
121  if(NULL == logfile) { logfile = null; }
122 
123  /* Open logfile */
124  res = fu_open_file(logfile, &fd,
125  POSIX_O_WRONLY | POSIX_O_CREAT | POSIX_O_TRUNC, LOG_PERM);
126  if(res)
127  {
128  PRINT_ERROR("Opening logfile failed");
129  res = -1;
130  }
131  else
132  {
133  /* Assign stream to logfile */
134  res = fu_assign_stream(fd, &fs, "wb");
135  if(res)
136  {
137  PRINT_ERROR("Cannot assign stream to logfile");
138  fu_close_file(&fd, NULL);
139  res = -1;
140  }
141  else
142  {
143  /* Success => Write stream pointer to 'lfs' */
144  *lfs = fs;
145  }
146  }
147 
148  return(res);
149 }
150 
151 
152 /* ========================================================================== */
153 /*! \brief Close logfile
154  *
155  * \param[in] lfs Pointer to logfile stream
156  */
157 
158 void log_close_logfile(FILE** lfs)
159 {
160  fu_close_file(NULL, lfs);
161 
162  return;
163 }
164 
165 
166 /* ========================================================================== */
167 /*! \brief Add data to end of logfile
168  *
169  * \param[in] lfs Logfile stream
170  * \param[in] data Data string that should be added to logfile
171  *
172  * This function never fail, write errors are ignored.
173  */
174 
175 void log_add(FILE* lfs, const char* data)
176 {
177  size_t i = 0;
178 
179  while(data[i])
180  {
181  /* Delete CR characters */
182  if((char) 0x0D != data[i]) { fputc((int) data[i], lfs); }
183  ++i;
184  }
185  fflush(lfs);
186 }
187 
188 
189 /* ========================================================================== */
190 /*! \brief Free an object allocated by logging module
191  *
192  * Use this function to release dynamic memory that was allocated by the
193  * logging module.
194  *
195  * \param[in] p Pointer to object
196  *
197  * Release the memory for the object pointed to by \e p.
198  */
199 
200 void log_free(void* p)
201 {
202  posix_free(p);
203 }
204 
205 
206 /*! @} */
207 
208 /* EOF */
log_free
void log_free(void *p)
Free an object allocated by logging module.
Definition: log.c:200
fu_assign_stream
int fu_assign_stream(int filedesc, FILE **stream, const char *mode)
Assign I/O stream to open file.
Definition: fileutils.c:373
log_get_logpathname
const char * log_get_logpathname(void)
Get logfile pathname.
Definition: log.c:55
LOG_PERM
#define LOG_PERM
Permissions for server protocol logfile.
Definition: log.c:41
fu_create_path
int fu_create_path(const char *path, posix_mode_t perm)
Create path.
Definition: fileutils.c:119
log_add
void log_add(FILE *lfs, const char *data)
Add data to end of logfile.
Definition: log.c:175
log_close_logfile
void log_close_logfile(FILE **lfs)
Close logfile.
Definition: log.c:158
fu_unlink_file
int fu_unlink_file(const char *pathname)
Unlink file.
Definition: fileutils.c:355
PRINT_ERROR
#define PRINT_ERROR(s)
Prepend module prefix and print error message.
Definition: main.h:19
data
struct core_data data
Global data object (shared by all threads)
Definition: core.c:242
xdg_get_confdir
const char * xdg_get_confdir(const char *)
Get configuration directory.
Definition: xdg.c:115
xdg_append_to_path
int xdg_append_to_path(const char **, const char *)
Append path component to buffer.
Definition: xdg.c:55
log_open_logfile
int log_open_logfile(FILE **lfs, const char *logfile)
Open logfile.
Definition: log.c:114
log_delete_logfile
void log_delete_logfile(void)
Delete logfile if present.
Definition: log.c:85
fu_close_file
void fu_close_file(int *filedesc, FILE **stream)
Close file (and potentially associated I/O stream)
Definition: fileutils.c:290
fu_open_file
int fu_open_file(const char *pathname, int *filedesc, int mode, posix_mode_t perm)
Open file.
Definition: fileutils.c:243

Generated at 2024-04-27 using  doxygen