# pserver-lib.pl do '../web-lib.pl'; &init_config(); do '../ui-lib.pl'; $cvs_path = &has_command($config{'cvs'}); $cvs_port = 2401; $cvs_inet_name = "cvspserver"; $has_xinetd = &foreign_check("xinetd"); $has_inetd = &foreign_check("inetd"); $passwd_file = "$config{'cvsroot'}/CVSROOT/passwd"; $readers_file = "$config{'cvsroot'}/CVSROOT/readers"; $writers_file = "$config{'cvsroot'}/CVSROOT/writers"; $cvs_config_file = "$config{'cvsroot'}/CVSROOT/config"; @features = ('passwd', 'access', 'config', 'cvsweb'); %access = &get_module_acl(); %featureprog = ( 'passwd' => 'list_passwd.cgi', 'access' => 'edit_access.cgi', 'config' => 'edit_config.cgi', 'cvsweb' => 'cvsweb.cgi' ); # check_inetd() # Find out if cvs is being run from inetd or xinetd sub check_inetd { if ($has_xinetd) { # Find an xinetd service on the CVS port, with the CVS command, or # with the CVS name &foreign_require("xinetd", "xinetd-lib.pl"); local @xic = &xinetd::get_xinetd_config(); local $x; foreach $x (@xic) { next if ($x->{'name'} ne 'service'); local $q = $x->{'quick'}; if ($q->{'server'}->[0] eq $cvs_path || $q->{'server'}->[0] eq $config{'cvs'} || $port == $cvs_port || $x->{'value'} eq $cvs_inet_name) { # Found the entry return { 'type' => 'xinetd', 'user' => $q->{'user'}->[0], 'command' => $q->{'server'}->[0], 'args' => $q->{'server'}->[0]." ". $q->{'server_args'}->[0], 'active' => $q->{'disable'}->[0] ne 'yes', 'xinetd' => $x }; } } } if ($has_inetd) { # Find an inetd service on the CVS port, with the CVS command, or # with the CVS name local (%portmap, $s, $a, $i); &foreign_require("inetd", "inetd-lib.pl"); foreach $s (&inetd::list_services()) { $portmap{$s->[1]} = $s; foreach $a (split(/\s+/, $s->[4])) { $portmap{$a} = $s; } } foreach $i (&inetd::list_inets()) { if ($i->[8] eq $cvs_path || $i->[8] eq $config{'cvs'} || $portmap{$i->[3]}->[2] == $cvs_port || $i->[3] eq $cvs_inet_name) { # Found the entry return { 'type' => 'inetd', 'user' => $i->[7], 'command' => $i->[8], 'args' => $i->[9], 'active' => $i->[1], 'inetd' => $i }; } } } return undef; } # list_passwords() # List all CVS users sub list_passwords { local @rv; local $lnum = 0; open(PASSWD, $passwd_file); while() { s/\r|\n//g; s/#.*$//; local @p = split(/:/, $_); if (@p) { push(@rv, { 'user' => $p[0], 'pass' => $p[1], 'unix' => $p[2], 'line' => $lnum, 'index' => scalar(@rv) }); } $lnum++; } close(PASSWD); return @rv; } sub create_password { local $lref = &read_file_lines($passwd_file); push(@$lref, join(":", $_[0]->{'user'}, $_[0]->{'pass'}, $_[0]->{'unix'})); &flush_file_lines(); } sub modify_password { local $lref = &read_file_lines($passwd_file); $lref->[$_[0]->{'line'}] = join(":", $_[0]->{'user'}, $_[0]->{'pass'}, $_[0]->{'unix'}); &flush_file_lines(); } sub delete_password { local $lref = &read_file_lines($passwd_file); splice(@$lref, $_[0]->{'line'}, 1); &flush_file_lines(); } # get_cvs_config() # Returns a list of values from the CVSROOT/config file sub get_cvs_config { local @rv; local $lnum = 0; open(CONFIG, $cvs_config_file); while() { s/\s+$//; s/^\s*#.*$//; if (/^\s*([^\s=]+)\s*=\s*(.*)/) { push(@rv, { 'name' => $1, 'value' => $2, 'line' => $lnum, 'index' => scalar(@rc) } ); } $lnum++; } close(CONFIG); return @rv; } # find(name, &config) sub find { local ($c, @rv); foreach $c (@{$_[1]}) { push(@rv, $c) if (lc($c->{'name'}) eq lc($_[0])); } return wantarray ? @rv : $rv[0]; } # save_cvs_config(&config, name, value, [default]) sub save_cvs_config { local $lref = &read_file_lines($cvs_config_file); local $old = &find($_[1], $_[0]); if ($old && $_[2]) { # Replacing an existing config line $lref->[$old->{'line'}] = "$_[1]=$_[2]"; } elsif ($old) { # Deleting a config line (unless it already exists with the default) if (!$_[3] || $old->{'value'} ne $_[3]) { splice(@$lref, $old->{'line'}, 1); local $c; foreach $c (@{$_[0]}) { $c->{'line'}-- if ($c->{'line'} > $old->{'line'}); } } } elsif ($_[2]) { # Adding a config line push(@$lref, "$_[1]=$_[2]"); } } # get_cvs_version(&out) # Returns the cvs command version number, or undef sub get_cvs_version { local $out = `$config{'cvs'} -v`; ${$_[0]} = $out; if ($out =~ /CVS[^0-9\.]*([0-9\.]+)/) { return $1; } else { return undef; } } @hist_chars = ( "F", "O", "E", "T", "C", "G", "U", "W", "A", "M", "R" ); 1;