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 /* End of modification history */ 10 11 #include <errno.h> 12 #include <fcntl.h> 13 #include <stdio.h> 14 #include <stdlib.h> 15 #include <string.h> 16 #include <sys/types.h> 17 #include <unistd.h> 18 19 #include "vos/syslog.h" 20 21 /* VOS doesn't supply a truncate function, so we build one up 22 from the available POSIX functions. */ 23 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 } 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 } 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 } 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 } 291