home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / system / mail / delivery / deliver.tz / deliver / sysdep.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-12-07  |  8.0 KB  |  444 lines

  1. /* $Header: sysdep.c,v 2.9 90/05/03 10:13:06 chip Exp $
  2.  *
  3.  * Routines which are (or might well be) system-dependant.
  4.  * I've put the message routines here since you may need to use
  5.  * the ANSI <stdarg.h> instead of <varargs.h>.
  6.  *
  7.  * $Log:    sysdep.c,v $
  8.  * Revision 2.9  90/05/03  10:13:06  chip
  9.  * Support nap() call in ABCenix.  (Huh?)
  10.  * 
  11.  * Revision 2.8  90/03/06  12:21:16  chip
  12.  * Move logging into log.c and address parsing into addr.c.
  13.  * New: error delivery file for messages that fail.
  14.  * Major rearrangement of delivery file code.
  15.  * 
  16.  * Revision 2.7  90/02/23  14:16:52  chip
  17.  * Support "#!" in delivery files.
  18.  * Support "user|program" and "user?error" from delivery files.
  19.  * Improve debugging and error message formatting.
  20.  * Rearrange code for clarity.
  21.  * 
  22.  * Revision 2.6  90/02/06  11:56:43  chip
  23.  * Enforce MBX_MODE regardless of UMASK.
  24.  * Enforce ordered logging with a log lockfile.
  25.  * Revise log format.
  26.  * 
  27.  * Revision 2.5  89/12/19  16:29:47  network
  28.  * Make timezone handling portable to System V.
  29.  * 
  30.  * Revision 2.4  89/11/10  12:23:58  network
  31.  * Log recursion depth, undelivered mail and failed headers.
  32.  * 
  33.  * Revision 2.3  89/11/01  12:19:06  network
  34.  * Delintify.
  35.  * 
  36.  * Revision 2.2  89/11/01  11:51:51  network
  37.  * Add logging.
  38.  * 
  39.  * Revision 2.1  89/06/09  12:25:40  network
  40.  * Update RCS revisions.
  41.  * 
  42.  * Revision 1.8  89/06/09  12:23:59  network
  43.  * Baseline for 2.0 release.
  44.  * 
  45.  */
  46.  
  47. #include "deliver.h"
  48. #include <errno.h>
  49. #ifdef HAS_STDARG
  50. #include <stdarg.h>
  51. #else
  52. #ifdef HAS_VARARGS
  53. #include <varargs.h>
  54. #else
  55. /*
  56.  * Non-portable home-grown varargs.  Use at your own risk.
  57.  * Especially note that if sizeof(int) > sizeof(short), then
  58.  * "va_arg(..,short)" is broken.
  59.  */
  60. typedef char *va_list;
  61. #define va_dcl          int va_alist;
  62. #define va_start(ap)    ap = (char *) &va_alist
  63. #define va_arg(ap,type) *(type *)(ap += sizeof(type), ap - sizeof(type))
  64. #define va_end(ap)      /* nothing */
  65. #endif
  66. #endif
  67.  
  68. #ifdef UNAME
  69. #include <sys/utsname.h>
  70. #endif
  71.  
  72. /*
  73.  * External functions.
  74.  */
  75.  
  76. #if defined(M_XENIX) || defined(ABCenix)
  77. #define CALL_NAP
  78. #endif
  79.  
  80. #ifdef CALL_NAP
  81. extern  long    nap();
  82. #else
  83. extern  unsigned sleep();
  84. #endif
  85.  
  86. /*
  87.  * External data.
  88.  */
  89.  
  90. extern  int     errno;
  91. extern  int     sys_nerr;
  92. /* extern  char    *sys_errlist[]; */
  93.  
  94. /*
  95.  * Locally useful macros.
  96.  */
  97.  
  98. /* Wrapper macros to hide stdarg/vararg differences. */
  99.  
  100. #ifdef HAS_STDARG
  101. #define FMT_PARAM       (char *fmt, ...)
  102. #define FMT_VARS        va_list ap;
  103. #define FMT_START       va_start(ap, fmt);
  104. #define FMT_END         va_end(ap);
  105. #else
  106. #define FMT_PARAM       (va_alist) va_dcl
  107. #define FMT_VARS        va_list ap; char *fmt;
  108. #define FMT_START       va_start(ap); fmt = va_arg(ap, char *);
  109. #define FMT_END         va_end(ap);
  110. #endif
  111.  
  112. /*----------------------------------------------------------------------
  113.  * Print a message.
  114.  */
  115.  
  116. /* VARARGS */
  117. message
  118. FMT_PARAM
  119. {
  120.     FMT_VARS
  121.  
  122.     FMT_START
  123.     (void) vfprintf(stderr, fmt, ap);
  124.     FMT_END
  125.  
  126.     if (errlog)
  127.     {
  128.         errstart();
  129.         FMT_START
  130.         (void) vfprintf(errlog, fmt, ap);
  131.         FMT_END
  132.     }
  133. }
  134.  
  135. /*----------------------------------------------------------------------
  136.  * Print an error message.
  137.  */
  138.  
  139. /* VARARGS */
  140. error
  141. FMT_PARAM
  142. {
  143.     FMT_VARS
  144.  
  145.     FMT_START
  146.     (void) fprintf(stderr, "%s: ", progname);
  147.     (void) vfprintf(stderr, fmt, ap);
  148.     FMT_END
  149.  
  150.     if (errlog)
  151.     {
  152.         errstart();
  153.         FMT_START
  154.         (void) fprintf(errlog, "%s: ", progname);
  155.         (void) vfprintf(errlog, fmt, ap);
  156.         FMT_END
  157.     }
  158. }
  159.  
  160. /*----------------------------------------------------------------------
  161.  * Report an error returned from a system call.
  162.  */
  163.  
  164. /* VARARGS */
  165. syserr
  166. FMT_PARAM
  167. {
  168.     int     e = errno;
  169.     FMT_VARS
  170.  
  171.     FMT_START
  172.     (void) fprintf(stderr, "%s: ", progname);
  173.     vsyserr(stderr, fmt, ap, e);
  174.     FMT_END
  175.  
  176.     if (errlog)
  177.     {
  178.         errstart();
  179.         FMT_START
  180.         (void) fprintf(errlog, "%s: ", progname);
  181.         vsyserr(errlog, fmt, ap, e);
  182.         FMT_END
  183.     }
  184. }
  185.  
  186. vsyserr(fp, fmt, ap, e)
  187. FILE    *fp;
  188. char    *fmt;
  189. va_list ap;
  190. int     e;
  191. {
  192.     (void) vfprintf(fp, fmt, ap);
  193.     if (e <= sys_nerr)
  194.         (void) fprintf(fp, ": %s\n", sys_errlist[e]);
  195.     else
  196.         (void) fprintf(fp, ": unknown system error %d\n", e);
  197. }
  198.  
  199. /*----------------------------------------------------------------------
  200.  * Sleep for the given number of seconds.
  201.  */
  202.  
  203. snooze(n)
  204. int     n;
  205. {
  206. #ifdef CALL_NAP
  207.     (void) nap(n * 1000L);
  208. #else
  209.     (void) sleep(n);
  210. #endif
  211. }
  212.  
  213. /*----------------------------------------------------------------------
  214.  * Get the host name from HOSTFILE.
  215.  */
  216.  
  217. #ifdef HOSTFILE
  218.  
  219. char *
  220. gethost()
  221. {
  222.     int     fd, rd;
  223.     char    *p;
  224.     static char name[32];
  225.  
  226.     if ((fd = open(HOSTFILE, O_RDONLY)) == -1)
  227.         return NULL;
  228.     rd = read(fd, name, sizeof(name) - 1);
  229.     (void) close(fd);
  230.  
  231.     if (rd < 1)
  232.         return NULL;
  233.     name[rd] = 0;
  234.     if ((p = strchr(name, '\n')) != NULL)
  235.         *p = 0;
  236.  
  237.     return (name[0] ? name : NULL);
  238. }
  239.  
  240. #endif /* HOSTFILE */
  241.  
  242. /*----------------------------------------------------------------------
  243.  * Get the host name via the uname() system call.
  244.  */
  245.  
  246. #ifdef UNAME
  247.  
  248. char *
  249. gethost()
  250. {
  251.     static struct utsname u;
  252.  
  253.     uname(&u);
  254.     return (u.nodename[0] ? u.nodename : NULL);
  255. }
  256.  
  257. #endif /* UNAME */
  258.  
  259. /*----------------------------------------------------------------------
  260.  * Get the host name via the gethostname() system call.
  261.  */
  262.  
  263. #ifdef GETHOSTNAME
  264.  
  265. char *
  266. gethost()
  267. {
  268.     static char hostname[64];
  269.  
  270.     if (gethostname(hostname, sizeof(hostname)) == -1)
  271.         return NULL;
  272.  
  273.     return hostname;
  274. }
  275.  
  276. #endif /* GETHOSTNAME */
  277.  
  278. /*----------------------------------------------------------------------
  279.  * Return a pre-defined HOSTNAME.
  280.  */
  281.  
  282. #ifdef HOSTNAME
  283.  
  284. char *
  285. gethost()
  286. {
  287.     return HOSTNAME;
  288. }
  289.  
  290. #endif /* HOSTNAME */
  291.  
  292. /*----------------------------------------------------------------------
  293.  * Variable-argument-list output, System V style.
  294.  */
  295.  
  296. #ifndef HAS_VPRINTF
  297.  
  298. vprintf(fmt, ap)
  299. char    *fmt;
  300. va_list ap;
  301. {
  302.     int     a,b,c,d,e,f,g,h;
  303.  
  304.     a = va_arg(ap, int);
  305.     b = va_arg(ap, int);
  306.     c = va_arg(ap, int);
  307.     d = va_arg(ap, int);
  308.     e = va_arg(ap, int);
  309.     f = va_arg(ap, int);
  310.     g = va_arg(ap, int);
  311.     h = va_arg(ap, int);
  312.  
  313.     (void) printf(fmt, a,b,c,d,e,f,g,h);
  314. }
  315.  
  316. vfprintf(fp, fmt, ap)
  317. FILE    *fp;
  318. char    *fmt;
  319. va_list ap;
  320. {
  321.     int     a,b,c,d,e,f,g,h;
  322.  
  323.     a = va_arg(ap, int);
  324.     b = va_arg(ap, int);
  325.     c = va_arg(ap, int);
  326.     d = va_arg(ap, int);
  327.     e = va_arg(ap, int);
  328.     f = va_arg(ap, int);
  329.     g = va_arg(ap, int);
  330.     h = va_arg(ap, int);
  331.  
  332.     (void) fprintf(fp, fmt, a,b,c,d,e,f,g,h);
  333. }
  334.  
  335. vsprintf(s, fmt, ap)
  336. char    *s;
  337. char    *fmt;
  338. va_list ap;
  339. {
  340.     int     a,b,c,d,e,f,g,h;
  341.  
  342.     a = va_arg(ap, int);
  343.     b = va_arg(ap, int);
  344.     c = va_arg(ap, int);
  345.     d = va_arg(ap, int);
  346.     e = va_arg(ap, int);
  347.     f = va_arg(ap, int);
  348.     g = va_arg(ap, int);
  349.     h = va_arg(ap, int);
  350.  
  351.     (void) sprintf(s, fmt, a,b,c,d,e,f,g,h);
  352. }
  353.  
  354. #endif  /* !HAS_VPRINTF */
  355.  
  356. /*----------------------------------------------------------------------
  357.  * Add a new environment variable.
  358.  */
  359.  
  360. #ifndef HAS_PUTENV
  361.  
  362. int
  363. putenv(s)
  364. char *s;
  365. {
  366.     static  char    **env_array;
  367.     static  int     env_size;
  368.     char    *e;
  369.     int     i, j;
  370.  
  371.     if (env_array == NULL)
  372.     {
  373.         for (i = 0; environ[i]; ++i)
  374.             {}
  375.         env_size = i + 10;      /* arbitrary */
  376.         env_array = (char **) zalloc(env_size * sizeof(char *));
  377.         Copy((char *)env_array, (char *)environ,
  378.              (int) ((i + 1) * sizeof(char *)));
  379.         environ = env_array;
  380.     }
  381.     else if (environ != env_array)
  382.         message("putenv: warning: someone moved environ!\n");
  383.  
  384.     if ((e = strchr(s, '=')) != NULL)
  385.         ++e;
  386.     else
  387.         e = s + strlen(s);
  388.  
  389.     j = 0;
  390.     for (i = 0; env_array[i]; ++i)
  391.     {
  392.         if (strncmp(env_array[i], s, e - s) != 0)
  393.             env_array[j++] = env_array[i];
  394.     }
  395.  
  396.     if ((j + 1) >= env_size)
  397.     {
  398.         env_size += 10;                 /* arbitrary */
  399.         env_array = (char **) srealloc((char *)env_array,
  400.                     env_size * sizeof(char **));
  401.     }
  402.  
  403.     env_array[j++] = s;
  404.     env_array[j] = NULL;
  405.  
  406.     environ = env_array;
  407.     return 0;
  408. }
  409.  
  410. #endif  /* !HAS_PUTENV */
  411.  
  412. /*----------------------------------------------------------------------
  413.  * Memory copy.
  414.  */
  415.  
  416. #ifdef MEMFUNCS
  417.  
  418. Copy(dest, src, len)
  419. char    *dest;
  420. char    *src;
  421. int     len;
  422. {
  423.     while (len-- > 0)
  424.         *dest++ = *src++;
  425. }
  426.  
  427. #endif
  428.  
  429. /*----------------------------------------------------------------------
  430.  * Memory clear.
  431.  */
  432.  
  433. #ifdef MEMFUNCS
  434.  
  435. Zero(dest, len)
  436. char    *dest;
  437. int     len;
  438. {
  439.     while (len-- > 0)
  440.         *dest++ = 0;
  441. }
  442.  
  443. #endif
  444.