OSDN Git Service

BugTrack2/122: tempnam() fails when open_basedir is specified in php.ini
[pukiwiki/pukiwiki.git] / plugin / attach.inc.php
index a075dd4..4fb0d08 100644 (file)
@@ -1,58 +1,54 @@
 <?php
-/////////////////////////////////////////////////
-// PukiWiki - Yet another WikiWikiWeb clone.
+// PukiWiki - Yet another WikiWikiWeb clone
+// $Id: attach.inc.php,v 1.80 2005/12/18 15:27:43 henoheno Exp $
+// Copyright (C)
+//   2003-2005 PukiWiki Developers Team
+//   2002-2003 PANDA <panda@arino.jp> http://home.arino.jp/
+//   2002      Y.MASUI <masui@hisec.co.jp> http://masui.net/pukiwiki/
+//   2001-2002 Originally written by yu-ji
+// License: GPL v2 or (at your option) any later version
 //
-//  $Id: attach.inc.php,v 1.58 2004/08/14 23:12:18 henoheno Exp $
-//
-
-/*
- ¥×¥é¥°¥¤¥ó attach
-
- changed by Y.MASUI <masui@hisec.co.jp> http://masui.net/pukiwiki/
- modified by PANDA <panda@arino.jp> http://home.arino.jp/
-*/
+// File attach plugin
 
+// NOTE (PHP > 4.2.3):
+//    This feature is disabled at newer version of PHP.
+//    Set this at php.ini if you want.
 // Max file size for upload on PHP (PHP default: 2MB)
 ini_set('upload_max_filesize', '2M');
 
 // Max file size for upload on script of PukiWikiX_FILESIZE
-define('MAX_FILESIZE', (1024 * 1024)); // default: 1MB
+define('PLUGIN_ATTACH_MAX_FILESIZE', (1024 * 1024)); // default: 1MB
 
 // ´ÉÍý¼Ô¤À¤±¤¬ÅºÉÕ¥Õ¥¡¥¤¥ë¤ò¥¢¥Ã¥×¥í¡¼¥É¤Ç¤­¤ë¤è¤¦¤Ë¤¹¤ë
-define('ATTACH_UPLOAD_ADMIN_ONLY', FALSE); // FALSE or TRUE
+define('PLUGIN_ATTACH_UPLOAD_ADMIN_ONLY', TRUE); // FALSE or TRUE
 
 // ´ÉÍý¼Ô¤À¤±¤¬ÅºÉÕ¥Õ¥¡¥¤¥ë¤òºï½ü¤Ç¤­¤ë¤è¤¦¤Ë¤¹¤ë
-define('ATTACH_DELETE_ADMIN_ONLY', FALSE); // FALSE or TRUE
+define('PLUGIN_ATTACH_DELETE_ADMIN_ONLY', TRUE); // FALSE or TRUE
 
 // ´ÉÍý¼Ô¤¬ÅºÉÕ¥Õ¥¡¥¤¥ë¤òºï½ü¤¹¤ë¤È¤­¤Ï¡¢¥Ð¥Ã¥¯¥¢¥Ã¥×¤òºî¤é¤Ê¤¤
-// ATTACH_DELETE_ADMIN_ONLY=TRUE¤Î¤È¤­Í­¸ú
-define('ATTACH_DELETE_ADMIN_NOBACKUP', FALSE); // FALSE or TRUE
+// PLUGIN_ATTACH_DELETE_ADMIN_ONLY=TRUE¤Î¤È¤­Í­¸ú
+define('PLUGIN_ATTACH_DELETE_ADMIN_NOBACKUP', TRUE); // FALSE or TRUE
 
 // ¥¢¥Ã¥×¥í¡¼¥É/ºï½ü»þ¤Ë¥Ñ¥¹¥ï¡¼¥É¤òÍ׵᤹¤ë(ADMIN_ONLY¤¬Í¥Àè)
-define('ATTACH_PASSWORD_REQUIRE', FALSE); // FALSE or TRUE
+define('PLUGIN_ATTACH_PASSWORD_REQUIRE', FALSE); // FALSE or TRUE
 
 // ¥Õ¥¡¥¤¥ë¤Î¥¢¥¯¥»¥¹¸¢
