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);