#!/usr/bin/perl # UseModWiki version 0.92K2 (2001-12-27) # Copyright (C) 2000-2001 Clifford A. Adams # or # Based on the GPLed AtisWiki 0.3 (C) 1998 Markus Denker # # ...which was based on # the LGPLed CVWiki CVS-patches (C) 1997 Peter Merel # and The Original WikiWikiWeb (C) Ward Cunningham # (code reused with permission) # Email and ThinLine options by Jim Mahoney # # 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 package UseModWiki; use strict; ############### ### added by gypark ### wiki.pl ¹öÀü Á¤º¸ use vars qw($WikiVersion $WikiRelease $HashKey); $WikiVersion = "0.92K3-ext1.44"; $WikiRelease = "2003-04-06"; $HashKey = "salt"; # 2-character string ### ############### local $| = 1; # Do not buffer output (localized for mod_perl) # Configuration/constant variables: ############### ### modified by gypark ### Á¦ÀÏ ³¡¿¡ ConfigFile µîµî Ãß°¡ use vars qw(@RcDays @HtmlPairs @HtmlSingle $TempDir $LockDir $DataDir $HtmlDir $UserDir $KeepDir $PageDir $InterFile $RcFile $RcOldFile $IndexFile $FullUrl $SiteName $HomePage $LogoUrl $RcDefault $IndentLimit $RecentTop $EditAllowed $UseDiff $UseSubpage $UseCache $RawHtml $SimpleLinks $NonEnglish $LogoLeft $KeepDays $HtmlTags $HtmlLinks $UseDiffLog $KeepMajor $KeepAuthor $FreeUpper $EmailNotify $SendMail $EmailFrom $FastGlob $EmbedWiki $ScriptTZ $BracketText $UseAmPm $UseIndex $UseLookup $RedirType $AdminPass $EditPass $UseHeadings $NetworkFile $BracketWiki $FreeLinks $WikiLinks $AdminDelete $FreeLinkPattern $RCName $RunCGI $ShowEdits $ThinLine $LinkPattern $InterLinkPattern $InterSitePattern $UrlProtocols $UrlPattern $ImageExtensions $RFCPattern $ISBNPattern $FS $FS1 $FS2 $FS3 $CookieName $SiteBase $StyleSheet $NotFoundPg $FooterNote $EditNote $MaxPost $NewText $NotifyDefault $HttpCharset); ### ############### ############### ### added by gypark ### ÆÐÄ¡¸¦ À§ÇØ Ãß°¡µÈ ȯ°æ¼³Á¤ º¯¼ö use vars qw( $UserGotoBar $UserGotoBar2 $UserGotoBar3 $UserGotoBar4 $ConfigFile $SOURCEHIGHLIGHT @SRCHIGHLANG $LinkFirstChar $EditGuideInExtern $SizeTopFrame $SizeBottomFrame $LogoPage $CheckTime $LinkDir $IconDir $CountDir $UploadDir $UploadUrl $HiddenPageFile ); ### ############### use vars qw($DocID $ImageTag $ClickEdit $UseEmoticon $EmoticonPath $EditPagePos $EditFlag); # luke use vars qw($TableOfContents @HeadingNumbers $NamedAnchors $AnchoredLinkPattern); use vars qw($TableTag $TableMode); # Note: $NotifyDefault is kept because it was a config variable in 0.90 # Other global variables: use vars qw(%Page %Section %Text %InterSite %SaveUrl %SaveNumUrl %KeptRevisions %UserCookie %SetCookie %UserData %IndexHash %Translate %LinkIndex $InterSiteInit $SaveUrlIndex $SaveNumUrlIndex $MainPage $OpenPageName @KeptList @IndexList $IndexInit $q $Now $UserID $TimeZoneOffset $ScriptName $BrowseCode $OtherCode); ############### ### added by gypark ### ÆÐÄ¡¸¦ À§ÇØ Ãß°¡µÈ ³»ºÎ Àü¿ª º¯¼ö use vars qw(%RevisionTs $FS_lt $FS_gt $StartTime $Sec_Revision $Sec_Ts $ViewCount $AnchoredFreeLinkPattern %UserInterest %HiddenPage); ### ############### # == Configuration ===================================================== ############### ### replaced by gypark ### º¸¾ÈÀ» À§Çؼ­ µ¥ÀÌŸ ÀúÀå °ø°£À» ´Ù¸¥ °÷À¸·Î ÁöÁ¤ ### ÀûÀýÈ÷ ¹Ù²Ù¾î¼­ »ç¿ëÇÒ °Í # $DataDir = "data"; # Main wiki directory $DataDir = "wikidata"; # Main wiki directory $ConfigFile = "config.pl"; # path of config file ### ############### $RunCGI = 1; # 1 = Run script as CGI, 0 = Load but do not run # == End of Configuration ================================================= umask 0; $TableOfContents = ""; # The "main" program, called at the end of this script file. sub DoWikiRequest { ############### ### replaced by gypark ### ȯ°æ º¯¼öµéÀ» ÁöÁ¤ÇÏ´Â ·çƾÀ» Á¦°Å. ¹«Á¶°Ç config file ¸¦ ÀÐÀ½. if (-f $ConfigFile) { do "$ConfigFile"; } else { die "Can not load config file"; } ### ############### ############### ### added by gypark ### ó¸® ½Ã°£ ÃøÁ¤ if ($CheckTime) { eval "use Time::HiRes qw( usleep ualarm gettimeofday tv_interval )"; if ($@) { $CheckTime = 0; } else { $StartTime = [gettimeofday()]; } } ### ############### ############### ### added by gypark ### oekaki if ($ENV{'QUERY_STRING'} eq "action=oekaki&mode=save") { &OekakiSave(); return; } ### ############### &InitLinkPatterns(); if (!&DoCacheBrowse()) { eval $BrowseCode; &InitRequest() or return; if (!&DoBrowseRequest()) { eval $OtherCode; &DoOtherRequest(); } } } # == Common and cache-browsing code ==================================== sub InitLinkPatterns { my ($UpperLetter, $LowerLetter, $AnyLetter, $LpA, $LpB, $QDelim); # Field separators are used in the URL-style patterns below. # $FS = "\xb3"; # The FS character is a superscript "3" $FS = "\x7f"; $FS1 = $FS . "1"; # The FS values are used to separate fields $FS2 = $FS . "2"; # in stored hashtables and other data structures. $FS3 = $FS . "3"; # The FS character is not allowed in user data. ############### ### added by gypark $FS_lt = $FS . "lt"; $FS_gt = $FS . "gt"; ### ############### $UpperLetter = "[A-Z"; $LowerLetter = "[a-z"; $AnyLetter = "[A-Za-z"; if ($NonEnglish) { $UpperLetter .= "\xc0-\xde"; $LowerLetter .= "\xdf-\xff"; $AnyLetter .= "\xc0-\xff"; } if (!$SimpleLinks) { $AnyLetter .= "_0-9"; } $UpperLetter .= "]"; $LowerLetter .= "]"; $AnyLetter .= "]"; # Main link pattern: lowercase between uppercase, then anything $LpA = $UpperLetter . "+" . $LowerLetter . "+" . $UpperLetter . $AnyLetter . "*"; # Optional subpage link pattern: uppercase, lowercase, then anything $LpB = $UpperLetter . "+" . $LowerLetter . "+" . $AnyLetter . "*"; if ($UseSubpage) { # Loose pattern: If subpage is used, subpage may be simple name $LinkPattern = "((?:(?:$LpA)?\\/$LpB)|$LpA)"; # Strict pattern: both sides must be the main LinkPattern # $LinkPattern = "((?:(?:$LpA)?\\/)?$LpA)"; } else { $LinkPattern = "($LpA)"; } $QDelim = '(?:"")?'; # Optional quote delimiter (not in output) ############### ### replaced by gypark ### anchor ¿¡ ÇÑ±Û »ç¿ë # $AnchoredLinkPattern = $LinkPattern . '#(\\w+)' . $QDelim if $NamedAnchors; $AnchoredLinkPattern = $LinkPattern . '#([0-9A-Za-z\xa0-\xff]+)' . $QDelim if $NamedAnchors; ### ############### $LinkPattern .= $QDelim; # Inter-site convention: sites must start with uppercase letter # (Uppercase letter avoids confusion with URLs) $InterSitePattern = $UpperLetter . $AnyLetter . "+"; $InterLinkPattern = "((?:$InterSitePattern:[^\\]\\s\"<>$FS]+)$QDelim)"; if ($FreeLinks) { # Note: the - character must be first in $AnyLetter definition #if ($NonEnglish) { $AnyLetter = "[-,.()' _0-9A-Za-z\xa0-\xff]"; #} else { # $AnyLetter = "[-,.()' _0-9A-Za-z]"; #} } $FreeLinkPattern = "($AnyLetter+)"; if ($UseSubpage) { $FreeLinkPattern = "((?:(?:$AnyLetter+)?\\/)?$AnyLetter+)"; } $FreeLinkPattern .= $QDelim; ############### ### added by gypark ### ÇÑ±ÛÆÐÀÌÁö¿¡ anchor »ç¿ë ### from Bab2's patch $AnchoredFreeLinkPattern = $FreeLinkPattern . '#([0-9A-Za-z\xa0-\xff]+)' . $QDelim if $NamedAnchors; ### ############### # Url-style links are delimited by one of: # 1. Whitespace (kept in output) # 2. Left or right angle-bracket (< or >) (kept in output) # 3. Right square-bracket (]) (kept in output) # 4. A single double-quote (") (kept in output) # 5. A $FS (field separator) character (kept in output) # 6. A double double-quote ("") (removed from output) $UrlProtocols = "http|https|ftp|afs|news|nntp|mid|cid|mailto|wais|mms|" . "prospero|telnet|gopher"; $UrlProtocols .= '|file' if $NetworkFile; $UrlPattern = "((?:(?:$UrlProtocols):[^\\]\\s\"<>$FS]+)$QDelim)"; $ImageExtensions = "(gif|jpg|png|bmp|jpeg|GIF|JPG|PNG|BMP|JPEG)"; $RFCPattern = "RFC\\s?(\\d+)"; ############### ### replaced by gypark ### ISBN ÆÐÅÏ ¼öÁ¤ # $ISBNPattern = "ISBN:?([0-9- xX]{10,})"; $ISBNPattern = "ISBN:?([0-9-xX]{10,})"; ### ############### } # Simple HTML cache sub DoCacheBrowse { my ($query, $idFile, $text); return 0 if (!$UseCache); $query = $ENV{'QUERY_STRING'}; if (($query eq "") && ($ENV{'REQUEST_METHOD'} eq "GET")) { ############### ### replaced by gypark ### LogoPage °¡ ÀÖÀ¸¸é À̰ÍÀ» embed Çü½ÄÀ¸·Î Ãâ·Â # $query = $HomePage; # Allow caching of home page. if ($LogoPage eq "") { $query = $HomePage; # Allow caching of home page. } else { $query = $LogoPage; } ### ############### } ############### ### added by gypark ### LogoPage °¡ ÀÖÀ¸¸é À̰ÍÀ» embed Çü½ÄÀ¸·Î Ãâ·Â return 0 if ($query eq $LogoPage); ### ############### if (!($query =~ /^$LinkPattern$/)) { if (!($FreeLinks && ($query =~ /^$FreeLinkPattern$/))) { return 0; # Only use cache for simple links } } $idFile = &GetHtmlCacheFile($query); if (-f $idFile) { local $/ = undef; # Read complete files open(INFILE, "<$idFile") or return 0; $text = ; close INFILE; print $text; return 1; } return 0; } sub GetHtmlCacheFile { my ($id) = @_; return $HtmlDir . "/" . &GetPageDirectory($id) . "/$id.htm"; } sub GetPageDirectory { my ($id) = @_; if ($id =~ /^([a-zA-Z])/) { return uc($1); } return "other"; } sub T { my ($text) = @_; if (1) { # Later make translation optional? if (defined($Translate{$text}) && ($Translate{$text} ne '')) { return $Translate{$text}; } } return $text; } sub Ts { my ($text, $string) = @_; $text = T($text); $text =~ s/\%s/$string/; return $text; } # == 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}"); $CGI::POST_MAX = $MaxPost; ############### ### replaced by gypark ### file upload # $CGI::DISABLE_UPLOADS = 1; # no uploads $CGI::DISABLE_UPLOADS = 0; ### ############### $q = new CGI; $q->autoEscape(undef); ############### ### added by gypark ### file upload if ($q->cgi_error() =~ m/^413/) { print $q->redirect(-url=>"http:$ENV{SCRIPT_NAME}?action=upload&error=3"); exit 1; } $UploadUrl = "http:$UploadDir" if ($UploadUrl eq ""); ### ############### $Now = time; # Reset in case script is persistent $ScriptName = pop(@ScriptPath); # Name used in links $IndexInit = 0; # Must be reset for each request $InterSiteInit = 0; %InterSite = (); $MainPage = "."; # For subpages only, the name of the top-level page $OpenPageName = ""; # Currently open page &CreateDir($DataDir); # Create directory if it doesn't exist if (!-d $DataDir) { &ReportError(Ts('Could not create %s', $DataDir) . ": $!"); return 0; } &InitCookie(); # Reads in user data ############### ### added by gypark ### hide page my ($status, $data) = &ReadFile($HiddenPageFile); if ($status) { %HiddenPage = split(/$FS1/, $data, -1); } ### ############### return 1; } sub InitCookie { %SetCookie = (); $TimeZoneOffset = 0; undef $q->{'.cookies'}; # Clear cache if it exists (for SpeedyCGI) %UserCookie = $q->cookie($CookieName); $UserID = $UserCookie{'id'}; &LoadUserData($UserID); if (($UserData{'id'} != $UserCookie{'id'}) || ($UserData{'randkey'} != $UserCookie{'randkey'})) { $UserID = 113; %UserData = (); # Invalid. Later consider warning message. } if ($UserData{'tzoffset'} != 0) { $TimeZoneOffset = $UserData{'tzoffset'} * (60 * 60); } } sub DoBrowseRequest { my ($id, $action, $text); if (!$q->param) { # No parameter ############### ### replaced by gypark ### LogoPage °¡ ÀÖÀ¸¸é À̰ÍÀ» embed Çü½ÄÀ¸·Î Ãâ·Â # &BrowsePage($HomePage); if ($LogoPage eq "") { &BrowsePage($HomePage); } else { $EmbedWiki = 1; &BrowsePage($LogoPage); } ### ############### return 1; } $id = &GetParam('keywords', ''); if ($id) { # Just script?PageName if ($FreeLinks && (!-f &GetPageFile($id))) { $id = &FreeToNormal($id); } if (($NotFoundPg ne '') && (!-f &GetPageFile($id))) { $id = $NotFoundPg; } $DocID = $id; &BrowsePage($id) if &ValidIdOrDie($id); return 1; } $action = lc(&GetParam('action', '')); $id = &GetParam('id', ''); $DocID = $id; if ($action eq 'browse') { if ($FreeLinks && (!-f &GetPageFile($id))) { $id = &FreeToNormal($id); } if (($NotFoundPg ne '') && (!-f &GetPageFile($id))) { $id = $NotFoundPg; } ############### ### added by gypark ### id °¡ NULL ÀÏ °æ¿ì ȨÀ¸·Î À̵¿ ### from Bab2's patch if ($id eq '') { $id = $HomePage; } ### ############### &BrowsePage($id) if &ValidIdOrDie($id); return 1; } elsif ($action eq 'rc') { &BrowsePage(T($RCName)); return 1; } elsif ($action eq 'random') { &DoRandom(); return 1; } elsif ($action eq 'history') { $ClickEdit = 0; # luke added &DoHistory($id) if &ValidIdOrDie($id); return 1; } return 0; # Request not handled } sub BrowsePage { my ($id) = @_; my ($fullHtml, $oldId, $allDiff, $showDiff, $openKept); my ($revision, $goodRevision, $diffRevision, $newText); ############### ### added by gypark ### hide page if (&PageIsHidden($id)) { print &GetHeader($id, &QuoteHtml($id), $oldId); print Ts('%s is a hidden page', $id); print &GetCommonFooter(); return; } ### ############### &OpenPage($id); &OpenDefaultText(); ############### ### added by gypark ### page count if (-f &GetPageFile($id)) { $ViewCount = &GetPageCount($id) if (-f &GetPageFile($id)); } ### ############### $openKept = 0; $revision = &GetParam('revision', ''); $revision =~ s/\D//g; # Remove non-numeric chars $goodRevision = $revision; # Non-blank only if exists if ($revision ne '') { &OpenKeptRevisions('text_default'); $openKept = 1; if (!defined($KeptRevisions{$revision})) { $goodRevision = ''; } else { &OpenKeptRevision($revision); } } ############### ### added by gypark ### ¸ÅÅ©·Î°¡ µé¾î°£ ÆäÀÌÁöÀÇ ÆíÁý°¡ÀÌµå ¹®Á¦ ÇØ°á $Sec_Revision = $Section{'revision'}; $Sec_Ts = $Section{'ts'}; ### ############### $newText = $Text{'text'}; # For differences # Handle a single-level redirect $oldId = &GetParam('oldid', ''); if (($oldId eq '') && (substr($Text{'text'}, 0, 10) eq '#REDIRECT ')) { $oldId = $id; if (($FreeLinks) && ($Text{'text'} =~ /\#REDIRECT\s+\[\[.+\]\]/)) { ($id) = ($Text{'text'} =~ /\#REDIRECT\s+\[\[(.+)\]\]/); $id = &FreeToNormal($id); } else { ($id) = ($Text{'text'} =~ /\#REDIRECT\s+(\S+)/); } if (&ValidId($id) eq '') { # Later consider revision in rebrowse? &ReBrowsePage($id, $oldId, 0); return; } else { # Not a valid target, so continue as normal page $id = $oldId; $oldId = ''; } } ############### ### added by gypark ### #EXTERN if (substr($Text{'text'}, 0, 8) eq '#EXTERN ') { $oldId = &GetParam('oldid', ''); my ($externURL) = ($Text{'text'} =~ /\#EXTERN\s+([^\s]+)/); if ($externURL =~ /^$UrlPattern$/) { &BrowseExternUrl($id, $oldId, $externURL); return; } } ### ############### $MainPage = $id; $MainPage =~ s|/.*||; # Only the main page name (remove subpage) $fullHtml = &GetHeader($id, &QuoteHtml($id), $oldId); if ($revision ne '') { # Later maybe add edit time? if ($goodRevision ne '') { $fullHtml .= '' . Ts('Showing revision %s', $revision) . "
"; } else { $fullHtml .= '' . Ts('Revision %s not available', $revision) . ' (' . T('showing current revision instead') . ')
'; } } $allDiff = &GetParam('alldiff', 0); if ($allDiff != 0) { $allDiff = &GetParam('defaultdiff', 1); } if ((($id eq $RCName) || (T($RCName) eq $id) || (T($id) eq $RCName)) && &GetParam('norcdiff', 1)) { $allDiff = 0; # Only show if specifically requested } $showDiff = &GetParam('diff', $allDiff); if ($UseDiff && $showDiff) { $diffRevision = $goodRevision; $diffRevision = &GetParam('diffrevision', $diffRevision); # Later try to avoid the following keep-loading if possible? &OpenKeptRevisions('text_default') if (!$openKept); ############### ### added by gypark ### ÃÖ±Ùº¯°æ³»¿ª¿¡ ºÏ¸¶Å© ±â´É µµÀÔ if ($showDiff == 5) { $diffRevision = $Page{'revision'} - 1; while (($diffRevision > 1) && (defined($RevisionTs{$diffRevision})) && ($RevisionTs{$diffRevision} > &GetParam('bookmark',-1))) { $diffRevision--; } $showDiff = &GetParam("defaultdiff", 1); } ### ############### $fullHtml .= &GetDiffHTML($showDiff, $id, $diffRevision, "$revision", $newText); $fullHtml .= "
\n"; } if ($EditPagePos >= 2) { $fullHtml .= &GetEditGuide($id, $goodRevision); # luke added } $fullHtml .= &WikiToHTML($Text{'text'}); # $fullHtml .= "
\n" if (!&GetParam('embed', $EmbedWiki)); if (($id eq $RCName) || (T($RCName) eq $id) || (T($id) eq $RCName)) { if (&GetParam("sincelastvisit", 0)) { my $cookie1 = $q->cookie( -name => $CookieName . "-RC", -value => time(), -expires => '+60d'); print "Set-Cookie: $cookie1\r\n"; } print $fullHtml; &DoRc(); # print "\n" if (!&GetParam('embed', $EmbedWiki)); print &GetFooterText($id, $goodRevision); return; } $fullHtml .= &GetFooterText($id, $goodRevision); print $fullHtml; return if ($showDiff || ($revision ne '')); # Don't cache special version ############### ### replaced by gypark ### redirect ·Î ¿Å°Ü°¡´Â °æ¿ì¿¡´Â cache »ý¼ºÀ» ÇÏÁö ¾Ê°Ô ÇÔ # &UpdateHtmlCache($id, $fullHtml) if $UseCache; &UpdateHtmlCache($id, $fullHtml) if ($UseCache && ($oldId eq '')); ### ############### } sub ReBrowsePage { my ($id, $oldId, $isEdit) = @_; if ($oldId ne "") { # Target of #REDIRECT (loop breaking) print &GetRedirectPage("action=browse&id=$id&oldid=$oldId", $id, $isEdit); } else { print &GetRedirectPage($id, $id, $isEdit); } } ############### ### added by gypark ### #EXTERN sub BrowseExternUrl { my ($id, $oldId, $url) = @_; my $sizeBottomFrame = $SizeBottomFrame * $EditGuideInExtern; if (&GetParam('InFrame','') eq '1') { print &GetHeader($id, "$id [InTopFrame]",$oldId); print &GetMinimumFooter(); return; } elsif ((&GetParam('InFrame','') eq '2') && ($EditGuideInExtern)) { print &GetHeader($id, "$id [InBottomFrame]",$oldId); print "
\n"; print &GetEditGuide($id, ''); print &GetMinimumFooter(); return; } else { print &GetHttpHeader(); print "\n"; print "\n"; print "$SiteName: $id\n"; print "\n"; print " \n"; print " \n"; print " \n" if ($EditGuideInExtern); print " \n"; print " <body>\n"; print " <p>".T('You need the web browser which supports frame tag.')."\n"; print " </body>\n"; print " \n"; print "\n"; print "\n"; return; } } ### ############### sub DoRc { my ($fileData, $rcline, $i, $daysago, $lastTs, $ts, $idOnly); my (@fullrc, $status, $oldFileData, $firstTs, $errorText); my $starttime = 0; my $showbar = 0; if (&GetParam("sincelastvisit", 0)) { $starttime = $q->cookie($CookieName ."-RC"); } elsif (&GetParam("from", 0)) { $starttime = &GetParam("from", 0); print "

" . Ts('Updates since %s', &TimeToText($starttime)) . "

\n"; } else { $daysago = &GetParam("days", 0); $daysago = &GetParam("rcdays", 0) if ($daysago == 0); if ($daysago) { $starttime = $Now - ((24*60*60)*$daysago); print "

" . Ts('Updates in the last %s day' . (($daysago != 1)?"s":""), $daysago) . "

\n"; # Note: must have two translations (for "day" and "days") # Following comment line is for translation helper script # Ts('Updates in the last %s days', ''); } } if ($starttime == 0) { $starttime = $Now - ((24*60*60)*$RcDefault); print "

" . Ts('Updates in the last %s day' . (($RcDefault != 1)?"s":""), $RcDefault) . "

\n"; # Translation of above line is identical to previous version } # Read rclog data (and oldrclog data if needed) ($status, $fileData) = &ReadFile($RcFile); $errorText = ""; if (!$status) { # Save error text if needed. $errorText = '

' . Ts('Could not open %s log file', $RCName) . ": $RcFile

" . T('Error was') . ":\n

$!
\n" . '

' . T('Note: This error is normal if no changes have been made.') . "\n"; } @fullrc = split(/\n/, $fileData); $firstTs = 0; if (@fullrc > 0) { # Only false if no lines in file ($firstTs) = split(/$FS3/, $fullrc[0]); } if (($firstTs == 0) || ($starttime <= $firstTs)) { ($status, $oldFileData) = &ReadFile($RcOldFile); if ($status) { @fullrc = split(/\n/, $oldFileData . $fileData); } else { if ($errorText ne "") { # could not open either rclog file print $errorText; print "

" . Ts('Could not open old %s log file', $RCName) . ": $RcOldFile

" . T('Error was') . ":\n

$!
\n"; return; } } } $lastTs = 0; if (@fullrc > 0) { # Only false if no lines in file ($lastTs) = split(/$FS3/, $fullrc[$#fullrc]); } $lastTs++ if (($Now - $lastTs) > 5); # Skip last unless very recent $idOnly = &GetParam("rcidonly", ""); if ($idOnly ne "") { print '(' . Ts('for %s only', &ScriptLink($idOnly, $idOnly)) . ')
'; } foreach $i (@RcDays) { print " | " if $showbar; $showbar = 1; print &ScriptLink("action=rc&days=$i", 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', ''); } ############### ### replaced by gypark ### ÃÖ±Ùº¯°æ³»¿ª¿¡ ºÏ¸¶Å© ±â´É µµÀÔ # print "
" . &ScriptLink("action=rc&from=$lastTs", # T('List new changes starting from')); # print " " . &TimeToText($lastTs) . "
\n"; if (&GetParam("username") eq "") { print "
" . &ScriptLink("action=rc&from=$lastTs", T('List new changes starting from')); print " " . &TimeToText($lastTs) . "
\n"; } else { my $bookmark = &GetParam('bookmark',-1); print "
" . &ScriptLink("action=bookmark&time=$Now", T('Update my bookmark timestamp')); print " (". Ts('currently set to %s', &TimeToText($bookmark)). ")
\n"; } ### ############### # Later consider a binary search? $i = 0; while ($i < @fullrc) { # Optimization: skip old entries quickly ($ts) = split(/$FS3/, $fullrc[$i]); if ($ts >= $starttime) { $i -= 1000 if ($i > 0); last; } $i += 1000; } $i -= 1000 if (($i > 0) && ($i >= @fullrc)); for (; $i < @fullrc ; $i++) { ($ts) = split(/$FS3/, $fullrc[$i]); last if ($ts >= $starttime); } if ($i == @fullrc) { print '
' . Ts('No updates since %s', &TimeToText($starttime)) . "
\n"; } else { splice(@fullrc, 0, $i); # Remove items before index $i # Later consider an end-time limit (items older than X) print &GetRcHtml(@fullrc); } print '

' . Ts('Page generated %s', &TimeToText($Now)), "
\n"; } sub GetRcHtml { my @outrc = @_; my ($rcline, $html, $date, $sum, $edit, $count, $newtop, $author); my ($showedit, $inlist, $link, $all, $idOnly); ############### ### replaced by gypark ### RcOldFile ¹ö±× ¼öÁ¤ # my ($ts, $oldts, $pagename, $summary, $isEdit, $host, $kind, $extraTemp); my ($ts, $pagename, $summary, $isEdit, $host, $kind, $extraTemp); ### ############### my ($tEdit, $tChanges, $tDiff); my %extra = (); my %changetime = (); my %pagecount = (); $tEdit = T('(edit)'); # Optimize translations out of main loop $tDiff = T('(diff)'); $tChanges = T('changes'); $showedit = &GetParam("rcshowedit", $ShowEdits); $showedit = &GetParam("showedit", $showedit); ############### ### added by gypark ### ÃÖ±Ùº¯°æ³»¿ª¿¡ ºÏ¸¶Å© ±â´É µµÀÔ my $bookmark; my $bookmarkuser = &GetParam('username', ""); my ($rcnew, $rcupdated, $rcdiff, $rcdeleted, $rcinterest) = ( "", "", "", "", ### °ü½É ÆäÀÌÁö "".T(", ); $bookmark = &GetParam('bookmark',-1); ### ############### if ($showedit != 1) { my @temprc = (); foreach $rcline (@outrc) { ($ts, $pagename, $summary, $isEdit, $host) = split(/$FS3/, $rcline); if ($showedit == 0) { # 0 = No edits push(@temprc, $rcline) if (!$isEdit); } else { # 2 = Only edits push(@temprc, $rcline) if ($isEdit); } } @outrc = @temprc; } # Later consider folding into loop above? # Later add lines to assoc. pagename array (for new RC display) foreach $rcline (@outrc) { ($ts, $pagename) = split(/$FS3/, $rcline); ############### ### replaced by gypark ### ÃÖ±Ùº¯°æ³»¿ª¿¡ ºÏ¸¶Å© ±â´É µµÀÔ # $pagecount{$pagename}++; $pagecount{$pagename}++ if ($ts > $bookmark); ### ############### $changetime{$pagename} = $ts; } $date = ""; $inlist = 0; ############### ### replaced by gypark ### ÃÖ±Ù º¯°æ ³»¿ªÀ» Å×À̺í·Î Ãâ·Â ### from Jof4002's patch # $html = ""; $html = ""; ### ############### $all = &GetParam("rcall", 0); $all = &GetParam("all", $all); $newtop = &GetParam("rcnewtop", $RecentTop); $newtop = &GetParam("newtop", $newtop); $idOnly = &GetParam("rcidonly", ""); @outrc = reverse @outrc if ($newtop); ############### ### commented by gypark ### RcOldFile ¹ö±× ¼öÁ¤ # ($oldts, $pagename, $summary, $isEdit, $host, $kind, $extraTemp) # = split(/$FS3/, $outrc[0]); # $oldts += 1; ### ############### foreach $rcline (@outrc) { ($ts, $pagename, $summary, $isEdit, $host, $kind, $extraTemp) = split(/$FS3/, $rcline); # Later: need to change $all for new-RC? next if ((!$all) && ($ts < $changetime{$pagename})); next if (($idOnly ne "") && ($idOnly ne $pagename)); ############### ### added by gypark ### hide page next if (&PageIsHidden($pagename)); ### ############### ############### ### commented by gypark ### RcOldFile ¹ö±× ¼öÁ¤ # next if ($ts >= $oldts); # $oldts = $ts; ### ############### # print $ts . " " . $pagename . "
\n"; %extra = split(/$FS2/, $extraTemp, -1); if ($date ne &CalcDay($ts)) { $date = &CalcDay($ts); if ($inlist) { ############### ### commented by gypark ### ÃÖ±Ù º¯°æ ³»¿ªÀ» Å×À̺í·Î Ãâ·Â ### from Jof4002's patch # $html .= "\n"; ### ############### $inlist = 0; } ############### ### replaced by gypark ### ÃÖ±Ùº¯°æ³»¿ª¿¡ ºÏ¸¶Å© ±â´É µµÀÔ ### ÃÖ±Ù º¯°æ ³»¿ªÀ» Å×À̺í·Î Ãâ·Â ÆÐÄ¡µµ °°ÀÌ Àû¿ë # $html .= "

