Jun 29

[linux] mv的一个BUG? 不指定

felix021 @ 2011-6-29 11:50 [IT » 其他] 评论(3) , 引用(0) , 阅读(10535) | Via 本站原创
如下
felix021@localhost:/tmp/test$ mkdir -p a/c/d b/c/d
felix021@localhost:/tmp/test$ mv b/c a/
mv: cannot move `b/c' to a subdirectory of itself, `a/c'
Jun 24
使用以下脚本来编译安装,需要把安装文件下载到 [ROOT]/src/ 下。

目录结构:

[ROOT]
    /src
        /php-5.2.17.tar.bz2
        ...
    /httpd
    /php
    /fcgi-bin

#!/bin/bash

set -x

ROOT="/home/felix021/lamp"
ROOT_E=${ROOT//\//\\\/}        # escape for sed, / => \/

WWWROOT="/home/felix021/lamp/wwwroot"
WWWROOT_E=${WWWROOT//\//\\\/}  # escape for sed, / => \/

HTTPD_PORT=80

FCGI_CHILDREN=4
FCGI_MAX_REQUESTS=1000

# 下载好的源码文件
fastcgi="mod_fastcgi-2.4.6"        #.tar.gz
httpd="httpd-2.2.17"                #.tar.bz2
php="php-5.2.17"                    #.tar.bz2
eaccelerator="eaccelerator-0.9.6.1" #.tar.bz2

SRCROOT=${ROOT}/src
mkdir -p $ROOT/{httpd,php,fcgi-bin}
mkdir -p $WWWROOT

# fcgi-bin (for apache + mod_fastcgi) 
# 创建这个脚本可以用来包装php-cgi,可以控制启动的FCGI进程数量
if [ ! -e "${ROOT}/fcgi-bin/php.cgi" ]; then
    > ${ROOT}/fcgi-bin/php.cgi echo "#!/bin/sh
# Shell Script To Run PHP5 using mod_fastcgi under Apache 2.x

### Set PATH ###
PHP_CGI=${ROOT}/php/bin/php-cgi
PHP_FCGI_CHILDREN=${FCGI_CHILDREN}
PHP_FCGI_MAX_REQUESTS=${FCGI_MAX_REQUESTS}

### no editing below ###
export PHP_FCGI_CHILDREN
export PHP_FCGI_MAX_REQUESTS
exec \$PHP_CGI
"
    chmod +x ${ROOT}/fcgi-bin/php.cgi
fi

# php
cd $SRCROOT
if [ ! -d "${php}" ]; then
    tar jxf ${php}.tar.bz2
    cd $php
    ./configure --prefix=${ROOT}/php --with-gd --with-iconv \
        --with-curl --enable-fastcgi --with-openssl --enable-mbstring  #有需要的话自己再增加一些模块吧
    echo Making... Please wait. "tail -f `pwd`/php.log" to view make output.
    make -j4 &> php.log
    make install
    cp php.init-dist ${ROOT}/php/lib/php.ini
fi

# eaccelerator
if [ ! -d "${eaccelerator}" ]; then
    tar jxf ${eaccelerator}.tar.bz2
    cd $eaccelerator
    export PHP_PREFIX=${ROOT}/php
    $PHP_PREFIX/bin/phpize
    ./configure --enable-eaccelerator=shared \
        --with-php-config=$PHP_PREFIX/bin/php-config
    make -j4 &> eaccelerator.log
    make install
    echo Please edit php.ini to enable eaccelerator.so
fi


# httpd
cd $SRCROOT
if [ ! -d "${httpd}" ]; then
    tar jxf ${httpd}.tar.bz2
    cd ${httpd}
    ./configure --prefix=${ROOT}/httpd --enable-rewrite
    echo Making... Please wait. "tail -f `pwd`/httpd.log" to view make output.
    make -j4 &> httpd.log
    make install

    conf_path="${ROOT}/httpd/conf/httpd.conf"

    # 下面这段sed脚本是把端口、DocRoot替换了,并允许目录下使用.htaccess来配置url rewrite
    sed -i $conf_path \
        -e "s/^Listen 80$/Listen ${HTTPD_PORT}/" \
        -e "s/\/.*\/htdocs\>/${WWWROOT_E}/" \
        -e "s/AllowOverride None/AllowOverride FileInfo/"

    fcgi_path="${ROOT}/fcgi-bin/"

    # 在配置中加入FastCgi相关的内容
    echo "
LoadModule fastcgi_module modules/mod_fastcgi.so

FastCgiServer \"${fcgi_path}php.cgi\"
AddHandler php-fastcgi .php

ScriptAlias /fcgi-bin/ \"${fcgi_path}\"
Action php-fastcgi "/fcgi-bin/php.cgi"
AddType application/x-httpd-php .php

<Directory \"${fcgi_path}\">
    SetHandler fastcgi-script
    Options FollowSymlinks +ExecCGI
    Order Allow,Deny
    Allow from All
</Directory>
"  >> $conf_path

fi

# mod_fastcgi for httpd
cd $SRCROOT
if [ ! -d "${fastcgi}" ]; then
    tar zxf ${fastcgi}.tar.gz
    cd ${fastcgi}
    cp Makefile.AP2 Makefile
    make top_dir=${ROOT}/httpd -j4 &> fastcgi.log
    make top_dir=${ROOT}/httpd install
fi

echo Done. Please run "${ROOT}/httpd/bin/apachectl start"
Jun 20
=> How to call a php function in a php extension

详细的说明参见:

[php-5.2.17]
    /Zend/zend_execute_API.c +623 & +636    call_user_function_ex
    /ext/standard/basic_functions.c +5174    PHP_FUNCTION(call_user_func_array)                                                                       
    /ext/pcre/pcre.c +833  (in function "preg_do_repl_func")

http://man.chinaunix.net/develop/php/php_manual_zh/html/zend.calling-user-functions.html

http://www.phpfreaks.com/forums/index.php?topic=10272.0

PHP_FUNCTION (caller)
{
    //call_user_function_ex
    zval *function, *str, *arr;
    zval **params[10];

    MAKE_STD_ZVAL(function);
    ZVAL_STRING(function, "var_dump", 1);  //I wanna call var_dump

    /*  //pass a string as its param
    MAKE_STD_ZVAL(str);
    ZVAL_STRING(str, "Hello, world!", 1);

    params[0] = &str;
    */

    //pass an array as its param
    MAKE_STD_ZVAL(arr);
    array_init(arr);
    add_assoc_string(arr, "name", "felix021", 1);
    params[0] = &arr;

    zval *ret;
    if (call_user_function_ex(CG(function_table), NULL,
            function, &ret, 2, params, 0, NULL TSRMLS_CC) != FAILURE)
    {
        *return_value = *ret;
        zval_copy_ctor(return_value);
        zval_ptr_dtor(&ret);
        return;
    }
    else {
        RETURN_FALSE;
    }
}

Jun 18
网上摘下来的代码,没什么好说的了(因为那一堆 mcrypt_* 函数太乱了,用就是了):
<?php

class DES
{
    public static function pkcs5_pad ($text, $blocksize) {
        $pad = $blocksize - (strlen($text) % $blocksize);
        return $text . str_repeat(chr($pad), $pad);
    }

    public static function pkcs5_unpad($text) {
        $pad = ord($text{strlen($text)-1});
        if ($pad > strlen($text)) {
            return false;
        }
        if (strspn($text, chr($pad), strlen($text) - $pad) != $pad) {
            return false;
        }
        return substr($text, 0, -1 * $pad);
    }

    public static function encrypt($key, $data) {
        $size = mcrypt_get_block_size('des', 'ecb');
        $data = DES::pkcs5_pad($data, $size);
        $td = mcrypt_module_open('des', '', 'ecb', '');
        $iv = @mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
        @mcrypt_generic_init($td, $key, $iv);
        $data = mcrypt_generic($td, $data);
        mcrypt_generic_deinit($td);
        mcrypt_module_close($td);
        return $data;
    }

    public static function decrypt($key, $data) {
        $td = mcrypt_module_open('des','','ecb','');
        $iv = @mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
        $ks = mcrypt_enc_get_key_size($td);
        @mcrypt_generic_init($td, $key, $iv);
        $decrypted = mdecrypt_generic($td, $data);
        mcrypt_generic_deinit($td);
        mcrypt_module_close($td);
        $result = DES::pkcs5_unpad($decrypted);
        return $result;
    }
}

/*  test code

$in = "04fMaWegkH1/BL9CNYxgusFpYK8wdraBX06mPiRmxJP+uVm31GQvyw==";
$des = base64_decode($in);
echo DES::decrypt("12345678", $des);
echo "\n";

$in = "cea3e8e1659582206e0be32539729e9f";
$des = DES::encrypt("12345678", $in);
$out = base64_encode($des);
echo $out;
echo "\n";

// */

?>
Jun 18
在"libc 4.6.27 and later, and glibc 2.1 and later"中,提供了 rpc/des_crypt.h这个头文件,其中有几个函数,比如:
void des_setparity(char *key);
int ecb_crypt(char *key, char *data, unsigned datalen, unsigned mode);

这个函数可以用于DES的加密/解密。详情可以看 man des_crypt ,以下说 ecb_crypt() 函数几个比较坑爹的地方:

1. 虽然提供给DES的密钥(key)是8个字节,但是实际上只用到了其中的56个bit,另外8个bit是用于奇偶校验的(从用户处取得一个64位长的密码key ,去除64位密码中作为奇偶校验位的第8、16、24、32、40、48、56、64位,剩下的56位作为有效输入密钥)。所以需要调用 des_setparity(key) 来处理key。

2. 必须在data后面补上1~8个 "\x8",以将datalen补齐到8的倍数。对,是1~8个。假设要加密的data是32个字节,需要先补齐到40个字节。

3. 传给des_setparity()的key和给ecb_crypt的data会被直接改写。

以下是样例代码:
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <rpc/des_crypt.h>

//注意:这里有个坑,需要保证 data 可以存放的字符串在后面补了\8 不会越界。否则结果是不确定的。
void des_encrypt(const char *key, char *data, int len)
{
    char pkey[8];
    strncpy(pkey, key, 8);
    des_setparity(pkey);
    do {
        data[len++] = '\x8';
    } while (len % 8 != 0);
    ecb_crypt(pkey, data, len, DES_ENCRYPT);
}

void des_decrypt(const char *key, char *data, int len)
{
    char pkey[8];
    strncpy(pkey, key, 8);
    des_setparity(pkey);
    ecb_crypt(pkey, data, len, DES_DECRYPT);
}

int main(int argc, char *argv[])
{
    /*
    * char data[4096] = "cea3e8e1659582206e0be32539729e9f";
    * des_encrypt("12345678", data, strlen(data));
    * printf("%s\n", data);
    * //should be "04fMaWegkH1/BL9CNYxgusFpYK8wdraBX06mPiRmxJP+uVm31GQvyw=="
    */

    char data[4096];
    int i = 0;
    while (EOF != (data[i] = fgetc(stdin))) {
        i++;
    }
    data[i] = '\0';
    des_decrypt("12345678", data, strlen(data));
    printf("%s\n", data);
    /*
    * echo -n 04fMaWegkH1/BL9CNYxgusFpYK8wdraBX06mPiRmxJP+uVm31GQvyw== | base64 -d | ./des
    * should be "cea3e8e1659582206e0be32539729e9f"
    */
    return 0;
}
Jun 15

坑爹的crontab #2 不指定

felix021 @ 2011-6-15 12:25 [IT » 操作系统] 评论(2) , 引用(0) , 阅读(14455) | Via 本站原创
我喜欢在自己的 $HOME 下面建立一个 bin ,然后添加到 $PATH 中,这样我可以方便地执行自己的程序:

$ mkdir ~/bin
$ vi .bashrc
export PATH=$PATH:~/bin

不过坑爹的 crontab 对 .bashrc 并不买账,通过

* * * * *  echo $PATH > ~/cronpath.txt

可以看出, crontab 执行命令时没有把环境变量给切过来。

$ cat ~/cronpath.txt
/usr/bin:/bin
Jun 14

坑爹的crontab 不指定

felix021 @ 2011-6-14 23:40 [IT » 操作系统] 评论(0) , 引用(0) , 阅读(4894) | Via 本站原创
#UPDATE: 并不是不能处理反引号,而是不能直接写%,需要转义。

某脚本x.sh,接受一个参数,比如20110517,用于处理20110517的日志。

处理前一天的日志,非常理所当然地使用如下命令
PATH_TO_SCRIPT/x.sh `date -d "-1 day" +%Y%m%d`


由于是每天早上8点30分执行,所以很理所当然地:

$ crontab -e
30  8    *    *    *    PATH_TO_SCRIPT/x.sh `date -d "-1 day" +%Y%m%d`

但是过了几天发现脚本根本就没有被处理(在某些机器上,cron fail时会将邮件发送给用户"You have new mail in /var/spool/mail/USERNAME")。

原因是坑爹的cron没法正确处理反引号。

解决办法是,额外写个脚本将这句命令包装,在crontab中执行包装脚本 在%前面都加上反斜杠。
分页: 1/1 第一页 1 最后页 [ 显示模式: 摘要 | 列表 ]