diff --git a/cryptobox.conf.d/scripts/check_smb_idle.sh b/cryptobox.conf.d/usr/lib/cryptobox/check_smb_idle.sh similarity index 100% rename from cryptobox.conf.d/scripts/check_smb_idle.sh rename to cryptobox.conf.d/usr/lib/cryptobox/check_smb_idle.sh diff --git a/cryptobox.conf.d/scripts/chroot-start.sh b/cryptobox.conf.d/usr/lib/cryptobox/chroot-start.sh similarity index 100% rename from cryptobox.conf.d/scripts/chroot-start.sh rename to cryptobox.conf.d/usr/lib/cryptobox/chroot-start.sh diff --git a/cryptobox.conf.d/scripts/configure-cryptobox.sh b/cryptobox.conf.d/usr/lib/cryptobox/configure-cryptobox.sh similarity index 100% rename from cryptobox.conf.d/scripts/configure-cryptobox.sh rename to cryptobox.conf.d/usr/lib/cryptobox/configure-cryptobox.sh diff --git a/cryptobox.conf.d/scripts/cryptobox.sh b/cryptobox.conf.d/usr/lib/cryptobox/cryptobox.sh similarity index 100% rename from cryptobox.conf.d/scripts/cryptobox.sh rename to cryptobox.conf.d/usr/lib/cryptobox/cryptobox.sh diff --git a/cryptobox.conf.d/scripts/devel-features.sh b/cryptobox.conf.d/usr/lib/cryptobox/devel-features.sh similarity index 100% rename from cryptobox.conf.d/scripts/devel-features.sh rename to cryptobox.conf.d/usr/lib/cryptobox/devel-features.sh diff --git a/cryptobox.conf.d/scripts/firewall.sh b/cryptobox.conf.d/usr/lib/cryptobox/firewall.sh similarity index 100% rename from cryptobox.conf.d/scripts/firewall.sh rename to cryptobox.conf.d/usr/lib/cryptobox/firewall.sh diff --git a/cryptobox.conf.d/scripts/make_stunnel_cert.sh b/cryptobox.conf.d/usr/lib/cryptobox/make_stunnel_cert.sh similarity index 100% rename from cryptobox.conf.d/scripts/make_stunnel_cert.sh rename to cryptobox.conf.d/usr/lib/cryptobox/make_stunnel_cert.sh diff --git a/cryptobox.conf.d/var/www/cryptobox b/cryptobox.conf.d/var/www/cryptobox new file mode 100755 index 0000000..70e8e9b --- /dev/null +++ b/cryptobox.conf.d/var/www/cryptobox @@ -0,0 +1,310 @@ +#!/usr/bin/perl +# +# Vorbereitung: +# - die Variable "MNTIMAGE" (siehe unten) setzen - es muss der Name der cryptoloop-image-Datei sein +# - in die /etc/fstab einen passenden Eintrag einfuegen, z.B.: +# /data/cryptoimage.loop /mnt/crypto auto noauto,user,loop,encryption=aes,keybits=256 +# - ein Image erstellen (als root): +# dd if=/dev/zero of=cryptoimage.loop bs=1M count=10 +# losetup -k 256 -e aes /dev/loop1 cryptoimage.loop +# mkfs.ext3 /dev/loop1 +# losetup -d /dev/loop1 +# + + +############################################### + +use strict; +use CGI; +use ClearSilver; +use ConfigFile; + +my ($pagedata, $pagename); + +my ($LANGUAGE_DIR, $LANGUAGE, $TEMPLATE_DIR, $DOC_DIR); +my ($CB_SCRIPT, $LOG_FILE, $DEVELOPMENT_MARKER); + +my $config = ConfigFile::read_config_file('/etc/cryptobox/cryptobox.conf'); + +$CB_SCRIPT = $config->{CB_SCRIPT}; +$LOG_FILE = $config->{LOG_FILE}; +$LANGUAGE_DIR = $config->{LANGUAGE_DIR}; +$LANGUAGE = $config->{LANGUAGE}; +$TEMPLATE_DIR = $config->{TEMPLATE_DIR}; +$DOC_DIR = $config->{DOC_DIR}; +$DEVELOPMENT_MARKER = $config->{DEVELOPMENT_MARKER}; + + +#################### subs ###################### + +sub load_hdf() +{ + my $hdf = ClearSilver::HDF->new(); + + my $fname = "$LANGUAGE_DIR/$LANGUAGE" . '.hdf'; + die ("Language file ($fname) not found!") unless (-e "$fname"); + $hdf->readFile("$fname"); + + $fname = "$TEMPLATE_DIR/main.cs"; + die ("Template directory is invalid ($fname not found)!") unless (-e "$fname"); + $hdf->setValue("TemplateDir","$TEMPLATE_DIR"); + + die ("Documentation directory ($DOC_DIR) not found!") unless (-d "$DOC_DIR"); + $hdf->setValue("DocDir","$DOC_DIR"); + + # if it was requested as directory index (link from index.html), we should + # set a real script name - otherwise links with a query string will break + $hdf->setValue("ScriptName", ($ENV{'SCRIPT_NAME'} eq '/')? '/cryptobox' : $ENV{'SCRIPT_NAME'}); + + return $hdf; +} + +sub check_mounted +{ + return (system("$CB_SCRIPT","is_crypto_mounted") == 0); +} + + +sub check_config +{ + return (system("$CB_SCRIPT","is_config_mounted") == 0); +} + + +sub check_init_running +{ + return (system("$CB_SCRIPT","is_init_running") == 0); +} + + +sub get_current_ip +# the IP of eth0 - not the configured value of the box (only for validation) +{ + return `$CB_SCRIPT get_current_ip`; +} + + +sub render() +{ + $pagedata->setValue("PageName","$pagename"); + my $pagefile = "$TEMPLATE_DIR/main.cs"; + print "Content-Type: text/html\n\n"; + + my $cs = ClearSilver::CS->new($pagedata); + $cs->parseFile($pagefile); + + print $cs->render(); +} + + +sub mount_vol +{ + my $pw = shift; + + if (&check_mounted) { + $pagedata->setValue('Data.Warning', 'Das Dateisystem war bereits aktiv!'); + return 0; + } + + # TODO: the output is always empty? + my $output = open(PW_INPUT, "| $CB_SCRIPT crypto-mount"); + print PW_INPUT $pw; + close(PW_INPUT); + + $pagedata->setValue('Data.ProgOutput',"$output") if ($output); + + if (!&check_mounted()) { + $pagedata->setValue('Data.Warning', 'MountFailed'); + $pagedata->setValue('Data.Action', 'umount_form'); + } +} + + +sub umount_vol +{ + unless (&check_mounted) { + $pagedata->setValue('Data.Warning', 'Das Dateisystem war bereits inaktiv!'); + return 0; + } + + # TODO: check if "system" returns output + my $output = `$CB_SCRIPT crypto-umount`; + $pagedata->setValue('Data.ProgOutput',"$output") if ($output); + + if (!&check_mounted()) { + $pagedata->setValue('Data.Warning', 'UmountFailed'); + $pagedata->setValue('Data.Action', 'mount_form'); + } +} + + +sub box_init +{ + # TODO: redirect output to pagedata + my $pw = shift; + + # partitioning, config and initial cryptsetup + open(PW_INPUT, "|$CB_SCRIPT box-init-fg"); + print PW_INPUT $pw; + close(PW_INPUT); + + # wipe and mkfs takes some time + my $output = `$CB_SCRIPT box-init-bg`; + + # TODO: "output" has to get filtered through something like "s/$/
/" - in perl, please! + $pagedata->setValue('Data.ProgOutput',"$output") if ($output); +} + + +################### main ######################### + +my $query = new CGI; + +$pagedata = load_hdf(); + + +#TODO: check result of actions and set Data.Error for failures + +if ($query->param) { + my $action = $query->param('action'); + + if ($action eq 'umount_do') { + if ( ! &check_config()) { + $pagedata->setValue('Data.Warning', 'NotConfigured'); + $pagedata->setValue('Data.Action', 'init_form'); + } elsif (&check_init_running()) { + $pagedata->setValue('Data.Warning', 'InitNotFinished'); + $pagedata->setValue('Data.Action', 'mount_form'); + } elsif ( ! &check_mounted()) { + $pagedata->setValue('Data.Warning', 'NotMounted'); + $pagedata->setValue('Data.Action', 'mount_form'); + } else { + # unmounten + &umount_vol(); + $pagedata->setValue('Data.Action', 'mount_form'); + } + } elsif ($action eq 'mount_do') { + # mount requested + if ( ! &check_config()) { + $pagedata->setValue('Data.Warning', 'NotConfigured'); + $pagedata->setValue('Data.Action', 'init_form'); + } elsif (&check_init_running()) { + $pagedata->setValue('Data.Warning', 'InitNotFinished'); + $pagedata->setValue('Data.Action', 'mount_form'); + } elsif (&check_mounted()) { + $pagedata->setValue('Data.Warning', 'IsMounted'); + $pagedata->setValue('Data.Action', 'umount_form'); + } elsif ($query->param('password') eq '') { + # leeres Passwort + $pagedata->setValue('Data.Warning', 'EmptyPassword'); + $pagedata->setValue('Data.Action', 'mount_form'); + } else { + # mounten + &mount_vol($query->param('password')); + $pagedata->setValue('Data.Action', 'umount_form'); + } + } elsif ($action eq 'mount_ask') { + if ( ! &check_config()) { + $pagedata->setValue('Data.Warning', 'NotConfigured'); + $pagedata->setValue('Data.Action', 'init_form'); + } elsif (&check_init_running()) { + $pagedata->setValue('Data.Warning', 'InitNotFinished'); + $pagedata->setValue('Data.Action', 'mount_form'); + } elsif (&check_mounted()) { + $pagedata->setValue('Data.Warning', 'IsMounted'); + $pagedata->setValue('Data.Action', 'intro'); + } else { + $pagedata->setValue('Data.Action', 'mount_form'); + } + } elsif ($action eq 'umount_ask') { + if ( ! &check_config()) { + $pagedata->setValue('Data.Warning', 'NotConfigured'); + $pagedata->setValue('Data.Action', 'init_form'); + } elsif ( ! &check_mounted()) { + $pagedata->setValue('Data.Warning', 'NotMounted'); + $pagedata->setValue('Data.Action', 'mount_form'); + } else { + $pagedata->setValue('Data.Action', 'umount_form'); + } + } elsif ($action eq 'init_ask') { + if (&check_init_running()) { + $pagedata->setValue('Data.Warning', 'InitNotFinished'); + $pagedata->setValue('Data.Action', 'intro'); + } elsif (&check_config()) { + $pagedata->setValue('Data.Warning', 'AlreadyConfigured'); + $pagedata->setValue('Data.Action', 'init_form'); + } else { + $pagedata->setValue('Data.Action', 'init_form'); + } + } elsif ($action eq 'init_do') { + if ($query->param('password') ne $query->param('password2')) { + # different passwords + $pagedata->setValue('Data.Warning', 'DifferentPasswords'); + $pagedata->setValue('Data.Action', 'init_form'); + } elsif ($query->param('password') eq '') { + # empty password + $pagedata->setValue('Data.Warning', 'EmptyPassword'); + $pagedata->setValue('Data.Action', 'init_form'); + } elsif ($query->param('confirm') ne $pagedata->getValue('Lang.Text.ConfirmInit','')) { + # wrong confirm string + $pagedata->setValue('Data.Warning', 'InitNotConfirmed'); + $pagedata->setValue('Data.Action', 'init_form'); + } else { + # do init + &box_init($query->param('password')); + $pagedata->setValue('Data.Action', 'config_form'); + } + } elsif ($action eq 'config_ask') { + if ( ! &check_config()) { + $pagedata->setValue('Data.Warning', 'NotConfigured'); + $pagedata->setValue('Data.Action', 'init_form'); + } else { + $pagedata->setValue('Data.Action', 'config_form'); + } + } elsif ($action eq 'config_do') { + # TODO: not implemented yet! + system("$CB_SCRIPT", "set_config", "language", $query->param('language')); + system("$CB_SCRIPT", "set_config", "timeout", $query->param('timeout')); + system("$CB_SCRIPT", "set_config", "ip", $query->param('ip')); + $pagedata->setValue('Data.Action', 'intro'); + } elsif ($action eq 'show_log') { + $pagedata->setValue('Data.Action', 'show_log'); + } elsif ($action eq 'doc') { + if ($query->param('page')) { + $pagedata->setValue('Data.Doc.Page', $query->param('page')); + } else { + $pagedata->setValue('Data.Doc.Page', 'CryptoBox.html'); + } + $pagedata->setValue('Data.Action', 'doc'); + } else { + $pagedata->setValue('Data.Error', 'UnknownAction'); + } +} else { + $pagedata->setValue('Data.Action', 'intro'); +} + +# check state of the cryptobox +$pagedata->setValue('Data.Status.Config', &check_config() ? 1 : 0); +$pagedata->setValue('Data.Status.InitRunning', &check_init_running() ? 1 : 0); +$pagedata->setValue('Data.Status.Mounted', &check_mounted() ? 1 : 0); +my $output = &get_current_ip(); +$pagedata->setValue('Data.Status.IP', "$output"); + +$output = `$CB_SCRIPT diskinfo 2>&1 | sed 's/^/
/'`; +$pagedata->setValue('Data.PartitionInfo',"$output"); + +# preset config settings for clearsilver +$pagedata->setValue('Data.Config.IP', `$CB_SCRIPT get_config ip`); +$pagedata->setValue('Data.Config.TimeOut', `$CB_SCRIPT get_config timeout`); +$pagedata->setValue('Data.Config.Language', `$CB_SCRIPT get_config language`); + +# read log - TODO: use perl filtering +$output = (-e "$LOG_FILE") ? `cat '$LOG_FILE' | sed 's/^/
/'` : ''; +$pagedata->setValue('Data.Log',"$output"); + +$pagedata->setValue('Data.Status.DevelopmentMode', 1) if (-e "$DEVELOPMENT_MARKER"); + +&render(); + +exit 0; + diff --git a/cryptobox.conf.d/var/www/index.html b/cryptobox.conf.d/var/www/index.html new file mode 100755 index 0000000..70e8e9b --- /dev/null +++ b/cryptobox.conf.d/var/www/index.html @@ -0,0 +1,310 @@ +#!/usr/bin/perl +# +# Vorbereitung: +# - die Variable "MNTIMAGE" (siehe unten) setzen - es muss der Name der cryptoloop-image-Datei sein +# - in die /etc/fstab einen passenden Eintrag einfuegen, z.B.: +# /data/cryptoimage.loop /mnt/crypto auto noauto,user,loop,encryption=aes,keybits=256 +# - ein Image erstellen (als root): +# dd if=/dev/zero of=cryptoimage.loop bs=1M count=10 +# losetup -k 256 -e aes /dev/loop1 cryptoimage.loop +# mkfs.ext3 /dev/loop1 +# losetup -d /dev/loop1 +# + + +############################################### + +use strict; +use CGI; +use ClearSilver; +use ConfigFile; + +my ($pagedata, $pagename); + +my ($LANGUAGE_DIR, $LANGUAGE, $TEMPLATE_DIR, $DOC_DIR); +my ($CB_SCRIPT, $LOG_FILE, $DEVELOPMENT_MARKER); + +my $config = ConfigFile::read_config_file('/etc/cryptobox/cryptobox.conf'); + +$CB_SCRIPT = $config->{CB_SCRIPT}; +$LOG_FILE = $config->{LOG_FILE}; +$LANGUAGE_DIR = $config->{LANGUAGE_DIR}; +$LANGUAGE = $config->{LANGUAGE}; +$TEMPLATE_DIR = $config->{TEMPLATE_DIR}; +$DOC_DIR = $config->{DOC_DIR}; +$DEVELOPMENT_MARKER = $config->{DEVELOPMENT_MARKER}; + + +#################### subs ###################### + +sub load_hdf() +{ + my $hdf = ClearSilver::HDF->new(); + + my $fname = "$LANGUAGE_DIR/$LANGUAGE" . '.hdf'; + die ("Language file ($fname) not found!") unless (-e "$fname"); + $hdf->readFile("$fname"); + + $fname = "$TEMPLATE_DIR/main.cs"; + die ("Template directory is invalid ($fname not found)!") unless (-e "$fname"); + $hdf->setValue("TemplateDir","$TEMPLATE_DIR"); + + die ("Documentation directory ($DOC_DIR) not found!") unless (-d "$DOC_DIR"); + $hdf->setValue("DocDir","$DOC_DIR"); + + # if it was requested as directory index (link from index.html), we should + # set a real script name - otherwise links with a query string will break + $hdf->setValue("ScriptName", ($ENV{'SCRIPT_NAME'} eq '/')? '/cryptobox' : $ENV{'SCRIPT_NAME'}); + + return $hdf; +} + +sub check_mounted +{ + return (system("$CB_SCRIPT","is_crypto_mounted") == 0); +} + + +sub check_config +{ + return (system("$CB_SCRIPT","is_config_mounted") == 0); +} + + +sub check_init_running +{ + return (system("$CB_SCRIPT","is_init_running") == 0); +} + + +sub get_current_ip +# the IP of eth0 - not the configured value of the box (only for validation) +{ + return `$CB_SCRIPT get_current_ip`; +} + + +sub render() +{ + $pagedata->setValue("PageName","$pagename"); + my $pagefile = "$TEMPLATE_DIR/main.cs"; + print "Content-Type: text/html\n\n"; + + my $cs = ClearSilver::CS->new($pagedata); + $cs->parseFile($pagefile); + + print $cs->render(); +} + + +sub mount_vol +{ + my $pw = shift; + + if (&check_mounted) { + $pagedata->setValue('Data.Warning', 'Das Dateisystem war bereits aktiv!'); + return 0; + } + + # TODO: the output is always empty? + my $output = open(PW_INPUT, "| $CB_SCRIPT crypto-mount"); + print PW_INPUT $pw; + close(PW_INPUT); + + $pagedata->setValue('Data.ProgOutput',"$output") if ($output); + + if (!&check_mounted()) { + $pagedata->setValue('Data.Warning', 'MountFailed'); + $pagedata->setValue('Data.Action', 'umount_form'); + } +} + + +sub umount_vol +{ + unless (&check_mounted) { + $pagedata->setValue('Data.Warning', 'Das Dateisystem war bereits inaktiv!'); + return 0; + } + + # TODO: check if "system" returns output + my $output = `$CB_SCRIPT crypto-umount`; + $pagedata->setValue('Data.ProgOutput',"$output") if ($output); + + if (!&check_mounted()) { + $pagedata->setValue('Data.Warning', 'UmountFailed'); + $pagedata->setValue('Data.Action', 'mount_form'); + } +} + + +sub box_init +{ + # TODO: redirect output to pagedata + my $pw = shift; + + # partitioning, config and initial cryptsetup + open(PW_INPUT, "|$CB_SCRIPT box-init-fg"); + print PW_INPUT $pw; + close(PW_INPUT); + + # wipe and mkfs takes some time + my $output = `$CB_SCRIPT box-init-bg`; + + # TODO: "output" has to get filtered through something like "s/$/
/" - in perl, please! + $pagedata->setValue('Data.ProgOutput',"$output") if ($output); +} + + +################### main ######################### + +my $query = new CGI; + +$pagedata = load_hdf(); + + +#TODO: check result of actions and set Data.Error for failures + +if ($query->param) { + my $action = $query->param('action'); + + if ($action eq 'umount_do') { + if ( ! &check_config()) { + $pagedata->setValue('Data.Warning', 'NotConfigured'); + $pagedata->setValue('Data.Action', 'init_form'); + } elsif (&check_init_running()) { + $pagedata->setValue('Data.Warning', 'InitNotFinished'); + $pagedata->setValue('Data.Action', 'mount_form'); + } elsif ( ! &check_mounted()) { + $pagedata->setValue('Data.Warning', 'NotMounted'); + $pagedata->setValue('Data.Action', 'mount_form'); + } else { + # unmounten + &umount_vol(); + $pagedata->setValue('Data.Action', 'mount_form'); + } + } elsif ($action eq 'mount_do') { + # mount requested + if ( ! &check_config()) { + $pagedata->setValue('Data.Warning', 'NotConfigured'); + $pagedata->setValue('Data.Action', 'init_form'); + } elsif (&check_init_running()) { + $pagedata->setValue('Data.Warning', 'InitNotFinished'); + $pagedata->setValue('Data.Action', 'mount_form'); + } elsif (&check_mounted()) { + $pagedata->setValue('Data.Warning', 'IsMounted'); + $pagedata->setValue('Data.Action', 'umount_form'); + } elsif ($query->param('password') eq '') { + # leeres Passwort + $pagedata->setValue('Data.Warning', 'EmptyPassword'); + $pagedata->setValue('Data.Action', 'mount_form'); + } else { + # mounten + &mount_vol($query->param('password')); + $pagedata->setValue('Data.Action', 'umount_form'); + } + } elsif ($action eq 'mount_ask') { + if ( ! &check_config()) { + $pagedata->setValue('Data.Warning', 'NotConfigured'); + $pagedata->setValue('Data.Action', 'init_form'); + } elsif (&check_init_running()) { + $pagedata->setValue('Data.Warning', 'InitNotFinished'); + $pagedata->setValue('Data.Action', 'mount_form'); + } elsif (&check_mounted()) { + $pagedata->setValue('Data.Warning', 'IsMounted'); + $pagedata->setValue('Data.Action', 'intro'); + } else { + $pagedata->setValue('Data.Action', 'mount_form'); + } + } elsif ($action eq 'umount_ask') { + if ( ! &check_config()) { + $pagedata->setValue('Data.Warning', 'NotConfigured'); + $pagedata->setValue('Data.Action', 'init_form'); + } elsif ( ! &check_mounted()) { + $pagedata->setValue('Data.Warning', 'NotMounted'); + $pagedata->setValue('Data.Action', 'mount_form'); + } else { + $pagedata->setValue('Data.Action', 'umount_form'); + } + } elsif ($action eq 'init_ask') { + if (&check_init_running()) { + $pagedata->setValue('Data.Warning', 'InitNotFinished'); + $pagedata->setValue('Data.Action', 'intro'); + } elsif (&check_config()) { + $pagedata->setValue('Data.Warning', 'AlreadyConfigured'); + $pagedata->setValue('Data.Action', 'init_form'); + } else { + $pagedata->setValue('Data.Action', 'init_form'); + } + } elsif ($action eq 'init_do') { + if ($query->param('password') ne $query->param('password2')) { + # different passwords + $pagedata->setValue('Data.Warning', 'DifferentPasswords'); + $pagedata->setValue('Data.Action', 'init_form'); + } elsif ($query->param('password') eq '') { + # empty password + $pagedata->setValue('Data.Warning', 'EmptyPassword'); + $pagedata->setValue('Data.Action', 'init_form'); + } elsif ($query->param('confirm') ne $pagedata->getValue('Lang.Text.ConfirmInit','')) { + # wrong confirm string + $pagedata->setValue('Data.Warning', 'InitNotConfirmed'); + $pagedata->setValue('Data.Action', 'init_form'); + } else { + # do init + &box_init($query->param('password')); + $pagedata->setValue('Data.Action', 'config_form'); + } + } elsif ($action eq 'config_ask') { + if ( ! &check_config()) { + $pagedata->setValue('Data.Warning', 'NotConfigured'); + $pagedata->setValue('Data.Action', 'init_form'); + } else { + $pagedata->setValue('Data.Action', 'config_form'); + } + } elsif ($action eq 'config_do') { + # TODO: not implemented yet! + system("$CB_SCRIPT", "set_config", "language", $query->param('language')); + system("$CB_SCRIPT", "set_config", "timeout", $query->param('timeout')); + system("$CB_SCRIPT", "set_config", "ip", $query->param('ip')); + $pagedata->setValue('Data.Action', 'intro'); + } elsif ($action eq 'show_log') { + $pagedata->setValue('Data.Action', 'show_log'); + } elsif ($action eq 'doc') { + if ($query->param('page')) { + $pagedata->setValue('Data.Doc.Page', $query->param('page')); + } else { + $pagedata->setValue('Data.Doc.Page', 'CryptoBox.html'); + } + $pagedata->setValue('Data.Action', 'doc'); + } else { + $pagedata->setValue('Data.Error', 'UnknownAction'); + } +} else { + $pagedata->setValue('Data.Action', 'intro'); +} + +# check state of the cryptobox +$pagedata->setValue('Data.Status.Config', &check_config() ? 1 : 0); +$pagedata->setValue('Data.Status.InitRunning', &check_init_running() ? 1 : 0); +$pagedata->setValue('Data.Status.Mounted', &check_mounted() ? 1 : 0); +my $output = &get_current_ip(); +$pagedata->setValue('Data.Status.IP', "$output"); + +$output = `$CB_SCRIPT diskinfo 2>&1 | sed 's/^/
/'`; +$pagedata->setValue('Data.PartitionInfo',"$output"); + +# preset config settings for clearsilver +$pagedata->setValue('Data.Config.IP', `$CB_SCRIPT get_config ip`); +$pagedata->setValue('Data.Config.TimeOut', `$CB_SCRIPT get_config timeout`); +$pagedata->setValue('Data.Config.Language', `$CB_SCRIPT get_config language`); + +# read log - TODO: use perl filtering +$output = (-e "$LOG_FILE") ? `cat '$LOG_FILE' | sed 's/^/
/'` : ''; +$pagedata->setValue('Data.Log',"$output"); + +$pagedata->setValue('Data.Status.DevelopmentMode', 1) if (-e "$DEVELOPMENT_MARKER"); + +&render(); + +exit 0; +