File: //kunden/lib/susshi/exec/Susshi.pm
package Susshi;
use Susshi::DB;
use warnings;
use strict;
use JSON;
use File::Spec;
use Sys::Syslog;
use IPC::Run qw( run timeout );
use File::Spec;
use constant {
UID_MIN => 1000,
DIR_PATTERN => qr{^(/kunden)?/homepages/\d{1,2}/d\d+/htdocs/\S+},
};
BEGIN {
require Exporter;
our @ISA = qw( Exporter );
our @EXPORT = qw( info error_die send_json_output );
}
sub new {
my $class = shift;
my %args = @_;
my $self = {};
my $name=$0;
$name =~ s|^/usr/lib/susshi/exec/|susshi::|;
openlog($name, 'pid', 'user');
error_die ("uid: $< <= " . UID_MIN) if $< <= UID_MIN;
info("Started for uid=$<");
if ($args{-read_input}) {
$self=_get_json_input();
}
return bless $self;
}
sub _get_json_input {
my $data;
eval {
local $/;
my $json = <STDIN>;
$data = decode_json ($json);
};
error_die ("$0: decode_json: $@") if $@;
return $data;
}
sub info {
my ($msg) = @_;
syslog('INFO', $msg);
}
sub error_die {
my ($msg, $status) = @_;
chomp $msg;
print STDERR "ERROR: ", $msg, "\n";
syslog('ERR', "ERROR: $msg");
exit ($status // 255);
}
sub send_json_output {
my ($data) = @_;
print to_json ($data, {pretty => 1})
}
sub get_directory {
my $self = shift;
my ($key, %args) = @_;
my $dir = $self->{$key} // '';
if ($dir) {
if ($dir !~ DIR_PATTERN) {
error_die ("'$key': $dir does pass check against" . DIR_PATTERN);
}
if (-e $dir) {
# $dir exists
-o $dir or error_die ("'$key': Owner of $dir is not $<");
-d $dir or error_die ("'$key': $dir is not a directory");
} elsif ($args{-must_exist}) {
# $dir does not exist
error_die ("'$key': $dir does not exist");
}
} else {
if ($args{-mandatory}) {
error_die "Need directory in '$key' key";
}
}
info "get_directory: $key: $dir";
return $dir;
}
sub get_database {
my $self = shift;
my ($key, %args) = @_;
my $dbobj;
my $db = $self->{$key};
if (ref $db eq 'HASH') {
eval {
$dbobj = Susshi::DB->new (%$db);
};
if ($@) {
error_die "Cannot instantiate $key: $@";
}
info "get_database: $key: $dbobj->{databasename}";
return $dbobj;
}
if ($args{-mandatory}) {
error_die "Need database in '$key' key";
}
return '';
}
sub get_backuppath {
my $self = shift;
my $backuppath = $self->{backuppath} or error_die("Missing 'backuppath' value");
my (undef, $backupdir, $filename) = File::Spec->splitpath ($backuppath);
chop $backupdir;
-e $backupdir or mkdir $backupdir,0700
or error_die "mkdir: $backupdir: $!";
-d $backupdir or error_die "$backupdir: Not a directory";
-o $backupdir or error_die "$backupdir: Owner is not $<";
chdir $backupdir or error_die "Cannot chdir to backup directory: $backupdir: $!";
$filename =~ /^[-_a-zA-Z0-9]+\.tar\.gz$/ or error_die "Filename does not pass check: $filename";
return ($backupdir, $filename);
}
1;