]> git.deb.at Git - pkg/abook.git/blob - filter.c
0020fc201fd43158a7c3dd00d72ca5403d3c7fab
[pkg/abook.git] / filter.c
1
2 /*
3  * $Id$
4  *
5  * by JH <jheinonen@users.sourceforge.net>
6  *
7  * Copyright (C) Jaakko Heinonen
8  */
9
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <ctype.h>
14 #include <pwd.h>
15 #include <sys/stat.h>
16 #include <sys/types.h>
17 #include "abook_curses.h"
18 #include "filter.h"
19 #include "abook.h"
20 #include "database.h"
21 #include "edit.h"
22 #include "gettext.h"
23 #include "list.h"
24 #include "misc.h"
25 #include "options.h"
26 #include "ui.h"
27 #include "xmalloc.h"
28 #include <assert.h>
29
30 extern int items;
31 extern abook_field_list *fields_list;
32 extern int fields_count;
33
34 /*
35  * function declarations
36  */
37
38 /*
39  * import filter prototypes
40  */
41
42 static int      ldif_parse_file(FILE *handle);
43 static int      mutt_parse_file(FILE *in);
44 static int      pine_parse_file(FILE *in);
45 static int      csv_parse_file(FILE *in);
46 static int      allcsv_parse_file(FILE *in);
47 static int      palmcsv_parse_file(FILE *in);
48
49 /*
50  * export filter prototypes
51  */
52
53 static int      ldif_export_database(FILE *out, struct db_enumerator e);
54 static int      html_export_database(FILE *out, struct db_enumerator e);
55 static int      pine_export_database(FILE *out, struct db_enumerator e);
56 static int      csv_export_database(FILE *out, struct db_enumerator e);
57 static int      allcsv_export_database(FILE *out, struct db_enumerator e);
58 static int      palm_export_database(FILE *out, struct db_enumerator e);
59 static int      gcrd_export_database(FILE *out, struct db_enumerator e);
60 static int      mutt_alias_export(FILE *out, struct db_enumerator e);
61 static int      elm_alias_export(FILE *out, struct db_enumerator e);
62 static int      text_export_database(FILE *out, struct db_enumerator e);
63 static int      spruce_export_database(FILE *out, struct db_enumerator e);
64 static int      wl_export_database(FILE *out, struct db_enumerator e);
65
66 /*
67  * end of function declarations
68  */
69
70 struct abook_input_filter i_filters[] = {
71         { "abook", N_("abook native format"), parse_database },
72         { "ldif", N_("ldif / Netscape addressbook"), ldif_parse_file },
73         { "mutt", N_("mutt alias"), mutt_parse_file },
74         { "pine", N_("pine addressbook"), pine_parse_file },
75         { "csv", N_("comma separated values"), csv_parse_file },
76         { "allcsv", N_("comma separated values (all fields)"), allcsv_parse_file },
77         { "palmcsv", N_("Palm comma separated values"), palmcsv_parse_file },
78         { "\0", NULL, NULL }
79 };
80
81 struct abook_output_filter e_filters[] = {
82         { "abook", N_("abook native format"), write_database },
83         { "ldif", N_("ldif / Netscape addressbook (.4ld)"), ldif_export_database },
84         { "mutt", N_("mutt alias"), mutt_alias_export },
85         { "html", N_("html document"), html_export_database },
86         { "pine", N_("pine addressbook"), pine_export_database },
87         { "gcrd", N_("GnomeCard (VCard) addressbook"), gcrd_export_database },
88         { "csv", N_("comma separated values"), csv_export_database },
89         { "allcsv", N_("comma separated values (all fields)"), allcsv_export_database },
90         { "palmcsv", N_("Palm comma separated values"), palm_export_database},
91         { "elm", N_("elm alias"), elm_alias_export },
92         { "text", N_("plain text"), text_export_database },
93         { "wl", N_("Wanderlust address book"), wl_export_database },
94         { "spruce", N_("Spruce address book"), spruce_export_database },
95         { "\0", NULL, NULL }
96 };
97
98 /*
99  * common functions
100  */
101
102 void
103 print_filters()
104 {
105         int i;
106
107         puts(_("input:"));
108         for(i=0; *i_filters[i].filtname ; i++)
109                 printf("\t%s\t%s\n", i_filters[i].filtname,
110                         gettext(i_filters[i].desc));
111
112         putchar('\n');
113
114         puts(_("output:"));
115         for(i=0; *e_filters[i].filtname ; i++)
116                 printf("\t%s\t%s\n", e_filters[i].filtname,
117                         gettext(e_filters[i].desc));
118
119         putchar('\n');
120 }
121
122 static int
123 number_of_output_filters()
124 {
125         int i;
126
127         for(i=0; *e_filters[i].filtname ; i++)
128                 ;
129
130         return i;
131 }
132
133 static int
134 number_of_input_filters()
135 {
136         int i;
137
138         for(i=0; *i_filters[i].filtname ; i++)
139                 ;
140
141         return i;
142 }
143
144 static char *
145 get_real_name()
146 {
147         char *username = getenv("USER");
148         struct passwd *pwent;
149         int rtn;
150         char *tmp;
151
152         pwent = getpwnam(username);
153
154         if((tmp = xstrdup(pwent->pw_gecos)) == NULL)
155                 return xstrdup(username);
156
157         rtn = sscanf(pwent->pw_gecos, "%[^,]", tmp);
158         if (rtn == EOF || rtn == 0) {
159                 free(tmp);
160                 return xstrdup(username);
161         } else
162                 return tmp;
163 }
164
165 /*
166  * import
167  */
168
169 static int              i_read_file(char *filename, int (*func) (FILE *in));
170
171 static void
172 import_screen()
173 {
174         int i;
175
176         clear();
177
178         refresh_statusline();
179         headerline(_("import database"));
180
181         mvaddstr(3, 1, _("please select a filter"));
182
183
184         for(i=0; *i_filters[i].filtname ; i++)
185                 mvprintw(5 + i, 6, "%c -\t%s\t%s\n", 'a' + i,
186                         i_filters[i].filtname,
187                         gettext(i_filters[i].desc));
188
189         mvprintw(6 + i, 6, _("x -\tcancel"));
190 }
191
192 int
193 import_database()
194 {
195         int filter;
196         char *filename;
197         int tmp = items;
198
199         import_screen();
200
201         filter = getch() - 'a';
202         if(filter == 'x' - 'a' ||
203                 filter >= number_of_input_filters() || filter < 0) {
204                 refresh_screen();
205                 return 1;
206         }
207
208         mvaddstr(5+filter, 2, "->");
209
210         filename = ask_filename(_("Filename: "));
211         if(!filename) {
212                 refresh_screen();
213                 return 2;
214         }
215
216         if(i_read_file(filename, i_filters[filter].func ))
217                 statusline_msg(_("Error occured while opening the file"));
218         else if(tmp == items)
219                 statusline_msg(_("File does not seem to be a valid addressbook"));
220
221         refresh_screen();
222         free(filename);
223
224         return 0;
225 }
226
227
228
229 static int
230 i_read_file(char *filename, int (*func) (FILE *in))
231 {
232         FILE *in;
233         int ret = 0;
234
235         if( (in = abook_fopen( filename, "r" )) == NULL )
236                 return 1;
237
238         ret = (*func) (in);
239
240         fclose(in);
241
242         return ret;
243 }
244
245 int
246 import_file(char filtname[FILTNAME_LEN], char *filename)
247 {
248         int i;
249         int tmp = items;
250         int ret = 0;
251
252         for(i=0;; i++) {
253                 if(! strncasecmp(i_filters[i].filtname, filtname,
254                                         FILTNAME_LEN) )
255                         break;
256                 if(! *i_filters[i].filtname) {
257                         i = -1;
258                         break;
259                 }
260         }
261
262         if(i < 0)
263                 return -1;
264
265         if(!strcmp(filename, "-")) {
266                 struct stat s;
267                 if((fstat(fileno(stdin), &s)) == -1 || S_ISDIR(s.st_mode))
268                         ret = 1;
269                 else
270                         ret = (*i_filters[i].func) (stdin);
271         } else
272                 ret =  i_read_file(filename, i_filters[i].func);
273
274         if(tmp == items)
275                 ret = 1;
276
277         return ret;
278 }
279
280 /*
281  * export
282  */
283
284 static int e_write_file(char *filename,
285                 int (*func) (FILE *in, struct db_enumerator e), int mode);
286
287 static void
288 export_screen()
289 {
290         int i;
291
292         clear();
293
294
295         refresh_statusline();
296         headerline(_("export database"));
297
298         mvaddstr(3, 1, _("please select a filter"));
299
300
301         for(i = 0; *e_filters[i].filtname ; i++)
302                 mvprintw(5 + i, 6, "%c -\t%s\t%s\n", 'a' + i,
303                         e_filters[i].filtname,
304                         gettext(e_filters[i].desc));
305
306         mvprintw(6 + i, 6, _("x -\tcancel"));
307 }
308
309 int
310 export_database()
311 {
312         int filter;
313         int enum_mode = ENUM_ALL;
314         char *filename;
315
316         export_screen();
317
318         filter = getch() - 'a';
319         if(filter == 'x' - 'a' ||
320                 filter >= number_of_output_filters() || filter < 0) {
321                 refresh_screen();
322                 return 1;
323         }
324
325         mvaddstr(5 + filter, 2, "->");
326
327         if(selected_items()) {
328                 switch(statusline_askchoice(
329                         _("Export <a>ll, export <s>elected, or <c>ancel?"),
330                         S_("keybindings:all/selected/cancel|asc"), 3)) {
331                         case 1:
332                                 break;
333                         case 2:
334                                 enum_mode = ENUM_SELECTED;
335                                 break;
336                         case 0:
337                         case 3:
338                                 refresh_screen();
339                                 return 1;
340                 }
341                 clear_statusline();
342         }
343
344         filename = ask_filename(_("Filename: "));
345         if(!filename) {
346                 refresh_screen();
347                 return 2;
348         }
349
350         if( e_write_file(filename, e_filters[filter].func, enum_mode))
351                 statusline_msg(_("Error occured while exporting"));
352
353         refresh_screen();
354         free(filename);
355
356         return 0;
357 }
358
359 static int
360 e_write_file(char *filename, int (*func) (FILE *in, struct db_enumerator e),
361                 int mode)
362 {
363         FILE *out;
364         int ret = 0;
365         struct db_enumerator enumerator = init_db_enumerator(mode);
366
367         if((out = fopen(filename, "a")) == NULL)
368                 return 1;
369
370         if(ftell(out))
371                 return 1;
372
373         ret = (*func) (out, enumerator);
374
375         fclose(out);
376
377         return ret;
378 }
379
380 int
381 fexport(char filtname[FILTNAME_LEN], FILE *handle, int enum_mode)
382 {
383         int i;
384         struct db_enumerator e = init_db_enumerator(enum_mode);
385
386         for(i=0;; i++) {
387                 if(!strncasecmp(e_filters[i].filtname, filtname,
388                                         FILTNAME_LEN))
389                         break;
390                 if(!*e_filters[i].filtname) {
391                         i = -1;
392                         break;
393                 }
394         }
395
396         return (e_filters[i].func) (handle, e);
397 }
398
399
400
401 int
402 export_file(char filtname[FILTNAME_LEN], char *filename)
403 {
404         const int mode = ENUM_ALL;
405         int i;
406         int ret = 0;
407         struct db_enumerator e = init_db_enumerator(mode);
408
409         for(i=0;; i++) {
410                 if(!strncasecmp(e_filters[i].filtname, filtname,
411                                         FILTNAME_LEN))
412                         break;
413                 if(!*e_filters[i].filtname) {
414                         i = -1;
415                         break;
416                 }
417         }
418
419         if(i < 0)
420                 return -1;
421
422         if(!strcmp(filename, "-"))
423                 ret = (e_filters[i].func) (stdout, e);
424         else
425                 ret =  e_write_file(filename, e_filters[i].func, mode);
426
427         return ret;
428 }
429
430 /*
431  * end of common functions
432  */
433
434 /*
435  * ldif import
436  */
437
438 #include "ldif.h"
439
440 static void     ldif_fix_string(char *str);
441
442 #define LDIF_ITEM_FIELDS        16
443
444 typedef char *ldif_item[LDIF_ITEM_FIELDS];
445
446 static ldif_item ldif_field_names = {
447         "cn",
448         "mail",
449         "streetaddress",
450         "streetaddress2",
451         "locality",
452         "st",
453         "postalcode",
454         "countryname",
455         "homephone",
456         "description",
457         "homeurl",
458         "facsimiletelephonenumber",
459         "cellphone",
460         "xmozillaanyphone",
461         "xmozillanickname",
462         "objectclass", /* this must be the last entry */
463 };
464
465 static int ldif_conv_table[LDIF_ITEM_FIELDS] = {
466         NAME,           /* "cn" */
467         EMAIL,          /* "mail" */
468         ADDRESS,        /* "streetaddress" */
469         ADDRESS2,       /* "streetaddress2" */
470         CITY,           /* "locality" */
471         STATE,          /* "st" */
472         ZIP,            /* "postalcode" */
473         COUNTRY,        /* "countryname" */
474         PHONE,          /* "homephone" */
475         NOTES,          /* "description" */
476         URL,            /* "homeurl" */
477         FAX,            /* "facsimiletelephonenumber" */
478         MOBILEPHONE,    /* "cellphone" */
479         WORKPHONE,      /* "xmozillaanyphone" */
480         NICK,           /* "xmozillanickname" */
481         -1,             /* "objectclass" */ /* this must be the last entry */
482 };
483
484
485 static char *
486 ldif_read_line(FILE *in)
487 {
488         char *buf = NULL;
489         char *ptr, *tmp;
490         long pos;
491         int i;
492
493         for(i = 1;;i++) {
494                 char *line;
495
496                 pos = ftell(in);
497                 line = getaline(in);
498
499                 if(feof(in) || !line)
500                         break;
501
502                 if(i == 1) {
503                         buf = line;
504                         continue;
505                 }
506
507                 if(*line != ' ') {
508                         fseek(in, pos, SEEK_SET); /* fixme ! */
509                         free(line);
510                         break;
511                 }
512
513                 ptr = line;
514                 while( *ptr == ' ')
515                         ptr++;
516
517                 tmp = buf;
518                 buf = strconcat(buf, ptr, NULL);
519                 free(tmp);
520                 free(line);
521         }
522
523         if(buf && *buf == '#' ) {
524                 free(buf);
525                 return NULL;
526         }
527
528         return buf;
529 }
530
531 static void
532 ldif_add_item(ldif_item li)
533 {
534         list_item item;
535         int i;
536
537         item = item_create();
538
539         if(!li[LDIF_ITEM_FIELDS -1])
540                 goto bail_out;
541
542
543         for(i=0; i < LDIF_ITEM_FIELDS; i++) {
544                 if(ldif_conv_table[i] >= 0 && li[i] && *li[i])
545                         item_fput(item,ldif_conv_table[i],xstrdup(li[i]));
546         }
547
548         add_item2database(item);
549
550 bail_out:
551         for(i=0; i < LDIF_ITEM_FIELDS; i++)
552                 xfree(li[i]);
553         item_free(&item);
554
555 }
556
557 static void
558 ldif_convert(ldif_item item, char *type, char *value)
559 {
560         int i;
561
562         if(!strcmp(type, "dn")) {
563                 ldif_add_item(item);
564                 return;
565         }
566
567         for(i=0; i < LDIF_ITEM_FIELDS; i++) {
568                 if(!safe_strcmp(ldif_field_names[i], type) && *value) {
569                         if(i == LDIF_ITEM_FIELDS - 1) /* this is a dirty hack */
570                                 if(safe_strcmp("person", value))
571                                         break;
572
573                         if(item_fget(item, i))
574                                 free(item_fget(item, i));
575
576                         item_fput(item, i, xstrdup(value));
577                 }
578         }
579 }
580
581 static int
582 ldif_parse_file(FILE *handle)
583 {
584         char *line = NULL;
585         char *type, *value;
586         int vlen;
587         ldif_item item;
588
589         memset(item, 0, sizeof(item));
590
591         do {
592                 if( !(line = ldif_read_line(handle)) )
593                         continue;
594
595                 if(-1 == (str_parse_line(line, &type, &value, &vlen))) {
596                         xfree(line);
597                         continue; /* just skip the errors */
598                 }
599
600                 ldif_fix_string(value);
601
602                 ldif_convert(item, type, value);
603
604                 xfree(line);
605         } while ( !feof(handle) );
606
607         ldif_convert(item, "dn", "");
608
609         return 0;
610 }
611
612 static void
613 ldif_fix_string(char *str)
614 {
615         int i, j;
616
617         for(i = 0, j = 0; j < (int)strlen(str); i++, j++)
618                 str[i] = ( str[j] == (char)0xc3 ?
619                                 (char) str[++j] + (char) 0x40 :
620                                 str[j] );
621
622         str[i] = 0;
623 }
624
625 /*
626  * end of ldif import
627  */
628
629 /*
630  * mutt alias import filter
631  */
632
633 #include "getname.h"
634
635 static int
636 mutt_read_line(FILE *in, char **alias, char **rest)
637 {
638         char *line, *ptr, *tmp;
639         size_t alias_len;
640
641         if( !(line = ptr = getaline(in)) )
642                 return 1; /* error / EOF */
643
644         SKIPWS(ptr);
645
646         if(strncmp("alias", ptr, 5)) {
647                 free(line);
648                 return 1;
649         }
650
651         ptr += 5;
652
653         SKIPWS(ptr);
654
655         tmp = ptr;
656
657         while( ! ISSPACE(*ptr) )
658                 ptr++;
659
660         alias_len = (size_t)(ptr - tmp);
661
662         if(alias)
663                 *alias = xmalloc_inc(alias_len, 1);
664
665         strncpy(*alias, tmp, alias_len);
666         *(*alias + alias_len) = 0;
667
668         SKIPWS(ptr);
669
670         *rest = xstrdup(ptr);
671
672         free(line);
673         return 0;
674 }
675
676 static void
677 mutt_fix_quoting(char *p)
678 {
679         char *escape = 0;
680
681         for(; *p; p++) {
682                 switch(*p) {
683                         case '\"':
684                                 if(escape)
685                                         *escape = ' ';
686                                 break;
687                         case '\\':
688                                 escape = p;
689                                 break;
690                         default:
691                                 escape = 0;
692                 }
693         }
694 }
695
696 static void
697 mutt_parse_email(list_item item)
698 {
699         char *line = item_fget(item, NAME);
700         char *tmp;
701         char *name, *email;
702 #if 0
703         char *start = line;
704         int i = 0;
705 #endif
706
707         mutt_fix_quoting(line);
708         tmp = strconcat("From: ", line, NULL);
709         getname(tmp, &name, &email);
710         free(tmp);
711
712         if(name)
713                 item_fput(item, NAME, name);
714         else
715                 return;
716
717         if(email)
718                 item_fput(item, EMAIL, email);
719         else
720                 return;
721
722         /*
723          * this is completely broken
724          */
725 #if 0
726         while( (start = strchr(start, ',')) && i++ < MAX_EMAILS - 1) {
727                 tmp = strconcat("From: ", ++start, NULL);
728                 getname(tmp, &name, &email);
729                 free(tmp);
730                 free(name);
731                 if(email) {
732                         if(*email) {
733                                 tmp = strconcat(item[EMAIL], ",", email, NULL);
734                                 free(item[EMAIL]);
735                                 item[EMAIL] = tmp;
736                         } else {
737                                 xfree(email);
738                         }
739                 }
740         }
741 #endif
742 }
743
744 static int
745 mutt_parse_file(FILE *in)
746 {
747         list_item item = item_create();
748
749         for(;;) {
750                 memset(item, 0, fields_count * sizeof(char *));
751
752                 if(!mutt_read_line(in,
753                                         (field_id(NICK) != -1) ?
754                                         &item[field_id(NICK)] : NULL,
755                                         &item[field_id(NAME)]))
756                         mutt_parse_email(item);
757
758                 if(feof(in)) {
759                         item_empty(item);
760                         break;
761                 }
762
763                 add_item2database(item);
764         }
765         item_free(&item);
766
767         return 0;
768 }
769
770 /*
771  * end of mutt alias import filter
772  */
773
774
775 /*
776  * ldif export filter
777  */
778
779 static void
780 ldif_fput_type_and_value(FILE *out,char *type, char *value )
781 {
782         char *tmp;
783
784         tmp = ldif_type_and_value(type, value, strlen(value));
785
786         fputs(tmp, out);
787
788         free(tmp);
789 }
790
791 static int
792 ldif_export_database(FILE *out, struct db_enumerator e)
793 {
794         char email[MAX_EMAILSTR_LEN];
795
796         fprintf(out, "version: 1\n");
797
798         db_enumerate_items(e) {
799                 char *tmp;
800                 int j;
801                 get_first_email(email, e.item);
802
803                 tmp = strdup_printf("cn=%s,mail=%s",db_name_get(e.item),email);
804
805                 ldif_fput_type_and_value(out, "dn", tmp);
806                 free(tmp);
807
808                 for(j = 0; j < LDIF_ITEM_FIELDS; j++) {
809                         if(ldif_conv_table[j] >= 0) {
810                                 if(ldif_conv_table[j] == EMAIL)
811                                         ldif_fput_type_and_value(out,
812                                                 ldif_field_names[j], email);
813                                 else if(db_fget(e.item,ldif_conv_table[j]))
814                                         ldif_fput_type_and_value(out,
815                                                 ldif_field_names[j],
816                                                 db_fget(e.item,
817                                                         ldif_conv_table[j]));
818                         }
819                 }
820
821                 fprintf(out, "objectclass: top\n"
822                                 "objectclass: person\n\n");
823         }
824
825         return 0;
826 }
827
828 /*
829  * end of ldif export filter
830  */
831
832 /*
833  * html export filter
834  */
835
836 static void            html_export_write_head(FILE *out, int extra_column);
837 static void            html_export_write_tail(FILE *out);
838
839 static int
840 html_export_database(FILE *out, struct db_enumerator e)
841 {
842         char tmp[MAX_EMAILSTR_LEN];
843         int extra_column;
844
845         if(items < 1)
846                 return 2;
847
848         extra_column = init_extra_field(STR_EXTRA_COLUMN);
849         html_export_write_head(out, extra_column);
850
851         db_enumerate_items(e) {
852                 get_first_email(tmp, e.item);
853                 if (*tmp)
854                     fprintf(out, "<tr>\n<td>"
855                                     "<a href=\"mailto:%s\">%s</a>"
856                                     "</td>\n",
857                             tmp,
858                             db_name_get(e.item));
859                 else
860                     fprintf(out, "<tr>\n<td>%s</td>\n", db_name_get(e.item));
861
862                 fprintf(out, "<td>%s</td>\n", db_email_get(e.item));
863                 if(extra_column >= 0)
864                         fprintf(out, "<td>%s</td>\n",
865                                 safe_str(db_fget_byid(e.item, extra_column)));
866                 fprintf(out, "</tr>\n\n");
867         }
868
869         html_export_write_tail(out);
870
871         return 0;
872 }
873
874 static void
875 html_export_write_head(FILE *out, int extra_column)
876 {
877         char *realname = get_real_name(), *extra_column_name = NULL;
878
879         fprintf(out, "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n");
880         fprintf(out, "<html>\n<head>\n <title>%s's addressbook</title>",
881                         realname );
882         fprintf(out, "\n</head>\n<body>\n");
883         fprintf(out, "\n<h2>%s's addressbook</h2>\n", realname );
884         fprintf(out, "<br><br>\n\n");
885
886         fprintf(out, "<table border=\"1\" align=\"center\">\n");
887         fprintf(out, "\n<tr><th>Name</th><th>E-mail address(es)</th>");
888         if(extra_column >= 0) {
889                 get_field_keyname(extra_column, NULL, &extra_column_name);
890                 fprintf(out, "<th>%s</th>", safe_str(extra_column_name));
891         }
892         fprintf(out, "</tr>\n\n");
893
894         free(realname);
895 }
896
897 static void
898 html_export_write_tail(FILE *out)
899 {
900         fprintf(out, "\n</table>\n");
901         fprintf(out, "\n</body>\n</html>\n");
902 }
903
904 /*
905  * end of html export filter
906  */
907
908
909 /*
910  * pine addressbook import filter
911  */
912
913 #define PINE_BUF_SIZE 2048
914
915 static void
916 pine_fixbuf(char *buf)
917 {
918         int i,j;
919
920         for(i=0,j=0; j < (int)strlen(buf); i++, j++)
921                 buf[i] = buf[j] == '\n' ? buf[++j] : buf[j];
922 }
923
924 static void
925 pine_convert_emails(char *s)
926 {
927         int i;
928         char *tmp;
929
930         if(s == NULL || *s != '(')
931                 return;
932
933         for(i=0; s[i]; i++ )
934                 s[i] = s[i+1];
935
936         if( ( tmp = strchr(s,')')) )
937                 *tmp=0;
938
939         for(i = 1; ( tmp = strchr(s, ',') ) != NULL ; i++, s = tmp + 1)
940                 if(i > MAX_LIST_ITEMS - 1) {
941                         *tmp = 0;
942                         break;
943                 }
944
945 }
946
947 static void
948 pine_parse_buf(char *buf)
949 {
950         list_item item;
951         char *start = buf;
952         char *end;
953         char tmp[PINE_BUF_SIZE];
954         int i, len, last;
955         int pine_conv_table[]= {NICK, NAME, EMAIL, -1, NOTES};
956
957         item = item_create();
958
959         for(i=0, last=0; !last ; i++) {
960                 if( !(end = strchr(start, '\t')) )
961                         last=1;
962
963                 len = last ? strlen(start) : (int) (end-start);
964                 len = min(len, PINE_BUF_SIZE - 1);
965
966                 if(i < (int)(sizeof(pine_conv_table) / sizeof(*pine_conv_table))
967                                 && pine_conv_table[i] >= 0) {
968                         strncpy(tmp, start, len);
969                         tmp[len] = 0;
970                         if(*tmp)
971                                 item_fput(item, pine_conv_table[i],
972                                                 xstrdup(tmp));
973                 }
974                 start = end + 1;
975         }
976
977         pine_convert_emails(item_fget(item, EMAIL));
978         add_item2database(item);
979         item_free(&item);
980 }
981
982
983 #define LINESIZE        1024
984
985 static int
986 pine_parse_file(FILE *in)
987 {
988         char line[LINESIZE];
989         char *buf = NULL;
990         char *ptr;
991         int i;
992
993         fgets(line, LINESIZE, in);
994
995         while(!feof(in)) {
996                 for(i = 2;;i++) {
997                         buf = xrealloc(buf, i*LINESIZE);
998                         if(i == 2)
999                                 strcpy(buf, line);
1000                         fgets(line, LINESIZE, in);
1001                         ptr=(char *)&line;
1002                         if(*ptr != ' ' || feof(in))
1003                                 break;
1004                         else
1005                                 while(*ptr == ' ')
1006                                         ptr++;
1007
1008                         strcat(buf, ptr);
1009                 }
1010                 if(*buf == '#') {
1011                         xfree(buf);
1012                         continue;
1013                 }
1014                 pine_fixbuf(buf);
1015
1016                 pine_parse_buf(buf);
1017
1018                 xfree(buf);
1019         }
1020
1021         return 0;
1022 }
1023
1024 /*
1025  * end of pine addressbook import filter
1026  */
1027
1028
1029 /*
1030  * pine addressbook export filter
1031  *
1032  *  filter doesn't wrap the lines as it should but Pine seems to handle
1033  *  created files without problems - JH
1034  */
1035
1036 static int
1037 pine_export_database(FILE *out, struct db_enumerator e)
1038 {
1039         db_enumerate_items(e) {
1040                 fprintf(out, have_multiple_emails(e.item) ?
1041                                 "%s\t%s\t(%s)\t\t%s\n" : "%s\t%s\t%s\t\t%s\n",
1042                                 safe_str(db_fget(e.item, NICK)),
1043                                 safe_str(db_name_get(e.item)),
1044                                 safe_str(db_email_get(e.item)),
1045                                 safe_str(db_fget(e.item, NOTES))
1046                                 );
1047         }
1048
1049         return 0;
1050 }
1051
1052 /*
1053  * end of pine addressbook export filter
1054  */
1055
1056
1057 /*
1058  * csv import filter
1059  */
1060
1061 /* FIXME
1062  * these files should be parsed according to a certain
1063  * lay out, or the default if layout is not given, at
1064  * the moment only default is done...
1065  */
1066
1067 #define CSV_COMMENT_CHAR        '#'
1068 #define CSV_DUPLICATE_SEPARATOR " "
1069 #define CSV_TABLE_SIZE(t)       (sizeof (t) / sizeof *(t))
1070
1071 static int csv_conv_table[] = {
1072         NAME,
1073         EMAIL,
1074         PHONE,
1075         NOTES,
1076         NICK
1077 };
1078
1079 static int allcsv_conv_table[] = {
1080         NAME,
1081         EMAIL,
1082         ADDRESS,
1083         ADDRESS2,
1084         CITY,
1085         STATE,
1086         ZIP,
1087         COUNTRY,
1088         PHONE,
1089         WORKPHONE,
1090         FAX,
1091         MOBILEPHONE,
1092         NICK,
1093         URL,
1094         NOTES,
1095         ANNIVERSARY
1096 };
1097
1098 static int palmcsv_conv_table[] = {
1099         NAME,           /* Last name */
1100         NAME,           /* First name */
1101         NOTES,          /* Title */
1102         NICK,           /* Company */
1103         WORKPHONE,
1104         PHONE,
1105         FAX,
1106         MOBILEPHONE,
1107         EMAIL,
1108         ADDRESS,
1109         CITY,
1110         STATE,
1111         ZIP,
1112         COUNTRY,
1113         ANNIVERSARY,
1114 };
1115
1116 static void
1117 csv_convert_emails(char *s)
1118 {
1119         int i;
1120         char *tmp;
1121
1122         if(s == NULL)
1123                 return;
1124
1125         for(i = 1; ( tmp = strchr(s, ',') ) != NULL ; i++, s = tmp + 1)
1126                 if(i > MAX_LIST_ITEMS - 1) {
1127                         *tmp = 0;
1128                         break;
1129                 }
1130
1131 }
1132
1133 static char *
1134 csv_remove_quotes(char *s)
1135 {
1136         char *copy, *trimmed;
1137         int len;
1138
1139         copy = trimmed = xstrdup(s);
1140         strtrim(trimmed);
1141
1142         len = strlen(trimmed);
1143         if(trimmed[len - 1] == '\"' && *trimmed == '\"') {
1144                 if(len < 3) {
1145                         xfree(copy);
1146                         return NULL;
1147                 }
1148                 trimmed[len - 1] = 0;
1149                 trimmed++;
1150                 trimmed = xstrdup(trimmed);
1151                 free(copy);
1152                 return trimmed;
1153         }
1154
1155         xfree(copy);
1156         return xstrdup(s);
1157 }
1158
1159 static int
1160 csv_field_to_item(int *table_base, size_t table_size, int field)
1161 {
1162         if(field < table_size)
1163                 return field_id(table_base[field]);
1164
1165         return -1;
1166 }
1167
1168 static void
1169 csv_store_item(list_item item, int i, char *s)
1170 {
1171         char *newstr = NULL;
1172
1173         if(!s || !*s)
1174                 return;
1175
1176         if( !(newstr = csv_remove_quotes(s)) )
1177                 return;
1178
1179         if(i >= 0) {
1180                 if (item[i] != NULL) {
1181                         char *oldstr = item[i];
1182
1183                         item[i] = strconcat(newstr, CSV_DUPLICATE_SEPARATOR,
1184                                 oldstr, NULL);
1185                         xfree(newstr);
1186                         xfree(oldstr);
1187                 } else {
1188                         item[i] = newstr;
1189                 }
1190         } else {
1191                 xfree(newstr);
1192         }
1193 }
1194
1195 static int
1196 csv_is_valid_quote_end(char *p)
1197 {
1198         if(*p != '\"')
1199                 return FALSE;
1200
1201         for(p++; *p; p++) {
1202                 if(*p == ',')
1203                         return TRUE;
1204                 else if(!ISSPACE(*p))
1205                         return FALSE;
1206         }
1207
1208         return TRUE;
1209 }
1210
1211 static int
1212 csv_is_valid_quote_start(char *p)
1213 {
1214         for(; *p; p++) {
1215                 if(*p == '\"')
1216                         return TRUE;
1217                 else if(!ISSPACE(*p))
1218                         return FALSE;
1219         }
1220
1221         return FALSE;
1222 }
1223
1224 static void
1225 csv_parse_line(char *line, int *table_base, size_t table_size)
1226 {
1227         char *p, *start;
1228         int field;
1229         bool in_quote = FALSE;
1230         list_item item;
1231
1232         item = item_create();
1233
1234         for(p = start = line, field = 0; *p; p++) {
1235                 if(in_quote) {
1236                         if(csv_is_valid_quote_end(p))
1237                                 in_quote = FALSE;
1238                 } else {
1239                         if ( (((p - start) / sizeof (char)) < 2 ) &&
1240                                 csv_is_valid_quote_start(p) )
1241                                 in_quote = TRUE;
1242                 }
1243
1244                 if(*p == ',' && !in_quote) {
1245                         *p = 0;
1246                         csv_store_item(item,
1247                                 csv_field_to_item(table_base,table_size,field),
1248                                 start);
1249                         field++;
1250                         start = p + 1;
1251                 }
1252         }
1253         /*
1254          * store last field
1255          */
1256         csv_store_item(item, csv_field_to_item(table_base, table_size, field),
1257                 start);
1258
1259         csv_convert_emails(item_fget(item, EMAIL));
1260         add_item2database(item);
1261         item_free(&item);
1262 }
1263
1264 static int
1265 csv_parse_file_common(FILE *in, int *conv_table, size_t table_size)
1266 {
1267         char *line = NULL;
1268
1269         while(!feof(in)) {
1270                 line = getaline(in);
1271
1272                 if(line && *line && *line != CSV_COMMENT_CHAR)
1273                         csv_parse_line(line, conv_table, table_size);
1274
1275                 xfree(line);
1276         }
1277
1278         return 0;
1279 }
1280
1281 static int
1282 csv_parse_file(FILE *in)
1283 {
1284         return csv_parse_file_common(in, csv_conv_table,
1285                 CSV_TABLE_SIZE(csv_conv_table));
1286 }
1287
1288 static int
1289 allcsv_parse_file(FILE *in)
1290 {
1291         return csv_parse_file_common(in, allcsv_conv_table,
1292                 CSV_TABLE_SIZE(allcsv_conv_table));
1293 }
1294
1295 static int
1296 palmcsv_parse_file(FILE *in)
1297 {
1298         return csv_parse_file_common(in, palmcsv_conv_table,
1299                 CSV_TABLE_SIZE(palmcsv_conv_table));
1300 }
1301
1302 /*
1303  * end of csv import filter
1304  */
1305
1306 /*
1307  * csv addressbook export filters
1308  */
1309
1310 #define CSV_LAST                (-1)
1311 #define CSV_UNDEFINED           (-2)
1312 #define CSV_SPECIAL(X)          (-3 - (X))
1313 #define CSV_IS_SPECIAL(X)       ((X) <= -3)
1314
1315 static int
1316 csv_export_common(FILE *out, struct db_enumerator e,
1317                 int fields[], void (*special_func)(FILE *, int, int))
1318 {
1319         int i;
1320
1321         db_enumerate_items(e) {
1322                 for(i = 0; fields[i] != CSV_LAST; i++) {
1323                         if(fields[i] == CSV_UNDEFINED)
1324                                 fprintf(out, "\"\"");
1325                         else if(CSV_IS_SPECIAL(fields[i])) {
1326                                 if(special_func)
1327                                         (*special_func)(out, e.item, fields[i]);
1328                         } else
1329                                 /*fprintf(out,(
1330                         strchr(safe_str(database[e.item][field_idx(fields[i])]), ',') ||
1331                         strchr(safe_str(database[e.item][field_idx(fields[i])]), '\"')) ?
1332                                 "\"%s\"" : "%s",
1333                                 safe_str(database[e.item][field_idx(fields[i])])
1334                                 );*/
1335                                 fprintf(out, "\"%s\"",
1336                                         safe_str(db_fget(e.item,fields[i])));
1337
1338                         if(fields[i + 1] != CSV_LAST)
1339                                 fputc(',', out);
1340                 }
1341                 fputc('\n', out);
1342         }
1343
1344         return 0;
1345 }
1346
1347 static int
1348 csv_export_database(FILE *out, struct db_enumerator e)
1349 {
1350         int csv_export_fields[] = {
1351                 NAME,
1352                 EMAIL,
1353                 PHONE,
1354                 NOTES,
1355                 NICK,
1356                 CSV_LAST
1357         };
1358
1359         csv_export_common(out, e, csv_export_fields, NULL);
1360
1361         return 0;
1362 }
1363
1364 static int
1365 allcsv_export_database(FILE *out, struct db_enumerator e)
1366 {
1367         /*
1368          * TODO: Should get these atomatically from abook_fileds
1369          *  - JH
1370          */
1371         int allcsv_export_fields[] = {
1372                 NAME,
1373                 EMAIL,
1374                 ADDRESS,
1375                 ADDRESS2,
1376                 CITY,
1377                 STATE,
1378                 ZIP,
1379                 COUNTRY,
1380                 PHONE,
1381                 WORKPHONE,
1382                 FAX,
1383                 MOBILEPHONE,
1384                 NICK,
1385                 URL,
1386                 NOTES,
1387                 ANNIVERSARY,
1388                 CSV_LAST
1389         };
1390
1391         fprintf(out, "#");
1392         fprintf(out, "\"NAME\",");
1393         fprintf(out, "\"EMAIL\",");
1394         fprintf(out, "\"ADDRESS\",");
1395         fprintf(out, "\"ADDRESS2\",");
1396         fprintf(out, "\"CITY\",");
1397         fprintf(out, "\"STATE\",");
1398         fprintf(out, "\"ZIP\",");
1399         fprintf(out, "\"COUNTRY\",");
1400         fprintf(out, "\"PHONE\",");
1401         fprintf(out, "\"WORKPHONE\",");
1402         fprintf(out, "\"FAX\",");
1403         fprintf(out, "\"MOBILEPHONE\",");
1404         fprintf(out, "\"NICK\",");
1405         fprintf(out, "\"URL\",");
1406         fprintf(out, "\"NOTES\",");
1407         fprintf(out, "\"ANNIVERSARY\"\n");
1408
1409         csv_export_common(out, e, allcsv_export_fields, NULL);
1410
1411         return 0;
1412 }
1413
1414 /*
1415  * palm csv
1416  */
1417
1418 #define PALM_CSV_NAME   CSV_SPECIAL(0)
1419 #define PALM_CSV_END    CSV_SPECIAL(1)
1420 #define PALM_CSV_CAT    CSV_SPECIAL(2)
1421
1422 static void
1423 palm_split_and_write_name(FILE *out, char *name)
1424 {
1425         char *p;
1426
1427         assert(name);
1428
1429         if ( (p = strchr(name, ' ')) ) {
1430                 /*
1431                  * last name first
1432                  */
1433                 fprintf(out, "\"%s\",\"" , p + 1);
1434                 fwrite((void *)name, p - name, sizeof(char), out);
1435                 fputc('\"', out);
1436         } else {
1437                 fprintf(out, "\"%s\"", safe_str(name));
1438         }
1439 }
1440
1441 static void
1442 palm_csv_handle_specials(FILE *out, int item, int field)
1443 {
1444         switch(field) {
1445                 case PALM_CSV_NAME:
1446                         palm_split_and_write_name(out, db_name_get(item));
1447                         break;
1448                 case PALM_CSV_CAT:
1449                         fprintf(out, "\"abook\"");
1450                         break;
1451                 case PALM_CSV_END:
1452                         fprintf(out, "\"0\"");
1453                         break;
1454                 default:
1455                         assert(0);
1456         }
1457 }
1458
1459 static int
1460 palm_export_database(FILE *out, struct db_enumerator e)
1461 {
1462         int palm_export_fields[] = {
1463                 PALM_CSV_NAME,          /* LASTNAME, FIRSTNAME  */
1464                 CSV_UNDEFINED,          /* TITLE                */
1465                 CSV_UNDEFINED,          /* COMPANY              */
1466                 WORKPHONE,              /* WORK PHONE           */
1467                 PHONE,                  /* HOME PHONE           */
1468                 FAX,                    /* FAX                  */
1469                 MOBILEPHONE,            /* OTHER                */
1470                 EMAIL,                  /* EMAIL                */
1471                 ADDRESS,                /* ADDRESS              */
1472                 CITY,                   /* CITY                 */
1473                 STATE,                  /* STATE                */
1474                 ZIP,                    /* ZIP                  */
1475                 COUNTRY,                /* COUNTRY              */
1476                 NICK,                   /* DEFINED 1            */
1477                 URL,                    /* DEFINED 2            */
1478                 CSV_UNDEFINED,          /* DEFINED 3            */
1479                 CSV_UNDEFINED,          /* DEFINED 4            */
1480                 NOTES,                  /* NOTE                 */
1481                 PALM_CSV_END,           /* "0"                  */
1482                 PALM_CSV_CAT,           /* CATEGORY             */
1483                 CSV_LAST
1484         };
1485
1486         csv_export_common(out, e, palm_export_fields, palm_csv_handle_specials);
1487
1488         return 0;
1489 }
1490
1491 /*
1492  * end of csv export filters
1493  */
1494
1495 /*
1496  * GnomeCard (VCard) addressbook export filter
1497  */
1498
1499 static int
1500 gcrd_export_database(FILE *out, struct db_enumerator e)
1501 {
1502         int j;
1503         char *name;
1504         abook_list *emails, *em;
1505
1506         db_enumerate_items(e) {
1507                 fprintf(out, "BEGIN:VCARD\nFN:%s\n",
1508                                 safe_str(db_name_get(e.item)));
1509
1510                 name = get_surname(db_name_get(e.item));
1511                 for( j = strlen(db_name_get(e.item)) - 1; j >= 0; j-- ) {
1512                         if((db_name_get(e.item))[j] == ' ')
1513                                 break;
1514                 }
1515                 fprintf(out, "N:%s;%.*s\n",
1516                         safe_str(name),
1517                         j,
1518                         safe_str(db_name_get(e.item))
1519                         );
1520
1521                 free(name);
1522
1523                 if(db_fget(e.item, ADDRESS))
1524                         fprintf(out, "ADR:;;%s;%s;%s;%s;%s;%s\n",
1525                                 safe_str(db_fget(e.item, ADDRESS)),
1526                                 safe_str(db_fget(e.item, ADDRESS2)),
1527                                 safe_str(db_fget(e.item, CITY)),
1528                                 safe_str(db_fget(e.item, STATE)),
1529                                 safe_str(db_fget(e.item, ZIP)),
1530                                 safe_str(db_fget(e.item, COUNTRY))
1531                                 );
1532
1533                 if(db_fget(e.item, PHONE))
1534                         fprintf(out, "TEL;HOME:%s\n",
1535                                         db_fget(e.item, PHONE));
1536                 if(db_fget(e.item, WORKPHONE))
1537                         fprintf(out, "TEL;WORK:%s\n",
1538                                         db_fget(e.item, WORKPHONE));
1539                 if(db_fget(e.item, FAX))
1540                         fprintf(out, "TEL;FAX:%s\n",
1541                                         db_fget(e.item, FAX));
1542                 if(db_fget(e.item, MOBILEPHONE))
1543                         fprintf(out, "TEL;CELL:%s\n",
1544                                         db_fget(e.item, MOBILEPHONE));
1545
1546                 if(*db_email_get(e.item)) {
1547                         emails = csv_to_abook_list(db_email_get(e.item));
1548
1549                         for(em = emails; em; em = em->next)
1550                                 fprintf(out, "EMAIL;INTERNET:%s\n", em->data);
1551
1552                         abook_list_free(&emails);
1553                 }
1554
1555                 if(db_fget(e.item, NOTES))
1556                         fprintf(out, "NOTE:%s\n",
1557                                         db_fget(e.item, NOTES));
1558                 if(db_fget(e.item, URL))
1559                         fprintf(out, "URL:%s\n",
1560                                         db_fget(e.item, URL));
1561
1562                 fprintf(out, "END:VCARD\n\n");
1563
1564         }
1565
1566         return 0;
1567 }
1568
1569 /*
1570  * end of GnomeCard export filter
1571  */
1572
1573
1574 /*
1575  * mutt alias export filter
1576  */
1577
1578 static char *
1579 mutt_alias_genalias(int i)
1580 {
1581         char *tmp, *pos;
1582
1583         if(db_fget(i, NICK))
1584                 return xstrdup(db_fget(i, NICK));
1585
1586         tmp = xstrdup(db_name_get(i));
1587
1588         if( ( pos = strchr(tmp, ' ') ) )
1589                 *pos = 0;
1590
1591         strlower(tmp);
1592
1593         return tmp;
1594 }
1595
1596 static int
1597 mutt_alias_export(FILE *out, struct db_enumerator e)
1598 {
1599         char email[MAX_EMAIL_LEN];
1600         char *alias = NULL;
1601
1602         db_enumerate_items(e) {
1603                 alias = mutt_alias_genalias(e.item);
1604                 get_first_email(email, e.item);
1605                 fprintf(out, *email ? "alias %s %s <%s>\n": "alias %s %s%s\n",
1606                                 alias,
1607                                 db_name_get(e.item),
1608                                 email);
1609                 xfree(alias);
1610         }
1611
1612         return 0;
1613 }
1614
1615 /*
1616  * end of mutt alias export filter
1617  */
1618
1619
1620 /*
1621  * printable export filter
1622  */
1623
1624
1625 static void
1626 text_write_address_us(FILE *out, int i) {
1627         fprintf(out, "\n%s", db_fget(i, ADDRESS));
1628
1629         if(db_fget(i, ADDRESS2))
1630                 fprintf(out, "\n%s", db_fget(i, ADDRESS2));
1631
1632         if(db_fget(i, CITY))
1633                 fprintf(out, "\n%s", db_fget(i, CITY));
1634
1635         if(db_fget(i, STATE) || db_fget(i, ZIP)) {
1636                 fputc('\n', out);
1637
1638                 if(db_fget(i, STATE)) {
1639                         fprintf(out, "%s", db_fget(i, STATE));
1640                         if(db_fget(i, ZIP))
1641                                 fputc(' ', out);
1642                 }
1643
1644                 if(db_fget(i, ZIP))
1645                         fprintf(out, "%s", db_fget(i, ZIP));
1646         }
1647
1648         if(db_fget(i, COUNTRY))
1649                 fprintf(out, "\n%s", db_fget(i, COUNTRY));
1650 }
1651
1652
1653 static void
1654 text_write_address_uk(FILE *out, int i) {
1655         int j;
1656
1657         for(j = ADDRESS; j <= COUNTRY; j++)
1658                 if(db_fget(i, j))
1659                         fprintf(out, "\n%s", db_fget(i, j));
1660 }
1661
1662 static void
1663 text_write_address_eu(FILE *out, int i) {
1664         fprintf(out, "\n%s", db_fget(i, ADDRESS));
1665
1666         if(db_fget(i, ADDRESS2))
1667                 fprintf(out, "\n%s", db_fget(i, ADDRESS2));
1668
1669         if(db_fget(i, ZIP) || db_fget(i, CITY)) {
1670                 fputc('\n', out);
1671
1672                 if(db_fget(i, ZIP)) {
1673                         fprintf(out, "%s", db_fget(i, ZIP));
1674                         if(db_fget(i, CITY))
1675                                 fputc(' ', out);
1676                 }
1677
1678                 fprintf(out, "%s", safe_str(db_fget(i, CITY)));
1679         }
1680
1681         if(db_fget(i, STATE))
1682                 fprintf(out, "\n%s", db_fget(i, STATE));
1683
1684         if(db_fget(i, COUNTRY))
1685                 fprintf(out, "\n%s", db_fget(i, COUNTRY));
1686 }
1687
1688 static int
1689 text_export_database(FILE * out, struct db_enumerator e)
1690 {
1691         abook_list *emails, *em;
1692         int j;
1693         char *realname = get_real_name(), *str = NULL;
1694         char *style = opt_get_str(STR_ADDRESS_STYLE);
1695
1696         fprintf(out,
1697                 "-----------------------------------------\n%s's address book\n"
1698                 "-----------------------------------------\n\n\n",
1699                 realname);
1700         free(realname);
1701
1702         db_enumerate_items(e) {
1703                 fprintf(out,
1704                         "-----------------------------------------\n\n");
1705                 fprintf(out, "%s", db_name_get(e.item));
1706                 if(db_fget(e.item, NICK) && *db_fget(e.item, NICK))
1707                         fprintf(out, "\n(%s)", db_fget(e.item, NICK));
1708                 fprintf(out, "\n");
1709
1710                 if(*db_email_get(e.item)) {
1711                         emails = csv_to_abook_list(db_email_get(e.item));
1712
1713                         fprintf(out, "\n");
1714                         for(em = emails; em; em = em->next)
1715                                 fprintf(out, "%s\n", em->data);
1716
1717                         abook_list_free(&emails);
1718                 }
1719                 /* Print address */
1720                 if(db_fget(e.item, ADDRESS)) {
1721                         if(!safe_strcmp(style, "us"))   /* US like */
1722                                 text_write_address_us(out, e.item);
1723                         else if(!safe_strcmp(style, "uk"))      /* UK like */
1724                                 text_write_address_uk(out, e.item);
1725                         else    /* EU like */
1726                                 text_write_address_eu(out, e.item);
1727
1728                         fprintf(out, "\n");
1729                 }
1730
1731                 if((db_fget(e.item, PHONE)) ||
1732                         (db_fget(e.item, WORKPHONE)) ||
1733                         (db_fget(e.item, FAX)) ||
1734                         (db_fget(e.item, MOBILEPHONE))) {
1735                         fprintf(out, "\n");
1736                         for(j = PHONE; j <= MOBILEPHONE; j++)
1737                                 if(db_fget(e.item, j)) {
1738                                         get_field_keyname(field_id(j),
1739                                                         NULL, &str);
1740                                         fprintf(out, "%s: %s\n", str,
1741                                                 db_fget(e.item, j));
1742                                 }
1743                 }
1744
1745                 if(db_fget(e.item, URL))
1746                         fprintf(out, "\n%s\n", db_fget(e.item, URL));
1747                 if(db_fget(e.item, NOTES))
1748                         fprintf(out, "\n%s\n", db_fget(e.item, NOTES));
1749
1750                 fprintf(out, "\n");
1751         }
1752
1753         fprintf(out, "-----------------------------------------\n");
1754
1755         return 0;
1756 }
1757
1758 /*
1759  * end of printable export filter
1760  */
1761
1762 /*
1763  * elm alias export filter
1764  */
1765
1766 static int
1767 elm_alias_export(FILE *out, struct db_enumerator e)
1768 {
1769         char email[MAX_EMAIL_LEN];
1770         char *alias = NULL;
1771
1772         db_enumerate_items(e) {
1773                 alias = mutt_alias_genalias(e.item);
1774                 get_first_email(email, e.item);
1775                 fprintf(out, "%s = %s = %s\n",alias,db_name_get(e.item),email);
1776                 xfree(alias);
1777         }
1778
1779         return 0;
1780 }
1781
1782 /*
1783  * end of elm alias export filter
1784  */
1785
1786
1787 /*
1788  * Spruce export filter
1789  */
1790
1791 static int
1792 spruce_export_database (FILE *out, struct db_enumerator e)
1793 {
1794         char email[MAX_EMAIL_LEN];
1795
1796         fprintf(out, "# This is a generated file made by abook for the Spruce e-mail client.\n\n");
1797
1798         db_enumerate_items(e) {
1799                 if(strcmp(safe_str(db_email_get(e.item)), "")) {
1800                         get_first_email(email, e.item);
1801                         fprintf(out, "# Address %d\nName: %s\nEmail: %s\nMemo: %s\n\n",
1802                                         e.item,
1803                                         db_name_get(e.item),
1804                                         email,
1805                                         safe_str(db_fget(e.item, NOTES))
1806                                         );
1807                 }
1808         }
1809
1810         fprintf (out, "# End of address book file.\n");
1811
1812         return 0;
1813 }
1814
1815 /*
1816  * end of Spruce export filter
1817  */
1818
1819 /*
1820  * wanderlust addressbook export filter
1821  */
1822
1823 static int
1824 wl_export_database(FILE *out, struct db_enumerator e)
1825 {
1826         abook_list *emails;
1827
1828         fprintf(out, "# Wanderlust address book written by %s\n\n", PACKAGE);
1829         db_enumerate_items(e) {
1830                 if((emails = csv_to_abook_list(db_email_get(e.item))) != NULL) {
1831                         fprintf(out,
1832                                 "%s\t\"%s\"\t\"%s\"\n",
1833                                 emails->data,
1834                                 safe_str(db_fget(e.item, NICK)),
1835                                 safe_str(db_name_get(e.item))
1836                         );
1837                 }
1838                 abook_list_free(&emails);
1839         }
1840
1841         fprintf (out, "\n# End of address book file.\n");
1842
1843         return 0;
1844 }
1845
1846 /*
1847  * end of wanderlust addressbook export filter
1848  */
1849