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