Commit 543739df 543739df4672bf881d91d0fa8fe03a0b46039f75 by Alain Magloire

attribute.c

		I broke it ... sigh.

file_stream.c header.c locker.c mapfile_stream.c mbx_default.c mbx_pop.c
		code cleanup put some comments in there ;-)
1 parent 29eb4e30
...@@ -108,7 +108,7 @@ attribute_set_recent (attribute_t attr) ...@@ -108,7 +108,7 @@ attribute_set_recent (attribute_t attr)
108 return EINVAL; 108 return EINVAL;
109 if (attr == NULL) 109 if (attr == NULL)
110 { 110 {
111 attr->flag |= MU_ATTRIBUTE_RECENT; 111 attr->flag = 0;
112 return 0; 112 return 0;
113 } 113 }
114 return EACCES; 114 return EACCES;
...@@ -167,7 +167,7 @@ attribute_is_recent (attribute_t attr) ...@@ -167,7 +167,7 @@ attribute_is_recent (attribute_t attr)
167 { 167 {
168 if (attr == NULL) 168 if (attr == NULL)
169 return 0; 169 return 0;
170 return attr->flag & MU_ATTRIBUTE_RECENT; 170 return attr->flag == 0;
171 } 171 }
172 172
173 int 173 int
...@@ -229,7 +229,7 @@ attribute_unset_recent (attribute_t attr) ...@@ -229,7 +229,7 @@ attribute_unset_recent (attribute_t attr)
229 { 229 {
230 if (attr == NULL) 230 if (attr == NULL)
231 return 0; 231 return 0;
232 attr->flag &= ~MU_ATTRIBUTE_RECENT; 232 attr->flag |= MU_ATTRIBUTE_SEEN;
233 return 0; 233 return 0;
234 } 234 }
235 235
......
...@@ -39,7 +39,7 @@ _file_destroy (stream_t stream) ...@@ -39,7 +39,7 @@ _file_destroy (stream_t stream)
39 { 39 {
40 struct _file_stream *fs = stream->owner; 40 struct _file_stream *fs = stream->owner;
41 41
42 if (fs->file) 42 if (fs && fs->file)
43 fclose (fs->file); 43 fclose (fs->file);
44 free (fs); 44 free (fs);
45 } 45 }
...@@ -50,26 +50,30 @@ _file_read (stream_t stream, char *optr, size_t osize, ...@@ -50,26 +50,30 @@ _file_read (stream_t stream, char *optr, size_t osize,
50 { 50 {
51 struct _file_stream *fs = stream->owner; 51 struct _file_stream *fs = stream->owner;
52 size_t n; 52 size_t n;
53 int err = 0;
54
55 if (fs == NULL)
56 return EINVAL;
53 57
54 if (fs->offset != offset) 58 if (fs->offset != offset)
55 { 59 {
56 fseek (fs->file, offset, SEEK_SET); 60 if (fseek (fs->file, offset, SEEK_SET) != 0)
61 return errno;
57 fs->offset = offset; 62 fs->offset = offset;
58 } 63 }
59 64
60 n = fread (optr, sizeof(char), osize, fs->file); 65 n = fread (optr, sizeof(char), osize, fs->file);
61
62 if (n == 0) 66 if (n == 0)
63 { 67 {
64 if (ferror(fs->file)) 68 if (ferror(fs->file))
65 return errno; 69 err = errno;
66 } 70 }
67 else 71 else
68 fs->offset += n; 72 fs->offset += n;
69 73
70 if (nbytes) 74 if (nbytes)
71 *nbytes = n; 75 *nbytes = n;
72 return 0; 76 return err;
73 } 77 }
74 78
75 static int 79 static int
...@@ -80,9 +84,13 @@ _file_readline (stream_t stream, char *optr, size_t osize, ...@@ -80,9 +84,13 @@ _file_readline (stream_t stream, char *optr, size_t osize,
80 size_t n = 0; 84 size_t n = 0;
81 int err = 0; 85 int err = 0;
82 86
87 if (fs == NULL)
88 return EINVAL;
89
83 if (fs->offset != offset) 90 if (fs->offset != offset)
84 { 91 {
85 fseek (fs->file, offset, SEEK_SET); 92 if (fseek (fs->file, offset, SEEK_SET) != 0)
93 return errno;
86 fs->offset = offset; 94 fs->offset = offset;
87 } 95 }
88 96
...@@ -110,32 +118,39 @@ _file_write (stream_t stream, const char *iptr, size_t isize, ...@@ -110,32 +118,39 @@ _file_write (stream_t stream, const char *iptr, size_t isize,
110 { 118 {
111 struct _file_stream *fs = stream->owner; 119 struct _file_stream *fs = stream->owner;
112 size_t n; 120 size_t n;
121 int err;
122
123 if (fs == NULL)
124 return EINVAL;
113 125
114 if (fs->offset != offset) 126 if (fs->offset != offset)
115 { 127 {
116 fseek (fs->file, offset, SEEK_SET); 128 if (fseek (fs->file, offset, SEEK_SET) != 0)
129 return errno;
117 fs->offset = offset; 130 fs->offset = offset;
118 } 131 }
119 132
120 n = fwrite (iptr, sizeof(char), isize, fs->file); 133 n = fwrite (iptr, sizeof(char), isize, fs->file);
121 134 if (n == 0)
122 if (*nbytes == 0)
123 { 135 {
124 if (ferror (fs->file)) 136 if (ferror (fs->file))
125 return errno; 137 err = errno;
126 } 138 }
127 else 139 else
128 fs->offset += *nbytes; 140 fs->offset += *nbytes;
129 141
130 if (nbytes) 142 if (nbytes)
131 *nbytes = n; 143 *nbytes = n;
132 return 0; 144 return err;
133 } 145 }
134 146
135 static int 147 static int
136 _file_truncate (stream_t stream, off_t len) 148 _file_truncate (stream_t stream, off_t len)
137 { 149 {
138 struct _file_stream *fs = stream->owner; 150 struct _file_stream *fs = stream->owner;
151
152 if (fs == NULL)
153 return EINVAL;
139 if (ftruncate (fileno(fs->file), len) != 0) 154 if (ftruncate (fileno(fs->file), len) != 0)
140 return errno; 155 return errno;
141 return 0; 156 return 0;
...@@ -146,6 +161,9 @@ _file_size (stream_t stream, off_t *psize) ...@@ -146,6 +161,9 @@ _file_size (stream_t stream, off_t *psize)
146 { 161 {
147 struct _file_stream *fs = stream->owner; 162 struct _file_stream *fs = stream->owner;
148 struct stat stbuf; 163 struct stat stbuf;
164
165 if (fs == NULL)
166 return EINVAL;
149 fflush (fs->file); 167 fflush (fs->file);
150 if (fstat(fileno(fs->file), &stbuf) == -1) 168 if (fstat(fileno(fs->file), &stbuf) == -1)
151 return errno; 169 return errno;
...@@ -158,6 +176,9 @@ static int ...@@ -158,6 +176,9 @@ static int
158 _file_flush (stream_t stream) 176 _file_flush (stream_t stream)
159 { 177 {
160 struct _file_stream *fs = stream->owner; 178 struct _file_stream *fs = stream->owner;
179
180 if (fs == NULL)
181 return EINVAL;
161 return fflush (fs->file); 182 return fflush (fs->file);
162 } 183 }
163 184
...@@ -165,6 +186,9 @@ static int ...@@ -165,6 +186,9 @@ static int
165 _file_get_fd (stream_t stream, int *pfd) 186 _file_get_fd (stream_t stream, int *pfd)
166 { 187 {
167 struct _file_stream *fs = stream->owner; 188 struct _file_stream *fs = stream->owner;
189
190 if (fs == NULL)
191 return EINVAL;
168 if (pfd) 192 if (pfd)
169 *pfd = fileno (fs->file); 193 *pfd = fileno (fs->file);
170 return 0; 194 return 0;
...@@ -174,10 +198,17 @@ static int ...@@ -174,10 +198,17 @@ static int
174 _file_close (stream_t stream) 198 _file_close (stream_t stream)
175 { 199 {
176 struct _file_stream *fs = stream->owner; 200 struct _file_stream *fs = stream->owner;
201 int err = 0;
202
203 if (fs == NULL)
204 return EINVAL;
177 if (fs->file) 205 if (fs->file)
178 if (fclose (fs->file) != 0) 206 {
179 return errno; 207 if (fclose (fs->file) != 0)
180 return 0; 208 err = errno;
209 fs->file = NULL;
210 }
211 return err;
181 } 212 }
182 213
183 static int 214 static int
...@@ -188,8 +219,12 @@ _file_open (stream_t stream, const char *filename, int port, int flags) ...@@ -188,8 +219,12 @@ _file_open (stream_t stream, const char *filename, int port, int flags)
188 int fd; 219 int fd;
189 const char *mode; 220 const char *mode;
190 221
191 (void)port; /* shutup gcc */ 222 (void)port; /* Ignored. */
192 /* map the flags to the system equivalent */ 223
224 if (fs == NULL)
225 return EINVAL;
226
227 /* Map the flags to the system equivalent. */
193 if (flags & MU_STREAM_WRITE) 228 if (flags & MU_STREAM_WRITE)
194 flg = O_WRONLY; 229 flg = O_WRONLY;
195 else if (flags & MU_STREAM_RDWR) 230 else if (flags & MU_STREAM_RDWR)
...@@ -197,24 +232,23 @@ _file_open (stream_t stream, const char *filename, int port, int flags) ...@@ -197,24 +232,23 @@ _file_open (stream_t stream, const char *filename, int port, int flags)
197 else /* default */ 232 else /* default */
198 flg = O_RDONLY; 233 flg = O_RDONLY;
199 234
200 /* local folders should not block it is local disk ??? 235 /* Local folders should not block it is local disk ???
201 * We simply ignore the O_NONBLOCK flag 236 We simply ignore the O_NONBLOCK flag
202 * But take care of the APPEND. 237 But take care of the APPEND. */
203 */
204 if (flags & MU_STREAM_APPEND) 238 if (flags & MU_STREAM_APPEND)
205 flg |= O_APPEND; 239 flg |= O_APPEND;
206 240
207 /* handle CREAT with care, not to follow symlinks */ 241 /* Handle CREAT with care, not to follow symlinks. */
208 if (flags & MU_STREAM_CREAT) 242 if (flags & MU_STREAM_CREAT)
209 { 243 {
210 /* first see if the file already exists */ 244 /* First see if the file already exists. */
211 fd = open(filename, flg); 245 fd = open(filename, flg);
212 if (fd == -1) 246 if (fd == -1)
213 { 247 {
214 /* oops bail out */ 248 /* Oops bail out. */
215 if (errno != ENOENT) 249 if (errno != ENOENT)
216 return errno; 250 return errno;
217 /* Race condition here when creating the file ?? */ 251 /* Race condition here when creating the file ??. */
218 fd = open(filename, flg|O_CREAT|O_EXCL, 0600); 252 fd = open(filename, flg|O_CREAT|O_EXCL, 0600);
219 if (fd < 0) 253 if (fd < 0)
220 return errno; 254 return errno;
...@@ -227,23 +261,22 @@ _file_open (stream_t stream, const char *filename, int port, int flags) ...@@ -227,23 +261,22 @@ _file_open (stream_t stream, const char *filename, int port, int flags)
227 return errno; 261 return errno;
228 } 262 }
229 263
230 /* we have to make sure that We did not open 264 /* We have to make sure that We did not open
231 * a symlink. From Casper D. in bugtraq. 265 a symlink. From Casper D. in bugtraq. */
232 */
233 if ((flg & MU_STREAM_CREAT) || 266 if ((flg & MU_STREAM_CREAT) ||
234 (flg & MU_STREAM_RDWR) || 267 (flg & MU_STREAM_RDWR) ||
235 (flg & MU_STREAM_WRITE)) 268 (flg & MU_STREAM_WRITE))
236 { 269 {
237 struct stat fdbuf, filebuf; 270 struct stat fdbuf, filebuf;
238 271
239 /* the next two stats should never fail */ 272 /* The next two stats should never fail. */
240 if (fstat(fd, &fdbuf) == -1) 273 if (fstat(fd, &fdbuf) == -1)
241 return errno; 274 return errno;
242 if (lstat(filename, &filebuf) == -1) 275 if (lstat(filename, &filebuf) == -1)
243 return errno; 276 return errno;
244 277
245 /* Now check that: file and fd reference the same file, 278 /* Now check that: file and fd reference the same file,
246 file only has one link, file is plain file */ 279 file only has one link, file is plain file. */
247 if (fdbuf.st_dev != filebuf.st_dev || 280 if (fdbuf.st_dev != filebuf.st_dev ||
248 fdbuf.st_ino != filebuf.st_ino || 281 fdbuf.st_ino != filebuf.st_ino ||
249 fdbuf.st_nlink != 1 || 282 fdbuf.st_nlink != 1 ||
...@@ -253,14 +286,14 @@ _file_open (stream_t stream, const char *filename, int port, int flags) ...@@ -253,14 +286,14 @@ _file_open (stream_t stream, const char *filename, int port, int flags)
253 return EINVAL; 286 return EINVAL;
254 } 287 }
255 } 288 }
256 /* we use FILE * object */ 289 /* We use FILE * object. */
257 if (flags & MU_STREAM_APPEND) 290 if (flags & MU_STREAM_APPEND)
258 mode = "a"; 291 mode = "a";
259 else if (flags & MU_STREAM_RDWR) 292 else if (flags & MU_STREAM_RDWR)
260 mode = "r+b"; 293 mode = "r+b";
261 else if (flags & MU_STREAM_WRITE) 294 else if (flags & MU_STREAM_WRITE)
262 mode = "wb"; 295 mode = "wb";
263 else /* default readonly*/ 296 else /* Default readonly. */
264 mode = "rb"; 297 mode = "rb";
265 298
266 fs->file = fopen (filename, mode); 299 fs->file = fopen (filename, mode);
...@@ -271,6 +304,7 @@ _file_open (stream_t stream, const char *filename, int port, int flags) ...@@ -271,6 +304,7 @@ _file_open (stream_t stream, const char *filename, int port, int flags)
271 return ret; 304 return ret;
272 } 305 }
273 #if BUFSIZ <= 1024 306 #if BUFSIZ <= 1024
307 /* Give us some roo to breathe, for OS with two small stdio buffers. */
274 { 308 {
275 char *iobuffer; 309 char *iobuffer;
276 iobuffer = malloc (8192); 310 iobuffer = malloc (8192);
......
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
27 #include <stdio.h> 27 #include <stdio.h>
28 #include <errno.h> 28 #include <errno.h>
29 29
30 static int header_parse (header_t h, char *blurb, int len); 30 static int header_parse (header_t h, const char *blurb, int len);
31 static int header_read (stream_t is, char *buf, size_t buflen, 31 static int header_read (stream_t is, char *buf, size_t buflen,
32 off_t off, size_t *pnread); 32 off_t off, size_t *pnread);
33 static int header_write (stream_t os, const char *buf, size_t buflen, 33 static int header_write (stream_t os, const char *buf, size_t buflen,
...@@ -43,18 +43,18 @@ struct _hdr ...@@ -43,18 +43,18 @@ struct _hdr
43 43
44 struct _header 44 struct _header
45 { 45 {
46 /* Data */ 46 /* Owner. */
47 void *owner;
48 /* Data. */
47 char *blurb; 49 char *blurb;
48 size_t blurb_len; 50 size_t blurb_len;
49 size_t hdr_count; 51 size_t hdr_count;
50 struct _hdr *hdr; 52 struct _hdr *hdr;
51 53
52 /* streams */ 54 /* Streams. */
53 stream_t stream; 55 stream_t stream;
54 int (*_get_value) __P ((header_t, const char *, char *, size_t , size_t *)); 56 int (*_get_value) __P ((header_t, const char *, char *, size_t , size_t *));
55 57
56 /* owner ? */
57 void *owner;
58 }; 58 };
59 59
60 int 60 int
...@@ -66,7 +66,7 @@ header_create (header_t *ph, const char *blurb, size_t len, void *owner) ...@@ -66,7 +66,7 @@ header_create (header_t *ph, const char *blurb, size_t len, void *owner)
66 return ENOMEM; 66 return ENOMEM;
67 h->owner = owner; 67 h->owner = owner;
68 68
69 header_parse (h, (char *)blurb, len); 69 header_parse (h, blurb, len);
70 70
71 *ph = h; 71 *ph = h;
72 return 0; 72 return 0;
...@@ -79,10 +79,9 @@ header_destroy (header_t *ph, void *owner) ...@@ -79,10 +79,9 @@ header_destroy (header_t *ph, void *owner)
79 { 79 {
80 header_t h = *ph; 80 header_t h = *ph;
81 81
82 /* can we destroy ? */ 82 /* Can we destroy ?. */
83 if (h->owner == owner) 83 if (h->owner == owner)
84 { 84 {
85 /* io */
86 stream_destroy (&(h->stream), h); 85 stream_destroy (&(h->stream), h);
87 free (h->hdr); 86 free (h->hdr);
88 free (h->blurb); 87 free (h->blurb);
...@@ -92,25 +91,23 @@ header_destroy (header_t *ph, void *owner) ...@@ -92,25 +91,23 @@ header_destroy (header_t *ph, void *owner)
92 } 91 }
93 } 92 }
94 93
95 /* 94 /* Parsing is done in a rather simple fashion.
96 * Parsing is done in a rather simple fashion. 95 meaning we just consider an entry to be
97 * meaning we just consider an entry to be 96 a field-name an a field-value. So they
98 * a field-name an a field-value. So they 97 maybe duplicate of field-name like "Received"
99 * maybe duplicate of field-name like "Received" 98 they are just put in the array, see _get_value()
100 * they are just put in the array, see _get_value() 99 on how to handle the case.
101 * on how to handle the case. 100 in the case of error .i.e a bad header construct
102 * in the case of error .i.e a bad header construct 101 we do a full stop and return what we have so far. */
103 * we do a full stop and return what we have so far.
104 */
105 static int 102 static int
106 header_parse (header_t header, char *blurb, int len) 103 header_parse (header_t header, const char *blurb, int len)
107 { 104 {
108 char *header_end; 105 char *header_end;
109 char *header_start; 106 char *header_start;
110 char *header_start2; 107 char *header_start2;
111 struct _hdr *hdr; 108 struct _hdr *hdr;
112 109
113 /* nothing to parse */ 110 /* Nothing to parse. */
114 if (blurb == NULL || len == 0) 111 if (blurb == NULL || len == 0)
115 return 0; 112 return 0;
116 113
...@@ -120,22 +117,26 @@ header_parse (header_t header, char *blurb, int len) ...@@ -120,22 +117,26 @@ header_parse (header_t header, char *blurb, int len)
120 return ENOMEM; 117 return ENOMEM;
121 memcpy (header->blurb, blurb, header->blurb_len); 118 memcpy (header->blurb, blurb, header->blurb_len);
122 119
123 free (header->hdr); 120 if (header->hdr)
121 free (header->hdr);
124 header->hdr = NULL; 122 header->hdr = NULL;
125 header->hdr_count = 0; 123 header->hdr_count = 0;
124
125 /* Get a header, a header is :
126 field-name ':' ' ' field-value '\r' '\n'
127 [ (' ' | '\t') field-value '\r' '\n' ]
128 */
129 /* First loop goes throught the blurb */
126 for (header_start = header->blurb;; header_start = ++header_end) 130 for (header_start = header->blurb;; header_start = ++header_end)
127 { 131 {
128 char *fn, *fn_end, *fv, *fv_end; 132 char *fn, *fn_end, *fv, *fv_end;
129 /* get a header, a header is :
130 * field-name ':' ' ' field-value '\r' '\n'
131 * [ (' ' | '\t') field-value '\r' '\n' ]
132 */
133 133
134 if (header_start[0] == ' ' || 134 if (header_start[0] == ' ' ||
135 header_start[0] == '\t' || 135 header_start[0] == '\t' ||
136 header_start[0]== '\n') 136 header_start[0]== '\n')
137 break; 137 break;
138 138
139 /* Second loop extract one header field. */
139 for (header_start2 = header_start;;header_start2 = ++header_end) 140 for (header_start2 = header_start;;header_start2 = ++header_end)
140 { 141 {
141 header_end = memchr (header_start2, '\n', len); 142 header_end = memchr (header_start2, '\n', len);
...@@ -151,15 +152,17 @@ header_parse (header_t header, char *blurb, int len) ...@@ -151,15 +152,17 @@ header_parse (header_t header, char *blurb, int len)
151 } 152 }
152 if (header_end[1] != ' ' 153 if (header_end[1] != ' '
153 && header_end[1] != '\t') 154 && header_end[1] != '\t')
154 break; /* new header break the inner for */ 155 break; /* New header break the inner for. */
155 } 156 }
156 /* *header_end = ' '; smash LF ? NO */ 157 /* *header_end = ' '; smash LF ? NO */
157 } 158 }
158 159
159 if (header_end == NULL) 160 if (header_end == NULL)
160 break; /* bail out */ 161 break; /* Bail out. */
161 162
162 /* Treats unix "From " specially */ 163 /* Now save the header in the data structure. */
164
165 /* Treats unix "From " specially. */
163 if ((header_end - header_start >= 5) 166 if ((header_end - header_start >= 5)
164 && strncmp (header_start, "From ", 5) == 0) 167 && strncmp (header_start, "From ", 5) == 0)
165 { 168 {
...@@ -168,23 +171,23 @@ header_parse (header_t header, char *blurb, int len) ...@@ -168,23 +171,23 @@ header_parse (header_t header, char *blurb, int len)
168 fv = header_start + 5; 171 fv = header_start + 5;
169 fv_end = header_end; 172 fv_end = header_end;
170 } 173 }
171 else 174 else /* Break the header in key: value */
172 { 175 {
173 char *colon = memchr (header_start, ':', header_end - header_start); 176 char *colon = memchr (header_start, ':', header_end - header_start);
174 177
175 /* Houston we have a problem */ 178 /* Houston we have a problem. */
176 if (colon == NULL) 179 if (colon == NULL)
177 break; /* disregard the rest and bailout */ 180 break; /* Disregard the rest and bailout. */
178 181
179 fn = header_start; 182 fn = header_start;
180 fn_end = colon; 183 fn_end = colon;
181 /* skip leading spaces */ 184 /* Skip leading spaces. */
182 while (*(++colon) == ' '); 185 while (*(++colon) == ' ');
183 fv = colon; 186 fv = colon;
184 fv_end = header_end; 187 fv_end = header_end;
185 } 188 }
186 189
187 /* allocate a new slot for the field:value */ 190 /* Allocate a new slot for the field:value. */
188 hdr = realloc (header->hdr, (header->hdr_count + 1) * sizeof (*hdr)); 191 hdr = realloc (header->hdr, (header->hdr_count + 1) * sizeof (*hdr));
189 if (hdr == NULL) 192 if (hdr == NULL)
190 { 193 {
...@@ -216,42 +219,40 @@ header_set_value (header_t header, const char *fn, const char *fv, int replace) ...@@ -216,42 +219,40 @@ header_set_value (header_t header, const char *fn, const char *fv, int replace)
216 return EINVAL; 219 return EINVAL;
217 220
218 /* Easy approach: if replace, overwrite the field-{namve,value} 221 /* Easy approach: if replace, overwrite the field-{namve,value}
219 * and readjust the pointers by calling header_parse () 222 and readjust the pointers by calling header_parse ()
220 * this is wastefull and bad, we're just fragmenting the memory 223 this is wastefull, we're just fragmenting the memory
221 * it can be done better. But that may imply a rewite of the headers 224 it can be done better. But that may imply a rewite of the headers
222 * So for another day. 225 So for another day. */
223 */ 226 if (replace)
224 { 227 {
225 size_t name_len; 228 size_t name_len;
226 size_t i; 229 size_t i;
227 size_t fn_len; 230 size_t fn_len;
228 size_t fv_len; 231 size_t fv_len;
229 len = header->blurb_len; 232 len = header->blurb_len;
230 for (name_len = strlen (fn), i = 0; i < header->hdr_count; i++) 233 for (name_len = strlen (fn), i = 0; i < header->hdr_count; i++)
231 { 234 {
232 fn_len = header->hdr[i].fn_end - header->hdr[i].fn; 235 fn_len = header->hdr[i].fn_end - header->hdr[i].fn;
233 fv_len = header->hdr[i].fv_end - header->hdr[i].fv; 236 fv_len = header->hdr[i].fv_end - header->hdr[i].fv;
234 if (fn_len == name_len && 237 if (fn_len == name_len &&
235 strncasecmp (header->hdr[i].fn, fn, fn_len) == 0) 238 strncasecmp (header->hdr[i].fn, fn, fn_len) == 0)
236 { 239 {
237 if (replace) 240 blurb = header->blurb;
238 { 241 memmove (header->hdr[i].fn, header->hdr[i + 1].fn,
239 blurb = header->blurb; 242 header->hdr[header->hdr_count - 1].fv_end
240 memmove (header->hdr[i].fn, header->hdr[i + 1].fn, 243 - header->hdr[i + 1].fn + 1 + 1);
241 header->hdr[header->hdr_count - 1].fv_end 244 /* readjust the pointers if move */
242 - header->hdr[i + 1].fn + 1 + 1); 245 len -= fn_len + fv_len + 2;
243 /* readjust the pointers if move */ 246 i--;
244 len -= fn_len + fv_len + 2; 247 blurb = header->blurb;
245 i--; 248 header_parse (header, blurb, len);
246 blurb = header->blurb; 249 free (blurb);
247 header_parse (header, blurb, len); 250 }
248 free (blurb); 251 }
249 } 252 }
250 } 253
251 } 254 /* Replacing was taking care of above now just add to
252 } 255 the end the new header. Really not cute. */
253
254 /* and it's getting worse, we free/malloc at will */
255 len = strlen (fn) + strlen (fv) + 1 + 1 + 1 + 1; 256 len = strlen (fn) + strlen (fv) + 1 + 1 + 1 + 1;
256 blurb = calloc (header->blurb_len + len, 1); 257 blurb = calloc (header->blurb_len + len, 1);
257 if (blurb == NULL) 258 if (blurb == NULL)
...@@ -290,18 +291,16 @@ header_get_value (header_t header, const char *name, char *buffer, ...@@ -290,18 +291,16 @@ header_get_value (header_t header, const char *name, char *buffer,
290 if (header == NULL || name == NULL) 291 if (header == NULL || name == NULL)
291 return EINVAL; 292 return EINVAL;
292 293
293 /* we set the threshold to be 1 less for the null */ 294 /* We set the threshold to be 1 less for the null. */
294 threshold = --buflen; 295 threshold = --buflen;
295 296
296 /* 297 /* Caution: We may have more then one value for a field
297 * Caution: We may have more then one value for a field 298 name, for example a "Received" field-name is added by
298 * name, for example a "Received" field-name is added by 299 each passing MTA. The way that the parsing (_parse())
299 * each passing MTA. The way that the parsing (_parse()) 300 is done it's not take to account. So we just stuff in
300 * is done it's not take to account. So we just stuff in 301 the buffer all the field-values to a corresponding field-name.
301 * the buffer all the field-values to a corresponding field-name. 302 FIXME: Should we kosher the output ? meaning replace
302 * FIXME: Should we kosher the output ? meaning replace 303 occurences of " \t\r\n" for spaces ? for now we don't. */
303 * occurences of " \t\r\n" for spaces ? for now we don't.
304 */
305 for (name_len = strlen (name), i = 0; i < header->hdr_count; i++) 304 for (name_len = strlen (name), i = 0; i < header->hdr_count; i++)
306 { 305 {
307 fn_len = header->hdr[i].fn_end - header->hdr[i].fn; 306 fn_len = header->hdr[i].fn_end - header->hdr[i].fn;
...@@ -310,7 +309,7 @@ header_get_value (header_t header, const char *name, char *buffer, ...@@ -310,7 +309,7 @@ header_get_value (header_t header, const char *name, char *buffer,
310 { 309 {
311 fv_len = (header->hdr[i].fv_end - header->hdr[i].fv); 310 fv_len = (header->hdr[i].fv_end - header->hdr[i].fv);
312 total += fv_len; 311 total += fv_len;
313 /* can everything fit in the buffer */ 312 /* Can everything fit in the buffer. */
314 if (buffer && threshold > 0) 313 if (buffer && threshold > 0)
315 { 314 {
316 threshold -= fv_len; 315 threshold -= fv_len;
...@@ -330,16 +329,16 @@ header_get_value (header_t header, const char *name, char *buffer, ...@@ -330,16 +329,16 @@ header_get_value (header_t header, const char *name, char *buffer,
330 } 329 }
331 } 330 }
332 if (buffer) 331 if (buffer)
333 *buffer = '\0'; /* null terminated */ 332 *buffer = '\0'; /* Null terminated. */
334 if (pn) 333 if (pn)
335 *pn = total; 334 *pn = total;
336 if (total == 0) 335 if (total == 0)
337 { 336 {
338 int err = ENOENT; 337 int err = ENOENT;
339 /* check if they provided a hook */ 338 /* Check if they provided a hook. */
340 if (header->_get_value != NULL) 339 if (header->_get_value != NULL)
341 err = header->_get_value (header, name, buffer, buflen, pn); 340 err = header->_get_value (header, name, buffer, buflen, pn);
342 /* cache it locally */ 341 /* Cache it locally. */
343 if (err == 0) 342 if (err == 0)
344 header_set_value (header, name, buffer, 0); 343 header_set_value (header, name, buffer, 0);
345 return err; 344 return err;
...@@ -421,7 +420,7 @@ header_entry_value (header_t header, size_t num, char *buf, ...@@ -421,7 +420,7 @@ header_entry_value (header_t header, size_t num, char *buf,
421 if (header->hdr_count == 0 || num > header->hdr_count) 420 if (header->hdr_count == 0 || num > header->hdr_count)
422 return ENOENT; 421 return ENOENT;
423 len = header->hdr[num].fv_end - header->hdr[num].fv; 422 len = header->hdr[num].fv_end - header->hdr[num].fv;
424 /* save one for the null */ 423 /* Save one for the null. */
425 --buflen; 424 --buflen;
426 if (buf && buflen > 0) 425 if (buf && buflen > 0)
427 { 426 {
......
...@@ -32,15 +32,12 @@ ...@@ -32,15 +32,12 @@
32 #define LOCKFILE_ATTR 0444 32 #define LOCKFILE_ATTR 0444
33 #define LOCK_EXPIRE_TIME (5 * 60) 33 #define LOCK_EXPIRE_TIME (5 * 60)
34 34
35 /* 35 /* First draft by Brian Edmond. */
36 * Waiting for Brian E. to implement this.
37 */
38 36
39 struct _locker 37 struct _locker
40 { 38 {
41 int fd; 39 int fd;
42 char *fname; 40 char *fname;
43 int locked;
44 int flags; 41 int flags;
45 }; 42 };
46 43
...@@ -59,7 +56,7 @@ locker_create (locker_t *plocker, char *filename, size_t len, int flags) ...@@ -59,7 +56,7 @@ locker_create (locker_t *plocker, char *filename, size_t len, int flags)
59 if (l == NULL) 56 if (l == NULL)
60 return ENOMEM; 57 return ENOMEM;
61 58
62 l->fname = calloc (len + 5 + 1, sizeof(char)); 59 l->fname = calloc (len + 5 /*strlen(".lock")*/ + 1, sizeof(char));
63 if (l->fname == NULL) 60 if (l->fname == NULL)
64 { 61 {
65 free (l); 62 free (l);
...@@ -68,11 +65,10 @@ locker_create (locker_t *plocker, char *filename, size_t len, int flags) ...@@ -68,11 +65,10 @@ locker_create (locker_t *plocker, char *filename, size_t len, int flags)
68 memcpy (l->fname, filename, len); 65 memcpy (l->fname, filename, len);
69 strcat (l->fname, ".lock"); 66 strcat (l->fname, ".lock");
70 67
71 l->locked = 0;
72 if (flags) 68 if (flags)
73 l->flags = flags; 69 l->flags = flags;
74 else 70 else
75 l->flags = MU_LOCKER_TIME; 71 l->flags = MU_LOCKER_TIME; /* Default is time lock implementation. */
76 l->fd = -1; 72 l->fd = -1;
77 *plocker = l; 73 *plocker = l;
78 return 0; 74 return 0;
...@@ -101,30 +97,32 @@ locker_lock (locker_t lock, int flags) ...@@ -101,30 +97,32 @@ locker_lock (locker_t lock, int flags)
101 if (lock == NULL) 97 if (lock == NULL)
102 return EINVAL; 98 return EINVAL;
103 99
104 /* check for lock existance 100 /*
105 * if it exists but the process is gone the lock can be removed 101 Check for lock existance:
106 */ 102 if it exists but the process is gone the lock can be removed,
103 if if the lock is expired and remove it. */
107 if ((fd = open(lock->fname, O_RDONLY)) != -1) 104 if ((fd = open(lock->fname, O_RDONLY)) != -1)
108 { 105 {
106 /* Check to see if this process is still running. */
109 if (lock->flags & MU_LOCKER_PID) 107 if (lock->flags & MU_LOCKER_PID)
110 { 108 {
111 if (read(fd, buf, sizeof (pid_t)) > 0) 109 if (read(fd, buf, sizeof (pid_t)) > 0)
112 { 110 {
113 /* check to see if this process is still running */
114 if ((pid = atoi(buf)) > 0) 111 if ((pid = atoi(buf)) > 0)
115 { 112 {
116 /* process is gone so we try to remove the lock */ 113 /* Process is gone so we try to remove the lock. */
117 if (kill(pid, 0) == -1) 114 if (kill(pid, 0) == -1)
118 removed = 1; 115 removed = 1;
119 } 116 }
120 } 117 }
121 } 118 }
119 /* Check to see if the lock expired. */
122 if (lock->flags & MU_LOCKER_TIME) 120 if (lock->flags & MU_LOCKER_TIME)
123 { 121 {
124 struct stat stbuf; 122 struct stat stbuf;
125 123
126 fstat(fd, &stbuf); 124 fstat(fd, &stbuf);
127 /* the lock has expired */ 125 /* The lock has expired. */
128 if ((time(NULL) - stbuf.st_mtime) > LOCK_EXPIRE_TIME) 126 if ((time(NULL) - stbuf.st_mtime) > LOCK_EXPIRE_TIME)
129 removed = 1; 127 removed = 1;
130 } 128 }
...@@ -134,15 +132,15 @@ locker_lock (locker_t lock, int flags) ...@@ -134,15 +132,15 @@ locker_lock (locker_t lock, int flags)
134 unlink(lock->fname); 132 unlink(lock->fname);
135 } 133 }
136 134
137 /* try to create the lockfile */ 135 /* Try to create the lockfile. */
138 if ((fd = open(lock->fname, 136 if ((fd = open(lock->fname,
139 O_WRONLY | O_CREAT | O_EXCL, LOCKFILE_ATTR)) == -1) 137 O_WRONLY | O_CREAT | O_EXCL, LOCKFILE_ATTR)) == -1)
140 return (-1); 138 return errno;
141 /* success */ 139 /* Success. */
142 sprintf(buf, "%d", getpid()); 140 sprintf(buf, "%d", getpid());
143 write(fd, buf, strlen(buf)); 141 write(fd, buf, strlen(buf));
144 142
145 /* try to get a file lock */ 143 /* Try to get a file lock. */
146 if (lock->flags & MU_LOCKER_FCNTL) 144 if (lock->flags & MU_LOCKER_FCNTL)
147 { 145 {
148 struct flock fl; 146 struct flock fl;
...@@ -151,10 +149,11 @@ locker_lock (locker_t lock, int flags) ...@@ -151,10 +149,11 @@ locker_lock (locker_t lock, int flags)
151 fl.l_type = F_WRLCK; 149 fl.l_type = F_WRLCK;
152 if (fcntl(fd, F_SETLK, &fl) == -1) 150 if (fcntl(fd, F_SETLK, &fl) == -1)
153 { 151 {
154 /* could not get the file lock */ 152 int err = errno;
153 /* Could not get the file lock. */
155 close (fd); 154 close (fd);
156 unlink(lock->fname); /* remove the file I created */ 155 unlink(lock->fname); /* Remove the file I created. */
157 return -1; 156 return err;
158 } 157 }
159 } 158 }
160 159
...@@ -165,7 +164,7 @@ locker_lock (locker_t lock, int flags) ...@@ -165,7 +164,7 @@ locker_lock (locker_t lock, int flags)
165 int 164 int
166 locker_touchlock (locker_t lock) 165 locker_touchlock (locker_t lock)
167 { 166 {
168 if (!lock || lock->fname || (lock->fd == -1)) 167 if (!lock || ! lock->fname || (lock->fd == -1))
169 return EINVAL; 168 return EINVAL;
170 return (utime(lock->fname, NULL)); 169 return (utime(lock->fname, NULL));
171 } 170 }
...@@ -173,7 +172,7 @@ locker_touchlock (locker_t lock) ...@@ -173,7 +172,7 @@ locker_touchlock (locker_t lock)
173 int 172 int
174 locker_unlock (locker_t lock) 173 locker_unlock (locker_t lock)
175 { 174 {
176 if (!lock || !lock->fname || (lock->fd == -1)) 175 if (!lock || ! lock->fname || (lock->fd == -1))
177 return EINVAL; 176 return EINVAL;
178 177
179 if (lock->flags & MU_LOCKER_FCNTL) 178 if (lock->flags & MU_LOCKER_FCNTL)
...@@ -182,11 +181,10 @@ locker_unlock (locker_t lock) ...@@ -182,11 +181,10 @@ locker_unlock (locker_t lock)
182 181
183 memset(&fl, 0, sizeof(struct flock)); 182 memset(&fl, 0, sizeof(struct flock));
184 fl.l_type = F_UNLCK; 183 fl.l_type = F_UNLCK;
185 /* unlock failed ? */ 184 /* Unlock failed ? */
186 if (fcntl(lock->fd, F_SETLK, &fl) == -1) 185 if (fcntl(lock->fd, F_SETLK, &fl) == -1)
187 return errno; 186 return errno;
188 } 187 }
189 lock->locked = 0;
190 close(lock->fd); 188 close(lock->fd);
191 lock->fd = -1; 189 lock->fd = -1;
192 unlink(lock->fname); 190 unlink(lock->fname);
......
...@@ -45,7 +45,7 @@ _mapfile_destroy (stream_t stream) ...@@ -45,7 +45,7 @@ _mapfile_destroy (stream_t stream)
45 { 45 {
46 struct _mapfile_stream *mfs = stream->owner; 46 struct _mapfile_stream *mfs = stream->owner;
47 47
48 if (mfs->ptr) 48 if (mfs && mfs->ptr)
49 { 49 {
50 munmap (mfs->ptr, mfs->size); 50 munmap (mfs->ptr, mfs->size);
51 close (mfs->fd); 51 close (mfs->fd);
...@@ -60,8 +60,9 @@ _mapfile_read (stream_t stream, char *optr, size_t osize, ...@@ -60,8 +60,9 @@ _mapfile_read (stream_t stream, char *optr, size_t osize,
60 struct _mapfile_stream *mfs = stream->owner; 60 struct _mapfile_stream *mfs = stream->owner;
61 size_t n; 61 size_t n;
62 62
63 if (mfs->ptr == NULL) 63 if (mfs == NULL || mfs->ptr == NULL)
64 return EINVAL; 64 return EINVAL;
65
65 if (offset >= (off_t)mfs->size) 66 if (offset >= (off_t)mfs->size)
66 { 67 {
67 if (nbytes) 68 if (nbytes)
...@@ -85,9 +86,9 @@ _mapfile_readline (stream_t stream, char *optr, size_t osize, ...@@ -85,9 +86,9 @@ _mapfile_readline (stream_t stream, char *optr, size_t osize,
85 char *nl; 86 char *nl;
86 size_t n = 0; 87 size_t n = 0;
87 88
88 if (mfs->ptr == NULL) 89 if (mfs == NULL || mfs->ptr == NULL)
89 return EINVAL; 90 return EINVAL;
90 /* save space for the null byte */ 91 /* Save space for the null byte. */
91 osize--; 92 osize--;
92 if (offset >= (off_t)mfs->size) 93 if (offset >= (off_t)mfs->size)
93 { 94 {
...@@ -112,13 +113,14 @@ _mapfile_write (stream_t stream, const char *iptr, size_t isize, ...@@ -112,13 +113,14 @@ _mapfile_write (stream_t stream, const char *iptr, size_t isize,
112 { 113 {
113 struct _mapfile_stream *mfs = stream->owner; 114 struct _mapfile_stream *mfs = stream->owner;
114 115
115 if (mfs->ptr == NULL) 116 if (mfs == NULL || mfs->ptr == NULL)
116 return EINVAL; 117 return EINVAL;
118
117 if (! (mfs->flags & PROT_WRITE)) 119 if (! (mfs->flags & PROT_WRITE))
118 return EACCES; 120 return EACCES;
119 121
120 /* not recommanded, really */ 122 /* Not recommanded, really. */
121 /* bigger we have to remmap */ 123 /* Bigger we have to remmap. */
122 if (mfs->size < (offset + isize)) 124 if (mfs->size < (offset + isize))
123 { 125 {
124 if (munmap (mfs->ptr, mfs->size) != 0) 126 if (munmap (mfs->ptr, mfs->size) != 0)
...@@ -150,9 +152,9 @@ static int ...@@ -150,9 +152,9 @@ static int
150 _mapfile_truncate (stream_t stream, off_t len) 152 _mapfile_truncate (stream_t stream, off_t len)
151 { 153 {
152 struct _mapfile_stream *mfs = stream->owner; 154 struct _mapfile_stream *mfs = stream->owner;
153 if (mfs->ptr == NULL) 155 if (mfs == NULL || mfs->ptr == NULL)
154 return EINVAL; 156 return EINVAL;
155 /* remap */ 157 /* Remap. */
156 if (munmap (mfs->ptr, mfs->size) != 0) 158 if (munmap (mfs->ptr, mfs->size) != 0)
157 { 159 {
158 int err = errno; 160 int err = errno;
...@@ -178,7 +180,8 @@ _mapfile_size (stream_t stream, off_t *psize) ...@@ -178,7 +180,8 @@ _mapfile_size (stream_t stream, off_t *psize)
178 { 180 {
179 struct _mapfile_stream *mfs = stream->owner; 181 struct _mapfile_stream *mfs = stream->owner;
180 struct stat stbuf; 182 struct stat stbuf;
181 if (mfs->ptr == NULL) 183
184 if (mfs == NULL || mfs->ptr == NULL)
182 return EINVAL; 185 return EINVAL;
183 msync (mfs->ptr, mfs->size, MS_SYNC); 186 msync (mfs->ptr, mfs->size, MS_SYNC);
184 if (fstat(mfs->fd, &stbuf) != 0) 187 if (fstat(mfs->fd, &stbuf) != 0)
...@@ -192,6 +195,8 @@ static int ...@@ -192,6 +195,8 @@ static int
192 _mapfile_flush (stream_t stream) 195 _mapfile_flush (stream_t stream)
193 { 196 {
194 struct _mapfile_stream *mfs = stream->owner; 197 struct _mapfile_stream *mfs = stream->owner;
198 if (mfs == NULL)
199 return EINVAL;
195 return msync (mfs->ptr, mfs->size, MS_SYNC); 200 return msync (mfs->ptr, mfs->size, MS_SYNC);
196 } 201 }
197 202
...@@ -199,6 +204,8 @@ static int ...@@ -199,6 +204,8 @@ static int
199 _mapfile_get_fd (stream_t stream, int *pfd) 204 _mapfile_get_fd (stream_t stream, int *pfd)
200 { 205 {
201 struct _mapfile_stream *mfs = stream->owner; 206 struct _mapfile_stream *mfs = stream->owner;
207 if (mfs == NULL)
208 return EINVAL;
202 if (pfd) 209 if (pfd)
203 *pfd = mfs->fd; 210 *pfd = mfs->fd;
204 return 0; 211 return 0;
...@@ -208,16 +215,17 @@ static int ...@@ -208,16 +215,17 @@ static int
208 _mapfile_close (stream_t stream) 215 _mapfile_close (stream_t stream)
209 { 216 {
210 struct _mapfile_stream *mfs = stream->owner; 217 struct _mapfile_stream *mfs = stream->owner;
211 if (mfs->ptr) 218 int err = 0;
219 if (mfs && mfs->ptr)
212 { 220 {
213 if (munmap (mfs->ptr, mfs->size) != 0) 221 if (munmap (mfs->ptr, mfs->size) != 0)
214 return errno; 222 err = errno;
215 mfs->ptr = NULL;
216 if (close (mfs->fd) != 0) 223 if (close (mfs->fd) != 0)
217 return errno; 224 err = errno;
225 mfs->ptr = NULL;
218 mfs->fd = -1; 226 mfs->fd = -1;
219 } 227 }
220 return 0; 228 return err;
221 } 229 }
222 230
223 static int 231 static int
...@@ -227,9 +235,12 @@ _mapfile_open (stream_t stream, const char *filename, int port, int flags) ...@@ -227,9 +235,12 @@ _mapfile_open (stream_t stream, const char *filename, int port, int flags)
227 int mflag, flg; 235 int mflag, flg;
228 struct stat st; 236 struct stat st;
229 237
230 (void)port; /* shutup gcc */ 238 (void)port; /* Ignored. */
239
240 if (mfs == NULL)
241 return EINVAL;
231 242
232 /* map the flags to the system equivalent */ 243 /* Map the flags to the system equivalent */
233 if (flags & MU_STREAM_WRITE) 244 if (flags & MU_STREAM_WRITE)
234 { 245 {
235 mflag = PROT_WRITE; 246 mflag = PROT_WRITE;
......
...@@ -22,13 +22,13 @@ mailbox_create_default (mailbox_t *pmbox, const char *mail) ...@@ -22,13 +22,13 @@ mailbox_create_default (mailbox_t *pmbox, const char *mail)
22 22
23 if (mail) 23 if (mail)
24 { 24 {
25 /* is it a fullpath ? */ 25 /* Is it a fullpath ? */
26 if (mail[0] != '/') 26 if (mail[0] != '/')
27 { 27 {
28 /* is it a URL ? */ 28 /* Is it a URL ? */
29 if (strchr (mail, ':') == NULL) 29 if (strchr (mail, ':') == NULL)
30 { 30 {
31 /* a user name */ 31 /* A user name. */
32 user = mail; 32 user = mail;
33 mail = NULL; 33 mail = NULL;
34 } 34 }
...@@ -44,7 +44,7 @@ mailbox_create_default (mailbox_t *pmbox, const char *mail) ...@@ -44,7 +44,7 @@ mailbox_create_default (mailbox_t *pmbox, const char *mail)
44 user = (getenv ("LOGNAME")) ? getenv ("LOGNAME") : getenv ("USER"); 44 user = (getenv ("LOGNAME")) ? getenv ("LOGNAME") : getenv ("USER");
45 if (user == NULL) 45 if (user == NULL)
46 { 46 {
47 fprintf (stderr, "who am I?\n"); 47 fprintf (stderr, "Who am I ?\n");
48 return EINVAL; 48 return EINVAL;
49 } 49 }
50 } 50 }
......