pixmicat

Subversion Repositories:
Compare Path: Rev
With Path: Rev
/release @ 461  →  /release/ @ 847
New file

Property changes:

Name: svn:keywords
+ Id Date Author

/release/Utilities-PIO-v6/mysql2pio.php
@@ -0,0 +1,70 @@
<?php
/**
* Pixmicat! PIO 公用程式 - Pixmicat!-MySQL -> Pixmciat-PIO (MySQL) 資料格式轉換器
*
* 本程式可以自 MySQL 版轉換格式自 PIO 版 MySQL 資料來源。
*
* 注意:本程式是給 MySQL 版舊程式使用以轉換,非直接用在 PIO 新版上面
*
* @package PMCUtility
* @version $Id$
* @date $Date$
*/
include_once('./config.php');
 
$dirimg = realpath('.').DIRECTORY_SEPARATOR.IMG_DIR; // 圖檔存放位置
 
/* 取得圖檔的寬長以存入資料 */
function getImageWH($imgname){
global $dirimg;
 
$imgpath = $dirimg.$imgname;
if(!file_exists($imgpath)) return array(0, 0);
list($width, $height,) = getimagesize($imgpath);
return array($width, $height); // 回傳寬高陣列
}
 
/* 取得圖檔的檔案大小字串 (單位 KB) */
function getImageSizeText($imgname){
global $dirimg;
 
$imgpath = $dirimg.$imgname;
if(!file_exists($imgpath)) return false;
$imgsize = filesize($imgpath);
return ($imgsize >= 1024 ? (int)($imgsize / 1024).' KB' : $imgsize.' B'); // 回傳檔案大小字串
}
 
 
if(@!$con=mysql_connect(MYSQL_SERVER, MYSQL_USER, MYSQL_PASSWORD)){
echo 'It occurred a fatal error when connecting to the MySQL server.<p>';
echo 'Check your MySQL login setting in config file or the MySQL server status.';
exit;
}
mysql_select_db(MYSQL_DBNAME, $con);
@mysql_query("SET NAMES 'utf8'"); // MySQL資料以UTF-8模式傳送
 
if(($result = mysql_query("SHOW COLUMNS FROM ".SQLLOG." LIKE 'category'")) && mysql_num_rows($result) == 0){ // 更新資料表結構
mysql_query('ALTER TABLE '.SQLLOG.' ADD category VARCHAR(255) NOT NULL AFTER md5, COMMENT = "For Pixmicat!-PIO [Structure V3]"'); // category
mysql_query('ALTER TABLE '.SQLLOG.' ADD imgw SMALLINT(1) NOT NULL AFTER ext'); // imgw
mysql_query('ALTER TABLE '.SQLLOG.' ADD imgh SMALLINT(1) NOT NULL AFTER imgw'); // imgh
mysql_query('ALTER TABLE '.SQLLOG.' ADD imgsize VARCHAR(10) NOT NULL AFTER imgh'); // imgsize
mysql_query('ALTER TABLE '.SQLLOG.' CHANGE md5 md5chksum VARCHAR(32) NOT NULL'); // md5chksum
mysql_query('ALTER TABLE '.SQLLOG.' CHANGE w tw SMALLINT(1) NOT NULL'); // tw
mysql_query('ALTER TABLE '.SQLLOG.' CHANGE h th SMALLINT(1) NOT NULL'); // th
mysql_query('ALTER TABLE '.SQLLOG.' MODIFY status VARCHAR(255) NOT NULL'); // status
mysql_query('UPDATE '.SQLLOG.' SET status = "_TS_" WHERE status = "T"'); // status 旗標改變
mysql_free_result($result);
 
$tmpSQL = 'SELECT no,tim,ext FROM '.SQLLOG.' WHERE ext <> "" ORDER BY no';
if(!$result2=mysql_query($tmpSQL)) echo "sql失敗814<br>";
while(list($dno, $dtim, $dext)=mysql_fetch_row($result2)){ // 個別跑迴圈
$s = getImageWH($dtim.$dext); // 圖檔寬長
mysql_query('UPDATE '.SQLLOG.' SET imgsize = "'.getImageSizeText($dtim.$dext).'", imgw = '.$s[0].', imgh = '.$s[1].' WHERE no = '.$dno);
}
mysql_free_result($result2);
echo 'done.';
}else{
echo 'It seems already done.';
}
mysql_close($con);
?>
New file

Property changes:

Name: svn:keywords
+ Id Date Author

/release/Utilities-PIO-v6/satellite/satellite.cgi
@@ -0,0 +1,193 @@
#!/usr/bin/perl -w
 
##
# Pixmicat! PIO 公用程式 - FileIO Satellite Perl
#
# 利用此一放置於外部空間的衛星程式,可以讓 FileIO 利用外部空間存放圖檔。
#
# @package PMCUtility
# @version $Id$
# @date $Date$
#
 
require './cgi-lib.pl';
 
$cgi_lib'maxdata = 2097152; # 上傳檔案大小上限
$TRANSPORT_KEY = '12345678'; # 傳輸認證金鑰
$USER_AGENT = 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1) Gecko/20061010 Firefox/2.0'; # Just for fun ;-)
$STORAGE_DIRECTORY = 'src/'; # 圖檔儲存目錄
 
&ReadParse;
$EOL = "\015\012";
$BLANK = $EOL x 2;
 
sub parse_url {
local($url) = @_;
 
$ftp_port = 21;
$http_port = 80;
$gopher_port = 70;
$telnet_port = 23;
$wais_port = 210;
$news_port = 119;
 
if ($url =~ m#^(\w+):#) {
$protocol = $1;
$protocol =~ tr/A-Z/a-z/;
} else {
return undef;
}
 
# URL of type: http://host[:port]/path[?search-string]
 
if ($protocol eq "http") {
if ($url =~ m#^\s*\w+://([\w-\.]+):?(\d*)([^ \t]*)$#) {
$server = $1;
$server =~ tr/A-Z/a-z/;
$port = ($2 ne "" ? $2 : $http_port);
$path = ( $3 ? $3 : '/');
return { protocol => $protocol, host => $server, port => $port, path => $path }; # Return by reference
}
return undef;
}
 
}
 
if ($ENV{'REQUEST_METHOD'} eq 'POST') {
$mode = defined($in{'mode'}) ? $in{'mode'} : ''; # 要求模式
$Tkey = defined($in{'key'}) ? $in{'key'} : ''; # 對方送來傳輸金鑰
$imgname = defined($in{'imgname'}) ? $in{'imgname'} : ''; # 圖檔名稱
}
 
if ($mode eq 'init') { # 初始化
DoConstruct() ? DoOK() : DoError();
} elsif ($mode eq 'transload') { # 遠端抓取
DoTransload($imgname) ? DoOK() : DoError();
} elsif ($mode eq 'upload') { # 上傳檔案
DoUpload($imgname) ? DoOK() : DoError();
} elsif ($mode eq 'delete') { # 刪除檔案
DoDelete($imgname) ? DoOK() : DoError();
} else {
DoNotFound();
}
 
### 初始化
sub DoConstruct{
return undef if $Tkey != $TRANSPORT_KEY; # 金鑰不符
 
if(! -d $STORAGE_DIRECTORY){ mkdir($STORAGE_DIRECTORY); chmod($STORAGE_DIRECTORY, 0777); }
return 1;
}
 
