100 #include <sys/time.h>
134 #define PC_FLAG_SEARCH_QUEUE (1<<0)
135 #define PC_FLAG_PRINT_OFFSET (1<<1)
136 #define PC_FLAG_PRINT_ENV (1<<2)
137 #define PC_FLAG_PRINT_HEADER (1<<3)
138 #define PC_FLAG_PRINT_BODY (1<<4)
139 #define PC_FLAG_PRINT_RTYPE_DEC (1<<5)
140 #define PC_FLAG_PRINT_RTYPE_SYM (1<<6)
142 #define PC_MASK_PRINT_TEXT (PC_FLAG_PRINT_HEADER | PC_FLAG_PRINT_BODY)
143 #define PC_MASK_PRINT_ALL (PC_FLAG_PRINT_ENV | PC_MASK_PRINT_TEXT)
148 #define PC_STATE_ENV 0
149 #define PC_STATE_HEADER 1
150 #define PC_STATE_BODY 2
152 #define STR vstring_str
153 #define LEN VSTRING_LEN
165 const char *error_text;
174 #define TEXT_RECORD(rec_type) \
175 (rec_type == REC_TYPE_CONT || rec_type == REC_TYPE_NORM)
196 data_offset = data_size = -1;
218 #define PRINT_MARKER(flags, fp, offset, type, text) do { \
219 if ((flags) & PC_FLAG_PRINT_OFFSET) \
220 vstream_printf("%9lu ", (unsigned long) (offset)); \
221 if (flags & PC_FLAG_PRINT_RTYPE_DEC) \
222 vstream_printf("%3d ", (type)); \
223 vstream_printf("*** %s %s ***\n", (text), VSTREAM_PATH(fp)); \
224 vstream_fflush(VSTREAM_OUT); \
227 #define PRINT_RECORD(flags, offset, type, value) do { \
228 if ((flags) & PC_FLAG_PRINT_OFFSET) \
229 vstream_printf("%9lu ", (unsigned long) (offset)); \
230 if (flags & PC_FLAG_PRINT_RTYPE_DEC) \
231 vstream_printf("%3d ", (type)); \
232 vstream_printf("%s: %s\n", rec_type_name(rec_type), (value)); \
233 vstream_fflush(VSTREAM_OUT); \
245 if (do_print == 0 && (flags & PC_FLAG_PRINT_ENV) == 0)
248 if (do_print == 0 && (flags & PC_FLAG_PRINT_ENV)
249 && data_offset >= 0 && data_size >= 0
257 msg_warn(
"%s: out-of-order message content marker",
260 if (flags & PC_FLAG_PRINT_ENV)
261 PRINT_MARKER(flags, fp, offset, rec_type,
"MESSAGE CONTENTS");
264 && data_offset >= 0 && data_size >= 0
274 msg_warn(
"%s: out-of-order extracted segment marker",
279 if (flags & PC_FLAG_PRINT_ENV)
280 PRINT_MARKER(flags, fp, offset, rec_type,
"HEADER EXTRACTED");
291 msg_warn(
"%s: out-of-order message end marker",
294 if (flags & PC_FLAG_PRINT_ENV)
295 PRINT_MARKER(flags, fp, offset, rec_type,
"MESSAGE FILE END");
305 msg_fatal(
"bad pointer record, or input is not seekable");
312 if (data_size >= 0 || data_offset >= 0) {
313 msg_warn(
"file contains multiple size records");
315 if (sscanf(
STR(buffer),
"%ld %ld", &data_size, &data_offset) != 2
316 || data_offset <= 0 || data_size <= 0)
319 if ((flags & PC_FLAG_PRINT_ENV) == 0) {
335 if (flags & PC_FLAG_PRINT_OFFSET)
344 asctime(localtime(&time)));
349 asctime(localtime(&time)));
358 || (flags & PC_FLAG_PRINT_OFFSET) != 0) {
377 if (error_text != 0) {
378 msg_warn(
"%s: malformed attribute: %s: %.100s",
383 time = atol(attr_value);
385 asctime(localtime(&time)));
388 attr_name, attr_value);
395 prev_type = rec_type;
408 msg_fatal(
"usage: %s [-b (body text)] [-c config_dir] [-d (decimal record type)] [-e (envelope records)] [-h (header text)] [-q (access queue)] [-v] [file(s)...]",
414 int main(
int argc,
char **argv)
422 static char *queue_names[] = {
445 for (fd = 0; fd < 3; fd++)
446 if (
fstat(fd, &st) == -1
447 && (close(fd), open(
"/dev/null", O_RDWR, 0)) != fd)
458 while ((ch =
GETOPT(argc, argv,
"bc:dehoqv")) > 0) {
508 if (argc == optind) {
521 while (optind < argc) {
523 msg_fatal(
"bad mail queue ID: %s", argv[optind]);
524 for (fp = 0, tries = 0; fp == 0 && tries < 2; tries++)
525 for (cpp = queue_names; fp == 0 && *cpp != 0; cpp++)
528 msg_fatal(
"open queue file %s: %m", argv[optind]);
529 postcat(fp, buffer, flags);
531 msg_warn(
"close %s: %m", argv[optind]);
540 while (optind < argc) {
543 postcat(fp, buffer, flags);
545 msg_warn(
"close %s: %m", argv[optind]);
#define MAIL_ATTR_CREATE_TIME
char * var_import_environ
#define PC_MASK_PRINT_ALL
int mail_queue_id_ok(const char *queue_id)
ARGV * argv_free(ARGV *argvp)
#define VAR_IMPORT_ENVIRON
int main(int argc, char **argv)
#define MAIL_QUEUE_ACTIVE
off_t vstream_ftell(VSTREAM *stream)
int rec_goto(VSTREAM *stream, const char *buf)
#define PC_FLAG_PRINT_ENV
const char * rec_type_name(int type)
#define VSTREAM_PUTCHAR(ch)
#define PC_FLAG_PRINT_RTYPE_DEC
const char * split_nameval(char *buf, char **name, char **value)
void mail_conf_read(void)
VSTREAM * vstream_fopen(const char *path, int flags, mode_t mode)
int rec_get_raw(VSTREAM *stream, VSTRING *buf, ssize_t maxsize, int flags)
#define PC_FLAG_PRINT_HEADER
#define PC_MASK_PRINT_TEXT
#define PC_FLAG_PRINT_OFFSET
ARGV * mail_parm_split(const char *name, const char *value)
MAIL_VERSION_STAMP_DECLARE
#define vstream_ungetc(vp, ch)
int vstream_fclose(VSTREAM *stream)
VSTREAM * mail_queue_open(const char *queue_name, const char *queue_id, int flags, mode_t mode)
VSTREAM * vstream_printf(const char *fmt,...)
#define MAIL_QUEUE_INCOMING
void msg_warn(const char *fmt,...)
VSTRING * vstring_alloc(ssize_t len)
#define PRINT_MARKER(flags, fp, offset, type, text)
#define MAIL_VERSION_STAMP_ALLOCATE
#define PC_FLAG_SEARCH_QUEUE
#define TEXT_RECORD(rec_type)
#define MAIL_QUEUE_MAILDROP
#define REC_TYPE_WARN_SCAN(cp, tv)
NORETURN msg_fatal(const char *fmt,...)
off_t vstream_fseek(VSTREAM *stream, off_t offset, int whence)
int vstream_fflush(VSTREAM *stream)
void update_env(char **preserve_list)
#define MAIL_QUEUE_DEFERRED
#define PC_FLAG_PRINT_BODY
#define GETOPT(argc, argv, str)
#define vstream_fwrite(v, b, n)
VSTRING * vstring_free(VSTRING *vp)
void msg_vstream_init(const char *name, VSTREAM *vp)
#define CA_VSTREAM_CTL_END
#define CA_VSTREAM_CTL_PATH(v)
void vstream_control(VSTREAM *stream, int name,...)
#define REC_TYPE_TIME_SCAN(cp, tv)
#define PRINT_RECORD(flags, offset, type, value)
#define REC_TYPE_ENVELOPE