]> arthur.barton.de Git - netatalk.git/blobdiff - libatalk/util/logger.c
Fix stupid free. Still banging my head against the table! Praise valgrind.
[netatalk.git] / libatalk / util / logger.c
index 3cf12380b628ea1ccbeddd8d2c315541b9646ea1..dbeede2f4113dc6141ae38de432d1bd744074ef9 100644 (file)
@@ -30,7 +30,9 @@
 #include <fcntl.h>
 #include <sys/uio.h>
 #include <unistd.h>
+#include <sys/time.h>
 #include <time.h>
+#include <ctype.h>
 
 #include <atalk/boolean.h>
 
@@ -95,6 +97,57 @@ static const int num_loglevel_strings = COUNT_ARRAY(arr_loglevel_strings);
     Internal function definitions
    ========================================================================= */
 
+/* 
+ * If filename == NULL its for syslog logging, otherwise its for file-logging.
+ * "unsetuplog" calls with loglevel == NULL.
+ * loglevel == NULL means:
+ *    if logtype == default
+ *       disable logging
+ *    else 
+ *       set to default logging
+ */
+
+  /* -[un]setuplog <logtype> <loglevel> [<filename>]*/
+static void setuplog_internal(const char *logtype, const char *loglevel, const char *filename)
+{
+  int typenum, levelnum;
+
+  /* Parse logtype */
+  for( typenum=0; typenum < num_logtype_strings; typenum++) {
+      if (strcasecmp(logtype, arr_logtype_strings[typenum]) == 0)
+         break;
+  }
+  if (typenum >= num_logtype_strings) {
+      return;
+  }
+
+  /* Parse loglevel */
+  if (loglevel == NULL) {
+      levelnum = 0;
+  } else {
+      for(levelnum=1; levelnum < num_loglevel_strings; levelnum++) {
+         if (strcasecmp(loglevel, arr_loglevel_strings[levelnum]) == 0)
+             break;
+      }
+      if (levelnum >= num_loglevel_strings) {
+         return;
+      }
+  }
+
+  /* is this a syslog setup or a filelog setup ? */
+  if (filename == NULL) {
+      /* must be syslog */
+      syslog_setup(levelnum, 0, 
+                  log_config.syslog_display_options,
+                  log_config.facility);
+  } else {
+      /* this must be a filelog */
+      log_setup(filename, levelnum, typenum);
+  }
+
+  return;
+}
+
 static void generate_message_details(char *message_details_buffer, 
                               int message_details_buffer_length,
                               int display_options,
@@ -103,18 +156,21 @@ static void generate_message_details(char *message_details_buffer,
     char   *ptr = message_details_buffer;
     int    templen;
     int    len = message_details_buffer_length;
+    struct timeval tv;
 
     *ptr = 0;
 
-    /* Print date */
-    time_t thetime;
-    time(&thetime);
-
-    strftime(ptr, len, "%b %d %H:%M:%S ", localtime(&thetime));
+    /* Print time */
+    gettimeofday(&tv, NULL);
+    strftime(ptr, len, "%b %d %H:%M:%S.", localtime(&tv.tv_sec));
     templen = strlen(ptr);
     len -= templen;
     ptr += templen;
 
+    templen = snprintf(ptr, len, "%06u ", (int)tv.tv_usec);
+    len -= templen;
+    ptr += templen;
+
     /* Process name */
     strncpy(ptr, log_config.processname, len);
     templen = strlen(ptr);
@@ -194,7 +250,7 @@ void log_init(void)
 #endif
 }
 
-void log_setup(char *filename, enum loglevels loglevel, enum logtypes logtype)
+void log_setup(const char *filename, enum loglevels loglevel, enum logtypes logtype)
 {
     uid_t process_uid;
 
@@ -260,7 +316,8 @@ void log_setup(char *filename, enum loglevels loglevel, enum logtypes logtype)
        file_configs[logtype].set = 0;
        return;
     }
-    
+
+    fcntl(file_configs[logtype].fd, F_SETFD, FD_CLOEXEC);
     file_configs[logtype].set = 1;
     log_config.filelogging = 1;
     log_config.inited = 1;
@@ -281,7 +338,7 @@ void log_setup(char *filename, enum loglevels loglevel, enum logtypes logtype)
        logtype = logtype_default;
     }
 