### 進行遠端抓取檔案並儲存
sub DoTransload{
use Socket;
my $imgname=$_[0];
$imgurl = defined($in{'imgurl'}) ? parse_url($in{'imgurl'}) : undef; # 圖檔遠端URL位置
if(! -d $STORAGE_DIRECTORY){ DoConstruct(); }
 
my ($remote,$port,$doc) = ($$imgurl{'host'},$$imgurl{'port'},$$imgurl{'path'}); # $$var = dereference
$sockaddr = 'S n a4 x8';
 
if ($port =~ /\D/) { $port = getservbyname($port, 'tcp'); }
return undef unless $port;
$thataddr = gethostbyname($remote);
$that = pack($sockaddr, AF_INET, $port, $thataddr);
$proto = (getprotobyname('tcp'))[2] || 6;
socket(SOCK, PF_INET, SOCK_STREAM, $proto) || return undef;
connect(SOCK, $that) || return undef;
binmode(SOCK);
$ofh = select(SOCK); $| = 1; select($ofh); # flush buffer on every write
 
print SOCK "GET $doc HTTP/1.1".$EOL.
"Host: $remote".$EOL.
"User-Agent: $USER_AGENT".$BLANK;
 
vec($rin='', fileno(SOCK), 1) = 1;
select($rin, undef, undef, 20) || return undef; # no response from server
 
while( <SOCK> ) {
s/\r\n/\n/g;
s/\r/\n/g;
if ( /HTTP([\/\.\d]+)\s+(\d+)\s+(.*)\n/i ) { $status = $2; }
if ( /Content-Length: (\s*)(\d+)\n/i ) { $content_length = $2; }
last if $_ =~ /^$/;
}
 
$content='';
if ($content_length) {
read(SOCK, $content, $content_length);
} else {
while ( <SOCK> ) { $content .= $_; }
}
close(SOCK);
select($ofh);
 
return undef if $status ne "200"; # 檔案不存在或伺服器出現問題
 
open(FS,">$STORAGE_DIRECTORY$imgname") || return undef;
binmode(FS);
print FS $content;
chmod($STORAGE_DIRECTORY.$imgname, 0666);
close(FS);
 
return 1;
}
 
### 接受上傳檔案並儲存
sub DoUpload{
my $imgname=$_[0];
$imgfile = defined($in{'imgfile'}) ? $in{'imgfile'} : undef;
if(!$imgfile){ return undef; }
if(! -d $STORAGE_DIRECTORY){ DoConstruct(); }
 
open(FS,">$STORAGE_DIRECTORY$imgname") || return undef;
binmode(FS);
print FS $imgfile;
chmod($STORAGE_DIRECTORY.$imgname, 0666);
close(FS);
 
return 1;
}
 
### 刪除檔案
sub DoDelete{
my $imgname=$_[0];
return undef if $Tkey != $TRANSPORT_KEY; # 金鑰不符
 
return unlink($STORAGE_DIRECTORY.$imgname);
}
 
### 阻止閒雜人士進入
sub DoNotFound{
print "Status: 404 Not Found".$EOL.
"Content-type: text/html".$BLANK.
"<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n".
"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n".
" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n".
"<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n".
" <head>\n".
" <title>404 - Not Found</title>\n".
" </head>\n".
" <body>\n".
" <h1>404 - Not Found</h1>\n".
" </body>\n".
"</html>";
}
 
### 操作成功,回傳成功訊息
sub DoOK{
print "Status: 202 Accepted".$EOL.
"Content-type: text/plain".$BLANK.
"Succeed.";
 
}
 
### 操作失敗,回傳錯誤訊息
sub DoError{
print "Status: 403 Forbidden".$EOL.
"Content-type: text/plain".$BLANK.
"Failed.";
}
 
__END__
New file

Property changes:

Name: svn:keywords
+ Id Date Author

/release/Utilities-PIO-v6/satellite/satellite.php
@@ -0,0 +1,117 @@
<?php
/**
* Pixmicat! PIO 公用程式 - FileIO Satellite PHP
*
* 利用此一放置於外部空間的衛星程式,可以讓 FileIO 利用外部空間存放圖檔。
*
* @package PMCUtility
* @version $Id$
* @date $Date$
*/
 
define('TRANSPORT_KEY', '12345678'); // 傳輸認證金鑰
define('USER_AGENT', 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1) Gecko/20061010 Firefox/2.0'); // Just for fun ;-)
define('STORAGE_DIRECTORY', 'src/'); // 圖檔儲存目錄
$mode = isset($_POST['mode']) ? $_POST['mode'] : ''; // 要求模式
$Tkey = isset($_POST['key']) ? $_POST['key'] : ''; // 對方送來傳輸金鑰
$imgname = isset($_POST['imgname']) ? $_POST['imgname'] : ''; // 圖檔名稱
 
switch($mode){
case 'init': // 初始化
DoConstruct() ? DoOK() : DoError();
break;
case 'transload': // 遠端抓取
DoTransload($imgname) ? DoOK() : DoError();
break;
case 'upload': // 上傳檔案
DoUpload($imgname) ? DoOK() : DoError();
break;
case 'delete': // 刪除檔案
DoDelete($imgname) ? DoOK() : DoError();
break;
default:
DoNotFound();
}
 
/* 初始化 */
function DoConstruct(){
global $Tkey;
if($Tkey != TRANSPORT_KEY) return false; // 金鑰不符
 
if(!is_dir(STORAGE_DIRECTORY)){ mkdir(STORAGE_DIRECTORY); @chmod(STORAGE_DIRECTORY, 0777); }
return true;
}
 
/* 進行遠端抓取檔案並儲存 */
function DoTransload($imgname){
$imgurl = isset($_POST['imgurl']) ? parse_url($_POST['imgurl']) : false; // 圖檔遠端URL位置
if(!is_dir(STORAGE_DIRECTORY)) DoConstruct();
 
if(!($fp = @fsockopen($imgurl['host'], 80))) return false;
 
$out = 'GET '.$imgurl['path']." HTTP/1.1\r\n";
$out .= 'Host: '.$imgurl['host']."\r\n";
$out .= 'User-Agent: '.USER_AGENT."\r\n\r\n";
fwrite($fp, $out);
$result = '';
while(!feof($fp)){ $result .= fgets($fp, 128); }
fclose($fp);
 
$result = explode("\r\n\r\n", $result); // 將檔頭和內容分隔開
if(strpos($result[0], '200 OK')===false) return false; // 檔案不存在或伺服器出現問題
 
$fs = fopen(STORAGE_DIRECTORY.$imgname, "wb"); // 二進位儲存
if(fwrite($fs, $result[1])===false) return false; // 寫入錯誤
chmod(STORAGE_DIRECTORY.$imgname, 0666);
fclose($fs);
 
return true;
}
 
/* 接受上傳檔案並儲存 */
function DoUpload($imgname){
$imgfile = isset($_FILES['imgfile']['tmp_name']) ? $_FILES['imgfile']['tmp_name'] : false;
if(!$imgfile) return false;
if(!is_dir(STORAGE_DIRECTORY)) DoConstruct();
 
$result = move_uploaded_file($imgfile, realpath('.').DIRECTORY_SEPARATOR.STORAGE_DIRECTORY.$imgname); // 搬移上傳檔案
if($result) chmod(STORAGE_DIRECTORY.$imgname, 0666);
 
return $result;
}
 
