You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

314 lines
7.6 KiB

/*
* $Id: address.c,v 1.30 2006/11/22 22:52:25 adridg Exp $
*
* address.c: Translate Pilot address book data formats
* (c) 1996, Kenneth Albanowski
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Library General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library
* General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "pi-macros.h"
#include "pi-address.h"
#define hi(x) (((x) >> 4) & 0x0f)
#define lo(x) ((x) & 0x0f)
#define pair(x,y) (((x) << 4) | (y))
/***********************************************************************
*
* Function: free_Address
*
* Summary: Free the members of an address structure
*
* Parameters: Address_t*
*
* Returns: void
*
***********************************************************************/
void
free_Address(Address_t *addr)
{
int i;
for (i = 0; i < 19; i++)
if (addr->entry[i]) {
free(addr->entry[i]);
addr->entry[i] = NULL;
}
}
/***********************************************************************
*
* Function: unpack_Address
*
* Summary: Fill in the address structure based on the raw record
* data
*
* Parameters: Address_t*, pi_buffer_t *buf
*
* Returns: -1 on error, 0 on success
*
***********************************************************************/
int
unpack_Address(Address_t *addr, const pi_buffer_t *buf, addressType type)
{
unsigned long contents,
v;
size_t ofs;
if (type != address_v1)
/* Don't support anything else yet */
return -1;
if (buf == NULL || buf->data == NULL || buf->used < 9)
return -1;
/* get_byte(buffer); gapfill */
addr->showPhone = hi(get_byte(buf->data + 1));
addr->phoneLabel[4] = lo(get_byte(buf->data + 1));
addr->phoneLabel[3] = hi(get_byte(buf->data + 2));
addr->phoneLabel[2] = lo(get_byte(buf->data + 2));
addr->phoneLabel[1] = hi(get_byte(buf->data + 3));
addr->phoneLabel[0] = lo(get_byte(buf->data + 3));
contents = get_long(buf->data + 4);
/* get_byte(buf->data+8) offset */
ofs = 9;
/* if(flag & 0x1) {
addr->lastname = strdup((buf->data + ofs);
ofs += strlen((buf->data + ofs)) + 1;
} else {
addr->lastname = 0;
} */
for (v = 0; v < 19; v++) {
if (contents & (1 << v)) {
if ((buf->used - ofs) < 1)
return 0;
addr->entry[v] = strdup((char *) (buf->data + ofs));
ofs += strlen(addr->entry[v]) + 1;
} else {
addr->entry[v] = 0;
}
}
return 0;
}
/***********************************************************************
*
* Function: pack_Address
*
* Summary: Fill in the raw address record data based on the
* address structure
*
* Parameters: Address_t*, pi_buffer_t *buf of record, record type
*
* Returns: -1 on error, 0 on success.
*
***********************************************************************/
int
pack_Address(const Address_t *addr, pi_buffer_t *buf, addressType type)
{
unsigned int l,
destlen = 9;
unsigned char *buffer;
unsigned long contents,
v,
phoneflag;
unsigned char offset;
if (addr == NULL || buf == NULL)
return -1;
if (type != address_v1)
/* Don't support anything else yet */
return -1;
for (v = 0; v < 19; v++)
if (addr->entry[v] && strlen(addr->entry[v]))
destlen += strlen(addr->entry[v]) + 1;
pi_buffer_expect (buf, destlen);
buf->used = destlen;
buffer = buf->data + 9;
phoneflag = 0;
contents = 0;
offset = 0;
for (v = 0; v < 19; v++) {
if (addr->entry[v] && strlen(addr->entry[v])) {
if (v == entryCompany)
offset =
(unsigned char) (buffer - buf->data) - 8;
contents |= (1 << v);
l = strlen(addr->entry[v]) + 1;
memcpy(buffer, addr->entry[v], l);
buffer += l;
}
}
phoneflag = ((unsigned long) addr->phoneLabel[0]) << 0;
phoneflag |= ((unsigned long) addr->phoneLabel[1]) << 4;
phoneflag |= ((unsigned long) addr->phoneLabel[2]) << 8;
phoneflag |= ((unsigned long) addr->phoneLabel[3]) << 12;
phoneflag |= ((unsigned long) addr->phoneLabel[4]) << 16;
phoneflag |= ((unsigned long) addr->showPhone) << 20;
set_long(buf->data, phoneflag);
set_long(buf->data + 4, contents);
set_byte(buf->data + 8, offset);
return 0;
}
/***********************************************************************
*
* Function: unpack_AddressAppInfo
*
* Summary: Fill in the app info structure based on the raw app
* info data
*
* Parameters: AddressAppInfo_t*, char * to record, record length
*
* Returns: The necessary length of the buffer if record is NULL,
* or 0 on error, the length of the data used from the
* buffer otherwise
*
***********************************************************************/
int
unpack_AddressAppInfo(AddressAppInfo_t *ai, const unsigned char *record, size_t len)
{
size_t i,
destlen = 4 + 16 * 22 + 2 + 2;
unsigned char *start = record;
unsigned long r;
ai->type = address_v1;
i = unpack_CategoryAppInfo(&ai->category, record, len);
if (!record)
return i + destlen;
if (!i)
return i;
record += i;
len -= i;
if (len < destlen)
return 0;
r = get_long(record);
for (i = 0; i < 22; i++)
ai->labelRenamed[i] = !!(r & (1 << i));
record += 4;
memcpy(ai->labels, record, 16 * 22);
record += 16 * 22;
ai->country = get_short(record);
record += 2;
ai->sortByCompany = get_byte(record);
record += 2;
for (i = 3; i < 8; i++)
strcpy(ai->phoneLabels[i - 3], ai->labels[i]);
for (i = 19; i < 22; i++)
strcpy(ai->phoneLabels[i - 19 + 5], ai->labels[i]);
return (record - start);
}
/***********************************************************************
*
* Function: pack_AddressAppInfo
*
* Summary: Fill in the raw app info record data based on the app
* info structure
*
* Parameters: AddressAppInfo_t*, char * to record, record length
*
* Returns: The length of the buffer required if record is NULL,
* or 0 on error, the length of the data used from the
* buffer otherwise
*
***********************************************************************/
int
pack_AddressAppInfo(const AddressAppInfo_t *ai, unsigned char *record, size_t len)
{
int i;
size_t destlen = 4 + 16 * 22 + 2 + 2;
unsigned char *pos = record;
unsigned long r;
i = pack_CategoryAppInfo(&ai->category, record, len);
if (!record)
return destlen + i;
if (!i)
return i;
pos += i;
len -= i;
for (i = 3; i < 8; i++)
strcpy(ai->phoneLabels[i - 3], ai->labels[i]);
for (i = 19; i < 22; i++)
strcpy(ai->phoneLabels[i - 19 + 5], ai->labels[i]);
memset(pos, 0, destlen);
r = 0;
for (i = 0; i < 22; i++)
if (ai->labelRenamed[i])
r |= (1 << i);
set_long(pos, r);
pos += 4;
memcpy(pos, ai->labels, 16 * 22);
pos += 16 * 22;
set_short(pos, ai->country);
pos += 2;
set_byte(pos, ai->sortByCompany);
pos += 2;
for (i = 3; i < 8; i++)
strcpy(ai->phoneLabels[i - 3], ai->labels[i]);
for (i = 19; i < 22; i++)
strcpy(ai->phoneLabels[i - 19 + 5], ai->labels[i]);
return (pos - record);
}
/* vi: set ts=8 sw=4 sts=4 noexpandtab: cin */
/* ex: set tabstop=4 expandtab: */
/* Local Variables: */
/* indent-tabs-mode: t */
/* c-basic-offset: 8 */
/* End: */