summaryrefslogtreecommitdiffstats
path: root/src/global/mail_queue.h
blob: 4928d60cc180c43967a842d1e9c55e3982ffd8af (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
#ifndef _MAIL_QUEUE_H_INCLUDED_
#define _MAIL_QUEUE_H_INCLUDED_

/*++
/* NAME
/*	mail_queue 3h
/* SUMMARY
/*	mail queue access
/* SYNOPSIS
/*	#include <mail_queue.h>
/* DESCRIPTION
/* .nf

 /*
  * System library.
  */
#include <sys/time.h>

 /*
  * Utility library.
  */
#include <vstring.h>
#include <vstream.h>

 /*
  * Mail queue names.
  */
#define MAIL_QUEUE_MAILDROP	"maildrop"
#define MAIL_QUEUE_HOLD		"hold"
#define MAIL_QUEUE_INCOMING	"incoming"
#define MAIL_QUEUE_ACTIVE	"active"
#define MAIL_QUEUE_DEFERRED	"deferred"
#define MAIL_QUEUE_TRACE	"trace"
#define MAIL_QUEUE_DEFER	"defer"
#define MAIL_QUEUE_BOUNCE	"bounce"
#define MAIL_QUEUE_CORRUPT	"corrupt"
#define MAIL_QUEUE_FLUSH	"flush"
#define MAIL_QUEUE_SAVED	"saved"

 /*
  * Queue file modes.
  * 
  * 4.4BSD-like systems don't allow (sticky AND executable) together, so we use
  * group read permission bits instead. These are more portable, but they
  * also are more likely to be turned on by accident. It would not be the end
  * of the world.
  */
#define MAIL_QUEUE_STAT_READY	(S_IRUSR | S_IWUSR | S_IXUSR)
#define MAIL_QUEUE_STAT_CORRUPT	(S_IRUSR)
#ifndef MAIL_QUEUE_STAT_UNTHROTTLE
#define MAIL_QUEUE_STAT_UNTHROTTLE (S_IRGRP)
#define MAIL_QUEUE_STAT_EXPIRE	(S_IXGRP)
#endif

extern struct VSTREAM *mail_queue_enter(const char *, mode_t, struct timeval *);
extern struct VSTREAM *mail_queue_open(const char *, const char *, int, mode_t);
extern int mail_queue_rename(const char *, const char *, const char *);
extern int mail_queue_remove(const char *, const char *);
extern const char *mail_queue_dir(VSTRING *, const char *, const char *);
extern const char *mail_queue_path(VSTRING *, const char *, const char *);
extern int mail_queue_mkdirs(const char *);
extern int mail_queue_name_ok(const char *);
extern int mail_queue_id_ok(const char *);

 /*
  * MQID - Mail Queue ID format definitions. Needed only by code that creates
  * or parses queue ID strings.
  */
#ifdef MAIL_QUEUE_INTERNAL

 /*
  * System library.
  */
#include <errno.h>

 /*
  * Global library.
  */
#include <safe_ultostr.h>

 /*
  * The long non-repeating queue ID is encoded in an alphabet of 10 digits,
  * 21 upper-case characters, and 21 or fewer lower-case characters. The
  * alphabet is made "safe" by removing all the vowels (AEIOUaeiou). The ID
  * is the concatenation of:
  * 
  * - the time in seconds (base 52 encoded, six or more chars),
  * 
  * - the time in microseconds (base 52 encoded, exactly four chars),
  * 
  * - the 'z' character to separate the time and inode information,
  * 
  * - the inode number (base 51 encoded so that it contains no 'z').
  */
#define MQID_LG_SEC_BASE	52	/* seconds safe alphabet base */
#define MQID_LG_SEC_PAD	6	/* seconds minimum field width */
#define MQID_LG_USEC_BASE	52	/* microseconds safe alphabet base */
#define MQID_LG_USEC_PAD	4	/* microseconds exact field width */
#define MQID_LG_TIME_PAD	(MQID_LG_SEC_PAD + MQID_LG_USEC_PAD)
#define MQID_LG_INUM_SEP	'z'	/* time-inode separator */
#define MQID_LG_INUM_BASE	51	/* inode safe alphabet base */
#define MQID_LG_INUM_PAD	0	/* no padding needed */

#define MQID_FIND_LG_INUM_SEPARATOR(cp, path) \
	(((cp) = strrchr((path), MQID_LG_INUM_SEP)) != 0 \
	    && ((cp) - (path) >= MQID_LG_TIME_PAD))

#define MQID_GET_INUM(path, inum, long_form, error) do { \
	char *_cp; \
	if (((long_form) = MQID_FIND_LG_INUM_SEPARATOR(_cp, (path))) != 0) { \
	    MQID_LG_DECODE_INUM(_cp + 1, (inum), (error)); \
	} else { \
	    MQID_SH_DECODE_INUM((path) + MQID_SH_USEC_PAD, (inum), (error)); \
	} \
    } while (0)