/* 刪除檔案 */
function DoDelete($imgname){
global $Tkey;
if($Tkey != TRANSPORT_KEY) return false;
 
return @unlink(STORAGE_DIRECTORY.$imgname);
}
 
/* 阻止閒雜人士進入 */
function DoNotFound(){
header('HTTP/1.1 404 Not Found');
echo '<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>404 - Not Found</title>
</head>
<body>
<h1>404 - Not Found</h1>
</body>
 
</html>';
}
 
/* 操作成功,回傳成功訊息 */
function DoOK(){
header('HTTP/1.1 202 Accepted');
}
 
/* 操作失敗,回傳錯誤訊息 */
function DoError(){
header('HTTP/1.1 403 Forbidden');
}
?>
New file
/release/Utilities-PIO-v6/satellite/cgi-lib.pl
@@ -0,0 +1,471 @@
# Perl Routines to Manipulate CGI input
# cgi-lib@pobox.com
# $Id: cgi-lib.pl,v 2.18 1999/02/23 08:16:43 brenner Exp $
#
# Copyright (c) 1993-1999 Steven E. Brenner
# Unpublished work.
# Permission granted to use and modify this library so long as the
# copyright above is maintained, modifications are documented, and
# credit is given for any use of the library.
#
# Thanks are due to many people for reporting bugs and suggestions
 
# For more information, see:
# http://cgi-lib.stanford.edu/cgi-lib/
 
$cgi_lib'version = sprintf("%d.%02d", q$Revision: 2.18 $ =~ /(\d+)\.(\d+)/);
 
 
# Parameters affecting cgi-lib behavior
# User-configurable parameters affecting file upload.
$cgi_lib'maxdata = 131072; # maximum bytes to accept via POST - 2^17
$cgi_lib'writefiles = 0; # directory to which to write files, or
# 0 if files should not be written
$cgi_lib'filepre = "cgi-lib"; # Prefix of file names, in directory above
 
# Do not change the following parameters unless you have special reasons
$cgi_lib'bufsize = 8192; # default buffer size when reading multipart
$cgi_lib'maxbound = 100; # maximum boundary length to be encounterd
$cgi_lib'headerout = 0; # indicates whether the header has been printed
 
 
# ReadParse
# Reads in GET or POST data, converts it to unescaped text, and puts
# key/value pairs in %in, using "\0" to separate multiple selections
 
# Returns >0 if there was input, 0 if there was no input
# undef indicates some failure.
 
# Now that cgi scripts can be put in the normal file space, it is useful
# to combine both the form and the script in one place. If no parameters
# are given (i.e., ReadParse returns FALSE), then a form could be output.
 
# If a reference to a hash is given, then the data will be stored in that
# hash, but the data from $in and @in will become inaccessable.
# If a variable-glob (e.g., *cgi_input) is the first parameter to ReadParse,
# information is stored there, rather than in $in, @in, and %in.
# Second, third, and fourth parameters fill associative arrays analagous to
# %in with data relevant to file uploads.
 
# If no method is given, the script will process both command-line arguments
# of the form: name=value and any text that is in $ENV{'QUERY_STRING'}
# This is intended to aid debugging and may be changed in future releases
 
