#! /usr/bin/perl -w # make the database scheme use strict ; use File::Path qw(mkpath) ; use Repocafe ; my $prog = substr($0,rindex($0,'/')+1) ; my $Usage = < ---------------------------------------- - $prog - setup the repocafe data. - $prog creates and/or chowns the configured data files and directories. - $prog must run as root or the configured , unless in dry-runs. ---------------------------------------- USAGE sub Usage { die "$_[0]$Usage" ; } sub Error { die "$prog: $_[0]\n" ; } sub Warn { warn "$prog: $_[0]\n" ; } # usage: &GetOptions(ARG,ARG,..) defines $opt_ID as 1 or user spec'ed value # usage: &GetOptions(\%opt,ARG,ARG,..) defines $opt{ID} as 1 or user value # ARG = 'ID' | 'ID=SPC' | 'ID:SPC' for no-arg, required-arg or optional-arg # ID = perl identifier # SPC = i|f|s for integer, fixedpoint real or string argument use Getopt::Long ; Getopt::Long::config('no_ignore_case') ; our %opt = () ; Usage('') unless GetOptions ( \%opt, qw(v q d f p c=s sql help) ) ; Usage("Arg count\n") unless @ARGV == 0 ; if ( $opt{help} ) { print $Usage ; exit 0 ; } my $CLEAN = 1 ; if ( $< != 0 ) { my $msg = "run as root (for 'chown www_user:www_group ...')" ; if ( $opt{f} ) { Error "must $msg" ; } else { printf "Warning : should %s\n", $msg ; } } my $Cafe = make_cafe ( %opt, -conn => 0 ) ; my $conf = $Cafe -> conf ; my $dir_admin = $conf -> dir_admin ; my $dir_data = $conf -> dir_data ; my $dir_www = $conf -> dir_www ; my $admin_user = $conf -> admin_user ; my $admin_group = $conf -> admin_group ; my $www_user = $conf -> www_user ; my $www_group = $conf -> www_group ; my $tag = $opt{f} ? 'DID' : 'WOULD' ; # $CONF_ROOT = "/home/csg/svn/dev-admin/repocafe.conf" ; sub create_local { my $line = shift ; my $path = shift ; my $txt = sprintf "\n", $line ; if ( $path and $opt{f} ) { open LOCAL, ">$path" or die "can't write $path ($!)" ; print LOCAL $txt ; close LOCAL ; } $txt ; } sub check_local_ppp { my $path_local = $dir_www . '/local.ppp' ; my $path_conf = $dir_admin . '/' . $conf -> root ; my $line = sprintf '$CONF_ROOT = "%s" ;', $path_conf ; unless ( -f $path_local ) { printf "%s create %s :\n%s", , $tag , $path_local , create_local $line ; create_local $line, $path_local if $opt{f} ; } elsif ( $opt{v} ) { printf "exists : %s\n", $path_local ; } } sub is_num ($) { my $n = shift ; $n =~ /^\d+$/ ; } sub get_xid { my $usr = shift ; my $grp = shift ; my $uid = is_num ( $usr ) ? $usr : getpwnam $usr ; my $gid = is_num ( $grp ) ? $grp : getgrnam $grp ; Error "can't get uid for user $usr" unless defined $uid ; Error "can't get gid for group $grp" unless defined $gid ; return $uid, $gid ; } sub Mkdir { my $dir = shift ; my $opt = shift ; printf "looking at '$dir' ...\n" if $opt{d} ; if ( -d $dir ) { my ( $UID, $GID ) = ( stat _ ) [ 4, 5 ] ; my @args = @{ $opt } { qw(owner group) } ; my ( $uid, $gid ) = get_xid @args ; if ( $uid != $UID or $gid != $GID ) { $CLEAN = 0 ; printf "$tag chown %s %s %s\n", @args, $dir ; if ( $opt{f} ) { chown $uid, $gid, $dir or die "can't chown $uid, $gid, $dir" ; } } printf "exists : %s\n", $dir if $opt{v} ; } else { $CLEAN = 0 ; print "$tag mkdir -p $dir\n" ; mkpath ( $dir, $opt ) if $opt{f} ; } } sub Copy { my $src = shift ; my $dst = shift ; unless ( -f $src ) { print "weird : can't find $src\n" ; } elsif ( -f $dst ) { printf "exists : %s\n", $dst if $opt{v} ; } else { printf "%s copy $src $dst\n", $tag, $src, $dst ; if ( $opt{f} ) { open SRC, $src or Error "can't open $src ($!)" ; open DST, ">$dst" or Error "can't write $dst ($!)" ; print DST ; close SRC ; close DST ; my ( $uid, $gid ) = get_xid $admin_user, $admin_group ; chown $uid, $gid, $dst or die "can't chown $uid, $gid, $dst" ; my $mode = ( stat $src ) [ 2 ] ; chmod $mode, $dst or die "can't chmod $mode, $dst" ; } $CLEAN = 0 ; } } sub cp_commit_email { my $name = 'commit-email.pl' ; Copy "lib/$name", $name ; } sub cp_commit_hook { my $name = shift ; Copy "lib/$name.tmpl", "lib/$name" ; } sub make_empty_guestlist { my $base = sprintf '%s/admin/%s' , $conf -> dir_data, $conf -> file_guests ; my $txt = "$base.txt" ; my $db = "$base.db" ; my ( $uid, $gid ) = get_xid $www_user, $www_group ; unless ( -f $txt ) { printf "%s create $txt\n", $tag ; if ( $opt{f} ) { open TXT, ">>$txt" or die "can't create $txt ($!)" ; close TXT ; chown $uid, $gid, $txt or die "can't chown $uid, $gid, $txt" ; } } elsif ( $opt{v} ) { printf "exists : %s\n", $txt ; } unless ( -f $db ) { printf "%s create $db\n", $tag ; if ( $opt{f} ) { use DB_File ; my %db ; tie %db , "DB_File" , $db , O_RDWR|O_CREAT , 0644 , $DB_HASH or die "can't tie $db" ; untie %db ; chown $uid, $gid, $db or die "can't chown $uid, $gid, $db" ; } } elsif ( $opt{v} ) { printf "exists : %s\n", $db ; } } my $opt_www = { mode => 0755, owner => $www_user , group => $www_group } ; my $opt_adm = { mode => 0755, owner => $admin_user, group => $admin_group } ; Mkdir $dir_admin, $opt_adm ; Mkdir $dir_data , $opt_www ; Mkdir $dir_www , $opt_adm ; for my $dir( qw(tmp) ) { Mkdir "$dir_admin/$dir", $opt_adm ; } for my $dir( qw(admin archive logs repos) ) { Mkdir "$dir_data/$dir", $opt_www ; } make_empty_guestlist ; check_local_ppp ; cp_commit_email ; cp_commit_hook 'pre-commit' ; cp_commit_hook 'post-commit' ; print "$prog: nothing to do\n" if $CLEAN ;