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