#!/bin/sh perl=/usr/local/bin/perl eval "exec $perl -x $0 $*" #!perl ## Copyright (c) 1996 Excite, Inc. ## ## This CGI script allows users to configure Excite, Inc. databases ## through a WWW interface. Naturally, there are plenty of security ## concerns associated with this scheme. ## ## This script appears as several different web pages, depending on ## its invocation. If invoked with a 'db=' argument, the ## script prints out the configuration information for a particular ## database and then allows the user to change it. If invoked with ## 'new=', the user is allowed to create a new database. If ## invoked with 'Update=Update' and 'dbname=', it updates an ## existing database configuration file. Without any of these ## arguments, it displays a list of currently existing database.conf ## files, and also allows the user to create a new database.conf file. BEGIN { $root = "/usr/home/photius/excite"; $perlportname = "i386-bsdos"; die "Invalid root directory '$root'\n" unless -d $root; if ($perlportname eq "i86pc-solaris") { unshift(@INC, "$root/perllib", "$root/perllib/$perlportname/5.00311", "$root/perllib/$perlportname"); } else { unshift(@INC, "$root/perllib", "$root/perllib/$perlportname/5.002", "$root/perllib/$perlportname"); } } require 'os_functions.pl'; require 'architext.pl'; require 'architextConf.pl'; require 'architextNotify.pl'; require 'architext_map.pl'; %form = &Architext'readFormArgs; %attr = &ArchitextConf'readConfig("$root/Architext.conf", $form{'db'}); if (&Architext'remoteMode($root)) { $helppath = &Architext'helpPath(); } else { $helppath = $attr{'ArchitextURL'}; } $script_suffix = &Architext'scriptSuffix(); $scriptname = "AT-config$script_suffix"; ## check for password, if one is specified in Architext.conf ## if it doesn't appear as a form arg, present password page $password = &Architext'password($attr{'ArchitextURL'}, $scriptname, $attr{'Password'}, %form) if $attr{'Password'}; $postpass = "" if ($attr{'Password'}); $getpass = "?$password=$attr{'Password'}" if $postpass; ## allow user to change passwords if ($form{'ChangePassword'} eq 'yes') { $warn = &Architext'errorIcon($attr{'ArchitextURL'}); $message = ""; if ((! $form{'first'}) && ($form{'pass1'} eq $form{'pass2'})) { $newpass = $form{'pass1'}; $message = "Password cannot contain the '#' character." if ($newpass =~ /\#/); $message = "Password cannot contain whitespace characters." if ($newpass =~ /\s/); ## password is legal, let user know it has been changed if (! $message) { &Architext'printHeader($attr{'ArchitextURL'}, "Password Changed"); &Architext'updatePassword($root, $newpass, $form{'db'}); &make_files_readwriteable("$root/Architext.conf"); print <Your password has been updated.
Go back to the main administration page. $postpass

EOF ; &Architext'Copyright($attr{'ArchitextURL'}); exit(0); } } else { $message = "Passwords didn't match." unless ($message || ($form{'first'} eq 'yes')); } ## give user screen to change password for admin or collection &Architext'printHeader($attr{'ArchitextURL'}, "Change Password"); $message = "$warn$message" if $message; print <$message

Please enter the new password in the spaces provided below.

Enter the password here:

Enter it again:

Save the new password. $postpass

Don't save, go back to the main administration page. $postpass

