errors.c
上传用户:seven77cht
上传日期:2007-01-04
资源大小:486k
文件大小:8k
源码类别:

浏览器

开发平台:

Unix_Linux

  1. /***************************************
  2.   $Header: /home/amb/wwwoffle/RCS/errors.c 2.18 2000/01/22 13:39:29 amb Exp $
  3.   WWWOFFLE - World Wide Web Offline Explorer - Version 2.5d.
  4.   Generate error messages in a standard format optionally to syslog and stderr.
  5.   ******************/ /******************
  6.   Written by Andrew M. Bishop
  7.   This file Copyright 1996,97,98,99,2000 Andrew M. Bishop
  8.   It may be distributed under the GNU Public License, version 2, or
  9.   any higher version.  See section COPYING of the GNU Public license
  10.   for conditions under which this file may be redistributed.
  11.   ***************************************/
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include <string.h>
  15. #include <unistd.h>
  16. #include <time.h>
  17. #include <sys/types.h>
  18. #include <sys/fcntl.h>
  19. #ifdef __STDC__
  20. #include <stdarg.h>
  21. #else
  22. #include <varargs.h>
  23. #endif
  24. #if !defined(__CYGWIN__)
  25. #include <syslog.h>
  26. #if defined (hpux)
  27. /* HP/UX does not declare these in <syslog.h> */
  28. extern int syslog (int pri, const char *message, ...);
  29. extern int openlog (const char *ident, int logopt, int facility);
  30. extern int closelog (void);
  31. #endif
  32. #else
  33. /* I prefer not to use the Cygwin syslog functions here. */
  34. static void openlog(char *facility);
  35. static void closelog(void);
  36. static void syslog(int level,const char* format,char* string);
  37. #endif /* __CYGWIN__ */
  38. #include <errno.h>
  39. #if defined(__sun__) && !defined(__svr4__)
  40. /* SunOS 4.x does not have strerror(). */
  41. char* strerror(int err);
  42. extern int sys_nerr;
  43. extern char *sys_errlist[];
  44. char* strerror(int err)
  45. {
  46.  if(err>0 && err<sys_nerr)
  47.     return(sys_errlist[err]);
  48.  else
  49.     return("Unknown error");
  50. }
  51. #endif /* defined(__sun__) && !defined(__svr4__) */
  52. #include <netdb.h>
  53. #if defined (hpux)
  54. /* HP/UX has h_errno but does not decalre it in any header file */
  55. extern int h_errno;
  56. #endif
  57. /* A function to get an error message for h_errno. */
  58. char* str_h_error(int err);
  59. char* str_h_error(int err)
  60. {
  61. #ifdef NETDB_INTERNAL
  62.  if(err==NETDB_INTERNAL)
  63.     return("Name Lookup Internal error");
  64.  else
  65. #endif
  66. #ifdef NETDB_SUCCESS
  67.  if(err==NETDB_SUCCESS)
  68.     return("Name Lookup Success");
  69.  else
  70. #endif
  71. #ifdef HOST_NOT_FOUND
  72.  if(err==HOST_NOT_FOUND)
  73.     return("Name Lookup Authoritative Answer Host not found");
  74.  else
  75. #endif
  76. #ifdef TRY_AGAIN
  77.  if(err==TRY_AGAIN)
  78.     return("Name Lookup Non-Authoritive Answer Host not found");
  79.  else
  80. #endif
  81. #ifdef NO_RECOVERY
  82.  if(err==NO_RECOVERY)
  83.     return("Name Lookup Non recoverable error");
  84.  else
  85. #endif
  86. #ifdef NO_DATA
  87.  if(err==NO_DATA)
  88.     return("Name Lookup Valid name, no data record of requested type");
  89.  else
  90. #endif
  91. #ifdef NO_ADDRESS
  92.  if(err==NO_ADDRESS)
  93.     return("Name Lookup Valid name, no data record of requested type");
  94.  else
  95. #endif
  96.  return("Unknown error");
  97. }
  98. #include "errors.h"
  99. #include "config.h"
  100. #include "misc.h"
  101. /*+ The name of the program. +*/
  102. static char *program=NULL;
  103. /*+ The process id of the program. +*/
  104. static pid_t pid;
  105. /*+ The last time that a message was printed. +*/
  106. static time_t last_time=0;
  107. /*+ The error messages. +*/
  108. static char *ErrorString[]={"ExtraDebug","Debug"  ,"Information","Important","Warning"  ,"Fatal"};
  109. /*+ The priority to apply to syslog messages. +*/
  110. #if defined(__CYGWIN__)
  111. static int ErrorPriority[]={-1          ,Debug    ,Inform       ,Important  ,Warning    ,Fatal};
  112. #else
  113. static int ErrorPriority[]={-1          ,LOG_DEBUG,LOG_INFO     ,LOG_NOTICE ,LOG_WARNING,LOG_ERR};
  114. #endif
  115. /*+ The error facility to use, +*/
  116. static int use_syslog=0,        /*+ use syslog. +*/
  117.            use_stderr=1;        /*+ use stderr. +*/
  118. /*++++++++++++++++++++++++++++++++++++++
  119.   Initialise the error handler, get the program name and pid.
  120.   char *name The name of the program.
  121.   int syslogable Set to true if the errors are allowed to go to syslog (or -1 to remain unchanged).
  122.   int stderrable Set to true if the errors are allowed to go to stderr (or -1 to remain unchanged).
  123.   ++++++++++++++++++++++++++++++++++++++*/
  124. void InitErrorHandler(char *name,int syslogable,int stderrable)
  125. {
  126.  if(use_syslog && program)
  127.     closelog();
  128.  program=name;
  129.  if(syslogable!=-1)
  130.     use_syslog=syslogable;
  131.  if(stderrable!=-1)
  132.     use_stderr=stderrable;
  133.  if(use_syslog)
  134.    {
  135. #if defined(__CYGWIN__)
  136.     openlog(program);
  137. #elif defined(__ultrix__)
  138.     openlog(program,LOG_PID);
  139. #else
  140.     openlog(program,LOG_CONS|LOG_PID,LOG_DAEMON);
  141. #endif
  142.     atexit(closelog);
  143.    }
  144.  pid=getpid();
  145.  last_time=time(NULL)-3300;
  146. }
  147. /*++++++++++++++++++++++++++++++++++++++
  148.   Print an error message.
  149.   char *PrintMessage Return the error message (except the pid etc.).
  150.   ErrorLevel errlev Which error level.
  151.   const char* fmt The format of the message.
  152.   ... The rest of the arguments (printf style).
  153.   ++++++++++++++++++++++++++++++++++++++*/
  154. char *PrintMessage(ErrorLevel errlev,const char* fmt, ...)
  155. {
  156.  int str_len=16+strlen(fmt);
  157.  static char* string=NULL;
  158.  va_list ap;
  159.  int i,j;
  160.  time_t this_time=time(NULL);
  161.  /* Shortcut (bypass if debug) */
  162.  if(errlev<=Debug && (errlev<LogLevel && errlev<DebugLevel))
  163.     return(NULL);
  164.  /* Periodic timestamp */
  165.  if(last_time && (this_time-last_time)>3600)
  166.    {
  167.     last_time=this_time;
  168.     if(use_stderr)
  169.        fprintf(stderr,"%s[%ld] Timestamp: %s",program,(long)pid,ctime(&this_time)); /* Used in audit-usage.pl */
  170.    }
  171.  /* Parsing of printf style arguments. */
  172.  if(string)
  173.     free(string);
  174.  string=(char*)malloc(str_len);
  175. #ifdef __STDC__
  176.  va_start(ap,fmt);
  177. #else
  178.  va_start(ap);
  179. #endif
  180.  for(i=0,j=0;fmt[i];i++)
  181.     if(fmt[i]!='%')
  182.        string[j++]=fmt[i];
  183.     else
  184.       {
  185.        char str[16],*strp=NULL;
  186.        switch(fmt[++i])
  187.          {
  188.          case '!':
  189.           if(fmt[++i]=='s')
  190.              if(errno!=-1)
  191.                 strp=strerror(errno);
  192.              else
  193.                 strp=str_h_error(h_errno);
  194.           else
  195.              if(errno!=-1)
  196.                 sprintf(strp=str,"%d",errno);
  197.              else
  198.                 sprintf(strp=str,"%d (h_errno)",h_errno);
  199.           break;
  200.          case 'c':
  201.           str[0]=(char)va_arg(ap,int); /* beware of type promotion */
  202.           str[1]=0;
  203.           strp=str;
  204.           break;
  205.          case 'd':
  206.           sprintf(strp=str,"%d",va_arg(ap,int));
  207.           break;
  208.          case 's':
  209.           strp=va_arg(ap,char*);
  210.           if(!strp) strp="(null)";
  211.           break;
  212.          default:
  213.           str[0]='%';
  214.           str[1]=fmt[i];
  215.           str[2]=0;
  216.           strp=str;
  217.           (void)va_arg(ap,void*);
  218.          }
  219.        str_len+=strlen(strp);
  220.        string=realloc(string,str_len);
  221.        strcpy(&string[j],strp);
  222.        j+=strlen(strp);
  223.       }
  224. #if defined(__CYGWIN__)
  225.  if(string[j-1]=='n')
  226.     j--;
  227.  string[j++]='r';
  228.  string[j++]='n';
  229. #else
  230.  if(string[j-1]!='n')
  231.     string[j++]='n';
  232. #endif
  233.  string[j]=0;
  234.  va_end(ap);
  235.  /* Output the result. */
  236.  if(UseSyslog && use_syslog && errlev>=LogLevel && ErrorPriority[errlev]!=-1)
  237.     syslog(ErrorPriority[errlev],"%s",string);
  238.  if(use_stderr && ((DebugLevel==-1 && errlev>=LogLevel) || (DebugLevel!=-1 && errlev>=DebugLevel)))
  239.     fprintf(stderr,"%s[%ld] %s: %s",program,(long)pid,ErrorString[errlev],string);
  240.  if(errlev==Fatal)
  241.     exit(2);
  242.  return(string);
  243. }
  244. #if defined(__CYGWIN__)
  245. static int syslog_file=-1;
  246. static char *syslog_facility=NULL;
  247. /*++++++++++++++++++++++++++++++++++++++
  248.   Open the syslog file.
  249.   ++++++++++++++++++++++++++++++++++++++*/
  250. static void openlog(char *facility)
  251. {
  252.  char *syslogfile=(char*)malloc(strlen(ConfigFile)+16),*p;
  253.  strcpy(syslogfile,ConfigFile);
  254.  p=syslogfile+strlen(syslogfile)-1;
  255.  while(p>=syslogfile && *p!='/')
  256.     *p--=0;
  257.  strcat(syslogfile,"wwwoffle.syslog");
  258.  syslog_file=open(syslogfile,O_WRONLY|O_CREAT|O_APPEND);
  259.  syslog_facility=facility;
  260. }
  261. /*++++++++++++++++++++++++++++++++++++++
  262.   Close the syslog file.
  263.   ++++++++++++++++++++++++++++++++++++++*/
  264. static void closelog(void)
  265. {
  266.  syslog_file=-1;
  267.  syslog_facility=NULL;
  268. }
  269. /*++++++++++++++++++++++++++++++++++++++
  270.   Write to the syslog file.
  271.   ++++++++++++++++++++++++++++++++++++++*/
  272. static void syslog(int level,const char* format,char* string)
  273. {
  274.  if(syslog_file!=-1 && syslog_facility)
  275.     write_formatted(syslog_file,"%s[%ld](%s): %s",syslog_facility,(long)pid,ErrorString[level],string);
  276. }
  277. #endif /* __CYGWIN__ */