• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

Commit MetaInfo

Revisionf0414e3a0a62364920a90d4c3d42e4cbf48bf565 (tree)
Time2010-05-30 23:04:31
Authormiko2u <miko@cafe...>
Commitermiko2u

Log Message

add dav.inc.php.

Change Summary

Incremental Difference

--- a/lib/funcplus.php
+++ b/lib/funcplus.php
@@ -1,8 +1,8 @@
11 <?php
22 // PukiWiki Plus! - Yet another WikiWikiWeb clone.
3-// $Id: funcplus.php,v 0.1.56 2009/05/07 00:36:00 upk Exp $
3+// $Id: funcplus.php,v 0.1.57 2010/05/30 23:01:00 upk Exp $
44 // Copyright (C)
5-// 2005-2009 PukiWiki Plus! Team
5+// 2005-2010 PukiWiki Plus! Team
66 // License: GPL v2 or (at your option) any later version
77 //
88 // Plus! extension function(s)
@@ -748,4 +748,48 @@ function strip_a($x)
748748 $x = preg_replace('#<a class="ext" href="(.*?)" .*?>(.*?)<img src="' . IMAGE_URI . 'plus/ext.png".*?</a>#si','$2',$x);
749749 return $x;
750750 }
751+
752+function is_webdav()
753+{
754+ global $log_ua;
755+ static $status = false;
756+ if ($status) return true;
757+
758+ static $ua_dav = array(
759+ 'Microsoft-WebDAV-MiniRedir\/',
760+ 'Microsoft Data Access Internet Publishing Provider',
761+ 'MS FrontPage',
762+ '^WebDrive',
763+ '^WebDAVFS\/',
764+ '^gnome-vfs\/',
765+ '^XML Spy',
766+ '^Dreamweaver-WebDAV-SCM1',
767+ );
768+
769+ switch($_SERVER['REQUEST_METHOD']) {
770+ case 'OPTIONS':
771+ case 'PROPFIND':
772+ case 'MOVE':
773+ case 'COPY':
774+ case 'DELETE':
775+ case 'PROPPATCH':
776+ case 'MKCOL':
777+ case 'LOCK':
778+ case 'UNLOCK':
779+ $status = true;
780+ return $status;
781+ default:
782+ continue;
783+ }
784+
785+ $matches = array();
786+ foreach($ua_dav as $pattern) {
787+ if (preg_match('/'.$pattern.'/', $log_ua, $matches)) {
788+ $status = true;
789+ return true;
790+ }
791+ }
792+
793+ return false;
794+}
751795 ?>
--- a/lib/pukiwiki.php
+++ b/lib/pukiwiki.php
@@ -1,9 +1,9 @@
11 <?php
22 // PukiWiki Plus! - Yet another WikiWikiWeb clone.
3-// $Id: pukiwiki.php,v 1.21.19 2009/08/19 01:51:00 upk Exp $
3+// $Id: pukiwiki.php,v 1.21.20 2010/05/30 23:01:00 upk Exp $
44 //
55 // PukiWiki Plus! 1.4.*
6-// Copyright (C) 2002-2009 by PukiWiki Plus! Team
6+// Copyright (C) 2002-2010 by PukiWiki Plus! Team
77 // http://pukiwiki.cafelounge.net/plus/
88 //
99 // PukiWiki 1.4.*
@@ -226,6 +226,12 @@ if ($is_protect) {
226226 die('PLUS_PROTECT_MODE is set.');
227227 }
228228
229+// WebDAV
230+if (is_webdav() && exist_plugin('dav')) {
231+ do_plugin_action('dav');
232+ exit;
233+}
234+
229235 // Set Home
230236 $auth_key = auth::get_user_info();
231237 if (!empty($auth_key['home'])) {
--- /dev/null
+++ b/plugin/dav.inc.php
@@ -0,0 +1,636 @@
1+<?php
2+/**
3+ * WebDAV プラグイン
4+ *
5+ * Author: a-urasim@pu-toyama.ac.jp
6+ * Version: 0.39
7+ *
8+ * @copyright Copyright &copy; 2010, Katsumi Saito <jo1upk@users.sourceforge.net>
9+ * @version $Id: dav.inc.php,v 0.39.1 2010/05/30 20:36:00 upk Exp $
10+ * @license http://opensource.org/licenses/gpl-license.php GNU Public License (GPL2)
11+ *
12+ * 現状では、DOMDocument の実装上、PHP5以降でのみ稼働。
13+ * CentOS の場合は、php-xml パッケージを導入する必要あり。
14+ *
15+ * == 稼働上の制限 ==
16+ * apache only:
17+ * $_SERVER: 'HTTPS', 'HTTP_HOST', 'REQUEST_METHOD', 'PATH_INFO', 'REQUEST_URI'
18+ * apache_getenv('SERVER_PORT');
19+ *
20+ * == for Windows Vista/7, check ==
21+ * HKLM\SYSTEM\CurrentControlSet\Services\WebClient\Parameters\BasicAuthLevel
22+ * 0 - Basic authentication disabled
23+ * 1 - Basic authentication enabled for SSL shares only
24+ * 2 or greater - Basic authentication enabled for SSL shares
25+ * and for non-SSL shares
26+ *
27+*/
28+
29+defined('PLUGIN_DAV_SHOWONLYEDITABLE') or define('PLUGIN_DAV_SHOWONLYEDITABLE', false);
30+
31+function plugin_dav_action()
32+{
33+ global $scriptname, $zslash, $log_ua;
34+
35+ if (!exist_plugin('attach')) plugin_dav_error_exit(500,'attach plugin not found.');
36+
37+ $scriptname = SCRIPT_NAME;
38+ // 区切り文字の全角
39+ $zslash = mb_convert_kana('/', 'A', SOURCE_ENCODING);
40+
41+ header('Expires: Sat, 1 Jan 2000 00:00:00 GMT');
42+ header('Cache-Control: no-store, no-cache, must-revalidate');
43+ header('Cache-Control: post-check=0, pre-check=0', false);
44+ header('Pragma: no-cache');
45+
46+ $req_headers = apache_request_headers();
47+ $path_info = (empty($_SERVER['PATH_INFO'])) ? '' : $_SERVER['PATH_INFO'];
48+
49+ switch ($_SERVER['REQUEST_METHOD']) {
50+ case 'OPTIONS':
51+ header('DAV: 1');
52+ // OPTIONS,PROPFIND,GET,HEAD,PUT,DELETE,MOVE,COPY
53+ header('Allow: OPTIONS,PROPFIND,GET,PUT,MOVE,COPY');
54+ header('MS-Author-Via: DAV');
55+ break;
56+ case 'PROPFIND':
57+ // 添付する際にパスワードまたは、管理者のみの場合は、認証を要求
58+ if (PLUGIN_ATTACH_PASSWORD_REQUIRE || PLUGIN_ATTACH_UPLOAD_ADMIN_ONLY) {
59+ // PLUGIN_ATTACH_UPLOAD_ADMIN_ONLY ? 'admin password' : 'password';
60+ if(!isset($req_headers['Authorization'])) plugin_dav_error_exit(401);
61+ //$user = auth::check_auth_pw(); // 認証済かのチェック
62+ //if (empty($user)) plugin_dav_error_exit(401); // 未認証なら認証を要求
63+ }
64+
65+ if( empty($path_info)) {
66+ plugin_dav_error_exit(301, NULL, plugin_dav_myurl1().'/');
67+ }
68+
69+ $tree = plugin_dav_maketree($path_info);
70+ if(!isset($tree)) plugin_dav_error_exit(404);
71+ $ret = plugin_dav_makemultistat($tree, $_SERVER['REQUEST_URI'], $req_headers['Depth']);
72+
73+ if(!isset($ret)) plugin_dav_error_exit(301, NULL, plugin_dav_myurl().'/');
74+ header('HTTP/1.1 207 Multi-Status');
75+ header('Content-Type: text/xml');
76+ echo $ret->saveXML();
77+ exit;
78+
79+ case 'GET':
80+ case 'HEAD':
81+ // 通常のファイル参照時は、このメソッドでアクセスされる
82+ $obj = & plugin_dav_getfileobj($path_info);
83+ if($obj != NULL && $obj->exist) {
84+ $obj->open();
85+ }
86+ else if($_SERVER['REQUEST_METHOD'] == 'GET' && empty($path_info) && strpos($log_ua, 'MSIE') > 0) {
87+ plugin_dav_officious_message();
88+ exit;
89+ }
90+ else plugin_dav_error_exit(404);
91+
92+ break;
93+
94+ case 'PUT':
95+ $pass = NULL;
96+
97+ if (auth::check_role('readonly')) plugin_dav_error_exit(403, 'PKWK_READONLY prohibits editing');
98+
99+ // 添付する際にパスワードまたは、管理者のみの場合は、認証を要求
100+ if (PLUGIN_ATTACH_PASSWORD_REQUIRE || PLUGIN_ATTACH_UPLOAD_ADMIN_ONLY) {
101+ if(isset($req_headers['Authorization']))
102+ $pass = plugin_dav_getbasicpass($req_headers['Authorization']);
103+ // else
104+ // PLUGIN_ATTACH_UPLOAD_ADMIN_ONLY ? 'admin password' : 'password';
105+ // plugin_dav_error_exit(401);
106+ }
107+ if (PLUGIN_ATTACH_UPLOAD_ADMIN_ONLY && $pass !== TRUE &&
108+ ($pass === NULL || ! pkwk_login($pass)))
109+ plugin_dav_error_exit(401); // 'admin only.'
110+
111+ $obj = & plugin_dav_getfileobj($path_info, false);
112+
113+ if(!isset($obj)) plugin_dav_error_exit(403, 'no page');
114+ if($obj->exist){
115+ unlink($tmpfilename);
116+ plugin_dav_error_exit(403, 'already exist.');
117+ }
118+
119+ $size = intval($req_headers['Content-Length']);
120+ // Windows 7のクライアントは、まず0バイト書いて、
121+ // それをLOCKしてから、上書きしにくる。
122+ // しかし、Pukiwikiは基本上書き禁止。
123+ // そこで0バイトの時は無視する。
124+ if($size > 0){
125+ if($size > PLUGIN_ATTACH_MAX_FILESIZE) {
126+ plugin_dav_error_exit(403, 'file size error');
127+ }
128+
129+ $tmpfilename = tempnam('/tmp', 'dav');
130+ $fp = fopen($tmpfilename, 'wb');
131+
132+ $size = 0;
133+ $putdata = fopen('php://input','rb');
134+ while ($data = fread($putdata,1024)){
135+ $size += strlen($data);
136+ fwrite($fp,$data);
137+ }
138+ fclose($putdata);
139+ fclose($fp);
140+
141+ if(copy($tmpfilename, $obj->filename)) {
142+ chmod($obj->filename, PLUGIN_ATTACH_FILE_MODE);
143+ }
144+
145+ if(is_page($obj->page)) touch(get_filename($obj->page));
146+ $obj->getstatus();
147+ $obj->status['pass'] = ($pass !== TRUE && $pass !== NULL) ? md5($pass) : '';
148+ $obj->putstatus();
149+ unlink($tmpfilename);
150+ }
151+
152+ break;
153+
154+ case 'DELETE':
155+ // FIXME
156+ // フォルダーは消せないくせに、消せたように処理してしまう。
157+ //
158+ $pass = NULL;
159+
160+ if (auth::check_role('readonly')) plugin_dav_error_exit(403, 'PKWK_READONLY prohibits editing');
161+
162+ // 添付する際にパスワードまたは、管理者のみの場合は、認証を要求
163+ if (PLUGIN_ATTACH_PASSWORD_REQUIRE || PLUGIN_ATTACH_UPLOAD_ADMIN_ONLY) {
164+ if(isset($req_headers['Authorization']))
165+ $pass = plugin_dav_getbasicpass($req_headers['Authorization']);
166+ // else
167+ // PLUGIN_ATTACH_UPLOAD_ADMIN_ONLY ? 'admin password' : 'password';
168+ // plugin_dav_error_exit(401);
169+ }
170+ if(PLUGIN_ATTACH_UPLOAD_ADMIN_ONLY && $pass !== TRUE &&
171+ ($pass === NULL || ! pkwk_login($pass)))
172+ plugin_dav_error_exit(401); // 'admin only.'
173+
174+ $obj = & plugin_dav_getfileobj($path_info, false);
175+
176+ if(!isset($obj)) plugin_dav_error_exit(403);
177+ if($obj->getstatus() == FALSE) plugin_dav_error_exit(404);
178+
179+ $obj->delete($pass);
180+ if(file_exists($obj->filename)) {
181+ plugin_dav_error_exit(406, "can't delete this file");
182+ }
183+
184+ break;
185+
186+ case 'MOVE':
187+ case 'COPY':
188+ // 添付ファイルのコピーと移動のみ
189+ // 同じページ内での添付ファイルの移動もわざわざ消して書いている
190+ // ページのコピーや移動は未実装
191+
192+ $pass = NULL;
193+
194+ if (auth::check_role('readonly')) plugin_dav_error_exit(403, 'PKWK_READONLY prohibits editing');
195+
196+ // 添付する際にパスワードまたは、管理者のみの場合は、認証を要求
197+ if (PLUGIN_ATTACH_PASSWORD_REQUIRE || PLUGIN_ATTACH_UPLOAD_ADMIN_ONLY) {
198+ if(isset($req_headers['Authorization']))
199+ $pass = plugin_dav_getbasicpass($req_headers['Authorization']);
200+ // else
201+ // PLUGIN_ATTACH_UPLOAD_ADMIN_ONLY ? 'admin password' : 'password';
202+ // plugin_dav_error_exit(401);
203+ }
204+ if(PLUGIN_ATTACH_UPLOAD_ADMIN_ONLY && $pass !== TRUE &&
205+ ($pass === NULL || ! pkwk_login($pass)))
206+ plugin_dav_error_exit(401); // 'admin only.'
207+
208+ // FROM (PATH_INFO)
209+ if($_SERVER['REQUEST_METHOD'] == 'MOVE'){
210+ $obj1 = & plugin_dav_getfileobj($path_info, false);
211+ }
212+ else {
213+ $obj1 = & plugin_dav_getfileobj($path_info, true); // readonly
214+ }
215+ if(!isset($obj1)) plugin_dav_error_exit(403, 'no src page.');
216+ if($obj1->getstatus() == FALSE) plugin_dav_error_exit(404);
217+
218+ // TO (Destination)
219+ $destname = $req_headers['Destination'];
220+ if(strpos($destname, plugin_dav_myurl0()) === 0) {
221+ $destname = substr($destname, strlen(plugin_dav_myurl0()));
222+ }
223+ if(strpos($destname, $scriptname) === 0) {
224+ $destname = urldecode(substr($destname, strlen($scriptname)));
225+ } else {
226+ plugin_dav_error_exit(403, 'not dav directory.');
227+ }
228+
229+ $obj2 = & plugin_dav_getfileobj($destname, false);
230+ if (!isset($obj2)) plugin_dav_error_exit(403, 'no dst page.');
231+ if ($obj2->exist) plugin_dav_error_exit(403, 'already exist');
232+
233+ if(copy($obj1->filename, $obj2->filename)) {
234+ chmod($obj2->filename, PLUGIN_ATTACH_FILE_MODE);
235+ } else {
236+ plugin_dav_error_exit(406, "can't copy it");
237+ }
238+
239+ // COPY
240+ if(is_page($obj2->page)) touch(get_filename($obj2->page));
241+ $obj2->getstatus();
242+ $obj2->status['pass'] = ($pass !== TRUE && $pass !== NULL) ? md5($pass) : '';
243+ $obj2->putstatus();
244+
245+ // MOVE(DELETE)
246+ if($_SERVER['REQUEST_METHOD'] == 'MOVE') {
247+ $obj1->delete($pass);
248+ if(file_exists($obj1->filename))
249+ plugin_dav_error_exit(406, "can't delete this file");
250+ }
251+
252+ break;
253+ /*
254+ case 'MKCOL':
255+ // ページは作成可能
256+ // セキュリティは未検証
257+ // Windowsクライアントを考えると、
258+ // ページのリネームを考えないと無意味
259+
260+ if (auth::check_role('readonly')) plugin_dav_error_exit(403, 'PKWK_READONLY prohibits editing');
261+
262+ // 添付する際にパスワードまたは、管理者のみの場合は、認証を要求
263+ if (PLUGIN_ATTACH_PASSWORD_REQUIRE || PLUGIN_ATTACH_UPLOAD_ADMIN_ONLY) {
264+ if(isset($req_headers['Authorization']))
265+ $pass = plugin_dav_getbasicpass($req_headers['Authorization']);
266+ // else
267+ // PLUGIN_ATTACH_UPLOAD_ADMIN_ONLY ? 'admin password' : 'password';
268+ // plugin_dav_error_exit(401);
269+ }
270+ $path = $path_info;
271+ if(!isset($path)) plugin_dav_error_exit(403);
272+ // $path = mb_convert_encoding($path, SOURCE_ENCODING, 'UTF-8');
273+
274+ if(preg_match('/^\/(.+)\/$/', $path, $matches) != 1)
275+ plugin_dav_error_exit(403);
276+
277+ $page = str_replace($zslash, '/', $matches[1]);
278+ if(is_page($page)) plugin_dav_error_exit(403);
279+
280+ // ここの辺りにもう一つチェックが必要かも
281+ page_write($page, "dav.php"); // write initial string to the page.
282+ break;
283+ */
284+
285+ case 'PROPPATCH':
286+ // ダミールーチン: Windows 7のクライアントは、PROPPATCHが
287+ // 失敗するとファイルを消しに来るため仕方なく。
288+ //
289+ header('HTTP/1.1 207 Multi-Status');
290+ header('Content-Type: text/xml');
291+ $doc = plugin_dav_proppatch_dummy_response($_SERVER['REQUEST_URI']);
292+ echo $doc->saveXML();
293+ exit;
294+
295+ case 'MKCOL':
296+ case 'LOCK':
297+ case 'UNLOCK':
298+ case 'POST':
299+ plugin_dav_error_exit(501); // Method not Implemented
300+ break;
301+ default:
302+ plugin_dav_error_exit(405); // Method not Allowed
303+ }
304+}
305+
306+function plugin_dav_makemultistat($tree, $path, $depth)
307+{
308+ global $zslash;
309+
310+ if(!isset($tree)) return NULL;
311+
312+ // preg_match('/\/$/', $path) != 1 => 1:dir/ 0:dir/filename
313+ // !=1 は、ファイル名の場合は、それを除外
314+ // dir の場合に処理する
315+ if(is_array($tree) && preg_match('/\/$/', $path) != 1) return NULL;
316+
317+ $ret = new DOMDocument();
318+ $ele = $ret->createElementNS('DAV:', 'D:multistatus');
319+ $ret->appendChild($ele);
320+
321+ plugin_dav_makemultistat_sub($ret, $ele, $path, $tree);
322+ if(is_array($tree) && $depth !== '0'){
323+ foreach($tree as $key => $value){
324+ //$str = mb_convert_encoding(str_replace('/', $zslash, $key), 'UTF-8');
325+ $str = str_replace('/', $zslash, $key);
326+ $str = $path.rawurlencode($str);
327+ if(is_array($value)) $str .= '/';
328+ plugin_dav_makemultistat_sub($ret, $ele, $str, $value);
329+ }
330+ }
331+ return $ret;
332+}
333+
334+function plugin_dav_makemultistat_sub(&$doc, &$ele, $name, $type)
335+{
336+ $res = $doc->createElementNS('DAV:', 'D:response');
337+ $ele->appendChild($res);
338+ $href = $doc->createElementNS('DAV:', 'D:href', $name);
339+ $res->appendChild($href);
340+
341+ $propstat = $doc->createElementNS('DAV:', 'D:propstat');
342+ $res->appendChild($propstat);
343+
344+ $prop = $doc->createElementNS('DAV:', 'D:prop');
345+ $propstat->appendChild($prop);
346+
347+ $resourcetype = $doc->createElementNS('DAV:', 'D:resourcetype');
348+ $prop->appendChild($resourcetype);
349+ if(is_array($type)){
350+ $coll = $doc->createElementNS('DAV:', 'D:collection');
351+ $resourcetype->appendChild($coll);
352+ }
353+ else if($type->getstatus() && isset($type->size)){
354+ $getcontentlength = $doc->createElementNS('DAV:', 'D:getcontentlength');
355+ $getcontentlength->appendChild($doc->createTextNode(''.$type->size));
356+ $prop->appendChild($getcontentlength);
357+ }
358+
359+ $stat = $doc->createElementNS('DAV:', 'D:status', 'HTTP/1.1 200 OK');
360+ $propstat->appendChild($stat);
361+}
362+
363+function plugin_dav_error_exit($code, $msg = NULL, $url = NULL)
364+{
365+ global $auth_type, $realm;
366+
367+ $array_msg = array(
368+ 301 => array('msg1'=>'Moved', 'msg2'=>''),
369+ 401 => array('msg1'=>'Authorization Required', 'msg2'=>''),
370+ 403 => array('msg1'=>'Forbidden', 'msg2'=>'Your request is forbideen.'),
371+ 404 => array('msg1'=>'Not Found', 'msg2'=>'The file/directory you request is not found.'),
372+ 405 => array('msg1'=>'Method not Allowed', 'msg2'=>'Your request is not allowd.'),
373+ 406 => array('msg1'=>'Not acceptable', 'msg2'=>'Your request is not acceptable'),
374+ 500 => array('msg1'=>'Internal Server Error', 'msg2'=>'Internal Server Error.'),
375+ 501 => array('msg1'=>'Method not Implemented', 'msg2'=>'The method you request is not implemented.'),
376+ );
377+
378+ if (!array_key_exists($code,$array_msg)) $code = 500;
379+ $msg1 = & $array_msg[$code]['msg1'];
380+ $msg2 = & $array_msg[$code]['msg2'];
381+ header('HTTP/1.1 '.$code.' '.$msg1);
382+
383+ switch ($code) {
384+ case 301:
385+ header('Location: '.$url);
386+ exit;
387+ case 401:
388+ switch ($auth_type) {
389+ case 2:
390+ header('WWW-Authenticate: Digest realm="'.$realm.
391+ '", qop="auth", nonce="'.uniqid().'", opaque="'.md5($realm).'"');
392+ exit;
393+ default:
394+ header('WWW-Authenticate: Basic realm="'.$realm.'"');
395+ exit;
396+ }
397+ exit;
398+ }
399+
400+ echo '<html><head>';
401+ echo '<title>'.$code.' '.$msg1.'</title>';
402+ echo '</head><body>';
403+ echo '<h1>'.$code.' '.$msg1.'</h1>';
404+ echo '<p>'.$msg2.'</p>';
405+ if(isset($msg)) echo '<p>'.htmlspecialchars($msg).'</p>';
406+ echo '<p>This script should be used with WebDAV protocol.</p>';
407+ echo '</body></html>';
408+ exit;
409+}
410+
411+function plugin_dav_officious_message()
412+{
413+ global $scriptname;
414+
415+ $myurl1 = plugin_dav_myurl1();
416+ $port = apache_getenv('SERVER_PORT');
417+ echo '<html>';
418+ echo '<head><title>officious message</title></head>';
419+ echo '<body>';
420+ echo '<p>Please use this script with WebDAV protocol.</p>';
421+ echo '<p>If your client OS is <font size=+2>Windows XP</font>,';
422+
423+ if( strrpos($scriptname, '/') != 0){
424+ echo ' you should place this script in document root directory';
425+ }
426+ else if($_SERVER['HTTPS'] != 'on' && (!isset($port) || $port == 80)){
427+ $myurl2 = preg_replace('/^http:/', 'https:', $myurl1);
428+ echo ' you may be able to click';
429+ echo ' <a style="behavior: url(#default#AnchorClick);"';
430+ echo ' Folder="'.$myurl1.'?">'.$myurl1.'?';
431+ echo '</a> or <a style="behavior: url(#default#AnchorClick);"';
432+ echo ' Folder="'.$myurl2.'/">'.$myurl2.'/';
433+ echo '</a>. <br>Or do <font size=+2>"Add Network Place"';
434+ echo ' in "My Network Place"</font>';
435+ }
436+ else {
437+ echo ' you may be able to click';
438+ echo ' <a style="behavior: url(#default#AnchorClick);"';
439+ echo ' Folder="'.$myurl1.'/">'.$myurl1.'/';
440+ echo '</a>. <br>Or do <font size=+2>"Add Network Place"';
441+ echo ' in "My Network Place"</font>';
442+ }
443+
444+ echo '</p>';
445+ echo '<p>If your client OS is <font size=+2>Windows 7</font>, ';
446+
447+ if($_SERVER['HTTPS'] != 'on' && (!isset($port) || $port == 80)){
448+ $myurl2 = preg_replace('/^http:/', 'https:', $myurl1);
449+ echo 'you can try <font size=+2>"net use w: '.$myurl1.'"</font>';
450+ echo ' or <font size=+2>"net use w: '.$myurl2.'".</font>';
451+ echo ' ("w:" is arbitary drive letter.)';
452+ echo '<br>Or you are rarely(at the very first time after booting?)';
453+ echo ' be able to click';
454+ echo ' <a style="behavior: url(#default#AnchorClick);"';
455+ echo ' Folder="'.$myurl1.'">'.$myurl1.'</a>';
456+ echo ' or <a style="behavior: url(#default#AnchorClick);"';
457+ echo ' Folder="'.$myurl2.'">'.$myurl2.'</a>.';
458+ echo '<br>(http: can be used only when the value in the regsitry key';
459+ echo ' "HKLM\SYSTEM\CurrentControlSet\Services\WebClient\Parameters\BasicAuthLevel" is "2")';
460+ }
461+ else {
462+ echo 'you can try <font size=+2>"net use w: '.$myurl1.'"</font>';
463+ echo ' ("w:" is arbitary drive letter.)';
464+ echo '<br>Or you are rarely(at the very first time after booting?)';
465+ echo ' be able to click';
466+ echo ' <a style="behavior: url(#default#AnchorClick);"';
467+ echo ' Folder="'.$myurl1.'">'.$myurl1.'</a>.';
468+ }
469+
470+ echo '</p>';
471+ echo '</body>';
472+ echo '</html>';
473+}
474+
475+function plugin_dav_myurl0()
476+{
477+ // $_SERVER['HTTPS'] - https かどうかの判定用
478+ // get_script_absuri();
479+ // rc - http://jo1upk.blogdns.net:80
480+ $url = ($_SERVER['HTTPS'] == 'on') ? 'https://' : 'http://';
481+ $url .= $_SERVER['HTTP_HOST'];
482+ $port = apache_getenv('SERVER_PORT');
483+ if(isset($port) && $port != 443 && $_SERVER['HTTPS'] == 'on')
484+ $url .= ':'.$port;
485+ else if(isset($port) && $port != 80 && $_SERVER['HTTPS'] != 'on')
486+ $url .= ':'.$port;
487+ return $url;
488+}
489+function plugin_dav_myurl1()
490+{
491+ global $scriptname;
492+ return plugin_dav_myurl0() . $scriptname;
493+}
494+function plugin_dav_myurl()
495+{
496+ return plugin_dav_myurl0() . $_SERVER['REQUEST_URI'];
497+}
498+
499+// このルーチンを何とかすると、
500+// 全角スラッシュの件が何とかなるかも。
501+function plugin_dav_maketree0()
502+{
503+ global $whatsnew, $attach_link;
504+
505+ $root = array();
506+ $pagelist = auth::get_existpages();
507+ foreach($pagelist as $page){
508+ if(check_non_list($page)) continue;
509+ if($page == $whatsnew) continue;
510+ if(PLUGIN_DAV_SHOWONLYEDITABLE && !is_editable($page)) continue;
511+
512+ $root[$page] = array();
513+ }
514+
515+ // FIXME
516+ // 認証時は、この制限を回避するようにする。
517+ // 現状は、添付ファイル非表示の場合は抑止
518+ if (!$attach_link) return $root;
519+
520+ $attaches = & new AttachPages('');
521+ foreach($attaches->pages as $key => $val){
522+ if(check_non_list($key)) continue;
523+ if(!check_readable($key, false, false)) continue;
524+ if(PLUGIN_DAV_SHOWONLYEDITABLE && !is_editable($key)) continue;
525+
526+ if(!isset($root[$key])) $root[$key] = array();
527+ if(is_array($root[$key])){
528+ foreach($val->files as $file => $arr){
529+ if(isset($arr[0])) $root[$key][$file] = $arr[0];
530+ }
531+ }
532+ }
533+
534+ return $root;
535+}
536+
537+function plugin_dav_maketree($path)
538+{
539+ global $zslash;
540+ $page = null;
541+
542+ $tree = plugin_dav_maketree0();
543+ if(empty($path)) return $tree;
544+
545+ // $path = mb_convert_encoding($path, SOURCE_ENCODING, 'UTF-8');
546+
547+ $pieces = explode('/', $path);
548+ if(!empty($pieces[0])) return NULL;
549+ $count = count($pieces);
550+ for($i = 1; $i < $count; $i++){
551+ if(empty($pieces[$i])){
552+ if(is_array($tree)){
553+ continue;
554+ }
555+ else
556+ return NULL;
557+ }
558+ else if(is_array($tree)){
559+ $pieces[$i] = str_replace($zslash, '/', $pieces[$i]);
560+
561+ if(isset($tree[$pieces[$i]]))
562+ $tree = $tree[$pieces[$i]];
563+ else
564+ return NULL;
565+
566+ if(is_array($tree)){
567+ if($page == null) $page = $pieces[$i];
568+ else $page .= '/'.$pieces[$i];
569+ }
570+ }
571+ else
572+ return NULL;
573+ }
574+
575+ if(isset($page) && !check_readable($page, false, false)) plugin_dav_error_exit(401); // 'user/password'
576+
577+ return $tree;
578+}
579+
580+function plugin_dav_getfileobj($path, $readonly=true)
581+{
582+ global $zslash;
583+
584+ if(!isset($path)) return NULL;
585+
586+ // $path = mb_convert_encoding($path, SOURCE_ENCODING, 'UTF-8');
587+
588+ if(preg_match('/^\/(.+)\/([^\/]+)$/', $path, $matches) != 1)
589+ return NULL;
590+
591+ $page = str_replace($zslash, '/', $matches[1]);
592+ if(!is_page($page)) return NULL;
593+ if(!$readonly && !is_editable($page)) return NULL;
594+
595+ if(!check_readable($page, false, false)) plugin_dav_error_exit(401); // 'user/password'
596+ if(!$readonly && !check_editable($page, false, false)) plugin_dav_error_exit(401); // 'user/password'
597+
598+ return new AttachFile($page, $matches[2]);
599+}
600+
601+function plugin_dav_getbasicpass($str)
602+{
603+ if(preg_match('/^Basic (.+)$/', $str, $matches) != 1)
604+ return NULL;
605+ $str2 = base64_decode($matches[1]);
606+ if($str2 === false) return NULL;
607+ if(preg_match('/^[^:]+:(.+)$/', $str2, $matches2) != 1)
608+ return NULL;
609+ if(!isset($matches2[1])) return NULL;
610+ if($matches2[1] == '') return NULL;
611+ return $matches2[1];
612+}
613+
614+function plugin_dav_proppatch_dummy_response($path)
615+{
616+ $doc = new DOMDocument();
617+ $ele = $doc->createElementNS('DAV:', 'D:multistatus');
618+ $doc->appendChild($ele);
619+ $res = $doc->createElementNS('DAV:', 'D:response');
620+ $ele->appendChild($res);
621+ $href = $doc->createElementNS('DAV:', 'D:href', $path);
622+ $res->appendChild($href);
623+ $propstat = $doc->createElementNS('DAV:', 'D:propstat');
624+ $res->appendChild($prospstat);
625+ $prop = $doc->createElementNS('DAV:', 'D:prop');
626+ $propstat->appendChild($prop);
627+ $prop->appendChild($doc->createElementNS('urn:schemas-microsoft-com:', 'Z:Win32CreationTime'));
628+ $prop->appendChild($doc->createElementNS('urn:schemas-microsoft-com:', 'Z:Win32LastAccessTime'));
629+ $prop->appendChild($doc->createElementNS('urn:schemas-microsoft-com:', 'Z:Win32LastModifiedTime'));
630+ $prop->appendChild($doc->createElementNS('urn:schemas-microsoft-com:', 'Z:Win32FileAttributes'));
631+ $stat = $doc->createElementNS('DAV:', 'D:status', 'HTTP/1.1 200 OK');
632+ $propstat->appendChild($stat);
633+ return $doc;
634+}
635+
636+?>