EOF ; &Architext'Copyright($attr{'ArchitextURL'}); exit(0); } ## don't allow access if user leaves collection name blank from admin page if ($form{'admin'} eq 'admin') { if (! $form{'new'}) { &Architext'printHeader($attr{'ArchitextURL'}, ""); &Architext'exitError($attr{'ArchitextURL'}, "You must provide a name for a new collection.", $postpass); } } if ($form{'Update'}) { ## Assuming all the relevant configuration options are specified ## as form arguments, this mode actually writes the db.conf file. ## will notify user if required information is missing from ## the form by passing a message to the next page ## Header again ## wrote the http header first to prevent mailer errors from ## causing a server error &Architext'printHttpHeader; if (! ($error_str = &createDbConf())) { &Architext'printHeader($attr{'ArchitextURL'}, "Collection Configuration", "Collection Configuration", 'none'); if (!$form{'dbname'}) { &Architext'exitError($attr{'ArchitextURL'}, "Configure specified with no dbname."); } ## Let the user know the update was a success. print "

Configuration successful

\n"; print "


\n"; if ($getpass) { $getpass .= "&"; } else { $getpass = "?"; } $getpass .= "db=$form{'dbname'}"; print <Possible Actions:

Create an index for this collection. $postpass

Generate search pages for this collection. $postpass

Go back to the main admin page for this collection. $postpass

EOF ; &Architext'Copyright($attr{'ArchitextURL'}); exit(0); } else { ## required elements were not passed in... $message = $error_str; $form{'db'} = $form{'dbname'}; } } if ($form{'new'}) { ## Print out a form to allow the user to create a new database. $form{'new'} =~ s/\W+/_/g; ## check to see if user has entered name of existing db opendir(CONF, "$root/collections"); @dbconf = grep(/\.conf$/, readdir(CONF)); for (@dbconf) { s|\.conf$||; $preexist = 1 if ($form{'new'} eq $_); last if $preexist; } if (! $preexist) { ## Our standard header ## VL -- this block fixed extra content-type bug if ($form{'Update'}) { &Architext'printHeader($attr{'ArchitextURL'}, "Configure New Collection: $form{'new'}", "Configure New Collection: $form{'new'}", 'none'); } else { &Architext'printHeader($attr{'ArchitextURL'}, "Configure New Collection: $form{'new'}"); } ## fixed code end $warn = &Architext'errorIcon($attr{'ArchitextURL'}); print "

$warnATTENTION: $message Please try again." if $message; ## Read the default configuration information. ##%attr = &ArchitextConf'readConfig("$root/Architext.conf"); ## Print the form. &printForm($form{'new'}, $form{'new'}); &Architext'Copyright($attr{'ArchitextURL'}); exit(0); } else { $form{'db'} = $form{'new'}; $message = "You chose a name for the new collection that was already in use by an existing collection. Go back if you want to create a new collection, otherwise, you can now configure the collection whose name you specified."; %attr = &ArchitextConf'readConfig("$root/Architext.conf", $form{'db'}); ## VL - Added this to fix create with same index name bug &Architext'printHttpHeader; } } if ($form{'db'}) { ## Print out configuration options for an already-existing ## database, and allow the user to update the options. ## Dump our standard header &Architext'printHeader($attr{'ArchitextURL'}, "Collection Configuration: $form{'db'}", "Collection Configuration: $form{'db'}", $message); $warn = &Architext'errorIcon($attr{'ArchitextURL'}); ## print a message from the Update mode if something was missing print "$warnATTENTION: $message" if $message; ## Check for the desired database.conf file. $dbconfig = $root . "/collections/" . $form{'db'} . ".conf"; if (! -r $dbconfig) { &Architext'exitFileError($dbconfig, "does not exist"); } ## Read all the configuration information. ##%attr = &ArchitextConf'readConfig("$root/Architext.conf", $form{'db'}); ## Print the form. &printForm($form{'db'}); &Architext'Copyright($attr{'ArchitextURL'}); } else { ## Print out the top-level screen: scan the root directory for ## db.conf files, and allow the user to initialize a new db.conf file. opendir(CONF, "$root/collections"); @dbconf = grep(/\.conf$/, readdir(CONF)); &Architext'printHeader($attr{'ArchitextURL'}, "Collection Configuration"); print < Choose a document collection to configure, or enter a new collection:

Existing document collections:
EOF ; if ($#dbconf > -1) { print "

\n"; } else { print "

(No document collections found)

\n"; } print < If you wish to configure a new collection please supply a name for it here.

$postpass
EOF ; &Architext'Copyright($attr{'ArchitextURL'}); } ## Prints an input line for a form. sub printInputLine { local($name, $text, $db) = @_; local($val); local($size); $text = $name unless $text; $val = eval "\$attr{$name}"; $val = "$attr{'ArchitextRoot'}/collections/" if $db; $val = $form{$name} if $form{$name}; $size=40; $size = (length($val) +10) unless ((length($val) +10) < 40); print <$text:

EOF ; } ## Prints out the Architext form. Uses dynamic scoping to ensure that ## the values in the %attr array are properly set. sub printForm { local($db, $new) = @_; local($files, $rules); local($fileval, $ruleval, $filter_html, $filter_both, $notify_check); print "

Please use absolute pathnames for filenames.\n"; print qq(

\n); &printHiddenLine('CollectionInfo', 'CollectionInfo', "$db.cf"); if ($new) { print qq(); } print "Designate the directory where the index files will be stored.\n"; print "Make sure there is enough space on the directory to accomodate the index files, which will be about 50 percent of the total size of the files you index during indexing, and 15 percent once indexing has completed.
\n"; &printInputLine('CollectionIndex', 'CollectionIndex', $db); $filterstring = "$form{'IndexFilterHTML'}$form{'IndexFilterTEXT'}$form{'IndexFilterBIN'}$form{'IndexFilterCUST'}"; $ifilter = $filterstring || $attr{'IndexFilter'}; $ifilter = 'HTMLTEXT' unless $ifilter; ##default to html and text $custfilter = $form{'ExclusionRules'} || $attr{'ExclusionRules'}; $custsize = length($custfilter) + 10; $custsize = 50 unless ($custsize > 50); if ($ifilter =~ /^Text/) { ## These set for back-compatibility reasons $filter_text = "CHECKED"; $filter_html = "CHECKED"; } if ($ifilter =~ /^HTML/) { $filter_html = "CHECKED"; } if ($ifilter =~ /TEXT/) { $filter_text = "CHECKED"; } if ($ifilter =~ /PDF/) { $filter_pdf = "CHECKED"; } if (($ifilter =~ /CUST/) || $custfilter) { $filter_cust = "CHECKED"; } $form{'FileListCheck'} = 'yes' if ($attr{'CollectionsContents'} =~ /^\+/); $files = "CHECKED" if ($form{'FileListCheck'} || $attr{'FileList'} || $form{'FileList'}); $rules = "CHECKED" if (($attr{'CollectionContents'} # && ($attr{'CollectionContents'} !~ /^\+/)) || $form{'FileSource'}); if ($files) { $fileval = $form{'FileList'} || $attr{'FileList'}; $fileval2 = $attr{'CollectionContents'} if ($attr{'CollectionContents'} =~ /^\+/); $fileval = $fileval2 unless $fileval; $fileval =~ s/^\+//; } $ccontents = $form{'CollectionContents'}; if (! $form{'CollectionContents'}) { $ccontents = $attr{'CollectionContents'} unless ($attr{'CollectionContents'} =~ /^\+/); } $ruleval = join("\n", &splitFileList($ccontents)) if $rules; $notify_check = "CHECKED" if ((-e "$root/collections/$form{'db'}.pub") || ($form{'notify'} eq "NOTIFY")); print < Choose the Files to Index

