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 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 23 /* All Rights Reserved */ 24 25 /* 26 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 27 * Use is subject to license terms. 28 */ 29 30 #pragma ident "%Z%%M% %I% %E% SMI" 31 32 /* 33 * error/logging/cleanup functions for the network listener process. 34 */ 35 36 37 /* system include files */ 38 39 #include <fcntl.h> 40 #include <signal.h> 41 #include <stdio.h> 42 #include <string.h> 43 #include <errno.h> 44 #include <tiuser.h> 45 #include <sys/utsname.h> 46 #include <sys/param.h> 47 #include <sys/types.h> 48 #include <sys/stat.h> 49 #include <sys/ipc.h> 50 #include <values.h> 51 #include <ctype.h> 52 #include <time.h> 53 54 /* listener include files */ 55 56 #include "lsparam.h" /* listener parameters */ 57 #include "listen.h" /* listener */ 58 #include "lsfiles.h" /* listener files info */ 59 #include "lserror.h" /* listener error codes */ 60 #include "lsdbf.h" 61 62 extern char Lastmsg[]; 63 extern int NLPS_proc; 64 extern char *Netspec; 65 extern FILE *Logfp; 66 extern FILE *Debugfp; 67 extern char Mytag[]; 68 69 static char *stamp(char *); 70 71 /* 72 * error handling and debug routines 73 * most routines take two args: code and exit. 74 * code is a #define in lserror.h. 75 * if EXIT bit in exitflag is non-zero, the routine exits. (see clean_up() ) 76 * define COREDUMP to do the obvious. 77 */ 78 79 80 /* 81 * error: catastrophic error handler 82 */ 83 84 error(code, exitflag) 85 int code, exitflag; 86 { 87 char scratch[BUFSIZ]; 88 89 if (!(exitflag & NO_MSG)) { 90 strcpy(scratch, err_list[code].err_msg); 91 clean_up(code, exitflag, scratch); 92 } 93 clean_up(code, exitflag, NULL); 94 } 95 96 /* 97 * tli_error: Deal (appropriately) with an error in a TLI call 98 */ 99 100 static char *tlirange = "Unknown TLI error (t_errno > t_nerr)"; 101 102 void 103 tli_error(int code, int exitflag) 104 { 105 void t_error(); 106 char scratch[256]; 107 const char *p; 108 int save_errno = errno; 109 110 p = (t_errno < t_nerr ? t_errlist[t_errno] : tlirange); 111 112 (void) snprintf(scratch, sizeof (scratch), "%s: %s", 113 err_list[code].err_msg, p); 114 if (t_errno == TSYSERR) { 115 (void) strlcat(scratch, ": ", sizeof (scratch)); 116 (void) strlcat(scratch, strerror(save_errno), sizeof (scratch)); 117 } 118 clean_up(code, exitflag, scratch); 119 } 120 121 122 /* 123 * sys_error: error in a system call 124 */ 125 126 void 127 sys_error(int code, int exitflag) 128 { 129 char scratch[256]; 130 131 (void) snprintf(scratch, sizeof (scratch), "%s: %s", 132 err_list[code].err_msg, strerror(errno)); 133 clean_up(code, exitflag, scratch); 134 } 135 136 137 /* 138 * clean_up: if 'flag', and main listener is exiting, clean things 139 * up and exit. Dumps core if !(flag & NOCORE). 140 * Tries to send a message to someone if the listener 141 * is exiting due to an error. (Inherrently machine dependent.) 142 */ 143 144 clean_up(code, flag, msg) 145 register code, flag; 146 char *msg; 147 { 148 extern int Dbf_entries; 149 extern void logexit(); 150 extern 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 log(code) 225 int code; 226 { 227 logmessage(err_list[code].err_msg); 228 } 229 230 231 static int nlogs; /* maintains size of logfile */ 232 233 logmessage(s) 234 char *s; 235 { 236 char log[BUFSIZ]; 237 char olog[BUFSIZ]; 238 register err = 0; 239 register 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