Comments and suggestions for improvement are greatly appreciated.
-- GordonWorley
@@ -62,19 +62,115 @@ $OpenPageName @KeptList @IndexList $IndexInit $TableMode $q $Now $UserID $TimeZoneOffset $ScriptName $BrowseCode $OtherCode $AnchoredLinkPattern @HeadingNumbers $TableOfContents $QuotedFullUrl - $ConfigError $UploadPattern ); + $ConfigError $UploadPattern); +# Wiki farm global variables: +use vars qw($WikiName $ConfigOverrideFile $FarmDir $FarmConfigFile + $NamedWikisOnly $UseFarmConfig $UseOverrideConfig $WikiNotFound + $WikiNamesFile $DefaultWiki); + +#Wiki farm config defaults + +$FarmDir = "/path/to/wikidbs"; #no trailing slash +$UseFarmConfig = 0; +$FarmConfigFile = "$FarmDir/config"; #set wiki farm options +$WikiNamesFile = "$FarmDir/names"; + +$ConfigOverrideFile = "$FarmDir/configall"; #farm-wide config override +$WikiNotFound = "/notfound.html"; #page if wiki not found +$DefaultWiki = "KiwiWiki"; + +$UseOverrideConfig = 1; +$NamedWikisOnly = 1; #only allow wikis in $WikiNamesFile + +if ($UseFarmConfig && (-f $FarmConfigFile)) +{ + $ConfigError = ''; + if (!do $FarmConfigFile) { # Some error occurred + $ConfigError = $@; + if ($ConfigError eq '') { + # Unfortunately, if the last expr returns 0, one will get a false + # error above. To remain compatible with existing installs the + # wiki must not report an error unless there is error text in $@. + # (Errors in "use strict" may not have error text.) + # Uncomment the line below if you want to catch use strict errors. +# $ConfigError = T('Unknown Error (no error text)'); + } + } +} + +use CGI; +use CGI::Carp qw(fatalsToBrowser); + +$q = new CGI; + +$WikiName = $q->param('keywords'); +if ($WikiName) + #just script?WikiName/PageName +{ + $WikiName =~ s/(.*?)\/.*/\1/; +} +elsif ($q->param("wiki")) + # url is something like ...?...&wiki=WikiName&... +{ + $WikiName = $q->param("wiki"); +} +else + # if no wiki name is given +{ + $WikiName = $DefaultWiki; +} + +unless (&WikiExists()) +{ + # handle missing wiki by sending to $WikiNotFound + print "Location: $WikiNotFound"; + error ($q, "wiki doesn't exist"); +} + +sub WikiExists + #should check if the wiki exists + #if not, take some action +{ + if (!$NamedWikisOnly) + { + #just return true + #wikis are created by naming them + return 1; + } + elsif (-e "$WikiNamesFile") + #check if the wiki exists + { + open (WNAMES, "<$WikiNamesFile"); + while (my $line = <WNAMES>) + { + if ($line =~ /^$WikiName$/) + { + close(WNAMES); + return 1; + } + } + close(WNAMES); + return 0; + } + else + { + #some kind of error + #shouldn't happen, but just in case + return 0; + } +} # == Configuration ===================================================== -$DataDir = "/Library/WebServer/mangowikidb"; # Main wiki directory +$DataDir = "$FarmDir/$WikiName"; # Main wiki directory $UseConfig = 1; # 1 = use config file, 0 = do not look for config $ConfigFile = "$DataDir/config"; # Configuration file # Default configuration (used if UseConfig is 0) -$CookieName = "Wiki"; # Name for this wiki (for multi-wiki sites) -$SiteName = "Wiki"; # Name of site (used for titles) -$HomePage = "HomePage"; # Home page (change space to _) +$CookieName = "$WikiName"; # Name for this wiki (for multi-wiki sites) +$SiteName = "$WikiName"; # Name of site (used for titles) +$HomePage = "$WikiName"; # Home page (change space to _) $RCName = "RecentChanges"; # Name of changes page (change space to _) -$LogoUrl = "/wiki.gif"; # URL for site logo ("" for no logo) +$LogoUrl = ""; # URL for site logo ("" for no logo) $ENV{PATH} = "/usr/bin/"; # Path used to find "diff" $ScriptTZ = ""; # Local time zone ("" means do not print) $RcDefault = 30; # Default number of RecentChanges days @@ -87,7 +183,7 @@ $EditPass = ""; # Like AdminPass, but for editing only $StyleSheet = ""; # URL for CSS stylesheet (like "/wiki.css") $NotFoundPg = ""; # Page for not-found links ("" for blank pg) -$EmailFrom = "Wiki"; # Text for "From: " field of email notes. +$EmailFrom = "$WikiName"; # Text for "From: " field of email notes. $SendMail = "/usr/sbin/sendmail"; # Full path to sendmail executable $FooterNote = ""; # HTML for bottom of every page $EditNote = ""; # HTML notice above buttons on edit page @@ -130,19 +226,19 @@ $ReplaceFile = 'ReplaceFile'; # 0 = disable, 'PageName' = indicator tag @ReplaceableFiles = (); # List of allowed server files to replace $TableSyntax = 1; # 1 = wiki syntax tables, 0 = no table syntax -$NewFS = 0; # 1 = new multibyte $FS, 0 = old $FS +$NewFS = 1; # 1 = new multibyte $FS, 0 = old $FS $UseUpload = 0; # 1 = allow uploads, 0 = no uploads # Minor options: $LogoLeft = 0; # 1 = logo on left, 0 = logo on right $RecentTop = 1; # 1 = recent on top, 0 = recent on bottom -$UseDiffLog = 1; # 1 = save diffs to log, 0 = do not save diffs +$UseDiffLog = 0; # 1 = save diffs to log, 0 = do not save diffs $KeepMajor = 1; # 1 = keep major rev, 0 = expire all revisions $KeepAuthor = 1; # 1 = keep author rev, 0 = expire all revisions $ShowEdits = 0; # 1 = show minor edits, 0 = hide edits by default $HtmlLinks = 0; # 1 = allow A HREF links, 0 = no raw HTML links $SimpleLinks = 0; # 1 = only letters, 0 = allow _ and numbers -$NonEnglish = 0; # 1 = extra link chars, 0 = only A-Za-z chars +$NonEnglish = 1; # 1 = extra link chars, 0 = only A-Za-z chars $ThinLine = 0; # 1 = fancy <hr> tags, 0 = classic wiki <hr> $BracketText = 1; # 1 = allow [URL text], 0 = no link descriptions $UseAmPm = 1; # 1 = use am/pm in times, 0 = use 24-hour times @@ -203,7 +299,7 @@ $KeepDir = "$DataDir/keep"; # Stores kept (old) page data $TempDir = "$DataDir/temp"; # Temporary files and locks $LockDir = "$TempDir/lock"; # DB is locked if this exists -$InterFile = "$DataDir/intermap"; # Interwiki site->url map +$InterFile = "$FarmDir/intermap"; # Interwiki site->url map $RcFile = "$DataDir/rclog"; # New RecentChanges logfile $RcOldFile = "$DataDir/oldrclog"; # Old RecentChanges logfile $IndexFile = "$DataDir/pageidx"; # List of all pages @@ -229,6 +325,23 @@ } } } +# override any user-set options that we want the same on all wikis +# mostly for security purposes, but also to prevent other things +# like if you want ads on all pages + if ($UseOverrideConfig && (-f $ConfigOverrideFile)) { + $ConfigError = ''; + if (!do $ConfigOverrideFile) { # Some error occurred + $ConfigError = $@; + if ($ConfigError eq '') { + # Unfortunately, if the last expr returns 0, one will get a false + # error above. To remain compatible with existing installs the + # wiki must not report an error unless there is error text in $@. + # (Errors in "use strict" may not have error text.) + # Uncomment the line below if you want to catch use strict errors. +# $ConfigError = T('Unknown Error (no error text)'); + } + } + } &InitLinkPatterns(); if (!&DoCacheBrowse()) { eval $BrowseCode; @@ -392,8 +505,6 @@ # == Normal page-browsing and RecentChanges code ======================= $BrowseCode = ""; # Comment next line to always compile (slower) #$BrowseCode = <<'#END_OF_BROWSE_CODE'; -use CGI; -use CGI::Carp qw(fatalsToBrowser); sub InitRequest { my @ScriptPath = split('/', "$ENV{SCRIPT_NAME}"); @@ -459,6 +570,7 @@ } $id = &GetParam('keywords', ''); if ($id) { # Just script?PageName + $id =~ s/.*?\/(.*)/\1/; # eat wiki name if ($FreeLinks && (!-f &GetPageFile($id))) { $id = &FreeToNormal($id); } @@ -593,7 +705,7 @@ my ($id, $oldId, $isEdit) = @_; if ($oldId ne "") { # Target of #REDIRECT (loop breaking) - print &GetRedirectPage("action=browse&id=$id&oldid=$oldId", + print &GetRedirectPage("action=browse&wiki=$WikiName&id=$id&oldid=$oldId", $id, $isEdit); } else { print &GetRedirectPage($id, $id, $isEdit); @@ -689,13 +801,13 @@ foreach $i (@RcDays) { print " | " if $showbar; $showbar = 1; - print &ScriptLink("action=rc&days=$i", + print &ScriptLink("action=rc&days=$i&wiki=$WikiName", Ts('%s day' . (($i != 1)?'s':''), $i)); # Note: must have two translations (for "day" and "days") # Following comment line is for translation helper script # Ts('%s days', ''); } - print "<br>" . &ScriptLink("action=rc&from=$lastTs", + print "<br>" . &ScriptLink("action=rc&from=$lastTs&wiki=$WikiName", T('List new changes starting from')); print " " . &TimeToText($lastTs) . "<br>\n"; } @@ -763,8 +875,8 @@ $tEdit = T('(edit)'); $tDiff = T('(diff)'); $tChanges = T('changes'); - $diffPrefix = $QuotedFullUrl . &QuoteHtml("?action=browse\&diff=4\&id="); - $historyPrefix = $QuotedFullUrl . &QuoteHtml("?action=history\&id="); + $diffPrefix = $QuotedFullUrl . &QuoteHtml("?action=browse\&wiki=$WikiName\&diff=4\&id="); + $historyPrefix = $QuotedFullUrl . &QuoteHtml("?action=history\&wiki=$WikiName\&id="); foreach $rcline (@outrc) { ($ts, $pagename) = split(/$FS3/, $rcline); $pagecount{$pagename}++; @@ -997,6 +1109,7 @@ <input type='hidden' name='action' value='browse'/> <input type='hidden' name='diff' value='1'/> <input type='hidden' name='id' value='$id'/> + <input type='hidden' name='wiki' value='$WikiName'/> <table border='0' width='100%'><tr> EOF } @@ -1111,7 +1224,7 @@ $id = &FreeToNormal($id); $name =~ s/_/ /g; } - return &ScriptLinkClass($id, $name, 'wikipagelink'); + return &ScriptLinkClass("$WikiName/$id", $name, 'wikipagelink'); } sub GetPageLink { @@ -1127,7 +1240,7 @@ $id = &FreeToNormal($id); $name =~ s/_/ /g; } - return &ScriptLinkClass("action=edit&id=$id", $name, 'wikipageedit'); + return &ScriptLinkClass("action=edit&wiki=$WikiName&id=$id", $name, 'wikipageedit'); } sub GetDeleteLink { @@ -1137,14 +1250,14 @@ $id = &FreeToNormal($id); $name =~ s/_/ /g; } - return &ScriptLink("action=delete&id=$id&confirm=$confirm", $name); + return &ScriptLink("action=delete&wiki=$WikiName&id=$id&confirm=$confirm", $name); } sub GetOldPageParameters { my ($kind, $id, $revision) = @_; $id = &FreeToNormal($id) if $FreeLinks; - return "action=$kind&id=$id&revision=$revision"; + return "action=$kind&wiki=$WikiName&id=$id&revision=$revision"; } sub GetOldPageLink { @@ -1208,15 +1321,15 @@ $name =~ s/_/ /g; # Display with spaces $id =~ s/_/+/g; # Search for url-escaped spaces } - return &ScriptLink("back=$id", $name); + return &ScriptLink("back=$id&wiki=$WikiName", $name); } sub GetPrefsLink { - return &ScriptLink("action=editprefs", T('Preferences')); + return &ScriptLink("action=editprefs&wiki=$WikiName", T('Preferences')); } sub GetRandomLink { - return &ScriptLink("action=random", T('Random Page')); + return &ScriptLink("action=random&wiki=$WikiName", T('Random Page')); } sub ScriptLinkDiff { @@ -1224,7 +1337,7 @@ $rev = "&revision=$rev" if ($rev ne ""); $diff = &GetParam("defaultdiff", 1) if ($diff == 4); - return &ScriptLink("action=browse&diff=$diff&id=$id$rev", $text); + return &ScriptLink("action=browse&wiki=$WikiName&diff=$diff&id=$id$rev", $text); } sub ScriptLinkDiffRevision { @@ -1232,11 +1345,11 @@ $rev = "&diffrevision=$rev" if ($rev ne ""); $diff = &GetParam("defaultdiff", 1) if ($diff == 4); - return &ScriptLink("action=browse&diff=$diff&id=$id$rev", $text); + return &ScriptLink("action=browse&wiki=$WikiName&diff=$diff&id=$id$rev", $text); } sub GetUploadLink { - return &ScriptLink('action=upload', T('Upload')); + return &ScriptLink('action=upload&wiki=$WikiName', T('Upload')); } sub ScriptLinkTitle { @@ -1262,7 +1375,7 @@ $userName = ""; # Just pretend it isn't there. } if (($uid > 0) && ($userName ne "")) { - $html = &ScriptLinkTitle($userName, $userNameShow, + $html = &ScriptLinkTitle("$WikiName/$userName", $userNameShow, Ts('ID %s', $uid) . ' ' . Ts('from %s', $host)); } else { $html = $host; @@ -1276,12 +1389,12 @@ if ($FreeLinks) { $id =~ s/ /_/g; } - return &ScriptLink("action=history&id=$id", $text); + return &ScriptLink("action=history&wiki=$WikiName&id=$id", $text); } sub GetHeader { my ($id, $title, $oldId) = @_; - my $header = ""; + my $header = "$WikiName: "; my $logoImage = ""; my $result = ""; my $embed = &GetParam('embed', $EmbedWiki); @@ -1304,7 +1417,7 @@ if (!$LogoLeft) { $logoImage .= " align=\"right\""; } - $header = &ScriptLink($HomePage, "<$logoImage>"); + $header = "$WikiName: " . &ScriptLink($HomePage, "<$logoImage>"); } if ($id ne '') { $result .= $q->h1($header . &GetBackLinksSearchLink($id)); @@ -1513,7 +1626,7 @@ # Normally get URL from script, but allow override. $FullUrl = $q->url(-full=>1) if ($FullUrl eq ""); - $url = $FullUrl . &ScriptLinkChar() . $newid; + $url = $FullUrl . &ScriptLinkChar() . "$WikiName/$newid"; $nameLink = "<a href=\"$url\">$name</a>"; if ($RedirType < 3) { if ($RedirType == 1) { # Use CGI.pm @@ -3244,7 +3357,8 @@ print &GetFormStart(); print &GetHiddenValue("title", $id), "\n", &GetHiddenValue("oldtime", $pageTime), "\n", - &GetHiddenValue("oldconflict", $isConflict), "\n"; + &GetHiddenValue("oldconflict", $isConflict), "\n", + &GetHiddenValue("wiki", $WikiName), "\n"; if ($revision ne "") { print &GetHiddenValue("revision", $revision), "\n"; } @@ -3402,6 +3516,7 @@ T('Add "Random Page" link to link bar')); print '<br>' . T('StyleSheet URL:') . ' ', &GetFormText('stylesheet', "", 30, 150); + print &GetHiddenValue('wiki', $WikiName), "\n"; print '<br>', $q->submit(-name=>'Save', -value=>T('Save')), "\n"; print '</div>'; print "<hr class=wikilinefooter>\n"; @@ -4089,7 +4204,7 @@ so only do that if you mean to. To remove yourself from this list, visit - ${home_url}?action=editprefs .) + ${home_url}?action=editprefs&wiki=$WikiName .) END_MAIL_CONTENT my $subject = "The $id page at $SiteName has been changed."; # I'm setting the "reply-to" field to be the same as the "to:" field @@ -4839,7 +4954,7 @@ if ($FreeLinks) { $id = &FreeToNormal($id); } - return &ScriptLink("action=pagelock&set=$status&id=$id", $name); + return &ScriptLink("action=pagelock&set=$status&wiki=$WikiName&id=$id", $name); } sub GetAdminBar { @@ -4854,13 +4969,13 @@ $result .= &GetPageLockLink($id, 1, T('Lock page')); } $result .= " | " . &GetDeleteLink($id, T('Delete this page'), 0); - $result .= " | " . &ScriptLink("action=editbanned", T("Edit Banned List")); - $result .= " | " . &ScriptLink("action=maintain", T("Run Maintenance")); - $result .= " | " . &ScriptLink("action=editlinks", T("Edit/Rename pages")); + $result .= " | " . &ScriptLink("action=editbanned&wiki=$WikiName", T("Edit Banned List")); + $result .= " | " . &ScriptLink("action=maintain&wiki=$WikiName", T("Run Maintenance")); + $result .= " | " . &ScriptLink("action=editlinks&wiki=$WikiName", T("Edit/Rename pages")); if (-f "$DataDir/noedit") { - $result .= " | " . &ScriptLink("action=editlock&set=0", T("Unlock site")); + $result .= " | " . &ScriptLink("action=editlock&set=0&wiki=$WikiName", T("Unlock site")); } else { - $result .= " | " . &ScriptLink("action=editlock&set=1", T("Lock site")); + $result .= " | " . &ScriptLink("action=editlock&set=1&wiki=$WikiName", T("Lock site")); } return $result; } @@ -4911,6 +5026,7 @@ print '<FORM METHOD="post" ACTION="' . $ScriptName . '" ENCTYPE="multipart/form-data">'; print '<input type="hidden" name="upload" value="1" />'; + print '<input type="hidden" name="wiki" value="' . $WikiName . '"/>'; print 'File to Upload: <INPUT TYPE="file" NAME="file"><br><BR>'; print '<INPUT TYPE="submit" NAME="Submit" VALUE="Upload">'; print '</FORM>';
Then load and run wiki.pl from wrapper scripts:
#!/usr/bin/perl package UseModWiki; $DataDir = '/path/to/wiki/data'; require '/path/to/wiki.pl'; DoWikiRequest();
This presupposes that there is a config file in the DataDir of each wiki. --GunnarH