1 /* -*- C -*-
2 mboxgrep - scan mailbox for messages matching a regular expression
3 Copyright (C) 2000, 2001, 2002, 2003 Daniel Spiljar
4
5 Mboxgrep is free software; you can redistribute it and/or modify it
6 under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 Mboxgrep is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with mboxgrep; if not, write to the Free Software Foundation,
17 Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19 $Id: mh.c,v 1.15 2003/03/30 23:07:10 dspiljar Exp $ */
20
21 #include <stdio.h>
22 #include <string.h>
23
24 #ifdef HAVE_DIRENT_H
25 # include <dirent.h>
26 # define NAMLEN(dirent) strlen((dirent)->d_name)
27 #else
28 # define dirent direct
29 # define NAMLEN(dirent) (dirent)->d_namlen
30 # ifdef HAVE_SYS_NDIR_H
31 # include <sys/ndir.h>
32 # endif /* HAVE_SYS_NDIR_H */
33 # ifdef HAVE_SYS_DIR_H
34 # include <sys/dir.h>
35 # endif /* HAVE_SYS_DIR_H */
36 # ifdef HAVE_NDIR_H
37 # include <ndir.h>
38 # endif /* HAVE_NDIR_H */
39 #endif /* HAVE_DIRENT_H */
40
41 #include <sys/types.h>
42 #include <stdlib.h>
43 #include <errno.h>
44 #include <time.h>
45
46 #include "mboxgrep.h"
47 #include "misc.h"
48 #include "mh.h"
49 #include "wrap.h"
50
51 #ifdef HAVE_LIBDMALLOC
52 # include <dmalloc.h>
53 #endif /* HAVE_LIBDMALLOC */
54
55 extern option_t config;
56
mh_open(const char * path)57 DIR *mh_open (const char *path)
58 {
59 DIR *dp;
60
61 dp = opendir (path);
62 if (dp == NULL)
63 {
64 if (config.merr)
65 {
66 fprintf (stderr, "%s: %s: ", APPNAME, path);
67 perror (NULL);
68 }
69 errno = 0;
70 return NULL;
71 }
72 return dp;
73 } /* mh_open */
74
mh_close(DIR * dp)75 void mh_close (DIR *dp)
76 {
77 closedir (dp);
78 } /* mh_close */
79
mh_read_message(DIR * dp)80 message_t *mh_read_message (DIR *dp)
81 {
82 int isheaders = 1;
83 int have_from = 0, have_return_path = 0,
84 have_date = 0, have_sender = 0;
85 static int s;
86 message_t *message;
87 struct dirent *d_content;
88 char buffer[BUFSIZ], *filename;
89 FILE *fp;
90 extern char *boxname;
91
92 message = (message_t *) xmalloc (sizeof (message_t));
93
94 message->headers = NULL;
95 message->hbytes = 0;
96
97 message->body = NULL;
98 message->bbytes = 0;
99
100 message->from = NULL;
101
102 filename = NULL;
103
104 for(;;)
105 {
106 d_content = readdir(dp);
107 if (d_content == NULL) return NULL;
108 if (d_content->d_name[0] == '.')
109 continue;
110
111 filename = (char *) xrealloc
112 (filename, ((strlen (d_content->d_name)) +
113 (strlen (boxname)) + 2));
114
115 /* message->headers = (char *) xrealloc (message->headers, 0); */
116 /* message->hbytes = 0; */
117 /* message->body = (char *) xrealloc (message->body, 0); */
118 /* message->bbytes = 0; */
119
120 filename[0] = '\0';
121 sprintf (filename, "%s/%s", boxname, d_content->d_name);
122 fp = m_fopen (filename, "r");
123 isheaders = 1;
124 if (fp == NULL)
125 {
126 free (message->headers);
127 free (message->body);
128 message->hbytes = 0;
129 message->bbytes = 0;
130 continue;
131 }
132
133 fgets (buffer, BUFSIZ, fp);
134
135 /* if (config.format == NNML || config.format == NNMH) */
136 /* { */
137 /* if (0 != strncmp ("X-From-Line: ", buffer, 13)) */
138 /* { */
139 /* if (config.merr) */
140 /* fprintf (stderr, "%s: %s: Not a Gnus folder message\n", */
141 /* APPNAME, filename); */
142 /* fclose (fp); */
143 /* free (message->headers); */
144 /* free (message->body); */
145 /* message->hbytes = 0; */
146 /* message->bbytes = 0; */
147 /* continue; */
148 /* } */
149 /* } */
150
151 fseek (fp, 0, SEEK_SET);
152
153 while (fgets (buffer, BUFSIZ, fp) != NULL)
154 {
155 s = strlen (buffer);
156 if (0 == strncmp ("\n", buffer, 1) && isheaders == 1)
157 {
158 isheaders = 0;
159 continue;
160 } /* if */
161 if (isheaders)
162 {
163 if (0 == strncasecmp ("From: ", buffer, 6))
164 have_from = 1;
165 if (0 == strncasecmp ("Sender: ", buffer, 8))
166 have_sender = 1;
167 if (0 == strncasecmp ("Date: ", buffer, 6))
168 have_date = 1;
169 if (0 == strncasecmp ("Return-Path: ", buffer, 13))
170 {
171 have_return_path = 1;
172 message->from = parse_return_path (buffer);
173 }
174
175 message->headers =
176 (char *) realloc (message->headers,
177 ((1 + s + message->hbytes) * sizeof (char)));
178 strcpy (message->headers + message->hbytes, buffer);
179 message->hbytes += s;
180 } /* if */
181 else
182 {
183 message->body =
184 (char *) realloc (message->body,
185 ((1 + s + message->bbytes) * sizeof (char)));
186 strcpy (message->body + message->bbytes, buffer);
187 message->bbytes += s;
188 } /* else */
189 } /* while */
190
191 if ((!have_from && !have_sender)|| !have_date)
192 {
193 if (config.merr)
194 fprintf (stderr, "%s: %s: Not a RFC 2822 message\n",
195 APPNAME, filename);
196 fclose (fp);
197 free (message->headers);
198 message->headers = NULL;
199 free (message->body);
200 message->body = NULL;
201 message->hbytes = 0;
202 message->bbytes = 0;
203 continue;
204 }
205
206 else
207 {
208 message->filename = (char *) xstrdup (filename);
209 fclose (fp);
210 free (filename);
211
212 return message;
213 }
214 } /* for */
215 } /* mh_read_message */
216
mh_write_message(message_t * m,const char * path)217 void mh_write_message (message_t *m, const char *path)
218 {
219 struct dirent *dc;
220 int x, y = 0;
221 char s1[BUFSIZ];
222 DIR *d; FILE *f;
223
224 d = m_opendir (path);
225 rewinddir (d);
226
227 while ((dc = readdir (d)) != NULL)
228 {
229 x = strtol (dc->d_name, NULL, 10);
230 if (x > y)
231 y = x;
232 }
233 y++;
234 sprintf (s1, "%s/%i", path, y);
235
236 f = m_fopen (s1, "w");
237 fprintf (f, "%s\n%s", m->headers, m->body);
238 fclose (f);
239 }
240