X-Git-Url: https://git.deb.at/?a=blobdiff_plain;f=filter.c;h=8d0faa95a01b3a9f6cae2850a4a5392d57c4d1bf;hb=ec21e25ffd8fe61704ae3588bcad4570de2946ac;hp=902c481485e872305197b3a5451434638b436b43;hpb=7dca83329bb3ce545d6d03e10754999b9a82ca01;p=pkg%2Fabook.git diff --git a/filter.c b/filter.c index 902c481..8d0faa9 100644 --- a/filter.c +++ b/filter.c @@ -1,6 +1,6 @@ /* - * $Id: filter.c,v 1.15 2002/01/19 11:07:02 jheinonen Exp $ + * $Id: filter.c,v 1.48.2.1.2.2 2006/04/10 16:02:10 jheinonen Exp $ * * by JH * @@ -12,16 +12,19 @@ #include #include #include -#include #include +#include #include "abook_curses.h" #include "filter.h" #include "abook.h" #include "database.h" #include "edit.h" +#include "gettext.h" #include "list.h" #include "misc.h" #include "options.h" +#include "ui.h" +#include "xmalloc.h" #include extern int items; @@ -40,6 +43,8 @@ static int ldif_parse_file(FILE *handle); static int mutt_parse_file(FILE *in); static int pine_parse_file(FILE *in); static int csv_parse_file(FILE *in); +static int allcsv_parse_file(FILE *in); +static int palmcsv_parse_file(FILE *in); /* * export filter prototypes @@ -49,36 +54,44 @@ static int ldif_export_database(FILE *out, struct db_enumerator e); static int html_export_database(FILE *out, struct db_enumerator e); static int pine_export_database(FILE *out, struct db_enumerator e); static int csv_export_database(FILE *out, struct db_enumerator e); +static int allcsv_export_database(FILE *out, struct db_enumerator e); +static int palm_export_database(FILE *out, struct db_enumerator e); static int gcrd_export_database(FILE *out, struct db_enumerator e); static int mutt_alias_export(FILE *out, struct db_enumerator e); static int elm_alias_export(FILE *out, struct db_enumerator e); static int text_export_database(FILE *out, struct db_enumerator e); static int spruce_export_database(FILE *out, struct db_enumerator e); +static int wl_export_database(FILE *out, struct db_enumerator e); /* * end of function declarations */ struct abook_input_filter i_filters[] = { - { "abook", "abook native format", parse_database }, - { "ldif", "ldif / Netscape addressbook", ldif_parse_file }, - { "mutt", "mutt alias", mutt_parse_file }, - { "pine", "pine addressbook", pine_parse_file }, - { "csv", "comma separated values", csv_parse_file }, + { "abook", N_("abook native format"), parse_database }, + { "ldif", N_("ldif / Netscape addressbook"), ldif_parse_file }, + { "mutt", N_("mutt alias"), mutt_parse_file }, + { "pine", N_("pine addressbook"), pine_parse_file }, + { "csv", N_("comma separated values"), csv_parse_file }, + { "allcsv", N_("comma separated values (all fields)"), allcsv_parse_file }, + { "palmcsv", N_("Palm comma separated values"), palmcsv_parse_file }, { "\0", NULL, NULL } }; struct abook_output_filter e_filters[] = { - { "abook", "abook native format", write_database }, - { "ldif", "ldif / Netscape addressbook (.4ld)", ldif_export_database }, - { "mutt", "mutt alias", mutt_alias_export }, - { "html", "html document", html_export_database }, - { "pine", "pine addressbook", pine_export_database }, - { "gcrd", "GnomeCard (VCard) addressbook", gcrd_export_database }, - { "csv", "comma separated values", csv_export_database }, - { "elm", "elm alias", elm_alias_export }, - { "text", "plain text", text_export_database }, - { "spruce", "Spruce address book", spruce_export_database }, + { "abook", N_("abook native format"), write_database }, + { "ldif", N_("ldif / Netscape addressbook (.4ld)"), ldif_export_database }, + { "mutt", N_("mutt alias"), mutt_alias_export }, + { "html", N_("html document"), html_export_database }, + { "pine", N_("pine addressbook"), pine_export_database }, + { "gcrd", N_("GnomeCard (VCard) addressbook"), gcrd_export_database }, + { "csv", N_("comma separated values"), csv_export_database }, + { "allcsv", N_("comma separated values (all fields)"), allcsv_export_database }, + { "palmcsv", N_("Palm comma separated values"), palm_export_database}, + { "elm", N_("elm alias"), elm_alias_export }, + { "text", N_("plain text"), text_export_database }, + { "wl", N_("Wanderlust address book"), wl_export_database }, + { "spruce", N_("Spruce address book"), spruce_export_database }, { "\0", NULL, NULL } }; @@ -90,18 +103,18 @@ void print_filters() { int i; - - puts("input:"); + + puts(_("input:")); for(i=0; *i_filters[i].filtname ; i++) printf("\t%s\t%s\n", i_filters[i].filtname, - i_filters[i].desc); + gettext(i_filters[i].desc)); putchar('\n'); - - puts("output:"); + + puts(_("output:")); for(i=0; *e_filters[i].filtname ; i++) printf("\t%s\t%s\n", e_filters[i].filtname, - e_filters[i].desc); + gettext(e_filters[i].desc)); putchar('\n'); } @@ -138,13 +151,13 @@ get_real_name() pwent = getpwnam(username); - if( (tmp = (char *)malloc(strlen(pwent->pw_gecos) +1)) == NULL) - return strdup(username); + if((tmp = xstrdup(pwent->pw_gecos)) == NULL) + return xstrdup(username); rtn = sscanf(pwent->pw_gecos, "%[^,]", tmp); if (rtn == EOF || rtn == 0) { free(tmp); - return strdup(username); + return xstrdup(username); } else return tmp; } @@ -152,28 +165,28 @@ get_real_name() /* * import */ - + static int i_read_file(char *filename, int (*func) (FILE *in)); static void import_screen() { int i; - + clear(); refresh_statusline(); - headerline("import database"); + headerline(_("import database")); + + mvaddstr(3, 1, _("please select a filter")); - mvaddstr(3, 1, "please select a filter"); - for(i=0; *i_filters[i].filtname ; i++) mvprintw(5 + i, 6, "%c -\t%s\t%s\n", 'a' + i, i_filters[i].filtname, - i_filters[i].desc); + gettext(i_filters[i].desc)); - mvprintw(6 + i, 6, "x -\tcancel"); + mvprintw(6 + i, 6, _("x -\tcancel")); } int @@ -184,28 +197,27 @@ import_database() int tmp = items; import_screen(); - + filter = getch() - 'a'; if(filter == 'x' - 'a' || filter >= number_of_input_filters() || filter < 0) { refresh_screen(); return 1; } - + mvaddstr(5+filter, 2, "->"); - - filename = ask_filename("Filename: ", 1); - if( !filename ) { + + filename = ask_filename(_("Filename: ")); + if(!filename) { refresh_screen(); return 2; } - - if( i_read_file(filename, i_filters[filter].func ) ) - statusline_msg("Error occured while opening the file"); - else - if( tmp == items ) - statusline_msg("Hmm.., file seems not to be a valid file"); - + + if(i_read_file(filename, i_filters[filter].func )) + statusline_msg(_("Error occured while opening the file")); + else if(tmp == items) + statusline_msg(_("File does not seem to be a valid addressbook")); + refresh_screen(); free(filename); @@ -220,47 +232,48 @@ i_read_file(char *filename, int (*func) (FILE *in)) FILE *in; int ret = 0; - if( ( in = abook_fopen( filename, "r" ) ) == NULL ) + if( (in = abook_fopen( filename, "r" )) == NULL ) return 1; ret = (*func) (in); fclose(in); - return ret; + return ret; } int -import(char filtname[FILTNAME_LEN], char *filename) +import_file(char filtname[FILTNAME_LEN], char *filename) { int i; int tmp = items; int ret = 0; for(i=0;; i++) { - if( ! strncmp(i_filters[i].filtname, filtname, FILTNAME_LEN) ) + if(! strncasecmp(i_filters[i].filtname, filtname, + FILTNAME_LEN) ) break; - if( ! *i_filters[i].filtname ) { + if(! *i_filters[i].filtname) { i = -1; break; } } - if( i<0 ) + if(i < 0) return -1; - if( !strcmp(filename, "-") ) { + if(!strcmp(filename, "-")) { struct stat s; - if( (fstat(fileno(stdin), &s)) == -1 || S_ISDIR(s.st_mode)) + if((fstat(fileno(stdin), &s)) == -1 || S_ISDIR(s.st_mode)) ret = 1; else ret = (*i_filters[i].func) (stdin); } else ret = i_read_file(filename, i_filters[i].func); - - if( tmp == items ) + + if(tmp == items) ret = 1; - + return ret; } @@ -275,22 +288,22 @@ static void export_screen() { int i; - + clear(); refresh_statusline(); - headerline("export database"); + headerline(_("export database")); - mvaddstr(3, 1, "please select a filter"); - + mvaddstr(3, 1, _("please select a filter")); - for(i=0; *e_filters[i].filtname ; i++) + + for(i = 0; *e_filters[i].filtname ; i++) mvprintw(5 + i, 6, "%c -\t%s\t%s\n", 'a' + i, e_filters[i].filtname, - e_filters[i].desc); + gettext(e_filters[i].desc)); - mvprintw(6 + i, 6, "x -\tcancel"); + mvprintw(6 + i, 6, _("x -\tcancel")); } int @@ -301,38 +314,42 @@ export_database() char *filename; export_screen(); - + filter = getch() - 'a'; if(filter == 'x' - 'a' || - filter >= number_of_output_filters(e_filters) || filter < 0) { + filter >= number_of_output_filters() || filter < 0) { refresh_screen(); return 1; } - - mvaddstr(5+filter, 2, "->"); - if( selected_items() ) { - statusline_addstr("Export All/Selected/Cancel (A/s/c)"); - switch( tolower(getch()) ) { - case 's': + mvaddstr(5 + filter, 2, "->"); + + if(selected_items()) { + switch(statusline_askchoice( + _("Export ll, export elected, or ancel?"), + S_("keybindings:all/selected/cancel|asc"), 3)) { + case 1: + break; + case 2: enum_mode = ENUM_SELECTED; break; - case 'c': - clear_statusline(); + case 0: + case 3: + refresh_screen(); return 1; } clear_statusline(); } - - filename = ask_filename("Filename: ", 0); - if( !filename ) { + + filename = ask_filename(_("Filename: ")); + if(!filename) { refresh_screen(); return 2; } - - if( e_write_file(filename, e_filters[filter].func, enum_mode ) ) - statusline_msg("Error occured while exporting"); - + + if( e_write_file(filename, e_filters[filter].func, enum_mode)) + statusline_msg(_("Error occured while exporting")); + refresh_screen(); free(filename); @@ -347,16 +364,16 @@ e_write_file(char *filename, int (*func) (FILE *in, struct db_enumerator e), int ret = 0; struct db_enumerator enumerator = init_db_enumerator(mode); - if( (out = fopen(filename, "a")) == NULL ) + if((out = fopen(filename, "a")) == NULL) return 1; - if( ftell(out) ) + if(ftell(out)) return 1; ret = (*func) (out, enumerator); - + fclose(out); - + return ret; } @@ -367,9 +384,10 @@ fexport(char filtname[FILTNAME_LEN], FILE *handle, int enum_mode) struct db_enumerator e = init_db_enumerator(enum_mode); for(i=0;; i++) { - if( ! strncmp(e_filters[i].filtname, filtname, FILTNAME_LEN) ) + if(!strncasecmp(e_filters[i].filtname, filtname, + FILTNAME_LEN)) break; - if( ! *e_filters[i].filtname ) { + if(!*e_filters[i].filtname) { i = -1; break; } @@ -378,29 +396,30 @@ fexport(char filtname[FILTNAME_LEN], FILE *handle, int enum_mode) return (e_filters[i].func) (handle, e); } - + int -export(char filtname[FILTNAME_LEN], char *filename) +export_file(char filtname[FILTNAME_LEN], char *filename) { const int mode = ENUM_ALL; int i; int ret = 0; struct db_enumerator e = init_db_enumerator(mode); - + for(i=0;; i++) { - if( ! strncmp(e_filters[i].filtname, filtname, FILTNAME_LEN) ) + if(!strncasecmp(e_filters[i].filtname, filtname, + FILTNAME_LEN)) break; - if( ! *e_filters[i].filtname ) { + if(!*e_filters[i].filtname) { i = -1; break; } } - if( i<0 ) + if(i < 0) return -1; - if( !strcmp(filename, "-") ) + if(!strcmp(filename, "-")) ret = (e_filters[i].func) (stdout, e); else ret = e_write_file(filename, e_filters[i].func, mode); @@ -422,10 +441,10 @@ static void ldif_fix_string(char *str); #define LDIF_ITEM_FIELDS 16 -typedef char* ldif_item[LDIF_ITEM_FIELDS]; +typedef char *ldif_item[LDIF_ITEM_FIELDS]; static ldif_item ldif_field_names = { - "cn", + "cn", "mail", "streetaddress", "streetaddress2", @@ -447,7 +466,7 @@ static int ldif_conv_table[LDIF_ITEM_FIELDS] = { NAME, /* "cn" */ EMAIL, /* "mail" */ ADDRESS, /* "streetaddress" */ - ADDRESS2, /* "streetaddress2" */ + ADDRESS2, /* "streetaddress2" */ CITY, /* "locality" */ STATE, /* "st" */ ZIP, /* "postalcode" */ @@ -463,7 +482,7 @@ static int ldif_conv_table[LDIF_ITEM_FIELDS] = { }; -static char * +static char * ldif_read_line(FILE *in) { char *buf = NULL; @@ -476,17 +495,17 @@ ldif_read_line(FILE *in) pos = ftell(in); line = getaline(in); - - if( feof(in) || !line ) + + if(feof(in) || !line) break; - + if(i == 1) { buf = line; continue; } - + if(*line != ' ') { - fseek(in, pos, SEEK_SET); + fseek(in, pos, SEEK_SET); /* fixme ! */ free(line); break; } @@ -505,32 +524,32 @@ ldif_read_line(FILE *in) free(buf); return NULL; } - + return buf; } static void -ldif_add_item(ldif_item ldif_item) +ldif_add_item(ldif_item li) { list_item abook_item; int i; memset(abook_item, 0, sizeof(abook_item)); - - if( !ldif_item[LDIF_ITEM_FIELDS -1] ) + + if(!li[LDIF_ITEM_FIELDS -1]) goto bail_out; - + for(i=0; i < LDIF_ITEM_FIELDS; i++) { - if(ldif_conv_table[i] >= 0 && ldif_item[i] && *ldif_item[i] ) - abook_item[ldif_conv_table[i]] = strdup(ldif_item[i]); + if(ldif_conv_table[i] >= 0 && li[i] && *li[i]) + abook_item[ldif_conv_table[i]] = xstrdup(li[i]); } add_item2database(abook_item); bail_out: for(i=0; i < LDIF_ITEM_FIELDS; i++) - my_free(ldif_item[i]); + xfree(li[i]); } @@ -539,19 +558,19 @@ ldif_convert(ldif_item item, char *type, char *value) { int i; - if( !strcmp(type, "dn") ) { + if(!strcmp(type, "dn")) { ldif_add_item(item); return; } for(i=0; i < LDIF_ITEM_FIELDS; i++) { - if( !safe_strcmp(ldif_field_names[i], type) && *value ) { - if( i == LDIF_ITEM_FIELDS -1) /* this is a dirty hack */ - if( safe_strcmp("person", value)) + if(!safe_strcmp(ldif_field_names[i], type) && *value) { + if(i == LDIF_ITEM_FIELDS - 1) /* this is a dirty hack */ + if(safe_strcmp("person", value)) break; if(item[i]) - my_free(item[i]); - item[i] = strdup(value); + xfree(item[i]); + item[i] = xstrdup(value); } } } @@ -567,19 +586,19 @@ ldif_parse_file(FILE *handle) memset(item, 0, sizeof(item)); do { - if( ! (line = ldif_read_line(handle)) ) + if( !(line = ldif_read_line(handle)) ) continue; - if( -1 == ( str_parse_line(line, &type, &value, &vlen)) ) { - my_free(line); + if(-1 == (str_parse_line(line, &type, &value, &vlen))) { + xfree(line); continue; /* just skip the errors */ } - + ldif_fix_string(value); ldif_convert(item, type, value); - my_free(line); + xfree(line); } while ( !feof(handle) ); ldif_convert(item, "dn", ""); @@ -592,7 +611,7 @@ ldif_fix_string(char *str) { int i, j; - for( i = 0, j = 0; j < strlen(str); i++, j++) + for(i = 0, j = 0; j < (int)strlen(str); i++, j++) str[i] = ( str[j] == (char)0xc3 ? (char) str[++j] + (char) 0x40 : str[j] ); @@ -614,6 +633,7 @@ static int mutt_read_line(FILE *in, char **alias, char **rest) { char *line, *ptr, *tmp; + size_t alias_len; if( !(line = ptr = getaline(in)) ) return 1; /* error / EOF */ @@ -621,11 +641,11 @@ mutt_read_line(FILE *in, char **alias, char **rest) while( ISSPACE(*ptr) ) ptr++; - if( strncmp("alias", ptr, 5) ) { + if(strncmp("alias", ptr, 5)) { free(line); return 1; } - + ptr += 5; while( ISSPACE(*ptr) ) @@ -636,31 +656,54 @@ mutt_read_line(FILE *in, char **alias, char **rest) while( ! ISSPACE(*ptr) ) ptr++; - if( (*alias = (char *)malloc(ptr-tmp+1)) == NULL) { - free(line); - return 1; - } + alias_len = (size_t)(ptr - tmp); - strncpy(*alias, tmp, ptr-tmp); - *(*alias + (ptr - tmp)) = 0; + *alias = xmalloc_inc(alias_len, 1); - while( ISSPACE(*ptr) ) + strncpy(*alias, tmp, alias_len); + *(*alias + alias_len) = 0; + + while(ISSPACE(*ptr)) ptr++; - *rest = strdup(ptr); + *rest = xstrdup(ptr); free(line); return 0; } +static void +mutt_fix_quoting(char *p) +{ + char *escape = 0; + + for(; *p; p++) { + switch(*p) { + case '\"': + if(escape) + *escape = ' '; + break; + case '\\': + escape = p; + break; + default: + escape = 0; + } + } +} + static void mutt_parse_email(list_item item) { char *line = item[NAME]; - char *start = line, *tmp; + char *tmp; char *name, *email; +#if 0 + char *start = line; int i = 0; +#endif + mutt_fix_quoting(line); tmp = strconcat("From: ", line, NULL); getname(tmp, &name, &email); free(tmp); @@ -673,7 +716,11 @@ mutt_parse_email(list_item item) item[EMAIL] = email; else return; - + + /* + * this is completely broken + */ +#if 0 while( (start = strchr(start, ',')) && i++ < MAX_EMAILS - 1) { tmp = strconcat("From: ", ++start, NULL); getname(tmp, &name, &email); @@ -685,10 +732,11 @@ mutt_parse_email(list_item item) free(item[EMAIL]); item[EMAIL] = tmp; } else { - my_free(email); + xfree(email); } } } +#endif } static int @@ -698,12 +746,12 @@ mutt_parse_file(FILE *in) for(;;) { memset(item, 0, sizeof(item)); - - if( !mutt_read_line(in, &item[NICK], + + if(!mutt_read_line(in, &item[NICK], &item[NAME]) ) mutt_parse_email(item); - if( feof(in) ) { + if(feof(in)) { free_list_item(item); break; } @@ -747,11 +795,11 @@ ldif_export_database(FILE *out, struct db_enumerator e) int j; get_first_email(email, e.item); - tmp = mkstr("cn=%s,mail=%s", database[e.item][NAME], email); + tmp = strdup_printf("cn=%s,mail=%s", database[e.item][NAME], email); ldif_fput_type_and_value(out, "dn", tmp); free(tmp); - for(j=0; j < LDIF_ITEM_FIELDS; j++) { + for(j = 0; j < LDIF_ITEM_FIELDS; j++) { if(ldif_conv_table[j] >= 0) { if(ldif_conv_table[j] == EMAIL) ldif_fput_type_and_value(out, @@ -778,22 +826,24 @@ ldif_export_database(FILE *out, struct db_enumerator e) * html export filter */ -static void html_export_write_head(FILE *out, int extra_column); +static void html_export_write_head(FILE *out, int extra); static void html_export_write_tail(FILE *out); +extern int extra_column; + static int html_export_database(FILE *out, struct db_enumerator e) { char tmp[MAX_EMAILSTR_LEN]; - int extra_column = options_get_int("extra_column"); + int extra; - if( items < 1 ) + if(items < 1) return 2; - extra_column = (extra_column > 2 && extra_column < ITEM_FIELDS) ? + extra = (extra_column > 2 && extra_column < ITEM_FIELDS) ? extra_column : PHONE; - html_export_write_head(out, extra_column); + html_export_write_head(out, extra); db_enumerate_items(e) { get_first_email(tmp, e.item); @@ -807,7 +857,7 @@ html_export_database(FILE *out, struct db_enumerator e) fprintf(out, "%s\n%s\n", database[e.item][EMAIL], - safe_str(database[e.item][extra_column]) ); + safe_str(database[e.item][extra]) ); fprintf(out, "\n\n"); } @@ -818,20 +868,19 @@ html_export_database(FILE *out, struct db_enumerator e) static void -html_export_write_head(FILE *out, int extra_column) +html_export_write_head(FILE *out, int extra) { char *realname = get_real_name(); - fprintf(out, "\n"); - fprintf(out, "\n\n %s's addressbook", - realname ); + fprintf(out, "\n"); + fprintf(out, "\n\n %s's addressbook", realname ); fprintf(out, "\n\n\n"); fprintf(out, "\n

