mirror of
				https://gitlab.alpinelinux.org/alpine/aports.git
				synced 2025-10-31 16:31:40 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			347 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			347 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| diff -aur old/filter.c new/filter.c
 | |
| --- old/filter.c	2006-09-06 15:26:10.000000000 +1000
 | |
| +++ new/filter.c	2012-05-31 17:48:18.644744197 +1000
 | |
| @@ -44,6 +44,7 @@
 | |
|  static int 	csv_parse_file(FILE *in);
 | |
|  static int 	allcsv_parse_file(FILE *in);
 | |
|  static int 	palmcsv_parse_file(FILE *in);
 | |
| +static int 	vcard_parse_file(FILE *in);
 | |
| 
 | |
|  /*
 | |
|   * export filter prototypes
 | |
| @@ -75,6 +76,7 @@
 | |
| 	{ "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 },
 | |
| +	{ "vcard", N_("vCard file"), vcard_parse_file },
 | |
| 	{ "\0", NULL, NULL }
 | |
|  };
 | |
| 
 | |
| @@ -1331,6 +1333,263 @@
 | |
|   */
 | |
| 
 | |
|  /*
 | |
| + * vCard import filter
 | |
| + */
 | |
| +
 | |
| +static char *vcard_fields[] = {
 | |
| +	"FN",			/* NAME */
 | |
| +	"EMAIL",		/* EMAIL */
 | |
| +	"ADR",			/* ADDRESS */
 | |
| +	"ADR",			/* ADDRESS2 - not used */
 | |
| +	"ADR",			/* CITY */
 | |
| +	"ADR",			/* STATE */
 | |
| +	"ADR",			/* ZIP */
 | |
| +	"ADR",			/* COUNTRY */
 | |
| +	"TEL",			/* PHONE */
 | |
| +	"TEL",			/* WORKPHONE */
 | |
| +	"TEL",			/* FAX */
 | |
| +	"TEL",			/* MOBILEPHONE */
 | |
| +	"NICKNAME",		/* NICK */
 | |
| +	"URL",			/* URL */
 | |
| +	"NOTE",			/* NOTES */
 | |
| +	"BDAY",			/* ANNIVERSARY */
 | |
| +	NULL
 | |
| +};
 | |
| +
 | |
| +/*
 | |
| + * mappings between vCard ADR field and abook's ADDRESS
 | |
| + * see rfc2426 section 3.2.1
 | |
| + */
 | |
| +static int vcard_address_fields[] = {
 | |
| +	-1,			/* vCard(post office box) - not used */
 | |
| +	-1,			/* vCard(the extended address) - not used */
 | |
| +	2,			/* vCard(the street address) - ADDRESS */
 | |
| +	4,			/* vCard(the locality) - CITY */
 | |
| +	5,			/* vCard(the region) - STATE */
 | |
| +	6,			/* vCard(the postal code) - ZIP */
 | |
| +	7			/* vCard(the country name) - COUNTRY */
 | |
| +};
 | |
| +
 | |
| +enum {
 | |
| +	VCARD_KEY = 0,
 | |
| +	VCARD_KEY_ATTRIBUTE,
 | |
| +	VCARD_VALUE,
 | |
| +};
 | |
| +
 | |
| +static char *
 | |
| +vcard_get_line_element(char *line, int element)
 | |
| +{
 | |
| +	int i;
 | |
| +	char *line_copy = 0;
 | |
| +	char *result = 0;
 | |
| +	char *key = 0;
 | |
| +	char *key_attr = 0;
 | |
| +	char *value = 0;
 | |
| +
 | |
| +	line_copy = xstrdup(line);
 | |
| +
 | |
| +	/* make newline characters if exist end of string */
 | |
| +	for(i=0; line_copy[i]; i++) {
 | |
| +		if(line_copy[i] == '\r' || line_copy[i] == '\n') {
 | |
| +			line_copy[i] = '\0';
 | |
| +			break;
 | |
| +		}
 | |
| +	}
 | |
| +
 | |
| +	/* separate key from value */
 | |
| +	for(i=0; line_copy[i]; i++) {
 | |
| +		if(line_copy[i] == ':') {
 | |
| +			line_copy[i] = '\0';
 | |
| +			key = line_copy;
 | |
| +			value = &line_copy[i+1];
 | |
| +			break;
 | |
| +		}
 | |
| +	}
 | |
| +
 | |
| +	/* separate key from key attributes */
 | |
| +	if (key) {
 | |
| +		for(i=0; key[i]; i++) {
 | |
| +			if(key[i] == ';') {
 | |
| +				key[i] = '\0';
 | |
| +				key_attr = &key[i+1];
 | |
| +				break;
 | |
| +			}
 | |
| +		}
 | |
| +	}
 | |
| +
 | |
| +	switch(element) {
 | |
| +	case VCARD_KEY:
 | |
| +		if(key)
 | |
| +			result = xstrdup(key);
 | |
| +		break;
 | |
| +	case VCARD_KEY_ATTRIBUTE:
 | |
| +		if(key_attr)
 | |
| +			result = xstrdup(key_attr);
 | |
| +		break;
 | |
| +	case VCARD_VALUE:
 | |
| +		if(value)
 | |
| +			result = xstrdup(value);
 | |
| +		break;
 | |
| +	}
 | |
| +
 | |
| +	xfree(line_copy);
 | |
| +	return result;
 | |
| +}
 | |