sub ReadParse {
# Disable warnings as this code deliberately uses local and environment
# variables which are preset to undef (i.e., not explicitly initialized)
local ($perlwarn);
$perlwarn = $^W;
$^W = 0;
 
local (*in) = shift if @_; # CGI input
local (*incfn, # Client's filename (may not be provided)
*inct, # Client's content-type (may not be provided)
*insfn) = @_; # Server's filename (for spooled files)
local ($len, $type, $meth, $errflag, $cmdflag, $got, $name);
binmode(STDIN); # we need these for DOS-based systems
binmode(STDOUT); # and they shouldn't hurt anything else
binmode(STDERR);
# Get several useful env variables
$type = $ENV{'CONTENT_TYPE'};
$len = $ENV{'CONTENT_LENGTH'};
$meth = $ENV{'REQUEST_METHOD'};
if ($len > $cgi_lib'maxdata) { #'
&CgiDie("cgi-lib.pl: Request to receive too much data: $len bytes\n");
}
if (!defined $meth || $meth eq '' || $meth eq 'GET' ||
$meth eq 'HEAD' ||
$type eq 'application/x-www-form-urlencoded') {
local ($key, $val, $i);
# Read in text
if (!defined $meth || $meth eq '') {
$in = $ENV{'QUERY_STRING'};
$cmdflag = 1; # also use command-line options
} elsif($meth eq 'GET' || $meth eq 'HEAD') {
$in = $ENV{'QUERY_STRING'};
} elsif ($meth eq 'POST') {
if (($got = read(STDIN, $in, $len) != $len))
{$errflag="Short Read: wanted $len, got $got\n";};
} else {
&CgiDie("cgi-lib.pl: Unknown request method: $meth\n");
}
 
@in = split(/[&;]/,$in);
push(@in, @ARGV) if $cmdflag; # add command-line parameters
 
foreach $i (0 .. $#in) {
# Convert plus to space
$in[$i] =~ s/\+/ /g;
 
# Split into key and value.
($key, $val) = split(/=/,$in[$i],2); # splits on the first =.
 
# Convert %XX from hex numbers to alphanumeric
$key =~ s/%([A-Fa-f0-9]{2})/pack("c",hex($1))/ge;
$val =~ s/%([A-Fa-f0-9]{2})/pack("c",hex($1))/ge;
 
# Associate key and value
$in{$key} .= "\0" if (defined($in{$key})); # \0 is the multiple separator
$in{$key} .= $val;
}
 
} elsif ($ENV{'CONTENT_TYPE'} =~ m#^multipart/form-data#) {
# for efficiency, compile multipart code only if needed
$errflag = !(eval <<'END_MULTIPART');
 
local ($buf, $boundary, $head, @heads, $cd, $ct, $fname, $ctype, $blen);
local ($bpos, $lpos, $left, $amt, $fn, $ser);
local ($bufsize, $maxbound, $writefiles) =
($cgi_lib'bufsize, $cgi_lib'maxbound, $cgi_lib'writefiles);
 
 
# The following lines exist solely to eliminate spurious warning messages
$buf = '';
 
($boundary) = $type =~ /boundary="([^"]+)"/; #"; # find boundary
($boundary) = $type =~ /boundary=(\S+)/ unless $boundary;
&CgiDie ("Boundary not provided: probably a bug in your server")
unless $boundary;
$boundary = "--" . $boundary;
$blen = length ($boundary);
 
if ($ENV{'REQUEST_METHOD'} ne 'POST') {
&CgiDie("Invalid request method for multipart/form-data: $meth\n");
}
 
if ($writefiles) {
local($me);
stat ($writefiles);
$writefiles = "/tmp" unless -d _ && -w _;
# ($me) = $0 =~ m#([^/]*)$#;
$writefiles .= "/$cgi_lib'filepre";
}
 
# read in the data and split into parts:
# put headers in @in and data in %in
# General algorithm:
# There are two dividers: the border and the '\r\n\r\n' between
# header and body. Iterate between searching for these
# Retain a buffer of size(bufsize+maxbound); the latter part is
# to ensure that dividers don't get lost by wrapping between two bufs
# Look for a divider in the current batch. If not found, then
# save all of bufsize, move the maxbound extra buffer to the front of
# the buffer, and read in a new bufsize bytes. If a divider is found,
# save everything up to the divider. Then empty the buffer of everything
# up to the end of the divider. Refill buffer to bufsize+maxbound
# Note slightly odd organization. Code before BODY: really goes with
# code following HEAD:, but is put first to 'pre-fill' buffers. BODY:
# is placed before HEAD: because we first need to discard any 'preface,'
# which would be analagous to a body without a preceeding head.
 
$left = $len;
PART: # find each part of the multi-part while reading data
while (1) {
die $@ if $errflag;
 
$amt = ($left > $bufsize+$maxbound-length($buf)
? $bufsize+$maxbound-length($buf): $left);
$errflag = (($got = read(STDIN, $buf, $amt, length($buf))) != $amt);
die "Short Read: wanted $amt, got $got\n" if $errflag;
$left -= $amt;
 
$in{$name} .= "\0" if defined $in{$name};
$in{$name} .= $fn if $fn;
 
$name=~/([-\w]+)/; # This allows $insfn{$name} to be untainted
if (defined $1) {
$insfn{$1} .= "\0" if defined $insfn{$1};
$insfn{$1} .= $fn if $fn;
}
BODY:
while (($bpos = index($buf, $boundary)) == -1) {
if ($left == 0 && $buf eq '') {
foreach $value (values %insfn) {
unlink(split("\0",$value));
}
&CgiDie("cgi-lib.pl: reached end of input while seeking boundary " .
"of multipart. Format of CGI input is wrong.\n");
}
die $@ if $errflag;
if ($name) { # if no $name, then it's the prologue -- discard
if ($fn) { print FILE substr($buf, 0, $bufsize); }
else { $in{$name} .= substr($buf, 0, $bufsize); }
}
$buf = substr($buf, $bufsize);
$amt = ($left > $bufsize ? $bufsize : $left); #$maxbound==length($buf);
$errflag = (($got = read(STDIN, $buf, $amt, length($buf))) != $amt);
die "Short Read: wanted $amt, got $got\n" if $errflag;
$left -= $amt;
}
if (defined $name) { # if no $name, then it's the prologue -- discard
if ($fn) { print FILE substr($buf, 0, $bpos-2); }
else { $in {$name} .= substr($buf, 0, $bpos-2); } # kill last \r\n
}
close (FILE);
last PART if substr($buf, $bpos + $blen, 2) eq "--";
substr($buf, 0, $bpos+$blen+2) = '';
$amt = ($left > $bufsize+$maxbound-length($buf)
? $bufsize+$maxbound-length($buf) : $left);
$errflag = (($got = read(STDIN, $buf, $amt, length($buf))) != $amt);
die "Short Read: wanted $amt, got $got\n" if $errflag;
$left -= $amt;
 
 
undef $head; undef $fn;
HEAD:
while (($lpos = index($buf, "\r\n\r\n")) == -1) {
if ($left == 0 && $buf eq '') {
foreach $value (values %insfn) {
unlink(split("\0",$value));
}
&CgiDie("cgi-lib: reached end of input while seeking end of " .
"headers. Format of CGI input is wrong.\n$buf");
}
die $@ if $errflag;
$head .= substr($buf, 0, $bufsize);
$buf = substr($buf, $bufsize);
$amt = ($left > $bufsize ? $bufsize : $left); #$maxbound==length($buf);
$errflag = (($got = read(STDIN, $buf, $amt, length($buf))) != $amt);
die "Short Read: wanted $amt, got $got\n" if $errflag;
$left -= $amt;
}
$head .= substr($buf, 0, $lpos+2);
push (@in, $head);
@heads = split("\r\n", $head);
($cd) = grep (/^\s*Content-Disposition:/i, @heads);
($ct) = grep (/^\s*Content-Type:/i, @heads);
 
($name) = $cd =~ /\bname="([^"]+)"/i; #";
($name) = $cd =~ /\bname=([^\s:;]+)/i unless defined $name;
 
($fname) = $cd =~ /\bfilename="([^"]*)"/i; #"; # filename can be null-str
($fname) = $cd =~ /\bfilename=([^\s:;]+)/i unless defined $fname;
$incfn{$name} .= (defined $in{$name} ? "\0" : "") .
(defined $fname ? $fname : "");
 
($ctype) = $ct =~ /^\s*Content-type:\s*"([^"]+)"/i; #";
($ctype) = $ct =~ /^\s*Content-Type:\s*([^\s:;]+)/i unless defined $ctype;
$inct{$name} .= (defined $in{$name} ? "\0" : "") . $ctype;
 
if ($writefiles && defined $fname) {
$ser++;
$fn = $writefiles . ".$$.$ser";
open (FILE, ">$fn") || &CgiDie("Couldn't open $fn\n");
binmode (FILE); # write files accurately
}
substr($buf, 0, $lpos+4) = '';
undef $fname;
undef $ctype;
}
 
1;
END_MULTIPART
if ($errflag) {
local ($errmsg, $value);
$errmsg = $@ || $errflag;
foreach $value (values %insfn) {
unlink(split("\0",$value));
}
&CgiDie($errmsg);
} else {
# everything's ok.
}
} else {
&CgiDie("cgi-lib.pl: Unknown Content-type: $ENV{'CONTENT_TYPE'}\n");
}
 
# no-ops to avoid warnings
$insfn = $insfn;
$incfn = $incfn;
$inct = $inct;
 
$^W = $perlwarn;
 
return ($errflag ? undef : scalar(@in));
}
 
 
# PrintHeader
# Returns the magic line which tells WWW that we're an HTML document
 
sub PrintHeader {
return "Content-type: text/html\n\n";
}
 
 
# HtmlTop
# Returns the <head> of a document and the beginning of the body
# with the title and a body <h1> header as specified by the parameter
 
sub HtmlTop
{
local ($title) = @_;
 
return <<END_OF_TEXT;
<html>
<head>
<title>$title</title>
</head>
<body>
<h1>$title</h1>
END_OF_TEXT
}
 
 
# HtmlBot
# Returns the </body>, </html> codes for the bottom of every HTML page
 
sub HtmlBot
{
return "</body>\n</html>\n";
}
 
 
# SplitParam
# Splits a multi-valued parameter into a list of the constituent parameters
 
sub SplitParam
{
local ($param) = @_;
local (@params) = split ("\0", $param);
return (wantarray ? @params : $params[0]);
}
 
 
# MethGet
# Return true if this cgi call was using the GET request, false otherwise
 
sub MethGet {
return (defined $ENV{'REQUEST_METHOD'} && $ENV{'REQUEST_METHOD'} eq "GET");
}
 
 
# MethPost
# Return true if this cgi call was using the POST request, false otherwise
 
