#!/usr/bin/perl
# ====================================================================
# The Apache Software License, Version 1.1
#
# Copyright (c) 2000-2003 The Apache Software Foundation.  All rights
# reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in
#    the documentation and/or other materials provided with the
#    distribution.
#
# 3. The end-user documentation included with the redistribution,
#    if any, must include the following acknowledgment:
#       "This product includes software developed by the
#        Apache Software Foundation (http://www.apache.org/)."
#    Alternately, this acknowledgment may appear in the software itself,
#    if and wherever such third-party acknowledgments normally appear.
#
# 4. The names "Apache" and "Apache Software Foundation" must
#    not be used to endorse or promote products derived from this
#    software without prior written permission. For written
#    permission, please contact apache@apache.org.
#
# 5. Products derived from this software may not be called "Apache",
#    nor may "Apache" appear in their name, without prior written
#    permission of the Apache Software Foundation.
#
# THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
# ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
# ====================================================================
#
# This software consists of voluntary contributions made by many
# individuals on behalf of the Apache Software Foundation.  For more
# information on the Apache Software Foundation, please see
# <http://www.apache.org/>.
#

# Based on the dbmmanage script from Apache 2.0
#
# usage: dbmchroot <DBMfile> <command> <user> <rootpath> <intialroot>

package dbmchroot;
#                               -ldb    -lndbm    -lgdbm    -lsdbm
BEGIN { @AnyDBM_File::ISA = qw(DB_File NDBM_File GDBM_File SDBM_File) }
use strict;
use Fcntl;
use AnyDBM_File ();

sub usage {
    my $cmds = join "|", sort keys %dbmc::;
    die <<SYNTAX;
Usage: dbmmanage dbname command [username [rootpath [initialpath [comment]]]

    command is one of: $cmds

	username is the user
	rootpath is the chroot for the user
	initialpath is the initial path from the chroot set on login
	comment is a comment to attach to the record
SYNTAX
}

my($file,$command,$key,$rootpath,$initialpath,$comment) = @ARGV;

usage() unless $file and $command and defined &{$dbmc::{$command}};

# remove extension if any
my $chop = join '|', qw{db.? pag dir};
$file =~ s/\.($chop)$//;

my $is_update = $command eq "update";
my %DB = ();
my @range = ();
my($mode, $flags) = $command =~ 
    /^(?:view|check)$/ ? (0644, O_RDONLY) : (0644, O_RDWR|O_CREAT);

tie (%DB, "AnyDBM_File", $file, $flags, $mode) || die "Can't tie $file: $!";
dbmc->$command();
untie %DB;


sub dbmc::update {
    die "Sorry, user `$key' doesn't exist!\n" unless $DB{$key};
    dbmc->add;
}

sub dbmc::add {
    unless($is_update) {
		die "Sorry, user `$key' already exists!\n" if $DB{$key};
    }
	$initialpath .= ":" . $comment if $comment;
    $rootpath .= ":" . $initialpath if $initialpath;
    $DB{$key} = $rootpath;
    my $action = $is_update ? "updated" : "added";
    print "User $key $action\n";
}

sub dbmc::delete {
    die "Sorry, user `$key' doesn't exist!\n" unless $DB{$key};
    delete $DB{$key}, print "`$key' deleted\n";
}

sub dbmc::view {
    print $key ? "$key:$DB{$key}\n" : map { "$_:$DB{$_}\n" if $DB{$_} } keys %DB;
}

sub dbmc::import {
    while(defined($_ = <STDIN>) and chomp) {
	($key,$rootpath,$initialpath,$comment) = split /:/, $_, 4;
	dbmc->add;
    }
}
