log.c (7758B)
1 /* log.c - report errors to the outside world */ 2 3 /* 4 * Copyright (c) 2013, Natacha Porté 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include <errno.h> 20 #include <stdarg.h> 21 #include <stdio.h> 22 #include <string.h> 23 #include <syslog.h> 24 25 #include "log.h" 26 27 /************* 28 * REPORTING * 29 *************/ 30 31 /* report - callback actually used by formatting functions */ 32 static report_fn report = &report_to_stderr; 33 34 35 /* set_report - use the given callback for error reporting */ 36 void 37 set_report(report_fn callback) { 38 report = callback; 39 } 40 41 42 /* report_to_stderr - wrapper to send the message to standard error output */ 43 void 44 report_to_stderr(int priority, const char *message, ...) { 45 va_list ap; 46 (void)priority; 47 48 va_start(ap, message); 49 vfprintf(stderr, message, ap); 50 va_end(ap); 51 fputc('\n', stderr); 52 } 53 54 55 56 /******************* 57 * ERROR FORMATING * 58 *******************/ 59 60 /* log_alloc - memory allocation failure */ 61 void 62 log_alloc(const char *subsystem) { 63 if (subsystem) 64 report(LOG_ERR, "Unable to allocate memory for %s", subsystem); 65 else 66 report(LOG_ERR, "Unable to allocate memory"); 67 } 68 69 70 /* log_assert - internal inconsistency */ 71 void 72 log_assert(const char *reason, const char *source, unsigned line) { 73 if (reason) 74 report(LOG_ERR, "Internal inconsistency at %s:%u (%s)", 75 source, line, reason); 76 else 77 report(LOG_ERR, "Internal inconsistency at %s:%u", 78 source, line); 79 } 80 81 82 /* log_bad_delay - invalid string provided for delay value */ 83 void 84 log_bad_delay(const char *opt) { 85 report(LOG_ERR, "Bad value \"%s\" for delay", opt); 86 } 87 88 89 /* log_chdir - chdir("/") failed after successful chroot() */ 90 void 91 log_chdir(const char *newroot) { 92 report(LOG_ERR, "chdir(\"/\") error after chroot to %s: %s", 93 newroot, strerror(errno)); 94 } 95 96 97 /* log_chroot - chroot() failed */ 98 void 99 log_chroot(const char *newroot) { 100 report(LOG_ERR, "Unable to chroot to %s: %s", 101 newroot, strerror(errno)); 102 } 103 104 105 /* log_entry_wait - watchtab entry successfully inserted in the queue */ 106 void 107 log_entry_wait(struct watch_entry *wentry) { 108 report(LOG_INFO, "Waiting for events on \"%s\"", wentry->path); 109 } 110 111 /* log_exec - execve() failed */ 112 void 113 log_exec(struct watch_entry *wentry) { 114 report(LOG_ERR, "Unable to execute \"%s\": %s", 115 wentry->command, strerror(errno)); 116 } 117 118 119 /* log_fork - fork() failed */ 120 void 121 log_fork(void) { 122 report(LOG_ERR, "Error in fork(): %s", strerror(errno)); 123 } 124 125 126 /* log_kevent_entry - kevent() failed when adding an event for a file entry */ 127 void 128 log_kevent_entry(const char *path) { 129 report(LOG_ERR, "Unable to queue filter for file \"%s\": %s", 130 path, strerror(errno)); 131 } 132 133 134 /* log_kevent_proc - kevent() failed when adding a command watcher */ 135 void 136 log_kevent_proc(struct watch_entry *wentry, pid_t pid) { 137 report(LOG_ERR, "Unable to watch command pid %d (\"%s\"): %s", 138 (int)pid, wentry->command, strerror(errno)); 139 } 140 141 142 /* log_kevent_timer - kevent() failed when adding a timer */ 143 void 144 log_kevent_timer(void) { 145 report(LOG_ERR, "Unable to queue timer for watchtab: %s", 146 strerror(errno)); 147 } 148 149 150 /* log_kevent_timer_off - kevent() failed when removing a timer */ 151 void 152 log_kevent_timer_off(void) { 153 report(LOG_ERR, "Unable to delete timer for watchtab: %s", 154 strerror(errno)); 155 } 156 157 158 /* log_kevent_wait - kevent() failed while waiting for an event */ 159 void 160 log_kevent_wait(void) { 161 report(LOG_ERR, "Error while waiting for a kevent: %s", 162 strerror(errno)); 163 } 164 165 166 /* log_kevent_watchtab - kevent() failed when adding a watchtab event */ 167 void 168 log_kevent_watchtab(const char *path) { 169 report(LOG_ERR, "Unable to queue filter for watchtab \"%s\": %s", 170 path, strerror(errno)); 171 } 172 173 174 /* log_kqueue - report failure in kqueue() call */ 175 void 176 log_kqueue(void) { 177 report(LOG_ERR, "Error in kqueue(): %s", strerror(errno)); 178 } 179 180 181 /* log_lookup_group - getgrnam() failed */ 182 void 183 log_lookup_group(const char *group) { 184 if (errno) 185 report(LOG_ERR, "Error while lookup group \"%s\": %s", 186 group, strerror(errno)); 187 else 188 report(LOG_ERR, "Unable to find group \"%s\"", group); 189 } 190 191 /* log_lookup_pw - getpwnam() failed */ 192 void 193 log_lookup_pw(const char *login) { 194 if (errno) 195 report(LOG_ERR, "Error while lookup user \"%s\": %s", 196 login, strerror(errno)); 197 else 198 report(LOG_ERR, "Unable to find user \"%s\"", login); 199 } 200 201 /* log_lookup_self - getlogin() or getpwnam() failed */ 202 void 203 log_lookup_self(void) { 204 report(LOG_ERR, "Error while trying to lookup current user login"); 205 } 206 207 208 /* log_open_entry - open() failed on watchtab entry file */ 209 void 210 log_open_entry(const char *path) { 211 report(LOG_ERR, "Unable to open watched file \"%s\": %s", 212 path, strerror(errno)); 213 } 214 215 216 /* log_open_watchtab - watchtab file open() failed */ 217 void 218 log_open_watchtab(const char *path) { 219 report(LOG_ERR, "Unable to open watchtab \"%s\": %s", 220 path, strerror(errno)); 221 } 222 223 224 /* log_running - a watchtab entry has been triggered */ 225 void 226 log_running(struct watch_entry *wentry) { 227 report(LOG_INFO, "Running \"%s\", triggered by \"%s\"", 228 wentry->command, wentry->path); 229 } 230 231 232 /* log_setgid - setgid() failed */ 233 void 234 log_setgid(gid_t gid) { 235 report(LOG_INFO, "Unable to set gID to %d: %s", 236 (int)gid, strerror(errno)); 237 } 238 239 240 /* log_setuid - setuid() failed */ 241 void 242 log_setuid(uid_t uid) { 243 report(LOG_INFO, "Unable to set uID to %d: %s", 244 (int)uid, strerror(errno)); 245 } 246 247 248 /* log_signal - signal() failed */ 249 void 250 log_signal(int sig) { 251 report(LOG_ERR, "Unable to setup signal handler for \"%s\": %s", 252 strsignal(sig), strerror(errno)); 253 } 254 255 256 /* log_watchtab_invalid_action - invalid action line in watchtab */ 257 void 258 log_watchtab_invalid_action(const char *filename, unsigned line_no) { 259 report(LOG_ERR, "Invalid action line at line %s:%u", 260 filename, line_no); 261 } 262 263 264 /* log_watchtab_invalid_delay - invalid delay field in watchtab entry */ 265 void 266 log_watchtab_invalid_delay(const char *filename, unsigned line_no, 267 const char *field) { 268 report(LOG_ERR, "Invalid delay field \"%s\" at %s:%u", 269 field, filename, line_no); 270 } 271 272 273 /* log_watchtab_invalid_events - parse error in watchtab event set */ 274 void 275 log_watchtab_invalid_events(const char *filename, unsigned line_no, 276 const char *field, size_t len) { 277 report(LOG_ERR, "Invalid event set \"%.*s\" at %s:%u", 278 (int)len, field, filename, line_no); 279 } 280 281 282 /* log_watchtab_loaded - watchtab has been successfully loaded */ 283 void 284 log_watchtab_loaded(const char *path) { 285 report(LOG_NOTICE, "Watchtab \"%s\" loaded successfully", path); 286 } 287 288 289 /* log_watchtab_read - read error on watchtab */ 290 void 291 log_watchtab_read(void) { 292 report(LOG_ERR, "Error while reading from watchtab"); 293 } 294 295 296 /* print_usage - output usage text upon request or after argument error */ 297 void 298 print_usage(int after_error, int argc, char **argv) { 299 (void)argc; 300 301 fprintf(after_error ? stderr : stdout, 302 "Usage: %s [-dh] [-f delay_ms] watchtab\n\n" 303 "\t-d, --foreground\n" 304 "\t\tDon't fork to background and log to stderr\n" 305 "\t-h, --help\n" 306 "\t\tDisplay this help text\n" 307 "\t-w, --wait delay_ms\n" 308 "\t\tWait that number of milliseconds after watchtab\n" 309 "\t\tchanges before reloading it\n", 310 argv[0]); 311 }