unzip的中文问题

唉,unzip的-O选项一直是一个传说中的存在,而且unzip的开发者一直没有意向修复。

故自己动手,丰衣足食,用python写了一个MultiCharset ZIP,代码附上:

#!/usr/bin/python
# -*- coding: utf-8 -*- 

import os
import sys
import zipfile
from optparse import OptionParser

def listZip(zipf):
    print "Archive:  %s" %zipf
    print "  Length      Date    Time    Name"
    print "---------  ---------- -----   ----"
    filist=zipfile.ZipFile(zipf).infolist()
    totalnum=0
    totalsize=0
    for finfo in filist:
        totalnum+=1
        totalsize+=finfo.file_size
        print "%9d " %finfo.file_size ,
        print "%04d-%02d-%02d" %(finfo.date_time[0],finfo.date_time[1],finfo.date_time[2]),
        print "%02d:%02d  " %(finfo.date_time[3],finfo.date_time[4]),
        print finfo.filename.decode('gb18030').encode('utf-8')
    print "---------                     -------"
    print "%9d" %totalsize ,
    print "                   ",
    print "%d files" %totalnum

def exZip(zipf,exdir):
    zf=zipfile.ZipFile(zipf)
    nlist=zf.namelist()
    nlist.sort(key=lambda x:len(x))
    for fn in nlist:
        fnew=unicode(fn,'gb2312').encode('utf8')
        if fnew.endswith('/'):
            os.mkdir(exdir+fnew)
        else:
            file(exdir+fnew,'wb').write(zf.read(fn))
        print fnew
    zf.close()

def main():
    usage = "usage: "+sys.argv[0]+" [options] zipfile1 zipfile2"
    parser = OptionParser(usage=usage)
    parser.add_option("-l","--list",action="store_true",help="list files in zip file",dest="islist",default=True)
    parser.add_option("-x","--extract",action="store_true",help="extract zip files",dest="isex",default=False)
    parser.add_option("-d","--exdir",action="store",help="define extract directory",dest="exdir",default=".")
    #parser.add_option("-z","--exdir",action="store",dest="exidr")

    (options,args)=parser.parse_args();

    if(options.isex):
        for zf in args:
            exZip(zf,options.exdir+"/")
    else:
        if(options.islist):
            for zf in args:
                listZip(zf)

if __name__ == "__main__":
    main()

可以在~/bin/目录下创建一个mczip文件,写入代码,添加可执行权限,

即可在终端中用mczip来列出zip文件内容、解压zip文件。

用法

Usage:mczip.py [options] zipfile1 zipfile2

Options:
-h, --help            show this help message and exit
-l, --list            list files in zip file
-x, --extract         extract zip files
-d EXDIR, --exdir=EXDIR     define extract directory

只有列出zip包的文件内容和解压zip文件两个功能,只能处理gb18030编码。

Python3的zip模块判断更加奇葩了,只要文件名不是ascii编码,就认为是utf8编码,而且不保留bytes格式的文件名,有点难办啊。

gcc的使用和编译时的符号确定

一般来说,我们编译c语言程序要经过编译(预处理)、和链接两步。当然教材上讲的时候还有预处理。

预处理

gcc -E code.c -o code.e.c

预处理主要处理文件包含和宏定义等等。

编译

gcc -c code.c -o code.o

编译主要把c语句翻译成二进制代码(一般此步骤包括了预处理)。

但是有一些函数的实现没有在预处理过的c语言文件中,类似的还有extern声明的变量,所以现在编译的文件还没有办法执行。这些无法决定位置的函数和变量,在.o文件中统称为未定义的符号。

链接

gcc code.o -o code

在这一步我们要把所有.o文件中的未定义符号给确定下来,确定的来源有两种,查看其他.o文件的导出表中查找,从其他.so(dll)文件的导出表中查找。

gcc还有一个重要的参数是-g,表示编译的时候保留调试信息(包括c语句和汇编语句的对应关系,变量的分配)

gcc的-o参数指定输出文件的名字。

让我们通过一个例子来了解这个流程

test.c文件:

#include <stdio.h>