sub MethPost {
return (defined $ENV{'REQUEST_METHOD'} && $ENV{'REQUEST_METHOD'} eq "POST");
}
 
 
# MyBaseUrl
# Returns the base URL to the script (i.e., no extra path or query string)
sub MyBaseUrl {
local ($ret, $perlwarn);
$perlwarn = $^W; $^W = 0;
$ret = 'http://' . $ENV{'SERVER_NAME'} .
($ENV{'SERVER_PORT'} != 80 ? ":$ENV{'SERVER_PORT'}" : '') .
$ENV{'SCRIPT_NAME'};
$^W = $perlwarn;
return $ret;
}
 
 
# MyFullUrl
# Returns the full URL to the script (i.e., with extra path or query string)
sub MyFullUrl {
local ($ret, $perlwarn);
$perlwarn = $^W; $^W = 0;
$ret = 'http://' . $ENV{'SERVER_NAME'} .
($ENV{'SERVER_PORT'} != 80 ? ":$ENV{'SERVER_PORT'}" : '') .
$ENV{'SCRIPT_NAME'} . $ENV{'PATH_INFO'} .
(length ($ENV{'QUERY_STRING'}) ? "?$ENV{'QUERY_STRING'}" : '');
$^W = $perlwarn;
return $ret;
}
 
 
# MyURL
# Returns the base URL to the script (i.e., no extra path or query string)
# This is obsolete and will be removed in later versions
sub MyURL {
return &MyBaseUrl;
}
 
 
# CgiError
# Prints out an error message which which containes appropriate headers,
# markup, etcetera.
# Parameters:
# If no parameters, gives a generic error message
# Otherwise, the first parameter will be the title and the rest will
# be given as different paragraphs of the body
 
sub CgiError {
local (@msg) = @_;
local ($i,$name);
 
if (!@msg) {
$name = &MyFullUrl;
@msg = ("Error: script $name encountered fatal error\n");
};
 
if (!$cgi_lib'headerout) { #')
print &PrintHeader;
print "<html>\n<head>\n<title>$msg[0]</title>\n</head>\n<body>\n";
}
print "<h1>$msg[0]</h1>\n";
foreach $i (1 .. $#msg) {
print "<p>$msg[$i]</p>\n";
}
 
$cgi_lib'headerout++;
}
 
 
# CgiDie
# Identical to CgiError, but also quits with the passed error message.
 
sub CgiDie {
local (@msg) = @_;
&CgiError (@msg);
die @msg;
}
 
 
# PrintVariables
# Nicely formats variables. Three calling options:
# A non-null associative array - prints the items in that array
# A type-glob - prints the items in the associated assoc array
# nothing - defaults to use %in
# Typical use: &PrintVariables()
 
sub PrintVariables {
local (*in) = @_ if @_ == 1;
local (%in) = @_ if @_ > 1;
local ($out, $key, $output);
 
$output = "\n<dl compact>\n";
foreach $key (sort keys(%in)) {
foreach (split("\0", $in{$key})) {
($out = $_) =~ s/\n/<br>\n/g;
$output .= "<dt><b>$key</b>\n <dd>:<i>$out</i>:<br>\n";
}
}
$output .= "</dl>\n";
 
return $output;
}
 
# PrintEnv
# Nicely formats all environment variables and returns HTML string
sub PrintEnv {
&PrintVariables(*ENV);
}
 
 
# The following lines exist only to avoid warning messages
$cgi_lib'writefiles = $cgi_lib'writefiles;
$cgi_lib'bufsize = $cgi_lib'bufsize ;
$cgi_lib'maxbound = $cgi_lib'maxbound;
$cgi_lib'version = $cgi_lib'version;
$cgi_lib'filepre = $cgi_lib'filepre;
 
1; #return true
 
New file

Property changes:

Name: svn:keywords
+ Id Date Author

/release/Utilities-PIO-v6/pio2pio.php
@@ -0,0 +1,94 @@
<?php
/**
* Pixmicat! PIO 公用程式 - PIO 匯入匯出轉換器
*
* 這是 PIO 額外提供的功能,可以執行匯出備份、匯入備份、來源轉換等動作。
* 請修改下方 PIO_ANOTHER_CONNSTR PIO 連線字串 (匯入及轉換動作才需要,匯入則直接使用設定檔設定)
*
* @package PMCUtility
* @version $Id$
* @date $Date$
*/
include('./config.php');
define('PIO_ANOTHER_CONNSTR', 'sqlite://pixmicat.db/imglog/'); // Another-PIO 連線字串 (此來源必須無任何資料,全新)
$PIOEnv = array( // PIO 環境常數
'BOARD' => '.',
'LUTCACHE' => './lutcache.dat',
'NONAME' => DEFAULT_NONAME,
'NOTITLE' => DEFAULT_NOTITLE,
'NOCOMMENT' => DEFAULT_NOCOMMENT,
'LOG_MAX' => defined('LOG_MAX') ? LOG_MAX : 0,
'PERIOD.POST' => RENZOKU,
'PERIOD.IMAGEPOST' => RENZOKU2
);
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="zh-tw">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta http-equiv="Content-Language" content="zh-tw" />
<title>PIO -> PIO Im/Exporter</title>
</head>
<body>
 
<div id="main">
請選擇下列一項進行操作:
<ul>
<li><a href="?mode=export">匯出目前 PIO 資料成中介檔案</a></li>
<li><a href="?mode=import">匯入目前中介檔案到 Another-PIO (見此頁原始碼設定)</a></li>
<li><a href="?mode=convert">將目前 PIO 資料轉換到 Another-PIO</a></li>
</ul>
<hr />
<div id="result">
<?php
$mode = isset($_GET['mode']) ? $_GET['mode'] : '';
switch($mode){
case 'export': doExport(); break;
case 'import': doImport(); break;
case 'convert': doConvert(); break;
}
 
function doExport(){
global $PIOEnv;
if(preg_match('/^(.*):\/\//i', CONNECTION_STRING, $backend)) define('PIO_FROM', $backend[1]);
include('./lib/pio/pio.'.PIO_FROM.'.php');
$pio1 = 'PIO'.PIO_FROM; $PIO = new $pio1(CONNECTION_STRING, $PIOEnv);
 
$gp = gzopen('piodata.log.gz', 'w9');
gzwrite($gp, $PIO->dbExport());
gzclose($gp);
echo '<a href="piodata.log.gz">下載 piodata.log.gz 中介檔案</a>';
}
 
function doImport(){
global $PIOEnv;
if(preg_match('/^(.*):\/\//i', PIO_ANOTHER_CONNSTR, $backend)) define('PIO_FROM', $backend[1]);
include('./lib/pio/pio.'.PIO_FROM.'.php');
$pio1 = 'PIO'.PIO_FROM; $PIO = new $pio1(PIO_ANOTHER_CONNSTR, $PIOEnv);
 
if(!file_exists('piodata.log.gz')){ echo '檔案不存在,請先放置在相同目錄。'; return; }
$data = '';
$gp = gzopen('piodata.log.gz', 'r');
while(!gzeof($gp)) $data .= gzread($gp, 4096);
gzclose($gp);
echo $PIO->dbImport($data) ? '匯入成功' : '匯入失敗';
}
 
