From 4b31b18031c427e0ed67825c531665e6ca6cce92 Mon Sep 17 00:00:00 2001 From: "Konstantin A. Lepikhov" Date: Wed, 10 Nov 2021 23:47:45 +0100 Subject: [PATCH 01/10] Add mailman2sympa migration script with my additions mailman2sympa 0.7, Konstantin Lepikhov - Nov 2020 + rewrote configuration parsing (use python unpickle) + import list info (if exists) + don't import if list host_name doesn't match + handle unicode names for users/subscribers --- utils/mailman2sympa/BUGS | 7 + utils/mailman2sympa/Changes | 90 +++++ utils/mailman2sympa/README | 57 +++ utils/mailman2sympa/TODO | 18 + utils/mailman2sympa/awk/.subscribers.awk.swp | Bin 0 -> 12288 bytes utils/mailman2sympa/awk/test_multipart.awk | 23 ++ .../mailman2sympa/conf/mailman2sympa.conf.alt | 127 ++++++ .../conf/mailman2sympa.conf.debian | 129 ++++++ .../conf/mailman2sympa.conf.local | 125 ++++++ utils/mailman2sympa/docs/COPYING | 340 ++++++++++++++++ utils/mailman2sympa/docs/INSTALL | 58 +++ utils/mailman2sympa/docs/LICENCE | 32 ++ utils/mailman2sympa/lib/mmparse.pm | 145 +++++++ utils/mailman2sympa/loadsubscribers.sh | 7 + utils/mailman2sympa/mailman2sympa.sh | 106 +++++ utils/mailman2sympa/old/README | 2 + utils/mailman2sympa/old/mailman2sympa.awk | 192 +++++++++ utils/mailman2sympa/old/mailman2sympa.sh | 101 +++++ utils/mailman2sympa/old/subscribers.awk | 142 +++++++ utils/mailman2sympa/scripts/dispatch_messages | 20 + utils/mailman2sympa/scripts/getmailmanarchive | 76 ++++ .../mailman2sympa/scripts/loadsubscribers.pl | 382 ++++++++++++++++++ utils/mailman2sympa/scripts/mboxsplit | 89 ++++ utils/mailman2sympa/scripts/mm2s_admins | 47 +++ utils/mailman2sympa/scripts/mm2s_aliases | 24 ++ utils/mailman2sympa/scripts/mm2s_blacklist | 47 +++ utils/mailman2sympa/scripts/mm2s_config | 285 +++++++++++++ utils/mailman2sympa/scripts/mm2s_info | 18 + utils/mailman2sympa/scripts/mm2s_subscribers | 92 +++++ utils/mailman2sympa/scripts/mm2s_unpickle.py | 27 ++ utils/mailman2sympa/scripts/mm2s_users | 58 +++ utils/mailman2sympa/utils/README | 16 + utils/mailman2sympa/utils/add_members | 64 +++ utils/mailman2sympa/utils/list_members | 94 +++++ utils/mailman2sympa/utils/remove_members | 133 ++++++ 35 files changed, 3173 insertions(+) create mode 100644 utils/mailman2sympa/BUGS create mode 100644 utils/mailman2sympa/Changes create mode 100644 utils/mailman2sympa/README create mode 100644 utils/mailman2sympa/TODO create mode 100644 utils/mailman2sympa/awk/.subscribers.awk.swp create mode 100644 utils/mailman2sympa/awk/test_multipart.awk create mode 100755 utils/mailman2sympa/conf/mailman2sympa.conf.alt create mode 100755 utils/mailman2sympa/conf/mailman2sympa.conf.debian create mode 100755 utils/mailman2sympa/conf/mailman2sympa.conf.local create mode 100644 utils/mailman2sympa/docs/COPYING create mode 100644 utils/mailman2sympa/docs/INSTALL create mode 100644 utils/mailman2sympa/docs/LICENCE create mode 100755 utils/mailman2sympa/lib/mmparse.pm create mode 100755 utils/mailman2sympa/loadsubscribers.sh create mode 100755 utils/mailman2sympa/mailman2sympa.sh create mode 100644 utils/mailman2sympa/old/README create mode 100644 utils/mailman2sympa/old/mailman2sympa.awk create mode 100755 utils/mailman2sympa/old/mailman2sympa.sh create mode 100644 utils/mailman2sympa/old/subscribers.awk create mode 100755 utils/mailman2sympa/scripts/dispatch_messages create mode 100755 utils/mailman2sympa/scripts/getmailmanarchive create mode 100755 utils/mailman2sympa/scripts/loadsubscribers.pl create mode 100755 utils/mailman2sympa/scripts/mboxsplit create mode 100755 utils/mailman2sympa/scripts/mm2s_admins create mode 100755 utils/mailman2sympa/scripts/mm2s_aliases create mode 100755 utils/mailman2sympa/scripts/mm2s_blacklist create mode 100755 utils/mailman2sympa/scripts/mm2s_config create mode 100755 utils/mailman2sympa/scripts/mm2s_info create mode 100755 utils/mailman2sympa/scripts/mm2s_subscribers create mode 100755 utils/mailman2sympa/scripts/mm2s_unpickle.py create mode 100755 utils/mailman2sympa/scripts/mm2s_users create mode 100644 utils/mailman2sympa/utils/README create mode 100755 utils/mailman2sympa/utils/add_members create mode 100755 utils/mailman2sympa/utils/list_members create mode 100755 utils/mailman2sympa/utils/remove_members diff --git a/utils/mailman2sympa/BUGS b/utils/mailman2sympa/BUGS new file mode 100644 index 0000000..8adb600 --- /dev/null +++ b/utils/mailman2sympa/BUGS @@ -0,0 +1,7 @@ +BUGS: + +The script to load the admins doesn't query the comment_user correctly + +Non-[a-z] characters in Gecos are escaped \xf3 + +probably other stuff too. diff --git a/utils/mailman2sympa/Changes b/utils/mailman2sympa/Changes new file mode 100644 index 0000000..73c82ae --- /dev/null +++ b/utils/mailman2sympa/Changes @@ -0,0 +1,90 @@ +mailman2sympa 0.7, Konstantin Lepikhov - Nov 2020 + ++ rewrote configuration parsing (use python unpickle) ++ import list info (if exists) ++ don't import if list host_name doesn't match ++ handle unicode names for users/subscribers + +mailman2sympa 0.5, John Bazik - May 2010 + ++ rewrote awk mailman config parsing scripts in perl ++ broke up scripts so that there is one per file generated ++ added translations for more list options ++ added ban_list/blacklist translation ++ dropped old-style subscriber list generation ++ made mailman2sympa.sh a little more concise ++ added mm2s_info script to pull list description info (not integrated) ++ added list_, add_ and remove_members mailman-like scripts + +mailman2sympa 0.4, Daniel Black - March 2009 + ++ fixed lots to make it work with mailman-2.1.9 ++ user gecos data now imported ++ mailman user options now respected that bit more ++ admin data now migrated ++ lots more error checking to you don't overwrite stuff unitentionall ++ additional database name to preview the changes in ++ parses mbox archives so no mime hacks are needed ++ email addresses with + now work + +mailman2sympa 0.0.2, Andreas de Pretis - February 2003 + + +mailman2sympa.awk +- ----------------- ++) moved to awk/mailman2sympa.awk ++) modified format for aliases (match sympa-generated + format) ++) added review, invite, clean_delay_queuemod, domain, footer_type + owner, digest, type_archive, expire_task, spam_protection, + web_archive_spam_protection, date_epoch, date, profile and + the resulting printfs, etc. ++) removed remind_task ++) compatibility with latest sympa-version (3.4.3) + +subscribers.awk +- --------------- ++) moved to awk/subscribers.awk ++) added password-support ++) modified CSV-Format (null instead of _null_, ...) + +mailman2sympa.sh +- ---------------- ++) ask user to run loadsubscribers.sh automatically (y/n) ++) created $WDIR if it doesn't exist ++) create CSV-Files in $WDIR/csv as import_users.csv + and import_subscribers.csv ++) added DOMAIN=$DOMAIN, SMTPSCRIPTPATH=$SYMPA_SMTPSCRIPTS and + OWNER=$DEFAULT_OWNER when running awk/mailman2sympa.awk ++) added support for ISO-8859-1 Charset (parse $WDIR/lists/$f) + +load_subscribers_Pg.pl +- ---------------------- ++) removed because it won't be used by load_subscribers_Pg.sh + (which used the loadsubscribers.pl in sympa-home (/bin or /sbin) + +load_subscribers_Pg.sh +- ---------------------- ++) removed because of new CSV-Import + +mailman2sympa.conf +- ------------------ ++) added 1990-1997 to YEARS ++) default WDIR is /tmp/mailman ++) added DEFAULT_OWNER ++) added CLEANTABLES ++) added HOSTDB and PASSWORDDB ++) added SYMPA_SBIN, SYMPA_LIB and SYMPA_SMTPSCRIPTS ++) default USER and GROUP set to 'sympa' (if you install + sympa as described in the documentation, apache must not + be the owner of expldir and arcdir ++) added empty line between parameters/settings + +general +- ------- ++) moved *.pl and additional sh-scripts to scripts ++) moved awk-scripts to awk ++) moved INSTALL, LICENCE and COPYING to docs ++) moved mailman2sympa.conf to conf ++) slightly modified README and INSTALL to match my changes + diff --git a/utils/mailman2sympa/README b/utils/mailman2sympa/README new file mode 100644 index 0000000..1a924b6 --- /dev/null +++ b/utils/mailman2sympa/README @@ -0,0 +1,57 @@ +Presentation +------------ + +Mailman2sympa is a set of scripts aimed to facilitate the migration +of mailing list managed by mailman to sympa. + +The problem with such scripts is that they are used only once by +an individual. So it may be difficult to find a permanent +project manager. + +I hope that each user will have the good idea to send back all +enhancement they would have to apply to the package. + +Features +-------- + +The version 0.0.3 of the package can do the following tasks: + +- create one list in sympa for each list found in the + mailman space. + +- create the subscribers files et config files for each list + with the appropriates attributes, when still relevant. + +- creates an aliases file to be concatenated at the bottom + of /etc/aliases. + +- split the archives stored by mailman into the mhonarc + archive directory + +- in the limited extent, restore the Content-type header + when the message is multipart, so that mhonarc may + nicely process attachments. + +- load the subscribers files into the database. Can specify + a different database (NEW_DATABASE) for testing. Change + NEW_DATABASE=DATABASE for migration + +This scripts gave me a good result, but I'm not sure they +would for you. If you have problems, I can take an hand, +but as my lists have already been migrated, I donr't have +anymore a test bed to run the software. + +You can contact me at pallart@illico.org + +Hope this helps. + +Philippe Allart + + +DumperSwitchboard problem - edit $MAILMAN_HOME/bin/dumpdb as follows: +http://arkiv.netbsd.se/?ml=mailman-users&a=2007-07&t=4791032 + +Required packages: +gawk +libdbd-csv-perl +procmail (for archive migration) diff --git a/utils/mailman2sympa/TODO b/utils/mailman2sympa/TODO new file mode 100644 index 0000000..9035da2 --- /dev/null +++ b/utils/mailman2sympa/TODO @@ -0,0 +1,18 @@ +Things that are converted: +user language preferences, +user bounce status + +Lst config headers and footers + +email addresses like +'=?iso-8859-15?q?=22fred_fr=f6hlich_=28gremlin_list=29?=' + + +Some posting rules are not converted correctly. In particular, +announce-only lists (what sympa calls a "newsletter") wind up +moderated for everyone. To tinker with this, edit the mm2s_config +script and look for the "send" rule in there. + +The mm2s_info script doesn't always work, and isn't integrated into +the framework. The info field in mailman is just a field, but in +sympa it's a separate file. diff --git a/utils/mailman2sympa/awk/.subscribers.awk.swp b/utils/mailman2sympa/awk/.subscribers.awk.swp new file mode 100644 index 0000000000000000000000000000000000000000..6dddd9029c76ca0b3178c373779dc97e0300c9f4 GIT binary patch literal 12288 zcmeI2OKjXk7{{kP3Jawm5b6mu@wV(E*+({M`UnmQB&s5sw4|j)Y&I+JW|EqC?Ul#d z5JC_YHx8|YRK#0cxN$+^(F+`bVyzZJc=JGs#Z%r}o6*~|+upI{mO8v#8)h#iO>h#iO>h#iO>h#j~E9PpYu$iJA!ZQwlE;e(I(6*~|+5IYb%5IYb%5IYb% z5IYb%5IYb%5IYb%aEmx#%oB1Qb2)H3-thnb;@<%NzMqi4z#rgua1C4lya7AHWsxId~tu3*G^5gLA+FC%`1w4@#g2 z3gC9|<1RwJ0H1+R!9`$!7k~+lfh6bw6zl|7@5Q*_3iuve248|Vz>A;^CO|KsU=R4` z9?TD10v8%m5AC3ohLOJ@7a<1Re%AP%G!a8h8mD0-}C~!2jg6MiNcew7rG2 zR;23BKCbmqyH<@n$daKWlukT%{3z858a+CB;v~Ls&+xc5OcKzLgi8DPF#g((-Czwo z2P1ye9lOp93kSthGqW~^5Hc7DeQ>0Yj*p$3z&IoH^!Vfq!w!E7`g*NaAy$6+yM z!d#%~aD=MVDEnF!s_V2rLsv;+!Ew<|4M9ztt~*2aStF1OOi-am-Xo#)igL?cHH@!2#cV2XijJLXfNy#o&_Ue z1Szv2qwPnRq{p3E4d+JpaT#NHAVWpoHd7NB3s0dvI@Ltt5ef1Xh9>7N2WZWK62Ag)?2cNyE@Btbe~Bee5xMa_s4e>h!UxvB{&luGtQZ z#iH{}yTwHARW6;TM{|BPB-C2eWoaambll`d&0^!sGS4!1#UBG_j07|3&?rgOa898L z#+<<_fX1<9`?$kB9#tx-bayBXN+qMd6oxWZU$UKLi_I^x4GM!@6b?!SnUPS#pU#xo zU{p*_WEE?KI=0m@w}V~u`iG=oyV7*czktbviySFmhPs?Qpqxq46Rl>`Wt<=Pm+lN} znD#t#X%5#RkK*EHu?Dj}HZLws@+rcoRRi6;8d7E@sqgVLF0zJKKV#a9C!MBQ=MZlg zD>b&IA%?n{*klEv@DP3n0x-L_Ls=W~-s1@(;mHtkq zE+OrGED>xvdhmq@K|&$e8}#5yv{9@pIbpRt|vT+E%X)E3PK4&ZF{;11*XbaL!MVv_q_bU?!^IWTC84wPg}nnO!q059-lSMV$U{k!i|F3g`WuF?vQt zO-{97`xAGH{+wje+7`LYYq>UdV2)LccO-t1*|9xL>`!aiR zYpKo7_KS~2ym6GpLd&j;n(inVE{aqHx0(KS)Wa&;vU)aMF6ItZvYGOn{M;;lzrNP% zdycr+xVXa-6PBqHR`t9>wS0CopT(lZZ(Y;Sm=xb47MACX+)HD*=P`c1nyaMC9Y3?9 zk>5EPXuCaE$!EJoEb`PIV)Y5yn@$NC3{kCQQ-^7JwOpaS8KkZ}H(J3Mb16utLbcM( T@~18U!Su + Copyright (C) + + 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 + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/utils/mailman2sympa/docs/INSTALL b/utils/mailman2sympa/docs/INSTALL new file mode 100644 index 0000000..953bf94 --- /dev/null +++ b/utils/mailman2sympa/docs/INSTALL @@ -0,0 +1,58 @@ +Mailman Installation Guide +-------------------------- + + +If you are able to read this file , you probably accomplished the main part of installation: + +- Get mailman2sympa-.tgz + +- unpack the package: tar -xzvf mailman2sympa-.tgz + +- enter the mailman2sympa- directory + +Now you still have to configure mailman2sympa: + +- edit conf/mailman2sympa.conf + The file is well documented (I hope). Just follow instructions + + +And lauch the task: + +./mailman2sympa.sh + +After completion +---------------- + +- a directory is created under the $EXPL directory of sympa + +- in each directory you can find a config file and a subscribers file. + +- if you asked it, you will find all messages splited under the mhonarc archive directory. + You may now use the web interface, connect as listmaster (as specified in /etc/sympa.conf) + go to "sympa admin" and ask for converting all lists to html. Click only once on the + button, don't care about the error message (sympa 3.2.1). The process runs in the + background, and may take a long time. + +- you can add the file $WDIR/aliases-sympa at the bottom of /etc/aliases. + If you chose to set a prefix, you don't still have to remove mailman lists aliases. + Run "rewaliases". + +- load the subscribers files into the database. + You've got two options: loading subscribers from sympa list-subscriber-files (via + 'loadsubscribers_from_config.sh') or mailman2sympa-generated CSV-Files in WDIR (see + 'conf/mailman2sympa.conf') + +- run 'crypt_passwords.pl' from sympa-directory (usually in /sbin or /bin) + + +For 'mailman2sympa.sh' you can give as parameter a file name containing the names of the +lists to process. One name per line. By default, all lists of mailman are processed. + +Example: +./mailman2sympa.sh restricted_liste + + +Enjoy! + +Philippe Allart + diff --git a/utils/mailman2sympa/docs/LICENCE b/utils/mailman2sympa/docs/LICENCE new file mode 100644 index 0000000..dde59ef --- /dev/null +++ b/utils/mailman2sympa/docs/LICENCE @@ -0,0 +1,32 @@ +LICENCE OF USE, COPYING, MODIFICATION AND DISTRIBUTION OF MAIMAN2SYMPA +------------------------------------------------------------------- + +You can use freely and without cost this set of script. + +For copying, modification and distribution you must follow +the tems of the General Public Licence (GPL). See the file +COPYING which is part of the package for more details. + +Use the script at your own risks. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. diff --git a/utils/mailman2sympa/lib/mmparse.pm b/utils/mailman2sympa/lib/mmparse.pm new file mode 100755 index 0000000..116e2f8 --- /dev/null +++ b/utils/mailman2sympa/lib/mmparse.pm @@ -0,0 +1,145 @@ +# mmparse.pm +# +# Parse the output of mailman's dumpdb command. Returns a hash. +# Author: John Bazik +# +# Copyright 2010 Brown University +# +# 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. + +package mmparse; + +use strict; +use warnings; + +use base qw(Exporter); +our @EXPORT = qw(mmparse); + +our $debug = 0; + +sub mmparse { + my $mmcfg = shift; + # + # skip to the beginning + # + $mmcfg =~ /[^{]*/sg; + + my @stk; + while (1) { + # + # single-quoted string + # + if ($mmcfg =~ /\G\s*([ur]+)?'([^'\\]*(?:\\.[^'\\]*)*)'/scg) { + push @stk, defined $2 ? procstr($1, $2) : ''; + warn "STRING->'$1'\n" if $debug; + } + # + # double-quoted string + # + elsif ($mmcfg =~ /\G\s*([ur]+)?"([^"\\]*(?:\\.[^"\\]*)*)"/scg) { + push @stk, defined $2 ? procstr($1, $2) : ''; + warn qq(STRING->"$1"\n) if $debug; + } + # + # pretty-printed reference (just save as a string) + # + elsif ($mmcfg =~ /\G\s*<([^>\\]*(?:\\.[^>\\]*)*)>/scg) { + push @stk, $1; + warn qq(REF->"$1"\n) if $debug; + } + # + # number + # + elsif ($mmcfg =~ /\G\s*(\d+(?:\.\d+)?)/scg) { + push @stk, $1; + warn "NUMBER->$1\n" if $debug; + } + # + # a word + # + elsif ($mmcfg =~ /\G\s*(\w+)/scg) { + push @stk, $1; + warn "WORD->$1\n" if $debug; + } + # + # start of an array or tuple + # + elsif ($mmcfg =~ /\G\s*[\[(]/scg) { + push @stk, undef; + warn "ARRAY START\n" if $debug; + } + # + # start of a hash + # + elsif ($mmcfg =~ /\G\s*\{/scg) { + push @stk, undef; + warn "HASH START\n" if $debug; + } + # + # end of an array or tuple + # + elsif ($mmcfg =~ /\G\s*[\])]/scg) { + my @array; + while (@stk) { + my $elmt = pop @stk; + last unless defined $elmt; + unshift @array, $elmt; + } + push @stk, \@array; + warn "ARRAY END\n" if $debug; + } + # + # end of a hash + # + elsif ($mmcfg =~ /\G\s*\}/scg) { + my %hash; + while (@stk) { + my $val = pop @stk; + last unless defined $val; + my $key = pop @stk; + $hash{$key} = $val; + } + push @stk, \%hash; + warn "HASH END\n" if $debug; + + last if @stk == 1; # done processing + } + # + # skip everything else - comments? + # + elsif ($mmcfg =~ /\G([^\w'"\d\[\]{}<>()]+)/scg) { + warn "SKIP->$1\n" if $debug; + # skip everything else + } + elsif ($mmcfg =~ /\G$/scg) { + die "parsing failed, stack contains ", scalar(@stk), " elements\n"; + } + } + return $stk[0]; +} + +# +# procstr +# +# Apply string conversions here. +# +sub procstr { + my $mode = shift; # u for unicode, r for raw + my $string = shift; + + return $string; +} + +1; diff --git a/utils/mailman2sympa/loadsubscribers.sh b/utils/mailman2sympa/loadsubscribers.sh new file mode 100755 index 0000000..e48e798 --- /dev/null +++ b/utils/mailman2sympa/loadsubscribers.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +. ./conf/mailman2sympa.conf + +./scripts/loadsubscribers.pl + +# [ -x "${SYMPA_SMTPSCRIPTS}"/crypt_passwd.pl ] && "${SYMPA_SMTPSCRIPTS}"/crypt_passwd.pl diff --git a/utils/mailman2sympa/mailman2sympa.sh b/utils/mailman2sympa/mailman2sympa.sh new file mode 100755 index 0000000..3264873 --- /dev/null +++ b/utils/mailman2sympa/mailman2sympa.sh @@ -0,0 +1,106 @@ +#!/bin/sh + +# USAGE: ./mailman2sympa [list_name...] + +. conf/mailman2sympa.conf + +[ ! -d $WDIR ] && mkdir -p $WDIR +[ ! -d $EXPL ] && mkdir -p $EXPL +[ ! -d $WDIR/lists ] && mkdir $WDIR/lists +[ ! -d $WDIR/csv ] && mkdir $WDIR/csv + +[ $# = 0 ] && set `ls -1 $MAILMAN_VAR/lists/ | sed 's=/==g'` +echo "$@" | tr '[:upper:]' '[:lower:]' > $WDIR/mailman-lists + +echo +echo Picking up configuration of mailman lists + +for f in `cat $WDIR/mailman-lists` ; do + if [ -s $MAILMAN_VAR/lists/$f/config.pck ]; then + mmdb=$MAILMAN_VAR/lists/$f/config.pck + elif [ -s $MAILMAN_VAR/lists/$f/config.db ]; then + mmdb=$MAILMAN_VAR/lists/$f/config.db + else + echo "Warning list $f not found - skipping" + sed -i -e "/^$f\$/d" $WDIR/mailman-lists + continue + fi + ./scripts/mm2s_unpickle.py "$mmdb" > $WDIR/lists/$f +done + +echo +echo Creating configuration files for Sympa lists + +echo -n "" > $WDIR/aliases-sympa +echo -n "" > $WDIR/csv/import_admins.csv +echo -n "" > $WDIR/csv/import_users.csv +echo -n "" > $WDIR/csv/import_subscribers.csv + +for l in `cat $WDIR/mailman-lists` ; do + + host_name=$(jq -r .host_name < $WDIR/lists/$l) + if [ -n "$host_name" -a "$DOMAIN" != "$host_name" ]; then + echo "Skipping $l - domain doesn't match" + continue + fi + + [ ! -d $EXPL/$l ] && mkdir $EXPL/$l + + ./scripts/mm2s_config < $WDIR/lists/$l > $WDIR/$l.config + ./scripts/mm2s_aliases $l >> $WDIR/aliases-sympa + ./scripts/mm2s_admins < $WDIR/lists/$l >> $WDIR/csv/import_admins.csv + ./scripts/mm2s_users < $WDIR/lists/$l >> $WDIR/csv/import_users.tmp + # mailman users are created per list so filter out duplicated emails + # of course only one password will be used after but it's better than nothing + sort $WDIR/csv/import_users.tmp |sort -u -k1,1 -t';' > $WDIR/csv/import_users.csv + ./scripts/mm2s_subscribers < $WDIR/lists/$l >> $WDIR/csv/import_subscribers.csv + ./scripts/mm2s_blacklist < $WDIR/lists/$l > $WDIR/$l.blacklist + if jq -er .info < $WDIR/lists/$l >/dev/null; then + info=$(jq -r .info < $WDIR/lists/$l) + [ -n "$info" ] && printf '%s\n' "$info" > $WDIR/$l.info + fi + + if [ -f $EXPL/$l/config ] ; then + echo "Skipping $l - config already exists" + else + mv $WDIR/$l.config $EXPL/$l/config + [ -s $WDIR/$l.info ] && mv $WDIR/$l.info $EXPL/$l/info + fi + + if [ -s $WDIR/$l.blacklist ] ; then + [ ! -d $EXPL/$l/search_filters ] && mkdir $EXPL/$l/search_filters + mv $WDIR/$l.blacklist $EXPL/$l/search_filters/blacklist.txt + else + rm $WDIR/$l.blacklist + fi +done + +echo +echo Giving lists configuration to $USER +chown -R ${USER}:${GROUP} $EXPL + +if [ $CONVERT_ARCHIVE = "yes" ] ; then + echo + echo Converting Archives + for l in `cat $WDIR/mailman-lists` ; do + ./scripts/getmailmanarchive $l + done + echo "To regenerate web archive as listmaster go to 'Sympa Admin' and under 'Archive' is options to regenerate html" +fi + +echo +echo Cleaning temporary files... + +rm -rf $WDIR/lists/ + +echo +echo -n "Do you want to import users/subscribers/admins from CSV into the sympa database? [y/n]: " +read IMPORT + +if [ "$IMPORT" == "y" ]; then + ./loadsubscribers.sh +fi + +echo +echo Done. +echo diff --git a/utils/mailman2sympa/old/README b/utils/mailman2sympa/old/README new file mode 100644 index 0000000..2f4cc8a --- /dev/null +++ b/utils/mailman2sympa/old/README @@ -0,0 +1,2 @@ +These are scripts from version 0.4 which were modified or replaced. +They are here for reference. diff --git a/utils/mailman2sympa/old/mailman2sympa.awk b/utils/mailman2sympa/old/mailman2sympa.awk new file mode 100644 index 0000000..17b0e75 --- /dev/null +++ b/utils/mailman2sympa/old/mailman2sympa.awk @@ -0,0 +1,192 @@ +BEGIN { +subject = "Mailingliste " LIST; +domain=DOMAIN; +owner_set=0; +subscribe = "auth_notify"; +visibility = "conceal"; +lang = "de"; +anonymous_sender = ""; +max_size = 10000000; +footer_type = "append"; +private=1; +moderator = ""; +owner = OWNER; +reply_to_header = "sender"; +custom_subject = "[" LIST "]"; +send = "private"; +digest = "digest 0 23:0"; +archive = 1; +review = "owner"; +invite = "closed"; +clean_delay_queuemod = 20; +type_archive = "private"; +expire_task = "yearly"; +spam_protection = "at"; +web_archive_spam_protection = "at"; +date_epoch = "1042631682"; +date = "15 Jan 2003 at 12:54:42"; +profile = "privileged"; +} + +function GetValueS(s) { + res = gensub(".*: *['\"](.*)['\"] *, *$", "\\1", "g", s); + return gensub(".351", "é", "%03o", res); +} + +function GetValueN(s) { + res = gensub("^.*: *([0-9]*)[^0-9]*$", "\\1", "g", s); + return res; +} + +function GetValueL(s) { + list = gensub(".*: *[[][:space:]*([^]]*)[]].*", "\\1", "g", s); + gsub("[ ']", "", list); + return list; +} + +function GetEmail(s) { + res=gensub("^{? +('[a-z0-9_]*': [{[] +)?'([^@]*@[^']*)'.*$", "\\2", "g", s); + #res=gensub("^.*[^a-zA-Z0-9._-]([a-zA-Z0-9._-]*@[a-zA-Z0-9.-]*)[^a-zA-Z0-9.-].*$", "\\1", "g", s); + if (res !~ ".*@.*") res=""; + return tolower(res); +} + +/'subscribe_policy' *:/ { + res = GetValueN($0); + if (res==1) {subscribe = "auth_notify";} + else if (res==2) {subscribe = "owner";} + else {subscribe = "owner";} + } +/'anonymous_list' *:/ { + res = GetValueN($0); + if (res!=0) { + anonymous_sender= LIST "@" domain; + } + } +/'description' *:/ { + subject_value = GetValueS($0); + + if (subject_value) subject = subject_value; + } +/'max_message_size' *:/ { + max_size = GetValueN($0) * 1000; + } +/'member_posting_only' *:/{ + private=GetValueN($0); + } +/'moderated' *:/ { + moderated=GetValueN($0); + } +/'owner' *:.*]/ { + owners = GetValueL($0); + } +/'owner' *:[^]]*$/,/] *,/ { + owners = owners "," GetEmail($0); + } +/'moderator' *:[^]]*$/,/] *,/ { + moderators = moderators "," GetEmail($0); + } +/'advertised' *:/ { + if (GetValueN($0)!=0) visibility="noconceal"; + else visibility="conceal"; + } +/'reply_goes_to_list' *:/ { + if (GetValueN($0)!=0) reply_to_header="list"; + else reply_to_header="sender"; + } +/'subject_prefix' *:/ { + custom_subject=GetValueS($0); + } +/'archive' *:/ { + archive = GetValueN($0); +} +/'archive_private' *:/ { + if (GetValueN($0)!=0) type_archive = "private"; + else type_archive = "public"; +} + + +END { + split(owners, array_owners, ","); + for (i in array_owners) { + if (array_owners[i]~".*@.*" && !owner_set) { + printf("creation\ndate_epoch %s\ndate %s\nemail %s\n\n", date_epoch, date, array_owners[i]); + owner_set = 1; + } + printf("%s;owner;%s\n",array_owners[i], LIST) >> WDIR "/csv/import_admins.csv"; + } + split(moderators, array_moderators, ","); + for (i in array_moderators) { + printf("%s;editor;%s\n",array_moderators[i], LIST) >> WDIR "/csv/import_admins.csv"; + } + +# printf("lang %s\n\n", lang); + printf("topics aful\n\n"); + printf("visibility %s\n\n", visibility); + printf("user_data_source database\n\n"); + printf("clean_delay_queuemod %s\n\n", clean_delay_queuemod); + printf("expire_task %s\n\n", expire_task); + printf("spam_protection %s\n\n", spam_protection); + printf("web_archive_spam_protection %s\n\n", web_archive_spam_protection); + printf("%s\n\n", digest); + if (anonymous_sender != "") printf("anonymous_sender %s\n\n", + anonymous_sender); + printf("subject %s\n\n", subject); + if (custom_subject != "") printf("custom_subject %s\n\n", custom_subject); + if (private!=0) { + if (moderator == "") send = "private"; + else send="privateandeditorkey"; + } else { + if (moderator == "") send = "public"; + else send="editorkey"; + } + printf("send %s\n\n", send); + if (archive!=0) { + printf("archive\nperiod day\naccess %s\n\n", type_archive); + } + if (reply_to_header != "") printf("reply_to_header\nvalue %s\napply forced\n\n", + reply_to_header); + printf("subscribe %s\n\n", subscribe); + + printf("review %s\n\n", review); + printf("invite %s\n\n", invite); + + printf("footer_type %s\n\n", footer_type); + + printf("max_size %s\n\n", max_size); + + for (i in array_owners) { + if (array_owners[i]~".*@.*") { + printf("owner\nemail %s\nprofile %s\n\n", array_owners[i], profile); + } + } + + if (moderated!=0) { + for (i in array_owners) { + if (array_owners[i]~".*@.*") { + printf("editor\nemail %s\n\n", array_owners[i]); + } + } + } + + if (archive!=0) { + printf("web_archive\naccess %s\n\n", type_archive); + } + + printf("\n# ---------------- %s%s@%s \n", ALIAS_PREFIX, LIST, domain) >> ALIASES ; + if (VIRTUAL_ALIASES == "yes") { + printf(PREFIX "%s%s@%s: \"| %s/queue %s@%s\"\n", ALIAS_PREFIX, LIST, domain, SMTPSCRIPTPATH, LIST, domain) >> ALIASES ; + printf(PREFIX "%s%s-request@%s: \"| %s/queue %s-request@%s\"\n", ALIAS_PREFIX, LIST, domain, SMTPSCRIPTPATH, LIST, domain ) >> ALIASES ; + printf(PREFIX "%s%s-editor@%s: \"| %s/queue %s-editor@%s\"\n", ALIAS_PREFIX, LIST, domain, SMTPSCRIPTPATH, LIST, domain ) >> ALIASES ; + printf(PREFIX "%s%s-owner@%s: \"| %s/bouncequeue %s@%s\"\n", ALIAS_PREFIX,LIST, domain, SMTPSCRIPTPATH, LIST, domain ) >> ALIASES ; + printf(PREFIX "%s%s-unsubscribe@%s: \"| %s/queue %s-unsubscribe@%s\"\n", ALIAS_PREFIX,LIST, domain, SMTPSCRIPTPATH, LIST, domain ) >> ALIASES ; + printf(PREFIX "# %s%s-subscribe@%s: \"| %s/queue %s-subscribe@%s\"\n\n", ALIAS_PREFIX,LIST, domain, SMTPSCRIPTPATH, LIST, domain ) >> ALIASES ; + } else { + printf(PREFIX "%s%s: \"| %s/queue %s@%s\"\n", ALIAS_PREFIX,LIST, SMTPSCRIPTPATH, LIST, domain) >> ALIASES ; + printf(PREFIX "%s%s-request: \"| %s/queue %s-request@%s\"\n", ALIAS_PREFIX,LIST, SMTPSCRIPTPATH, LIST, domain ) >> ALIASES ; + printf(PREFIX "%s%s-editor: \"| %s/queue %s-editor@%s\"\n", ALIAS_PREFIX,LIST, SMTPSCRIPTPATH, LIST, domain ) >> ALIASES ; + printf(PREFIX "%s%s-owner: \"| %s/bouncequeue %s@%s\"\n", ALIAS_PREFIX,LIST, SMTPSCRIPTPATH, LIST, domain ) >> ALIASES ; + printf(PREFIX "%s%s-unsubscribe: \"| %s/queue %s-unsubscribe@%s\"\n", ALIAS_PREFIX,LIST, SMTPSCRIPTPATH, LIST, domain ) >> ALIASES ; + printf(PREFIX "# %s%s-subscribe: \"| %s/queue %s-subscribe@%s\"\n\n", ALIAS_PREFIX, LIST, SMTPSCRIPTPATH, LIST, domain ) >> ALIASES ; + } +} diff --git a/utils/mailman2sympa/old/mailman2sympa.sh b/utils/mailman2sympa/old/mailman2sympa.sh new file mode 100755 index 0000000..693d7af --- /dev/null +++ b/utils/mailman2sympa/old/mailman2sympa.sh @@ -0,0 +1,101 @@ +#!/bin/sh + +# USAGE: ./mailman2sympa nom_fichier +# Le fichier contient la liste des listes à migrer + +. conf/mailman2sympa.conf + +if [ ! -d $WDIR ]; then + mkdir -p $WDIR +fi + +if [ $# = 0 ] ; then + ls -1 $MAILMAN_VAR/lists/ | sed 's=/==g' | tr '[:upper:]' '[:lower:]' > $WDIR/mailman-lists + set $WDIR/mailman-lists +else + echo "$@" | tr '[:upper:]' '[:lower:]' > $WDIR/mailman-lists + set $WDIR/mailman-lists +fi + +if [ ! -d $EXPL ] ; then + mkdir $EXPL + fi + +if [ ! -d $WDIR/lists ] ; then + mkdir $WDIR/lists + fi + +if [ ! -d $WDIR/csv ] ; then + mkdir $WDIR/csv + fi +echo +echo Picking up configuration of mailman lists + +for f in `cat $WDIR/mailman-lists` ; do + if [ -f $MAILMAN_VAR/lists/$f/config.pck ]; then + $MAILMAN_HOME/bin/dumpdb $MAILMAN_VAR/lists/$f/config.pck > $WDIR/lists/$f + elif [ -f $MAILMAN_VAR/lists/$f/config.db ]; then + $MAILMAN_HOME/bin/dumpdb $MAILMAN_VAR/lists/$f/config.db > $WDIR/lists/$f + else + echo "Warning list $f not found - skipping" + sed -i -e "/^$f\$/d" $WDIR/mailman-lists + continue + fi + perl -pe 's/\\([0-3][0-7][0-7])/chr(oct($1))/eg;' $WDIR/lists/$f > $WDIR/lists/$f.perl + mv -f $WDIR/lists/$f.perl $WDIR/lists/$f +done + +echo +echo Creating configuration files for Sympa lists +ALIASES="$WDIR/aliases-sympa" +for l in `cat $WDIR/mailman-lists` ; do + if [ ! -d $EXPL/$l ] ; then + mkdir $EXPL/$l + fi + echo -n "" > $ALIASES + echo -n "" > $WDIR/csv/import_admins.csv + awk -v LIST=$l -v ALIASES=$ALIASES -v PREFIX=$ALIAS_PREFIX -v DOMAIN=$DOMAIN -v SMTPSCRIPTPATH=$SYMPA_SMTPSCRIPTS -v OWNER=$DEFAULT_OWNER -v WDIR=$WDIR -f awk/mailman2sympa.awk $WDIR/lists/$l > $WDIR/$l.config + if [ -f $EXPL/$l/config ] ; then + echo "Skipping $l - config already exists" + else + mv $WDIR/$l.config $EXPL/$l/config + fi +done + +echo +echo Creating subscribers files + +echo -n "" > $WDIR/csv/import_users.csv +echo -n "" > $WDIR/csv/import_subscribers.csv +for l in `cat $WDIR/mailman-lists` ; do + awk -v EXPL=$EXPL -v LIST=$l -v WDIR=$WDIR -v NOMAIL=$TAKE_NOMAIL -v DATE=$DEFAULT_DATE -f awk/subscribers.awk $WDIR/lists/$l + done +echo +echo Giving lists configuration to $USER +chown -R ${USER}:${GROUP} $EXPL + +if [ $CONVERT_ARCHIVE = "yes" ] ; then + echo + echo Converting Archives + for l in `cat $WDIR/mailman-lists` ; do + ./scripts/getmailmanarchive $l + done + echo "To regenerate web archive as listmaster go to 'Sympa Admin' and under 'Archive' is options to regenerate html" +fi + +echo +echo Cleaning temporary files... + +rm -rf $WDIR/lists/ + +echo +echo -n "Do you want to import users/subscribers/admins from CSV into the sympa database? [y/n]: " +read IMPORT + +if [ "$IMPORT" == "y" ]; then + ./loadsubscribers.sh +fi + +echo +echo Done. +echo diff --git a/utils/mailman2sympa/old/subscribers.awk b/utils/mailman2sympa/old/subscribers.awk new file mode 100644 index 0000000..abdaa71 --- /dev/null +++ b/utils/mailman2sympa/old/subscribers.awk @@ -0,0 +1,142 @@ +BEGIN { + +} + +function GetEmail(s) { + res=gensub("^{? +('[a-z0-9_]*': [{[] +)?'([^@]*@[^']*)'.*$", "\\2", "g", s); + #res=gensub("^.*[^a-zA-Z0-9._-]([a-zA-Z0-9._-]*@[a-zA-Z0-9.-]*)[^a-zA-Z0-9.-].*$", "\\1", "g", s); + if (res !~ ".*@.*") res=""; + return tolower(res); +} + +function GetValueN(s) { + res = gensub("^.*: *([0-9]*)[^0-9]*$", "\\1", "g", s); + return res; +} + +function GetPassword(s) { + res = gensub("^.*: '(.*)'(},|,)$", "\\1", "g", s); + return res; +} + +function GetUsername(s) { + res = gensub("^.*: u?'(.*)'(},|,)$", "\\1", "g", s); + return res; +} + +/'digest_members' *: *{/,/} */ { + digest[GetEmail($0)]=1; +} + + +/'members' *: *{/,/}/ { + email=GetEmail($0); + if (email in options) { + } else { + options[email]=0; + } +} + +# Make these non-members with nomail option +/'accept_these_nonmembers' *: *\[/,/\]/ { + nonmember_email[GetEmail($0)]=1; +} + +/'user_options' *: *{/,/} */ { + options[GetEmail($0)] += GetValueN($0); +} + +/'passwords' *: *{/,/}/ { + passwords[GetEmail($0)] = GetPassword($0); +} + +/'usernames' *: *{/,/}/ { + usernames[GetEmail($0)] = GetUsername($0); +} + + +END { + nb_subscribers=0; + print "" > EXPL "/" LIST "/subscribers"; + for (email in options) { + if (email == "") continue; + opt=options[email]; + visibility="noconceal"; + plain=0; + ack=0; + password=passwords[email]; + username=usernames[email]; + if (nonmember_email[email] == 1) { + # former nonmember that was allowed to post that is now a member + nonmember_email[email]=0; + delete nonmember_email[email]; + } + no_metoo=0; + nomail=0; + # from /usr/lib64/mailman/Mailman/Defaults.py + if (opt>=256) { + # DontReceiveDuplicate - not implemented in sympa + opt -= 256; + } + if (opt>=128) { + # Moderate - not implemented in sympa + opt -= 128; + } + if (opt>=64) { + # ReceiveNonmatchingTopics - maybe not implemented in sympa + opt -= 64; + } + if (opt>=32) { + # SuppressPasswordReminder - not implemented in sympa + opt -= 32; + } + if (opt>=16) { + visibility="conceal"; + opt -= 16; + } + if (opt>=8) { + # DisableMime # Digesters only + plain=1; + opt -= 8; + } + if (opt>=4) { + # AcknowledgePosts + ack=1; + opt -= 4; + } + if (opt>=2) { + # DontReceiveOwnPosts + no_metoo=1; + opt -= 2; + } + if (opt>=1) { + # DisableDelivery + nomail=1; + opt -= 1; + } + if (nomail==1 && TAKE_NOMAIL=="no") continue; + + if (nomail==1) {reception="nomail";} + else if (no_metoo==1) {reception="not_me";} + else if (digest[email]==1) { + if (plain) reception="digestplain"; + else reception="digest"; + } + else {reception="mail";} + printf("email %s\nvisibility %s\n", email, visibility) >> EXPL "/" LIST "/subscribers"; + if (reception != "mail") { + printf("reception %s\n", reception) >> EXPL "/" LIST "/subscribers"; + } + printf("\n") >> EXPL "/" LIST "/subscribers"; + nb_subscribers += 1; + printf("%s;%s;%s\n", email, username, password) >> WDIR "/csv/import_users.csv"; + printf("%s;%s;%s;%s;%s;%s\n", LIST, email, username, DATE, visibility, reception) >> WDIR "/csv/import_subscribers.csv"; + + } + for (nmemail in nonmember_email) { + if (nonmember_email[nmemail] == 1) { + printf("%s;%s;nonmember;%s;conceal;nomail\n", LIST, nmemail, DATE) >> WDIR "/csv/import_subscribers.csv"; + } + } + printf("0 0 0 0 %s", nb_subscribers) > EXPL "/" LIST "/stats"; +} diff --git a/utils/mailman2sympa/scripts/dispatch_messages b/utils/mailman2sympa/scripts/dispatch_messages new file mode 100755 index 0000000..dc136ed --- /dev/null +++ b/utils/mailman2sympa/scripts/dispatch_messages @@ -0,0 +1,20 @@ +#!/bin/sh + +NUM=`cat $2` +NUM=$[NUM+1] +echo $NUM > $2 +. ./conf/mailman2sympa.conf +if [ "$RESTORE_MULTIPART" = "yes" ] ; then + cat > $WDIR/message.$$ + multipart=`awk -f ./awk/test_multipart.awk $WDIR/message.$$` + if [ "$multipart" != "" ] ; then + cat $WDIR/message.$$ | formail -a "Content-Type: multipart/mixed; + boundary=\"$multipart\"" > $1/$NUM + else + cat $WDIR/message.$$ > $1/$NUM + fi + rm -f $WDIR/message.$$ +else +cat > $1/$NUM +fi + diff --git a/utils/mailman2sympa/scripts/getmailmanarchive b/utils/mailman2sympa/scripts/getmailmanarchive new file mode 100755 index 0000000..a8effaa --- /dev/null +++ b/utils/mailman2sympa/scripts/getmailmanarchive @@ -0,0 +1,76 @@ +#!/bin/sh + +. ./conf/mailman2sympa.conf + +if [ "$CLEAN_ARCHIVE" = "yes" ] ; then + echo -n 'Are you sure that you want remove all sympa archive (yes/no) ? ' + read r + if [ "$r" != "yes" ] ; then + echo Please fix mailman2sympa.conf and try again + exit + fi + echo + echo Cleaning archives... + rm -rf $MHONARC_ARC + echo +fi + +if [ ! -d $MHONARC_ARC ] ; then + mkdir $MHONARC_ARC +fi + +for l in $1 ; do + if [ -f $MAILMAN_VAR/archives/public/$l.mbox/$l.mbox ] ; then + echo -e "\nprocessing list $l" + cat $MAILMAN_VAR/archives/public/$l.mbox/$l.mbox | formail -s scripts/mboxsplit $l + continue + elif [ -f $MAILMAN_VAR/archives/private/$l.mbox/$l.mbox ] ; then + echo -e "\nprocessing list $l" + cat $MAILMAN_VAR/archives/private/$l.mbox/$l.mbox | formail -s scripts/mboxsplit $l + continue + fi + for y in $YEARS ; do + m=0 + for mc in January February March April May June July August September October November December ; do + m=$[m+1] + month=`printf "%04d-%02d" $y $m` + mail="" + if [ -f $MAILMAN_VAR/archives/public/$l/${y}-${mc}.txt ] ; then + mail=$MAILMAN_VAR/archives/public/$l/${y}-${mc}.txt + cat=cat + elif [ -f $MAILMAN_VAR/archives/public/$l/${y}-${mc}.txt.gz ] ; then + mail=$MAILMAN_VAR/archives/public/$l/${y}-${mc}.txt.gz + cat="gunzip -c" + elif [ -f $MAILMAN_VAR/archives/private/$l/${y}-${mc}.txt ] ; then + mail=$MAILMAN_VAR/archives/private/$l/${y}-${mc}.txt + cat="cat" + elif [ -f $MAILMAN_VAR/archives/private/$l/${y}-${mc}.txt.gz ] ; then + mail=$MAILMAN_VAR/archives/private/$l/${y}-${mc}.txt.gz + cat="gunzip -c" + fi + if [ "$mail" != "" ] ; then + #echo "processing list $l - $month" + dest=$MHONARC_ARC/${l}@$DOMAIN/${month}/arctxt + index=$MHONARC_ARC/${l}@$DOMAIN/${month}/index + if [ ! -d $dest ] ; then + mkdir -p $dest + fi + echo 0 > $index + $cat $mail | formail -s scripts/dispatch_messages $dest $index + echo $l $month ':' `cat $index` messages + fi + done + done + + dest="$MHONARC_ARC/${l}@$DOMAIN" + if [ ! -d $dest ] ; then + mkdir -p $dest + echo $l has an empty archive! + fi +done + +echo +echo Giving archive to $USER... +chown -R ${USER}:${GROUP} $MHONARC_ARC + + diff --git a/utils/mailman2sympa/scripts/loadsubscribers.pl b/utils/mailman2sympa/scripts/loadsubscribers.pl new file mode 100755 index 0000000..eaca268 --- /dev/null +++ b/utils/mailman2sympa/scripts/loadsubscribers.pl @@ -0,0 +1,382 @@ +#!/usr/bin/perl + +# loadsubscribers.pl - This script loads a CSV-file +# (generated by mailman2sympa) in a Database +# +# Copyright (c) 2002 Andreas de Pretis for +# Uptime Systemloesungen GmbH and +# t0 Institut fuer neue Kulturtechnologien +# +# 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. + +# +# Pragmas +# +use strict; +use diagnostics; + +# +# Classes +# +use DBI qw(:sql_types); +use POSIX qw(strftime); +# +# Variables +# +my $listname; +my $dbh; +my $dbhnew; +my $dbh_csv; +my $date_func; +my $query_users_ins; +my $query_users_sel; +my $query_subscribers; +my $query_csv; +my $sth_csv; +my $sth_users_ins; +my $sth_users_sel; +my $sth_subscribers; +my $resetted = {}; + +my $query_admins; +my $sth_admins; +my $email_name; + +# +# Load ENV +# +&getConfig(); + +# +# connect to database +# +&db_connect(); + +# +# Clean tables +# +if (exists($ENV{'CLEANTABLES'}) && defined($ENV{'CLEANTABLES'}) && $ENV{'CLEANTABLES'} == 1) { + print STDOUT "#### deleteing user_table and subscriber_table ####\n"; + + eval { + $dbhnew->do("DELETE FROM user_table"); + $dbhnew->do("DELETE FROM subscriber_table"); + }; + + if ($@) { + $dbhnew->rollback(); + die "Error: $@\n"; + } else { + $dbhnew->commit(); + } +} + +print STDOUT "#### importing ####\n"; + +# +# SQL-Statements +# +eval { + # + # CSV-Users + # + $query_csv = qq! + SELECT email_user, gecos_user, password_user from users + !; + $sth_csv = $dbh_csv->prepare($query_csv); + + # + # Users + # + $query_users_sel = qq! + SELECT gecos_user + FROM user_table + WHERE email_user like ? + !; + $sth_users_sel = $dbh->prepare($query_users_sel); + + $query_users_ins = qq! + INSERT INTO user_table (email_user, gecos_user, password_user) + VALUES (?, ?, ?) + !; + $sth_users_ins = $dbhnew->prepare($query_users_ins); + + + # + # Execute + # + $sth_csv->execute(); + + while (my ($email, $username, $password) = $sth_csv->fetchrow_array()) { + # + # Check for existing user + # + if (!exists($resetted->{$email}) && !defined($resetted->{$email})) { + $sth_users_sel->bind_param(1, $email, SQL_VARCHAR); + $sth_users_sel->execute(); + + if ($sth_users_sel->rows()) { + if ($ENV{'RESET_PASSWORDS'} == 1) { + my $sth; + my $query; + + if ($ENV{'DATABASE'} == $ENV{'NEW_DATABASE'}) { + print STDOUT " - user '$email' already exists (setting password to null)\n"; + $query = qq! + UPDATE user_table + SET password_user = null + WHERE email_user like ? + !; + + $sth = $dbh->prepare($query); + $sth->bind_param(1, $email, SQL_VARCHAR); + $sth->execute(); + $sth->finish(); + $dbh->commit(); + } else { + print STDOUT " - user '$email' already exists (pretending to set password to null)\n"; + } + + } else { + print STDOUT " - user '$email' already exists (skipping)\n"; + } + $resetted->{$email} = 1; + } else { + $sth_users_ins->bind_param(1, $email, SQL_VARCHAR); + $sth_users_ins->bind_param(2, $username, SQL_VARCHAR); + $sth_users_ins->bind_param(3, $password, SQL_VARCHAR); + $sth_users_ins->execute(); + } + } + } + $dbhnew->commit(); + $sth_users_ins->finish(); + $sth_csv->finish(); + + print STDOUT "\nFinished with users - now handling their subscription\n"; + # + # CSV-Subscribers + # + $query_csv = qq! + SELECT list_subscriber, email_subscriber, geos_subscriber, date_subscriber, visibility_subscriber,reception_subscriber from subscribers + !; + $sth_csv = $dbh_csv->prepare($query_csv); + + # + # Execute subscribers + # + + # + # Subscribers + # + # date_subscriber & update_subscriber (datetime) was obsoleted. + # Use date_epoch_subscriber & update_epoch_subscriber (int). + $query_subscribers = qq! + INSERT INTO subscriber_table (list_subscriber, user_subscriber, comment_subscriber, date_epoch_subscriber, reception_subscriber, visibility_subscriber, robot_subscriber, subscribed_subscriber) + VALUES (?, ?, ?, ?, ?, ?, ?, 1) + !; + $sth_subscribers = $dbhnew->prepare($query_subscribers); + $sth_subscribers->bind_param(7, $ENV{'DOMAIN'}, SQL_VARCHAR); + + $sth_csv->execute(); + + while (my ($list, $user, $comment, $date, $visiblity, $reception) = $sth_csv->fetchrow_array()) { + $sth_subscribers->bind_param(1, $list, SQL_VARCHAR); + $sth_subscribers->bind_param(2, $user, SQL_VARCHAR); + $sth_subscribers->bind_param(3, $comment, SQL_VARCHAR); + $sth_subscribers->bind_param(4, $date, SQL_TIMESTAMP); + $sth_subscribers->bind_param(5, $reception, SQL_VARCHAR); + $sth_subscribers->bind_param(6, $visiblity, SQL_VARCHAR); + $sth_subscribers->execute(); + } + + $dbhnew->commit(); + $sth_csv->finish(); + $sth_subscribers->finish(); + + + print STDOUT "\nFinished with subscriptions - now handling list admins and moderators\n"; + + # + # Admins + # + # date_admin & update_admin (datetime) was obsoleted. + # Use date_epoch_admin & update_epoch_admin (int). + + $query_admins = qq! + INSERT INTO admin_table (comment_admin, date_epoch_admin, list_admin, profile_admin, reception_admin, robot_admin, role_admin, subscribed_admin, update_epoch_admin, user_admin) + VALUES (?, ?, ?, 'privileged', 'mail', ?, ?, 1, ?, ?) + !; + $sth_admins = $dbhnew->prepare($query_admins); + $sth_admins->bind_param(4, $ENV{'DOMAIN'}, SQL_VARCHAR); + $sth_admins->bind_param(2, strftime("%F %T", localtime), SQL_TIMESTAMP); + $sth_admins->bind_param(6, strftime("%F %T", localtime), SQL_TIMESTAMP); + + $query_csv = qq! + SELECT email_admin,role_admin,list_admin from admins + !; + $sth_csv = $dbh_csv->prepare($query_csv); + $sth_csv->execute(); + + + while (my ($email, $role, $list) = $sth_csv->fetchrow_array()) { + + $sth_admins->bind_param(7, $email, SQL_VARCHAR); + $sth_admins->bind_param(5, $role, SQL_VARCHAR); + $sth_admins->bind_param(3, $list, SQL_VARCHAR); + #$sth_admins->bind_param(1, undef, SQL_VARCHAR); + $sth_users_sel->bind_param(1, $email, SQL_VARCHAR); + $sth_users_sel->execute(); + $email_name = $sth_users_sel->fetchrow_array(); + if ($email_name) { + print STDOUT "admin $email found with name $email_name\n"; + } + $sth_admins->bind_param(1, $email_name, SQL_VARCHAR); + $sth_admins->execute(); + } + $sth_csv->finish(); + $sth_users_sel->finish(); + $dbhnew->commit(); + $sth_admins->finish(); + +}; + +# +# Exception-Handling +# +if ($@) { + $dbh->rollback(); + $sth_csv->finish(); + $sth_users_ins->finish(); + $sth_users_sel->finish(); + $sth_subscribers->finish(); + $sth_admins->finish(); + die "Error: $@"; +} else { + # $dbh->commit(); + $dbhnew->commit(); +} + +if ($ENV{'RESET_PASSWORDS'} == 1 && $ENV{'DATABASE'} != $ENV{'NEW_DATABASE'}) { + print "\n\nPasswords resetted to null: " . keys (%{$resetted}) . "\n"; +} + +# +# disconnect from database +# +&db_disconnect(); + +# +# getConfig +# +sub getConfig + { + my @env = qx|. ./conf/mailman2sympa.conf;set|; + + # + # Import ENV from mailman2sympa.conf into Perl-ENV + # + foreach my $env (@env) + { + chomp $env; + $env =~ /^\s*(.*?)\s*=\s*(.*)/; + + unless (exists($ENV{$1}) || $1 eq 'SHELLOPTS') + { + my $name = $1; + my $value = $2; + + if ($value =~ /^\'(.*)\'$/) + { + $value = $1; + } + + $ENV{$name} = $value; + } + } + } + +# +# db_connect +# +sub db_connect { + my $db_type = $ENV{'SGBD'}; + my $db_name = $ENV{'DATABASE'}; + my $db_newname = $ENV{'NEW_DATABASE'}; + my $db_host = $ENV{'HOSTDB'}; + my $db_user = $ENV{'USERDB'}; + my $db_passwd = $ENV{'PASSWORDDB'}; + + unless ($dbh = DBI->connect("dbi:$db_type:dbname=$db_name;host=$db_host", $db_user, $db_passwd, { RaiseError => 1, AutoCommit => 0 })) { + die "Can't connect to Database :", $DBI::errstr; + } + unless ($dbhnew = DBI->connect("dbi:$db_type:dbname=$db_newname;host=$db_host", $db_user, $db_passwd, { RaiseError => 1, AutoCommit => 0 })) { + die "Can't connect to Database :", $DBI::errstr; + } + + unless ($dbh_csv = DBI->connect("dbi:CSV:f_dir=$ENV{'WDIR'}/csv", { RaiseError => 1, AutoCommit => 0 })) { + die "Can't connect to CSV-Directory :", $DBI::errstr; + } + + $dbh_csv->{'csv_tables'}->{'users'}= { + 'file' => 'import_users.csv', + 'sep_char' => ";", + 'eol' => "\n", + 'col_names' => [ + 'email_user', + 'gecos_user', + 'password_user', + ], + }; + + $dbh_csv->{'csv_tables'}->{'subscribers'} = { + 'file' => 'import_subscribers.csv', + 'sep_char' => ";", + 'eol' => "\n", + 'col_names' => [ + 'list_subscriber', + 'email_subscriber', + 'geos_subscriber', + 'date_subscriber', + 'visibility_subscriber', + 'reception_subscriber', + 'bounce_subscriber', + 'comment_subscriber', + 'subscribed_subscriber', + 'included_subscriber', + 'include_sources_subscriber', + ], + }; + $dbh_csv->{'csv_tables'}->{'admins'}= { + 'file' => 'import_admins.csv', + 'sep_char' => ";", + 'eol' => "\n", + 'col_names' => [ + 'email_admin', + 'role_admin', + 'list_admin', + ], + }; + +} + +# +# db_disconnect +# +sub db_disconnect { + $dbh->disconnect(); + $dbhnew->disconnect(); + $dbh_csv->disconnect(); +} diff --git a/utils/mailman2sympa/scripts/mboxsplit b/utils/mailman2sympa/scripts/mboxsplit new file mode 100755 index 0000000..4e16180 --- /dev/null +++ b/utils/mailman2sympa/scripts/mboxsplit @@ -0,0 +1,89 @@ +#!/usr/bin/perl +use strict; + +use Date::Parse; + +my $from; +my $month; +my $year; +my $dest; +my $dir; +my $num; +my $numfile; +my $outfile; +my $a; +my $b; +my $c; +my $d; +my $e; + + +if ($#ARGV < 0) { + die 'need an arguement of the list name'; +} + +&getConfig(); + + +$_ = $from = ; +/[^ ]* +[^ ]* +(.*)/; +($a,$b,$c,$d,$month,$year,$e) = strptime($1); + +$month=sprintf('%02d',$month+1); +$dir=$ENV{'MHONARC_ARC'} . '/' . $ARGV[0] . '@' . $ENV{'DOMAIN'} . '/' . ($year + 1900) . '-' . $month; +$dest=$dir . '/arctxt'; +$numfile=$dir . '/index'; + +if ( open NUM, '<', $numfile) { + $num = ; + close(NUM); + $num++; + `echo $num > $numfile`; +} else { + print ' ' . ($year + 1900) . '-' . $month; + `mkdir -p $dest`; + $num=1; + `echo $num > $numfile`; +} + +$outfile=$dest . '/' . $num; +unless ( open FILE,'>', $outfile ) { + die; +} + +print FILE $from; + +while () { + print FILE $_; +} +close FILE; +# +# getConfig + +# +sub getConfig + { + my @env = qx|. ./conf/mailman2sympa.conf;set|; + + # + # Import ENV from mailman2sympa.conf into Perl-ENV + # + foreach my $env (@env) + { + chomp $env; + $env =~ /^\s*(.*?)\s*=\s*(.*)/; + + unless (exists($ENV{$1}) || $1 eq 'SHELLOPTS') + { + my $name = $1; + my $value = $2; + + if ($value =~ /^\'(.*)\'$/) + { + $value = $1; + } + + $ENV{$name} = $value; + } + } + } diff --git a/utils/mailman2sympa/scripts/mm2s_admins b/utils/mailman2sympa/scripts/mm2s_admins new file mode 100755 index 0000000..b1bdd78 --- /dev/null +++ b/utils/mailman2sympa/scripts/mm2s_admins @@ -0,0 +1,47 @@ +#!/usr/bin/perl -w + +# mm2s_admins - Generate a csv of list administrators. +# +# Author: John Bazik +# +# Copyright 2010 Brown University +# +# 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. + +use lib 'lib'; + +use mmparse; + +my $m_cfg; + +# +# Load mailman config. +# +{ + local $/=undef; + $m_cfg = mmparse(); +} + +my $list_name = lc($m_cfg->{real_name}); + +# +# Generate admins +# +for my $owner (@{$m_cfg->{owner}}) { + print "$owner;owner;$list_name\n" +} +for my $editor (@{$m_cfg->{moderator}}) { + print "$editor;editor;$list_name\n" +} diff --git a/utils/mailman2sympa/scripts/mm2s_aliases b/utils/mailman2sympa/scripts/mm2s_aliases new file mode 100755 index 0000000..95ba74e --- /dev/null +++ b/utils/mailman2sympa/scripts/mm2s_aliases @@ -0,0 +1,24 @@ +#!/bin/sh + +. ./conf/mailman2sympa.conf + +LIST=$1 + +if [ "$VIRTUAL_ALIASES" = "yes" ]; then + domain="@$DOMAIN" +else + domain='' +fi + +PREFIX=$ALIAS_PREFIX +SYMPA_PATH=$(echo $SYMPA_SMTPSCRIPTS | sed 's/\/$//') + +echo "" +echo "# ---------------- $PREFIX$LIST$domain" +echo "$PREFIX$LIST$domain: \"| $SYMPA_PATH/queue $LIST$domain\"" +echo "$PREFIX$LIST-request$domain: \"| $SYMPA_PATH/queue $LIST-request$domain\"" +echo "$PREFIX$LIST-editor$domain: \"| $SYMPA_PATH/queue $LIST-editor$domain\"" +echo "$PREFIX$LIST-owner$domain: \"| $SYMPA_PATH/bouncequeue $LIST$domain\"" +echo "$PREFIX$LIST-unsubscribe$domain: \"| $SYMPA_PATH/queue $LIST-unsubscribe$domain\"" +echo "# $PREFIX$LIST-subscribe$domain: \"| $SYMPA_PATH/queue $LIST-subscribe$domain\"" +echo "" diff --git a/utils/mailman2sympa/scripts/mm2s_blacklist b/utils/mailman2sympa/scripts/mm2s_blacklist new file mode 100755 index 0000000..f10c1a1 --- /dev/null +++ b/utils/mailman2sympa/scripts/mm2s_blacklist @@ -0,0 +1,47 @@ +#!/usr/bin/perl -w + +# mm2s_blacklist - Copy per-list blacklist. +# +# Author: John Bazik +# +# Copyright 2010 Brown University +# +# 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. + +use lib 'lib'; + +use mmparse; + +my $m_cfg; + +# +# Load mailman config. +# +{ + local $/=undef; + $m_cfg = mmparse(); +} + +# +# Generate blacklist +# +for my $addr (@{$m_cfg->{ban_list}}) { + if ($addr =~ /^\^/) { + print "# $addr\n"; # preserve regex's, but comment them out + } + else { + print "$addr\n"; + } +} diff --git a/utils/mailman2sympa/scripts/mm2s_config b/utils/mailman2sympa/scripts/mm2s_config new file mode 100755 index 0000000..0584989 --- /dev/null +++ b/utils/mailman2sympa/scripts/mm2s_config @@ -0,0 +1,285 @@ +#!/usr/bin/perl -w + +# mm2s_config - Convert the output of Mailman's dumpdb command into +# a matching Sympa list configuration. This script is a filter, +# it reads stdin and writes to stdout. +# +# Author: John Bazik +# +# Copyright 2010 Brown University +# +# 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. + +use JSON; + +my ($m_cfg, @s_cfg); + +# +# Load mailman config. +# +{ + local $/=undef; + $m_cfg = decode_json ; +} + +my $list_name = lc($m_cfg->{real_name}); +my $now = localtime(time); +my $boolmap = { # to normalize boolean settings + '0' => 0, False => 0, + '1' => 1, True => 1, +}; + +my @mo = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec); + +# +# Generate Sympa config +# +addlines( + "## Converted from Mailman by mailman2sympa, $now", + "## List '$list_name'", +); + +#---------------------------------------------------------------- +# Translate list options starting here. +#---------------------------------------------------------------- + +{ my $subject; + + $subject = $m_cfg->{description} || "\u$list_name mailing list"; +# $subject = decode_json '"'.$subject.'"'; + addlines( + "subject $subject", + ); +} + +setopt('status', undef, 'open'); + +setopt('visibility', 'advertised', 'conceal', { + True => 'noconceal', 1 => 'noconceal', + False => 'conceal', 0 => 'conceal', +}); + +setopt('subscribe', 'subscribe_policy', 'auth', { + 1 => 'auth', + 2 => 'owner', + 3 => 'auth_owner', +}); + +setopt('unsubscribe', 'unsubscribe_policy', 'auth', { + 0 => 'auth', + 1 => 'auth_owner', +}); + +{ my $send; + + my $mm_nma = $m_cfg->{generic_nonmember_action}; + my $mm_dmm = $boolmap->{$m_cfg->{default_member_moderation}}; + if ($mm_nma == 0) { # public + $send = 'public'; + } + elsif ($mm_nma == 1 && $mm_dmm) { # moderated + $send = 'editorkey'; + } + elsif ($mm_nma == 1 && !$mm_dmm) { # private, moderate non-subscribers + $send = 'privateoreditorkey'; + } + elsif ($mm_nma > 1 && $mm_dmm) { # private, moderated + $send = 'privateandeditorkey'; + } + else { # private + $send = 'private'; + } + setopt('send', undef, $send); +} + +{ my $owner; + + if (my $mm_owner = $m_cfg->{owner}) { + for $owner (@$mm_owner) { + addlines( + "owner", + "email $owner", + "profile privileged", + ); + } + } +} + +{ my $editor; + + if (my $mm_mod = $m_cfg->{moderator}) { + for $editor (@$mm_mod) { + addlines( + "editor", + "email $editor", + ); + } + } +} + +setopt('digest', undef, '0,1,2,3,4,5,6 12:00') + if $boolmap->{$m_cfg->{digestable}}; + +{ my $reply_to_header; + + my $mm_goesto = $m_cfg->{reply_goes_to_list}; + + my @extra; + if ($mm_goesto == 0) { + $reply_to_header = 'sender'; + } + elsif ($mm_goesto == 1) { + $reply_to_header = 'list'; + } + elsif ($mm_goesto == 2) { + $reply_to_header = 'other_email'; + my $addr = $m_cfg->{reply_to_address} || ''; + push @extra, "other_email $addr" if $addr; + } + if ($boolmap->{$m_cfg->{first_strip_reply_to}}) { + push @extra, "apply forced"; + } + addlines( + "reply_to_header", + "value $reply_to_header", + @extra, + ); +} + +{ my $created_at; + + if (my $mm_created_at = $m_cfg->{created_at}) { + my $owner = ($m_cfg->{owner} && @{$m_cfg->{owner}}) ? + $m_cfg->{owner}->[0] : 'unknown@example.com'; + my $ts = int($mm_created_at); + my @ts = localtime($ts); + addlines( + "creation", + "email $owner", + sprintf("date %02d %s %04d at %02d:%02d:%02d", + $ts[3], $mo[$ts[4]], $ts[5] + 1900, $ts[2], $ts[1], $ts[0]), + "date_epoch $ts", + ); + } +} + +setopt('custom_subject', 'subject_prefix', "[\u$list_name] "); + +setopt('footer_type', undef, 'append'); + +setopt('invite', undef, 'closed'); + +setopt('review', undef, 'owner'); + +{ my $archive; + + my @freqmap = qw(year month quarter week day); + + $archive = $boolmap->{$m_cfg->{archive}}; + my $period = $freqmap[$m_cfg->{archive_volume_frequency}]; + my @extra; + push @extra, $boolmap->{$m_cfg->{archive_private}} ? + 'web_access private' : 'web_access public'; + + if ($archive) { + addlines( + "archive", + "period $period", + @extra, + ); + addlines( + "process_archive on" + ); + } +} + +{ my $bounce; + + $bounce = $boolmap->{$m_cfg->{bounce_processing}}; + my $notify1 = $boolmap->{$m_cfg->{bounce_notify_owner_on_disable}} ? + 'owner' : 'none'; + my $notify2 = $boolmap->{$m_cfg->{bounce_notify_owner_on_removal}} ? + 'owner' : 'none'; + + # not sure how to map the bounce rate from mailman to sympa... + + if ($bounce) { + addlines( + "bouncers_level1", + "notification $notify1", + ); + addlines( + "bouncers_level2", + "notification $notify2", + ); + } +} + +setopt('remind', undef, 'monthly') if $boolmap->{$m_cfg->{send_reminders}}; + +{ my $max_size; + + my $mm_size = $m_cfg->{max_message_size}; + + if ($mm_size > 0) { # zero is no limit + $max_size = $mm_size * 1024; + addlines( + "max_size $max_size", + ); + } +} + +{ my $spam_protection; + + $spam_protection = $boolmap->{$m_cfg->{obscure_addresses}} ? + 'at' : 'none'; + addlines( + "spam_protection $spam_protection", + ); + addlines( + "web_archive_spam_protection $spam_protection", + ); +} + +# +# All done, write it out. +# +print join("\n\n", @s_cfg), "\n"; + + +sub setopt { + my $sopt = shift; # sympa option name + my $mopt = shift; # mailman option name + my $default = shift; # default if not set (rarely happens) + my $map = shift; # map mailman option values to sympa values + my $val; + + if ($mopt && defined $m_cfg->{$mopt}) { + if ($map && defined $map->{$m_cfg->{$mopt}}) { + $val = $map->{$m_cfg->{$mopt}}; + } + else { + $val = $m_cfg->{$mopt}; + } + } + elsif (defined $default) { + $val = $default; + } + push @s_cfg, join(' ', $sopt, $val) if defined $val; +} + +sub addlines { + push @s_cfg, join("\n", @_); +} diff --git a/utils/mailman2sympa/scripts/mm2s_info b/utils/mailman2sympa/scripts/mm2s_info new file mode 100755 index 0000000..5c01f5c --- /dev/null +++ b/utils/mailman2sympa/scripts/mm2s_info @@ -0,0 +1,18 @@ +#!/usr/bin/perl -w +# +# mailman2sympa doesn't convert the mailman info field, since, in +# sympa, it's a separate, per-list file (expl/listname/info). +# +# This script does the simple conversion of that field. +# +# dumpdb listname.pck | mm2s_info > expl/listname/info + +for () { + next unless /^\s*'info':\s*'(.*)'/; + $_ = $1; + s/\\n/\n/g; + s/\\r/\r/g; + s/\\t/\t/g; + print $_, "\n" if $_; + exit 0; +} diff --git a/utils/mailman2sympa/scripts/mm2s_subscribers b/utils/mailman2sympa/scripts/mm2s_subscribers new file mode 100755 index 0000000..a2a0ff6 --- /dev/null +++ b/utils/mailman2sympa/scripts/mm2s_subscribers @@ -0,0 +1,92 @@ +#!/usr/bin/perl -w + +# mm2s_subscribers - Generate a csv of subscribers. +# +# Author: John Bazik +# +# Copyright 2010 Brown University +# +# 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. + +use lib 'lib'; + +use JSON; + +my $m_cfg; + +# +# Load mailman config. +# +{ + local $/=undef; + $m_cfg = decode_json ; +} + +my $list_name = lc($m_cfg->{real_name}); +my @now = localtime; +my $now = sprintf("%d-%02d-%02d", $now[5] + 1900, $now[4] + 1, $now[3]); + +my %users = map {$_, 1} + keys %{$m_cfg->{user_options}}, + @{$m_cfg->{accept_these_nonmembers}}, +; + +# User options: bitmasks from mailman's Defaults.py +my $notmetoo = 2; # DontReceiveOwnPosts (Non-digesters only) +my $ack = 4; # AcknowledgePosts +my $plain = 8; # DisableMime (Digesters only) +my $hide = 16; # ConcealSubscription +my $noremind = 32; # SuppressPasswordReminder +my $alltopics = 64; # ReceiveNonmatchingTopics +my $mod = 128; # Moderate +my $nodups = 256; # DontReceiveDuplicates + +# Delivery status, from mailman's MemberAdaptor.py +my $enabled = 0; # ENABLED +my $unknown = 1; # UNKNOWN (legacy disabled) +my $byuser = 2; # BYUSER +my $byadmin = 3; # BYADMIN (disabled by admin choice) +my $bybounce = 4; # BYBOUNCE + +for my $user (sort keys %users) { + my ($name, $date, $vis, $rcpt); + + my $options = $m_cfg->{user_options}->{$user}; + + $date = $now; + + if (defined $options) { # actual subscriber + $name = $m_cfg->{usernames}->{$user} || ''; + $vis = $options & $hide ? 'conceal' : 'noconceal'; + + my $status = $m_cfg->{delivery_status}->{$user}; + if ($status && $status->[0]) { + $rcpt = 'nomail'; + } + elsif (exists $m_cfg->{digest_members}->{$user}) { + $rcpt = $options & $plain ? 'digestplain' : 'digest'; + } + else { + $rcpt = $options & $notmetoo ? 'not_me' : 'mail'; + } + } + else { # non-member + $name = 'nonmember'; + $vis = 'conceal'; + $rcpt = 'nomail'; + } + + print "$list_name;$user;$name;$date;$vis;$rcpt\n"; +} diff --git a/utils/mailman2sympa/scripts/mm2s_unpickle.py b/utils/mailman2sympa/scripts/mm2s_unpickle.py new file mode 100755 index 0000000..681ed87 --- /dev/null +++ b/utils/mailman2sympa/scripts/mm2s_unpickle.py @@ -0,0 +1,27 @@ +#!/usr/bin/python2 + +import sys +import pickle +import json +import os + +mm_path=os.getenv('MAILMAN_HOME', '/usr/share/mailman') +sys.path.insert(1,mm_path) +filename = sys.argv[1] +infile = open(filename,'rb') +while True: + try: + config_dict = pickle.load(infile) + except EOFError: + break + except pickle.UnpicklingError: + print( + _('Not a Mailman 2.1 configuration file: $infile')) + else: + if not isinstance(config_dict, dict): + print(_('Ignoring non-dictionary: {0!r}').format( + config_dict)) + continue +config_dict['bounce_info'] = str(config_dict.get('bounce_info')) +print(json.dumps(config_dict)) +infile.close() diff --git a/utils/mailman2sympa/scripts/mm2s_users b/utils/mailman2sympa/scripts/mm2s_users new file mode 100755 index 0000000..cadafb9 --- /dev/null +++ b/utils/mailman2sympa/scripts/mm2s_users @@ -0,0 +1,58 @@ +#!/usr/bin/perl -w + +# mm2s_users - Generate a csv of users. +# +# Author: John Bazik +# +# Copyright 2010 Brown University +# +# 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. + +use lib 'lib'; + +use JSON; + +my $m_cfg; + +# +# Load mailman config. +# +{ + local $/=undef; + $m_cfg = decode_json ; +} + +my %users = map {$_, 1} + keys %{$m_cfg->{user_options}}, + @{$m_cfg->{accept_these_nonmembers}}, +; + + +for my $user (sort keys %users) { + my $name = $m_cfg->{usernames}->{$user} || ''; + my $pass = $m_cfg->{passwords}->{$user} || genpw(); + print "$user;$name;$pass\n"; +} + +sub genpw { + my $chars = 'abcdefghijkmnpqrstuvwxyz23456789ABCDEFGHJKLMNPQRSTUVWXYZ'; + my $len = length $chars; + my $password = ''; + + for (1..8) { + $password .= substr($chars, int(rand($len)), 1); + } + return $password; +} diff --git a/utils/mailman2sympa/utils/README b/utils/mailman2sympa/utils/README new file mode 100644 index 0000000..07609dc --- /dev/null +++ b/utils/mailman2sympa/utils/README @@ -0,0 +1,16 @@ +Mailman has a number of commands for manipulating lists and subscribers. +Contained here are three: + +add_members +list_members +remove_members + +If you use robots, as we do, list names require a little finessing, +which the latter two scripts have, but add_members does not (but could +if someone would like to improve it). + +Add_members uses sympa's command-line options. The other two scripts +go directly to the database. Needless to say, that makes them a little +more fragile. + +- John Bazik, 30 Aug 2010 diff --git a/utils/mailman2sympa/utils/add_members b/utils/mailman2sympa/utils/add_members new file mode 100755 index 0000000..88c5b82 --- /dev/null +++ b/utils/mailman2sympa/utils/add_members @@ -0,0 +1,64 @@ +#!/bin/sh + +# add_members - Add members to a sympa list. This is a mailman-like +# command that uses sympa.pl to add new subscribers. +# +# Author: John Bazik +# +# Copyright 2010 Brown University +# +# 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. + +# NOTE: set your default robot here. This script could be improved +# by also accepting listnames like listname@robot. +robot= + +usage() { + cat < \$opt_h, +) or die $usage; + +if ($opt_h) { + print $usage; + exit 0; +} + +die $usage unless @ARGV; +my ($listname, $robot) = split(/\@/, shift @ARGV); +$robot ||= $default_robot; + +my $configfile = '/etc/sympa/sympa.conf'; +my $config = config($configfile); +my $dbh = dbh($config); + +my $rows = $dbh->selectcol_arrayref(join(' ', + "SELECT user_subscriber FROM subscriber_table", + "WHERE list_subscriber = '$listname'", + $robot ? "AND robot_subscriber = '$robot'" : '', +)); + +print join("\n", sort @$rows), @$rows ? "\n" : ''; + +sub dbh { + my $config = shift; + + my $dsn = "dbi:$config->{db_type}:dbname=$config->{db_name}"; + $dsn .= ";host=$config->{db_host}" if $config->{db_host}; + $dsn .= ";port=$config->{db_port}" if $config->{db_port}; + + return DBI->connect($dsn, $config->{db_user}, $config->{db_passwd}); +} + +sub config { + my $file = shift; + my @fields = qw(db_type db_name db_passwd db_user db_port db_host); + my $config = {}; + + my $pat = join('|', @fields); + + open my $fd, $file or die "$file: $!\n"; + for (<$fd>) { + if (/^\s*($pat)\s+(.+)/) { + $config->{$1} = $2; + } + } + close $fd; + + for (qw(db_type db_name)) { + die "$configfile: missing $_ field\n" unless $config->{$_}; + } + return $config; +} diff --git a/utils/mailman2sympa/utils/remove_members b/utils/mailman2sympa/utils/remove_members new file mode 100755 index 0000000..9ac1a8d --- /dev/null +++ b/utils/mailman2sympa/utils/remove_members @@ -0,0 +1,133 @@ +#!/usr/bin/perl -w + +# remove_members - a mailman-like command for sympa that removes +# subscribers from a list. +# +# Author: John Bazik +# +# Copyright 2010 Brown University +# +# 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. + +use DBI; +use Getopt::Long; + +use strict; + +## +## Set your default robot here, e.g. lists.example.com +## +my $default_robot = ''; + +my($opt_a, $opt_f, $opt_h, $opt_fromall); + +my $usage = 'usage: remove_members [options] [listname] [addr ...] + -a remove all members of the mailing list + -f file remove member addresses found in the given file + --fromall remove members from all lists (cannot be used with -a) + -h print this help message +'; + +GetOptions( + 'a|all' => \$opt_a, + 'f|file=s' => \$opt_f, + 'fromall' => \$opt_fromall, + 'h|help' => \$opt_h, +) or die $usage; + +if ($opt_h) { + print $usage; + exit 0; +} + +die $usage if $opt_a && $opt_fromall; + +my ($listname, $robot) = split(/\@/, shift @ARGV) if @ARGV; +$robot ||= $default_robot; + +die $usage unless $opt_fromall || $listname; + +my @members; +if ($opt_f) { + if ($opt_f eq '-') { + chomp(@members = ); + } + else { + open my $fd, $opt_f or die "$opt_f: $!\n"; + chomp(@members = <$fd>); + close $fd; + } +} +else { + @members = @ARGV; +} + +my $configfile = '/etc/sympa/sympa.conf'; +my $config = config($configfile); +my $dbh = dbh($config); + +my $sql = join(' ', + "DELETE FROM subscriber_table WHERE", + join(' AND ', + $opt_fromall ? () : "list_subscriber = '$listname'", + $robot ? "robot_subscriber = '$robot'" : (), + $opt_a ? () : "user_subscriber = ?", + ), +); + +my $sth = $dbh->prepare($sql); + +if ($opt_a) { + $sth->execute; +} +elsif (@members) { + for (@members) { + $sth->execute($_); + } +} +else { + die $usage; +} + +sub dbh { + my $config = shift; + + my $dsn = "dbi:$config->{db_type}:dbname=$config->{db_name}"; + $dsn .= ";host=$config->{db_host}" if $config->{db_host}; + $dsn .= ";port=$config->{db_port}" if $config->{db_port}; + + return DBI->connect($dsn, $config->{db_user}, $config->{db_passwd}); +} + +sub config { + my $file = shift; + my @fields = qw(db_type db_name db_passwd db_user db_port db_host); + my $config = {}; + + my $pat = join('|', @fields); + + open my $fd, $file or die "$file: $!\n"; + for (<$fd>) { + if (/^\s*($pat)\s+(.+)/) { + $config->{$1} = $2; + } + } + close $fd; + + for (qw(db_type db_name)) { + die "$configfile: missing $_ field\n" unless $config->{$_}; + } + return $config; +} From fd0131439ea09a1c7f727d2cca52e86d97a27ebc Mon Sep 17 00:00:00 2001 From: "Konstantin A. Lepikhov" Date: Thu, 11 Nov 2021 10:01:38 +0100 Subject: [PATCH 02/10] mailman2sympa.sh: add notes for password - show notes about `upgrade_sympa_password.pl` run after users import (as users password imported as clear text and need to converted to hashes). --- utils/mailman2sympa/mailman2sympa.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/utils/mailman2sympa/mailman2sympa.sh b/utils/mailman2sympa/mailman2sympa.sh index 3264873..4532391 100755 --- a/utils/mailman2sympa/mailman2sympa.sh +++ b/utils/mailman2sympa/mailman2sympa.sh @@ -99,6 +99,9 @@ read IMPORT if [ "$IMPORT" == "y" ]; then ./loadsubscribers.sh + if [ "$?" -eq 0 ]; then + echo "Import complete. Don't forget to run 'sympa_upgrade_password.pl' to update password hashes" + fi fi echo From e973af0328fa4ff53076011cbc4feea06f606829 Mon Sep 17 00:00:00 2001 From: "Konstantin A. Lepikhov" Date: Thu, 11 Nov 2021 10:11:43 +0100 Subject: [PATCH 03/10] Changes: update --- utils/mailman2sympa/Changes | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/utils/mailman2sympa/Changes b/utils/mailman2sympa/Changes index 73c82ae..53e7b4f 100644 --- a/utils/mailman2sympa/Changes +++ b/utils/mailman2sympa/Changes @@ -1,9 +1,10 @@ -mailman2sympa 0.7, Konstantin Lepikhov - Nov 2020 +mailman2sympa 0.7, Konstantin Lepikhov - Nov 2021 + rewrote configuration parsing (use python unpickle) + import list info (if exists) + don't import if list host_name doesn't match + handle unicode names for users/subscribers ++ update import users script for sql scheme changes. mailman2sympa 0.5, John Bazik - May 2010 From 7c18aa29dab219bb54474f35a02be344ca556226 Mon Sep 17 00:00:00 2001 From: "Konstantin A. Lepikhov" Date: Thu, 11 Nov 2021 10:12:01 +0100 Subject: [PATCH 04/10] BUGS: update --- utils/mailman2sympa/BUGS | 2 -- 1 file changed, 2 deletions(-) diff --git a/utils/mailman2sympa/BUGS b/utils/mailman2sympa/BUGS index 8adb600..12e9b89 100644 --- a/utils/mailman2sympa/BUGS +++ b/utils/mailman2sympa/BUGS @@ -2,6 +2,4 @@ BUGS: The script to load the admins doesn't query the comment_user correctly -Non-[a-z] characters in Gecos are escaped \xf3 - probably other stuff too. From 2964a66b7fa433fcfb809aba5be158f463121388 Mon Sep 17 00:00:00 2001 From: "Konstantin A. Lepikhov" Date: Thu, 11 Nov 2021 10:12:37 +0100 Subject: [PATCH 05/10] README: convert to md --- utils/mailman2sympa/{README => README.md} | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) rename utils/mailman2sympa/{README => README.md} (82%) diff --git a/utils/mailman2sympa/README b/utils/mailman2sympa/README.md similarity index 82% rename from utils/mailman2sympa/README rename to utils/mailman2sympa/README.md index 1a924b6..b5da900 100644 --- a/utils/mailman2sympa/README +++ b/utils/mailman2sympa/README.md @@ -1,5 +1,4 @@ -Presentation ------------- +## Presentation Mailman2sympa is a set of scripts aimed to facilitate the migration of mailing list managed by mailman to sympa. @@ -11,8 +10,7 @@ project manager. I hope that each user will have the good idea to send back all enhancement they would have to apply to the package. -Features --------- +## Features The version 0.0.3 of the package can do the following tasks: @@ -23,7 +21,7 @@ The version 0.0.3 of the package can do the following tasks: with the appropriates attributes, when still relevant. - creates an aliases file to be concatenated at the bottom - of /etc/aliases. + of `/etc/aliases`. - split the archives stored by mailman into the mhonarc archive directory @@ -33,8 +31,8 @@ The version 0.0.3 of the package can do the following tasks: nicely process attachments. - load the subscribers files into the database. Can specify - a different database (NEW_DATABASE) for testing. Change - NEW_DATABASE=DATABASE for migration + a different database `(NEW_DATABASE)` for testing. Change + `NEW_DATABASE=DATABASE` for migration This scripts gave me a good result, but I'm not sure they would for you. If you have problems, I can take an hand, @@ -51,7 +49,10 @@ Philippe Allart DumperSwitchboard problem - edit $MAILMAN_HOME/bin/dumpdb as follows: http://arkiv.netbsd.se/?ml=mailman-users&a=2007-07&t=4791032 -Required packages: -gawk -libdbd-csv-perl -procmail (for archive migration) +### Required packages: +- gawk +- libdbd-csv-perl +- procmail (for archive migration) +- perl-JSON +- jq +- python2 (pickle and json modules) From aba05fd0ceec571c9cebae059f711cc065ef638c Mon Sep 17 00:00:00 2001 From: "Konstantin A. Lepikhov" Date: Thu, 11 Nov 2021 10:12:44 +0100 Subject: [PATCH 06/10] TODO: update --- utils/mailman2sympa/TODO | 2 ++ 1 file changed, 2 insertions(+) diff --git a/utils/mailman2sympa/TODO b/utils/mailman2sympa/TODO index 9035da2..28dff23 100644 --- a/utils/mailman2sympa/TODO +++ b/utils/mailman2sympa/TODO @@ -16,3 +16,5 @@ script and look for the "send" rule in there. The mm2s_info script doesn't always work, and isn't integrated into the framework. The info field in mailman is just a field, but in sympa it's a separate file. + +Virtual domains supprt \ No newline at end of file From 29816126ec24d4263601d8899c0e085991638dde Mon Sep 17 00:00:00 2001 From: "Konstantin A. Lepikhov" Date: Thu, 11 Nov 2021 10:14:30 +0100 Subject: [PATCH 07/10] awk: drop vim leftovers --- utils/mailman2sympa/awk/.subscribers.awk.swp | Bin 12288 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 utils/mailman2sympa/awk/.subscribers.awk.swp diff --git a/utils/mailman2sympa/awk/.subscribers.awk.swp b/utils/mailman2sympa/awk/.subscribers.awk.swp deleted file mode 100644 index 6dddd9029c76ca0b3178c373779dc97e0300c9f4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12288 zcmeI2OKjXk7{{kP3Jawm5b6mu@wV(E*+({M`UnmQB&s5sw4|j)Y&I+JW|EqC?Ul#d z5JC_YHx8|YRK#0cxN$+^(F+`bVyzZJc=JGs#Z%r}o6*~|+upI{mO8v#8)h#iO>h#iO>h#iO>h#j~E9PpYu$iJA!ZQwlE;e(I(6*~|+5IYb%5IYb%5IYb% z5IYb%5IYb%5IYb%aEmx#%oB1Qb2)H3-thnb;@<%NzMqi4z#rgua1C4lya7AHWsxId~tu3*G^5gLA+FC%`1w4@#g2 z3gC9|<1RwJ0H1+R!9`$!7k~+lfh6bw6zl|7@5Q*_3iuve248|Vz>A;^CO|KsU=R4` z9?TD10v8%m5AC3ohLOJ@7a<1Re%AP%G!a8h8mD0-}C~!2jg6MiNcew7rG2 zR;23BKCbmqyH<@n$daKWlukT%{3z858a+CB;v~Ls&+xc5OcKzLgi8DPF#g((-Czwo z2P1ye9lOp93kSthGqW~^5Hc7DeQ>0Yj*p$3z&IoH^!Vfq!w!E7`g*NaAy$6+yM z!d#%~aD=MVDEnF!s_V2rLsv;+!Ew<|4M9ztt~*2aStF1OOi-am-Xo#)igL?cHH@!2#cV2XijJLXfNy#o&_Ue z1Szv2qwPnRq{p3E4d+JpaT#NHAVWpoHd7NB3s0dvI@Ltt5ef1Xh9>7N2WZWK62Ag)?2cNyE@Btbe~Bee5xMa_s4e>h!UxvB{&luGtQZ z#iH{}yTwHARW6;TM{|BPB-C2eWoaambll`d&0^!sGS4!1#UBG_j07|3&?rgOa898L z#+<<_fX1<9`?$kB9#tx-bayBXN+qMd6oxWZU$UKLi_I^x4GM!@6b?!SnUPS#pU#xo zU{p*_WEE?KI=0m@w}V~u`iG=oyV7*czktbviySFmhPs?Qpqxq46Rl>`Wt<=Pm+lN} znD#t#X%5#RkK*EHu?Dj}HZLws@+rcoRRi6;8d7E@sqgVLF0zJKKV#a9C!MBQ=MZlg zD>b&IA%?n{*klEv@DP3n0x-L_Ls=W~-s1@(;mHtkq zE+OrGED>xvdhmq@K|&$e8}#5yv{9@pIbpRt|vT+E%X)E3PK4&ZF{;11*XbaL!MVv_q_bU?!^IWTC84wPg}nnO!q059-lSMV$U{k!i|F3g`WuF?vQt zO-{97`xAGH{+wje+7`LYYq>UdV2)LccO-t1*|9xL>`!aiR zYpKo7_KS~2ym6GpLd&j;n(inVE{aqHx0(KS)Wa&;vU)aMF6ItZvYGOn{M;;lzrNP% zdycr+xVXa-6PBqHR`t9>wS0CopT(lZZ(Y;Sm=xb47MACX+)HD*=P`c1nyaMC9Y3?9 zk>5EPXuCaE$!EJoEb`PIV)Y5yn@$NC3{kCQQ-^7JwOpaS8KkZ}H(J3Mb16utLbcM( T@~18U!Su Date: Thu, 11 Nov 2021 10:19:10 +0100 Subject: [PATCH 08/10] scripts: remove mm2s_info - jq does the better job. --- utils/mailman2sympa/scripts/mm2s_info | 18 ------------------ 1 file changed, 18 deletions(-) delete mode 100755 utils/mailman2sympa/scripts/mm2s_info diff --git a/utils/mailman2sympa/scripts/mm2s_info b/utils/mailman2sympa/scripts/mm2s_info deleted file mode 100755 index 5c01f5c..0000000 --- a/utils/mailman2sympa/scripts/mm2s_info +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/perl -w -# -# mailman2sympa doesn't convert the mailman info field, since, in -# sympa, it's a separate, per-list file (expl/listname/info). -# -# This script does the simple conversion of that field. -# -# dumpdb listname.pck | mm2s_info > expl/listname/info - -for () { - next unless /^\s*'info':\s*'(.*)'/; - $_ = $1; - s/\\n/\n/g; - s/\\r/\r/g; - s/\\t/\t/g; - print $_, "\n" if $_; - exit 0; -} From 53e1b0ac6a31a0a5a8c38b46d1d9f889d7a2c452 Mon Sep 17 00:00:00 2001 From: "Konstantin A. Lepikhov" Date: Thu, 11 Nov 2021 10:24:00 +0100 Subject: [PATCH 09/10] docs: update password upgrade command --- utils/mailman2sympa/docs/INSTALL | 2 +- utils/mailman2sympa/loadsubscribers.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/utils/mailman2sympa/docs/INSTALL b/utils/mailman2sympa/docs/INSTALL index 953bf94..eb4842e 100644 --- a/utils/mailman2sympa/docs/INSTALL +++ b/utils/mailman2sympa/docs/INSTALL @@ -42,7 +42,7 @@ After completion 'loadsubscribers_from_config.sh') or mailman2sympa-generated CSV-Files in WDIR (see 'conf/mailman2sympa.conf') -- run 'crypt_passwords.pl' from sympa-directory (usually in /sbin or /bin) +- run 'upgrade_sympa_password.pl' from sympa-directory (usually in /sbin or /bin) For 'mailman2sympa.sh' you can give as parameter a file name containing the names of the diff --git a/utils/mailman2sympa/loadsubscribers.sh b/utils/mailman2sympa/loadsubscribers.sh index e48e798..0285468 100755 --- a/utils/mailman2sympa/loadsubscribers.sh +++ b/utils/mailman2sympa/loadsubscribers.sh @@ -4,4 +4,4 @@ ./scripts/loadsubscribers.pl -# [ -x "${SYMPA_SMTPSCRIPTS}"/crypt_passwd.pl ] && "${SYMPA_SMTPSCRIPTS}"/crypt_passwd.pl +# [ -x "${SYMPA_SMTPSCRIPTS}"/upgrade_sympa_passwd.pl ] && "${SYMPA_SMTPSCRIPTS}"/upgrade_sympa_passwd.pl From 008c01f19fe08845fc0578925ad429dbac7d04cf Mon Sep 17 00:00:00 2001 From: "Konstantin A. Lepikhov" Date: Thu, 11 Nov 2021 10:25:48 +0100 Subject: [PATCH 10/10] README: add link to mailman2sympa --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 7079cd6..15b24b4 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,7 @@ it You can also update this README by giving a brief description of your contrib Tools for sysadmins. * [datasources_utils](utils/datasources_utils/README.md): view and test list datasources and custom attributes datasources +* [mailman2sympa](utils/mailman2sympa/README.md): mailman 2.x migration scripts * [sympatoldap](utils/sympatoldap/README.md): creates LDAP entries for every list (and its aliases) whose status is open on the LDAP server * [splitting_daemons_logs](utils/splitting_daemons_logs/README.md): split Sympa processus logs into separated files * [sqlite2mysql](utils/sqlite2mysql/README.md): attempt to convert sqlite to mysql