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