1 /* ISC license. */
2
3 #undef INTERNAL_MARK
4 #ifndef SYSLOG_NAMES
5 #define SYSLOG_NAMES
6 #endif
7
8 #include <skalibs/nonposix.h>
9 #include <sys/types.h>
10 #include <errno.h>
11 #include <stdlib.h>
12 #include <syslog.h>
13 #include <skalibs/types.h>
14 #include <skalibs/sgetopt.h>
15 #include <skalibs/bytestr.h>
16 #include <skalibs/buffer.h>
17 #include <skalibs/strerr2.h>
18 #include <skalibs/stralloc.h>
19 #include <skalibs/env.h>
20 #include <skalibs/skamisc.h>
21
22 #define USAGE "ucspilogd [ -D default ] [ var... ]"
23 #define dieusage() strerr_dieusage(100, USAGE)
24
die(void)25 static inline void die (void)
26 {
27 strerr_diefu1sys(111, "write to stdout") ;
28 }
29
30
31 /*
32 Hack: INTERNAL_MARK is defined by all systems that
33 use the CODE stuff, and not by others (Solaris).
34 */
35
36 #ifndef INTERNAL_MARK
37
38 typedef struct CODE_s CODE, *CODE_ref ;
39 struct CODE_s
40 {
41 char *c_name ;
42 unsigned int c_val ;
43 } ;
44
45 static CODE const prioritynames[] =
46 {
47 { "emerg", LOG_EMERG },
48 { "alert", LOG_ALERT },
49 { "crit", LOG_CRIT },
50 { "err", LOG_ERR },
51 { "warning", LOG_WARNING },
52 { "notice", LOG_NOTICE },
53 { "info", LOG_INFO },
54 { "debug", LOG_DEBUG },
55 { 0, -1 }
56 } ;
57
58 static CODE const facilitynames[] =
59 {
60 { "kern", LOG_KERN },
61 { "user", LOG_USER },
62 { "mail", LOG_MAIL },
63 { "news", LOG_NEWS },
64 { "uucp", LOG_UUCP },
65 { "daemon", LOG_DAEMON },
66 { "auth", LOG_AUTH },
67 { "cron", LOG_CRON },
68 { "lpr", LOG_LPR },
69 #ifdef LOG_SYSLOG
70 { "syslog", LOG_SYSLOG },
71 #endif
72 #ifdef LOG_AUDIT
73 { "audit", LOG_AUDIT },
74 #endif
75 { "local0", LOG_LOCAL0 },
76 { "local1", LOG_LOCAL1 },
77 { "local2", LOG_LOCAL2 },
78 { "local3", LOG_LOCAL3 },
79 { "local4", LOG_LOCAL4 },
80 { "local5", LOG_LOCAL5 },
81 { "local6", LOG_LOCAL6 },
82 { "local7", LOG_LOCAL7 },
83 { 0, -1 }
84 } ;
85
86 #define LOG_PRI(p) ((p) & LOG_PRIMASK)
87 #define LOG_FAC(p) (((p) & LOG_FACMASK) / (LOG_PRIMASK + 1))
88
89 #endif
90
91
syslog_names(char const * line)92 static size_t syslog_names (char const *line)
93 {
94 size_t i ;
95 unsigned int fpr ;
96 int fp ;
97 CODE const *p = facilitynames ;
98
99 if (line[0] != '<') return 0 ;
100 i = uint_scan(line+1, &fpr) ;
101 if (!i || (line[i+1] != '>')) return 0 ;
102 i += 2 ;
103
104 fp = LOG_FAC(fpr) << 3 ;
105 for (; p->c_name ; p++) if (p->c_val == fp) break ;
106 if (p->c_name)
107 {
108 if ((buffer_puts(buffer_1, p->c_name) < 0)
109 || (buffer_put(buffer_1, ".", 1) < 1)) die() ;
110 }
111 else
112 {
113 if (buffer_put(buffer_1, "unknown.", 8) < 8) die() ;
114 i = 0 ;
115 }
116
117 fp = LOG_PRI(fpr) ;
118 for (p = prioritynames ; p->c_name ; p++) if (p->c_val == fp) break ;
119 if (p->c_name)
120 {
121 if ((buffer_puts(buffer_1, p->c_name) < 0)
122 || (buffer_put(buffer_1, ": ", 2) < 2)) die() ;
123 }
124 else
125 {
126 if (buffer_put(buffer_1, "unknown: ", 9) < 9) die() ;
127 i = 0 ;
128 }
129 return i ;
130 }
131
132
main(int argc,char const * const * argv,char const * const * envp)133 int main (int argc, char const *const *argv, char const *const *envp)
134 {
135 char const *d = "<undefined>" ;
136 PROG = "ucspilogd" ;
137 {
138 subgetopt_t l = SUBGETOPT_ZERO ;
139 for (;;)
140 {
141 int opt = subgetopt_r(argc, argv, "D:", &l) ;
142 if (opt == -1) break ;
143 switch (opt)
144 {
145 case 'D' : d = l.arg ; break ;
146 default : dieusage() ;
147 }
148 }
149 argc -= l.ind ; argv += l.ind ;
150 }
151
152 {
153 char const *envs[argc] ;
154 unsigned int i = 0 ;
155 for (; i < (unsigned int)argc ; i++)
156 {
157 envs[i] = env_get2(envp, argv[i]) ;
158 if (!envs[i]) envs[i] = d ;
159 }
160 for (;;)
161 {
162 size_t pos = 0 ;
163 satmp.len = 0 ;
164 {
165 int r = skagetlnsep(buffer_0f1, &satmp, "\n", 2) ;
166 if (r < 0)
167 {
168 if (errno != EPIPE || !stralloc_0(&satmp))
169 strerr_diefu1sys(111, "read from stdin") ;
170 }
171 if (!r) break ;
172 }
173 if (!satmp.len) continue ;
174 satmp.s[satmp.len-1] = '\n' ;
175 if ((satmp.s[0] == '@') && (satmp.len > 26) && (byte_chr(satmp.s, 26, ' ') == 25))
176 {
177 if (buffer_put(buffer_1, satmp.s, 26) < 26) die() ;
178 pos += 26 ;
179 }
180 for (i = 0 ; i < (unsigned int)argc ; i++)
181 if ((buffer_puts(buffer_1, envs[i]) < 0)
182 || (buffer_put(buffer_1, ": ", 2) < 2)) die() ;
183 pos += syslog_names(satmp.s + pos) ;
184 if (buffer_put(buffer_1, satmp.s + pos, satmp.len - pos) < (ssize_t)(satmp.len - pos)) die() ;
185 }
186 }
187 return 0 ;
188 }
189