1 /* Beginning of modification history */ 2 /* Written 02-01-02 by Nick Ing-Simmons (nick@ing-simmons.net) */ 3 /* Modified 02-03-27 by Paul Green (Paul.Green@stratus.com) to 4 add socketpair() dummy. */ 5 /* Modified 02-04-24 by Paul Green (Paul.Green@stratus.com) to 6 have pow(0,0) return 1, avoiding c-1471. */ 7 /* Modified 06-09-25 by Paul Green (Paul.Green@stratus.com) to 8 add syslog entries. */ 9 /* Modified 08-02-04 by Paul Green (Paul.Green@stratus.com) to 10 open the syslog file in the working dir. */ 11 /* End of modification history */ 12 13 #include <errno.h> 14 #include <fcntl.h> 15 #include <stdio.h> 16 #include <stdlib.h> 17 #include <string.h> 18 #include <sys/types.h> 19 #include <unistd.h> 20 21 #include "vos/syslog.h" 22 23 /* VOS doesn't supply a truncate function, so we build one up 24 from the available POSIX functions. */ 25 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 } 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 } 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 } 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; 92 char vos_syslog_path[PATH_LEN] = "syslog"; 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 } 293