home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / dos / communic / pcmail / main / logs.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-06-05  |  5.7 KB  |  271 lines

  1. /*++
  2. /* NAME
  3. /*      logs 3
  4. /* SUMMARY
  5. /*      exception handling, error logging, status reports, debugging
  6. /* PROJECT
  7. /*      pc-mail
  8. /* PACKAGE
  9. /*      cico
  10. /* SYNOPSIS
  11. /*      int dbg(fmt[,args]);
  12. /*      char *fmt;
  13. /*
  14. /*      int open_log();
  15. /*
  16. /*      void log(fmt[,args]);
  17. /*      char *fmt;
  18. /*
  19. /*      void trap(code,fmt[,args]);
  20. /*      char *fmt;
  21. /* DESCRIPTION
  22. /*      All functions in this module do some form of logging, and accept
  23. /*      printf-like format strings with %s, %c, and %S, %C. The latter
  24. /*    two cause output mapping of arbitrary byte values to printable codes.
  25. /*
  26. /*      dbg() formats its arguments and writes the result to the standard
  27. /*      output.
  28. /*
  29. /*      open_log() tries to open the logfile for writing. It returns
  30. /*      a status E_WRITERR if the file could not be opened or created.
  31. /*
  32. /*      log() writes status info to the log file. If debugging is enabled,
  33. /*    the message is also written to the standard output.
  34. /*
  35. /*      trap() writes a message to the log file and performs a longjmp call
  36. /*      (systrap) with the status as given in the code parameter. If
  37. /*    debugging is enabled, the message is also written to the standard
  38. /*    output.
  39. /* FUNCTIONS AND MACROS
  40. /*      longjmp()
  41. /* FILES
  42. /*      LOGFILE         status reports
  43. /* BUGS
  44. /*      Logfile info may be lost if the program terminates abnormally.
  45. /*      We do not open/close the with each log() call since that would
  46. /*      slow down performance on floppy-based systems dramatically.
  47. /* AUTHOR(S)
  48. /*      W.Z. Venema
  49. /*      Eindhoven University of Technology
  50. /*      Department of Mathematics and Computer Science
  51. /*      Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  52. /* CREATION DATE
  53. /*      Thu Mar 26 17:45:19 GMT+1:00 1987
  54. /* LAST MODIFICATION
  55. /*    90/01/22 13:02:01
  56. /* VERSION/RELEASE
  57. /*    2.1
  58. /*--*/
  59.  
  60. #include <stdio.h>
  61. #include <setjmp.h>
  62. #include <ctype.h>
  63. #include <varargs.h>
  64. #include <time.h>
  65.  
  66. #include "defs.h"
  67. #include "logs.h"
  68. #include "path.h"
  69. #include "status.h"
  70.  
  71. #define    dbgout    stdout            /* where debugging output should go */
  72.  
  73. hidden FILE *logfp = NULL;        /* log file file pointer */
  74. hidden char *visible();            /* map characters to readable codes */
  75. hidden void dprintf();            /* special-purpose formatting
  76.                      * function */
  77.  
  78. /* now - write current time */
  79.  
  80. hidden void now(fp)
  81. FILE   *fp;
  82. {
  83.     struct tm *localtime();
  84.     char   *asctime();
  85.     long    time();
  86.     long    t;
  87.  
  88.     t = time((long *) 0);
  89.     fprintf(fp, "%.15s ", asctime(localtime(&t)) + 4);
  90. }
  91.  
  92. /* open_log - check the logfile can be written */
  93.  
  94. public int open_log()
  95. {
  96.     if (logfp == NULL && (logfp = fopen(logfile(), "a")) == NULL)
  97.     return (E_WRITERR);
  98.     else
  99.     return (0);
  100. }
  101.  
  102.  /*
  103.   * As long as we have to use old C, use two versions of variadic functions,
  104.   * one for real use, and one for checking with lint.
  105.   */
  106.  
  107. #ifndef lint
  108.  
  109. /* dbg - write debugging info to the debugging output */
  110.  
  111. public int dbg(va_alist)
  112. va_dcl
  113. {
  114.     va_list s;
  115.     register char *fmt;
  116.  
  117.     va_start(s);
  118.     fmt = va_arg(s, char *);
  119.     dprintf(dbgout, fmt, s);
  120.     va_end(s);
  121. }
  122.  
  123. /* log - write status info to the log file */
  124.  
  125. public void log(va_alist)
  126. va_dcl
  127. {
  128.     va_list s;
  129.     register char *fmt;
  130.  
  131.     /* log file should be open! */
  132.  
  133.     if (logfp == NULL)
  134.     exit(E_CONFUSED);
  135.  
  136.     /* write status record to log file */
  137.  
  138.     now(logfp);
  139.     va_start(s);
  140.     fmt = va_arg(s, char *);
  141.     dprintf(logfp, fmt, s);
  142.     putc('\n', logfp);
  143.     va_end(s);
  144.  
  145.     /* if debugging on, write also to debugging output */
  146.  
  147.     if (dflag) {
  148.     va_start(s);
  149.     fmt = va_arg(s, char *);
  150.     dprintf(dbgout, fmt, s);
  151.     putc('\n', dbgout);
  152.     va_end(s);
  153.     }
  154. }
  155.  
  156. /* trap - exception handler */
  157.  
  158. public void trap(va_alist)
  159. va_dcl
  160. {
  161.     va_list s;
  162.     int     code;
  163.     char   *fmt;
  164.  
  165.     /* write exception record to log file */
  166.  
  167.     now(logfp);
  168.     va_start(s);
  169.     code = va_arg(s, int);
  170.     fmt = va_arg(s, char *);
  171.     dprintf(logfp, fmt, s);
  172.     putc('\n', logfp);
  173.     va_end(s);
  174.  
  175.     /* if debugging on, write also to debugging output */
  176.  
  177.     if (dflag) {
  178.     va_start(s);
  179.     code = va_arg(s, int);
  180.     fmt = va_arg(s, char *);
  181.     dprintf(dbgout, fmt, s);
  182.     putc('\n', dbgout);
  183.     va_end(s);
  184.     }
  185.     longjmp(systrap, code);
  186. }
  187.  
  188. #else
  189.  
  190. /* VARARGS1 */
  191.  
  192. public int dbg(fmt)
  193. char   *fmt;
  194. {
  195. }
  196.  
  197. /* VARARGS2 */
  198.  
  199. public void trap(err, fmt)
  200. int   err;
  201. char *fmt;
  202. {
  203. }
  204.  
  205. /* VARARGS1 */
  206.  
  207. public void log(fmt)
  208. char   *fmt;
  209. {
  210. }
  211.  
  212. #endif
  213.  
  214. /* visible - turn arbitrary character into something visible */
  215.  
  216. static char *visible(c)
  217. register int c;
  218. {
  219.     static char buf[5];
  220.  
  221.     switch (c &= 0377) {
  222.     default:
  223.     sprintf(buf, isascii(c) && isprint(c) ? "%c" : "\\%03o", c);
  224.     return (buf);
  225.     case ' ':
  226.     return ("\\s");
  227.     case '\b':
  228.     return ("\\b");
  229.     case '\t':
  230.     return ("\\t");
  231.     case '\r':
  232.     return ("\\r");
  233.     case '\n':
  234.     return ("\\n");
  235.     case '\f':
  236.     return ("\\f");
  237.     case '\\':
  238.     return ("\\\\");
  239.     }
  240. }
  241.  
  242. /* dprintf - handle %s, %c, %S and %C format requests */
  243.  
  244. static void dprintf(fp, fmt, s)
  245. register FILE *fp;
  246. register char *fmt;
  247. va_list s;
  248. {
  249.     register int c;
  250.  
  251.     for ( /* void */ ; c = *fmt; fmt++) {
  252.     if (c != '%') {
  253.         putc(c, fp);
  254.     } else if ((c = *++fmt) == 'S') {    /* %S: translated */
  255.         register char *cp = va_arg(s, char *);
  256.  
  257.         while (*cp)
  258.         fputs(visible(*cp++ & 0377), fp);
  259.     } else if (c == 'C') {            /* %C: translated */
  260.         fputs(visible(va_arg(s, int)), fp);
  261.     } else if (c == 's') {            /* %s: string, as is */
  262.         fputs(va_arg(s, char *), fp);
  263.     } else if (c == 'c') {            /* %c: char, as is */
  264.         putc(va_arg(s, int), fp);
  265.     } else if (c == '%') {            /* real % character */
  266.         putc(c, fp);
  267.     }
  268.     }
  269.     (void) fflush(fp);
  270. }
  271.