| +
 | |
| +static void
 | |
| +vcard_parse_email(list_item item, char *line)
 | |
| +{
 | |
| +	char *email;
 | |
| +
 | |
| +	email = vcard_get_line_element(line, VCARD_VALUE);
 | |
| +
 | |
| +	if(item[1]) {
 | |
| +		item[1] = strconcat(item[1], ",", email, 0);
 | |
| +		xfree(email);
 | |
| +	}
 | |
| +	else {
 | |
| +		item[1] = email;
 | |
| +	}
 | |
| +}
 | |
| +
 | |
| +static void
 | |
| +vcard_parse_address(list_item item, char *line)
 | |
| +{
 | |
| +	int i;
 | |
| +	int k;
 | |
| +	char *value;
 | |
| +	char *address_field;
 | |
| +
 | |
| +	value = vcard_get_line_element(line, VCARD_VALUE);
 | |
| +	if(!value)
 | |
| +		return;
 | |
| +
 | |
| +	address_field = value;
 | |
| +	for(i=k=0; value[i]; i++) {
 | |
| +		if(value[i] == ';') {
 | |
| +			value[i] = '\0';
 | |
| +			if(vcard_address_fields[k] >= 0) {
 | |
| +				item[vcard_address_fields[k]] = xstrdup(address_field);
 | |
| +			}
 | |
| +			address_field = &value[i+1];
 | |
| +			k++;
 | |
| +			if((k+1)==(sizeof(vcard_address_fields)/sizeof(*vcard_address_fields)))
 | |
| +				break;
 | |
| +		}
 | |
| +	}
 | |
| +	item[vcard_address_fields[k]] = xstrdup(address_field);
 | |
| +	xfree(value);
 | |
| +}
 | |
| +
 | |
| +static void
 | |
| +vcard_parse_phone(list_item item, char *line)
 | |
| +{
 | |
| +	int index = 8;
 | |
| +	char *type = vcard_get_line_element(line, VCARD_KEY_ATTRIBUTE);
 | |
| +	char *value = vcard_get_line_element(line, VCARD_VALUE);
 | |
| +
 | |
| +	/* set the standard number */
 | |
| +	if (!type) {
 | |
| +		item[index] = value;
 | |
| +	}
 | |
| +
 | |
| +	/*
 | |
| +	 * see rfc2426 section 3.3.1
 | |
| +	 */
 | |
| +	else if (strstr(type, "TYPE=") == type){
 | |
| +		if (strcasestr(type, "home")) {
 | |
| +			item[index] = xstrdup(value);
 | |
| +		}
 | |
| +		if (strcasestr(type, "work")) {
 | |
| +			item[index+1] = xstrdup(value);
 | |
| +		}
 | |
| +		if (strcasestr(type, "fax")) {
 | |
| +			item[index+2] = xstrdup(value);
 | |
| +		}
 | |
| +		if (strcasestr(type, "cell")) {
 | |
| +			item[index+3] = xstrdup(value);
 | |
| +		}
 | |
| +
 | |
| +		xfree(type);
 | |
| +		xfree(value);
 | |
| +	}
 | |
| +}
 | |
| +
 | |
| +static void
 | |
| +vcard_parse_line(list_item item, char *line)
 | |
| +{
 | |
| +	int i;
 | |
| +	char *key;
 | |
| +
 | |
| +	for(i=0; vcard_fields[i]; i++) {
 | |
| +		key = vcard_fields[i];
 | |
| +
 | |
| +		if(!strncmp(key, line, strlen(key))) {
 | |
| +			if(i == 1) {
 | |
| +				vcard_parse_email(item, line);
 | |
| +			}
 | |
| +			else if(i == 2) {
 | |
| +				vcard_parse_address(item, line);
 | |
| +			}
 | |
| +			else if(i == 8) {
 | |
| +				vcard_parse_phone(item, line);
 | |
| +			}
 | |
| +			else {
 | |
| +				item[i] = vcard_get_line_element(line, VCARD_VALUE);
 | |
| +			}
 | |
| +			break;
 | |
| +		}
 | |
| +	}
 | |
| +}
 | |
