Commit | Line | Data |
---|---|---|
7b2b351e PG |
1 | /* Beginning of modification history */ |
2 | /* Written 02-01-02 by Nick Ing-Simmons (nick@ing-simmons.net) */ | |
a5f25d7a PG |
3 | /* Modified 02-03-27 by Paul Green (Paul.Green@stratus.com) to |
4 | add socketpair() dummy. */ | |
0ee4199b PG |
5 | /* Modified 02-04-24 by Paul Green (Paul.Green@stratus.com) to |
6 | have pow(0,0) return 1, avoiding c-1471. */ | |
dab8accc PG |
7 | /* Modified 06-09-25 by Paul Green (Paul.Green@stratus.com) to |
8 | add syslog entries. */ | |
3722f0dc PG |
9 | /* Modified 08-02-04 by Paul Green (Paul.Green@stratus.com) to |
10 | open the syslog file in the working dir. */ | |
7b2b351e PG |
11 | /* End of modification history */ |
12 | ||
a5f25d7a | 13 | #include <errno.h> |
7b2b351e | 14 | #include <fcntl.h> |
dab8accc PG |
15 | #include <stdio.h> |
16 | #include <stdlib.h> | |
17 | #include <string.h> | |
7b2b351e PG |
18 | #include <sys/types.h> |
19 | #include <unistd.h> | |
20 | ||
dab8accc PG |
21 | #include "vos/syslog.h" |
22 | ||
a5f25d7a PG |
23 | /* VOS doesn't supply a truncate function, so we build one up |
24 | from the available POSIX functions. */ | |
25 | ||
7b2b351e PG |
26 | int |
27 | truncate(const char *path, off_t len) | |
28 | { | |
29 | int fd = open(path,O_WRONLY); | |
30 | int code = -1; | |
31 | if (fd >= 0) { | |
32 | code = ftruncate(fd,len); | |
33 | close(fd); | |
34 | } | |
35 | return code; | |
36 | } | |
a5f25d7a PG |
37 | |
38 | /* VOS doesn't implement AF_UNIX (AF_LOCAL) style sockets, and | |
39 | the perl emulation of them hangs on VOS (due to stcp-1257), | |
40 | so we supply this version that always fails. */ | |
41 | ||
42 | int | |
43 | socketpair (int family, int type, int protocol, int fd[2]) { | |
44 | fd[0] = 0; | |
45 | fd[1] = 0; | |
46 | errno = ENOSYS; | |
47 | return -1; | |
48 | } | |
0ee4199b PG |
49 | |
50 | /* Supply a private version of the power function that returns 1 | |
51 | for x**0. This avoids c-1471. Abigail's Japh tests depend | |
52 | on this fix. We leave all the other cases to the VOS C | |
53 | runtime. */ | |
54 | ||
55 | double s_crt_pow(double *x, double *y); | |
56 | ||
57 | double pow(x,y) | |
58 | double x, y; | |
59 | { | |
60 | if (y == 0e0) /* c-1471 */ | |
61 | { | |
62 | errno = EDOM; | |
63 | return (1e0); | |
64 | } | |
65 | ||
66 | return(s_crt_pow(&x,&y)); | |
67 | } | |
dab8accc PG |
68 | |
69 | /* entries */ | |
70 | ||
71 | extern void s$log_system_message ( | |
72 | /* char_varying (256) *message_text, | |
73 | char_varying (66) *module_name, | |
74 | short int *error_code */ ); | |
75 | ||
76 | /* constants */ | |
77 | ||
78 | #define ALL_PRIORITIES 255 /* 8 priorities, all enabled */ | |
79 | #define BUFFER_LEN 256 | |
80 | #define IDENT_LEN 64 | |
81 | #define MSG_LEN 256 | |
82 | #define PATH_LEN 257 | |
83 | ||
84 | /* static */ | |
85 | ||
86 | int vos_syslog_facility = LOG_USER>>3; | |
87 | int vos_syslog_fd = -1; | |
88 | int vos_syslog_logopt = 0; | |
89 | char vos_syslog_ident[IDENT_LEN] = ""; | |
90 | int vos_syslog_ident_len = 0; | |
91 | int vos_syslog_mask = ALL_PRIORITIES; | |
3722f0dc | 92 | char vos_syslog_path[PATH_LEN] = "syslog"; |
dab8accc PG |
93 | |
94 | char vos_syslog_facility_name [17][10] = { | |
95 | "[KERN] ", /* LOG_KERN */ | |
96 | "[USER] ", /* LOG_USER */ | |
97 | "[MAIL] ", /* LOG_MAIL */ | |
98 | "[NEWS] ", /* LOG_NEWS */ | |
99 | "[UUCP] ", /* LOG_UUCP */ | |
100 | "[DAEMON] ", /* LOG_DAEMON */ | |
101 | "[AUTH] ", /* LOG_AUTH */ | |
102 | "[CRON] ", /* LOG_CRON */ | |
103 | "[LPR] ", /* LOG_LPR */ | |
104 | "[LOCAL0] ", /* LOG_LOCAL0 */ | |
105 | "[LOCAL1] ", /* LOG_LOCAL1 */ | |
106 | "[LOCAL2] ", /* LOG_LOCAL2 */ | |
107 | "[LOCAL3] ", /* LOG_LOCAL3 */ | |
108 | "[LOCAL4] ", /* LOG_LOCAL4 */ | |
109 | "[LOCAL5] ", /* LOG_LOCAL5 */ | |
110 | "[LOCAL6] ", /* LOG_LOCAL6 */ | |
111 | "[LOCAL7] "}; /* LOG_LOCAL7 */ | |
112 | ||
113 | /* syslog functions */ | |
114 | ||
115 | static void open_syslog (void) | |
116 | { | |
117 | if (vos_syslog_fd >= 0) | |
118 | return; | |
119 | ||
120 | vos_syslog_fd = open (vos_syslog_path, O_RDWR | O_CREAT | O_APPEND, 0777); | |
121 | if (vos_syslog_fd < 0) | |
122 | fprintf (stderr, "Unable to open %s (errno=%d, os_errno=%d)\n", | |
123 | vos_syslog_path, errno, os_errno); | |
124 | } | |
125 | ||
126 | void closelog (void) | |
127 | { | |
128 | if (vos_syslog_fd >= 0) | |
129 | close (vos_syslog_fd); | |
130 | ||
131 | vos_syslog_facility = LOG_USER>>3; | |
132 | vos_syslog_fd = -1; | |
133 | vos_syslog_logopt = 0; | |
134 | vos_syslog_ident[0] = '\0'; | |
135 | vos_syslog_ident_len = 0; | |
136 | vos_syslog_mask = ALL_PRIORITIES; | |
137 | return; | |
138 | } | |
139 | ||
140 | void openlog (const char *ident, int logopt, int facility) | |
141 | { | |
142 | int n; | |
143 | ||
144 | if (ident != NULL) | |
145 | { | |
146 | strncpy (vos_syslog_ident, ident, sizeof (vos_syslog_ident)); | |
147 | n = IDENT_LEN - | |
148 | strnlen (vos_syslog_ident, sizeof (vos_syslog_ident)); | |
149 | strncat (vos_syslog_ident, ": ", n); | |
150 | vos_syslog_ident_len = strnlen (vos_syslog_ident, | |
151 | sizeof (vos_syslog_ident)); | |
152 | } | |
153 | ||
154 | vos_syslog_logopt = logopt; | |
155 | vos_syslog_facility = facility>>3; | |
156 | ||
157 | if ((logopt & LOG_NDELAY) == LOG_NDELAY) | |
158 | open_syslog (); | |
159 | ||
160 | return; | |
161 | } | |
162 | ||
163 | int setlogmask (int maskpri) | |
164 | { | |
165 | int old_mask; | |
166 | ||
167 | old_mask = vos_syslog_mask; | |
168 | ||
169 | if (maskpri > 0) | |
170 | vos_syslog_mask = maskpri; | |
171 | ||
172 | return old_mask; | |
173 | } | |
174 | ||
175 | void syslog (int priority, const char *format, ...) | |
176 | { | |
177 | va_list ap; | |
178 | int bare_facility; | |
179 | int bare_priority; | |
180 | int buffer_n; | |
181 | char buffer[BUFFER_LEN]; | |
182 | short int code; | |
183 | char_varying(MSG_LEN) message; | |
184 | char_varying(66) module_name; | |
185 | int n; | |
186 | int pid_n; | |
187 | char pid_string[32]; | |
188 | int r; | |
189 | int user_n; | |
190 | char user_string[256]; | |
191 | ||
192 | /* Calculate priority and facility value. */ | |
193 | ||
194 | bare_priority = priority & 3; | |
195 | bare_facility = priority >> 3; | |
196 | ||
197 | /* If the priority is not set in the mask, do not log the | |
198 | message. */ | |
199 | ||
200 | if ((vos_syslog_mask & LOG_MASK(bare_priority)) == 0) | |
201 | return; | |
202 | ||
203 | /* Output facility name. */ | |
204 | ||
205 | if (bare_facility == 0) | |
206 | bare_facility = vos_syslog_facility; | |
207 | ||
208 | strcpy (buffer, vos_syslog_facility_name[bare_facility]); | |
209 | ||
210 | /* Output priority value. */ | |
211 | ||
212 | /* TBD */ | |
213 | ||
214 | /* Output identity string. */ | |
215 | ||
216 | buffer_n = BUFFER_LEN - strlen (buffer); | |
217 | strncat (buffer, vos_syslog_ident, buffer_n); | |
218 | ||
219 | /* Output process ID. */ | |
220 | ||
221 | if ((vos_syslog_logopt & LOG_PID) == LOG_PID) | |
222 | { | |
223 | pid_n = snprintf (pid_string, sizeof (pid_string), | |
224 | "PID=0x%x ", getpid ()); | |
225 | if (pid_n) | |
226 | { | |
227 | buffer_n = BUFFER_LEN - strlen (buffer); | |
228 | strncat (buffer, pid_string, buffer_n); | |
229 | } | |
230 | } | |
231 | ||
232 | /* Output formatted message. */ | |
233 | ||
234 | va_start (ap, format); | |
235 | user_n = vsnprintf (user_string, sizeof (user_string), format, ap); | |
236 | va_end (ap); | |
237 | ||
238 | /* Ensure string ends in a newline. */ | |
239 | ||
240 | if (user_n > 0) | |
241 | { | |
242 | if (user_n >= sizeof (user_string)) | |
243 | user_n = sizeof (user_string) - 1; | |
244 | ||
245 | /* arrays are zero-origin.... */ | |
246 | ||
247 | if (user_string [user_n-1] != '\n') | |
248 | { | |
249 | user_string [user_n-1] = '\n'; | |
250 | user_string [user_n++] = '\0'; | |
251 | } | |
252 | } | |
253 | else | |
254 | { | |
255 | user_string [0] = '\n'; | |
256 | user_string [1] = '\0'; | |
257 | user_n = 1; | |
258 | } | |
259 | ||
260 | buffer_n = BUFFER_LEN - strnlen (buffer, sizeof (buffer)); | |
261 | strncat (buffer, user_string, buffer_n); | |
262 | ||
263 | /* If the log is not open, try to open it now. */ | |
264 | ||
265 | if (vos_syslog_fd < 0) | |
266 | open_syslog (); | |
267 | ||
268 | /* Try to write the message to the syslog file. */ | |
269 | ||
270 | if (vos_syslog_fd < 0) | |
271 | r = -1; | |
272 | else | |
273 | { | |
274 | buffer_n = strnlen (buffer, sizeof (buffer)); | |
275 | r = write (vos_syslog_fd, buffer, buffer_n); | |
276 | } | |
277 | ||
278 | /* If we were unable to write to the log and if LOG_CONS is | |
279 | set, send it to the console. */ | |
280 | ||
281 | if (r < 0) | |
282 | if ((vos_syslog_logopt & LOG_CONS) == LOG_CONS) | |
283 | { | |
284 | strcpy_vstr_nstr (&message, "syslog: "); | |
285 | n = MSG_LEN - sizeof ("syslog: "); | |
286 | strncat_vstr_nstr (&message, buffer, n); | |
287 | strcpy_vstr_nstr (&module_name, ""); | |
288 | s$log_system_message (&message, &module_name, &code); | |
289 | } | |
290 | ||
291 | return; | |
292 | } |