1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 23 /* 24 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 25 * Use is subject to license terms. 26 */ 27 28 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 29 /* All Rights Reserved */ 30 31 /* 32 * error/logging/cleanup functions for the network listener process. 33 */ 34 35 36 /* system include files */ 37 38 #include <fcntl.h> 39 #include <signal.h> 40 #include <stdio.h> 41 #include <string.h> 42 #include <errno.h> 43 #include <tiuser.h> 44 #include <sys/utsname.h> 45 #include <sys/param.h> 46 #include <sys/types.h> 47 #include <sys/stat.h> 48 #include <sys/ipc.h> 49 #include <values.h> 50 #include <ctype.h> 51 #include <time.h> 52 53 /* listener include files */ 54 55 #include "lsparam.h" /* listener parameters */ 56 #include "listen.h" /* listener */ 57 #include "lsfiles.h" /* listener files info */ 58 #include "lserror.h" /* listener error codes */ 59 #include "lsdbf.h" 60 61 extern char Lastmsg[]; 62 extern int NLPS_proc; 63 extern char *Netspec; 64 extern FILE *Logfp; 65 extern FILE *Debugfp; 66 extern char Mytag[]; 67 68 static char *stamp(char *); 69 void logmessage(char *s); 70 void clean_up(int code, int flag, char *msg); 71 72 /* 73 * error handling and debug routines 74 * most routines take two args: code and exit. 75 * code is a #define in lserror.h. 76 * if EXIT bit in exitflag is non-zero, the routine exits. (see clean_up() ) 77 * define COREDUMP to do the obvious. 78 */ 79 80 81 /* 82 * error: catastrophic error handler 83 */ 84 85 void 86 error(int code, int exitflag) 87 { 88 char scratch[BUFSIZ]; 89 90 if (!(exitflag & NO_MSG)) { 91 strcpy(scratch, err_list[code].err_msg); 92 clean_up(code, exitflag, scratch); 93 } 94 clean_up(code, exitflag, NULL); 95 } 96 97 /* 98 * tli_error: Deal (appropriately) with an error in a TLI call 99 */ 100 101 static char *tlirange = "Unknown TLI error (t_errno > t_nerr)"; 102 103 void 104 tli_error(int code, int exitflag) 105 { 106 void t_error(); 107 char scratch[256]; 108 const char *p; 109 int save_errno = errno; 110 111 p = (t_errno < t_nerr ? t_errlist[t_errno] : tlirange); 112 113 (void) snprintf(scratch, sizeof (scratch), "%s: %s", 114 err_list[code].err_msg, p); 115 if (t_errno == TSYSERR) { 116 (void) strlcat(scratch, ": ", sizeof (scratch)); 117 (void) strlcat(scratch, strerror(save_errno), sizeof (scratch)); 118 } 119 clean_up(code, exitflag, scratch); 120 } 121 122 123 /* 124 * sys_error: error in a system call 125 */ 126 127 void 128 sys_error(int code, int exitflag) 129 { 130 char scratch[256]; 131 132 (void) snprintf(scratch, sizeof (scratch), "%s: %s", 133 err_list[code].err_msg, strerror(errno)); 134 clean_up(code, exitflag, scratch); 135 } 136 137 138 /* 139 * clean_up: if 'flag', and main listener is exiting, clean things 140 * up and exit. Dumps core if !(flag & NOCORE). 141 * Tries to send a message to someone if the listener 142 * is exiting due to an error. (Inherrently machine dependent.) 143 */ 144 145 void 146 clean_up(int code, int flag, char *msg) 147 { 148 extern int Dbf_entries; 149 extern void logexit(); 150 extern int NLPS_proc, Nflag; 151 int i; 152 extern dbf_t Dbfhead; 153 dbf_t *dbp = &Dbfhead; 154 155 if (!(flag & EXIT)) { 156 logmessage(msg); 157 return; 158 } 159 160 if (!(NLPS_proc)) { 161 162 /* 163 * unbind anything that we bound. 164 * Needs more intelligence. 165 */ 166 167 168 for (i=0;i<Dbf_entries;i++) { 169 t_unbind(dbp->dbf_fd); 170 dbp++; 171 } 172 } 173 174 #ifdef COREDUMP 175 if (!(flag & NOCORE)) 176 abort(); 177 #endif /* COREDUMP */ 178 179 logexit(err_list[code].err_code, msg); 180 } 181 182 183 void 184 logexit(exitcode, msg) 185 int exitcode; 186 char *msg; 187 { 188 if (msg) { 189 logmessage(msg); /* put it in the log */ 190 } 191 if (!NLPS_proc) 192 logmessage("*** listener terminating!!! ***"); 193 exit(exitcode); 194 195 } 196 197 198 #ifdef DEBUGMODE 199 200 /*VARARGS2*/ 201 int 202 debug(int level, char *format, ...) 203 { 204 char buf[256]; 205 va_list ap; 206 207 va_start(ap, format); 208 (void) vsprintf(buf, format, ap); 209 va_end(ap); 210 211 fprintf(Debugfp, stamp(buf)); 212 fflush(Debugfp); 213 } 214 215 #endif 216 217 218 219 /* 220 * log: given a message number (code), write a message to the logfile 221 * logmessage: given a string, write a message to the logfile 222 */ 223 224 void 225 log(int code) 226 { 227 logmessage(err_list[code].err_msg); 228 } 229 230 231 static int nlogs; /* maintains size of logfile */ 232 233 void 234 logmessage(char *s) 235 { 236 char log[BUFSIZ]; 237 char olog[BUFSIZ]; 238 int err = 0; 239 FILE *nlogfp; 240 extern int Logmax; 241 extern int Splflag; 242 243 /* 244 * The listener may be maintaining the size of it's logfile. 245 * Nothing in here should make the listener abort. 246 * If it can't save the file, it rewinds the existing log. 247 * Note that the algorithm is not exact, child listener's 248 * messages do not affect the parent's count. 249 */ 250 251 if (!Logfp) 252 return; 253 if (!NLPS_proc && Logmax && ( nlogs >= Logmax ) && !Splflag) { 254 nlogs = 0; 255 fprintf(Logfp, stamp("Restarting log file")); 256 sprintf(log, "%s/%s/%s", ALTDIR, Mytag, LOGNAME); 257 sprintf(olog, "%s/%s/%s", ALTDIR, Mytag, OLOGNAME); 258 DEBUG((1, "Logfile exceeds Logmax (%d) lines", Logmax)); 259 unlink(olog); /* remove stale saved logfile */ 260 if (rename(log, olog)) { 261 ++err; 262 rewind(Logfp); 263 DEBUG((1,"errno %d renaming log to old logfile",errno)); 264 } 265 else if (nlogfp = fopen(log, "a+")) { 266 fclose(Logfp); 267 Logfp = nlogfp; 268 fcntl(fileno(Logfp), F_SETFD, 1); /* reset close-on-exec */ 269 DEBUG((1, "logmessage: logfile saved successfully")); 270 } else { 271 ++err; 272 rewind(Logfp); 273 DEBUG((1, "Lost the logfile, errno %d", errno)); 274 } 275 if (err) 276 fprintf(Logfp, stamp("Trouble saving the logfile")); 277 } 278 279 fprintf(Logfp, stamp(s)); 280 fflush(Logfp); 281 ++nlogs; 282 } 283 284 extern pid_t Pid; 285 286 static char * 287 stamp(char *msg) 288 { 289 time_t clock; 290 struct tm *tm_p; 291 292 (void)time(&clock); 293 tm_p = (struct tm *) localtime(&clock); 294 tm_p->tm_mon++; /* since months are 0-11 */ 295 sprintf(Lastmsg, "%2.2d/%2.2d/%2.2d %2.2d:%2.2d:%2.2d; %ld; %s\n", 296 tm_p->tm_mon, tm_p->tm_mday, (tm_p->tm_year % 100), 297 tm_p->tm_hour, tm_p->tm_min, tm_p->tm_sec, Pid, msg); 298 return(Lastmsg); 299 } 300