FIXED: most config variables not related to drivers had

invalid sentence in note, so the new ones of the new config
                were ignored.
FIXED:          added version to NOTEDB::text.
FIXED:          fixed handling of NOTEDB::crypt_supported, now encryption
                works again.
ADDED:          NOTEDB::text now supports internal caching too.
CHANGED:        lock() sets the umask internally to 022, so that other
                users are able to read the lockfile.
This commit is contained in:
TLINDEN
2012-02-10 20:31:13 +01:00
parent 773584e400
commit b2b5cea5ec
10 changed files with 117 additions and 87 deletions

View File

@@ -1,4 +1,15 @@
1.2.7: 1.3.1:
FIXED: most config variables not related to drivers had
invalid sentence in note, so the new ones of the new config
were ignored.
FIXED: added version to NOTEDB::text.
FIXED: fixed handling of NOTEDB::crypt_supported, now encryption
works again.
ADDED: NOTEDB::text now supports internal caching too.
CHANGED: lock() sets the umask internally to 022, so that other
users are able to read the lockfile.
================================================================================
1.3.0:
ADDED: new config option: ReadOnly ADDED: new config option: ReadOnly
ADDED: new database backend: NOTEDB::text, which uses the Storable ADDED: new database backend: NOTEDB::text, which uses the Storable
module. module.

View File

