[Thread Prev][Thread Next][Thread Index]

Re: AddressDB.pdb --> AddressDB.txt ?



Martin von Weissenberg writes:
>For a few weeks now I have been writing on a perl script that will
>list addresses and grep stuff from the AddressDB.pdb file, but my
>schedule is a little cramped and the script is not releasable yet.
>I'll spend some hours on it tomorrow (assuming that my boss is looking
>the other way) and then post the results, functional or not.

Here goes.  The PrintRecord routine is unfinished.  Otherwise it's
pretty OK, and the UpdateWorkfile routine seems to work very well.
The work file is BTW a tab-delimited file. I'm currently working on
the pattern binding stuff at the end that will prevent line feeds from
entering the work data base...

If you try this out and/or find bugs in it, mail me at mvw@xxxxxxx

Save this as ~/bin/pad.

--Martin

===============
#!/usr/local/bin/perl -- # -*- perl -*-
eval 'exec /usr/local/bin/perl -S $0 "$*"'
    if undef;

# Pilot Address Dumper (or Pretty Awesome D...)
# (C) Martin von Weissenberg (mvw@xxxxxx), 1997
# Very alpha-stage software.  Insert standard disclaimer here.
#
# This script keeps a translated database in a work file in
# ~/.pilotmgr, to save some time.  If AddressDB.pdb is newer than the
# work file, we update the work file by translating the address file
# again.
#
# In any case, if there are arguments left when all options have been
# parsed, we grep through the work file and then pretty-print the
# lines we found.

$addressdbpath = $ENV{HOME} . "/.pilotmgr/Backup/AddressDB.pdb";
$workdbpath = $ENV{HOME} . "/.pilotmgr/addresses";

$caseSensitivity='-i';
$fieldNum=22;			# = 23-1, why not 20-1 as in address.c??
@phoneLabels = ("Work", "Home", "Fax", "Other", "E-mail", "Main", "Pager", "Mobile");
$mode='d';
$forceUpdate=0;

while ($_=$ARGV[0], /^-/) {
    shift @ARGV;
    if (/^-d(.*)$/ && length($1)) {
	$addressdbpath=$1;
	next;
    } elsif (/^-w(.*)$/ && length($1)) {
	$workdbpath=$1;
	next;
    } elsif (/^-l(.*)$/ && length($1)) {
	$mode=substr($1,0,1);
	next;
    } elsif (/^-f$/) {
	$forceUpdate=1;
	next;
    } elsif (/^-c$/) {
	$caseSensitivity='';
	next;
    } else {
	goto USAGE;
    }
}

if ($forceUpdate) {
    &UpdateWorkbase($addressdbpath, $workdbpath);
    if (! $ARGV[0]) {
	exit 0;
    }
}

if ($ARGV[0]) {
    @ads = stat($addressdbpath) || die "$0: No such address database as $addressdbpath";
    @wds = stat($workdbpath);
    
    if ($ads[9]>$wds[9]) {
	&UpdateWorkbase($addressdbpath, $workdbpath);
    }
    open (INF, "< $workdbpath") ||
	die "$0: Cannot find work database file $workdbpath\n";
    $labels=<INF>;
    close(INF);

    while ($keyword=$ARGV[0]) {
	shift;
	open (INF, "grep $caseSensitivity $keyword $workdbpath |");
	while ($line=<INF>) {
	    &PrintRecord($labels, $line, $mode);
	}
	close (INF);
    }

} else {
USAGE:
    print <<EOF;
Usage: $0 re1 [re2 ...]
Options:
\t-l[paz]\tList options: default is to print only current phone
\t\tp = phone#, a = address, z = all
\t-c\tCase sensitivity on (default: off)
\t-f\tForce work file update (default: off).
\t-dPATH\tThe address pdb file to use.
\t-wPATH\tThe work file to use.
EOF
exit 1;
}
exit 0;

#
# PrintRecord prints the specified record using the labels and mode.
# Data field 22 contains phone field labels in a packed format.
#

