Mercurial > masqmail
comparison src/spool.c @ 82:83a182793503
refactoring
author | meillo@marmaro.de |
---|---|
date | Sat, 19 Jun 2010 12:35:08 +0200 |
parents | 3b344bf57162 |
children | 46f407c0727a |
comparison
equal
deleted
inserted
replaced
81:71ce3a1568e9 | 82:83a182793503 |
---|---|
89 | 89 |
90 gboolean | 90 gboolean |
91 spool_read_data(message * msg) | 91 spool_read_data(message * msg) |
92 { | 92 { |
93 FILE *in; | 93 FILE *in; |
94 gboolean ok = FALSE; | |
95 gchar *spool_file; | 94 gchar *spool_file; |
96 | 95 |
97 DEBUG(5) debugf("spool_read_data entered\n"); | 96 DEBUG(5) debugf("spool_read_data entered\n"); |
98 spool_file = g_strdup_printf("%s/input/%s-D", conf.spool_dir, msg->uid); | 97 spool_file = g_strdup_printf("%s/input/%s-D", conf.spool_dir, msg->uid); |
99 DEBUG(5) debugf("reading data spool file '%s'\n", spool_file); | 98 DEBUG(5) debugf("reading data spool file '%s'\n", spool_file); |
100 if ((in = fopen(spool_file, "r"))) { | 99 in = fopen(spool_file, "r"); |
101 char buf[MAX_DATALINE]; | 100 if (!in) { |
102 int len; | |
103 | |
104 /* msg uid */ | |
105 read_line(in, buf, MAX_DATALINE); | |
106 | |
107 /* data */ | |
108 msg->data_list = NULL; | |
109 while ((len = read_line(in, buf, MAX_DATALINE)) > 0) { | |
110 msg->data_list = g_list_prepend(msg->data_list, g_strdup(buf)); | |
111 } | |
112 msg->data_list = g_list_reverse(msg->data_list); | |
113 fclose(in); | |
114 ok = TRUE; | |
115 } else | |
116 logwrite(LOG_ALERT, "could not open spool data file %s: %s\n", spool_file, strerror(errno)); | 101 logwrite(LOG_ALERT, "could not open spool data file %s: %s\n", spool_file, strerror(errno)); |
117 return ok; | 102 return FALSE; |
103 } | |
104 | |
105 char buf[MAX_DATALINE]; | |
106 int len; | |
107 | |
108 /* msg uid */ | |
109 read_line(in, buf, MAX_DATALINE); | |
110 | |
111 /* data */ | |
112 msg->data_list = NULL; | |
113 while ((len = read_line(in, buf, MAX_DATALINE)) > 0) { | |
114 msg->data_list = g_list_prepend(msg->data_list, g_strdup(buf)); | |
115 } | |
116 msg->data_list = g_list_reverse(msg->data_list); | |
117 fclose(in); | |
118 return TRUE; | |
118 } | 119 } |
119 | 120 |
120 gboolean | 121 gboolean |
121 spool_read_header(message * msg) | 122 spool_read_header(message * msg) |
122 { | 123 { |
123 FILE *in; | 124 FILE *in; |
124 gboolean ok = FALSE; | |
125 gchar *spool_file; | 125 gchar *spool_file; |
126 | 126 |
127 /* header spool: */ | 127 /* header spool: */ |
128 spool_file = g_strdup_printf("%s/input/%s-H", conf.spool_dir, msg->uid); | 128 spool_file = g_strdup_printf("%s/input/%s-H", conf.spool_dir, msg->uid); |
129 if ((in = fopen(spool_file, "r"))) { | 129 in = fopen(spool_file, "r"); |
130 header *hdr = NULL; | 130 if (!in) { |
131 char buf[MAX_DATALINE]; | 131 logwrite(LOG_ALERT, "could not open spool header file %s: %s\n", |
132 int len; | 132 spool_file, strerror(errno)); |
133 | 133 return FALSE; |
134 /* msg uid */ | 134 } |
135 read_line(in, buf, MAX_DATALINE); | 135 |
136 | 136 header *hdr = NULL; |
137 /* envelope header */ | 137 char buf[MAX_DATALINE]; |
138 while ((len = read_line(in, buf, MAX_DATALINE)) > 0) { | 138 int len; |
139 if (buf[0] == '\n') | 139 |
140 break; | 140 /* msg uid */ |
141 else if (strncasecmp(buf, "MF:", 3) == 0) { | 141 read_line(in, buf, MAX_DATALINE); |
142 msg->return_path = create_address(&(buf[3]), TRUE); | 142 |
143 DEBUG(3) debugf("spool_read: MAIL FROM: %s", msg->return_path->address); | 143 /* envelope header */ |
144 } else if (strncasecmp(buf, "RT:", 3) == 0) { | 144 while ((len = read_line(in, buf, MAX_DATALINE)) > 0) { |
145 address *addr; | 145 if (buf[0] == '\n') { |
146 addr = spool_scan_rcpt(buf); | 146 break; |
147 if (!addr_is_delivered(addr) && !addr_is_failed(addr)) { | 147 } else if (strncasecmp(buf, "MF:", 3) == 0) { |
148 msg->rcpt_list = g_list_append(msg->rcpt_list, addr); | 148 msg->return_path = create_address(&(buf[3]), TRUE); |
149 } else { | 149 DEBUG(3) debugf("spool_read: MAIL FROM: %s", msg->return_path->address); |
150 msg->non_rcpt_list = g_list_append(msg->non_rcpt_list, addr); | 150 } else if (strncasecmp(buf, "RT:", 3) == 0) { |
151 address *addr; | |
152 addr = spool_scan_rcpt(buf); | |
153 if (!addr_is_delivered(addr) && !addr_is_failed(addr)) { | |
154 msg->rcpt_list = g_list_append(msg->rcpt_list, addr); | |
155 } else { | |
156 msg->non_rcpt_list = g_list_append(msg->non_rcpt_list, addr); | |
157 } | |
158 } else if (strncasecmp(buf, "PR:", 3) == 0) { | |
159 prot_id i; | |
160 for (i = 0; i < PROT_NUM; i++) { | |
161 if (strncasecmp(prot_names[i], &(buf[3]), strlen(prot_names[i])) == 0) { | |
162 break; | |
151 } | 163 } |
152 } else if (strncasecmp(buf, "PR:", 3) == 0) { | |
153 prot_id i; | |
154 for (i = 0; i < PROT_NUM; i++) { | |
155 if (strncasecmp(prot_names[i], &(buf[3]), strlen(prot_names[i])) == 0) { | |
156 break; | |
157 } | |
158 } | |
159 msg->received_prot = i; | |
160 } else if (strncasecmp(buf, "RH:", 3) == 0) { | |
161 g_strchomp(buf); | |
162 msg->received_host = g_strdup(&(buf[3])); | |
163 } else if (strncasecmp(buf, "ID:", 3) == 0) { | |
164 g_strchomp(buf); | |
165 msg->ident = g_strdup(&(buf[3])); | |
166 } else if (strncasecmp(buf, "DS:", 3) == 0) { | |
167 msg->data_size = atoi(&(buf[3])); | |
168 } else if (strncasecmp(buf, "TR:", 3) == 0) { | |
169 msg->received_time = (time_t) (atoi(&(buf[3]))); | |
170 } else if (strncasecmp(buf, "TW:", 3) == 0) { | |
171 msg->warned_time = (time_t) (atoi(&(buf[3]))); | |
172 } | 164 } |
173 /* so far ignore other tags */ | 165 msg->received_prot = i; |
174 } | 166 } else if (strncasecmp(buf, "RH:", 3) == 0) { |
175 | 167 g_strchomp(buf); |
176 /* mail headers */ | 168 msg->received_host = g_strdup(&(buf[3])); |
177 while ((len = read_line(in, buf, MAX_DATALINE)) > 0) { | 169 } else if (strncasecmp(buf, "ID:", 3) == 0) { |
178 if (strncasecmp(buf, "HD:", 3) == 0) { | 170 g_strchomp(buf); |
179 hdr = get_header(&(buf[3])); | 171 msg->ident = g_strdup(&(buf[3])); |
180 msg->hdr_list = g_list_append(msg->hdr_list, hdr); | 172 } else if (strncasecmp(buf, "DS:", 3) == 0) { |
181 } else if ((buf[0] == ' ' || buf[0] == '\t') && hdr) { | 173 msg->data_size = atoi(&(buf[3])); |
182 char *tmp = hdr->header; | 174 } else if (strncasecmp(buf, "TR:", 3) == 0) { |
183 /* header continuation */ | 175 msg->received_time = (time_t) (atoi(&(buf[3]))); |
184 hdr->header = g_strconcat(hdr->header, buf, NULL); | 176 } else if (strncasecmp(buf, "TW:", 3) == 0) { |
185 hdr->value = hdr->header + (hdr->value - tmp); | 177 msg->warned_time = (time_t) (atoi(&(buf[3]))); |
186 } else | 178 } |
187 break; | 179 /* so far ignore other tags */ |
188 } | 180 } |
189 fclose(in); | 181 |
190 ok = TRUE; | 182 /* mail headers */ |
191 } else | 183 while ((len = read_line(in, buf, MAX_DATALINE)) > 0) { |
192 logwrite(LOG_ALERT, "could not open spool header file %s: %s\n", spool_file, strerror(errno)); | 184 if (strncasecmp(buf, "HD:", 3) == 0) { |
193 return ok; | 185 hdr = get_header(&(buf[3])); |
186 msg->hdr_list = g_list_append(msg->hdr_list, hdr); | |
187 } else if ((buf[0] == ' ' || buf[0] == '\t') && hdr) { | |
188 char *tmp = hdr->header; | |
189 /* header continuation */ | |
190 hdr->header = g_strconcat(hdr->header, buf, NULL); | |
191 hdr->value = hdr->header + (hdr->value - tmp); | |
192 } else { | |
193 break; | |
194 } | |
195 } | |
196 fclose(in); | |
197 return TRUE; | |
194 } | 198 } |
195 | 199 |
196 message* | 200 message* |
197 msg_spool_read(gchar * uid, gboolean do_readdata) | 201 msg_spool_read(gchar * uid, gboolean do_readdata) |
198 { | 202 { |
306 } | 310 } |
307 | 311 |
308 /* header spool: */ | 312 /* header spool: */ |
309 ok = spool_write_header(msg); | 313 ok = spool_write_header(msg); |
310 | 314 |
311 if (ok) { | 315 if (ok && do_write_data) { |
312 | 316 /* data spool: */ |
313 if (do_write_data) { | 317 tmp_file = g_strdup_printf("%s/input/%d-D.tmp", conf.spool_dir, getpid()); |
314 /* data spool: */ | 318 DEBUG(4) debugf("tmp_file = %s\n", tmp_file); |
315 tmp_file = g_strdup_printf("%s/input/%d-D.tmp", conf.spool_dir, getpid()); | 319 |
316 DEBUG(4) debugf("tmp_file = %s\n", tmp_file); | 320 if ((out = fopen(tmp_file, "w"))) { |
317 | 321 fprintf(out, "%s\n", msg->uid); |
318 if ((out = fopen(tmp_file, "w"))) { | 322 for (list = g_list_first(msg->data_list); list != NULL; list = g_list_next(list)) { |
319 fprintf(out, "%s\n", msg->uid); | 323 fprintf(out, "%s", (gchar *) (list->data)); |
320 for (list = g_list_first(msg->data_list); list != NULL; list = g_list_next(list)) { | 324 } |
321 fprintf(out, "%s", (gchar *) (list->data)); | 325 |
326 /* possibly paranoid ;-) */ | |
327 if (fflush(out) == EOF) { | |
328 ok = FALSE; | |
329 } else if (fdatasync(fileno(out)) != 0) { | |
330 if (errno != EINVAL) { /* some fs do not support this.. I hope this also means that it is not necessary */ | |
331 ok = FALSE; | |
322 } | 332 } |
323 | |
324 /* possibly paranoid ;-) */ | |
325 if (fflush(out) == EOF) | |
326 ok = FALSE; | |
327 else if (fdatasync(fileno(out)) != 0) { | |
328 if (errno != EINVAL) /* some fs do not support this.. I hope this also means that it is not necessary */ | |
329 ok = FALSE; | |
330 } | |
331 fclose(out); | |
332 if (ok) { | |
333 spool_file = g_strdup_printf("%s/input/%s-D", conf.spool_dir, msg->uid); | |
334 DEBUG(4) debugf("spool_file = %s\n", spool_file); | |
335 ok = (rename(tmp_file, spool_file) != -1); | |
336 g_free(spool_file); | |
337 } | |
338 } else { | |
339 logwrite(LOG_ALERT, "could not open temporary data spool file: %s\n", strerror(errno)); | |
340 ok = FALSE; | |
341 } | 333 } |
342 g_free(tmp_file); | 334 fclose(out); |
343 } | 335 if (ok) { |
336 spool_file = g_strdup_printf("%s/input/%s-D", conf.spool_dir, msg->uid); | |
337 DEBUG(4) debugf("spool_file = %s\n", spool_file); | |
338 ok = (rename(tmp_file, spool_file) != -1); | |
339 g_free(spool_file); | |
340 } | |
341 } else { | |
342 logwrite(LOG_ALERT, "could not open temporary data spool file: %s\n", | |
343 strerror(errno)); | |
344 ok = FALSE; | |
345 } | |
346 g_free(tmp_file); | |
344 } | 347 } |
345 | 348 |
346 /* set uid and gid back */ | 349 /* set uid and gid back */ |
347 if (!conf.run_as_user) { | 350 if (!conf.run_as_user) { |
348 set_euidgid(saved_uid, saved_gid, NULL, NULL); | 351 set_euidgid(saved_uid, saved_gid, NULL, NULL); |
419 set_euidgid(conf.mail_uid, conf.mail_gid, &saved_uid, &saved_gid); | 422 set_euidgid(conf.mail_uid, conf.mail_gid, &saved_uid, &saved_gid); |
420 } | 423 } |
421 | 424 |
422 /* header spool: */ | 425 /* header spool: */ |
423 spool_file = g_strdup_printf("%s/input/%s-H", conf.spool_dir, msg->uid); | 426 spool_file = g_strdup_printf("%s/input/%s-H", conf.spool_dir, msg->uid); |
424 if (unlink(spool_file) != 0) | 427 if (unlink(spool_file) != 0) { |
425 logwrite(LOG_ALERT, "could not delete spool file %s: %s\n", spool_file, strerror(errno)); | 428 logwrite(LOG_ALERT, "could not delete spool file %s: %s\n", spool_file, strerror(errno)); |
429 } | |
426 g_free(spool_file); | 430 g_free(spool_file); |
427 | 431 |
428 /* data spool: */ | 432 /* data spool: */ |
429 spool_file = g_strdup_printf("%s/input/%s-D", conf.spool_dir, msg->uid); | 433 spool_file = g_strdup_printf("%s/input/%s-D", conf.spool_dir, msg->uid); |
430 if (unlink(spool_file) != 0) | 434 if (unlink(spool_file) != 0) { |
431 logwrite(LOG_ALERT, "could not delete spool file %s: %s\n", spool_file, strerror(errno)); | 435 logwrite(LOG_ALERT, "could not delete spool file %s: %s\n", spool_file, strerror(errno)); |
436 } | |
432 g_free(spool_file); | 437 g_free(spool_file); |
433 | 438 |
434 /* set uid and gid back */ | 439 /* set uid and gid back */ |
435 if (!conf.run_as_user) { | 440 if (!conf.run_as_user) { |
436 set_euidgid(saved_uid, saved_gid, NULL, NULL); | 441 set_euidgid(saved_uid, saved_gid, NULL, NULL); |