--- /dev/null
+/*
+ gw-log.c: Implementation of logging facilities.
+
+ Europagate, 1994-1995.
+
+ $Log: gw-log.c,v $
+ Revision 1.1 1995/02/09 17:27:11 adam
+ Initial revision
+
+
+ Initial: Dec 7, 94 (Adam Dickmeiss)
+ Last update: Dec 13, 94 (Adam Dickmeiss)
+
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <time.h>
+
+#include <gw-log.h>
+
+static char *app_name = NULL;
+static unsigned level = GW_LOG_DEFAULT;
+static int session = 0;
+
+struct file_mask {
+ unsigned mask; /* level mask for this file entry */
+ int fd; /* file descriptor for this file */
+ char *fname; /* name of file ("" if stdout) */
+ struct file_mask *next; /* next file in chain */
+};
+
+struct file_mask *file_mask_list = NULL;
+
+char *gw_strdup (const char *s)
+{
+ char *n = malloc (strlen(s)+1);
+ if (n)
+ strcpy (n, s);
+ return n;
+}
+
+void gw_log_init (const char *app_name_a)
+{
+ struct file_mask *list, *list1;
+
+ app_name = gw_strdup (app_name_a);
+ level = GW_LOG_DEFAULT;
+ session = 0;
+
+ /* clean up all output file masks... */
+ for (list = file_mask_list; list; list = list1)
+ {
+ if (list->fd > 2) /* avoid closing stdout/stderr */
+ close (list->fd);
+ free (list->fname);
+ list1 = list->next;
+ free (list);
+ }
+ file_mask_list = NULL;
+}
+
+void gw_log_level (unsigned level_a)
+{
+ level = level_a;
+}
+
+void gw_log_session (int session_a)
+{
+ session = session_a;
+}
+
+int gw_log_file (unsigned level_a, const char *fname_a)
+{
+ struct file_mask **listp, *new_file_mask;
+ listp = &file_mask_list;
+
+ /* go through file mask list and close files already associated */
+ /* on new level */
+ while (*listp)
+ {
+ if (!((*listp)->mask &= ~level_a)) /* any levels left on this one? */
+ {
+ if ((*listp)->fd > 2) /* close if not stdout/stderr */
+ close ((*listp)->fd);
+ free ((*listp)->fname);
+ *listp = (*listp)->next;
+ }
+ listp = &(*listp)->next;
+ }
+ if (!fname_a) /* stderr? */
+ return 0; /* stderr doesn't appear on list */
+ new_file_mask = malloc (sizeof(*new_file_mask));
+ if (!new_file_mask)
+ return -1;
+ new_file_mask->mask = level_a;
+ new_file_mask->next = file_mask_list;
+ file_mask_list = new_file_mask;
+ if (!(file_mask_list->fname = gw_strdup (fname_a)))
+ return -1;
+ if (*fname_a == '\0') /* stdout? */
+ new_file_mask->fd = 1;
+ else /* no, open as usual */
+ {
+ new_file_mask->fd = open (fname_a, O_WRONLY|O_CREAT|O_APPEND, 0666);
+ if (new_file_mask->fd == -1)
+ return -1;
+ }
+ return 0;
+}
+
+int gw_log (unsigned level_a, const char *event_type, const char *format, ...)
+{
+ static char emit_str[2048];
+ struct file_mask *list;
+ va_list ap;
+ unsigned e_level = level_a & level;
+ int count;
+ int err = 0;
+ time_t time_now;
+ char *cp;
+
+ if (!e_level) /* any effective level(s)? */
+ return 0;
+
+ va_start (ap, format);
+ time (&time_now);
+ sprintf (emit_str, "%s %d %s %d %s ", app_name, session,
+ ctime (&time_now), e_level, event_type);
+ if ((cp = strchr (emit_str, '\n'))) /* remove \n from ctime-str */
+ *cp = ' ';
+ count = strlen (emit_str);
+ vsprintf (emit_str+count, format, ap);
+ strcat (emit_str, "\n");
+ count = strlen (emit_str);
+
+ /* go through file mask list... */
+ for (list = file_mask_list; list; list = list->next)
+ if (list->mask & e_level) /* output this one? */
+ {
+ e_level &= ~list->mask; /* remove from effective level */
+ if (write (list->fd, emit_str, count) != count)
+ err = 1;
+ }
+ if (e_level) /* bits left on effective level? */
+ write (2, emit_str, count);
+ va_end (ap);
+ return err;
+}