-define('ATTACH_FILE_MODE', 0644);
-//define('ATTACH_FILE_MODE', 0604); // for XREA.COM
-
-// file icon image
-if (! defined('FILE_ICON')) {
-       define('FILE_ICON', '<img src="' . IMAGE_DIR .  'file.png"' .
-               ' width="20" height="20" alt="file"' .
-               ' style="border-width:0px" />');
-}
+define('PLUGIN_ATTACH_FILE_MODE', 0644);
+//define('PLUGIN_ATTACH_FILE_MODE', 0604); // for XREA.COM
+
+// File icon image
+define('PLUGIN_ATTACH_FILE_ICON', '<img src="' . IMAGE_DIR .  'file.png"' .
+       ' width="20" height="20" alt="file"' .
+       ' style="border-width:0px" />');
 
 // mime-type¤òµ­½Ò¤·¤¿¥Ú¡¼¥¸
-define('ATTACH_CONFIG_PAGE_MIME', 'plugin/attach/mime-type');
+define('PLUGIN_ATTACH_CONFIG_PAGE_MIME', 'plugin/attach/mime-type');
 
 //-------- convert
 function plugin_attach_convert()
 {
        global $vars;
 
-       if (! ini_get('file_uploads'))
-               return '#attach(): file_uploads disabled';
-
        $page = isset($vars['page']) ? $vars['page'] : '';
 
        $nolist = $noform = FALSE;
@@ -108,8 +104,14 @@ function plugin_attach_action()
        if (isset($_FILES['attach_file'])) {
                // Upload
                return attach_upload($_FILES['attach_file'], $refer, $pass);
-       }
-       switch ($pcmd) {
+       } else {
+               switch ($pcmd) {
+               case 'delete':  /*FALLTHROUGH*/
+               case 'freeze':
+               case 'unfreeze':
+                       if (PKWK_READONLY) die_message('PKWK_READONLY prohibits editing');
+               }
+               switch ($pcmd) {
                case 'info'     : return attach_info();
                case 'delete'   : return attach_delete();
                case 'open'     : return attach_open();
@@ -117,11 +119,12 @@ function plugin_attach_action()
                case 'freeze'   : return attach_freeze(TRUE);
                case 'unfreeze' : return attach_freeze(FALSE);
                case 'upload'   : return attach_showform();
-       }
-       if ($page == '' || ! is_page($page)) {
-               return attach_list();
-       } else {
-               return attach_showform();
+               }
+               if ($page == '' || ! is_page($page)) {
+                       return attach_list();
+               } else {
+                       return attach_showform();
+               }
        }
 }
 