sub PrintRecord {
    local ($lbls, $line, $mode) = @_;

    @labels = split(/\t/, $lbls);
    @data = split(/\t/, $line);

    if ($mode = 'd') {
	$whph = (ord($data[22]) - ord('0'));
	$whlbl = ord(substr($data[22],$whph+1,1)) - ord('0');
	
	print (STDOUT  (($data[0]) ? $data[0] . " " . $data[1] : $data[2])
	       . " --- " . $phoneLabels[$whlbl] . ": " . $data[$whph + 3]
	       . "\n");
    } elsif ($mode = 'p') {
	print (STDOUT "\n");
    } elsif ($mode = 'a') {

    } elsif ($mode = 'z') {

    } else {
	die "$0: Invalid mode specification.";
    }
}

#
# UpdateWorkbase parses the specified AddressDB file to a
# tab-delimited file specified by $wdb.  The last field in each record
# contains the phone number field labels in a packed format.
#

sub UpdateWorkbase {
    local ($adb,$wdb)=@_;
    
    @foo = stat($adb);

    open (ADB, "<" . $adb) ||
	die "$0: Cannot find the AddressDB.pdb file\n";
    if (-f $wdb) {
	system("mv -f $wdb $wdb.bak");
    }
    open (WDB, ">" . $wdb) ||
	die "$0: Cannot open the work data file $wdb\n";

    read ADB, $packedHeader, 78;
    @fileHeader = unpack("a32 a28 a8 a8 S", $packedHeader);
    $name = $fileHeader[0];
    $typecrea = $fileHeader[2];
    $numRecords = $fileHeader[4];

#    if ($typecrea != "DATAaddr") die "$0: File $adb is not a suitable database\n";

    for ($i=0; $i<$numRecords; $i++) { # read in record offsets
	read ADB, $d, 8;
	$offset[$i] = unpack ("N x4", $d);
#	print (STDOUT $offset[$i]);
    }
    $offset[$numRecords] = $foo[7]; # EOF location

    read ADB, $d, 284;		# skip all category stuff
				# can be implemented later

    for ($i=0; $i<$fieldNum; $i++) {	# read in field labels
	read ADB, $labels[$i], 16;
	$idx = index($labels[$i], "\0");
	$labels[$i] = substr($labels[$i], 0, $idx);
	print (WDB $labels[$i] . "\t");
    }
    print (WDB "Labels\n");
    
    read ADB, $d, 4;		# skip stuff

    for ($i=0; $i<$numRecords-1; $i++) {
# the following seek command is commented out for speed
	seek ADB, $offset[$i], 0;
	read ADB, $d, 9;
	@rawRec = unpack("C C C C C C C C C", $d);
	$whichPh = ($rawRec[1] & 0xF0)>>4;	# which phone nr is the default
	$phLbl[4] = ($rawRec[1] & 0x0F);
	$phLbl[3] = ($rawRec[2] & 0xF0)>>4;
	$phLbl[2] = ($rawRec[2] & 0x0F);
	$phLbl[1] = ($rawRec[3] & 0xF0)>>4;
	$phLbl[0] = ($rawRec[3] & 0x0F);
	$contents =  ($rawRec[5] * (1 << 16))
	    + ($rawRec[6] * (1 << 8)) + ($rawRec[7]);

	read ADB, $d, ($offset[$i+1] - $offset[$i]) - 9;

	for ($j=0; $j<$fieldNum; $j++) {
	    if ($contents & (1 << $j)) {
		$idx = index($d, "\0");
		$data[$j] = substr($d, 0, $idx);
		$d = substr($d, length($data[$j])+1);
	    } else {
		$data[$j] = "";
	    }			# 
	    $data[$j] =~ s/\r/, /go;
	    print (WDB $data[$j] . "\t");
	}
	print (WDB join("",$whichPh,@phLbl));
	print (WDB "\n");
    }
    close (WDB);
    close (ADB);
}

---------------------------------------------------------------------
********************************************
*   PLEASE DO NOT POST PILOTMANAGER BUGS   *
*  TO THIS ALIAS.  SUBMIT BUG REPORTS VIA  *
*     THE FEEDBACK MENU IN PILOTMANAGER    *
*             --------------------         *
*      This is a public mailing list!      *
*  Please do not publish Sun proprietary   *
*            information here!             *
********************************************


SourceForge.net Logo