Commit 5059666f 5059666f66472e2ff2c4a96bee47f5527abbf254 by Alain Magloire

header.c mailer.c mbx_unix.c mime.c tcp.c

 	include/public/header.h include/public/mailer.h

add dirty/ugly support for header_set_value()
1 parent 4f2b8ab8
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
24 #include <io0.h> 24 #include <io0.h>
25 #include <string.h> 25 #include <string.h>
26 #include <stdlib.h> 26 #include <stdlib.h>
27 #include <stdio.h>
27 #include <errno.h> 28 #include <errno.h>
28 29
29 static int header_parse (header_t h, char *blurb, int len); 30 static int header_parse (header_t h, char *blurb, int len);
...@@ -113,11 +114,14 @@ header_parse (header_t header, char *blurb, int len) ...@@ -113,11 +114,14 @@ header_parse (header_t header, char *blurb, int len)
113 return 0; 114 return 0;
114 115
115 header->blurb_len = len; 116 header->blurb_len = len;
116 header->blurb = calloc (1, header->blurb_len + 1); 117 header->blurb = calloc (header->blurb_len + 1, 1);
117 if (header->blurb == NULL) 118 if (header->blurb == NULL)
118 return ENOMEM; 119 return ENOMEM;
119 memcpy (header->blurb, blurb, header->blurb_len); 120 memcpy (header->blurb, blurb, header->blurb_len);
120 121
122 free (header->hdr);
123 header->hdr = NULL;
124 header->hdr_count = 0;
121 for (header_start = header->blurb;; header_start = ++header_end) 125 for (header_start = header->blurb;; header_start = ++header_end)
122 { 126 {
123 char *fn, *fn_end, *fv, *fv_end; 127 char *fn, *fn_end, *fv, *fv_end;
...@@ -195,27 +199,68 @@ header_parse (header_t header, char *blurb, int len) ...@@ -195,27 +199,68 @@ header_parse (header_t header, char *blurb, int len)
195 header->hdr_count++; 199 header->hdr_count++;
196 } /* for (header_start ...) */ 200 } /* for (header_start ...) */
197 201
198 #if 0 202 return 0;
199 header->blurb_len -= len;
200 if (header->blurb_len <= 0)
201 {
202 free (header->blurb);
203 free (header->hdr);
204 return EINVAL;
205 }
206 /* always add the separtor LF */
207 header->blurb [header->blurb_len] = '\n';
208 header->blurb_len++;
209 #endif
210 return 0;
211 } 203 }
212 204
205 /* FIXME: grossly inneficient, to many copies and reallocating
206 * This all header business need a good rewrite.
207 */
213 int 208 int
214 header_set_value (header_t h, const char *fn, const char *fv, 209 header_set_value (header_t header, const char *fn, const char *fv, int replace)
215 size_t n, int replace)
216 { 210 {
217 (void)h; (void)fn; (void)fv; (void)n; (void)replace; 211 char *blurb;
218 return ENOSYS; 212 size_t len;
213
214 if (header == NULL || fn == NULL || fv == NULL)
215 return EINVAL;
216
217 /* Easy approach: if replace, overwrite the field-{namve,value}
218 * and readjust the pointers by calling header_parse ()
219 * this is wastefull and bad, we're just fragmenting the memory
220 * it can be done better. But that may imply a rewite of the headers
221 * So for another day.
222 */
223 {
224 size_t name_len;
225 size_t i;
226 size_t fn_len;
227 size_t fv_len;
228 len = header->blurb_len;
229 for (name_len = strlen (fn), i = 0; i < header->hdr_count; i++)
230 {
231 fn_len = header->hdr[i].fn_end - header->hdr[i].fn;
232 fv_len = header->hdr[i].fv_end - header->hdr[i].fv;
233 if (fn_len == name_len &&
234 strncasecmp (header->hdr[i].fn, fn, fn_len) == 0)
235 {
236 if (replace)
237 {
238 blurb = header->blurb;
239 memmove (header->hdr[i].fn, header->hdr[i + 1].fn,
240 header->hdr[header->hdr_count - 1].fv_end
241 - header->hdr[i + 1].fn + 1 + 1);
242 /* readjust the pointers if move */
243 len -= fn_len + fv_len + 2;
244 i--;
245 blurb = header->blurb;
246 header_parse (header, blurb, len);
247 free (blurb);
248 }
249 }
250 }
251 }
252
253 /* and it's getting worse, we free/malloc at will */
254 len = strlen (fn) + strlen (fv) + 1 + 1 + 1 + 1;
255 blurb = calloc (header->blurb_len + len, 1);
256 if (blurb == NULL)
257 return ENOMEM;
258 sprintf (blurb, "%s: %s\n", fn, fv);
259 memcpy (blurb + len - 1, header->blurb, header->blurb_len);
260 free (header->blurb);
261 header_parse (header, blurb, len + header->blurb_len);
262 free (blurb);
263 return 0;
219 } 264 }
220 265
221 int 266 int
......
...@@ -72,9 +72,9 @@ extern int header_create __P ((header_t *, const char *blurb, ...@@ -72,9 +72,9 @@ extern int header_create __P ((header_t *, const char *blurb,
72 extern void header_destroy __P ((header_t *, void *owner)); 72 extern void header_destroy __P ((header_t *, void *owner));
73 73
74 extern int header_set_value __P ((header_t, const char *fn, 74 extern int header_set_value __P ((header_t, const char *fn,
75 const char *fv, size_t n, int replace)); 75 const char *fv, int replace));
76 extern int header_get_value __P ((header_t, const char *fn, char *fv, 76 extern int header_get_value __P ((header_t, const char *fn, char *buf,
77 size_t len, size_t *nwritten)); 77 size_t buflen, size_t *nwritten));
78 extern int header_entry_count __P ((header_t, size_t *num)); 78 extern int header_entry_count __P ((header_t, size_t *num));
79 extern int header_entry_name __P ((header_t, size_t num, char *buf, 79 extern int header_entry_name __P ((header_t, size_t num, char *buf,
80 size_t buflen, size_t *total)); 80 size_t buflen, size_t *total));
......
...@@ -38,6 +38,7 @@ struct _mailer; ...@@ -38,6 +38,7 @@ struct _mailer;
38 typedef struct _mailer *mailer_t; 38 typedef struct _mailer *mailer_t;
39 39
40 extern int mailer_create __P ((mailer_t *, message_t)); 40 extern int mailer_create __P ((mailer_t *, message_t));
41 extern int mailer_destroy __P ((mailer_t *));
41 extern int mailer_connect __P ((mailer_t, char *host)); 42 extern int mailer_connect __P ((mailer_t, char *host));
42 extern int mailer_disconnect __P ((mailer_t)); 43 extern int mailer_disconnect __P ((mailer_t));
43 extern int mailer_send_header __P ((mailer_t, message_t)); 44 extern int mailer_send_header __P ((mailer_t, message_t));
......
...@@ -35,7 +35,8 @@ int _mailer_sock_connect(char *host, int port); ...@@ -35,7 +35,8 @@ int _mailer_sock_connect(char *host, int port);
35 char *_mailer_find_mailbox(char *addr); 35 char *_mailer_find_mailbox(char *addr);
36 int _mailer_send_command(mailer_t ml, message_t msg, int cmd); 36 int _mailer_send_command(mailer_t ml, message_t msg, int cmd);
37 char *nb_fgets(char *buf, int size, int s); 37 char *nb_fgets(char *buf, int size, int s);
38 char *nb_fprintf(int s, char *format, ...); 38 const char *nb_fprintf(int s, const char *format, ...);
39 static int _mailer_rctp(mailer_t ml, char *str);
39 40
40 #define nb_read read 41 #define nb_read read
41 #define nb_write write 42 #define nb_write write
...@@ -76,15 +77,15 @@ mailer_destroy(mailer_t *pml) ...@@ -76,15 +77,15 @@ mailer_destroy(mailer_t *pml)
76 return (0); 77 return (0);
77 } 78 }
78 79
79 int 80 int
80 mailer_connect(mailer_t ml, char *host) 81 mailer_connect(mailer_t ml, char *host)
81 { 82 {
82 if (!ml || !host) 83 if (!ml || !host)
83 return (EINVAL); 84 return (EINVAL);
84 85
85 if ((ml->socket = _mailer_sock_connect(host, 25)) < 0) 86 if ((ml->socket = _mailer_sock_connect(host, 25)) < 0)
86 return (-1); 87 return (-1);
87 do 88 do
88 { 89 {
89 nb_fgets(ml->line_buf, MAILER_LINE_BUF_SIZE, ml->socket); /* read header line */ 90 nb_fgets(ml->line_buf, MAILER_LINE_BUF_SIZE, ml->socket); /* read header line */
90 } while ( strlen(ml->line_buf) > 4 && *(ml->line_buf+3) == '-'); 91 } while ( strlen(ml->line_buf) > 4 && *(ml->line_buf+3) == '-');
...@@ -92,8 +93,8 @@ mailer_connect(mailer_t ml, char *host) ...@@ -92,8 +93,8 @@ mailer_connect(mailer_t ml, char *host)
92 return (0); 93 return (0);
93 } 94 }
94 95
95 int 96 int
96 mailer_disconnect(mailer_t ml) 97 mailer_disconnect(mailer_t ml)
97 { 98 {
98 if (!ml || (ml->socket != -1)) 99 if (!ml || (ml->socket != -1))
99 return (EINVAL); 100 return (EINVAL);
...@@ -102,7 +103,7 @@ mailer_disconnect(mailer_t ml) ...@@ -102,7 +103,7 @@ mailer_disconnect(mailer_t ml)
102 return (0); 103 return (0);
103 } 104 }
104 105
105 int 106 int
106 mailer_send_header(mailer_t ml, message_t msg) 107 mailer_send_header(mailer_t ml, message_t msg)
107 { 108 {
108 header_t hdr; 109 header_t hdr;
...@@ -138,7 +139,8 @@ mailer_send_header(mailer_t ml, message_t msg) ...@@ -138,7 +139,8 @@ mailer_send_header(mailer_t ml, message_t msg)
138 int 139 int
139 mailer_send_message(mailer_t ml, message_t msg) 140 mailer_send_message(mailer_t ml, message_t msg)
140 { 141 {
141 int status, len = 0, data_len = 0, consumed = 0; 142 int status, data_len = 0;
143 size_t consumed = 0, len = 0;
142 char *data, *p, *q; 144 char *data, *p, *q;
143 145
144 if (!ml || !msg || (ml->socket == -1)) 146 if (!ml || !msg || (ml->socket == -1))
...@@ -227,13 +229,13 @@ _mailer_find_mailbox(char *addr) ...@@ -227,13 +229,13 @@ _mailer_find_mailbox(char *addr)
227 { 229 {
228 char *p, *c; 230 char *p, *c;
229 p = addr; 231 p = addr;
230 if ( (c = strchr( p, '<')) != 0) 232 if ( (c = strchr( p, '<')) != 0)
231 { 233 {
232 p = c+1; 234 p = c+1;
233 if ( c = strchr( p, '>')) 235 if ( (c = strchr( p, '>')) )
234 *c = '\0'; 236 *c = '\0';
235 } 237 }
236 else if ( (c = strchr( p, '(' )) != 0 ) 238 else if ( (c = strchr( p, '(' )) != 0 )
237 { 239 {
238 --c; 240 --c;
239 while ( c > p && *c && isspace( *c ) ) { 241 while ( c > p && *c && isspace( *c ) ) {
...@@ -244,14 +246,14 @@ _mailer_find_mailbox(char *addr) ...@@ -244,14 +246,14 @@ _mailer_find_mailbox(char *addr)
244 return p; 246 return p;
245 } 247 }
246 248
247 int 249 static int
248 _mailer_rctp(mailer_t ml, char *str) 250 _mailer_rctp(mailer_t ml, char *str)
249 { 251 {
250 char *p, *c = NULL, *q = NULL; 252 char *p, *c = NULL, *q = NULL;
251 253
252 for (q = p = str; q && *p; p = q+1) 254 for (q = p = str; q && *p; p = q+1)
253 { 255 {
254 if ( q = strchr( p, ',')) 256 if ( (q = strchr( p, ',')) )
255 *q = '\0'; 257 *q = '\0';
256 while ( p && *p && isspace( *p ) ) 258 while ( p && *p && isspace( *p ) )
257 p++; 259 p++;
...@@ -270,10 +272,10 @@ int ...@@ -270,10 +272,10 @@ int
270 _mailer_send_command(mailer_t ml, message_t msg, int cmd) 272 _mailer_send_command(mailer_t ml, message_t msg, int cmd)
271 { 273 {
272 header_t hdr; 274 header_t hdr;
273 char *p, *c = NULL, *q = NULL; 275 char *p;
274 char str[128]; 276 char str[128];
275 size_t str_len; 277 size_t str_len;
276 char *success = "250"; 278 const char *success = "250";
277 279
278 switch (cmd) 280 switch (cmd)
279 { 281 {
...@@ -320,7 +322,7 @@ _mailer_send_command(mailer_t ml, message_t msg, int cmd) ...@@ -320,7 +322,7 @@ _mailer_send_command(mailer_t ml, message_t msg, int cmd)
320 } 322 }
321 323
322 char * 324 char *
323 nb_fgets( char *buf, int size, int s ) 325 nb_fgets( char *buf, int size, int s )
324 { 326 {
325 static char *buffer[25]; 327 static char *buffer[25];
326 char *p, *b, *d; 328 char *p, *b, *d;
...@@ -331,9 +333,9 @@ nb_fgets( char *buf, int size, int s ) ...@@ -331,9 +333,9 @@ nb_fgets( char *buf, int size, int s )
331 return 0; 333 return 0;
332 bytes = i = strlen( p = b = buffer[s] ); 334 bytes = i = strlen( p = b = buffer[s] );
333 *( d = buf ) = '\0'; 335 *( d = buf ) = '\0';
334 for ( ; i-- > 0; p++ ) 336 for ( ; i-- > 0; p++ )
335 { 337 {
336 if ( *p == '\n' ) 338 if ( *p == '\n' )
337 { 339 {
338 char c = *( p+1 ); 340 char c = *( p+1 );
339 341
...@@ -346,19 +348,19 @@ nb_fgets( char *buf, int size, int s ) ...@@ -346,19 +348,19 @@ nb_fgets( char *buf, int size, int s )
346 } 348 }
347 flags = fcntl( s, F_GETFL ); 349 flags = fcntl( s, F_GETFL );
348 fcntl( s, F_SETFL, O_NONBLOCK ); 350 fcntl( s, F_SETFL, O_NONBLOCK );
349 while ( bytes <= size ) 351 while ( bytes <= size )
350 { 352 {
351 fd_set fds; 353 fd_set fds;
352 354
353 FD_ZERO( &fds ); 355 FD_ZERO( &fds );
354 FD_SET( s, &fds ); 356 FD_SET( s, &fds );
355 select( s+1, &fds, 0, 0, 0 ); /* we really don't care what it returns */ 357 select( s+1, &fds, 0, 0, 0 ); /* we really don't care what it returns */
356 if ( ( i = nb_read( s, p, BUFFSIZE - bytes ) ) == -1 ) 358 if ( ( i = nb_read( s, p, BUFFSIZE - bytes ) ) == -1 )
357 { 359 {
358 *b = '\0'; 360 *b = '\0';
359 return 0; 361 return 0;
360 } 362 }
361 else if ( i == 0 ) 363 else if ( i == 0 )
362 { 364 {
363 *( p+1 ) = '\0'; 365 *( p+1 ) = '\0';
364 strcat( d, b ); 366 strcat( d, b );
...@@ -368,9 +370,9 @@ nb_fgets( char *buf, int size, int s ) ...@@ -368,9 +370,9 @@ nb_fgets( char *buf, int size, int s )
368 } 370 }
369 *( p+i ) = '\0'; 371 *( p+i ) = '\0';
370 bytes += i; 372 bytes += i;
371 for ( ; i-- > 0; p++ ) 373 for ( ; i-- > 0; p++ )
372 { 374 {
373 if ( *p == '\n' ) 375 if ( *p == '\n' )
374 { 376 {
375 char c = *( p+1 ); 377 char c = *( p+1 );
376 378
...@@ -382,7 +384,7 @@ nb_fgets( char *buf, int size, int s ) ...@@ -382,7 +384,7 @@ nb_fgets( char *buf, int size, int s )
382 return buf; 384 return buf;
383 } 385 }
384 } 386 }
385 if ( bytes == BUFFSIZE ) 387 if ( bytes == BUFFSIZE )
386 { 388 {
387 memcpy( d, b, BUFFSIZE ); 389 memcpy( d, b, BUFFSIZE );
388 d += BUFFSIZE; 390 d += BUFFSIZE;
...@@ -397,8 +399,8 @@ nb_fgets( char *buf, int size, int s ) ...@@ -397,8 +399,8 @@ nb_fgets( char *buf, int size, int s )
397 return buf; 399 return buf;
398 } 400 }
399 401
400 char * 402 const char *
401 nb_fprintf( int s, char *format, ... ) 403 nb_fprintf( int s, const char *format, ... )
402 { 404 {
403 char buf[MAILER_LINE_BUF_SIZE]; 405 char buf[MAILER_LINE_BUF_SIZE];
404 va_list vl; 406 va_list vl;
......
...@@ -770,37 +770,6 @@ mailbox_unix_expunge (mailbox_t mbox) ...@@ -770,37 +770,6 @@ mailbox_unix_expunge (mailbox_t mbox)
770 goto bailout; 770 goto bailout;
771 stream_flush (mbox->stream); 771 stream_flush (mbox->stream);
772 772
773 /* we need to readjust the pointers */
774 {
775 size_t dlast;
776 for (j = dirty, dlast = mud->messages_count - 1;
777 j < mud->messages_count; j++)
778 {
779 /* clear all the references,
780 * any attach messages been already destroy above
781 */
782 mum = mud->umessages[j];
783 if (mum->new_attr && attribute_is_deleted (mum->new_attr))
784 {
785 memmove (mud->umessages + j, mud->umessages + j + 1,
786 (dlast - dirty) * sizeof (mum));
787 mum->header_from = mum->header_from_end = 0;
788 mum->header_status = mum->header_status_end = 0;
789 mum->body = mum->body_end = 0;
790 mum->header_lines = mum->body_lines = 0;
791 attribute_destroy (&(mum->new_attr));
792 mud->umessages[dlast] = mum;
793 dlast--;
794 mum = mud->umessages[j];
795 }
796 mum->header_from = mum->header_from_end = 0;
797 mum->header_status = mum->header_status_end = 0;
798 mum->body = mum->body_end = 0;
799 mum->header_lines = mum->body_lines = 0;
800 }
801 mailbox_unix_scan0 (mbox, dirty, NULL, 0);
802 }
803
804 /* Don't remove the tmp mbox in case of errors */ 773 /* Don't remove the tmp mbox in case of errors */
805 remove (tmpmbox); 774 remove (tmpmbox);
806 775
...@@ -813,6 +782,37 @@ mailbox_unix_expunge (mailbox_t mbox) ...@@ -813,6 +782,37 @@ mailbox_unix_expunge (mailbox_t mbox)
813 fclose (tempfile); 782 fclose (tempfile);
814 sigprocmask (SIG_UNBLOCK, &sigset, 0); 783 sigprocmask (SIG_UNBLOCK, &sigset, 0);
815 784
785 /* we need to readjust the pointers */
786 if (status == 0)
787 {
788 size_t dlast;
789 for (j = dirty, dlast = mud->messages_count - 1;
790 j < mud->messages_count; j++)
791 {
792 /* clear all the references,
793 * any attach messages been already destroy above
794 */
795 mum = mud->umessages[j];
796 if (mum->new_attr && attribute_is_deleted (mum->new_attr))
797 {
798 memmove (mud->umessages + j, mud->umessages + j + 1,
799 (dlast - dirty) * sizeof (mum));
800 mum->header_from = mum->header_from_end = 0;
801 mum->header_status = mum->header_status_end = 0;
802 mum->body = mum->body_end = 0;
803 mum->header_lines = mum->body_lines = 0;
804 attribute_destroy (&(mum->new_attr));
805 mud->umessages[dlast] = mum;
806 dlast--;
807 mum = mud->umessages[j];
808 }
809 mum->header_from = mum->header_from_end = 0;
810 mum->header_status = mum->header_status_end = 0;
811 mum->body = mum->body_end = 0;
812 mum->header_lines = mum->body_lines = 0;
813 }
814 mailbox_unix_scan0 (mbox, dirty, NULL, 0);
815 }
816 return status; 816 return status;
817 } 817 }
818 818
......
...@@ -74,9 +74,9 @@ static int _mime_append_part(mime_t mime, message_t msg, int body_offset, int bo ...@@ -74,9 +74,9 @@ static int _mime_append_part(mime_t mime, message_t msg, int body_offset, int bo
74 mime->header_length = 0; 74 mime->header_length = 0;
75 if ( ( ret = header_get_value(mime_part->hdr, "Content-Type", NULL, 0, &size) ) != 0 || size == 0 ) { 75 if ( ( ret = header_get_value(mime_part->hdr, "Content-Type", NULL, 0, &size) ) != 0 || size == 0 ) {
76 if ( _mime_is_multipart_digest(mime) ) 76 if ( _mime_is_multipart_digest(mime) )
77 header_set_value(mime_part->hdr, "Content-Type", "message/rfc822", 0, 0); 77 header_set_value(mime_part->hdr, "Content-Type", "message/rfc822", 0);
78 else 78 else
79 header_set_value(mime_part->hdr, "Content-Type", "text/plain", 0, 0); 79 header_set_value(mime_part->hdr, "Content-Type", "text/plain", 0);
80 } 80 }
81 } 81 }
82 mime_part->body_len = body_len; 82 mime_part->body_len = body_len;
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
25 #include <sys/socket.h> 25 #include <sys/socket.h>
26 #include <netinet/in.h> 26 #include <netinet/in.h>
27 #include <arpa/inet.h> 27 #include <arpa/inet.h>
28 #include <unistd.h>
28 29
29 #include <io0.h> 30 #include <io0.h>
30 #include <tcp.h> 31 #include <tcp.h>
...@@ -126,10 +127,10 @@ static int _tcp_get_fd(stream_t stream, int *fd) ...@@ -126,10 +127,10 @@ static int _tcp_get_fd(stream_t stream, int *fd)
126 static int _tcp_read(stream_t stream, char *buf, size_t buf_size, off_t offset, size_t *br) 127 static int _tcp_read(stream_t stream, char *buf, size_t buf_size, off_t offset, size_t *br)
127 { 128 {
128 struct _tcp_instance *tcp = stream->owner; 129 struct _tcp_instance *tcp = stream->owner;
129 int bytes; 130 int bytes;
130 131
131 offset = offset; 132 offset = offset;
132 if ( br == NULL ) 133 if ( br == NULL )
133 return EINVAL; 134 return EINVAL;
134 *br = 0; 135 *br = 0;
135 if ( ( bytes = recv(tcp->fd, buf, buf_size, 0) ) == -1 ) { 136 if ( ( bytes = recv(tcp->fd, buf, buf_size, 0) ) == -1 ) {
...@@ -143,10 +144,10 @@ static int _tcp_read(stream_t stream, char *buf, size_t buf_size, off_t offset, ...@@ -143,10 +144,10 @@ static int _tcp_read(stream_t stream, char *buf, size_t buf_size, off_t offset,
143 static int _tcp_write(stream_t stream, const char *buf, size_t buf_size, off_t offset, size_t *bw) 144 static int _tcp_write(stream_t stream, const char *buf, size_t buf_size, off_t offset, size_t *bw)
144 { 145 {
145 struct _tcp_instance *tcp = stream->owner; 146 struct _tcp_instance *tcp = stream->owner;
146 int bytes; 147 int bytes;
147 148
148 offset = offset; 149 offset = offset;
149 if ( bw == NULL ) 150 if ( bw == NULL )
150 return EINVAL; 151 return EINVAL;
151 *bw = 0; 152 *bw = 0;
152 if ( ( bytes = send(tcp->fd, buf, buf_size, 0) ) == -1 ) { 153 if ( ( bytes = send(tcp->fd, buf, buf_size, 0) ) == -1 ) {
......