#!/usr/local/bin/perl
# save_dir.cgi
# Create or update a .htaccess file

require './htaccess-lib.pl';
&ReadParse();
@dirs = &list_directories();
&error_setup($text{'dir_err'});
&foreign_require($apachemod, "apache-lib.pl");

# Work out what .htaccess file to use
if ($in{'new'} && $in{'dir'} !~ /^\// && $default_dir ne "/") {
	# Make path absolute
	$in{'dir'} = "$default_dir/$in{'dir'}";
	}
($dir) = grep { $_->[0] eq $in{'dir'} } @dirs;
if ($in{'new'}) {
	$dir && &error($text{'dir_eclash'});
	$htaccess = "$in{'dir'}/$config{'htaccess'}";
	}
else {
	$htaccess = "$dir->[0]/$config{'htaccess'}";
	}

&lock_file($htaccess);
&lock_file($directories_file);

# Get the apache directives for the .htaccess file, if any
$conf = &foreign_call($apachemod, "get_htaccess_config", $htaccess);
$currfile = &foreign_call($apachemod, "find_directive",
			  "AuthUserFile", $conf, 1);
&lock_file($currfile) if ($currfile);

# Make sure it is allowed
&switch_user();
&can_access_dir($htaccess) || &error($text{'dir_ecannot'});
open(TEST, ">>$htaccess") || &error(&text('dir_ehtaccess', $htaccess, $!));
close(TEST);

if ($in{'delete'}) {
	if ($in{'remove'}) {
		# Blow away .htaccess and htpasswd
		unlink($htaccess);
		unlink($currfile) if ($currfile);
		@dirs = grep { $_ ne $dir } @dirs;
		}
	else {
		# Take the authentication directives out of the .htaccess
		@dirs = grep { $_ ne $dir } @dirs;
		&foreign_call($apachemod, "save_directive",
			      "require", [ ], $conf, $conf);
		}
	}
else {
	# Validate inputs?
	if ($in{'new'}) {
		$in{'dir'} =~ /^\// && -d $in{'dir'} ||
			&error($text{'dir_edir'});
		}
	if (!$can_htpasswd) {
		# Users file is always automatic
		$file = $in{'new'} ? "$in{'dir'}/$config{'htpasswd'}"
				   : $dir->[1];
		}
	elsif ($in{'auto'}) {
		# User choose for it to be automatic
		$file = "$in{'dir'}/$config{'htpasswd'}";
		}
	else {
		# Entered by user
		if ($in{'file'} !~ /^\//) {
			$file = "$in{'dir'}/$file";
			}
		else {
			$file = $in{'file'};
			}
		}
	$sync = join(",", grep { $in{'sync_'.$_} }
			       ('create', 'update', 'delete'));
	$sync ||= "-";

	if ($in{'new'}) {
		# Either update an existing .htaccess to ensure that all
		# needed directives exist, or create from scratch

		# Use the existing users path if there is one, otherwise add
		$currfile = &foreign_call($apachemod, "find_directive",
					  "AuthUserFile", $conf, 1);
		if ($currfile) {
			$file = $currfile;
			}
		else {
			&foreign_call($apachemod, "save_directive",
				      "AuthUserFile", [ $file ], $conf, $conf);
			}

		# Add an auth type if needed
		$currtype = &foreign_call($apachemod, "find_directive",
					  "AuthType", $conf, 1);
		if (!$currtype) {
			&foreign_call($apachemod, "save_directive",
				      "AuthType", [ "Basic" ], $conf, $conf);
			}

		# Add a realm if needed
		$currrealm = &foreign_call($apachemod, "find_directive",
					   "AuthName", $conf, 1);
		if (!$currrealm) {
			$in{'realm'} || &error($text{'dir_erealm'});
			&foreign_call($apachemod, "save_directive", "AuthName",
				      [ "\"$in{'realm'}\"" ], $conf, $conf);
			}

		# Add a require if needed
		$currrequire = &foreign_call($apachemod, "find_directive",
					     "require", $conf, 1);
		if (!$currrequire) {
			&foreign_call($apachemod, "save_directive",
				      "require", [ "valid-user" ],
						$conf, $conf);
			}

		# Add to the known directories list
		$sync = "-" if (!$can_sync);
		$dir = [ $in{'dir'}, $file, $in{'crypt'}, $sync ];
		push(@dirs, $dir);
		}
	else {
		# Just update the users file path and realm
		&foreign_call($apachemod, "save_directive",
			      "AuthUserFile", [ $file ],
					$conf, $conf);
		&foreign_call($apachemod, "save_directive",
			      "AuthName", [ "\"$in{'realm'}\"" ],
					$conf, $conf);

		# Update the known directories list
		$dir->[1] = $file;
		$dir->[2] = $in{'crypt'};
		$dir->[3] = $sync if ($can_sync);
		}

	# Create an empty users file if needed
	if (!-r $file) {
		&lock_file($file);
		open(FILE, ">$file") ||
			&error(&text('dir_ehtpasswd', $file, $!));
		close(FILE);
		&unlock_file($file);
		}
	}

&flush_file_lines();
&switch_back();

&save_directories(\@dirs);
&unlock_all_files();
&webmin_log($in{'delete'} ? "delete" : $in{'new'} ? "create" : "modify",
	    "dir", $dir->[0]);
&redirect("");

