/*
- * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 2001-2007 Match Grun and the Claws Mail team
+ * Claws Mail -- a GTK+ based, lightweight, and fast e-mail client
+ * Copyright (C) 2001-2015 Match Grun and the Claws Mail team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
*/
/*
* Functions necessary to access vCard files. vCard files are used
* by GnomeCard for addressbook, and Netscape for sending business
- * card information. Refer to RFC2426 for more information.
+ * card information. Refer to http://www.imc.org/pdi/vcard-21.txt and
+ * RFC2426 for more information.
*/
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#include "claws-features.h"
+#endif
+
#include <glib.h>
#include <sys/stat.h>
#include <string.h>
#include "addrcache.h"
#include "adbookbase.h"
#include "utils.h"
+#include "codeconv.h"
+#include "quoted-printable.h"
+#include "file-utils.h"
#define GNOMECARD_DIR ".gnome"
#define GNOMECARD_FILE "GnomeCard"
* Properties...
*/
void vcard_set_name( VCardFile* cardFile, const gchar *value ) {
- g_return_if_fail( cardFile != NULL );
+ cm_return_if_fail( cardFile != NULL );
addrcache_set_name( cardFile->addressCache, value );
}
void vcard_set_file( VCardFile* cardFile, const gchar *value ) {
- g_return_if_fail( cardFile != NULL );
+ cm_return_if_fail( cardFile != NULL );
addrcache_refresh( cardFile->addressCache );
cardFile->path = mgu_replace_string( cardFile->path, value );
g_strstrip( cardFile->path );
}
void vcard_set_accessed( VCardFile *cardFile, const gboolean value ) {
- g_return_if_fail( cardFile != NULL );
+ cm_return_if_fail( cardFile != NULL );
cardFile->addressCache->accessFlag = value;
}
* Return: TRUE if file was modified.
*/
gboolean vcard_get_modified( VCardFile *cardFile ) {
- g_return_val_if_fail( cardFile != NULL, FALSE );
+ cm_return_val_if_fail( cardFile != NULL, FALSE );
cardFile->addressCache->modified =
addrcache_check_file( cardFile->addressCache, cardFile->path );
return cardFile->addressCache->modified;
}
gboolean vcard_get_accessed( VCardFile *cardFile ) {
- g_return_val_if_fail( cardFile != NULL, FALSE );
+ cm_return_val_if_fail( cardFile != NULL, FALSE );
return cardFile->addressCache->accessFlag;
}
* Return: TRUE if file was read.
*/
gboolean vcard_get_read_flag( VCardFile *cardFile ) {
- g_return_val_if_fail( cardFile != NULL, FALSE );
+ cm_return_val_if_fail( cardFile != NULL, FALSE );
return cardFile->addressCache->dataRead;
}
-void vcard_set_read_flag( VCardFile *cardFile, const gboolean value ) {
- g_return_if_fail( cardFile != NULL );
- cardFile->addressCache->dataRead = value;
-}
/*
* Return status code from last file operation.
* Return: Status code.
*/
gint vcard_get_status( VCardFile *cardFile ) {
- g_return_val_if_fail( cardFile != NULL, -1 );
+ cm_return_val_if_fail( cardFile != NULL, -1 );
return cardFile->retVal;
}
ItemFolder *vcard_get_root_folder( VCardFile *cardFile ) {
- g_return_val_if_fail( cardFile != NULL, NULL );
+ cm_return_val_if_fail( cardFile != NULL, NULL );
return addrcache_get_root_folder( cardFile->addressCache );
}
gchar *vcard_get_name( VCardFile *cardFile ) {
- g_return_val_if_fail( cardFile != NULL, NULL );
+ cm_return_val_if_fail( cardFile != NULL, NULL );
return addrcache_get_name( cardFile->addressCache );
}
-/*
-* Refresh internal variables to force a file read.
-*/
-void vcard_force_refresh( VCardFile *cardFile ) {
- addrcache_refresh( cardFile->addressCache );
-}
-
/*
* Create new cardfile object for specified file.
*/
-VCardFile *vcard_create_path( const gchar *path ) {
+static VCardFile *vcard_create_path( const gchar *path ) {
VCardFile *cardFile;
cardFile = vcard_create();
vcard_set_file(cardFile, path);
* Free up cardfile object by releasing internal memory.
*/
void vcard_free( VCardFile *cardFile ) {
- g_return_if_fail( cardFile != NULL );
+ cm_return_if_fail( cardFile != NULL );
/* Close file */
- if( cardFile->file ) fclose( cardFile->file );
+ if( cardFile->file ) claws_fclose( cardFile->file );
/* Clear cache */
addrcache_clear( cardFile->addressCache );
* return: TRUE if file opened successfully.
*/
static gint vcard_open_file( VCardFile* cardFile ) {
- g_return_val_if_fail( cardFile != NULL, -1 );
+ cm_return_val_if_fail( cardFile != NULL, -1 );
/* g_print( "Opening file\n" ); */
cardFile->addressCache->dataRead = FALSE;
if( cardFile->path ) {
- cardFile->file = g_fopen( cardFile->path, "rb" );
+ cardFile->file = claws_fopen( cardFile->path, "rb" );
if( ! cardFile->file ) {
/* g_printerr( "can't open %s\n", cardFile->path ); */
cardFile->retVal = MGU_OPEN_FILE;
* Close file.
*/
static void vcard_close_file( VCardFile *cardFile ) {
- g_return_if_fail( cardFile != NULL );
- if( cardFile->file ) fclose( cardFile->file );
+ cm_return_if_fail( cardFile != NULL );
+ if( cardFile->file ) claws_fclose( cardFile->file );
cardFile->file = NULL;
}
*/
static gchar *vcard_read_line( VCardFile *cardFile ) {
while( *cardFile->bufptr == '\n' || *cardFile->bufptr == '\0' ) {
- if( fgets( cardFile->buffer, VCARDBUFSIZE, cardFile->file ) == NULL )
+ if( claws_fgets( cardFile->buffer, VCARDBUFSIZE, cardFile->file ) == NULL )
return NULL;
g_strstrip( cardFile->buffer );
cardFile->bufptr = cardFile->buffer;
start = cardFile->bufptr;
len = strlen( start );
end = start + len;
- strncpy( buf, start, len );
+ memcpy( buf, start, len );
buf[ len ] = '\0';
g_strstrip(buf);
cardFile->bufptr = end + 1;
* Free linked lists of character strings.
*/
static void vcard_free_lists( GSList *listName, GSList *listAddr, GSList *listRem, GSList* listID ) {
- mgu_free_list( listName );
- mgu_free_list( listAddr );
- mgu_free_list( listRem );
- mgu_free_list( listID );
+ g_slist_free_full( listName, g_free );
+ g_slist_free_full( listAddr, g_free );
+ g_slist_free_full( listRem, g_free );
+ g_slist_free_full( listID, g_free );
}
/*
line = mgu_list_coalesce( listQP );
/* Clean up */
- mgu_free_list( listQP );
+ g_slist_free_full( listQP, g_free );
listQP = NULL;
return line;
}
gint len = 0;
gchar *tag = NULL;
gchar *lptr = line;
-
+ gchar *down;
while( *lptr++ ) {
if( *lptr == dlm ) {
len = lptr - line;
tag = g_strndup( line, len+1 );
tag[ len ] = '\0';
- g_strdown( tag );
- return tag;
+ down = g_utf8_strdown( tag, -1 );
+ g_free(tag);
+ return down;
}
}
return tag;
if( *str != '\0' ) {
ItemEMail *email = addritem_create_item_email();
addritem_email_set_address( email, str );
- str = nodeRemarks->data;
if( nodeRemarks ) {
+ str = nodeRemarks->data;
if( str ) {
if( g_utf8_collate( str, "internet" ) != 0 ) {
if( *str != '\0' )
}
/* Unescape characters in quoted-printable string. */
-static void vcard_unescape_qp( gchar *value ) {
- gchar *ptr, *src, *dest;
- gint d, v = 0;
- gchar ch;
- gboolean gotch;
- ptr = value;
- while( *ptr ) {
- gotch = FALSE;
- if( *ptr == '=' ) {
- v = 0;
- ch = *(ptr + 1);
- if( ch ) {
- if( ch > '0' && ch < '8' ) v = ch - '0';
- }
- d = -1;
- ch = *(ptr + 2);
- if( ch ) {
- if( ch > '\x60' ) ch -= '\x20';
- if( ch > '0' && ch < ' ' ) d = ch - '0';
- d = ch - '0';
- if( d > 9 ) d -= 7;
- if( d > -1 && d < 16 ) {
- v = ( 16 * v ) + d;
- gotch = TRUE;
- }
- }
- }
- if( gotch ) {
- /* Replace = with char and move down in buffer */
- *ptr = v;
- src = ptr + 3;
- dest = ptr + 1;
- while( *src ) {
- *dest++ = *src++;
- }
- *dest = '\0';
- }
- ptr++;
+static gchar *vcard_unescape_qp( gchar *value ) {
+ gchar *res = NULL;
+ gint len;
+ if (value == NULL)
+ return NULL;
+
+ len = strlen(value);
+ res = g_malloc(len);
+ qp_decode_const(res, len-1, value);
+ if (!g_utf8_validate(res, -1, NULL)) {
+ gchar *mybuf = g_malloc(strlen(res)*2 +1);
+ conv_localetodisp(mybuf, strlen(res)*2 +1, res);
+ g_free(res);
+ res = mybuf;
}
+ return res;
}
-/*
+ /*
* Read file data into root folder.
* Note that one vCard can have multiple E-Mail addresses (MAIL tags);
* these are broken out into separate address items. An address item
/* g_print( "\ttype: %s\n", tagtype ); */
/* g_print( "\tvalue: %s\n", tagvalue ); */
- if( g_utf8_collate( tagtype, VCARD_TYPE_QP ) == 0 ) {
+ if( g_utf8_collate( tagtype, VCARD_TYPE_QP ) == 0
+ || g_utf8_collate( tagtype, VCARD_TYPE_E_QP ) == 0
+ || g_utf8_collate( tagtype, VCARD_TYPE_CS_UTF8_E_QP ) == 0) {
+ gchar *tmp;
/* Quoted-Printable: could span multiple lines */
tagvalue = vcard_read_qp( cardFile, tagvalue );
- vcard_unescape_qp( tagvalue );
+ tmp = vcard_unescape_qp( tagvalue );
+ g_free(tagvalue);
+ tagvalue=tmp;
/* g_print( "QUOTED-PRINTABLE !!! final\n>%s<\n", tagvalue ); */
}
*/
/* ============================================================================================ */
gint vcard_read_data( VCardFile *cardFile ) {
- g_return_val_if_fail( cardFile != NULL, -1 );
+ cm_return_val_if_fail( cardFile != NULL, -1 );
cardFile->retVal = MGU_SUCCESS;
cardFile->addressCache->accessFlag = FALSE;
* Return link list of persons.
*/
GList *vcard_get_list_person( VCardFile *cardFile ) {
- g_return_val_if_fail( cardFile != NULL, NULL );
+ cm_return_val_if_fail( cardFile != NULL, NULL );
return addrcache_get_list_person( cardFile->addressCache );
}
* Return: NULL.
*/
GList *vcard_get_list_folder( VCardFile *cardFile ) {
- g_return_val_if_fail( cardFile != NULL, NULL );
+ cm_return_val_if_fail( cardFile != NULL, NULL );
return NULL;
}
* Return: List of items, or NULL if none.
*/
GList *vcard_get_all_persons( VCardFile *cardFile ) {
- g_return_val_if_fail( cardFile != NULL, NULL );
+ cm_return_val_if_fail( cardFile != NULL, NULL );
return addrcache_get_all_persons( cardFile->addressCache );
}
-/*
-* Validate that all parameters specified.
-* Return: TRUE if data is good.
-*/
-gboolean vcard_validate( const VCardFile *cardFile ) {
- gboolean retVal;
- gchar *name;
-
- g_return_val_if_fail( cardFile != NULL, FALSE );
-
- retVal = TRUE;
- if( cardFile->path ) {
- if( strlen( cardFile->path ) < 1 ) retVal = FALSE;
- }
- else {
- retVal = FALSE;
- }
- name = addrcache_get_name( cardFile->addressCache );
- if( name ) {
- if( strlen( name ) < 1 ) retVal = FALSE;
- }
- else {
- retVal = FALSE;
- }
- return retVal;
-}
-
#define WORK_BUFLEN 1024
/*
gchar *vcard_find_gnomecard( void ) {
const gchar *homedir;
gchar buf[ WORK_BUFLEN ];
- gchar str[ WORK_BUFLEN ];
+ gchar str[ WORK_BUFLEN + 1 ];
gchar *fileSpec;
gint len, lenlbl, i;
FILE *fp;
homedir = get_home_dir();
if( ! homedir ) return NULL;
- strcpy( str, homedir );
+ strncpy( str, homedir, WORK_BUFLEN );
len = strlen( str );
if( len > 0 ) {
if( str[ len-1 ] != G_DIR_SEPARATOR ) {
str[ ++len ] = '\0';
}
}
- strcat( str, GNOMECARD_DIR );
- strcat( str, G_DIR_SEPARATOR_S );
- strcat( str, GNOMECARD_FILE );
+ strncat( str, GNOMECARD_DIR, WORK_BUFLEN - strlen(str) );
+ strncat( str, G_DIR_SEPARATOR_S, WORK_BUFLEN - strlen(str) );
+ strncat( str, GNOMECARD_FILE, WORK_BUFLEN - strlen(str) );
fileSpec = NULL;
- if( ( fp = g_fopen( str, "rb" ) ) != NULL ) {
+ if( ( fp = claws_fopen( str, "rb" ) ) != NULL ) {
/* Read configuration file */
lenlbl = strlen( GNOMECARD_SECTION );
- while( fgets( buf, sizeof( buf ), fp ) != NULL ) {
+ while( claws_fgets( buf, sizeof( buf ), fp ) != NULL ) {
if( 0 == g_ascii_strncasecmp( buf, GNOMECARD_SECTION, lenlbl ) ) {
break;
}
}
- while( fgets( buf, sizeof( buf ), fp ) != NULL ) {
+ while( claws_fgets( buf, sizeof( buf ), fp ) != NULL ) {
g_strchomp( buf );
if( buf[0] == '[' ) break;
for( i = 0; i < lenlbl; i++ ) {
}
}
}
- fclose( fp );
+ claws_fclose( fp );
}
if( fileSpec == NULL ) {
}
if( g_utf8_collate( tagtype, VCARD_TYPE_QP ) == 0 ) {
+ gchar *tmp;
/* Quoted-Printable: could span multiple lines */
tagvalue = vcard_read_qp( cardFile, tagvalue );
- vcard_unescape_qp( tagvalue );
+ tmp = vcard_unescape_qp( tagvalue );
+ g_free(tagvalue);
+ tagvalue=tmp;
}
if( g_utf8_collate( tagname, VCARD_TAG_START ) == 0 &&
g_ascii_strcasecmp( tagvalue, VCARD_NAME ) == 0 ) {