j2to1
script
Download, Add a comment, Back to main page
#!/usr/bin/perl
#
# Jabberd2 to 1 migration script, version 0.3
#
# This script pulls data out of a Jabberd2 database and creates a Jabberd1
# spool directory based off what it finds. It is built around a MySQL-based
# Jabberd2 database, but may work with a Postgres one as well.
#
# Daniel Henninger <JID: daniel@jabber.vorpalcloud.org>
#
# Instructions:
# 1. Edit the variables in the section marked Configuration. Configure
# with a username/password that can read the jabber spool database.
# 2. Run this script with a single argument containing the spool directory
# path you wish to create. Note that this directory should not exist.
#
# Perl Module Requirements:
# XML-Simple
# DBI/DBD-mysql (or DBD-whatever other db, postgres?)
#
# Changes:
# 0.3: Fixed group conversion via patch from Jacek Konieczny (Jajcus).
# 0.2: Added pulling of "name" field from rosters.
#
### Configuration Start ###
my $dbtype = "mysql";
my $dbhost = "localhost";
my $dbdatabase = "jabberd2";
my $dbusername = "jabberd2";
my $dbpassword = "password";
### Configuration End ###
use strict;
use DBI;
use XML::Simple;
my $spooldir = $ARGV[0];
die "Usage: j2to1.pl <spool dir to create>" if (!defined $spooldir);
mkdir($spooldir) || die "Unable to create spool dir.";
my $DBSERVER = "DBI:$dbtype:database=$dbdatabase;host=$dbhost";
my $DBUSER = $dbusername;
my $DBPASS = $dbpassword;
my $dbh = DBI->connect($DBSERVER, $DBUSER, $DBPASS);
die("Failed to connect to database.") if (!$dbh);
my $sth = $dbh->prepare("SELECT * FROM authreg");
$sth->execute;
while (my $r = $sth->fetchrow_hashref) {
my $id = $r->{username};
my $realm = $r->{realm};
my $jid = $id . "@" . $realm;
print "Converting $jid...\n";
my $xdb;
$xdb->{password}->{xmlns} = "jabber:iq:auth";
$xdb->{password}->{xdbns} = "jabber:iq:auth";
$xdb->{password}->{content} = $r->{password};
# The primary purpose of this script was migration to ejabberd,
# which does not like zerok, so byebye.
#$xdb->{zerok}->{xmlns} = "jabber:iq:auth:0k";
#$xdb->{zerok}->{xdbns} = "jabber:iq:auth:0k";
#$xdb->{zerok}->{token}->{content} = $r->{token};
#$xdb->{zerok}->{sequence}->{content} = $r->{sequence};
#$xdb->{zerok}->{hash}->{content} = $r->{hash};
$xdb->{query}->[0]->{xmlns} = "jabber:iq:roster";
$xdb->{query}->[0]->{xdbns} = "jabber:iq:roster";
my $asth = $dbh->prepare("SELECT `roster-items`.jid,`roster-items`.name,`roster-items`.`to`,`roster-items`.`from`,`roster-items`.ask,`roster-groups`.`group` FROM `roster-items` LEFT JOIN `roster-groups` ON (`roster-items`.jid = `roster-groups`.jid and `roster-items`.`collection-owner` = `roster-groups`.`collection-owner`) WHERE `roster-items`.`collection-owner` = '$jid' ORDER BY `group`,jid");
$asth->execute;
my $cnt = 0;
while (my $ar = $asth->fetchrow_hashref) {
$xdb->{query}->[0]->{item}->[$cnt]->{jid} = $ar->{jid};
$xdb->{query}->[0]->{item}->[$cnt]->{subscription} =
( $ar->{to} && $ar->{from} ? "both" :
( $ar->{to} ? "to" :
( $ar->{from} ? "from" :
"none" )));
if (defined($ar->{name})) {
$xdb->{query}->[0]->{item}->[$cnt]->{name} = $ar->{name};
}
if (defined($ar->{group})) {
$xdb->{query}->[0]->{item}->[$cnt]->{group}->{content} = $ar->{group};
}
if ($ar->{ask}) {
$xdb->{query}->[0]->{item}->[$cnt]->{ask} = 'subscribe';
}
$cnt++;
}
my $asth = $dbh->prepare("SELECT * FROM vcard WHERE `collection-owner` = '$jid'");
$asth->execute;
my $vr = $asth->fetchrow_hashref;
if (defined $vr) {
$xdb->{vCard}->{xmlns} = 'vcard-temp';
$xdb->{vCard}->{xdbns} = 'vcard-temp';
$xdb->{vCard}->{version} = '3.0';
$xdb->{vCard}->{prodid} = '-//HandGen//NONSGML vGen v1.0//EN';
$xdb->{vCard}->{FN}->{content} = $vr->{fn};
$xdb->{vCard}->{NICKNAME}->{content} = $vr->{nickname};
$xdb->{vCard}->{EMAIL}->{content} = $vr->{email};
$xdb->{vCard}->{BDAY}->{content} = $vr->{bday};
$xdb->{vCard}->{URL}->{content} = $vr->{url};
$xdb->{vCard}->{TEL}->{content} = $vr->{tel};
$xdb->{vCard}->{DESC}->{content} = $vr->{desc};
$xdb->{vCard}->{N}->{GIVEN}->[0]->{content} = $vr->{'n-given'};
$xdb->{vCard}->{N}->{FAMILY}->[0]->{content} = $vr->{'n-family'};
$xdb->{vCard}->{ORG}->{ORGNAME}->[0]->{content} = $vr->{'org-orgname'};
$xdb->{vCard}->{ORG}->{ORGUNIT}->[0]->{content} = $vr->{'org-orgunit'};
$xdb->{vCard}->{TITLE}->{content} = $vr->{title};
$xdb->{vCard}->{ROLE}->{content} = $vr->{role};
$xdb->{vCard}->{ADR}->{STREET}->[0]->{content} = $vr->{'adr-street'};
$xdb->{vCard}->{ADR}->{EXTADD}->[0]->{content} = $vr->{'adr-extadd'};
$xdb->{vCard}->{ADR}->{LOCALITY}->[0]->{content} = $vr->{'adr-locality'};
$xdb->{vCard}->{ADR}->{REGION}->[0]->{content} = $vr->{'adr-region'};
$xdb->{vCard}->{ADR}->{PCODE}->[0]->{content} = $vr->{'adr-pcode'};
$xdb->{vCard}->{ADR}->{COUNTRY}->[0]->{content} = $vr->{'adr-country'};
}
my $asth = $dbh->prepare("SELECT time FROM logout WHERE `collection-owner` = '$jid'");
$asth->execute;
my $lr = $asth->fetchrow_hashref;
if (defined $lr) {
$xdb->{query}->[1]->{xmlns} = 'jabber:iq:last';
$xdb->{query}->[1]->{xdbns} = 'jabber:iq:last';
$xdb->{query}->[1]->{last} = $lr->{time};
}
# Theoretically we should pull offline message as well.
# Haven't gotten to that yet. ;)
mkdir("$spooldir/$realm") if (! -d "$spooldir/$realm");
open(SPOOLFILE, "> $spooldir/$realm/${id}.xml") || die "Unable to create spool file.";
print SPOOLFILE XMLout($xdb, RootName => "xdb");
close(SPOOLFILE);
}
$dbh->disconnect;
exit 0;