extern int a;

extern void test();

int main()
{
	test();
	return 0;
}

先预处理它:

gcc -E test.c -o test.e.c

可以看到源文件多了许多头文件中的代码。

编译它:

gcc -c test.c -o test.o

我们用nm命令来获取其中有哪些符号:

nm test.o

输出(第一列是符号地址,第二列是状态,第三列是符号名):

                 U a
0000000000000000 B b
0000000000000000 T main
                 U test

可以看到,a和test的状态是未定义(U),因为gcc目前无法确定这两个符号的地址。

T表示main函数位于代码区,B表示b位于非初始化数据段(bss)中。

此时直接链接会出现若干undefined reference 。

我们再写一个c文件:

test2.c

int a;
void test()
{
}

编译,用nm查看相应.o文件

0000000000000004 C a
0000000000000000 T test

此时链接就没有错误:gcc test.o test2.o -o test

但是我们可以看到nm test的结果中仍然有未定义的符号:

nm test

输出如下:

..............
                 U [email protected]@GLIBC_2.2.5
..............

这涉及到动态链接库技术,程序在执行的时候才能决定符号地址(一般来说,这个符号地址在某个so/dll文件中)。

现在我们来查看程序使用了哪些动态链接库(so/dll文件):

执行

ldd test

结果如下

	linux-vdso.so.1 =>  (0x00007fff629fe000)
	libc.so.6 => /lib64/libc.so.6 (0x00000038f9200000)
	/lib64/ld-linux-x86-64.so.2 (0x00000038f8e00000)

可以看到,我们的程序用到了三个动态链接库。

最后一个动态链接库严格说来并不是动态链接库,是动态库的装载器。

libc.so属于glibc(一个linux下c语言的运行时库),Windows下对应的文件是msvcrt.dll。

fedora 18 安装配置

安装fastestmirror:

个人不推荐更改repo文件,因为有单点依赖

yum install yum-plugin-fastestmirror

安装rpmfusion源:

RPM Fusion is a merger of Dribble, Freshrpms, and Livna.

yum localinstall --nogpgcheck http://mirrors.163.com/rpmfusion/free/fedora/rpmfusion-free-release-stable.noarch.rpm http://mirrors.163.com/rpmfusion/nonfree/fedora/rpmfusion-nonfree-release-stable.noarch.rpm

字体:

yum install wqy-bitmap-fonts wqy-zenhei-fonts wqy-unibit-fonts wqy-microhei-fonts
yum install cjkuni-uming-fonts cjkuni-ukai-fonts

gedit乱码:

gsettings set org.gnome.gedit.preferences.encodings auto-detected "['GB18030', 'BIG5', 'UTF-8', 'CURRENT', 'UTF-16']"
gsettings set org.gnome.gedit.preferences.encodings shown-in-menu "['GB18030', 'BIG5', 'ISO-8859-15']"

#复原
#gsettings set org.gnome.gedit.preferences.encodings auto-detected “[‘UTF-8’, ‘CURRENT’, ‘ISO-8859-15’, ‘UTF-16’]”
#gsettings set org.gnome.gedit.preferences.encodings shown-in-menu “[‘GB18030’, ‘ISO-8859-15’]”

输入法:

当然,得另外配置一下才可以哦

yum install fcitx-gtk3 fcitx-libpinyin fcitx-cloudpinyin fcitx-configtool

办公软件:

Libre office 是一个非常优秀的办公软件。

yum install libreoffice-base libreoffice-calc libreoffice-math libreoffice-writer libreoffice-ogltrans libreoffice-wiki-publisher libreoffice-draw

Adobe Flash Plugin:

可以自动更新。

yum localinstall --nogpgcheck http://linuxdownload.adobe.com/adobe-release/adobe-release-x86_64-1.0-1.noarch.rpm
yum install flash-plugin

多媒体/解码器:

yum install ffmpeg ffmpeg-libs gstreamer-ffmpeg xvidcore libdvdread libdvdnav lsdvd gstreamer-plugins-good gstreamer-plugins-bad gstreamer-plugins-ugly

FileZilla:

