diff --git a/Changelog b/Changelog
index 4544efa..fbed4c3 100644
--- a/Changelog
+++ b/Changelog
@@ -1,3 +1,12 @@
+1.3.3:
+ADDED: new configfile parameter PrintLines (default: YES), which
+ controls wether listings are separated by horizontal lines.
+================================================================================
+1.3.2:
+FIXED: NOTEDB::mysql backend parameter fixed (dbtype)
+FIXED: NOTEDB::mysql didn't fetch topics correctly
+FIXED: NOTEDB::text didn't correctly return last highest note id
+================================================================================
1.3.1:
FIXED: most config variables not related to drivers had
invalid sentence in note, so the new ones of the new config
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..a1598a5
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,782 @@
+# This Makefile is for the NOTEDB extension to perl.
+#
+# It was generated automatically by MakeMaker version
+# 6.17 (Revision: 1.133) from the contents of
+# Makefile.PL. Don't edit this file, edit Makefile.PL instead.
+#
+# ANY CHANGES MADE HERE WILL BE LOST!
+#
+# MakeMaker ARGV: ()
+#
+# MakeMaker Parameters:
+
+# EXE_FILES => [q[bin/note]]
+# NAME => q[NOTEDB]
+# VERSION_FROM => q[NOTEDB.pm]
+
+# --- MakeMaker post_initialize section:
+
+
+# --- MakeMaker const_config section:
+
+# These definitions are from config.sh (via /usr/lib/perl/5.8/Config.pm)
+
+# They may have been overridden via Makefile.PL or on the command line
+AR = ar
+CC = cc
+CCCDLFLAGS = -fPIC
+CCDLFLAGS = -Wl,-E
+DLEXT = so
+DLSRC = dl_dlopen.xs
+LD = cc
+LDDLFLAGS = -shared -L/usr/local/lib
+LDFLAGS = -L/usr/local/lib
+LIBC = /lib/libc-2.3.2.so
+LIB_EXT = .a
+OBJ_EXT = .o
+OSNAME = linux
+OSVERS = 2.4.27-ti1211
+RANLIB = :
+SITELIBEXP = /usr/local/share/perl/5.8.4
+SITEARCHEXP = /usr/local/lib/perl/5.8.4
+SO = so
+EXE_EXT =
+FULL_AR = /usr/bin/ar
+VENDORARCHEXP = /usr/lib/perl5
+VENDORLIBEXP = /usr/share/perl5
+
+
+# --- MakeMaker constants section:
+AR_STATIC_ARGS = cr
+DIRFILESEP = /
+NAME = NOTEDB
+NAME_SYM = NOTEDB
+VERSION = 1.31
+VERSION_MACRO = VERSION
+VERSION_SYM = 1_31
+DEFINE_VERSION = -D$(VERSION_MACRO)=\"$(VERSION)\"
+XS_VERSION = 1.31
+XS_VERSION_MACRO = XS_VERSION
+XS_DEFINE_VERSION = -D$(XS_VERSION_MACRO)=\"$(XS_VERSION)\"
+INST_ARCHLIB = blib/arch
+INST_SCRIPT = blib/script
+INST_BIN = blib/bin
+INST_LIB = blib/lib
+INST_MAN1DIR = blib/man1
+INST_MAN3DIR = blib/man3
+MAN1EXT = 1p
+MAN3EXT = 3pm
+INSTALLDIRS = site
+DESTDIR =
+PREFIX = /usr
+PERLPREFIX = $(PREFIX)
+SITEPREFIX = $(PREFIX)/local
+VENDORPREFIX = $(PREFIX)
+INSTALLPRIVLIB = $(PERLPREFIX)/share/perl/5.8
+DESTINSTALLPRIVLIB = $(DESTDIR)$(INSTALLPRIVLIB)
+INSTALLSITELIB = $(SITEPREFIX)/share/perl/5.8.4
+DESTINSTALLSITELIB = $(DESTDIR)$(INSTALLSITELIB)
+INSTALLVENDORLIB = $(VENDORPREFIX)/share/perl5
+DESTINSTALLVENDORLIB = $(DESTDIR)$(INSTALLVENDORLIB)
+INSTALLARCHLIB = $(PERLPREFIX)/lib/perl/5.8
+DESTINSTALLARCHLIB = $(DESTDIR)$(INSTALLARCHLIB)
+INSTALLSITEARCH = $(SITEPREFIX)/lib/perl/5.8.4
+DESTINSTALLSITEARCH = $(DESTDIR)$(INSTALLSITEARCH)
+INSTALLVENDORARCH = $(VENDORPREFIX)/lib/perl5
+DESTINSTALLVENDORARCH = $(DESTDIR)$(INSTALLVENDORARCH)
+INSTALLBIN = $(PERLPREFIX)/bin
+DESTINSTALLBIN = $(DESTDIR)$(INSTALLBIN)
+INSTALLSITEBIN = $(SITEPREFIX)/bin
+DESTINSTALLSITEBIN = $(DESTDIR)$(INSTALLSITEBIN)
+INSTALLVENDORBIN = $(VENDORPREFIX)/bin
+DESTINSTALLVENDORBIN = $(DESTDIR)$(INSTALLVENDORBIN)
+INSTALLSCRIPT = $(PERLPREFIX)/bin
+DESTINSTALLSCRIPT = $(DESTDIR)$(INSTALLSCRIPT)
+INSTALLMAN1DIR = $(PERLPREFIX)/share/man/man1
+DESTINSTALLMAN1DIR = $(DESTDIR)$(INSTALLMAN1DIR)
+INSTALLSITEMAN1DIR = $(SITEPREFIX)/man/man1
+DESTINSTALLSITEMAN1DIR = $(DESTDIR)$(INSTALLSITEMAN1DIR)
+INSTALLVENDORMAN1DIR = $(VENDORPREFIX)/share/man/man1
+DESTINSTALLVENDORMAN1DIR = $(DESTDIR)$(INSTALLVENDORMAN1DIR)
+INSTALLMAN3DIR = $(PERLPREFIX)/share/man/man3
+DESTINSTALLMAN3DIR = $(DESTDIR)$(INSTALLMAN3DIR)
+INSTALLSITEMAN3DIR = $(SITEPREFIX)/man/man3
+DESTINSTALLSITEMAN3DIR = $(DESTDIR)$(INSTALLSITEMAN3DIR)
+INSTALLVENDORMAN3DIR = $(VENDORPREFIX)/share/man/man3
+DESTINSTALLVENDORMAN3DIR = $(DESTDIR)$(INSTALLVENDORMAN3DIR)
+PERL_LIB = /usr/share/perl/5.8
+PERL_ARCHLIB = /usr/lib/perl/5.8
+LIBPERL_A = libperl.a
+FIRST_MAKEFILE = Makefile
+MAKEFILE_OLD = $(FIRST_MAKEFILE).old
+MAKE_APERL_FILE = $(FIRST_MAKEFILE).aperl
+PERLMAINCC = $(CC)
+PERL_INC = /usr/lib/perl/5.8/CORE
+PERL = /usr/bin/perl
+FULLPERL = /usr/bin/perl
+ABSPERL = $(PERL)
+PERLRUN = $(PERL)
+FULLPERLRUN = $(FULLPERL)
+ABSPERLRUN = $(ABSPERL)
+PERLRUNINST = $(PERLRUN) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)"
+FULLPERLRUNINST = $(FULLPERLRUN) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)"
+ABSPERLRUNINST = $(ABSPERLRUN) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)"
+PERL_CORE = 0
+PERM_RW = 644
+PERM_RWX = 755
+
+MAKEMAKER = /usr/share/perl/5.8/ExtUtils/MakeMaker.pm
+MM_VERSION = 6.17
+MM_REVISION = 1.133
+
+# FULLEXT = Pathname for extension directory (eg Foo/Bar/Oracle).
+# BASEEXT = Basename part of FULLEXT. May be just equal FULLEXT. (eg Oracle)
+# PARENT_NAME = NAME without BASEEXT and no trailing :: (eg Foo::Bar)
+# DLBASE = Basename part of dynamic library. May be just equal BASEEXT.
+FULLEXT = NOTEDB
+BASEEXT = NOTEDB
+PARENT_NAME =
+DLBASE = $(BASEEXT)
+VERSION_FROM = NOTEDB.pm
+OBJECT =
+LDFROM = $(OBJECT)
+LINKTYPE = dynamic
+
+# Handy lists of source code files:
+XS_FILES =
+C_FILES =
+O_FILES =
+H_FILES =
+MAN1PODS =
+MAN3PODS = NOTEDB/binary.pm \
+ NOTEDB/dbm.pm \
+ NOTEDB/dumper.pm \
+ NOTEDB/general.pm \
+ NOTEDB/mysql.pm \
+ NOTEDB/text.pm \
+ note.pod
+
+# Where is the Config information that we are using/depend on
+CONFIGDEP = $(PERL_ARCHLIB)$(DIRFILESEP)Config.pm $(PERL_INC)$(DIRFILESEP)config.h
+
+# Where to build things
+INST_LIBDIR = $(INST_LIB)
+INST_ARCHLIBDIR = $(INST_ARCHLIB)
+
+INST_AUTODIR = $(INST_LIB)/auto/$(FULLEXT)
+INST_ARCHAUTODIR = $(INST_ARCHLIB)/auto/$(FULLEXT)
+
+INST_STATIC =
+INST_DYNAMIC =
+INST_BOOT =
+
+# Extra linker info
+EXPORT_LIST =
+PERL_ARCHIVE =
+PERL_ARCHIVE_AFTER =
+
+
+TO_INST_PM = NOTEDB.pm \
+ NOTEDB/README \
+ NOTEDB/binary.pm \
+ NOTEDB/dbm.pm \
+ NOTEDB/dumper.pm \
+ NOTEDB/general.pm \
+ NOTEDB/mysql.pm \
+ NOTEDB/text.pm \
+ note.pod
+
+PM_TO_BLIB = NOTEDB/general.pm \
+ $(INST_LIB)/NOTEDB/general.pm \
+ NOTEDB/dbm.pm \
+ $(INST_LIB)/NOTEDB/dbm.pm \
+ NOTEDB/README \
+ $(INST_LIB)/NOTEDB/README \
+ NOTEDB.pm \
+ $(INST_LIB)/NOTEDB.pm \
+ NOTEDB/text.pm \
+ $(INST_LIB)/NOTEDB/text.pm \
+ NOTEDB/mysql.pm \
+ $(INST_LIB)/NOTEDB/mysql.pm \
+ NOTEDB/binary.pm \
+ $(INST_LIB)/NOTEDB/binary.pm \
+ NOTEDB/dumper.pm \
+ $(INST_LIB)/NOTEDB/dumper.pm \
+ note.pod \
+ $(INST_LIB)/note.pod
+
+
+# --- MakeMaker platform_constants section:
+MM_Unix_VERSION = 1.42
+PERL_MALLOC_DEF = -DPERL_EXTMALLOC_DEF -Dmalloc=Perl_malloc -Dfree=Perl_mfree -Drealloc=Perl_realloc -Dcalloc=Perl_calloc
+
+
+# --- MakeMaker tool_autosplit section:
+# Usage: $(AUTOSPLITFILE) FileToSplit AutoDirToSplitInto
+AUTOSPLITFILE = $(PERLRUN) -e 'use AutoSplit; autosplit($$ARGV[0], $$ARGV[1], 0, 1, 1)'
+
+
+
+# --- MakeMaker tool_xsubpp section:
+
+
+# --- MakeMaker tools_other section:
+SHELL = /bin/sh
+CHMOD = chmod
+CP = cp
+MV = mv
+NOOP = $(SHELL) -c true
+NOECHO = @
+RM_F = rm -f
+RM_RF = rm -rf
+TEST_F = test -f
+TOUCH = touch
+UMASK_NULL = umask 0
+DEV_NULL = > /dev/null 2>&1
+MKPATH = $(PERLRUN) "-MExtUtils::Command" -e mkpath
+EQUALIZE_TIMESTAMP = $(PERLRUN) "-MExtUtils::Command" -e eqtime
+ECHO = echo
+ECHO_N = echo -n
+UNINST = 0
+VERBINST = 0
+MOD_INSTALL = $(PERLRUN) -MExtUtils::Install -e 'install({@ARGV}, '\''$(VERBINST)'\'', 0, '\''$(UNINST)'\'');'
+DOC_INSTALL = $(PERLRUN) "-MExtUtils::Command::MM" -e perllocal_install
+UNINSTALL = $(PERLRUN) "-MExtUtils::Command::MM" -e uninstall
+WARN_IF_OLD_PACKLIST = $(PERLRUN) "-MExtUtils::Command::MM" -e warn_if_old_packlist
+
+
+# --- MakeMaker makemakerdflt section:
+makemakerdflt: all
+ $(NOECHO) $(NOOP)
+
+
+# --- MakeMaker dist section:
+TAR = tar
+TARFLAGS = cvf
+ZIP = zip
+ZIPFLAGS = -r
+COMPRESS = gzip --best
+SUFFIX = .gz
+SHAR = shar
+PREOP = $(NOECHO) $(NOOP)
+POSTOP = $(NOECHO) $(NOOP)
+TO_UNIX = $(NOECHO) $(NOOP)
+CI = ci -u
+RCS_LABEL = rcs -Nv$(VERSION_SYM): -q
+DIST_CP = best
+DIST_DEFAULT = tardist
+DISTNAME = NOTEDB
+DISTVNAME = NOTEDB-1.31
+
+
+# --- MakeMaker macro section:
+
+
+# --- MakeMaker depend section:
+
+
+# --- MakeMaker cflags section:
+
+
+# --- MakeMaker const_loadlibs section:
+
+
+# --- MakeMaker const_cccmd section:
+
+
+# --- MakeMaker post_constants section:
+
+
+# --- MakeMaker pasthru section:
+
+PASTHRU = LIB="$(LIB)"\
+ LIBPERL_A="$(LIBPERL_A)"\
+ LINKTYPE="$(LINKTYPE)"\
+ PREFIX="$(PREFIX)"\
+ OPTIMIZE="$(OPTIMIZE)"\
+ PASTHRU_DEFINE="$(PASTHRU_DEFINE)"\
+ PASTHRU_INC="$(PASTHRU_INC)"
+
+
+# --- MakeMaker special_targets section:
+.SUFFIXES: .xs .c .C .cpp .i .s .cxx .cc $(OBJ_EXT)
+
+.PHONY: all config static dynamic test linkext manifest
+
+
+
+# --- MakeMaker c_o section:
+
+
+# --- MakeMaker xs_c section:
+
+
+# --- MakeMaker xs_o section:
+
+
+# --- MakeMaker top_targets section:
+all :: pure_all manifypods
+ $(NOECHO) $(NOOP)
+
+
+pure_all :: config pm_to_blib subdirs linkext
+ $(NOECHO) $(NOOP)
+
+subdirs :: $(MYEXTLIB)
+ $(NOECHO) $(NOOP)
+
+config :: $(FIRST_MAKEFILE) $(INST_LIBDIR)$(DIRFILESEP).exists
+ $(NOECHO) $(NOOP)
+
+config :: $(INST_ARCHAUTODIR)$(DIRFILESEP).exists
+ $(NOECHO) $(NOOP)
+
+config :: $(INST_AUTODIR)$(DIRFILESEP).exists
+ $(NOECHO) $(NOOP)
+
+$(INST_AUTODIR)/.exists :: /usr/lib/perl/5.8/CORE/perl.h
+ $(NOECHO) $(MKPATH) $(INST_AUTODIR)
+ $(NOECHO) $(EQUALIZE_TIMESTAMP) /usr/lib/perl/5.8/CORE/perl.h $(INST_AUTODIR)/.exists
+
+ -$(NOECHO) $(CHMOD) $(PERM_RWX) $(INST_AUTODIR)
+
+$(INST_LIBDIR)/.exists :: /usr/lib/perl/5.8/CORE/perl.h
+ $(NOECHO) $(MKPATH) $(INST_LIBDIR)
+ $(NOECHO) $(EQUALIZE_TIMESTAMP) /usr/lib/perl/5.8/CORE/perl.h $(INST_LIBDIR)/.exists
+
+ -$(NOECHO) $(CHMOD) $(PERM_RWX) $(INST_LIBDIR)
+
+$(INST_ARCHAUTODIR)/.exists :: /usr/lib/perl/5.8/CORE/perl.h
+ $(NOECHO) $(MKPATH) $(INST_ARCHAUTODIR)
+ $(NOECHO) $(EQUALIZE_TIMESTAMP) /usr/lib/perl/5.8/CORE/perl.h $(INST_ARCHAUTODIR)/.exists
+
+ -$(NOECHO) $(CHMOD) $(PERM_RWX) $(INST_ARCHAUTODIR)
+
+config :: $(INST_MAN3DIR)$(DIRFILESEP).exists
+ $(NOECHO) $(NOOP)
+
+
+$(INST_MAN3DIR)/.exists :: /usr/lib/perl/5.8/CORE/perl.h
+ $(NOECHO) $(MKPATH) $(INST_MAN3DIR)
+ $(NOECHO) $(EQUALIZE_TIMESTAMP) /usr/lib/perl/5.8/CORE/perl.h $(INST_MAN3DIR)/.exists
+
+ -$(NOECHO) $(CHMOD) $(PERM_RWX) $(INST_MAN3DIR)
+
+help:
+ perldoc ExtUtils::MakeMaker
+
+
+# --- MakeMaker linkext section:
+
+linkext :: $(LINKTYPE)
+ $(NOECHO) $(NOOP)
+
+
+# --- MakeMaker dlsyms section:
+
+
+# --- MakeMaker dynamic section:
+
+dynamic :: $(FIRST_MAKEFILE) $(INST_DYNAMIC) $(INST_BOOT)
+ $(NOECHO) $(NOOP)
+
+
+# --- MakeMaker dynamic_bs section:
+
+BOOTSTRAP =
+
+
+# --- MakeMaker dynamic_lib section:
+
+
+# --- MakeMaker static section:
+
+## $(INST_PM) has been moved to the all: target.
+## It remains here for awhile to allow for old usage: "make static"
+static :: $(FIRST_MAKEFILE) $(INST_STATIC)
+ $(NOECHO) $(NOOP)
+
+
+# --- MakeMaker static_lib section:
+
+
+# --- MakeMaker manifypods section:
+
+POD2MAN_EXE = $(PERLRUN) "-MExtUtils::Command::MM" -e pod2man "--"
+POD2MAN = $(POD2MAN_EXE)
+
+
+manifypods : pure_all \
+ NOTEDB/general.pm \
+ NOTEDB/text.pm \
+ NOTEDB/dbm.pm \
+ NOTEDB/mysql.pm \
+ NOTEDB/binary.pm \
+ NOTEDB/dumper.pm \
+ note.pod \
+ NOTEDB/general.pm \
+ NOTEDB/text.pm \
+ NOTEDB/dbm.pm \
+ NOTEDB/mysql.pm \
+ NOTEDB/binary.pm \
+ NOTEDB/dumper.pm \
+ note.pod
+ $(NOECHO) $(POD2MAN) --section=$(MAN3EXT) --perm_rw=$(PERM_RW)\
+ NOTEDB/general.pm $(INST_MAN3DIR)/NOTEDB::general.$(MAN3EXT) \
+ NOTEDB/text.pm $(INST_MAN3DIR)/NOTEDB::text.$(MAN3EXT) \
+ NOTEDB/dbm.pm $(INST_MAN3DIR)/NOTEDB::dbm.$(MAN3EXT) \
+ NOTEDB/mysql.pm $(INST_MAN3DIR)/NOTEDB::mysql.$(MAN3EXT) \
+ NOTEDB/binary.pm $(INST_MAN3DIR)/NOTEDB::binary.$(MAN3EXT) \
+ NOTEDB/dumper.pm $(INST_MAN3DIR)/NOTEDB::dumper.$(MAN3EXT) \
+ note.pod $(INST_MAN3DIR)/note.$(MAN3EXT)
+
+
+
+
+# --- MakeMaker processPL section:
+
+
+# --- MakeMaker installbin section:
+
+$(INST_SCRIPT)/.exists :: /usr/lib/perl/5.8/CORE/perl.h
+ $(NOECHO) $(MKPATH) $(INST_SCRIPT)
+ $(NOECHO) $(EQUALIZE_TIMESTAMP) /usr/lib/perl/5.8/CORE/perl.h $(INST_SCRIPT)/.exists
+
+ -$(NOECHO) $(CHMOD) $(PERM_RWX) $(INST_SCRIPT)
+
+EXE_FILES = bin/note
+
+FIXIN = $(PERLRUN) "-MExtUtils::MY" -e "MY->fixin(shift)"
+
+pure_all :: $(INST_SCRIPT)/note
+ $(NOECHO) $(NOOP)
+
+realclean ::
+ $(RM_F) $(INST_SCRIPT)/note
+
+$(INST_SCRIPT)/note: bin/note $(FIRST_MAKEFILE) $(INST_SCRIPT)/.exists
+ $(NOECHO) $(RM_F) $(INST_SCRIPT)/note
+ $(CP) bin/note $(INST_SCRIPT)/note
+ $(FIXIN) $(INST_SCRIPT)/note
+ -$(NOECHO) $(CHMOD) $(PERM_RWX) $(INST_SCRIPT)/note
+
+
+# --- MakeMaker subdirs section:
+
+# none
+
+# --- MakeMaker clean_subdirs section:
+clean_subdirs :
+ $(NOECHO) $(NOOP)
+
+
+# --- MakeMaker clean section:
+
+# Delete temporary files but do not touch installed files. We don't delete
+# the Makefile here so a later make realclean still has a makefile to use.
+
+clean :: clean_subdirs
+ -$(RM_RF) ./blib $(MAKE_APERL_FILE) $(INST_ARCHAUTODIR)/extralibs.all $(INST_ARCHAUTODIR)/extralibs.ld perlmain.c tmon.out mon.out so_locations pm_to_blib *$(OBJ_EXT) *$(LIB_EXT) perl.exe perl perl$(EXE_EXT) $(BOOTSTRAP) $(BASEEXT).bso $(BASEEXT).def lib$(BASEEXT).def $(BASEEXT).exp $(BASEEXT).x core core.*perl.*.? *perl.core core.[0-9] core.[0-9][0-9] core.[0-9][0-9][0-9] core.[0-9][0-9][0-9][0-9] core.[0-9][0-9][0-9][0-9][0-9]
+ -$(MV) $(FIRST_MAKEFILE) $(MAKEFILE_OLD) $(DEV_NULL)
+
+
+# --- MakeMaker realclean_subdirs section:
+realclean_subdirs :
+ $(NOECHO) $(NOOP)
+
+
+# --- MakeMaker realclean section:
+
+# Delete temporary files (via clean) and also delete installed files
+realclean purge :: clean realclean_subdirs
+ $(RM_RF) $(INST_AUTODIR) $(INST_ARCHAUTODIR)
+ $(RM_RF) $(DISTVNAME)
+ $(RM_F) $(INST_LIB)/NOTEDB/dumper.pm $(INST_LIB)/NOTEDB/mysql.pm $(INST_LIB)/NOTEDB/binary.pm $(MAKEFILE_OLD) $(INST_LIB)/NOTEDB/text.pm $(INST_LIB)/NOTEDB/general.pm $(INST_LIB)/NOTEDB.pm
+ $(RM_F) $(INST_LIB)/note.pod $(INST_LIB)/NOTEDB/dbm.pm $(INST_LIB)/NOTEDB/README $(FIRST_MAKEFILE)
+
+
+# --- MakeMaker metafile section:
+metafile :
+ $(NOECHO) $(ECHO) '# http://module-build.sourceforge.net/META-spec.html' > META.yml
+ $(NOECHO) $(ECHO) '#XXXXXXX This is a prototype!!! It will change in the future!!! XXXXX#' >> META.yml
+ $(NOECHO) $(ECHO) 'name: NOTEDB' >> META.yml
+ $(NOECHO) $(ECHO) 'version: 1.31' >> META.yml
+ $(NOECHO) $(ECHO) 'version_from: NOTEDB.pm' >> META.yml
+ $(NOECHO) $(ECHO) 'installdirs: site' >> META.yml
+ $(NOECHO) $(ECHO) 'requires:' >> META.yml
+ $(NOECHO) $(ECHO) '' >> META.yml
+ $(NOECHO) $(ECHO) 'distribution_type: module' >> META.yml
+ $(NOECHO) $(ECHO) 'generated_by: ExtUtils::MakeMaker version 6.17' >> META.yml
+
+
+# --- MakeMaker metafile_addtomanifest section:
+metafile_addtomanifest:
+ $(NOECHO) $(PERLRUN) -MExtUtils::Manifest=maniadd -e 'eval { maniadd({q{META.yml} => q{Module meta-data (added by MakeMaker)}}) } ' \
+ -e ' or print "Could not add META.yml to MANIFEST: $${'\''@'\''}\n"'
+
+
+# --- MakeMaker dist_basics section:
+distclean :: realclean distcheck
+ $(NOECHO) $(NOOP)
+
+distcheck :
+ $(PERLRUN) "-MExtUtils::Manifest=fullcheck" -e fullcheck
+
+skipcheck :
+ $(PERLRUN) "-MExtUtils::Manifest=skipcheck" -e skipcheck
+
+manifest :
+ $(PERLRUN) "-MExtUtils::Manifest=mkmanifest" -e mkmanifest
+
+veryclean : realclean
+ $(RM_F) *~ *.orig */*~ */*.orig
+
+
+
+# --- MakeMaker dist_core section:
+
+dist : $(DIST_DEFAULT) $(FIRST_MAKEFILE)
+ $(NOECHO) $(PERLRUN) -l -e 'print '\''Warning: Makefile possibly out of date with $(VERSION_FROM)'\''' \
+ -e ' if -e '\''$(VERSION_FROM)'\'' and -M '\''$(VERSION_FROM)'\'' < -M '\''$(FIRST_MAKEFILE)'\'';'
+
+tardist : $(DISTVNAME).tar$(SUFFIX)
+ $(NOECHO) $(NOOP)
+
+uutardist : $(DISTVNAME).tar$(SUFFIX)
+ uuencode $(DISTVNAME).tar$(SUFFIX) $(DISTVNAME).tar$(SUFFIX) > $(DISTVNAME).tar$(SUFFIX)_uu
+
+$(DISTVNAME).tar$(SUFFIX) : distdir
+ $(PREOP)
+ $(TO_UNIX)
+ $(TAR) $(TARFLAGS) $(DISTVNAME).tar $(DISTVNAME)
+ $(RM_RF) $(DISTVNAME)
+ $(COMPRESS) $(DISTVNAME).tar
+ $(POSTOP)
+
+zipdist : $(DISTVNAME).zip
+ $(NOECHO) $(NOOP)
+
+$(DISTVNAME).zip : distdir
+ $(PREOP)
+ $(ZIP) $(ZIPFLAGS) $(DISTVNAME).zip $(DISTVNAME)
+ $(RM_RF) $(DISTVNAME)
+ $(POSTOP)
+
+shdist : distdir
+ $(PREOP)
+ $(SHAR) $(DISTVNAME) > $(DISTVNAME).shar
+ $(RM_RF) $(DISTVNAME)
+ $(POSTOP)
+
+
+# --- MakeMaker distdir section:
+distdir : metafile metafile_addtomanifest
+ $(RM_RF) $(DISTVNAME)
+ $(PERLRUN) "-MExtUtils::Manifest=manicopy,maniread" \
+ -e "manicopy(maniread(),'$(DISTVNAME)', '$(DIST_CP)');"
+
+
+
+# --- MakeMaker dist_test section:
+
+disttest : distdir
+ cd $(DISTVNAME) && $(ABSPERLRUN) Makefile.PL
+ cd $(DISTVNAME) && $(MAKE) $(PASTHRU)
+ cd $(DISTVNAME) && $(MAKE) test $(PASTHRU)
+
+
+# --- MakeMaker dist_ci section:
+
+ci :
+ $(PERLRUN) "-MExtUtils::Manifest=maniread" \
+ -e "@all = keys %{ maniread() };" \
+ -e "print(qq{Executing $(CI) @all\n}); system(qq{$(CI) @all});" \
+ -e "print(qq{Executing $(RCS_LABEL) ...\n}); system(qq{$(RCS_LABEL) @all});"
+
+
+# --- MakeMaker install section:
+
+install :: all pure_install doc_install
+
+install_perl :: all pure_perl_install doc_perl_install
+
+install_site :: all pure_site_install doc_site_install
+
+install_vendor :: all pure_vendor_install doc_vendor_install
+
+pure_install :: pure_$(INSTALLDIRS)_install
+
+doc_install :: doc_$(INSTALLDIRS)_install
+
+pure__install : pure_site_install
+ $(NOECHO) $(ECHO) INSTALLDIRS not defined, defaulting to INSTALLDIRS=site
+
+doc__install : doc_site_install
+ $(NOECHO) $(ECHO) INSTALLDIRS not defined, defaulting to INSTALLDIRS=site
+
+pure_perl_install ::
+ $(NOECHO) umask 022; $(MOD_INSTALL) \
+ $(INST_LIB) $(DESTINSTALLPRIVLIB) \
+ $(INST_ARCHLIB) $(DESTINSTALLARCHLIB) \
+ $(INST_BIN) $(DESTINSTALLBIN) \
+ $(INST_SCRIPT) $(DESTINSTALLSCRIPT) \
+ $(INST_MAN1DIR) $(DESTINSTALLMAN1DIR) \
+ $(INST_MAN3DIR) $(DESTINSTALLMAN3DIR)
+ $(NOECHO) $(WARN_IF_OLD_PACKLIST) \
+ $(SITEARCHEXP)/auto/$(FULLEXT)
+
+
+pure_site_install ::
+ $(NOECHO) umask 02; $(MOD_INSTALL) \
+ read $(SITEARCHEXP)/auto/$(FULLEXT)/.packlist \
+ write $(DESTINSTALLSITEARCH)/auto/$(FULLEXT)/.packlist \
+ $(INST_LIB) $(DESTINSTALLSITELIB) \
+ $(INST_ARCHLIB) $(DESTINSTALLSITEARCH) \
+ $(INST_BIN) $(DESTINSTALLSITEBIN) \
+ $(INST_SCRIPT) $(DESTINSTALLSCRIPT) \
+ $(INST_MAN1DIR) $(DESTINSTALLSITEMAN1DIR) \
+ $(INST_MAN3DIR) $(DESTINSTALLSITEMAN3DIR)
+ $(NOECHO) $(WARN_IF_OLD_PACKLIST) \
+ $(PERL_ARCHLIB)/auto/$(FULLEXT)
+
+pure_vendor_install ::
+ $(NOECHO) umask 022; $(MOD_INSTALL) \
+ $(INST_LIB) $(DESTINSTALLVENDORLIB) \
+ $(INST_ARCHLIB) $(DESTINSTALLVENDORARCH) \
+ $(INST_BIN) $(DESTINSTALLVENDORBIN) \
+ $(INST_SCRIPT) $(DESTINSTALLSCRIPT) \
+ $(INST_MAN1DIR) $(DESTINSTALLVENDORMAN1DIR) \
+ $(INST_MAN3DIR) $(DESTINSTALLVENDORMAN3DIR)
+
+doc_perl_install ::
+
+doc_site_install ::
+ $(NOECHO) $(ECHO) Appending installation info to $(DESTINSTALLSITEARCH)/perllocal.pod
+ -$(NOECHO) umask 02; $(MKPATH) $(DESTINSTALLSITEARCH)
+ -$(NOECHO) umask 02; $(DOC_INSTALL) \
+ "Module" "$(NAME)" \
+ "installed into" "$(INSTALLSITELIB)" \
+ LINKTYPE "$(LINKTYPE)" \
+ VERSION "$(VERSION)" \
+ EXE_FILES "$(EXE_FILES)" \
+ >> $(DESTINSTALLSITEARCH)/perllocal.pod
+
+doc_vendor_install ::
+
+
+uninstall :: uninstall_from_$(INSTALLDIRS)dirs
+
+uninstall_from_perldirs ::
+ $(NOECHO) $(UNINSTALL) $(PERL_ARCHLIB)/auto/$(FULLEXT)/.packlist
+
+uninstall_from_sitedirs ::
+ $(NOECHO) $(UNINSTALL) $(SITEARCHEXP)/auto/$(FULLEXT)/.packlist
+
+uninstall_from_vendordirs ::
+ $(NOECHO) $(UNINSTALL) $(VENDORARCHEXP)/auto/$(FULLEXT)/.packlist
+
+
+# --- MakeMaker force section:
+# Phony target to force checking subdirectories.
+FORCE:
+ $(NOECHO) $(NOOP)
+
+
+# --- MakeMaker perldepend section:
+
+
+# --- MakeMaker makefile section:
+
+# We take a very conservative approach here, but it's worth it.
+# We move Makefile to Makefile.old here to avoid gnu make looping.
+$(FIRST_MAKEFILE) : Makefile.PL $(CONFIGDEP)
+ $(NOECHO) $(ECHO) "Makefile out-of-date with respect to $?"
+ $(NOECHO) $(ECHO) "Cleaning current config before rebuilding Makefile..."
+ $(NOECHO) $(RM_F) $(MAKEFILE_OLD)
+ $(NOECHO) $(MV) $(FIRST_MAKEFILE) $(MAKEFILE_OLD)
+ -$(MAKE) -f $(MAKEFILE_OLD) clean $(DEV_NULL) || $(NOOP)
+ $(PERLRUN) Makefile.PL
+ $(NOECHO) $(ECHO) "==> Your Makefile has been rebuilt. <=="
+ $(NOECHO) $(ECHO) "==> Please rerun the make command. <=="
+ false
+
+
+
+# --- MakeMaker staticmake section:
+
+# --- MakeMaker makeaperl section ---
+MAP_TARGET = perl
+FULLPERL = /usr/bin/perl
+
+$(MAP_TARGET) :: static $(MAKE_APERL_FILE)
+ $(MAKE) -f $(MAKE_APERL_FILE) $@
+
+$(MAKE_APERL_FILE) : $(FIRST_MAKEFILE)
+ $(NOECHO) $(ECHO) Writing \"$(MAKE_APERL_FILE)\" for this $(MAP_TARGET)
+ $(NOECHO) $(PERLRUNINST) \
+ Makefile.PL DIR= \
+ MAKEFILE=$(MAKE_APERL_FILE) LINKTYPE=static \
+ MAKEAPERL=1 NORECURS=1 CCCDLFLAGS=
+
+
+# --- MakeMaker test section:
+
+TEST_VERBOSE=0
+TEST_TYPE=test_$(LINKTYPE)
+TEST_FILE = test.pl
+TEST_FILES =
+TESTDB_SW = -d
+
+testdb :: testdb_$(LINKTYPE)
+
+test :: $(TEST_TYPE)
+ $(NOECHO) $(ECHO) 'No tests defined for $(NAME) extension.'
+
+test_dynamic :: pure_all
+
+testdb_dynamic :: pure_all
+ PERL_DL_NONLAZY=1 $(FULLPERLRUN) $(TESTDB_SW) "-I$(INST_LIB)" "-I$(INST_ARCHLIB)" $(TEST_FILE)
+
+test_ : test_dynamic
+
+test_static :: test_dynamic
+testdb_static :: testdb_dynamic
+
+
+# --- MakeMaker ppd section:
+# Creates a PPD (Perl Package Description) for a binary distribution.
+ppd:
+ $(NOECHO) $(ECHO) '' > $(DISTNAME).ppd
+ $(NOECHO) $(ECHO) ' $(DISTNAME)' >> $(DISTNAME).ppd
+ $(NOECHO) $(ECHO) ' ' >> $(DISTNAME).ppd
+ $(NOECHO) $(ECHO) ' ' >> $(DISTNAME).ppd
+ $(NOECHO) $(ECHO) ' ' >> $(DISTNAME).ppd
+ $(NOECHO) $(ECHO) ' ' >> $(DISTNAME).ppd
+ $(NOECHO) $(ECHO) ' ' >> $(DISTNAME).ppd
+ $(NOECHO) $(ECHO) ' ' >> $(DISTNAME).ppd
+ $(NOECHO) $(ECHO) ' ' >> $(DISTNAME).ppd
+ $(NOECHO) $(ECHO) '' >> $(DISTNAME).ppd
+
+
+# --- MakeMaker pm_to_blib section:
+
+pm_to_blib: $(TO_INST_PM)
+ $(NOECHO) $(PERLRUN) -MExtUtils::Install -e 'pm_to_blib({@ARGV}, '\''$(INST_LIB)/auto'\'', '\''$(PM_FILTER)'\'')'\
+ NOTEDB/general.pm $(INST_LIB)/NOTEDB/general.pm \
+ NOTEDB/dbm.pm $(INST_LIB)/NOTEDB/dbm.pm \
+ NOTEDB/README $(INST_LIB)/NOTEDB/README \
+ NOTEDB.pm $(INST_LIB)/NOTEDB.pm \
+ NOTEDB/text.pm $(INST_LIB)/NOTEDB/text.pm \
+ NOTEDB/mysql.pm $(INST_LIB)/NOTEDB/mysql.pm \
+ NOTEDB/binary.pm $(INST_LIB)/NOTEDB/binary.pm \
+ NOTEDB/dumper.pm $(INST_LIB)/NOTEDB/dumper.pm \
+ note.pod $(INST_LIB)/note.pod
+ $(NOECHO) $(TOUCH) $@
+
+# --- MakeMaker selfdocument section:
+
+
+# --- MakeMaker postamble section:
+
+
+# End.
diff --git a/README b/README
index a7186ed..b2375f9 100644
--- a/README
+++ b/README
@@ -1,4 +1,4 @@
-note 1.3.1 by Thomas Linden, 12/01/2005
+note 1.3.3 by Thomas Linden, 02/12/2005
=======================================
Introduction
@@ -214,4 +214,4 @@ and I'll add you.
Last changed
============
-11/01/2005
+02/12/2005
diff --git a/VERSION b/VERSION
index 3a3cd8c..31e5c84 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.3.1
+1.3.3
diff --git a/bin/note b/bin/note
index 010b112..79dcf4a 100755
--- a/bin/note
+++ b/bin/note
@@ -123,7 +123,7 @@ $CONF = File::Spec->catfile($ENV{HOME}, ".noterc");
$USER = getlogin || getpwuid($<);
chomp $USER;
$TOPIC = 1;
-$version = "1.3.1";
+$version = "1.3.3";
$CurDepth = 1; # the current depth inside the topic "directory" structure...
$maxlen = "auto";
$timelen = 22;
@@ -1271,9 +1271,11 @@ sub output {
$SSS = "-" x ($maxlen + 30);
$nlen = length("$num");
$LINE = "$BORDERC $SSS $_BORDERC\n";
- $L = $BORDERC . "[" . $_BORDERC;
$LONGSPC = " " x (25 - $nlen);
- $R = $BORDERC . "]" . $_BORDERC;
+ if ($conf{printlines}) {
+ $L = $BORDERC . "[" . $_BORDERC;
+ $R = $BORDERC . "]" . $_BORDERC;
+ }
$PathLen = length($PATH); # will be ZERO, if not in TOPIC mode!
$VersionLen = length($version) + 7;
@@ -1284,13 +1286,13 @@ sub output {
$SP = " " x ($maxlen - 2 - $PathLen - $VersionLen);
if (!$Raw) {
# no title in raw-mode!
- print C $LINE;
+ print C $LINE if ($conf{printlines});
print C "$L $NUMC#$_NUMC ";
if ($ListType eq "LONG") {
print C " $TIMEC" . "creation date$_TIMEC ";
}
else {
- print $LONGSPC;
+ print $LONGSPC if ($conf{printlines});
}
if ($TOPIC) {
print C $TOPICC . "$PATH $_TOPICC$SP" . " note $version $R\n";
@@ -1298,7 +1300,7 @@ sub output {
else {
print C $NOTEC . "note$_NOTEC$SP" . " note $version $R\n";
}
- print C $LINE;
+ print C $LINE if ($conf{printlines});
}
$SetTitle = 1;
}
@@ -1328,7 +1330,7 @@ sub output {
else {
$title = substr($note,0,($txtlen - 2 - $nlen));
if (!$Raw) {
- $title = $BORDERC . $NOTEC . $title . "... $_NOTEC$_BORDERC";
+ $title = $BORDERC . $NOTEC . $title . " $_NOTEC$_BORDERC";
}
}
if ($Raw) {
@@ -1346,18 +1348,18 @@ sub output {
print C "$L$TIMEC" . $time . " $_TIMEC$R";
}
print C "$L $NOTEC" . $title . "$_NOTEC $R\n";
- print C $LINE;
+ print C $LINE if ($conf{printlines});
}
}
else {
# we will not reach this in raw-mode, therefore no decision here!
chomp $note;
$Space = " " x (($maxlen + $timelen) - $nlen - 16);
- print C $LINE;
+ print C $LINE if ($conf{printlines});
print C "$L $NUMC$num$_NUMC $R$L$TIMEC$time$_TIMEC $Space$R\n";
print "\n";
print C $NOTEC . $note . $_NOTEC . "\n";
- print C $LINE if ($count == 1);
+ print C $LINE if ($count == 1 && $conf{printlines});
}
}
diff --git a/blib/arch/auto/NOTEDB/.exists b/blib/arch/auto/NOTEDB/.exists
new file mode 100644
index 0000000..e69de29
diff --git a/blib/lib/.exists b/blib/lib/.exists
new file mode 100644
index 0000000..e69de29
diff --git a/blib/lib/NOTEDB.pm b/blib/lib/NOTEDB.pm
new file mode 100644
index 0000000..c561e3c
--- /dev/null
+++ b/blib/lib/NOTEDB.pm
@@ -0,0 +1,305 @@
+#
+# this is a generic module, used by note database
+# backend modules.
+#
+# Copyright (c) 2000-2004 Thomas Linden
+
+
+package NOTEDB;
+
+use Exporter ();
+use vars qw(@ISA @EXPORT $crypt_supported);
+
+$NOTEDB::VERSION = "1.31";
+
+BEGIN {
+ # make sure, it works, otherwise encryption
+ # is not supported on this system!
+ eval { require Crypt::CBC; };
+ if($@) {
+ $NOTEDB::crypt_supported = 0;
+ }
+ else {
+ $NOTEDB::crypt_supported = 1;
+ }
+}
+
+
+sub no_crypt {
+ $NOTEDB::crypt_supported = 0;
+}
+
+
+sub use_crypt {
+ my($this,$key,$method) = @_;
+ my($cipher);
+ if($NOTEDB::crypt_supported == 1) {
+ eval {
+ $cipher = new Crypt::CBC($key, $method);
+ };
+ if($@) {
+ print "warning: Crypt::$method not supported by system!\n";
+ $NOTEDB::crypt_supported = 0;
+ }
+ else {
+ $this->{cipher} = $cipher;
+ }
+ }
+ else{
+ print "warning: Crypt::CBC not supported by system!\n";
+ }
+}
+
+
+sub use_cache {
+ #
+ # this sub turns on cache support
+ #
+ my $this = shift;
+ $this->{use_cache} = 1;
+ $this->{changed} = 1;
+}
+
+sub cache {
+ #
+ # store the whole db as hash
+ # if use_cache is turned on
+ #
+ my $this = shift;
+ if ($this->{use_cache}) {
+ my %res = @_;
+ %{$this->{cache}} = %res;
+ }
+}
+
+sub unchanged {
+ #
+ # return true if $this->{changed} is true, this will
+ # be set to true by writing subs using $this->changed().
+ #
+ my $this = shift;
+ return 0 if(!$this->{use_cache});
+ if ($this->{changed}) {
+ $this->{changed} = 0;
+ return 0;
+ }
+ else {
+ print "%\n";
+ return 1;
+ }
+}
+
+sub changed {
+ #
+ # turn on $this->{changed}
+ # this will be used by update or create subs.
+ #
+ my $this = shift;
+ $this->{changed} = 1;
+}
+
+
+sub generate_search {
+ #
+ # get user input and create perlcode ready for eval
+ # sample input:
+ # "ann.a OR eg???on AND u*do$"
+ # resulting output:
+ # "$match = 1 if(/ann\.a/i or /eg...on/i and /u.*do\$/i );
+ #
+ my($this, $string) = @_;
+
+ my $case = "i";
+
+ if ($string =~ /^\/.+?\/$/) {
+ return $string;
+ }
+ elsif (!$string) {
+ return "/^/";
+ }
+
+ # we will get a / in front of the first word too!
+ $string = " " . $string . " ";
+
+ # check for apostrophs
+ $string =~ s/(?<=\s)(\(??)("[^"]+"|\S+)(\)??)(?=\s)/$1 . $this->check_exact($2) . $3/ge;
+
+ # remove odd spaces infront of and after »and« and »or«
+ $string =~ s/\s\s*(AND|OR)\s\s*/ $1 /g;
+
+ # remove odd spaces infront of »(« and after »)«
+ $string =~ s/(\s*\()/\(/g;
+ $string =~ s/(\)\s*)/\)/g;
+
+ # remove first and last space so it will not masked!
+ $string =~ s/^\s//;
+ $string =~ s/\s$//;
+
+ # mask spaces if not infront of or after »and« and »or«
+ $string =~ s/(?check_or($1, $case) /ge;
+
+ # remove slashes on »and« and »or«
+ $string =~ s/\/(and|or)\/$case/$1/g;
+
+ # remove spaces inside /string/ constructs
+ $string =~ s/(? '.*',
+ '?' => '.',
+ '[' => '[',
+ ']' => ']',
+ '+' => '\+',
+ '.' => '\.',
+ '$' => '\$',
+ '@' => '\@',
+ '/' => '\/',
+ '|' => '\|',
+ '}' => '\}',
+ '{' => '\{',
+ );
+
+ my %escapes = (
+ '*' => '\*',
+ '?' => '\?',
+ '[' => '[',
+ ']' => ']',
+ '+' => '\+',
+ '.' => '\.',
+ '$' => '\$',
+ '@' => '\@',
+ '(' => '\(',
+ ')' => '\)',
+ '/' => '\/',
+ '|' => '\|',
+ '}' => '\}',
+ '{' => '\{',
+ );
+
+ # mask backslash
+ $str =~ s/\\/\\\\/g;
+
+
+ if ($str =~ /^"/ && $str =~ /"$/) {
+ # mask bracket-constructs
+ $str =~ s/(.)/$escapes{$1} || "$1"/ge;
+ }
+ else {
+ $str =~ s/(.)/$wildcards{$1} || "$1"/ge;
+ }
+
+ $str =~ s/^"//;
+ $str =~ s/"$//;
+
+ # mask spaces
+ $str =~ s/\s/\\s/g;
+ return $str;
+}
+
+
+
+
+sub lock {
+ my ($this) = @_;
+
+ if (-e $this->{LOCKFILE}) {
+ open LOCK, "<$this->{LOCKFILE}" or die "could not open $this->{LOCKFILE}: $!\n";
+ my $data = ;
+ close LOCK;
+ chomp $data;
+ print "-- waiting for lock by $data --\n";
+ print "-- remove the lockfile if you are sure: \"$this->{LOCKFILE}\" --\n";
+ }
+
+ my $timeout = 60;
+
+ eval {
+ local $SIG{ALRM} = sub { die "timeout" };
+ local $SIG{INT} = sub { die "interrupted" };
+ alarm $timeout - 2;
+ while (1) {
+ if (! -e $this->{LOCKFILE}) {
+ umask 022;
+ open LOCK, ">$this->{LOCKFILE}" or die "could not open $this->{LOCKFILE}: $!\n";
+ flock LOCK, LOCK_EX;
+
+ my $now = scalar localtime();
+ print LOCK "$ENV{USER} since $now (PID: $$)\n";
+
+ flock LOCK, LOCK_UN;
+ close LOCK;
+ alarm 0;
+ return 0;
+ }
+ printf " %0d\r", $timeout;
+ $timeout--;
+ sleep 1;
+ }
+ };
+ if($@) {
+ if ($@ =~ /^inter/) {
+ print " interrupted\n";
+ }
+ else {
+ print $@;
+ print " timeout\n";
+ }
+ return 1;
+ }
+ return 0;
+}
+
+sub unlock {
+ my ($this) = @_;
+ unlink $this->{LOCKFILE};
+}
+
+
+
+1;
diff --git a/blib/lib/NOTEDB/README b/blib/lib/NOTEDB/README
new file mode 100644
index 0000000..447198c
--- /dev/null
+++ b/blib/lib/NOTEDB/README
@@ -0,0 +1,7 @@
+perl modules for note used as database backends.
+the install.sh script will install both of them,
+although you may only need one backend. Perhaps
+other users on your system have oter ideas in mind...
+
+Therefore, please ignore these file. There is nothing
+to edit or to do. Simply leave this directory :-)
diff --git a/blib/lib/NOTEDB/binary.pm b/blib/lib/NOTEDB/binary.pm
new file mode 100644
index 0000000..8ddabb9
--- /dev/null
+++ b/blib/lib/NOTEDB/binary.pm
@@ -0,0 +1,487 @@
+#!/usr/bin/perl
+# $Id: binary.pm,v 1.3 2000/08/11 00:05:58 zarahg Exp $
+# Perl module for note
+# binary database backend. see docu: perldoc NOTEDB::binary
+#
+package NOTEDB::binary;
+
+$NOTEDB::binary::VERSION = "1.10";
+
+use strict;
+#use Data::Dumper;
+use IO::Seekable;
+use File::Spec;
+use Fcntl qw(LOCK_EX LOCK_UN);
+
+use NOTEDB;
+use Exporter ();
+use vars qw(@ISA @EXPORT);
+@ISA = qw(NOTEDB Exporter);
+
+
+
+
+sub new {
+ my($this, %param) = @_;
+
+ my $class = ref($this) || $this;
+ my $self = {};
+ bless($self,$class);
+
+ $self->{NOTEDB} = $param{dbname} || File::Spec->catfile($ENV{HOME}, ".notedb");
+ my $MAX_NOTE = $param{max_note} || 4096;
+ my $MAX_TIME = $param{max_time} || 64;
+
+ if(! -e $self->{NOTEDB}) {
+ open(TT,">$self->{NOTEDB}") or die "Could not create $self->{NOTEDB}: $!\n";
+ close (TT);
+ }
+ elsif(! -w $self->{NOTEDB}) {
+ print "$self->{NOTEDB} is not writable!\n";
+ exit(1);
+ }
+
+
+ my $TYPEDEF = "i a$MAX_NOTE a$MAX_TIME";
+ my $SIZEOF = length pack($TYPEDEF, () );
+
+ $self->{sizeof} = $SIZEOF;
+ $self->{typedef} = $TYPEDEF;
+ $self->{maxnote} = $MAX_NOTE;
+ $self->{LOCKFILE} = $self->{NOTEDB} . "~LOCK";
+
+ return $self;
+}
+
+
+sub DESTROY
+{
+ # clean the desk!
+}
+
+sub version {
+ my $this = shift;
+ return $NOTEDB::binary::VERSION;
+}
+
+
+
+sub set_del_all
+{
+ my $this = shift;
+ unlink $this->{NOTEDB};
+ open(TT,">$this->{NOTEDB}") or die "Could not create $this->{NOTEDB}: $!\n";
+ close (TT);
+}
+
+
+sub get_single {
+ my($this, $num) = @_;
+ my($address, $note, $date, $buffer, $n, $t, $buffer, );
+
+ open NOTE, "+<$this->{NOTEDB}" or die "could not open $this->{NOTEDB}\n";
+ flock NOTE, LOCK_EX;
+
+ $address = ($num-1) * $this->{sizeof};
+ seek(NOTE, $address, IO::Seekable::SEEK_SET);
+ read(NOTE, $buffer, $this->{sizeof});
+ ($num, $n, $t) = unpack($this->{typedef}, $buffer);
+
+ $note = $this->ude($n);
+ $date = $this->ude($t);
+
+ flock NOTE, LOCK_UN;
+ close NOTE;
+
+ return $note, $date;
+}
+
+
+sub get_all
+{
+ my $this = shift;
+ my($num, $note, $date, %res);
+
+ if ($this->unchanged) {
+ return %{$this->{cache}};
+ }
+ open NOTE, "+<$this->{NOTEDB}" or die "could not open $this->{NOTEDB}\n";
+ flock NOTE, LOCK_EX;
+ my($buffer, $t, $n);
+ seek(NOTE, 0, 0); # START FROM BEGINNING
+ while(read(NOTE, $buffer, $this->{sizeof})) {
+ ($num, $note, $date) = unpack($this->{typedef}, $buffer);
+ $t = $this->ude($date);
+ $n = $this->ude($note);
+ $res{$num}->{'note'} = $n;
+ $res{$num}->{'date'} = $t;
+ }
+ flock NOTE, LOCK_UN;
+ close NOTE;
+
+ $this->cache(%res);
+ return %res;
+}
+
+sub import_data {
+ my ($this, $data) = @_;
+ foreach my $num (keys %{$data}) {
+ my $pos = $this->get_nextnum();
+ $this->set_edit($pos, $data->{$num}->{note}, $data->{$num}->{date});
+ }
+}
+
+sub get_nextnum
+{
+ my $this = shift;
+ my($num, $te, $me, $buffer);
+
+ if ($this->unchanged) {
+ $num = 1;
+ foreach (keys %{$this->{cache}}) {
+ $num++;
+ }
+ return $num;
+ }
+ open NOTE, "+<$this->{NOTEDB}" or die "could not open $this->{NOTEDB}\n";
+ flock NOTE, LOCK_EX;
+
+ seek(NOTE, 0, 0); # START FROM BEGINNING
+ while(read(NOTE, $buffer, $this->{sizeof})) {
+ ($num, $te, $me) = unpack($this->{typedef}, $buffer);
+ }
+ $num += 1;
+ flock NOTE, LOCK_UN;
+ close NOTE;
+
+ return $num;
+}
+
+sub get_search
+{
+ my($this, $searchstring) = @_;
+ my($buffer, $num, $note, $date, %res, $t, $n, $match);
+
+ my $regex = $this->generate_search($searchstring);
+ eval $regex;
+ if ($@) {
+ print "invalid expression: \"$searchstring\"!\n";
+ return;
+ }
+ $match = 0;
+
+ if ($this->unchanged) {
+ foreach my $num (keys %{$this->{cache}}) {
+ $_ = $this->{cache}{$num}->{note};
+ eval $regex;
+ if ($match) {
+ $res{$num}->{note} = $this->{cache}{$num}->{note};
+ $res{$num}->{date} = $this->{cache}{$num}->{date}
+ }
+ $match = 0;
+ }
+ return %res;
+ }
+
+ open NOTE, "+<$this->{NOTEDB}" or die "could not open $this->{NOTEDB}\n";
+ flock NOTE, LOCK_EX;
+
+ seek(NOTE, 0, 0); # START FROM BEGINNING
+ while(read(NOTE, $buffer, $this->{sizeof})) {
+ ($num, $note, $date) = unpack($this->{typedef}, $buffer);
+ $n = $this->ude($note);
+ $t = $this->ude($date);
+ $_ = $n;
+ eval $regex;
+ if($match)
+ {
+ $res{$num}->{'note'} = $n;
+ $res{$num}->{'date'} = $t;
+ }
+ $match = 0;
+ }
+ flock NOTE, LOCK_UN;
+ close NOTE;
+
+ return %res;
+}
+
+
+
+
+sub set_edit {
+ my($this, $num, $note, $date) = @_;
+
+ $this->warn_if_too_big($note, $num);
+
+ my $address = ($num -1 ) * $this->{sizeof};
+
+ open NOTE, "+<$this->{NOTEDB}" or die "could not open $this->{NOTEDB}\n";
+ flock NOTE, LOCK_EX;
+
+ seek(NOTE, $address, IO::Seekable::SEEK_SET);
+ my $n = $this->uen($note);
+ my $t = $this->uen($date);
+
+ my $buffer = pack($this->{typedef}, $num, $n, $t);
+ print NOTE $buffer;
+
+ flock NOTE, LOCK_UN;
+ close NOTE;
+
+ $this->changed;
+}
+
+
+sub set_new {
+ my($this, $num, $note, $date) = @_;
+
+ $this->warn_if_too_big($note, $num);
+
+ open NOTE, "+<$this->{NOTEDB}" or die "could not open $this->{NOTEDB}\n";
+ flock NOTE, LOCK_EX;
+
+ seek(NOTE, 0, IO::Seekable::SEEK_END); # APPEND
+ my $n = $this->uen($note);
+ my $t = $this->uen($date);
+ my $buffer = pack($this->{typedef}, $num, $n, $t);
+ print NOTE $buffer;
+
+ flock NOTE, LOCK_UN;
+ close NOTE;
+
+ $this->changed;
+}
+
+
+sub set_del
+{
+ my($this, $num) = @_;
+ my(%orig, $note, $date, $T, $setnum, $buffer, $n, $N, $t);
+
+ $setnum = 1;
+
+ %orig = $this->get_all();
+ return "ERROR" if (! exists $orig{$num});
+
+ delete $orig{$num};
+
+ # overwrite, but keep number!
+ open NOTE, ">$this->{NOTEDB}" or die "could not open $this->{NOTEDB}\n";
+ flock NOTE, LOCK_EX;
+ seek(NOTE, 0, 0); # START FROM BEGINNING
+ foreach $N (keys %orig) {
+ $n = $this->uen($orig{$N}->{'note'});
+ $t = $this->uen($orig{$N}->{'date'});
+ $buffer = pack( $this->{typedef}, $N, $n, $t);
+ # keep orig number, note have to call recount!
+ print NOTE $buffer;
+ seek(NOTE, 0, IO::Seekable::SEEK_END);
+ $setnum++;
+ }
+ flock NOTE, LOCK_UN;
+ close NOTE;
+
+ $this->changed;
+
+ return;
+}
+
+sub set_recountnums
+{
+ my($this) = @_;
+ my(%orig, $note, $date, $T, $setnum, $buffer, $n, $N, $t);
+
+ $setnum = 1;
+ %orig = $this->get_all();
+
+ open NOTE, ">$this->{NOTEDB}" or die "could not open $this->{NOTEDB}\n";
+ flock NOTE, LOCK_EX;
+ seek(NOTE, 0, 0); # START FROM BEGINNING
+
+ foreach $N (sort {$a <=> $b} keys %orig) {
+ $n = $this->uen($orig{$N}->{'note'});
+ $t = $this->uen($orig{$N}->{'date'});
+ $buffer = pack( $this->{typedef}, $setnum, $n, $t);
+ print NOTE $buffer;
+ seek(NOTE, 0, IO::Seekable::SEEK_END);
+ $setnum++;
+ }
+ flock NOTE, LOCK_UN;
+ close NOTE;
+
+ $this->changed;
+
+ return;
+}
+
+sub uen
+{
+ my $this = shift;
+ my($T);
+ if($NOTEDB::crypt_supported == 1) {
+ eval {
+ $T = pack("u", $this->{cipher}->encrypt($_[0]));
+ };
+ }
+ else {
+ $T = pack("u", $_[0]);
+ }
+ chomp $T;
+
+ return $T;
+}
+
+sub ude
+{
+ my $this = shift;
+ my($T);
+ if($NOTEDB::crypt_supported == 1) {
+ eval {
+ $T = $this->{cipher}->decrypt(unpack("u",$_[0]));
+ };
+ }
+ else {
+ $T = unpack("u", $_[0]);
+ }
+ return $T;
+}
+
+
+sub warn_if_too_big {
+ my ($this, $note, $num) = @_;
+
+ my $len = length($this->uen($note));
+
+ if ($len > $this->{maxnote}) {
+ # calculate the 30% uuencoding overhead
+ my $overhead = int(($this->{maxnote} / 100) * 28);
+
+ # fetch what's left by driver
+ my $left = substr $note, $this->{maxnote} - $overhead;
+
+ $left = "\n$left\n";
+ $left =~ s/\n/\n> /gs;
+
+ print STDERR "*** WARNING $this->{version} WARNING ***\n"
+ ."The driver encountered a string length problem with your\n"
+ ."note entry number $num. The entry is too long. Either shorten\n"
+ ."the entry or resize the database field for entries.\n\n"
+ ."The following data has been cut off the entry:\n"
+ ."\n$left\n\n";
+
+ my $copy = File::Spec->catfile($ENV{'HOME'}, "entry-$num.txt");
+ open N, ">$copy" or die "Could not open $copy: $!\n";
+ print N $note;
+ close N;
+
+ print "*** Wrote the complete note entry number $num to file: $copy ***\n";
+ }
+}
+
+sub _retrieve {
+ my ($this) = @_;
+ my $file = $this->{dbname};
+ if (-s $file) {
+ if ($this->changed() || $this->{unread}) {
+ my $fh = new FileHandle "<$this->{dbname}" or die "could not open $this->{dbname}\n";
+ flock $fh, LOCK_EX;
+
+ my %data = ParseConfig(-ConfigFile => $fh) or die "could not read to database: $!\n";
+
+ flock $fh, LOCK_UN;
+ $fh->close();
+
+ $this->{unread} = 0;
+ $this->{data} = \%data;
+ return %data;
+ }
+ else {
+ return %{$this->{data}};
+ }
+ }
+ else {
+ return ();
+ }
+}
+
+
+1; # keep this!
+
+__END__
+
+=head1 NAME
+
+NOTEDB::binary - module lib for accessing a notedb from perl
+
+=head1 SYNOPSIS
+
+ # include the module
+ use NOTEDB;
+
+ # create a new NOTEDB object
+ $db = new NOTEDB("binary", "/home/tom/.notedb", 4096, 24);
+
+ # decide to use encryption
+ # $key is the cipher to use for encryption
+ # $method must be either Crypt::IDEA or Crypt::DES
+ # you need Crypt::CBC, Crypt::IDEA and Crypt::DES to have installed.
+ $db->use_crypt($key,$method);
+
+ # do not use encryption
+ # this is the default
+ $db->no_crypt;
+
+ # get a single note
+ ($note, $date) = $db->get_single(1);
+
+ # search for a certain note
+ %matching_notes = $db->get_search("somewhat");
+ # format of returned hash:
+ #$matching_notes{$numberofnote}->{'note' => 'something', 'date' => '23.12.2000 10:33:02'}
+
+ # get all existing notes
+ %all_notes = $db->get_all();
+ # format of returnes hash like the one from get_search above
+
+ # get the next noteid available
+ $next_num = $db->get_nextnum();
+
+ # modify a certain note
+ $db->set_edit(1, "any text", "23.12.2000 10:33:02");
+
+ # create a new note
+ $db->set_new(5, "any new text", "23.12.2000 10:33:02");
+
+ # delete a certain note
+ $db->set_del(5);
+
+ # turn on encryption. CryptMethod must be IDEA, DES or BLOWFISH
+ $db->use_crypt("passphrase", "CryptMethod");
+
+ # turn off encryption. This is the default.
+ $db->no_crypt();
+
+
+=head1 DESCRIPTION
+
+You can use this module for accessing a note database. There are currently
+two versions of this module, one version for a SQL database and one for a
+binary file (note's own database-format).
+However, both versions provides identical interfaces, which means, you do
+not need to change your code, if you want to switch to another database format.
+
+Currently, NOTEDB module is only used by note itself. But feel free to use it
+within your own project! Perhaps someone want to implement a webinterface to
+note...
+
+=head1 USAGE
+
+please see the section SYNOPSIS, it says it all.
+
+=head1 AUTHOR
+
+Thomas Linden .
+
+
+=cut
diff --git a/blib/lib/NOTEDB/dbm.pm b/blib/lib/NOTEDB/dbm.pm
new file mode 100644
index 0000000..7f6724f
--- /dev/null
+++ b/blib/lib/NOTEDB/dbm.pm
@@ -0,0 +1,269 @@
+#!/usr/bin/perl
+# $Id: dbm.pm,v 1.3 2000/08/11 00:05:58 zarahg Exp $
+# Perl module for note
+# DBM database backend. see docu: perldoc NOTEDB::dbm
+#
+
+package NOTEDB::dbm;
+
+$NOTEDB::dbm::VERSION = "1.40";
+
+use DB_File;
+use NOTEDB;
+use strict;
+use Exporter ();
+use vars qw(@ISA @EXPORT %note %date);
+@ISA = qw(NOTEDB Exporter);
+
+
+
+
+
+
+sub new
+{
+ my($this, %param) = @_;
+ my $class = ref($this) || $this;
+ my $self = {};
+ bless($self,$class);
+
+ my $notefile = "note.dbm";
+ my $timefile = "date.dbm";
+ my $dbm_dir = $param{directory} || File::Spec->catfile($ENV{HOME}, ".note_dbm");
+
+ if (! -d $dbm_dir) {
+ # try to make it
+ mkdir $dbm_dir || die "Could not create $dbm_dir: $!\n";
+ }
+
+ tie %note, "DB_File", "$dbm_dir/$notefile" || die "Could not tie $dbm_dir/$notefile: $!\n";
+ tie %date, "DB_File", "$dbm_dir/$timefile" || die "Could not tie $dbm_dir/$timefile: $!\n";
+
+ $self->{LOCKFILE} = $param{dbname} . "~LOCK";
+
+ return $self;
+}
+
+
+sub DESTROY
+{
+ # clean the desk!
+ untie %note, %date;
+}
+
+sub version {
+ my $this = shift;
+ return $this->{version};
+}
+
+
+sub get_single
+{
+ my($this, $num) = @_;
+ my($note, $date);
+ return $this->ude ($note{$num}), $this->ude($date{$num});
+}
+
+
+sub get_all
+{
+ my $this = shift;
+ my($num, $note, $date, %res, $real);
+ foreach $num (sort {$a <=> $b} keys %date) {
+ $res{$num}->{'note'} = $this->ude($note{$num});
+ $res{$num}->{'date'} = $this->ude($date{$num});
+ }
+ return %res;
+}
+
+sub import_data {
+ my ($this, $data) = @_;
+ foreach my $num (keys %{$data}) {
+ my $pos = $this->get_nextnum();
+ $note{$pos} = $this->ude($note{$num}->{note});
+ $date{$pos} = $this->ude($date{$num}->{date});
+ }
+}
+
+sub get_nextnum
+{
+ my($this, $num);
+ foreach (sort {$a <=> $b} keys %date) {
+ $num = $_;
+ }
+ $num++;
+ return $num;
+}
+
+sub get_search
+{
+ my($this, $searchstring) = @_;
+ my($num, $note, $date, %res, $match);
+
+ my $regex = $this->generate_search($searchstring);
+ eval $regex;
+ if ($@) {
+ print "invalid expression: \"$searchstring\"!\n";
+ return;
+ }
+ $match = 0;
+ foreach $num (sort {$a <=> $b} keys %date) {
+ $_ = $this->ude($note{$num});
+ eval $regex;
+ if ($match) {
+ $res{$num}->{'note'} = $this->ude($note{$num});
+ $res{$num}->{'date'} = $this->ude($date{$num});
+ }
+ $match = 0;
+ }
+
+ return %res;
+}
+
+
+
+sub set_recountnums
+{
+ my $this = shift;
+ my(%Note, %Date, $num, $setnum);
+ $setnum = 1;
+ foreach $num (sort {$a <=> $b} keys %note) {
+ $Note{$setnum} = $note{$num};
+ $Date{$setnum} = $date{$num};
+ $setnum++;
+ }
+ %note = %Note;
+ %date = %Date;
+}
+
+
+
+sub set_edit
+{
+ my($this, $num, $note, $date) = @_;
+ $note{$num} = $this->uen($note);
+ $date{$num} = $this->uen($date);
+}
+
+
+sub set_new
+{
+ my($this, $num, $note, $date) = @_;
+ $this->set_edit($num, $note, $date); # just the same thing
+}
+
+
+sub set_del
+{
+ my($this, $num) = @_;
+ my($note, $date, $T);
+ ($note, $date) = $this->get_single($num);
+ return "ERROR" if ($date !~ /^\d/);
+ delete $note{$num};
+ delete $date{$num};
+}
+
+sub set_del_all
+{
+ my($this) = @_;
+ %note = ();
+ %date = ();
+ return;
+}
+
+sub uen
+{
+ my $this = shift;
+ my($T);
+ if($NOTEDB::crypt_supported == 1) {
+ eval {
+ $T = pack("u", $this->{cipher}->encrypt($_[0]));
+ };
+ }
+ else {
+ $T = $_[0];
+ }
+ chomp $T;
+ return $T;
+}
+
+sub ude
+{
+ my $this = shift;
+ my($T);
+ if($NOTEDB::crypt_supported == 1) {
+ eval {
+ $T = $this->{cipher}->decrypt(unpack("u",$_[0]))
+ };
+ return $T;
+ }
+ else {
+ return $_[0];
+ }
+}
+
+
+
+1; # keep this!
+
+__END__
+
+=head1 NAME
+
+NOTEDB::dbm - module lib for accessing a notedb from perl
+
+=head1 SYNOPSIS
+
+ # include the module
+ use NOTEDB;
+
+ # create a new NOTEDB object (the last 4 params are db table/field names)
+ $db = new NOTEDB("mysql","note","/home/user/.notedb/");
+
+ # get a single note
+ ($note, $date) = $db->get_single(1);
+
+ # search for a certain note
+ %matching_notes = $db->get_search("somewhat");
+ # format of returned hash:
+ #$matching_notes{$numberofnote}->{'note' => 'something', 'date' => '23.12.2000 10:33:02'}
+
+ # get all existing notes
+ %all_notes = $db->get_all();
+ # format of returnes hash like the one from get_search above
+
+ # get the next noteid available
+ $next_num = $db->get_nextnum();
+
+ # recount all noteids starting by 1 (usefull after deleting one!)
+ $db->set_recountnums();
+
+ # modify a certain note
+ $db->set_edit(1, "any text", "23.12.2000 10:33:02");
+
+ # create a new note
+ $db->set_new(5, "any new text", "23.12.2000 10:33:02");
+
+ # delete a certain note
+ $db->set_del(5);
+
+=head1 DESCRIPTION
+
+You can use this module for accessing a note database. This is the dbm module.
+It uses the DB_FILE module to store it's data and it uses DBM files for tis purpose.
+
+Currently, NOTEDB module is only used by note itself. But feel free to use it
+within your own project! Perhaps someone want to implement a webinterface to
+note...
+
+=head1 USAGE
+
+please see the section SYNOPSIS, it says it all.
+
+=head1 AUTHOR
+
+Thomas Linden .
+
+
+
+=cut
diff --git a/blib/lib/NOTEDB/dumper.pm b/blib/lib/NOTEDB/dumper.pm
new file mode 100644
index 0000000..3ae1ffb
--- /dev/null
+++ b/blib/lib/NOTEDB/dumper.pm
@@ -0,0 +1,371 @@
+# Perl module for note
+# text database backend. see docu: perldoc NOTEDB::text
+# using Storable as backend.
+
+package NOTEDB::dumper;
+
+$NOTEDB::text::VERSION = "1.00";
+
+use strict;
+use Data::Dumper;
+use File::Spec;
+use MIME::Base64;
+
+use NOTEDB;
+
+use Fcntl qw(LOCK_EX LOCK_UN);
+
+use Exporter ();
+use vars qw(@ISA @EXPORT);
+@ISA = qw(NOTEDB Exporter);
+
+
+
+
+sub new {
+ my($this, %param) = @_;
+
+ my $class = ref($this) || $this;
+ my $self = {};
+ bless($self,$class);
+
+ $self->{NOTEDB} = $param{dbname} || File::Spec->catfile($ENV{HOME}, ".notedb");
+
+ if(! -e $param{dbname}) {
+ open(TT,">$param{dbname}") or die "Could not create $param{dbname}: $!\n";
+ close (TT);
+ }
+ elsif(! -w $param{dbname}) {
+ print "$param{dbname} is not writable!\n";
+ exit(1);
+ }
+
+ $self->{LOCKFILE} = $param{dbname} . "~LOCK";
+ $self->{mtime} = $self->get_stat();
+ $self->{unread} = 1;
+ $self->{data} = {};
+
+ return $self;
+}
+
+
+sub DESTROY
+{
+ # clean the desk!
+}
+
+sub version {
+ my $this = shift;
+ return $NOTEDB::text::VERSION;
+}
+
+sub get_stat {
+ my ($this) = @_;
+ my $mtime = (stat($this->{dbname}))[9];
+ return $mtime;
+}
+
+
+sub set_del_all {
+ my $this = shift;
+ unlink $this->{NOTEDB};
+ open(TT,">$this->{NOTEDB}") or die "Could not create $this->{NOTEDB}: $!\n";
+ close (TT);
+}
+
+
+sub get_single {
+ my($this, $num) = @_;
+ my($address, $note, $date, $buffer, $n, $t, $buffer, );
+
+ my %data = $this->get_all();
+ return ($data{$num}->{note}, $data{$num}->{date});
+}
+
+
+sub get_all {
+ my $this = shift;
+ my($num, $note, $date, %res);
+
+ if ($this->unchanged) {
+ return %{$this->{cache}};
+ }
+
+ my %data = $this->_retrieve();
+ foreach my $num (keys %data) {
+ $res{$num}->{note} = $this->ude($data{$num}->{note});
+ $res{$num}->{date} = $this->ude($data{$num}->{date});
+ }
+
+ $this->cache(%res);
+ return %res;
+}
+
+sub import_data {
+ my ($this, $data) = @_;
+ my %res = $this->_retrieve();
+ my $pos = (scalar keys %res) + 1;
+ foreach my $num (keys %{$data}) {
+ $res{$pos}->{note} = $this->uen($data->{$num}->{note});
+ $res{$pos}->{date} = $this->uen($data->{$num}->{date});
+ $pos++;
+ }
+ $this->_store(\%res);
+}
+
+sub get_nextnum {
+ my $this = shift;
+ my($num, $te, $me, $buffer);
+
+ if ($this->unchanged) {
+ $num = 1;
+ foreach (keys %{$this->{cache}}) {
+ $num++;
+ }
+ return $num;
+ }
+
+ my %data = $this->get_all();
+ my $size = scalar keys %data;
+ $num = $size + 1;
+ return $num;
+}
+
+sub get_search {
+ my($this, $searchstring) = @_;
+ my($buffer, $num, $note, $date, %res, $t, $n, $match);
+
+ my $regex = $this->generate_search($searchstring);
+ eval $regex;
+ if ($@) {
+ print "invalid expression: \"$searchstring\"!\n";
+ return;
+ }
+ $match = 0;
+
+ if ($this->unchanged) {
+ foreach my $num (keys %{$this->{cache}}) {
+ $_ = $this->{cache}{$num}->{note};
+ eval $regex;
+ if ($match) {
+ $res{$num}->{note} = $this->{cache}{$num}->{note};
+ $res{$num}->{date} = $this->{cache}{$num}->{date}
+ }
+ $match = 0;
+ }
+ return %res;
+ }
+
+ my %data = $this->get_all();
+
+ foreach my $num(sort keys %data) {
+ $_ = $data{$num}->{note};
+ eval $regex;
+ if($match)
+ {
+ $res{$num}->{note} = $data{$num}->{note};
+ $res{$num}->{date} = $data{$num}->{data};
+ }
+ $match = 0;
+ }
+
+ return %res;
+}
+
+
+
+
+sub set_edit {
+ my($this, $num, $note, $date) = @_;
+
+ my %data = $this->_retrieve();
+
+ $data{$num} = {
+ note => $this->uen($note),
+ date => $this->uen($date)
+ };
+
+ $this->_store(\%data);
+
+ $this->changed;
+}
+
+
+sub set_new {
+ my($this, $num, $note, $date) = @_;
+ $this->set_edit($num, $note, $date);
+}
+
+
+sub set_del {
+ my($this, $num) = @_;
+ my(%data, $note, $date, $T, $setnum, $buffer, $n, $N, $t);
+
+ $setnum = 1;
+
+ %data = $this->_retrieve();
+ return "ERROR" if (! exists $data{$num});
+
+ delete $data{$num};
+
+ $this->_store(\%data);
+
+ $this->changed;
+
+ return;
+}
+
+sub set_recountnums {
+ my($this) = @_;
+ my(%orig, %data, $note, $date, $T, $setnum, $buffer, $n, $N, $t);
+
+ $setnum = 1;
+ %orig = $this->_retrieve();
+
+ foreach $N (sort {$a <=> $b} keys %orig) {
+ $data{$setnum} = {
+ note => $orig{$N}->{note},
+ date => $orig{$N}->{date}
+ };
+ $setnum++;
+ }
+
+ $this->_store(\%data);
+
+ $this->changed;
+
+ return;
+}
+
+sub uen {
+ my ($this, $raw) = @_;
+ my($crypted);
+ if($NOTEDB::crypt_supported == 1) {
+ eval {
+ $crypted = $this->{cipher}->encrypt($raw);
+ return encode_base64($crypted);
+ };
+ }
+ else {
+ return $raw;
+ }
+}
+
+sub ude {
+ my ($this, $crypted) = @_;
+ my($raw);
+ if($NOTEDB::crypt_supported == 1) {
+ eval {
+ $raw = $this->{cipher}->decrypt(decode_base64($crypted));
+ };
+ return $raw;
+ }
+ else {
+ return $crypted;
+ }
+}
+
+
+sub _store {
+ my ($this, $data) = @_;
+ open N, ">$this->{NOTEDB}" or die "Could not open db: $!\n";
+ print N Data::Dumper->Dump([$data], [qw(*data)]);
+ close N;
+}
+
+sub _retrieve {
+ my $this = shift;
+ if (-s $this->{NOTEDB}) {
+ if ($this->changed() || $this->{unread}) {
+ open N, "<$this->{NOTEDB}" or die "Could not open db: $!\n";
+ my $content = join "", ;
+ close N;
+ my %data;
+ eval $content; # creates %data
+ $this->{unread} = 0;
+ $this->{data} = \%data;
+ return %data;
+ }
+ }
+ else {
+ return ();
+ }
+}
+
+
+1; # keep this!
+
+__END__
+
+=head1 NAME
+
+NOTEDB::text - module lib for accessing a notedb from perl
+
+=head1 SYNOPSIS
+
+ # include the module
+ use NOTEDB;
+
+ # create a new NOTEDB object
+ $db = new NOTEDB("text", "/home/tom/.notedb", 4096, 24);
+
+ # decide to use encryption
+ # $key is the cipher to use for encryption
+ # $method must be either Crypt::IDEA or Crypt::DES
+ # you need Crypt::CBC, Crypt::IDEA and Crypt::DES to have installed.
+ $db->use_crypt($key,$method);
+
+ # do not use encryption
+ # this is the default
+ $db->no_crypt;
+
+ # get a single note
+ ($note, $date) = $db->get_single(1);
+
+ # search for a certain note
+ %matching_notes = $db->get_search("somewhat");
+ # format of returned hash:
+ #$matching_notes{$numberofnote}->{'note' => 'something', 'date' => '23.12.2000 10:33:02'}
+
+ # get all existing notes
+ %all_notes = $db->get_all();
+ # format of returnes hash like the one from get_search above
+
+ # get the next noteid available
+ $next_num = $db->get_nextnum();
+
+ # modify a certain note
+ $db->set_edit(1, "any text", "23.12.2000 10:33:02");
+
+ # create a new note
+ $db->set_new(5, "any new text", "23.12.2000 10:33:02");
+
+ # delete a certain note
+ $db->set_del(5);
+
+ # turn on encryption. CryptMethod must be IDEA, DES or BLOWFISH
+ $db->use_crypt("passphrase", "CryptMethod");
+
+ # turn off encryption. This is the default.
+ $db->no_crypt();
+
+
+=head1 DESCRIPTION
+
+You can use this module for accessing a note database. This backend uses
+a text file for storage and Storable for accessing the file.
+
+Currently, NOTEDB module is only used by note itself. But feel free to use it
+within your own project! Perhaps someone want to implement a webinterface to
+note...
+
+=head1 USAGE
+
+please see the section SYNOPSIS, it says it all.
+
+=head1 AUTHOR
+
+Thomas Linden .
+
+
+=cut
diff --git a/blib/lib/NOTEDB/general.pm b/blib/lib/NOTEDB/general.pm
new file mode 100644
index 0000000..31671d6
--- /dev/null
+++ b/blib/lib/NOTEDB/general.pm
@@ -0,0 +1,408 @@
+# Perl module for note
+# general database backend. see docu: perldoc NOTEDB::general
+# using Config::General as backend.
+
+package NOTEDB::general;
+
+$NOTEDB::general::VERSION = "1.01";
+
+use strict;
+#use Data::Dumper;
+use File::Spec;
+use Config::General;
+use MIME::Base64;
+use FileHandle;
+use NOTEDB;
+
+use Fcntl qw(LOCK_EX LOCK_UN);
+
+use Exporter ();
+use vars qw(@ISA @EXPORT);
+@ISA = qw(NOTEDB Exporter);
+
+
+
+
+
+sub new {
+ my($this, %param) = @_;
+
+ my $class = ref($this) || $this;
+ my $self = {};
+ bless($self,$class);
+
+ $self->{dbname} = $param{dbname} || File::Spec->catfile($ENV{HOME}, ".notedb");
+
+ if(! -e $param{dbname}) {
+ open(TT,">$param{dbname}") or die "Could not create $param{dbname}: $!\n";
+ close (TT);
+ }
+ elsif(! -w $param{dbname}) {
+ print "$param{dbname} is not writable!\n";
+ exit(1);
+ }
+
+ $self->{mtime} = $self->get_stat();
+ $self->{unread} = 1;
+ $self->{data} = {};
+ $self->{LOCKFILE} = $param{dbname} . "~LOCK";
+
+ return $self;
+}
+
+
+sub DESTROY {
+ # clean the desk!
+}
+
+sub version {
+ my $this = shift;
+ return $NOTEDB::general::VERSION;
+}
+
+sub get_stat {
+ my ($this) = @_;
+ my $mtime = (stat($this->{dbname}))[9];
+ return $mtime;
+}
+
+sub changed {
+ my ($this) = @_;
+ my $current = $this->get_stat();
+ if ($current > $this->{mtime}) {
+ $this->{mtime} = $current;
+ return $current;
+ }
+ else {
+ return 0;
+ }
+}
+
+sub set_del_all {
+ my $this = shift;
+ unlink $this->{dbname};
+ open(TT,">$this->{dbname}") or die "Could not create $this->{dbname}: $!\n";
+ close (TT);
+}
+
+
+sub get_single {
+ my($this, $num) = @_;
+ my($address, $note, $date, $buffer, $n, $t, $buffer, );
+
+ my %data = $this->get_all();
+
+ return ($data{$num}->{note}, $data{$num}->{date});
+}
+
+
+sub get_all {
+ my $this = shift;
+ my($num, $note, $date, %res);
+
+ if ($this->unchanged) {
+ return %{$this->{cache}};
+ }
+
+ my %data = $this->_retrieve();
+
+ foreach my $num (keys %data) {
+ $res{$num}->{note} = $this->ude($data{$num}->{note});
+ $res{$num}->{date} = $this->ude($data{$num}->{date});
+ }
+
+ $this->cache(%res);
+ return %res;
+}
+
+sub import_data {
+ my ($this, $data) = @_;
+ my %res = $this->_retrieve();
+ my $pos = (scalar keys %res) + 1;
+ foreach my $num (keys %{$data}) {
+ $res{$pos}->{note} = $this->uen($data->{$num}->{note});
+ $res{$pos}->{date} = $this->uen($data->{$num}->{date});
+ $pos++;
+ }
+ $this->_store(\%res);
+}
+
+sub get_nextnum {
+ my $this = shift;
+ my($num, $te, $me, $buffer);
+
+ if ($this->unchanged) {
+ $num = 1;
+ foreach (keys %{$this->{cache}}) {
+ $num++;
+ }
+ return $num;
+ }
+
+ my %data = $this->get_all();
+ my $size = scalar keys %data;
+ $num = $size + 1;
+ return $num;
+}
+
+sub get_search {
+ my($this, $searchstring) = @_;
+ my($buffer, $num, $note, $date, %res, $t, $n, $match);
+
+ my $regex = $this->generate_search($searchstring);
+ eval $regex;
+ if ($@) {
+ print "invalid expression: \"$searchstring\"!\n";
+ return;
+ }
+ $match = 0;
+
+ if ($this->unchanged) {
+ foreach my $num (keys %{$this->{cache}}) {
+ $_ = $this->{cache}{$num}->{note};
+ eval $regex;
+ if ($match) {
+ $res{$num}->{note} = $this->{cache}{$num}->{note};
+ $res{$num}->{date} = $this->{cache}{$num}->{date}
+ }
+ $match = 0;
+ }
+ return %res;
+ }
+
+ my %data = $this->get_all();
+
+ foreach my $num(sort keys %data) {
+ $_ = $data{$num}->{note};
+ eval $regex;
+ if($match)
+ {
+ $res{$num}->{note} = $data{$num}->{note};
+ $res{$num}->{date} = $data{$num}->{data};
+ }
+ $match = 0;
+ }
+
+ return %res;
+}
+
+
+
+
+sub set_edit {
+ my($this, $num, $note, $date) = @_;
+
+ my %data = $this->_retrieve();
+
+ $data{$num} = {
+ note => $this->uen($note),
+ date => $this->uen($date)
+ };
+
+ $this->_store(\%data);
+
+ $this->changed;
+}
+
+
+sub set_new {
+ my($this, $num, $note, $date) = @_;
+ $this->set_edit($num, $note, $date);
+}
+
+
+sub set_del {
+ my($this, $num) = @_;
+ my(%data, $note, $date, $T, $setnum, $buffer, $n, $N, $t);
+
+ $setnum = 1;
+
+ %data = $this->_retrieve();
+ return "ERROR" if (! exists $data{$num});
+
+ delete $data{$num};
+
+ $this->_store(\%data);
+
+ $this->changed;
+
+ return;
+}
+
+sub set_recountnums {
+ my($this) = @_;
+ my(%orig, %data, $note, $date, $T, $setnum, $buffer, $n, $N, $t);
+
+ $setnum = 1;
+ %orig = $this->_retrieve();
+
+ foreach $N (sort {$a <=> $b} keys %orig) {
+ $data{$setnum} = {
+ note => $orig{$N}->{note},
+ date => $orig{$N}->{date}
+ };
+ $setnum++;
+ }
+
+ $this->_store(\%data);
+
+ $this->changed;
+
+ return;
+}
+
+sub uen {
+ my ($this, $raw) = @_;
+ my($crypted);
+ if($NOTEDB::crypt_supported == 1) {
+ eval {
+ $crypted = $this->{cipher}->encrypt($raw);
+ };
+ print $@;
+ }
+ else {
+ $crypted = $raw;
+ }
+ my $coded = encode_base64($crypted);
+ return $coded;
+}
+
+sub ude {
+ my ($this, $crypted) = @_;
+ my($raw);
+ if($NOTEDB::crypt_supported == 1) {
+ eval {
+ $raw = $this->{cipher}->decrypt(decode_base64($crypted));
+ };
+ }
+ else {
+ $raw = decode_base64($crypted)
+ }
+ return $raw;
+}
+
+
+
+sub _store {
+ my ($this, $data) = @_;
+ open NOTE, ">$this->{dbname}" or die "could not open $this->{dbname}: $!\n";
+ flock NOTE, LOCK_EX;
+
+ if (%{$data}) {
+ my $content = SaveConfigString($data) or die "could not serialize data: $!\n";
+ print NOTE $content;
+ }
+ else {
+ print NOTE "";
+ }
+
+ flock NOTE, LOCK_UN;
+ close NOTE;
+
+ # finally re-read the db, so that we always have the latest data
+ $this->_retrieve();
+}
+
+sub _retrieve {
+ my ($this) = @_;
+ my $file = $this->{dbname};
+ if (-s $file) {
+ if ($this->changed() || $this->{unread}) {
+ my $fh = new FileHandle "<$this->{dbname}" or die "could not open $this->{dbname}\n";
+ flock $fh, LOCK_EX;
+
+ my %data = ParseConfig(-ConfigFile => $fh) or die "could not read to database: $!\n";
+
+ flock $fh, LOCK_UN;
+ $fh->close();
+
+ $this->{unread} = 0;
+ $this->{data} = \%data;
+ return %data;
+ }
+ else {
+ return %{$this->{data}};
+ }
+ }
+ else {
+ return ();
+ }
+}
+
+
+1; # keep this!
+
+__END__
+
+=head1 NAME
+
+NOTEDB::general - module lib for accessing a notedb from perl
+
+=head1 SYNOPSIS
+
+ # include the module
+ use NOTEDB;
+
+ # create a new NOTEDB object
+ $db = new NOTEDB("text", "/home/tom/.notedb", 4096, 24);
+
+ # decide to use encryption
+ # $key is the cipher to use for encryption
+ # $method must be either Crypt::IDEA or Crypt::DES
+ # you need Crypt::CBC, Crypt::IDEA and Crypt::DES to have installed.
+ $db->use_crypt($key,$method);
+
+ # do not use encryption
+ # this is the default
+ $db->no_crypt;
+
+ # get a single note
+ ($note, $date) = $db->get_single(1);
+
+ # search for a certain note
+ %matching_notes = $db->get_search("somewhat");
+ # format of returned hash:
+ #$matching_notes{$numberofnote}->{'note' => 'something', 'date' => '23.12.2000 10:33:02'}
+
+ # get all existing notes
+ %all_notes = $db->get_all();
+ # format of returnes hash like the one from get_search above
+
+ # get the next noteid available
+ $next_num = $db->get_nextnum();
+
+ # modify a certain note
+ $db->set_edit(1, "any text", "23.12.2000 10:33:02");
+
+ # create a new note
+ $db->set_new(5, "any new text", "23.12.2000 10:33:02");
+
+ # delete a certain note
+ $db->set_del(5);
+
+ # turn on encryption. CryptMethod must be IDEA, DES or BLOWFISH
+ $db->use_crypt("passphrase", "CryptMethod");
+
+ # turn off encryption. This is the default.
+ $db->no_crypt();
+
+
+=head1 DESCRIPTION
+
+You can use this module for accessing a note database. This backend uses
+a text file for storage and Config::General for accessing the file.
+
+Currently, NOTEDB module is only used by note itself. But feel free to use it
+within your own project! Perhaps someone want to implement a webinterface to
+note...
+
+=head1 USAGE
+
+please see the section SYNOPSIS, it says it all.
+
+=head1 AUTHOR
+
+Thomas Linden .
+
+
+=cut
diff --git a/blib/lib/NOTEDB/mysql.pm b/blib/lib/NOTEDB/mysql.pm
new file mode 100644
index 0000000..f17478c
--- /dev/null
+++ b/blib/lib/NOTEDB/mysql.pm
@@ -0,0 +1,425 @@
+#
+# Perl module for note
+# mysql database backend. see docu: perldoc NOTEDB::mysql
+#
+
+
+package NOTEDB::mysql;
+
+$NOTEDB::mysql::VERSION = "1.51";
+
+use DBI;
+use strict;
+#use Data::Dumper;
+use NOTEDB;
+
+use Exporter ();
+use vars qw(@ISA @EXPORT);
+@ISA = qw(NOTEDB Exporter);
+
+
+
+
+sub new {
+ my($this, %param) = @_;
+
+ my $class = ref($this) || $this;
+ my $self = {};
+ bless($self,$class);
+
+ my $dbname = $param{dbname} || "note";
+ my $dbhost = $param{dbhost} || "localhost";
+ my $dbuser = $param{dbuser} || "";
+ my $dbpasswd = $param{dbpasswd} || "";
+ my $dbport = $param{dbport} || "";
+ my $fnum = "number";
+ my $fnote = "note";
+ my $fdate = "date";
+ my $ftopic = "topic";
+
+ my $database;
+ if ($dbport) {
+ $database = "DBI:mysql:$dbname;host=$dbhost:$dbport";
+ }
+ else {
+ $database = "DBI:mysql:$dbname;host=$dbhost";
+ }
+
+ $self->{table} = "note";
+
+ $self->{sql_getsingle} = "SELECT $fnote,$fdate,$ftopic FROM $self->{table} WHERE $fnum = ?";
+ $self->{sql_all} = "SELECT $fnum,$fnote,$fdate,$ftopic FROM $self->{table}";
+ $self->{sql_nextnum} = "SELECT max($fnum) FROM $self->{table}";
+ $self->{sql_incrnum} = "SELECT $fnum FROM $self->{table} ORDER BY $fnum";
+ $self->{sql_setnum} = "UPDATE $self->{table} SET $fnum = ? WHERE $fnum = ?";
+ $self->{sql_edit} = "UPDATE $self->{table} SET $fnote = ?, $fdate = ?, $ftopic = ? WHERE $fnum = ?";
+ $self->{sql_insertnew} = "INSERT INTO $self->{table} VALUES (?, ?, ?, ?)";
+ $self->{sql_del} = "DELETE FROM $self->{table} WHERE $fnum = ?";
+ $self->{sql_del_all} = "DELETE FROM $self->{table}";
+
+ $self->{DB} = DBI->connect($database, $dbuser, $dbpasswd) or die DBI->errstr();
+
+ return $self;
+}
+
+
+sub DESTROY
+{
+ # clean the desk!
+ my $this = shift;
+ $this->{DB}->disconnect;
+}
+
+
+sub lock {
+ my($this) = @_;
+ # LOCK the database!
+ my $lock = $this->{DB}->prepare("LOCK TABLES $this->{table} WRITE")
+ || die $this->{DB}->errstr();
+ $lock->execute() || die $this->{DB}->errstr();
+}
+
+
+sub unlock {
+ my($this) = @_;
+ my $unlock = $this->{DB}->prepare("UNLOCK TABLES") || die $this->{DB}->errstr;
+ $unlock->execute() || die $this->{DB}->errstr();
+}
+
+
+sub version {
+ my $this = shift;
+ return $this->{version};
+}
+
+
+sub get_single {
+ my($this, $num) = @_;
+
+ my($note, $date, $topic);
+ my $statement = $this->{DB}->prepare($this->{sql_getsingle}) || die $this->{DB}->errstr();
+
+ $statement->execute($num) || die $this->{DB}->errstr();
+ $statement->bind_columns(undef, \($note, $date, $topic)) || die $this->{DB}->errstr();
+
+ while($statement->fetch) {
+ $note = $this->ude($note);
+ if ($topic) {
+ $note = "$topic\n" . $note;
+ }
+ return $note, $this->ude($date);
+ }
+}
+
+
+sub get_all
+{
+ my $this = shift;
+ my($num, $note, $date, %res, $topic);
+
+ if ($this->unchanged) {
+ return %{$this->{cache}};
+ }
+
+ my $statement = $this->{DB}->prepare($this->{sql_all}) or die $this->{DB}->errstr();
+
+ $statement->execute or die $this->{DB}->errstr();
+ $statement->bind_columns(undef, \($num, $note, $date, $topic)) or die $this->{DB}->errstr();
+
+ while($statement->fetch) {
+ $res{$num}->{'note'} = $this->ude($note);
+ $res{$num}->{'date'} = $this->ude($date);
+ if ($topic) {
+ $res{$num}->{'note'} = "$topic\n" . $res{$num}->{'note'};
+ }
+ }
+
+ $this->cache(%res);
+ return %res;
+}
+
+
+sub get_nextnum
+{
+ my $this = shift;
+ my($num);
+ if ($this->unchanged) {
+ $num = 1;
+ foreach (keys %{$this->{cache}}) {
+ $num++;
+ }
+ return $num;
+ }
+
+ my $statement = $this->{DB}->prepare($this->{sql_nextnum}) || die $this->{DB}->errstr();
+
+ $statement->execute || die $this->{DB}->errstr();
+ $statement->bind_columns(undef, \($num)) || die $this->{DB}->errstr();
+
+ while($statement->fetch) {
+ return $num+1;
+ }
+}
+
+sub get_search
+{
+ my($this, $searchstring) = @_;
+ my($num, $note, $date, %res, $match, $use_cache, $topic);
+
+ my $regex = $this->generate_search($searchstring);
+ eval $regex;
+ if ($@) {
+ print "invalid expression: \"$searchstring\"!\n";
+ return;
+ }
+ $match = 0;
+
+ if ($this->unchanged) {
+ foreach my $num (keys %{$this->{cache}}) {
+ $_ = $this->{cache}{$num}->{note};
+ eval $regex;
+ if ($match) {
+ $res{$num}->{note} = $this->{cache}{$num}->{note};
+ $res{$num}->{date} = $this->{cache}{$num}->{date}
+ }
+ $match = 0;
+ }
+ return %res;
+ }
+
+ my $statement = $this->{DB}->prepare($this->{sql_all}) or die $this->{DB}->errstr();
+
+ $statement->execute or die $this->{DB}->errstr();
+ $statement->bind_columns(undef, \($num, $note, $date, $topic)) or die $this->{DB}->errstr();
+
+ while($statement->fetch) {
+ $note = $this->ude($note);
+ $date = $this->ude($date);
+ if ($topic) {
+ $note = "$topic\n" . $note;
+ }
+ $_ = $note;
+ eval $regex;
+ if($match) {
+ $res{$num}->{'note'} = $note;
+ $res{$num}->{'date'} = $date;
+ }
+ $match = 0;
+ }
+ return %res;
+}
+
+
+
+
+sub set_edit
+{
+ my($this, $num, $note, $date) = @_;
+
+ $this->lock;
+ my $statement = $this->{DB}->prepare($this->{sql_edit}) or die $this->{DB}->errstr();
+ $note =~ s/'/\'/g;
+ $note =~ s/\\/\\\\/g;
+ $statement->execute($this->uen($note), $this->uen($date), $num)
+ or die $this->{DB}->errstr();
+ $this->unlock;
+ $this->changed;
+}
+
+
+sub set_new
+{
+ my($this, $num, $note, $date) = @_;
+ $this->lock;
+ my $statement = $this->{DB}->prepare($this->{sql_insertnew}) || die $this->{DB}->errstr();
+
+ my ($topic, $note) = $this->get_topic($note);
+
+ $note =~ s/'/\'/g;
+ $note =~ s/\\/\\\\/g;
+ $topic =~ s/\\/\\\\/g;
+ $statement->execute($num, $this->uen($note), $this->uen($date), $topic) || die $this->{DB}->errstr();
+ $this->unlock;
+ $this->changed;
+}
+
+
+sub set_del
+{
+ my($this, $num) = @_;
+ my($note, $date, $T);
+
+ $this->lock;
+ ($note, $date) = $this->get_single($num);
+
+ return "ERROR" if ($date !~ /^\d/);
+
+ # delete record!
+ my $statement = $this->{DB}->prepare($this->{sql_del}) || die $this->{DB}->errstr();
+ $statement->execute($num) || die $this->{DB}->errstr();
+ $this->unlock;
+ $this->changed;
+ return;
+}
+
+
+sub set_del_all
+{
+ my($this) = @_;
+ $this->lock;
+ my $statement = $this->{DB}->prepare($this->{sql_del_all}) || die $this->{DB}->errstr();
+ $statement->execute() || die $this->{DB}->errstr();
+ $this->unlock;
+ $this->changed;
+ return;
+}
+
+sub set_recountnums {
+ my $this = shift;
+
+ $this->lock;
+
+ my(@count, $i, $num, $setnum, $pos);
+ $setnum = 1;
+ $pos=0; $i=0; @count = ();
+
+ my $statement = $this->{DB}->prepare($this->{sql_incrnum}) || die $this->{DB}->errstr();
+ $statement->execute || die $this->{DB}->errstr();
+ $statement->bind_columns(undef, \($num)) || die $this->{DB}->errstr();
+ # store real id's in an array!
+ while($statement->fetch) {
+ $count[$i] = $num;
+ $i++;
+ }
+ # now recount them!
+ my $sub_statement = $this->{DB}->prepare($this->{sql_setnum}) || die $this->{DB}->errstr();
+ for($pos=0;$pos<$i;$pos++) {
+ $setnum = $pos +1;
+ $sub_statement->execute($setnum,$count[$pos]) || die $this->{DB}->errstr();
+ }
+ $this->unlock;
+ $this->changed;
+}
+
+sub import_data {
+ my ($this, $data) = @_;
+ foreach my $num (keys %{$data}) {
+ my $pos = $this->get_nextnum();
+ $this->set_new($pos, $data->{$num}->{note}, $data->{$num}->{date});
+ }
+}
+
+sub uen
+{
+ my $this = shift;
+ my($T);
+ if($NOTEDB::crypt_supported == 1) {
+ eval {
+ $T = pack("u", $this->{cipher}->encrypt($_[0]));
+ };
+ }
+ else {
+ $T = $_[0];
+ }
+ chomp $T;
+ return $T;
+}
+
+sub ude
+{
+ my $this = shift;
+ my($T);
+ if($NOTEDB::crypt_supported == 1) {
+ eval {
+ $T = $this->{cipher}->decrypt(unpack("u",$_[0]))
+ };
+ return $T;
+ }
+ else {
+ return $_[0];
+ }
+}
+
+sub get_topic {
+ my ($this, $data) = @_;
+ if ($data =~ /^\//) {
+ my($topic, $note) = split /\n/, $data, 2;
+ return ($topic, $note);
+ }
+ else {
+ return ("", $data);
+ }
+}
+
+1; # keep this!
+
+__END__
+
+=head1 NAME
+
+NOTEDB::mysql - module lib for accessing a notedb from perl
+
+=head1 SYNOPSIS
+
+ # include the module
+ use NOTEDB;
+
+ # create a new NOTEDB object (the last 4 params are db table/field names)
+ $db = new NOTEDB("mysql","note","localhost","username","password","note","number","note","date");
+
+ # get a single note
+ ($note, $date) = $db->get_single(1);
+
+ # search for a certain note
+ %matching_notes = $db->get_search("somewhat");
+ # format of returned hash:
+ #$matching_notes{$numberofnote}->{'note' => 'something', 'date' => '23.12.2000 10:33:02'}
+
+ # get all existing notes
+ %all_notes = $db->get_all();
+ # format of returnes hash like the one from get_search above
+
+ # get the next noteid available
+ $next_num = $db->get_nextnum();
+
+ # recount all noteids starting by 1 (usefull after deleting one!)
+ $db->set_recountnums();
+
+ # modify a certain note
+ $db->set_edit(1, "any text", "23.12.2000 10:33:02");
+
+ # create a new note
+ $db->set_new(5, "any new text", "23.12.2000 10:33:02");
+
+ # delete a certain note
+ $db->set_del(5);
+
+ # turn on encryption. CryptMethod must be IDEA, DES or BLOWFISH
+ $db->use_crypt("passphrase", "CryptMethod");
+
+ # turn off encryption. This is the default.
+ $db->no_crypt();
+
+=head1 DESCRIPTION
+
+You can use this module for accessing a note database. There are currently
+two versions of this module, one version for a SQL database and one for a
+binary file (note's own database-format).
+However, both versions provides identical interfaces, which means, you do
+not need to change your code, if you want to switch to another database format.
+
+Currently, NOTEDB module is only used by note itself. But feel free to use it
+within your own project! Perhaps someone want to implement a webinterface to
+note...
+
+=head1 USAGE
+
+please see the section SYNOPSIS, it says it all.
+
+=head1 AUTHOR
+
+Thomas Linden .
+
+
+
+=cut
diff --git a/blib/lib/NOTEDB/text.pm b/blib/lib/NOTEDB/text.pm
new file mode 100644
index 0000000..b06edee
--- /dev/null
+++ b/blib/lib/NOTEDB/text.pm
@@ -0,0 +1,358 @@
+# Perl module for note
+# text database backend. see docu: perldoc NOTEDB::text
+# using Storable as backend.
+
+package NOTEDB::text;
+
+$NOTEDB::text::VERSION = "1.03";
+
+use strict;
+#use Data::Dumper;
+use File::Spec;
+use Storable qw(lock_nstore lock_retrieve);
+use MIME::Base64;
+
+use NOTEDB;
+
+use Fcntl qw(LOCK_EX LOCK_UN);
+
+use Exporter ();
+use vars qw(@ISA @EXPORT);
+@ISA = qw(NOTEDB Exporter);
+
+
+
+
+sub new {
+ my($this, %param) = @_;
+
+ my $class = ref($this) || $this;
+ my $self = {};
+ bless($self,$class);
+
+ $self->{NOTEDB} = $param{dbname} || File::Spec->catfile($ENV{HOME}, ".notedb");
+
+ if(! -e $param{dbname}) {
+ open(TT,">$param{dbname}") or die "Could not create $param{dbname}: $!\n";
+ close (TT);
+ }
+ elsif(! -w $param{dbname}) {
+ print "$param{dbname} is not writable!\n";
+ exit(1);
+ }
+
+ $self->{LOCKFILE} = $param{dbname} . "~LOCK";
+ $self->{mtime} = $self->get_stat();
+ $self->{unread} = 1;
+ $self->{data} = {};
+
+ return $self;
+}
+
+
+sub DESTROY
+{
+ # clean the desk!
+}
+
+sub version {
+ my $this = shift;
+ return $NOTEDB::text::VERSION;
+}
+
+sub get_stat {
+ my ($this) = @_;
+ my $mtime = (stat($this->{dbname}))[9];
+ return $mtime;
+}
+
+
+sub set_del_all {
+ my $this = shift;
+ unlink $this->{NOTEDB};
+ open(TT,">$this->{NOTEDB}") or die "Could not create $this->{NOTEDB}: $!\n";
+ close (TT);
+}
+
+
+sub get_single {
+ my($this, $num) = @_;
+ my($address, $note, $date, $buffer, $n, $t, $buffer, );
+
+ my %data = $this->get_all();
+
+ return ($data{$num}->{note}, $data{$num}->{date});
+}
+
+
+sub get_all {
+ my $this = shift;
+ my($num, $note, $date, %res);
+
+ if ($this->unchanged) {
+ return %{$this->{cache}};
+ }
+
+ my %data = $this->_retrieve();
+
+ foreach my $num (keys %data) {
+ $res{$num}->{note} = $this->ude($data{$num}->{note});
+ $res{$num}->{date} = $this->ude($data{$num}->{date});
+ }
+
+ $this->cache(%res);
+ return %res;
+}
+
+sub import_data {
+ my ($this, $data) = @_;
+ my %res = $this->_retrieve();
+ my $pos = (scalar keys %res) + 1;
+ foreach my $num (keys %{$data}) {
+ $res{$pos}->{note} = $this->uen($data->{$num}->{note});
+ $res{$pos}->{date} = $this->uen($data->{$num}->{date});
+ $pos++;
+ }
+ $this->_store(\%res);
+}
+
+sub get_nextnum {
+ my $this = shift;
+ my($num, $te, $me, $buffer);
+
+ if ($this->unchanged) {
+ my @numbers = sort { $a <=> $b } keys %{$this->{cache}};
+ $num = pop @numbers;
+ $num++;
+ #$num = 1;
+ #foreach (keys %{$this->{cache}}) {
+ # $num++;
+ #}
+ return $num;
+ }
+
+ my %data = $this->get_all();
+ my @numbers = sort { $a <=> $b } keys %data;
+ $num = pop @numbers;
+ $num++;
+ #my $size = scalar keys %data;
+ #$num = $size + 1;
+ return $num;
+}
+
+sub get_search {
+ my($this, $searchstring) = @_;
+ my($buffer, $num, $note, $date, %res, $t, $n, $match);
+
+ my $regex = $this->generate_search($searchstring);
+ eval $regex;
+ if ($@) {
+ print "invalid expression: \"$searchstring\"!\n";
+ return;
+ }
+ $match = 0;
+
+ if ($this->unchanged) {
+ foreach my $num (keys %{$this->{cache}}) {
+ $_ = $this->{cache}{$num}->{note};
+ eval $regex;
+ if ($match) {
+ $res{$num}->{note} = $this->{cache}{$num}->{note};
+ $res{$num}->{date} = $this->{cache}{$num}->{date}
+ }
+ $match = 0;
+ }
+ return %res;
+ }
+
+ my %data = $this->get_all();
+
+ foreach my $num(sort keys %data) {
+ $_ = $data{$num}->{note};
+ eval $regex;
+ if($match)
+ {
+ $res{$num}->{note} = $data{$num}->{note};
+ $res{$num}->{date} = $data{$num}->{data};
+ }
+ $match = 0;
+ }
+
+ return %res;
+}
+
+
+
+
+sub set_edit {
+ my($this, $num, $note, $date) = @_;
+
+ my %data = $this->_retrieve();
+
+ $data{$num} = {
+ note => $this->uen($note),
+ date => $this->uen($date)
+ };
+
+ $this->_store(\%data);
+
+ $this->changed;
+}
+
+
+sub set_new {
+ my($this, $num, $note, $date) = @_;
+ $this->set_edit($num, $note, $date);
+}
+
+
+sub set_del {
+ my($this, $num) = @_;
+ my(%data, $note, $date, $T, $setnum, $buffer, $n, $N, $t);
+
+ $setnum = 1;
+
+ %data = $this->_retrieve();
+ return "ERROR" if (! exists $data{$num});
+
+ delete $data{$num};
+
+ $this->_store(\%data);
+
+ $this->changed;
+
+ return;
+}
+
+sub set_recountnums {
+ # not required here
+ return;
+}
+
+sub uen {
+ my ($this, $raw) = @_;
+ my($crypted);
+ if($NOTEDB::crypt_supported == 1) {
+ eval {
+ $crypted = $this->{cipher}->encrypt($raw);
+ };
+ }
+ else {
+ $crypted = $raw;
+ }
+ my $coded = encode_base64($crypted);
+ return $coded;
+}
+
+sub ude {
+ my ($this, $crypted) = @_;
+ my($raw);
+ if($NOTEDB::crypt_supported == 1) {
+ eval {
+ $raw = $this->{cipher}->decrypt(decode_base64($crypted));
+ };
+ }
+ else {
+ $raw = decode_base64($crypted)
+ }
+ return $raw;
+}
+
+
+sub _store {
+ my ($this, $data) = @_;
+ lock_nstore($data, $this->{NOTEDB});
+}
+
+sub _retrieve {
+ my $this = shift;
+ if (-s $this->{NOTEDB}) {
+ if ($this->changed() || $this->{unread}) {
+ my $data = lock_retrieve($this->{NOTEDB});
+ $this->{unread} = 0;
+ $this->{data} = $data;
+ return %{$data};
+ }
+ }
+ else {
+ return ();
+ }
+}
+
+
+1; # keep this!
+
+__END__
+
+=head1 NAME
+
+NOTEDB::text - module lib for accessing a notedb from perl
+
+=head1 SYNOPSIS
+
+ # include the module
+ use NOTEDB;
+
+ # create a new NOTEDB object
+ $db = new NOTEDB("text", "/home/tom/.notedb", 4096, 24);
+
+ # decide to use encryption
+ # $key is the cipher to use for encryption
+ # $method must be either Crypt::IDEA or Crypt::DES
+ # you need Crypt::CBC, Crypt::IDEA and Crypt::DES to have installed.
+ $db->use_crypt($key,$method);
+
+ # do not use encryption
+ # this is the default
+ $db->no_crypt;
+
+ # get a single note
+ ($note, $date) = $db->get_single(1);
+
+ # search for a certain note
+ %matching_notes = $db->get_search("somewhat");
+ # format of returned hash:
+ #$matching_notes{$numberofnote}->{'note' => 'something', 'date' => '23.12.2000 10:33:02'}
+
+ # get all existing notes
+ %all_notes = $db->get_all();
+ # format of returnes hash like the one from get_search above
+
+ # get the next noteid available
+ $next_num = $db->get_nextnum();
+
+ # modify a certain note
+ $db->set_edit(1, "any text", "23.12.2000 10:33:02");
+
+ # create a new note
+ $db->set_new(5, "any new text", "23.12.2000 10:33:02");
+
+ # delete a certain note
+ $db->set_del(5);
+
+ # turn on encryption. CryptMethod must be IDEA, DES or BLOWFISH
+ $db->use_crypt("passphrase", "CryptMethod");
+
+ # turn off encryption. This is the default.
+ $db->no_crypt();
+
+
+=head1 DESCRIPTION
+
+You can use this module for accessing a note database. This backend uses
+a text file for storage and Storable for accessing the file.
+
+Currently, NOTEDB module is only used by note itself. But feel free to use it
+within your own project! Perhaps someone want to implement a webinterface to
+note...
+
+=head1 USAGE
+
+please see the section SYNOPSIS, it says it all.
+
+=head1 AUTHOR
+
+Thomas Linden .
+
+
+=cut
diff --git a/blib/lib/auto/NOTEDB/.exists b/blib/lib/auto/NOTEDB/.exists
new file mode 100644
index 0000000..e69de29
diff --git a/blib/lib/note.pod b/blib/lib/note.pod
new file mode 100644
index 0000000..a16d2a3
--- /dev/null
+++ b/blib/lib/note.pod
@@ -0,0 +1,528 @@
+# -*-perl-*-
+
+=head1 NAME
+
+note - a perl script for maintaining notes.
+
+
+=head1 SYNPOPSIS
+
+note [options] [ number [,number...]]
+
+
+=head1 DESCRIPTION
+
+B is a small console program written in perl, which allows
+you to manage notes similar to programs like "knotes" but from
+the commandline. Note can use different database-backends for
+notes-storage. It ships with a DBI-based mysql-module(which
+can also be used for other by DBI supported DBMS), another
+module, which uses a binary file for storage and a DBM module.
+There are also two modules available which uses a text file.
+Note supports since version 1.0.0 encryption(IDEA or DES)!
+
+
+=head1 OPTIONS
+
+
+=over
+
+=item I<-c, --config file>
+
+Use another config file than the default ~/.noterc.
+
+
+=item I<-l, --list [topic]>
+
+Lists all existing notes. If no topic were specified,
+it will display a list of all existing topics.
+See the section I for details about topics.
+
+=item I<-L, --longlist [topic]>
+
+The same as I<-l> but prints also the timestamp of the notes.
+
+
+=item I<-t, --topic>
+
+Prints a list of all topics as a tree.
+
+
+=item I<-T, --longtopic>
+
+Prints the topic-tree with the notes under each topic.
+
+
+=item I<-s, --search string>
+
+Searches for trough the notes database. See the section
+I for details about the search engine.
+
+
+=item I<-e, --edit number>
+
+Edit the note with the number using your default editor
+or the one you specified in the config file.
+
+
+=item I<-d, --delete number>
+
+Delete the note with the number . You can delete multiple notes
+with one command. "1-4" deletes the notes 1,2,3,4. And "1,5,7" deletes
+the specified ones.
+
+
+=item I<-D, --Dump [file | -]>
+
+Dumps all notes to the textfile . If is a "-" it will
+be printed out to standard output (STDOUT).
+
+
+=item I<-I, --Import file | ->
+
+Imports a previously dumped textfile into the
+note database. Data will be appended by default.
+You can also specify a dash I instead of a ,
+which causes note, silently to read in a dump from STDIN.
+
+
+=item I<-o, --overwrite>
+
+Only suitable for use with --Import. Overwrites an
+existing notedb. Use with care.
+
+
+=item I<-r, --raw>
+
+Raw mode, output will not be formatted. Works not in interactive
+mode, only on cmd-line for list and display. That means, no colors
+will be used and no lines or titles.
+
+
+=item I<-i, --interactive>
+
+Start note in interactive mode. See the section I
+for details on this mode.
+
+
+=item I<--encrypt cleartext>
+
+Encrypt the given clear text string. You would need that if you want to
+store the mysql password not in cleartext in the config(if you are using
+the mysql backend!).
+
+
+=item I<-h, --help>
+
+Display this help screen.
+
+
+=item I<-v, --version>
+
+Display the version number.
+
+
+=item B<->
+
+If you run note just with one dash: B, then it will read in a new
+note from STDIN until EOF. This makes it possible to pipe text into a new note, i.e.:
+
+ cat sometextfile | note -
+
+
+=back
+
+
+
+
+=head1 USAGE
+
+=head2 GENERAL USAGE
+
+If you don't know, how to run note, try "note -h" first.
+It will tell you all available commandline options.
+
+To create a new note, simply run "note". You can enter
+the note (the length is by default limited to 4096 bytes,
+which you can change from your config file if you are using
+the binary backend, otherwise there is no limitation).
+End by typing a . on a line itself. note will tell you the
+number of the note.
+
+If you want to view the note, type "note 1", if the notenumber
+was 1.
+
+If you want to get an overview of all notes, type "note -l".
+You will get a list of all notes, containing the number,
+the first line and the creation date. If topic-support is
+turned on (which is by default), then all subtopics under the
+current topic will be displayed first.
+If you want to see the timestamps, use "-L" instead of "-l".
+Read more about topics below in the section "Topics".
+You can also specify the topic which notes you want to see:
+"-l mytopic" does the trick.
+Additional, you might want to get an overview of your topic-
+structure. You can use the command "-t" in this case, which
+will display a tree-view of your topic-structure. You can
+use the command "-T" if you want to see the notes under each
+topic too. "-T" will also show the number of each note.
+
+To edit a certain note, type "note -e 1". It will invoke your
+editor (vi or pico). You can edit it, after saving, note
+will store the changed note to the database.
+
+Of course you can drop a certain note: "note -d 1" deletes
+note number 1. If a note in the middle or the beginning of
+the database will be deleted, note will recount the other
+existent notes. For example there are 3 notes, number 1, 2
+and 3. If you delete number 2, then number 3 will become
+number 2.
+You can also make use of the extended delete-syntax:
+To delete note 1 and 2, use "-d 1,2"
+To delete note 1,2 and 3, use "-d 1-3".
+
+
+
+=head2 SEARCHING
+
+If you cannot remember, which note you are looking for, you
+can use the search capability of note: "note -s ".
+note will search the whole note database case insensitive for
+an occurence of this string and tell you the number and first-
+line it has.
+
+You can extend the searchstring using B, B ( and ) and
+shell-like wildcards:
+
+ $ note -s "moses AND lenin"
+
+or:
+
+ $ note -s "(mike OR arnold) AND (jackson OR schwarzenegger)"
+
+If note finds a note, which first line is a topic, then it will
+display it's second line.
+
+These rules apply for the interactive search too.
+
+You need to know, that note searches for the expression in every
+note. In other words, "moses AND lenin" searches for an occurence
+of "moses" and "lenin" in ONE note. Or, if you are looking for
+"mike OR daniel", then it searches for an occurence of "mike" or
+daniel" in ONE note. Thus a note with the text "mike oldfield" will
+match that search.
+
+
+=head2 TOPICS
+
+If topic-support is turned on (which is by default), the various
+notes are sorted under various topics. There is no special database
+field for the topic. Instead the topic will be stored right in the
+note.
+If the first line of your note contains some text bordered by slashes
+(or whatever you prefer, set "TopicSeparator" in your config! default
+is slash), then note will consider it as the topic of this certain
+note. For examle:
+
+ B
+
+If you are using topics, no data after the topic is allowed, if there
+is any text, note will consider it as a subtopic! Therefore, don't for-
+get to put a newline after the topic-line.
+
+The list-command will only show you notes under this topic. If you
+create a new note, it will automagically inserted under the current
+topic (note will prepend the string "/topicname/" to the text of your
+note).
+
+You can create at any time from any point a new topic. Just create a new
+note and type the name of the new topic bordered by slashes (or
+TopicSeparator) at the first line of this note. After saving, there
+will be available a new topic with one note in it.
+
+You can create as many subtopics as you like, the format is similar to
+a filesystem-path. An example, say, you want to create such a
+structure:
+
+ (root - top level)
+ |
+ |----test
+ | |----subtopic
+ | | |--note 1
+ | | |--note 2
+ | |
+ | |--note 4
+ |
+ |--note 3
+
+Then you may create those 4 new notes:
+
+ --- snip ---
+ /test/subtopic/
+ note 1
+ --- snip ---
+ /test/subtopic/
+ note 2
+ --- snip ---
+ note 3
+ --- snip ---
+ /test/
+ note 4
+ --- snip ---
+
+I hope, you got the point ;-)
+
+If a note does not contain the "magic" /topic/ construction on the first
+line, it will be listed under the "root" of note, that is the point
+you are at the startup of note.
+
+You can subsequently move a note without a topic to a certain topic.
+Simply edit it and insert at the first line the above mentioned
+construction.
+
+Note: Please don't forget the prepending and appending a slash of a
+topic. You will get strange results without it!
+
+
+
+
+=head2 INTERACTIVE MODE
+
+If you start note with the commandline flag B<-i>, then it starts
+with an interactive interface.
+It will start with a listing under the default top-topic ("/").
+You can enter the name of a topic to change to that topic. This works
+similar to a filesystem structure. The current topic will be
+displayed on the top of the screen.
+
+The following commands are available:
+
+=over
+
+=item B
+
+This command lists all notes with a timestamp. If you specify a topic, it
+will only list the notes under this topic. If you are under a certain subtopic,
+then it will only display the notes under this topic.
+
+=item B
+
+This commands behaves similar to B but it does not display the timestamp.
+You can achieve the same result by simply pressing enter at any time.
+
+
+=item B
+
+You can create a new note by simply pressing B or B. You favorite
+editor will be started and you can enter your note text. If you are already
+under a topic then this new note will automatically go to this topic.
+note adds an aditional line to the top of the note with the topic. But
+you can of course specify your own topic.
+
+Note will tell you which number it has assigned to the newly created note.
+
+=item B
+
+By entering B or B and a note-number you can edit an existing note
+using your favorite editor. This way you can also move an existing note
+from one topic to another one by editing the first line of the note.
+
+
+=item B
+
+B or B deletes one or more existing note(s). It requires a note number
+or a set of note numbers. 1-5 and 1,7,9 are possible values.
+After one or more notes has been deleted note will recount all remaining notes.
+Say if you delete 1 and 2, then 3 will become 1, 4 will become 5 and so forth.
+
+
+=item B
+
+You can search for the occurence of a text in your notes-database with the
+command B or B. If you omit an expression note will ask you for one.
+
+If your search criteria matches on exactly one entry, note will display
+that note entry instead of displaying its number.
+
+=item B
+
+This prints a tree-view of your topic-structure. B displays the tree with
+notes, B displays just the topics without notes.
+
+
+=item B
+
+Change the actual topic under which you are. This works identical like just
+entering the topic but it has some advantages. You can enter B if
+you want to go one level up in the topic-structure. And you can enter B
+to go to the top of the structure. You can always leave out the 'cd' keyword too.
+
+Additional it is possible to enter a note-number instead of a topic name.
+For this feature to be active you need to set the config option B
+to B<1> or B. If you use a number and the note with this number is
+under a certain topic then you will "cd" to this topic. This allows you
+to do kind of jumps over multiple levels of topics.
+
+If is possible to abbreviate a topic. This works only if the abbreviation
+matches on one single topic. If it matches more than one topic then the
+available ones will be suggested.
+
+=item B or h>
+
+Display a short help screen.
+
+
+=item B
+
+Quit note.
+
+=back
+
+
+
+
+
+=head2 BACKUP
+
+You can also dump the contents of your note-database into a
+ASCII-textfile(I<-D>). You can use this file later to import it into
+your note-database(-I). This is usefull, if you want quickly trans-
+fer your notes from one host to another (i.e. you could mail
+your note-dump form your office to home and import it there
+for further use).
+
+The dumps from the two versions of note are in the same format.
+Using dumps it is also possible to reinitialize your database. You
+can use the "-o" switch whcih causes note to overwrite your existing
+database. This is very handy if you changed heavily your config. And
+it is required, if you changed: encryption, db-driver, (binary-format)
+and the password. You can use the following command for reinitializing:
+
+ $ note -D - | note -o -I -
+
+What the hell, does this do?! Step by step:
+
+=over
+
+=item *
+
+B creates a note-database dump and prints it out
+to stantdard output.
+
+=item *
+
+B<|> this is the shell's pipe command. It takes the output
+of the left program and gives it to the right program as
+standard input.
+
+=item *
+
+B imports a note-database dump from standard
+input and overwrites an existing database.
+
+=back
+
+Before you use the B<-o> switch, I consider you to make a backup!
+
+
+
+
+
+=head2 FORMATING
+
+Another very nice feature is the possibility to format the note-text
+(as much as shell allows it). First, you can use the note-internal
+"magic-strings" for colorizing. Those strings looks much like HTML:
+"here is a green line of text no more green."
+As you see, the beginning of another color starts with a tag(kinda) of
+the color and ends with an end tag .
+
+The following colors are available:
+black, red, green, yellow, blue, magenta, cyan and white.
+
+Beside colorizing text, you can also create bold or underlined text! If
+you decide to use this (additional) feature, you need to set the
+Config-Option "FormatText" to 1 which turns it on.
+Usage is very straightforward, if a word (a word is defined as some
+text with at least one space surrounded) is between a magic mark-
+character. Here are the available things, you can do:
+
+ bold: **word**
+ underlined: __word__
+ inverse: {{word}}
+ hidden: //word//
+
+The text will be formatted using the actually note-color.
+
+The hidden formatting will use blue forground and blue background
+to hide a string from the terminal, which is usefull for passwords.
+
+If you set "FormatText" to I then the formatting can be
+done this way instead:
+
+ bold: *word*
+ underlined: _word_
+ inverse: {word}
+ hidden: /word/
+
+=head1 ENCRYPTION
+
+You can turn on encryption from the config file.
+Simply set UseEncryption to 1. Please note, that you need
+to decide, if you want to use encryption before the first use
+of note! If have already a note database and want to "migrate"
+to encryption, I suggest you to follow the directions in the
+file UPGRADE!
+
+You can choose from different encryption algorythms. The default
+is IDEA, but DES or BLOWFISH are also possible. You need to have
+installed the following additional perl-modules on your system:
+MD5
+Crypt::IDEA
+Crypt::DES
+Crypt::CBC
+
+After turning on encryption, note will ask you for a passphrase
+everytime it runs! It will *not* store this passphrase!
+So, don't forget it! Be careful!
+
+
+
+
+=head1 CONFIGURATION
+
+You can use a configuration file with note but it is not required.
+Note will use default values if there is no config.
+
+The default config file is B<~/.noterc>. You may specify another
+one with the commandline flag I<--config>.
+
+Comments start with #, empty lines will be ignored.
+
+To turn on an option, set it to: B<1>, B or B.
+
+To turn off an option, set it to: B<0>, B or B.
+
+An option consists of an atribute-value pair separated
+by minimum one space (more spaces and/or tabs are allowed)
+and an optional equal sign in between.
+
+Variable names are case in-sensitive.
+
+For a detailed explanation of each possible parameter take a look
+at the supplied sample configuration file in B.
+
+
+
+
+
+=head1 AUTHOR
+
+Thomas Linden
+
+
+=head1 VERSION
+
+1.3.1 (12/01/2005)
+
+=cut
diff --git a/blib/man3/.exists b/blib/man3/.exists
new file mode 100644
index 0000000..e69de29
diff --git a/blib/man3/NOTEDB::binary.3pm b/blib/man3/NOTEDB::binary.3pm
new file mode 100644
index 0000000..f728e94
--- /dev/null
+++ b/blib/man3/NOTEDB::binary.3pm
@@ -0,0 +1,224 @@
+.\" Automatically generated by Pod::Man v1.37, Pod::Parser v1.14
+.\"
+.\" Standard preamble:
+.\" ========================================================================
+.de Sh \" Subsection heading
+.br
+.if t .Sp
+.ne 5
+.PP
+\fB\\$1\fR
+.PP
+..
+.de Sp \" Vertical space (when we can't use .PP)
+.if t .sp .5v
+.if n .sp
+..
+.de Vb \" Begin verbatim text
+.ft CW
+.nf
+.ne \\$1
+..
+.de Ve \" End verbatim text
+.ft R
+.fi
+..
+.\" Set up some character translations and predefined strings. \*(-- will
+.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
+.\" double quote, and \*(R" will give a right double quote. | will give a
+.\" real vertical bar. \*(C+ will give a nicer C++. Capital omega is used to
+.\" do unbreakable dashes and therefore won't be available. \*(C` and \*(C'
+.\" expand to `' in nroff, nothing in troff, for use with C<>.
+.tr \(*W-|\(bv\*(Tr
+.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
+.ie n \{\
+. ds -- \(*W-
+. ds PI pi
+. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
+. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
+. ds L" ""
+. ds R" ""
+. ds C` ""
+. ds C' ""
+'br\}
+.el\{\
+. ds -- \|\(em\|
+. ds PI \(*p
+. ds L" ``
+. ds R" ''
+'br\}
+.\"
+.\" If the F register is turned on, we'll generate index entries on stderr for
+.\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index
+.\" entries marked with X<> in POD. Of course, you'll have to process the
+.\" output yourself in some meaningful fashion.
+.if \nF \{\
+. de IX
+. tm Index:\\$1\t\\n%\t"\\$2"
+..
+. nr % 0
+. rr F
+.\}
+.\"
+.\" For nroff, turn off justification. Always turn off hyphenation; it makes
+.\" way too many mistakes in technical documents.
+.hy 0
+.if n .na
+.\"
+.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
+.\" Fear. Run. Save yourself. No user-serviceable parts.
+. \" fudge factors for nroff and troff
+.if n \{\
+. ds #H 0
+. ds #V .8m
+. ds #F .3m
+. ds #[ \f1
+. ds #] \fP
+.\}
+.if t \{\
+. ds #H ((1u-(\\\\n(.fu%2u))*.13m)
+. ds #V .6m
+. ds #F 0
+. ds #[ \&
+. ds #] \&
+.\}
+. \" simple accents for nroff and troff
+.if n \{\
+. ds ' \&
+. ds ` \&
+. ds ^ \&
+. ds , \&
+. ds ~ ~
+. ds /
+.\}
+.if t \{\
+. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
+. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
+. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
+. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
+. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
+. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
+.\}
+. \" troff and (daisy-wheel) nroff accents
+.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
+.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
+.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
+.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
+.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
+.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
+.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
+.ds ae a\h'-(\w'a'u*4/10)'e
+.ds Ae A\h'-(\w'A'u*4/10)'E
+. \" corrections for vroff
+.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
+.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
+. \" for low resolution devices (crt and lpr)
+.if \n(.H>23 .if \n(.V>19 \
+\{\
+. ds : e
+. ds 8 ss
+. ds o a
+. ds d- d\h'-1'\(ga
+. ds D- D\h'-1'\(hy
+. ds th \o'bp'
+. ds Th \o'LP'
+. ds ae ae
+. ds Ae AE
+.\}
+.rm #[ #] #H #V #F C
+.\" ========================================================================
+.\"
+.IX Title "NOTEDB::binary 3pm"
+.TH NOTEDB::binary 3pm "2005-10-25" "perl v5.8.4" "User Contributed Perl Documentation"
+.SH "NAME"
+NOTEDB::binary \- module lib for accessing a notedb from perl
+.SH "SYNOPSIS"
+.IX Header "SYNOPSIS"
+.Vb 2
+\& # include the module
+\& use NOTEDB;
+.Ve
+.PP
+.Vb 2
+\& # create a new NOTEDB object
+\& $db = new NOTEDB("binary", "/home/tom/.notedb", 4096, 24);
+.Ve
+.PP
+.Vb 5
+\& # decide to use encryption
+\& # $key is the cipher to use for encryption
+\& # $method must be either Crypt::IDEA or Crypt::DES
+\& # you need Crypt::CBC, Crypt::IDEA and Crypt::DES to have installed.
+\& $db\->use_crypt($key,$method);
+.Ve
+.PP
+.Vb 3
+\& # do not use encryption
+\& # this is the default
+\& $db\->no_crypt;
+.Ve
+.PP
+.Vb 2
+\& # get a single note
+\& ($note, $date) = $db\->get_single(1);
+.Ve
+.PP
+.Vb 4
+\& # search for a certain note
+\& %matching_notes = $db\->get_search("somewhat");
+\& # format of returned hash:
+\& #$matching_notes{$numberofnote}\->{'note' => 'something', 'date' => '23.12.2000 10:33:02'}
+.Ve
+.PP
+.Vb 3
+\& # get all existing notes
+\& %all_notes = $db\->get_all();
+\& # format of returnes hash like the one from get_search above
+.Ve
+.PP
+.Vb 2
+\& # get the next noteid available
+\& $next_num = $db\->get_nextnum();
+.Ve
+.PP
+.Vb 2
+\& # modify a certain note
+\& $db\->set_edit(1, "any text", "23.12.2000 10:33:02");
+.Ve
+.PP
+.Vb 2
+\& # create a new note
+\& $db\->set_new(5, "any new text", "23.12.2000 10:33:02");
+.Ve
+.PP
+.Vb 2
+\& # delete a certain note
+\& $db\->set_del(5);
+.Ve
+.PP
+.Vb 2
+\& # turn on encryption. CryptMethod must be IDEA, DES or BLOWFISH
+\& $db\->use_crypt("passphrase", "CryptMethod");
+.Ve
+.PP
+.Vb 2
+\& # turn off encryption. This is the default.
+\& $db\->no_crypt();
+.Ve
+.SH "DESCRIPTION"
+.IX Header "DESCRIPTION"
+You can use this module for accessing a note database. There are currently
+two versions of this module, one version for a \s-1SQL\s0 database and one for a
+binary file (note's own database\-format).
+However, both versions provides identical interfaces, which means, you do
+not need to change your code, if you want to switch to another database format.
+.PP
+Currently, \s-1NOTEDB\s0 module is only used by note itself. But feel free to use it
+within your own project! Perhaps someone want to implement a webinterface to
+note...
+.SH "USAGE"
+.IX Header "USAGE"
+please see the section \s-1SYNOPSIS\s0, it says it all.
+.SH "AUTHOR"
+.IX Header "AUTHOR"
+Thomas Linden .
diff --git a/blib/man3/NOTEDB::dbm.3pm b/blib/man3/NOTEDB::dbm.3pm
new file mode 100644
index 0000000..8ea3047
--- /dev/null
+++ b/blib/man3/NOTEDB::dbm.3pm
@@ -0,0 +1,202 @@
+.\" Automatically generated by Pod::Man v1.37, Pod::Parser v1.14
+.\"
+.\" Standard preamble:
+.\" ========================================================================
+.de Sh \" Subsection heading
+.br
+.if t .Sp
+.ne 5
+.PP
+\fB\\$1\fR
+.PP
+..
+.de Sp \" Vertical space (when we can't use .PP)
+.if t .sp .5v
+.if n .sp
+..
+.de Vb \" Begin verbatim text
+.ft CW
+.nf
+.ne \\$1
+..
+.de Ve \" End verbatim text
+.ft R
+.fi
+..
+.\" Set up some character translations and predefined strings. \*(-- will
+.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
+.\" double quote, and \*(R" will give a right double quote. | will give a
+.\" real vertical bar. \*(C+ will give a nicer C++. Capital omega is used to
+.\" do unbreakable dashes and therefore won't be available. \*(C` and \*(C'
+.\" expand to `' in nroff, nothing in troff, for use with C<>.
+.tr \(*W-|\(bv\*(Tr
+.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
+.ie n \{\
+. ds -- \(*W-
+. ds PI pi
+. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
+. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
+. ds L" ""
+. ds R" ""
+. ds C` ""
+. ds C' ""
+'br\}
+.el\{\
+. ds -- \|\(em\|
+. ds PI \(*p
+. ds L" ``
+. ds R" ''
+'br\}
+.\"
+.\" If the F register is turned on, we'll generate index entries on stderr for
+.\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index
+.\" entries marked with X<> in POD. Of course, you'll have to process the
+.\" output yourself in some meaningful fashion.
+.if \nF \{\
+. de IX
+. tm Index:\\$1\t\\n%\t"\\$2"
+..
+. nr % 0
+. rr F
+.\}
+.\"
+.\" For nroff, turn off justification. Always turn off hyphenation; it makes
+.\" way too many mistakes in technical documents.
+.hy 0
+.if n .na
+.\"
+.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
+.\" Fear. Run. Save yourself. No user-serviceable parts.
+. \" fudge factors for nroff and troff
+.if n \{\
+. ds #H 0
+. ds #V .8m
+. ds #F .3m
+. ds #[ \f1
+. ds #] \fP
+.\}
+.if t \{\
+. ds #H ((1u-(\\\\n(.fu%2u))*.13m)
+. ds #V .6m
+. ds #F 0
+. ds #[ \&
+. ds #] \&
+.\}
+. \" simple accents for nroff and troff
+.if n \{\
+. ds ' \&
+. ds ` \&
+. ds ^ \&
+. ds , \&
+. ds ~ ~
+. ds /
+.\}
+.if t \{\
+. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
+. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
+. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
+. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
+. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
+. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
+.\}
+. \" troff and (daisy-wheel) nroff accents
+.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
+.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
+.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
+.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
+.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
+.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
+.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
+.ds ae a\h'-(\w'a'u*4/10)'e
+.ds Ae A\h'-(\w'A'u*4/10)'E
+. \" corrections for vroff
+.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
+.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
+. \" for low resolution devices (crt and lpr)
+.if \n(.H>23 .if \n(.V>19 \
+\{\
+. ds : e
+. ds 8 ss
+. ds o a
+. ds d- d\h'-1'\(ga
+. ds D- D\h'-1'\(hy
+. ds th \o'bp'
+. ds Th \o'LP'
+. ds ae ae
+. ds Ae AE
+.\}
+.rm #[ #] #H #V #F C
+.\" ========================================================================
+.\"
+.IX Title "NOTEDB::dbm 3pm"
+.TH NOTEDB::dbm 3pm "2005-10-25" "perl v5.8.4" "User Contributed Perl Documentation"
+.SH "NAME"
+NOTEDB::dbm \- module lib for accessing a notedb from perl
+.SH "SYNOPSIS"
+.IX Header "SYNOPSIS"
+.Vb 2
+\& # include the module
+\& use NOTEDB;
+.Ve
+.PP
+.Vb 2
+\& # create a new NOTEDB object (the last 4 params are db table/field names)
+\& $db = new NOTEDB("mysql","note","/home/user/.notedb/");
+.Ve
+.PP
+.Vb 2
+\& # get a single note
+\& ($note, $date) = $db\->get_single(1);
+.Ve
+.PP
+.Vb 4
+\& # search for a certain note
+\& %matching_notes = $db\->get_search("somewhat");
+\& # format of returned hash:
+\& #$matching_notes{$numberofnote}\->{'note' => 'something', 'date' => '23.12.2000 10:33:02'}
+.Ve
+.PP
+.Vb 3
+\& # get all existing notes
+\& %all_notes = $db\->get_all();
+\& # format of returnes hash like the one from get_search above
+.Ve
+.PP
+.Vb 2
+\& # get the next noteid available
+\& $next_num = $db\->get_nextnum();
+.Ve
+.PP
+.Vb 2
+\& # recount all noteids starting by 1 (usefull after deleting one!)
+\& $db\->set_recountnums();
+.Ve
+.PP
+.Vb 2
+\& # modify a certain note
+\& $db\->set_edit(1, "any text", "23.12.2000 10:33:02");
+.Ve
+.PP
+.Vb 2
+\& # create a new note
+\& $db\->set_new(5, "any new text", "23.12.2000 10:33:02");
+.Ve
+.PP
+.Vb 2
+\& # delete a certain note
+\& $db\->set_del(5);
+.Ve
+.SH "DESCRIPTION"
+.IX Header "DESCRIPTION"
+You can use this module for accessing a note database. This is the dbm module.
+It uses the \s-1DB_FILE\s0 module to store it's data and it uses \s-1DBM\s0 files for tis purpose.
+.PP
+Currently, \s-1NOTEDB\s0 module is only used by note itself. But feel free to use it
+within your own project! Perhaps someone want to implement a webinterface to
+note...
+.SH "USAGE"
+.IX Header "USAGE"
+please see the section \s-1SYNOPSIS\s0, it says it all.
+.SH "AUTHOR"
+.IX Header "AUTHOR"
+Thomas Linden .
diff --git a/blib/man3/NOTEDB::dumper.3pm b/blib/man3/NOTEDB::dumper.3pm
new file mode 100644
index 0000000..117089c
--- /dev/null
+++ b/blib/man3/NOTEDB::dumper.3pm
@@ -0,0 +1,221 @@
+.\" Automatically generated by Pod::Man v1.37, Pod::Parser v1.14
+.\"
+.\" Standard preamble:
+.\" ========================================================================
+.de Sh \" Subsection heading
+.br
+.if t .Sp
+.ne 5
+.PP
+\fB\\$1\fR
+.PP
+..
+.de Sp \" Vertical space (when we can't use .PP)
+.if t .sp .5v
+.if n .sp
+..
+.de Vb \" Begin verbatim text
+.ft CW
+.nf
+.ne \\$1
+..
+.de Ve \" End verbatim text
+.ft R
+.fi
+..
+.\" Set up some character translations and predefined strings. \*(-- will
+.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
+.\" double quote, and \*(R" will give a right double quote. | will give a
+.\" real vertical bar. \*(C+ will give a nicer C++. Capital omega is used to
+.\" do unbreakable dashes and therefore won't be available. \*(C` and \*(C'
+.\" expand to `' in nroff, nothing in troff, for use with C<>.
+.tr \(*W-|\(bv\*(Tr
+.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
+.ie n \{\
+. ds -- \(*W-
+. ds PI pi
+. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
+. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
+. ds L" ""
+. ds R" ""
+. ds C` ""
+. ds C' ""
+'br\}
+.el\{\
+. ds -- \|\(em\|
+. ds PI \(*p
+. ds L" ``
+. ds R" ''
+'br\}
+.\"
+.\" If the F register is turned on, we'll generate index entries on stderr for
+.\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index
+.\" entries marked with X<> in POD. Of course, you'll have to process the
+.\" output yourself in some meaningful fashion.
+.if \nF \{\
+. de IX
+. tm Index:\\$1\t\\n%\t"\\$2"
+..
+. nr % 0
+. rr F
+.\}
+.\"
+.\" For nroff, turn off justification. Always turn off hyphenation; it makes
+.\" way too many mistakes in technical documents.
+.hy 0
+.if n .na
+.\"
+.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
+.\" Fear. Run. Save yourself. No user-serviceable parts.
+. \" fudge factors for nroff and troff
+.if n \{\
+. ds #H 0
+. ds #V .8m
+. ds #F .3m
+. ds #[ \f1
+. ds #] \fP
+.\}
+.if t \{\
+. ds #H ((1u-(\\\\n(.fu%2u))*.13m)
+. ds #V .6m
+. ds #F 0
+. ds #[ \&
+. ds #] \&
+.\}
+. \" simple accents for nroff and troff
+.if n \{\
+. ds ' \&
+. ds ` \&
+. ds ^ \&
+. ds , \&
+. ds ~ ~
+. ds /
+.\}
+.if t \{\
+. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
+. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
+. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
+. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
+. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
+. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
+.\}
+. \" troff and (daisy-wheel) nroff accents
+.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
+.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
+.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
+.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
+.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
+.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
+.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
+.ds ae a\h'-(\w'a'u*4/10)'e
+.ds Ae A\h'-(\w'A'u*4/10)'E
+. \" corrections for vroff
+.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
+.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
+. \" for low resolution devices (crt and lpr)
+.if \n(.H>23 .if \n(.V>19 \
+\{\
+. ds : e
+. ds 8 ss
+. ds o a
+. ds d- d\h'-1'\(ga
+. ds D- D\h'-1'\(hy
+. ds th \o'bp'
+. ds Th \o'LP'
+. ds ae ae
+. ds Ae AE
+.\}
+.rm #[ #] #H #V #F C
+.\" ========================================================================
+.\"
+.IX Title "NOTEDB::dumper 3pm"
+.TH NOTEDB::dumper 3pm "2005-10-25" "perl v5.8.4" "User Contributed Perl Documentation"
+.SH "NAME"
+NOTEDB::text \- module lib for accessing a notedb from perl
+.SH "SYNOPSIS"
+.IX Header "SYNOPSIS"
+.Vb 2
+\& # include the module
+\& use NOTEDB;
+.Ve
+.PP
+.Vb 2
+\& # create a new NOTEDB object
+\& $db = new NOTEDB("text", "/home/tom/.notedb", 4096, 24);
+.Ve
+.PP
+.Vb 5
+\& # decide to use encryption
+\& # $key is the cipher to use for encryption
+\& # $method must be either Crypt::IDEA or Crypt::DES
+\& # you need Crypt::CBC, Crypt::IDEA and Crypt::DES to have installed.
+\& $db\->use_crypt($key,$method);
+.Ve
+.PP
+.Vb 3
+\& # do not use encryption
+\& # this is the default
+\& $db\->no_crypt;
+.Ve
+.PP
+.Vb 2
+\& # get a single note
+\& ($note, $date) = $db\->get_single(1);
+.Ve
+.PP
+.Vb 4
+\& # search for a certain note
+\& %matching_notes = $db\->get_search("somewhat");
+\& # format of returned hash:
+\& #$matching_notes{$numberofnote}\->{'note' => 'something', 'date' => '23.12.2000 10:33:02'}
+.Ve
+.PP
+.Vb 3
+\& # get all existing notes
+\& %all_notes = $db\->get_all();
+\& # format of returnes hash like the one from get_search above
+.Ve
+.PP
+.Vb 2
+\& # get the next noteid available
+\& $next_num = $db\->get_nextnum();
+.Ve
+.PP
+.Vb 2
+\& # modify a certain note
+\& $db\->set_edit(1, "any text", "23.12.2000 10:33:02");
+.Ve
+.PP
+.Vb 2
+\& # create a new note
+\& $db\->set_new(5, "any new text", "23.12.2000 10:33:02");
+.Ve
+.PP
+.Vb 2
+\& # delete a certain note
+\& $db\->set_del(5);
+.Ve
+.PP
+.Vb 2
+\& # turn on encryption. CryptMethod must be IDEA, DES or BLOWFISH
+\& $db\->use_crypt("passphrase", "CryptMethod");
+.Ve
+.PP
+.Vb 2
+\& # turn off encryption. This is the default.
+\& $db\->no_crypt();
+.Ve
+.SH "DESCRIPTION"
+.IX Header "DESCRIPTION"
+You can use this module for accessing a note database. This backend uses
+a text file for storage and Storable for accessing the file.
+.PP
+Currently, \s-1NOTEDB\s0 module is only used by note itself. But feel free to use it
+within your own project! Perhaps someone want to implement a webinterface to
+note...
+.SH "USAGE"
+.IX Header "USAGE"
+please see the section \s-1SYNOPSIS\s0, it says it all.
+.SH "AUTHOR"
+.IX Header "AUTHOR"
+Thomas Linden .
diff --git a/blib/man3/NOTEDB::general.3pm b/blib/man3/NOTEDB::general.3pm
new file mode 100644
index 0000000..aed44c1
--- /dev/null
+++ b/blib/man3/NOTEDB::general.3pm
@@ -0,0 +1,221 @@
+.\" Automatically generated by Pod::Man v1.37, Pod::Parser v1.14
+.\"
+.\" Standard preamble:
+.\" ========================================================================
+.de Sh \" Subsection heading
+.br
+.if t .Sp
+.ne 5
+.PP
+\fB\\$1\fR
+.PP
+..
+.de Sp \" Vertical space (when we can't use .PP)
+.if t .sp .5v
+.if n .sp
+..
+.de Vb \" Begin verbatim text
+.ft CW
+.nf
+.ne \\$1
+..
+.de Ve \" End verbatim text
+.ft R
+.fi
+..
+.\" Set up some character translations and predefined strings. \*(-- will
+.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
+.\" double quote, and \*(R" will give a right double quote. | will give a
+.\" real vertical bar. \*(C+ will give a nicer C++. Capital omega is used to
+.\" do unbreakable dashes and therefore won't be available. \*(C` and \*(C'
+.\" expand to `' in nroff, nothing in troff, for use with C<>.
+.tr \(*W-|\(bv\*(Tr
+.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
+.ie n \{\
+. ds -- \(*W-
+. ds PI pi
+. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
+. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
+. ds L" ""
+. ds R" ""
+. ds C` ""
+. ds C' ""
+'br\}
+.el\{\
+. ds -- \|\(em\|
+. ds PI \(*p
+. ds L" ``
+. ds R" ''
+'br\}
+.\"
+.\" If the F register is turned on, we'll generate index entries on stderr for
+.\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index
+.\" entries marked with X<> in POD. Of course, you'll have to process the
+.\" output yourself in some meaningful fashion.
+.if \nF \{\
+. de IX
+. tm Index:\\$1\t\\n%\t"\\$2"
+..
+. nr % 0
+. rr F
+.\}
+.\"
+.\" For nroff, turn off justification. Always turn off hyphenation; it makes
+.\" way too many mistakes in technical documents.
+.hy 0
+.if n .na
+.\"
+.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
+.\" Fear. Run. Save yourself. No user-serviceable parts.
+. \" fudge factors for nroff and troff
+.if n \{\
+. ds #H 0
+. ds #V .8m
+. ds #F .3m
+. ds #[ \f1
+. ds #] \fP
+.\}
+.if t \{\
+. ds #H ((1u-(\\\\n(.fu%2u))*.13m)
+. ds #V .6m
+. ds #F 0
+. ds #[ \&
+. ds #] \&
+.\}
+. \" simple accents for nroff and troff
+.if n \{\
+. ds ' \&
+. ds ` \&
+. ds ^ \&
+. ds , \&
+. ds ~ ~
+. ds /
+.\}
+.if t \{\
+. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
+. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
+. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
+. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
+. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
+. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
+.\}
+. \" troff and (daisy-wheel) nroff accents
+.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
+.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
+.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
+.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
+.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
+.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
+.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
+.ds ae a\h'-(\w'a'u*4/10)'e
+.ds Ae A\h'-(\w'A'u*4/10)'E
+. \" corrections for vroff
+.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
+.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
+. \" for low resolution devices (crt and lpr)
+.if \n(.H>23 .if \n(.V>19 \
+\{\
+. ds : e
+. ds 8 ss
+. ds o a
+. ds d- d\h'-1'\(ga
+. ds D- D\h'-1'\(hy
+. ds th \o'bp'
+. ds Th \o'LP'
+. ds ae ae
+. ds Ae AE
+.\}
+.rm #[ #] #H #V #F C
+.\" ========================================================================
+.\"
+.IX Title "NOTEDB::general 3pm"
+.TH NOTEDB::general 3pm "2005-10-25" "perl v5.8.4" "User Contributed Perl Documentation"
+.SH "NAME"
+NOTEDB::general \- module lib for accessing a notedb from perl
+.SH "SYNOPSIS"
+.IX Header "SYNOPSIS"
+.Vb 2
+\& # include the module
+\& use NOTEDB;
+.Ve
+.PP
+.Vb 2
+\& # create a new NOTEDB object
+\& $db = new NOTEDB("text", "/home/tom/.notedb", 4096, 24);
+.Ve
+.PP
+.Vb 5
+\& # decide to use encryption
+\& # $key is the cipher to use for encryption
+\& # $method must be either Crypt::IDEA or Crypt::DES
+\& # you need Crypt::CBC, Crypt::IDEA and Crypt::DES to have installed.
+\& $db\->use_crypt($key,$method);
+.Ve
+.PP
+.Vb 3
+\& # do not use encryption
+\& # this is the default
+\& $db\->no_crypt;
+.Ve
+.PP
+.Vb 2
+\& # get a single note
+\& ($note, $date) = $db\->get_single(1);
+.Ve
+.PP
+.Vb 4
+\& # search for a certain note
+\& %matching_notes = $db\->get_search("somewhat");
+\& # format of returned hash:
+\& #$matching_notes{$numberofnote}\->{'note' => 'something', 'date' => '23.12.2000 10:33:02'}
+.Ve
+.PP
+.Vb 3
+\& # get all existing notes
+\& %all_notes = $db\->get_all();
+\& # format of returnes hash like the one from get_search above
+.Ve
+.PP
+.Vb 2
+\& # get the next noteid available
+\& $next_num = $db\->get_nextnum();
+.Ve
+.PP
+.Vb 2
+\& # modify a certain note
+\& $db\->set_edit(1, "any text", "23.12.2000 10:33:02");
+.Ve
+.PP
+.Vb 2
+\& # create a new note
+\& $db\->set_new(5, "any new text", "23.12.2000 10:33:02");
+.Ve
+.PP
+.Vb 2
+\& # delete a certain note
+\& $db\->set_del(5);
+.Ve
+.PP
+.Vb 2
+\& # turn on encryption. CryptMethod must be IDEA, DES or BLOWFISH
+\& $db\->use_crypt("passphrase", "CryptMethod");
+.Ve
+.PP
+.Vb 2
+\& # turn off encryption. This is the default.
+\& $db\->no_crypt();
+.Ve
+.SH "DESCRIPTION"
+.IX Header "DESCRIPTION"
+You can use this module for accessing a note database. This backend uses
+a text file for storage and Config::General for accessing the file.
+.PP
+Currently, \s-1NOTEDB\s0 module is only used by note itself. But feel free to use it
+within your own project! Perhaps someone want to implement a webinterface to
+note...
+.SH "USAGE"
+.IX Header "USAGE"
+please see the section \s-1SYNOPSIS\s0, it says it all.
+.SH "AUTHOR"
+.IX Header "AUTHOR"
+Thomas Linden .
diff --git a/blib/man3/NOTEDB::mysql.3pm b/blib/man3/NOTEDB::mysql.3pm
new file mode 100644
index 0000000..3c13afb
--- /dev/null
+++ b/blib/man3/NOTEDB::mysql.3pm
@@ -0,0 +1,215 @@
+.\" Automatically generated by Pod::Man v1.37, Pod::Parser v1.14
+.\"
+.\" Standard preamble:
+.\" ========================================================================
+.de Sh \" Subsection heading
+.br
+.if t .Sp
+.ne 5
+.PP
+\fB\\$1\fR
+.PP
+..
+.de Sp \" Vertical space (when we can't use .PP)
+.if t .sp .5v
+.if n .sp
+..
+.de Vb \" Begin verbatim text
+.ft CW
+.nf
+.ne \\$1
+..
+.de Ve \" End verbatim text
+.ft R
+.fi
+..
+.\" Set up some character translations and predefined strings. \*(-- will
+.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
+.\" double quote, and \*(R" will give a right double quote. | will give a
+.\" real vertical bar. \*(C+ will give a nicer C++. Capital omega is used to
+.\" do unbreakable dashes and therefore won't be available. \*(C` and \*(C'
+.\" expand to `' in nroff, nothing in troff, for use with C<>.
+.tr \(*W-|\(bv\*(Tr
+.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
+.ie n \{\
+. ds -- \(*W-
+. ds PI pi
+. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
+. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
+. ds L" ""
+. ds R" ""
+. ds C` ""
+. ds C' ""
+'br\}
+.el\{\
+. ds -- \|\(em\|
+. ds PI \(*p
+. ds L" ``
+. ds R" ''
+'br\}
+.\"
+.\" If the F register is turned on, we'll generate index entries on stderr for
+.\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index
+.\" entries marked with X<> in POD. Of course, you'll have to process the
+.\" output yourself in some meaningful fashion.
+.if \nF \{\
+. de IX
+. tm Index:\\$1\t\\n%\t"\\$2"
+..
+. nr % 0
+. rr F
+.\}
+.\"
+.\" For nroff, turn off justification. Always turn off hyphenation; it makes
+.\" way too many mistakes in technical documents.
+.hy 0
+.if n .na
+.\"
+.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
+.\" Fear. Run. Save yourself. No user-serviceable parts.
+. \" fudge factors for nroff and troff
+.if n \{\
+. ds #H 0
+. ds #V .8m
+. ds #F .3m
+. ds #[ \f1
+. ds #] \fP
+.\}
+.if t \{\
+. ds #H ((1u-(\\\\n(.fu%2u))*.13m)
+. ds #V .6m
+. ds #F 0
+. ds #[ \&
+. ds #] \&
+.\}
+. \" simple accents for nroff and troff
+.if n \{\
+. ds ' \&
+. ds ` \&
+. ds ^ \&
+. ds , \&
+. ds ~ ~
+. ds /
+.\}
+.if t \{\
+. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
+. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
+. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
+. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
+. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
+. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
+.\}
+. \" troff and (daisy-wheel) nroff accents
+.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
+.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
+.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
+.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
+.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
+.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
+.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
+.ds ae a\h'-(\w'a'u*4/10)'e
+.ds Ae A\h'-(\w'A'u*4/10)'E
+. \" corrections for vroff
+.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
+.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
+. \" for low resolution devices (crt and lpr)
+.if \n(.H>23 .if \n(.V>19 \
+\{\
+. ds : e
+. ds 8 ss
+. ds o a
+. ds d- d\h'-1'\(ga
+. ds D- D\h'-1'\(hy
+. ds th \o'bp'
+. ds Th \o'LP'
+. ds ae ae
+. ds Ae AE
+.\}
+.rm #[ #] #H #V #F C
+.\" ========================================================================
+.\"
+.IX Title "NOTEDB::mysql 3pm"
+.TH NOTEDB::mysql 3pm "2005-10-25" "perl v5.8.4" "User Contributed Perl Documentation"
+.SH "NAME"
+NOTEDB::mysql \- module lib for accessing a notedb from perl
+.SH "SYNOPSIS"
+.IX Header "SYNOPSIS"
+.Vb 2
+\& # include the module
+\& use NOTEDB;
+.Ve
+.PP
+.Vb 2
+\& # create a new NOTEDB object (the last 4 params are db table/field names)
+\& $db = new NOTEDB("mysql","note","localhost","username","password","note","number","note","date");
+.Ve
+.PP
+.Vb 2
+\& # get a single note
+\& ($note, $date) = $db\->get_single(1);
+.Ve
+.PP
+.Vb 4
+\& # search for a certain note
+\& %matching_notes = $db\->get_search("somewhat");
+\& # format of returned hash:
+\& #$matching_notes{$numberofnote}\->{'note' => 'something', 'date' => '23.12.2000 10:33:02'}
+.Ve
+.PP
+.Vb 3
+\& # get all existing notes
+\& %all_notes = $db\->get_all();
+\& # format of returnes hash like the one from get_search above
+.Ve
+.PP
+.Vb 2
+\& # get the next noteid available
+\& $next_num = $db\->get_nextnum();
+.Ve
+.PP
+.Vb 2
+\& # recount all noteids starting by 1 (usefull after deleting one!)
+\& $db\->set_recountnums();
+.Ve
+.PP
+.Vb 2
+\& # modify a certain note
+\& $db\->set_edit(1, "any text", "23.12.2000 10:33:02");
+.Ve
+.PP
+.Vb 2
+\& # create a new note
+\& $db\->set_new(5, "any new text", "23.12.2000 10:33:02");
+.Ve
+.PP
+.Vb 2
+\& # delete a certain note
+\& $db\->set_del(5);
+.Ve
+.PP
+.Vb 2
+\& # turn on encryption. CryptMethod must be IDEA, DES or BLOWFISH
+\& $db\->use_crypt("passphrase", "CryptMethod");
+.Ve
+.PP
+.Vb 2
+\& # turn off encryption. This is the default.
+\& $db\->no_crypt();
+.Ve
+.SH "DESCRIPTION"
+.IX Header "DESCRIPTION"
+You can use this module for accessing a note database. There are currently
+two versions of this module, one version for a \s-1SQL\s0 database and one for a
+binary file (note's own database\-format).
+However, both versions provides identical interfaces, which means, you do
+not need to change your code, if you want to switch to another database format.
+.PP
+Currently, \s-1NOTEDB\s0 module is only used by note itself. But feel free to use it
+within your own project! Perhaps someone want to implement a webinterface to
+note...
+.SH "USAGE"
+.IX Header "USAGE"
+please see the section \s-1SYNOPSIS\s0, it says it all.
+.SH "AUTHOR"
+.IX Header "AUTHOR"
+Thomas Linden .
diff --git a/blib/man3/NOTEDB::text.3pm b/blib/man3/NOTEDB::text.3pm
new file mode 100644
index 0000000..b1168b1
--- /dev/null
+++ b/blib/man3/NOTEDB::text.3pm
@@ -0,0 +1,221 @@
+.\" Automatically generated by Pod::Man v1.37, Pod::Parser v1.14
+.\"
+.\" Standard preamble:
+.\" ========================================================================
+.de Sh \" Subsection heading
+.br
+.if t .Sp
+.ne 5
+.PP
+\fB\\$1\fR
+.PP
+..
+.de Sp \" Vertical space (when we can't use .PP)
+.if t .sp .5v
+.if n .sp
+..
+.de Vb \" Begin verbatim text
+.ft CW
+.nf
+.ne \\$1
+..
+.de Ve \" End verbatim text
+.ft R
+.fi
+..
+.\" Set up some character translations and predefined strings. \*(-- will
+.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
+.\" double quote, and \*(R" will give a right double quote. | will give a
+.\" real vertical bar. \*(C+ will give a nicer C++. Capital omega is used to
+.\" do unbreakable dashes and therefore won't be available. \*(C` and \*(C'
+.\" expand to `' in nroff, nothing in troff, for use with C<>.
+.tr \(*W-|\(bv\*(Tr
+.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
+.ie n \{\
+. ds -- \(*W-
+. ds PI pi
+. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
+. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
+. ds L" ""
+. ds R" ""
+. ds C` ""
+. ds C' ""
+'br\}
+.el\{\
+. ds -- \|\(em\|
+. ds PI \(*p
+. ds L" ``
+. ds R" ''
+'br\}
+.\"
+.\" If the F register is turned on, we'll generate index entries on stderr for
+.\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index
+.\" entries marked with X<> in POD. Of course, you'll have to process the
+.\" output yourself in some meaningful fashion.
+.if \nF \{\
+. de IX
+. tm Index:\\$1\t\\n%\t"\\$2"
+..
+. nr % 0
+. rr F
+.\}
+.\"
+.\" For nroff, turn off justification. Always turn off hyphenation; it makes
+.\" way too many mistakes in technical documents.
+.hy 0
+.if n .na
+.\"
+.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
+.\" Fear. Run. Save yourself. No user-serviceable parts.
+. \" fudge factors for nroff and troff
+.if n \{\
+. ds #H 0
+. ds #V .8m
+. ds #F .3m
+. ds #[ \f1
+. ds #] \fP
+.\}
+.if t \{\
+. ds #H ((1u-(\\\\n(.fu%2u))*.13m)
+. ds #V .6m
+. ds #F 0
+. ds #[ \&
+. ds #] \&
+.\}
+. \" simple accents for nroff and troff
+.if n \{\
+. ds ' \&
+. ds ` \&
+. ds ^ \&
+. ds , \&
+. ds ~ ~
+. ds /
+.\}
+.if t \{\
+. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
+. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
+. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
+. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
+. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
+. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
+.\}
+. \" troff and (daisy-wheel) nroff accents
+.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
+.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
+.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
+.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
+.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
+.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
+.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
+.ds ae a\h'-(\w'a'u*4/10)'e
+.ds Ae A\h'-(\w'A'u*4/10)'E
+. \" corrections for vroff
+.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
+.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
+. \" for low resolution devices (crt and lpr)
+.if \n(.H>23 .if \n(.V>19 \
+\{\
+. ds : e
+. ds 8 ss
+. ds o a
+. ds d- d\h'-1'\(ga
+. ds D- D\h'-1'\(hy
+. ds th \o'bp'
+. ds Th \o'LP'
+. ds ae ae
+. ds Ae AE
+.\}
+.rm #[ #] #H #V #F C
+.\" ========================================================================
+.\"
+.IX Title "NOTEDB::text 3pm"
+.TH NOTEDB::text 3pm "2005-10-25" "perl v5.8.4" "User Contributed Perl Documentation"
+.SH "NAME"
+NOTEDB::text \- module lib for accessing a notedb from perl
+.SH "SYNOPSIS"
+.IX Header "SYNOPSIS"
+.Vb 2
+\& # include the module
+\& use NOTEDB;
+.Ve
+.PP
+.Vb 2
+\& # create a new NOTEDB object
+\& $db = new NOTEDB("text", "/home/tom/.notedb", 4096, 24);
+.Ve
+.PP
+.Vb 5
+\& # decide to use encryption
+\& # $key is the cipher to use for encryption
+\& # $method must be either Crypt::IDEA or Crypt::DES
+\& # you need Crypt::CBC, Crypt::IDEA and Crypt::DES to have installed.
+\& $db\->use_crypt($key,$method);
+.Ve
+.PP
+.Vb 3
+\& # do not use encryption
+\& # this is the default
+\& $db\->no_crypt;
+.Ve
+.PP
+.Vb 2
+\& # get a single note
+\& ($note, $date) = $db\->get_single(1);
+.Ve
+.PP
+.Vb 4
+\& # search for a certain note
+\& %matching_notes = $db\->get_search("somewhat");
+\& # format of returned hash:
+\& #$matching_notes{$numberofnote}\->{'note' => 'something', 'date' => '23.12.2000 10:33:02'}
+.Ve
+.PP
+.Vb 3
+\& # get all existing notes
+\& %all_notes = $db\->get_all();
+\& # format of returnes hash like the one from get_search above
+.Ve
+.PP
+.Vb 2
+\& # get the next noteid available
+\& $next_num = $db\->get_nextnum();
+.Ve
+.PP
+.Vb 2
+\& # modify a certain note
+\& $db\->set_edit(1, "any text", "23.12.2000 10:33:02");
+.Ve
+.PP
+.Vb 2
+\& # create a new note
+\& $db\->set_new(5, "any new text", "23.12.2000 10:33:02");
+.Ve
+.PP
+.Vb 2
+\& # delete a certain note
+\& $db\->set_del(5);
+.Ve
+.PP
+.Vb 2
+\& # turn on encryption. CryptMethod must be IDEA, DES or BLOWFISH
+\& $db\->use_crypt("passphrase", "CryptMethod");
+.Ve
+.PP
+.Vb 2
+\& # turn off encryption. This is the default.
+\& $db\->no_crypt();
+.Ve
+.SH "DESCRIPTION"
+.IX Header "DESCRIPTION"
+You can use this module for accessing a note database. This backend uses
+a text file for storage and Storable for accessing the file.
+.PP
+Currently, \s-1NOTEDB\s0 module is only used by note itself. But feel free to use it
+within your own project! Perhaps someone want to implement a webinterface to
+note...
+.SH "USAGE"
+.IX Header "USAGE"
+please see the section \s-1SYNOPSIS\s0, it says it all.
+.SH "AUTHOR"
+.IX Header "AUTHOR"
+Thomas Linden .
diff --git a/blib/man3/note.3pm b/blib/man3/note.3pm
new file mode 100644
index 0000000..d28a460
--- /dev/null
+++ b/blib/man3/note.3pm
@@ -0,0 +1,566 @@
+.\" Automatically generated by Pod::Man v1.37, Pod::Parser v1.14
+.\"
+.\" Standard preamble:
+.\" ========================================================================
+.de Sh \" Subsection heading
+.br
+.if t .Sp
+.ne 5
+.PP
+\fB\\$1\fR
+.PP
+..
+.de Sp \" Vertical space (when we can't use .PP)
+.if t .sp .5v
+.if n .sp
+..
+.de Vb \" Begin verbatim text
+.ft CW
+.nf
+.ne \\$1
+..
+.de Ve \" End verbatim text
+.ft R
+.fi
+..
+.\" Set up some character translations and predefined strings. \*(-- will
+.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
+.\" double quote, and \*(R" will give a right double quote. | will give a
+.\" real vertical bar. \*(C+ will give a nicer C++. Capital omega is used to
+.\" do unbreakable dashes and therefore won't be available. \*(C` and \*(C'
+.\" expand to `' in nroff, nothing in troff, for use with C<>.
+.tr \(*W-|\(bv\*(Tr
+.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
+.ie n \{\
+. ds -- \(*W-
+. ds PI pi
+. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
+. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
+. ds L" ""
+. ds R" ""
+. ds C` ""
+. ds C' ""
+'br\}
+.el\{\
+. ds -- \|\(em\|
+. ds PI \(*p
+. ds L" ``
+. ds R" ''
+'br\}
+.\"
+.\" If the F register is turned on, we'll generate index entries on stderr for
+.\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index
+.\" entries marked with X<> in POD. Of course, you'll have to process the
+.\" output yourself in some meaningful fashion.
+.if \nF \{\
+. de IX
+. tm Index:\\$1\t\\n%\t"\\$2"
+..
+. nr % 0
+. rr F
+.\}
+.\"
+.\" For nroff, turn off justification. Always turn off hyphenation; it makes
+.\" way too many mistakes in technical documents.
+.hy 0
+.if n .na
+.\"
+.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
+.\" Fear. Run. Save yourself. No user-serviceable parts.
+. \" fudge factors for nroff and troff
+.if n \{\
+. ds #H 0
+. ds #V .8m
+. ds #F .3m
+. ds #[ \f1
+. ds #] \fP
+.\}
+.if t \{\
+. ds #H ((1u-(\\\\n(.fu%2u))*.13m)
+. ds #V .6m
+. ds #F 0
+. ds #[ \&
+. ds #] \&
+.\}
+. \" simple accents for nroff and troff
+.if n \{\
+. ds ' \&
+. ds ` \&
+. ds ^ \&
+. ds , \&
+. ds ~ ~
+. ds /
+.\}
+.if t \{\
+. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
+. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
+. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
+. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
+. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
+. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
+.\}
+. \" troff and (daisy-wheel) nroff accents
+.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
+.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
+.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
+.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
+.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
+.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
+.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
+.ds ae a\h'-(\w'a'u*4/10)'e
+.ds Ae A\h'-(\w'A'u*4/10)'E
+. \" corrections for vroff
+.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
+.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
+. \" for low resolution devices (crt and lpr)
+.if \n(.H>23 .if \n(.V>19 \
+\{\
+. ds : e
+. ds 8 ss
+. ds o a
+. ds d- d\h'-1'\(ga
+. ds D- D\h'-1'\(hy
+. ds th \o'bp'
+. ds Th \o'LP'
+. ds ae ae
+. ds Ae AE
+.\}
+.rm #[ #] #H #V #F C
+.\" ========================================================================
+.\"
+.IX Title "note 3pm"
+.TH note 3pm "2005-10-25" "perl v5.8.4" "User Contributed Perl Documentation"
+.SH "NAME"
+note \- a perl script for maintaining notes.
+.SH "SYNPOPSIS"
+.IX Header "SYNPOPSIS"
+note [options] [ number [,number...]]
+.SH "DESCRIPTION"
+.IX Header "DESCRIPTION"
+\&\fBnote\fR is a small console program written in perl, which allows
+you to manage notes similar to programs like \*(L"knotes\*(R" but from
+the commandline. Note can use different database-backends for
+notes\-storage. It ships with a DBI-based mysql\-module(which
+can also be used for other by \s-1DBI\s0 supported \s-1DBMS\s0), another
+module, which uses a binary file for storage and a \s-1DBM\s0 module.
+There are also two modules available which uses a text file.
+Note supports since version 1.0.0 encryption(\s-1IDEA\s0 or \s-1DES\s0)!
+.SH "OPTIONS"
+.IX Header "OPTIONS"
+.IP "\fI\-c, \-\-config file\fR" 4
+.IX Item "-c, --config file"
+Use another config file than the default ~/.noterc.
+.IP "\fI\-l, \-\-list [topic]\fR" 4
+.IX Item "-l, --list [topic]"
+Lists all existing notes. If no topic were specified,
+it will display a list of all existing topics.
+See the section \fI\s-1TOPICS\s0\fR for details about topics.
+.IP "\fI\-L, \-\-longlist [topic]\fR" 4
+.IX Item "-L, --longlist [topic]"
+The same as \fI\-l\fR but prints also the timestamp of the notes.
+.IP "\fI\-t, \-\-topic\fR" 4
+.IX Item "-t, --topic"
+Prints a list of all topics as a tree.
+.IP "\fI\-T, \-\-longtopic\fR" 4
+.IX Item "-T, --longtopic"
+Prints the topic-tree with the notes under each topic.
+.IP "\fI\-s, \-\-search string\fR" 4
+.IX Item "-s, --search string"
+Searches for trough the notes database. See the section
+\&\fI\s-1SEARCHING\s0\fR for details about the search engine.
+.IP "\fI\-e, \-\-edit number\fR" 4
+.IX Item "-e, --edit number"
+Edit the note with the number using your default editor
+or the one you specified in the config file.
+.IP "\fI\-d, \-\-delete number\fR" 4
+.IX Item "-d, --delete number"
+Delete the note with the number . You can delete multiple notes
+with one command. \*(L"1\-4\*(R" deletes the notes 1,2,3,4. And \*(L"1,5,7\*(R" deletes
+the specified ones.
+.IP "\fI\-D, \-\-Dump [file | \-]\fR" 4
+.IX Item "-D, --Dump [file | -]"
+Dumps all notes to the textfile . If is a \*(L"\-\*(R" it will
+be printed out to standard output (\s-1STDOUT\s0).
+.IP "\fI\-I, \-\-Import file | \-\fR" 4
+.IX Item "-I, --Import file | -"
+Imports a previously dumped textfile into the
+note database. Data will be appended by default.
+You can also specify a dash \fInote \-I \-\fR instead of a ,
+which causes note, silently to read in a dump from \s-1STDIN\s0.
+.IP "\fI\-o, \-\-overwrite\fR" 4
+.IX Item "-o, --overwrite"
+Only suitable for use with \-\-Import. Overwrites an
+existing notedb. Use with care.
+.IP "\fI\-r, \-\-raw\fR" 4
+.IX Item "-r, --raw"
+Raw mode, output will not be formatted. Works not in interactive
+mode, only on cmd-line for list and display. That means, no colors
+will be used and no lines or titles.
+.IP "\fI\-i, \-\-interactive\fR" 4
+.IX Item "-i, --interactive"
+Start note in interactive mode. See the section \fI\s-1INTERACTIVE\s0 \s-1MODE\s0\fR
+for details on this mode.
+.IP "\fI\-\-encrypt cleartext\fR" 4
+.IX Item "--encrypt cleartext"
+Encrypt the given clear text string. You would need that if you want to
+store the mysql password not in cleartext in the config(if you are using
+the mysql backend!).
+.IP "\fI\-h, \-\-help\fR" 4
+.IX Item "-h, --help"
+Display this help screen.
+.IP "\fI\-v, \-\-version\fR" 4
+.IX Item "-v, --version"
+Display the version number.
+.IP "\fB\-\fR" 4
+.IX Item "-"
+If you run note just with one dash: \fBnote \-\fR, then it will read in a new
+note from \s-1STDIN\s0 until \s-1EOF\s0. This makes it possible to pipe text into a new note, i.e.:
+.Sp
+.Vb 1
+\& cat sometextfile | note \-
+.Ve
+.SH "USAGE"
+.IX Header "USAGE"
+.Sh "\s-1GENERAL\s0 \s-1USAGE\s0"
+.IX Subsection "GENERAL USAGE"
+If you don't know, how to run note, try \*(L"note \-h\*(R" first.
+It will tell you all available commandline options.
+.PP
+To create a new note, simply run \*(L"note\*(R". You can enter
+the note (the length is by default limited to 4096 bytes,
+which you can change from your config file if you are using
+the binary backend, otherwise there is no limitation).
+End by typing a . on a line itself. note will tell you the
+number of the note.
+.PP
+If you want to view the note, type \*(L"note 1\*(R", if the notenumber
+was 1.
+.PP
+If you want to get an overview of all notes, type \*(L"note \-l\*(R".
+You will get a list of all notes, containing the number,
+the first line and the creation date. If topic-support is
+turned on (which is by default), then all subtopics under the
+current topic will be displayed first.
+If you want to see the timestamps, use \*(L"\-L\*(R" instead of \*(L"\-l\*(R".
+Read more about topics below in the section \*(L"Topics\*(R".
+You can also specify the topic which notes you want to see:
+\&\*(L"\-l mytopic\*(R" does the trick.
+Additional, you might want to get an overview of your topic\-
+structure. You can use the command \*(L"\-t\*(R" in this case, which
+will display a tree-view of your topic\-structure. You can
+use the command \*(L"\-T\*(R" if you want to see the notes under each
+topic too. \*(L"\-T\*(R" will also show the number of each note.
+.PP
+To edit a certain note, type \*(L"note \-e 1\*(R". It will invoke your
+editor (vi or pico). You can edit it, after saving, note
+will store the changed note to the database.
+.PP
+Of course you can drop a certain note: \*(L"note \-d 1\*(R" deletes
+note number 1. If a note in the middle or the beginning of
+the database will be deleted, note will recount the other
+existent notes. For example there are 3 notes, number 1, 2
+and 3. If you delete number 2, then number 3 will become
+number 2.
+You can also make use of the extended delete\-syntax:
+To delete note 1 and 2, use \*(L"\-d 1,2\*(R"
+To delete note 1,2 and 3, use \*(L"\-d 1\-3\*(R".
+.Sh "\s-1SEARCHING\s0"
+.IX Subsection "SEARCHING"
+If you cannot remember, which note you are looking for, you
+can use the search capability of note: \*(L"note \-s \*(R".
+note will search the whole note database case insensitive for
+an occurence of this string and tell you the number and first\-
+line it has.
+.PP
+You can extend the searchstring using \fB\s-1AND\s0\fR, \fB\s-1OR\s0\fR ( and ) and
+shell-like wildcards:
+.PP
+.Vb 1
+\& $ note \-s "moses AND lenin"
+.Ve
+.PP
+or:
+.PP
+.Vb 1
+\& $ note \-s "(mike OR arnold) AND (jackson OR schwarzenegger)"
+.Ve
+.PP
+If note finds a note, which first line is a topic, then it will
+display it's second line.
+.PP
+These rules apply for the interactive search too.
+.PP
+You need to know, that note searches for the expression in every
+note. In other words, \*(L"moses \s-1AND\s0 lenin\*(R" searches for an occurence
+of \*(L"moses\*(R" and \*(L"lenin\*(R" in \s-1ONE\s0 note. Or, if you are looking for
+\&\*(L"mike \s-1OR\s0 daniel\*(R", then it searches for an occurence of \*(L"mike\*(R" or
+daniel\*(L" in \s-1ONE\s0 note. Thus a note with the text \*(R"mike oldfield" will
+match that search.
+.Sh "\s-1TOPICS\s0"
+.IX Subsection "TOPICS"
+If topic-support is turned on (which is by default), the various
+notes are sorted under various topics. There is no special database
+field for the topic. Instead the topic will be stored right in the
+note.
+If the first line of your note contains some text bordered by slashes
+(or whatever you prefer, set \*(L"TopicSeparator\*(R" in your config! default
+is slash), then note will consider it as the topic of this certain
+note. For examle:
+.PP
+.Vb 1
+\& B
+.Ve
+.PP
+If you are using topics, no data after the topic is allowed, if there
+is any text, note will consider it as a subtopic! Therefore, don't for\-
+get to put a newline after the topic\-line.
+.PP
+The list-command will only show you notes under this topic. If you
+create a new note, it will automagically inserted under the current
+topic (note will prepend the string \*(L"/topicname/\*(R" to the text of your
+note).
+.PP
+You can create at any time from any point a new topic. Just create a new
+note and type the name of the new topic bordered by slashes (or
+TopicSeparator) at the first line of this note. After saving, there
+will be available a new topic with one note in it.
+.PP
+You can create as many subtopics as you like, the format is similar to
+a filesystem\-path. An example, say, you want to create such a
+structure:
+.PP
+.Vb 10
+\& (root \- top level)
+\& |
+\& |\-\-\-\-test
+\& | |\-\-\-\-subtopic
+\& | | |\-\-note 1
+\& | | |\-\-note 2
+\& | |
+\& | |\-\-note 4
+\& |
+\& |\-\-note 3
+.Ve
+.PP
+Then you may create those 4 new notes:
+.PP
+.Vb 12
+\& \-\-\- snip \-\-\-
+\& /test/subtopic/
+\& note 1
+\& \-\-\- snip \-\-\-
+\& /test/subtopic/
+\& note 2
+\& \-\-\- snip \-\-\-
+\& note 3
+\& \-\-\- snip \-\-\-
+\& /test/
+\& note 4
+\& \-\-\- snip \-\-\-
+.Ve
+.PP
+I hope, you got the point ;\-)
+.PP
+If a note does not contain the \*(L"magic\*(R" /topic/ construction on the first
+line, it will be listed under the \*(L"root\*(R" of note, that is the point
+you are at the startup of note.
+.PP
+You can subsequently move a note without a topic to a certain topic.
+Simply edit it and insert at the first line the above mentioned
+construction.
+.PP
+Note: Please don't forget the prepending and appending a slash of a
+topic. You will get strange results without it!
+.Sh "\s-1INTERACTIVE\s0 \s-1MODE\s0"
+.IX Subsection "INTERACTIVE MODE"
+If you start note with the commandline flag \fB\-i\fR, then it starts
+with an interactive interface.
+It will start with a listing under the default top-topic (\*(L"/\*(R").
+You can enter the name of a topic to change to that topic. This works
+similar to a filesystem structure. The current topic will be
+displayed on the top of the screen.
+.PP
+The following commands are available:
+.IP "\fBL [topic]\fR" 4
+.IX Item "L [topic]"
+This command lists all notes with a timestamp. If you specify a topic, it
+will only list the notes under this topic. If you are under a certain subtopic,
+then it will only display the notes under this topic.
+.IP "\fBl [topic]\fR" 4
+.IX Item "l [topic]"
+This commands behaves similar to \fBL\fR but it does not display the timestamp.
+You can achieve the same result by simply pressing enter at any time.
+.IP "\fBN\fR" 4
+.IX Item "N"
+You can create a new note by simply pressing \fBN\fR or \fBn\fR. You favorite
+editor will be started and you can enter your note text. If you are already
+under a topic then this new note will automatically go to this topic.
+note adds an aditional line to the top of the note with the topic. But
+you can of course specify your own topic.
+.Sp
+Note will tell you which number it has assigned to the newly created note.
+.IP "\fBE number\fR" 4
+.IX Item "E number"
+By entering \fBE\fR or \fBe\fR and a note-number you can edit an existing note
+using your favorite editor. This way you can also move an existing note
+from one topic to another one by editing the first line of the note.
+.IP "\fBD number\fR" 4
+.IX Item "D number"
+\&\fBE\fR or \fBe\fR deletes one or more existing note(s). It requires a note number
+or a set of note numbers. 1\-5 and 1,7,9 are possible values.
+After one or more notes has been deleted note will recount all remaining notes.
+Say if you delete 1 and 2, then 3 will become 1, 4 will become 5 and so forth.
+.IP "\fBS [expression]\fR" 4
+.IX Item "S [expression]"
+You can search for the occurence of a text in your notes-database with the
+command \fBS\fR or \fBs\fR. If you omit an expression note will ask you for one.
+.Sp
+If your search criteria matches on exactly one entry, note will display
+that note entry instead of displaying its number.
+.IP "\fBT\fR" 4
+.IX Item "T"
+This prints a tree-view of your topic\-structure. \fBT\fR displays the tree with
+notes, \fBt\fR displays just the topics without notes.
+.IP "\fBcd topic\fR" 4
+.IX Item "cd topic"
+Change the actual topic under which you are. This works identical like just
+entering the topic but it has some advantages. You can enter \fBcd ..\fR if
+you want to go one level up in the topic\-structure. And you can enter \fBcd /\fR
+to go to the top of the structure. You can always leave out the 'cd' keyword too.
+.Sp
+Additional it is possible to enter a note-number instead of a topic name.
+For this feature to be active you need to set the config option \fBShortCd\fR
+to \fB1\fR or \fByes\fR. If you use a number and the note with this number is
+under a certain topic then you will \*(L"cd\*(R" to this topic. This allows you
+to do kind of jumps over multiple levels of topics.
+.Sp
+If is possible to abbreviate a topic. This works only if the abbreviation
+matches on one single topic. If it matches more than one topic then the
+available ones will be suggested.
+.IP "\fB? or h\fR" 4
+.IX Item "? or h"
+Display a short help screen.
+.IP "\fBQ\fR" 4
+.IX Item "Q"
+Quit note.
+.Sh "\s-1BACKUP\s0"
+.IX Subsection "BACKUP"
+You can also dump the contents of your note-database into a
+ASCII\-textfile(\fI\-D\fR). You can use this file later to import it into
+your note\-database(\-I). This is usefull, if you want quickly trans\-
+fer your notes from one host to another (i.e. you could mail
+your note-dump form your office to home and import it there
+for further use).
+.PP
+The dumps from the two versions of note are in the same format.
+Using dumps it is also possible to reinitialize your database. You
+can use the \*(L"\-o\*(R" switch whcih causes note to overwrite your existing
+database. This is very handy if you changed heavily your config. And
+it is required, if you changed: encryption, db\-driver, (binary\-format)
+and the password. You can use the following command for reinitializing:
+.PP
+.Vb 1
+\& $ note \-D \- | note \-o \-I \-
+.Ve
+.PP
+What the hell, does this do?! Step by step:
+.IP "\(bu" 4
+\&\fBnote \-D \-\fR creates a note-database dump and prints it out
+to stantdard output.
+.IP "\(bu" 4
+\&\fB|\fR this is the shell's pipe command. It takes the output
+of the left program and gives it to the right program as
+standard input.
+.IP "\(bu" 4
+\&\fBnote \-o \-I \-\fR imports a note-database dump from standard
+input and overwrites an existing database.
+.PP
+Before you use the \fB\-o\fR switch, I consider you to make a backup!
+.Sh "\s-1FORMATING\s0"
+.IX Subsection "FORMATING"
+Another very nice feature is the possibility to format the note-text
+(as much as shell allows it). First, you can use the note-internal
+\&\*(L"magic\-strings\*(R" for colorizing. Those strings looks much like \s-1HTML:\s0
+\&\*(L"here is a green line of text no more green.\*(R"
+As you see, the beginning of another color starts with a tag(kinda) of
+the color and ends with an end tag .
+.PP
+The following colors are available:
+black, red, green, yellow, blue, magenta, cyan and white.
+.PP
+Beside colorizing text, you can also create bold or underlined text! If
+you decide to use this (additional) feature, you need to set the
+Config-Option \*(L"FormatText\*(R" to 1 which turns it on.
+Usage is very straightforward, if a word (a word is defined as some
+text with at least one space surrounded) is between a magic mark\-
+character. Here are the available things, you can do:
+.PP
+.Vb 4
+\& bold: **word**
+\& underlined: __word__
+\& inverse: {{word}}
+\& hidden: //word//
+.Ve
+.PP
+The text will be formatted using the actually note\-color.
+.PP
+The hidden formatting will use blue forground and blue background
+to hide a string from the terminal, which is usefull for passwords.
+.PP
+If you set \*(L"FormatText\*(R" to \fIsimple\fR then the formatting can be
+done this way instead:
+.PP
+.Vb 4
+\& bold: *word*
+\& underlined: _word_
+\& inverse: {word}
+\& hidden: /word/
+.Ve
+.SH "ENCRYPTION"
+.IX Header "ENCRYPTION"
+You can turn on encryption from the config file.
+Simply set UseEncryption to 1. Please note, that you need
+to decide, if you want to use encryption before the first use
+of note! If have already a note database and want to \*(L"migrate\*(R"
+to encryption, I suggest you to follow the directions in the
+file \s-1UPGRADE\s0!
+.PP
+You can choose from different encryption algorythms. The default
+is \s-1IDEA\s0, but \s-1DES\s0 or \s-1BLOWFISH\s0 are also possible. You need to have
+installed the following additional perl-modules on your system:
+\&\s-1MD5\s0
+Crypt::IDEA
+Crypt::DES
+Crypt::CBC
+.PP
+After turning on encryption, note will ask you for a passphrase
+everytime it runs! It will *not* store this passphrase!
+So, don't forget it! Be careful!
+.SH "CONFIGURATION"
+.IX Header "CONFIGURATION"
+You can use a configuration file with note but it is not required.
+Note will use default values if there is no config.
+.PP
+The default config file is \fB~/.noterc\fR. You may specify another
+one with the commandline flag \fI\-\-config\fR.
+.PP
+Comments start with #, empty lines will be ignored.
+.PP
+To turn on an option, set it to: \fB1\fR, \fBon\fR or \fByes\fR.
+.PP
+To turn off an option, set it to: \fB0\fR, \fBoff\fR or \fBno\fR.
+.PP
+An option consists of an atribute-value pair separated
+by minimum one space (more spaces and/or tabs are allowed)
+and an optional equal sign in between.
+.PP
+Variable names are case in\-sensitive.
+.PP
+For a detailed explanation of each possible parameter take a look
+at the supplied sample configuration file in \fBconfig/noterc\fR.
+.SH "AUTHOR"
+.IX Header "AUTHOR"
+Thomas Linden
+.SH "VERSION"
+.IX Header "VERSION"
+1.3.1 (12/01/2005)
diff --git a/blib/script/.exists b/blib/script/.exists
new file mode 100644
index 0000000..e69de29
diff --git a/blib/script/note b/blib/script/note
new file mode 100755
index 0000000..b842a6a
--- /dev/null
+++ b/blib/script/note
@@ -0,0 +1,1671 @@
+#!/usr/bin/perl
+
+eval 'exec /usr/bin/perl -S $0 ${1+"$@"}'
+ if 0; # not running under some shell
+#
+# note - console notes management with database and encryption support.
+# Copyright (C) 1999-2004 Thomas Linden (see README for details!)
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# - Thomas Linden
+#
+# latest version on:
+# http://www.daemon.de/note/
+#
+
+BEGIN {
+ # works on unix or cygwin only!
+ my $path = $0;
+ $path =~ s#/[^/]*$##;
+ unshift @INC, "$path/..";
+}
+
+use strict;
+no strict 'refs';
+use Getopt::Long;
+use FileHandle;
+use File::Spec;
+#use Data::Dumper;
+
+
+#
+# prototypes
+#
+sub usage; # print usage message for us thumb userz :-)
+sub find_editor; # returns an external editor for use
+sub output; # used by &list and &display
+sub C; # print colourized
+sub num_bereich; # returns array from "1-4" (1,2,3,4)
+sub getdate; # return pretty formatted day
+sub new; # crate new note
+sub edit; # edit a note
+sub del; # delete a note
+sub display; # display one or more notes
+sub list; # note-listing
+sub help; # interactive help screen
+sub import; # import from notedb-dump
+sub display_tree; # show nice tree-view
+sub tree; # build the tree
+sub print_tree; # print the tree, contributed by Jens Heunemann . THX!
+
+
+#
+# globals
+#
+my (
+ #
+ # commandline options
+ #
+ $opt_, $opt_i, $opt_r, $opt_e, $opt_d, $opt_enc,
+ $opt_s, $opt_t, $opt_T, $opt_l, $opt_L, $opt_c,
+ $opt_D, $opt_I, $opt_o, $opt_h, $opt_n, $opt_v,
+
+ #
+ # set from commandline (or interactive)
+ #
+ $number, $searchstring, $dump_file, $ImportType, $NewType, $Raw, $TOPIC,
+
+ #
+ # configuration options
+ %conf, %driver,
+
+ #
+ # processed colors
+ #
+ $BORDERC, $_BORDERC, $NOTEC, $NUMC, $_NUMC, $_NOTEC, $TIMEC,
+ $_TIMEC, $TOPICC, $_TOPICC,
+
+ #
+ # config presets
+ #
+ $DEFAULTDBNAME, $USER, $PATH, $CONF,
+
+ #
+ # internals
+ #
+ $TYPE, $mode, $NoteKey, %Color, @LastTopic, $timelen, $maxlen,
+ $version, $CurTopic, $CurDepth, $WantTopic, $db,
+ $sizeof, %TP, $TreeType, $ListType, $SetTitle, $clearstring,
+ @ArgTopics, $key, $typedef, @NumBlock, $has_nothing, @completion_topics, @completion_notes,
+ );
+
+
+#
+# DEFAULTS, allows one to use note without a config
+# don't change them, instead use the config file!
+#
+
+$conf{dbdriver} = "binary";
+$conf{usecolors} = 1;
+$conf{bordercolor} = "bold";
+$conf{numbercolor} = "blue";
+$conf{notecolor} = "green";
+$conf{timecolor} = "blue";
+$conf{topiccolor} = "bold";
+$conf{topicseparator} = '/';
+$conf{useencryption} = 0;
+$conf{tempdirectory} = File::Spec->tmpdir();
+$conf{alwaysinteractive} = 1;
+$conf{alwayseditor} = 1;
+$conf{autoclear} = 1;
+
+$CONF = File::Spec->catfile($ENV{HOME}, ".noterc");
+$USER = getlogin || getpwuid($<);
+chomp $USER;
+$TOPIC = 1;
+$version = "1.3.3";
+$CurDepth = 1; # the current depth inside the topic "directory" structure...
+$maxlen = "auto";
+$timelen = 22;
+
+
+# colors available
+# \033[1m%30s\033[0m
+%Color = ( 'black' => '0;30',
+ 'red' => '0;31',
+ 'green' => '0;32',
+ 'yellow' => '0;33',
+ 'blue' => '0;34',
+ 'magenta' => '0;35',
+ 'cyan' => '0;36',
+ 'white' => '0;37',
+ 'B' => '1;30',
+ 'BLACK' => '1;30',
+ 'RED' => '1;31',
+ 'GREEN' => '1;32',
+ 'YELLOW' => '1;33',
+ 'BLUE' => '1;34',
+ 'MAGENTA' => '1;35',
+ 'CYAN' => '1;36',
+ 'WHITE' => '1;37',
+ 'black_' => '4;30',
+ 'red_' => '4;31',
+ 'green_' => '4;32',
+ 'yellow_' => '4;33',
+ 'blue_' => '4;34',
+ 'magenta_' => '4;35',
+ 'cyan_' => '4;36',
+ 'white_' => '4;37',
+ 'blackI' => '7;30',
+ 'redI' => '7;31',
+ 'greenI' => '7;32',
+ 'yellowI' => '7;33',
+ 'blueI' => '7;34',
+ 'magentaI' => '7;35',
+ 'cyanI' => '7;36',
+ 'whiteI' => '7;37',
+ 'white_black' => '40;37;01',
+ 'bold' => ';01',
+ 'hide' => '44;34'
+ );
+
+#
+# process command line args
+#
+if ($ARGV[0] eq "") {
+ $mode = "new";
+}
+elsif ($#ARGV == 0 && $ARGV[0] eq "-") {
+ $mode = "new";
+ $NewType = 1; # read from STDIN until EOF
+ shift;
+ undef $has_nothing;
+}
+else {
+ Getopt::Long::Configure( qw(no_ignore_case));
+ GetOptions (
+ "interactive|i!" => \$opt_i, # no arg
+ "config|c=s" => \$opt_c, # string, required
+ "raw|r!" => \$opt_r, # no arg
+ "edit|e=i" => \$opt_e, # integer, required
+ "delete|d=s" => \$opt_d, # integer, required
+ "search|s=s" => \$opt_s, # string, required
+ "tree|topic|t!" => \$opt_t, # no arg
+ "longtopic|T!" => \$opt_T, # no arg
+ "list|l:s" => \$opt_l, # string, optional
+ "longlist|L:s" => \$opt_L, # string, optional
+ "dump||Dump|D:s" => \$opt_D, # string, optional
+ "import|Import|I:s" => \$opt_I, # string, optional
+ "overwrite|o!" => \$opt_o, # no arg
+ "help|h|?!" => \$opt_h, # no arg
+ "version|v!" => \$opt_v, # no arg
+ "encrypt=s" => \$opt_enc, # string, required
+ );
+ $opt_n = shift; # after that @ARGV contains eventually
+ # a note-number
+ # $opt_ is a single dash, in case of existence!
+ #
+ # determine mode
+ #
+ if ($opt_i) {
+ $mode = "interactive";
+ }
+ elsif (defined $opt_l || defined $opt_L) {
+ $mode = "list";
+ if (defined $opt_l) {
+ @ArgTopics = split /$conf{topicseparator}/, $opt_l;
+ }
+ else {
+ $ListType = "LONG";
+ @ArgTopics = split /$conf{topicseparator}/, $opt_L;
+ }
+ $CurDepth += $#ArgTopics + 1 if($opt_l || $opt_L);
+ $CurTopic = $ArgTopics[$#ArgTopics]; # use the last element everytime...
+ }
+ elsif ($opt_t || $opt_T) {
+ $mode = "tree";
+ $TreeType = "LONG" if($opt_T);
+ }
+ elsif (defined $opt_s) {
+ $mode = "search";
+ $searchstring = $opt_s;
+ }
+ elsif ($opt_e) {
+ $mode = "edit";
+ $number = $opt_e;
+ }
+ elsif ($opt_d) {
+ $mode = "delete";
+ $number = $opt_d;
+ }
+ elsif ($opt_enc) {
+ $mode = "encrypt_passwd";
+ $clearstring = $opt_enc;
+ }
+ elsif (defined $opt_D) {
+ $mode = "dump";
+ if (!$opt_) {
+ if ($opt_D ne "") {
+ $dump_file = $opt_D;
+ }
+ else {
+ $dump_file = "note.dump.$$";
+ print "no dumpfile specified, using $dump_file.\n";
+ }
+ }
+ else {
+ $dump_file = "-"; # use STDIN
+ }
+ }
+ elsif (defined $opt_I) {
+ $mode = "import";
+ if (!$opt_) {
+ if ($opt_I ne "") {
+ $dump_file = $opt_I;
+ }
+ else {
+ print "Import-error! No dump_file specified!\n";
+ exit(1);
+ }
+ }
+ else {
+ $dump_file = "-";
+ }
+ }
+ elsif ($opt_v) {
+ print "This is note $version by Thomas Linden .\n";
+ exit(0);
+ }
+ elsif ($opt_h) {
+ &usage;
+ }
+ else {
+ if ($opt_c && $mode eq "" && !$opt_n) {
+ $mode = "new";
+ }
+ elsif ($opt_c && $mode eq "") {
+ $mode = ""; # huh?!
+ }
+ else {
+ $has_nothing = 1;
+ }
+ }
+ ### determine generic options
+ if ($opt_n =~ /^[\d+\-?\,*]+$/) {
+ # first arg is a digit!
+ if ($mode eq "") {
+ $number = $opt_n;
+ $mode = "display";
+ undef $has_nothing;
+ }
+ else {
+ print "mode <$mode> does not take a numerical argument!\n";
+ exit(1);
+ }
+ }
+ elsif ($opt_n ne "") {
+ print "Unknown option: $opt_n\n";
+ &usage;
+ }
+ if ($opt_r) {
+ $Raw = 1;
+ }
+ if ($opt_o) {
+ $ImportType = "overwrite";
+ if (!$opt_I) {
+ print "--overwrite is only suitable for use with --import!\n";
+ exit(1);
+ }
+ }
+ #####
+}
+if ($has_nothing && $mode eq "") {
+ &usage;
+}
+
+
+# read the configfile.
+$CONF = $opt_c if($opt_c); # if given by commandline, use this.
+if (-e $CONF) {
+ &getconfig($CONF);
+}
+elsif ($opt_c) {
+ # only wrong, if specified by commandline! else use default values!
+ print STDERR "Could not open \"$CONF\": file does not exist or permission denied!\n";
+ exit(1);
+}
+
+# directly jump to encrypt, 'cause this sub does
+# not require a database connection
+if ($mode eq "encrypt_passwd") {
+ &encrypt_passwd;
+ exit;
+}
+
+# Always interactive?
+if ($conf{alwaysinteractive} && $mode ne "dump" && $mode ne "import") {
+ $mode = "interactive";
+}
+
+# OK ... Long-Listing shall be default ... You wanted it!!!
+if ($conf{defaultlong}) {
+ # takes only precedence in commandline mode
+ $ListType="LONG";
+}
+
+
+
+
+# calculate some constants...
+$BORDERC = "<$conf{bordercolor}>";
+$_BORDERC = "$conf{bordercolor}>";
+$NUMC = "<$conf{numbercolor}>";
+$_NUMC = "$conf{numbercolor}>";
+$NOTEC = "<$conf{notecolor}>";
+$_NOTEC = "$conf{notecolor}>";
+$TIMEC = "<$conf{timecolor}>";
+$_TIMEC = "$conf{timecolor}>";
+$TOPICC = "<$conf{topiccolor}>";
+$_TOPICC = "$conf{topiccolor}>";
+
+$NoteKey = $conf{topicseparator} . "notes" . $conf{topicseparator};
+
+
+
+
+# default permissions on new files (tmp)
+umask 077;
+
+
+# load the parent module
+&load_driver(1);
+
+# check wether the user wants to use encryption:
+if ($conf{useencryption} && $NOTEDB::crypt_supported == 1) {
+ if ($conf{cryptmethod} eq "") {
+ $conf{cryptmethod} = "Crypt::IDEA";
+ }
+ if (!exists $ENV{'NOTE_PASSWD'}) {
+ print "password: ";
+ eval {
+ local($|) = 1;
+ local(*TTY);
+ open(TTY,"/dev/tty") or die "No /dev/tty!";
+ system ("stty -echo );
+ print STDERR "\r\n";
+ system ("stty echo ;
+ }
+ }
+ else {
+ $key = $ENV{'NOTE_PASSWD'};
+ }
+ chomp $key;
+ if ($conf{dbdriver} eq "mysql") {
+ eval {
+ require Crypt::CBC;
+ my $cipher = new Crypt::CBC($key, $conf{cryptmethod});
+ # decrypt the dbpasswd, if it's encrypted!
+ $driver{mysql}->{dbpasswd} =
+ $cipher->decrypt(unpack("u", $driver{mysql}->{dbpasswd})) if($driver{mysql}->{encrypt_passwd});
+ &load_driver();
+ };
+ die "Could not connect do db: $@!\n" if($@);
+ }
+ else {
+ &load_driver();
+ }
+ $db->use_crypt($key,$conf{cryptmethod});
+ undef $key;
+ # verify correctness of passwd
+ my ($cnote, $cdate) = $db->get_single(1);
+ if ($cdate ne "") {
+ if ($cdate !~ /^\d+\.\d+?/) {
+ print "access denied.\n"; # decrypted $date is not a number!
+ exit(1);
+ }
+ } #else empty database!
+}
+else {
+ &load_driver();
+ $db->no_crypt;
+
+ # does: NOTEDB::crypt_supported = 0;
+ my ($cnote, $cdate) = $db->get_single(1);
+ if ($cdate ne "") {
+ if ($cdate !~ /^\d+\.\d+?/) {
+ print "notedb seems to be encrypted!\n";
+ exit(1);
+ }
+ }
+}
+
+
+# do we use the db cache?
+if ($conf{cache}) {
+ $db->use_cache();
+}
+
+
+# add the backend version to the note version:
+$version .= ", " . $conf{dbdriver} . " " . $db->version();
+
+
+# main loop: ###############
+&$mode;
+exit(0);
+################## EOP ################
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+############ encrypt a given password ##############
+sub encrypt_passwd {
+ my($key, $crypt_string);
+ print "password: ";
+ eval {
+ local($|) = 1;
+ local(*TTY);
+ open(TTY,"/dev/tty") or die "No /dev/tty!";
+ system ("stty -echo );
+ print STDERR "\r\n";
+ system ("stty echo ;
+ }
+ chomp $key;
+ eval {
+ require Crypt::CBC;
+ my $cipher = new Crypt::CBC($key, $conf{cryptmethod});
+ $crypt_string = pack("u", $cipher->encrypt($clearstring));
+ };
+ if ($@) {
+ print "Something went wrong: $@\n";
+ exit 1;
+ } else {
+ print "Encrypted password:\n$crypt_string\n";
+ }
+}
+
+
+############################### DISPLAY ##################################
+sub display {
+ my($N,$match,$note,$date,$num);
+ # display a certain note
+ print "\n";
+ &num_bereich; # get @NumBlock from $numer
+ my $count = scalar @NumBlock;
+ foreach $N (@NumBlock) {
+ ($note, $date) = $db->get_single($N);
+ if ($note) {
+ if ($Raw) {
+ print "$N\n$date\n$note\n\n";
+ }
+ else {
+ output($N, $note, $date, "SINGLE", $count);
+ print "\n";
+ }
+ $match = 1;
+ }
+ $count--;
+ }
+ if (!$match) {
+ print "no note with that number found!\n";
+ }
+ }
+
+############################### SEARCH ##################################
+sub search {
+ my($n,$match,$note,$date,$num,%res);
+ if ($searchstring eq "") {
+ print "No searchstring specified!\n";
+ }
+ else {
+ print "searching the database $conf{dbname} for \"$searchstring\"...\n\n";
+
+ %res = $db->get_search($searchstring);
+ my $nummatches = scalar keys %res;
+ foreach $num (sort { $a <=> $b } keys %res) {
+ if ($nummatches == 1) {
+ output($num, $res{$num}->{'note'}, $res{$num}->{'date'}, "SINGLE");
+ }
+ else {
+ output($num, $res{$num}->{'note'}, $res{$num}->{'date'}, "search");
+ }
+ $match = 1;
+ }
+ if (!$match) {
+ print "no matching note found!\n";
+ }
+ print "\n";
+ }
+ }
+
+
+############################### LIST ##################################
+sub list {
+ my(@topic,@RealTopic, $i,$t,$n,$num,@CurItem,$top,$in,%res);
+ if ($mode ne "interactive" && !$Raw) {
+ print "\nList of all existing notes:\n\n";
+ }
+ else {
+ print "\n";
+ }
+
+ # list all available notes (number and firstline)
+ %res = $db->get_all();
+
+ if ($TOPIC) {
+ undef %TP;
+ }
+
+ foreach $num (sort { $a <=> $b } keys %res) {
+ $n = $res{$num}->{'note'};
+ $t = $res{$num}->{'date'};
+ if ($TOPIC) {
+ # this allows us to have multiple topics (subtopics!)
+ my ($firstline,$dummy) = split /\n/, $n, 2;
+ if ($firstline =~ /^($conf{topicseparator})/) {
+ @topic = split(/$conf{topicseparator}/,$firstline);
+ }
+ else {
+ @topic = ();
+ }
+ # looks like: "\topic\"
+ # collect a list of topics under the current topic
+ if ($topic[$CurDepth-1] eq $CurTopic && $topic[$CurDepth] ne "") {
+ if (exists $TP{$topic[$CurDepth]}) {
+ $TP{$topic[$CurDepth]}++;
+ }
+ else {
+ # only if the next item *is* a topic!
+ $TP{$topic[$CurDepth]} = 1 if(($CurDepth) <= $#topic);
+ }
+ }
+ elsif ($topic[$CurDepth-1] eq $CurTopic || ($topic[$CurDepth] eq "" && $CurDepth ==1)) {
+ # cut the topic off the note-text
+ if ($n =~ /^($conf{topicseparator})/) {
+ $CurItem[$i]->{'note'} = $dummy;
+ }
+ else {
+ $CurItem[$i]->{'note'} = $n;
+ }
+ # save for later output() call
+ $CurItem[$i]->{'num'} = $num;
+ $CurItem[$i]->{'time'} = $t;
+ $i++;
+ # use this note for building the $PATH!
+ if ($RealTopic[0] eq "") {
+ @RealTopic = @topic;
+ }
+ }
+ }
+ else {
+ output($num, $n, $t);
+ }
+ }
+ if ($TOPIC) {
+ if ($CurTopic ne "") {
+ if ($i) {
+ # only if there were notes under current topic
+ undef $PATH;
+ foreach (@RealTopic) {
+ $PATH .= $_ . $conf{topicseparator};
+ last if($_ eq $CurTopic);
+ }
+ }
+ else {
+ # it is an empty topic, no notes here
+ $PATH = join $conf{topicseparator}, @LastTopic;
+ $PATH .= $conf{topicseparator} . $CurTopic . $conf{topicseparator};
+ $PATH =~ s/^\Q$conf{topicseparator}$conf{topicseparator}\E/$conf{topicseparator}/;
+ }
+ }
+ else {
+ $PATH = $conf{topicseparator};
+ }
+
+ @completion_topics = ();
+ @completion_notes = ();
+ # we are at top level, print a list of topics...
+ foreach $top (sort(keys %TP)) {
+ push @completion_topics, $top;
+ output("-", " => ". $top . "$conf{topicseparator} ($TP{$top} notes)",
+ " Sub Topic ");
+ }
+ #print Dumper(@CurItem);
+ for ($in=0;$in<$i;$in++) {
+ push @completion_notes, $CurItem[$in]->{'num'};
+ output( $CurItem[$in]->{'num'},
+ $CurItem[$in]->{'note'},
+ $CurItem[$in]->{'time'} );
+ }
+ }
+
+ print "\n";
+ }
+
+############################### NEW ##################################
+sub new {
+ my($TEMP,$editor, $date, $note, $WARN, $c, $line, $num, @topic);
+ if ($conf{readonly}) {
+ print "readonly\n";
+ return;
+ }
+ $date = &getdate;
+ return if $db->lock();
+ if ($conf{alwayseditor}) {
+ $TEMP = &gettemp;
+ # security!
+ unlink $TEMP;
+ # let the user edit it...
+ $editor = &find_editor;
+ if ($editor) {
+ # create the temp file
+ open NEW, "> $TEMP" or die "Could not write $TEMP: $!\n";
+ close NEW;
+ system "chattr", "+s", $TEMP; # ignore errors, since only on ext2 supported!
+ system $editor, $TEMP;
+ }
+ else {
+ print "Could not find an editor to use!\n";
+ $db->unlock();
+ exit(0);
+ }
+ # read it in ($note)
+ $note = "";
+ open E, "<$TEMP" or $WARN = 1;
+ if ($WARN) {
+ print "...edit process interupted! No note has been saved.\n";
+ undef $WARN;
+ $db->unlock();
+ return;
+ }
+ $c = 0;
+ while () {
+ $note = $note . $_;
+ }
+ chomp $note;
+ close E;
+ # privacy!
+ unlink $TEMP;
+ }
+ else {
+ $note = "";
+ $line = "";
+ # create a new note
+ if ($NewType) {
+ # be silent! read from STDIN until EOF.
+ while () {
+ $note .= $_;
+ }
+ }
+ else {
+ print "enter the text of the note, end with a single .\n";
+ do
+ {
+ $line = ;
+ $note = $note . $line;
+ } until $line eq ".\n";
+ # remove the . !
+ chop $note;
+ chop $note;
+ }
+ }
+ # look if the note was empty, so don't store it!
+ if ($note =~ /^\s*$/) {
+ print "...your note was empty and will not be saved.\n";
+ $db->unlock();
+ return;
+ }
+ # since we have not a number, look for the next one available:
+ $number = $db->get_nextnum();
+ if ($TOPIC && $CurTopic ne "") {
+ @topic = split(/$conf{topicseparator}/,$note);
+ if ($topic[1] eq "") {
+ $note = $PATH . "\n$note";
+ }
+ }
+ $db->set_new($number,$note,$date);
+ # everything ok until here!
+ print "note stored. it has been assigned the number $number.\n\n";
+ $db->unlock();
+ }
+
+
+############################### DELETE ##################################
+sub del {
+ my($i,@count, $setnum, $pos, $ERR);
+ if ($conf{readonly}) {
+ print "readonly\n";
+ return;
+ }
+ # delete a note
+ &num_bereich; # get @NumBlock from $number
+
+ return if $db->lock();
+
+ foreach $_ (@NumBlock) {
+ $ERR = $db->set_del($_);
+ if ($ERR) {
+ print "no note with number $_ found!\n";
+ }
+ else {
+ print "note number $_ has been deleted.\n";
+ }
+ }
+ # recount the notenumbers:
+ $db->set_recountnums();
+
+ $db->unlock();
+ @NumBlock = ();
+ }
+
+############################### EDIT ##################################
+sub edit {
+ my($keeptime, $date, $editor, $TEMP, $note, $t, $num, $match, $backup);
+ if ($conf{readonly}) {
+ print "readonly\n";
+ return;
+ }
+ # edit a note
+ $date = &getdate;
+
+ return if $db->lock();
+
+ ($note, $keeptime) = $db->get_single($number);
+ if ($keeptime eq "") {
+ print "no note with that number found ($number)!\n\n";
+ if($mode ne "interactive") {
+ $db->unlock();
+ exit(0);
+ }
+ else {
+ $db->unlock();
+ return;
+ }
+ }
+
+ $TEMP = &gettemp;
+ open NOTE,">$TEMP" or die "Could not open $TEMP\n";
+ select NOTE;
+
+ system "chattr", "+s", $TEMP; # ignore errors, like in new()
+
+ print $note;
+ close NOTE;
+ select STDOUT;
+ $editor = &find_editor;
+
+ $backup = $note;
+
+ if ($editor) {
+ system ($editor, $TEMP) and die "Could not execute $editor: $!\n";
+ }
+ else {
+ print "Could not find an editor to use!\n";
+ exit(0);
+ }
+ $note = "";
+ open NOTE,"<$TEMP" or die "Could not open $TEMP\n";
+
+ while () {
+ $note = $note . $_;
+ }
+ chomp $note;
+ close NOTE;
+
+ unlink $TEMP || die $!;
+
+ if ($note ne $backup) {
+ if ($conf{keeptimestamp}) {
+ $t = $keeptime;
+ }
+ else {
+ $t = $date;
+ }
+ # we got it, now save to db
+ $db->set_edit($number, $note, $t);
+
+ print "note number $number has been changed.\n";
+ }
+ else {
+ print "note number $number has not changed, no save done.\n";
+ }
+ $db->unlock();
+ }
+
+
+sub dump {
+ my(%res, $num, $DUMP);
+ # $dump_file
+ if ($dump_file eq "-") {
+ $DUMP = *STDOUT;
+ }
+ else {
+ open (DUMPFILE, ">$dump_file") or die "could not open $dump_file\n";
+ $DUMP = *DUMPFILE;
+ }
+ select $DUMP;
+ %res = $db->get_all();
+ foreach $num (sort { $a <=> $b } keys %res) {
+ print STDOUT "dumping note number $num to $dump_file\n" if($dump_file ne "-");
+ print "Number: $num\n"
+ ."Timestamp: $res{$num}->{'date'}\n"
+ ."$res{$num}->{'note'}\n";
+ }
+ print "\n";
+ close(DUMPFILE);
+ select STDOUT;
+ }
+
+sub import {
+ my($num, $start, $complete, $dummi, $note, $date, $time, $number, $stdin, $DUMP, %data);
+ # open $dump_file and import it into the notedb
+ $stdin = 1 if($dump_file eq "-");
+ if ($stdin) {
+ $DUMP = *STDIN;
+ }
+ else {
+ open (DUMPFILE, "<$dump_file") or die "could not open $dump_file\n";
+ $DUMP = *DUMPFILE;
+ }
+
+ $complete = $start = 0;
+ $number = 1;
+ while (<$DUMP>) {
+ chomp $_;
+ if ($_ =~ /^Number:\s\d+/) {
+ if ($start == 0) {
+ # we have no previous record
+ $start = 1;
+ }
+ else {
+ # we got a complete record, save it!
+ $data{$number} = {
+ date => $date,
+ note => $note
+ };
+ print "fetched note number $number from $dump_file from $date.\n" if(!$stdin);
+ $complete = 0;
+ $note = "";
+ $date = "";
+ $number++;
+ }
+ }
+ elsif ($_ =~ /^Timestamp:\s\d+/ && $complete == 0) {
+ ($dummi,$date,$time) = split(/\s/,$_);
+ $date = "$date $time";
+ $complete = 1;
+ }
+ else {
+ $note .= $_ . "\n";
+ }
+ }
+
+ if ($note ne "" && $date ne "") {
+ # the last record, if existent
+ $data{$number} = {
+ data => $date,
+ note => $note
+ };
+ print "fetched note number $number from $dump_file from $date.\n" if(!$stdin);
+ }
+
+ $db->set_del_all() if($ImportType ne "");
+ $db->import_data(\%data);
+}
+
+sub determine_width {
+ # determine terminal wide, if possible
+ if ($maxlen eq "auto") {
+ eval {
+ my $wide = `stty -a`;
+ if ($wide =~ /columns (\d+?);/) {
+ $maxlen = $1 - 32; # (32 = timestamp + borders)
+ }
+ elsif ($wide =~ /; (\d+?) columns;/) {
+ # bsd
+ $maxlen = $1 - 32; # (32 = timestamp + borders)
+ }
+ else {
+ # stty didn't work
+ $maxlen = 80 - 32;
+ }
+ };
+ }
+}
+
+sub clear {
+ # first, try to determine the terminal height
+ return if(!$conf{autoclear});
+ my $hoch;
+ eval {
+ my $height = `stty -a`;
+ if ($height =~ /rows (\d+?);/) {
+ $hoch = $1;
+ }
+ elsif ($height =~ /; (\d+?) rows;/) {
+ # bsd
+ $hoch = $1;
+ }
+ };
+ if (!$hoch) {
+ # stty didn't work
+ $hoch = 25;
+ }
+ print "\n" x $hoch;
+}
+
+sub interactive {
+ my($B, $BB, $menu, $char, $Channel);
+ $Channel = $|;
+ local $| = 1;
+ # create menu:
+ $B = "";
+ $BB = "";
+ $menu = "[" . $B . "L" . $BB . "-List ";
+ if ($TOPIC) {
+ $menu .= $B . "T" . $BB . "-Topics ";
+ }
+ $menu .= $B . "N" . $BB . "-New "
+ . $B . "D" . $BB . "-Delete "
+ . $B . "S" . $BB . "-Search "
+ . $B . "E" . $BB . "-Edit "
+ . $B . "?" . $BB . "-Help "
+ . $B . "Q" . $BB . "-Quit] "; # $CurTopic will be empty if $TOPIC is off!
+
+ # per default let's list all the stuff:
+ # Initially do a list command!
+ &determine_width;
+ $ListType = ($conf{defaultlong}) ? "LONG" : "";
+ &list;
+
+ my ($term, $prompt, $attribs);
+ eval { require Term::ReadLine; };
+ if (!$@) {
+ $term = new Term::ReadLine('');
+ $attribs = $term->Attribs;
+ $attribs->{completion_function} = \&complete;
+ }
+
+ for (;;) {
+ $ListType = ($conf{defaultlong}) ? "LONG" : "";
+ undef $SetTitle;
+ if ($CurDepth > 2) {
+ print C $menu . $TOPICC . "../" . $CurTopic . $_TOPICC . ">";
+ }
+ else {
+ print C $menu . $TOPICC . $CurTopic . $_TOPICC . ">";
+ }
+
+ # endless until user press "Q" or "q"!
+ if ($term) {
+ if (defined ($char = $term->readline(" "))) {
+ $term->addhistory($char) if $char =~ /\S/;
+ $char =~ s/\s*$//; # remove trailing whitespace (could come from auto-completion)
+ }
+ else {
+ # shutdown
+ $| = $Channel;
+ print "\n\ngood bye!\n";
+ exit(0);
+ }
+ }
+ else {
+ $char = ;
+ chomp $char;
+ }
+
+ &determine_width;
+ &clear;
+
+ if ($char =~ /^\d+\s*[\di*?,*?\-*?]*$/) {
+ $ListType = ""; #overrun
+ # display notes
+ $number = $char;
+ &display;
+ }
+ elsif ($char =~ /^n$/i) {
+ # create a new one
+ &new;
+ }
+ elsif ($char =~ /^$/) {
+ &list;
+ }
+ elsif ($char =~ /^l$/) {
+ $ListType = "";
+ &list;
+ }
+ elsif ($char =~ /^L$/) {
+ $ListType = "LONG";
+ &list;
+ undef $SetTitle;
+ }
+ elsif ($char =~ /^h$/i || $char =~ /^\?/) {
+ # zu dumm der Mensch ;-)
+ &help;
+ }
+ elsif ($char =~ /^d\s+([\d*?,*?\-*?]*)$/i) {
+ # delete one!
+ $number = $1;
+ &del;
+ }
+ elsif ($char =~ /^d$/i) {
+ # we have to ask her:
+ print "enter number(s) of note(s) you want to delete: ";
+ $char = ;
+ chomp $char;
+ $number = $char;
+ &del;
+ }
+ elsif ($char =~ /^e\s+(\d+\-*\,*\d*)/i) {
+ # edit one!
+ $number = $1;
+ &edit;
+ }
+ elsif ($char =~ /^e$/i) {
+ # we have to ask her:
+ print "enter number of the note you want to edit: ";
+ $char = ;
+ chomp $char;
+ $number = $char;
+ &edit;
+ }
+ elsif ($char =~ /^s\s+/i) {
+ # she want's to search
+ $searchstring = $';
+ chomp $searchstring;
+ &search;
+ }
+ elsif ($char =~ /^s$/i) {
+ # we have to ask her:
+ print "enter the string you want to search for: ";
+ $char = ;
+ chomp $char;
+ $char =~ s/^\n//;
+ $searchstring = $char;
+ &search;
+ }
+ elsif ($char =~ /^q$/i) {
+ # schade!!!
+ $| = $Channel;
+ print "\n\ngood bye!\n";
+ exit(0);
+ }
+ elsif ($char =~ /^t$/) {
+ $TreeType = "";
+ &display_tree;
+ }
+ elsif ($char =~ /^T$/) {
+ $TreeType = "LONG";
+ &display_tree;
+ $TreeType = "";
+ }
+ elsif ($char =~ /^\.\.$/ || $char =~ /^cd\s*\.\.$/) {
+ $CurDepth-- if ($CurDepth > 1);
+ $CurTopic = $LastTopic[$CurDepth];
+ pop @LastTopic; # remove last element
+ &list;
+ }
+ elsif ($char =~ /^l\s+(\w+)$/) {
+ # list
+ $WantTopic = $1;
+ if (exists $TP{$WantTopic}) {
+ my %SaveTP = %TP;
+ $LastTopic[$CurDepth] = $CurTopic;
+ $CurTopic = $1;
+ $CurDepth++;
+ &list;
+ $CurTopic = $LastTopic[$CurDepth];
+ $CurDepth--;
+ %TP = %SaveTP;
+ }
+ else {
+ print "\nunknown command!\n";
+ }
+ }
+ else {
+ # unknown
+ my $unchar = $char;
+ $unchar =~ s/^cd //; # you may use cd now!
+ if ($unchar =~ /^\d+?$/ && $conf{short_cd}) {
+ # just a number!
+ my @topic;
+ my ($cnote, $cdate) = $db->get_single($unchar);
+ my ($firstline,$dummy) = split /\n/, $cnote, 2;
+ if ($firstline =~ /^($conf{topicseparator})/) {
+ @topic = split(/$conf{topicseparator}/,$firstline);
+ }
+ else {
+ @topic = ();
+ }
+ if (@topic) {
+ # only jump, if, and only if there were at least one topic!
+ $CurDepth = $#topic + 1;
+ $CurTopic = pop @topic;
+ @LastTopic = ("");
+ push @LastTopic, @topic;
+ }
+ &list;
+ }
+ elsif ($unchar eq $conf{topicseparator}) {
+ # cd /
+ $CurDepth = 1;
+ $CurTopic = "";
+ &list;
+ }
+ elsif (exists $TP{$char} || exists $TP{$unchar}) {
+ $char = $unchar if(exists $TP{$unchar});
+ $LastTopic[$CurDepth] = $CurTopic;
+ $CurTopic = $char;
+ $CurDepth++;
+ &list;
+ }
+ else {
+ # try incomplete match
+ my @matches;
+ foreach my $topic (keys %TP) {
+ if ($topic =~ /^$char/) {
+ push @matches, $topic;
+ }
+ }
+ my $nm = scalar @matches;
+ if ($nm == 1) {
+ # match on one incomplete topic, use this
+ $LastTopic[$CurDepth] = $CurTopic;
+ $CurTopic = $matches[0];
+ $CurDepth++;
+ &list;
+ }
+ elsif ($nm > 1) {
+ print "available topics: " . join( "," , @matches) . "\n";
+ }
+ else {
+ print "\nunknown command!\n";
+ }
+ }
+ undef $unchar;
+ }
+ }
+ }
+
+
+sub usage
+ {
+ print qq~This is the program note $version by Thomas Linden (c) 1999-2003.
+It comes with absolutely NO WARRANTY. It is distributed under the
+terms of the GNU General Public License. Use it at your own risk :-)
+
+Usage: note [ options ] [ number [,number...]]
+Read the note(1) manpage for more details.
+~;
+ exit 1;
+ }
+
+sub find_editor {
+ return $conf{preferrededitor} || $ENV{"VISUAL"} || $ENV{"EDITOR"} || "vi";
+}
+
+#/
+
+sub format {
+ # make text bold/underlined/inverse using current $NOTEC
+ my($note) = @_;
+ if ($conf{formattext}) {
+ # prepare colors to be used for replacement
+ my $BN = uc($NOTEC);
+ my $_BN = uc($_NOTEC);
+ my $UN = $NOTEC;
+ $UN =~ s/<(.*)>/<$1_>/;
+ my $_UN = $UN;
+ $_UN =~ s/<(.*)>/<\/$1>/;
+ my $IN = $NOTEC;
+ my $_IN = $_NOTEC;
+ $IN =~ s/<(.*)>/<$1I>/;
+ $_IN =~ s/<(.*)>/<$1I>/;
+
+ if ($conf{formattext} eq "simple") {
+ $note =~ s/\*([^\*]*)\*/$BN$1$_BN/g;
+ $note =~ s/_([^_]*)_/$UN$1$_UN/g;
+ $note =~ s/{([^}]*)}/$IN$1$_IN/g;
+ $note =~ s#(?$1#g;
+ }
+ else {
+ $note =~ s/\*\*([^\*]{2,})\*\*/$BN$1$_BN/g;
+ $note =~ s/__([^_]{2,})__/$UN$1$_UN/g;
+ $note =~ s/{{([^}]{2,})}}/$IN$1$_IN/g;
+ $note =~ s#//([^/]{2,})//#$1#g;
+ }
+
+ $note =~ s/(<\/.*>)/$1$NOTEC/g;
+ }
+ $note;
+}
+
+sub output {
+ my($SSS, $LINE, $num, $note, $time, $TYPE, $L, $LONGSPC, $R, $PathLen, $SP, $title, $CUTSPACE,
+ $VersionLen, $len, $diff, $Space, $nlen, $txtlen, $count);
+ ($num, $note, $time, $TYPE, $count) = @_;
+
+ $txtlen = ($ListType eq "LONG") ? $maxlen : $timelen + $maxlen;
+ $note = &format($note);
+
+ $SSS = "-" x ($maxlen + 30);
+ $nlen = length("$num");
+ $LINE = "$BORDERC $SSS $_BORDERC\n";
+ $LONGSPC = " " x (25 - $nlen);
+ if ($conf{printlines}) {
+ $L = $BORDERC . "[" . $_BORDERC;
+ $R = $BORDERC . "]" . $_BORDERC;
+ }
+ $PathLen = length($PATH); # will be ZERO, if not in TOPIC mode!
+ $VersionLen = length($version) + 7;
+
+ if ($TYPE ne "SINGLE") {
+ if (!$SetTitle) {
+ $SP = "";
+ # print only if it is the first line!
+ $SP = " " x ($maxlen - 2 - $PathLen - $VersionLen);
+ if (!$Raw) {
+ # no title in raw-mode!
+ print C $LINE if ($conf{printlines});
+ print C "$L $NUMC#$_NUMC ";
+ if ($ListType eq "LONG") {
+ print C " $TIMEC" . "creation date$_TIMEC ";
+ }
+ else {
+ print $LONGSPC if ($conf{printlines});
+ }
+ if ($TOPIC) {
+ print C $TOPICC . "$PATH $_TOPICC$SP" . " note $version $R\n";
+ }
+ else {
+ print C $NOTEC . "note$_NOTEC$SP" . " note $version $R\n";
+ }
+ print C $LINE if ($conf{printlines});
+ }
+ $SetTitle = 1;
+ }
+ $title = "";
+ $CUTSPACE = " " x $txtlen;
+ if ($TYPE eq "search") {
+ $note =~ s/^\Q$conf{topicseparator}\E.+?\Q$conf{topicseparator}\E\n//;
+ }
+ $note =~ s/\n/$CUTSPACE/g;
+ $len = length($note);
+ if ($len < ($txtlen - 2 - $nlen)) {
+ $diff = $txtlen - $len;
+ if (!$Raw) {
+ if ($num eq "-") {
+ $Space = " " x $diff;
+ $title = $BORDERC . $TOPICC . $note . " " . $_TOPICC . $Space . "$_BORDERC";
+ }
+ else {
+ $Space = " " x ($diff - ($nlen - 1));
+ $title = $BORDERC . $NOTEC . $note . " " . $_NOTEC . $Space . "$_BORDERC";
+ }
+ }
+ else {
+ $title = $note;
+ }
+ }
+ else {
+ $title = substr($note,0,($txtlen - 2 - $nlen));
+ if (!$Raw) {
+ $title = $BORDERC . $NOTEC . $title . " $_NOTEC$_BORDERC";
+ }
+ }
+ if ($Raw) {
+ print "$num ";
+ print "$time " if($ListType eq "LONG");
+ if ($title =~ /^ => (.*)$conf{topicseparator} (.*)$/) {
+ $title = "$1$conf{topicseparator} $2"; # seems to be a topic!
+ }
+ print "$title\n";
+ }
+ else {
+ # $title should now look as: "A sample note "
+ print C "$L $NUMC$num$_NUMC $R";
+ if ($ListType eq "LONG") {
+ print C "$L$TIMEC" . $time . " $_TIMEC$R";
+ }
+ print C "$L $NOTEC" . $title . "$_NOTEC $R\n";
+ print C $LINE if ($conf{printlines});
+ }
+ }
+ else {
+ # we will not reach this in raw-mode, therefore no decision here!
+ chomp $note;
+ $Space = " " x (($maxlen + $timelen) - $nlen - 16);
+ print C $LINE if ($conf{printlines});
+ print C "$L $NUMC$num$_NUMC $R$L$TIMEC$time$_TIMEC $Space$R\n";
+ print "\n";
+ print C $NOTEC . $note . $_NOTEC . "\n";
+ print C $LINE if ($count == 1 && $conf{printlines});
+ }
+ }
+
+
+
+sub C {
+ my($default, $S, $Col, $NC, $T);
+ $default = "\033[0m";
+ $S = $_[0];
+ foreach $Col (%Color) {
+ if ($S =~ /<$Col>/g) {
+ if ($conf{usecolors}) {
+ $NC = "\033[" . $Color{$Col} . "m";
+ $S =~ s/<$Col>/$NC/g;
+ $S =~ s/<\/$Col>/$default/g;
+ }
+ else {
+ $S =~ s/<$Col>//g;
+ $S =~ s/<\/$Col>//g;
+ }
+ }
+ }
+ return $S;
+ }
+
+
+
+sub num_bereich {
+ my($m,@LR,@Sorted_LR,$i);
+ # $number is the one we want to delete!
+ # But does it contain commas?
+ @NumBlock = (); #reset
+ $m = 0;
+ if ($number =~ /\,/) {
+ # accept -d 3,4,7
+ @NumBlock = split(/\,/,$number);
+ }
+ elsif ($number =~ /^\d+\-\d+$/) {
+ # accept -d 3-9
+ @LR = split(/\-/,$number);
+ @Sorted_LR = ();
+
+ if ($LR[0] > $LR[1]) {
+ @Sorted_LR = ($LR[1], $LR[0]);
+ }
+ elsif ($LR[0] == $LR[1]) {
+ # 0 and 1 are the same
+ @Sorted_LR = ($LR[0], $LR[1]);
+ }
+ else {
+ @Sorted_LR = ($LR[0], $LR[1]);
+ }
+
+ for ($i=$Sorted_LR[0]; $i<=$Sorted_LR[1]; $i++) {
+ # from 3-6 create @NumBlock (3,4,5,6)
+ $NumBlock[$m] = $i;
+ $m++;
+ }
+ }
+ else {
+ @NumBlock = ($number);
+ }
+
+ }
+
+sub getdate {
+ my($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
+ $year += 1900;
+ $mon += 1;
+ $mon =~ s/^(\d)$/0$1/;
+ $hour =~ s/^(\d)$/0$1/;
+ $min =~ s/^(\d)$/0$1/;
+ $sec =~ s/^(\d)$/0$1/;
+ $mday =~ s/^(\d)$/0$1/;
+ if ($conf{timeformat}) {
+ my $back = $conf{timeformat};
+ $back =~ s/YYYY/$year/;
+ $back =~ s/YY/substr($year, 1, 2)/e;
+ $back =~ s/MM/$mon/;
+ $back =~ s/DD/$mday/;
+ $back =~ s/mm/$min/;
+ $back =~ s/hh/$hour/;
+ $back =~ s/ss/$sec/;
+ return $back;
+ }
+ return "$mday.$mon.$year $hour:$min:$sec";
+ }
+
+
+sub gettemp {
+ my($random, @range);
+ @range=('0'..'9','a'..'z','A'..'Z');
+ srand(time||$$);
+ for (0..10) {
+ $random .= $range[rand(int($#range)+1)];
+ }
+ my $tempfile = File::Spec->catfile($conf{tempdirectory}, $USER . $random);
+ if (-e $tempfile) {
+ # avoid race conditions!
+ unlink $tempfile;
+ }
+ return $tempfile;
+ }
+
+
+
+sub help {
+ my $B = "";
+ my $BB = "";
+ my($S, $L, $T, $Q, $H, $N, $D, $E);
+ $L = $B . "L" . $BB . $NOTEC;
+ $T = $B . "T" . $BB . $NOTEC;
+ $Q = $B . "Q" . $BB . $NOTEC;
+ $H = $B . "?" . $BB . $NOTEC;
+ $N = $B . "N" . $BB . $NOTEC;
+ $D = $B . "D" . $BB . $NOTEC;
+ $E = $B . "E" . $BB . $NOTEC;
+ $S = $B . "S" . $BB . $NOTEC;
+
+ print C qq~$BORDERC
+----------------------------------------------------------------------$_BORDERC $TOPICC
+HELP for interactive note $version
+$_TOPICC $NOTEC
+The following commands are available:
+$L List notes. L=long, with timestamp and l=short without timestamp.
+ You can also just hit for short list.
+ If you specify a subtopic, then list will display it's contents,
+ i.e.: "l mytopic" will dislpay notes under mytopic.
+$N Create a new note.
+$D Delete a note. You can either hit "d 1" or "d 1-4" or just hit "d".
+ If you don't specify a number, you will be asked for.
+$S Search trough the notes database. Usage is similar to Delete, use
+ a string instead of a number to search for.
+$E Edit a note. Usage is similar to Delete but you can only edit note
+ a time.
+$H This help screen.
+$Q Exit the program.~;
+ if ($TOPIC) {
+ print C qq~
+$T print a list of all existing topics as a tree. T prints the tree
+ with all notes under each topic.~;
+ }
+ print C qq~
+
+All commands except the List and Topic commands are case insensitive.
+Read the note(1) manpage for more details.$BORDERC
+----------------------------------------------------------------------$_BORDERC
+~;
+ }
+
+
+sub display_tree {
+ # displays a tree of all topics
+ my(%TREE, %res, $n, $t, $num, @nodes, $firstline, $text, $untext);
+ %res = $db->get_all();
+ foreach $num (keys %res) {
+ $n = $res{$num}->{'note'};
+ $t = $res{$num}->{'date'};
+ # this allows us to have multiple topics (subtopics!)
+ my ($firstline,$text,$untext) = split /\n/, $n, 3;
+ if ($firstline =~ /^($conf{topicseparator})/) {
+ $firstline =~ s/($conf{topicseparator})*$//; #remove Topicseparator
+ @nodes = split(/$conf{topicseparator}/,$firstline);
+ }
+ else {
+ @nodes = (); #("$conf{topicseparator}");
+ $text = $firstline;
+ }
+ &tree($num, $text, \%TREE, @nodes);
+ }
+ #return if ($num == 0);
+ # now that we have build our tree (in %TREE) go on t display it:
+ print C $BORDERC . "\n[" . $conf{topicseparator} . $BORDERC . "]\n";
+ &print_tree(\%{$TREE{''}},"") if(%TREE);
+ print C $BORDERC . $_BORDERC . "\n";
+}
+
+
+sub tree {
+ my($num, $text, $LocalTree, $node, @nodes) = @_;
+ if (@nodes) {
+ if (! exists $LocalTree->{$node}->{$NoteKey}) {
+ $LocalTree->{$node}->{$NoteKey} = [];
+ }
+ &tree($num, $text, $LocalTree->{$node}, @nodes);
+ } else {
+ if (length($text) > ($maxlen - 5)) {
+ $text = substr($text, 0, ($maxlen -5));
+ }
+ $text = $text . " (" . $NUMC . "#" . $num . $_NUMC . $NOTEC . ")" . $_NOTEC if($text ne "");
+ push @{$LocalTree->{$node}->{$NoteKey}}, $text;
+ }
+}
+
+
+sub print_tree {
+ # thanks to Jens for his hints and this sub!
+ my $hashref=shift;
+ my $prefix=shift;
+ my @notes=@{$hashref->{$NoteKey}};
+ my @subnotes=sort grep { ! /^$NoteKey$/ } keys %$hashref;
+ if ($TreeType eq "LONG") {
+ for my $note (@notes) {
+ if ($note ne "") {
+ print C $BORDERC ; # . $prefix. "|\n";
+ print C "$prefix+---<" . $NOTEC . $note . $BORDERC . ">" . $_NOTEC . "\n";
+ }
+ }
+ }
+ for my $index (0..$#subnotes) {
+ print C $BORDERC . $prefix. "|\n";
+ print C "$prefix+---[" . $TOPICC . $subnotes[$index] . $BORDERC . "]\n";
+ &print_tree($hashref->{$subnotes[$index]},($index == $#subnotes?"$prefix ":"$prefix| "));
+ }
+}
+
+
+sub getconfig {
+ my($configfile) = @_;
+ my ($home, $value, $option);
+ # checks are already done, so trust myself and just open it!
+ open CONFIG, "<$configfile" || die $!;
+ while () {
+ chomp;
+ next if(/^\s*$/ || /^\s*#/);
+ my ($option,$value) = split /\s\s*=?\s*/, $_, 2;
+
+ $value =~ s/\s*$//;
+ $value =~ s/\s*#.*$//;
+ if ($value =~ /^(~\/)(.*)$/) {
+ $value = File::Spec->catfile($ENV{HOME}, $2);
+ }
+
+ if ($value =~ /^(yes|on|1)$/i) {
+ $value = 1;
+ }
+ elsif ($value =~ /^(no|off|0)$/i) {
+ $value = 0;
+ }
+
+ $option = lc($option);
+
+ if ($option =~ /^(.+)::(.*)$/) {
+ # driver option
+ $driver{$1}->{$2} = $value;
+ }
+ else {
+ # other option
+ $conf{$option} = $value;
+ }
+ }
+
+ close CONFIG;
+}
+
+
+sub complete {
+ my ($text, $line, $start) = @_;
+
+ if ($line =~ /^\s*$/) {
+ # notes or topics allowed
+ return @completion_topics, @completion_notes;
+ }
+ if ($line =~ /^cd/) {
+ # only topics allowed
+ return @completion_topics, "..";
+ }
+ if ($line =~ /^l/i) {
+ # only topics allowed
+ return @completion_topics;
+ }
+ if ($line =~ /^[ed]/) {
+ # only notes allowed
+ return @completion_notes;
+ }
+ if ($line =~ /^[snt\?q]/i) {
+ # nothing allowed
+ return ();
+ }
+}
+
+sub load_driver {
+ my ($parent) = @_;
+
+ if ($parent) {
+ my $pkg = "NOTEDB";
+ eval "use $pkg;";
+ if ($@) {
+ die "Could not load the NOTEDB module: $@\n";
+ }
+ }
+ else {
+ # load the backend driver
+ my $pkg = "NOTEDB::$conf{dbdriver}";
+ eval "use $pkg;";
+ if ($@) {
+ die "$conf{dbdriver} backend unsupported: $@\n";
+ }
+ else {
+ $db = $pkg->new(%{$driver{$conf{dbdriver}}});
+ }
+ }
+}
+
+
+__END__
diff --git a/config/noterc b/config/noterc
index 4bc7226..e306ca0 100644
--- a/config/noterc
+++ b/config/noterc
@@ -1,4 +1,4 @@
- # note 1.3.1 -*- sh -*-
+ # note 1.3.3 -*- sh -*-
#
# This is a sample config for the note script
# There are useful defaults set in note itself.
@@ -232,6 +232,13 @@ ReadOnly = NO
+ #
+ # Note separates titles and topics using horizontal lines when
+ # listing them. You can turn off this behavior by setting
+ # PrintLines to NO.
+ # The default is: YES
+PrintLines = YES
+
#
#
diff --git a/pm_to_blib b/pm_to_blib
new file mode 100644
index 0000000..e69de29