* Replaced serv_gets() with serv_getln() - which now requires the caller
[citadel.git] / webcit / vcard_edit.c
1 /*
2  * $Id$
3  *
4  * Handles editing of vCard objects.
5  *
6  */
7
8 #include <ctype.h>
9 #include <stdlib.h>
10 #include <unistd.h>
11 #include <stdio.h>
12 #include <fcntl.h>
13 #include <signal.h>
14 #include <sys/types.h>
15 #include <sys/wait.h>
16 #include <sys/socket.h>
17 #include <sys/time.h>
18 #include <limits.h>
19 #include <netinet/in.h>
20 #include <netdb.h>
21 #include <string.h>
22 #include <pwd.h>
23 #include <errno.h>
24 #include <stdarg.h>
25 #include <pthread.h>
26 #include <signal.h>
27 #include "webcit.h"
28 #include "vcard.h"
29
30
31 /* Edit the vCard component of a MIME message.  Supply the message number
32  * and MIME part number to fetch.  Or, specify -1 for the message number
33  * to start with a blank card.
34  */
35 void do_edit_vcard(long msgnum, char *partnum, char *return_to) {
36         char buf[SIZ];
37         char *serialized_vcard = NULL;
38         size_t total_len = 0;
39         struct vCard *v;
40         int i;
41         char *key, *value;
42         char whatuser[SIZ];
43
44         char lastname[SIZ];
45         char firstname[SIZ];
46         char middlename[SIZ];
47         char prefix[SIZ];
48         char suffix[SIZ];
49         char pobox[SIZ];
50         char extadr[SIZ];
51         char street[SIZ];
52         char city[SIZ];
53         char state[SIZ];
54         char zipcode[SIZ];
55         char country[SIZ];
56         char hometel[SIZ];
57         char worktel[SIZ];
58         char primary_inetemail[SIZ];
59         char other_inetemail[SIZ];
60         char extrafields[SIZ];
61         char title[SIZ];
62         char org[SIZ];
63
64         lastname[0] = 0;
65         firstname[0] = 0;
66         middlename[0] = 0;
67         prefix[0] = 0;
68         suffix[0] = 0;
69         pobox[0] = 0;
70         extadr[0] = 0;
71         street[0] = 0;
72         city[0] = 0;
73         state[0] = 0;
74         zipcode[0] = 0;
75         country[0] = 0;
76         hometel[0] = 0;
77         worktel[0] = 0;
78         primary_inetemail[0] = 0;
79         other_inetemail[0] = 0;
80         title[0] = 0;
81         org[0] = 0;
82         extrafields[0] = 0;
83
84         strcpy(whatuser, "");
85
86         if (msgnum >= 0) {
87                 sprintf(buf, "MSG0 %ld|1", msgnum);
88                 serv_puts(buf);
89                 serv_getln(buf, sizeof buf);
90                 if (buf[0] != '1') {
91                         convenience_page("770000", "Error", &buf[4]);
92                         return;
93                 }
94                 while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
95                         if (!strncasecmp(buf, "from=", 5)) {
96                                 strcpy(whatuser, &buf[5]);
97                         }
98                         else if (!strncasecmp(buf, "node=", 5)) {
99                                 strcat(whatuser, " @ ");
100                                 strcat(whatuser, &buf[5]);
101                         }
102                 }
103         
104                 sprintf(buf, "OPNA %ld|%s", msgnum, partnum);
105                 serv_puts(buf);
106                 serv_getln(buf, sizeof buf);
107                 if (buf[0] != '2') {
108                         convenience_page("770000", "Error", &buf[4]);
109                         return;
110                 }
111         
112                 total_len = atoi(&buf[4]);
113                 serialized_vcard = malloc(total_len + 2);
114         
115                 read_server_binary(serialized_vcard, total_len);
116         
117                 serv_puts("CLOS");
118                 serv_getln(buf, sizeof buf);
119                 serialized_vcard[total_len] = 0;
120         
121                 v = vcard_load(serialized_vcard);
122                 free(serialized_vcard);
123         
124                 /* Populate the variables for our form */
125                 i = 0;
126                 while (key = vcard_get_prop(v, "", 0, i, 1), key != NULL) {
127                         value = vcard_get_prop(v, "", 0, i++, 0);
128         
129                         if (!strcasecmp(key, "n")) {
130                                 extract_token(lastname, value, 0, ';', sizeof lastname);
131                                 extract_token(firstname, value, 1, ';', sizeof firstname);
132                                 extract_token(middlename, value, 2, ';', sizeof middlename);
133                                 extract_token(prefix, value, 3, ';', sizeof prefix);
134                                 extract_token(suffix, value, 4, ';', sizeof suffix);
135                         }
136
137                         else if (!strcasecmp(key, "title")) {
138                                 strcpy(title, value);
139                         }
140         
141                         else if (!strcasecmp(key, "org")) {
142                                 strcpy(org, value);
143                         }
144         
145                         else if (!strcasecmp(key, "adr")) {
146                                 extract_token(pobox, value, 0, ';', sizeof pobox);
147                                 extract_token(extadr, value, 1, ';', sizeof extadr);
148                                 extract_token(street, value, 2, ';', sizeof street);
149                                 extract_token(city, value, 3, ';', sizeof city);
150                                 extract_token(state, value, 4, ';', sizeof state);
151                                 extract_token(zipcode, value, 5, ';', sizeof zipcode);
152                                 extract_token(country, value, 6, ';', sizeof country);
153                         }
154         
155                         else if (!strcasecmp(key, "tel;home")) {
156                                 extract_token(hometel, value, 0, ';', sizeof hometel);
157                         }
158         
159                         else if (!strcasecmp(key, "tel;work")) {
160                                 extract_token(worktel, value, 0, ';', sizeof worktel);
161                         }
162         
163                         else if (!strcasecmp(key, "email;internet")) {
164                                 if (primary_inetemail[0] == 0) {
165                                         strcpy(primary_inetemail, value);
166                                 }
167                                 else {
168                                         if (other_inetemail[0] != 0) {
169                                                 strcat(other_inetemail, "\n");
170                                         }
171                                         strcat(other_inetemail, value);
172                                 }
173                         }
174         
175                         else {
176                                 strcat(extrafields, key);
177                                 strcat(extrafields, ":");
178                                 strcat(extrafields, value);
179                                 strcat(extrafields, "\n");
180                         }
181         
182                 }
183         
184                 vcard_free(v);
185         }
186
187         /* Display the form */
188         output_headers(1, 1, 2, 0, 0, 0, 0);
189         wprintf("<div id=\"banner\">\n"
190                 "<TABLE WIDTH=100%% BORDER=0 BGCOLOR=\"#444455\"><TR><TD>"
191                 "<SPAN CLASS=\"titlebar\">"
192                 "<img src=\"/static/vcard.gif\">"
193                 "Edit contact information"
194                 "</SPAN>"
195                 "</TD></TR></TABLE>\n"
196                 "</div>\n<div id=\"content\">\n"
197         );
198
199         wprintf("<FORM METHOD=\"POST\" ACTION=\"/submit_vcard\">\n");
200         wprintf("<div id=\"fix_scrollbar_bug\">"
201                 "<table border=0 width=100%% bgcolor=\"#ffffff\"><tr><td>\n");
202
203         wprintf("<TABLE border=0><TR>"
204                 "<TD>Prefix</TD>"
205                 "<TD>First</TD>"
206                 "<TD>Middle</TD>"
207                 "<TD>Last</TD>"
208                 "<TD>Suffix</TD></TR>\n");
209         wprintf("<TR><TD><INPUT TYPE=\"text\" NAME=\"prefix\" "
210                 "VALUE=\"%s\" MAXLENGTH=\"5\" SIZE=\"5\"></TD>",
211                 prefix);
212         wprintf("<TD><INPUT TYPE=\"text\" NAME=\"firstname\" "
213                 "VALUE=\"%s\" MAXLENGTH=\"29\"></TD>",
214                 firstname);
215         wprintf("<TD><INPUT TYPE=\"text\" NAME=\"middlename\" "
216                 "VALUE=\"%s\" MAXLENGTH=\"29\"></TD>",
217                 middlename);
218         wprintf("<TD><INPUT TYPE=\"text\" NAME=\"lastname\" "
219                 "VALUE=\"%s\" MAXLENGTH=\"29\"></TD>",
220                 lastname);
221         wprintf("<TD><INPUT TYPE=\"text\" NAME=\"suffix\" "
222                 "VALUE=\"%s\" MAXLENGTH=\"10\" SIZE=\"10\"></TD></TR></TABLE>\n",
223                 suffix);
224
225         wprintf("<table border=0 width=100%% bgcolor=\"#dddddd\">");
226         wprintf("<tr><td>");
227
228         wprintf("Title:<br>"
229                 "<INPUT TYPE=\"text\" NAME=\"title\" "
230                 "VALUE=\"%s\" MAXLENGTH=\"40\"><br><br>\n",
231                 title
232         );
233
234         wprintf("Organization:<br>"
235                 "<INPUT TYPE=\"text\" NAME=\"org\" "
236                 "VALUE=\"%s\" MAXLENGTH=\"40\"><br><br>\n",
237                 org
238         );
239
240         wprintf("</td><td>");
241
242         wprintf("<table border=0>");
243         wprintf("<tr><td>PO box:</td><td>"
244                 "<INPUT TYPE=\"text\" NAME=\"pobox\" "
245                 "VALUE=\"%s\" MAXLENGTH=\"29\"></td></tr>\n",
246                 pobox);
247         wprintf("<tr><td>Address:</td><td>"
248                 "<INPUT TYPE=\"text\" NAME=\"extadr\" "
249                 "VALUE=\"%s\" MAXLENGTH=\"29\"></td></tr>\n",
250                 extadr);
251         wprintf("<tr><td> </td><td>"
252                 "<INPUT TYPE=\"text\" NAME=\"street\" "
253                 "VALUE=\"%s\" MAXLENGTH=\"29\"></td></tr>\n",
254                 street);
255         wprintf("<tr><td>City:</td><td>"
256                 "<INPUT TYPE=\"text\" NAME=\"city\" "
257                 "VALUE=\"%s\" MAXLENGTH=\"29\"></td></tr>\n",
258                 city);
259         wprintf("<tr><td>State:</td><td>"
260                 "<INPUT TYPE=\"text\" NAME=\"state\" "
261                 "VALUE=\"%s\" MAXLENGTH=\"2\"></td></tr>\n",
262                 state);
263         wprintf("<tr><td>ZIP code:</td><td>"
264                 "<INPUT TYPE=\"text\" NAME=\"zipcode\" "
265                 "VALUE=\"%s\" MAXLENGTH=\"10\"></td></tr>\n",
266                 zipcode);
267         wprintf("<tr><td>Country:</td><td>"
268                 "<INPUT TYPE=\"text\" NAME=\"country\" "
269                 "VALUE=\"%s\" MAXLENGTH=\"29\" WIDTH=\"5\"></td></tr>\n",
270                 country);
271         wprintf("</table>\n");
272
273         wprintf("</table>\n");
274
275         wprintf("<TABLE BORDER=0><TR><TD>Home telephone:</TD>"
276                 "<TD><INPUT TYPE=\"text\" NAME=\"hometel\" "
277                 "VALUE=\"%s\" MAXLENGTH=\"29\"></TD>\n",
278                 hometel);
279         wprintf("<TD>Work telephone:</TD>"
280                 "<TD><INPUT TYPE=\"text\" NAME=\"worktel\" "
281                 "VALUE=\"%s\" MAXLENGTH=\"29\"></TD></TR></TABLE>\n",
282                 worktel);
283
284         wprintf("<table border=0 width=100%% bgcolor=\"#dddddd\">");
285         wprintf("<tr><td>");
286
287         wprintf("<TABLE border=0><TR>"
288                 "<TD VALIGN=TOP>Primary Internet e-mail address<br />"
289                 "<INPUT TYPE=\"text\" NAME=\"primary_inetemail\" "
290                 "SIZE=40 MAXLENGTH=40 VALUE=\"");
291         escputs(primary_inetemail);
292         wprintf("\"><br />"
293                 "</TD><TD VALIGN=TOP>"
294                 "Internet e-mail aliases<br />"
295                 "<TEXTAREA NAME=\"other_inetemail\" ROWS=5 COLS=40 WIDTH=40>");
296         escputs(other_inetemail);
297         wprintf("</TEXTAREA></TD></TR></TABLE>\n");
298
299         wprintf("</td></tr></table>\n");
300
301         wprintf("<INPUT TYPE=\"hidden\" NAME=\"extrafields\" VALUE=\"");
302         escputs(extrafields);
303         wprintf("\">\n");
304
305         wprintf("<INPUT TYPE=\"hidden\" NAME=\"return_to\" VALUE=\"");
306         urlescputs(return_to);
307         wprintf("\">\n");
308
309         wprintf("<CENTER>\n"
310                 "<INPUT TYPE=\"submit\" NAME=\"sc\" VALUE=\"OK\">"
311                 "&nbsp;"
312                 "<INPUT TYPE=\"submit\" NAME=\"sc\" VALUE=\"Cancel\">"
313                 "</CENTER></FORM>\n"
314         );
315         
316         wprintf("</td></tr></table></div>\n");
317         wDumpContent(1);
318 }
319
320
321
322 void edit_vcard(void) {
323         long msgnum;
324         char *partnum;
325
326         msgnum = atol(bstr("msgnum"));
327         partnum = bstr("partnum");
328         do_edit_vcard(msgnum, partnum, "");
329 }
330
331
332
333
334 void submit_vcard(void) {
335         char buf[SIZ];
336         int i;
337
338         if (strcmp(bstr("sc"), "OK")) { 
339                 readloop("readnew");
340                 return;
341         }
342
343         sprintf(buf, "ENT0 1|||4||");
344         serv_puts(buf);
345         serv_getln(buf, sizeof buf);
346         if (buf[0] != '4') {
347                 edit_vcard();
348                 return;
349         }
350
351         serv_puts("Content-type: text/x-vcard");
352         serv_puts("");
353         serv_puts("begin:vcard");
354         serv_printf("n:%s;%s;%s;%s;%s",
355                 bstr("lastname"),
356                 bstr("firstname"),
357                 bstr("middlename"),
358                 bstr("prefix"),
359                 bstr("suffix") );
360         serv_printf("title:%s", bstr("title") );
361         serv_printf("org:%s", bstr("org") );
362         serv_printf("adr:%s;%s;%s;%s;%s;%s;%s",
363                 bstr("pobox"),
364                 bstr("extadr"),
365                 bstr("street"),
366                 bstr("city"),
367                 bstr("state"),
368                 bstr("zipcode"),
369                 bstr("country") );
370         serv_printf("tel;home:%s", bstr("hometel") );
371         serv_printf("tel;work:%s", bstr("worktel") );
372
373         serv_printf("email;internet:%s\n", bstr("primary_inetemail"));  
374         for (i=0; i<num_tokens(bstr("other_inetemail"), '\n'); ++i) {
375                 extract_token(buf, bstr("other_inetemail"), i, '\n', sizeof buf);
376                 if (strlen(buf) > 0) {
377                         serv_printf("email;internet:%s", buf);
378                 }
379         }
380
381         serv_printf("%s", bstr("extrafields") );
382         serv_puts("end:vcard");
383         serv_puts("000");
384
385         if (!strcmp(bstr("return_to"), "/select_user_to_edit")) {
386                 select_user_to_edit(NULL, NULL);
387         }
388         else if (!strcmp(bstr("return_to"), "/do_welcome")) {
389                 do_welcome();
390         }
391         else {
392                 readloop("readnew");
393         }
394 }