| +
 | |
| +static void
 | |
| +vcard_parse_item(FILE *in)
 | |
| +{
 | |
| +	char *line = NULL;
 | |
| +	list_item item = item_create();
 | |
| +
 | |
| +	while(!feof(in)) {
 | |
| +		line = getaline(in);
 | |
| +
 | |
| +		if(line && !strncmp("END:VCARD", line, 9)) {
 | |
| +			xfree(line);
 | |
| +			break;
 | |
| +		}
 | |
| +		else if(line) {
 | |
| +			vcard_parse_line(item, line);
 | |
| +			xfree(line);
 | |
| +		}
 | |
| +	}
 | |
| +
 | |
| +	add_item2database(item);
 | |
| +	item_free(&item);
 | |
| +}
 | |
| +
 | |
| +static int
 | |
| +vcard_parse_file(FILE *in)
 | |
| +{
 | |
| +	char *line = NULL;
 | |
| +
 | |
| +	while(!feof(in)) {
 | |
| +		line = getaline(in);
 | |
| +
 | |
| +		if(line && !strncmp("BEGIN:VCARD", line, 11)) {
 | |
| +			xfree(line);
 | |
| +			vcard_parse_item(in);
 | |
| +		}
 | |
| +		else if(line) {
 | |
| +			xfree(line);
 | |
| +		}
 | |
| +	}
 | |
| +
 | |
| +	return 0;
 | |
| +}
 | |
| +
 | |
| +/*
 | |
| + * end of vCard import filter
 | |
| + */
 | |
| +
 | |
| +/*
 | |
|   * csv addressbook export filters
 | |
|   */
 | |
| 
 | |
| @@ -1547,10 +1806,18 @@
 | |
| 
 | |
| 		free(name);
 | |
| 
 | |
| +		if(db_fget(e.item, NICK))
 | |
| +			fprintf(out, "NICKNAME:%s\r\n",
 | |
| +					db_fget(e.item, NICK));
 | |
| +
 | |
| +		if(db_fget(e.item, ANNIVERSARY))
 | |
| +			fprintf(out, "BDAY:%s\r\n",
 | |
| +					db_fget(e.item, ANNIVERSARY));
 | |
| +
 | |
| 		if(db_fget(e.item, ADDRESS))
 | |
| -			fprintf(out, "ADR:;;%s;%s;%s;%s;%s;%s\r\n",
 | |
| -				safe_str(db_fget(e.item, ADDRESS)),
 | |
| +			fprintf(out, "ADR:;%s;%s;%s;%s;%s;%s\r\n",
 | |
| 				safe_str(db_fget(e.item, ADDRESS2)),
 | |
| +				safe_str(db_fget(e.item, ADDRESS)),
 | |
| 				safe_str(db_fget(e.item, CITY)),
 | |
| 				safe_str(db_fget(e.item, STATE)),
 | |
| 				safe_str(db_fget(e.item, ZIP)),
 | |
| diff -aur old/misc.c new/misc.c
 | |
| --- old/misc.c	2006-09-05 05:24:18.000000000 +1000
 | |
| +++ new/misc.c	2012-05-31 17:40:46.241284874 +1000
 | |
| @@ -77,6 +77,27 @@
 | |
| 	return 1;
 | |
|  }
 | |
| 
 | |
| +char *
 | |
| +strcasestr(char *haystack, char *needle)
 | |
| +{
 | |
| +	int i;
 | |
| +	int k;
 | |
| +
 | |
| +	assert(haystack != NULL);
 | |
| +	assert(needle != NULL);
 | |
| +
 | |
| +	for(i=0; i<strlen(haystack)-strlen(needle)+1; i++) {
 | |
| +		for(k=0; k<strlen(needle); k++, i++) {
 | |
| +			if (tolower(haystack[i]) != tolower(needle[k]))
 | |
| +				break;
 | |
| +			else if ((k+1) == strlen(needle))
 | |
| +				return &haystack[i];
 | |
| +		}
 | |
| +	}
 | |
| +
 | |
| +	return NULL;
 | |
| +}
 | |
| +
 | |
| 
 | |
|  #ifdef HAVE_CONFIG_H
 | |
|  #	include "config.h"
 | |
| diff -aur old/misc.h new/misc.h
 | |
| --- old/misc.h	2006-09-05 05:24:18.000000000 +1000
 | |
| +++ new/misc.h	2012-05-31 17:40:46.241284874 +1000
 | |
| @@ -18,6 +18,8 @@
 | |
| 
 | |
|  int		is_number(char *s);
 | |
| 
 | |
| +char		*strcasestr(char *haystack, char *needle);
 | |
| +
 | |
|  char		*strdup_printf(const char *format, ... );
 | |
|  char		*strconcat(const char *str, ...);
 |