%s's addressbook

\n", realname ); fprintf(out, "

\n\n"); - fprintf(out, "
\n"); + fprintf(out, "
\n"); fprintf(out, "\n\n\n", - abook_fields[extra_column].name); + abook_fields[extra].name); free(realname); } @@ -839,10 +888,10 @@ html_export_write_head(FILE *out, int extra_column) static void html_export_write_tail(FILE *out) { - fprintf(out, "\n
NameE-mail address(es)%s
\n"); + fprintf(out, "\n\n"); fprintf(out, "\n\n\n"); } - + /* * end of html export filter */ @@ -852,12 +901,14 @@ html_export_write_tail(FILE *out) * pine addressbook import filter */ +#define PINE_BUF_SIZE 2048 + static void pine_fixbuf(char *buf) { int i,j; - for(i=0,j=0; j < strlen(buf); i++, j++) + for(i = 0,j = 0; j < (int)strlen(buf); i++, j++) buf[i] = buf[j] == '\n' ? buf[++j] : buf[j]; } @@ -867,21 +918,20 @@ pine_convert_emails(char *s) int i; char *tmp; - if( s == NULL || *s != '(' ) + if(s == NULL || *s != '(') return; - for(i=0; s[i]; i++ ) - s[i] = s[i+1]; + for(i = 0; s[i]; i++) + s[i] = s[i + 1]; if( ( tmp = strchr(s,')')) ) - *tmp=0; - - for(i=1; ( tmp = strchr(s, ',') ) != NULL ; i++, s=tmp+1 ) - if( i > MAX_EMAILS - 1 ) { - *tmp = 0; - break; - } + *tmp = '\0'; + for(i = 1; ( tmp = strchr(s, ',') ) != NULL ; i++, s = tmp + 1) + if(i > MAX_EMAILS - 1) { + *tmp = '\0'; + break; + } } static void @@ -890,32 +940,33 @@ pine_parse_buf(char *buf) list_item item; char *start = buf; char *end; - char tmp[400]; + char tmp[PINE_BUF_SIZE]; int i, len, last; - int pine_conv_table[]= {NICK, NAME, EMAIL, -1, NOTES}; + int pine_conv_table[] = {NICK, NAME, EMAIL, -1, NOTES}; - memset(&item, 0, sizeof(item) ); - - for(i=0, last=0; !last ; i++) { - if( ! (end = strchr(start, '\t')) ) + memset(&item, 0, sizeof(item)); + + for(i = 0, last=0; !last ; i++) { + if( !(end = strchr(start, '\t')) ) last=1; - + len = last ? strlen(start) : (int) (end-start); - len = min(len, 400-1); - - if(i < sizeof(pine_conv_table) / sizeof(*pine_conv_table) + len = min(len, PINE_BUF_SIZE - 1); + + if(i < (int)(sizeof(pine_conv_table) / sizeof(*pine_conv_table)) && pine_conv_table[i] >= 0) { strncpy(tmp, start, len); tmp[len] = 0; - item[pine_conv_table[i]] = strdup(tmp); + if(*tmp) + item[pine_conv_table[i]] = xstrdup(tmp); } start = end + 1; } - + pine_convert_emails(item[EMAIL]); add_item2database(item); } - + #define LINESIZE 1024 @@ -927,32 +978,32 @@ pine_parse_file(FILE *in) char *ptr; int i; - fgets(line, LINESIZE, in); - + fgets(line, LINESIZE, in); + while(!feof(in)) { for(i = 2;;i++) { - buf = (char *) realloc(buf, i*LINESIZE); + buf = xrealloc(buf, i*LINESIZE); if(i == 2) strcpy(buf, line); fgets(line, LINESIZE, in); ptr=(char *)&line; - if(*ptr != ' ' || feof(in) ) + if(*ptr != ' ' || feof(in)) break; else - while( *ptr == ' ') + while(*ptr == ' ') ptr++; - + strcat(buf, ptr); } - if( *buf == '#' ) { - my_free(buf); + if(*buf == '#') { + xfree(buf); continue; } pine_fixbuf(buf); pine_parse_buf(buf); - my_free(buf); + xfree(buf); } return 0; @@ -997,11 +1048,13 @@ pine_export_database(FILE *out, struct db_enumerator e) /* FIXME * these files should be parsed according to a certain - * lay out, or the default if layout is not given, at + * lay out, or the default if layout is not given, at * the moment only default is done... - */ + */ #define CSV_COMMENT_CHAR '#' +#define CSV_DUPLICATE_SEPARATOR " " +#define CSV_TABLE_SIZE(t) (sizeof (t) / sizeof *(t)) static int csv_conv_table[] = { NAME, @@ -1011,19 +1064,64 @@ static int csv_conv_table[] = { NICK }; +static int allcsv_conv_table[] = { + NAME, + EMAIL, + ADDRESS, + ADDRESS2, + CITY, + STATE, + ZIP, + COUNTRY, + PHONE, + WORKPHONE, + FAX, + MOBILEPHONE, + NICK, + URL, + NOTES, + CUSTOM1, + CUSTOM2, + CUSTOM3, + CUSTOM4, + CUSTOM5, +}; + +static int palmcsv_conv_table[] = { + NAME, /* Last name */ + NAME, /* First name */ + NOTES, /* Title */ + NICK, /* Company */ + WORKPHONE, + PHONE, + FAX, + MOBILEPHONE, + EMAIL, + ADDRESS, + CITY, + STATE, + ZIP, + COUNTRY, + CUSTOM1, + CUSTOM2, + CUSTOM3, + CUSTOM4, + CUSTOM5, +}; + static void csv_convert_emails(char *s) { int i; char *tmp; - if( s == NULL ) + if(s == NULL) return; - for(i=1; ( tmp = strchr(s, ',') ) != NULL ; i++, s = tmp + 1 ) - if( i > MAX_EMAILS - 1 ) { + for(i = 1; ( tmp = strchr(s, ',') ) != NULL ; i++, s = tmp + 1) + if(i > MAX_EMAILS - 1) { *tmp = 0; - break; + break; } } @@ -1033,29 +1131,38 @@ csv_remove_quotes(char *s) { char *copy, *trimmed; int len; - - copy = trimmed = strdup(s); + + copy = trimmed = xstrdup(s); strtrim(trimmed); - + len = strlen(trimmed); if(trimmed[len - 1] == '\"' && *trimmed == '\"') { if(len < 3) { - my_free(copy); + xfree(copy); return NULL; } trimmed[len - 1] = 0; trimmed++; - trimmed = strdup(trimmed); + trimmed = xstrdup(trimmed); free(copy); return trimmed; } - my_free(copy); - return strdup(s); + xfree(copy); + return xstrdup(s); +} + +static int +csv_field_to_item(int *table_base, size_t table_size, int field) +{ + if(field < table_size) + return table_base[field]; + + return -1; } static void -csv_store_field(list_item item, char *s, int field) +csv_store_item(list_item item, int i, char *s) { char *newstr = NULL; @@ -1065,9 +1172,19 @@ csv_store_field(list_item item, char *s, int field) if( !(newstr = csv_remove_quotes(s)) ) return; - if(field < (sizeof(csv_conv_table) / sizeof(*csv_conv_table)) - && csv_conv_table[field] >= 0) { - item[csv_conv_table[field]] = newstr; + if(i >= 0) { + if (item[i] != NULL) { + char *oldstr = item[i]; + + item[i] = strconcat(newstr, CSV_DUPLICATE_SEPARATOR, + oldstr, NULL); + xfree(newstr); + xfree(oldstr); + } else { + item[i] = newstr; + } + } else { + xfree(newstr); } } @@ -1101,11 +1218,11 @@ csv_is_valid_quote_start(char *p) } static void -csv_parse_line(char *line) +csv_parse_line(char *line, int *table_base, size_t table_size) { char *p, *start; int field; - int in_quote = FALSE; + bool in_quote = FALSE; list_item item; memset(item, 0, sizeof(item)); @@ -1120,9 +1237,13 @@ csv_parse_line(char *line) in_quote = TRUE; } - if( *p == ',' && !in_quote) { + if(*p == ',' && !in_quote) { *p = 0; - csv_store_field(item, start, field); + csv_field_to_item(table_base, table_size, field); + csv_store_item(item, + csv_field_to_item(table_base, + table_size, field), + start); field++; start = p + 1; } @@ -1130,15 +1251,15 @@ csv_parse_line(char *line) /* * store last field */ - csv_store_field(item, start, field); + csv_store_item(item, csv_field_to_item(table_base, table_size, field), + start); csv_convert_emails(item[EMAIL]); add_item2database(item); } - static int -csv_parse_file(FILE *in) +csv_parse_file_common(FILE *in, int *conv_table, size_t table_size) { char *line = NULL; @@ -1146,59 +1267,235 @@ csv_parse_file(FILE *in) line = getaline(in); if(line && *line && *line != CSV_COMMENT_CHAR) - csv_parse_line(line); + csv_parse_line(line, conv_table, table_size); - my_free(line); + xfree(line); } return 0; } +static int +csv_parse_file(FILE *in) +{ + return csv_parse_file_common(in, csv_conv_table, + CSV_TABLE_SIZE(csv_conv_table)); +} + +static int +allcsv_parse_file(FILE *in) +{ + return csv_parse_file_common(in, allcsv_conv_table, + CSV_TABLE_SIZE(allcsv_conv_table)); +} + +static int +palmcsv_parse_file(FILE *in) +{ + return csv_parse_file_common(in, palmcsv_conv_table, + CSV_TABLE_SIZE(palmcsv_conv_table)); +} + /* * end of csv import filter */ /* - * csv addressbook export filter + * csv addressbook export filters */ +#define CSV_LAST (-1) +#define CSV_UNDEFINED (-2) +#define CSV_SPECIAL(X) (-3 - (X)) +#define CSV_IS_SPECIAL(X) ((X) <= -3) + +static int +csv_export_common(FILE *out, struct db_enumerator e, + int fields[], void (*special_func)(FILE *, int, int)) +{ + int i; + + db_enumerate_items(e) { + for(i = 0; fields[i] != CSV_LAST; i++) { + if(fields[i] == CSV_UNDEFINED) + fprintf(out, "\"\""); + else if(CSV_IS_SPECIAL(fields[i])) { + if(special_func) + (*special_func)(out, e.item, fields[i]); + } else + /*fprintf(out,( + strchr(safe_str(database[e.item][fields[i]]), ',') || + strchr(safe_str(database[e.item][fields[i]]), '\"')) ? + "\"%s\"" : "%s", + safe_str(database[e.item][fields[i]]) + );*/ + fprintf(out, "\"%s\"", + safe_str(database[e.item][fields[i]])); + + if(fields[i + 1] != CSV_LAST) + fputc(',', out); + } + fputc('\n', out); + } + + return 0; +} + static int csv_export_database(FILE *out, struct db_enumerator e) { - int j; int csv_export_fields[] = { NAME, EMAIL, PHONE, NOTES, NICK, - -1 + CSV_LAST }; - db_enumerate_items(e) { - for(j = 0; csv_export_fields[j] >= 0; j++) { - fprintf(out,( - strchr(safe_str(database[e.item][csv_export_fields[j]]), ',') || - strchr(safe_str(database[e.item][csv_export_fields[j]]), '\"') - ) ? - "\"%s\"" : "%s", - safe_str(database[e.item][csv_export_fields[j]]) - ); - if(csv_export_fields[j+1] >= 0) - fputc(',', out); - } - fputc('\n', out); - } - + csv_export_common(out, e, csv_export_fields, NULL); + return 0; +} + +static int +allcsv_export_database(FILE *out, struct db_enumerator e) +{ + /* + * TODO: Should get these atomatically from abook_fileds + * - JH + */ + int allcsv_export_fields[] = { + NAME, + EMAIL, + ADDRESS, + ADDRESS2, + CITY, + STATE, + ZIP, + COUNTRY, + PHONE, + WORKPHONE, + FAX, + MOBILEPHONE, + NICK, + URL, + NOTES, + CUSTOM1, + CUSTOM2, + CUSTOM3, + CUSTOM4, + CUSTOM5, + CSV_LAST + }; + + fprintf(out, "#"); + fprintf(out, "\"NAME\","); + fprintf(out, "\"EMAIL\","); + fprintf(out, "\"ADDRESS\","); + fprintf(out, "\"ADDRESS2\","); + fprintf(out, "\"CITY\","); + fprintf(out, "\"STATE\","); + fprintf(out, "\"ZIP\","); + fprintf(out, "\"COUNTRY\","); + fprintf(out, "\"PHONE\","); + fprintf(out, "\"WORKPHONE\","); + fprintf(out, "\"FAX\","); + fprintf(out, "\"MOBILEPHONE\","); + fprintf(out, "\"NICK\","); + fprintf(out, "\"URL\","); + fprintf(out, "\"NOTES\","); + fprintf(out, "\"CUSTOM1\","); + fprintf(out, "\"CUSTOM2\","); + fprintf(out, "\"CUSTOM3\","); + fprintf(out, "\"CUSTOM4\","); + fprintf(out, "\"CUSTOM5\"\n"); + + csv_export_common(out, e, allcsv_export_fields, NULL); return 0; } /* - * end of csv export filter + * palm csv */ +#define PALM_CSV_NAME CSV_SPECIAL(0) +#define PALM_CSV_END CSV_SPECIAL(1) +#define PALM_CSV_CAT CSV_SPECIAL(2) + +static void +palm_split_and_write_name(FILE *out, char *name) +{ + char *p; + + assert(name); + + if ( (p = strchr(name, ' ')) ) { + /* + * last name first + */ + fprintf(out, "\"%s\",\"" , p + 1); + fwrite((void *)name, p - name, sizeof(char), out); + fputc('\"', out); + } else { + fprintf(out, "\"%s\"", safe_str(name)); + } +} + +static void +palm_csv_handle_specials(FILE *out, int item, int field) +{ + switch(field) { + case PALM_CSV_NAME: + palm_split_and_write_name(out, database[item][NAME]); + break; + case PALM_CSV_CAT: + fprintf(out, "\"abook\""); + break; + case PALM_CSV_END: + fprintf(out, "\"0\""); + break; + default: + assert(0); + } +} + +static int +palm_export_database(FILE *out, struct db_enumerator e) +{ + int palm_export_fields[] = { + PALM_CSV_NAME, /* LASTNAME, FIRSTNAME */ + CSV_UNDEFINED, /* TITLE */ + CSV_UNDEFINED, /* COMPANY */ + WORKPHONE, /* WORK PHONE */ + PHONE, /* HOME PHONE */ + FAX, /* FAX */ + MOBILEPHONE, /* OTHER */ + EMAIL, /* EMAIL */ + ADDRESS, /* ADDRESS */ + CITY, /* CITY */ + STATE, /* STATE */ + ZIP, /* ZIP */ + COUNTRY, /* COUNTRY */ + NICK, /* DEFINED 1 */ + URL, /* DEFINED 2 */ + CSV_UNDEFINED, /* DEFINED 3 */ + CSV_UNDEFINED, /* DEFINED 4 */ + NOTES, /* NOTE */ + PALM_CSV_END, /* "0" */ + PALM_CSV_CAT, /* CATEGORY */ + CSV_LAST + }; + + csv_export_common(out, e, palm_export_fields, palm_csv_handle_specials); + + return 0; +} + +/* + * end of csv export filters + */ /* * GnomeCard (VCard) addressbook export filter @@ -1212,57 +1509,60 @@ gcrd_export_database(FILE *out, struct db_enumerator e) char *name; db_enumerate_items(e) { - fprintf(out, "BEGIN:VCARD\nFN:%s\n", + fprintf(out, "BEGIN:VCARD\r\nFN:%s\r\n", safe_str(database[e.item][NAME])); name = get_surname(database[e.item][NAME]); for( j = strlen(database[e.item][NAME]) - 1; j >= 0; j-- ) { if(database[e.item][NAME][j] == ' ') break; - } - fprintf(out, "N:%s;%.*s\n", + } + fprintf(out, "N:%s;%.*s\r\n", safe_str(name), j, safe_str(database[e.item][NAME]) - ); + ); free(name); if ( database[e.item][ADDRESS] ) - fprintf(out, "ADR:;;%s;%s;%s;%s;%s;%s\n", + fprintf(out, "ADR:;;%s;%s;%s;%s;%s;%s\r\n", safe_str(database[e.item][ADDRESS]), - safe_str(database[e.item][ADDRESS2]), + safe_str(database[e.item][ADDRESS2]), safe_str(database[e.item][CITY]), safe_str(database[e.item][STATE]), safe_str(database[e.item][ZIP]), safe_str(database[e.item][COUNTRY]) ); - + if (database[e.item][PHONE]) - fprintf(out, "TEL;HOME:%s\n", database[e.item][PHONE]); + fprintf(out, "TEL;HOME:%s\r\n", + database[e.item][PHONE]); if (database[e.item][WORKPHONE]) - fprintf(out, "TEL;WORK:%s\n", database[e.item][WORKPHONE]); + fprintf(out, "TEL;WORK:%s\r\n", + database[e.item][WORKPHONE]); + if (database[e.item][FAX]) - fprintf(out, "TEL;FAX:%s\n", database[e.item][FAX]); + fprintf(out, "TEL;FAX:%s\r\n", database[e.item][FAX]); if (database[e.item][MOBILEPHONE]) - fprintf(out, "TEL;CELL:%s\n", database[e.item][MOBILEPHONE]); + fprintf(out, "TEL;CELL:%s\r\n", database[e.item][MOBILEPHONE]); if ( database[e.item][EMAIL] ) { split_emailstr(e.item, emails); for(j=0; j < MAX_EMAILS ; j++) { - if ( *emails[j] ) - fprintf(out, "EMAIL;INTERNET:%s\n", + if ( *emails[j] ) + fprintf(out, "EMAIL;INTERNET:%s\r\n", emails[j]); } } - - if ( database[e.item][NOTES] ) - fprintf(out, "NOTE:%s\n", database[e.item][NOTES]); + + if ( database[e.item][NOTES] ) + fprintf(out, "NOTE:%s\r\n", database[e.item][NOTES]); if (database[e.item][URL]) - fprintf(out, "URL:%s\n", database[e.item][URL]); + fprintf(out, "URL:%s\r\n", database[e.item][URL]); + + fprintf(out, "END:VCARD\r\n\r\n"); - fprintf(out, "END:VCARD\n\n"); - } return 0; @@ -1281,18 +1581,18 @@ static char * mutt_alias_genalias(int i) { char *tmp, *pos; - + if(database[i][NICK]) - return strdup(database[i][NICK]); + return xstrdup(database[i][NICK]); - tmp = strdup(database[i][NAME]); + tmp = xstrdup(database[i][NAME]); if( ( pos = strchr(tmp, ' ') ) ) *pos = 0; strlower(tmp); - return tmp; + return tmp; } static int @@ -1309,7 +1609,7 @@ mutt_alias_export(FILE *out, struct db_enumerator e) alias, database[e.item][NAME], email); - my_free(alias); + xfree(alias); } return 0; @@ -1334,10 +1634,10 @@ text_write_address_us(FILE *out, int i) { if (database[i][CITY]) fprintf(out, "\n%s", database[i][CITY]); - + if (database[i][STATE] || database[i][ZIP]) { fputc('\n', out); - + if(database[i][STATE]) { fprintf(out, "%s", database[i][STATE]); if(database[i][ZIP]) @@ -1381,7 +1681,7 @@ text_write_address_eu(FILE *out, int i) { if(database[i][CITY]) fprintf(out, "%s", database[i][CITY]); } - + if (database[i][STATE]) fprintf(out, "\n%s", database[i][STATE]); @@ -1395,7 +1695,7 @@ text_export_database(FILE * out, struct db_enumerator e) char emails[MAX_EMAILS][MAX_EMAIL_LEN]; int j; char *realname = get_real_name(); - char *style = options_get_str("address_style"); + char *style = opt_get_str(STR_ADDRESS_STYLE); fprintf(out, "-----------------------------------------\n%s's address book\n" @@ -1407,7 +1707,7 @@ text_export_database(FILE * out, struct db_enumerator e) fprintf(out, "-----------------------------------------\n\n"); fprintf(out, "%s", database[e.item][NAME]); - if (database[e.item][NICK]) + if (database[e.item][NICK] && *database[e.item][NICK]) fprintf(out, "\n(%s)", database[e.item][NICK]); fprintf(out, "\n"); @@ -1476,7 +1776,7 @@ elm_alias_export(FILE *out, struct db_enumerator e) alias, database[e.item][NAME], email); - my_free(alias); + xfree(alias); } return 0; @@ -1519,3 +1819,34 @@ spruce_export_database (FILE *out, struct db_enumerator e) * end of Spruce export filter */ +/* + * wanderlust addressbook export filter + */ + +static int +wl_export_database(FILE *out, struct db_enumerator e) +{ + char emails[MAX_EMAILS][MAX_EMAIL_LEN]; + + fprintf (out, "# Wanderlust address book written by %s\n\n", PACKAGE); + db_enumerate_items(e) { + split_emailstr(e.item, emails); + if (**emails) { + fprintf(out, + "%s\t\"%s\"\t\"%s\"\n", + *emails, + safe_str(database[e.item][NICK]), + safe_str(database[e.item][NAME]) + ); + } + } + + fprintf (out, "\n# End of address book file.\n"); + + return 0; +} + +/* + * end of wanderlust addressbook export filter + */ +