#!/usr/local/bin/perl5 -- # -*- perl -*-
###########################################################################
#
# Name:
#    adduser - add new user
#
# Usage:
#    adduser [-vn] [-g gid] [-u uid] login realname email shell
#
# Options:
#    -u uid ... Specify numeric uid, e.g. 123
#    -g gid ... Sepcify group, either numerif or any from /etc/group
#    -v ....... Verbose; -v -v gives more output
#    -n ....... Do Not! This implies -v -v
#
# Arguments:
#    login .... any valid login-name, may not exist
#    realname . description, no "," here!
#    email .... valid email-address (must contain "@")
#    shell .... shell to use, must be in /etc/shells
#
#
# This script creates:
#    1.) Entry in passwd (via vipw)
#    2.) Home-Dir + Permissions (from /etc/skel)
#    3.) Mail-folder
#    4.) Empty crontab
#
# Date:
#    March   9th, 1994
#    July   11th, 1994 - replace vi by ex, Arguments of crontab
#    August 27th, 1994 - vipw is in /usr/sbin in NetBSD-1.0BETA
#    Dec,   27th, 1995 - escape some variables in edit_passwd for perl5
#
# Author:
#    Hubert Feyrer, hubert.feyrer@rz.uni-regensburg.de
#    Copyright (c) 1994 Hubert Feyrer. All rights reserved.
#
###########################################################################


$DEFAULT_GROUP="guest";
$MIN_UID=1000;			# Lowest possible uid
$MAX_UID=9000;
$ETC_SHELLS="/etc/shells";
$MAILDIR="/var/mail";
$HOMEBASE="/home/dusk";
$not=0;
$verbose=0;
$v='';

#
# Little sanity-check
#
die "$0: Only root is allowed to run this!\n" if $>;

#
# Parse options
#
$gid=getgrnam("$DEFAULT_GROUP");
$uid=-1;
while($ARGV[0]=~/^-/){
    if($ARGV[0]=~/^-u(.*)/){
	if($1=~/\d+/){
	    $uid=$1;
	}else{
	    shift;
	    $uid=$ARGV[0];
	}
    }elsif($ARGV[0]=~/^-g(.*)/){
	if($1=~/.+/){
	    $gid=$1;
	}else{
	    shift;
	    $gid=$ARGV[0];
	}

	if($gid!~/\d+/){
	    if(!getgrnam($gid)){
		die "$0: unknown group \'$gid\'\n";
	    }else{
		$gid=getgrnam($gid);
	    }
	}
    }elsif($ARGV[0]=~/^-n/){
	$not=1;
	$verbose=2;
    }elsif($ARGV[0]=~/^-v/){
	$verbose++;
	$v=':' if $verbose>1;
    }else{
	die "$0: unknown option \'$ARGV[0]\'\n";
    }
    shift;
}

if( $#ARGV != 3 ){
    die "Usage: $0 [-vn] [-u uid] [-g gid] login realname email shell\n";
}

$login=$ARGV[0];
$realname=$ARGV[1];
$email=$ARGV[2];
$shell=$ARGV[3];

# Does $login already exist?
{
    if(getpwnam($login)){
	die "$0: User \"$login\" already exists. Exiting...\n";
    }
}

# Check for "," in realname
{
    if($realname=~/,/){
	die "$0: No \",\" allowed in realname!\n";
    }
}

# Check for "@" in email-address
{
    if($email!~/@/){
	die "$0: No \"@\" in email-address.\n";
    }
}

# Check for valid shell (/etc/shells)
{
    open(SHELLS,"<$ETC_SHELLS") || die "$0: Can't open \"$ETC_SHELLS\": $!\n";
    $found=0;
  loop:
    while(<SHELLS>){
	if(/^$shell$/){
	    $found=1;
	    last loop;
	}
    }
    close(SHELLS);
    if(!$found){
	die "$0: \"$shell\" not a valid login-shell.\n";
    }
}

# find next unused uid
{
    if($uid==-1){
	$uid=$MIN_UID;
	while($uid<$MAX_UID && getpwuid($uid)){ $uid++; }
	if($uid==$MAX_UID){
	    die "$0: No more free uid's. Maximum of $MAX_UID reached.\n";
	}
    }
}


&edit_passwd;
&create_homedir;
&create_mailfolder;
&create_crontab;

endgrent;
endpwent;
exit 0;

###########################################################################
sub edit_passwd
{
    $entry="${login}::${uid}:${gid}::0:0:${realname},${email},,:${HOMEBASE}/${login}:${shell}";

    print "Adding entry to passwd$v\n" if $verbose>0;
    print "\t$entry\n" if $verbose>1;
    if(!$not){
	$rv=system("EDITOR=/usr/bin/ex ; export EDITOR ; ( echo 'a' ; echo '${entry}' ; echo . ; echo x ) | /usr/sbin/vipw >/dev/null");
	$rv>>=8;
	if($rv){
	    die "$0: Fatal error in vipw!\n";
	}
    }

    print "\n" if $verbose>1;
}

###########################################################################
sub create_homedir
{
    $n_gid=getgrgid($gid);
    
    print "Munching up homedir$v\n" if $verbose>0;

    $cmd="cp -pr /etc/skel $HOMEBASE/$login";
    print "\t$cmd\n" if $verbose>1;
    system "$cmd" if !$not;

    $cmd="chown -R $login.$n_gid $HOMEBASE/$login";
    print "\t$cmd\n" if $verbose>1;
    system "$cmd" if !$not;

    print "\n" if $verbose>1;
}

###########################################################################
sub create_mailfolder
{
    $n_gid=getgrgid($gid);

    print "Creating Mailfolder$v\n" if $verbose>0;

    $cmd="cp /dev/null $MAILDIR/$login";
    print "\t$cmd\n" if $verbose>1;
    system  "$cmd" if !$not;

    $cmd="chmod 700 $MAILDIR/$login";
    print "\t$cmd\n" if $verbose>1;
    system  "$cmd" if !$not;

    $cmd="chown $login.$n_gid $MAILDIR/$login";
    print "\t$cmd\n" if $verbose>1;
    system  "$cmd" if !$not;

    print "\n" if $verbose>1;
}

###########################################################################
sub create_crontab
{
    print "Creating empty crontab$v\n" if $verbose>0;

    $cmd="crontab -u $login /dev/null";
    print "\t$cmd\n" if $verbose>1;
    system  "$cmd" if !$not;

    print "\n" if $verbose>1;
}
