2vcard-0.5/ 40755 1750 144 0 7675156254 11676 5 ustar jschauma users 2vcard-0.5/AUTHORS 100600 1750 144 237 7632465377 13017 0 ustar jschauma users Jan Schaumann
Support for Juno format by
Support for LDIF format by
2vcard-0.5/CHANGES 100600 1750 144 1263 7675155646 12764 0 ustar jschauma users 2003-06-22: Released version 0.5:
- support conversion from eudora
- import changes from christophe.huibonhoa@memscap.com to
enable support for LDIF
- minor bugfix in getopts handling
- minor code cleanup
2002-11-27: Released version 0.4:
- import changes from Gregory.Krohne@AFRC.AF.MIL to
enable conversion from Juno
- change license to BSD style license
2001-10-10: Released version 0.3:
- now supports conversion from abook-addressbook files
2001-09-24: Released version 0.2:
- now supports conversion from mh-alias files
2001-09-23: Released first version of 2vcard to the world
2vcard-0.5/COPYING 100600 1750 144 3332 7632425432 13005 0 ustar jschauma users ###############################################################################
#
# $Author: Jan Schaumann $
#
# Copyright (c) 2001,2002,2003 Jan Schaumann
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * The name of the author may not be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
###############################################################################
2vcard-0.5/Makefile 100600 1750 144 705 7571447137 13403 0 ustar jschauma users DOC = doc/html/index.html doc/html/index-1.html doc/html/index-2.html \
doc/html/index-3.html doc/html/index-4.html doc/html/index-5.html
INSTALL = install -c -m 644
PREFIX= /usr/local
all:
install: $(DOC)
install -d $(PREFIX)/bin
install -d $(PREFIX)/share/man/man1
install -d $(PREFIX)/share/doc/2vcard
install -c -m 755 src/2vcard $(PREFIX)/bin
$(INSTALL) doc/2vcard.1 $(PREFIX)/share/man/man1
$(INSTALL) $(DOC) $(PREFIX)/share/doc/2vcard
2vcard-0.5/README 100600 1750 144 10162 7675155704 12662 0 ustar jschauma users The 2vcard Handbook
Jan Schaumann jschauma@netmeister.org
Version 0.5 , Sat Jun 21 18:14:30 EDT 2003
This Handbook describes 2vcard Version 0.5
1. Introduction
2. Installation
2.1 How to obtain 2vcard
2.2 Requirements
2.3 Compilation and installation
3. Usage
4. Copyright
5. Misc
------------------------------------------
1. Introduction
2vcard is a little perl script to convert an addressbook to the popular VCARD
file format. Currently, 2vcard can convert mutt's and mh's alias as well as
pine's, abook's and juno's addressbook format.
The VCARD format is used by gnomecard, for example, which in turn is used by
the balsa email client.
This is version 0.5 of 2vcard.
------------------------------------------
2. Installation
2.1 How to obtain 2vcard
2vcard 0.4 can be obtained from:
http://www.netmeister.org/apps/2vcard/2vcard-0.5.tar.gz - as a gzipped source-tarball
http://www.netmeister.org/apps/2vcard/2vcard-0.5.tar.bz2 - as a bzip2'ed source-tarball
2.2 Requirements
In order to successfully use 2vcard, you need the following programs and
libraries which are available on most platforms as distribution packages and
thereby can be installed easily.
Required:
Perl http://www.perl.com
2.3 Compilation and installation
2vcard assumes that the Perl executable lives in /usr/bin/perl - if that is
not the case, use your favorite editor to modify the first line of the file
2vcard accordingly.
In order to install 2vcard from sources, type the following in the directory
to which you downloaded the 2vcard distribution:
% tar zxvf 2vcard-0.5.tar.gz
% cd 2vcard-0.5
% less README
% su
% make install
This will install 2vcard in /usr/local/bin, the man page in /usr/local/share/man/man1/ and
the documentation in /usr/local/share/doc/2vcard/.
Should you run into problems please report them to the the author at
jschauma@netmeister.org
------------------------------------------
3. Usage
Per default, 2vcard reads from stdin and writes to stdout. Alternatively, the
input- and output-files can be specified as command-line options.
Examples:
In a pipe:
cat ~/.addressbook | 2vcard -p
Alone:
2vcard -i ~/.aliases -o ~/.addbook.grcd
If you run into any problems, if you encounter bugs, or if you have any other
comments on this program,please don't hesitate to email me.
------------------------------------------
4. Copyright
2vcard Copyright 2001,2002,2003 Jan Schaumann, jschauma@netmeister.org
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
------------------------------------------
5. Misc
Please take the time to visit these websites:
http://www.hrweb.org/legal/udhr.html
http://www.aclu.org
http://www.amnesty.org
http://www.worldwildlife.org
http://www.ncadp.org
Take the time to think about it.
2vcard-0.5/doc/ 40700 1750 144 0 7675156567 12440 5 ustar jschauma users 2vcard-0.5/doc/html/ 40700 1750 144 0 7675156566 13403 5 ustar jschauma users 2vcard-0.5/doc/html/index.html 100600 1750 144 4324 7675156562 15476 0 ustar jschauma users
The 2vcard Handbook
Next Previous Table
of Contents
The 2vcard Handbook
Jan Schaumann jschauma@netmeister.org
Version 0.5 , Sat Jun 21 18:21:44 EDT 2003
Back to
netmeister.org
This Handbook describes 2vcard Version 0.5
Next Previous Table
of Contents