非常优秀的开源ftp客户端

yum install filezilla

图形相关:

yum install gimp blender

远程桌面:

yum install rdesktop spice-client
sudo yum install remmina remmina-plugins-rdp remmina-plugins-gnome remmina-plugins-vnc

系统工具:

yum install system-storage-manager systemd-ui gparted

小工具/插件:

包括字体查看器、nautilus插件、gonme插件、gedit插件。

yum install gnome-font-viewer nautilus-open-terminal gnome-shell-extension-alternative-status-menu gnome-exe-thumbnailer
yum install gedit-plugins gedit-beesu-plugin gnome-nettool

常用工具:

yum install wget patch unrar axel

开发工具:

yum install git-svn git
yum install gcc gcc-c++ gdb autoconf automake java-1.7.0-openjdk java-1.7.0-openjdk-devel indent

web/ftp 服务器:

yum install httpd mysql mysql-server php php-mysql
yum install proftpd

虚拟化:

yum group install virtualization

用reveal.js+markdown制作树型结构的slides

reveal.js 可以让你制作出基于网页的slides,轻量级,跨平台,非私有格式。

说来惭愧,我做的大多slides都是想表达这样的结构:

image1

于是,就做出了这样的slides:

image2

我们姑且称这样的slides为“树型结构slides”。我们要用 reveal.js来制作这样的 slides 。

fork项目:

git clone git://github.com/hakimel/reveal.js.git

然后修改index.html文件,把class为slides的div元素换为如下div元素(覆盖掉原来的div元素及其子孙元素)

<div class="slides">
  <section data-markdown data-separator="^\n\n\n" data-vertical="^\n\n">
    <script type="text/template">
      <!-- [markdown 内容] -->
    </script>
  </section>
</div>

data-separator=”^\n\n\n”表示用三个连续的换行作为横向分隔符(即顶层slide之间的分隔),data-vertical=”^\n\n”表示用两个个连续的换行作为纵向分隔符(即第二层slide之间的分隔)。

举例如下:

<div class="slides">
  <section data-markdown data-separator="= = =" data-vertical="- - -">
    <script type="text/template">
      #start slide
      = = =
      #slide 1
      - - -
      #slide 1.1
      - - -
      #slide 1.2
      = = =
      #slide 2
      - - -
      #slide 2.1
      - - -
      #slide 2.2
      = = =
      #end slide
    </script>
  </section>
</div>

使用方法:首先展示开始页,按右或者回车显示下一页,按左显示上一页,按上下显示相应页面子页面。Esc显示概览。

如图:

image3

不足:

需要slides作者有html/css基础。

加载时需要下载网页字体(这个可以先用离线模式解决,日后联系开发者解决)

只适用于“扁平”状的slides,如果层数太多,展示效果不好。

建立xdebug+eclipse的调试环境

几周了,终于让 eclipse 能够调试php代码了,期间找了许多资料,但是总不能如愿,于是记录如下。

安装xdebug

fedora 下直接安装 php-pecl-xdebug 包就算是配置好了 php 的 xdebug 扩展。

记得systemctl reload httpd.service

访问 phpinfo 页面时应该有 xdebug 的相关信息:

Screenshot from 2013-04-03 16:01:51

然后打开 display_errors ,即 php.ini 里面有 display_errors= On ,那么打开一个有异常的页面会出现彩色提示。Screenshot from 2013-04-03 15:51:52

配置远程调试

这时可以配置远程调试。在 /etc/php.d/xdebug.ini 中写入如下几行:

[Xdebug]
xdebug.remote_autostart=On
xdebug.remote_enable=On
xdebug.remote_host=127.0.0.1
xdebug.remote_handler=dbgp

然后systemctl reload httpd.service ,在 phpinfo 页面确认上述参数已经生效。

然后用 debugclient 来测试xdebug是否正常工作。

运行 debugclient ,显示等待连接:

Screenshot from 2013-04-03 16:10:25

然后访问一个会产生异常的页面,debugclient 会得到连接:

Screenshot from 2013-04-03 17:06:43

配置eclipse