" . $date . "

\n"; $html .= "

". "". "\n"; } else { $html .= " [" .&ScriptLink("action=bookmark&time=$ts",T('set bookmark')) ."]" . "\n"; } ### ############### } if (!$inlist) { ############### ### commented by gypark ### ÃÖ±Ù º¯°æ ³»¿ªÀ» Å×À̺í·Î Ãâ·Â ### from Jof4002's patch # $html .= "
    \n"; ### ############### $inlist = 1; } $host = &QuoteHtml($host); if (defined($extra{'name'}) && defined($extra{'id'})) { $author = &GetAuthorLink($host, $extra{'name'}, $extra{'id'}); } else { $author = &GetAuthorLink($host, "", 0); } $sum = ""; if (($summary ne "") && ($summary ne "*")) { $summary = &QuoteHtml($summary); ############### ### replaced by gypark ### ÃÖ±Ù º¯°æ ³»¿ªÀ» Å×À̺í·Î Ãâ·Â # $sum = "[$summary] "; $sum = "[$summary]"; ### ############### } $edit = ""; $edit = "$tEdit " if ($isEdit); $count = ""; if ((!$all) && ($pagecount{$pagename} > 1)) { $count = "($pagecount{$pagename} "; if (&GetParam("rcchangehist", 1)) { $count .= &GetHistoryLink($pagename, $tChanges); } else { $count .= $tChanges; } $count .= ") "; } $link = ""; if ($UseDiff && &GetParam("diffrclink", 1)) { ############### ### replaced by gypark ### ÃÖ±Ùº¯°æ³»¿ª¿¡ ºÏ¸¶Å© ±â´É µµÀÔ # $link .= &ScriptLinkDiff(4, $pagename, $tDiff, "") . " "; if (!(-f &GetPageFile($pagename))) { $link .= &GetHistoryLink($pagename, $rcdeleted); } elsif (($bookmarkuser eq "") || ($ts <= $bookmark)) { $link .= &ScriptLinkDiff(4, $pagename, $rcdiff, "") . " "; } elsif ($extra{'tscreate'} > $bookmark) { $link .= $rcnew . " "; } else { $link .= &ScriptLinkDiffRevision(5, $pagename, "", $rcupdated) . " "; } ### ############### } ############### ### replaced by gypark ### ÃÖ±Ù º¯°æ ³»¿ªÀ» Å×À̺í·Î Ãâ·Â ### from Jof4002's patch # $link .= &GetPageLink($pagename); # $html .= "
  • $link "; # # Later do new-RC looping here. # $html .= &CalcTime($ts) . " $count$edit" . " $sum"; # $html .= ". . . . . $author\n"; # Make dots optional? # } # $html .= "
\n" if ($inlist); $html .= "" . "" . "" . "" . "" . "" . "\n"; if ($sum ne "") { $html .= "" . "\n"; } } $html .= "
 
" . $date . ""; if ($bookmarkuser eq "") { $html .= "
" ### °ü½É ÆäÀÌÁö . ((defined ($UserInterest{$pagename}))?"$rcinterest":"  ") . "$link " . &GetPageOrEditLink($pagename) . "" . &CalcTime($ts) . "$count$edit$author
  $sum
"; ### ############### return $html; } sub DoRandom { my ($id, @pageList); @pageList = &AllPagesList(); # Optimize? $id = $pageList[int(rand($#pageList + 1))]; &ReBrowsePage($id, "", 0); } sub DoHistory { my ($id) = @_; my ($html, $canEdit, $row, $newText); ############### ### added by gypark ### hide page if (&PageIsHidden($id)) { print &GetHeader("",&QuoteHtml(Ts('History of %s', $id)), ""); print Ts('%s is a hidden page', $id); print &GetCommonFooter(); return; } ### ############### print &GetHeader("",&QuoteHtml(Ts('History of %s', $id)), "") . "
"; &OpenPage($id); &OpenDefaultText(); $canEdit = &UserCanEdit($id); $canEdit = 0; # Turn off direct "Edit" links if ( $UseDiff ) { print < FORMEOF } $html = &GetHistoryLine($id, $Page{'text_default'}, $canEdit, $row++); &OpenKeptRevisions('text_default'); foreach (reverse sort {$a <=> $b} keys %KeptRevisions) { next if ($_ eq ""); # (needed?) $html .= &GetHistoryLine($id, $KeptRevisions{$_}, $canEdit, $row++); } print $html; if( $UseDiff ) { my $label = T('Compare'); print "
 
\n"; print "