@@ -7,7 +7,10 @@
package NOTEDB; package NOTEDB;
$NOTEDB::VERSION = "1.3"; use Exporter ();
use vars qw(@ISA @EXPORT $crypt_supported);
$NOTEDB::VERSION = "1.31";
BEGIN { BEGIN {
# make sure, it works, otherwise encryption # make sure, it works, otherwise encryption
@@ -35,7 +38,8 @@ sub use_crypt {
$cipher = new Crypt::CBC($key, $method); $cipher = new Crypt::CBC($key, $method);
}; };
if($@) { if($@) {
$NOTEDB::crypt_supported == 0; print "warning: Crypt::$method not supported by system!\n";
$NOTEDB::crypt_supported = 0;
} }
else { else {
$this->{cipher} = $cipher; $this->{cipher} = $cipher;
@@ -261,6 +265,7 @@ sub lock {
alarm $timeout - 2; alarm $timeout - 2;
while (1) { while (1) {
if (! -e $this->{LOCKFILE}) { if (! -e $this->{LOCKFILE}) {
umask 022;
open LOCK, ">$this->{LOCKFILE}" or die "could not open $this->{LOCKFILE}: $!\n"; open LOCK, ">$this->{LOCKFILE}" or die "could not open $this->{LOCKFILE}: $!\n";
flock LOCK, LOCK_EX; flock LOCK, LOCK_EX;
@@ -282,6 +287,7 @@ sub lock {
print " interrupted\n"; print " interrupted\n";
} }
else { else {
print $@;
print " timeout\n"; print " timeout\n";
} }
return 1; return 1;

View File

@@ -4,7 +4,7 @@
package NOTEDB::general; package NOTEDB::general;
$NOTEDB::general::VERSION = "1.00"; $NOTEDB::general::VERSION = "1.01";
use strict; use strict;
#use Data::Dumper; #use Data::Dumper;
@@ -258,6 +258,7 @@ sub uen {
eval { eval {
$crypted = $this->{cipher}->encrypt($raw); $crypted = $this->{cipher}->encrypt($raw);
}; };
print $@;
} }
else { else {
$crypted = $raw; $crypted = $raw;
@@ -287,8 +288,13 @@ sub _store {
open NOTE, ">$this->{dbname}" or die "could not open $this->{dbname}: $!\n"; open NOTE, ">$this->{dbname}" or die "could not open $this->{dbname}: $!\n";
flock NOTE, LOCK_EX; flock NOTE, LOCK_EX;
my $content = SaveConfigString($data) or die "could not serialize data: $!\n"; if (%{$data}) {
print NOTE $content; my $content = SaveConfigString($data) or die "could not serialize data: $!\n";
print NOTE $content;
}
else {
print NOTE "";
}
flock NOTE, LOCK_UN; flock NOTE, LOCK_UN;
close NOTE; close NOTE;

View File

@@ -4,6 +4,8 @@
package NOTEDB::text; package NOTEDB::text;
$NOTEDB::text::VERSION = "1.01";
use strict; use strict;
#use Data::Dumper; #use Data::Dumper;
use File::Spec; use File::Spec;
@@ -40,6 +42,9 @@ sub new {
} }
$self->{LOCKFILE} = $param{dbname} . "~LOCK"; $self->{LOCKFILE} = $param{dbname} . "~LOCK";
$self->{mtime} = $self->get_stat();
$self->{unread} = 1;
$self->{data} = {};
return $self; return $self;
} }
@@ -52,9 +57,14 @@ sub DESTROY
sub version { sub version {
my $this = shift; my $this = shift;
return $this->{version}; return $NOTEDB::text::VERSION;
} }
sub get_stat {
my ($this) = @_;
my $mtime = (stat($this->{dbname}))[9];
return $mtime;
}
sub set_del_all { sub set_del_all {
@@ -268,8 +278,12 @@ sub _store {
sub _retrieve { sub _retrieve {
my $this = shift; my $this = shift;
if (-s $this->{NOTEDB}) { if (-s $this->{NOTEDB}) {
my $data = lock_retrieve($this->{NOTEDB}); if ($this->changed() || $this->{unread}) {
return %{$data}; my $data = lock_retrieve($this->{NOTEDB});
$this->{unread} = 0;
$this->{data} = $data;
return %{$data};
}
} }
else { else {
return (); return ();

2
README
View File

@@ -1,4 +1,4 @@
note 1.3.0 by Thomas Linden, 11/01/2005 note 1.3.1 by Thomas Linden, 12/01/2005
======================================= =======================================
Introduction Introduction

6
TODO
View File

@@ -3,10 +3,4 @@
- ncurses support - ncurses support
- readline/editline support for interactive prompt
with: completion and history
- LOCKing support, so that multiple people can use
note simultaneously while not interfering with
each other

View File

@@ -1 +1 @@
1.2.7 1.3.1

133
bin/note
View File

@@ -105,31 +105,30 @@ my (
# don't change them, instead use the config file! # don't change them, instead use the config file!
# #
$conf{dbdriver} = "binary"; $conf{dbdriver} = "binary";
$conf{color} = 1; $conf{usecolors} = 1;
$conf{border_color} = "bold"; $conf{bordercolor} = "bold";
$conf{num_color} = "blue"; $conf{numbercolor} = "blue";
$conf{note_color} = "green"; $conf{notecolor} = "green";
$conf{time_color} = "blue"; $conf{timecolor} = "blue";
$conf{topic_color} = "bold"; $conf{topiccolor} = "bold";
$conf{topicsep} = '/'; $conf{topicseparator} = '/';
$conf{use_crypt} = 0; $conf{useencryption} = 0;
$conf{tempdirectory} = File::Spec->tmpdir(); $conf{tempdirectory} = File::Spec->tmpdir();
$conf{always_int} = 1; $conf{alwaysinteractive} = 1;
$conf{always_edit} = 1; $conf{alwayseditor} = 1;
$conf{auto_clear} = 1; $conf{autoclear} = 1;
$CONF = File::Spec->catfile($ENV{HOME}, ".noterc"); $CONF = File::Spec->catfile($ENV{HOME}, ".noterc");
$USER = getlogin || getpwuid($<); $USER = getlogin || getpwuid($<);
chomp $USER; chomp $USER;
$TOPIC = 1; $TOPIC = 1;
$version = "1.3.0"; $version = "1.3.1";
$CurDepth = 1; # the current depth inside the topic "directory" structure... $CurDepth = 1; # the current depth inside the topic "directory" structure...
$maxlen = "auto"; $maxlen = "auto";
$timelen = 22; $timelen = 22;
# colors available # colors available
# \033[1m%30s\033[0m # \033[1m%30s\033[0m
%Color = ( 'black' => '0;30', %Color = ( 'black' => '0;30',
@@ -214,11 +213,11 @@ else {
elsif (defined $opt_l || defined $opt_L) { elsif (defined $opt_l || defined $opt_L) {
$mode = "list"; $mode = "list";
if (defined $opt_l) { if (defined $opt_l) {
@ArgTopics = split /$conf{topicsep}/, $opt_l; @ArgTopics = split /$conf{topicseparator}/, $opt_l;
} }
else { else {
$ListType = "LONG"; $ListType = "LONG";
@ArgTopics = split /$conf{topicsep}/, $opt_L; @ArgTopics = split /$conf{topicseparator}/, $opt_L;
} }
$CurDepth += $#ArgTopics + 1 if($opt_l || $opt_L); $CurDepth += $#ArgTopics + 1 if($opt_l || $opt_L);
$CurTopic = $ArgTopics[$#ArgTopics]; # use the last element everytime... $CurTopic = $ArgTopics[$#ArgTopics]; # use the last element everytime...
@@ -344,12 +343,12 @@ if ($mode eq "encrypt_passwd") {
} }
# Always interactive? # Always interactive?
if ($conf{always_int} && $mode ne "dump" && $mode ne "import") { if ($conf{alwaysinteractive} && $mode ne "dump" && $mode ne "import") {
$mode = "interactive"; $mode = "interactive";
} }
# OK ... Long-Listing shall be default ... You wanted it!!! # OK ... Long-Listing shall be default ... You wanted it!!!
if ($conf{default_list} eq "LONG") { if ($conf{defaultlong}) {
# takes only precedence in commandline mode # takes only precedence in commandline mode
$ListType="LONG"; $ListType="LONG";
} }
@@ -358,18 +357,18 @@ if ($conf{default_list} eq "LONG") {
# calculate some constants... # calculate some constants...
$BORDERC = "<$conf{border_color}>"; $BORDERC = "<$conf{bordercolor}>";
$_BORDERC = "</$conf{border_color}>"; $_BORDERC = "</$conf{bordercolor}>";
$NUMC = "<$conf{num_color}>"; $NUMC = "<$conf{numbercolor}>";
$_NUMC = "</$conf{num_color}>"; $_NUMC = "</$conf{numbercolor}>";
$NOTEC = "<$conf{note_color}>"; $NOTEC = "<$conf{notecolor}>";
$_NOTEC = "</$conf{note_color}>"; $_NOTEC = "</$conf{notecolor}>";
$TIMEC = "<$conf{time_color}>"; $TIMEC = "<$conf{timecolor}>";
$_TIMEC = "</$conf{time_color}>"; $_TIMEC = "</$conf{timecolor}>";
$TOPICC = "<$conf{topic_color}>"; $TOPICC = "<$conf{topiccolor}>";
$_TOPICC = "</$conf{topic_color}>"; $_TOPICC = "</$conf{topiccolor}>";
$NoteKey = $conf{topicsep} . "notes" . $conf{topicsep}; $NoteKey = $conf{topicseparator} . "notes" . $conf{topicseparator};
@@ -381,11 +380,10 @@ umask 077;
# load the parent module # load the parent module
&load_driver(1); &load_driver(1);
# check wether the user wants to use encryption: # check wether the user wants to use encryption:
if ($conf{use_crypt} && $NOTEDB::crypt_supported == 1) { if ($conf{useencryption} && $NOTEDB::crypt_supported == 1) {
if ($conf{crypt_method} eq "") { if ($conf{cryptmethod} eq "") {
$conf{crypt_method} = "Crypt::IDEA"; $conf{cryptmethod} = "Crypt::IDEA";
} }
if (!exists $ENV{'NOTE_PASSWD'}) { if (!exists $ENV{'NOTE_PASSWD'}) {
print "password: "; print "password: ";
@@ -410,7 +408,7 @@ if ($conf{use_crypt} && $NOTEDB::crypt_supported == 1) {
if ($conf{dbdriver} eq "mysql") { if ($conf{dbdriver} eq "mysql") {
eval { eval {
require Crypt::CBC; require Crypt::CBC;
my $cipher = new Crypt::CBC($key, $conf{crypt_method}); my $cipher = new Crypt::CBC($key, $conf{cryptmethod});
# decrypt the dbpasswd, if it's encrypted! # decrypt the dbpasswd, if it's encrypted!
$driver{mysql}->{dbpasswd} = $driver{mysql}->{dbpasswd} =
$cipher->decrypt(unpack("u", $driver{mysql}->{dbpasswd})) if($driver{mysql}->{encrypt_passwd}); $cipher->decrypt(unpack("u", $driver{mysql}->{dbpasswd})) if($driver{mysql}->{encrypt_passwd});
@@ -421,7 +419,7 @@ if ($conf{use_crypt} && $NOTEDB::crypt_supported == 1) {
else { else {
&load_driver(); &load_driver();
} }
$db->use_crypt($key,$conf{crypt_method}); $db->use_crypt($key,$conf{cryptmethod});
undef $key; undef $key;
# verify correctness of passwd # verify correctness of passwd
my ($cnote, $cdate) = $db->get_single(1); my ($cnote, $cdate) = $db->get_single(1);
@@ -448,7 +446,7 @@ else {
# do we use the db cache? # do we use the db cache?
if ($conf{use_cache}) { if ($conf{cache}) {
$db->use_cache(); $db->use_cache();
} }
@@ -495,7 +493,7 @@ sub encrypt_passwd {
chomp $key; chomp $key;
eval { eval {
require Crypt::CBC; require Crypt::CBC;
my $cipher = new Crypt::CBC($key, $conf{crypt_method}); my $cipher = new Crypt::CBC($key, $conf{cryptmethod});
$crypt_string = pack("u", $cipher->encrypt($clearstring)); $crypt_string = pack("u", $cipher->encrypt($clearstring));
}; };
if ($@) { if ($@) {
@@ -584,8 +582,8 @@ sub list {
if ($TOPIC) { if ($TOPIC) {
# this allows us to have multiple topics (subtopics!) # this allows us to have multiple topics (subtopics!)
my ($firstline,$dummy) = split /\n/, $n, 2; my ($firstline,$dummy) = split /\n/, $n, 2;
if ($firstline =~ /^($conf{topicsep})/) { if ($firstline =~ /^($conf{topicseparator})/) {
@topic = split(/$conf{topicsep}/,$firstline); @topic = split(/$conf{topicseparator}/,$firstline);
} }
else { else {
@topic = (); @topic = ();
@@ -603,7 +601,7 @@ sub list {
} }
elsif ($topic[$CurDepth-1] eq $CurTopic || ($topic[$CurDepth] eq "" && $CurDepth ==1)) { elsif ($topic[$CurDepth-1] eq $CurTopic || ($topic[$CurDepth] eq "" && $CurDepth ==1)) {
# cut the topic off the note-text # cut the topic off the note-text
if ($n =~ /^($conf{topicsep})/) { if ($n =~ /^($conf{topicseparator})/) {
$CurItem[$i]->{'note'} = $dummy; $CurItem[$i]->{'note'} = $dummy;
} }
else { else {
@@ -629,19 +627,19 @@ sub list {
# only if there were notes under current topic # only if there were notes under current topic
undef $PATH; undef $PATH;
foreach (@RealTopic) { foreach (@RealTopic) {
$PATH .= $_ . $conf{topicsep}; $PATH .= $_ . $conf{topicseparator};
last if($_ eq $CurTopic); last if($_ eq $CurTopic);
} }
} }
else { else {
# it is an empty topic, no notes here # it is an empty topic, no notes here
$PATH = join $conf{topicsep}, @LastTopic; $PATH = join $conf{topicseparator}, @LastTopic;
$PATH .= $conf{topicsep} . $CurTopic . $conf{topicsep}; $PATH .= $conf{topicseparator} . $CurTopic . $conf{topicseparator};
$PATH =~ s/^\Q$conf{topicsep}$conf{topicsep}\E/$conf{topicsep}/; $PATH =~ s/^\Q$conf{topicseparator}$conf{topicseparator}\E/$conf{topicseparator}/;
} }
} }
else { else {
$PATH = $conf{topicsep}; $PATH = $conf{topicseparator};
} }
@completion_topics = (); @completion_topics = ();
@@ -649,7 +647,7 @@ sub list {
# we are at top level, print a list of topics... # we are at top level, print a list of topics...
foreach $top (sort(keys %TP)) { foreach $top (sort(keys %TP)) {
push @completion_topics, $top; push @completion_topics, $top;
output("-", " => ". $top . "$conf{topicsep} ($TP{$top} notes)", output("-", " => ". $top . "$conf{topicseparator} ($TP{$top} notes)",
" Sub Topic "); " Sub Topic ");
} }
#print Dumper(@CurItem); #print Dumper(@CurItem);
@@ -673,7 +671,7 @@ sub new {
} }
$date = &getdate; $date = &getdate;
return if $db->lock(); return if $db->lock();
if ($conf{always_edit}) { if ($conf{alwayseditor}) {
$TEMP = &gettemp; $TEMP = &gettemp;
# security! # security!
unlink $TEMP; unlink $TEMP;
@@ -740,7 +738,7 @@ sub new {
# since we have not a number, look for the next one available: # since we have not a number, look for the next one available:
$number = $db->get_nextnum(); $number = $db->get_nextnum();
if ($TOPIC && $CurTopic ne "") { if ($TOPIC && $CurTopic ne "") {
@topic = split(/$conf{topicsep}/,$note); @topic = split(/$conf{topicseparator}/,$note);
if ($topic[1] eq "") { if ($topic[1] eq "") {
$note = $PATH . "\n$note"; $note = $PATH . "\n$note";
} }
@@ -837,7 +835,7 @@ sub edit {
unlink $TEMP || die $!; unlink $TEMP || die $!;
if ($note ne $backup) { if ($note ne $backup) {
if ($conf{keep_timestamp}) { if ($conf{keeptimestamp}) {
$t = $keeptime; $t = $keeptime;
} }
else { else {
@@ -957,7 +955,7 @@ sub determine_width {
sub clear { sub clear {
# first, try to determine the terminal height # first, try to determine the terminal height
return if(!$conf{auto_clear}); return if(!$conf{autoclear});
my $hoch; my $hoch;
eval { eval {
my $height = `stty -a`; my $height = `stty -a`;
@@ -997,7 +995,7 @@ sub interactive {
# per default let's list all the stuff: # per default let's list all the stuff:
# Initially do a list command! # Initially do a list command!
&determine_width; &determine_width;
$ListType = ($conf{default_list} eq "LONG") ? "LONG" : ""; $ListType = ($conf{defaultlong}) ? "LONG" : "";
&list; &list;
my ($term, $prompt, $attribs); my ($term, $prompt, $attribs);
@@ -1009,7 +1007,7 @@ sub interactive {
} }
for (;;) { for (;;) {
$ListType = ($conf{default_list} eq "LONG") ? "LONG" : ""; $ListType = ($conf{defaultlong}) ? "LONG" : "";
undef $SetTitle; undef $SetTitle;
if ($CurDepth > 2) { if ($CurDepth > 2) {
print C $menu . $TOPICC . "../" . $CurTopic . $_TOPICC . ">"; print C $menu . $TOPICC . "../" . $CurTopic . $_TOPICC . ">";
@@ -1153,8 +1151,8 @@ sub interactive {
my @topic; my @topic;
my ($cnote, $cdate) = $db->get_single($unchar); my ($cnote, $cdate) = $db->get_single($unchar);
my ($firstline,$dummy) = split /\n/, $cnote, 2; my ($firstline,$dummy) = split /\n/, $cnote, 2;
if ($firstline =~ /^($conf{topicsep})/) { if ($firstline =~ /^($conf{topicseparator})/) {
@topic = split(/$conf{topicsep}/,$firstline); @topic = split(/$conf{topicseparator}/,$firstline);
} }
else { else {
@topic = (); @topic = ();
@@ -1168,7 +1166,7 @@ sub interactive {
} }
&list; &list;
} }
elsif ($unchar eq $conf{topicsep}) { elsif ($unchar eq $conf{topicseparator}) {
# cd / # cd /
$CurDepth = 1; $CurDepth = 1;
$CurTopic = ""; $CurTopic = "";
@@ -1307,7 +1305,7 @@ sub output {
$title = ""; $title = "";
$CUTSPACE = " " x $txtlen; $CUTSPACE = " " x $txtlen;
if ($TYPE eq "search") { if ($TYPE eq "search") {
$note =~ s/^\Q$conf{topicsep}\E.+?\Q$conf{topicsep}\E\n//; $note =~ s/^\Q$conf{topicseparator}\E.+?\Q$conf{topicseparator}\E\n//;
} }
$note =~ s/\n/$CUTSPACE/g; $note =~ s/\n/$CUTSPACE/g;
$len = length($note); $len = length($note);
@@ -1336,8 +1334,8 @@ sub output {
if ($Raw) { if ($Raw) {
print "$num "; print "$num ";
print "$time " if($ListType eq "LONG"); print "$time " if($ListType eq "LONG");
if ($title =~ /^ => (.*)$conf{topicsep} (.*)$/) { if ($title =~ /^ => (.*)$conf{topicseparator} (.*)$/) {
$title = "$1$conf{topicsep} $2"; # seems to be a topic! $title = "$1$conf{topicseparator} $2"; # seems to be a topic!
} }
print "$title\n"; print "$title\n";
} }
@@ -1371,7 +1369,7 @@ sub C {
$S = $_[0]; $S = $_[0];
foreach $Col (%Color) { foreach $Col (%Color) {
if ($S =~ /<$Col>/g) { if ($S =~ /<$Col>/g) {
if ($conf{color}) { if ($conf{usecolors}) {
$NC = "\033[" . $Color{$Col} . "m"; $NC = "\033[" . $Color{$Col} . "m";
$S =~ s/<$Col>/$NC/g; $S =~ s/<$Col>/$NC/g;
$S =~ s/<\/$Col>/$default/g; $S =~ s/<\/$Col>/$default/g;
@@ -1434,8 +1432,8 @@ sub getdate {
$min =~ s/^(\d)$/0$1/; $min =~ s/^(\d)$/0$1/;
$sec =~ s/^(\d)$/0$1/; $sec =~ s/^(\d)$/0$1/;
$mday =~ s/^(\d)$/0$1/; $mday =~ s/^(\d)$/0$1/;
if ($conf{time_format}) { if ($conf{timeformat}) {
my $back = $conf{time_format}; my $back = $conf{timeformat};
$back =~ s/YYYY/$year/; $back =~ s/YYYY/$year/;
$back =~ s/YY/substr($year, 1, 2)/e; $back =~ s/YY/substr($year, 1, 2)/e;
$back =~ s/MM/$mon/; $back =~ s/MM/$mon/;
@@ -1520,19 +1518,19 @@ sub display_tree {
$t = $res{$num}->{'date'}; $t = $res{$num}->{'date'};
# this allows us to have multiple topics (subtopics!) # this allows us to have multiple topics (subtopics!)
my ($firstline,$text,$untext) = split /\n/, $n, 3; my ($firstline,$text,$untext) = split /\n/, $n, 3;
if ($firstline =~ /^($conf{topicsep})/) { if ($firstline =~ /^($conf{topicseparator})/) {
$firstline =~ s/($conf{topicsep})*$//; #remove TopicSepatator $firstline =~ s/($conf{topicseparator})*$//; #remove Topicseparator
@nodes = split(/$conf{topicsep}/,$firstline); @nodes = split(/$conf{topicseparator}/,$firstline);
} }
else { else {
@nodes = (); #("$conf{topicsep}"); @nodes = (); #("$conf{topicseparator}");
$text = $firstline; $text = $firstline;
} }
&tree($num, $text, \%TREE, @nodes); &tree($num, $text, \%TREE, @nodes);
} }
#return if ($num == 0); #return if ($num == 0);
# now that we have build our tree (in %TREE) go on t display it: # now that we have build our tree (in %TREE) go on t display it:
print C $BORDERC . "\n[" . $conf{topicsep} . $BORDERC . "]\n"; print C $BORDERC . "\n[" . $conf{topicseparator} . $BORDERC . "]\n";
&print_tree(\%{$TREE{''}},"") if(%TREE); &print_tree(\%{$TREE{''}},"") if(%TREE);
print C $BORDERC . $_BORDERC . "\n"; print C $BORDERC . $_BORDERC . "\n";
} }
@@ -1646,6 +1644,7 @@ sub load_driver {
if ($parent) { if ($parent) {
my $pkg = "NOTEDB"; my $pkg = "NOTEDB";
eval "use $pkg;";
if ($@) { if ($@) {
die "Could not load the NOTEDB module: $@\n"; die "Could not load the NOTEDB module: $@\n";
} }

View File

@@ -1,4 +1,4 @@
# note 1.3.0 -*- sh -*- # note 1.3.1 -*- sh -*-
# #
# This is a sample config for the note script # This is a sample config for the note script
# There are useful defaults set in note itself. # There are useful defaults set in note itself.

View File

@@ -475,7 +475,7 @@ to encryption, I suggest you to follow the directions in the
file UPGRADE! file UPGRADE!
You can choose from different encryption algorythms. The default You can choose from different encryption algorythms. The default
is IDEA, but DES or BLOWFISH is also possible. You need to have is IDEA, but DES or BLOWFISH are also possible. You need to have
installed the following additional perl-modules on your system: installed the following additional perl-modules on your system:
MD5 MD5
Crypt::IDEA Crypt::IDEA
@@ -523,6 +523,6 @@ Thomas Linden <tom@daemon.de>
=head1 VERSION =head1 VERSION
1.3.0 (11/01/2005) 1.3.1 (12/01/2005)
=cut =cut