eclipse安装好相关的插件(PDT),创建项目,把项目目录配置为虚拟主机,然后设置项目的调试器。

有待完善啊。。

Linux 下 Eclipse 的外观修改(图标大小)

在Linux(F18+gnome3)下用Eclipse最显著的一个特点是图标特别的“大气”,菜单栏都到两行了,就是图标特别的大。给张图就明白了:

before

今天突然有改了它的冲动,百度之,曰为gtk2的风格问题。不过,百度出来的答案都没用,于是google,得之:https://www.davidandrzejewski.com/2012/08/03/make-eclipse-less-ugly- in-linux-mint/

文中的配置有一点不妥,引用如下:

style "compact"
{
GtkButton::default_border={0,0,0,0}
GtkButton::default_outside_border={0,0,0,0}
GtkButtonBox::child_min_width=0
GtkButtonBox::child_min_heigth=0
GtkButtonBox::child_internal_pad_x=0
GtkButtonBox::child_internal_pad_y=0
GtkMenu::vertical-padding=1
GtkMenuBar::internal_padding=1
GtkMenuItem::horizontal_padding=4
GtkToolbar::internal-padding=1
GtkToolbar::space-size=1
GtkOptionMenu::indicator_size=0
GtkOptionMenu::indicator_spacing=0
GtkPaned::handle_size=4
GtkRange::trough_border=0
GtkRange::stepper_spacing=0
GtkScale::value_spacing=0
GtkScrolledWindow::scrollbar_spacing=0
GtkExpander::expander_size=10
GtkExpander::expander_spacing=0
GtkTreeView::vertical-separator=0
GtkTreeView::horizontal-separator=0
GtkTreeView::expander-size=12
GtkTreeView::fixed-height-mode=TRUE
GtkWidget::focus_padding=0
font_name="Liberation Sans,Sans Regular 8"
text[SELECTED] = @selected_text_color
}
class "GtkWidget" style "compact"
style "compact2"
{
xthickness=1
ythickness=1
}

class "GtkButton" style "compact2"
class "GtkToolbar" style "compact2"
class "GtkPaned" style "compact2"

第30行使tweak丧失了对程序字体的控制权,有越俎代庖之嫌,删去。

第5行个人觉得边框太小,故改为1 。

最终解决方案:

在~/gtkrc-2.0文件中添加如下语句:

style "compact"
{
  GtkButton::default_border={1,1,1,1}
  GtkButton::default_outside_border={0,0,0,0}
  GtkButtonBox::child_min_width=0
  GtkButtonBox::child_min_heigth=0
  GtkButtonBox::child_internal_pad_x=0
  GtkButtonBox::child_internal_pad_y=0
  GtkMenu::vertical-padding=1
  GtkMenuBar::internal_padding=1
  GtkMenuItem::horizontal_padding=4
  GtkToolbar::internal-padding=1
  GtkToolbar::space-size=1
  GtkOptionMenu::indicator_size=0
  GtkOptionMenu::indicator_spacing=0
  GtkPaned::handle_size=4
  GtkRange::trough_border=0
  GtkRange::stepper_spacing=0
  GtkScale::value_spacing=0
  GtkScrolledWindow::scrollbar_spacing=0
  GtkExpander::expander_size=10
  GtkExpander::expander_spacing=0
  GtkTreeView::vertical-separator=0
  GtkTreeView::horizontal-separator=0
  GtkTreeView::expander-size=12
  GtkTreeView::fixed-height-mode=TRUE
  GtkWidget::focus_padding=0
}
class "GtkWidget" style "compact"
style "compact2"
{
  xthickness=1
  ythickness=1
}
class "GtkButton" style "compact2"
class "GtkToolbar" style "compact2"
class "GtkPaned" style "compact2"

效果:

after

注意:此法可能对其他使用gtk2的程序产生影响。

ProFTPD限制FTP模式

以前搞过ProFTPD禁止主动模式,但是这两天有这个需求的时候却忘记了,看来得写一日志记录下。

首先,环境是 fedora 17 + proftp 。

默认的配置是主动模式和被动模式都可用。