@@ -148,13 +151,23 @@ function attach_filelist()
 // $pass = TRUE : ¥¢¥Ã¥×¥í¡¼¥Éµö²Ä
 function attach_upload($file, $page, $pass = NULL)
 {
-       global $_attach_messages;
+       global $_attach_messages, $notify, $notify_subject;
+
+       if (PKWK_READONLY) die_message('PKWK_READONLY prohibits editing');
 
-       if (! is_page($page)) {
-               die_message("No such page");
+       // Check query-string
+       $query = 'plugin=attach&amp;pcmd=info&amp;refer=' . rawurlencode($page) .
+               '&amp;file=' . rawurlencode($file['name']);
+
+       if (PKWK_QUERY_STRING_MAX && strlen($query) > PKWK_QUERY_STRING_MAX) {
+               pkwk_common_headers();
+               echo('Query string (page name and/or file name) too long');
+               exit;
+       } else if (! is_page($page)) {
+               die_message('No such page');
        } else if ($file['tmp_name'] == '' || ! is_uploaded_file($file['tmp_name'])) {
                return array('result'=>FALSE);
-       } else if ($file['size'] > MAX_FILESIZE) {
+       } else if ($file['size'] > PLUGIN_ATTACH_MAX_FILESIZE) {
                return array(
                        'result'=>FALSE,
                        'msg'=>$_attach_messages['err_exceed']);
@@ -162,7 +175,7 @@ function attach_upload($file, $page, $pass = NULL)
                return array(
                        'result'=>FALSE,'
                        msg'=>$_attach_messages['err_noparm']);
-       } else if (ATTACH_UPLOAD_ADMIN_ONLY && $pass !== TRUE &&
+       } else if (PLUGIN_ATTACH_UPLOAD_ADMIN_ONLY && $pass !== TRUE &&
                  ($pass === NULL || ! pkwk_login($pass))) {
                return array(
                        'result'=>FALSE,
@@ -170,23 +183,42 @@ function attach_upload($file, $page, $pass = NULL)
        }
 
        $obj = & new AttachFile($page, $file['name']);
-       if ($obj->exist) {
+       if ($obj->exist)
                return array('result'=>FALSE,
                        'msg'=>$_attach_messages['err_exists']);
-       }
 
-       if (move_uploaded_file($file['tmp_name'], $obj->filename)) {
-               chmod($obj->filename, ATTACH_FILE_MODE);
-       }
+       if (move_uploaded_file($file['tmp_name'], $obj->filename))
+               chmod($obj->filename, PLUGIN_ATTACH_FILE_MODE);
 
-       if (is_page($page)) {
+       if (is_page($page))
                touch(get_filename($page));
-       }
 
        $obj->getstatus();
-       $obj->status['pass'] = ($pass !== TRUE && $pass !== NULL) ? $pass : '';
+       $obj->status['pass'] = ($pass !== TRUE && $pass !== NULL) ? md5($pass) : '';
        $obj->putstatus();
 
+       if ($notify) {
+               $footer['ACTION']   = 'File attached';
+               $footer['FILENAME'] = & $file['name'];
+               $footer['FILESIZE'] = & $file['size'];
+               $footer['PAGE']     = & $page;
+
+               $footer['URI']      = get_script_uri() .
+                       //'?' . rawurlencode($page);
+
+                       // MD5 may heavy
+                       '?plugin=attach' .
+                               '&refer=' . rawurlencode($page) .
+                               '&file='  . rawurlencode($file['name']) .
+                               '&pcmd=info';
+
+               $footer['USER_AGENT']  = TRUE;
+               $footer['REMOTE_ADDR'] = TRUE;
+
+               pkwk_mail_notify($notify_subject, "\n", $footer) or
+                       die('pkwk_mail_notify(): Failed');
+       }
+
        return array(
                'result'=>TRUE,
                'msg'=>$_attach_messages['msg_uploaded']);
@@ -197,9 +229,8 @@ function attach_info($err = '')
 {
        global $vars, $_attach_messages;
 
-       foreach (array('refer', 'file', 'age') as $var) {
+       foreach (array('refer', 'file', 'age') as $var)
                ${$var} = isset($vars[$var]) ? $vars[$var] : '';
-       }
 
        $obj = & new AttachFile($refer, $file, $age);
        return $obj->getstatus() ?
@@ -212,18 +243,17 @@ function attach_delete()
 {
        global $vars, $_attach_messages;
 
-       foreach (array('refer', 'file', 'age', 'pass') as $var) {
+       foreach (array('refer', 'file', 'age', 'pass') as $var)
                ${$var} = isset($vars[$var]) ? $vars[$var] : '';
-       }
 
-       if (is_freeze($refer) || ! is_editable($refer)) {
+       if (is_freeze($refer) || ! is_editable($refer))
                return array('msg'=>$_attach_messages['err_noparm']);
-       } else {
-               $obj = & new AttachFile($refer, $file, $age);
-               return $obj->getstatus() ?
-                       $obj->delete($pass) :
-                       array('msg'=>$_attach_messages['err_notfound']);
-       }
+
+       $obj = & new AttachFile($refer, $file, $age);
+       if (! $obj->getstatus())
+               return array('msg'=>$_attach_messages['err_notfound']);
+               
+       return $obj->delete($pass);
 }
 
 // Åà·ë
@@ -277,22 +307,14 @@ function attach_list()
        return array('msg'=>$msg, 'body'=>$body);
 }
 
-// ¥¢¥Ã¥×¥í¡¼¥É¥Õ¥©¡¼¥à¤òɽ¼¨
+// ¥¢¥Ã¥×¥í¡¼¥É¥Õ¥©¡¼¥à¤òɽ¼¨ (action»þ)
 function attach_showform()
 {
        global $vars, $_attach_messages;
 
        $page = isset($vars['page']) ? $vars['page'] : '';
-
        $vars['refer'] = $page;
-
-       if (! ini_get('file_uploads')) {
-               $body = '#attach(): file_uploads disabled.';
-       } else if (! is_page($page)) {
-               $body = '#attach(): No such page';
-       } else {
-               $body = attach_form($page);
-       }
+       $body = attach_form($page);
 
        return array('msg'=>$_attach_messages['msg_upload'], 'body'=>$body);
 }
@@ -322,7 +344,7 @@ function attach_mime_content_type($filename)
        $filename = decode($matches[1]);
 
        // mime-type°ìÍ÷ɽ¤ò¼èÆÀ
-       $config = new Config(ATTACH_CONFIG_PAGE_MIME);
+       $config = new Config(PLUGIN_ATTACH_CONFIG_PAGE_MIME);
        $table = $config->read() ? $config->get('mime-type') : array();
        unset($config); // ¥á¥â¥êÀáÌó
 
@@ -337,7 +359,7 @@ function attach_mime_content_type($filename)
        return $type;
 }
 
-// ¥¢¥Ã¥×¥í¡¼¥É¥Õ¥©¡¼¥à
+// ¥¢¥Ã¥×¥í¡¼¥É¥Õ¥©¡¼¥à¤Î½ÐÎÏ
 function attach_form($page)
 {
        global $script, $vars, $_attach_messages;
@@ -351,14 +373,15 @@ function attach_form($page)
   </span><br />
 EOD;
 
-       if (! (bool)ini_get('file_uploads')) return $navi;
+       if (! ini_get('file_uploads')) return '#attach(): file_uploads disabled<br />' . $navi;
+       if (! is_page($page))          return '#attach(): No such page<br />'          . $navi;
 
-       $maxsize = MAX_FILESIZE;
+       $maxsize = PLUGIN_ATTACH_MAX_FILESIZE;
        $msg_maxsize = sprintf($_attach_messages['msg_maxsize'], number_format($maxsize/1024) . 'KB');
 
        $pass = '';
-       if (ATTACH_PASSWORD_REQUIRE || ATTACH_UPLOAD_ADMIN_ONLY) {
-               $title = $_attach_messages[ATTACH_UPLOAD_ADMIN_ONLY ? 'msg_adminpass' : 'msg_password'];
+       if (PLUGIN_ATTACH_PASSWORD_REQUIRE || PLUGIN_ATTACH_UPLOAD_ADMIN_ONLY) {
+               $title = $_attach_messages[PLUGIN_ATTACH_UPLOAD_ADMIN_ONLY ? 'msg_adminpass' : 'msg_password'];
                $pass = '<br />' . $title . ': <input type="password" name="pass" size="8" />';
        }
        return <<<EOD
@@ -372,7 +395,7 @@ EOD;
   <span class="small">
    $msg_maxsize
   </span><br />
-  {$_attach_messages['msg_file']}: <input type="file" name="attach_file" />
+  <label for="_p_attach_file">{$_attach_messages['msg_file']}:</label> <input type="file" name="attach_file" id="_p_attach_file" />
   $pass
   <input type="submit" value="{$_attach_messages['btn_upload']}" />
  </div>
@@ -394,7 +417,7 @@ class AttachFile
        function AttachFile($page, $file, $age = 0)
        {
                $this->page = $page;
-               $this->file = basename($file);
+               $this->file = preg_replace('#^.*/#','',$file);
                $this->age  = is_numeric($age) ? $age : 0;
 
                $this->basename = UPLOAD_DIR . encode($page) . '_' . encode($this->file);
@@ -455,14 +478,14 @@ class AttachFile
                $param  = '&amp;file=' . rawurlencode($this->file) . '&amp;refer=' . rawurlencode($this->page) .
                        ($this->age ? '&amp;age=' . $this->age : '');
                $title = $this->time_str . ' ' . $this->size_str;
-               $label = ($showicon ? FILE_ICON : '') . htmlspecialchars($this->file);
+               $label = ($showicon ? PLUGIN_ATTACH_FILE_ICON : '') . htmlspecialchars($this->file);
                if ($this->age) {
                        $label .= ' (backup No.' . $this->age . ')';
                }
                $info = $count = '';
                if ($showinfo) {
                        $_title = str_replace('$1', rawurlencode($this->file), $_attach_messages['msg_info']);
-                       $info = "\n<span class=\"small\">[<a href=\"$script?plugin=attach&amp;pcmd=info$param\" title=\"$_title\">{$_attach_messages['btn_info']}</a>]</span>";
+                       $info = "\n<span class=\"small\">[<a href=\"$script?plugin=attach&amp;pcmd=info$param\" title=\"$_title\">{$_attach_messages['btn_info']}</a>]</span>\n";
                        $count = ($showicon && ! empty($this->status['count'][$this->age])) ?
                                sprintf($_attach_messages['msg_count'], $this->status['count'][$this->age]) : '';
                }
@@ -481,28 +504,27 @@ class AttachFile
 
                if ($this->age) {
                        $msg_freezed = '';
-                       $msg_delete  = '<input type="radio" name="pcmd" value="delete" />' .
-                               $_attach_messages['msg_delete'] .
-                               $_attach_messages['msg_require'] . '<br />';
+                       $msg_delete  = '<input type="radio" name="pcmd" id="_p_attach_delete" value="delete" />' .
+                               '<label for="_p_attach_delete">' .  $_attach_messages['msg_delete'] .
+                               $_attach_messages['msg_require'] . '</label><br />';
                        $msg_freeze  = '';
                } else {
                        if ($this->status['freeze']) {
                                $msg_freezed = "<dd>{$_attach_messages['msg_isfreeze']}</dd>";
                                $msg_delete  = '';
-                               $msg_freeze  = '<input type="radio" name="pcmd" value="unfreeze" />' .
-                                       $_attach_messages['msg_unfreeze'] .
-                                       $_attach_messages['msg_require'] . '<br />';
+                               $msg_freeze  = '<input type="radio" name="pcmd" id="_p_attach_unfreeze" value="unfreeze" />' .
+                                       '<label for="_p_attach_unfreeze">' .  $_attach_messages['msg_unfreeze'] .
+                                       $_attach_messages['msg_require'] . '</label><br />';
                        } else {
                                $msg_freezed = '';
-                               $msg_delete = '<input type="radio" name="pcmd" value="delete" />' .
-                                       $_attach_messages['msg_delete'];
-                               if (ATTACH_DELETE_ADMIN_ONLY || $this->age) {
+                               $msg_delete = '<input type="radio" name="pcmd" id="_p_attach_delete" value="delete" />' .
+                                       '<label for="_p_attach_delete">' . $_attach_messages['msg_delete'];
+                               if (PLUGIN_ATTACH_DELETE_ADMIN_ONLY || $this->age)
                                        $msg_delete .= $_attach_messages['msg_require'];
-                               }
-                               $msg_delete .= '<br />';
-                               $msg_freeze  = '<input type="radio" name="pcmd" value="freeze" />' .
-                                       $_attach_messages['msg_freeze'] .
-                                       $_attach_messages['msg_require'] . '<br />';
+                               $msg_delete .= '</label><br />';
+                               $msg_freeze  = '<input type="radio" name="pcmd" id="_p_attach_freeze" value="freeze" />' .
+                                       '<label for="_p_attach_freeze">' .  $_attach_messages['msg_freeze'] .
+                                       $_attach_messages['msg_require'] . '</label><br />';
                        }
                }
                $info = $this->toString(TRUE, FALSE);
@@ -534,7 +556,8 @@ $s_err
   <input type="hidden" name="age" value="{$this->age}" />
   $msg_delete
   $msg_freeze
-  {$_attach_messages['msg_password']}: <input type="password" name="pass" size="8" />
+  <label for="_p_attach_password">{$_attach_messages['msg_password']}:</label>
+  <input type="password" name="pass" id="_p_attach_password" size="8" />
   <input type="submit" value="{$_attach_messages['btn_submit']}" />
  </div>
 </form>
@@ -544,14 +567,14 @@ EOD;
 
        function delete($pass)
        {
-               global $_attach_messages;
+               global $_attach_messages, $notify, $notify_subject;
 
                if ($this->status['freeze']) return attach_info('msg_isfreeze');
 
                if (! pkwk_login($pass)) {
-                       if (ATTACH_DELETE_ADMIN_ONLY || $this->age) {
+                       if (PLUGIN_ATTACH_DELETE_ADMIN_ONLY || $this->age) {
                                return attach_info('err_adminpass');
-                       } else if (ATTACH_PASSWORD_REQUIRE &&
+                       } else if (PLUGIN_ATTACH_PASSWORD_REQUIRE &&
                                md5($pass) != $this->status['pass']) {
                                return attach_info('err_password');
                        }
@@ -559,7 +582,7 @@ EOD;
 
                // ¥Ð¥Ã¥¯¥¢¥Ã¥×
                if ($this->age ||
-                       (ATTACH_DELETE_ADMIN_ONLY && ATTACH_DELETE_ADMIN_NOBACKUP)) {
+                       (PLUGIN_ATTACH_DELETE_ADMIN_ONLY && PLUGIN_ATTACH_DELETE_ADMIN_NOBACKUP)) {
                        @unlink($this->filename);
                } else {
                        do {
@@ -576,8 +599,19 @@ EOD;
                        $this->putstatus();
                }
 
-               if (is_page($this->page)) {
+               if (is_page($this->page))
                        touch(get_filename($this->page));
+
+               if ($notify) {
+                       $footer['ACTION']   = 'File deleted';
+                       $footer['FILENAME'] = & $this->file;
+                       $footer['PAGE']     = & $this->page;
+                       $footer['URI']      = get_script_uri() .
+                               '?' . rawurlencode($this->page);
+                       $footer['USER_AGENT']  = TRUE;
+                       $footer['REMOTE_ADDR'] = TRUE;
+                       pkwk_mail_notify($notify_subject, "\n", $footer) or
+                               die('pkwk_mail_notify(): Failed');
                }
 
                return array('msg'=>$_attach_messages['msg_deleted']);
@@ -601,16 +635,30 @@ EOD;
                $this->getstatus();
                $this->status['count'][$this->age]++;
                $this->putstatus();
-
-               // for Japanese (???)
-               $filename = htmlspecialchars(mb_convert_encoding($this->file,'SJIS','auto'));
+               $filename = $this->file;
+
+               // Care for Japanese-character-included file name
+               if (LANG == 'ja') {
+                       switch(UA_NAME . '/' . UA_PROFILE){
+                       case 'Opera/default':
+                               // Care for using _auto-encode-detecting_ function
+                               $filename = mb_convert_encoding($filename, 'UTF-8', 'auto');
+                               break;
+                       case 'MSIE/default':
+                               $filename = mb_convert_encoding($filename, 'SJIS', 'auto');
+                               break;
+                       }
+               }
+               $filename = htmlspecialchars($filename);
 
                ini_set('default_charset', '');
                mb_http_output('pass');
 
+               pkwk_common_headers();
                header('Content-Disposition: inline; filename="' . $filename . '"');
                header('Content-Length: ' . $this->size);
                header('Content-Type: '   . $this->type);
+
                @readfile($this->filename);
                exit;
        }
@@ -720,8 +768,6 @@ class AttachPages
 
        function toString($page = '', $flat = FALSE)
        {
-               global $non_list;
-
                if ($page != '') {
                        if (! isset($this->pages[$page])) {
                                return '';
@@ -735,10 +781,10 @@ class AttachPages
                sort($pages);
 
                foreach ($pages as $page) {
-                       if (preg_match("/$non_list/", $page)) continue;
-                       $ret .= '<li>' . $this->pages[$page]->toString($flat) . "</li>\n";
+                       if (check_non_list($page)) continue;
+                       $ret .= '<li>' . $this->pages[$page]->toString($flat) . '</li>' . "\n";
                }
-               return "\n<ul>\n" . $ret . "</ul>\n";
+               return "\n" . '<ul>' . "\n" . $ret . '</ul>' . "\n";
        }
 }
 ?>