filewatcherd

FreeBSD daemon that watches files and runs commands when they change
git clone https://git.instinctive.eu/filewatcherd.git
Log | Files | Refs | README | LICENSE

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 }