2 gw-log.c: Implementation of logging facilities.
7 Revision 1.1 1995/02/09 17:27:11 adam
11 Initial: Dec 7, 94 (Adam Dickmeiss)
12 Last update: Dec 13, 94 (Adam Dickmeiss)
26 static char *app_name = NULL;
27 static unsigned level = GW_LOG_DEFAULT;
28 static int session = 0;
31 unsigned mask; /* level mask for this file entry */
32 int fd; /* file descriptor for this file */
33 char *fname; /* name of file ("" if stdout) */
34 struct file_mask *next; /* next file in chain */
37 struct file_mask *file_mask_list = NULL;
39 char *gw_strdup (const char *s)
41 char *n = malloc (strlen(s)+1);
47 void gw_log_init (const char *app_name_a)
49 struct file_mask *list, *list1;
51 app_name = gw_strdup (app_name_a);
52 level = GW_LOG_DEFAULT;
55 /* clean up all output file masks... */
56 for (list = file_mask_list; list; list = list1)
58 if (list->fd > 2) /* avoid closing stdout/stderr */
64 file_mask_list = NULL;
67 void gw_log_level (unsigned level_a)
72 void gw_log_session (int session_a)
77 int gw_log_file (unsigned level_a, const char *fname_a)
79 struct file_mask **listp, *new_file_mask;
80 listp = &file_mask_list;
82 /* go through file mask list and close files already associated */
86 if (!((*listp)->mask &= ~level_a)) /* any levels left on this one? */
88 if ((*listp)->fd > 2) /* close if not stdout/stderr */
90 free ((*listp)->fname);
91 *listp = (*listp)->next;
93 listp = &(*listp)->next;
95 if (!fname_a) /* stderr? */
96 return 0; /* stderr doesn't appear on list */
97 new_file_mask = malloc (sizeof(*new_file_mask));
100 new_file_mask->mask = level_a;
101 new_file_mask->next = file_mask_list;
102 file_mask_list = new_file_mask;
103 if (!(file_mask_list->fname = gw_strdup (fname_a)))
105 if (*fname_a == '\0') /* stdout? */
106 new_file_mask->fd = 1;
107 else /* no, open as usual */
109 new_file_mask->fd = open (fname_a, O_WRONLY|O_CREAT|O_APPEND, 0666);
110 if (new_file_mask->fd == -1)
116 int gw_log (unsigned level_a, const char *event_type, const char *format, ...)
118 static char emit_str[2048];
119 struct file_mask *list;
121 unsigned e_level = level_a & level;
127 if (!e_level) /* any effective level(s)? */
130 va_start (ap, format);
132 sprintf (emit_str, "%s %d %s %d %s ", app_name, session,
133 ctime (&time_now), e_level, event_type);
134 if ((cp = strchr (emit_str, '\n'))) /* remove \n from ctime-str */
136 count = strlen (emit_str);
137 vsprintf (emit_str+count, format, ap);
138 strcat (emit_str, "\n");
139 count = strlen (emit_str);
141 /* go through file mask list... */
142 for (list = file_mask_list; list; list = list->next)
143 if (list->mask & e_level) /* output this one? */
145 e_level &= ~list->mask; /* remove from effective level */
146 if (write (list->fd, emit_str, count) != count)
149 if (e_level) /* bits left on effective level? */
150 write (2, emit_str, count);