function doConvert(){
global $PIOEnv;
if(preg_match('/^(.*):\/\//i', CONNECTION_STRING, $backend)) define('PIO_FROM', $backend[1]);
if(preg_match('/^(.*):\/\//i', PIO_ANOTHER_CONNSTR, $backend)) define('PIO_TO', $backend[1]);
 
include('./lib/pio/pio.'.PIO_FROM.'.php');
include('./lib/pio/pio.'.PIO_TO.'.php');
 
$pio1 = 'PIO'.PIO_FROM; $pio2 = 'PIO'.PIO_TO;
$PIOa = new $pio1(CONNECTION_STRING, $PIOEnv); $PIOb = new $pio2(PIO_ANOTHER_CONNSTR, $PIOEnv);
echo $PIOb->dbImport($PIOa->dbExport()) ? '轉換成功' : '轉換失敗'; // PIOa -> PIOb
}
?>
</div>
</div>
 
</body>
</html>
New file

Property changes:

Name: svn:keywords
+ Id Date Author

/release/Utilities-PIO-v6/checkenv.php
@@ -0,0 +1,232 @@
<?php
/**
* Pixmicat! PIO 公用程式 - 檢查伺服器執行環境支援 (SQLite, PDO, PostgreSQL, MySQL, GD, Imagick, MagickWand, ImageMagick, repng2jpeg)
*
* 本公用程式可為您檢查伺服器支援的項目,讓您選擇最適合的 PIO 資料來源後端和預覽圖生成物件。
* - 伺服器資訊: 得知伺服器的基本資訊,如伺服器版本、PHP 版本等
* - PIO 檢查: 在設定檔的 CONNECTION_STRING 可以使用的後端檢查,除了 Log 外您還可以使用更穩定的 SQL
* - 預覽圖生成檢查: 檢查您的伺服器是否支援各類預覽圖生成,並提供多種支援供您選擇
* - ImageMagick 和 repng2jpeg 支援檢查: 協助您選擇最適用的 repng2jpeg 執行檔和找出 ImageMagick convert 程式路徑
*
* Original source: SUGA <http://sugachan.dip.jp/> @ 2004/10/16
* Custom: SakaQ <http://www.punyu.net/> @ 2004/11/22
* FIXED: scribe <http://scribe.chkkk.idv.tw> @ 2005/07/09
* Rewrite: Pixmicat! Development Team <http://pixmicat.openfoundry.org/>
*
* @package PMCUtility
* @version $Id$
* @date $Date$
*/
 
class CheckEnvironment{
/* 尋找檔案路徑 */
function _findfile($filename, $isWin=false){
if(@is_file("./$filename")){ return "./$filename"; }
$ary = explode(PATH_SEPARATOR, getenv('PATH'));
if(!$isWin){
$ary = array_merge($ary, explode(':',
':/bin'.
':/usr/bin'.
':/usr/ucb'.
':/etc'.
':/lib'.
':/usr/etc'.
':/usr/lib'.
':/usr/local/bin'.
':/usr/local/X11R6/bin'.
':/usr/local/bin/mh'.
':/usr/local/lib'.
':/usr/local/lib/mh'.
':/usr/local/sbin'.
':/usr/local/libexec'.
':/usr/local/canna/bin'.
':'.ini_get('safe_mode_include_dir')));
}
foreach($ary as $value){
if(@is_file($value.DIRECTORY_SEPARATOR.$filename)){ return ($value.DIRECTORY_SEPARATOR.$filename); }
if(@realpath($value.DIRECTORY_SEPARATOR.$filename)){ return ($value.DIRECTORY_SEPARATOR.$filename); } // smbfs workaround, from http://php.net/file-exists#82269
}
return false;
}
 
/* 檢查適用環境之 repng2jpeg 種類 */
function checkRepng2jpegRecommended(){
$os = PHP_OS;
$msg = ''; // HTML 文字流
if(!function_exists('exec')){ return 'This server has disabled the exec() function. So repng2jpeg can\'t be used.'; } // 封鎖 exec 功能
if(stristr($os, 'Linux')){ // 系統為 Linux
$libjpeg = $this->_findfile('libjpeg.so.62'); $libpng = $this->_findfile('libpng.so.2'); $libz = $this->_findfile('libz.so.1');
$libm = $this->_findfile('libm.so.6'); $libc = $this->_findfile('libc.so.6'); $ldlinux = $this->_findfile("ld-linux.so.2");
$msg .= '- libjpeg -> '.($libjpeg ? $libjpeg : 'Not Found')."\n";
$msg .= '- libpng -> '.($libpng ? $libpng : 'Not Found')."\n";
$msg .= '- libz -> '.($libz ? $libz : 'Not Found')."\n";
$msg .= '- libm -> '.($libm ? $libm : 'Not Found')."\n";
$msg .= '- libc -> '.($libc ? $libc : 'Not Found')."\n";
$msg .= '- ldlinux -> '.($ldlinux ? $ldlinux : 'Not Found')."\n";
 
if($libjpeg && $libpng && $libz && $libm && $libc && $ldlinux){
$msg .= 'You can use repng2jpeg (i386_linux_dynamic).';
return $msg;
}
if($libz && $libm && $libc && $ldlinux){
$msg .= 'You can use repng2jpeg (i386_linux_standard).';
return $msg;
}
$msg .= 'You can use repng2jpeg (i386_linux_static).';
return $msg;
}elseif(stristr($os, 'FreeBSD')){ // 系統為 FreeBSD
$libjpeg = $this->_findfile('libjpeg.so.9'); $libpng = $this->_findfile('libpng.so.5'); $libz = $this->_findfile('libz.so.2');
$libm = $this->_findfile('libm.so.2'); $libc = $this->_findfile('libc.so.4');
$msg .= '- libjpeg -> '.($libjpeg ? $libjpeg : 'Not Found')."\n";
$msg .= '- libpng -> '.($libpng ? $libpng : 'Not Found')."\n";
$msg .= '- libz -> '.($libz ? $libz : 'Not Found')."\n";
$msg .= '- libm -> '.($libm ? $libm : 'Not Found')."\n";
$msg .= '- libc -> '.($libc ? $libc : 'Not Found')."\n";
 
if($libjpeg && $libpng && $libz && $libm && $libc){
$msg .= 'You can use repng2jpeg (i386_freebsd4_dynamic).';
return $msg;
}
if($libz && $libm && $libc){
$msg .= 'You can use repng2jpeg (386_freebsd4_standard).';
return $msg;
}
$msg .= 'You can use repng2jpeg (i386_freebsd4_static).';
return $msg;
}elseif(stristr($os, 'Solaris')){ // 系統為 Solaris
$libc = $this->_findfile('libc.so.1'); $libdl = $this->_findfile('libdl.so.1');
$msg .= '- libc -> '.($libc ? $libc : 'Not Found')."\n";
$msg .= '- libdl -> '.($libdl ? $libdl : 'Not Found')."\n";
 
if($libc && $libdl){
$msg .= 'You can use repng2jpeg (i386_solaris_standard).';
return $msg;
}
$msg .= 'You can use repng2jpeg (i386_solaris_static).';
return $msg;
}elseif(stristr($os, 'Win')){ // 系統為 Windows
$msvcrt = $this->_findfile('msvcrt.dll', 1);
$msg .= '- msvcrt.dll -> '.($msvcrt ? $msvcrt : 'Not Found')."\n";
 
if($msvcrt){
$msg .= 'You can use repng2jpeg (i386_win32).';
}else{
$msg .= 'You can\'t use repng2jpeg (i386_win32). Try others.';
}
return $msg;
}else{ return 'You can\'t use repng2jpeg on this platform because no suitable binary can be used.'; } // 無法支援的系統
}
 
/* 檢查 repng2jpeg 可用性 */
function checkRepng2jpeg(){
$_exec = realpath('./repng2jpeg'.(strtoupper(substr(PHP_OS, 0, 3))==='WIN' ? '.exe' : ''));
if(function_exists('exec') && file_exists($_exec) && (strtoupper(substr(PHP_OS, 0, 3))==='WIN' || is_executable($_exec))){
return `$_exec --version`;
}else{ return false; }
}
 
/* 檢查 GD 可用性 */
function checkGD(){
if(extension_loaded('gd') && function_exists('ImageCreateTrueColor') && function_exists('ImageCopyResampled')){
$a = gd_info(); return $a['GD Version'];
}else{ return false; }
}
 
/* 檢查 Imagick 可用性 */
function checkImagick(){
if(extension_loaded('imagick') && class_exists('Imagick')){
$a = new Imagick(); $b = $a->getVersion(); $b = $b['versionString'];
unset($a);
return $b;
}else{ return false; }
}
 
/* 檢查 MagickWand 可用性 */
function checkMagickWand(){
if(extension_loaded('magickwand') && function_exists('MagickThumbnailImage')){
$a = MagickGetVersion(); $b = $a[0];
unset($a);
return $b;
}else{ return false; }
}
 
/* 檢查 ImageMagick 可用性 */
function checkImageMagick(){
if(!function_exists('exec')) return false;
$_exec = 'convert'.(strtoupper(substr(PHP_OS, 0, 3))==='WIN' ? '.exe' : '');
if($newexec = $this->_findfile($_exec)){ $_exec = $newexec; } // ImageMagick "convert" Binary Location
 
@exec("\"$_exec\" -version", $status, $retval);
$a = null;
if(preg_match('/^Version: (.*)/', $status[0], $a)){
return $a[1]."\n\t\t".'- Location guessed: '.$_exec;
}else{ return false; }
}
 
/* 檢查 MySQL 可用性 */
function checkPIOMySQL(){
return (extension_loaded('mysql') && function_exists('mysql_pconnect'));
}
 
/* 檢查 SQLite 可用性 */
function checkPIOSQLite(){
return (extension_loaded('sqlite') && function_exists('sqlite_popen'));
}
 
/* 檢查 PostgreSQL 可用性 */
function checkPIOPostgreSQL(){
return (extension_loaded('pgsql') && function_exists('pg_pconnect'));
}
 
/* 檢查 PDO SQLite3 可用性 */
function checkPIOPDOSQLite3(){
return (class_exists('PDO') && extension_loaded('pdo_sqlite'));
}
 
/* 回傳伺服器資訊 */
function getServerInfo(){
$msg = "\t".'PHP: '.phpversion()."\n";
$msg .= "\t\t".'- upload_max_filesize: '.ini_get('upload_max_filesize')."\n";
$msg .= "\t\t".'- post_max_size: '.ini_get('post_max_size')."\n";
$msg .= "\t\t".'- disable_functions: '.ini_get('disable_functions')."\n";
$msg .= "\t".'HTTPd: '.($_SERVER['SERVER_SOFTWARE'] ? $_SERVER['SERVER_SOFTWARE'] : getenv('SERVER_SOFTWARE'))."\n";
$msg .= "\t".'OS: '.php_uname('s').' '.php_uname('r').' '.php_uname('v');
return $msg;
}
}
 
