[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Maintaining /etc/mail/xxx databases for sendmail



I'm planning to have sendmailconfig update any user defined
databases as a normal part of its job.

To that end, I've now got a script that 
  * parses /etc/sendmail.mc and builds a list of databases
  * Runs makedb on the list
  * Any database that would be empty is *not* generated
  * If a database needs to be moved (from /etc/ to /etc/mail), the
    script will do so

The script runs fine here, and at home, but I'd appreciate any
feedback before I inflict this puppy on others (especially since
it contains my first awk script).

Here is what it does at work:
[badlands:/etc/mail 0]$ ./update 
Locating databases.
Updating databases.
makemap hash /etc/mail/access < /etc/mail/access
Informational: FEATURE(bitdomain) file empty: /etc/mail/bitdomain
makemap hash /etc/mail/domaintable < /etc/mail/domaintable
makemap hash /etc/mail/genericstable < /etc/mail/genericstable
makemap hash /etc/mail/mailertable < /etc/mail/mailertable
Informational: FEATURE(uucpdomain) no data: /etc/mail/uudomain
makemap hash /etc/mail/virtusertable < /etc/mail/virtusertable
makemap btree /etc/mail/users < /etc/mail/users

-- 
Rick Nelson
C:\WINDOWS C:\WINDOWS\GO C:\PC\CRAWL
#!/bin/sh
#
# Update Sendmail databases for Debian
#
# 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
#
# Notes (to self):
#   * remember to change gawk to awk before release (gawk is more anal)
#   * should alias databases also be done herein?
#
# List of db features
db_features="access_db bitdomain domaintable genericstable \
	     mailertable uucpdomain virtusertable";
# kluge for userdb support
db_features="$db_features confUSERDB_SPEC";
export db_features;
#
echo "Locating databases."
# My first awk program ;-}
pattern='BEGIN { \
		# List of db features, split into an array \
		str = ENVIRON["db_features"]; \
		split(str, db_features); \
		# Pre-fill kluge for userdb, it is in ostype/debian.m4 \
		str = "confUSERDB_SPEC btree - /etc/mail/users"; \
		split(str, entry); \
		dbs[entry[1]] = entry[2]" "entry[3]" "entry[4]; \
		# ditto for access_db \
		str = "access_db hash -o /etc/mail/access"; \
		split(str, entry); \
		dbs[entry[1]] = entry[2]" "entry[3]" "entry[4]; \
		}; \
	# Look for userdb specification \
	# define(confUSERDB_SPEC, /etc/mail/users.db)dnl \
	/^[:space:]*define\([:space:]*`?confUSERDB_SPEC/ { \
		str = $0; \
		# Strip garbage from string \
		sub(/define\(/, "", str); \
		sub(/\)dnl/, "", str); \
		sub(/\)/, "", str); \
		sub(/\,/, "", str); \
		gsub(/`/, "", str); \
		gsub(/'"'"'/, "", str); \
		split(str, entry); \
		entry[4] = entry[2]; \
		entry[2] = "btree"; \
		entry[3] = "-";
		# Save lastmost entry \
		sub(/.db/, "", entry[4]); \
		dbs[entry[1]] = entry[2]" "entry[3]" "entry[4]; \
		} \
	# Locate all non-commented FEATURE macros \
	# FEATURE(name[, type [flags] file]) \
 	/^[:space:]*FEATURE\(.*\)/ { \
		str = $0; \
		# Strip garbage from string \
		sub(/FEATURE\(/, "", str); \
		sub(/\)dnl/, "", str); \
		sub(/\)/, "", str); \
		if (index(str, ",") != 0) { \
		   sub(/\,/, "", str); \
		   sub(/`/, "", str); \
		   sub(/'"'"'/, "", 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[2] = "hash"; \
			 entry[3] = "-o"; \
			 if (entry[1] == "access_db") \
			    entry[4] = "/etc/mail/access"; \
			 else if (entry[1] == "uucpdomain") \
			    entry[4] = "/etc/mail/uudomain"; \
			 else \
			    entry[4] = "/etc/mail/"entry[1]; \
		         } \
		      else if (entry[4] == "") { \
			 entry[4] = entry[3]; \
			 entry[3] = "-o"; \
			 }; \
		      # Save lastmost entry \
		      sub(/.db/, "", entry[4]); \
		      dbs[entry[1]] = entry[2]" "entry[3]" "entry[4]; \
		      }; \
		   }; \
		}; \
	END { \
		# Print the found features \
		print "# The following database are used by sendmail"; \
		for (x in dbs) \
		    print x" "dbs[x]; \
		}; \
	';
awk -- "$pattern" /etc/mail/sendmail.mc > /etc/mail/databases; \
#cat /etc/mail/databases
#
echo "Updating databases."
for file in $db_features; do \
	line=$(egrep -e "^[[:space:]]*$file" /etc/mail/databases);
	if [ "$line" != "" ]; then
	   # Strip line back into four pieces: feature, type, opts, name
	   dbfeat=$(echo "$line" | cut -d " " -f 1)
	   dbtype=$(echo "$line" | cut -d " " -f 2)
	   dbopts=$(echo "$line" | cut -d " " -f 3)
	   dbname=$(echo "$line" | cut -d " " -f 4)
	   if [ "$dbopts" = "-" ]; then
	      dbopts="";
	      fi;
	   # Locate database, moving it to /etc/mail if need be
	   if [ ! -f "$dbname" ]; then
	      echo "Warning: FEATURE($dbfeat) file not found: $dbname"
	      if [ -f /etc/$(basename "$dbname") ]; then
		 echo "  Aha! it is still in /etc/";
		 if [ ! -L /etc/$(basename "$dbname") ]; then
		    echo "  it isn't a link, will move it";
		    mv -f /etc/$(basename "$dbname"){,.db,.pag,.dir} \
			/etc/mail/ 1 >/dev/null 2>&1;
	            fi;
		 fi;
	   # Check database, and makemap iff needed
	   # Herein, we could move user specified databases...
	   else
	      if [ ! -s "$dbname" ]; then
	         echo "Informational: FEATURE($dbfeat) file empty: $dbname"
		 rm -rf $dbname{.db,.pag,.dir} 1 >/dev/null 2>&1
	      elif ! egrep -q -e "^[[:space:]]*[^$\#]" $dbname; then
	         echo "Informational: FEATURE($dbfeat) no data: $dbname"
		 rm -rf $dbname{.db,.pag,.dir} 1 >/dev/null 2>&1
	      else
	         #ls $dbname{,.db,.pag,.dir}
	         echo "makemap $dbtype $dbname < $dbname"
		 if [ "$dbtype" = "btree" ]; then
		    makemap $dbtype -d $dbname < $dbname
		 elif [ "$dbtype" = "text" ]; then
		    true;
		 else
		    makemap $dbtype $dbname < $dbname
		    fi;
	         fi;
	      fi;
	   fi;
	done;
exit 0
echo "calling sendmailconfig."
sendmailconfig

Reply to: