Home | History | Annotate | Line # | Download | only in global
      1 /*	$NetBSD: mail_queue.h,v 1.4 2025/02/25 19:15:45 christos Exp $	*/
      2 
      3 #ifndef _MAIL_QUEUE_H_INCLUDED_
      4 #define _MAIL_QUEUE_H_INCLUDED_
      5 
      6 /*++
      7 /* NAME
      8 /*	mail_queue 3h
      9 /* SUMMARY
     10 /*	mail queue access
     11 /* SYNOPSIS
     12 /*	#include <mail_queue.h>
     13 /* DESCRIPTION
     14 /* .nf
     15 
     16  /*
     17   * System library.
     18   */
     19 #include <sys/time.h>
     20 
     21  /*
     22   * Utility library.
     23   */
     24 #include <vstring.h>
     25 #include <vstream.h>
     26 
     27  /*
     28   * Mail queue names.
     29   */
     30 #define MAIL_QUEUE_MAILDROP	"maildrop"
     31 #define MAIL_QUEUE_HOLD		"hold"
     32 #define MAIL_QUEUE_INCOMING	"incoming"
     33 #define MAIL_QUEUE_ACTIVE	"active"
     34 #define MAIL_QUEUE_DEFERRED	"deferred"
     35 #define MAIL_QUEUE_TRACE	"trace"
     36 #define MAIL_QUEUE_DEFER	"defer"
     37 #define MAIL_QUEUE_BOUNCE	"bounce"
     38 #define MAIL_QUEUE_CORRUPT	"corrupt"
     39 #define MAIL_QUEUE_FLUSH	"flush"
     40 #define MAIL_QUEUE_SAVED	"saved"
     41 
     42  /*
     43   * Queue file modes.
     44   *
     45   * 4.4BSD-like systems don't allow (sticky AND executable) together, so we use
     46   * group read permission bits instead. These are more portable, but they
     47   * also are more likely to be turned on by accident. It would not be the end
     48   * of the world.
     49   */
     50 #define MAIL_QUEUE_STAT_READY	(S_IRUSR | S_IWUSR | S_IXUSR)
     51 #define MAIL_QUEUE_STAT_CORRUPT	(S_IRUSR)
     52 #ifndef MAIL_QUEUE_STAT_UNTHROTTLE
     53 #define MAIL_QUEUE_STAT_UNTHROTTLE (S_IRGRP)
     54 #define MAIL_QUEUE_STAT_EXPIRE	(S_IXGRP)
     55 #endif
     56 
     57 extern struct VSTREAM *mail_queue_enter(const char *, mode_t, struct timeval *);
     58 extern struct VSTREAM *mail_queue_open(const char *, const char *, int, mode_t);
     59 extern int mail_queue_rename(const char *, const char *, const char *);
     60 extern int mail_queue_remove(const char *, const char *);
     61 extern const char *mail_queue_dir(VSTRING *, const char *, const char *);
     62 extern const char *mail_queue_path(VSTRING *, const char *, const char *);
     63 extern int mail_queue_mkdirs(const char *);
     64 extern int mail_queue_name_ok(const char *);
     65 extern int mail_queue_id_ok(const char *);
     66 
     67  /*
     68   * MQID - Mail Queue ID format definitions. Needed only by code that creates
     69   * or parses queue ID strings.
     70   */
     71 #ifdef MAIL_QUEUE_INTERNAL
     72 
     73  /*
     74   * System library.
     75   */
     76 #include <errno.h>
     77 
     78  /*
     79   * Global library.
     80   */
     81 #include <safe_ultostr.h>
     82 
     83  /*
     84   * The long non-repeating queue ID is encoded in an alphabet of 10 digits,
     85   * 21 upper-case characters, and 21 or fewer lower-case characters. The
     86   * alphabet is made "safe" by removing all the vowels (AEIOUaeiou). The ID
     87   * is the concatenation of:
     88   *
     89   * - the time in seconds (base 52 encoded, six or more chars),
     90   *
     91   * - the time in microseconds (base 52 encoded, exactly four chars),
     92   *
     93   * - the 'z' character to separate the time and inode information,
     94   *
     95   * - the inode number (base 51 encoded so that it contains no 'z').
     96   */
     97 #define MQID_LG_SEC_BASE	52	/* seconds safe alphabet base */
     98 #define MQID_LG_SEC_PAD	6		/* seconds minimum field width */
     99 #define MQID_LG_USEC_BASE	52	/* microseconds safe alphabet base */
    100 #define MQID_LG_USEC_PAD	4	/* microseconds exact field width */
    101 #define MQID_LG_TIME_PAD	(MQID_LG_SEC_PAD + MQID_LG_USEC_PAD)
    102 #define MQID_LG_INUM_SEP	'z'	/* time-inode separator */
    103 #define MQID_LG_INUM_BASE	51	/* inode safe alphabet base */
    104 #define MQID_LG_INUM_PAD	0	/* no padding needed */
    105 
    106 #define MQID_FIND_LG_INUM_SEPARATOR(cp, path) \
    107 	(((cp) = strrchr((path), MQID_LG_INUM_SEP)) != 0 \
    108 	    && ((cp) - (path) >= MQID_LG_TIME_PAD))
    109 
    110 #define MQID_GET_INUM(path, inum, long_form, error) do { \
    111 	char *_cp; \
    112 	if (((long_form) = MQID_FIND_LG_INUM_SEPARATOR(_cp, (path))) != 0) { \
    113 	    MQID_LG_DECODE_INUM(_cp + 1, (inum), (error)); \
    114 	} else { \
    115 	    MQID_SH_DECODE_INUM((path) + MQID_SH_USEC_PAD, (inum), (error)); \
    116 	} \
    117     } while (0)
    118 
    119 #define MQID_LG_ENCODE_SEC(buf, val) \
    120 	MQID_LG_ENCODE((buf), (val), MQID_LG_SEC_BASE, MQID_LG_SEC_PAD)
    121 
    122 #define MQID_LG_ENCODE_USEC(buf, val) \
    123 	MQID_LG_ENCODE((buf), (val), MQID_LG_USEC_BASE, MQID_LG_USEC_PAD)
    124 
    125 #define MQID_LG_ENCODE_INUM(buf, val) \
    126 	MQID_LG_ENCODE((buf), (val), MQID_LG_INUM_BASE, MQID_LG_INUM_PAD)
    127 
    128 #define MQID_LG_DECODE_USEC(str, ulval, error) \
    129 	MQID_LG_DECODE((str), (ulval), MQID_LG_USEC_BASE, (error))
    130 
    131 #define MQID_LG_DECODE_INUM(str, ulval, error) \
    132 	MQID_LG_DECODE((str), (ulval), MQID_LG_INUM_BASE, (error))
    133 
    134 #define MQID_LG_ENCODE(buf, val, base, padlen) \
    135 	safe_ultostr((buf), (unsigned long) (val), (base), (padlen), '0')
    136 
    137 #define MQID_LG_DECODE(str, ulval, base, error) do { \
    138 	char *_end; \
    139 	errno = 0; \
    140 	(ulval) = safe_strtoul((str), &_end, (base)); \
    141 	(error) = (*_end != 0 || ((ulval) == ULONG_MAX && errno == ERANGE)); \
    142     } while (0)
    143 
    144 #define MQID_LG_GET_HEX_USEC(bp, zp) do { \
    145 	int _error; \
    146 	unsigned long _us_val; \
    147 	vstring_strncpy((bp), (zp) - MQID_LG_USEC_PAD, MQID_LG_USEC_PAD); \
    148 	MQID_LG_DECODE_USEC(STR(bp), _us_val, _error); \
    149 	if (_error) \
    150 	    _us_val = 0; \
    151 	(void) MQID_SH_ENCODE_USEC((bp), _us_val); \
    152     } while (0)
    153 
    154  /*
    155   * The short repeating queue ID is encoded in upper-case hexadecimal, and is
    156   * the concatenation of:
    157   *
    158   * - the time in microseconds (exactly five chars),
    159   *
    160   * - the inode number.
    161   */
    162 #define MQID_SH_USEC_PAD	5	/* microseconds exact field width */
    163 
    164 #define MQID_SH_ENCODE_USEC(buf, usec) \
    165 	vstring_str(vstring_sprintf((buf), "%05X", (int) (usec)))
    166 
    167 #define MQID_SH_ENCODE_INUM(buf, inum) \
    168 	vstring_str(vstring_sprintf((buf), "%lX", (unsigned long) (inum)))
    169 
    170 #define MQID_SH_DECODE_INUM(str, ulval, error) do { \
    171         char *_end; \
    172 	errno = 0; \
    173 	(ulval) = strtoul((str), &_end, 16); \
    174 	(error) = (*_end != 0 || ((ulval) == ULONG_MAX && errno == ERANGE)); \
    175     } while (0)
    176 
    177 #endif					/* MAIL_QUEUE_INTERNAL */
    178 
    179 /* LICENSE
    180 /* .ad
    181 /* .fi
    182 /*	The Secure Mailer license must be distributed with this software.
    183 /* AUTHOR(S)
    184 /*	Wietse Venema
    185 /*	IBM T.J. Watson Research
    186 /*	P.O. Box 704
    187 /*	Yorktown Heights, NY 10598, USA
    188 /*
    189 /*	Wietse Venema
    190 /*	Google, Inc.
    191 /*	111 8th Avenue
    192 /*	New York, NY 10011, USA
    193 /*--*/
    194 
    195 #endif					/* _MAIL_QUEUE_H_INCLUDED_ */
    196