$objChk = new CheckEnvironment();
?>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>CheckEnvironment</title>
</head>
<body>
<pre>
Server Infomation:
 
<?php echo $objChk->getServerInfo(); ?>
 
PIO Check:
 
SQLite Support: <?php echo $objChk->checkPIOSQLite(); ?>
MySQL Support: <?php echo $objChk->checkPIOMySQL(); ?>
PDO SQLite3 Support: <?php echo $objChk->checkPIOPDOSQLite3(); ?>
PostgreSQL Support: <?php echo $objChk->checkPIOPostgreSQL(); ?>
 
Thumbnail Generator Check:
 
GD Support: <?php echo $objChk->checkGD(); ?>
Imagick Support: <?php echo $objChk->checkImagick(); ?>
MagickWand Support: <?php echo $objChk->checkMagickWand(); ?>
ImageMagick Support: <?php echo $objChk->checkImageMagick(); ?>
repng2jpeg Support: <?php echo $objChk->checkRepng2jpeg(); ?>
 
Check suitable repng2jpeg:
 
<?php echo $objChk->checkRepng2jpegRecommended(); ?>
 
</pre>
</body>
</html>
New file

Property changes:

Name: svn:keywords
+ Id Date Author

/release/Utilities-PIO-v6/rebuildtree.php
@@ -0,0 +1,46 @@
<?php
/**
* Pixmicat! PIO 公用程式 - 重建 tree 樹狀結構檔
*
* 本公用程式可嘗試修復毀損的樹狀結構檔。原理是 PIO Log 來源已有內建一些相關樹狀結構供恢復用,
* 此程式可以將這些資訊統整後再輸出,即成為樹狀結構檔。
*
* 注意:若原文章儲存檔已有部分毀損,恕無法正確重建資訊。另原文章 sage 效果亦無法重現,一切按時間排序。
*
* @package PMCUtility
* @version $Id$
* @date $Date$
*/
include('./config.php');
if(preg_match('/^log:\/\/(.*)\:(.*)\/$/i', CONNECTION_STRING, $linkinfos)){
$logfile = './'.$linkinfos[1]; // 投稿文字記錄檔檔名
$treefile = './'.$linkinfos[2]; // 樹狀結構記錄檔檔名
}else{
exit('PIO Connection String Error! ("log://" Expected).');
}
 
$tree = array(); // 樹狀結構陣列
$treeline = ''; // 樹狀結構資料
$f = file($logfile);
$f_cnt = count($f);
for($i = 0; $i < $f_cnt; $i++){
$line = explode(',', $f[$i]);
if($line[1]==0){ // 首篇
if(!isset($tree[$line[0]])) $tree[$line[0]] = array($line[0]); // 僅自身一篇
else array_unshift($tree[$line[0]], $line[0]);
continue;
}
if(!isset($tree[$line[1]])) $tree[$line[1]] = array();
array_unshift($tree[$line[1]], $line[0]);
}
 
foreach($tree as $t){ $treeline .= implode(',', $t)."\r\n"; } // 自陣列整理成文字檔形式
$fp = fopen($treefile.'.new', 'w');
stream_set_write_buffer($fp, 0);
fwrite($fp, $treeline);
fclose($fp);
unset($fp);
@chmod($treefile.'.new', 0666);
 
echo '重建完成,檔案名稱為 "'.$treefile.'.new",請自行更名為 "'.$treefile.'"。以下是預覽:<hr/><pre>'.$treeline.'</pre>';
?>
New file
/release/Utilities-PIO-v6/rebuildifs.php
@@ -0,0 +1,21 @@
<?php
include('./config.php');
include('./lib/fileio/ifs.php');
 
@unlink(FILEIO_INDEXLOG);
$fio = new IndexFS(FILEIO_INDEXLOG);
 
