12 #include <sys/types.h>
15 #include "string_utils.h"
16 #include "file_utils.h"
23 static int hdr_only
= 0;
24 static int mime_only
= 0;
26 static void plain_body(char *line
)
32 static void qp_body(char *line
)
36 rfc2047_decode_quoted_printable(buf
, line
, sizeof(buf
) - 1);
40 static void parse_mail_body(FILE *fh
, struct mail_header
*hdr
)
43 void (*decode_body
)(char *line
);
45 switch (hdr
->mime
.transfer_encoding
) {
46 case MIME_ENCODING_QUOTED_PRINTABLE
:
47 decode_body
= qp_body
;
50 decode_body
= plain_body
;
54 (void) fseek(fh
, hdr
->body_offset
, SEEK_SET
);
56 while (fgets(buf
, sizeof(buf
), fh
)) {
61 static void parse_mail_header(FILE *fh
, struct mail_header
*hdr
)
67 while (fgets(buf
, sizeof(buf
), fh
)) {
68 if (!strncasecmp(buf
, "From:", 5)) {
69 rfc5322_extract_address(hdr
->from
, buf
, sizeof(hdr
->from
));
70 crlf
= strrchr(buf
, '\n');
73 } else if (!strncasecmp(buf
, "Subject:", 8)) {
74 rfc5322_extract_subject(hdr
->subject
, buf
, sizeof(hdr
->subject
));
75 } else if (!strncasecmp(buf
, "Date:", 5)) {
76 hdr
->date
= rfc822_parsedt(buf
);
77 } else if (!strncasecmp(buf
, "Content-Type:", 13)) {
78 mime_content_type(buf
, &hdr
->mime
);
79 } else if (!strncasecmp(buf
, "Content-Disposition:", 20)) {
80 mime_content_disposition(buf
, &hdr
->mime
);
81 } else if (!strncasecmp(buf
, "Content-Transfer-Encoding:", 26)) {
82 mime_content_transfer_encoding(buf
, &hdr
->mime
);
84 if (rfc822_check_header_end(buf
)) {
87 /*printf("[SKIP] ------- %s", buf); */
91 hdr
->body_offset
= ftell(fh
);
94 static void init_mail_header(struct mail_header
*hdr
)
96 memset(hdr
->from
, 0, sizeof(hdr
->from
));
97 memset(hdr
->subject
, 0, sizeof(hdr
->subject
));
99 hdr
->body_offset
= 0L;
103 * If no Content-Type header field is specified, default to:
104 * Content-type: text/plain; charset=us-ascii
106 hdr
->mime
.type
= MIME_TYPE_TEXT
;
107 hdr
->mime
.subtype
= MIME_SUBTYPE_PLAIN
;
108 hdr
->mime
.disposition
= MIME_DISPOSITION_UNKNOWN
;
110 /* [RFC2045] "Content-Transfer-Encoding: 7BIT" is assumed if the
111 * Content-Transfer-Encoding header field is not present.
112 * ... If a Content-Transfer-Encoding header field appears as part
113 * of a message header, it applies to the entire body of that message.
114 * If a Content-Transfer-Encoding header field appears as part of an
115 * entity's headers, it applies only to the body of that entity.
116 * If an entity is of type "multipart" the Content-Transfer-Encoding
117 * is not permitted to have any value other than "7bit", "8bit" or
120 hdr
->mime
.transfer_encoding
= MIME_ENCODING_7BIT
;
123 void usage(const char *appname
)
125 fprintf(stderr
, "Usage:\n%s options\n", appname
);
126 fprintf(stderr
, "Options:\n");
127 fprintf(stderr
, " -h Parse header only\n"
128 " -m Parse MIMI only\n"
129 " -f <file> Parse file\n"
130 " -d <maildir> Parse maildir\n");
133 static void parse_file(const char *file
)
136 struct mail_header mail_hdr
;
141 fh
= fopen(file
, "r");
146 init_mail_header(&mail_hdr
);
148 parse_mail_header(fh
, &mail_hdr
);
150 fprintf(stderr
, "-------------------------------------------\n");
151 fprintf(stderr
, "Test file: %s\n", file
);
152 fprintf(stderr
, "-------------------------------------------\n");
154 fprintf(stderr
, "Date : %s\n", rfc822_mkdt(mail_hdr
.date
));
155 fprintf(stderr
, "From : %s\n", mail_hdr
.from
);
156 fprintf(stderr
, "Subject: %s\n", mail_hdr
.subject
);
159 debug_mime_header(&mail_hdr
.mime
);
161 fprintf(stderr
, "-------------------------------------------\n");
165 parse_mail_body(fh
, &mail_hdr
);
172 int main(int argc
, char **argv
)
177 char *maildir_path
= NULL
;
179 char old_path
[PATH_MAX
];
182 while ((opt
= getopt(argc
, argv
, "d:f:hm")) != -1) {
185 maildir_path
= optarg
;
197 fprintf(stderr
, "Unknown parameter.\n");
203 if ((file
== NULL
) && (maildir_path
== NULL
)) {
207 if ((file
!= NULL
) && (maildir_path
!= NULL
)) {
208 fprintf(stderr
, "-f and -d are mutually esclusive!.\n");
217 /* Parse all maildir */
218 if (!getcwd(old_path
, PATH_MAX
)) {
219 fprintf(stderr
, "%s - GETCWD: %s\n", __func__
, strerror(errno
));
223 if (chdir(maildir_path
) < 0) {
224 fprintf(stderr
, "%s - CHDIR: %s\n", __func__
, strerror(errno
));
228 rc
= scan_dir(maildir_path
, parse_file
);
230 if (chdir(old_path
) < 0) {
231 fprintf(stderr
, "%s - Cannot restore path %s!\n", __func__
, strerror(errno
));