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