2vcard-0.5/doc/html/index-3.html 100600 1750 144 3537 7675156525 15642 0 ustar jschauma users
The 2vcard Handbook: Usage
Next Previous Table of
Contents
Per default, 2vcard reads from stdin and writes to stdout.
Alternatively, the input- and output-files can be specified as command-line options.
Examples:
In a pipe:
tr '^M' '\n' < EudoraNicknames | 2vcard -f eudora > out
Alone:
2vcard -i ~/.aliases -o ~/.addbook.grcd
If you run into any problems, if you encounter bugs, or if
you have any other comments on this program,please don't
hesitate to email
me.
Next Previous Table of
Contents

2vcard-0.5/doc/html/index-2.html 100600 1750 144 6151 7632465743 15632 0 ustar jschauma users
The 2vcard Handbook: Installation
Next Previous Table of
Contents
2vcard 0.5 can be obtained from:
In order to successfully use 2vcard, you need the
following programs and libraries which are available on most
platforms as distribution packages and thereby can be installed
easily.
Required:
2vcard assumes that the Perl executable lives in
/usr/bin/perl
- if that is not the case, use your
favorite editor to modify the first line of the file
2vcard accordingly.
In order to install 2vcard from sources, type the
following in the directory to which you downloaded the
2vcard distribution:
% tar zxvf 2vcard-0.5.tar.gz
% cd 2vcard-0.5
% less README
% su
% make install
This will install 2vcard in
/usr/local/bin
, the man page in
/usr/local/share/man/man1/
and the documentation in
/usr/local/share/doc/2vcard/
Should you run into problems please report them to the the
author at jschauma@netmeister.org
Next Previous Table of
Contents

2vcard-0.5/doc/html/index-1.html 100600 1750 144 3220 7675156436 15626 0 ustar jschauma users
The 2vcard Handbook: Introduction
Next Previous Table of Contents
2vcard
is a little perl script to convert an addressbook to the popular
VCARD file format. Currently, 2vcard can convert addressbooks
and alias files from the following formats: abook, eudora, juno,
ldif, mutt, mh and pine.
The VCARD format is used by gnomecard, for example, which in turn is used
by the balsa email client.
This is version 0.5 of 2vcard.
Next Previous Table of Contents

2vcard-0.5/doc/html/index-5.html 100600 1750 144 3424 7361177146 15631 0 ustar jschauma users
The 2vcard Handbook: Misc
Next Previous Table of Contents
Please take the time to visit these websites:
Take the time to think about it.
Next Previous Table of Contents

2vcard-0.5/doc/html/index-4.html 100600 1750 144 5517 7632465760 15640 0 ustar jschauma users
The 2vcard Handbook: Copyright
Next Previous Table of
Contents
2vcard Copyright 2001,2002,2003 Jan Schaumann, jschauma@netmeister.org
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
Next Previous Table of
Contents

