/******************************************************************** * wilkinson * 3.10VMS * 1995/09/25 14:25 * gopher_root1:[gopher.g2.vms2_13.gopherd]error.c,v * Exp * * Paul Lindner, University of Minnesota CIS. * * Copyright 1991, 1992 by the Regents of the University of Minnesota * see the file "Copyright" in the distribution for conditions of use. ********************************************************************* * MODULE: error.c * Error handling/logging routines. ********************************************************************* * Revision History: * error.c,v * Revision 3.10VMS 1995/09/24 14:25 wilkinson * Consolodate VMS/Unix source code for server as well as client * - VMS Syslog.h is private * * Revision 3.10 1995/02/07 07:12:32 lindner * oops! * * Revision 3.9 1995/02/07 07:04:29 lindner * performance fixes * * Revision 3.8 1994/07/19 20:28:08 lindner * Fix for syslog problem with WAIS * * Revision 3.7 1994/01/20 06:37:43 lindner * Fix for stdc declaration for err_quit() * * Revision 3.6 1993/10/11 04:40:49 lindner * Changes to allow logging via daemon.info syslogd facility * * Revision 3.5 1993/07/30 17:19:53 lindner * Fix for NeXTs * * Revision 3.4 1993/07/20 23:58:01 lindner * LOGGopher mods * * Revision 3.3 1993/07/10 04:21:55 lindner * mods for solaris2.2 * * Revision 3.2 1993/07/07 19:39:09 lindner * fix for linux * * Revision 3.1.1.1 1993/02/11 18:02:50 lindner * Gopher+1.2beta release * * Revision 1.1 1992/12/10 23:13:27 lindner * gopher 1.1 release * * *********************************************************************/ /* * Error handling routines from Stevens: UNIX network programming * pp 722-731 */ /* * Error handling routines. * * The functions in this file are independent of any application * variables, and may be used in any C program. Either of the names * CLIENT of SERVER may be defined when compiling this function. * If neither are defined, we assume SERVER. */ #include "gopherd.h" void my_perror(); #ifndef NULL #define NULL ((void *) 0) #endif extern char *pname; #ifndef NOSYSLOG /* * Under useful OS's, these server routines use the syslog(3) facility. * They don't append a newline for example. */ #ifndef VMS_SERVER /* * Get around the existance of syslog.h in the wais source code... * Arghhh!!! */ #ifdef WAISSEARCH #include "/usr/include/syslog.h" #else #include #endif #else /* * VMS implementations require their own syslog.h file */ #ifdef MULTINET #include "syslog.h" #endif #endif #else /* no syslog() */ /* * There really ought to be a better way to handle server logging * under System V */ #ifndef VMS_SERVER #define syslog(a,b) fprintf(stderr, "%s\n", (b)) #define openlog(a,b,c) fprintf(stderr, "%s\n", (a)) #else #define syslog(a,b) VMS$fprintf(stderr, "%s\n", (b)) #define openlog(a,b,c) VMS$fprintf(stderr, "%s\n", (a)) #endif #endif /* NOSYSLOG */ #if defined(__STDC__) && !defined(NeXT) #define __stdc__ #endif #if defined(__stdc__) #include #else #include #endif char emesgstr[255] = {0}; /* used by all server routines */ /* * Identify ourselves, for syslog() messages. * * LOG_PID is an option that says prepend each message with our pid. * LOG_CONS is an option that says write to the console if unable to * send the message to syslogd. * LOG_DAEMON is our facility. */ void err_init() { #ifndef VMS_SERVER /* have to be able to reopen, since daemon_start keeps closing us */ closelog(); /* in case we've been closed by daemon_start */ #endif #ifdef LOG_DAEMON openlog("gopherd", (LOG_PID|LOG_CONS), LOG_DAEMON); setlogmask(LOG_UPTO(LOG_INFO)); #else /* old old syslog - probably Ultrix */ openlog("gopherd", LOG_PID); #endif } /* * Fatal error. Print a message and terminate. * Don't print the system's errno value. * * err_quit(str, arg1, arg2, ...) */ #ifdef __stdc__ void err_quit(char *va_alist, ...) #else /*VARARGS1*/ void err_quit(va_alist) va_dcl #endif { va_list args; char *fmt; #ifdef __stdc__ fmt = va_alist; va_start(args, va_alist); #else va_start(args); fmt = va_arg(args, char *); #endif (void) vsprintf(emesgstr, fmt, args); va_end(args); syslog(LOG_ERR, emesgstr); LOGGopher(-1, "%s", emesgstr); #ifndef VMS_SERVER exit(1); #else gopherd_exit(1); #endif } /* * Fatal error related to a system call. Print the message and terminate. * Don't dump core, but do print the systems errno value and its associated * message. */ #ifdef __stdc__ void err_sys(char *va_alist, ...) #else /*VARARGS*/ void err_sys(va_alist) va_dcl #endif { va_list args; char *fmt; #ifdef __stdc__ fmt = va_alist; va_start(args,va_alist); #else va_start(args); fmt = va_arg(args, char *); #endif (void) vsprintf(emesgstr, fmt, args); va_end(args); my_perror(); syslog(LOG_ERR, emesgstr); LOGGopher(-1, "%s", emesgstr); #ifndef VMS_SERVER exit(1); #else gopherd_exit(1); #endif } /* * Recoverable error. Print a message, and return to caller. */ #ifdef __stdc__ void err_ret(char *va_alist, ...) #else /*VARARGS1*/ void err_ret(va_alist) va_dcl #endif { va_list args; char *fmt; #ifdef __stdc__ fmt = va_alist; va_start(args, va_alist); #else va_start(args); fmt = va_arg(args, char *); #endif (void) vsprintf(emesgstr, fmt, args); va_end(args); my_perror(); syslog(LOG_ERR, emesgstr); LOGGopher(-1, "%s", emesgstr); return; } /* * Fatal error. Print a message, dump core and terminate. */ #ifdef __stdc__ void err_dump(char *va_alist, ...) #else /*VARARGS1*/ void err_dump(va_alist) va_dcl #endif { va_list args; char *fmt; #ifdef __stdc__ fmt = va_alist; va_start(args, va_alist); #else va_start(args); fmt = va_arg(args, char *); #endif (void) vsprintf(emesgstr, fmt, args); va_end(args); my_perror(); syslog(LOG_ERR, emesgstr); LOGGopher(-1, "%s", emesgstr); abort(); } /* * Print the UNIX errno value. * We just append it the the end of the emesgstr[] array. */ void my_perror() { int len; char *sys_err_str(); len = strlen(emesgstr); sprintf(emesgstr + len, " %s", sys_err_str()); } extern int errno; /* UNIX error number */ extern int sys_nerr; /* # of error message strings in sys table */ #ifndef VMS_SERVER extern char *sys_errlist[]; /* the system error message table */ #endif #ifdef SYS5 int t_errno; int t_nerr; char *t_errlist[1]; #endif /* * Return a string containing some additional operating system * dependent information. * Note that different versions of UNIX assign different meanings * to the same value of "errno". This means that if an error * condition is being sent ot another UNIX system, we must interpret * the errno value on the system that generated the error, and not * just send the decimal value of errno to the other system. */ char * sys_err_str() { static char msgstr[200]; if (errno != 0) { if (errno >0 && errno < sys_nerr) #ifndef VMS_SERVER sprintf(msgstr, "(%s)", sys_errlist[errno]); #else sprintf(msgstr, "(%s)", strerror(errno)); #endif else sprintf(msgstr, "(errno = %d)", errno); } else { msgstr[0] = '\0'; } #ifdef SYS5 if (t_errno != 0) { char tmsgstr[100]; if (t_errno > 0 && t_errno < sys_nerr) sprintf(tmsgstr, " (%s)", t_errlist[t_errno]); else sprintf(tmsgstr, ", (t_errno = %d)", t_errno); strcat(msgstr, tmsgstr); } #endif return(msgstr); } .