-    LOG(log_note, logtype_logger, "Setup file logging: type: %s, level: %s, file: %s",
+    LOG(log_debug, logtype_logger, "Setup file logging: type: %s, level: %s, file: %s",
        arr_logtype_strings[logtype], arr_loglevel_strings[loglevel], file_configs[logtype].filename);
 }
 
@@ -304,7 +361,7 @@ void log_close()
 }
 
 /* This function sets up the processname */
-void set_processname(char *processname)
+void set_processname(const char *processname)
 {
   strncpy(log_config.processname, processname, 15);
   log_config.processname[15] = 0;
@@ -361,7 +418,7 @@ void make_log_entry(enum loglevels loglevel, enum logtypes logtype,
       fd = file_configs[logtype_default].fd;
 
   /* If default wasnt setup its fd is -1 */
-  if (fd > 0) {
+  if (fd >= 0) {
       iov[0].iov_base = log_details_buffer;
       iov[0].iov_len = strlen(log_details_buffer);
       iov[1].iov_base = temp_buffer;
@@ -403,54 +460,54 @@ void make_syslog_entry(enum loglevels loglevel, enum logtypes logtype, char *mes
     inlog = 0;
 }
 
-/* 
- * This is called from the afpd.conf parsing code.
- * If filename == NULL its for syslog logging, otherwise its for file-logging.
- * "unsetuplog" calls with loglevel == NULL.
- * loglevel == NULL means:
- *    if logtype == default
- *       disable logging
- *    else 
- *       set to default logging
- */
+void setuplog(const char *logstr)
+{
+    char *ptr, *ptrbak, *logtype, *loglevel, *filename;
+    ptr = strdup(logstr);
+    ptrbak = ptr;
+
+    /* logtype */
+    logtype = ptr; 
+
+    /* get loglevel */
+    ptr = strpbrk(ptr, " \t");
+    if (ptr) {
+        *ptr++ = 0;
+        while (*ptr && isspace(*ptr))
+            ptr++;
+        loglevel = ptr;
+      
+        /* get filename */
+        ptr = strpbrk(ptr, " \t");
+        if (ptr) {
+            *ptr++ = 0;
+            while (*ptr && isspace(*ptr))
+                ptr++;
+        }
+        filename = ptr;
+    }
 
-  /* -[un]setuplog <logtype> <loglevel> [<filename>]*/
-void setuplog(char *logtype, char *loglevel, char *filename)
+    /* finally call setuplog, filename can be NULL */
+    setuplog_internal(logtype, loglevel, filename);
+
+    free(ptrbak);
+}
+
+void unsetuplog(const char *logstr)
 {
-  int typenum, levelnum;
+      char *str, *logtype, *filename;
 
-  /* Parse logtype */
-  for( typenum=0; typenum < num_logtype_strings; typenum++) {
-      if (strcasecmp(logtype, arr_logtype_strings[typenum]) == 0)
-         break;
-  }
-  if (typenum >= num_logtype_strings) {
-      return;
-  }
+      str = strdup(logstr);
 
-  /* Parse loglevel */
-  if (loglevel == NULL) {
-      levelnum = 0;
-  } else {
-      for(levelnum=1; levelnum < num_loglevel_strings; levelnum++) {
-         if (strcasecmp(loglevel, arr_loglevel_strings[levelnum]) == 0)
-             break;
-      }
-      if (levelnum >= num_loglevel_strings) {
-         return;
-      }
-  }
+      /* logtype */
+      logtype = str; 
 
-  /* is this a syslog setup or a filelog setup ? */
-  if (filename == NULL) {
-      /* must be syslog */
-      syslog_setup(levelnum, 0, 
-                  log_config.syslog_display_options,
-                  log_config.facility);
-  } else {
-      /* this must be a filelog */
-      log_setup(filename, levelnum, typenum);
-  }
+      /* get filename, can be NULL */
+      strtok(str, " \t");
+      filename = strtok(NULL, " \t");
 
-  return;
+      /* finally call setuplog, filename can be NULL */
+      setuplog_internal(str, NULL, filename);
+
+      free(str);
 }