主动模式下访问记录:

Command:    PORT 127,0,0,1,237,87
Response:    200 PORT command successful

被动模式访问记录:

Command:    PASV
Response:    227 Entering Passive Mode (127,0,0,1,157,107).

如果需要禁止主动模式访问,则只需要在/etc/proftd.conf的<Global>段中添加如下三行:

<Limit PORT>
DenyAll
</Limit>

即禁止PORT指令,则主动模式访问记录变为:

Command:    PORT 127,0,0,1,199,3
Response:    501 PORT: Operation not permitted

如果需要禁止被动模式访问,则只需要在/etc/proftd.conf的<Global>段中添加如下三行:

<Limit PASV>
DenyAll
</Limit>

即禁止PASV指令,则被动模式访问记录变为:

Command:    PASV
Response:    501 PASV: Operation not permitted

东华大学 WiFi 的认证流程

登陆

首先,我们连接上DHU的时候,http请求(甚至是https请求)都会返回302
Location:http://www3.dhu.edu.cn/wireless/dhu-login_page.htm?cmd=login& amp;mac=ec:55:f9:6c:54:15&ip=10.200.3.32&essid=DHU&url=http%3A%2F%2Fbaidu%2Ecom%2F

若是https请求,则会出错(ERROR: certificate common name `securelogin.arubanetworks.com’ doesn’t match requested host name `xxxx’.)

http请求则能正常打开页面。

现在转到http://www3.dhu.edu.cn/wireless/dhu-login_page.htm

首先,在此页面,验证码的比对是由javascript完成的,若验证码不符,则不会提交表单。

若验证码通过,则此页面向https://securelogin.arubanetworks.com/auth/index.html/u提交表单(post方式),各参数如下:
[%%MAGICID%%] => %%MAGICVAL%%
[user] => 学号
[password] => 密码
[text] => 验证码
[text2] => 验证码
[%%REDIRID%%] => %%PROTURI%%
通过我后来的实验可知,只提交user和password也可通过认证。

若之前没有登陆,且用户名密码匹配,则返回如下:
POST https://securelogin.arubanetworks.com/auth/index.html/u [HTTP/1.1 200 OK 331ms]
若用户名密码不匹配,返回如下:
POST https://securelogin.arubanetworks.com/auth/index.html/u [HTTP/1.1 302 Temporarily Moved 342ms]
Location: http://www3.dhu.edu.cn/wireless/dhu-login_page.htm?errmsg=Authentication failed
若之前登陆成功,不论你用户名密码是否匹配,都返回:
POST https://securelogin.arubanetworks.com/auth/index.html/u [HTTP/1.1 302 Temporarily Moved 101ms]
Location:?errmsg=Access denied
然后就一直:
GET https://securelogin.arubanetworks.com/auth/index.html/u?errmsg=Access%20denied [HTTP/1.1 302 Temporarily Moved 37ms]
Location:?errmsg=Access denied

退出

至于退出,则是向https://securelogin.arubanetworks.com/auth/logout.html POST 如下数据
[button] => ע�� (gb2312编码的“按钮”两字)
当然,只是 GET https://securelogin.arubanetworks.com/auth/logout.html 也可退出。

Linux下管理MP3文件(乱码,临时文件)

很多MP3文件在Linux的播放器中都显示乱码,原理在此:http://www.linuxdiyf.com/viewarticle.php?id=57099

另外,Linux下有的音乐播放器会在目录下创建隐藏文件,备份时当然要删除这些文件了。
1.删除目录下除MP3和LRC文件以外的其他文件:

find ./ -type f ! -iname \*.mp3 ! -iname  \*.lrc -exec rm -v \{\} \;

2.删除空目录:

find ./ -type d -empty -delete

注意:此处不能用 -exec rm ,因为删除目录时find命令仍然在这个目录,会报错。

3.修复MP3文件的标签:

find ./ -type f -iname \*.mp3 -exec mid3iconv -e gbk \{\} --remove-v1 \;

注:经测试 mid3iconv -e gbk X.mp3 –remove-v1 不会改变原来正常MP3文件的编码。