2vcard-0.5/doc/2vcard.1 100600 1750 144 4002 7675160235 13761 0 ustar jschauma users .\"
.\" This page was created on 2001-10-10 22:04:52 by makeman.pl
.\" ``makeman.pl'' is part of the ``MakeMan'' project.
.\" For more information, please see http://mama.sourceforge.net
.\"
.TH 2VCARD 1 "March 08th, 2003" "2vcard" "Addressbook conversion tools"
.SH NAME
2vcard \- convert addressbooks to VCARD format
.SH SYNOPSIS
\fB2vcard\fR
[ \fI\-F | \-f | \-h | \-v \fR ] [ \fI
\-i \fR\fIFILE\fR ] [ \fI
\-o \fR\fIFILE\fR ]
.SH "DESCRIPTION"
.PP
\fB2vcard\fR is a little perl script to convert an
addressbook to the popular VCARD file format.
Currently,
\fB2vcard\fR can convert addressbooks and alias files from the following
formats: \fBabook\fR, \fBeudora\fR, \fBjuno\fR, \fBldif\fR,
\fBmutt\fR, \fBmh\fR and \fBpine\fR.
.PP
The VCARD format is used by \fBgnomecard\fR, for
example, which, in turn is used by the \fBbalsa\fR
email client.
.SH "USAGE"
.PP
Per default, \fB2vcard\fR reads
from \fIstdin\fR and
writes to \fIstdout\fR. Alternatively,
the input\- and output\-files can be specified as command\-line
options.
.SH "OPTIONS"
.PP
A summary of the options supported by
\fB2vcard\fR is included below.
.\" Begin List
.TP
\fB\-F\fR
print a list of the currently supported formats
.TP
\fB\-f \fR\fIformat\fR
convert from \fIformat\fR [
default: mutt ]
.TP
\fB\-h\fR
Show summary of options and exit.
.TP
\fB\-i \fR\fIFILE\fR
Read input from \fIFILE\fR.
.TP
\fB\-o \fR\fIFILE\fR
Write output to \fIFILE\fR.
.TP
\fB\-v\fR
Show version information and exit.
.\" End List
.SH "EXAMPLES"
.\" Begin List
.TP
In a pipe:
tr \fI'^M'\fR \fI'\\n'\fR < EudoraNicknames |
\fB2vcard \-f\fR \fIeudora\fR > out
.TP
Alone:
\fB2vcard \-i\fR
\fI~/.aliases\fR \fB\-o\fR
\fI~/.addbook.grcd\fR
.\" End List
.SH "VERSION"
.PP
0.5
.SH "BUGS"
.PP
Please report all bugs to the author.
.SH "SEE ALSO"
.PP
\fBmutt(1)\fR, \fBpine(1)\fR,
\fBgnomecard(1)\fR, \fBbalsa(1)\fR,
\fBnmh(1)\fR, \fBexmh(1)\fR,
\fBabook(1)\fR
.PP
The 2vcard
Handbook (Link to \fIhttp://www.netmeister.org/apps/2vcard/\fR)
.SH "AUTHOR"
.PP
Jan Schaumann
2vcard-0.5/src/ 40700 1750 144 0 7675155716 12455 5 ustar jschauma users 2vcard-0.5/src/2vcard 100700 1750 0 36302 7675154757 13603 0 ustar jschauma wheel #!/usr/bin/perl -w
use strict;
# Hint from http://www.seligma.com/download/palm-ldif2csv
use MIME::Base64;
use MIME::QuotedPrint;
###############################################################################
#
# $Author: Jan Schaumann $
#
# Copyright (c) 2001,2002,2003 Jan Schaumann
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * The name of the author may not be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
###############################################################################
use Getopt::Std;
my $NAME = "2vcard";
my $VERSION = "0.5";
my %SUPPORTED = ("abook" => 0, "mh" => 0, "mutt" => 1,
"pine" => 0, "juno" => 0, "ldif" => 0,
"eudora" => 0);
init();
main();
done();
#we're done - bye, bye
exit 0;
######### #########
######### Functions #########
######### #########
###
# parses command-line options etc.
###
sub init
{
my %Options;
my $ok = getopts('Ff:hi:o:v', \%Options);
if (!$ok) {
my $i;
my @values = keys(%Options);
foreach $i (@values) {
if (!$Options{$i}) {
print STDERR "Option '$i' requires an argument.\n";
print STDERR "Try $NAME -h for details.\n";
exit(1);
}
}
usage();
exit(1);
}
open (READ, "<&STDIN") ||
die "Can't read from STDIN-- WTF??\n";
open (WRITE, ">&STDOUT") ||
die "Can't write to STDOUT -- WTF??\n";
if ($Options{'f'}) {
setFormat("$Options{'f'}");
}
if ($Options{'F'}) {
formats();
exit 0;
}
if ($Options{'h'}) {
usage();
exit 0;
}
if ($Options{'v'}) {
print "$NAME Version $VERSION\n";
exit 0;
}
if ($Options{'i'}) {
open(READ, "$Options{'i'}") ||
die "Can't open \"$Options{'i'}\" for reading!\n";
}
if ($Options{'o'}) {
open(WRITE, ">$Options{'o'}") ||
die "Can't open \"$Options{'o'}\" for writing!\n";
}
if ($#ARGV > -1) {
usage();
exit(1);
}
}
###
# sets the current format
###
sub setFormat
{
my ($which) = @_;
my $key;
foreach $key (keys %SUPPORTED) {
$SUPPORTED{"$key"} = 0;
}
if ($which =~ m/(abook)|(eudora)|(juno)|(ldif)|(mh)|(mutt)|(pine)/) {
$SUPPORTED{"$which"} = 1;
} else {
print STDERR "$NAME: ERROR:\n";
print STDERR "Format \"$which\" not supported.\n";
print STDERR "Try \"-F\" and/or \"-h\".\n";
exit(1);
}
}
###
# check which format we want to read and dispatch to the proper function
###
sub main
{
parseAbook() if ($SUPPORTED{"abook"});
parseEudora() if ($SUPPORTED{"eudora"});
parseJuno() if ($SUPPORTED{"juno"});
parseLdif() if ($SUPPORTED{"ldif"});
parseMH() if ($SUPPORTED{"mh"});
parseMutt() if ($SUPPORTED{"mutt"});
parsePine() if ($SUPPORTED{"pine"});
}
###
# cleanup before we say bye bye
###
sub done
{
close WRITE;
close READ;
}
###
# Outputs one info line
###
sub Oneline
{
if ($_[0]) {
print WRITE "$_[1]";
if ($_[2]) {print WRITE ";quoted-printable";}
print WRITE ":$_[0]\n";
}
}
###
# parse Eudora alias file
###
sub parseEudora
{
my %eudoras = ();
while () {
#s/
/\n/g;
# Format is:
# alias nick email@address
# alias nick2 email@address
# ...
# note nick ...unknown^Cfields
# nicks first
if (m/^alias (.*) (.*@.*)$/) {
my $nick = $1;
my $email = $2;
$eudoras{"$nick"} = ();
$eudoras{"$nick"}{"email"} = $email;
}
elsif (m/^alias (.*) ,$/) {
my $nick = $1;
$eudoras{"$nick"} = ();
}
# all else later
if (m/note (.*) <(.*)$/) {
my $nick = $1;
my $info = $2;
if ($info =~ m/.*name:([^>]*)>[<\$]/) {
$eudoras{"$nick"}{"name"} = $1;
}
if ($info =~ m/.*phone:([^>]*)>.*/) {
$eudoras{"$nick"}{"phone"} = $1;
}
if ($info =~ m/.*address:([^>]*)>.*/) {
my $add = $1;
$add =~ s//;/g;
$eudoras{"$nick"}{"address"} = $add;
}
if ($info =~ m/.*fax:([^>]*)>.*/) {
$eudoras{"$nick"}{"fax"} = $1;
print $1;
}
if ($info =~ m/>([^<>]*)$/) {
$eudoras{"$nick"}{"note"} = $1;
}
}
}
my $key;
foreach $key (keys %eudoras) {
print WRITE "BEGIN:VCARD\n";
print WRITE "NICKNAME:$key\n";
my $fn = $eudoras{"$key"}{"name"};
if ($fn) {
my @name = split / /, $fn, 2;
my $x;
print WRITE "FN:$fn\n";
print WRITE "N:";
foreach $x (reverse @name) {
print WRITE "$x;";
}
print WRITE "\n";
}
my $email = $eudoras{"$key"}{"email"};
if ($email) {
print WRITE "EMAIL;INTERNET:$email\n";
}
my $phone = $eudoras{"$key"}{"phone"};
if ($phone) {
print WRITE "TEL;HOME:$phone\n";
}
my $fax = $eudoras{"$key"}{"fax"};
if ($fax) {
print WRITE "TEL;FAX:$fax\n";
}
my $addr = $eudoras{"$key"}{"address"};
if ($addr) {
print WRITE "ADR;HOME:Default;;$addr\n";
}
my $note = $eudoras{"$key"}{"note"};
if ($note) {
$note =~ s//;/g;
print WRITE "NOTE:$note\n";
}
print WRITE "END:VCARD\n\n";
}
}
###
# parses a mutt aliases file
###
sub parseMutt
{
while () {
# alias nick email@address (full name)
if (m/^alias (.*) (.*) \((.*)\)$/) {
my @name = split / /, $3, 2;
my $x;
print WRITE "BEGIN:VCARD\n";
print WRITE "FN:$3\n";
print WRITE "N:";
foreach $x (reverse @name) {
print WRITE "$x;";
}
print WRITE "\n";
$x = $2;
if ($x =~ m/(.*,.*)/) {
my @emails = split /,/, $1;
foreach $x (@emails)
{
print WRITE "EMAIL;INTERNET:$x\n";
}
} else {
print WRITE "EMAIL;INTERNET:$x\n";
}
print WRITE "END:VCARD\n\n";
} elsif (m/^alias ([^\s]*) (.*) (<.*>)/) {
# alias nick full name
my @name = split / /, $2, 2;
my $x;
print WRITE "BEGIN:VCARD\n";
print WRITE "FN:$2\n";
print WRITE "N:";
foreach $x (reverse @name) {
print WRITE "$x;";
}
print WRITE "\n";
$x = $3;
if ($x =~ m/(.*,.*)/) {
my @emails = split /,/, $1;
foreach $x (@emails) {
$x =~ s/[<>]//g;
print WRITE "EMAIL;INTERNET:$x\n";
}
} else {
$x =~ s/[<>]//g;
print WRITE "EMAIL;INTERNET:$x\n";
}
print WRITE "END:VCARD\n\n";
} else {
print STDERR "Skipping ill-formatted line:\n";
print STDERR " $_\n";
}
}
}
###
# parses a mh alias file
###
sub parseMH
{
while () {
# alias: email@address, email@address
if (m/^(.*): (.*)/) {
my $x;
print WRITE "BEGIN:VCARD\n";
print WRITE "FN:$1\n";
print WRITE "N:$1\n";
$x = $2;
if ($x =~ m/(.*,.*)/) {
my @emails = split /,/, $1;
foreach $x (@emails) {
$x =~ s/\s//g;
print WRITE "EMAIL;INTERNET:$x\n";
}
} else {
print WRITE "EMAIL;INTERNET:$x\n";
}
print WRITE "END:VCARD\n\n";
} else {
print STDERR "Skipping ill-formatted line:\n";
print STDERR " $_\n";
}
}
}
###
# parses a pine addressbook file
###
sub parsePine
{
while () {
# nick\tFull Name\temail@address
# nick\tFull Name\t(email@address,email@address)
if (m/^(.*)\t(.*)\t(.*\@.*)$/) {
my @name = split / /, $2, 2;
my $x;
print WRITE "BEGIN:VCARD\n";
print WRITE "FN:$2\n";
print WRITE "N:";
foreach $x (reverse @name) {
print WRITE "$x;";
}
print WRITE "\n";
$x = $3;
if ($x =~ m/\((.*)\)/) {
my @emails = split /,/, $1;
foreach $x (@emails) {
print WRITE "EMAIL;INTERNET:$x\n";
}
} else {
print WRITE "EMAIL;INTERNET:$3\n";
}
print WRITE "END:VCARD\n\n";
} else {
print STDERR "Skipping ill-formatted line:\n";
print STDERR " $_\n";
}
}
}
###
# parses a abook addressbook file
###
sub parseAbook
{
my $count = 0;
my %info;
LOOP:
while () {
# [num]
# name=Full Name
# email=foo@bar.com,foo@barbar.com
# address=Street
# city=City
# state=State
# zip=123123
# country=Country
# phone=1234/1234525
# workphone=1234/123455
# fax=fax
# mobile=mobile
# nick=Nick
# url=http://bl;ahlbahl.com
# notes=CellPhone#: 12345678901
next LOOP if (m/^#/);
if (m/^\[\d+\]$/) {
$count++;
next LOOP;
}
if (m/^$/) {
my $x;
# no entries without a note
if ($info{'name'}) {
my @name = split / /, $info{'name'}, 2;
print WRITE "BEGIN:VCARD\n";
print WRITE "FN:$info{'name'}\n";
print WRITE "N:";
foreach $x (reverse @name) {
print WRITE "$x;";
}
print WRITE "\n";
my @emails = split /,/, $info{'email'};
foreach $x (@emails) {
print WRITE "EMAIL;INTERNET:$x\n";
}
if ($info{'address'}) {
print WRITE "ADR;HOME:Default;;$info{'address'};";
foreach $x ("city", "address", "zip", "country") {
print WRITE "$info{$x};";
}
print WRITE "\n";
}
if ($info{'phone'}) {
print WRITE "TEL;HOME:$info{'phone'}\n";
}
if ($info{'workphone'}) {
print write "TEL;WORK:$info{'workphone'}\n";
}
if ($info{'fax'}) {
print write "TEL;FAX:$info{'fax'}\n";
}
if ($info{'mobile'}) {
print write "TEL;CELL:$info{'mobile'}\n";
}
if ($info{'url'}) {
print WRITE "URL:$info{'url'}\n";
}
if ($info{'notes'}) {
print WRITE "NOTE:$info{'notes'}\n";
}
print WRITE "END:VCARD\n\n";
}
foreach $x (keys %info) {
$info{$x} = "";
}
next LOOP;
}
if ($count) {
my ($key, $val) = split /=/;
if ($val) {
chomp($val);
$info{$key} = $val;
}
next LOOP;
}
}
}
###
# parses a Juno address book export file
###
sub parseJuno
{
my $count = 0;
my %info;
LOOP:
while () {
# Type:Entry
# Name:Burdell, George P.
# Email:burdell@gatech.edu,gburdell@cc.gatech.edu
# Alias:YellowJacket
next LOOP if (m/^#/);
if (m/^Type:Entry$/) {
$count++;
next LOOP;
}
if (m/^$/) {
my $x;
# no entries without a note
if ($info{'Name'}) {
my @name = split /,/, $info{'Name'}, 2;
print WRITE "BEGIN:VCARD\n";
print WRITE "FN:";
foreach $x (reverse @name) {
# Trim leading/trailing whitespace
$x =~ s/^\s+//;
$x =~ s/\s+$//;
print WRITE "$x ";
}
print WRITE "\n";
print WRITE "N:";
foreach $x (@name) {
# Trim leading/trailing whitespace
$x =~ s/^\s+//;
$x =~ s/\s+$//;
print WRITE "$x;";
}
print WRITE "\n";
my @emails = split /,/, $info{'Email'};
foreach $x (@emails) {
print WRITE "EMAIL;INTERNET:$x\n";
}
if ($info{'Alias'}) {
print WRITE "NOTE:$info{'Alias'}\n";
}
print WRITE "END:VCARD\n\n";
}
foreach $x (keys %info) {
$info{$x} = "";
}
next LOOP;
}
if ($count) {
my ($key, $val) = split /:/;
if ($val) {
chomp($val);
$info{$key} = $val;
}
next LOOP;
}
}
}
###
# parses a ldif addressbook file
###
sub parseLdif
{
my $count = 1;
my $key;
my $val;
my %info;
my %qp;
my %v;
LOOP:
while () {
# dn: cn=FIRST LNAME,mail=EM
# modifytimestamp: 20030227150502Z
# cn: FIRST LNAME
# mail: EM
# xmozillausehtmlmail: TRUE
# o: ORG
# locality: CITY
# givenname: FIRST
# sn: LNAME
# title: TITLE
# streetaddress:: QUREMQ0KQU
# QUREMQ0KQUREMg==
# postalcode: ZIP
# countryname: COUN
# telephonenumber: WORKph
# facsimiletelephonenumber: FAX
# xmozillaanyphone: WORKph
# homephone: HOMEPH
# cellphone: CELL
# ou: DPT
# homeurl: URL
# st: STAT
# xmozillanickname: NICK
# description:: Tk9UMQ0KTk9UMg==
# pagerphone: PAGER
# objectclass: top
# objectclass: person
next LOOP if (m/^#/);
# if newline is followed by space, remove both
if (s/^ //ms) {
chomp();
s/\r?\n$//;
$info{$key} .= $_;
next LOOP;
}
if ($key && $qp{$key}) {
$val = decode_base64($info{$key});
$val = encode_qp($val);
$val =~ s/\n/=0A/g;
$info{$key} = $val;
}
if (m/^\r?$/) {
my $x;
# no entries without a note
if ($info{'dn'}) {
my @name = split /[=,]/, $info{'dn'}, 2;
print WRITE "BEGIN:VCARD\n";
print WRITE "FN:$info{'cn'}\n";
print WRITE "N:";
if ($info{'sn'}) {print WRITE "$info{'sn'};";}
if ($info{'givenname'}) {print WRITE "$info{'givenname'}";}
print WRITE "\n";
my @emails = split /,/, $info{'mail'};
foreach $x (@emails) {
print WRITE "EMAIL;INTERNET:$x\n";
}
if ($info{'streetaddress'}) {
print WRITE "ADR";
if ( $qp{"streetaddress"} || $qp{"locality"} ||
$qp{"address"} || $qp{"st"} ||
$qp{"postalcode"} || $qp{"countryname"}) {
print WRITE ";quoted-printable";
}
print WRITE ":;;$info{'streetaddress'};";
foreach $x ("locality", "address", "st", "postalcode", "countryname") {
print WRITE "$info{$x};";
}
print WRITE "\n";
}
Oneline($info{'homephone'}, 'TEL;HOME', $qp{'homephone'});
Oneline($info{'telephonenumber'}, 'TEL;WORK', $qp{'telephonenumber'});
Oneline($info{'facsimiletelephonenumber'}, 'TEL;FAX', $qp{'facsimiletelephonenumber'});
Oneline($info{'cellphone'}, 'TEL;CELL', $qp{'cellphone'});
Oneline($info{'pagerphone'}, 'tel;pager', $qp{'pagerphone'});
Oneline($info{'xmozillausehtmlmail'}, 'x-mozilla-html', $qp{'xmozillausehtmlmail'});
Oneline($info{'title'}, 'title', $qp{'title'});
Oneline($info{'homeurl'}, 'URL', $qp{'homeurl'});
Oneline($info{'description'}, 'NOTE', $qp{'description'});
if ($info{'o'}) {
print WRITE "org:$info{'o'};";
if ($info{'ou'}) {print WRITE "$info{'ou'}";}
print WRITE "\n";
}
print WRITE "END:VCARD\n\n";
}
foreach $x (keys %info) {
$info{$x} = "";
$qp{$x} = "";
}
$key = "";
next LOOP;
}
($key, $val) = split /: /;
if ($val) {
chomp($val);
$val =~ s/\r$//;
if ($key =~ s/:$//) {
$qp{$key} = 1;
}
$info{$key} = $val;
}
next LOOP;
}
}
###
# prints a list of supported formats
###
sub formats
{
my $key;
print "$NAME $VERSION can convert the addressbooks of the following:\n";
foreach $key (sort(keys %SUPPORTED)) {
print "\t$key\n";
}
}
###
# prints out helpful information
###
sub usage
{
print "$NAME: convert an addressbook to vcard format\n";
print "Usage: $NAME [OPTION...]\n";
print "Options:\n";
print " -F\t\tshow supported formats\n";
print " -f FORMAT\tconvert from FROMAT [ default: mutt ]\n";
print " -h\t\tprint this message and exit\n";
print " -i FILE\tread input from FILE\n";
print " -o FILE\twrite output to FILE\n";
print " -v\t\tprint version number and exit\n";
}