xref: /illumos-gate/usr/src/cmd/listen/lslog.c (revision 2a8bcb4e)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
57c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
67c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
77c478bd9Sstevel@tonic-gate  * with the License.
87c478bd9Sstevel@tonic-gate  *
97c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate  * and limitations under the License.
137c478bd9Sstevel@tonic-gate  *
147c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate  *
207c478bd9Sstevel@tonic-gate  * CDDL HEADER END
217c478bd9Sstevel@tonic-gate  */
227c478bd9Sstevel@tonic-gate 
23ace1a5f1Sdp /*
24ace1a5f1Sdp  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
25ace1a5f1Sdp  * Use is subject to license terms.
26ace1a5f1Sdp  */
277c478bd9Sstevel@tonic-gate 
28*113f4232Sakaplan /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
29*113f4232Sakaplan /*	  All Rights Reserved  	*/
30*113f4232Sakaplan 
317c478bd9Sstevel@tonic-gate /*
327c478bd9Sstevel@tonic-gate  * error/logging/cleanup functions for the network listener process.
337c478bd9Sstevel@tonic-gate  */
347c478bd9Sstevel@tonic-gate 
357c478bd9Sstevel@tonic-gate 
367c478bd9Sstevel@tonic-gate /* system include files	*/
377c478bd9Sstevel@tonic-gate 
387c478bd9Sstevel@tonic-gate #include <fcntl.h>
397c478bd9Sstevel@tonic-gate #include <signal.h>
407c478bd9Sstevel@tonic-gate #include <stdio.h>
417c478bd9Sstevel@tonic-gate #include <string.h>
427c478bd9Sstevel@tonic-gate #include <errno.h>
437c478bd9Sstevel@tonic-gate #include <tiuser.h>
447c478bd9Sstevel@tonic-gate #include <sys/utsname.h>
457c478bd9Sstevel@tonic-gate #include <sys/param.h>
467c478bd9Sstevel@tonic-gate #include <sys/types.h>
477c478bd9Sstevel@tonic-gate #include <sys/stat.h>
487c478bd9Sstevel@tonic-gate #include <sys/ipc.h>
497c478bd9Sstevel@tonic-gate #include <values.h>
507c478bd9Sstevel@tonic-gate #include <ctype.h>
517c478bd9Sstevel@tonic-gate #include <time.h>
527c478bd9Sstevel@tonic-gate 
537c478bd9Sstevel@tonic-gate /* listener include files */
547c478bd9Sstevel@tonic-gate 
557c478bd9Sstevel@tonic-gate #include "lsparam.h"		/* listener parameters		*/
567c478bd9Sstevel@tonic-gate #include "listen.h"		/* listener */
577c478bd9Sstevel@tonic-gate #include "lsfiles.h"		/* listener files info		*/
587c478bd9Sstevel@tonic-gate #include "lserror.h"		/* listener error codes		*/
597c478bd9Sstevel@tonic-gate #include "lsdbf.h"
607c478bd9Sstevel@tonic-gate 
617c478bd9Sstevel@tonic-gate extern char Lastmsg[];
627c478bd9Sstevel@tonic-gate extern int NLPS_proc;
637c478bd9Sstevel@tonic-gate extern char *Netspec;
647c478bd9Sstevel@tonic-gate extern FILE *Logfp;
657c478bd9Sstevel@tonic-gate extern FILE *Debugfp;
667c478bd9Sstevel@tonic-gate extern char Mytag[];
67ace1a5f1Sdp 
68ace1a5f1Sdp static char *stamp(char *);
69*113f4232Sakaplan void logmessage(char *s);
70*113f4232Sakaplan void clean_up(int code, int flag, char *msg);
717c478bd9Sstevel@tonic-gate 
727c478bd9Sstevel@tonic-gate /*
737c478bd9Sstevel@tonic-gate  * error handling and debug routines
747c478bd9Sstevel@tonic-gate  * most routines take two args: code and exit.
757c478bd9Sstevel@tonic-gate  * code is a #define in lserror.h.
767c478bd9Sstevel@tonic-gate  * if EXIT bit in exitflag is non-zero, the routine exits. (see clean_up() )
777c478bd9Sstevel@tonic-gate  * define COREDUMP to do the obvious.
787c478bd9Sstevel@tonic-gate  */
797c478bd9Sstevel@tonic-gate 
807c478bd9Sstevel@tonic-gate 
817c478bd9Sstevel@tonic-gate /*
827c478bd9Sstevel@tonic-gate  * error: catastrophic error handler
837c478bd9Sstevel@tonic-gate  */
847c478bd9Sstevel@tonic-gate 
85*113f4232Sakaplan void
error(int code,int exitflag)86*113f4232Sakaplan error(int code, int exitflag)
877c478bd9Sstevel@tonic-gate {
887c478bd9Sstevel@tonic-gate 	char scratch[BUFSIZ];
897c478bd9Sstevel@tonic-gate 
907c478bd9Sstevel@tonic-gate 	if (!(exitflag & NO_MSG)) {
917c478bd9Sstevel@tonic-gate 		strcpy(scratch, err_list[code].err_msg);
927c478bd9Sstevel@tonic-gate 		clean_up(code, exitflag, scratch);
937c478bd9Sstevel@tonic-gate 	}
947c478bd9Sstevel@tonic-gate 	clean_up(code, exitflag, NULL);
957c478bd9Sstevel@tonic-gate }
967c478bd9Sstevel@tonic-gate 
977c478bd9Sstevel@tonic-gate /*
987c478bd9Sstevel@tonic-gate  * tli_error:  Deal (appropriately) with an error in a TLI call
997c478bd9Sstevel@tonic-gate  */
1007c478bd9Sstevel@tonic-gate 
1017c478bd9Sstevel@tonic-gate static char *tlirange = "Unknown TLI error (t_errno > t_nerr)";
1027c478bd9Sstevel@tonic-gate 
103ace1a5f1Sdp void
tli_error(int code,int exitflag)104ace1a5f1Sdp tli_error(int code, int exitflag)
1057c478bd9Sstevel@tonic-gate {
1067c478bd9Sstevel@tonic-gate 	void	t_error();
1077c478bd9Sstevel@tonic-gate 	char	scratch[256];
1087c478bd9Sstevel@tonic-gate 	const char *p;
109ace1a5f1Sdp 	int	save_errno = errno;
1107c478bd9Sstevel@tonic-gate 
111ace1a5f1Sdp 	p = (t_errno < t_nerr ? t_errlist[t_errno] : tlirange);
1127c478bd9Sstevel@tonic-gate 
113ace1a5f1Sdp 	(void) snprintf(scratch, sizeof (scratch), "%s: %s",
114ace1a5f1Sdp 	    err_list[code].err_msg, p);
1157c478bd9Sstevel@tonic-gate 	if (t_errno == TSYSERR)  {
116ace1a5f1Sdp 		(void) strlcat(scratch, ": ", sizeof (scratch));
117ace1a5f1Sdp 		(void) strlcat(scratch, strerror(save_errno), sizeof (scratch));
1187c478bd9Sstevel@tonic-gate 	}
1197c478bd9Sstevel@tonic-gate 	clean_up(code, exitflag, scratch);
1207c478bd9Sstevel@tonic-gate }
1217c478bd9Sstevel@tonic-gate 
1227c478bd9Sstevel@tonic-gate 
1237c478bd9Sstevel@tonic-gate /*
1247c478bd9Sstevel@tonic-gate  * sys_error: error in a system call
1257c478bd9Sstevel@tonic-gate  */
1267c478bd9Sstevel@tonic-gate 
127ace1a5f1Sdp void
sys_error(int code,int exitflag)128ace1a5f1Sdp sys_error(int code, int exitflag)
1297c478bd9Sstevel@tonic-gate {
1307c478bd9Sstevel@tonic-gate 	char scratch[256];
1317c478bd9Sstevel@tonic-gate 
132ace1a5f1Sdp 	(void) snprintf(scratch, sizeof (scratch), "%s: %s",
133ace1a5f1Sdp 	    err_list[code].err_msg, strerror(errno));
1347c478bd9Sstevel@tonic-gate 	clean_up(code, exitflag, scratch);
1357c478bd9Sstevel@tonic-gate }
1367c478bd9Sstevel@tonic-gate 
1377c478bd9Sstevel@tonic-gate 
1387c478bd9Sstevel@tonic-gate /*
1397c478bd9Sstevel@tonic-gate  * clean_up:	if 'flag', and main listener is exiting, clean things
1407c478bd9Sstevel@tonic-gate  *		up and exit.  Dumps core if !(flag & NOCORE).
1417c478bd9Sstevel@tonic-gate  *		Tries to send a message to someone if the listener
1427c478bd9Sstevel@tonic-gate  *		is exiting due to an error. (Inherrently machine dependent.)
1437c478bd9Sstevel@tonic-gate  */
1447c478bd9Sstevel@tonic-gate 
145*113f4232Sakaplan void
clean_up(int code,int flag,char * msg)146*113f4232Sakaplan clean_up(int code, int flag, char *msg)
1477c478bd9Sstevel@tonic-gate {
1487c478bd9Sstevel@tonic-gate 	extern int Dbf_entries;
1497c478bd9Sstevel@tonic-gate 	extern void logexit();
150*113f4232Sakaplan 	extern int NLPS_proc, Nflag;
1517c478bd9Sstevel@tonic-gate 	int i;
1527c478bd9Sstevel@tonic-gate 	extern dbf_t Dbfhead;
1537c478bd9Sstevel@tonic-gate 	dbf_t	*dbp = &Dbfhead;
1547c478bd9Sstevel@tonic-gate 
1557c478bd9Sstevel@tonic-gate 	if (!(flag & EXIT)) {
1567c478bd9Sstevel@tonic-gate 		logmessage(msg);
1577c478bd9Sstevel@tonic-gate 		return;
1587c478bd9Sstevel@tonic-gate 	}
1597c478bd9Sstevel@tonic-gate 
1607c478bd9Sstevel@tonic-gate 	if (!(NLPS_proc))  {
1617c478bd9Sstevel@tonic-gate 
1627c478bd9Sstevel@tonic-gate 		/*
1637c478bd9Sstevel@tonic-gate 		 * unbind anything that we bound.
1647c478bd9Sstevel@tonic-gate 		 * Needs more intelligence.
1657c478bd9Sstevel@tonic-gate 		 */
1667c478bd9Sstevel@tonic-gate 
1677c478bd9Sstevel@tonic-gate 
1687c478bd9Sstevel@tonic-gate 		for (i=0;i<Dbf_entries;i++) {
1697c478bd9Sstevel@tonic-gate 			t_unbind(dbp->dbf_fd);
1707c478bd9Sstevel@tonic-gate 			dbp++;
171ace1a5f1Sdp 		}
1727c478bd9Sstevel@tonic-gate 	}
1737c478bd9Sstevel@tonic-gate 
1747c478bd9Sstevel@tonic-gate #ifdef	COREDUMP
1757c478bd9Sstevel@tonic-gate 	if (!(flag & NOCORE))
1767c478bd9Sstevel@tonic-gate 		abort();
1777c478bd9Sstevel@tonic-gate #endif	/* COREDUMP */
1787c478bd9Sstevel@tonic-gate 
1797c478bd9Sstevel@tonic-gate 	logexit(err_list[code].err_code, msg);
1807c478bd9Sstevel@tonic-gate }
1817c478bd9Sstevel@tonic-gate 
1827c478bd9Sstevel@tonic-gate 
1837c478bd9Sstevel@tonic-gate void
logexit(exitcode,msg)1847c478bd9Sstevel@tonic-gate logexit(exitcode, msg)
1857c478bd9Sstevel@tonic-gate int exitcode;
1867c478bd9Sstevel@tonic-gate char *msg;
1877c478bd9Sstevel@tonic-gate {
1887c478bd9Sstevel@tonic-gate 	if (msg) {
1897c478bd9Sstevel@tonic-gate 		logmessage(msg); /* put it in the log */
1907c478bd9Sstevel@tonic-gate 	}
1917c478bd9Sstevel@tonic-gate 	if (!NLPS_proc)
1927c478bd9Sstevel@tonic-gate 		logmessage("*** listener terminating!!! ***");
1937c478bd9Sstevel@tonic-gate 	exit(exitcode);
1947c478bd9Sstevel@tonic-gate 
1957c478bd9Sstevel@tonic-gate }
1967c478bd9Sstevel@tonic-gate 
1977c478bd9Sstevel@tonic-gate 
1987c478bd9Sstevel@tonic-gate #ifdef	DEBUGMODE
1997c478bd9Sstevel@tonic-gate 
2007c478bd9Sstevel@tonic-gate /*VARARGS2*/
2017c478bd9Sstevel@tonic-gate int
debug(int level,char * format,...)2027c478bd9Sstevel@tonic-gate debug(int level, char *format, ...)
2037c478bd9Sstevel@tonic-gate {
2047c478bd9Sstevel@tonic-gate 	char buf[256];
2057c478bd9Sstevel@tonic-gate 	va_list ap;
2067c478bd9Sstevel@tonic-gate 
2077c478bd9Sstevel@tonic-gate 	va_start(ap, format);
2087c478bd9Sstevel@tonic-gate 	(void) vsprintf(buf, format, ap);
2097c478bd9Sstevel@tonic-gate 	va_end(ap);
2107c478bd9Sstevel@tonic-gate 
2117c478bd9Sstevel@tonic-gate 	fprintf(Debugfp, stamp(buf));
2127c478bd9Sstevel@tonic-gate 	fflush(Debugfp);
2137c478bd9Sstevel@tonic-gate }
2147c478bd9Sstevel@tonic-gate 
2157c478bd9Sstevel@tonic-gate #endif
2167c478bd9Sstevel@tonic-gate 
2177c478bd9Sstevel@tonic-gate 
2187c478bd9Sstevel@tonic-gate 
2197c478bd9Sstevel@tonic-gate /*
2207c478bd9Sstevel@tonic-gate  * log:		given a message number (code), write a message to the logfile
2217c478bd9Sstevel@tonic-gate  * logmessage:	given a string, write a message to the logfile
2227c478bd9Sstevel@tonic-gate  */
2237c478bd9Sstevel@tonic-gate 
224*113f4232Sakaplan void
log(int code)225*113f4232Sakaplan log(int code)
2267c478bd9Sstevel@tonic-gate {
2277c478bd9Sstevel@tonic-gate 	logmessage(err_list[code].err_msg);
2287c478bd9Sstevel@tonic-gate }
2297c478bd9Sstevel@tonic-gate 
2307c478bd9Sstevel@tonic-gate 
2317c478bd9Sstevel@tonic-gate static int nlogs;		/* maintains size of logfile	*/
2327c478bd9Sstevel@tonic-gate 
233*113f4232Sakaplan void
logmessage(char * s)234*113f4232Sakaplan logmessage(char *s)
2357c478bd9Sstevel@tonic-gate {
2367c478bd9Sstevel@tonic-gate 	char log[BUFSIZ];
2377c478bd9Sstevel@tonic-gate 	char olog[BUFSIZ];
238*113f4232Sakaplan 	int err = 0;
239*113f4232Sakaplan 	FILE *nlogfp;
2407c478bd9Sstevel@tonic-gate 	extern int Logmax;
2417c478bd9Sstevel@tonic-gate 	extern int Splflag;
2427c478bd9Sstevel@tonic-gate 
2437c478bd9Sstevel@tonic-gate 	/*
2447c478bd9Sstevel@tonic-gate 	 * The listener may be maintaining the size of it's logfile.
2457c478bd9Sstevel@tonic-gate 	 * Nothing in here should make the listener abort.
2467c478bd9Sstevel@tonic-gate 	 * If it can't save the file, it rewinds the existing log.
2477c478bd9Sstevel@tonic-gate 	 * Note that the algorithm is not exact, child listener's
2487c478bd9Sstevel@tonic-gate 	 * messages do not affect the parent's count.
2497c478bd9Sstevel@tonic-gate 	 */
2507c478bd9Sstevel@tonic-gate 
2517c478bd9Sstevel@tonic-gate 	if (!Logfp)
2527c478bd9Sstevel@tonic-gate 		return;
2537c478bd9Sstevel@tonic-gate 	if (!NLPS_proc && Logmax && ( nlogs >= Logmax ) && !Splflag)  {
2547c478bd9Sstevel@tonic-gate 		nlogs = 0;
2557c478bd9Sstevel@tonic-gate 		fprintf(Logfp, stamp("Restarting log file"));
2567c478bd9Sstevel@tonic-gate 		sprintf(log, "%s/%s/%s", ALTDIR, Mytag, LOGNAME);
2577c478bd9Sstevel@tonic-gate 		sprintf(olog, "%s/%s/%s", ALTDIR, Mytag, OLOGNAME);
2587c478bd9Sstevel@tonic-gate 		DEBUG((1, "Logfile exceeds Logmax (%d) lines", Logmax));
2597c478bd9Sstevel@tonic-gate 		unlink(olog); /* remove stale saved logfile */
2607c478bd9Sstevel@tonic-gate 		if (rename(log, olog))  {
2617c478bd9Sstevel@tonic-gate 			++err;
2627c478bd9Sstevel@tonic-gate 			rewind(Logfp);
2637c478bd9Sstevel@tonic-gate 			DEBUG((1,"errno %d renaming log to old logfile",errno));
2647c478bd9Sstevel@tonic-gate 		}
265ace1a5f1Sdp 		else  if (nlogfp = fopen(log, "a+"))  {
2667c478bd9Sstevel@tonic-gate 			fclose(Logfp);
2677c478bd9Sstevel@tonic-gate 			Logfp = nlogfp;
2687c478bd9Sstevel@tonic-gate 			fcntl(fileno(Logfp), F_SETFD, 1); /* reset close-on-exec */
2697c478bd9Sstevel@tonic-gate 			DEBUG((1, "logmessage: logfile saved successfully"));
2707c478bd9Sstevel@tonic-gate 		}  else  {
2717c478bd9Sstevel@tonic-gate 			++err;
2727c478bd9Sstevel@tonic-gate 			rewind(Logfp);
2737c478bd9Sstevel@tonic-gate 			DEBUG((1, "Lost the logfile, errno %d", errno));
2747c478bd9Sstevel@tonic-gate 		}
2757c478bd9Sstevel@tonic-gate 		if (err)
2767c478bd9Sstevel@tonic-gate 			fprintf(Logfp, stamp("Trouble saving the logfile"));
2777c478bd9Sstevel@tonic-gate 	}
2787c478bd9Sstevel@tonic-gate 
2797c478bd9Sstevel@tonic-gate 	fprintf(Logfp, stamp(s));
2807c478bd9Sstevel@tonic-gate 	fflush(Logfp);
2817c478bd9Sstevel@tonic-gate 	++nlogs;
2827c478bd9Sstevel@tonic-gate }
2837c478bd9Sstevel@tonic-gate 
2847c478bd9Sstevel@tonic-gate extern pid_t Pid;
2857c478bd9Sstevel@tonic-gate 
2867c478bd9Sstevel@tonic-gate static char *
stamp(char * msg)2877c478bd9Sstevel@tonic-gate stamp(char *msg)
2887c478bd9Sstevel@tonic-gate {
2897c478bd9Sstevel@tonic-gate 	time_t clock;
2907c478bd9Sstevel@tonic-gate 	struct tm *tm_p;
2917c478bd9Sstevel@tonic-gate 
2927c478bd9Sstevel@tonic-gate 	(void)time(&clock);
2937c478bd9Sstevel@tonic-gate 	tm_p = (struct tm *) localtime(&clock);
2947c478bd9Sstevel@tonic-gate 	tm_p->tm_mon++;	/* since months are 0-11 */
2957c478bd9Sstevel@tonic-gate 	sprintf(Lastmsg, "%2.2d/%2.2d/%2.2d %2.2d:%2.2d:%2.2d; %ld; %s\n",
296ace1a5f1Sdp 		tm_p->tm_mon, tm_p->tm_mday, (tm_p->tm_year % 100),
2977c478bd9Sstevel@tonic-gate 		tm_p->tm_hour, tm_p->tm_min, tm_p->tm_sec, Pid, msg);
2987c478bd9Sstevel@tonic-gate 	return(Lastmsg);
2997c478bd9Sstevel@tonic-gate }
300