Describe the CollectionContents (the files you wish to index) using any combination of the three options provided below:

Enter the Files to Index Directly into this Form

    Index the files and directories listed here:

Index Using File List

    Index the files and directories listed in the following file:
    Filenames must be listed using absolute pathnames, with one filename per line.
EOF ; ##indexing option to allow index of ~user dirs if (&Architext'indexUserDirs() && (! ($ews_port eq 'NT'))) { $user_val = 'CHECKED' if ($form{'user_dirs'} || $attr{'PublicHtml'}); $public_html = $form{'PublicHtml'} || $attr{'PublicHtml'} || 'public_html'; $pub_size = length($public_html) + 10; print < Index ~user Directories
    In addition to the files specified above, index the files in the following subdirectory of each user's home directory:
EOF ; } print < Index Filter
    Configure the IndexFilter (the types of files you wish to include in the index.):
    HTML Files (filenames with a .*htm* suffix)
    EOF ; &Architext'additionalOptions($filter_pdf); print < Text Files
    Files that match user-defined expressions in the Custom Filter File designated below:


EOF ; if (&Architext'inlineSummaryMode()) { $fast_check = "CHECKED" if (($form{'SummaryMode'} eq 'fast') || ($attr{'SummaryMode'} eq 'fast')); $q_check = "CHECKED" if (($form{'SummaryMode'} eq 'quality') || ($attr{'SummaryMode'} eq 'quality')); print <Summary Mode
    Choose a summary mode. Summaries are generated at indexing time, and therefore impact indexing speed.
    Fast summaries. (Just the first few lines from the file.)
    Quality summaries. (These summaries are calculated using excite's summarization technology. These are generally better descriptions than the first two lines of the file, but do slow down indexing a bit.

EOF ; } if (&Architext'externalSitesMode()) { $spider_dir = $form{'SpiderDir'} || $attr{'SpiderDir'}; $spider_dir_length = length($spider_dir); $spider_dir_length = 30 if ($spider_dir_length < 30); print < Spider Directory
    Enter the name of a directory where the spider's output is stored:

EOF ; } if (&Architext'notifyMode()) { print < Participate in excite notifier
    Please provide an email address below that works from outside your site.

EOF ; } if (&os_name() eq 'NT') { $server_name = $ENV{'SERVER_NAME'}; $server_name =~ s/\..*$//g; print <Please be sure that the NT Messenger Service is running on that machine.
IndexingContact: EOF ; } else { $admin_mail = $form{'AdminMail'} || $attr{'AdminMail'}; print <If you would like to receive email notification when the indexing process completes, provide an address here.
IndexingContact: EOF ; } if (&Architext'customFormat()) { $title_delimiter = $form{'TitleDelimiter'} || $attr{'TitleDelimiter'}; $doc_delimiter = $form{'DocumentDelimiter'} || $attr{'DocumentDelimiter'}; $dd_size = (length($doc_delimiter) > 30) ? length($doc_delimiter)+5 : 30; $td_size = (length($title_delimiter) > 30) ? length($title_delimiter)+5 : 30; print < Custom Document Format Information EOF ; } print < Possible Actions:

Save the configuration characteristics for this collection. $postpass


EOF ; if (-e "$root/collections/$db.conf") { $dbline = ""; } print <
$dbline Don't save, go back to the admin page. $postpass

EOF ; } ## pass around all the parameters that user doesn't need to see sub printHiddenLine { local($name, $value, $dummy) = @_; if (!&Architext'debugMode()) { $val = eval "\$attr{$name}"; $val = "$attr{'ArchitextRoot'}/collections/$dummy" if $dummy; print qq(); } else { &printInputLine($name, $value, $dummy); } } ## writes a db conf file to disk and does some error checking ## to make sure that the user has entered sensible values. ## also adds the AdminMail field to Architext.conf if it is ## not already there, so that it will be defaulted in the ## future sub createDbConf { local($dbconfig, $message, $collection_root, $exit, @index); local($n_do, $n_exist, $n_mail, $n_port, $n_server, $n_cgdir, %n_attr); if (!$form{'CollectionIndex'}) { return "You cannot leave the 'CollectionIndex' field blank."; } return "You must choose the files you wish to index." unless ($form{'user_dirs'} || $form{'FileListCheck'} || $form{'FileSource'} || $form{'SpiderDir'}); if ($form{'FileListCheck'}) { return "You must supply a filename for the file list." unless $form{'FileList'}; return "The file list file '$form{'FileList'}' does not exist." unless (-e $form{'FileList'}); return "The file list file '$form{'FileList'}' is not readable." unless (-r $form{'FileList'}); } if ($form{'FileSource'}) { return "You must supply filenames for the files you wish to index." unless $form{'CollectionContents'}; } ## add rootnmame to collection index path $dbconfig = $root . "/collections/" . $form{'dbname'} . ".conf"; $form{'CollectionIndex'} .= "/" unless $form{'CollectionIndex'} =~ /\/$/; $collection_root = "$form{'CollectionIndex'}$form{'dbname'}"; ## Can we write to the db.conf file? if (-e $dbconfig && ! -w $dbconfig) { &Architext'printHeader($attr{'ArchitextURL'}, "Error"); &Architext'exitFileError($attr{'ArchitextURL'}, $dbconfig, "is not writable."); } if ($form{'SpiderDir'}) { return "The spider output directory '$form{'SpiderDir'}' does not exist." unless (-e $form{'SpiderDir'}); return "The spider output directory '$form{'SpiderDir'}' is not a directory" unless (-d $form{'SpiderDir'}); } ## test user's entries to make sure they are valid ## makes sense and will not be likely to kill the indexing ## process. if ($form{'user_dirs'}) { return "You must provide a name for the subdirectory where user's HTML files are stored." unless $form{'PublicHtml'}; } return "The index binary '$attr{'IndexExecutable'}' does not exist." if ((! -e $attr{'IndexExecutable'}) && (! -e "$attr{'IndexExecutable'}.exe")); return "The search binary '$attr{'SearchExecutable'}' does not exist." if ((! -e $attr{'SearchExecutable'}) && (! -e "$attr{'SearchExecutable'}.exe")); return "The stem table '$attr{'StemTable'}' is not readable." if (! -r $attr{'StemTable'}); return "The stop table '$attr{'StopTable'}.key' is not readable." if (! -r "$attr{'StopTable'}.key"); return "The stop table '$attr{'StopTable'}.ptr' is not readable." if (! -r "$attr{'StopTable'}.ptr"); return "The CollectionIndex directory you specified ($form{'CollectionIndex'}) does not exist." if (! -e $form{'CollectionIndex'}); return "The CollectionIndex directory you specified ($form{'CollectionIndex'}) is not a directory." if (! -d $form{'CollectionIndex'}); return "The CollectionIndex directory you specified ($form{'CollectionIndex'}) is not writeable." if (! -w $form{'CollectionIndex'}); return "You must choose at least one of the IndexFilter options." unless ($form{'IndexFilterHTML'} || $form{'IndexFilterTEXT'} || $form{'IndexFilterBIN'} || $form{'IndexFilterCUST'} || $form{'IndexFilterPDF'}); if (($form{'IndexFilterCUST'}) && (!$form{'ExclusionRules'})) { return "You must supply the name of Custom Filter File."; } if ($form{'ExclusionRules'} && ($form{'IndexFilterCUST'})) { return "The Custom Filter File you specified ($form{'ExclusionRules'}) does not exist." if (! -e $form{'ExclusionRules'}); return "The Custom Filter File you specified ($form{'ExclusionRules'}) is not readable." if (! -r $form{'ExclusionRules'}); } if ($form{'FileListCheck'}) { return "You must provide the name of a file list." unless ($form{'FileList'}); return "The file list '$form{'FileList'}' you specified does not exist." unless (-e $form{'FileList'}); $form{'FileList'} =~ s/^\s+//; $form{'FileList'} =~ s/\s+$//; return "Please specify only one file list file." if ($form{'FileList'} =~ /\S\s\S/); } else { $form{'CollectionContents'} = join(" ", &splitFileList($form{'CollectionContents'})); } %url_maps = &ArchitextMap'getMappings($attr{'HtmlRoot'}, "$root/url.map"); @index = &splitFileList($form{'CollectionContents'}); for (@index) { if (/^\+/) { if ($form{'FileSource'} eq 'Files') { return "Bad filename given. ($_) Please use absolute pathnames."; } s/^\+//; return "Could not find file list '$_'. Please re-enter the file list filename." if (! -e $_); return "Could not read from file list '$_'. Please re-enter the file list filename." if (! -r $_); ## check to to enforce files in file list appear under html root open(FLIST, "$_"); while () { if (! &Architext'underRoot($_, $ews_port || '*', %url_maps)) { close(FLIST); return "The file '$_' specified in the file list does not appear under your html root directory or any of the directories mentioned in your URL Mapping configuration. Please specify files that appear under these directories, or your Web server will not have access to them."; } } close(FLIST); } else { ## check here to enforce that files appear under html root return "Specified file or directory '$_' does not appear under your html root directory or any of the directories mentioned in your URL Mapping configuration. Please specify files that appear under your these directories, or your Web server will not have access to them." unless &Architext'underRoot($_, $ews_port || '*', %url_maps); return "Specified file or directory '$_' does not exist. Please re-enter the list of files to index." if (! -e $_); return "Could not read from the specified file or directory '$_'. Please re-enter the list of files to index." if (! -r $_); } } if (&Architext'notifyMode()) { $n_do = 0; $n_exist = 0; $n_do = 1 if ($form{'notify'} eq "NOTIFY"); $n_exist = 1 if (-e "$root/collections/$form{'dbname'}.pub"); $n_mail = $form{'AdminMail'}; $n_port = $ENV{'SERVER_PORT'} || $attr{'ServerPort'}; $n_server = $attr{'ServerName'}; $n_cgdir = $attr{'ServerCgi'}; $n_server = $n_server . ":" . $n_port if ($n_port); if ($n_exist && !$n_do) { unlink "$root/collections/$form{'dbname'}.pub"; &ArchitextNotify'notify($form{'dbname'}, "OFF"); $mailapp = &mailer($root); open(MAIL, "| $mailapp ews_notify\@atext.com"); print MAIL "To: ews_notify\@atext.com\n"; print MAIL "Subject: Architext notifier UNSUBSCRIBE\n"; print MAIL "Collection: $form{'dbname'}\n"; print MAIL "Server: $n_server\n"; print MAIL "CgiBin: $n_cgdir\n"; print MAIL "AdminMail: $n_mail\n"; close MAIL; } if ($n_do && !$n_exist) { if ($form{'AdminMail'} !~ /\@/) { return "Please supply an email address that works from outside your organization when choosing to participate in the notifier"; } if (! open(TMP, ">$root/collections/$form{'dbname'}.pub")) { &Architext'exitFileError($attr{'ArchitextURL'}, "$root/collections/$form{'dbname'}.pub", "could not be opened for writing."); } close TMP; &ArchitextNotify'notify($form{'dbname'}, "ON"); open(MAIL, "| mail ews_notify\@atext.com"); print MAIL "To: ews_notify\@atext.com\n"; print MAIL "Subject: Architext notifier SUBSCRIBE\n"; print MAIL "Collection: $form{'dbname'}\n"; print MAIL "Server: $n_server\n"; print MAIL "CgiBin: $n_cgdir\n"; print MAIL "AdminMail: $n_mail\n"; close MAIL; } } if (! open(DBCONF, ">$dbconfig")) { &Architext'exitFileError($attr{'ArchitextURL'}, $dbconfig, "could not be opened for writing."); } ## now that everything has been tested for accuracy, write to disk print DBCONF "\n"; for ('CollectionIndex', 'CollectionInfo') { print DBCONF "$_ $form{$_}\n"; } $filterstring = "$form{'IndexFilterHTML'}$form{'IndexFilterTEXT'}$form{'IndexFilterBIN'}$form{'IndexFilterCUST'}$form{'IndexFilterPDF'}"; print DBCONF "IndexFilter $filterstring\n"; $form{'CollectionContents'} = "" unless $form{'FileSource'}; print DBCONF "CollectionContents $form{'CollectionContents'}\n"; print DBCONF "FileList $form{'FileList'}\n" if $form{'FileListCheck'}; if ($form{'user_dirs'}) { &generateUserFile("$root/collections/$form{'dbname'}.usr", $form{'PublicHtml'}); print DBCONF "PublicHtml $form{'PublicHtml'}\n"; } print DBCONF "CollectionRoot $collection_root\n"; print DBCONF "AdminMail $form{'AdminMail'}\n"; print DBCONF "ExclusionRules $form{'ExclusionRules'}\n" if ($form{'ExclusionRules'} && $form{'IndexFilterCUST'}); print DBCONF "SpiderDir $form{'SpiderDir'}\n" if $form{'SpiderDir'}; if ($form{'SummaryMode'}) { print DBCONF "SummaryMode $form{'SummaryMode'}\n"; $num_sum_sent = &Architext'numSumSent(); print DBCONF "NumSumSent $num_sum_sent\n"; } if (&Architext'customFormat()) { print DBCONF "DocumentDelimiter $form{'DocumentDelimiter'}\n" if $form{'DocumentDelimiter'}; print DBCONF "TitleDelimiter $form{'TitleDelimiter'}\n" if $form{'TitleDelimiter'}; if ($form{'TitleDelimiter'} || $form{'DocumentDelimiter'}) { if (! open(CUSTOM, ">$root/collections/$form{'dbname'}.cus")) { &Architext'printHeader($attr{'ArchitextURL'}, "Error"); &Architext'exitFileError($attr{'ArchitextURL'}, "$root/collections/$form{'dbname'}.cus", "Could not be opened for writing"); } print CUSTOM "$form{'DocumentDelimiter'}\n"; print CUSTOM "$form{'TitleDelimiter'}\n"; close(CUSTOM); } } print DBCONF "ServerPort $ENV{'SERVER_PORT'}\n"; print DBCONF "\n"; close(DBCONF); ## put AdminMail in Architext.conf if it is not already there if ($form{'AdminMail'} && (! $attr{'AdminMail'})) { $exit = &append_line_to_file("$root/Architext.conf", "AdminMail $form{'AdminMail'}"); &Architext'exitError($attr{'ArchitextURL'}, "Error updating Architext.conf with AdminMail - $!") if $exit; } return($message); } ## grabs user info from /etc/passwd for indexing of ## user's public_html directories sub generateUserFile { local($filename, $subdir) = @_; local($user, $dir, $file, $filename2); local(%homedirs) = &getHomeDirs(); $filename2 = $filename; $filename2 .= "2"; unlink($filename); unlink($filename2); open(USERFILE, ">$filename"); open(UFILE, ">$filename2"); foreach $user (keys %homedirs) { $file = $homedirs{$user}; $file .= "/" unless ($file =~ /\/$/); $file .= $subdir; $file .= "/" unless ($file =~ /\/$/); if (-e $file) { print USERFILE "~$user $file\n"; print UFILE "$file\n"; } } close(USERFILE); close(UFILE); } ## gets the home directories for all the users on the server sub getHomeDirs { local(%homes); local($name, $passwd, $uid, $gid, $quota, $comment, $gcos, $dir, $shell); local($members); # local($group) = "sysadmin"; local($group) = "real"; ($name, $passwd, $gid, $members) = getgrnam($group); if ($name eq $group) { local(@members) = split(/\s/, $members); foreach $name (@members) { ($name, $passwd, $uid, $gid, $quota, $comment, $gcos, $dir, $shell) = getpwnam($name); $homes{$name} = $dir if $name; } } else { while (($name, $passwd, $uid, $gid, $quota, $comment, $gcos, $dir, $shell) = getpwent) { next if $passwd eq "*"; next unless $shell =~ /sh$/; next if $dir eq "/"; next if $dir =~ /tmp/; next unless ((-f "$dir/.cshrc") || (-f "$dir/.login")); $homes{$name} = $dir; } ##endpwent; ## perl bug? causes bad free(). } %homes; }