$fio->openIndex();
clearstatcache();
$dirs = array(IMG_DIR, THUMB_DIR);
foreach ($dirs as $dir) {
if ($handle = opendir($dir)) {
while (false !== ($file = readdir($handle))) {
if ($file == "." || $file == "..") continue;
$fio->addRecord($file,filesize($dir.'/'.$file),'');
}
}
}
$fio->saveIndex();
echo "done";
?>
New file

Property changes:

Name: svn:keywords
+ Id Date Author

/release/Utilities-PIO-v6/log2pio.php
@@ -0,0 +1,85 @@
<?php
/**
* Pixmicat! PIO 公用程式 - Pixmicat!-Log -> Pixmciat-PIO (Log) 資料格式轉換器
*
* 本程式可以自 Log 版轉換格式自 PIO 版 Log 資料來源。
*
* 注意:本程式是給 Log 版舊程式使用以轉換,非直接用在 PIO 新版上面
*
* @package PMCUtility
* @version $Id$
* @date $Date$
*/
include_once('./config.php');
define('DEL_ZOMBIE', true); // 如果有文章沒有出現在樹狀結構,是否不要轉換直接刪除?
define('SAVE_LOG', true); // 是否儲存新結構 (舊結構將保留並更名)
 
// 各資料儲存檔位置
$logimg = file(LOGFILE); $logimg_cnt = count($logimg);
$trees = array(); // 文章回應對應編號陣列 (回應No. => 首篇No.)
$logtree = array_map('rtrim', file(TREEFILE));
foreach($logtree as $treeline){ // 解析樹狀結構製成對應索引
if($treeline=='') continue;
$tline = explode(',', $treeline); $tline_cnt = count($tline);
$trees[$tline[0]] = 0;
for($t = 1; $t < $tline_cnt; $t++){ $trees[$tline[$t]] = $tline[0]; }
}
unset($logtree);
 
// 圖檔存放位置
$dirimg = realpath('.').DIRECTORY_SEPARATOR.IMG_DIR;
 
/* 取得圖檔的寬長以存入資料 */
function getImageWH($imgname){
global $dirimg;
 
$imgpath = $dirimg.$imgname;
if(!file_exists($imgpath)) return array(0, 0);
list($width, $height,) = getimagesize($imgpath);
return array($width, $height); // 回傳寬高陣列
}
 
/* 取得圖檔的檔案大小字串 (單位 KB) */
function getImageSizeText($imgname){
global $dirimg;
 
$imgpath = $dirimg.$imgname;
if(!file_exists($imgpath)) return false;
$imgsize = filesize($imgpath);
return ($imgsize >= 1024 ? (int)($imgsize / 1024).' KB' : $imgsize.' B'); // 回傳檔案大小字串
}
 
/* 取得回應的對象編號 */
function getReplyTargetNo($no){
global $trees;
 
if(isset($trees[$no])) return $trees[$no];
return false;
}
 
/* 更改 log 檔結構 */
// OLD: 編號,時間 (ID),名稱,E-Mail,標題,內文,狀態旗標,主機位置,編碼後文章密碼,附加圖檔類型,預覽圖寬,預覽圖長,Unix時間撮記,附加圖檔MD5,
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13
// NEW: 編號,回應目標編號,附加圖檔MD5,類別標籤,Unix時間撮記,附加圖檔類型,圖檔寬,圖檔長,圖檔大小,預覽圖寬,預覽圖長,編碼後文章密碼,時間 (ID),名稱,E-mail,標題,內文,主機位置,狀態旗標,
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
header('Content-Type: text/plain; charset=utf-8');
$newLine = array(); // 新資料格式
if(count(explode(',', $logimg[0])) != 15) die('File structure error. maybe it\'s already a PIO structure.');
for($i = 0; $i < $logimg_cnt; $i++){
$l = explode(',', $logimg[$i]); // 舊資料格式 (用逗號拆開)
$s = getImageWH($l[12].$l[9]); // 圖檔寬長 (寬, 長)
$l[6] = str_replace('_THREADSTOP_', '_TS_', $l[6]); // 討論串停止旗標自 _THREADSTOP_ 改為 _TS_
if(!DEL_ZOMBIE || getReplyTargetNo($l[0]) !== false) $newLine[] = implode(',', array($l[0], getReplyTargetNo($l[0]), $l[13], '', $l[12], $l[9], $s[0], $s[1], getImageSizeText($l[12].$l[9]), (int) $l[10], (int) $l[11], $l[8], $l[1], $l[2], $l[3], $l[4], $l[5], $l[7], $l[6], ''))."\r\n";
}
$writeContent = implode('', $newLine);
 
if(SAVE_LOG){
rename(LOGFILE, LOGFILE.'.old');
$fs = fopen(LOGFILE, 'w');
fwrite($fs, $writeContent);
fclose($fs);
die('File save OK. The old file already renamed.');
}else{
echo $writeContent;
}
?>
New file

Property changes:

Name: svn:keywords
+ Id Date Author

/release/Utilities-PIO-v6/piov2tov3.php
@@ -0,0 +1,50 @@
<?php
/**
* Pixmicat! PIO 公用程式 - PIO V2 -> PIO V3 資料格式轉換器
*
* 本程式可以將舊版的 PIO V2 結構轉成新的 PIO V3 結構,
* 主要不同點在於 status 欄位擴充至 VARCHAR(255) 及討論串停止代表旗標參數改變 (T -> _TS_)。
*
* @package PMCUtility
* @version $Id$
* @date $Date$
*/
 
include_once('./config.php');
include_once('./lib/lib_pio.php');
 
$PIO->dbConnect(CONNECTION_STRING);
$PIO->dbPrepare();
 
switch(PIXMICAT_BACKEND){
case 'mysql': // MySQL
/* 修正 status VARCHAR(255), T -> _TS_ */
$PIO->_mysql_call('ALTER TABLE '.$PIO->tablename.' CHANGE status status VARCHAR(255) NOT NULL');
$PIO->_mysql_call('UPDATE '.$PIO->tablename.' SET status = "_TS_" WHERE status = "T"');
break;
case 'pgsql': // PostgresSQL
/* 修正 status VARCHAR(255), T -> _TS_ */
$PIO->_pgsql_call('ALTER TABLE '.$PIO->tablename.' ALTER COLUMN status TYPE VARCHAR(255); UPDATE '.$PIO->tablename.' SET status = "_TS_" WHERE status = "T"');
break;
case 'sqlite':
/* 修正 T -> _TS_ (SQLite VARCHAR 無硬性限制) */
$PIO->_sqlite_call('UPDATE '.$PIO->tablename.' SET status = "_TS_" WHERE status = "T"');
break;
case 'sqlite3':
case 'log':
case 'logflockp':
/* 修正 _THREADSTOP_ -> _TS_ */
$plist = $PIO->fetchThreadList(0, $PIO->threadCount());
$post = $PIO->fetchPosts($plist); // 取出資料
$post_count = count($post);
 
for($i = 0; $i < $post_count; $i++){
$PIO->setPostStatus($post[$i]['no'], str_replace('_THREADSTOP_', '_TS_', $post[$i]['status']));
}
break;
default:
echo('What backend did you use? Sorry we can\'t fix it now.<br />');
}
$PIO->dbCommit();
echo('PIO V3 Update OK.');
?>

Property changes:

Name: svn:mergeinfo
+ /branches/totalsize_fix/Utilities:784-790

/Utilities-PIO-v6