]> git.deb.at Git - pkg/abook.git/blob - filter.c
Imported Upstream version 0.5.6+cvs1
[pkg/abook.git] / filter.c
1
2 /*
3  * $Id: filter.c,v 1.53 2006/08/07 19:20:26 cduval Exp $
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], *emails;
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                 emails = db_email_get(e.item);
862                 fprintf(out, "<td>%s</td>\n", emails);
863                 free(emails);
864                 if(extra_column >= 0)
865                         fprintf(out, "<td>%s</td>\n",
866                                 safe_str(db_fget_byid(e.item, extra_column)));
867                 fprintf(out, "</tr>\n\n");
868         }
869
870         html_export_write_tail(out);
871
872         return 0;
873 }
874
875 static void
876 html_export_write_head(FILE *out, int extra_column)
877 {
878         char *realname = get_real_name(), *extra_column_name = NULL;
879
880         fprintf(out, "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n");
881         fprintf(out, "<html>\n<head>\n <title>%s's addressbook</title>",
882                         realname );
883         fprintf(out, "\n</head>\n<body>\n");
884         fprintf(out, "\n<h2>%s's addressbook</h2>\n", realname );
885         fprintf(out, "<br><br>\n\n");
886
887         fprintf(out, "<table border=\"1\" align=\"center\">\n");
888         fprintf(out, "\n<tr><th>Name</th><th>E-mail address(es)</th>");
889         if(extra_column >= 0) {
890                 get_field_keyname(extra_column, NULL, &extra_column_name);
891                 fprintf(out, "<th>%s</th>", safe_str(extra_column_name));
892         }
893         fprintf(out, "</tr>\n\n");
894
895         free(realname);
896 }
897
898 static void
899 html_export_write_tail(FILE *out)
900 {
901         fprintf(out, "\n</table>\n");
902         fprintf(out, "\n</body>\n</html>\n");
903 }
904
905 /*
906  * end of html export filter
907  */
908
909
910 /*
911  * pine addressbook import filter
912  */
913
914 #define PINE_BUF_SIZE 2048
915
916 static void
917 pine_fixbuf(char *buf)
918 {
919         int i,j;
920
921         for(i = 0,j = 0; j < (int)strlen(buf); i++, j++)
922                 buf[i] = buf[j] == '\n' ? buf[++j] : buf[j];
923 }
924
925 static void
926 pine_convert_emails(char *s)
927 {
928         int i;
929         char *tmp;
930
931         if(s == NULL || *s != '(')
932                 return;
933
934         for(i = 0; s[i]; i++)
935                 s[i] = s[i + 1];
936
937         if( ( tmp = strchr(s,')')) )
938                 *tmp = '\0';
939
940         for(i = 1; ( tmp = strchr(s, ',') ) != NULL ; i++, s = tmp + 1)
941                 if(i > MAX_LIST_ITEMS - 1) {
942                         *tmp = '\0';
943                         break;
944                 }
945
946 }
947
948 static void
949 pine_parse_buf(char *buf)
950 {
951         list_item item;
952         char *start = buf;
953         char *end;
954         char tmp[PINE_BUF_SIZE];
955         int i, len, last;
956         int pine_conv_table[]= {NICK, NAME, EMAIL, -1, NOTES};
957
958         item = item_create();
959
960         for(i=0, last=0; !last ; i++) {
961                 if( !(end = strchr(start, '\t')) )
962                         last=1;
963
964                 len = last ? strlen(start) : (int) (end-start);
965                 len = min(len, PINE_BUF_SIZE - 1);
966
967                 if(i < (int)(sizeof(pine_conv_table) / sizeof(*pine_conv_table))
968                                 && pine_conv_table[i] >= 0) {
969                         strncpy(tmp, start, len);
970                         tmp[len] = 0;
971                         if(*tmp)
972                                 item_fput(item, pine_conv_table[i],
973                                                 xstrdup(tmp));
974                 }
975                 start = end + 1;
976         }
977
978         pine_convert_emails(item_fget(item, EMAIL));
979         add_item2database(item);
980         item_free(&item);
981 }
982
983
984 #define LINESIZE        1024
985
986 static int
987 pine_parse_file(FILE *in)
988 {
989         char line[LINESIZE];
990         char *buf = NULL;
991         char *ptr;
992         int i;
993
994         fgets(line, LINESIZE, in);
995
996         while(!feof(in)) {
997                 for(i = 2;;i++) {
998                         buf = xrealloc(buf, i*LINESIZE);
999                         if(i == 2)
1000                                 strcpy(buf, line);
1001                         fgets(line, LINESIZE, in);
1002                         ptr=(char *)&line;
1003                         if(*ptr != ' ' || feof(in))
1004                                 break;
1005                         else
1006                                 while(*ptr == ' ')
1007                                         ptr++;
1008
1009                         strcat(buf, ptr);
1010                 }
1011                 if(*buf == '#') {
1012                         xfree(buf);
1013                         continue;
1014                 }
1015                 pine_fixbuf(buf);
1016
1017                 pine_parse_buf(buf);
1018
1019                 xfree(buf);
1020         }
1021
1022         return 0;
1023 }
1024
1025 /*
1026  * end of pine addressbook import filter
1027  */
1028
1029
1030 /*
1031  * pine addressbook export filter
1032  *
1033  *  filter doesn't wrap the lines as it should but Pine seems to handle
1034  *  created files without problems - JH
1035  */
1036
1037 static int
1038 pine_export_database(FILE *out, struct db_enumerator e)
1039 {
1040         char *emails;
1041
1042         db_enumerate_items(e) {
1043                 emails = db_email_get(e.item);
1044                 fprintf(out, strchr(emails, ',') /* multiple addresses? */ ?
1045                                 "%s\t%s\t(%s)\t\t%s\n" : "%s\t%s\t%s\t\t%s\n",
1046                                 safe_str(db_fget(e.item, NICK)),
1047                                 safe_str(db_name_get(e.item)),
1048                                 emails,
1049                                 safe_str(db_fget(e.item, NOTES))
1050                                 );
1051                 free(emails);
1052         }
1053
1054         return 0;
1055 }
1056
1057 /*
1058  * end of pine addressbook export filter
1059  */
1060
1061
1062 /*
1063  * csv import filter
1064  */
1065
1066 /* FIXME
1067  * these files should be parsed according to a certain
1068  * lay out, or the default if layout is not given, at
1069  * the moment only default is done...
1070  */
1071
1072 #define CSV_COMMENT_CHAR        '#'
1073 #define CSV_DUPLICATE_SEPARATOR " "
1074 #define CSV_TABLE_SIZE(t)       (sizeof (t) / sizeof *(t))
1075
1076 static int csv_conv_table[] = {
1077         NAME,
1078         EMAIL,
1079         PHONE,
1080         NOTES,
1081         NICK
1082 };
1083
1084 static int allcsv_conv_table[] = {
1085         NAME,
1086         EMAIL,
1087         ADDRESS,
1088         ADDRESS2,
1089         CITY,
1090         STATE,
1091         ZIP,
1092         COUNTRY,
1093         PHONE,
1094         WORKPHONE,
1095         FAX,
1096         MOBILEPHONE,
1097         NICK,
1098         URL,
1099         NOTES,
1100         ANNIVERSARY
1101 };
1102
1103 static int palmcsv_conv_table[] = {
1104         NAME,           /* Last name */
1105         NAME,           /* First name */
1106         NOTES,          /* Title */
1107         NICK,           /* Company */
1108         WORKPHONE,
1109         PHONE,
1110         FAX,
1111         MOBILEPHONE,
1112         EMAIL,
1113         ADDRESS,
1114         CITY,
1115         STATE,
1116         ZIP,
1117         COUNTRY,
1118         ANNIVERSARY,
1119 };
1120
1121 static void
1122 csv_convert_emails(char *s)
1123 {
1124         int i;
1125         char *tmp;
1126
1127         if(s == NULL)
1128                 return;
1129
1130         for(i = 1; ( tmp = strchr(s, ',') ) != NULL ; i++, s = tmp + 1)
1131                 if(i > MAX_LIST_ITEMS - 1) {
1132                         *tmp = 0;
1133                         break;
1134                 }
1135
1136 }
1137
1138 static char *
1139 csv_remove_quotes(char *s)
1140 {
1141         char *copy, *trimmed;
1142         int len;
1143
1144         copy = trimmed = xstrdup(s);
1145         strtrim(trimmed);
1146
1147         len = strlen(trimmed);
1148         if(trimmed[len - 1] == '\"' && *trimmed == '\"') {
1149                 if(len < 3) {
1150                         xfree(copy);
1151                         return NULL;
1152                 }
1153                 trimmed[len - 1] = 0;
1154                 trimmed++;
1155                 trimmed = xstrdup(trimmed);
1156                 free(copy);
1157                 return trimmed;
1158         }
1159
1160         xfree(copy);
1161         return xstrdup(s);
1162 }
1163
1164 static int
1165 csv_field_to_item(int *table_base, size_t table_size, int field)
1166 {
1167         if(field < table_size)
1168                 return field_id(table_base[field]);
1169
1170         return -1;
1171 }
1172
1173 static void
1174 csv_store_item(list_item item, int i, char *s)
1175 {
1176         char *newstr = NULL;
1177
1178         if(!s || !*s)
1179                 return;
1180
1181         if( !(newstr = csv_remove_quotes(s)) )
1182                 return;
1183
1184         if(i >= 0) {
1185                 if (item[i] != NULL) {
1186                         char *oldstr = item[i];
1187
1188                         item[i] = strconcat(newstr, CSV_DUPLICATE_SEPARATOR,
1189                                 oldstr, NULL);
1190                         xfree(newstr);
1191                         xfree(oldstr);
1192                 } else {
1193                         item[i] = newstr;
1194                 }
1195         } else {
1196                 xfree(newstr);
1197         }
1198 }
1199
1200 static int
1201 csv_is_valid_quote_end(char *p)
1202 {
1203         if(*p != '\"')
1204                 return FALSE;
1205
1206         for(p++; *p; p++) {
1207                 if(*p == ',')
1208                         return TRUE;
1209                 else if(!ISSPACE(*p))
1210                         return FALSE;
1211         }
1212
1213         return TRUE;
1214 }
1215
1216 static int
1217 csv_is_valid_quote_start(char *p)
1218 {
1219         for(; *p; p++) {
1220                 if(*p == '\"')
1221                         return TRUE;
1222                 else if(!ISSPACE(*p))
1223                         return FALSE;
1224         }
1225
1226         return FALSE;
1227 }
1228
1229 static void
1230 csv_parse_line(char *line, int *table_base, size_t table_size)
1231 {
1232         char *p, *start;
1233         int field;
1234         bool in_quote = FALSE;
1235         list_item item;
1236
1237         item = item_create();
1238
1239         for(p = start = line, field = 0; *p; p++) {
1240                 if(in_quote) {
1241                         if(csv_is_valid_quote_end(p))
1242                                 in_quote = FALSE;
1243                 } else {
1244                         if ( (((p - start) / sizeof (char)) < 2 ) &&
1245                                 csv_is_valid_quote_start(p) )
1246                                 in_quote = TRUE;
1247                 }
1248
1249                 if(*p == ',' && !in_quote) {
1250                         *p = 0;
1251                         csv_store_item(item,
1252                                 csv_field_to_item(table_base,table_size,field),
1253                                 start);
1254                         field++;
1255                         start = p + 1;
1256                 }
1257         }
1258         /*
1259          * store last field
1260          */
1261         csv_store_item(item, csv_field_to_item(table_base, table_size, field),
1262                 start);
1263
1264         csv_convert_emails(item_fget(item, EMAIL));
1265         add_item2database(item);
1266         item_free(&item);
1267 }
1268
1269 static int
1270 csv_parse_file_common(FILE *in, int *conv_table, size_t table_size)
1271 {
1272         char *line = NULL;
1273
1274         while(!feof(in)) {
1275                 line = getaline(in);
1276
1277                 if(line && *line && *line != CSV_COMMENT_CHAR)
1278                         csv_parse_line(line, conv_table, table_size);
1279
1280                 xfree(line);
1281         }
1282
1283         return 0;
1284 }
1285
1286 static int
1287 csv_parse_file(FILE *in)
1288 {
1289         return csv_parse_file_common(in, csv_conv_table,
1290                 CSV_TABLE_SIZE(csv_conv_table));
1291 }
1292
1293 static int
1294 allcsv_parse_file(FILE *in)
1295 {
1296         return csv_parse_file_common(in, allcsv_conv_table,
1297                 CSV_TABLE_SIZE(allcsv_conv_table));
1298 }
1299
1300 static int
1301 palmcsv_parse_file(FILE *in)
1302 {
1303         return csv_parse_file_common(in, palmcsv_conv_table,
1304                 CSV_TABLE_SIZE(palmcsv_conv_table));
1305 }
1306
1307 /*
1308  * end of csv import filter
1309  */
1310
1311 /*
1312  * csv addressbook export filters
1313  */
1314
1315 #define CSV_LAST                (-1)
1316 #define CSV_UNDEFINED           (-2)
1317 #define CSV_SPECIAL(X)          (-3 - (X))
1318 #define CSV_IS_SPECIAL(X)       ((X) <= -3)
1319
1320 static int
1321 csv_export_common(FILE *out, struct db_enumerator e,
1322                 int fields[], void (*special_func)(FILE *, int, int))
1323 {
1324         int i;
1325
1326         db_enumerate_items(e) {
1327                 for(i = 0; fields[i] != CSV_LAST; i++) {
1328                         if(fields[i] == CSV_UNDEFINED)
1329                                 fprintf(out, "\"\"");
1330                         else if(CSV_IS_SPECIAL(fields[i])) {
1331                                 if(special_func)
1332                                         (*special_func)(out, e.item, fields[i]);
1333                         } else
1334                                 /*fprintf(out,(
1335                         strchr(safe_str(database[e.item][field_idx(fields[i])]), ',') ||
1336                         strchr(safe_str(database[e.item][field_idx(fields[i])]), '\"')) ?
1337                                 "\"%s\"" : "%s",
1338                                 safe_str(database[e.item][field_idx(fields[i])])
1339                                 );*/
1340                                 fprintf(out, "\"%s\"",
1341                                         safe_str(db_fget(e.item,fields[i])));
1342
1343                         if(fields[i + 1] != CSV_LAST)
1344                                 fputc(',', out);
1345                 }
1346                 fputc('\n', out);
1347         }
1348
1349         return 0;
1350 }
1351
1352 static int
1353 csv_export_database(FILE *out, struct db_enumerator e)
1354 {
1355         int csv_export_fields[] = {
1356                 NAME,
1357                 EMAIL,
1358                 PHONE,
1359                 NOTES,
1360                 NICK,
1361                 CSV_LAST
1362         };
1363
1364         csv_export_common(out, e, csv_export_fields, NULL);
1365
1366         return 0;
1367 }
1368
1369 static int
1370 allcsv_export_database(FILE *out, struct db_enumerator e)
1371 {
1372         /*
1373          * TODO: Should get these atomatically from abook_fileds
1374          *  - JH
1375          */
1376         int allcsv_export_fields[] = {
1377                 NAME,
1378                 EMAIL,
1379                 ADDRESS,
1380                 ADDRESS2,
1381                 CITY,
1382                 STATE,
1383                 ZIP,
1384                 COUNTRY,
1385                 PHONE,
1386                 WORKPHONE,
1387                 FAX,
1388                 MOBILEPHONE,
1389                 NICK,
1390                 URL,
1391                 NOTES,
1392                 ANNIVERSARY,
1393                 CSV_LAST
1394         };
1395
1396         fprintf(out, "#");
1397         fprintf(out, "\"NAME\",");
1398         fprintf(out, "\"EMAIL\",");
1399         fprintf(out, "\"ADDRESS\",");
1400         fprintf(out, "\"ADDRESS2\",");
1401         fprintf(out, "\"CITY\",");
1402         fprintf(out, "\"STATE\",");
1403         fprintf(out, "\"ZIP\",");
1404         fprintf(out, "\"COUNTRY\",");
1405         fprintf(out, "\"PHONE\",");
1406         fprintf(out, "\"WORKPHONE\",");
1407         fprintf(out, "\"FAX\",");
1408         fprintf(out, "\"MOBILEPHONE\",");
1409         fprintf(out, "\"NICK\",");
1410         fprintf(out, "\"URL\",");
1411         fprintf(out, "\"NOTES\",");
1412         fprintf(out, "\"ANNIVERSARY\"\n");
1413
1414         csv_export_common(out, e, allcsv_export_fields, NULL);
1415
1416         return 0;
1417 }
1418
1419 /*
1420  * palm csv
1421  */
1422
1423 #define PALM_CSV_NAME   CSV_SPECIAL(0)
1424 #define PALM_CSV_END    CSV_SPECIAL(1)
1425 #define PALM_CSV_CAT    CSV_SPECIAL(2)
1426
1427 static void
1428 palm_split_and_write_name(FILE *out, char *name)
1429 {
1430         char *p;
1431
1432         assert(name);
1433
1434         if ( (p = strchr(name, ' ')) ) {
1435                 /*
1436                  * last name first
1437                  */
1438                 fprintf(out, "\"%s\",\"" , p + 1);
1439                 fwrite((void *)name, p - name, sizeof(char), out);
1440                 fputc('\"', out);
1441         } else {
1442                 fprintf(out, "\"%s\"", safe_str(name));
1443         }
1444 }
1445
1446 static void
1447 palm_csv_handle_specials(FILE *out, int item, int field)
1448 {
1449         switch(field) {
1450                 case PALM_CSV_NAME:
1451                         palm_split_and_write_name(out, db_name_get(item));
1452                         break;
1453                 case PALM_CSV_CAT:
1454                         fprintf(out, "\"abook\"");
1455                         break;
1456                 case PALM_CSV_END:
1457                         fprintf(out, "\"0\"");
1458                         break;
1459                 default:
1460                         assert(0);
1461         }
1462 }
1463
1464 static int
1465 palm_export_database(FILE *out, struct db_enumerator e)
1466 {
1467         int palm_export_fields[] = {
1468                 PALM_CSV_NAME,          /* LASTNAME, FIRSTNAME  */
1469                 CSV_UNDEFINED,          /* TITLE                */
1470                 CSV_UNDEFINED,          /* COMPANY              */
1471                 WORKPHONE,              /* WORK PHONE           */
1472                 PHONE,                  /* HOME PHONE           */
1473                 FAX,                    /* FAX                  */
1474                 MOBILEPHONE,            /* OTHER                */
1475                 EMAIL,                  /* EMAIL                */
1476                 ADDRESS,                /* ADDRESS              */
1477                 CITY,                   /* CITY                 */
1478                 STATE,                  /* STATE                */
1479                 ZIP,                    /* ZIP                  */
1480                 COUNTRY,                /* COUNTRY              */
1481                 NICK,                   /* DEFINED 1            */
1482                 URL,                    /* DEFINED 2            */
1483                 CSV_UNDEFINED,          /* DEFINED 3            */
1484                 CSV_UNDEFINED,          /* DEFINED 4            */
1485                 NOTES,                  /* NOTE                 */
1486                 PALM_CSV_END,           /* "0"                  */
1487                 PALM_CSV_CAT,           /* CATEGORY             */
1488                 CSV_LAST
1489         };
1490
1491         csv_export_common(out, e, palm_export_fields, palm_csv_handle_specials);
1492
1493         return 0;
1494 }
1495
1496 /*
1497  * end of csv export filters
1498  */
1499
1500 /*
1501  * GnomeCard (VCard) addressbook export filter
1502  */
1503
1504 static int
1505 gcrd_export_database(FILE *out, struct db_enumerator e)
1506 {
1507         int j;
1508         char *name, *tmp;
1509         abook_list *emails, *em;
1510
1511         db_enumerate_items(e) {
1512                 fprintf(out, "BEGIN:VCARD\r\nFN:%s\r\n",
1513                                 safe_str(db_name_get(e.item)));
1514
1515                 name = get_surname(db_name_get(e.item));
1516                 for( j = strlen(db_name_get(e.item)) - 1; j >= 0; j-- ) {
1517                         if((db_name_get(e.item))[j] == ' ')
1518                                 break;
1519                 }
1520                 fprintf(out, "N:%s;%.*s\r\n",
1521                         safe_str(name),
1522                         j,
1523                         safe_str(db_name_get(e.item))
1524                         );
1525
1526                 free(name);
1527
1528                 if(db_fget(e.item, ADDRESS))
1529                         fprintf(out, "ADR:;;%s;%s;%s;%s;%s;%s\r\n",
1530                                 safe_str(db_fget(e.item, ADDRESS)),
1531                                 safe_str(db_fget(e.item, ADDRESS2)),
1532                                 safe_str(db_fget(e.item, CITY)),
1533                                 safe_str(db_fget(e.item, STATE)),
1534                                 safe_str(db_fget(e.item, ZIP)),
1535                                 safe_str(db_fget(e.item, COUNTRY))
1536                                 );
1537
1538                 if(db_fget(e.item, PHONE))
1539                         fprintf(out, "TEL;HOME:%s\r\n",
1540                                         db_fget(e.item, PHONE));
1541                 if(db_fget(e.item, WORKPHONE))
1542                         fprintf(out, "TEL;WORK:%s\r\n",
1543                                         db_fget(e.item, WORKPHONE));
1544                 if(db_fget(e.item, FAX))
1545                         fprintf(out, "TEL;FAX:%s\r\n",
1546                                         db_fget(e.item, FAX));
1547                 if(db_fget(e.item, MOBILEPHONE))
1548                         fprintf(out, "TEL;CELL:%s\r\n",
1549                                         db_fget(e.item, MOBILEPHONE));
1550
1551                 tmp = db_email_get(e.item);
1552                 if(*tmp) {
1553                         emails = csv_to_abook_list(tmp);
1554
1555                         for(em = emails; em; em = em->next)
1556                                 fprintf(out, "EMAIL;INTERNET:%s\r\n", em->data);
1557
1558                         abook_list_free(&emails);
1559                 }
1560                 free(tmp);
1561
1562                 if(db_fget(e.item, NOTES))
1563                         fprintf(out, "NOTE:%s\r\n",
1564                                         db_fget(e.item, NOTES));
1565                 if(db_fget(e.item, URL))
1566                         fprintf(out, "URL:%s\r\n",
1567                                         db_fget(e.item, URL));
1568
1569                 fprintf(out, "END:VCARD\r\n\r\n");
1570
1571         }
1572
1573         return 0;
1574 }
1575
1576 /*
1577  * end of GnomeCard export filter
1578  */
1579
1580
1581 /*
1582  * mutt alias export filter
1583  */
1584
1585 static char *
1586 mutt_alias_genalias(int i)
1587 {
1588         char *tmp, *pos;
1589
1590         if(db_fget(i, NICK))
1591                 return xstrdup(db_fget(i, NICK));
1592
1593         tmp = xstrdup(db_name_get(i));
1594
1595         if( ( pos = strchr(tmp, ' ') ) )
1596                 *pos = 0;
1597
1598         strlower(tmp);
1599
1600         return tmp;
1601 }
1602
1603 static int
1604 mutt_alias_export(FILE *out, struct db_enumerator e)
1605 {
1606         char email[MAX_EMAIL_LEN];
1607         char *alias = NULL;
1608
1609         db_enumerate_items(e) {
1610                 alias = mutt_alias_genalias(e.item);
1611                 get_first_email(email, e.item);
1612                 fprintf(out, *email ? "alias %s %s <%s>\n": "alias %s %s%s\n",
1613                                 alias,
1614                                 db_name_get(e.item),
1615                                 email);
1616                 xfree(alias);
1617         }
1618
1619         return 0;
1620 }
1621
1622 /*
1623  * end of mutt alias export filter
1624  */
1625
1626
1627 /*
1628  * printable export filter
1629  */
1630
1631
1632 static void
1633 text_write_address_us(FILE *out, int i) {
1634         fprintf(out, "\n%s", db_fget(i, ADDRESS));
1635
1636         if(db_fget(i, ADDRESS2))
1637                 fprintf(out, "\n%s", db_fget(i, ADDRESS2));
1638
1639         if(db_fget(i, CITY))
1640                 fprintf(out, "\n%s", db_fget(i, CITY));
1641
1642         if(db_fget(i, STATE) || db_fget(i, ZIP)) {
1643                 fputc('\n', out);
1644
1645                 if(db_fget(i, STATE)) {
1646                         fprintf(out, "%s", db_fget(i, STATE));
1647                         if(db_fget(i, ZIP))
1648                                 fputc(' ', out);
1649                 }
1650
1651                 if(db_fget(i, ZIP))
1652                         fprintf(out, "%s", db_fget(i, ZIP));
1653         }
1654
1655         if(db_fget(i, COUNTRY))
1656                 fprintf(out, "\n%s", db_fget(i, COUNTRY));
1657 }
1658
1659
1660 static void
1661 text_write_address_uk(FILE *out, int i) {
1662         int j;
1663
1664         for(j = ADDRESS; j <= COUNTRY; j++)
1665                 if(db_fget(i, j))
1666                         fprintf(out, "\n%s", db_fget(i, j));
1667 }
1668
1669 static void
1670 text_write_address_eu(FILE *out, int i) {
1671         fprintf(out, "\n%s", db_fget(i, ADDRESS));
1672
1673         if(db_fget(i, ADDRESS2))
1674                 fprintf(out, "\n%s", db_fget(i, ADDRESS2));
1675
1676         if(db_fget(i, ZIP) || db_fget(i, CITY)) {
1677                 fputc('\n', out);
1678
1679                 if(db_fget(i, ZIP)) {
1680                         fprintf(out, "%s", db_fget(i, ZIP));
1681                         if(db_fget(i, CITY))
1682                                 fputc(' ', out);
1683                 }
1684
1685                 fprintf(out, "%s", safe_str(db_fget(i, CITY)));
1686         }
1687
1688         if(db_fget(i, STATE))
1689                 fprintf(out, "\n%s", db_fget(i, STATE));
1690
1691         if(db_fget(i, COUNTRY))
1692                 fprintf(out, "\n%s", db_fget(i, COUNTRY));
1693 }
1694
1695 static int
1696 text_export_database(FILE * out, struct db_enumerator e)
1697 {
1698         abook_list *emails, *em;
1699         int j;
1700         char *realname = get_real_name(), *str = NULL, *tmp;
1701         char *style = opt_get_str(STR_ADDRESS_STYLE);
1702
1703         fprintf(out,
1704                 "-----------------------------------------\n%s's address book\n"
1705                 "-----------------------------------------\n\n\n",
1706                 realname);
1707         free(realname);
1708
1709         db_enumerate_items(e) {
1710                 fprintf(out,
1711                         "-----------------------------------------\n\n");
1712                 fprintf(out, "%s", db_name_get(e.item));
1713                 if(db_fget(e.item, NICK) && *db_fget(e.item, NICK))
1714                         fprintf(out, "\n(%s)", db_fget(e.item, NICK));
1715                 fprintf(out, "\n");
1716
1717                 tmp = db_email_get(e.item);
1718                 if(*tmp) {
1719                         emails = csv_to_abook_list(tmp);
1720
1721                         fprintf(out, "\n");
1722                         for(em = emails; em; em = em->next)
1723                                 fprintf(out, "%s\n", em->data);
1724
1725                         abook_list_free(&emails);
1726                 }
1727                 free(tmp);
1728                 /* Print address */
1729                 if(db_fget(e.item, ADDRESS)) {
1730                         if(!safe_strcmp(style, "us"))   /* US like */
1731                                 text_write_address_us(out, e.item);
1732                         else if(!safe_strcmp(style, "uk"))      /* UK like */
1733                                 text_write_address_uk(out, e.item);
1734                         else    /* EU like */
1735                                 text_write_address_eu(out, e.item);
1736
1737                         fprintf(out, "\n");
1738                 }
1739
1740                 if((db_fget(e.item, PHONE)) ||
1741                         (db_fget(e.item, WORKPHONE)) ||
1742                         (db_fget(e.item, FAX)) ||
1743                         (db_fget(e.item, MOBILEPHONE))) {
1744                         fprintf(out, "\n");
1745                         for(j = PHONE; j <= MOBILEPHONE; j++)
1746                                 if(db_fget(e.item, j)) {
1747                                         get_field_keyname(field_id(j),
1748                                                         NULL, &str);
1749                                         fprintf(out, "%s: %s\n", str,
1750                                                 db_fget(e.item, j));
1751                                 }
1752                 }
1753
1754                 if(db_fget(e.item, URL))
1755                         fprintf(out, "\n%s\n", db_fget(e.item, URL));
1756                 if(db_fget(e.item, NOTES))
1757                         fprintf(out, "\n%s\n", db_fget(e.item, NOTES));
1758
1759                 fprintf(out, "\n");
1760         }
1761
1762         fprintf(out, "-----------------------------------------\n");
1763
1764         return 0;
1765 }
1766
1767 /*
1768  * end of printable export filter
1769  */
1770
1771 /*
1772  * elm alias export filter
1773  */
1774
1775 static int
1776 elm_alias_export(FILE *out, struct db_enumerator e)
1777 {
1778         char email[MAX_EMAIL_LEN];
1779         char *alias = NULL;
1780
1781         db_enumerate_items(e) {
1782                 alias = mutt_alias_genalias(e.item);
1783                 get_first_email(email, e.item);
1784                 fprintf(out, "%s = %s = %s\n",alias,db_name_get(e.item),email);
1785                 xfree(alias);
1786         }
1787
1788         return 0;
1789 }
1790
1791 /*
1792  * end of elm alias export filter
1793  */
1794
1795
1796 /*
1797  * Spruce export filter
1798  */
1799
1800 static int
1801 spruce_export_database (FILE *out, struct db_enumerator e)
1802 {
1803         char email[MAX_EMAIL_LEN];
1804
1805         fprintf(out, "# This is a generated file made by abook for the Spruce e-mail client.\n\n");
1806
1807         db_enumerate_items(e) {
1808                 get_first_email(email, e.item);
1809                 if(strcmp(email, "")) {
1810                         fprintf(out, "# Address %d\nName: %s\nEmail: %s\nMemo: %s\n\n",
1811                                         e.item,
1812                                         db_name_get(e.item),
1813                                         email,
1814                                         safe_str(db_fget(e.item, NOTES))
1815                                         );
1816                 }
1817         }
1818
1819         fprintf (out, "# End of address book file.\n");
1820
1821         return 0;
1822 }
1823
1824 /*
1825  * end of Spruce export filter
1826  */
1827
1828 /*
1829  * wanderlust addressbook export filter
1830  */
1831
1832 static int
1833 wl_export_database(FILE *out, struct db_enumerator e)
1834 {
1835         char email[MAX_EMAIL_LEN];
1836
1837         fprintf(out, "# Wanderlust address book written by %s\n\n", PACKAGE);
1838         db_enumerate_items(e) {
1839                 get_first_email(email, e.item);
1840                 if(*email) {
1841                         fprintf(out,
1842                                 "%s\t\"%s\"\t\"%s\"\n",
1843                                 email,
1844                                 safe_str(db_fget(e.item, NICK)),
1845                                 safe_str(db_name_get(e.item))
1846                         );
1847                 }
1848         }
1849
1850         fprintf (out, "\n# End of address book file.\n");
1851
1852         return 0;
1853 }
1854
1855 /*
1856  * end of wanderlust addressbook export filter
1857  */
1858