2 * Copyright (c) 2017, De Rais <derais@cock.li>
4 * Permission to use, copy, modify, and/or distribute this software for
5 * any purpose with or without fee is hereby granted, provided that the
6 * above copyright notice and this permission notice appear in all
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16 * PERFORMANCE OF THIS SOFTWARE.
23 #include <gmime/gmime.h>
28 /* User data for callback */
29 struct gmime_cb_data
{
35 /* Initialize GMime */
36 int setup_multipart(void)
43 /* Callback to add things - get stuff out of mime so we can strcmp() it */
44 static void record_argument(GMimeObject
*parent
, GMimeObject
*part
, gpointer
48 struct gmime_cb_data
*d
= (struct gmime_cb_data
*) user_data
;
50 if (!(GMIME_IS_PART(part
))) {
54 if (GMIME_IS_MESSAGE_PART(part
)) {
55 GMimeMessage
*m
= g_mime_message_part_get_message(
56 (GMimeMessagePart
*) part
);
58 g_mime_message_foreach(m
, record_argument
, user_data
);
61 GMimePart
*p
= (GMimePart
*) part
;
62 const char *name
= g_mime_object_get_content_disposition_parameter(part
,
70 size_t *set_this_len
= 0;
72 if (!strcmp(name
, "action")) {
73 set_this
= &d
->pc
.raw
.action
;
74 set_this_len
= &d
->pc
.raw
.action_len
;
75 } else if (!strcmp(name
, "board")) {
76 set_this
= &d
->pc
.raw
.board
;
77 set_this_len
= &d
->pc
.raw
.board_len
;
78 } else if (!strcmp(name
, "thread")) {
79 set_this
= &d
->pc
.raw
.thread
;
80 set_this_len
= &d
->pc
.raw
.thread_len
;
81 } else if (!strcmp(name
, "post")) {
82 set_this
= &d
->pc
.raw
.post
;
83 set_this_len
= &d
->pc
.raw
.post_len
;
84 } else if (!strcmp(name
, "name")) {
85 set_this
= &d
->pc
.raw
.name
;
86 set_this_len
= &d
->pc
.raw
.name_len
;
87 } else if (!strcmp(name
, "email")) {
88 set_this
= &d
->pc
.raw
.email
;
89 set_this_len
= &d
->pc
.raw
.email_len
;
90 } else if (!strcmp(name
, "subject")) {
91 set_this
= &d
->pc
.raw
.subject
;
92 set_this_len
= &d
->pc
.raw
.subject_len
;
93 } else if (!strcmp(name
, "comment")) {
94 set_this
= &d
->pc
.raw
.comment
;
95 set_this_len
= &d
->pc
.raw
.comment_len
;
96 } else if (!strcmp(name
, "comment")) {
97 set_this
= &d
->pc
.raw
.comment
;
98 set_this_len
= &d
->pc
.raw
.comment_len
;
99 } else if (!strcmp(name
, "challengeid")) {
100 set_this
= &d
->pc
.raw
.challenge_id
;
101 set_this_len
= &d
->pc
.raw
.challenge_id_len
;
102 } else if (!strcmp(name
, "challengeresponse")) {
103 set_this
= &d
->pc
.raw
.challenge_response
;
104 set_this_len
= &d
->pc
.raw
.challenge_response_len
;
105 } else if (!strcmp(name
, "file")) {
106 set_this
= &d
->pc
.raw
.file_contents
;
107 set_this_len
= &d
->pc
.raw
.file_contents_len
;
108 free(d
->pc
.raw
.file_name
);
109 d
->pc
.raw
.file_name
= 0;
110 d
->pc
.raw
.file_name_len
= 0;
111 const char *file_name
= g_mime_part_get_filename(p
);
114 file_name
= "[No filename provided]";
117 if (!(d
->pc
.raw
.file_name
= strdup(file_name
))) {
118 ERROR_MESSAGE("strdup");
124 d
->pc
.raw
.file_name_len
= strlen(d
->pc
.raw
.file_name
);
131 GMimeDataWrapper
*w
= 0;
136 if (!(w
= g_mime_part_get_content_object(p
))) {
142 if (!(s
= g_mime_data_wrapper_get_stream(w
))) {
148 l
= g_mime_stream_length(s
);
150 if (!(buf
= malloc(l
+ 1))) {
151 PERROR_MESSAGE("malloc");
157 g_mime_stream_read(s
, buf
, l
);
163 /* Don't g_object_unref here. I think. */
167 * This is segmented off because, one day, I want to go full NIH.
168 * No pre/postconditions until then.
170 int multipart_decompose(const char *full_data
, size_t full_data_len
, struct
178 struct gmime_cb_data d
= { 0 };
180 memcpy(&d
, post_cmd
, sizeof *post_cmd
);
182 if (!(s
= g_mime_stream_mem_new_with_buffer(full_data
,
184 ERROR_MESSAGE("Some kind of GMime error");
188 if (!(p
= g_mime_parser_new_with_stream(s
))) {
189 ERROR_MESSAGE("Some kind of GMime error");
193 if (!(m
= g_mime_parser_construct_message(p
))) {
194 ERROR_MESSAGE("Some kind of GMime error");
198 g_mime_message_foreach(m
, record_argument
, (gpointer
) & d
);
201 ERROR_MESSAGE("Some kind of GMime error");
205 memcpy(post_cmd
, &d
.pc
, sizeof *post_cmd
);
224 /* Tear down GMime */
225 int clean_multipart(void)