\n"; print &GetDiffHTML( &GetParam('defaultdiff',1), $id, '', '', $newText ); } print &GetCommonFooter(); } sub GetHistoryLine { my ($id, $section, $canEdit, $row) = @_; my ($html, $expirets, $rev, $summary, $host, $user, $uid, $ts, $minor); my (%sect, %revtext); %sect = split(/$FS2/, $section, -1); %revtext = split(/$FS3/, $sect{'data'}); $rev = $sect{'revision'}; $summary = $revtext{'summary'}; if ((defined($sect{'host'})) && ($sect{'host'} ne '')) { $host = $sect{'host'}; } else { $host = $sect{'ip'}; $host =~ s/\d+$/xxx/; # Be somewhat anonymous (if no host) } $user = $sect{'username'}; $uid = $sect{'id'}; $ts = $sect{'ts'}; $minor = ''; $minor = '' . T('(edit)') . ' ' if ($revtext{'minor'}); $expirets = $Now - ($KeepDays * 24 * 60 * 60); if ($UseDiff) { my ($c1, $c2); $c1 = 'checked="checked"' if 1 == $row; $c2 = 'checked="checked"' if 0 == $row; $html .= " "; $html .= ""; } if (0 == $row) { # current revision ############### ### replaced by gypark ### History È­¸é¿¡¼­, Á¦ÀÏ ¸¶Áö¸· revision Àº revision ¹øÈ£ ´ë½Å ### "ÇöÀç ¹öÀü" À̶ó°í ³ª¿À°Ô ÇÔ # $html .= &GetPageLinkText($id, Ts('Revision %s', $rev)) . ' '; $html .= &GetPageLinkText($id, Ts('Current Revision', $rev)) . ' '; ### ############### if ($canEdit) { $html .= &GetEditLink($id, T('Edit')) . ' '; } } else { $html .= &GetOldPageLink('browse', $id, $rev, Ts('Revision %s', $rev)) . ' '; if ($canEdit) { $html .= &GetOldPageLink('edit', $id, $rev, T('Edit')) . ' '; } } $html .= ". . . . " . $minor . &TimeToText($ts) . " "; $html .= T('by') . ' ' . &GetAuthorLink($host, $user, $uid) . " "; if (defined($summary) && ($summary ne "") && ($summary ne "*")) { $summary = &QuoteHtml($summary); # Thanks Sunir! :-) $html .= "[$summary] "; } $html .= $UseDiff ? "\n" : "
\n"; return $html; } # ==== HTML and page-oriented functions ==== sub ScriptLink { my ($action, $text) = @_; return "$text"; } # luke added sub HelpLink { my ($id, $text) = @_; my $url = "$ScriptName?action=help&index=$id"; return "$text"; } # end sub GetPageLink { my ($id) = @_; my $name = $id; $id =~ s|^/|$MainPage/|; if ($FreeLinks) { $id = &FreeToNormal($id); $name =~ s/_/ /g; } return &ScriptLink($id, $name); } sub GetPageLinkText { my ($id, $name) = @_; $id =~ s|^/|$MainPage/|; if ($FreeLinks) { $id = &FreeToNormal($id); $name =~ s/_/ /g; } return &ScriptLink($id, $name); } sub GetEditLink { my ($id, $name) = @_; if ($FreeLinks) { $id = &FreeToNormal($id); $name =~ s/_/ /g; } return &ScriptLink("action=edit&id=$id", $name); } sub GetOldPageLink { my ($kind, $id, $revision, $name) = @_; if ($FreeLinks) { $id = &FreeToNormal($id); $name =~ s/_/ /g; } return &ScriptLink("action=$kind&id=$id&revision=$revision", $name); } sub GetPageOrEditAnchoredLink { my ($id, $anchor, $name) = @_; my (@temp, $exists); if ($name eq "") { $name = $id; if ($FreeLinks) { $name =~ s/_/ /g; } } $id =~ s|^/|$MainPage/|; if ($FreeLinks) { $id = &FreeToNormal($id); } $exists = 0; if ($UseIndex) { if (!$IndexInit) { @temp = &AllPagesList(); # Also initializes hash } $exists = 1 if ($IndexHash{$id}); } elsif (-f &GetPageFile($id)) { # Page file exists $exists = 1; } if ($exists) { $id = "$id#$anchor" if $anchor; $name = "$name#$anchor" if $anchor && $NamedAnchors != 2; return &GetPageLinkText($id, $name); } if ($FreeLinks) { if ($name =~ m| |) { # Not a single word $name = "[$name]"; # Add brackets so boundaries are obvious } } ############### ### replaced by gypark ### Á¸ÀçÇÏÁö ¾Ê´Â ÆäÀÌÁö¿¡ ´ëÇÑ ¸µÅ© Ãâ·Â Çü½Ä º¯°æ # return $name . &GetEditLink($id,"?"); if ((&GetParam('linkstyle', $LinkFirstChar)) && ($name =~ /(\[)?([^\/]*\/)?([a-zA-Z0-9\/]|[\x80-\xff][\x80-\xff])([^\]]*)(\])?/)) { return $2 . &GetEditLink($id,"$3") . $4; } else { return $name . &GetEditLink($id,"?"); } ### ############### } sub GetPageOrEditLink { my ($id, $name) = @_; return &GetPageOrEditAnchoredLink( $id, "", $name ); } sub GetSearchLink { my ($id) = @_; my $name = $id; $id =~ s|.+/|/|; # Subpage match: search for just /SubName if ($FreeLinks) { $name =~ s/_/ /g; # Display with spaces $id =~ s/_/+/g; # Search for url-escaped spaces } return &ScriptLink("search=$id", $name); } ############### ### added by gypark ### ¿ª¸µÅ© Ãß°¡ sub GetReverseLink { my ($id) = @_; my $name = $id; if ($FreeLinks) { $name =~ s/_/ /g; # Display with spaces } return &ScriptLink("reverse=$id", $name); } ### ############### sub GetPrefsLink { return &ScriptLink("action=editprefs", T('Preferences')); } sub GetRandomLink { return &ScriptLink("action=random", T('Random Page')); } sub ScriptLinkDiff { my ($diff, $id, $text, $rev) = @_; $rev = "&revision=$rev" if ($rev ne ""); $diff = &GetParam("defaultdiff", 1) if ($diff == 4); return &ScriptLink("action=browse&diff=$diff&id=$id$rev", $text); } sub ScriptLinkDiffRevision { my ($diff, $id, $rev, $text) = @_; $rev = "&diffrevision=$rev" if ($rev ne ""); $diff = &GetParam("defaultdiff", 1) if ($diff == 4); return &ScriptLink("action=browse&diff=$diff&id=$id$rev", $text); } sub ScriptLinkTitle { my ($action, $text, $title) = @_; if ($FreeLinks) { $action =~ s/ /_/g; } return "$text"; } sub GetAuthorLink { my ($host, $userName, $uid) = @_; my ($html, $title, $userNameShow); $userNameShow = $userName; if ($FreeLinks) { $userName =~ s/ /_/g; $userNameShow =~ s/_/ /g; } if (&ValidId($userName) ne "") { # Invalid under current rules $userName = ""; # Just pretend it isn't there. } # Later have user preference for link titles and/or host text? if (($uid ne "") && ($userName ne "")) { $html = &ScriptLinkTitle($userName, $userNameShow, Ts('ID %s', $uid) . ' ' . Ts('from %s', $host)); } else { $html = $host; } return $html; } sub GetHistoryLink { my ($id, $text) = @_; if ($FreeLinks) { $id =~ s/ /_/g; } return &ScriptLink("action=history&id=$id", $text); } sub GetHeader { my ($id, $title, $oldId) = @_; my $header = ""; my $logoImage = ""; my $result = ""; my $embed = &GetParam('embed', $EmbedWiki); my $altText = T('[Home]'); $result = &GetHttpHeader(); if ($FreeLinks) { $title =~ s/_/ /g; # Display as spaces } $result .= &GetHtmlHeader("$SiteName: $title", $title); return $result if ($embed); ############### ### added by gypark ### #EXTERN return $result if (&GetParam('InFrame','') eq '2'); ### ############### ############### ### replaced by gypark ### #EXTERN # if ($oldId ne '') { # $result .= $q->h3('(' . Ts('redirected from %s', # &GetEditLink($oldId, $oldId)) . ')'); # } my $topMsg = ""; if ($oldId ne '') { $topMsg .= '('.Ts('redirected from %s',&GetEditLink($oldId, $oldId)).') '; } if (&GetParam('InFrame','') eq '1') { $topMsg .= '('.Ts('%s includes external page',&GetEditLink($id,$id)).')'; } $result .= $q->h3($topMsg) if (($oldId ne '') || (&GetParam('InFrame','') eq '1')); ### ############### if ((!$embed) && ($LogoUrl ne "")) { $logoImage = "IMG class='logoimage' src=\"$LogoUrl\" alt=\"$altText\" border=0"; if (!$LogoLeft) { $logoImage .= " align=\"right\""; } ############### ### replaced by gypark ### ·Î°í À̹ÌÁö¿¡ ´ÜÃàŰ alt+w ÁöÁ¤ # $header = &ScriptLink($HomePage, "<$logoImage>"); $header = "<$logoImage>"; ### ############### } if ($id ne '') { ############### ### replaced by gypark ### »çÀÌÆ® ·Î°í°¡, action ÀÌ µé¾î°¡´Â ÆäÀÌÁö¿¡¼­¸¸ Ç¥½ÃµÇ´Â ¹®Á¦¸¦ ÇØ°á ### from http://host9.swidc.com/~ncc1701/wiki/wiki.cgi?FAQ # $result .= $q->h1(&GetSearchLink($id)); ### ¿ª¸µÅ© °³¼± # $result .= $q->h1($header . &GetSearchLink($id)); $result .= $q->h1({-class=>"pagename"}, $header . &GetReverseLink($id)); ### ############### } else { $result .= $q->h1({-class=>"actionname"}, $header . $title); } ############### ### added by gypark ### page óÀ½¿¡ bottom À¸·Î °¡´Â ¸µÅ©¸¦ Ãß°¡ ### #EXTERN if (&GetParam('InFrame','') eq '') { $result .= "\n\n"; } ### ############### if (&GetParam("toplinkbar", 1)) { # Later consider smaller size? $result .= &GetGotoBar($id); } return $result; } sub GetHttpHeader { my $cookie; my $t; $t = gmtime; if (defined($SetCookie{'id'})) { ############### ### replaced by gypark ### ·Î±äÇÒ ¶§ ÀÚµ¿ ·Î±×ÀÎ ¿©ºÎ ¼±Åà ### from Bab2's patch # $cookie = "$CookieName=" # . "rev&" . $SetCookie{'rev'} # . "&id&" . $SetCookie{'id'} # . "&randkey&" . $SetCookie{'randkey'}; # $cookie .= ";expires=Fri, 08-Sep-2010 19:48:23 GMT"; $cookie = "$CookieName=" . "expire&" . $SetCookie{'expire'} . "&rev&" . $SetCookie{'rev'} . "&id&" . $SetCookie{'id'} . "&randkey&" . $SetCookie{'randkey'} . ";"; if ($SetCookie{'expire'} eq "1") { $cookie .= "expires=Fri, 08-Sep-2010 19:47:23 GMT"; } ### ############### if ($HttpCharset ne '') { return $q->header(-cookie=>$cookie, -pragma=>"no-cache", -cache_control=>"no-cache", -last_modified=>"$t", -expires=>"+10s", -type=>"text/html; charset=$HttpCharset"); } return $q->header(-cookie=>$cookie); } if ($HttpCharset ne '') { return $q->header(-type=>"text/html; charset=$HttpCharset", -pragma=>"no-cache", -cache_control=>"no-cache", -last_modified=>"$t", -expires=>"+10s"); } return $q->header(); } sub GetHtmlHeader { my ($title, $id) = @_; my ($dtd, $bgcolor, $html, $bodyExtra); $html = ''; $dtd = '-//IETF//DTD HTML//EN'; $bgcolor = 'white'; # Later make an option $html = qq(\n); $title = $q->escapeHTML($title); $html .= "$title\n"; if ($SiteBase ne "") { $html .= qq(\n); } if ($StyleSheet ne '') { $html .= qq(\n); } # Insert other header stuff here (like inline style sheets?) ############### ### added by gypark ### Çì´õ Ãâ·Â °³¼± $html .= qq(\n); $html .= qq(\n); ### ############### $bodyExtra = ''; if ($bgcolor ne '') { $bodyExtra = qq(BGCOLOR="$bgcolor" ); } ############### ### replaced by gypark ### #EXTERN # added luke # if ($ClickEdit) { # if ($FreeLinks) { # $id = &FreeToNormal($id); # } # $bodyExtra .= qq(ondblclick="location.href='$ScriptName?action=edit&id=$id'"); # } # end if (&GetParam('InFrame','') ne '') { $html .= qq(\n); } else { if ($ClickEdit) { if ($FreeLinks) { $id = &FreeToNormal($id); } $bodyExtra .= qq(ondblclick="location.href='$ScriptName?action=edit&id=$id'"); } } ### ############### # Insert any other body stuff (like scripts) into $bodyExtra here # (remember to add a space at the beginning to separate from prior text) $html .= "\n\n"; return $html; } sub GetEditGuide { my ($id, $rev) = @_; my $result = "\n\n
"; # print "\n" if (!&GetParam('embed', $EmbedWiki)); ############### ### added by gypark ### °ü¸®ÀÚ°¡ ÆäÀÌÁö¸¦ º¼ ¶§´Â ÇÏ´Ü¿¡ ¼öÁ¤ ±ÝÁö ¿©ºÎ¸¦ ¾Ë·ÁÁÖ°í ±ÝÁö ¼³Á¤/ÇØÁ¦¸¦ ÇÒ ¼ö ÀÖ°Ô ÇÔ if (&UserIsAdmin()) { if (-f &GetLockedPageFile($id)) { $result .= T('(locked)') . " | "; } $result .= &ScriptLink("action=pagelock&set=1&id=" . $id, T('lock')); $result .= " | " . &ScriptLink("action=pagelock&set=0&id=" . $id, T('unlock')); ### hide page by gypark $result .= " | "; if (defined($HiddenPage{$id})) { $result .= T('(hidden)') . " | "; } $result .= &ScriptLink("action=pagehide&set=1&id=" . $id, T('hide')); $result .= " | " . &ScriptLink("action=pagehide&set=0&id=". $id, T('unhide')); } ### ############### ############### ### replaced by gypark ### ÆäÀÌÁö ÇÏ´Ü¿¡ Ãâ·ÂµÇ´Â ¼ø¼­¸¦ ¹Ù²Þ # if (&UserCanEdit($id, 0)) { # if ($rev ne '') { # $result .= &GetOldPageLink('edit', $id, $rev, # Ts('Edit revision %s of this page', $rev)); # } else { # $result .= &GetEditLink($id, T('Edit text of this page')); # } # } else { # $result .= T('This page is read-only'); # } # $result .= ' | '; # $result .= &GetHistoryLink($id, T('History')); # if ($rev ne '') { # $result .= ' | '; # $result .= &GetPageLinkText($id, T('View current revision')); # } # if ($Section{'revision'} > 0) { # $result .= '
'; # if ($rev eq '') { # Only for most current rev # $result .= T('Last edited'); # } else { # $result .= T('Edited'); # } # $result .= ' ' . &TimeToText($Section{ts}); # } # if ($UseDiff) { # $result .= ' ' . &ScriptLinkDiff(4, $id, T('(diff)'), $rev); # } # # $result .= "
"; ############### ### replaced by gypark ### ¸ÅÅ©·Î°¡ µé¾î°£ ÆäÀÌÁöÀÇ ÆíÁý°¡ÀÌµå ¹®Á¦ ÇØ°á # if ($Section{'revision'} > 0) { if ($Sec_Revision > 0) { ### ############### $result .= '
'; if ($rev eq '') { # Only for most current rev $result .= T('Last edited'); } else { $result .= T('Edited'); } ############### ### replaced by gypark ### ¸ÅÅ©·Î°¡ µé¾î°£ ÆäÀÌÁöÀÇ ÆíÁý°¡ÀÌµå ¹®Á¦ ÇØ°á # $result .= ' ' . &TimeToText($Section{ts}); $result .= ' ' . &TimeToText($Sec_Ts); ### ############### } if ($UseDiff) { $result .= ' ' . &ScriptLinkDiff(4, $id, T('(diff)'), $rev); } $result .= '
'; ############### ### added by gypark ### page count $result .= Ts('%s hit' . (($ViewCount > 1)?'s':'') , $ViewCount)." | " if ($ViewCount ne ""); ### ############### ############### ### added by gypark ### °ü½É ÆäÀÌÁö if (&GetParam('username') ne "") { if (defined($UserInterest{$id})) { $result .= &ScriptLink("action=interest&mode=remove&id=$id", T('Remove from interest list')); } else { $result .= &ScriptLink("action=interest&mode=add&id=$id", T('Add to my interest list')); } $result .= " | "; } ### ############### $result .= &GetHistoryLink($id, T('History')); if ($rev ne '') { $result .= ' | '; $result .= &GetPageLinkText($id, T('View current revision')); } $result .= ' | '; if (&UserCanEdit($id, 0)) { if ($rev ne '') { $result .= &GetOldPageLink('edit', $id, $rev, Ts('Edit revision %s of this page', $rev)); } else { $result .= &GetEditLink($id, T('Edit text of this page')); } } else { ############### ### replaced by gypark ### view action Ãß°¡ # $result .= T('This page is read-only'); if ($rev ne '') { $result .= &GetOldPageLink('edit', $id, $rev, Ts('View revision %s of this page', $rev)); } else { $result .= &GetEditLink($id, T('View text of this page')); } ### ############### } $result .= ""; ### ############### return $result; } sub GetFooterText { my ($id, $rev) = @_; my $result = ''; if (&GetParam('embed', $EmbedWiki)) { return $q->end_html; } if ($EditPagePos eq 1 or $EditPagePos eq 3) { $result .= &GetEditGuide($id, $rev); } if ($DataDir =~ m|/tmp/|) { $result .= '
' . T('Warning') . ': ' . Ts('Database is stored in temporary directory %s', $DataDir) . '
'; } $result .= ""; $result .= &GetMinimumFooter(); return $result; } sub GetCommonFooter { return "" . &GetMinimumFooter(); } sub GetMinimumFooter { ############### ### replaced by gypark ### page ¸¶Áö¸·¿¡ top À¸·Î °¡´Â ¸µÅ©¸¦ Ãß°¡ # if ($FooterNote ne '') { # return T($FooterNote) . $q->end_html; # Allow local translations # } # return $q->end_html; ### #EXTERN if (&GetParam('InFrame','') ne '') { return $q->end_html; } ### my $result = ''; if ($FooterNote ne '') { $result .= T($FooterNote); # Allow local translations } ### ó¸® ½Ã°£ ÃøÁ¤ $result .= "\n\n" . $q->end_html; ### return $result; ### ############### } sub GetFormStart { #return $q->startform("POST", "$ScriptName", ""); ############### ### replaced by gypark ### form ¿¡ À̸§À» ³ÖÀ» ¼ö ÀÖµµ·Ï ÇÔ # return $q->startform("POST", "$ScriptName", "application/x-www-form-urlencoded"); my ($name) = @_; if ($name eq '') { return $q->startform("POST", "$ScriptName", "application/x-www-form-urlencoded"); } else { return $q->startform(-method=>"POST", -action=>"$ScriptName", -enctype=>"application/x-www-form-urlencoded" ,-name=>"$name") ; } ### ############### } sub GetGotoBar { my ($id) = @_; my ($main, $bartext); $bartext = "\n"; $bartext .= &GetFormStart(); $bartext .= "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"; $bartext .= $q->endform; $bartext .= "
"; $bartext .= &GetPageLink($HomePage); $bartext .= "" . &ScriptLink("action=index", T('Index')); $bartext .= " " . &GetPageLink(T($RCName)); if ($id =~ m|/|) { $main = $id; $main =~ s|/.*||; # Only the main page name (remove subpage) ############### ### replaceed by gypark ### subpage ÀÇ °æ¿ì, »óÀ§ÆäÀÌÁö À̸§ ¾Õ¿¡ ¾ÆÀÌÄÜ Ç¥½Ã # $bartext .= " " . &GetPageLink($main); $bartext .= " \""" . &GetPageLink($main); ### ############### } ############### ### added by gypark ### »ó´Ü ¸Þ´º ¹Ù¿¡ »ç¿ëÀÚ Á¤ÀÇ Ç׸ñÀ» Ãß°¡ ### UserGotoBar2~4 ¶ó´Â À̸§À¸·Î ÁöÁ¤ÇØÁÖ¸é µÈ´Ù if ($UserGotoBar2 ne '') { $bartext .= " " . $UserGotoBar2; } if ($UserGotoBar3 ne '') { $bartext .= " " . $UserGotoBar3; } if ($UserGotoBar4 ne '') { $bartext .= " " . $UserGotoBar4; } ### ############### $bartext .= " " . &GetPrefsLink(); if (&GetParam("linkrandom", 0)) { $bartext .= " " . &GetRandomLink(); } if (&UserIsAdmin()) { $bartext .= " " . &ScriptLink("action=editlinks", T('Admin')); } $bartext .= " " . &ScriptLink("action=login", T('Login')); } else { $bartext .= " " . &ScriptLink("action=logout", T('Logout')); } $bartext .= " " . &GetSearchForm(); if ($UserGotoBar ne '') { $bartext .= " " . $UserGotoBar; } $bartext .= "

\n"; return $bartext; } sub GetSearchForm { my ($result); ############### ### repalced by gypark ### »ó´Ü¸Þ´º¿¡ "Search:" µµ ¹ø¿ªÀ» ½ÃÅ´ ### ´ÜÃàŰ alt-s ÁöÁ¤ # $result = "Search: " # . $q->textfield(-name=>'search', -size=>12) # . &GetHiddenValue("dosearch", 1); $result = T('Search:') . " " . &GetHiddenValue("dosearch", 1); ### ############### return $result; } sub GetRedirectPage { my ($newid, $name, $isEdit) = @_; my ($url, $html); my ($nameLink); # Normally get URL from script, but allow override. $FullUrl = $q->url(-full=>1) if ($FullUrl eq ""); $url = $FullUrl . "?" . $newid; $nameLink = "$name"; if ($RedirType < 3) { if ($RedirType == 1) { # Use CGI.pm # NOTE: do NOT use -method (does not work with old CGI.pm versions) # Thanks to Daniel Neri for fixing this problem. $html = $q->redirect(-uri=>$url); } else { # Minimal header $html = "Status: 302 Moved\n"; $html .= "Location: $url\n"; $html .= "Content-Type: text/html\n"; # Needed for browser failure $html .= "\n"; } $html .= "\n" . Ts('Your browser should go to the %s page.', $newid); $html .= ' ' . Ts('If it does not, click %s to continue.', $nameLink); } else { if ($isEdit) { $html = &GetHeader('', T('Thanks for editing...'), ''); $html .= Ts('Thank you for editing %s.', $nameLink); } else { $html = &GetHeader('', T('Link to another page...'), ''); } $html .= "\n

"; $html .= Ts('Follow the %s link to continue.', $nameLink); $html .= &GetMinimumFooter(); } return $html; } # ==== Common wiki markup ==== sub WikiToHTML { my ($pageText) = @_; $TableMode = 0; %SaveUrl = (); %SaveNumUrl = (); $SaveUrlIndex = 0; $SaveNumUrlIndex = 0; $pageText =~ s/$FS//g; # Remove separators (paranoia) ############### ### added by gypark ### include ¸ÅÅ©·Î ¾È¿¡¼­ À§Å°Å±׸¦ ÀÛµ¿ÇÏ°Ô ÇÔ ### http://whitejames.x-y.net/cgi-bin/jofcgi/wiki/wiki.pl?ÇÁ·Î±×·¡¹ÖÆÁ/Wiki $pageText = &MacroIncludeSubst($pageText); ### ############### if ($RawHtml) { $pageText =~ s/((.|\n)*?)<\/html>/&StoreRaw($1)/ige; } ############### ### replaced by gypar ### {{{ }}} 󸮸¦ À§ÇØ, º»¹® ¼Ò½º´Â Ưº°ÇÏ°Ô Quote ÇÑ´Ù # $pageText = &QuoteHtml($pageText); $pageText = &QuoteHtmlForPageContent($pageText); ### ############### ############### ### replaced by gypark ### {{{ }}} 󸮸¦ À§Çؼ­, ÁÙ ³¡¿¡ ¿À´Â ¹é½½·¡½¬ µÎ°³¿Í Çϳªµµ ÀÓ½Ãű׸¦ °ÅÃÄ º¯È¯½ÃŲ´Ù # $pageText =~ s/\\\\ *\r?\n/
/g; # double backslash for forced
- comes in handy for

  • # $pageText =~ s/\\ *\r?\n/ /g; # Join lines with backslash at end $pageText =~ s/\\\\ *\r?\n/&__DOUBLEBACKSLASH__;/g; # double backslash for forced
    - comes in handy for
  • $pageText =~ s/\\ *\r?\n/&__SINGLEBACKSLASH__;/g; # Join lines with backslash at end ### ############### ############### ### replaced by gypark ### {{{ }}} 󸮸¦ À§ÇØ ¾Æ·¡ µÎ ¶óÀÎÀÇ ¼ø¼­¸¦ ¹Ù²Þ ### from danny's patch. # $pageText = &WikiLinesToHtml($pageText); # Line-oriented markup # $pageText = &CommonMarkup($pageText, 1, 0); # Multi-line markup # line wraped. luke $pageText = &CommonMarkup($pageText, 1, 0); # Multi-line markup # line wraped. luke $pageText = &WikiLinesToHtml($pageText); # Line-oriented markup ### ############### $pageText =~ s/$FS(\d+)$FS/$SaveUrl{$1}/ge; # Restore saved text $pageText =~ s/$FS(\d+)$FS/$SaveUrl{$1}/ge; # Restore nested saved text while (@HeadingNumbers) { pop @HeadingNumbers; $TableOfContents .= "\n\n"; } $pageText =~ s/&__LT__;toc&__GT__;/$TableOfContents/gi; ############### ### added by gypark ### {{{ }}} 󸮸¦ À§ÇØ Ãß°¡. Àӽà ű׸¦ ¿ø·¡´ë·Î º¹¿ø $pageText =~ s/&__DOUBLEBACKSLASH__;/
    \n/g; $pageText =~ s/&__SINGLEBACKSLASH__;/ /g; $pageText =~ s/&__LT__;/</g; $pageText =~ s/&__GT__;/>/g; $pageText =~ s/&__AMP__;/&/g; $pageText =~ s/$FS_lt/</g; $pageText =~ s/$FS_gt/>/g; ### ############### return &RestoreSavedText($pageText); # return $pageText; } sub CommonMarkup { my ($text, $useImage, $doLines) = @_; local $_ = $text; if ($doLines < 2) { # 2 = do line-oriented only ############### ### added by gypark ### {{{ }}} ó¸® s/(^|\n)\{\{\{[ \t\r\f]*\n((.|\n)*?)\n\}\}\}[ \t\r\f]*\n/&StoreRaw("\n
    ") . &StoreCodeRaw($2) . &StoreRaw("\n<\/PRE>") . "\n"/igem;
    
    ### {{{lang|n|t }}} ó¸®
    		s/(^|\n)\{\{\{([a-zA-Z0-9+]+)(\|(n|\d*|n\d+|\d+n))?[ \t\r\f]*\n((.|\n)*?)\n\}\}\}[ \t\r\f]*\n/&StoreRaw("
    ") . &StoreSyntaxHighlight($2, $4, $5) . &StoreRaw("<\/PRE>") . "\n"/igem;
    ###
    ###############
    
    ###############
    ### added by gypark
    ###  ÅÂ±× - quoting µµ ÇÏÁö ¾Ê´Â´Ù
    		s/\&__LT__;raw\&__GT__;(([^\n])*?)\&__LT__;\/raw\&__GT__;/&StoreCodeRaw($1)/ige;
    ###
    ###############
    
    		# The  tag stores text with no markup (except quoting HTML)
    		s/\&__LT__;nowiki\&__GT__;((.|\n)*?)\&__LT__;\/nowiki\&__GT__;/&StoreRaw($1)/ige;
    		# The 
     tag wraps the stored text with the HTML 
     tag
    		s/\&__LT__;pre\&__GT__;((.|\n)*?)\&__LT__;\/pre\&__GT__;/&StorePre($1, "pre")/ige;
    		s/\&__LT__;code\&__GT__;((.|\n)*?)\&__LT__;\/code\&__GT__;/&StorePre($1, "code")/ige;
    
    		s/\[\#(\w+)\]/&StoreHref(" name=\"$1\"")/ge if $NamedAnchors;
    		if ($HtmlTags) {
    			my ($t);
    			foreach $t (@HtmlPairs) {
    				s/\&__LT__;$t(\s[^<>]+?)?\&__GT__;(.*?)\&__LT__;\/$t\&__GT__;/<$t$1>$2<\/$t>/gis;
    			}
    			foreach $t (@HtmlSingle) {
    				s/\&__LT__;$t(\s[^<>]+?)?\&__GT__;/<$t$1>/gi;
    			}
    		} else {
    			# Note that these tags are restricted to a single line
    			s/\&__LT__;b\&__GT__;(.*?)\&__LT__;\/b\&__GT__;/$1<\/b>/gi;
    			s/\&__LT__;i\&__GT__;(.*?)\&__LT__;\/i\&__GT__;/$1<\/i>/gi;
    			s/\&__LT__;strong\&__GT__;(.*?)\&__LT__;\/strong\&__GT__;/$1<\/strong>/gi;
    			s/\&__LT__;em\&__GT__;(.*?)\&__LT__;\/em\&__GT__;/$1<\/em>/gi;
    		}
    		s/\&__LT__;tt\&__GT__;(.*?)\&__LT__;\/tt\&__GT__;/$1<\/tt>/gis;  #  (MeatBall)
    		if ($HtmlLinks) {
    			s/\&__LT__;A(\s[^<>]+?)\&__GT__;(.*?)\&__LT__;\/a\&__GT__;/&StoreHref($1, $2)/gise;
    		}
    		if ($FreeLinks) {
    			# Consider: should local free-link descriptions be conditional?
    			# Also, consider that one could write [[Bad Page|Good Page]]?
    			s/\[\[$FreeLinkPattern\|([^\]]+)\]\]/&StorePageOrEditLink($1, $2)/geo;
    			s/\[\[$FreeLinkPattern\]\]/&StorePageOrEditLink($1, "")/geo;
    ###############
    ### added by gypark
    ### ÇÑ±ÛÆÐÀÌÁö¿¡ anchor »ç¿ë
    ### from Bab2's patch
    			s/\[\[$AnchoredFreeLinkPattern\|([^\]]+)\]\]/&StoreBracketAnchoredLink($1, $2, $3)/geos if $NamedAnchors;
    			s/\[\[$AnchoredFreeLinkPattern\]\]/&StoreRaw(&GetPageOrEditAnchoredLink($1, $2, ""))/geos if $NamedAnchors;
    ###
    ###############
    		}
    		if ($BracketText) {  # Links like [URL text of link]
    			s/\[$UrlPattern\s+([^\]]+?)\]/&StoreBracketUrl($1, $2)/geos;
    			s/\[$InterLinkPattern\s+([^\]]+?)\]/&StoreBracketInterPage($1, $2)/geos;
    			if ($WikiLinks && $BracketWiki) {  # Local bracket-links
    				s/\[$LinkPattern\s+([^\]]+?)\]/&StoreBracketLink($1, $2)/geos;
    				s/\[$AnchoredLinkPattern\s+([^\]]+?)\]/&StoreBracketAnchoredLink($1, $2, $3)/geos if $NamedAnchors;
    			}
    		}
    
    
    		if ($useImage) {
    			$_ = &EmoticonSubst($_);			# luke added
    		}
    
    		s/\[$UrlPattern\]/&StoreBracketUrl($1, "")/geo;
    		s/\[$InterLinkPattern\]/&StoreBracketInterPage($1, "")/geo;
    ###############
    ### added by gypark
    ### °³º°ÀûÀÎ IMG: ű×
    		s/IMG:([^<>\n]*)\n?$UrlPattern/&StoreImgUrl($1, $2, $useImage)/geo;
    ###
    ###############
    		s/$UrlPattern/&StoreUrl($1, $useImage)/geo;
    ###############
    ### replaced by gypark
    ### InterWiki ·Î ÀûÈù À̹ÌÁö ó¸®
    #		s/$InterLinkPattern/&StoreInterPage($1)/geo;
    		s/$InterLinkPattern/&StoreInterPage($1, $useImage)/geo;
    ###
    ###############
    
    		if ($WikiLinks) {
    			s/$AnchoredLinkPattern/&StoreRaw(&GetPageOrEditAnchoredLink($1, $2, ""))/geo if $NamedAnchors;
    			s/$LinkPattern/&GetPageOrEditLink($1, "")/geo;
    		}
    
    		s/$RFCPattern/&StoreRFC($1)/geo;
    		s/$ISBNPattern/&StoreISBN($1)/geo;
    		s/CD:\s*(\d+)/&StoreHotTrack($1)/geo;
    
    ###############
    ### commented by gypark
    ### ¸ÅÅ©·Î ó¸® ½ÃÁ¡À» ¹ÛÀ¸·Î »©³½´Ù
    		$_ = &MacroSubst($_); 				# luke added
    ###
    ###############
    
    ###############
    ### replaced by gypark
    ### ==== °¡ hr °ú Çìµå¶óÀÎ ¾çÂÊ¿¡¼­ 󸮵Ǿî Ãæµ¹ÀÌ »ý±ä´Ù. hr ÆÐÅÏÀ» ¼öÁ¤
    ### http://www.usemod.com/cgi-bin/wiki.pl?ThinLine
    # 		if ($ThinLine) {
    # 			s/----+/
    /g; # s/====+/
    /g; # } else { # s/----+/
    /g; # } if ($ThinLine) { s/--------+/
    /g; s/-------+/
    /g; s/------+/
    /g; s/-----+/
    /g; s/----+/
    /g; } else { s/----+/
    /g; } ### ############### } if ($doLines) { # 0 = no line-oriented, 1 or 2 = do line-oriented # The quote markup patterns avoid overlapping tags (with 5 quotes) # by matching the inner quotes for the strong pattern. s/('*)'''(.*?)'''/$1$2<\/strong>/g; s/''(.*?)''/$1<\/em>/g; if ($UseHeadings) { s/(^|\n)\s*(\=+)\s+([^\n]+)\s+\=+/&WikiHeading($1, $2, $3)/geo; ############### ### replaced by gypark ### table ³» ¼¿ º°·Î Á¤·Ä # s/((\|\|)+)/"<\/TD>"/ge if $TableMode; # rowspan À» vvv.. ·Î Ç¥ÇöÇÏ´Â °æ¿ì (Â÷ÈÄ¿¡ ´Ù½Ã °í·ÁÇÒ ¿¹Á¤) # my %td_align = ("&__LT__;", "left", "&__GT__;", "right", "|", "center"); # s/((\|\|)*)(\|(&__LT__;|&__GT__;|\|)(v*))/"<\/TD>"/ge if $TableMode; # rowspan À» v3 À¸·Î Ç¥ÇöÇÏ´Â °æ¿ì my %td_align = ("&__LT__;", "left", "&__GT__;", "right", "|", "center"); s/((\|\|)*)(\|(&__LT__;|&__GT__;|\|)((v(\d*))?))/"<\/TD>"/ge if $TableMode; ### ############### } } ############### ### commented by gypark ### {{{ }}} ó¸® ¶§¹®¿¡ ÇÔ¼ö È£Ãâ ¼ø¼­¸¦ ¹Ù²Ù¸é Ç¥ÀÛ¼ºÀÌ ¾ÈµÈ´Ù ### ´ÙÀ½ µÎ ÁÙÀ» ÁÖ¼®Ã³¸®ÇØÁÖ¾î ÇØ°á # s/^\|([^|]+)[^|]/$1<\/TD>\n/g; # start of line: new table-row -- luke # s/\|([^|]+)[^|]/$1<\/td>\n/g; # new field -- luke ### ############### return $_; } # luke added sub EmoticonSubst { my ($txt) = @_; if ($UseEmoticon) { my ($e, $e1, $e2, $e3, $e4, $e5, $e6, $e7, $e8); $e1 = $EmoticonPath . "/emoticon-ambivalent.gif "; $e2 = $EmoticonPath . "/emoticon-laugh.gif "; $e3 = $EmoticonPath . "/emoticon-sad.gif "; $e4 = $EmoticonPath . "/emoticon-smile.gif "; $e5 = $EmoticonPath . "/emoticon-surprised.gif "; $e6 = $EmoticonPath . "/emoticon-tongue-in-cheek.gif "; $e7 = $EmoticonPath . "/emoticon-unsure.gif "; $e8 = $EmoticonPath . "/emoticon-wink.gif "; $txt =~ s/\s\^[oO_\-]*\^[;]*/$e2/g; $txt =~ s/\s-[_]+-[;]*/$e7/g; $txt =~ s/\so\.O[^A-z]/$e5/g; $txt =~ s/\s\*\.\*/$e5/g; $txt =~ s/\s\=\.\=[;]*/$e7/g; $txt =~ s/\s\:-[sS][^A-z]/$e7/g; $txt =~ s/\s\:[-]*D[^A-z]/$e2/g; $txt =~ s/\s\:[-]*\([^A-z]/$e3/g; $txt =~ s/\s\:[-]*\)[^A-z]/$e4/g; $txt =~ s/\s\:[-]*[oO][^A-z]/$e5/g; $txt =~ s/\s\:[-]*[pP][^A-z]/$e6/g; $txt =~ s/\s\;[-]*\)[^A-z]/$e8/g; } return $txt; } sub MacroSubst { my ($txt) = @_; $txt =~ s/\&__LT__;Date\&__GT__;/&MacroDate()/gei; $txt =~ s/\&__LT__;time\&__GT__;/&MacroTime()/gei; $txt =~ s/\&__LT__;DateTime\&__GT__;/&MacroDateTime()/gei; $txt =~ s/\&__LT__;PageCount\&__GT__;/&MacroPageCount()/gei; $txt =~ s/\&__LT__;Anchor\((.*)\)\&__GT__;/&MacroAnchor($1)/gei; $txt =~ s/\&__LT__;RandomPage\((.*)\)\&__GT__;/&MacroRandom($1)/gei; ############### ### commented by gypark ### include ¸ÅÅ©·Î ¾È¿¡¼­ À§Å°Å±׸¦ ÀÛµ¿ÇÏ°Ô ÇÔ ### http://whitejames.x-y.net/cgi-bin/jofcgi/wiki/wiki.pl?ÇÁ·Î±×·¡¹ÖÆÁ/Wiki # $txt =~ s/\&__LT__;Include\((.*)\)\&__GT__;/&MacroInclude($1)/gei; ### ############### $txt =~ s/\&__LT__;FullSearch\((.*)\)\&__GT__;/&MacroFullSearch($1)/gei; $txt =~ s/\&__LT__;titlesearch\((.*)\)\&__GT__;/&MacroTitleSearch($1)/gei; $txt =~ s/\&__LT__;goto\((.*)\)\&__GT__;/&MacroGoto($1)/gei; $txt =~ s/\&__LT__;history\((.*)\)\&__GT__;/&MacroHistory($1)/gei; ############### ### added by gypark ### ¸ÅÅ©·Î Ãß°¡ ### $txt =~ s/\&__LT__;mysign\(([^,]+),(\d+-\d+-\d+ \d+:\d+.*)\)\&__GT__;/&MacroMySign($1, $2)/gei; ### $txt =~ s/\&__LT__;calendar\(([^,\n]+,)?([-+]?\d+),([-+]?\d+)\)\&__GT__;/&MacroCalendar($1, $2, $3)/gei; ### $txt =~ s/\&__LT__;wikiversion&__GT__;/&MacroWikiVersion()/gei; ### $txt =~ s/\&__LT__;vote\((\d+)(,(\d+))?\)&__GT__;/&MacroVote($1,$3)/gei; ### $txt =~ s/\&__LT__;allpagesto\(([^\n]+)\)\&__GT__;/&MacroAllPagesTo($1)/gei; ### $txt =~ s/\&__LT__;allpagesfrom\(([^,\n]+)(,\d)?\)\&__GT__;/&MacroAllPagesFrom($1, $2)/gei; ### $txt =~ s/\&__LT__;orphanedpages\(([-+])?(\d+)\)\&__GT__;/&MacroOrphanedPages($1, $2)/gei; ### $txt =~ s/\&__LT__;wantedpages\&__GT__;/&MacroWantedPages()/gei; ### $txt =~ s/\&__LT__;userlist\&__GT__;/&MacroUserList()/gei; ### »çÀü¸ÅÅ©·Î $txt =~ s/\&__LT__;dic\(([^)]+)\)\&__GT__;/&MacroEDic($1)/gei; $txt =~ s/\&__LT__;kdic\(([^)]+)\)\&__GT__;/&MacroKDic($1)/gei; $txt =~ s/\&__LT__;jdic\(([^)]+)\)\&__GT__;/&MacroJDic($1)/gei; ### $txt =~ s/(\&__LT__;mostpopular\(([-+]?\d+),([-+]?\d+)\)\&__GT__;)/&MacroMostPopular($1,$2, $3)/gei; ### $txt =~ s/(\&__LT__;uploadedfiles\&__GT__;)/&MacroUploadedFiles($1)/gei; ### $txt =~ s/(\&__LT__;myinterest(\(([^\n]+)\))?\&__GT__;)/&MacroMyInterest($1, $3)/gei; ### ############### return $txt; } ############### ### added by gypark sub RemoveLink { my ($string) = @_; $string =~ s/]*>(\?<\/a>)?//ig; $string =~ s/<\/?b>//ig; $string =~ s/<\/a>//ig; return $string; } ### ############### ############### ### added by gypark ### include ¸ÅÅ©·Î ¾È¿¡¼­ À§Å°Å±׸¦ ÀÛµ¿ÇÏ°Ô ÇÔ ### http://whitejames.x-y.net/cgi-bin/jofcgi/wiki/wiki.pl?ÇÁ·Î±×·¡¹ÖÆÁ/Wiki sub MacroIncludeSubst { my ($txt) = @_; $txt =~ s//&MacroInclude($1)/gei; ### toc ¸¦ Æ÷ÇÔÇÏÁö ¾Ê´Â includenotoc ¸ÅÅ©·Î Ãß°¡ $txt =~ s//&MacroInclude($1, "notoc")/gei; ### includday ¸ÅÅ©·Î $txt =~ s//&MacroIncludeDay($1, $2)/gei; return $txt; } ### ############### ############### ### added by gypark ### Ãß°¡ÇÑ ¸ÅÅ©·ÎÀÇ µ¿ÀۺΠ### MyInterest sub MacroMyInterest { my ($itself, $username) = (@_); my ($data, $status, @pages); my (%tempUserData, %tempUserInterest); my $txt = ""; if ($username eq "") { if (&GetParam('username') eq "") { return ""; } else { $username = &GetParam('username'); } } %tempUserData = (); ($status, $data) = &ReadFile(&UserDataFilename($username)); if (!$status) { return ""; } %tempUserData = split(/$FS1/, $data, -1); # -1 keeps trailing null fields %tempUserInterest = split(/$FS2/, $tempUserData{'interest'}, -1); @pages = sort (keys (%tempUserInterest)); foreach (@pages) { $txt .= ".... " if ($_ =~ m|/|); $txt .= &GetPageLink($_)."
    "; } return $txt; } ### UploadedFiles sub MacroUploadedFiles { my ($itself) = (@_); my (@files, %filesize, %filemtime, $size, $totalSize); my $txt; my $uploadsearch = ""; my $canDelete = &UserIsAdmin(); if (!(-e $UploadDir)) { &CreateDir($UploadDir); } opendir (DIR, "$UploadDir") || die Ts('cant opening %s', $UploadDir) . ": $!"; @files = readdir(DIR); shift @files; shift @files; close (DIR); $totalSize = 0; foreach (@files) { $filesize{$_} = (-s "$UploadDir/$_"); $totalSize += $filesize{$_}; $filemtime{$_} = ($Now - (-M "$UploadDir/$_") * 86400); } @files = sort { $filemtime{$b} <=> $filemtime{$a} || $a cmp $b } @files; $txt = $q->start_form("post","$ScriptName",""); $txt .= ""; $txt .= ""; $txt .= ""; $txt .= ""; if ($canDelete) { $txt .= ""; } $txt .= "". "". ""; $txt .= ""; foreach (@files) { $txt .= ""; if ($canDelete) { $txt .= ""; } $txt .= ""; $size = $filesize{$_}; while ($size =~ m/(\d+)(\d{3})((,\d{3})*$)/) { $size = "$1,$2$3"; } $txt .= ""; $txt .= ""; $txt .= ""; } $txt .= ""; $txt .= "" if ($canDelete); $txt .= ""; while ($totalSize =~ m/(\d+)(\d{3})((,\d{3})*$)/) { $totalSize = "$1,$2$3"; } $txt .= ""; $txt .= ""; $txt .= "
    ".T('Delete')."".T('File Name')."".T('Size (byte)')."".T('Date')."
    "; $txt .= " "; $txt .= ""; $txt .= &ScriptLink("reverse=Upload:$_", $uploadsearch) . " "; $txt .= "$_"; $txt .= "$size".&TimeToText($filemtime{$_})."
     "; $txt .= "". Ts('Total %s files', ($#files + 1)).""; $txt .= ""; $txt .= "$totalSize"; $txt .= " 
    "; $txt .= $q->submit(T('Delete Checked Files')) if ($canDelete); $txt .= $q->endform; return $txt; } ### MostPopular sub MacroMostPopular { my ($itself, $start, $end) = (@_); my (%pgcount, $page, $countfile, $status, $count, @pages); my $txt; if (($start == 0) || ($end == 0)) { return $itself; } foreach $page (&AllPagesList()) { $countfile = &GetCountFile($page); ($status, $count) = &ReadFile($countfile); if ($status) { $pgcount{$page} = $count; } else { $pgcount{$page} = 0; } } @pages = sort { $pgcount{$b} <=> $pgcount{$a} || $a cmp $b } keys %pgcount; if ($start > 0) { $start--; } else { $start = $#pages + $start + 1; } if ($end > 0) { $end--; } else { $end = $#pages + $end + 1; } $start = 0 if ($start < 0); $start = $#pages if ($start > $#pages); $end = 0 if ($end < 0); $end = $#pages if ($end > $#pages); if ($start <= $end) { @pages = @pages[$start .. $end]; } else { @pages = reverse(@pages[$end .. $start]); } foreach $page (@pages) { $txt .= ".... " if ($page =~ m|/|); $txt .= &GetPageLink($page) . " (".Ts('%s hit'.(($pgcount{$page}>1)?'s':''), $pgcount{$page}) . ")
    "; } return $txt; } ### ¼¼ °¡Áö »çÀü ¸ÅÅ©·Î sub MacroEDic { return "
    @_"; } sub MacroKDic { return "@_"; } sub MacroJDic { return "@_"; } ### sub MacroIncludeDay { my ($mainpage, $day_offset) = @_; my $page = ""; my $temp; # main page ó¸® if ($mainpage ne "") { $temp = $mainpage; $temp =~ s/,$//; $temp = &RemoveLink($temp); $temp = &FreeToNormal($temp); if (&ValidId($temp) ne "") { return "<includeday($mainpage$day_offset)>"; } $temp =~ s/\/.*$//; $page = "$temp/"; } # ³¯Â¥ÀÇ º¯À§ °è»ê $temp = $Now + ($day_offset * 86400); my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($temp+$TimeZoneOffset); $page .= ($year + 1900) . "-"; if ($mon + 1 < 10) { $page .= "0"; } $page .= ($mon + 1) . "-"; if ($mday < 10) { $page .= "0"; } $page .= "$mday"; return &MacroInclude($page); } ### sub MacroUserList { my (@userlist, $result); my $usernumber; opendir(USERLIST, $UserDir); @userlist = readdir(USERLIST); close(USERLIST); shift @userlist; shift @userlist; @userlist = sort @userlist; foreach $usernumber (0..(@userlist-1)) { @userlist[$usernumber] =~ s/(.*)\.db/($1)/gei; @userlist[$usernumber] = &StorePageOrEditLink("@userlist[$usernumber]", "@userlist[$usernumber]") . "
    "; } $result = "@userlist"; return $result; } ### sub MacroWantedPages { my ($pageline, @found, $page); my %numOfReverse; my $txt; foreach $pageline (&GetFullLinkList("exists=0&sort=0")) { my @links = split(' ', $pageline); my $id = shift(@links); foreach $page (@links) { $page = (split('/',$id))[0]."$page" if ($page =~ /^\//); push(@found, $page) if ($numOfReverse{$page} == 0); $numOfReverse{$page}++; } } @found = sort(@found); foreach $page (@found) { $txt .= ".... " if ($page =~ m|/|); $txt .= &GetPageOrEditLink($page, $page) . " (" . &ScriptLink("action=links&editlink=1&empty=0&reverse=$page", $numOfReverse{$page}) . ")
    "; } return $txt; } ### sub MacroOrphanedPages { my ($less_or_more, $criterion) = @_; my (@allPages, $page, $pageline); my %numOfReverse; my $txt; @allPages = &AllPagesList(); foreach $page (@allPages) { $numOfReverse{$page} = 0; } foreach $pageline (&GetFullLinkList("exists=1&sort=0")) { my @links = split(' ', $pageline); my $id = shift(@links); my $link; foreach $link (@links) { $link = (split('/',$id))[0]."$link" if ($link =~ /^\//); next if ($id eq $link); $numOfReverse{$link}++; } } foreach $page (@allPages) { next if (($less_or_more eq "-") && ($numOfReverse{$page} > $criterion)); next if (($less_or_more eq "+") && ($numOfReverse{$page} < $criterion)); next if (($less_or_more eq "") && ($numOfReverse{$page} != $criterion)); $txt .= ".... " if ($page =~ m|/|); $txt .= &GetPageLink($page) . "
    "; } return $txt; } ### sub MacroAllPagesFrom { my ($string, $exists) = @_; my (@x, @links, $pagename, %seen, %pgExists); my $txt; $string = &RemoveLink($string); $string = &FreeToNormal($string); if (&ValidId($string) ne "") { return "<allpagesfrom($string)>"; } if ($exists =~ /,(\d)/) { $exists = $1; } else { $exists = 2; } %pgExists = (); foreach $pagename (&AllPagesList()) { $pgExists{$pagename} = 1; } ############### ### replaced by gypark ### ¸µÅ© ¸ñ·ÏÀ» º°µµ·Î °ü¸® # @x = &GetPageLinks($string, 1, 0, 0); @x = &GetPageLinksFromFile($string, 1, 0, 0); ### ############### foreach $pagename (@x) { $pagename = (split('/',$string))[0]."$pagename" if ($pagename =~ /^\//); if ($seen{$pagename} != 0) { next; } if (($exists == 0) && ($pgExists{$pagename} == 1)) { next; } if (($exists == 1) && ($pgExists{$pagename} != 1)) { next; } $seen{$pagename}++; push (@links, $pagename); } @links = sort(@links); foreach $pagename (@links) { $txt .= ".... " if ($pagename =~ m|/|); $txt .= &GetPageOrEditLink($pagename) . "
    "; } return $txt; } ### sub MacroAllPagesTo { my ($string) = @_; my @x = (); my ($pagelines, $pagename, $txt); my $pagename; $string = &RemoveLink($string); $string = &FreeToNormal($string); if (&ValidId($string) ne "") { return "<allpagesto($string)>"; } foreach $pagelines (&GetFullLinkList("empty=0&sort=1&reverse=$string")) { my @pages = split(' ', $pagelines); @x = (@x, shift(@pages)); } foreach $pagename (@x) { $txt .= ".... " if ($pagename =~ m|/|); $txt .= &GetPageLink($pagename) . "
    "; } return $txt; } ### sub MacroVote { my ($count, $scale) = @_; my $maximum = 1000; $scale = 10 if ($scale eq ''); my $width = $count * $scale; $width = $maximum if ($width > $maximum); return "" ."
    $count" ."
    "; } ### ¸ÅÅ©·Î Ãß°¡ sub MacroMySign { my ($author, $timestamp) = @_; return "
    -- $author $timestamp
    "; } ### ¸ÅÅ©·Î Ãß°¡ sub MacroCalendar { use Time::Local; my ($cal_mainpage, $cal_year, $cal_month) = @_; my $result=''; my $cal_result=''; my $cal_page; my @cal_color = ("red", "black", "black", "black", "black", "black", "blue", "green"); my @cal_dow = (T('Su'), T('Mo'), T('Tu'), T('We'), T('Th'), T('Fr'), T('Sa')); my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($Now+$TimeZoneOffset); my ($this_year, $this_month, $this_day) = ($year, $mon, $mday); my $cal_time; my ($td_class, $span_style); my $temp; # ´ÞÀÇ °ªÀÌ 13 ÀÌ»óÀÌ¸é ¹«È¿ if (!($cal_month =~ /[-+]/) && ($cal_month > 12)) { return "<calendar($cal_mainpage$cal_year,$cal_month)>"; } # prefix ó¸® if (length($cal_mainpage) != 0) { $temp = $cal_mainpage; $temp =~ s/,$//; $temp = &RemoveLink($temp); $temp = &FreeToNormal($temp); if (&ValidId($temp) ne "") { return "<calendar($cal_mainpage$cal_year,$cal_month)>"; } $temp =~ s/\/.*$//; $cal_mainpage = "$temp/"; } # ³âµµ³ª ´Þ¿¡ 0 À» ÀÎÀÚ·Î ¹ÞÀ¸¸é ¿ÃÇØ ¶Ç´Â À̹ø ´Þ $cal_year = $this_year+1900 if ($cal_year == 0); $cal_month = $this_month+1 if ($cal_month == 0); # ³âµµ¿¡ + ¶Ç´Â - °¡ ÀÖÀ¸¸é ¿ÃÇØ·ÎºÎÅÍ º¯À§ °è»ê if ($cal_year =~ /\+(\d+)/ ) { $cal_year = $this_year+1900 + $1; } elsif ($cal_year =~ /-(\d+)/ ) { $cal_year = $this_year+1900 - $1; } # ´Þ¿¡ + ¶Ç´Â - °¡ ÀÖÀ¸¸é À̹ø ´Þ·ÎºÎÅÍ º¯À§ °è»ê if ($cal_month =~ /\+(\d+)/ ) { $cal_month = $this_month+1 + $1; while ($cal_month > 12) { $cal_month -= 12; $cal_year++; } } elsif ($cal_month =~ /-(\d+)/ ) { $cal_month = $this_month+1 - $1; while ($cal_month < 1) { $cal_month += 12; $cal_year--; } } # 1902³âºÎÅÍ 2037³â »çÀ̸¸ Áö¿øÇÔ. ±× ¹üÀ§¸¦ ¹þ¾î³ª¸é 1902³â°ú 2037³âÀ¸·Î °è»ê $cal_year = 2037 if ($cal_year > 2037); $cal_year = 1902 if ($cal_year < 1902); # 1¿ù~9¿ùÀº 01~09·Î ¸¸µê if ($cal_month < 10) { $cal_month = "0" . $cal_month; } # ´Þ·Â Á¦¸ñ Ãâ·Â $result .= ""; $result .= ""; # »ó´ÜÀÇ ¿äÀÏ Ãâ·Â $result .= ""; for (0..6) { $result .= ""; } $result .= ""; # ÀÎÀÚ·Î ÁÖ¾îÁø ´ÞÀÇ 1Àϳ¯À» ãÀ½ $cal_time = timelocal(0,0,0,1,$cal_month-1,$cal_year); ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($cal_time); # ´Þ·ÂÀÇ Ã¹¹øÂ° ³¯ ãÀ½ $cal_time -= $wday * (60 * 60 * 24); ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($cal_time); # ´Þ·Â ±×¸² my ($temp_month, $temp_day); for (1..6) { $result .= ""; for (0..6) { # 1~9´Â 01~09·Î ¸¸µê ($temp_month, $temp_day) = ($mon + 1, $mday); $temp_month = "0".$temp_month if ($temp_month < 10); $temp_day = "0".$temp_day if ($temp_day < 10); $cal_page = ($year + 1900)."-".($temp_month)."-".($temp_day); $cal_result = $mday; $span_style = ""; if (($year == $this_year) && ($mon == $this_month) && ($mday == $this_day)) { $td_class = "calendartoday"; $span_style = "text-decoration: underline; "; } else { $td_class = "calendar"; } if (-f &GetPageFile($cal_mainpage . $cal_page)) { $span_style .= "font-weight: bold; text-decoration: underline; "; $wday = 7; } if ($cal_month != ($mon+1)) { $span_style .= "font-size: 0.9em; "; } $result .= ""; $cal_time += (60 * 60 * 24); ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($cal_time); } $result .= ""; # 4 ¶Ç´Â 5 ÁÙ·Î ³¡³¾ ¼ö ÀÖÀ¸¸é ³¡³¿ last if (($mon+1 > $cal_month) || ($year+1900 > $cal_year)); } $result .= "
    " ."" .(length($cal_mainpage)?"$cal_mainpage
    ":"") ."$cal_year-$cal_month" ."
    " ."
    " . "$cal_dow[$_]
    " ."" ."" .$cal_result ."
    "; return $result; } ### ¸ÅÅ©·Î Ãß°¡ sub MacroWikiVersion { return &ScriptLink("action=version", $WikiVersion); } ### ############### sub MacroHistory { my ($n) = @_; my ($html, $i); &OpenPage($DocID); &OpenDefaultText(); $html = "
    "; $html .= ""; $html .= ""; $html .= ""; $html .= ""; ############### ### replaced by gypark ### History ¸ÅÅ©·Î ¹ö±× ¼öÁ¤ # $html .= &GetHistoryLine($DocID, $Page{'text_default'}, 0, 1); $html .= &GetHistoryLine($DocID, $Page{'text_default'}, 0, 0); ### ############### &OpenKeptRevisions('text_default'); $i = 0; foreach (reverse sort {$a <=> $b} keys %KeptRevisions) { if (++$i > $n) { $html .= "
     
    \n"; return $html; } next if ($_ eq ""); # (needed?) ############### ### replaced by gypark ### History ¸ÅÅ©·Î ¹ö±× ¼öÁ¤ # $html .= &GetHistoryLine($DocID, $KeptRevisions{$_}, 0, 0); $html .= &GetHistoryLine($DocID, $KeptRevisions{$_}, 0, $i); ### ############### } $html .= "  \n"; return $html; } sub MacroGoto { my ($string) = @_; ############### ### added by gypark ### goto ¸ÅÅ©·Î °³¼± $string = &RemoveLink($string); ### ############### return ############### ### replaced by gypark ### goto ¸ÅÅ©·Î °³¼± ### from Bab2's patch # "
    " . # "" . # "
    "; "
    ". "" . " " . "". "
    "; ### ############### } sub MacroTitleSearch { my ($string) = @_; my ($name, $freeName, $txt); foreach $name (&AllPagesList()) { if ($name =~ /$string/i) { ############### ### replace by gypark ### °Ë»ö °á°ú¸¦ ¼¼·Î·Î º¸À̵µ·Ï ¼öÁ¤ # $txt .= &GetPageLink($name) . " "; $txt .= &GetPageLink($name) . "
    "; ### ############### } elsif ($FreeLinks && ($name =~ m/_/)) { $freeName = $name; $freeName =~ s/_/ /g; if ($freeName =~ /$string/i) { ############### ### replace by gypark ### °Ë»ö °á°ú¸¦ ¼¼·Î·Î º¸À̵µ·Ï ¼öÁ¤ # $txt .= &GetPageLink($name) . " "; $txt .= &GetPageLink($name) . "
    "; ### ############### } } } return $txt; } sub MacroFullSearch() { my $pagename; my ($string) = @_; my @x = &SearchTitleAndBody($string); my $txt; foreach $pagename (@x) { $txt .= ".... " if ($pagename =~ m|/|); ############### ### replace by gypark ### °Ë»ö °á°ú¸¦ ¼¼·Î·Î º¸À̵µ·Ï ¼öÁ¤ # $txt .= &GetPageLink($pagename) . " "; $txt .= &GetPageLink($pagename) . "
    "; ### ############### } return $txt; } sub MacroDate() { return &CalcDay(time); } sub MacroTime() { return &CalcTime(time); } sub MacroDateTime() { return &CalcDay(time) . " " . &CalcTime(time); } sub MacroAnchor() { return ""; } sub MacroPageCount() { my @pageList = &AllPagesList(); return $#pageList + 1; } sub MacroRandom() { my ($count) = @_; my @pageList = &AllPagesList(); my ($txt); srand($Now); while ($count-- > 0) { $txt .= &GetPageLink($pageList[int(rand($#pageList + 1))]) . " "; } return $txt; } sub MacroInclude { my ($name, $opt) = @_; if ($OpenPageName eq $name) { # Recursive Include ¹æÁö return ""; } my $fname = &GetPageFile($name); # Á¸ÀçÇÏÁö ¾Ê´Â ÆÄÀÏÀÌ¸é ±×³É ¸®ÅÏ if (!(-f $fname)) { return ""; } ############### ### added by gypark ### hide page if (&PageIsHidden($name)) { return ""; } ### ############### my $data = &ReadFileOrDie($fname); my %SubPage = split(/$FS1/, $data, -1); # -1 keeps trailing null fields if (!defined($SubPage{"text_default"})) { return ""; } my %SubSection = split(/$FS2/, $SubPage{"text_default"}, -1); my %TextInclude = split(/$FS3/, $SubSection{'data'}, -1); # includenotoc ÀÇ °æ¿ì $TextInclude{'text'} =~ s//$FS_lt."toc".$FS_gt/gei if ($opt eq "notoc"); return $TextInclude{'text'}; } # end sub WikiLinesToHtml { my ($pageText) = @_; my ($pageHtml, @htmlStack, $code, $depth, $oldCode); my ($tag); ############### ### added by gypark my %td_align = ("&__LT__;", "left", "&__GT__;", "right", "|", "center"); ### ############### @htmlStack = (); $depth = 0; $pageHtml = ""; foreach (split(/\n/, $pageText)) { # Process lines one-at-a-time $_ .= "\n"; if (s/^(\;+)([^:]+\:?)\:/
    $2
    /) { $code = "DL"; $depth = length $1; } elsif (s/^(\:+)/
    /) { $code = "DL"; $depth = length $1; } elsif (s/^(\*+)/
  • /) { $code = "UL"; $depth = length $1; } elsif (s/^(\#+)/
  • /) { $code = "OL"; $depth = length $1; } elsif (/^[ \t].*\S/) { $code = "PRE"; $depth = 1; ############### ### replaced by gypark ### table ³» ¼¿ º°·Î Á¤·Ä # } elsif (s/^((\|\|)+)(.*)\|\|\s*$/"$3<\/TD><\/TR>\n"/e) { # $code = 'TABLE'; # $TableMode = 1; # $depth = 1; # rowspan À» vvv.. ·Î Ç¥ÇöÇÏ´Â °æ¿ì (Â÷ÈÄ¿¡ ´Ù½Ã °í·ÁÇÒ ¿¹Á¤) # } elsif (s/^((\|\|)*)(\|(&__LT__;|&__GT__;|\|)(v*))(.*)\|\|\s*$/"" # . "" # . $6 . "<\/TD><\/TR>\n"/e) { # $code = 'TABLE'; # $TableMode = 1; # $depth = 1; } elsif (s/^((\|\|)*)(\|(&__LT__;|&__GT__;|\|)((v(\d*))?))(.*)\|\|\s*$/"" . "" . $8 . "<\/TD><\/TR>\n"/e) { $code = 'TABLE'; $TableMode = 1; $depth = 1; ### ############### } elsif (/^IMG:(.*)$/) { # luke added StoreImageTag($1); $_ = ""; } elsif (/^TABLE:(.*)$/) { # luke added StoreTableTag($1); $_ = ""; } else { $depth = 0; } while (@htmlStack > $depth) { # Close tags as needed # $pageHtml .= "\n"; -- deleted luke $tag = pop(@htmlStack); # added luke if ($tag eq "TABLE") { ############### ### replaced by gypark ### ÁÙ Áß°£ || ¹®Á¦ ÇØ°á ### from Jof4002's patch # $pageHtml .= "\n"; # $tag = "table" $TableMode = 0; ### ############### }; $pageHtml .= "\n"; # added end luke } if ($depth > 0) { $depth = $IndentLimit if ($depth > $IndentLimit); if (@htmlStack) { # Non-empty stack $oldCode = pop(@htmlStack); if ($oldCode ne $code) { ############### ### added by gypark ### ÁÙ Áß°£ || ¹®Á¦ ÇØ°á ### from Jof4002's patch if ($oldCode eq "TABLE") { $TableMode = 0; } ### ############### $pageHtml .= "<$code>\n"; } push(@htmlStack, $code); } while (@htmlStack < $depth) { push(@htmlStack, $code); if ($code eq "TABLE") { # added luke $pageHtml .= "\n"; } else { $pageHtml .= "<$code>\n"; }; # added luke # $pageHtml .= "<$code>\n"; # deleted luke } } s/^\s*$/

    \n/; # Blank lines become

    tags $pageHtml .= &CommonMarkup($_, 1, 2); # Line-oriented common markup } while (@htmlStack > 0) { # Clear stack $pageHtml .= "\n"; } return $pageHtml; } sub QuoteHtml { my ($html) = @_; $html =~ s/&/&/g; $html =~ s//>/g; if (1) { # Make an official option? $html =~ s/&([#a-zA-Z0-9]+);/&$1;/g; # Allow character references } return $html; } ############### ### added by gypark ### {{{ }}} 󸮸¦ À§ÇØ º»¹® 󸮽ÿ¡´Â Quote ¸¦ ´Ù¸£°Ô ÇÔ sub QuoteHtmlForPageContent { my ($html) = @_; $html =~ s/&/&__AMP__;/g; $html =~ s//&__GT__;/g; if (1) { # Make an official option? $html =~ s/&__AMP__;([#a-zA-Z0-9]+);/&$1;/g; # Allow character references } return $html; } ### ############### sub StoreInterPage { ############### ### replaced by gypark ### InterWiki ·Î ÀûÈù À̹ÌÁö ó¸® # my ($id) = @_; my ($id, $useImage) = @_; ### ############### my ($link, $extra); ############### ### replaced by gypark ### InterWiki ·Î ÀûÈù À̹ÌÁö ó¸® # ($link, $extra) = &InterPageLink($id); ($link, $extra) = &InterPageLink($id, $useImage); ### ############### # Next line ensures no empty links are stored $link = &StoreRaw($link) if ($link ne ""); return $link . $extra; } sub InterPageLink { ############### ### replaced by gypark ### InterWiki ·Î ÀûÈù À̹ÌÁö ó¸® # my ($id) = @_; my ($id, $useImage) = @_; ### ############### my ($name, $site, $remotePage, $url, $punct); ($id, $punct) = &SplitUrlPunct($id); $name = $id; ($site, $remotePage) = split(/:/, $id, 2); $url = &GetSiteUrl($site); return ("", $id . $punct) if ($url eq ""); $remotePage =~ s/&/&/g; # Unquote common URL HTML $url .= $remotePage; ############### ### added by gypark ### InterWiki ·Î ÀûÈù À̹ÌÁö ó¸® ### from Jof's patch if ($useImage && ($url =~ /^(http:|https:|ftp:).+\.$ImageExtensions$/)) { $url = $1 if ($url =~ /^https?:(.*)/ && $1 !~ /^\/\//); return ("\"$id\"", $punct); } ### ############### ############### ### replaced by gypark ### ¿ÜºÎ URL À» »õâÀ¸·Î ¶ç¿ï ¼ö ÀÖ´Â ¸µÅ©¸¦ ºÙÀÓ ### from http://whitejames.x-y.net/cgi-bin/jofcgi/wiki/wiki.pl?ÇÁ·Î±×·¡¹ÖÆÁ/Wiki # return ("$name", $punct); return ("$name\""", $punct); ### ############### } sub StoreBracketInterPage { my ($id, $text) = @_; my ($site, $remotePage, $url, $index); ($site, $remotePage) = split(/:/, $id, 2); $remotePage =~ s/&/&/g; # Unquote common URL HTML $url = &GetSiteUrl($site); if ($text ne "") { return "[$id $text]" if ($url eq ""); } else { return "[$id]" if ($url eq ""); $text = &GetBracketUrlIndex($id); } $url .= $remotePage; ############### ### replaced by gypark ### ¿ÜºÎ URL À» »õâÀ¸·Î ¶ç¿ï ¼ö ÀÖ´Â ¸µÅ©¸¦ ºÙÀÓ ### from http://whitejames.x-y.net/cgi-bin/jofcgi/wiki/wiki.pl?ÇÁ·Î±×·¡¹ÖÆÁ/Wiki # return &StoreRaw("[$text]"); return &StoreRaw("[$text]\"""); ### ############### } sub GetBracketUrlIndex { my ($id) = @_; my ($index, $key); # Consider plain array? if ($SaveNumUrl{$id} > 0) { return $SaveNumUrl{$id}; } $SaveNumUrlIndex++; # Start with 1 $SaveNumUrl{$id} = $SaveNumUrlIndex; return $SaveNumUrlIndex; } sub GetSiteUrl { my ($site) = @_; my ($data, $url, $status); if (!$InterSiteInit) { $InterSiteInit = 1; ############### ### replaced by gypark ### file upload # ($status, $data) = &ReadFile($InterFile); # return "" if (!$status); # %InterSite = split(/\s+/, $data); # Later consider defensive code ($status, $data) = &ReadFile($InterFile); if ($status) { %InterSite = split(/\s+/, $data); } $InterSite{'Upload'} = "$UploadUrl\/"; ### ############### } $url = $InterSite{$site} if (defined($InterSite{$site})); return $url; } sub StoreRaw { my ($html) = @_; $SaveUrl{$SaveUrlIndex} = $html; return $FS . $SaveUrlIndex++ . $FS; } ############### ### added by gypark ### ¸î °¡Áö ÇÔ¼öµé Ãß°¡ ### {{{ }}} 󸮸¦ À§ÇØ sub StoreCodeRaw { my ($html) = @_; # $html =~ s/&__LT__;//g; # $html =~ s/&__AMP__;/&/g; # $html =~ s/&__AMP__;([#a-zA-Z0-9]+);/&$1;/g; # Allow character references $html =~ s/&([#a-zA-Z0-9]+);/&$1;/g; $html =~ s/&__DOUBLEBACKSLASH__;/\\\\\n/g; $html =~ s/&__SINGLEBACKSLASH__;/\\\n/g; $html =~ s/&__LT__;/</g; $html =~ s/&__GT__;/>/g; $html =~ s/&__AMP__;/&/g; $SaveUrl{$SaveUrlIndex} = $html; return $FS . $SaveUrlIndex++ . $FS; } ### {{{lang }}} 󸮸¦ À§ÇØ sub StoreSyntaxHighlight { my ($lang, $opt , @code) = @_; my %LANG; foreach (@SRCHIGHLANG) { $LANG{$_} = "1"; } if (!((-x "$SOURCEHIGHLIGHT") && defined($LANG{$lang}))) { return &StoreCodeRaw(@code); } my ($option) = " -fhtml -s$lang "; if ($opt =~ s/n//) { $option .= " -n "; } if ($opt ne "") { $option .= " -t$opt "; } my (@html) = `$SOURCEHIGHLIGHT $option << "EnDoFwIkIcOdE" @code EnDoFwIkIcOdE`; # source-highlight Ãâ·Â¹° ¾ÕµÚÀÇ pre ÅÂ±×¿Í tt ű׸¦ »«´Ù shift @html; shift @html; pop @html; pop @html; my ($line, $result); $result = ""; foreach $line (@html) { $line =~ s/(]*>)?&(<\/font>)?(]*>)?__DOUBLEBACKSLASH__(<\/font>)?(]*>)?;(<\/font>)?/$1\\\\\n$6/g; $line =~ s/(]*>)?&(<\/font>)?(]*>)?__SINGLEBACKSLASH__(<\/font>)?(]*>)?;(<\/font>)?/$1\\\n$6/g; $line =~ s/(]*>)?&(<\/font>)?(]*>)?__GT__(<\/font>)?(]*>)?;(<\/font>)?/$1>$6/g; $line =~ s/(]*>)?&(<\/font>)?(]*>)?__LT__(<\/font>)?(]*>)?;(<\/font>)?/$1<$6/g; $line =~ s/(]*>)?&(<\/font>)?(]*>)?__AMP__(<\/font>)?(]*>)?;(<\/font>)?/$1&$6/g; $SaveUrl{$SaveUrlIndex} = $line; $result .= $FS . $SaveUrlIndex++ . $FS; } return $result; } ### ±ÛÀ» ÀÛ¼ºÇÑ Á÷ÈÄ¿¡ ¼öÇàµÇ´Â ¸ÅÅ©·Îµé sub ProcessPostMacro { my ($string) = @_; ### ¿©±â¿¡ »ç¿ëÇÒ ¸ÅÅ©·ÎµéÀ» ³ª¿­ÇÑ´Ù $string = &PostMacroMySign($string); return $string; } ### ¸ÅÅ©·Î ó¸® sub PostMacroMySign { my ($string) = @_; my ($timestamp) = &TimeToText($Now); my ($author) = &GetParam('username'); if ($author ne "") { # ÀÌ ½ÃÁ¡¿¡¼­ [[ ]] ¸¦ ºÙÀÌ´Â °ÍÀÌ ¿ÇÀº°¡ È®ÀÎÇÒ °Í $author = "[[$author]]"; } else { $author = &GetRemoteHost(0); } # ¿©±â¼­´Â ±×³É mysign(À̸§,½Ã°£)À¸·Î¸¸ º¯°æ $string =~ s///g; return $string; } ### ############### sub StorePre { my ($html, $tag) = @_; return &StoreRaw("<$tag>" . $html . ""); } sub StoreHref { my ($anchor, $text) = @_; return "$text"; } sub StoreUrl { my ($name, $useImage) = @_; my ($link, $extra); ($link, $extra) = &UrlLink($name, $useImage); # Next line ensures no empty links are stored $link = &StoreRaw($link) if ($link ne ""); return $link . $extra; } ############### ### added by gypark ### °³º°ÀûÀÎ IMG: ÅÂ±× sub StoreImgUrl { my ($imgTag, $name, $useImage) = @_; my ($link, $extra); $ImageTag = $imgTag; ($link, $extra) = &UrlLink($name, $useImage); # Next line ensures no empty links are stored $link = &StoreRaw($link) if ($link ne ""); $ImageTag = ""; return $link . $extra; } ### ############### sub UrlLink { my ($rawname, $useImage) = @_; my ($name, $punct); ($name, $punct) = &SplitUrlPunct($rawname); if ($NetworkFile && $name =~ m|^file:|) { # Only do remote file:// links. No file:///c|/windows. if ($name =~ m|^file://[^/]|) { return ("$name", $punct); } return $rawname; } # Restricted image URLs so that mailto:foo@bar.gif is not an image if ($useImage && ($name =~ /^(http:|https:|ftp:).+\.$ImageExtensions$/)) { $name = $1 if ($name =~ /^https?:(.*)/ && $1 !~ /^\/\//); ############### ### replaced by gypark ### À̹ÌÁö¿¡ alt ű׸¦ ³Ö¾î ¿ø·¡ ÁÖ¼Ò¸¦ º¸ÀÓ # return ("", $punct); return ("\"$name\"", $punct); ### ############### } ############### ### added by gypark ### »ó´ë °æ·Î·Î ÀûÈù URL À» Á¦´ë·Î ó¸® my $protocol; ($protocol, $name) = ($1, $2) if ($name =~ /^(https?:)(.*)/ && $2 !~ /^\/\//); ### ############### ############### ### replaced by gypark ### ¿ÜºÎ URL À» »õâÀ¸·Î ¶ç¿ï ¼ö ÀÖ´Â ¸µÅ©¸¦ ºÙÀÓ ### from http://whitejames.x-y.net/cgi-bin/jofcgi/wiki/wiki.pl?ÇÁ·Î±×·¡¹ÖÆÁ/Wiki # return ("$name", $punct); return ("$protocol$name\""", $punct); ### ############### } sub StoreBracketUrl { my ($url, $text) = @_; $url = $1 if ($url =~ /^https?:(.*)/ && $1 !~ /^\/\//); if ($text eq "") { $text = &GetBracketUrlIndex($url); } ############### ### replaced by gypark ### ¿ÜºÎ URL À» »õâÀ¸·Î ¶ç¿ï ¼ö ÀÖ´Â ¸µÅ©¸¦ ºÙÀÓ ### from http://whitejames.x-y.net/cgi-bin/jofcgi/wiki/wiki.pl?ÇÁ·Î±×·¡¹ÖÆÁ/Wiki # return &StoreRaw("[$text]"); return &StoreRaw("[$text]\"""); ### ############### } sub StoreBracketLink { my ($name, $text) = @_; return &StoreRaw(&GetPageLinkText($name, "[$text]")); } sub StoreBracketAnchoredLink { my ($name, $anchor, $text) = @_; return &StoreRaw(&GetPageLinkText("$name#$anchor", "[$text]")); } sub StorePageOrEditLink { my ($page, $name) = @_; if ($FreeLinks) { $page =~ s/^\s+//; # Trim extra spaces $page =~ s/\s+$//; $page =~ s|\s*/\s*|/|; # ...also before/after subpages } $name =~ s/^\s+//; $name =~ s/\s+$//; return &StoreRaw(&GetPageOrEditLink($page, $name)); } sub StoreRFC { my ($num) = @_; return &StoreRaw(&RFCLink($num)); } sub RFCLink { my ($num) = @_; return "RFC $num"; } # luke add begin sub StoreImageTag { my ($x) = @_; $ImageTag = $x; return ""; } sub StoreTableTag { my ($x) = @_; $TableTag = $x; return ""; } sub StoreHotTrack { my ($id) = @_; return "" . ""; } # luke add end sub StoreISBN { my ($num) = @_; return &StoreRaw(&ISBNLink($num)); } sub ISBNLink { my ($rawnum) = @_; my ($rawprint, $html, $num, $first, $second, $third, $hyphened); $num = $rawnum; $rawprint = $rawnum; $rawprint =~ s/ +$//; $num =~ s/[- ]//g; if (length($num) != 10) { return "ISBN $rawnum"; } #$hyphened = $num; #$hyphened =~ s/(..)(.....)(..)(.)/\1-\2-\3-\4/; ############### ### replaced by gypark ### ISBNLink °³¼± my ($noCoverIcon, $iconNum) = ("icons/isbn-nocover.jpg", ($num % 5)); $noCoverIcon = "icons/isbn-nocover-$iconNum.jpg" if (-f "icons/isbn-nocover-$iconNum.jpg"); if ($num =~ /^89/) { return "" . "". ""; } ### ÀϺ» ¼­ÀûÀº º°µµ·Î ¸µÅ© if ($num =~ /^4/) { return "" . "". ""; } ### ############### $first = ""; $second = "" . T('alternate') . ""; $third = "" . T('search') . ""; $html = $first . "ISBN " . $rawprint . " "; $html .= "($second, $third)"; $html .= " " if ($rawnum =~ / $/); # Add space if old ISBN had space. return $html; } sub SplitUrlPunct { my ($url) = @_; my ($punct); if ($url =~ s/\"\"$//) { return ($url, ""); # Delete double-quote delimiters here } $punct = ""; ############### ### replaced by gypark ### ÇѱÛÀÌ Æ÷ÇÔµÈ ÀÎÅÍÀ§Å°¿¡¼­ ÀϺΠÇѱÛÀ» ÀνÄÇÏÁö ¸øÇÏ´Â ¹®Á¦ ÇØ°á ### from http://whitejames.x-y.net/cgi-bin/jofcgi/wiki/wiki.pl?ÇÁ·Î±×·¡¹ÖÆÁ/Wiki # ($punct) = ($url =~ /([^a-zA-Z0-9\/\xc0-\xff]+)$/); # $url =~ s/([^a-zA-Z0-9\/\xc0-\xff]+)$//; ($punct) = ($url =~ /([^a-zA-Z0-9\/\x80-\xff]+)$/); $url =~ s/([^a-zA-Z0-9\/\x80-\xff]+)$//; ### ############### return ($url, $punct); } sub StripUrlPunct { my ($url) = @_; my ($junk); ($url, $junk) = &SplitUrlPunct($url); return $url; } sub WikiHeadingNumber { my ($depth,$text) = @_; my ($anchor, $number); return '' unless --$depth > 0; # Don't number H1s because it looks stupid while (scalar @HeadingNumbers < ($depth-1)) { push @HeadingNumbers, 1; $TableOfContents .= '

    '; } if (scalar @HeadingNumbers < $depth) { push @HeadingNumbers, 0; $TableOfContents .= '
    '; } while (scalar @HeadingNumbers > $depth) { pop @HeadingNumbers; $TableOfContents .= "
    \n\n"; } $HeadingNumbers[$#HeadingNumbers]++; $number = (join '.', @HeadingNumbers) . '. '; # Remove embedded links. THIS IS FRAGILE! $text = &RestoreSavedText($text); $text =~ s/\\?\<\/a\>//si; # No such page syntax $text =~ s/\(.*?)\<\/a\>/$1/si; # Cook anchor by canonicalizing $text. ############### ### replaced by gypark ### »ç¿ë¿¡ À־ Çìµå¶óÀÎ ¹®ÀÚ¿­ÀÇ ³¡´Ü¾î°¡ °°À¸¸é Á¦´ë·Î toc ¸µÅ©°¡ ### µÇÁö ¾Ê´Â ¹ö±× ÇØ°á ### from http://host9.swidc.com/~ncc1701/wiki/wiki.cgi?FAQ # $anchor = $text; # $anchor =~ s/\<.*?\>//g; # $anchor =~ s/\W/_/g; # $anchor =~ s/__+/_/g; # $anchor =~ s/^_//; # $anchor =~ s/_$//; # $anchor = '_' . (join '_', @HeadingNumbers) unless $anchor; # Last ditch effort $anchor = 'H_' . (join '_', @HeadingNumbers); ### ############### ############### ### replaced by gypark ### °³¼± ### http://whitejames.x-y.net/cgi-bin/jofcgi/wiki/wiki.pl?ÇÁ·Î±×·¡¹ÖÆÁ # $TableOfContents .= $number . &ScriptLink("$OpenPageName#$anchor",$text) . "
    \n
    "; $TableOfContents .= $number . "" . $text . "
    \n
    "; ### ############### return &StoreHref(" name=\"$anchor\"") . $number; } sub WikiHeading { my ($pre, $depth, $text) = @_; $depth = length($depth); $depth = 6 if ($depth > 6); $text =~ s/^#\s+/&WikiHeadingNumber($depth,$')/e; # $' == $POSTMATCH return $pre . "$text\n"; } sub RestoreSavedText { my ($text) = @_; $text =~ s/$FS(\d+)$FS/$SaveUrl{$1}/ge; # Restore saved text $text =~ s/$FS(\d+)$FS/$SaveUrl{$1}/ge; # Restore nested saved text return $text; } # ==== Difference markup and HTML ==== sub GetDiffHTML { my ($diffType, $id, $revOld, $revNew, $newText) = @_; my ($html, $diffText, $diffTextTwo, $priorName, $links, $usecomma); my ($major, $minor, $author, $useMajor, $useMinor, $useAuthor, $cacheName); $links = "("; $usecomma = 0; $major = &ScriptLinkDiff(1, $id, T('major diff'), ""); $minor = &ScriptLinkDiff(2, $id, T('minor diff'), ""); $author = &ScriptLinkDiff(3, $id, T('author diff'), ""); $useMajor = 1; $useMinor = 1; $useAuthor = 1; if ($diffType == 1) { $priorName = T('major'); $cacheName = 'major'; $useMajor = 0; } elsif ($diffType == 2) { $priorName = T('minor'); $cacheName = 'minor'; $useMinor = 0; } elsif ($diffType == 3) { $priorName = T('author'); $cacheName = 'author'; $useAuthor = 0; } if ($revOld ne "") { # Note: OpenKeptRevisions must have been done by caller. # Later optimize if same as cached revision $diffText = &GetKeptDiff($newText, $revOld, 1); # 1 = get lock if ($diffText eq "") { $diffText = T('(The revisions are identical or unavailable.)'); } } else { $diffText = &GetCacheDiff($cacheName); } $useMajor = 0 if ($useMajor && ($diffText eq &GetCacheDiff("major"))); $useMinor = 0 if ($useMinor && ($diffText eq &GetCacheDiff("minor"))); $useAuthor = 0 if ($useAuthor && ($diffText eq &GetCacheDiff("author"))); $useMajor = 0 if ((!defined(&GetPageCache('oldmajor'))) || (&GetPageCache("oldmajor") < 1)); $useAuthor = 0 if ((!defined(&GetPageCache('oldauthor'))) || (&GetPageCache("oldauthor") < 1)); if ($useMajor) { $links .= $major; $usecomma = 1; } if ($useMinor) { $links .= ", " if ($usecomma); $links .= $minor; $usecomma = 1; } if ($useAuthor) { $links .= ", " if ($usecomma); $links .= $author; } if (!($useMajor || $useMinor || $useAuthor)) { $links .= T('no other diffs'); } $links .= ")"; if ((!defined($diffText)) || ($diffText eq "")) { $diffText = T('No diff available.'); } if ($revOld ne "") { my $currentRevision = T('Current Revision'); $currentRevision = Ts('Revision %s', $revNew) if $revNew; ############### ### added by gypark ### ¹ø¿ªÀÇ ÆíÀǸ¦ À§ÇÏ¿© my $fromRevision = Ts('Revision %s', $revOld); ### ############### $html = '' . Ts('(Difference from %s', $fromRevision) . " " . Ts('to %s)', $currentRevision) . "\n$links
    " . &DiffToHTML($diffText); } else { if (($diffType != 2) && ((!defined(&GetPageCache("old$cacheName"))) || (&GetPageCache("old$cacheName") < 1))) { $html = '' . Ts('No diff available--this is the first %s revision.', $priorName) . "\n$links
    "; } else { $html = '' . Ts('Difference (from prior %s revision)', $priorName) . "\n$links
    " . &DiffToHTML($diffText) . "
    \n"; } } ############### ### added by gypark ### {{{ }}} 󸮸¦ À§ÇØ Ãß°¡. Àӽà ű׸¦ ¿ø·¡´ë·Î º¹¿ø ### diff È­¸é¿¡¼­µµ \\ ¿Í \ 󸮸¦ ÇØ ÁÖ´Â °Ô ³ªÀ»·Á³ª? $html =~ s/&__LT__;/</g; $html =~ s/&__GT__;/>/g; $html =~ s/&__AMP__;/&/g; ### ############### return $html; } sub GetCacheDiff { my ($type) = @_; my ($diffText); $diffText = &GetPageCache("diff_default_$type"); $diffText = &GetCacheDiff('minor') if ($diffText eq "1"); $diffText = &GetCacheDiff('major') if ($diffText eq "2"); return $diffText; } # Must be done after minor diff is set and OpenKeptRevisions called sub GetKeptDiff { my ($newText, $oldRevision, $lock) = @_; my (%sect, %data, $oldText); $oldText = ""; if (defined($KeptRevisions{$oldRevision})) { %sect = split(/$FS2/, $KeptRevisions{$oldRevision}, -1); %data = split(/$FS3/, $sect{'data'}, -1); $oldText = $data{'text'}; } return "" if ($oldText eq ""); # Old revision not found return &GetDiff($oldText, $newText, $lock); } sub GetDiff { my ($old, $new, $lock) = @_; my ($diff_out, $oldName, $newName); &CreateDir($TempDir); $oldName = "$TempDir/old_diff"; $newName = "$TempDir/new_diff"; if ($lock) { &RequestDiffLock() or return ""; $oldName .= "_locked"; $newName .= "_locked"; } &WriteStringToFile($oldName, $old); &WriteStringToFile($newName, $new); ############### ### replaced by gypark ### diff Ãâ·Â °³¼± # $diff_out = `diff $oldName $newName`; $diff_out = `diff -u $oldName $newName`; if ($diff_out eq "") { $diff_out = `diff $oldName $newName`; } ### ############### &ReleaseDiffLock() if ($lock); $diff_out =~ s/\\ No newline.*\n//g; # Get rid of common complaint. # No need to unlink temp files--next diff will just overwrite. return $diff_out; } ############### ### added by gypark ### diff Ãâ·Â °³¼± sub DiffToHTML { my ($html) = @_; if ($html =~ /^---/) { return &DiffToHTMLunified($html); } else { return &DiffToHTMLplain($html); } } ### ############### ############### ### replaced by gypark ### diff Ãâ·Â °³¼± # sub DiffToHTML { sub DiffToHTMLplain { ### ############### my ($html) = @_; my ($tChanged, $tRemoved, $tAdded); $tChanged = T('Changed:'); $tRemoved = T('Removed:'); $tAdded = T('Added:'); $html =~ s/\n--+//g; # Note: Need spaces before
    to be different from diff section. $html =~ s/(^|\n)(\d+.*c.*)/$1
    $tChanged $2<\/strong>
    /g; $html =~ s/(^|\n)(\d+.*d.*)/$1
    $tRemoved $2<\/strong>
    /g; $html =~ s/(^|\n)(\d+.*a.*)/$1
    $tAdded $2<\/strong>
    /g; $html =~ s/\n((<.*\n)+)/&ColorDiff($1,"ffffaf")/ge; $html =~ s/\n((>.*\n)+)/&ColorDiff($1,"cfffcf")/ge; return $html; } ############### ### added by gypark ### diff Ãâ·Â °³¼± sub DiffToHTMLunified { my ($html) = @_; my (@lines, $line, $result, $row, $td_class, $in_table, $output_exist); @lines = split("\n", $html); shift(@lines); shift(@lines); $output_exist = 0; $in_table = 0; foreach $line (@lines) { $row = ""; $line = &QuoteHtml($line); if ($line =~ /^@@ (.*)@@.*$/) { if ($in_table) { $in_table = 0; $result .= "
    \n"; } $result .= "\n
    \n"; $output_exist = 1; $in_table = 1; $row = $1; $td_class = "diffrange"; } elsif ($line =~ /^ (.*)$/) { $row = $1; $row =~ s/ / /g; $row = "= ".$row; $td_class = "diff"; } elsif ($line =~ /^-(.*)$/) { $row = $1; $row =~ s/ / /g; $row = "- ".$row; $td_class = "diffremove"; } elsif ($line =~ /^\+(.*)$/) { $row = $1; $row =~ s/ / /g; $row = "+ ".$row; $td_class = "diffadd"; } $result .= "\n"; } $result .= "
    $row
    \n" if ($output_exist); return $result; } ### ############### sub ColorDiff { my ($diff, $color) = @_; $diff =~ s/(^|\n)[<>]/$1/g; $diff = &QuoteHtml($diff); # Do some of the Wiki markup rules: %SaveUrl = (); %SaveNumUrl = (); $SaveUrlIndex = 0; $SaveNumUrlIndex = 0; $diff =~ s/$FS//g; $diff = &CommonMarkup($diff, 0, 1); # No images, all patterns $diff =~ s/$FS(\d+)$FS/$SaveUrl{$1}/ge; # Restore saved text $diff =~ s/$FS(\d+)$FS/$SaveUrl{$1}/ge; # Restore nested saved text $diff =~ s/\r?\n/
    /g; return "
    \n" . $diff . "
    \n"; } # ==== Database (Page, Section, Text, Kept, User) functions ==== sub OpenNewPage { my ($id) = @_; %Page = (); $Page{'version'} = 3; # Data format version $Page{'revision'} = 0; # Number of edited times $Page{'tscreate'} = $Now; # Set once at creation $Page{'ts'} = $Now; # Updated every edit } sub OpenNewSection { my ($name, $data) = @_; %Section = (); $Section{'name'} = $name; $Section{'version'} = 1; # Data format version $Section{'revision'} = 0; # Number of edited times $Section{'tscreate'} = $Now; # Set once at creation $Section{'ts'} = $Now; # Updated every edit $Section{'ip'} = $ENV{REMOTE_ADDR}; $Section{'host'} = ''; # Updated only for real edits (can be slow) $Section{'id'} = $UserID; $Section{'username'} = &GetParam("username", ""); $Section{'data'} = $data; $Page{$name} = join($FS2, %Section); # Replace with save? } sub OpenNewText { my ($name) = @_; # Name of text (usually "default") %Text = (); # Later consider translation of new-page message? (per-user difference?) if ($NewText ne '') { $Text{'text'} = T($NewText); } else { $Text{'text'} = T('Describe the new page here.') . "\n"; } $Text{'text'} .= "\n" if (substr($Text{'text'}, -1, 1) ne "\n"); $Text{'minor'} = 0; # Default as major edit $Text{'newauthor'} = 1; # Default as new author $Text{'summary'} = ''; &OpenNewSection("text_$name", join($FS3, %Text)); } sub GetPageFile { my ($id) = @_; return $PageDir . "/" . &GetPageDirectory($id) . "/$id.db"; } sub OpenPage { my ($id) = @_; my ($fname, $data); if ($OpenPageName eq $id) { return; } %Section = (); %Text = (); $fname = &GetPageFile($id); if (-f $fname) { $data = &ReadFileOrDie($fname); %Page = split(/$FS1/, $data, -1); # -1 keeps trailing null fields } else { &OpenNewPage($id); } if ($Page{'version'} != 3) { &UpdatePageVersion(); } $OpenPageName = $id; } sub OpenSection { my ($name) = @_; if (!defined($Page{$name})) { &OpenNewSection($name, ""); } else { %Section = split(/$FS2/, $Page{$name}, -1); } } sub OpenText { my ($name) = @_; if (!defined($Page{"text_$name"})) { &OpenNewText($name); } else { &OpenSection("text_$name"); %Text = split(/$FS3/, $Section{'data'}, -1); } } sub OpenDefaultText { &OpenText('default'); } # Called after OpenKeptRevisions sub OpenKeptRevision { my ($revision) = @_; %Section = split(/$FS2/, $KeptRevisions{$revision}, -1); %Text = split(/$FS3/, $Section{'data'}, -1); } sub GetPageCache { my ($name) = @_; return $Page{"cache_$name"}; } # Always call SavePage within a lock. sub SavePage { my $file = &GetPageFile($OpenPageName); $Page{'revision'} += 1; # Number of edited times $Page{'ts'} = $Now; # Updated every edit &CreatePageDir($PageDir, $OpenPageName); &WriteStringToFile($file, join($FS1, %Page)); } sub SaveSection { my ($name, $data) = @_; $Section{'revision'} += 1; # Number of edited times $Section{'ts'} = $Now; # Updated every edit $Section{'ip'} = $ENV{REMOTE_ADDR}; $Section{'id'} = $UserID; $Section{'username'} = &GetParam("username", ""); $Section{'data'} = $data; $Page{$name} = join($FS2, %Section); } sub SaveText { my ($name) = @_; &SaveSection("text_$name", join($FS3, %Text)); } sub SaveDefaultText { &SaveText('default'); } sub SetPageCache { my ($name, $data) = @_; $Page{"cache_$name"} = $data; } sub UpdatePageVersion { &ReportError(T('Bad page version (or corrupt page).')); } sub KeepFileName { return $KeepDir . "/" . &GetPageDirectory($OpenPageName) . "/$OpenPageName.kp"; } sub SaveKeepSection { my $file = &KeepFileName(); my $data; ############### ### replaced by gypark ### ÆäÀÌÁö »èÁ¦ ½Ã¿¡ keep È­ÀÏÀº º¸Á¸ÇØ µÒ # return if ($Section{'revision'} < 1); # Don't keep "empty" revision if ($Section{'revision'} < 1) { if (-f $file) { unlink($file) || die "error while removing obsolete keep file [$file]"; } return; } ### ############### $Section{'keepts'} = $Now; $data = $FS1 . join($FS2, %Section); &CreatePageDir($KeepDir, $OpenPageName); &AppendStringToFile($file, $data); } sub ExpireKeepFile { my ($fname, $data, @kplist, %tempSection, $expirets); my ($anyExpire, $anyKeep, $expire, %keepFlag, $sectName, $sectRev); my ($oldMajor, $oldAuthor); $fname = &KeepFileName(); return if (!(-f $fname)); $data = &ReadFileOrDie($fname); @kplist = split(/$FS1/, $data, -1); # -1 keeps trailing null fields return if (length(@kplist) < 1); # Also empty shift(@kplist) if ($kplist[0] eq ""); # First can be empty return if (length(@kplist) < 1); # Also empty %tempSection = split(/$FS2/, $kplist[0], -1); if (!defined($tempSection{'keepts'})) { # die("Bad keep file." . join("|", %tempSection)); return; } $expirets = $Now - ($KeepDays * 24 * 60 * 60); return if ($tempSection{'keepts'} >= $expirets); # Nothing old enough $anyExpire = 0; $anyKeep = 0; %keepFlag = (); $oldMajor = &GetPageCache('oldmajor'); $oldAuthor = &GetPageCache('oldauthor'); foreach (reverse @kplist) { %tempSection = split(/$FS2/, $_, -1); $sectName = $tempSection{'name'}; $sectRev = $tempSection{'revision'}; $expire = 0; if ($sectName eq "text_default") { if (($KeepMajor && ($sectRev == $oldMajor)) || ($KeepAuthor && ($sectRev == $oldAuthor))) { $expire = 0; } elsif ($tempSection{'keepts'} < $expirets) { $expire = 1; } } else { if ($tempSection{'keepts'} < $expirets) { $expire = 1; } } if (!$expire) { $keepFlag{$sectRev . "," . $sectName} = 1; $anyKeep = 1; } else { $anyExpire = 1; } } if (!$anyKeep) { # Empty, so remove file unlink($fname); return; } return if (!$anyExpire); # No sections expired open (OUT, ">$fname") or die (Ts('cant write %s', $fname) . ": $!"); foreach (@kplist) { %tempSection = split(/$FS2/, $_, -1); $sectName = $tempSection{'name'}; $sectRev = $tempSection{'revision'}; if ($keepFlag{$sectRev . "," . $sectName}) { print OUT $FS1, $_; } } close(OUT); } sub OpenKeptList { my ($fname, $data); @KeptList = (); $fname = &KeepFileName(); return if (!(-f $fname)); $data = &ReadFileOrDie($fname); @KeptList = split(/$FS1/, $data, -1); # -1 keeps trailing null fields } sub OpenKeptRevisions { my ($name) = @_; # Name of section my ($fname, $data, %tempSection); %KeptRevisions = (); &OpenKeptList(); ############### ### added by gypark ### ÃÖ±Ùº¯°æ³»¿ª¿¡ ºÏ¸¶Å© ±â´É µµÀÔ %RevisionTs = (); ### ############### foreach (@KeptList) { %tempSection = split(/$FS2/, $_, -1); next if ($tempSection{'name'} ne $name); $KeptRevisions{$tempSection{'revision'}} = $_; ############### ### added by gypark ### ÃÖ±Ùº¯°æ³»¿ª¿¡ ºÏ¸¶Å© ±â´É µµÀÔ $RevisionTs{$tempSection{'revision'}} = $tempSection{'ts'}; ### ############### } } sub LoadUserData { my ($data, $status); %UserData = (); ($status, $data) = &ReadFile(&UserDataFilename($UserID)); if (!$status) { $UserID = 112; # Could not open file. Later warning message? return; } %UserData = split(/$FS1/, $data, -1); # -1 keeps trailing null fields ############### ### added by gypark ### °ü½É ÆäÀÌÁö %UserInterest = split(/$FS2/, $UserData{'interest'}, -1); ### ############### } sub UserDataFilename { my ($id) = @_; return $UserDir . "/" . "$id.db"; } # ==== Misc. functions ==== sub ReportError { my ($errmsg) = @_; print $q->header, "

    ", $errmsg, "

    ", $q->end_html; } sub ValidId { my ($id) = @_; if (length($id) > 120) { return Ts('Page name is too long: %s', $id); } if ($id =~ m| |) { return Ts('Page name may not contain space characters: %s', $id); } if ($UseSubpage) { if ($id =~ m|.*/.*/|) { return Ts('Too many / characters in page %s', $id); } if ($id =~ /^\//) { return Ts('Invalid Page %s (subpage without main page)', $id); } if ($id =~ /\/$/) { return Ts('Invalid Page %s (missing subpage name)', $id); } } if ($FreeLinks) { $id =~ s/ /_/g; if (!$UseSubpage) { if ($id =~ /\//) { return Ts('Invalid Page %s (/ not allowed)', $id); } } if (!($id =~ m|^$FreeLinkPattern$|)) { return Ts('Invalid Page %s', $id); } if ($id =~ m|\.db$|) { return Ts('Invalid Page %s (must not end with .db)', $id); } if ($id =~ m|\.lck$|) { return Ts('Invalid Page %s (must not end with .lck)', $id); } return ""; } else { if (!($id =~ /^$LinkPattern$/)) { return Ts('Invalid Page %s', $id); } } return ""; } sub ValidIdOrDie { my ($id) = @_; my $error; $error = &ValidId($id); if ($error ne "") { &ReportError($error); return 0; } return 1; } sub UserCanEdit { my ($id, $deepCheck) = @_; ############### ### added by gypark ### hide page if (($id ne "") && (&PageIsHidden($id))) { return 0; } ### ############### # Optimized for the "everyone can edit" case (don't check passwords) if (($id ne "") && (-f &GetLockedPageFile($id))) { return 1 if (&UserIsAdmin()); # Requires more privledges # Later option for editor-level to edit these pages? return 0; } if (!$EditAllowed) { return 1 if (&UserIsEditor()); return 0; } if (-f "$DataDir/noedit") { return 1 if (&UserIsEditor()); return 0; } if ($deepCheck) { # Deeper but slower checks (not every page) return 1 if (&UserIsEditor()); return 0 if (&UserIsBanned()); } return 1; } sub UserIsBanned { my ($host, $ip, $data, $status); ($status, $data) = &ReadFile("$DataDir/banlist"); return 0 if (!$status); # No file exists, so no ban $ip = $ENV{'REMOTE_ADDR'}; $host = &GetRemoteHost(0); foreach (split(/\n/, $data)) { next if ((/^\s*$/) || (/^#/)); # Skip empty, spaces, or comments return 1 if ($ip =~ /$_/i); return 1 if ($host =~ /$_/i); } return 0; } sub UserIsAdmin { my (@pwlist, $userPassword); return 0 if ($AdminPass eq ""); $userPassword = &GetParam("adminpw", ""); return 0 if ($userPassword eq ""); foreach (split(/\s+/, $AdminPass)) { next if ($_ eq ""); ############### ### replaced by gypark ### ¾ÏÈ£¸¦ ¾ÏÈ£È­ÇØ¼­ ÀúÀå ### from Bab2's patch # return 1 if ($userPassword eq $_); return 1 if (crypt($_, $userPassword) eq $userPassword); ### ############### } return 0; } sub UserIsEditor { my (@pwlist, $userPassword); return 1 if (&UserIsAdmin()); # Admin includes editor return 0 if ($EditPass eq ""); $userPassword = &GetParam("adminpw", ""); # Used for both return 0 if ($userPassword eq ""); foreach (split(/\s+/, $EditPass)) { next if ($_ eq ""); ############### ### replaced by gypark ### ¾ÏÈ£¸¦ ¾ÏÈ£È­ÇØ¼­ ÀúÀå ### from Bab2's patch # return 1 if ($userPassword eq $_); return 1 if (crypt($_, $userPassword) eq $userPassword); ### ############### } return 0; } sub GetLockedPageFile { my ($id) = @_; return $PageDir . "/" . &GetPageDirectory($id) . "/$id.lck"; } sub RequestLockDir { my ($name, $tries, $wait, $errorDie) = @_; my ($lockName, $n); &CreateDir($TempDir); $lockName = $LockDir . $name; $n = 0; while (mkdir($lockName, 0555) == 0) { if ($! != 17) { die(Ts('can not make %s', $LockDir) . ": $!\n") if $errorDie; return 0; } return 0 if ($n++ >= $tries); sleep($wait); } return 1; } sub ReleaseLockDir { my ($name) = @_; rmdir($LockDir . $name); } sub RequestLock { # 10 tries, 3 second wait, die on error return &RequestLockDir("main", 10, 3, 1); } sub ReleaseLock { &ReleaseLockDir('main'); } sub ForceReleaseLock { my ($name) = @_; my $forced; # First try to obtain lock (in case of normal edit lock) # 5 tries, 3 second wait, do not die on error $forced = !&RequestLockDir($name, 5, 3, 0); &ReleaseLockDir($name); # Release the lock, even if we didn't get it. return $forced; } sub RequestCacheLock { # 4 tries, 2 second wait, do not die on error return &RequestLockDir('cache', 4, 2, 0); } sub ReleaseCacheLock { &ReleaseLockDir('cache'); } sub RequestDiffLock { # 4 tries, 2 second wait, do not die on error return &RequestLockDir('diff', 4, 2, 0); } sub ReleaseDiffLock { &ReleaseLockDir('diff'); } # Index lock is not very important--just return error if not available sub RequestIndexLock { # 1 try, 2 second wait, do not die on error return &RequestLockDir('index', 1, 2, 0); } sub ReleaseIndexLock { &ReleaseLockDir('index'); } sub ReadFile { my ($fileName) = @_; my ($data); local $/ = undef; # Read complete files if (open(IN, "<$fileName")) { $data=; close IN; return (1, $data); } return (0, ""); } sub ReadFileOrDie { my ($fileName) = @_; my ($status, $data); ($status, $data) = &ReadFile($fileName); if (!$status) { die(Ts('Can not open %s', $fileName) . ": $!"); } return $data; } sub WriteStringToFile { my ($file, $string) = @_; open (OUT, ">$file") or die(Ts('cant write %s', $file) . ": $!"); print OUT $string; close(OUT); } sub AppendStringToFile { my ($file, $string) = @_; open (OUT, ">>$file") or die(Ts('cant write %s', $file) . ": $!"); print OUT $string; close(OUT); } sub CreateDir { my ($newdir) = @_; ############### ### replaced by gypark ### µð·ºÅ丮 »ý¼º¿¡ ½ÇÆÐÇÒ °æ¿ì ¿¡·¯ Ãâ·Â # mkdir($newdir, 0775) if (!(-d $newdir)); if (!(-d $newdir)) { mkdir($newdir, 0775) or die(Ts('cant create directory %s', $newdir) . ": $!"); } ### ############### } sub CreatePageDir { my ($dir, $id) = @_; my $subdir; &CreateDir($dir); # Make sure main page exists $subdir = $dir . "/" . &GetPageDirectory($id); &CreateDir($subdir); if ($id =~ m|([^/]+)/|) { $subdir = $subdir . "/" . $1; &CreateDir($subdir); } } sub UpdateHtmlCache { my ($id, $html) = @_; my $idFile; $idFile = &GetHtmlCacheFile($id); &CreatePageDir($HtmlDir, $id); if (&RequestCacheLock()) { &WriteStringToFile($idFile, $html); &ReleaseCacheLock(); } } sub GenerateAllPagesList { my (@pages, @dirs, $id, $dir, @pageFiles, @subpageFiles, $subId); @pages = (); if ($FastGlob) { # The following was inspired by the FastGlob code by Marc W. Mengel. # Thanks to Bob Showalter for pointing out the improvement. opendir(PAGELIST, $PageDir); @dirs = readdir(PAGELIST); closedir(PAGELIST); @dirs = sort(@dirs); foreach $dir (@dirs) { next if (($dir eq '.') || ($dir eq '..')); opendir(PAGELIST, "$PageDir/$dir"); @pageFiles = readdir(PAGELIST); closedir(PAGELIST); foreach $id (@pageFiles) { next if (($id eq '.') || ($id eq '..')); if (substr($id, -3) eq '.db') { push(@pages, substr($id, 0, -3)); } elsif (substr($id, -4) ne '.lck') { opendir(PAGELIST, "$PageDir/$dir/$id"); @subpageFiles = readdir(PAGELIST); closedir(PAGELIST); foreach $subId (@subpageFiles) { if (substr($subId, -3) eq '.db') { push(@pages, "$id/" . substr($subId, 0, -3)); } } } } } } else { # Old slow/compatible method. @dirs = qw(A B C D E F G H I J K L M N O P Q R S T U V W X Y Z other); foreach $dir (@dirs) { if (-e "$PageDir/$dir") { # Thanks to Tim Holt while (<$PageDir/$dir/*.db $PageDir/$dir/*/*.db>) { s|^$PageDir/||; m|^[^/]+/(\S*).db|; $id = $1; push(@pages, $id); } } } } return sort(@pages); } sub AllPagesList { my ($rawIndex, $refresh, $status); if (!$UseIndex) { ### hide page by gypark # return &GenerateAllPagesList(); return &GetNotHiddenPages(&GenerateAllPagesList()); ### } $refresh = &GetParam("refresh", 0); if ($IndexInit && !$refresh) { # Note for mod_perl: $IndexInit is reset for each query # Eventually consider some timestamp-solution to keep cache? ### hide page by gypark # return @IndexList; return &GetNotHiddenPages(@IndexList); ### } if ((!$refresh) && (-f $IndexFile)) { ($status, $rawIndex) = &ReadFile($IndexFile); if ($status) { %IndexHash = split(/\s+/, $rawIndex); @IndexList = sort(keys %IndexHash); $IndexInit = 1; ### hide page by gypark # return @IndexList; return &GetNotHiddenPages(@IndexList); ### } # If open fails just refresh the index } @IndexList = (); %IndexHash = (); @IndexList = &GenerateAllPagesList(); foreach (@IndexList) { $IndexHash{$_} = 1; } $IndexInit = 1; # Initialized for this run of the script # Try to write out the list for future runs &RequestIndexLock() or return @IndexList; &WriteStringToFile($IndexFile, join(" ", %IndexHash)); &ReleaseIndexLock(); ### hide page by gypark # return @IndexList; return &GetNotHiddenPages(@IndexList); ### } sub CalcDay { my ($ts) = @_; $ts += $TimeZoneOffset; my ($sec, $min, $hour, $mday, $mon, $year) = localtime($ts); return ($year + 1900) . "-" . ($mon+1) . "-" . $mday; # luke added return ("January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December")[$mon]. " " . $mday . ", " . ($year+1900); } sub CalcDayNow { return CalcDay($Now); } sub CalcTime { my ($ts) = @_; my ($ampm, $mytz); $ts += $TimeZoneOffset; my ($sec, $min, $hour, $mday, $mon, $year) = localtime($ts); $mytz = ""; if (($TimeZoneOffset == 0) && ($ScriptTZ ne "")) { $mytz = " " . $ScriptTZ; } $ampm = ""; if ($UseAmPm) { $ampm = " am"; if ($hour > 11) { $ampm = " pm"; $hour = $hour - 12; } $hour = 12 if ($hour == 0); } $min = "0" . $min if ($min<10); return $hour . ":" . $min . $ampm . $mytz; } sub TimeToText { my ($t) = @_; return &CalcDay($t) . " " . &CalcTime($t); } sub GetParam { my ($name, $default) = @_; my $result; $result = $q->param($name); if (!defined($result)) { if (defined($UserData{$name})) { $result = $UserData{$name}; } else { $result = $default; } } return $result; } sub GetHiddenValue { my ($name, $value) = @_; $q->param($name, $value); return $q->hidden($name); } sub GetRemoteHost { my ($doMask) = @_; my ($rhost, $iaddr); $rhost = $ENV{REMOTE_HOST}; if ($UseLookup && ($rhost eq "")) { # Catch errors (including bad input) without aborting the script eval 'use Socket; $iaddr = inet_aton($ENV{REMOTE_ADDR});' . '$rhost = gethostbyaddr($iaddr, AF_INET)'; } if ($rhost eq "") { $rhost = $ENV{REMOTE_ADDR}; $rhost =~ s/\d+$/xxx/ if ($doMask); # Be somewhat anonymous } return $rhost; } sub FreeToNormal { my ($id) = @_; $id =~ s/ /_/g; $id = ucfirst($id); if (index($id, '_') > -1) { # Quick check for any space/underscores $id =~ s/__+/_/g; $id =~ s/^_//; $id =~ s/_$//; if ($UseSubpage) { $id =~ s|_/|/|g; $id =~ s|/_|/|g; } } if ($FreeUpper) { # Note that letters after ' are *not* capitalized if ($id =~ m|[-_.,\(\)/][a-z]|) { # Quick check for non-canonical case $id =~ s|([-_.,\(\)/])([a-z])|$1 . uc($2)|ge; } } return $id; } #END_OF_BROWSE_CODE # == Page-editing and other special-action code ======================== $OtherCode = ""; # Comment next line to always compile (slower) #$OtherCode = <<'#END_OF_OTHER_CODE'; # luke added sub DoPreview { $ClickEdit = 0; print &GetHttpHeader(); print &GetHtmlHeader("$SiteName: " . T('Preview'), "Preview"); ############### ### replaced by gypark ### ¹Ì¸®º¸±â¿¡¼­ µîÀÇ preprocessor »ç¿ë # print &WikiToHTML(&GetParam("text", undef)); my ($textPreview) = &GetParam("text", undef); print &WikiToHTML(&ProcessPostMacro($textPreview)); ### ############### } ############### ### replaceed by gypark ### µµ¿ò¸» º°µµÀÇ È­ÀÏ·Î ºÐ¸® sub DoHelp { my $idx = &GetParam("index", ""); require mod_edithelp; use vars qw(@HelpItem @HelpText); my $title = T("$HelpItem[$idx]"); my $text; $text = "== $title ==\n"; $text .= $HelpText[$idx]; $ClickEdit = 0; $UseEmoticon = 1; print &GetHttpHeader(); print &GetHtmlHeader(T('Editing Help :'). " $title", "$title"); print &WikiToHTML($text); } ### ############### sub DoOtherRequest { my ($id, $action, $text, $search); $ClickEdit = 0; # luke added $action = &GetParam("action", ""); $id = &GetParam("id", ""); if ($action ne "") { $action = lc($action); if ($action eq "edit") { &DoEdit($id, 0, 0, "", 0) if &ValidIdOrDie($id); } elsif ($action eq "unlock") { &DoUnlock(); } elsif ($action eq "index") { &DoIndex(); ############### ### added by gypark ### titleindex action Ãß°¡ ### from Bab2's patch } elsif ($action eq "titleindex") { &DoTitleIndex(); ### ############### } elsif ($action eq "help") { # luke added &DoHelp(); # luke added } elsif ($action eq "preview") { # luke added &DoPreview(); # luke added } elsif ($action eq "links") { &DoLinks(); } elsif ($action eq "maintain") { &DoMaintain(); } elsif ($action eq "pagelock") { &DoPageLock(); } elsif ($action eq "editlock") { &DoEditLock(); } elsif ($action eq "editprefs") { &DoEditPrefs(); } elsif ($action eq "editbanned") { &DoEditBanned(); } elsif ($action eq "editlinks") { &DoEditLinks(); } elsif ($action eq "login") { &DoEnterLogin(); } elsif ($action eq "logout") { &DoLogout(); } elsif ($action eq "newlogin") { $UserID = 0; &DoEditPrefs(); # Also creates new ID } elsif ($action eq "version") { &DoShowVersion(); ############### ### added by gypark ### ÃÖ±Ùº¯°æ³»¿ª¿¡ ºÏ¸¶Å© ±â´É µµÀÔ } elsif ($action eq "bookmark") { &DoBookmark(); ### file upload } elsif ($action eq "upload") { &DoUpload(); ### oekaki } elsif ($action eq "oekaki") { &DoOekaki(); ### °ü½É ÆäÀÌÁö } elsif ($action eq "interest") { &DoInterest(); ### UploadedFiles ¸ÅÅ©·Î } elsif ($action eq "deleteuploadedfiles") { &DoDeleteUploadedFiles(); ### hide page by gypark } elsif ($action eq "pagehide") { &DoPageHide(); ### ############### } else { # Later improve error reporting &ReportError(Ts('Invalid action parameter %s', $action)); } return; } if (&GetParam("edit_prefs", 0)) { &DoUpdatePrefs(); return; } if (&GetParam("edit_ban", 0)) { &DoUpdateBanned(); return; } if (&GetParam("enter_login", 0)) { &DoLogin(); return; } if (&GetParam("edit_links", 0)) { &DoUpdateLinks(); return; } $search = &GetParam("search", ""); if (($search ne "") || (&GetParam("dosearch", "") ne "")) { &DoSearch($search); return; } ############### ### added by gypark ### ¿ª¸µÅ© $search = &GetParam("reverse", ""); if ($search ne "") { &DoReverse($search); return; } ### ############### # Handle posted pages if (&GetParam("oldtime", "") ne "") { $id = &GetParam("title", ""); &DoPost() if &ValidIdOrDie($id); return; } # Later improve error message &ReportError(T('Invalid URL.')); } sub DoEdit { my ($id, $isConflict, $oldTime, $newText, $preview) = @_; my ($header, $editRows, $editCols, $userName, $revision, $oldText); my ($summary, $isEdit, $pageTime); ############### ### added by gypark ### view action Ãß°¡ my $canEdit = &UserCanEdit($id,1); ### ############### ############### ### commented by gypark ### view action Ãß°¡ # if (!&UserCanEdit($id, 1)) { # print &GetHeader("", T('Editing Denied'), ""); # if (&UserIsBanned()) { # print T('Editing not allowed: user, ip, or network is blocked.'); # print "

    "; # print T('Contact the wiki administrator for more information.'); # } else { ### ¼öÁ¤ ºÒ°¡¸¦ ¾Ë¸®´Â ¸Þ¼¼Áö¿¡, »çÀÌÆ® Á¦¸ñÀÌ ¾Æ´Ï¶ó ### ÇØ´ç ÆäÀÌÁö¸íÀÌ ³ª¿Àµµ·Ï ¼öÁ¤ # print Ts('Editing not allowed: %s is read-only.', $SiteName); # print Ts('Editing not allowed: %s is read-only.', $id); # } # print &GetCommonFooter(); # return; # } ### ############### # Consider sending a new user-ID cookie if user does not have one &OpenPage($id); &OpenDefaultText(); $pageTime = $Section{'ts'}; $header = Ts('Editing %s', $id); ############### ### added by gypark ### view action Ãß°¡ $header = Ts('Viewing %s', $id) if (!$canEdit); ### ############### # Old revision handling $revision = &GetParam('revision', ''); $revision =~ s/\D//g; # Remove non-numeric chars if ($revision ne '') { &OpenKeptRevisions('text_default'); if (!defined($KeptRevisions{$revision})) { $revision = ''; # Later look for better solution, like error message? } else { &OpenKeptRevision($revision); $header = Ts('Editing revision %s of', $revision) . " $id"; ############### ### added by gypark ### view action Ãß°¡ $header = Ts('Viewing revision %s of', $revision) . " $id" if (!$canEdit); ### ############### } } $oldText = $Text{'text'}; if ($preview && !$isConflict) { $oldText = $newText; } $editRows = &GetParam("editrows", 20); $editCols = &GetParam("editcols", 65); print &GetHeader('', &QuoteHtml($header), ''); ############### ### added by gypark ### hide page if (&PageIsHidden($id)) { print Ts('%s is a hidden page', $id); print &GetCommonFooter(); return; } ### ############### ############### ### added by gypark ### view action Ãß°¡ if (!$canEdit) { if (&UserIsBanned()) { print T('Editing not allowed: user, ip, or network is blocked.'); print "

    "; print T('Contact the wiki administrator for more information.'); } else { print Ts('Editing not allowed: %s is read-only.', $id); } print "
    \n"; } ### ############### ############### ### replaced by gypark ### view action Ãß°¡ # if ($revision ne '') { if ($canEdit && ($revision ne '')) { ### ############### print "\n" . Ts('Editing old revision %s.', $revision) . " " . T('Saving this page will replace the latest revision with this text.') . '
    ' } ############### ### replaced by gypark ### view action Ãß°¡ # if ($isConflict) { if ($canEdit && $isConflict) { ### ############### $editRows -= 10 if ($editRows > 19); print "\n

    " . T('Edit Conflict!') . "

    \n"; if ($isConflict>1) { # The main purpose of a new warning is to display more text # and move the save button down from its old location. print "\n

    " . T('(This is a new conflict)') . "

    \n"; } print "

    ", T('Someone saved this page after you started editing.'), " ", T('The top textbox contains the saved text.'), " ", T('Only the text in the top textbox will be saved.'), "
    \n", T('Scroll down to see your edited text.'), "
    \n"; print T('Last save time:'), ' ', &TimeToText($oldTime), " (", T('Current time is:'), ' ', &TimeToText($Now), ")
    \n"; } # luke added print qq| |; ############### ### added by gypark ### file upload print qq| |; ### ############### ############### ### added by gypark ### view action Ãß°¡ if ($canEdit) { ### ############### print T('Editing Help :') . " "; ############### ### replaced by gypark ### µµ¿ò¸» º°µµÀÇ È­ÀÏ·Î ºÐ¸® # print &HelpLink(1, T('Make Page')) . " | "; # ... # print &HelpLink(5, T('Emoticon')) . "
    \n"; use vars qw(@HelpItem); require mod_edithelp; foreach (0 .. $#HelpItem) { print &HelpLink($_, T("$HelpItem[$_]")); print " | " if ($_ ne $#HelpItem); } print "
    \n"; ### ############### ############### ### added by gypark ### view action Ãß°¡ } ### ############### ############### ### replaced by gypark ### ÆíÁý¸ðµå¿¡ µé¾î°¬À»¶§ Æ÷Ä¿½º°¡ ÆíÁýâ¿¡ ÀÖµµ·Ï ÇÑ´Ù # print &GetFormStart(); print &GetFormStart("form_edit"); ### ############### ############### ### added by gypark ### view action Ãß°¡ if ($canEdit) { ### ############### print &GetHiddenValue("title", $id), "\n", &GetHiddenValue("oldtime", $pageTime), "\n", &GetHiddenValue("oldconflict", $isConflict), "\n"; if ($revision ne "") { print &GetHiddenValue("revision", $revision), "\n"; } print &GetTextArea('text', $oldText, $editRows, $editCols); $summary = &GetParam("summary", "*"); print "

    ", T('Summary:') . " ", $q->textfield(-name=>'summary', -default=>$summary, -override=>1, -size=>60, -maxlength=>200); if (&GetParam("recent_edit") eq "on") { print "
    ", $q->checkbox(-name=>'recent_edit', -checked=>1, -label=>T('This change is a minor edit.')); } else { print "
    ", $q->checkbox(-name=>'recent_edit', -label=>T('This change is a minor edit.')); } if ($EmailNotify) { print "   " . $q->checkbox(-name=> 'do_email_notify', -label=>Ts('Send email notification that %s has been changed.', $id)); } print "
    "; if ($EditNote ne '') { print T($EditNote) . '
    '; # Allow translation } print $q->submit(-name=>'Save', -value=>T('Save')), "\n"; $userName = &GetParam("username", ""); if ($userName ne "") { print ' (', T('Your user name is'), ' ', &GetPageLink($userName) . ') '; } else { print ' (', Ts('Visit %s to set your user name.', &GetPrefsLink()), ') '; } #print $q->submit(-name=>'Preview', -value=>T('Preview')); # luke delete ############### ### replaced by gypark ### ¹Ì¸®º¸±â ¹öư¿¡ ¹ø¿ªÇÔ¼ö Àû¿ë # print q(); # luke added print q(); # luke added ### ############### ############### ### added by gypark ### file upload print " ".q(); ### oekaki print " ".q(); ### ############### if ($isConflict) { print "\n


    ", T('This is the text you submitted:'), "

    ", &GetTextArea('newtext', $newText, $editRows, $editCols), "

    \n"; ############### ### added by gypark ### conflict ¹ß»ý½Ã ¾çÂÊÀÇ ÀÔ·ÂÀ» ºñ±³ my $conflictdiff = &GetDiff($oldText, $newText, 1); $conflictdiff = T('No diff available.') if ($conflictdiff eq ""); print "\n


    ", T('This is the difference between the saved text and your text:'), "

    ", &DiffToHTML($conflictdiff), "

    \n"; ### ############### } ############### ### added by gypark ### view action Ãß°¡ } else { print $q->textarea(-class=>'view', -accesskey=>'i', -name=>'text', -default=>$oldText, -rows=>$editRows, -columns=>$editCols, -override=>1, -style=>'width:100%', -wrap=>'virtual', -readonly=>'true'); } ### ############### print "

    \n"; if ($preview) { print "

    ", T('Preview:'), "

    \n"; if ($isConflict) { print "", T('NOTE: This preview shows the revision of the other author.'), "
    \n"; } $MainPage = $id; $MainPage =~ s|/.*||; # Only the main page name (remove subpage) print &WikiToHTML($oldText) . "
    \n"; print "

    ", T('Preview only, not yet saved'), "

    \n"; } ############### ### added by gypark ### ÆíÁý È­¸é ¾Æ·¡¿¡ ÆíÁýÀ» Ãë¼ÒÇÏ°í ¿ø·¡ ÆäÀÌÁö·Î µ¹¾Æ°¡´Â ¸µÅ© Ãß°¡ ### from http://whitejames.x-y.net/cgi-bin/jofcgi/wiki/wiki.pl?ÇÁ·Î±×·¡¹ÖÆÁ/Wiki print Ts('Return to %s' , &GetPageLink($id)) . " | "; ### ############### print &GetHistoryLink($id, T('View other revisions')) . "
    \n"; # print &GetGotoBar($id); print $q->endform; ############### ### added by gypark ### ÆíÁý¸ðµå¿¡ µé¾î°¬À»¶§ Æ÷Ä¿½º°¡ ÆíÁýâ¿¡ ÀÖµµ·Ï ÇÑ´Ù print "\n\n"; ### ############### print &GetMinimumFooter(); } sub GetTextArea { my ($name, $text, $rows, $cols) = @_; ############### ### added by gypark ### < ¿Í > °¡ µé¾î°¡ ÀÖ´Â ÆäÀÌÁö¸¦ ¼öÁ¤ÇÒ °æ¿ì ÀÚµ¿À¸·Î ºÎµîÈ£·Î ¹Ù²î¾î ### ¹ö¸®´Â ¹®Á¦¸¦ ÇØ°á ### from http://whitejames.x-y.net/cgi-bin/jofcgi/wiki/wiki.pl?ÇÁ·Î±×·¡¹ÖÆÁ/Wiki $text =~ s/(\&)/\&/g; ### ############### ############### ### replaced by gypark ### ÆíÁýâ¿¡ alt+i ´ÜÃàŰ Ãß°¡ # if (&GetParam("editwide", 1)) { # return $q->textarea(-name=>$name, -default=>$text, # -rows=>$rows, -columns=>$cols, -override=>1, # -style=>'width:100%', -wrap=>'virtual'); # } # return $q->textarea(-name=>$name, -default=>$text, # -rows=>$rows, -columns=>$cols, -override=>1, # -wrap=>'virtual'); if (&GetParam("editwide", 1)) { return $q->textarea(-accesskey=>'i', -name=>$name, -default=>$text, -rows=>$rows, -columns=>$cols, -override=>1, -style=>'width:100%', -wrap=>'virtual'); } return $q->textarea(-accesskey=>'i', -name=>$name, -default=>$text, -rows=>$rows, -columns=>$cols, -override=>1, -wrap=>'virtual'); ### ############### } sub DoEditPrefs { my ($check, $recentName, %labels); $recentName = $RCName; $recentName =~ s/_/ /g; &DoNewLogin() if ($UserID eq ""); print &GetHeader('', T('Editing Preferences'), ""); print &GetFormStart(); print GetHiddenValue("edit_prefs", 1), "\n"; print '' . T('User Information:') . "\n"; print '
    ' . T('UserName:') . ' ', &GetFormText('username', "", 20, 50); print ' ' . T('(blank to remove, or valid page name)'); print '
    ' . T('Set Password:') . ' ', $q->password_field(-name=>'p_password', -value=>'*', -size=>15, -maxlength=>50), ' ', T('(blank to remove password)'), '
    (', T('Passwords allow sharing preferences between multiple systems.'), ' ', T('Passwords are completely optional.'), ')'; if ($AdminPass ne '') { print '
    ', T('Administrator Password:'), ' ', $q->password_field(-name=>'p_adminpw', -value=>'*', -size=>15, -maxlength=>50), ' ', T('(blank to remove password)'), '
    ', T('(Administrator passwords are used for special maintenance.)'); } if ($EmailNotify) { print "
    "; print &GetFormCheck('notify', 1, T('Include this address in the site email list.')), ' ', T('(Uncheck the box to remove the address.)'); print '
    ', T('Email Address:'), ' ', &GetFormText('email', "", 30, 60); } print "
    $recentName:\n"; print '
    ', T('Default days to display:'), ' ', &GetFormText('rcdays', $RcDefault, 4, 9); print "
    ", &GetFormCheck('rcnewtop', $RecentTop, T('Most recent changes on top')); print "
    ", &GetFormCheck('rcall', 0, T('Show all changes (not just most recent)')); %labels = (0=>T('Hide minor edits'), 1=>T('Show minor edits'), 2=>T('Show only minor edits')); print '
    ', T('Minor edit display:'), ' '; print $q->popup_menu(-name=>'p_rcshowedit', -values=>[0,1,2], -labels=>\%labels, -default=>&GetParam("rcshowedit", $ShowEdits)); print "
    ", &GetFormCheck('rcchangehist', 1, T('Use "changes" as link to history')); if ($UseDiff) { print '
    ', T('Differences:'), "\n"; print "
    ", &GetFormCheck('diffrclink', 1, Ts('Show (diff) links on %s', $recentName)); print "
    ", &GetFormCheck('alldiff', 0, T('Show differences on all pages')); print " (", &GetFormCheck('norcdiff', 1, Ts('No differences on %s', $recentName)), ")"; %labels = (1=>T('Major'), 2=>T('Minor'), 3=>T('Author')); print '
    ', T('Default difference type:'), ' '; print $q->popup_menu(-name=>'p_defaultdiff', -values=>[1,2,3], -labels=>\%labels, -default=>&GetParam("defaultdiff", 1)); } print '
    ', T('Misc:'), "\n"; # Note: TZ offset is added by TimeToText, so pre-subtract to cancel. print '
    ', T('Server time:'), ' ', &TimeToText($Now-$TimeZoneOffset); print '
    ', T('Time Zone offset (hours):'), ' ', &GetFormText('tzoffset', 0, 4, 9); print '
    ', &GetFormCheck('editwide', 1, T('Use 100% wide edit area (if supported)')); print '
    ', T('Edit area rows:'), ' ', &GetFormText('editrows', 20, 4, 4), ' ', T('columns:'), ' ', &GetFormText('editcols', 65, 4, 4); print '
    ', &GetFormCheck('toplinkbar', 1, T('Show link bar on top')); ############### ### added by gypark ### ºó ÆäÀÌÁö ¸µÅ© ½ºÅ¸ÀÏÀ» ȯ°æ ¼³Á¤¿¡¼­ °áÁ¤ ### from Bab2's patch print '
    ', &GetFormCheck('linkstyle', $LinkFirstChar, T('Use wikiX style for the links to empty pages')); ### ############### print '
    ', &GetFormCheck('linkrandom', 0, T('Add "Random Page" link to link bar')); print '
    ', $q->submit(-name=>'Save', -value=>T('Save')), "\n"; print "\n"; print $q->endform; print &GetMinimumFooter(); } sub GetFormText { my ($name, $default, $size, $max) = @_; my $text = &GetParam($name, $default); return $q->textfield(-name=>"p_$name", -default=>$text, -override=>1, -size=>$size, -maxlength=>$max); } sub GetFormCheck { my ($name, $default, $label) = @_; my $checked = (&GetParam($name, $default) > 0); return $q->checkbox(-name=>"p_$name", -override=>1, -checked=>$checked, -label=>$label); } sub DoUpdatePrefs { my ($username, $password); ############### ### added by gypark ### ¾ÏÈ£¸¦ ¾ÏÈ£È­ÇØ¼­ ÀúÀå ### from Bab2's patch my $hashpass = ""; ### ############### # All link bar settings should be updated before printing the header &UpdatePrefCheckbox("toplinkbar"); ############### ### added by gypark ### ºó ÆäÀÌÁö ¸µÅ© ½ºÅ¸ÀÏÀ» ȯ°æ ¼³Á¤¿¡¼­ °áÁ¤ ### from Bab2's patch &UpdatePrefCheckbox("linkstyle"); ### ############### &UpdatePrefCheckbox("linkrandom"); print &GetHeader('',T('Saving Preferences'), ''); print '
    '; ############### ### replaced by gypark ### ¾ÆÀ̵ð ù±ÛÀÚ¸¦ ´ë¹®ÀÚ·Î º¯È¯ # $UserID = &GetParam("p_username", ""); # $username = &GetParam("p_username", ""); $UserID = &FreeToNormal(&GetParam("p_username", "")); $username = &FreeToNormal(&GetParam("p_username", "")); ### ############### ############### ### added by gypark ### ´Ù¸¥ »ç¿ëÀÚÀÇ È¯°æ¼³Á¤ º¯°æÀ» ±ÝÁö my ($status, $data) = &ReadFile(&UserDataFilename($UserID)); if ($status) { if ((!(&UserIsAdmin)) && ($UserData{'id'} ne $UserID)) { print T('Error: Can not update prefs. That ID already exists and does not match your ID.'). '
    '; print &GetCommonFooter(); return; } } ### ############### if ($FreeLinks) { $username =~ s/^\[\[(.+)\]\]/$1/; # Remove [[ and ]] if added $username = &FreeToNormal($username); $username =~ s/_/ /g; } ############### ### replaced by gypark ### ¾ÆÀ̵ð Ç׸ñÀ» °ø¶õÀ¸·Î ³õÁö ¸øÇÏ°Ô Çϰí, ÃÖ¼Ò 4ÀÚ ÀÌ»óÀ̾î¾ß Çϵµ·Ï Á¦ÇÑ ### based on Bab2's patch # if ($username eq "") { # print T('UserName removed.'), '
    '; # undef $UserData{'username'}; # } elsif ((!$FreeLinks) && (!($username =~ /^$LinkPattern$/))) { # print Ts('Invalid UserName %s: not saved.', $username), "
    \n"; # } elsif ($FreeLinks && (!($username =~ /^$FreeLinkPattern$/))) { # print Ts('Invalid UserName %s: not saved.', $username), "
    \n"; # } elsif (length($username) > 50) { # Too long # print T('UserName must be 50 characters or less. (not saved)'), "
    \n"; if (length($username) < 4) { print T('UserName must be 4 characters or more. (not saved)'), "
    \n"; $UserID = 0; print &ScriptLink("action=editprefs", T('Try Again')); print &GetCommonFooter(); return; } elsif ((!$FreeLinks) && (!($username =~ /^$LinkPattern$/))) { print Ts('Invalid UserName %s: not saved.', $username), "
    \n"; $UserID = 0; print &ScriptLink("action=editprefs", T('Try Again')); print &GetCommonFooter(); return; } elsif ($FreeLinks && (!($username =~ /^$FreeLinkPattern$/))) { print Ts('Invalid UserName %s: not saved.', $username), "
    \n"; $UserID = 0; print &ScriptLink("action=editprefs", T('Try Again')); print &GetCommonFooter(); return; } elsif (length($username) > 50) { # Too long print T('UserName must be 50 characters or less. (not saved)'), "
    \n"; $UserID = 0; print &ScriptLink("action=editprefs", T('Try Again')); print &GetCommonFooter(); return; ### ############### } else { print Ts('UserName %s saved.', $username), '
    '; $UserData{'username'} = $username; } $password = &GetParam("p_password", ""); ############### ### added by gypark ### ¾ÏÈ£¸¦ ¾ÏÈ£È­ÇØ¼­ ÀúÀå ### from Bab2's patch $hashpass = crypt($password, $HashKey); ### ############### if ($password eq "") { print T('Password removed.'), '
    '; undef $UserData{'password'}; } elsif ($password ne "*") { print T('Password changed.'), '
    '; ############### ### replaced by gypark ### ¾ÏÈ£¸¦ ¾ÏÈ£È­ÇØ¼­ ÀúÀå ### from Bab2's patch # $UserData{'password'} = $password; $UserData{'password'} = $hashpass; ### ############### } if ($AdminPass ne "") { $password = &GetParam("p_adminpw", ""); ############### ### added by gypark ### ¾ÏÈ£¸¦ ¾ÏÈ£È­ÇØ¼­ ÀúÀå ### from Bab2's patch $hashpass = crypt($password, $HashKey); ### ############### if ($password eq "") { print T('Administrator password removed.'), '
    '; undef $UserData{'adminpw'}; } elsif ($password ne "*") { print T('Administrator password changed.'), '
    '; ############### ### replaced by gypark ### ¾ÏÈ£¸¦ ¾ÏÈ£È­ÇØ¼­ ÀúÀå ### from Bab2's patch # $UserData{'adminpw'} = $password; $UserData{'adminpw'} = $hashpass; ### ############### if (&UserIsAdmin()) { print T('User has administrative abilities.'), '
    '; } elsif (&UserIsEditor()) { print T('User has editor abilities.'), '
    '; } else { print T('User does not have administrative abilities.'), ' ', T('(Password does not match administrative password(s).)'), '
    '; } } } if ($EmailNotify) { &UpdatePrefCheckbox("notify"); &UpdateEmailList(); } &UpdatePrefNumber("rcdays", 0, 0, 999999); &UpdatePrefCheckbox("rcnewtop"); &UpdatePrefCheckbox("rcall"); &UpdatePrefCheckbox("rcchangehist"); &UpdatePrefCheckbox("editwide"); if ($UseDiff) { &UpdatePrefCheckbox("norcdiff"); &UpdatePrefCheckbox("diffrclink"); &UpdatePrefCheckbox("alldiff"); &UpdatePrefNumber("defaultdiff", 1, 1, 3); } &UpdatePrefNumber("rcshowedit", 1, 0, 2); &UpdatePrefNumber("tzoffset", 0, -999, 999); &UpdatePrefNumber("editrows", 1, 1, 999); &UpdatePrefNumber("editcols", 1, 1, 999); print T('Server time:'), ' ', &TimeToText($Now-$TimeZoneOffset), '
    '; $TimeZoneOffset = &GetParam("tzoffset", 0) * (60 * 60); print T('Local time:'), ' ', &TimeToText($Now), '
    '; $UserData{'id'} = $UserID; &SaveUserData(); print '', T('Preferences saved.'), ''; print &GetCommonFooter(); } # add or remove email address from preferences to $DatDir/emails sub UpdateEmailList { my (@old_emails); local $/ = "\n"; # don't slurp whole files in this sub. if (my $new_email = $UserData{'email'} = &GetParam("p_email", "")) { my $notify = $UserData{'notify'}; if (-f "$DataDir/emails") { open(NOTIFY, "$DataDir/emails") or die(Ts('Could not read from %s:', "$DataDir/emails") . " $!\n"); @old_emails = ; close(NOTIFY); } else { @old_emails = (); } my $already_in_list = grep /$new_email/, @old_emails; if ($notify and (not $already_in_list)) { &RequestLock() or die(T('Could not get mail lock')); open(NOTIFY, ">>$DataDir/emails") or die(Ts('Could not append to %s:', "$DataDir/emails") . " $!\n"); print NOTIFY $new_email, "\n"; close(NOTIFY); &ReleaseLock(); } elsif ((not $notify) and $already_in_list) { &RequestLock() or die(T('Could not get mail lock')); open(NOTIFY, ">$DataDir/emails") or die(Ts('Could not overwrite %s:', "$DataDir/emails") . " $!\n"); foreach (@old_emails) { print NOTIFY "$_" unless /$new_email/; } close(NOTIFY); &ReleaseLock(); } } } sub UpdatePrefCheckbox { my ($param) = @_; my $temp = &GetParam("p_$param", "*"); $UserData{$param} = 1 if ($temp eq "on"); $UserData{$param} = 0 if ($temp eq "*"); # It is possible to skip updating by using another value, like "2" } sub UpdatePrefNumber { my ($param, $integer, $min, $max) = @_; my $temp = &GetParam("p_$param", "*"); return if ($temp eq "*"); $temp =~ s/[^-\d\.]//g; $temp =~ s/\..*// if ($integer); return if ($temp eq ""); return if (($temp < $min) || ($temp > $max)); $UserData{$param} = $temp; # Later consider returning status? } ############### ### added by gypark ### titleindex action Ãß°¡ ### from Bab2's patch sub DoTitleIndex { my (@list); my $index; print "Content-type: text/plain\n\n"; @list = &AllPagesList(); foreach $index (@list) { print $index."\r\n"; } } ### ############### sub DoIndex { print &GetHeader('', T('Index of all pages'), ''); print '
    '; &PrintPageList(&AllPagesList()); print &GetCommonFooter(); } # Create a new user file/cookie pair sub DoNewLogin { # Later consider warning if cookie already exists # (maybe use "replace=1" parameter) $SetCookie{'randkey'} = int(rand(1000000000)); $SetCookie{'rev'} = 1; %UserCookie = %SetCookie; $UserID = $SetCookie{'id'}; # The cookie will be transmitted in the next header %UserData = %UserCookie; $UserData{'createtime'} = $Now; $UserData{'createip'} = $ENV{REMOTE_ADDR}; &SaveUserData(); } sub DoEnterLogin { print &GetHeader('', T('Login'), ""); ############### ### replaced by gypark ### »ç¿ëÀÚ ¾ÆÀ̵𸦠ÀÔ·ÂÇÏ´Â ¶õ¿¡ Æ÷Ä¿½º¸¦ ÁØ´Ù # print &GetFormStart(); print &GetFormStart("form_login"); ### ############### print &ScriptLink("action=newlogin", T('Create new UserName') . "
    "); print &GetHiddenValue('enter_login', 1), "\n"; print '
    ', T('UserName:'), ' ', $q->textfield(-name=>'p_userid', -value=>'', -size=>15, -maxlength=>50); print '
    ', T('Password:'), ' ', $q->password_field(-name=>'p_password', -value=>'', -size=>15, -maxlength=>50); ############### ### added by gypark ### ·Î±äÇÒ ¶§ ÀÚµ¿ ·Î±×ÀÎ ¿©ºÎ ¼±Åà ### from Bab2's patch print '
    ', &GetFormCheck('expire', 0, T('Keep login information')); ### ############### print '
    ', $q->submit(-name=>'Login', -value=>T('Login')), "\n"; print "\n"; print $q->endform; ############### ### added by gypark ### »ç¿ëÀÚ ¾ÆÀ̵𸦠ÀÔ·ÂÇÏ´Â ¶õ¿¡ Æ÷Ä¿½º¸¦ ÁØ´Ù print "\n\n"; ### ############### print &GetMinimumFooter(); } sub DoLogin { my ($uid, $password, $success); $success = 0; ############### ### replaced by gypark ### ¾ÆÀ̵ð ù±ÛÀÚ¸¦ ¹«Á¶°Ç ´ë¹®ÀÚ·Î º¯È¯ # $uid = &GetParam("p_userid", ""); $uid = &FreeToNormal(&GetParam("p_userid", "")); ### ############### $password = &GetParam("p_password", ""); if (($password ne "") && ($password ne "*")) { $UserID = $uid; &LoadUserData(); ############### ### replaced by gypark ### ¾ÏÈ£¸¦ ¾ÏÈ£È­ÇØ¼­ ÀúÀå ### from Bab2's patch # if (defined($UserData{'password'}) && # ($UserData{'password'} eq $password)) { if (defined($UserData{'password'}) && (crypt($password, $UserData{'password'}) eq $UserData{'password'})) { ### ############### ############### ### added by gypark ### ·Î±äÇÒ ¶§ ÀÚµ¿ ·Î±×ÀÎ ¿©ºÎ ¼±Åà ### from Bab2's patch my $expire_mode = &UpdatePrefCheckbox("expire"); if ($expire_mode eq "") { $SetCookie{'expire'} = 1; } else { $SetCookie{'expire'} = $expire_mode; } ### ############### $SetCookie{'id'} = $uid; $SetCookie{'randkey'} = $UserData{'randkey'}; $SetCookie{'rev'} = 1; $success = 1; } else { $SetCookie{'id'} = ""; ############### ### added by gypark ### À߸øµÈ ¾ÆÀ̵𸦠³Ö¾úÀ» ¶§ÀÇ Ã³¸® Ãß°¡ ### from Bab2's patch $UserID = ""; &LoadUserData(); ### ############### } } ############### ### replaced by gypark ### ·Î±ä ¼º°ø ¶Ç´Â ½ÇÆÐ½ÃÀÇ ¸Þ½ÃÁö ¼öÁ¤ # print &GetHeader('', T('Login Results'), ''); # # if ($success) { # print Ts('Login for user ID %s complete.', $uid); # %UserCookie = %SetCookie; # } else { # print Ts('Login for user ID %s failed.', $uid); # %UserCookie = %SetCookie; # $UserID = ""; # } if ($success) { print &GetHeader('', T('Login completed'), ''); print Ts('Login for user ID %s complete.', $uid); %UserCookie = %SetCookie; } else { print &GetHeader('', T('Login failed'), ''); print Ts('Login for user ID %s failed.', $uid); %UserCookie = %SetCookie; $UserID = ""; print "
    " . &ScriptLink("action=login", T('Try Again')); } ### ############### print "\n"; #print &GetGotoBar(''); print $q->endform; print &GetMinimumFooter(); } sub DoLogout { my ($uid); $SetCookie{'id'} = ""; $SetCookie{'randkey'} = $UserData{'randkey'}; $SetCookie{'rev'} = 1; ############### ### replaced by gypark ### logout Á÷ÈÄ¿¡µµ »ó´Ü¸Þ´º¿¡ logout ¸µÅ©°¡ ³²¾Æ ÀÖ´Â ¹®Á¦ ÇØ°á ### ±Ùº»ÀûÀÎ Á¶Ä¡°¡ µÇÁö ¸øÇÑ´Ù. ÁÖÀÇ # print &GetHeader('', T('Logout Results'), ''); my $tempUserID = $UserID; $UserID = "113"; print &GetHeader('', T('Logout Results'), ''); $UserID = $tempUserID; ### ############### if (($UserID ne "113") && ($UserID ne "112")) { print Ts('Logout for user ID %s complete.', $UserID); } print "\n"; %UserCookie = %SetCookie; $UserID = ""; #print &GetGotoBar(''); print $q->endform; print &GetMinimumFooter(); } # Later get user-level lock sub SaveUserData { my ($userFile, $data); ############### ### added by gypark ### ¼³Ä¡ ÈÄ Ã³À½À¸·Î »ç¿ëÀÚ ¾ÆÀ̵𸦠¸¸µé ¶§ ¿¡·¯°¡ ³ª´Â °ÍÀ» ÇØ°á &CreateDir($UserDir); ### ############### $userFile = &UserDataFilename($UserID); $data = join($FS1, %UserData); &WriteStringToFile($userFile, $data); } sub DoSearch { my ($string) = @_; my @x; if ($string eq '') { &DoIndex(); return; } print &GetHeader('', &QuoteHtml(Ts('Search for: %s', $string)), ''); print '
    '; @x = &SearchTitleAndBody($string); &PrintPageList(@x); if ($#x eq -1) { print &ScriptLink("action=edit&id=$string", Ts('Create a new page : %s', $string)); } print &GetCommonFooter(); } ############### ### added by gypark sub DoReverse { my ($string) = @_; my @x = (); my $pagelines; if ($string eq '') { &DoIndex(); return; } print &GetHeader('', &QuoteHtml(Ts('Links to %s', $string)), ''); ### hide page by gypark if (&PageIsHidden($string)) { print Ts('%s is a hidden page', $string); print &GetCommonFooter(); return; } ### print '
    '; foreach $pagelines (&GetFullLinkList("page=1&inter=1&unique=1&sort=1&exists=2&empty=0&reverse=$string")) { my @pages = split(' ', $pagelines); @x = (@x, shift(@pages)); } &PrintPageList(@x); if ($#x eq -1) { print T('No reverse link.') . "
    "; } if (&ValidId($string) eq "") { print "
    "; print Ts('Return to %s' , &GetPageLink($string)) . "
    "; } print &GetCommonFooter(); } ### ############### ############### ### replaced by gypark ### ¸ñÂ÷¸¦ A,B,..,°¡,³ª,... µîÀ¸·Î ±¸ºÐÇØ¼­ Ãâ·ÂÇϵµ·Ï ÇÔ ### from http://whitejames.x-y.net/cgi-bin/jofcgi/wiki/wiki.pl?ÇÁ·Î±×·¡¹ÖÆÁ/Wiki # sub PrintPageList { # my $pagename; # # print "

    ", Ts('ÆäÀÌÁö ¼ö: %s', ($#_ + 1)), "

    \n"; # foreach $pagename (@_) { # print ".... " if ($pagename =~ m|/|); # print &GetPageLink($pagename); # # if (&UserIsAdmin()) { # print " | " . &ScriptLink("action=pagelock&set=1&id=" . $pagename, T('lock')); # print " | " . &ScriptLink("action=pagelock&set=0&id=" . $pagename, T('unlock')); # } # print "
    \n"; # } # } sub PrintPageList { my ($pagename); my $count = 0; my $titleIsPrinted = 0; my @han = qw(°¡ ³ª ´Ù ¶ó ¸¶ ¹Ù »ç ¾Æ ÀÚ Â÷ Ä« Ÿ ÆÄ ÇÏ); my @indexTitle = (0, "A".."Z"); push (@indexTitle, @han, "±âŸ"); my @indexSearch=("A".."Z"); push (@indexSearch, @han, "ËÐ"); print "

    ", Ts('%s pages found:', ($#_ + 1)), "

    \n"; ############### ### replaced by gypark ### index ¶Ç´Â °Ë»ö°á°ú âÀÇ Á¦ÀÏ »ó´Ü¿¡ ±¸ºÐÅÇ ¸µÅ©¸¦ ³ÖÀ½ # foreach $pagename(@_) { # until ( # $pagename lt @indexSearch[$count] # && ($count == 0 || $pagename gt @indexSearch[$count-1]) # ) { # $count++; # $titleIsPrinted = 0; # last if $count > 40; # } # if (!$titleIsPrinted) { # print $q->h3($indexTitle[$count]); # »ó´Ü¿¡ ¾ÞÄ¿¸¦ °¡¸®Å°´Â À妽º ³ª¿­ my $count2 = 0; print("\n|"); while ( $count2 <= $#indexTitle ) { # if ($indexTitle[$count2] == 'Z') { if ($count2 == 27) { print("
    \n|"); } print(""); print(" $indexTitle[$count2] "); print("|"); $count2++; } print "

    "; $count2 = 0; foreach $pagename(@_) { ############### ### added by gypark ### hide page next if (&PageIsHidden($pagename)); ### ############### until ( $pagename lt @indexSearch[$count] && ($count == 0 || $pagename gt @indexSearch[$count-1]) ) { $count++; $titleIsPrinted = 0; last if $count > 40; } if (!$titleIsPrinted) { # ÆäÀÌÁö°¡ ¾ø´Â »öÀÎÀÇ ¾ÞÄ¿ ó¸® while ( $count2 <= ($count - 1) ) { print "\n"; # ¾Æ·¡ ÁÖ¼®À» ÇØÁ¦ÇÏ¸é ÆäÀÌÁö°¡ ¾ø´Â »öÀεµ Çìµå¶óÀÎÀÌ ³ª¿À³ª, # »ç¿ëÇÏÁö ¾Ê´Â °ÍÀÌ ÁÁ´Ù. ¿ª¸µÅ©¸¦ »ç¿ëÇØº¸¸é ÀÌÇØ°¡ µÉ µí # print $q->h3($indexTitle[$count2]); print ""; $count2++; } # ¾ÞÄ¿¸¦ »ðÀÔ print "\n"; print $q->h3($indexTitle[$count] . " \"""); $count2 = $count + 1; ### gypark ÀÇ »öÀÎ ÆÐÄ¡ ############### $titleIsPrinted=1; } print ".... " if ($pagename =~ m|/|); print &GetPageLink($pagename); if (&UserIsAdmin()) { ############### ### added by gypark ### °ü¸®ÀÚÀÇ À妽º È­¸é¿¡¼­´Â Àá±ä ÆäÀÌÁö¸¦ º°µµ·Î Ç¥½Ã if (-f &GetLockedPageFile($pagename)) { print " " . T('(locked)'); } ### ############### print " | " . &ScriptLink("action=pagelock&set=1&id=" . $pagename, T('lock')); print " | " . &ScriptLink("action=pagelock&set=0&id=" . $pagename, T('unlock')); ############### ### added by gypark ### hide page if (defined($HiddenPage{$pagename})) { print " | " . T('(hidden)'); } print " | " . &ScriptLink("action=pagehide&set=1&id=" . $pagename, T('hide')); print " | " . &ScriptLink("action=pagehide&set=0&id=" . $pagename, T('unhide')); ### ############### } print $q->br; print "\n"; } } ### jof4002 ÀÇ index È­¸é ÆÐÄ¡ ############### sub DoLinks { print &GetHeader('', &QuoteHtml(T('Full Link List')), ''); print "
    \n";  # Extra lines to get below the logo
    	&PrintLinkList(&GetFullLinkList());
    	print "
    \n"; print &GetMinimumFooter(); } ############### ### added by gypark ### ¿ª¸µÅ©¸¦ ã´Â ÇÔ¼ö Ãß°¡ # sub MacroReverse { # my $pagelines; # my @result = (); # # foreach $pagelines (&GetFullLinkList(@_)) { # my @pages = split(' ', $pagelines); # @result = (@result, shift(@pages)); # } # return @result; # } ### ############### sub PrintLinkList { my ($pagelines, $page, $names, $editlink); my ($link, $extra, @links, %pgExists); %pgExists = (); foreach $page (&AllPagesList()) { $pgExists{$page} = 1; } $names = &GetParam("names", 1); $editlink = &GetParam("editlink", 0); foreach $pagelines (@_) { @links = (); ############### ### replaced by gypark ### full link list °³¼± # foreach $page (split(' ', $pagelines)) { my @pages = split(' ', $pagelines); foreach $page (@pages) { ### ############### if ($page =~ /\:/) { # URL or InterWiki form if ($page =~ /$UrlPattern/) { ($link, $extra) = &UrlLink($page); } else { ($link, $extra) = &InterPageLink($page); } } else { if ($pgExists{$page}) { $link = &GetPageLink($page); ############### ### added by gypark ### full link list °³¼± } elsif ($page =~ /^\// && $pgExists{(split ('/',$pages[0]))[0].$page}) { ($link, $extra) = &GetPageLinkText((split ('/',$pages[0]))[0].$page, $page); ### ############### } else { $link = $page; if ($editlink) { $link .= &GetEditLink($page, "?"); } } } push(@links, $link); } if (!$names) { shift(@links); } print join(' ', @links), "\n"; } } sub GetFullLinkList { ############### ### added by gypark ### GetFullLinkList ¿¡ ÀÎÀÚó¸® ±â´É Ãß°¡ my ($opt) = @_; my $opt_item; my %args = ( # default °ª "unique" , 1, "sort", 1, "page", 1, "inter", 0, "url", 0, "exists", 2, "empty", 0, "search", "", "reverse", "" ); foreach $opt_item (split('&',$opt)) { if ($opt_item =~ /^(.+)=(.+)$/) { $args{$1} = $2; } } ### ############### ############### ### replaceed by gypark ### ¿ª¸µÅ© °Ë»ö ¿É¼Ç Ãß°¡ # my ($name, $unique, $sort, $exists, $empty, $link, $search); my ($name, $unique, $sort, $exists, $empty, $link, $search, $reverse); ### ############### my ($pagelink, $interlink, $urllink); my (@found, @links, @newlinks, @pglist, %pgExists, %seen); ############### ### replaced by gypark ### GetFullLinkList ¿¡ ÀÎÀÚó¸® ±â´É Ãß°¡ # $unique = &GetParam("unique", 1); # $sort = &GetParam("sort", 1); # $pagelink = &GetParam("page", 1); # $interlink = &GetParam("inter", 0); # $urllink = &GetParam("url", 0); # $exists = &GetParam("exists", 2); # $empty = &GetParam("empty", 0); # $search = &GetParam("search", ""); $unique = &GetParam("unique", $args{"unique"}); $sort = &GetParam("sort", $args{"sort"}); $pagelink = &GetParam("page", $args{"page"}); $interlink = &GetParam("inter", $args{"inter"}); $urllink = &GetParam("url", $args{"url"}); $exists = &GetParam("exists", $args{"exists"}); $empty = &GetParam("empty", $args{"empty"}); $search = &GetParam("search", $args{"search"}); ### ############### ############### ### added by gypark ### ¿ª¸µÅ© ±â´É Ãß°¡ $reverse = &GetParam("reverse", $args{"reverse"}); ### ############### if (($interlink == 2) || ($urllink == 2)) { $pagelink = 0; } %pgExists = (); @pglist = &AllPagesList(); foreach $name (@pglist) { $pgExists{$name} = 1; } %seen = (); foreach $name (@pglist) { @newlinks = (); if ($unique != 2) { %seen = (); } ############### ### replaced by gypark ### ¸µÅ© ¸ñ·ÏÀ» º°µµ·Î °ü¸® # @links = &GetPageLinks($name, $pagelink, $interlink, $urllink); @links = &GetPageLinksFromFile($name, $pagelink, $interlink, $urllink); ### ############### foreach $link (@links) { $seen{$link}++; if (($unique > 0) && ($seen{$link} != 1)) { next; } ############### ### replaced by gypark ### /ÆäÀÌÁö Çü½ÄÀÇ ÇÏÀ§ÆäÀÌÁöÀÇ Á¸Àç¿¡ ´ëÇÑ ¹ö±×¼öÁ¤ # if (($exists == 0) && ($pgExists{$link} == 1)) { # next; # } # if (($exists == 1) && ($pgExists{$link} != 1)) { # next; # } my $link2 = $link; $link2 = (split ('/',$name))[0]."$link" if ($link =~ /^\//); if (($exists == 0) && ($pgExists{$link2} == 1)) { next; } if (($exists == 1) && ($pgExists{$link2} != 1)) { next; } ### ############### if (($search ne "") && !($link =~ /$search/)) { next; } ############### ### added by gypark ### ¿ª¸µÅ© ±â´É Ãß°¡ if ($reverse ne "") { my ($mainpage, $subpage) = ("", ""); if ($reverse =~ /(.+)\/(.+)/) { ($mainpage, $subpage) = ($1, $2); } if (!((split('/',$name))[0] eq $mainpage && $link eq "\/$subpage") && !($link eq $reverse)) { next; } } ### ############### push(@newlinks, $link); } @links = @newlinks; if ($sort) { @links = sort(@links); } unshift (@links, $name); if ($empty || ($#links > 0)) { # If only one item, list is empty. push(@found, join(' ', @links)); } } return @found; } sub GetPageLinks { my ($name, $pagelink, $interlink, $urllink) = @_; my ($text, @links); @links = (); &OpenPage($name); &OpenDefaultText(); $text = $Text{'text'}; $text =~ s/((.|\n)*?)<\/html>/ /ig; $text =~ s/(.|\n)*?\<\/nowiki>/ /ig; $text =~ s/
    (.|\n)*?\<\/pre>/ /ig;
    	$text =~ s/(.|\n)*?\<\/code>/ /ig;
    ###############
    ### added by gypark
    ### {{{ }}} ³»ÀÇ ³»¿ëÀº ű׷Π°£ÁÖÇÏÁö ¾ÊÀ½
    	$text =~ s/(^|\n)\{\{\{[ \t\r\f]*\n((.|\n)*?)\n\}\}\}[ \t\r\f]*\n/ \n/igm;
    	$text =~ s/(^|\n)\{\{\{([a-zA-Z0-9+]+)(\|(n|\d*|n\d+|\d+n))?[ \t\r\f]*\n((.|\n)*?)\n\}\}\}[ \t\r\f]*\n/ \n/igm;
    ###
    ###############
    	if ($interlink) {
    		$text =~ s/''+/ /g;  # Quotes can adjacent to inter-site links
    		$text =~ s/$InterLinkPattern/push(@links, &StripUrlPunct($1)), ' '/ge;
    	} else {
    		$text =~ s/$InterLinkPattern/ /g;
    	}
    	if ($urllink) {
    		$text =~ s/''+/ /g;  # Quotes can adjacent to URLs
    		$text =~ s/$UrlPattern/push(@links, &StripUrlPunct($1)), ' '/ge;
    	} else {
    		$text =~ s/$UrlPattern/ /g;
    	}
    	if ($pagelink) {
    		if ($FreeLinks) {
    			my $fl = $FreeLinkPattern;
    			$text =~ s/\[\[$fl\|[^\]]+\]\]/push(@links, &FreeToNormal($1)), ' '/ge;
    			$text =~ s/\[\[$fl\]\]/push(@links, &FreeToNormal($1)), ' '/ge;
    		}
    		if ($WikiLinks) {
    			$text =~ s/$LinkPattern/push(@links, &StripUrlPunct($1)), ' '/ge;
    		}
    	}
    	return @links;
    }
    
    sub DoPost {
    	my ($editDiff, $old, $newAuthor, $pgtime, $oldrev, $preview, $user);
    	my $string = &GetParam("text", undef);
    	my $id = &GetParam("title", "");
    	my $summary = &GetParam("summary", "");
    	my $oldtime = &GetParam("oldtime", "");
    	my $oldconflict = &GetParam("oldconflict", "");
    	my $isEdit = 0;
    	my $editTime = $Now;
    	my $authorAddr = $ENV{REMOTE_ADDR};
    
    	if (!&UserCanEdit($id, 1)) {
    		# This is an internal interface--we don't need to explain
    		&ReportError(Ts('Editing not allowed for %s.', $id));
    		return;
    	}
    
    	if (($id eq 'SampleUndefinedPage') || ($id eq T('SampleUndefinedPage'))) {
    		&ReportError(Ts('%s cannot be defined.', $id));
    		return;
    	}
    	if (($id eq 'Sample_Undefined_Page')
    			|| ($id eq T('Sample_Undefined_Page'))) {
    		&ReportError(Ts('[[%s]] cannot be defined.', $id));
    		return;
    	}
    	$string =~ s/$FS//g;
    	$summary =~ s/$FS//g;
    	$summary =~ s/[\r\n]//g;
    	# Add a newline to the end of the string (if it doesn't have one)
    	$string .= "\n"  if (!($string =~ /\n$/));
    
    	# Remove "\r"-s (0x0d) from the string
    	$string =~ s/\r//g;
    	
    ###############
    ### added by gypark
    ###  µî ±ÛÀÛ¼º Á÷ÈÄ ¼öÇàÇÒ ¸ÅÅ©·Î
    	$string = &ProcessPostMacro($string);
    ###
    ###############
    	# Lock before getting old page to prevent races
    	&RequestLock() or die(T('Could not get editing lock'));
    	# Consider extracting lock section into sub, and eval-wrap it?
    	# (A few called routines can die, leaving locks.)
    	&OpenPage($id);
    	&OpenDefaultText();
    	$old = $Text{'text'};
    	$oldrev = $Section{'revision'};
    	$pgtime = $Section{'ts'};
    
    	$preview = 0;
    	$preview = 1  if (&GetParam("Preview", "") ne "");
    	if (!$preview && ($old eq $string)) {  # No changes (ok for preview)
    		&ReleaseLock();
    		&ReBrowsePage($id, "", 1);
    		return;
    	}
    	# Later extract comparison?
    #	if (($UserID > 399) || ($Section{'id'} > 399))  {
    ###############
    ### replaced by gypark
    ### ·Î±×ÀÎ ÇÏÁö ¾ÊÀº °æ¿ìÀÇ conflict
    #	if (($UserID ne "") || ($Section{'id'} ne ""))  {
    	if (
    		(($UserID ne "") && ($UserID ne "112") && ($UserID ne "113")) ||
    		(($Section{'id'} ne "") && ($Section{'id'} ne "112") && ($Section{'id'} ne "113"))
    		) {
    ###
    ###############
    		$newAuthor = ($UserID ne $Section{'id'});       # known user(s)
    	} else {
    		$newAuthor = ($Section{'ip'} ne $authorAddr);  # hostname fallback
    	}
    	$newAuthor = 1  if ($oldrev == 0);  # New page
    	$newAuthor = 0  if (!$newAuthor);   # Standard flag form, not empty
    	# Detect editing conflicts and resubmit edit
    	if (($oldrev > 0) && ($newAuthor && ($oldtime != $pgtime))) {
    		&ReleaseLock();
    		if ($oldconflict>0) {  # Conflict again...
    			&DoEdit($id, 2, $pgtime, $string, $preview);
    		} else {
    			&DoEdit($id, 1, $pgtime, $string, $preview);
    		}
    		return;
    	}
    	if ($preview) {
    		&ReleaseLock();
    		&DoEdit($id, 0, $pgtime, $string, 1);
    		return;
    	}
    
    	$user = &GetParam("username", "");
    	# If the person doing editing chooses, send out email notification
    	if ($EmailNotify) {
    		EmailNotify($id, $user) if &GetParam("do_email_notify", "") eq 'on';
    	}
    	if (&GetParam("recent_edit", "") eq 'on') {
    		$isEdit = 1;
    	}
    	if (!$isEdit) {
    		&SetPageCache('oldmajor', $Section{'revision'});
    	}
    	if ($newAuthor) {
    		&SetPageCache('oldauthor', $Section{'revision'});
    	}
    	&SaveKeepSection();
    	&ExpireKeepFile();
    	if ($UseDiff) {
    		&UpdateDiffs($id, $editTime, $old, $string, $isEdit, $newAuthor);
    	}
    	$Text{'text'} = $string;
    	$Text{'minor'} = $isEdit;
    	$Text{'newauthor'} = $newAuthor;
    	$Text{'summary'} = $summary;
    	$Section{'host'} = &GetRemoteHost(1);
    	&SaveDefaultText();
    	&SavePage();
    ###############
    ### added by gypark
    ### ¸µÅ© ¸ñ·ÏÀ» º°µµ·Î °ü¸®
    	&SaveLinkFile($id);
    ###
    ###############
    	&WriteRcLog($id, $summary, $isEdit, $editTime, $user, $Section{'host'});
    	if ($UseCache) {
    		UnlinkHtmlCache($id);          # Old cached copy is invalid
    		if ($Page{'revision'} < 2) {   # If this is a new page...
    			&NewPageCacheClear($id);     # ...uncache pages linked to this one.
    		}
    	}
    	if ($UseIndex && ($Page{'revision'} == 1)) {
    		unlink($IndexFile);  # Regenerate index on next request
    	}
    	&ReleaseLock();
    	&ReBrowsePage($id, "", 1);
    }
    
    sub UpdateDiffs {
    	my ($id, $editTime, $old, $new, $isEdit, $newAuthor) = @_;
    	my ($editDiff, $oldMajor, $oldAuthor);
    
    	$editDiff  = &GetDiff($old, $new, 0);     # 0 = already in lock
    	$oldMajor  = &GetPageCache('oldmajor');
    	$oldAuthor = &GetPageCache('oldauthor');
    	if ($UseDiffLog) {
    		&WriteDiff($id, $editTime, $editDiff);
    	}
    	&SetPageCache('diff_default_minor', $editDiff);
    	if ($isEdit || !$newAuthor) {
    		&OpenKeptRevisions('text_default');
    	}
    	if (!$isEdit) {
    		&SetPageCache('diff_default_major', "1");
    	} else {
    		&SetPageCache('diff_default_major', &GetKeptDiff($new, $oldMajor, 0));
    	}
    	if ($newAuthor) {
    		&SetPageCache('diff_default_author', "1");
    	} elsif ($oldMajor == $oldAuthor) {
    		&SetPageCache('diff_default_author', "2");
    	} else {
    		&SetPageCache('diff_default_author', &GetKeptDiff($new, $oldAuthor, 0));
    	}
    }
    
    # Translation note: the email messages are still sent in English
    # Send an email message.
    sub SendEmail {
    	my ($to, $from, $reply, $subject, $message) = @_;
    		### debug
    		## print "Content-type: text/plain\n\n";
    		## print " to: '$to'\n";
    		## return;
    	# sendmail options:
    	#    -odq : send mail to queue (i.e. later when convenient)
    	#    -oi  : do not wait for "." line to exit
    	#    -t   : headers determine recipient.
    	open (SENDMAIL, "| $SendMail -oi -t ") or die "Can't send email: $!\n";
    	print SENDMAIL <<"EOF";
    From: $from
    To: $to
    Reply-to: $reply
    Subject: $subject\n
    $message
    EOF
    	close(SENDMAIL) or warn "sendmail didn't close nicely";
    }
    
    ## Email folks who want to know a note that a page has been modified. - JimM.
    sub EmailNotify {
    	local $/ = "\n";   # don't slurp whole files in this sub.
    	if ($EmailNotify) {
    		my ($id, $user) = @_;
    		if ($user) {
    			$user = " by $user";
    		}
    		my $address;
    		open(EMAIL, "$DataDir/emails")
    			or die "Can't open $DataDir/emails: $!\n";
    		$address = join ",", ;
    		$address =~ s/\n//g;
    		close(EMAIL);
    		my $home_url = $q->url();
    		my $page_url = $home_url . "?$id";
    		my $editors_summary = $q->param("summary");
    		if (($editors_summary eq "*") or ($editors_summary eq "")){
    			$editors_summary = "";
    		}
    		else {
    			$editors_summary = "\n Summary: $editors_summary";
    		}
    		my $content = <<"END_MAIL_CONTENT";
    
     The $SiteName page $id at
    	 $page_url
     has been changed$user to revision $Page{revision}. $editors_summary
    
     (Replying to this notification will
    	send email to the entire mailing list,
    	so only do that if you mean to.
    
    	To remove yourself from this list, visit
    	${home_url}?action=editprefs .)
    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
    		# which seems appropriate for a mailing list, especially since the
    		# $EmailFrom string needn't be a real email address.
    		&SendEmail($address, $EmailFrom, $address, $subject, $content);
    	}
    }
    
    sub SearchTitleAndBody {
    	my ($string) = @_;
    	my ($name, $freeName, @found);
    
    	foreach $name (&AllPagesList()) {
    		&OpenPage($name);
    		&OpenDefaultText();
    		if (($Text{'text'} =~ /$string/i) || ($name =~ /$string/i)) {
    			push(@found, $name);
    		} elsif ($FreeLinks && ($name =~ m/_/)) {
    			$freeName = $name;
    			$freeName =~ s/_/ /g;
    			if ($freeName =~ /$string/i) {
    				push(@found, $name);
    			}
    		}
    	}
    	return @found;
    }
    
    sub SearchBody {
    	my ($string) = @_;
    	my ($name, @found);
    
    	foreach $name (&AllPagesList()) {
    		&OpenPage($name);
    		&OpenDefaultText();
    		if ($Text{'text'} =~ /$string/i){
    			push(@found, $name);
    		}
    	}
    	return @found;
    }
    
    sub UnlinkHtmlCache {
    	my ($id) = @_;
    	my $idFile;
    
    	$idFile = &GetHtmlCacheFile($id);
    	if (-f $idFile) {
    		unlink($idFile);
    	}
    }
    
    sub NewPageCacheClear {
    	my ($id) = @_;
    	my $name;
    
    	return if (!$UseCache);
    	$id =~ s|.+/|/|;  # If subpage, search for just the subpage
    	# The following code used to search the body for the $id
    	foreach $name (&AllPagesList()) {  # Remove all to be safe
    		&UnlinkHtmlCache($name);
    	}
    }
    
    # Note: all diff and recent-list operations should be done within locks.
    sub DoUnlock {
    	my $LockMessage = T('Normal Unlock.');
    
    	print &GetHeader('', T('Removing edit lock'), '');
    	print '

    ', T('This operation may take several seconds...'), "\n"; if (&ForceReleaseLock('main')) { $LockMessage = T('Forced Unlock.'); } # Later display status of other locks? &ForceReleaseLock('cache'); &ForceReleaseLock('diff'); &ForceReleaseLock('index'); print "

    $LockMessage

    "; print &GetCommonFooter(); } # Note: all diff and recent-list operations should be done within locks. sub WriteRcLog { my ($id, $summary, $isEdit, $editTime, $name, $rhost) = @_; my ($extraTemp, %extra); %extra = (); $extra{'id'} = $UserID if ($UserID ne ""); $extra{'name'} = $name if ($name ne ""); ############### ### added by gypark ### ÃÖ±Ùº¯°æ³»¿ª¿¡ ºÏ¸¶Å© ±â´É µµÀÔ $extra{'tscreate'} = $Page{'tscreate'}; ### ############### $extraTemp = join($FS2, %extra); # The two fields at the end of a line are kind and extension-hash my $rc_line = join($FS3, $editTime, $id, $summary, $isEdit, $rhost, "0", $extraTemp); if (!open(OUT, ">>$RcFile")) { die(Ts('%s log error:', $RCName) . " $!"); } print OUT $rc_line . "\n"; close(OUT); } sub WriteDiff { my ($id, $editTime, $diffString) = @_; open (OUT, ">>$DataDir/diff_log") or die(T('can not write diff_log')); print OUT "------\n" . $id . "|" . $editTime . "\n"; print OUT $diffString; close(OUT); } sub DoMaintain { my ($name, $fname, $data); print &GetHeader('', T('Maintenance on all pages'), ''); print "
    "; $fname = "$DataDir/maintain"; if (!&UserIsAdmin()) { if ((-f $fname) && ((-M $fname) < 0.5)) { print T('Maintenance not done.'), ' '; print T('(Maintenance can only be done once every 12 hours.)'); print ' ', T('Remove the "maintain" file or wait.'); print &GetCommonFooter(); return; } } &RequestLock() or die(T('Could not get maintain-lock')); foreach $name (&AllPagesList()) { &OpenPage($name); &OpenDefaultText(); &ExpireKeepFile(); ############### ### added by gypark ### ¸µÅ© ¸ñ·ÏÀ» º°µµ·Î °ü¸® &SaveLinkFile($name); ### page count if (!(-f &GetCountFile($name))) { &CreatePageDir($CountDir, $name); # It might not exist yet &WriteStringToFile(&GetCountFile($name), "0"); } ### ############### print ".... " if ($name =~ m|/|); print &GetPageLink($name), "
    \n"; } &WriteStringToFile($fname, "Maintenance done at " . &TimeToText($Now)); &ReleaseLock(); # Do any rename/deletion commands # (Must be outside lock because it will grab its own lock) $fname = "$DataDir/editlinks"; if (-f $fname) { $data = &ReadFileOrDie($fname); print '
    ', T('Processing rename/delete commands:'), "
    \n"; &UpdateLinksList($data, 1, 1); # Always update RC and links unlink("$fname.old"); rename($fname, "$fname.old"); } print &GetCommonFooter(); } sub UserIsEditorOrError { if (!&UserIsEditor()) { print '

    ', T('This operation is restricted to site editors only...'); print &GetCommonFooter(); return 0; } return 1; } sub UserIsAdminOrError { if (!&UserIsAdmin()) { print '

    ', T('This operation is restricted to administrators only...'); print &GetCommonFooter(); return 0; } return 1; } sub DoEditLock { my ($fname); print &GetHeader('', T('Set or Remove global edit lock'), ''); return if (!&UserIsAdminOrError()); $fname = "$DataDir/noedit"; if (&GetParam("set", 1)) { &WriteStringToFile($fname, "editing locked."); } else { unlink($fname); } if (-f $fname) { print '

    ', T('Edit lock created.'), '
    '; } else { print '

    ', T('Edit lock removed.'), '
    '; } print &GetCommonFooter(); } sub DoPageLock { my ($fname, $id); print &GetHeader('', T('Set or Remove page edit lock'), ''); # Consider allowing page lock/unlock at editor level? return if (!&UserIsAdminOrError()); $id = &GetParam("id", ""); if ($id eq "") { print '

    ', T('Missing page id to lock/unlock...'); return; } return if (!&ValidIdOrDie($id)); # Later consider nicer error? $fname = &GetLockedPageFile($id); if (&GetParam("set", 1)) { &WriteStringToFile($fname, "editing locked."); } else { unlink($fname); } if (-f $fname) { print '

    ', Ts('Lock for %s created.', $id), '
    '; } else { print '

    ', Ts('Lock for %s removed.', $id), '
    '; } print &GetCommonFooter(); } sub DoEditBanned { my ($banList, $status); print &GetHeader("", "Editing Banned list", ""); return if (!&UserIsAdminOrError()); ($status, $banList) = &ReadFile("$DataDir/banlist"); $banList = "" if (!$status); print &GetFormStart(); print GetHiddenValue("edit_ban", 1), "\n"; print "Banned IP/network/host list:
    \n"; print "

    Each entry is either a commented line (starting with #), ", "or a Perl regular expression (matching either an IP address or ", "a hostname). Note: To test the ban on yourself, you must ", "give up your admin access (remove password in Preferences)."; print "

    Examples:
    ", "\\.foocorp.com\$ (blocks hosts ending with .foocorp.com)
    ", "^123.21.3.9\$ (blocks exact IP address)
    ", "^123.21.3. (blocks whole 123.21.3.* IP network)

    "; print &GetTextArea('banlist', $banList, 12, 50); print "
    ", $q->submit(-name=>'Save'), "\n"; print "

    \n"; # print &GetGotoBar(""); print $q->endform; print &GetMinimumFooter(); } sub DoUpdateBanned { my ($newList, $fname); print &GetHeader("", "Updating Banned list", ""); return if (!&UserIsAdminOrError()); $fname = "$DataDir/banlist"; $newList = &GetParam("banlist", "#Empty file"); if ($newList eq "") { print "

    Empty banned list or error."; print "

    Resubmit with at least one space character to remove."; } elsif ($newList =~ /^\s*$/s) { unlink($fname); print "

    Removed banned list"; } else { &WriteStringToFile($fname, $newList); print "

    Updated banned list"; } print &GetCommonFooter(); } # ==== Editing/Deleting pages and links ==== sub DoEditLinks { print &GetHeader("", T('Editing Links'), ""); if ($AdminDelete) { return if (!&UserIsAdminOrError()); } else { return if (!&UserIsEditorOrError()); } print &GetFormStart(); print GetHiddenValue("edit_links", 1), "\n"; print "", Ts('Editing/Deleting page titles:'), "
    \n"; print "

    ", Ts('Enter one command on each line. Commands are:'), "
    ", Ts('!PageName -- deletes the page called PageName'), "
    \n", Ts('=OldPageName=NewPageName -- Renames OldPageName'), " ", Ts('to NewPageName and updates links to OldPageName.'), "
    ", Ts('|OldPageName|NewPageName -- Changes links to OldPageName to NewPageName.'), " ", Ts('(Used to rename links to non-existing pages.)'), "
    \n"; print &GetTextArea('commandlist', "", 12, 50); print $q->checkbox(-name=>"p_changerc", -override=>1, -checked=>1, # -label=>"Edit $RCName"); -label=>Ts('Edit %s', $RCName)); print "
    \n"; print $q->checkbox(-name=>"p_changetext", -override=>1, -checked=>1, # -label=>"Substitute text for rename"); -label=>T('Substitute text for rename')); print "
    ", $q->submit(-name=>'Edit'), "\n"; # print &GetGotoBar(""); print $q->endform; print "

    \n"; print &GetMinimumFooter(); } sub UpdateLinksList { my ($commandList, $doRC, $doText) = @_; if ($doText) { &BuildLinkIndex(); } &RequestLock() or die "UpdateLinksList could not get main lock"; unlink($IndexFile) if ($UseIndex); foreach (split(/\n/, $commandList)) { s/\s+$//g; next if (!(/^[=!|]/)); # Only valid commands. print "Processing $_
    \n"; if (/^\!(.+)/) { &DeletePage($1, $doRC, $doText); } elsif (/^\=(?:\[\[)?([^]=]+)(?:\]\])?\=(?:\[\[)?([^]=]+)(?:\]\])?/) { &RenamePage($1, $2, $doRC, $doText); } elsif (/^\|(?:\[\[)?([^]|]+)(?:\]\])?\|(?:\[\[)?([^]|]+)(?:\]\])?/) { &RenameTextLinks($1, $2); } } &NewPageCacheClear("."); # Clear cache (needs testing?) unlink($IndexFile) if ($UseIndex); &ReleaseLock(); } sub BuildLinkIndex { my (@pglist, $page, @links, $link, %seen); @pglist = &AllPagesList(); %LinkIndex = (); foreach $page (@pglist) { &BuildLinkIndexPage($page); } } sub BuildLinkIndexPage { my ($page) = @_; my (@links, $link, %seen); ############### ### replaced by gypark ### ¸µÅ© ¸ñ·ÏÀ» º°µµ·Î °ü¸® # @links = &GetPageLinks($page, 1, 0, 0); @links = &GetPageLinksFromFile($page, 1, 0, 0); ### ############### %seen = (); foreach $link (@links) { if (defined($LinkIndex{$link})) { if (!$seen{$link}) { $LinkIndex{$link} .= " " . $page; } } else { $LinkIndex{$link} .= " " . $page; } $seen{$link} = 1; } } sub DoUpdateLinks { my ($commandList, $doRC, $doText); print &GetHeader("", T('Updating Links'), ""); if ($AdminDelete) { return if (!&UserIsAdminOrError()); } else { return if (!&UserIsEditorOrError()); } $commandList = &GetParam("commandlist", ""); $doRC = &GetParam("p_changerc", "0"); $doRC = 1 if ($doRC eq "on"); $doText = &GetParam("p_changetext", "0"); $doText = 1 if ($doText eq "on"); if ($commandList eq "") { print "

    Empty command list or error."; } else { &UpdateLinksList($commandList, $doRC, $doText); print "

    ". T('Finished command list.'); } print &GetCommonFooter(); } sub EditRecentChanges { my ($action, $old, $new) = @_; &EditRecentChangesFile($RcFile, $action, $old, $new); ############### ### replaced by gypark ### RcOldFile ¹ö±× ¼öÁ¤ # &EditRecentChangesFile($RcOldFile, $action, $old, $new); &EditRecentChangesFile($RcOldFile, $action, $old, $new) if (-f $RcOldFile); ### ############### } sub EditRecentChangesFile { my ($fname, $action, $old, $new) = @_; my ($status, $fileData, $errorText, $rcline, @rclist); my ($outrc, $ts, $page, $junk); ($status, $fileData) = &ReadFile($fname); if (!$status) { # Save error text if needed. $errorText = "

    Could not open $RCName log file:" . " $fname

    Error was:\n

    $!
    \n"; print $errorText; # Maybe handle differently later? return; } $outrc = ""; @rclist = split(/\n/, $fileData); foreach $rcline (@rclist) { ($ts, $page, $junk) = split(/$FS3/, $rcline); if ($page eq $old) { if ($action == 1) { # Delete ; # Do nothing (don't add line to new RC) } elsif ($action == 2) { $junk = $rcline; $junk =~ s/^(\d+$FS3)$old($FS3)/"$1$new$2"/ge; $outrc .= $junk . "\n"; } } else { $outrc .= $rcline . "\n"; } } &WriteStringToFile($fname . ".old", $fileData); # Backup copy &WriteStringToFile($fname, $outrc); } # Delete and rename must be done inside locks. sub DeletePage { my ($page, $doRC, $doText) = @_; my ($fname, $status); $page =~ s/ /_/g; $page =~ s/\[+//; $page =~ s/\]+//; $status = &ValidId($page); if ($status ne "") { # print "Delete-Page: page $page is invalid, error is: $status
    \n"; print Ts('Delete-Page: page %s is invalid', $page) . ".
    " . Ts('error is: %s', $status) . "
    \n"; return; } ############### ### added by gypark ### ÆäÀÌÁö »èÁ¦ ½Ã¿¡ keep È­ÀÏÀº º¸Á¸ÇØ µÒ &OpenPage($page); &OpenDefaultText(); &SaveKeepSection(); &ExpireKeepFile(); &WriteRcLog($OpenPageName, "*", 0, $Now, &GetParam("username",""), &GetRemoteHost(0)); ### ############### $fname = &GetPageFile($page); unlink($fname) if (-f $fname); ############### ### commented by gypark ### ÆäÀÌÁö »èÁ¦ ½Ã¿¡ keep È­ÀÏÀº º¸Á¸ÇØ µÒ # $fname = $KeepDir . "/" . &GetPageDirectory($page) . "/$page.kp"; # unlink($fname) if (-f $fname); ### ############### #########################################################3 ### added by gypark ### lck È­Àϵµ °°ÀÌ »èÁ¦ $fname = &GetLockedPageFile($page); unlink($fname) if (-f $fname); ### cache È­Àϵµ °°ÀÌ »èÁ¦ &UnlinkHtmlCache($page); ### page count È­Àϵµ °°ÀÌ »èÁ¦ $fname = &GetCountFile($page); unlink ($fname) if (-f $fname); ### hide page by gypark if (defined($HiddenPage{$page})) { delete $HiddenPage{$page}; &SaveHiddenPageFile(); } #########################################################3 ############### ### added by gypark ### ¸µÅ© ¸ñ·ÏÀ» º°µµ·Î °ü¸® $fname = &GetLinkFile($page); unlink($fname) if (-f $fname); ### ############### unlink($IndexFile) if ($UseIndex); ############### ### commented by gypark ### ÆäÀÌÁö »èÁ¦ ½Ã¿¡ keep È­ÀÏÀº º¸Á¸ÇØ µÒ # &EditRecentChanges(1, $page, "") if ($doRC); # Delete page ### ############### # Currently don't do anything with page text } # Given text, returns substituted text sub SubstituteTextLinks { my ($old, $new, $text) = @_; # Much of this is taken from the common markup %SaveUrl = (); $SaveUrlIndex = 0; $text =~ s/$FS//g; # Remove separators (paranoia) if ($RawHtml) { $text =~ s/(((.|\n)*?)<\/html>)/&StoreRaw($1)/ige; } $text =~ s/(
    ((.|\n)*?)<\/pre>)/&StoreRaw($1)/ige;
    	$text =~ s/(((.|\n)*?)<\/code>)/&StoreRaw($1)/ige;
    	$text =~ s/(((.|\n)*?)<\/nowiki>)/&StoreRaw($1)/ige;
    ###############
    ### added by gypark
    ### {{{ }}} ³»ÀÇ ³»¿ëÀº ű׷Π°£ÁÖÇÏÁö ¾ÊÀ½
    	$text =~ s/((^|\n)\{\{\{[ \t\r\f]*\n((.|\n)*?)\n\}\}\}[ \t\r\f]*\n)/&StoreRaw($1)/igem;
    	$text =~ s/((^|\n)\{\{\{([a-zA-Z0-9+]+)(\|(n|\d*|n\d+|\d+n))?[ \t\r\f]*\n((.|\n)*?)\n\}\}\}[ \t\r\f]*\n)/&StoreRaw($1)/igem;
    ###
    ###############
    
    	if ($FreeLinks) {
    		$text =~
    		 s/\[\[$FreeLinkPattern\|([^\]]+)\]\]/&SubFreeLink($1,$2,$old,$new)/geo;
    		$text =~ s/\[\[$FreeLinkPattern\]\]/&SubFreeLink($1,"",$old,$new)/geo;
    	}
    	if ($BracketText) {  # Links like [URL text of link]
    		$text =~ s/(\[$UrlPattern\s+([^\]]+?)\])/&StoreRaw($1)/geo;
    		$text =~ s/(\[$InterLinkPattern\s+([^\]]+?)\])/&StoreRaw($1)/geo;
    	}
    	$text =~ s/(\[?$UrlPattern\]?)/&StoreRaw($1)/geo;
    	$text =~ s/(\[?$InterLinkPattern\]?)/&StoreRaw($1)/geo;
    	if ($WikiLinks) {
    		$text =~ s/$LinkPattern/&SubWikiLink($1, $old, $new)/geo;
    	}
    
    	$text =~ s/$FS(\d+)$FS/$SaveUrl{$1}/ge;   # Restore saved text
    	return $text;
    }
    
    sub SubFreeLink {
    	my ($link, $name, $old, $new) = @_;
    	my ($oldlink);
    
    	$oldlink = $link;
    	$link =~ s/^\s+//;
    	$link =~ s/\s+$//;
    	if (($link eq $old) || (&FreeToNormal($old) eq &FreeToNormal($link))) {
    		$link = $new;
    	} else {
    		$link = $oldlink;  # Preserve spaces if no match
    	}
    	$link = "[[$link";
    	if ($name ne "") {
    		$link .= "|$name";
    	}
    	$link .= "]]";
    	return &StoreRaw($link);
    }
    
    sub SubWikiLink {
    	my ($link, $old, $new) = @_;
    	my ($newBracket);
    
    	$newBracket = 0;
    	if ($link eq $old) {
    		$link = $new;
    		if (!($new =~ /^$LinkPattern$/)) {
    			$link = "[[$link]]";
    		}
    	}
    	return &StoreRaw($link);
    }
    
    # Rename is mostly copied from expire
    sub RenameKeepText {
    	my ($page, $old, $new) = @_;
    	my ($fname, $status, $data, @kplist, %tempSection, $changed);
    	my ($sectName, $newText);
    
    	$fname = $KeepDir . "/" . &GetPageDirectory($page) .  "/$page.kp";
    	return  if (!(-f $fname));
    	($status, $data) = &ReadFile($fname);
    	return  if (!$status);
    	@kplist = split(/$FS1/, $data, -1);  # -1 keeps trailing null fields
    	return  if (length(@kplist) < 1);  # Also empty
    	shift(@kplist)  if ($kplist[0] eq "");  # First can be empty
    	return  if (length(@kplist) < 1);  # Also empty
    	%tempSection = split(/$FS2/, $kplist[0], -1);
    	if (!defined($tempSection{'keepts'})) {
    		return;
    	}
    
    	# First pass: optimize for nothing changed
    	$changed = 0;
    	foreach (@kplist) {
    		%tempSection = split(/$FS2/, $_, -1);
    		$sectName = $tempSection{'name'};
    		if ($sectName =~ /^(text_)/) {
    			%Text = split(/$FS3/, $tempSection{'data'}, -1);
    			$newText = &SubstituteTextLinks($old, $new, $Text{'text'});
    			$changed = 1  if ($Text{'text'} ne $newText);
    		}
    		# Later add other section types? (maybe)
    	}
    
    	return  if (!$changed);  # No sections changed
    	open (OUT, ">$fname") or return;
    	foreach (@kplist) {
    		%tempSection = split(/$FS2/, $_, -1);
    		$sectName = $tempSection{'name'};
    		if ($sectName =~ /^(text_)/) {
    			%Text = split(/$FS3/, $tempSection{'data'}, -1);
    			$newText = &SubstituteTextLinks($old, $new, $Text{'text'});
    			$Text{'text'} = $newText;
    			$tempSection{'data'} = join($FS3, %Text);
    			print OUT $FS1, join($FS2, %tempSection);
    		} else {
    			print OUT $FS1, $_;
    		}
    	}
    	close(OUT);
    }
    
    sub RenameTextLinks {
    	my ($old, $new) = @_;
    	my ($changed, $file, $page, $section, $oldText, $newText, $status);
    	my ($oldCanonical, @pageList);
    
    	$old =~ s/ /_/g;
    	$oldCanonical = &FreeToNormal($old);
    	$new =~ s/ /_/g;
    	$status = &ValidId($old);
    	if ($status ne "") {
    		print "Rename-Text: old page $old is invalid, error is: $status
    \n"; return; } $status = &ValidId($new); if ($status ne "") { print "Rename-Text: new page $new is invalid, error is: $status
    \n"; return; } $old =~ s/_/ /g; $new =~ s/_/ /g; # Note: the LinkIndex must be built prior to this routine return if (!defined($LinkIndex{$oldCanonical})); @pageList = split(' ', $LinkIndex{$oldCanonical}); foreach $page (@pageList) { $changed = 0; &OpenPage($page); foreach $section (keys %Page) { if ($section =~ /^text_/) { &OpenSection($section); %Text = split(/$FS3/, $Section{'data'}, -1); $oldText = $Text{'text'}; $newText = &SubstituteTextLinks($old, $new, $oldText); if ($oldText ne $newText) { $Text{'text'} = $newText; $Section{'data'} = join($FS3, %Text); $Page{$section} = join($FS2, %Section); $changed = 1; } } elsif ($section =~ /^cache_diff/) { $oldText = $Page{$section}; $newText = &SubstituteTextLinks($old, $new, $oldText); if ($oldText ne $newText) { $Page{$section} = $newText; $changed = 1; } } # Later: add other text-sections (categories) here } if ($changed) { $file = &GetPageFile($page); &WriteStringToFile($file, join($FS1, %Page)); ############### ### added by gypark ### ¸µÅ© ¸ñ·ÏÀ» º°µµ·Î °ü¸® &SaveLinkFile($page); ### ############### } &RenameKeepText($page, $old, $new); } } sub RenamePage { my ($old, $new, $doRC, $doText) = @_; my ($oldfname, $newfname, $oldkeep, $newkeep, $status); $old =~ s/ /_/g; $new = &FreeToNormal($new); $status = &ValidId($old); if ($status ne "") { print "Rename: old page $old is invalid, error is: $status
    \n"; return; } $status = &ValidId($new); if ($status ne "") { print "Rename: new page $new is invalid, error is: $status
    \n"; return; } $newfname = &GetPageFile($new); if (-f $newfname) { print "Rename: new page $new already exists--not renamed.
    \n"; return; } $oldfname = &GetPageFile($old); if (!(-f $oldfname)) { print "Rename: old page $old does not exist--nothing done.
    \n"; return; } &CreatePageDir($PageDir, $new); # It might not exist yet rename($oldfname, $newfname); &CreatePageDir($KeepDir, $new); $oldkeep = $KeepDir . "/" . &GetPageDirectory($old) . "/$old.kp"; $newkeep = $KeepDir . "/" . &GetPageDirectory($new) . "/$new.kp"; unlink($newkeep) if (-f $newkeep); # Clean up if needed. rename($oldkeep, $newkeep); unlink($IndexFile) if ($UseIndex); ############### ### added by gypark ### ÆäÀÌÁö À̸§ º¯°æ½Ã, lock È­Àϵµ °°ÀÌ º¯°æ my ($oldlock, $newlock); $oldlock = &GetLockedPageFile($old); if (-f $oldlock) { $newlock = &GetLockedPageFile($new); rename($oldlock, $newlock) || die "error while renaming lock"; } ### cache È­ÀÏÀº »èÁ¦ &UnlinkHtmlCache($old); ### page count È­Àϵµ º¯°æ my ($oldcnt, $newcnt); $oldcnt = &GetCountFile($old); if (-f $oldcnt) { $newcnt = &GetCountFile($new); &CreatePageDir($CountDir, $new); # It might not exist yet rename($oldcnt, $newcnt) || die "error while renaming count file"; } ### hide page by gypark if (defined($HiddenPage{$old})) { delete $HiddenPage{$old}; $HiddenPage{$new} = "1"; &SaveHiddenPageFile(); } ### ############### ############### ### added by gypark ### ¸µÅ© ¸ñ·ÏÀ» º°µµ·Î °ü¸® my ($oldlink, $newlink); $oldlink = &GetLinkFile($old); if (-f $oldlink) { $newlink = &GetLinkFile($new); &CreatePageDir($LinkDir, $new); # It might not exist yet rename($oldlink, $newlink) || die "error while renaming link file"; } ### ############### &EditRecentChanges(2, $old, $new) if ($doRC); if ($doText) { &BuildLinkIndexPage($new); # Keep index up-to-date &RenameTextLinks($old, $new); } } sub DoShowVersion { print &GetHeader("", T('Displaying Wiki Version'), ""); ############### ### replaced by gypark ### ¹öÀü Á¤º¸¸¦ º°µµÀÇ º¯¼ö¿¡ º¸°ü # print "

    UseModWiki version 0.92K2

    \n"; print "

    UseModWiki version $WikiVersion ($WikiRelease)

    \n"; ### ############### print &GetCommonFooter(); } #END_OF_OTHER_CODE ############### ### added by gypark ### Åëä·Î Ãß°¡ÇÑ ÇÔ¼öµéÀº ¿©±â¿¡ µÒ ############### ### added by gypark ### ÃÖ±Ùº¯°æ³»¿ª¿¡ ºÏ¸¶Å© ±â´É µµÀÔ sub DoBookmark { if (&GetParam('username') eq "") { # ·Î±×ÀÎÇÏÁö ¾ÊÀº °æ¿ì &BrowsePage(T($RCName)); # ±×³É ÃÖ±Ù º¯°æ ³»¿ªÀ¸·Î À̵¿ return 1; } if (&GetParam('time') ne "") { $UserData{'bookmark'} = &GetParam('time'); } else { $UserData{'bookmark'} = $Now; } &SaveUserData(); &BrowsePage(T($RCName)); return 1; } ### ############### ############### ### added by gypark ### ¸µÅ© ¸ñ·ÏÀ» º°µµ·Î °ü¸® sub GetLinkFile { my ($id) = @_; return $LinkDir . "/" . &GetPageDirectory($id) . "/$id.lnk"; } sub SaveLinkFile { my ($page) = @_; my (%links, @pagelinks, @interlinks, @urllinks, @alllinks, $link); @alllinks = &GetPageLinks($page, 1, 1, 1); foreach $link (@alllinks) { if ($link =~ /^$InterLinkPattern$/) { push(@interlinks, $link); } elsif ($link =~ /^$UrlPattern$/) { push(@urllinks, $link); } else { push(@pagelinks, $link); } } $links{'pagelinks'} = join($FS2, @pagelinks); $links{'interlinks'} = join($FS2, @interlinks); $links{'urllinks'} = join($FS2, @urllinks); &CreatePageDir($LinkDir, $page); &WriteStringToFile(&GetLinkFile($page), join($FS1, %links)); } sub GetPageLinksFromFile { my ($name, $pagelink, $interlink, $urllink) = @_; my ($status, $data, %links, @result, $fname); ############### ### added by gypark ### hide page if (&PageIsHidden($name)) { return; } ### ############### @result = (); $fname = &GetLinkFile($name); if (!(-f $fname)) { &SaveLinkFile($name); } ($status, $data) = &ReadFile($fname); if (!($status)) { return &GetPageLinks($name, $pagelink, $interlink, $urllink); } %links = split($FS1, $data, -1); ### hide page by gypark # push (@result, split($FS2, $links{'pagelinks'}, -1)) if ($pagelink); push (@result, &GetNotHiddenPages(split($FS2, $links{'pagelinks'}, -1))) if ($pagelink); ### push (@result, split($FS2, $links{'interlinks'}, -1)) if ($interlink); push (@result, split($FS2, $links{'urllinks'}, -1)) if ($urllink); return @result; } ### page count sub GetCountFile { my ($id) = @_; return $CountDir . "/" . &GetPageDirectory($id) . "/$id.cnt"; } sub GetPageCount { my ($id) = @_; my ($pagecount, $countfile, $status); my ($edit_user, $edit_ip, $view_user, $view_ip, $add) = ($Section{'username'}, $Section{'ip'}, &GetParam('username', ""), $ENV{REMOTE_ADDR}, 0); # Ä«¿îÆ® Àоî¿È &CreatePageDir($CountDir, $id); $countfile = &GetCountFile($id); ($status, $pagecount) = &ReadFile($countfile); $pagecount = 0 if ($status == 0); # Ä«¿îÆ® °»½Å ¿©ºÎ °áÁ¤ if ($view_user eq "") { if ($edit_ip ne $view_ip) { $add = 1; } } elsif ($edit_user ne $view_user) { $add = 1; } if (&GetParam('InFrame',"") ne "") { $add = 0; } $pagecount += $add; # Ä«¿îÆ® ±â·Ï if ($add == 1) { &RequestLockDir('count', 1, 1, 0) || return $pagecount; &WriteStringToFile($countfile, $pagecount); &ReleaseLockDir('count'); } return $pagecount; } ### file upload sub DoUpload { my $file; my $upload = &GetParam('upload'); my $prev_error = &GetParam('error', ""); my @uploadError = ( T('Upload completed successfully'), T('Invalid filename'), T('You can not upload html or any executable scripts'), T('File is too large'), T('File has no content'), T('Failed to get lock'), ); my $result; print &GetHttpHeader(); print &GetHtmlHeader("$SiteName : ". T('Upload File'), ""); print $q->h2(T('Upload File')) . "\n"; if (!(&UserCanEdit("",1))) { print T('Uploading is not allowed'); print $q->end_html; return; } if ($prev_error) { print "$uploadError[$prev_error]


    \n"; } elsif ($upload) { $file = &GetParam('upload_file'); $result = &UploadFile($file); print "$uploadError[$result]

    \n"; } &PrintUploadFileForm(); print $q->end_html; } sub PrintUploadFileForm { print T('Select the file you want to upload') . "\n"; print "
    ".Ts('File must be smaller than %s MB', ($MaxPost / 1024 / 1024)) . "\n"; print $q->start_form('post',"$ScriptName", 'multipart/form-data') . "\n"; print ""; print "" . "\n"; print "
    " . "\n"; print $q->filefield("upload_file","",60,80) . "\n"; print "  " . "\n"; print $q->submit(T('Upload')) . "\n"; print "
    " . "\n"; print $q->endform(); } sub UploadFile { my ($file) = @_; my ($filename); my ($target); if ($file =~ m/\//) { $file =~ m/(.*)\/([^\/]*)/; $filename = $2; } elsif ($file =~ m/\\/) { $file =~ m/(.*)\\([^\\]*)/; $filename = $2; } else { $filename = $file; } if (($filename eq "") || ($filename =~ /\0/)) { return 1; } if ($filename =~ m/(\.pyc|\.py|\.pl|\.html|\.htm|\.php|\.cgi)$/i) { return 2; } $filename =~ s/ /_/g; $filename =~ s/#/_/g; &RequestLockDir('upload', 5, 2, 0) || return 5; my $prefix = &GetLastPrefix($UploadDir, $filename); my $target = $prefix.$filename; my $target_full = "$UploadDir/$target"; &CreateDir($UploadDir); if (!open (FILE, ">$target_full")) { &ReleaseLockDir('upload'); die Ts('cant opening %s', $target_full) . ": $!"; } &ReleaseLockDir('upload'); binmode FILE; while (<$file>) { print FILE $_; } close(FILE); chmod(0644, "$target_full"); if ((-s "$target_full") > $MaxPost) { unlink "$target_full"; return 3; } if ((-s "$target_full") == 0) { unlink "$target_full"; return 4; } print T('Following is the Interlink of your file') . "
    \n"; print "
    \n"; print "Upload:$target\n"; print "
    \n"; return 0; } ### DeleteUploadedFiles ¸ÅÅ©·Î sub DoDeleteUploadedFiles { my (%vars, @files); print &GetHeader("", T('Delete Uploaded Files'), ""); if (!(&UserIsAdmin())) { print T('Deleting is not allowed'); print "
    \n"; } else { %vars = $q->Vars; @files = split(/\0/,$vars{'files'}, -1); foreach (@files) { if (unlink ("$UploadDir/$_")) { print Ts('%s is deleted successfully', $_)."
    "; } else { print Ts('%s can not be deleted', $_). " : $!
    "; } } } if (&GetParam('pagename') ne "") { print "
    ".Ts('Return to %s' , &GetPageLink(&GetParam('pagename'))); } print &GetCommonFooter(); } ### oekaki sub DoOekaki { my $mode = &GetParam('mode','paint'); print &GetHttpHeader(); print &GetHtmlHeader("$SiteName : ". T("Oekaki $mode"), ""); print $q->h2(T('Oekaki')) . "\n"; if (!(&UserCanEdit("",1))) { print T('Oekaki is not allowed'); print $q->end_html; return; } if ($mode eq "exit") { &OekakiExit(); } elsif ($mode eq "save") { &OekakiSave(); } elsif ($mode eq "paint") { &OekakiPaint(); } else { print Ts('Invalid action parameter %s', ": $mode"); } print $q->end_html; } sub OekakiExit { my $filename = "oekaki.png"; my (@allfiles, @files, %filemtime); opendir (DIR, "$UploadDir") || die Ts('cant opening %s', $UploadDir) . ": $!"; @allfiles = readdir(DIR); shift @allfiles; shift @allfiles; close(DIR); foreach (@allfiles) { if ($_ =~ m/$filename$/) { push (@files, $_); $filemtime{$_} = ($Now - (-M "$UploadDir/$_") * 86400); } } @files = sort { $filemtime{$b} <=> $filemtime{$a} || $a cmp $b } @files; print T('If saving oekaki was done successfully')."
    \n"; print T('Following is the Interlink of your file') . "
    \n"; print "
    \n"; print "Upload:$files[0]
    \n"; print "\n"; print "
    \n"; print "
    "; print T('If you want to paint a new picture')."
    \n"; print qq|
    width [640-40] height [480-40]
    |; print "
    "; print T('If the picture above is not what you had painted, find your picture from the follwing list')."
    \n"; print "
      \n"; foreach (@files) { print "
    • "; print "Upload:$_"; print " (".&TimeToText($filemtime{$_}).")
    • \n"; } print "
    \n"; } sub OekakiSave { my ($buffer, $p, $filename, $prefix, $target_full); # POST µ¥ÀÌŸ ÀÐÀ½ read (STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); $p = index($buffer, "\r"); # °¢Á¾ ¿¡·¯ ó¸® if (!($buffer =~ m/^\0\0\0\0\r\n/)) { die("Invalid POST data"); } if ($p < 0) { my $size = length($buffer); die("Data size $size"); } # ÇöÀç´Â Á¦´ë·Î µ¿ÀÛÇÏÁö ¾Ê´Â´Ù # if (!(&UserCanEdit("",1))) { # die T('Oekaki is not allowed'); # } # ¶ôÀ» ȹµæ if (!(&RequestLockDir('oekaki', 4, 3, 0))) { die("can not get lock"); } # ÀúÀåÇÒ È­ÀÏ¸í °áÁ¤ $filename = "oekaki.png"; $prefix = &GetLastPrefix($UploadDir, $filename); $target_full = $UploadDir."/".$prefix.$filename; # ÀúÀå &CreateDir($UploadDir); &WriteStringToFile($target_full, substr($buffer, $p+2)); # ¶ôÀ» ÇØÁ¦ &ReleaseLockDir('oekaki'); chmod(0644, "$target_full"); # Á¾·á print "Content-type: text/plain\n\n"; print "success\n"; } sub OekakiPaint { my ($imageWidth, $imageHeight) = ( &GetParam('width','300'), &GetParam('height','300') ); $imageWidth = 40 if ($imageWidth < 40); $imageWidth = 640 if ($imageWidth > 640); $imageHeight = 40 if ($imageHeight < 40); $imageHeight = 480 if ($imageHeight > 480); my ($appletWidth, $appletHeight) = ( (($imageWidth < 300)?400:($imageWidth+100)), (($imageHeight < 300)?420:($imageHeight+120)) ); print qq|
    width [640-40] height [480-40]

    |; } ### È­ÀϸíÀÌ °ãÄ¥ °æ¿ì ¾Õ¿¡ ºÙÀÏ prefix ¸¦ ¾ò´Â ÇÔ¼ö sub GetLastPrefix { my ($dir, $file) = @_; if (!(-f "$dir/$file")) { return ""; } if (!(-f "$dir/2_$file")) { return "2_"; } my $prefix = 2; while (-f "$dir/$prefix"."_$file") { $prefix += 10; } $prefix -= 10; while (-f "$dir/$prefix"."_$file") { $prefix++; } return $prefix ."_"; } ### °ü½É ÆäÀÌÁö sub DoInterest { my ($title, $temp); my $mode = &GetParam('mode'); my $id = &GetParam('id'); my $failMsg = T('Fail to access Interest Page List'); if (&GetParam('username') eq "") { print &GetHeader('', $failMsg, ''); print T('You must login to do this action'); print &GetCommonFooter(); return; } if ($mode eq "add") { $title = T('Add a page to Interest Page List'); } elsif (&GetParam('mode') eq "remove") { $title = T('Remove a page from Interest Page List'); } else { print &GetHeader('', $failMsg, ''); print Ts('Invalid action parameter %s', $mode); print &GetCommonFooter(); return; } $temp = &ValidId($id); if ($temp ne "") { print &GetHeader('', $failMsg, ''); print $temp; print &GetCommonFooter(); return; } print &GetHeader('', $title, ''); if ($mode eq "add") { $UserInterest{$id} = "1"; print Ts('Page %s is added to your Interest Page List', $id); } else { delete $UserInterest{$id}; print Ts('Page %s is removed from your Interest Page List', $id); } $UserData{'interest'} = join($FS2, %UserInterest); &SaveUserData(); print "
    "; print Ts('Return to %s' , &GetPageLink($id)); print &GetCommonFooter(); return 1; } ### hide page by gypark sub DoPageHide { my ($id); print &GetHeader('', T('Hide or Unhide page'), ''); return if (!&UserIsAdminOrError()); $id = &GetParam("id", ""); if ($id eq "") { print '

    ', T('Missing page id to hide/unhide'); return; } return if (!&ValidIdOrDie($id)); # Later consider nicer error? if (&GetParam("set", 1)) { $HiddenPage{$id} = "1"; } else { delete $HiddenPage{$id}; } if (!(&SaveHiddenPageFile())) { print T('Hiding/Unhiding page failed'); print &GetCommonFooter(); return; } if (defined ($HiddenPage{$id})) { print '

    ', Ts('%s is hidden.', $id), '
    '; } else { print '

    ', Ts('%s is revealed.', $id), '
    '; } print &GetCommonFooter(); } sub PageIsHidden { my ($id) = @_; if ((!(defined $HiddenPage{$id})) || (&UserIsAdmin())) { return 0; } else { return 1; } } sub GetNotHiddenPages { my (@pages) = @_; my @notHiddenPages = (); foreach (@pages) { push (@notHiddenPages, $_) if (!(&PageIsHidden($_))); } return @notHiddenPages; } sub SaveHiddenPageFile { my $data; $data = join($FS1, %HiddenPage); &WriteStringToFile($HiddenPageFile, $data); chmod(0600, $HiddenPageFile); return 1; } ### Åëä·Î Ãß°¡ÇÑ ÇÔ¼öµéÀÇ ³¡ ############### &DoWikiRequest() if ($RunCGI && ($_ ne 'nocgi')); # Do everything. 1; # In case we are loaded from elsewhere # == End of UseModWiki script. ===========================================