gnu indented
Showing
2 changed files
with
586 additions
and
450 deletions
... | @@ -37,184 +37,225 @@ char from[256]; | ... | @@ -37,184 +37,225 @@ char from[256]; |
37 | char subject[256]; | 37 | char subject[256]; |
38 | 38 | ||
39 | int | 39 | int |
40 | main(int argc, char **argv) | 40 | main (int argc, char **argv) |
41 | { | 41 | { |
42 | mailbox_t mbox = NULL; | 42 | mailbox_t mbox = NULL; |
43 | int ret; | 43 | int ret; |
44 | size_t i; | 44 | size_t i; |
45 | size_t count = 0; | 45 | size_t count = 0; |
46 | char *mailbox_name = NULL; | 46 | char *mailbox_name = NULL; |
47 | |||
48 | /* have an argument */ | ||
49 | if (argc > 1) | ||
50 | mailbox_name = argv[1]; | ||
51 | |||
52 | /* Registration. */ | ||
53 | { | ||
54 | list_t bookie; | ||
55 | registrar_get_list (&bookie); | ||
56 | list_append (bookie, mbox_record); | ||
57 | list_append (bookie, path_record); | ||
58 | list_append (bookie, pop_record); | ||
59 | list_append (bookie, imap_record); | ||
60 | } | ||
61 | 47 | ||
62 | if ( ( ret = mailbox_create_default (&mbox, mailbox_name) ) != 0) { | 48 | /* have an argument */ |
63 | fprintf (stderr, "could not create - %s\n", strerror(ret)); | 49 | if (argc > 1) |
64 | exit (2); | 50 | mailbox_name = argv[1]; |
65 | } | ||
66 | 51 | ||
67 | /* Debuging Trace. */ | 52 | /* Registration. */ |
68 | if ( 0 ) { | 53 | { |
69 | mu_debug_t debug; | 54 | list_t bookie; |
70 | mailbox_get_debug (mbox, &debug); | 55 | registrar_get_list (&bookie); |
71 | mu_debug_set_level (debug, MU_DEBUG_TRACE|MU_DEBUG_PROT); | 56 | list_append (bookie, mbox_record); |
72 | } | 57 | list_append (bookie, path_record); |
58 | list_append (bookie, pop_record); | ||
59 | list_append (bookie, imap_record); | ||
60 | } | ||
73 | 61 | ||
74 | /* Open the mailbox for reading only. */ | 62 | if ((ret = mailbox_create_default (&mbox, mailbox_name)) != 0) |
75 | if ( ( ret = mailbox_open (mbox, MU_STREAM_RDWR) ) != 0) { | 63 | { |
76 | fprintf (stderr, "could not open - %s\n", strerror(ret)); | 64 | fprintf (stderr, "could not create - %s\n", strerror (ret)); |
77 | exit (2); | 65 | exit (2); |
78 | } | 66 | } |
67 | |||
68 | /* Debuging Trace. */ | ||
69 | if (0) | ||
70 | { | ||
71 | mu_debug_t debug; | ||
72 | mailbox_get_debug (mbox, &debug); | ||
73 | mu_debug_set_level (debug, MU_DEBUG_TRACE | MU_DEBUG_PROT); | ||
74 | } | ||
79 | 75 | ||
80 | /* Iterator through the entire message set. */ | 76 | /* Open the mailbox for reading only. */ |
81 | mailbox_messages_count (mbox, &count); | 77 | if ((ret = mailbox_open (mbox, MU_STREAM_RDWR)) != 0) |
82 | for(i = 1; i <= count; ++i) { | 78 | { |
83 | message_t msg; | 79 | fprintf (stderr, "could not open - %s\n", strerror (ret)); |
84 | header_t hdr; | 80 | exit (2); |
85 | size_t nparts; | 81 | } |
86 | size_t msize; | 82 | |
87 | 83 | /* Iterator through the entire message set. */ | |
88 | if (( ret = mailbox_get_message (mbox, i, &msg) ) != 0) { | 84 | mailbox_messages_count (mbox, &count); |
89 | fprintf (stderr, "mailbox_get_message - %s\n", strerror(ret)); | 85 | for (i = 1; i <= count; ++i) |
90 | exit(2); | 86 | { |
91 | } | 87 | message_t msg; |
92 | if (( ret = message_size (msg, &msize) ) != 0) { | 88 | header_t hdr; |
93 | fprintf (stderr, "message_size - %s\n", strerror(ret)); | 89 | size_t nparts; |
94 | exit(2); | 90 | size_t msize; |
95 | } | 91 | |
96 | if (( ret = message_get_header (msg, &hdr) ) != 0) { | 92 | if ((ret = mailbox_get_message (mbox, i, &msg)) != 0) |
97 | fprintf (stderr, "message_get_header - %s\n", strerror(ret)); | 93 | { |
98 | exit(2); | 94 | fprintf (stderr, "mailbox_get_message - %s\n", strerror (ret)); |
99 | } | 95 | exit (2); |
100 | header_get_value (hdr, MU_HEADER_FROM, from, sizeof (from), NULL); | 96 | } |
101 | header_get_value (hdr, MU_HEADER_SUBJECT, subject, sizeof (subject), NULL); | 97 | if ((ret = message_size (msg, &msize)) != 0) |
102 | printf("From: %s\tSubject: %s\n", from, subject); | 98 | { |
103 | if ( ( ret = message_get_num_parts(msg, &nparts) ) != 0 ) { | 99 | fprintf (stderr, "message_size - %s\n", strerror (ret)); |
104 | fprintf (stderr, "message_get_num_parts - %s\n", strerror(ret)); | 100 | exit (2); |
105 | exit(2); | 101 | } |
106 | } | 102 | if ((ret = message_get_header (msg, &hdr)) != 0) |
107 | printf("-- Number of parts in message - %d\n",nparts); | 103 | { |
108 | printf("-- Total message size - %d\n",msize); | 104 | fprintf (stderr, "message_get_header - %s\n", strerror (ret)); |
109 | message_display_parts(msg, "\t"); | 105 | exit (2); |
110 | } | 106 | } |
111 | mailbox_close(mbox); | 107 | header_get_value (hdr, MU_HEADER_FROM, from, sizeof (from), NULL); |
112 | mailbox_destroy(&mbox); | 108 | header_get_value (hdr, MU_HEADER_SUBJECT, subject, sizeof (subject), |
113 | return 0; | 109 | NULL); |
110 | printf ("From: %s\tSubject: %s\n", from, subject); | ||
111 | if ((ret = message_get_num_parts (msg, &nparts)) != 0) | ||
112 | { | ||
113 | fprintf (stderr, "message_get_num_parts - %s\n", strerror (ret)); | ||
114 | exit (2); | ||
115 | } | ||
116 | printf ("-- Number of parts in message - %d\n", nparts); | ||
117 | printf ("-- Total message size - %d\n", msize); | ||
118 | message_display_parts (msg, "\t"); | ||
119 | } | ||
120 | mailbox_close (mbox); | ||
121 | mailbox_destroy (&mbox); | ||
122 | return 0; | ||
114 | } | 123 | } |
115 | 124 | ||
116 | char buf[2048]; | 125 | char buf[2048]; |
117 | 126 | ||
118 | void | 127 | void |
119 | message_display_parts(message_t msg, char *indent) | 128 | message_display_parts (message_t msg, char *indent) |
120 | { | 129 | { |
121 | int ret, j; | 130 | int ret, j; |
122 | size_t msize, nparts, nsubparts; | 131 | size_t msize, nparts, nsubparts; |
123 | message_t part; | 132 | message_t part; |
124 | header_t hdr; | 133 | header_t hdr; |
125 | char type[256]; | 134 | char type[256]; |
126 | char encoding[256]; | 135 | char encoding[256]; |
127 | stream_t str; | 136 | stream_t str; |
128 | body_t body; | 137 | body_t body; |
129 | int offset, ismulti; | 138 | int offset, ismulti; |
130 | size_t nbytes; | 139 | size_t nbytes; |
131 | 140 | ||
132 | /* How many part those the message has? */ | 141 | /* How many part those the message has? */ |
133 | if ( ( ret = message_get_num_parts(msg, &nparts) ) != 0 ) { | 142 | if ((ret = message_get_num_parts (msg, &nparts)) != 0) |
134 | fprintf (stderr, "message_get_num_parts - %s\n", strerror(ret)); | 143 | { |
135 | exit(2); | 144 | fprintf (stderr, "message_get_num_parts - %s\n", strerror (ret)); |
145 | exit (2); | ||
146 | } | ||
147 | |||
148 | /* Iterate through all the parts. | ||
149 | Treat type "message/rfc822" differently, since it is a message of is own | ||
150 | that can have other subparts(recursive). */ | ||
151 | for (j = 1; j <= nparts; j++) | ||
152 | { | ||
153 | if ((ret = message_get_part (msg, j, &part)) != 0) | ||
154 | { | ||
155 | fprintf (stderr, "mime_get_part - %s\n", strerror (ret)); | ||
156 | exit (2); | ||
157 | } | ||
158 | if ((ret = message_size (part, &msize)) != 0) | ||
159 | { | ||
160 | fprintf (stderr, "message_size - %s\n", strerror (ret)); | ||
161 | exit (2); | ||
162 | } | ||
163 | if ((ret = message_get_header (part, &hdr)) != 0) | ||
164 | { | ||
165 | fprintf (stderr, "message_get_header - %s\n", strerror (ret)); | ||
166 | exit (2); | ||
136 | } | 167 | } |
168 | header_get_value (hdr, MU_HEADER_CONTENT_TYPE, type, sizeof (type), | ||
169 | NULL); | ||
170 | printf ("%sType of part %d = %s\n", indent, j, type); | ||
171 | printf ("%sMessage part size - %d\n", indent, msize); | ||
172 | encoding[0] = '\0'; | ||
173 | header_get_value (hdr, MU_HEADER_CONTENT_TRANSFER_ENCODING, encoding, | ||
174 | sizeof (encoding), NULL); | ||
175 | ismulti = 0; | ||
176 | if ((type[0] | ||
177 | && strncasecmp (type, "message/rfc822", strlen (type)) == 0) | ||
178 | || (message_is_multipart (part, &ismulti) == 0 && ismulti)) | ||
179 | { | ||
180 | char tmp[10]; | ||
137 | 181 | ||
138 | /* Iterate through all the parts. | 182 | if (!ismulti) |
139 | Treat type "message/rfc822" differently, since it is a message of is own | 183 | { |
140 | that can have other subparts(recursive). */ | 184 | ret = message_unencapsulate (part, &part, NULL); |
141 | for( j = 1; j <= nparts; j++) { | 185 | if (ret != 0) |
142 | if (( ret = message_get_part(msg, j, &part ) ) != 0 ) { | 186 | fprintf (stderr, "message_unencapsulate - %s\n", |
143 | fprintf (stderr, "mime_get_part - %s\n", strerror(ret)); | 187 | strerror (ret)); |
144 | exit(2); | 188 | break; |
145 | } | 189 | } |
146 | if (( ret = message_size (part, &msize) ) != 0) { | 190 | if ((ret = message_get_header (part, &hdr)) != 0) |
147 | fprintf (stderr, "message_size - %s\n", strerror(ret)); | 191 | { |
148 | exit(2); | 192 | fprintf (stderr, "message_get_header - %s\n", strerror (ret)); |
149 | } | 193 | exit (2); |
150 | if (( ret = message_get_header (part, &hdr) ) != 0) { | 194 | } |
151 | fprintf (stderr, "message_get_header - %s\n", strerror(ret)); | 195 | header_get_value (hdr, MU_HEADER_FROM, from, sizeof (from), NULL); |
152 | exit(2); | 196 | header_get_value (hdr, MU_HEADER_SUBJECT, subject, sizeof (subject), |
153 | } | 197 | NULL); |
154 | header_get_value (hdr, MU_HEADER_CONTENT_TYPE, type, sizeof (type), NULL); | 198 | printf ("%sEncapsulated message : %s\t%s\n", indent, from, subject); |
155 | printf("%sType of part %d = %s\n", indent, j, type); | 199 | printf |
156 | printf("%sMessage part size - %d\n",indent, msize); | 200 | ("%s-------------------------------------------------------------------\n", |
157 | encoding[0] = '\0'; | 201 | indent); |
158 | header_get_value (hdr, MU_HEADER_CONTENT_TRANSFER_ENCODING, encoding, sizeof (encoding), NULL); | 202 | if ((ret = message_get_num_parts (part, &nsubparts)) != 0) |
159 | ismulti = 0; | 203 | { |
160 | if ( (type[0] && strncasecmp( type, "message/rfc822", strlen(type)) == 0 ) || | 204 | fprintf (stderr, "mime_get_num_parts - %s\n", strerror (ret)); |
161 | ( message_is_multipart (part, &ismulti) == 0 && ismulti ) ) { | 205 | exit (2); |
162 | char tmp[10]; | 206 | } |
163 | 207 | strcpy (tmp, indent); | |
164 | if ( !ismulti ) { | 208 | strcat (tmp, "\t"); |
165 | ret = message_unencapsulate(part, &part, NULL); | 209 | message_display_parts (part, tmp); |
166 | if (ret != 0) | 210 | message_destroy (&part, NULL); |
167 | fprintf (stderr, "message_unencapsulate - %s\n", strerror(ret)); | 211 | } |
168 | break; | 212 | else if (type[0] == '\0' |
169 | } | 213 | || (strncasecmp (type, "text/plain", strlen ("text/plain")) == |
170 | if (( ret = message_get_header (part, &hdr) ) != 0) { | 214 | 0) |
171 | fprintf (stderr, "message_get_header - %s\n", strerror(ret)); | 215 | || (strncasecmp (type, "text/html", strlen ("text/html")) == |
172 | exit(2); | 216 | 0)) |
173 | } | 217 | { |
174 | header_get_value (hdr, MU_HEADER_FROM, from, sizeof (from), NULL); | 218 | printf ("%sText Message\n", indent); |
175 | header_get_value (hdr, MU_HEADER_SUBJECT, subject, sizeof (subject), NULL); | 219 | printf |
176 | printf("%sEncapsulated message : %s\t%s\n", indent, from, subject); | 220 | ("%s-------------------------------------------------------------------\n", |
177 | printf("%s-------------------------------------------------------------------\n", indent); | 221 | indent); |
178 | if ( ( ret = message_get_num_parts(part, &nsubparts) ) != 0 ) { | 222 | message_get_body (part, &body); |
179 | fprintf (stderr, "mime_get_num_parts - %s\n", strerror(ret)); | 223 | body_get_stream (body, &str); |
180 | exit(2); | 224 | filter_create (&str, str, encoding, 0, 0); |
181 | } | 225 | offset = 0; |
182 | strcpy(tmp, indent); | 226 | while (stream_readline (str, buf, sizeof (buf), offset, &nbytes) == |
183 | strcat(tmp,"\t"); | 227 | 0 && nbytes) |
184 | message_display_parts(part, tmp); | 228 | { |
185 | message_destroy (&part, NULL); | 229 | printf ("%s%s", indent, buf); |
186 | } | 230 | offset += nbytes; |
187 | else if ( type[0] == '\0' || (strncasecmp( type, "text/plain", strlen("text/plain")) == 0) || (strncasecmp( type, "text/html", strlen("text/html")) == 0)) { | 231 | } |
188 | printf("%sText Message\n",indent); | 232 | stream_destroy (&str, NULL); |
189 | printf("%s-------------------------------------------------------------------\n", indent); | 233 | } |
190 | message_get_body(part, &body); | 234 | else |
191 | body_get_stream(body, &str); | 235 | { |
192 | filter_create(&str, str, encoding, 0, 0); | ||
193 | offset = 0; | ||
194 | while( stream_readline( str, buf, sizeof(buf), offset, &nbytes ) == 0 && nbytes ) { | ||
195 | printf("%s%s", indent, buf); | ||
196 | offset += nbytes; | ||
197 | } | ||
198 | stream_destroy(&str, NULL); | ||
199 | } | ||
200 | else { | ||
201 | #if 1 | 236 | #if 1 |
202 | 237 | ||
203 | /* Save the attachements. */ | 238 | /* Save the attachements. */ |
204 | char *fname; | 239 | char *fname; |
205 | message_attachment_filename( part, &fname); | 240 | message_attachment_filename (part, &fname); |
206 | if ( fname == NULL ) { | 241 | if (fname == NULL) |
207 | char buffer[PATH_MAX+1]; | 242 | { |
208 | fname = tempnam(getcwd(buffer, PATH_MAX), "msg-" ); | 243 | char buffer[PATH_MAX + 1]; |
209 | } | 244 | fname = tempnam (getcwd (buffer, PATH_MAX), "msg-"); |
210 | printf("%sAttachment - saving [%s]\n",indent, fname); | 245 | } |
211 | printf("%s-------------------------------------------------------------------\n", indent); | 246 | printf ("%sAttachment - saving [%s]\n", indent, fname); |
212 | /* FIXME: Somethings is not quite correct with this function. | 247 | printf |
213 | Please fix. */ | 248 | ("%s-------------------------------------------------------------------\n", |
214 | message_save_attachment(part, fname, NULL); | 249 | indent); |
215 | free(fname); | 250 | /* FIXME: Somethings is not quite correct with this function. |
251 | Please fix. */ | ||
252 | message_save_attachment (part, fname, NULL); | ||
253 | free (fname); | ||
216 | #endif | 254 | #endif |
217 | } | ||
218 | printf("\n%s End -------------------------------------------------------------------\n", indent); | ||
219 | } | 255 | } |
256 | printf | ||
257 | ("\n%s End -------------------------------------------------------------------\n", | ||
258 | indent); | ||
259 | } | ||
220 | } | 260 | } |
261 | ... | ... |
... | @@ -48,112 +48,139 @@ | ... | @@ -48,112 +48,139 @@ |
48 | /* FIXME: this should be in a public header. */ | 48 | /* FIXME: this should be in a public header. */ |
49 | extern int message_attachment_filename __P ((message_t, const char **filename)); | 49 | extern int message_attachment_filename __P ((message_t, const char **filename)); |
50 | 50 | ||
51 | struct _msg_info { | 51 | struct _msg_info |
52 | char *buf; | 52 | { |
53 | size_t nbytes; | 53 | char *buf; |
54 | char *header_buf; | 54 | size_t nbytes; |
55 | int header_len; | 55 | char *header_buf; |
56 | int header_size; | 56 | int header_len; |
57 | header_t hdr; | 57 | int header_size; |
58 | message_t msg; | 58 | header_t hdr; |
59 | int ioffset; | 59 | message_t msg; |
60 | int ooffset; | 60 | int ioffset; |
61 | stream_t stream; /* output file/decoding stream for saving attachment */ | 61 | int ooffset; |
62 | stream_t fstream; /* output file stream for saving attachment */ | 62 | stream_t stream; /* output file/decoding stream for saving attachment */ |
63 | stream_t fstream; /* output file stream for saving attachment */ | ||
63 | }; | 64 | }; |
64 | 65 | ||
65 | #define MSG_HDR "Content-Type: %s; name=%s\nContent-Transfer-Encoding: %s\nContent-Disposition: attachment; filename=%s\n\n" | 66 | #define MSG_HDR "Content-Type: %s; name=%s\nContent-Transfer-Encoding: %s\nContent-Disposition: attachment; filename=%s\n\n" |
66 | 67 | ||
67 | int message_create_attachment(const char *content_type, const char *encoding, const char *filename, message_t *newmsg) | 68 | int |
69 | message_create_attachment (const char *content_type, const char *encoding, | ||
70 | const char *filename, message_t * newmsg) | ||
68 | { | 71 | { |
69 | header_t hdr; | 72 | header_t hdr; |
70 | body_t body; | 73 | body_t body; |
71 | stream_t fstream = NULL, tstream = NULL; | 74 | stream_t fstream = NULL, tstream = NULL; |
72 | char *header, *name = NULL, *fname = NULL; | 75 | char *header, *name = NULL, *fname = NULL; |
73 | int ret; | 76 | int ret; |
74 | 77 | ||
75 | if ( filename == NULL || newmsg == NULL ) | 78 | if (filename == NULL || newmsg == NULL) |
76 | return EINVAL; | 79 | return EINVAL; |
77 | 80 | ||
78 | if ( ( ret = message_create(newmsg, NULL) ) == 0 ) { | 81 | if ((ret = message_create (newmsg, NULL)) == 0) |
79 | if ( content_type == NULL ) | 82 | { |
80 | content_type = "text/plain"; | 83 | if (content_type == NULL) |
81 | if ( encoding == NULL ) | 84 | content_type = "text/plain"; |
82 | encoding = "7bit"; | 85 | if (encoding == NULL) |
83 | if ( ( fname = strdup(filename) ) != NULL ) { | 86 | encoding = "7bit"; |
84 | name = strrchr (fname, '/'); | 87 | if ((fname = strdup (filename)) != NULL) |
85 | if (name) | 88 | { |
86 | name++; | 89 | name = strrchr (fname, '/'); |
87 | else | 90 | if (name) |
88 | name = fname; | 91 | name++; |
89 | if ( ( header = alloca(strlen(MSG_HDR) + strlen(content_type) + strlen(name) * 2 + strlen(encoding) + 1) ) == NULL ) | 92 | else |
90 | ret = ENOMEM; | 93 | name = fname; |
91 | else { | 94 | if ((header = |
92 | sprintf(header, MSG_HDR, content_type, name, encoding, name); | 95 | alloca (strlen (MSG_HDR) + strlen (content_type) + |
93 | if ( ( ret = header_create( &hdr, header, strlen(header), *newmsg ) ) == 0 ) { | 96 | strlen (name) * 2 + strlen (encoding) + 1)) == NULL) |
94 | message_get_body(*newmsg, &body); | 97 | ret = ENOMEM; |
95 | if ( ( ret = file_stream_create(&fstream, filename, MU_STREAM_READ) ) == 0 ) { | 98 | else |
96 | if ( ( ret = stream_open(fstream) ) == 0 ) { | 99 | { |
97 | if ( ( ret = filter_create(&tstream, fstream, encoding, MU_FILTER_ENCODE, MU_STREAM_READ) ) == 0 ) { | 100 | sprintf (header, MSG_HDR, content_type, name, encoding, name); |
98 | body_set_stream(body, tstream, *newmsg); | 101 | if ((ret = |
99 | message_set_header(*newmsg, hdr, NULL); | 102 | header_create (&hdr, header, strlen (header), |
100 | } | 103 | *newmsg)) == 0) |
101 | } | 104 | { |
102 | } | 105 | message_get_body (*newmsg, &body); |
103 | } | 106 | if ((ret = |
107 | file_stream_create (&fstream, filename, | ||
108 | MU_STREAM_READ)) == 0) | ||
109 | { | ||
110 | if ((ret = stream_open (fstream)) == 0) | ||
111 | { | ||
112 | if ((ret = | ||
113 | filter_create (&tstream, fstream, encoding, | ||
114 | MU_FILTER_ENCODE, | ||
115 | MU_STREAM_READ)) == 0) | ||
116 | { | ||
117 | body_set_stream (body, tstream, *newmsg); | ||
118 | message_set_header (*newmsg, hdr, NULL); | ||
119 | } | ||
104 | } | 120 | } |
121 | } | ||
105 | } | 122 | } |
123 | } | ||
106 | } | 124 | } |
107 | if ( ret ) { | 125 | } |
108 | if ( *newmsg ) | 126 | if (ret) |
109 | message_destroy(newmsg, NULL); | 127 | { |
110 | if ( hdr ) | 128 | if (*newmsg) |
111 | header_destroy(&hdr, NULL); | 129 | message_destroy (newmsg, NULL); |
112 | if ( fstream ) | 130 | if (hdr) |
113 | stream_destroy(&fstream, NULL); | 131 | header_destroy (&hdr, NULL); |
114 | if ( fname ) | 132 | if (fstream) |
115 | free(fname); | 133 | stream_destroy (&fstream, NULL); |
116 | } | 134 | if (fname) |
117 | return ret; | 135 | free (fname); |
136 | } | ||
137 | return ret; | ||
118 | } | 138 | } |
119 | 139 | ||
120 | 140 | ||
121 | static int _attachment_setup(struct _msg_info **info, message_t msg, stream_t *stream, void **data) | 141 | static int |
142 | _attachment_setup (struct _msg_info **info, message_t msg, stream_t * stream, | ||
143 | void **data) | ||
122 | { | 144 | { |
123 | int sfl, ret; | 145 | int sfl, ret; |
124 | body_t body; | 146 | body_t body; |
125 | 147 | ||
126 | if ( ( ret = message_get_body(msg, &body) ) != 0 || | 148 | if ((ret = message_get_body (msg, &body)) != 0 || |
127 | ( ret = body_get_stream(body, stream) ) != 0 ) | 149 | (ret = body_get_stream (body, stream)) != 0) |
128 | return ret; | 150 | return ret; |
129 | stream_get_flags(*stream, &sfl); | 151 | stream_get_flags (*stream, &sfl); |
130 | if ( data == NULL && (sfl & MU_STREAM_NONBLOCK) ) | 152 | if (data == NULL && (sfl & MU_STREAM_NONBLOCK)) |
131 | return EINVAL; | 153 | return EINVAL; |
132 | if ( data ) | 154 | if (data) |
133 | *info = *data; | 155 | *info = *data; |
134 | if ( *info == NULL ) { | 156 | if (*info == NULL) |
135 | if ( ( *info = calloc(1, sizeof(struct _msg_info)) ) == NULL ) | 157 | { |
136 | return ENOMEM; | 158 | if ((*info = calloc (1, sizeof (struct _msg_info))) == NULL) |
137 | } | 159 | return ENOMEM; |
138 | if ( ( (*info)->buf = malloc(BUF_SIZE) ) == NULL ) { | 160 | } |
139 | free(*info); | 161 | if (((*info)->buf = malloc (BUF_SIZE)) == NULL) |
140 | return ENOMEM; | 162 | { |
141 | } | 163 | free (*info); |
142 | return 0; | 164 | return ENOMEM; |
165 | } | ||
166 | return 0; | ||
143 | } | 167 | } |
144 | 168 | ||
145 | static void _attachment_free(struct _msg_info *info, int free_message) { | 169 | static void |
146 | if ( info->buf ) | 170 | _attachment_free (struct _msg_info *info, int free_message) |
147 | free(info->buf); | 171 | { |
148 | if ( info->header_buf ) | 172 | if (info->buf) |
149 | free(info->header_buf); | 173 | free (info->buf); |
150 | if ( free_message ) { | 174 | if (info->header_buf) |
151 | if ( info->msg ) | 175 | free (info->header_buf); |
152 | message_destroy(&(info->msg), NULL); | 176 | if (free_message) |
153 | else if ( info->hdr ) | 177 | { |
154 | header_destroy(&(info->hdr), NULL); | 178 | if (info->msg) |
155 | } | 179 | message_destroy (&(info->msg), NULL); |
156 | free(info); | 180 | else if (info->hdr) |
181 | header_destroy (&(info->hdr), NULL); | ||
182 | } | ||
183 | free (info); | ||
157 | } | 184 | } |
158 | 185 | ||
159 | #define _ISSPECIAL(c) ( \ | 186 | #define _ISSPECIAL(c) ( \ |
... | @@ -162,221 +189,289 @@ static void _attachment_free(struct _msg_info *info, int free_message) { | ... | @@ -162,221 +189,289 @@ static void _attachment_free(struct _msg_info *info, int free_message) { |
162 | || ((c) == '\\') || ((c) == '.') || ((c) == '[') \ | 189 | || ((c) == '\\') || ((c) == '.') || ((c) == '[') \ |
163 | || ((c) == ']') ) | 190 | || ((c) == ']') ) |
164 | 191 | ||
165 | static char *_header_get_param(char *field_body, const char *param, size_t *len) | 192 | static char * |
193 | _header_get_param (char *field_body, const char *param, size_t * len) | ||
166 | { | 194 | { |
167 | char *str, *p, *v, *e; | 195 | char *str, *p, *v, *e; |
168 | int quoted = 0, was_quoted = 0; | 196 | int quoted = 0, was_quoted = 0; |
169 | 197 | ||
170 | if ( len == NULL || ( str = field_body ) == NULL ) | 198 | if (len == NULL || (str = field_body) == NULL) |
171 | return NULL; | 199 | return NULL; |
172 | 200 | ||
173 | p = strchr(str, ';' ); | 201 | p = strchr (str, ';'); |
174 | while ( p ) { | 202 | while (p) |
175 | p++; | 203 | { |
176 | while( isspace((unsigned)*p) ) /* walk upto start of param */ | 204 | p++; |
177 | p++; | 205 | while (isspace ((unsigned) *p)) /* walk upto start of param */ |
178 | if ( ( v = strchr(p, '=' ) ) == NULL ) | 206 | p++; |
179 | break; | 207 | if ((v = strchr (p, '=')) == NULL) |
180 | *len = 0; | 208 | break; |
181 | v = e = v + 1; | 209 | *len = 0; |
182 | while ( *e && (quoted || ( !_ISSPECIAL(*e) && !isspace((unsigned)*e) ) ) ) { /* skip pass value and calc len */ | 210 | v = e = v + 1; |
183 | if ( *e == '\"' ) | 211 | while (*e && (quoted || (!_ISSPECIAL (*e) && !isspace ((unsigned) *e)))) |
184 | quoted = ~quoted, was_quoted = 1; | 212 | { /* skip pass value and calc len */ |
185 | else | 213 | if (*e == '\"') |
186 | (*len)++; | 214 | quoted = ~quoted, was_quoted = 1; |
187 | e++; | 215 | else |
188 | } | 216 | (*len)++; |
189 | if ( strncasecmp(p, param, strlen(param)) ) { /* no match jump to next */ | 217 | e++; |
190 | p = strchr(e, ';' ); | 218 | } |
191 | continue; | 219 | if (strncasecmp (p, param, strlen (param))) |
192 | } | 220 | { /* no match jump to next */ |
193 | else | 221 | p = strchr (e, ';'); |
194 | return was_quoted ? v + 1 : v; /* return unquoted value */ | 222 | continue; |
195 | } | 223 | } |
196 | return NULL; | 224 | else |
225 | return was_quoted ? v + 1 : v; /* return unquoted value */ | ||
226 | } | ||
227 | return NULL; | ||
197 | } | 228 | } |
198 | 229 | ||
199 | int message_attachment_filename(message_t msg, const char **filename) | 230 | int |
231 | message_attachment_filename (message_t msg, const char **filename) | ||
200 | { | 232 | { |
201 | char *pTmp, *fname = NULL; | 233 | char *pTmp, *fname = NULL; |
202 | header_t hdr; | 234 | header_t hdr; |
203 | int ret = EINVAL; | 235 | int ret = EINVAL; |
204 | size_t size = 0; | 236 | size_t size = 0; |
205 | 237 | ||
206 | if ( filename != NULL && ( ret = message_get_header(msg, &hdr) ) == 0 ) { | 238 | if (filename != NULL && (ret = message_get_header (msg, &hdr)) == 0) |
207 | *filename = NULL; | 239 | { |
208 | header_get_value(hdr, "Content-Disposition", NULL, 0, &size); | 240 | *filename = NULL; |
209 | if ( size ) { | 241 | header_get_value (hdr, "Content-Disposition", NULL, 0, &size); |
210 | if ( ( pTmp = alloca(size+1) ) == NULL ) | 242 | if (size) |
211 | ret = ENOMEM; | 243 | { |
212 | header_get_value(hdr, "Content-Disposition", pTmp, size+1, 0); | 244 | if ((pTmp = alloca (size + 1)) == NULL) |
213 | if ( strstr( pTmp, "attachment" ) != NULL ) | 245 | ret = ENOMEM; |
214 | fname = _header_get_param(pTmp, "filename", &size); | 246 | header_get_value (hdr, "Content-Disposition", pTmp, size + 1, 0); |
215 | } | 247 | if (strstr (pTmp, "attachment") != NULL) |
216 | if ( fname == NULL ) { | 248 | fname = _header_get_param (pTmp, "filename", &size); |
217 | size = 0; | ||
218 | header_get_value(hdr, "Content-Type", NULL, 0, &size); | ||
219 | if ( size ) { | ||
220 | if ( ( pTmp = alloca(size+1) ) == NULL ) | ||
221 | ret = ENOMEM; | ||
222 | header_get_value(hdr, "Content-Type", pTmp, size+1, 0); | ||
223 | fname = _header_get_param(pTmp, "name", &size); | ||
224 | } | ||
225 | } | ||
226 | if ( fname ) { | ||
227 | fname[size] = '\0'; | ||
228 | if ( ( *filename = strdup(fname) ) == NULL ) | ||
229 | ret = ENOMEM; | ||
230 | } else | ||
231 | ret = ENOENT; | ||
232 | } | 249 | } |
233 | return ret; | 250 | if (fname == NULL) |
251 | { | ||
252 | size = 0; | ||
253 | header_get_value (hdr, "Content-Type", NULL, 0, &size); | ||
254 | if (size) | ||
255 | { | ||
256 | if ((pTmp = alloca (size + 1)) == NULL) | ||
257 | ret = ENOMEM; | ||
258 | header_get_value (hdr, "Content-Type", pTmp, size + 1, 0); | ||
259 | fname = _header_get_param (pTmp, "name", &size); | ||
260 | } | ||
261 | } | ||
262 | if (fname) | ||
263 | { | ||
264 | fname[size] = '\0'; | ||
265 | if ((*filename = strdup (fname)) == NULL) | ||
266 | ret = ENOMEM; | ||
267 | } | ||
268 | else | ||
269 | ret = ENOENT; | ||
270 | } | ||
271 | return ret; | ||
234 | } | 272 | } |
235 | 273 | ||
236 | int message_save_attachment(message_t msg, const char *filename, void **data) | 274 | int |
275 | message_save_attachment (message_t msg, const char *filename, void **data) | ||
237 | { | 276 | { |
238 | stream_t istream; | 277 | stream_t istream; |
239 | struct _msg_info *info = NULL; | 278 | struct _msg_info *info = NULL; |
240 | int ret; | 279 | int ret; |
241 | size_t size; | 280 | size_t size; |
242 | size_t nbytes; | 281 | size_t nbytes; |
243 | header_t hdr; | 282 | header_t hdr; |
244 | char *content_encoding; | 283 | char *content_encoding; |
245 | const char *fname = NULL; | 284 | const char *fname = NULL; |
246 | 285 | ||
247 | if ( msg == NULL || filename == NULL) | 286 | if (msg == NULL || filename == NULL) |
248 | return EINVAL; | 287 | return EINVAL; |
249 | 288 | ||
250 | if ( ( ret = _attachment_setup( &info, msg, &istream, data) ) != 0 ) | 289 | if ((ret = _attachment_setup (&info, msg, &istream, data)) != 0) |
251 | return ret; | 290 | return ret; |
252 | 291 | ||
253 | if ( ret == 0 && ( ret = message_get_header(msg, &hdr) ) == 0 ) { | 292 | if (ret == 0 && (ret = message_get_header (msg, &hdr)) == 0) |
254 | if ( filename == NULL ) | 293 | { |
255 | ret = message_attachment_filename(msg, &fname); | 294 | if (filename == NULL) |
256 | else | 295 | ret = message_attachment_filename (msg, &fname); |
257 | fname = filename; | 296 | else |
258 | if ( fname && ( ret = file_stream_create(&info->fstream, fname, MU_STREAM_WRITE|MU_STREAM_CREAT) ) == 0 ) { | 297 | fname = filename; |
259 | if ( ( ret = stream_open(info->fstream) ) == 0 ) { | 298 | if (fname |
260 | header_get_value(hdr, "Content-Transfer-Encoding", NULL, 0, &size); | 299 | && (ret = |
261 | if ( size ) { | 300 | file_stream_create (&info->fstream, fname, |
262 | if ( ( content_encoding = alloca(size+1) ) == NULL ) | 301 | MU_STREAM_WRITE | MU_STREAM_CREAT)) == 0) |
263 | ret = ENOMEM; | 302 | { |
264 | header_get_value(hdr, "Content-Transfer-Encoding", content_encoding, size+1, 0); | 303 | if ((ret = stream_open (info->fstream)) == 0) |
265 | } else | 304 | { |
266 | content_encoding = (char *)"7bit"; | 305 | header_get_value (hdr, "Content-Transfer-Encoding", NULL, 0, |
267 | ret = filter_create(&info->stream, istream, content_encoding, MU_FILTER_DECODE, MU_STREAM_READ); | 306 | &size); |
268 | } | 307 | if (size) |
269 | } | 308 | { |
270 | } | 309 | if ((content_encoding = alloca (size + 1)) == NULL) |
271 | if ( info->stream && istream ) { | 310 | ret = ENOMEM; |
272 | if ( info->nbytes ) | 311 | header_get_value (hdr, "Content-Transfer-Encoding", |
273 | memmove( info->buf, info->buf + (BUF_SIZE - info->nbytes), info->nbytes); | 312 | content_encoding, size + 1, 0); |
274 | while ( (ret == 0 && info->nbytes) || ( ( ret = stream_read(info->stream, info->buf, BUF_SIZE, info->ioffset, &info->nbytes) ) == 0 && info->nbytes ) ) { | ||
275 | info->ioffset += info->nbytes; | ||
276 | while( info->nbytes ) { | ||
277 | if ( ( ret = stream_write(info->fstream, info->buf, info->nbytes, info->ooffset, &nbytes ) ) != 0 ) | ||
278 | break; | ||
279 | info->nbytes -= nbytes; | ||
280 | info->ooffset += nbytes; | ||
281 | } | ||
282 | } | 313 | } |
314 | else | ||
315 | content_encoding = (char *) "7bit"; | ||
316 | ret = | ||
317 | filter_create (&info->stream, istream, content_encoding, | ||
318 | MU_FILTER_DECODE, MU_STREAM_READ); | ||
319 | } | ||
283 | } | 320 | } |
284 | if ( ret != EAGAIN && info ) { | 321 | } |
285 | stream_close(info->fstream); | 322 | if (info->stream && istream) |
286 | stream_destroy(&info->stream, NULL); | 323 | { |
287 | stream_destroy(&info->fstream, NULL); | 324 | if (info->nbytes) |
288 | _attachment_free(info, ret); | 325 | memmove (info->buf, info->buf + (BUF_SIZE - info->nbytes), |
326 | info->nbytes); | ||
327 | while ((ret == 0 && info->nbytes) | ||
328 | || | ||
329 | ((ret = | ||
330 | stream_read (info->stream, info->buf, BUF_SIZE, info->ioffset, | ||
331 | &info->nbytes)) == 0 && info->nbytes)) | ||
332 | { | ||
333 | info->ioffset += info->nbytes; | ||
334 | while (info->nbytes) | ||
335 | { | ||
336 | if ((ret = | ||
337 | stream_write (info->fstream, info->buf, info->nbytes, | ||
338 | info->ooffset, &nbytes)) != 0) | ||
339 | break; | ||
340 | info->nbytes -= nbytes; | ||
341 | info->ooffset += nbytes; | ||
342 | } | ||
289 | } | 343 | } |
290 | return ret; | 344 | } |
345 | if (ret != EAGAIN && info) | ||
346 | { | ||
347 | stream_close (info->fstream); | ||
348 | stream_destroy (&info->stream, NULL); | ||
349 | stream_destroy (&info->fstream, NULL); | ||
350 | _attachment_free (info, ret); | ||
351 | } | ||
352 | return ret; | ||
291 | } | 353 | } |
292 | 354 | ||
293 | int message_encapsulate(message_t msg, message_t *newmsg, void **data) | 355 | int |
356 | message_encapsulate (message_t msg, message_t * newmsg, void **data) | ||
294 | { | 357 | { |
295 | stream_t istream, ostream; | 358 | stream_t istream, ostream; |
296 | const char *header; | 359 | const char *header; |
297 | struct _msg_info *info = NULL; | 360 | struct _msg_info *info = NULL; |
298 | int ret = 0; | 361 | int ret = 0; |
299 | size_t nbytes; | 362 | size_t nbytes; |
300 | body_t body; | 363 | body_t body; |
301 | 364 | ||
302 | if ( msg == NULL || newmsg == NULL) | 365 | if (msg == NULL || newmsg == NULL) |
303 | return EINVAL; | 366 | return EINVAL; |
304 | 367 | ||
305 | if ( ( ret = _attachment_setup( &info, msg, &ostream, data) ) != 0 ) | 368 | if ((ret = _attachment_setup (&info, msg, &ostream, data)) != 0) |
306 | return ret; | 369 | return ret; |
307 | 370 | ||
308 | if ( info->msg == NULL && ( ret = message_create(&(info->msg), NULL) ) == 0 ) { | 371 | if (info->msg == NULL && (ret = message_create (&(info->msg), NULL)) == 0) |
309 | header = "Content-Type: message/rfc822\nContent-Transfer-Encoding: 7bit\n\n"; | 372 | { |
310 | if ( ( ret = header_create( &(info->hdr), header, strlen(header), msg ) ) == 0 ) | 373 | header = |
311 | ret = message_set_header(info->msg, info->hdr, NULL); | 374 | "Content-Type: message/rfc822\nContent-Transfer-Encoding: 7bit\n\n"; |
312 | } | 375 | if ((ret = |
313 | if ( ret == 0 && ( ret = message_get_stream(msg, &istream ) ) == 0 ) { | 376 | header_create (&(info->hdr), header, strlen (header), msg)) == 0) |
314 | if ( ( ret = message_get_body(info->msg, &body) ) == 0 && | 377 | ret = message_set_header (info->msg, info->hdr, NULL); |
315 | ( ret = body_get_stream(body, &ostream) ) == 0 ) { | 378 | } |
316 | if ( info->nbytes ) | 379 | if (ret == 0 && (ret = message_get_stream (msg, &istream)) == 0) |
317 | memmove( info->buf, info->buf + (BUF_SIZE - info->nbytes), info->nbytes); | 380 | { |
318 | while ( (ret == 0 && info->nbytes) || ( ( ret = stream_read(istream, info->buf, BUF_SIZE, info->ioffset, &info->nbytes) ) == 0 && info->nbytes ) ) { | 381 | if ((ret = message_get_body (info->msg, &body)) == 0 && |
319 | info->ioffset += info->nbytes; | 382 | (ret = body_get_stream (body, &ostream)) == 0) |
320 | while( info->nbytes ) { | 383 | { |
321 | if ( ( ret = stream_write(ostream, info->buf, info->nbytes, info->ooffset, &nbytes ) ) != 0 ) | 384 | if (info->nbytes) |
322 | break; | 385 | memmove (info->buf, info->buf + (BUF_SIZE - info->nbytes), |
323 | info->nbytes -= nbytes; | 386 | info->nbytes); |
324 | info->ooffset += nbytes; | 387 | while ((ret == 0 && info->nbytes) |
325 | } | 388 | || |
326 | } | 389 | ((ret = |
390 | stream_read (istream, info->buf, BUF_SIZE, info->ioffset, | ||
391 | &info->nbytes)) == 0 && info->nbytes)) | ||
392 | { | ||
393 | info->ioffset += info->nbytes; | ||
394 | while (info->nbytes) | ||
395 | { | ||
396 | if ((ret = | ||
397 | stream_write (ostream, info->buf, info->nbytes, | ||
398 | info->ooffset, &nbytes)) != 0) | ||
399 | break; | ||
400 | info->nbytes -= nbytes; | ||
401 | info->ooffset += nbytes; | ||
327 | } | 402 | } |
403 | } | ||
328 | } | 404 | } |
329 | if ( ret == 0 ) | 405 | } |
330 | *newmsg = info->msg; | 406 | if (ret == 0) |
331 | if ( ret != EAGAIN && info ) | 407 | *newmsg = info->msg; |
332 | _attachment_free(info, ret); | 408 | if (ret != EAGAIN && info) |
333 | return ret; | 409 | _attachment_free (info, ret); |
410 | return ret; | ||
334 | } | 411 | } |
335 | 412 | ||
336 | int message_unencapsulate(message_t msg, message_t *newmsg, void **data) | 413 | int |
414 | message_unencapsulate (message_t msg, message_t * newmsg, void **data) | ||
337 | { | 415 | { |
338 | size_t size, nbytes; | 416 | size_t size, nbytes; |
339 | int ret = 0; | 417 | int ret = 0; |
340 | char *content_type; | 418 | char *content_type; |
341 | header_t hdr; | 419 | header_t hdr; |
342 | stream_t istream, ostream; | 420 | stream_t istream, ostream; |
343 | struct _msg_info *info = NULL; | 421 | struct _msg_info *info = NULL; |
344 | 422 | ||
345 | if ( msg == NULL || newmsg == NULL) | 423 | if (msg == NULL || newmsg == NULL) |
346 | return EINVAL; | 424 | return EINVAL; |
347 | 425 | ||
348 | if ( (data == NULL || *data == NULL ) && ( ret = message_get_header(msg, &hdr) ) == 0 ) { | 426 | if ((data == NULL || *data == NULL) |
349 | header_get_value(hdr, "Content-Type", NULL, 0, &size); | 427 | && (ret = message_get_header (msg, &hdr)) == 0) |
350 | if ( size ) { | 428 | { |
351 | if ( ( content_type = alloca(size+1) ) == NULL ) | 429 | header_get_value (hdr, "Content-Type", NULL, 0, &size); |
352 | return ENOMEM; | 430 | if (size) |
353 | header_get_value(hdr, "Content-Type", content_type, size+1, 0); | 431 | { |
354 | if ( strncasecmp(content_type, "message/rfc822", strlen("message/rfc822")) != 0 ) | 432 | if ((content_type = alloca (size + 1)) == NULL) |
355 | return EINVAL; | 433 | return ENOMEM; |
356 | } else | 434 | header_get_value (hdr, "Content-Type", content_type, size + 1, 0); |
357 | return EINVAL; | 435 | if (strncasecmp |
436 | (content_type, "message/rfc822", | ||
437 | strlen ("message/rfc822")) != 0) | ||
438 | return EINVAL; | ||
358 | } | 439 | } |
359 | if ( ( ret = _attachment_setup( &info, msg, &istream, data) ) != 0 ) | 440 | else |
360 | return ret; | 441 | return EINVAL; |
361 | if ( info->msg == NULL ) | 442 | } |
362 | ret = message_create(&(info->msg), NULL); | 443 | if ((ret = _attachment_setup (&info, msg, &istream, data)) != 0) |
363 | if ( ret == 0 ) { | 444 | return ret; |
364 | message_get_stream(info->msg, &ostream); | 445 | if (info->msg == NULL) |
365 | if ( info->nbytes ) | 446 | ret = message_create (&(info->msg), NULL); |
366 | memmove( info->buf, info->buf + (BUF_SIZE - info->nbytes), info->nbytes); | 447 | if (ret == 0) |
367 | while ( (ret == 0 && info->nbytes) || ( ( ret = stream_read(istream, info->buf, BUF_SIZE, info->ioffset, &info->nbytes) ) == 0 && info->nbytes ) ) { | 448 | { |
368 | info->ioffset += info->nbytes; | 449 | message_get_stream (info->msg, &ostream); |
369 | while( info->nbytes ) { | 450 | if (info->nbytes) |
370 | if ( ( ret = stream_write(ostream, info->buf, info->nbytes, info->ooffset, &nbytes ) ) != 0 ) | 451 | memmove (info->buf, info->buf + (BUF_SIZE - info->nbytes), |
371 | break; | 452 | info->nbytes); |
372 | info->nbytes -= nbytes; | 453 | while ((ret == 0 && info->nbytes) |
373 | info->ooffset += nbytes; | 454 | || |
374 | } | 455 | ((ret = |
375 | } | 456 | stream_read (istream, info->buf, BUF_SIZE, info->ioffset, |
457 | &info->nbytes)) == 0 && info->nbytes)) | ||
458 | { | ||
459 | info->ioffset += info->nbytes; | ||
460 | while (info->nbytes) | ||
461 | { | ||
462 | if ((ret = | ||
463 | stream_write (ostream, info->buf, info->nbytes, | ||
464 | info->ooffset, &nbytes)) != 0) | ||
465 | break; | ||
466 | info->nbytes -= nbytes; | ||
467 | info->ooffset += nbytes; | ||
468 | } | ||
376 | } | 469 | } |
377 | if ( ret == 0 ) | 470 | } |
378 | *newmsg = info->msg; | 471 | if (ret == 0) |
379 | if ( ret != EAGAIN && info ) | 472 | *newmsg = info->msg; |
380 | _attachment_free(info, ret); | 473 | if (ret != EAGAIN && info) |
381 | return ret; | 474 | _attachment_free (info, ret); |
475 | return ret; | ||
382 | } | 476 | } |
477 | ... | ... |
-
Please register or sign in to post a comment