diff options
Diffstat (limited to 'debian/local/parsemc')
-rw-r--r-- | debian/local/parsemc | 608 |
1 files changed, 608 insertions, 0 deletions
diff --git a/debian/local/parsemc b/debian/local/parsemc new file mode 100644 index 0000000..81a180e --- /dev/null +++ b/debian/local/parsemc @@ -0,0 +1,608 @@ +#!/bin/bash +# +# Parse Sendmail config for databases +# +# Copyright (c) 1999, Richard Nelson <cowboy@debian.org>. +# Time-stamp: <1999/05/19 10:00:00 cowboy> +# +# Notes (to all): +# * assumes makemap dbtype /etc/mail/database < /etc/mail/database +# * Does *not* run with sh=ash (no echo -e support) +# +# Notes (to self): +# * changes made herein *must* be reflected in parsemc,updatedb,debian.m4 +# * remember to change gawk to awk before release (gawk is more anal) +# * multiple db options not supported +# * chmod/chown of secondary alias databases not being done - no harm... +# * userdb can also have multiple databases and then a forward! +# * need sendmail stop/start +# +# List of db features +db_features="access_db bitdomain domaintable genericstable \ + mailertable uucpdomain virtusertable use_cw_file use_ct_file"; +export db_features; +# kluge for userdb, cr, ct, and cw files support +db_files="confCR_FILE confUSERDB_SPEC ALIAS_FILE"; +db_files="sendmail.mc $db_features $db_files"; +export db_files; +# +# Variables for documentation +date=$(date) +export date +user=$USER +export user +hostname=$(hostname) +export hostname +script=$0 +export script +directory=$(pwd) +export directory + +#------------------------------------------------------------------------ +# My first awk program ;-} +pattern='BEGIN { \ + # List of db features, split into an array \ + str = ENVIRON["db_features"]; \ + split(str, db_features); \ + str = ENVIRON["db_files"]; \ + split(str, db_files); \ + # Prefill entries based upon sendmail/debian defaults \ + str = "sendmail.mc m4 - /etc/mail/sendmail.mc -"; \ + split(str, entry); \ + dbs[entry[1]] = entry[2]":"entry[3]":"entry[4]":"entry[5]":"; \ + str = "MAIL_SETTINGS_DIR /etc/mail/ - - -"; \ + split(str, entry); \ + db_loc=entry[2]; \ + dbs[entry[1]] = entry[2]":"entry[3]":"entry[4]":"entry[5]":"; \ + str = "DATABASE_MAP_TYPE hash - - -"; \ + split(str, entry); \ + db_type=entry[2]; \ + dbs[entry[1]] = entry[2]":"entry[3]":"entry[4]":"entry[5]":"; \ + str = "confUSERDB_SPEC btree -o /etc/mail/users -"; \ + split(str, entry); \ + dbs[entry[1]] = entry[2]":"entry[3]":"entry[4]":"entry[5]":"; \ + str = "confCR_FILE - -o /etc/mail/relay-domains %[^\#]"; \ + split(str, entry); \ + dbs[entry[1]] = entry[2]":"entry[3]":"entry[4]":"entry[5]":"; \ + str = "confCT_FILE - -o /etc/mail/trusted-users %[^\#]"; \ + split(str, entry); \ + dbs[entry[1]] = entry[2]":"entry[3]":"entry[4]":"entry[5]":"; \ + str = "confCW_FILE - -o /etc/mail/local-host-names %[^\#]"; \ + split(str, entry); \ + dbs[entry[1]] = entry[2]":"entry[3]":"entry[4]":"entry[5]":"; \ + str = "ALIAS_FILE newaliases - /etc/mail/aliases -"; \ + split(str, entry); \ + dbs[entry[1]] = entry[2]":"entry[3]":"entry[4]":"entry[5]":"; \ + }; \ + # Look for default database location \ + # define(MAIL_SETTINGS_DIR, /etc/mail/)dnl # comment \ + /^[:space:]*define\([:space:]*`?MAIL_SETTINGS_DIR/ { \ + str = $0; \ + # Strip garbage from string \ + sub(/define\(/, "", str); \ + sub(/\)(dnl)?.*/, "", str); \ + sub(/\,/, "", str); \ + gsub(/`/, "", str); \ + gsub(/'"'"'/, "", str); \ + split(str, entry); \ + entry[5] = "-"; \ + entry[4] = "-"; \ + entry[3] = "-"; \ + db_loc=entry[2]; \ + # Save lastmost entry \ + dbs[entry[1]] = entry[2]":"entry[3]":"entry[4]":"entry[5]":"; \ + } \ + # Look for default database type \ + # define(DATABASE_MAP_TYPE, hash)dnl # comment \ + /^[:space:]*define\([:space:]*`?DATABASE_MAP_TYPE/ { \ + str = $0; \ + # Strip garbage from string \ + sub(/define\(/, "", str); \ + sub(/\)(dnl)?.*/, "", str); \ + sub(/\,/, "", str); \ + gsub(/`/, "", str); \ + gsub(/'"'"'/, "", str); \ + split(str, entry); \ + entry[5] = "-"; \ + entry[4] = "-"; \ + entry[3] = "-"; \ + db_type=entry[2]; \ + # Save lastmost entry \ + dbs[entry[1]] = entry[2]":"entry[3]":"entry[4]":"entry[5]":"; \ + } \ + # Look for userdb specification \ + # define(confUSERDB_SPEC, /etc/mail/users.db)dnl # comment \ + /^[:space:]*define\([:space:]*`?confUSERDB_SPEC/ { \ + str = $0; \ + # Strip garbage from string \ + sub(/define\(/, "", str); \ + sub(/\)(dnl)?.*/, "", str); \ + sub(/\,/, "", str); \ + gsub(/`/, "", str); \ + gsub(/'"'"'/, "", str); \ + split(str, entry); \ + entry[5] = "-"; \ + entry[4] = entry[2]; \ + entry[3] = "-o"; \ + entry[2] = "btree"; \ + # Save lastmost entry \ + sub(/\.db/, "", entry[4]); \ + dbs[entry[1]] = entry[2]":"entry[3]":"entry[4]":"entry[5]":"; \ + } \ + # Look for all confC?_FILE specifications \ + # define(confCR_FILE, -o /etc/mail/relay-domains %[^\#])dnl \ + # define(confCT_FILE, -o /etc/mail/sendmail.ct %[^\#])dnl \ + # define(confCW_FILE, -o /etc/mail/sendmail.cw %[^\#])dnl \ + /^[:space:]*define\([:space:]*`?confC[RTW]_FILE/ { \ + str = $0; \ + # Strip garbage from string \ + sub(/define\(/, "", str); \ + sub(/\)(dnl)?.*/, "", str); \ + sub(/\,/, "", str); \ + gsub(/`/, "", str); \ + gsub(/'"'"'/, "", str); \ + split(str, entry); \ + # Default elided info - format: \ + # name [ [opts] file [opts] ] \ + if (entry[2] == "-o") { \ + entry[5] = entry[4]; \ + entry[4] = entry[3]; \ + entry[3] = entry[2]; \ + } \ + else { \ + entry[5] = entry[3]; \ + entry[4] = entry[2]; \ + entry[3] = "-"; \ + entry[2] = "-"; \ + } \ + # Save lastmost entry \ + dbs[entry[1]] = entry[2]":"entry[3]":"entry[4]":"entry[5]":"; \ + } \ + # Look for all ALIAS_FILE specifications \ + #define(ALIAS_FILE, /etc/mail/aliases.private,/etc/mail/aliases)dnl \ + /^[:space:]*define\([:space:]*`?ALIAS_FILE/ { \ + str = $0; \ + # Strip garbage from string \ + sub(/define\(/, "", str); \ + sub(/\)(dnl)?.*/, "", str); \ + gsub(/ /, "", str); \ + sub(/\,/, " ", str); \ + gsub(/`/, "", str); \ + gsub(/'"'"'/, "", str); \ + split(str, entry); \ + entry[5] = "-"; \ + entry[4] = entry[2]; \ + entry[3] = "-"; \ + entry[2] = "newaliases"; \ + # Save lastmost entry \ + dbs[entry[1]] = entry[2]":"entry[3]":"entry[4]":"entry[5]":"; \ + } \ + # Locate all non-commented FEATURE macros \ + # FEATURE(name[, type [flags] file])dnl #comment \ + /^[:space:]*FEATURE\(.*\)/ { \ + str = $0; \ + # Strip garbage from string \ + sub(/FEATURE\(/, "", str); \ + sub(/\)(dnl)?.*/, "", str); \ + if (index(str, ",") != 0) { \ + sub(/\,/, "", str); \ + gsub(/`/, "", str); \ + gsub(/'"'"'/, "", str); \ + }; \ + split(str, entry); \ + # Ignore non-db features \ + for (x in db_features) { \ + if (entry[1] == db_features[x]) { \ + # Default elided info - format: \ + # name [type [opts] file] \ + if (entry[2] == "") { \ + entry[5] = "-"; \ + entry[4] = db_loc""entry[1]; \ + entry[3] = "-o"; \ + entry[2] = db_type; \ + if (entry[1] == "use_ct_file" || \ + entry[1] == "use_cw_file") { \ + if (entry[1] == "use_ct_file") \ + str = entry[1]":"dbs["confCT_FILE"]; \ + else \ + str = entry[1]":"dbs["confCW_FILE"]; \ + split(str, entry, ":"); \ + } \ + else if (entry[1] == "access_db") \ + entry[4] = db_loc"access"; \ + else if (entry[1] == "uucpdomain") \ + entry[4] = db_loc"uudomain"; \ + } \ + else if (entry[3] == "") { \ + entry[5] = "-"; \ + entry[4] = entry[2]; \ + entry[3] = "-"; \ + entry[2] = db_type; \ + } \ + else if (entry[4] == "") { \ + entry[5] = "-"; \ + entry[4] = entry[3]; \ + entry[3] = "-"; \ + }; \ + # Save lastmost entry \ + sub(/\.db/, "", entry[4]); \ + dbs[entry[1]]=entry[2]":"entry[3]":"entry[4]":"entry[5]":"; \ + }; \ + }; \ + }; \ + END { \ + # Print the found features \ + date = ENVIRON["date"]; \ + user = ENVIRON["user"]; \ + hostname = ENVIRON["hostname"]; \ + script = ENVIRON["script"]; \ + directory = ENVIRON["directory"]; \ + print "####################################################################"; \ + print "##### This file is automatically generated -- edit at your own risk"; \ + print "#####"; \ + print "##### file: /etc/mail/databases"; \ + print "##### generated via: "script; \ + print "##### by: "user"@"hostname; \ + print "##### on: "date; \ + print "##### in: "directory; \ + print "#####"; \ + print "##### The following databases are used by sendmail"; \ + print "#####"; \ + print "####################################################################"; \ + # delete unneeded elements \ + #delete dbs["MAIL_SETTINGS_DIR"]; \ + #delete dbs["DATABASE_MAP_TYPE"]; \ + #delete dbs["confCT_FILE"]; \ + #delete dbs["confCW_FILE"]; \ + for (x in dbs) \ + if (x != "ALIAS_FILE" && \ + x != "confUSERDB_SPEC") { \ + print x":"dbs[x]; \ + } \ + else { \ + split(x":"dbs[x], entry, ":"); \ + pfx = entry[1]":"entry[2]":"entry[3]; \ + str = entry[4]; \ + sfx = entry[5]":"; \ + sub(/\,/, " ", str); \ + split(str, entry); \ + for (y in entry) \ + print pfx":"entry[y]":"sfx; \ + } \ + }; \ + '; + +#------------------------------------------------------------------------ +# Make sure not using text mailertable (it doesn't work) +if (grep -q "^[[:space:]]*FEATURE(mailertable, \`text /etc/mail/mailertable')dnl" /etc/mail/sendmail.mc); then + sed "s?FEATURE(mailertable, \`text /etc/mail/mailertable')dnl?FEATURE(mailertable)dnl?g" \ + /etc/mail/sendmail.mc > /etc/mail/sendmail.mc.new + chown root.mail /etc/mail/sendmail.mc.new + chmod 0664 /etc/mail/sendmail.mc.new + mv /etc/mail/sendmail.mc.new /etc/mail/sendmail.mc + fi; + +#------------------------------------------------------------------------ +# parse /etc/mail/sendmail.mc +echo "Scanning /etc/mail/sendmail.mc" +awk -- "$pattern" /etc/mail/sendmail.mc > /etc/mail/databases; \ +chown root.mail /etc/mail/databases +chmod 0664 /etc/mail/databases +#cat /etc/mail/databases +#exit 0 + +#------------------------------------------------------------------------ +# check for extant, non automagically generated Makefile and abort if found +CFGFILE="/etc/mail/Makefile" +HEADER="##### This file is automatically generated -- edit at your own risk" +if [ -s $CFGFILE ]; then + if ! head -3 $CFGFILE | grep -q "^$HEADER" ; then + echo "Error: the current $CFGFILE is not automatically generated." + if [ "$1" != "force" ]; then + echo "Use \"$0 force\" to force (re)generation." + exit 1 + else + echo "force specified, (re)generating file anyway." + fi; + fi; + + fi; + +#------------------------------------------------------------------------ +echo -n "Creating /etc/mail/Makefile" +makefile="/etc/mail/Makefile.new " +cat <<EOT > $makefile +#!/usr/bin/make -f +#################################################################### +##### This file is automatically generated -- edit at your own risk +##### +##### file: /etc/mail/Makefile +##### generated via: $script +##### by: $user@$hostname +##### on: $date +##### in: $directory +##### +##### Makefile for Sendmail databases +##### +#################################################################### +SHELL=/bin/sh + +# flag used to ensure only one newaliases command is run +newaliases_run=0 + +# +# all, the default target will update everything +# +all: \\ +EOT +echo -n "." +# +# create all target +# +cnt=0 +for file in $db_files; do + line=$(egrep -e "^[[:space:]]*$file" /etc/mail/databases); + while ([ "$line" != "" ]); do + str=$(echo "$line" | cut -d " +" -f 1) + line=$(echo "$line" | cut -d " +" -f 2) + # Strip line back into four pieces: feature, type, opts, name + dbfeat=$(echo "$str" | cut -d ":" -f 1) + dbtype=$(echo "$str" | cut -d ":" -f 2) + dbopts=$(echo "$str" | cut -d ":" -f 3) + dbname=$(echo "$str" | cut -d ":" -f 4) + dbregx=$(echo "$str" | cut -d ":" -f 5) + if [ $(dirname "$dbname") = "/etc/mail" ]; then + dbsname=$(basename "$dbname") + else + dbsname="$dbname" + fi; + if [ "$dbtype" != "-" ]; then + cnt=`expr $cnt + 1`; + if [ $cnt -ne 1 ]; then + echo -e " \\" >> $makefile + fi; + if [ "$dbtype" = "m4" ]; then + echo -ne "\tsendmail.cf" >> $makefile + else + echo -ne "\t$dbsname.db" >> $makefile + fi; + fi; + done; + done; + +#------------------------------------------------------------------------ +cat <<EOT >> $makefile + +# +# clean target, remove sendmail.cf and databases +# +clean: +EOT +echo -n "." +for file in $db_files; do + line=$(egrep -e "^[[:space:]]*$file" /etc/mail/databases); + while ([ "$line" != "" ]); do + str=$(echo "$line" | cut -d " +" -f 1) + line=$(echo "$line" | cut -d " +" -f 2) + + # Strip line back into four pieces: feature, type, opts, name + dbfeat=$(echo "$str" | cut -d ":" -f 1) + dbtype=$(echo "$str" | cut -d ":" -f 2) + dbopts=$(echo "$str" | cut -d ":" -f 3) + dbname=$(echo "$str" | cut -d ":" -f 4) + dbregx=$(echo "$str" | cut -d ":" -f 5) + if [ $(dirname "$dbname") = "/etc/mail" ]; then + dbsname=$(basename "$dbname") + else + dbsname="$dbname" + fi; + if [ "$dbtype" != "-" ]; then + if [ "$dbtype" = "m4" ]; then + echo -e "\trm -f sendmail.cf" >> $makefile + else + echo -e "\trm -f $dbsname.db" >> $makefile + fi; + fi; + done; + done; + +#------------------------------------------------------------------------ +cat <<EOT >> $makefile + +# +# Individual targets +# +EOT +echo -n "." +cnt=0 +for file in $db_files; do + line=$(egrep -e "^[[:space:]]*$file" /etc/mail/databases); + while ([ "$line" != "" ]); do + str=$(echo "$line" | cut -d " +" -f 1) + line=$(echo "$line" | cut -d " +" -f 2) + + # Strip line back into four pieces: feature, type, opts, name + dbfeat=$(echo "$str" | cut -d ":" -f 1) + dbtype=$(echo "$str" | cut -d ":" -f 2) + dbopts=$(echo "$str" | cut -d ":" -f 3) + dbname=$(echo "$str" | cut -d ":" -f 4) + dbregx=$(echo "$str" | cut -d ":" -f 5) + if [ $(dirname "$dbname") = "/etc/mail" ]; then + dbsname=$(basename "$dbname") + else + dbsname="$dbname" + fi; + if [ "$dbtype" != "-" ]; then + cnt=`expr $cnt + 1`; + if [ $cnt -ne 1 ]; then + echo -e " " >> $makefile + fi; + if [ "$dbtype" = "m4" ]; then + echo -ne "sendmail.cf:\t$dbsname" >> $makefile + echo -e " dialup.m4 provider.m4" >> $makefile + else + echo -e "$dbsname.db:\t$dbsname" >> $makefile + fi; + pad="\t" + sfx="" + if [ "$dbopts" = "-o" ]; then + pad="\t\t" + sfx="; \\" + echo -e "\trm -f $dbname.db" >> $makefile + echo -e "\tif [ -s $dbname ] && \\" >> $makefile + echo -e "\t " \ + "egrep -qe \"^[[:space:]]*[^\$$\#]\"" \ + "$dbname; then \\" \ + >> $makefile + fi; + case "$dbtype" in + btree) + echo -e $pad"makemap -d $dbtype" \ + "$dbname.db < $dbname"$sfx >> $makefile + echo -e $pad"chown root.mail $dbname.db"$sfx \ + >> $makefile + echo -e $pad"chmod 0664 $dbname.db"$sfx \ + >> $makefile + ;; + dbm | btree | hash) + echo -e $pad"makemap $dbtype" \ + "$dbname.db < $dbname"$sfx >> $makefile + echo -e $pad"chown root.mail $dbname.db"$sfx \ + >> $makefile + echo -e $pad"chmod 0664 $dbname.db"$sfx \ + >> $makefile + ;; + text) + true; + ;; + newaliases) + echo -ne $pad"if [ \$(newaliases_run)" \ + >> $makefile + echo -e " -eq 0 ]; then \\" \ + >> $makefile + echo -e $pad"\tnewaliases_run=1; \\" \ + >> $makefile + echo -e $pad"\tnewaliases; \\" >> $makefile + echo -e $pad"\tfi" >> $makefile + echo -e $pad"chown root.mail $dbname.db" \ + >> $makefile + echo -e $pad"chmod 0664 $dbname.db" \ + >> $makefile + ;; + m4) + cat <<EOT >> $makefile + echo "Generating /etc/mail/sendmail.cf ..." + m4 \\ + /usr/share/sendmail/sendmail.cf/m4/cf.m4 \\ + /etc/mail/sendmail.mc \\ + > /etc/mail/sendmail.cf.new \\ + 2> /etc/mail/sendmail.cf.errors + chown root.mail /etc/mail/sendmail.cf.new + chmod 0644 /etc/mail/sendmail.cf.new + if [ ! -s /etc/mail/sendmail.cf.errors ]; then \\ + rm /etc/mail/sendmail.cf.errors; \\ + else \\ + cat /etc/mail/sendmail.cf.errors; \\ + echo ""; \\ + fi; + # Can't tell if the errors are fatal or not ;-{ + mv -f /etc/mail/sendmail.cf.new /etc/mail/sendmail.cf; +EOT + ;; + *) + echo -e $pad"# $dbtype map not done herein" \ + >> $makefile + ;; + esac + if [ "$dbopts" = "-o" ]; then + echo -e "\t\tfi;" >> $makefile + fi; + fi; + done; + done; + +cat <<EOT >> $makefile +# +# Optional targets... Will be touched if they don't exist. +# +EOT +echo -n "." +cnt=0 +for file in $db_files; do + line=$(egrep -e "^[[:space:]]*$file" /etc/mail/databases); + while ([ "$line" != "" ]); do + str=$(echo "$line" | cut -d " +" -f 1) + line=$(echo "$line" | cut -d " +" -f 2) + + # Strip line back into four pieces: feature, type, opts, name + dbfeat=$(echo "$str" | cut -d ":" -f 1) + dbtype=$(echo "$str" | cut -d ":" -f 2) + dbopts=$(echo "$str" | cut -d ":" -f 3) + dbname=$(echo "$str" | cut -d ":" -f 4) + dbregx=$(echo "$str" | cut -d ":" -f 5) + if [ $(dirname "$dbname") = "/etc/mail" ]; then + dbsname=$(basename "$dbname") + else + dbsname="$dbname" + fi; + + if [ "$dbopts" = "-o" ]; then + cnt=`expr $cnt + 1`; + if [ $cnt -ne 1 ]; then + echo -e " " >> $makefile + fi; + echo -e "$dbsname:" >>$makefile + echo -e "\ttouch $dbname" >>$makefile + echo -e "\tchmod 0664 $dbname" >>$makefile + echo -e "\tchown root.mail $dbname" >>$makefile + fi; + + done; + done; + +cat <<EOT >> $makefile + +# +# A few special targets that may not exists... +# + +# dialup.m4 - created/updated by /etc/ppp/ip-up.d/sendmail +# used to provide the true, hopefully resolvable +# hostname (from the ISP nameservers) +# +# To activate, put this in /etc/mail/sendmail.mc: +# include(\`/etc/mail/dialup.m4')dnl +dialup.m4: + touch /etc/mail/dialup.m4 + chmod 0664 /etc/mail/dialup.m4 + chown root.mail /etc/mail/dialup.m4 + +# provider.m4 - created by the user, or /etc/ppp/ip-up.d/sendmail +# used to provide ISP information (masquerade_as, etc.) +# If its a link, it will *not* be overwritten +# +# To activate, put this in /etc/mail/sendmail.mc: +# include(\`/etc/mail/provider.m4')dnl +provider.m4: + touch /etc/mail/provider.m4 + chmod 0664 /etc/mail/provider.m4 + chown root.mail /etc/mail/provider.m4 + +EOT +echo -n "." + +echo " done." + +#------------------------------------------------------------------------ +chown root.mail $makefile +chmod 0770 $makefile +mv $makefile /etc/mail/Makefile +exit 0 |