]> mj.ucw.cz Git - umpf.git/blob - ham.c
ddc8e3ce5680ec660c287c2bdc4427de45bef77e
[umpf.git] / ham.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4
5 #include <unistd.h>
6
7 #include "brum.h"
8
9 #define BUFSIZE 1024 
10
11 int curbufsize;
12
13 char mbox_write_buf[BUFSIZE];
14 int mbox_write_pos;
15 int mbox_write_err;
16
17 static void
18 new_header(char* buf, struct list* h)
19 {
20         char* p;
21         struct hlist* new;
22
23         new = xmalloc(sizeof(struct hlist));
24
25         p = strchr(buf, ':');
26         if (!p)
27                 new->value = xstrdup("");
28         else {
29                 *p = 0;
30                 new->value = xstrdup(p+1);
31         }
32         new->name = xstrdup(buf);
33
34         list_add_last(h, &new->car);
35 }
36
37 struct list*
38 make_hlist(void)
39 {
40         struct list* l = xmalloc(sizeof(struct list));
41         char* buf;
42         int i = 0; /* current position */
43         int c, last = 0;
44
45         list_init(l);
46         buf = xmalloc(BUFSIZE);
47         curbufsize = BUFSIZE;
48         
49         while ((c = getchar()) != EOF){
50                 if (c == '\r')
51                         continue;
52
53                 if (i >= curbufsize-2)
54                         buf = xrealloc(buf, curbufsize *= 2);
55                 
56                 buf[i++] = c; 
57                 if (c == '\n'){
58                         if (last == '\n')
59                                 break;
60                         if ((c = getchar()) != ' ' && c != '\t'){
61                                 if (c != EOF)
62                                         ungetc(c, stdin);
63                                 buf[i] = 0;
64                                 new_header(buf, l);
65                                 i = 0;
66                         } else
67                                 buf[i++] = c;
68                 }
69                         last = c;
70         }
71         free(buf);
72         return l;
73 }
74
75 char*
76 get_body(void)
77 {
78         char* buf;
79         int c;
80         int i = 0;
81         int curbufsize = BUFSIZE;
82
83         buf = xmalloc(BUFSIZE);
84         while ((c = getchar()) != EOF){
85                 buf[i++] = c;
86
87                 if (i >= curbufsize - 1)
88                         buf = xrealloc(buf, curbufsize *= 2);
89         }
90
91         buf[i] = 0;
92
93         return buf; 
94 }
95
96 void
97 print_headers(struct list* l)
98 {
99         struct hlist* p;
100
101         LIST_FOREACH(p,l)
102                 printf("%s:%s",p->name,p->value);
103 }
104
105 static void
106 write_char_to_mailbox(char c, int fd)
107 {
108         int res;
109
110         if (mbox_write_err)
111                 return;
112
113         if (!c){
114                 if (!mbox_write_pos)
115                         return;
116                 res = write(fd, mbox_write_buf, mbox_write_pos);
117                 if (res < 0)
118                         mbox_write_err++;
119                 mbox_write_pos = 0;
120                 return;
121         }
122         if (mbox_write_pos >= BUFSIZE){
123                 res = write(fd, mbox_write_buf, BUFSIZE);
124                 if (res < 0)
125                         mbox_write_err++;
126                 mbox_write_pos = 0;
127                 return;
128         }
129         mbox_write_buf[mbox_write_pos++] = c;
130 }
131
132 /* try to copy e-mail to mailbox, if it fails,
133  truncate mailbox to the original size */
134 static int
135 copy_email(int fd, struct email* email)
136 {
137         off_t mb_end;
138
139         mb_end = lseek(fd, 0, SEEK_END);
140         if (mb_end < 1)
141                 return -1;
142
143         /* init globals */
144         mbox_write_err = 0;
145         mbox_write_pos = 0;
146
147         /* headers */
148         struct hlist* ph;
149         char* pc;
150         LIST_FOREACH(ph, email->headers){
151                 for (pc = ph->name; *pc; pc++)
152                         write_char_to_mailbox(*pc, fd);
153                 write_char_to_mailbox(':', fd); 
154                 write_char_to_mailbox(' ', fd); 
155                 for (pc = ph->value; *pc; pc++)
156                         write_char_to_mailbox(*pc, fd); 
157                         write_char_to_mailbox('\n', fd);        
158         }
159
160         write_char_to_mailbox('\n', fd);
161         /* body */
162         //FIXME that nasty FROM
163         for (pc = email->body; *pc; pc++){
164                         write_char_to_mailbox(*pc, fd); 
165         }       
166
167         /* flush the buffer */
168         write_char_to_mailbox(0, fd);
169
170         /* errors? */
171         if (mbox_write_err)
172                 return -1;      
173
174         return 0; 
175 }
176
177 static int
178 deliver_local_email(char* folder, struct email* email)
179 {
180         int res = -1;
181         int is_default_mailbox = 0;
182         int fd;
183
184         if (!strcmp(default_mailbox, folder))   
185                 is_default_mailbox = 1;
186
187         fd = open_mailbox(folder, is_default_mailbox);
188         if (fd < 0){
189                 if (is_default_mailbox)
190                         return res;
191                 else /* try to save to default mailbox instead */
192                         return deliver_local_email(default_mailbox, email);
193         }
194
195         res = copy_email(fd, email);
196         if (res < 0){
197
198                 /* try to deliver to the default mailbox */
199                 if (is_default_mailbox)
200                         return res;
201                 else
202                         return deliver_local_email(default_mailbox, email);
203         }
204
205         close_mailbox(fd, folder, is_default_mailbox);  
206
207         return res; 
208 }
209
210 void
211 do_action(struct action* a)
212 {
213         /* -> address */
214         if (! a->r && !a->l ){
215                 deliver_local_email(a->s, &a->e);
216         }
217 }