xref: /illumos-gate/usr/src/cmd/listen/lslog.c (revision bdcaf82257ab2deb6b46efaaa4bc93a1a44b3885)
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