#define MQID_LG_ENCODE_SEC(buf, val) \
	MQID_LG_ENCODE((buf), (val), MQID_LG_SEC_BASE, MQID_LG_SEC_PAD)

#define MQID_LG_ENCODE_USEC(buf, val) \
	MQID_LG_ENCODE((buf), (val), MQID_LG_USEC_BASE, MQID_LG_USEC_PAD)

#define MQID_LG_ENCODE_INUM(buf, val) \
	MQID_LG_ENCODE((buf), (val), MQID_LG_INUM_BASE, MQID_LG_INUM_PAD)

#define MQID_LG_DECODE_USEC(str, ulval, error) \
	MQID_LG_DECODE((str), (ulval), MQID_LG_USEC_BASE, (error))

#define MQID_LG_DECODE_INUM(str, ulval, error) \
	MQID_LG_DECODE((str), (ulval), MQID_LG_INUM_BASE, (error))

#define MQID_LG_ENCODE(buf, val, base, padlen) \
	safe_ultostr((buf), (unsigned long) (val), (base), (padlen), '0')

#define MQID_LG_DECODE(str, ulval, base, error) do { \
	char *_end; \
	errno = 0; \
	(ulval) = safe_strtoul((str), &_end, (base)); \
	(error) = (*_end != 0 || ((ulval) == ULONG_MAX && errno == ERANGE)); \
    } while (0)

#define MQID_LG_GET_HEX_USEC(bp, zp) do { \
	int _error; \
	unsigned long _us_val; \
	vstring_strncpy((bp), (zp) - MQID_LG_USEC_PAD, MQID_LG_USEC_PAD); \
	MQID_LG_DECODE_USEC(STR(bp), _us_val, _error); \
	if (_error) \
	    _us_val = 0; \
	(void) MQID_SH_ENCODE_USEC((bp), _us_val); \
    } while (0)

 /*
  * The short repeating queue ID is encoded in upper-case hexadecimal, and is
  * the concatenation of:
  * 
  * - the time in microseconds (exactly five chars),
  * 
  * - the inode number.
  */
#define MQID_SH_USEC_PAD	5	/* microseconds exact field width */

#define MQID_SH_ENCODE_USEC(buf, usec) \
	vstring_str(vstring_sprintf((buf), "%05X", (int) (usec)))

#define MQID_SH_ENCODE_INUM(buf, inum) \
	vstring_str(vstring_sprintf((buf), "%lX", (unsigned long) (inum)))

#define MQID_SH_DECODE_INUM(str, ulval, error) do { \
        char *_end; \
	errno = 0; \
	(ulval) = strtoul((str), &_end, 16); \
	(error) = (*_end != 0 || ((ulval) == ULONG_MAX && errno == ERANGE)); \
    } while (0)

#endif					/* MAIL_QUEUE_INTERNAL */

/* LICENSE
/* .ad
/* .fi
/*	The Secure Mailer license must be distributed with this software.
/* AUTHOR(S)
/*	Wietse Venema
/*	IBM T.J. Watson Research
/*	P.O. Box 704
/*	Yorktown Heights, NY 10598, USA
/*
/*	Wietse Venema
/*	Google, Inc.
/*	111 8th Avenue
/*	New York, NY 10011, USA
/*--*/

#endif					/* _MAIL_QUEUE_H_INCLUDED_ */