[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [coldsync-hackers] speed
On Friday 17 October 2003 19:07, Christophe Beauregard wrote:
> Correct me if I'm wrong, but instead of implementing another SPC stack,
> couldn't he just link his C program to libpconn and use
> spc_client/dlp_cmd directly? That _appears_ to be what it's for, but I'm
> not sure how far the implementation goes towards what is needed.
Okay, that's cool. It actually works.
I cranked out a couple simple C conduits that use the spc_client code. See
attached. Once the SPC pipe is set up, all the DLP stuff just plain works.
There's also a plethora of code within coldsync itself which can serve as
guidelines on how to use the DLP stuff.
libpconn isn't exacly designed to be an external library (spc.h #including
"config.h" is a good indicator), but I hacked up a Makefile that does the
trick.
Oh, and it would probably be a Bad Thing to try to close the SPC pconn using
PConn_close(). The spc_client close function looks like it'll probably do
the Wrong Thing. Actually, spc_client.c could use some fine tuning all
around. The read() and write() methods don't handle errors, for example.
c.
/*
Very simple example of a ColdSync sync conduit in C.
It demonstrates an interesting function: to be able to use the
DLP (PalmOS RPC) function set from a C conduit.
It's also not one of my better pieces of code. You're better off throwing
away the code and using the concepts than trying to expand this into a
"real" conduit.
christophe.beauregard@sympatico.ca
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <ctype.h>
#include <errno.h>
#include <pconn/spc_client.h>
#include <pconn/dlp_cmd.h>
int main( int ac, char* av[] ) {
PConnection* pconn = NULL;
struct dlp_time dt;
time_t t;
struct tm* now;
int spc_fd = -1;
char* tmp;
char buf[PATH_MAX];
char* prefs[256]; /* arbitrary, but large enough */
unsigned int nprefs = 0;
char* headers[256];
unsigned int nheaders = 0;
memset( &dt, 0, sizeof(dt) );
/* not pretty, but all we expect is "-config" or "conduit sync" */
if( ac == 2 ) {
if( strcmp(av[1],"-config") ) {
fprintf( stderr, "usage: %s <flavor|-config>\n", av[0] );
exit( -1 );
}
printf(
"conduit sync {\n"
"\tpath: \"%s\"\n"
"\ttype: none\n"
"}\n", av[0] );
exit( 0 );
} else if( ac == 3 && !strcmp(av[1],"conduit") ) {
if( strcmp(av[2],"sync") ) {
fprintf( stderr, "401 Unknown flavor '%s'\n", av[2] );
exit( -1 );
}
} else {
fprintf( stderr, "usage: %s -config\n", av[0] );
exit( -1 );
}
/* read headers */
while( fgets(buf,sizeof(buf),stdin) != NULL ) {
buf[sizeof(buf)-1] = 0; /* fgets() is pretty stupid */
tmp = strrchr( buf, '\n' ); /* fgets doesn't strip trailing newline */
if( tmp ) *tmp = 0;
if( buf[0] == 0 ) break; /* end of headers */
tmp = strchr(buf,':');
if( tmp == NULL ) {
printf( "401 Invalid input [%s]\n", buf );
exit( -1 );
}
tmp ++;
while( *tmp && isspace(*tmp) ) tmp++;
if( !strncmp("Preference:", buf, 11 ) ) {
prefs[nprefs++] = strdup( tmp );
} else {
headers[nheaders++] = strdup( headers );
/* For this conduit, we only care about SPCpipe. The rest of the
headers are gravy */
if( !strncmp( "SPCPipe:", buf, 8 ) ) {
spc_fd = atoi( tmp );
}
}
}
if( spc_fd < 0 ) {
printf( "401 Unable to get SPC pipe\n" );
exit( -1 );
}
/* open a SPC connection */
pconn = new_spc_client( spc_fd );
if( pconn == NULL ) {
printf( "401 Failed to create SPC connection\n" );
exit( -1 );
}
/* feed time to PDA */
t = time(NULL);
now = localtime(&t);
if( now == NULL ) {
printf( "401 %s\n", strerror(errno) );
exit( -1 );
}
dt.year = now->tm_year + 1900;
dt.month = now->tm_mon + 1;
dt.day = now->tm_mday;
dt.hour = now->tm_hour;
dt.minute = now->tm_min;
dt.second = now->tm_sec;
DlpSetSysDateTime( pconn, &dt );
printf( "201 Timing is everything\n" );
exit( 0 );
}
/*
More complicated example of a ColdSync sync conduit in C.
This is ugly, but it shows you how you can read the memo database
in a C conduit.
christophe.beauregard@sympatico.ca
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <ctype.h>
#include <errno.h>
#include <pconn/spc_client.h>
#include <pconn/dlp_cmd.h>
static void process_memo( PConnection* pconn ) {
ubyte dbhandle;
uword index;
struct dlp_recinfo record;
char* buf = NULL;
struct dlp_opendbinfo dbinfo;
int rc;
rc = DlpOpenDB( pconn, 0, "MemoDB", DLPCMD_MODE_READ, &dbhandle );
if( rc ) return;
rc = DlpReadOpenDBInfo( pconn, dbhandle, &dbinfo );
if( rc ) dbinfo.numrecs = 0;
fprintf( stderr, "Reading %hu records\n", dbinfo.numrecs );
for( index = 0; index < dbinfo.numrecs; index ++ ) {
rc = DlpReadRecordByIndex( pconn, dbhandle, index, &record );
if( rc ) break;
rc = DlpReadRecordByID( pconn, dbhandle, record.id, 0, DLPC_RECORD_TOEND,
&record, &buf );
if( rc ) break;
fprintf( stderr, "Memo %u (%hu bytes)\n%s\n\n\n",
record.id, record.size, buf );
}
DlpCloseDB( pconn, dbhandle, 0 );
}
int main( int ac, char* av[] ) {
PConnection* pconn = NULL;
int spc_fd = -1;
char* tmp;
char buf[PATH_MAX];
char* prefs[256]; /* arbitrary, but large enough */
unsigned int nprefs = 0;
char* headers[256];
unsigned int nheaders = 0;
/* not pretty, but all we expect is "-config" or "conduit sync" */
if( ac == 2 ) {
if( strcmp(av[1],"-config") ) {
fprintf( stderr, "usage: %s <flavor|-config>\n", av[0] );
exit( -1 );
}
printf(
"conduit sync {\n"
"\tpath: \"%s\"\n"
"\ttype: memo/DATA\n"
"}\n", av[0] );
exit( 0 );
} else if( ac == 3 && !strcmp(av[1],"conduit") ) {
if( strcmp(av[2],"sync") ) {
fprintf( stderr, "401 Unknown flavor '%s'\n", av[2] );
exit( -1 );
}
} else {
fprintf( stderr, "usage: %s -config\n", av[0] );
exit( -1 );
}
/* read headers */
while( fgets(buf,sizeof(buf),stdin) != NULL ) {
buf[sizeof(buf)-1] = 0; /* fgets() is pretty stupid */
tmp = strrchr( buf, '\n' ); /* fgets doesn't strip trailing newline */
if( tmp ) *tmp = 0;
if( buf[0] == 0 ) break; /* end of headers */
tmp = strchr(buf,':');
if( tmp == NULL ) {
printf( "401 Invalid input [%s]\n", buf );
exit( -1 );
}
tmp ++;
while( *tmp && isspace(*tmp) ) tmp++;
if( !strncmp("Preference:", buf, 11 ) ) {
prefs[nprefs++] = strdup( tmp );
} else {
headers[nheaders++] = strdup( headers );
/* For this conduit, we only care about SPCpipe. The rest of the
headers are gravy */
if( !strncmp( "SPCPipe:", buf, 8 ) ) {
spc_fd = atoi( tmp );
}
}
}
if( spc_fd < 0 ) {
printf( "401 Unable to get SPC pipe\n" );
exit( -1 );
}
/* open a SPC connection */
pconn = new_spc_client( spc_fd );
if( pconn == NULL ) {
printf( "401 Failed to create SPC connection\n" );
exit( -1 );
}
process_memo( pconn );
printf( "201 Make a note\n" );
exit( 0 );
}
all: time-conduit memo-conduit
COLDSYNC=$(HOME)/src/coldsync-cvs/coldsync
time-conduit: time-conduit.c
$(CC) $(CFLAGS) -g -o time-conduit -I$(COLDSYNC) -I$(COLDSYNC)/include \
-L$(COLDSYNC)/libpconn -L$(COLDSYNC)/libpdb \
-lusb -lcap time-conduit.c -lpconn
memo-conduit: memo-conduit.c
$(CC) $(CFLAGS) -g -o memo-conduit -I$(COLDSYNC) -I$(COLDSYNC)/include \
-L$(COLDSYNC)/libpconn -L$(COLDSYNC)/libpdb \
-lusb -lcap memo-conduit.c -lpconn