#!/usr/bin/perl -w # phadmin.pl - builds a Yahoo like Web directory # by Jonathan Eisenzopf. v1.0 19990629 # Copyright (c) 1999 internet.com LLC. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Originally published and documented at http://www.webreference.com # Contact eisen@internet.com for all other uses. # Modules use strict; use Text::CSV_XS; use CGI; use CGI::Carp qw(fatalsToBrowser); # Constants my $datafile = 'perlhoo.csv'; my $rootdir = '/www/perlhoo'; my $baseurl = '/cgi-bin/phadmin.pl'; my $new_datafile = 'perlhoo_new.csv'; # Main my $query = new CGI; print $query->header; # get relative directory from URL my $reldir = $query->path_info; # strip of leading and trailing / $reldir =~ s/^\/+//; $reldir =~ s/\/+$//; # get directory based on $rootdir and $reldir my $dir = $reldir =~ /\S+/ ? "$rootdir/$reldir" : ($rootdir); # Main code body if ($query->param('action') eq 'add') { &print_header; &add_link($dir); &list_categories($dir); &print_footer; } elsif ($query->param('action') eq 'edit') { &edit_link($dir); } elsif ($query->param('action') eq 'delete') { &print_header; &delete_link($dir,$query->param('url'),$query->param('type')); &list_categories($dir); &print_footer; } else { &print_header; &list_categories($dir); &print_footer; } # Subroutines sub add_link { my $dir = shift; # delete link from $new_datafile if type is new &delete_link($dir,$query->param('url'),1) if ($query->param('type') eq 'new'); # delete link from $datafile if it exists &delete_link($dir,$query->param('url')); # lock semaphore file open(SEM, "> $dir/$datafile.semaphore") || die "Cannot open $dir/$datafile.semaphore for write: $!"; flock(SEM, 2) || die "Cannot get exclusive lock for $dir/$datafile.semaphore: $!"; # open $datafile open(FILE, ">> $dir/$datafile") || die "Cannot open $dir/$datafile for write: $!"; # append record to $datafile my $csv = Text::CSV_XS->new(); print FILE $csv->string,"\n" if $csv->combine($query->param('url'),$query->param('title'),$query->param('description'),$query->param('name'),$query->param('email')); # close all filehandles close(FILE); close(SEM); unlink "$dir/$datafile.semaphore"; } sub delete_link { my ($dir,$url,$new) = @_; my $foundit = 0; # set to 1 if we find the url # do we want to modify $datafile or $new_datafile my $file = ($new) ? "$new_datafile" : "$datafile"; # if the file doesn't exist, simply exit return unless -e "$dir/$file"; # open data file open(IN, "$dir/$file") || die "Cannot open $dir/$file for read: $!"; # open temp file open(OUT, "> $dir/$file.$$") || die "Cannot open $dir/$file.$$ for write: $!"; # loop over the data file, looking for $url while () { if (/$url/) { # skip the line if it contains the url $foundit=1; } else { print OUT; # print to the temp file } } close(IN); close(OUT); # if we found the url, we need to move the tmp file to production if ($foundit > 0) { # lock semaphore file open(SEM, "> $dir/$file.semaphore") || die "Cannot open $dir/$file.semaphore for write: $!"; flock(SEM, 2) || die "Cannot get exclusive lock for $dir/$file.semaphore: $!"; # move the tmp file to production rename "$dir/$file.$$","$dir/$file"; close(SEM); unlink "$dir/$file.semaphore"; # otherwise, just delete the tmp file } else { unlink "$dir/$file.$$"; } } sub edit_link { my $dir = shift; my $url = $query->param('url'); my ($title,$description,$name,$email); &print_header; my $file = ($query->param('type') eq 'new') ? "$new_datafile" : "$datafile"; my $entries = &retreive_entries("$dir/$file"); foreach my $entry (@$entries) { if ($entry->[0] eq $url) { $title = $entry->[1]; $description = $entry->[2]; $name = $entry->[3]; $email = $entry->[4]; } } print <
HTML print '' if $query->param('type') eq 'new'; print < PerlHoo Entry URL Title Description Submitter Email HTML &print_footer; } sub list_categories { my $dir = shift; my $reldir = $dir; $reldir =~ s#$rootdir/?##; my @parts = split(/\//,$reldir); my $category = "Home"; for (my $i=0; $i < @parts; $i++) { $category .= ": $parts[$i]"; } print ''; print "\n"; &print_entries("$dir/$new_datafile",$reldir,1); &print_entries("$dir/$datafile",$reldir); print "
$category

\n"; opendir DIR,$dir || die "Cannot open $dir: $!\n"; my @dirs = grep -d, map "$dir/$_", grep !/^\./, readdir DIR; closedir DIR; foreach my $dir (@dirs) { &list_categories($dir); } } sub print_entries { my ($datafile,$reldir,$new) = @_; my $entries = &retreive_entries($datafile); my $url; foreach my $entry (@$entries) { if ($new) { $url = "$baseurl/$reldir?action=edit&url=$entry->[0]&type=new"; print "\n"; } else { $url = "$baseurl/$reldir?action=edit&url=$entry->[0]"; print "\n"; } print "$entry->[1]\n"; print "$entry->[2]\n"; print "[0]\" target=\"_new\">$entry->[0]\n"; print "[0]"; print "&type=new" if $new; print "\">Delete\n"; } } sub retreive_entries { my $datafile = shift; my @entries = (); if (-e $datafile) { open(DATA,$datafile) || die "Cannot open $datafile: $!"; my $csv = Text::CSV_XS->new(); while () { chomp; $csv->parse($_); my @columns = $csv->fields(); push(@entries,\@columns); } } return \@entries; } sub print_footer { print < HTML } sub print_header { print < PerlHoo Admin
PerlHoo Admin
Home | Add new site
HTML }