61
61
extern int mail_queue_name_ok(const char *);
62
62
extern int mail_queue_id_ok(const char *);
65
* MQID - Mail Queue ID format definitions. Needed only by code that creates
66
* or parses queue ID strings.
68
#ifdef MAIL_QUEUE_INTERNAL
78
#include <safe_ultostr.h>
81
* The long non-repeating queue ID is encoded in an alphabet of 10 digits,
82
* 21 upper-case characters, and 21 or fewer lower-case characters. The
83
* alphabet is made "safe" by removing all the vowels (AEIOUaeiou). The ID
84
* is the concatenation of:
86
* - the time in seconds (base 52 encoded, six or more chars),
88
* - the time in microseconds (base 52 encoded, exactly four chars),
90
* - the 'z' character to separate the time and inode information,
92
* - the inode number (base 51 encoded so that it contains no 'z').
94
#define MQID_LG_SEC_BASE 52 /* seconds safe alphabet base */
95
#define MQID_LG_SEC_PAD 6 /* seconds minumum field width */
96
#define MQID_LG_USEC_BASE 52 /* microseconds safe alphabet base */
97
#define MQID_LG_USEC_PAD 4 /* microseconds exact field width */
98
#define MQID_LG_TIME_PAD (MQID_LG_SEC_PAD + MQID_LG_USEC_PAD)
99
#define MQID_LG_INUM_SEP 'z' /* time-inode separator */
100
#define MQID_LG_INUM_BASE 51 /* inode safe alphabet base */
101
#define MQID_LG_INUM_PAD 0 /* no padding needed */
103
#define MQID_FIND_LG_INUM_SEPARATOR(cp, path) \
104
(((cp) = strrchr((path), MQID_LG_INUM_SEP)) != 0 \
105
&& ((cp) - (path) >= MQID_LG_TIME_PAD))
107
#define MQID_GET_INUM(path, inum, long_form, error) do { \
109
if (((long_form) = MQID_FIND_LG_INUM_SEPARATOR(_cp, (path))) != 0) { \
110
MQID_LG_DECODE_INUM(_cp + 1, (inum), (error)); \
112
MQID_SH_DECODE_INUM((path) + MQID_SH_USEC_PAD, (inum), (error)); \
116
#define MQID_LG_ENCODE_SEC(buf, val) \
117
MQID_LG_ENCODE((buf), (val), MQID_LG_SEC_BASE, MQID_LG_SEC_PAD)
119
#define MQID_LG_ENCODE_USEC(buf, val) \
120
MQID_LG_ENCODE((buf), (val), MQID_LG_USEC_BASE, MQID_LG_USEC_PAD)
122
#define MQID_LG_ENCODE_INUM(buf, val) \
123
MQID_LG_ENCODE((buf), (val), MQID_LG_INUM_BASE, MQID_LG_INUM_PAD)
125
#define MQID_LG_DECODE_USEC(str, ulval, error) \
126
MQID_LG_DECODE((str), (ulval), MQID_LG_USEC_BASE, (error))
128
#define MQID_LG_DECODE_INUM(str, ulval, error) \
129
MQID_LG_DECODE((str), (ulval), MQID_LG_INUM_BASE, (error))
131
#define MQID_LG_ENCODE(buf, val, base, padlen) \
132
safe_ultostr((buf), (unsigned long) (val), (base), (padlen), '0')
134
#define MQID_LG_DECODE(str, ulval, base, error) do { \
137
(ulval) = safe_strtoul((str), &_end, (base)); \
138
(error) = (*_end != 0 || ((ulval) == ULONG_MAX && errno == ERANGE)); \
141
#define MQID_LG_GET_HEX_USEC(bp, zp) do { \
143
unsigned long _us_val; \
144
vstring_strncpy((bp), (zp) - MQID_LG_USEC_PAD, MQID_LG_USEC_PAD); \
145
MQID_LG_DECODE_USEC(STR(bp), _us_val, _error); \
146
(void) MQID_SH_ENCODE_USEC((bp), _us_val); \
150
* The short repeating queue ID is encoded in upper-case hexadecimal, and is
151
* the concatenation of:
153
* - the time in microseconds (exactly five chars),
155
* - the inode number.
157
#define MQID_SH_USEC_PAD 5 /* microseconds exact field width */
159
#define MQID_SH_ENCODE_USEC(buf, usec) \
160
vstring_str(vstring_sprintf((buf), "%05X", (int) (usec)))
162
#define MQID_SH_ENCODE_INUM(buf, inum) \
163
vstring_str(vstring_sprintf((buf), "%lX", (unsigned long) (inum)))
165
#define MQID_SH_DECODE_INUM(str, ulval, error) do { \
168
(ulval) = strtoul((str), &_end, 16); \
169
(error) = (*_end != 0 || ((ulval) == ULONG_MAX && errno == ERANGE)); \
172
#endif /* MAIL_QUEUE_INTERNAL */