OSDN Git Service

get_existpages(),get_existfiles():ファイル名チェックを厳密に
[pukiwiki/pukiwiki.git] / file.php
1 <?php
2 /////////////////////////////////////////////////
3 // PukiWiki - Yet another WikiWikiWeb clone.
4 //
5 // $Id: file.php,v 1.22 2003/06/10 13:59:02 arino Exp $
6 //
7
8 // ¥½¡¼¥¹¤ò¼èÆÀ
9 function get_source($page)
10 {
11         if (!is_page($page)) {
12                 return array();
13         }
14         return str_replace("\r",'',file(get_filename($page)));
15 }
16
17 // ¥Ú¡¼¥¸¤Î¹¹¿·»þ¹ï¤òÆÀ¤ë
18 function get_filetime($page)
19 {
20         return filemtime(get_filename($page)) - LOCALZONE;
21 }
22
23 // ¥Ú¡¼¥¸¤Î¥Õ¥¡¥¤¥ë̾¤òÆÀ¤ë
24 function get_filename($page)
25 {
26         return DATA_DIR.encode($page).'.txt';
27 }
28
29 // ¥Ú¡¼¥¸¤Î½ÐÎÏ
30 function page_write($page,$postdata,$notimestamp=FALSE)
31 {
32         $postdata = make_str_rules($postdata);
33         
34         // º¹Ê¬¥Õ¥¡¥¤¥ë¤ÎºîÀ®
35         $oldpostdata = is_page($page) ? join('',get_source($page)) : '';
36         $diffdata = do_diff($oldpostdata,$postdata);
37         file_write(DIFF_DIR,$page,$diffdata);
38         
39         // ¥Ð¥Ã¥¯¥¢¥Ã¥×¤ÎºîÀ®
40         make_backup($page,$postdata == '');
41         
42         // ¥Õ¥¡¥¤¥ë¤Î½ñ¤­¹þ¤ß
43         file_write(DATA_DIR,$page,$postdata,$notimestamp);
44         
45         // TrackBack Ping ¤ÎÁ÷¿®
46         tb_send($page,$postdata);
47         
48         // is_page¤Î¥­¥ã¥Ã¥·¥å¤ò¥¯¥ê¥¢¤¹¤ë¡£
49         is_page($page,TRUE);
50         
51         // link¥Ç¡¼¥¿¥Ù¡¼¥¹¤ò¹¹¿·
52         links_update($page);
53 }
54
55 // ¥æ¡¼¥¶ÄêµÁ¥ë¡¼¥ë(¥½¡¼¥¹¤òÃÖ´¹¤¹¤ë)
56 function make_str_rules($str)
57 {
58         global $str_rules,$fixed_heading_anchor;
59         
60         $arr = explode("\n",$str);
61         
62         foreach ($arr as $str)
63         {
64                 if ($str != '' and $str{0} != ' ' and $str{0} != "\t")
65                 {
66                         foreach ($str_rules as $rule => $replace)
67                         {
68                                 $str = preg_replace("/$rule/",$replace,$str);
69                         }
70                 }
71                 // ¸«½Ð¤·¤Ë¸ÇÍ­ID¤òÉÕÍ¿¤¹¤ë
72                 if ($fixed_heading_anchor and
73                         preg_match('/^(\*{1,3}(.(?!\[#[A-Za-z][\w-]+\]))+)$/',$str,$matches))
74                 {
75                         // ¸ÇÍ­ID¤òÀ¸À®¤¹¤ë
76                         // ¥é¥ó¥À¥à¤Ê±Ñ»ú(1ʸ»ú)+md5¥Ï¥Ã¥·¥å¤Î¥é¥ó¥À¥à¤ÊÉôʬʸ»úÎó(7ʸ»ú)
77                         $anchor = chr(mt_rand(ord('a'),ord('z'))).
78                                 substr(md5(uniqid(substr($matches[1],0,100),1)),mt_rand(0,24),7);
79                         $str = rtrim($matches[1])." [#$anchor]";
80                 }
81                 $retvars[] = $str;
82         }
83         
84         return join("\n",$retvars);
85 }
86
87 // ¥Õ¥¡¥¤¥ë¤Ø¤Î½ÐÎÏ
88 function file_write($dir,$page,$str,$notimestamp=FALSE)
89 {
90         global $post,$update_exec;
91         global $_msg_invalidiwn;
92         
93         if (!is_pagename($page))
94         {
95                 die_message(
96                         str_replace('$1',htmlspecialchars($page),
97                                 str_replace('$2','WikiName',$_msg_invalidiwn)
98                         )
99                 );
100         }
101         $page = strip_bracket($page);
102         $timestamp = FALSE;
103         $file = $dir.encode($page).'.txt';
104         
105         if ($dir == DATA_DIR and $str == '' and file_exists($file)) {
106                 unlink($file);
107         }
108         if ($str != '') {
109                 $str = preg_replace("/\r/",'',$str);
110                 $str = rtrim($str)."\n";
111                 
112                 if ($notimestamp and file_exists($file)) {
113                         $timestamp = filemtime($file) - LOCALZONE;
114                 }
115                 
116                 $fp = fopen($file,'w')
117                         or die_message('cannot write page file or diff file or other'.htmlspecialchars($page).'<br />maybe permission is not writable or filename is too long');
118                 flock($fp,LOCK_EX);
119                 fputs($fp,$str);
120                 flock($fp,LOCK_UN);
121                 fclose($fp);
122                 if ($timestamp) {
123                         touch($file,$timestamp + LOCALZONE);
124                 }
125         }
126         
127         if (!$timestamp) {
128                 put_lastmodified();
129         }
130         
131         if ($update_exec and $dir == DATA_DIR) {
132                 system($update_exec.' > /dev/null &');
133         }
134 }
135
136 // ºÇ½ª¹¹¿·¥Ú¡¼¥¸¤Î¹¹¿·
137 function put_lastmodified()
138 {
139         global $maxshow,$whatsnew,$non_list,$autolink;
140
141         $pages = get_existpages();
142         $recent_pages = array();
143         foreach($pages as $page)
144         {
145                 if ($page != $whatsnew and !preg_match("/$non_list/",$page))
146                 {
147                         $recent_pages[$page] = get_filetime($page);
148                 }
149         }
150         
151         //»þ¹ï¹ß½ç¤Ç¥½¡¼¥È
152         arsort($recent_pages,SORT_NUMERIC);
153         
154         // create recent.dat (for recent.inc.php)
155         $fp = fopen(CACHE_DIR.'recent.dat','w')
156                 or die_message('cannot write cache file '.CACHE_DIR.'recent.dat<br />maybe permission is not writable or filename is too long');
157         flock($fp,LOCK_EX);
158         foreach ($recent_pages as $page=>$time)
159         {
160                 fputs($fp,"$time\t$page\n");
161         }
162         flock($fp,LOCK_UN);
163         fclose($fp);
164
165         // create RecentChanges
166         $fp = fopen(get_filename($whatsnew),'w')
167                 or die_message('cannot write page file '.htmlspecialchars($whatsnew).'<br />maybe permission is not writable or filename is too long');
168         flock($fp,LOCK_EX);
169         foreach (array_splice($recent_pages,0,$maxshow) as $page=>$time)
170         {
171                 $s_lastmod = htmlspecialchars(format_date($time));
172                 $s_page = htmlspecialchars($page);
173                 fputs($fp, "-$s_lastmod - [[$s_page]]\n");
174         }
175         fputs($fp,"#norelated\n"); // :)
176         flock($fp,LOCK_UN);
177         fclose($fp);
178         
179         // for autolink
180         if ($autolink)
181         {
182                 list($pattern,$forceignorelist) = get_autolink_pattern($pages);
183                 
184                 $fp = fopen(CACHE_DIR.'autolink.dat','w')
185                         or die_message('cannot write autolink file '.CACHE_DIR.'/autolink.dat<br />maybe permission is not writable');
186                 flock($fp,LOCK_EX);
187                 fputs($fp,$pattern."\n");
188                 fputs($fp,join("\t",$forceignorelist));
189                 flock($fp,LOCK_UN);
190                 fclose($fp);
191         }
192 }
193
194 // »ØÄꤵ¤ì¤¿¥Ú¡¼¥¸¤Î·Ð²á»þ¹ï
195 function get_pg_passage($page,$sw=TRUE)
196 {
197         global $show_passage;
198         static $pg_passage = array();
199         
200         if (!$show_passage)
201         {
202                 return '';
203         }
204         
205         if (!array_key_exists($page,$pg_passage))
206         {
207                 $pg_passage[$page] = (is_page($page) and $time = get_filetime($page)) ?
208                         get_passage($time) : '';
209         }
210         
211         return $sw ? "<small>{$pg_passage[$page]}</small>" : " {$pg_passage[$page]}";
212 }
213
214 // Last-Modified ¥Ø¥Ã¥À
215 function header_lastmod()
216 {
217         global $lastmod;
218         
219         if ($lastmod and is_page($page)) {
220                 header('Last-Modified: '.date('D, d M Y H:i:s',get_filetime($page)).' GMT');
221         }
222 }
223
224 // Á´¥Ú¡¼¥¸Ì¾¤òÇÛÎó¤Ë
225 function get_existpages($dir=DATA_DIR,$ext='.txt')
226 {
227         $aryret = array();
228         
229         $pattern = '^((?:[0-9A-F]{2})+)';
230         if ($ext != '')
231         {
232                 $pattern .= preg_quote($ext,'/').'$';
233         }
234         $dp = @opendir($dir)
235                 or die_message($dir. ' is not found or not readable.');
236         while ($file = readdir($dp))
237         {
238                 if (preg_match("/$pattern/",$file,$matches))
239                 {
240                         $aryret[$file] = decode($matches[1]);
241                 }
242         }
243         closedir($dp);
244         return $aryret;
245 }
246 //¥Õ¥¡¥¤¥ë̾¤Î°ìÍ÷¤òÇÛÎó¤Ë(¥¨¥ó¥³¡¼¥ÉºÑ¤ß¡¢³ÈÄ¥»Ò¤ò»ØÄê)
247 function get_existfiles($dir,$ext)
248 {
249         $aryret = array();
250         
251         $pattern = '^(?:[0-9A-F]{2})+'.preg_quote($ext,'/').'$';
252         $dp = @opendir($dir)
253                 or die_message($dir. ' is not found or not readable.');
254         while ($file = readdir($dp)) {
255                 if (preg_match("/$pattern/",$file)) {
256                         $aryret[] = $dir.$file;
257                 }
258         }
259         closedir($dp);
260         return $aryret;
261 }
262 //¤¢¤ë¥Ú¡¼¥¸¤Î´ØÏ¢¥Ú¡¼¥¸¤òÆÀ¤ë
263 function links_get_related($page)
264 {
265         global $vars,$related;
266         static $links = array();
267         
268         if (array_key_exists($page,$links))
269         {
270                 return $links[$page];
271         }
272         
273         // ²Äǽ¤Ê¤émake_link()¤ÇÀ¸À®¤·¤¿´ØÏ¢¥Ú¡¼¥¸¤ò¼è¤ê¹þ¤à
274         $links[$page] = ($page == $vars['page']) ? $related : array();
275         
276         // ¥Ç¡¼¥¿¥Ù¡¼¥¹¤«¤é´ØÏ¢¥Ú¡¼¥¸¤òÆÀ¤ë
277         $links[$page] += links_get_related_db($vars['page']);
278         
279         return $links[$page];
280 }
281 ?>