log.c
Go to the documentation of this file.
1 /* ========================================================================== */
2 /*! \file
3  * \brief Server protocol logging
4  *
5  * Copyright (c) 2012-2024 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 (api_posix_mode_t) (API_POSIX_S_IRUSR | API_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, (api_posix_mode_t) API_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  api_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  api_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  API_POSIX_O_WRONLY | API_POSIX_O_CREAT
126  | API_POSIX_O_TRUNC,
127  LOG_PERM);
128  if(res)
129  {
130  PRINT_ERROR("Opening logfile failed");
131  res = -1;
132  }
133  else
134  {
135  /* Assign stream to logfile */
136  res = fu_assign_stream(fd, &fs, "wb");
137  if(res)
138  {
139  PRINT_ERROR("Cannot assign stream to logfile");
140  fu_close_file(&fd, NULL);
141  res = -1;
142  }
143  else
144  {
145  /* Success => Write stream pointer to 'lfs' */
146  *lfs = fs;
147  }
148  }
149 
150  return(res);
151 }
152 
153 
154 /* ========================================================================== */
155 /*! \brief Close logfile
156  *
157  * \param[in] lfs Pointer to logfile stream
158  */
159 
160 void log_close_logfile(FILE** lfs)
161 {
162  fu_close_file(NULL, lfs);
163 
164  return;
165 }
166 
167 
168 /* ========================================================================== */
169 /*! \brief Add data to end of logfile
170  *
171  * \param[in] lfs Logfile stream
172  * \param[in] data Data string that should be added to logfile
173  *
174  * This function never fail, write errors are ignored.
175  */
176 
177 void log_add(FILE* lfs, const char* data)
178 {
179  size_t i = 0;
180 
181  while(data[i])
182  {
183  /* Delete CR characters */
184  if((char) 0x0D != data[i]) { fputc((int) data[i], lfs); }
185  ++i;
186  }
187  fflush(lfs);
188 }
189 
190 
191 /* ========================================================================== */
192 /*! \brief Free an object allocated by logging module
193  *
194  * Use this function to release dynamic memory that was allocated by the
195  * logging module.
196  *
197  * \param[in] p Pointer to object
198  *
199  * Release the memory for the object pointed to by \e p.
200  */
201 
202 void log_free(void* p)
203 {
204  api_posix_free(p);
205 }
206 
207 
208 /*! @} */
209 
210 /* EOF */
log_free
void log_free(void *p)
Free an object allocated by logging module.
Definition: log.c:202
fu_assign_stream
int fu_assign_stream(int filedesc, FILE **stream, const char *mode)
Assign I/O stream to open file.
Definition: fileutils.c:380
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
log_add
void log_add(FILE *lfs, const char *data)
Add data to end of logfile.
Definition: log.c:177
log_close_logfile
void log_close_logfile(FILE **lfs)
Close logfile.
Definition: log.c:160
fu_create_path
int fu_create_path(const char *path, api_posix_mode_t perm)
Create path.
Definition: fileutils.c:122
fu_unlink_file
int fu_unlink_file(const char *pathname)
Unlink file.
Definition: fileutils.c:362
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:116
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:297
fu_open_file
int fu_open_file(const char *pathname, int *filedesc, int mode, api_posix_mode_t perm)
Open file.
Definition: fileutils.c:246

Generated at 2026-01-27 using  doxygen