[中秋零献] 神州数码802.1x局域网UDP拔号软件MyNet-Gnome源代码大分析(Part3)关键逻辑

/***
* Author: cc0cc
* E-mail: cc0cc@126.com
* WebSite: http://www.54chen.com * Date: the Mid-Autumn Festival of 2008
* FileName: callbacks.c
* Description: callbacks.c为事件处理的核心逻辑,是MyNet的中心
***/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <gnome.h>
#include "Mythread.h"
#include "connect.h"
#include "callbacks.h"
#include "interface.h"
#include "support.h"

gchar line2[255];//用来存去掉回车后的字符串
void write_config(gchar *usr,gchar *pwd);//remember pwd
void write_new_config();//first time to write config
gchar * scape(gchar *line);//escapse the enter like '\n'
/*
* 关于mac和ip的:http://hi.baidu.com/cc0cc/blog/item/403cbb25a0cd9a6435a80fa7.html
*/
char *get_mac();//return the mac address
char *get_ip();//get ip address
int get_socket();
int tr_mac();//translate the mac address
int CreateMutex();//a file like mutex (互斥体,用来保证只能同时运行一个此软件,后来被干掉啦:))
int trayshow;

/*这个是window1,也就是软件一打开的时候会执行这个函数*/
void
on_window1_show                        (GtkWidget       *widget,
                                        gpointer         user_data)
{ /*
//采访一下:为什么要把这段干掉?
//A:因为在程序异常关闭的时候,老是不能自己删除掉原来的PID文件,于是就得手工去删除,实在是不爽,干脆不限制了。
char runfile[1024]="";
FILE *runfp;   
sprintf(runfile,"%s/.mynet/run.pid",getenv("HOME"));

if((runfp = fopen(runfile, "r")) != NULL)
    {   
    gtk_widget_hide(window1);
    getAtrBox = create_messagebox("错误","程序已经运行了!",0);
     gtk_widget_show (getAtrBox);
    }else{
        CreateMutex();
        }
*/
username[0x40]=0;
host[0x1E]=0;
memcpy(host,SERVER,strlen((char *)SERVER));
mac_addr[0x20]=0;
mac_Hex[6]=0;
ip_addr[0x20]=0;
passwd[0x40]=0;
server_type[0x40]=0;
memcpy(server_type,"internet",strlen((char *)"internet"));

gchar *line = ((char *) malloc(255));//is 255b enough?
char cfgfile[1024]="";
FILE *fp;   
   
sprintf(cfgfile,"%s/.mynet/config",getenv("HOME"));
if ((fp = fopen(cfgfile, "r")) == NULL)    write_new_config();//看出来这是在干什么了吗?这是把用户的当前设置给写进一个config文件,就算是windows里的注册表了
else
    {
    fgets(line,254,fp);
    gtk_entry_set_text ((GtkEntry *)entry1,(const gchar *)scape(line));
    memcpy(username,scape(line),strlen(scape(line)));
    fgets(line,254,fp);
    gtk_entry_set_text ((GtkEntry *)entry2,(const gchar *)scape(line));   
    memcpy(passwd,scape(line),strlen(scape(line)));
    fgets(line,254,fp);
    memcpy(ip_addr,scape(line),strlen(scape(line)));
    fgets(line,254,fp);
    memcpy(host,scape(line),strlen(scape(line)));g_message("here1");
    //get_socket((char *)scape(line));//host to
        g_message("%c",&line);
    fgets(line,254,fp);g_message("here3");
    memcpy(mac_addr,scape(line),strlen(scape(line)));g_message("here4");
    tr_mac();g_message("here5");
    }   
g_message("mem now here:usr:%s\npwd:%s\nip:%s\nmac:%s\nserver:%s",username,passwd,ip_addr,mac_addr,host);
free(line);
}

/*这是设置服务器的一个窗口*/
void
on_window2_show                        (GtkWidget       *widget,
                                        gpointer         user_data)
{     gtk_entry_set_text ((GtkEntry *)entry3,(char *)ip_addr);

    gtk_entry_set_text ((GtkEntry *)entry4,(char *)host);   

    gtk_combo_box_append_text (GTK_COMBO_BOX (comboboxentry1),(char *)mac_addr);
    gtk_combo_box_set_active(GTK_COMBO_BOX (comboboxentry1),0);
   
}

/*这个是哪个button?...是设置属性的那个按钮*/
void
on_button3_clicked                     (GtkButton       *button,
                                        gpointer         user_data)
{     GtkWidget *mac_set;
    mac_set = create_window2 ();
     gtk_widget_show (mac_set);
    return;
}

/*
*这个是什么东东? 记好了,这个在后面要用的,用来数数的计时的。
*/
gint
flash_timeout(gpointer data)
{if(Acc_Keep_Link==-1){
    gtk_widget_hide_all (linkwindow);
    gtk_widget_show_all (window1);
    getAtrBox = create_messagebox("提示","与网络连接中断!",1);
     gtk_widget_show_all (getAtrBox);
    return FALSE;
    }
    create_tray(tray);
    return TRUE;
}

/*关键的一个来了!!这就是主界面中的连接按钮!主逻辑从它开始*/
void
on_button1_clicked                     (GtkButton       *button,
                                        gpointer         user_data)
{   
/*这个的意思是,如果连接的时候选择了记住密码,那么就要把用户名密码写进config文件去,不然的话就写个用户名得了*/
if(gtk_toggle_button_get_active((GtkToggleButton *)checkbutton1))
write_config((gchar *)gtk_entry_get_text ((GtkEntry *)entry1),
            (gchar *)gtk_entry_get_text ((GtkEntry *)entry2));
else
write_config((gchar *)gtk_entry_get_text ((GtkEntry *)entry1),
            "");   
gtk_widget_hide_all (window1);//所有窗口隐藏掉。。。
linkwindow = create_window3 ();//window3就是“请稍候”的那个窗口,大家都隐藏的时候它就要出来了
gtk_widget_show_all (linkwindow);
gint ptimer_flash=0;
gtk_timeout_remove(ptimer_flash);
ptimer_flash=gtk_timeout_add(15000,flash_timeout,NULL);    //这是一个计时器,每1.5秒执行一次flash_timeout
   
pthread_t getaccess;
Acc_Keep_Link=0;
memcpy(username,(char *)gtk_entry_get_text ((GtkEntry *)entry1),strlen((char *)gtk_entry_get_text ((GtkEntry *)entry1)));
memcpy(passwd,(char *)gtk_entry_get_text ((GtkEntry *)entry2),strlen((char *)gtk_entry_get_text ((GtkEntry *)entry2)));
pthread_create(&getaccess,NULL,Access_Thread,NULL);//这会创建一个叫getaccess的线程
}

/*垃圾按钮~~就是获取服务的那个按钮*/
void
on_button4_clicked                     (GtkButton       *button,
                                        gpointer         user_data)
{ memcpy(host,(char *)gtk_entry_get_text ((GtkEntry *)entry4),strlen((gchar *)gtk_entry_get_text ((GtkEntry *)entry4)));
write_config((gchar *)gtk_entry_get_text ((GtkEntry *)entry1),
            "");

    get_socket((char *)gtk_entry_get_text ((GtkEntry *)entry4));
    getAtrBox = create_messagebox("提示","恭喜,获取服务成功!",1);
     gtk_widget_show (getAtrBox);
    return;//sorry i can not understand what is this
}

/*
* 当断开网络时会用
*/
void
before_quit                      (GtkWidget       *widget,
                                        gpointer         user_data)
{ /*
char cfgfile[1024]="";
sprintf(cfgfile,"%s/.mynet/run.pid",getenv("HOME"));
unlink(cfgfile);//delete mutex file*/
   
if(gtk_toggle_button_get_active((GtkToggleButton *)checkbutton1))
write_config((gchar *)gtk_entry_get_text ((GtkEntry *)entry1),
            (gchar *)gtk_entry_get_text ((GtkEntry *)entry2));//remember the passwd
close(sockfd);
gtk_main_quit();
}

/*先说过的,用来写文件记录用户的基本信息的*/
void write_new_config()
{ int log;
char filename[1024];
char log_string[1024];
char filepath[1024];
char *dir;
strcpy(log_string,"");
strcat(log_string,"\n");memcpy(username,"0",strlen((char *)username));
strcat(log_string,"\n");memcpy(passwd,"0",strlen((char *)passwd));
get_ip();   
strcat(log_string,(char *)ip_addr);strcat(log_string,"\n");
strcat(log_string,SERVER);strcat(log_string,"\n");
get_mac();tr_mac();
strcat(log_string,(char *)mac_addr);strcat(log_string,"\n");
dir=getenv("HOME");
sprintf(filepath,"%s/.mynet/",dir);
mkdir(filepath,O_RDWR|O_CREAT|O_TRUNC);
chmod(filepath,0777);
sprintf(filename,"%sconfig",filepath);
log=open(filename,O_RDWR|O_CREAT|O_TRUNC,0777);
chmod(filename,0777);
write(log,log_string,strlen(log_string));
close(log);   
}

/*下面这个东东把line也就是存成文件了的用户名密码(原来是回车分隔的),这些东东一行一行地取出来*/
gchar * scape(gchar *line)
{ int i;
int j;
for(i=0;i<254;i++)line2[i]=NULL;//这个主要目的是全部干成空的
for(i=0;i<254;i++){if((line[i]=='\n')||(line[i]=='\r'))break;}//一旦遇到回车直接就over掉
for(j=0;j<i;j++){line2[j]=line[j];/*g_message("%c",line[j]);*/}//复制到line2中
return line2;
}

/*和write_new_config相比少个new,在用户名密码更改的时候才用的*/
void write_config( gchar* usr, gchar* pwd)
{ int log;
char filename[1024];
char log_string[1024];
char filepath[1024];

strcpy(log_string,"");
strcat(log_string,usr);strcat(log_string,"\n");
strcat(log_string,pwd);strcat(log_string,"\n");
strcat(log_string,(char *)ip_addr);strcat(log_string,"\n");
strcat(log_string,(char *)host);strcat(log_string,"\n");
strcat(log_string,(char *)mac_addr);strcat(log_string,"\n");

sprintf(filepath,"%s/.mynet/",getenv("HOME"));
mkdir(filepath,O_RDWR|O_CREAT|O_TRUNC);
chmod(filepath,0777);
sprintf(filename,"%sconfig",filepath);
log=open(filename,O_RDWR|O_CREAT|O_TRUNC,0777);
chmod(filename,0777);
write(log,log_string,strlen(log_string));
close(log);   
}

void
delete_event                     (GtkButton       *button,
                                        gpointer         user_data)
{ before_quit((GtkWidget *)button,(gpointer)user_data);
}

char *
get_mac()
{         int nSocket;
        struct ifreq struReq;
        nSocket = socket(PF_INET,SOCK_STREAM,0);
        memset(&struReq,0,sizeof(struReq));
        strncpy(struReq.ifr_name, "eth0", sizeof(struReq.ifr_name));  
        ioctl(nSocket,SIOCGIFHWADDR,&struReq);
        close(nSocket);
        //strcpy(mac_addr,(BYTE)ether_ntoa(struReq.ifr_hwaddr.sa_data));
        memcpy(mac_addr,(char *)ether_ntoa(struReq.ifr_hwaddr.sa_data),strlen((char *)ether_ntoa(struReq.ifr_hwaddr.sa_data)));
        //g_message("\n get_mac: %s\n",(char *)ether_ntoa(struReq.ifr_hwaddr.sa_data)+1);
        //g_message("\n mem_mac : %s lenth:%d\n",mac_addr,strlen((char *)mac_addr));
        return 0;
}

char *
get_ip()
{            int sock;
           struct sockaddr_in sin;
           struct ifreq ifr;  
           sock = socket(AF_INET, SOCK_DGRAM, 0);
           if (sock == -1)
           {
                       perror("socket");
                       return "";                         
           }
            
           strncpy(ifr.ifr_name, "eth0", sizeof(ifr.ifr_name));      
   
           if (ioctl(sock, SIOCGIFADDR, &ifr) < 0)
           {
                       perror("ioctl");
                       return "";
           }

           memcpy(&sin, &ifr.ifr_addr, sizeof(sin));  
           close(sock);
           memcpy(ip_addr,inet_ntoa(sin.sin_addr),strlen(inet_ntoa(sin.sin_addr)));
           //g_message("\n get_ip:eth0: %s\n",inet_ntoa(sin.sin_addr));
           //g_message("\n mem_ip: %s",ip_addr);
           return "";
}

int
get_socket()
{ char *ser;
    ser=(gchar *)gtk_entry_get_text ((GtkEntry *)entry4);
    //digtalser
           sockfd=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
           if (sockfd == -1)
           {
                       perror("socket");
                       return 0;                         
           }
           client.sin_family=AF_INET;
           client.sin_port=htons(3848);
           //client.sin_addr=inet_addr(host);   
           inet_pton(AF_INET, ser, &client.sin_addr);           
           //g_message("udp socket ok!%d",sockfd);
           return 1;
} int
chToHex(int x)//字符转成十六进制用
{ if(x>=97&&x<=102)x=x-87;
else x=x-48;
return x;
} int
tr_mac()
{ int p,i;

p=0;
for(i=0;i<6;i++)
    {
    if (mac_addr[p+1]==':'){mac_Hex[i]=chToHex((int)mac_addr[p]);p+=2;}
      else{mac_Hex[i]=16*(chToHex((int)mac_addr[p]))+chToHex((char)mac_addr[p+1]);p+=3;}   
    }
//g_message("%s",mac_addr);
//for(i=0;i<6;i++)
//g_message("%d---%c-%c-%c-%c",mac_Hex[i],mac_addr[i],mac_addr[i+1],mac_addr[i+2],mac_addr[i+3]);
return 0;
}

int
CreateMutex()//a file like mutex
{ int log;
char filename[1024];
char log_string[1024];
char filepath[1024];
char *dir;
strcpy(log_string,"MyNet");
dir=getenv("HOME");
sprintf(filepath,"%s/.mynet/",dir);
mkdir(filepath,O_RDWR|O_CREAT|O_TRUNC);
chmod(filepath,0777);
sprintf(filename,"%srun.pid",filepath);
log=open(filename,O_RDWR|O_CREAT|O_TRUNC,0777);
chmod(filename,0777);
write(log,log_string,strlen(log_string));
close(log);   
return 1;   
}

void
delete_getAtrBox()
{ gtk_widget_hide (getAtrBox);
}

/***
* Author: cc0cc
* E-mail: cc0cc@126.com
* WebSite: http://www.54chen.com * Date: the Mid-Autumn Festival of 2008
* FileName: callbacks.c
***/
Part4将讲述getaccess线程内的故事,该线程完整再现UDP拔号的情境,待续。。。

[中秋零献] 神州数码802.1x局域网UDP拔号软件MyNet-Gnome源代码大分析(Part2)

/***
* Author: cc0cc
* E-mail: cc0cc@126.com
* WebSite: http://www.54chen.com * Date: the Mid-Autumn Festival of 2008
* FileName: main.c
***/
/*
* Initial main.c file generated by Glade. Edit as required.
* Glade will not overwrite this file.
*/

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdio.h>
#include <gtk/gtk.h>
#include <pthread.h>

#include <gnome.h>
/*如果没记错的话eggtrayicon.h/tray.h都是在Linux用来做系统托盘的头文件,参见
*http://hi.baidu.com/cc0cc/blog/item/26da147a4a428ce92f73b3da.html
*/
#include "eggtrayicon.h"
#include "tray.h"
#include "interface.h"
#include "support.h"
#include "connect.h"

/*系统托盘*/
static void activate_action (GtkAction * action);
static void net_quit (GtkAction * action);
static const gchar *ui_info =
    "<ui>"
    " <popup name='PopupMenu'>"
    "    <menuitem action='About'/>"
    "    <separator/>"
    "    <menuitem action='Quit'/>"
    " </popup>"
    "</ui>";
static GtkActionEntry entries[] = {
    {"Quit", GTK_STOCK_QUIT,    /* name, stock id */
    N_("_断开"), "<control>Q",    /* label, accelerator */
    N_("Quit"),        /* tooltip */
    G_CALLBACK (net_quit)},
    {"About", GTK_STOCK_ABOUT,    /* name, stock id */
    N_( "_关于"), "<control>A",    /* label, accelerator 关于断开*/
    N_("About"),        /* tooltip */
    G_CALLBACK (activate_action)},
};static guint n_entries = G_N_ELEMENTS (entries);
/*系统托盘END*/

/*GTK程序入口*/
int
main (int argc, char *argv[])
{

    GtkUIManager *ui;
    GError *error = NULL;
    GtkActionGroup *actions;
#ifdef ENABLE_NLS
bindtextdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
textdomain (GETTEXT_PACKAGE);
#endif
gnome_program_init (PACKAGE, VERSION, LIBGNOMEUI_MODULE,
                      argc, argv,
                      GNOME_PARAM_APP_DATADIR, PACKAGE_DATA_DIR,
                      NULL);
window1 = create_window1 ();//这是第一个界面,也就是一出来的时候等待输入密码进行连接的界面
    //g_thread_create(thread1,NULL,NULL,NULL);//wait for the book :)
     //pthread_create(&tid,NULL,thread1,NULL);//it is not so good!
     tray = g_new0 (tray_demo, 1);//这里开始弄系统托盘
    tray->window_main = window1;
    create_tray(tray);
    actions = gtk_action_group_new ("Actions");
    gtk_action_group_set_translation_domain (actions, GETTEXT_PACKAGE);
    gtk_action_group_add_actions (actions, entries, n_entries, NULL);
    ui = gtk_ui_manager_new ();
    gtk_ui_manager_insert_action_group (ui, actions, 0);
    gtk_window_add_accel_group (GTK_WINDOW (window1),
                    gtk_ui_manager_get_accel_group (ui));
    if (!gtk_ui_manager_add_ui_from_string (ui, ui_info, -1, &error))
    {
        g_message ("building menus failed: %s", error->message);
        g_error_free (error);
    }
    tray->ui = ui;
    tray->actions = actions;
    tray->menus = gtk_ui_manager_get_widget (ui, "/PopupMenu");//这段代码可以在gnome的网站上找到。。:)
g_message("ccc");   
gtk_widget_show (window1);
gtk_main ();g_message("here2!");
return 0;
}

//下面两个都是为系统托盘的事件做的
static void
activate_action (GtkAction * action)
{   GtkWidget *about;
    about = create_aboutdialog1 ();
     gtk_widget_show (about);
    return;
} static void
net_quit (GtkAction * action)
{     Acc_Keep_Link=-1;
    gtk_widget_show_all (window1);
    send_access_request();
    //g_message("net_quit!");
}

/***
* Author: cc0cc
* E-mail: cc0cc@126.com
* WebSite: http://www.54chen.com

* Date: the Mid-Autumn Festival of 2008
***/

[中秋零献] 神州数码802.1x局域网UDP拔号软件MyNet-Gnome源代码大分析(Part1)

/***
* Author: cc0cc
* E-mail: cc0cc@126.com
* WebSite: http://www.54chen.com * Date: the Mid-Autumn Festival of 2008
***/
概要:这个软件是三年前的时候在学校里写的,主要目的是给广大的Linuxers一个上网的机会,不过后来在我推出后官方又出了个Linux下的拔号二进制包。

PS:神州数码的局域网拔号软件在各大高校使用很多,有不少小区也是,一般官方发布的会有一定的限制。。。

熟悉802.1x协议的过程,对网络编程的学习也有一定的提高。
代码中的ASM汇编部分代码取自北航的高手xdkui(目前在MS就职),在此一并感谢他的努力hack。
声明:本代码只供学习使用,完全遵循计算机软件保护条例。

1.开发环境:
gtk+/gnome
Anjuta+Glade
2.文件树(截图):

/***
* Author: cc0cc
* E-mail: cc0cc@126.com
* WebSite: http://www.54chen.com
* Date: the Mid-Autumn Festival of 2008
***/

flex实时换肤术-动态切换CSS样式表文件

HTML中有一个非常好的特性就是可以动态切换页面链接的CSS样式表,而FLEX并不具备动态导入CSS的特性,因为FLEX的所有的UI外观都是在后台SERVER生成在发布到前台的(当然,通过AS可以实时更改UI外观setStyle,这是单个更改的方式,并不是实时的CSS文件切换),一直觉得挺不爽的,今天在mannu看到一个使用_global.styles来实现动态切换CSS文件的非常巧妙的方式:

首先,因为FLEX是将CSS编译进SWF文件的,所有我们将我们需要切换的CSS编译成SWF文件;

green.css Label{
color:#00FF00;
fontSize:20px;
}

green.mxml <?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.macromedia.com/2003/mxml">

<mx:Style source="green.css"></mx:Style>

</mx:Application>

类似的还有red.css/red.mxml,blue.css/blue.mxml。 然后,我们要切换到相应的CSS就直接LOAD相应的SWF文件; 最后,将_global.styles设置为所导入的SWF文件的_global.styles 。 这里有一个工具封装好的工具类:

RuntimeStyle.as import mx.controls.Loader;
import mx.core.MXMLObject;
import mx.utils.Delegate;

class RuntimeStyle implements MXMLObject
{

private var _document:Object;
private var loader:Loader;

public function initialized(document:Object, id:String):Void
{ _document = document;
}

private var _source:String;

public function get source():String
{ return _source;
}

public function set source(value:String):Void
{ if (_source != value)
{ _source = value;

if (loader == undefined)
{ loader = Loader(_document.createClassObject(Loader,
"runtimeStyleLoader", 21983));
loader.width = loader.height = 0;
loader.addEventListener("complete",
Delegate.create(this, loader_complete));
}

loader.source = _source + ".swf";
} }

private function loader_complete(event:Object):Void
{ _global.styles = Loader(event.target).content._global.styles;
_document.styleName = _document.styleName == "!" ? "@" : "!";
}

}

测试代码:cssChg.mxml<local:RuntimeStyle xmlns:local="*"

source="{stylesWrappers.selectedItem.source}" />

<mx:Model id="alternateStyles"

source="alternateStyles.xml" />

<mx:ComboBox id="stylesWrappers"
dataProvider="{alternateStyles.stylesheets}"
labelField="name" selectedIndex="-1" />

alternateStyles.xml <?xml version="1.0" encoding="UTF-8"?>
<styles>

<stylesheets>
<name>red</name>
<source>red.mxml</source>
</stylesheets>
<stylesheets>
<name>green</name>
<source>green.mxml</source>
</stylesheets>
<stylesheets>
<name>blue</name>
<source>blue.mxml</source>
</stylesheets>

</styles>

PHP“收发”邮件的一个程序

<?php
if ($EMAIL_INC) return;
$EMAIL_INC=   "defined";
define( "SmtpPort",25);

class Pop3 {
var $subject;                           // 邮件主题
var $from_email;                        // 发件人地址
var $from_name;                         // 发件人姓名
var $to_email;                          // 收件人地址
var $to_name;                           // 收件人姓名
var $body;                              // 邮件内容
var $filename;                          // 文件名
var $socket;                  // 当前的 socket
var $Line;
var $Status;

function pop3_open($server, $port)
{

$this->Socket = fsockopen($server, $port);
if ($this->Socket <= 0){
return false;
} $this->Line = fgets($this->Socket, 1024);
$this->Status[ "LASTRESULT"] = substr($this->Line, 0, 1);
$this->Status[ "LASTRESULTTXT"] = substr($this->Line, 0, 1024);

if ($this->Status[ "LASTRESULT"] <>   "+") return false;
return true;
}

function pop3_user($user)
{

if ($this->Socket < 0){
return false;
} fputs($this->Socket,   "USER $this->user\r\n");
$this->Line = fgets($this->Socket, 1024);
$this->Status[ "LASTRESULT"] = substr($this->Line, 0, 1);
$this->Status[ "LASTRESULTTXT"] = substr($this->Line, 0, 1024);

if ($this->Status[ "LASTRESULT"] <>   "+") return false;

return true;
}

function pop3_pass( $pass)
{

fputs($this->Socket,   "PASS $pass\r\n");
$this->Line = fgets($this->Socket, 1024);
$this->Status[ "LASTRESULT"] = substr($this->Line, 0, 1);
$this->Status[ "LASTRESULTTXT"] = substr($this->Line, 0, 1024);

if ($this->Status[ "LASTRESULT"] <>   "+") return 0;

return 1;
}

function pop3_stat()
{

fputs($this->Socket,   "STAT\r\n");
$this->Line = fgets($this->Socket, 1024);
$this->Status[ "LASTRESULT"] = substr($this->Line, 0, 1);
$this->Status[ "LASTRESULTTXT"] = substr($this->Line, 0, 1024);

if ($this->Status[ "LASTRESULT"] <>   "+") return 0;

if (!eregi( "+OK (.*) (.*)", $this->Line, $regs))
return 0;

return $regs[1];
}

function pop3_list()
{ fputs($this->Socket,   "LIST\r\n");
$this->Line = fgets($this->Socket, 1024);
$this->Status[ "LASTRESULT"] = substr($this->Line, 0, 1);
$this->Status[ "LASTRESULTTXT"] = substr($this->Line, 0, 1024);

if ($this->Status[ "LASTRESULT"] <>   "+") return 0;

$i = 0;
while   (substr($this->Line   =   fgets($this->Socket, 1024),   0,   1)   <>    ".")
{ $articles[$i] = $this->Line;
$i++;
} $articles[ "count"] = $i;

return $articles;
}

function pop3_retr($nr)
{

fputs($this->Socket,   "RETR $nr\r\n");
$this->Line = fgets($this->Socket, 1024);
$this->Status[ "LASTRESULT"] = substr($this->Line, 0, 1);
$this->Status[ "LASTRESULTTXT"] = substr($this->Line, 0, 1024);

if ($this->Status[ "LASTRESULT"] <>   "+") return 0;

while   (substr($this->Line   =   fgets($this->Socket, 1024),   0,   1)   <>    ".")
{ $data[$i] = $this->Line;
$i++;
} $data[ "count"] = $i;

return $data;
}

function pop3_dele( $nr)
{

fputs($this->Socket,   "DELE $nr\r\n");
$this->Line = fgets($this->Socket, 1024);
$this->Status[ "LASTRESULT"] = substr($this->Line, 0, 1);
$this->Status[ "LASTRESULTTXT"] = substr($this->Line, 0, 1024);

if ($this->Status[ "LASTRESULT"] <>   "+") return 0;
return 1;
}

function pop3_quit()
{

fputs($this->Socket,   "QUIT\r\n");
$this->Line = fgets($this->Socket, 1024);
$this->Status[ "LASTRESULT"] = substr($this->Line, 0, 1);
$this->Status[ "LASTRESULTTXT"] = substr($this->Line, 0, 1024);

if ($this->Status[ "LASTRESULT"] <>   "+") return 0;

return 1;
} }

class Smtp {

var $Subject;               // string the email@#s subject
var $FromName;                  // string sender@#s name (opt)
var $ToName;                    // string recipient@#s name (opt)
var $Body;                      // string body copy
var $Attachment;          // attachment (optional)
var $AttachmentType;
var $Socket;
var $Line;
var $Status;

function Smtp($Server =   "localhost",$Port = SmtpPort)
{ return $this->Open($Server, $Port);
}

function SmtpMail($FromEmail, $FromName, $ToEmail, $ToName, $Subject, $Body, $Attachment=null, $AttachmentType= "TEXT")
{ $this->Subject    = $Subject;
$this->ToName     = $ToName;

$this->FromName     = $FromName;
$this->Body       = $Body;

$this->Attachment = $Attachment;
$this->AttachmentType = $AttachmentType;

if ($this->Helo() == false){
return false;
} if ($this->MailFrom($FromEmail) == false){
return false;
} if ($this->RcptTo($ToEmail) == false){
return false;
} if ($this->Body() == false){
return false;
} if ($this->Quit() == false){
return false;
} }

function Open($Server, $Port)
{

$this->Socket = fsockopen($Server, $Port);
if ($this->Socket < 0) return false;

$this->Line = fgets($this->Socket, 1024);

$this->Status[ "LASTRESULT"] = substr($this->Line, 0, 1);
$this->Status[ "LASTRESULTTXT"] = substr($this->Line, 0, 1024);

if ($this->Status[ "LASTRESULT"] <>   "2") return false;

return true;
} function Helo()
{ if (fputs($this->Socket,   "helo\r\n") < 0 ){
return false;
} $this->Line = fgets($this->Socket, 1024);

$this->Status[ "LASTRESULT"] = substr($this->Line, 0, 1);
$this->Status[ "LASTRESULTTXT"] = substr($this->Line, 0, 1024);

if ($this->Status[ "LASTRESULT"] <>   "2") return false;

return true;
}

function Ehlo()
{

/* Well, let@#s use "helo" for now.. Until we need the
extra func@#s    [Unk]
*/
if(fputs($this->Socket,   "helo localhost\r\n")<0){
return false;
} $this->Line = fgets($this->Socket, 1024);

$this->Status[ "LASTRESULT"] = substr($this->Line, 0, 1);
$this->Status[ "LASTRESULTTXT"] = substr($this->Line, 0, 1024);

if ($this->Status[ "LASTRESULT"] <>   "2") return false;

return true;
}

function MailFrom($FromEmail)
{

if (fputs($this->Socket,   "MAIL FROM: <$FromEmail>\r\n")<0){
return false;
}

$this->Line = fgets($this->Socket, 1024);

$this->Status[ "LASTRESULT"] = substr($this->Line, 0, 1);
$this->Status[ "LASTRESULTTXT"] = substr($this->Line, 0, 1024);

if ($this->Status[ "LASTRESULT"] <>   "2") return false;

return true;
}

function RcptTo($ToEmail)
{

if(fputs($this->Socket,   "RCPT TO: <$ToEmail>\r\n")<0){
return false;
} $this->Line = fgets($this->Socket, 1024);

$this->Status[ "LASTRESULT"] = substr($this->Line, 0, 1);
$this->Status[ "LASTRESULTTXT"] = substr($this->Line, 0, 1024);

if ($this->Status[ "LASTRESULT"] <>   "2") return false;
return true;
}

function Body()
{ $FileSize = 0;
$Attachment = null;
$fp = null;

$buffer = sprintf( "From: %s\r\nTo:%s\r\nSubject:%s\r\n", $this->FromName, $this->ToName, $this->Subject);

if(fputs($this->Socket,   "DATA\r\n")<0){
return false;
} $this->Line = fgets($this->Socket, 1024);

$this->Status[ "LASTRESULT"] = substr($this->Line, 0, 1);
$this->Status[ "LASTRESULTTXT"] = substr($this->Line, 0, 1024);

if ($this->Status[ "LASTRESULT"] <>   "3") return false;

if(fputs($this->Socket, $buffer)<0){
return false;
}

if ($this->Attachment == null){

if(fputs($this->Socket,   "MIME-Version: 1.0\r\nContent-Type: text/plain; charset=ISO-8859-1\r\nContent-Transfer-Encoding: 7bit\r\n\r\n")<0){
return false;
} if(fputs($this->Socket,   "$this->Body\r\n\r\n")<0){
return false;
}

if(fputs($this->Socket,   ".\r\n")<0){
return false;
}

$this->Line = fgets($this->Socket, 1024);
if (substr($this->Line, 0, 1) <>   "2"){
return false;
}else{
return true;
} }else{
if(fputs($this->Socket, "MIME-Version: 1.0\r\nContent-Type: multipart/mixed; boundary=\"----=_NextPart_000_01BCFA61.A3697360\"\r\n".
"Content-Transfer-Encoding: 7bit\r\n\r\n".
"This is a multi-part message in MIME format.\r\n".
"\r\n------=_NextPart_000_01BCFA61.A3697360\r\n".
"Content-Type: text/plain; charset=ISO-8859-1\r\n".
"Content-Transfer-Encoding: 7bit\r\n".
"\r\n")<0){
return false;
}

/* 输出邮件内容 */
if(fputs($this->Socket,   "$this->Body\r\n\r\n")<0){
return false;
}

if ( fputs($this->Socket, "\r\n------=_NextPart_000_01BCFA61.A3697360\r\n")<0){
return false;
} $FileSize = filesize($this->Attachment);
if ($FileSize == false){
return false;
} if (($fp = fopen($this->Attachment, "r"))== false) {
return false;
}else{
$Attachment = fread($fp,$FileSize);
}

// 如果没有附件的目录
if (($AttachName = strrchr($this->Attachment, @#/@#)) == false){

$AttachName = $this->Attachment;
}

if( fputs($this->Socket,
"Content-Type: application/octet-stream; \r\nname=\"$AttachName\"\r\n".
"Content-Transfer-Encoding: quoted-printable\r\n".
"Content-Description: $AttachName\r\n".
"Content-Disposition: attachment; \r\n\tfilename=\"$AttachName\"\r\n".
"\r\n")<0){
return false;
}

/* 输出附件*/
if( fputs($this->Socket, $Attachment)<0){
return false;
} if ( fputs($this->Socket, "\r\n\r\n------=_NextPart_000_01BCFA61.A3697360--\r\n")<0){
return false;
}

if( fputs($this->Socket, ".\r\n")<0){
return false;
}

$this->Line = fgets($this->Socket, 1024);
if (substr($this->Line, 0, 1) <>   "2")
return false;

return true;

}
}

function Quit()
{

if(fputs($this->Socket,   "QUIT\r\n")<0){
return false;
} $this->Line = fgets($this->Socket, 1024);

$this->Status[ "LASTRESULT"] = substr($this->Line, 0, 1);
$this->Status[ "LASTRESULTTXT"] = substr($this->Line, 0, 1024);

if ($this->Status[ "LASTRESULT"] <>   "2") return 0;

return 1;
} function Close()
{ fclose($this->Socket);
} }
/*

怎样使用这个程序的一个示例

$MailTo = new Smtp();
$MailTo->SmtpMail("Dave@micro-automation.net","Dave Cramer",
"Dave@micro-automation.net","David",
"Test Mail",$MailMessage,"service.tab",0);
$MailTo->Close();
$MailTo=null;

*/
/*
$pop3 = pop3_open("localhost", "110");
if (!$pop3) {
printf("[ERROR] Failed to connect to localhost<BR>\n");
return 0;
}

if (!pop3_user($pop3, "unk")) {
printf("[ERROR] Username failed!<BR>\n");
return 0;
}

if (!pop3_pass($pop3, "secret")) {
printf("[ERROR] PASS failed!<BR>\n");
return 0;
}

$articles = pop3_list($pop3);
if (!$articles) {
printf("[ERROR] LIST failed!<BR>\n");
return 0;
}

for ($i = 1; $i < $articles ["count"] + 1; $i++)
{ printf("i=$i<BR>\n");
$data = pop3_retr($pop3,$i);
if (!$data) {
printf("data goes wrong on @#$i@#<BR>\n");
return 0;
}

for ($j = 0; $j < $data["count"]; $j++)
{ printf("$data[$j]<BR>\n");
} }
*/
?>

全角半角判断

  • 半角范围:u0000 - u00FF, uFF61 - uFF9F, uFFE8 - uFFEE
  • 全角范围:
    • 全角数字(0-9) uFF10 - uFF19
    • 全角大文字(A-Z): uFF21 - uFF3A
    • 全角小文字(a-z): uFF41 - uFF5A
    • 全角平仮名:u3040 - u309F
    • 全角片仮名:u30A0 - u30FF
    • 全角Latin: uFF01 - uFF5E
    • 全角Symbol: uFFE0 - uFFE5
    以下是判断全角半角混合字符串的字节数是否超过指定的字节数。(半角被认为是一个字节)
    1. function isOverBytes(s, maxbytes)
    2. {
    3.     var i = 0;
    4.     var bytes = 0;
    5.     var uFF61 = parseInt("FF61", 16);
    6.     var uFF9F = parseInt("FF9F", 16);
    7.     var uFFE8 = parseInt("FFE8", 16);
    8.     var uFFEE = parseInt("FFEE", 16);
    9.     while (i < s.length)
    10.      {
    11.         var c = parseInt(s.charCodeAt(i));
    12.         if (c < 256) {
    13.              bytes = bytes + 1;
    14.          }
    15.         else {
    16.             if ((uFF61 <= c) && (c <= uFF9F)) {
    17.                  bytes = bytes + 1;
    18.              } else if ((uFFE8 <= c) && (c <= uFFEE)) {
    19.                                 bytes = bytes + 1;
    20.                         }
    21.                        else {
    22.                  bytes = bytes + 2;
    23.              }
    24.          }
    25.         if (bytes > maxbytes) {
    26.             return true;
    27.          }
    28.          i = i + 1;
    29.      }
    30.     return false;
    31. }
  • Flex加载图片的常用的几种方式

    <?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" applicationComplete="InitApp()">     <mx:Script>         <![CDATA[                      //第一种方式 这种方式编译以后1.jpg 会直接编译进swf文件中 所以swf可以存在              [Bindable]              [Embed(source="1.jpg")]              private var imgClass:Class;                          //第2种方式              private var _loader:Loader;                           private function InitApp():void{                                  //第一种方式的代码                  _img.source = imgClass;                                  //第二种方式的代码                  _loader = new Loader();                 //这里需要注意的是 不是_loader.addEventListener   这样是没有效果的                  _loader.contentLoaderInfo.addEventListener(Event.COMPLETE,function(e:Event):void{                      _img.source = e.currentTarget.content;                  });                 //这里说一个技巧   当url 中有中文字体的话 使用encodeURI方法 如果没有 则可以不加                  _loader.load(new URLRequest(encodeURI("1.jpg")));                                                   //第三种方式比较简单                  _img.source = "1.jpg";  //注意这里必须设置img autoLoad属性为true                                  //最后说明 其中第2 第3种方式中swf都不能存在 必须配合1.jpg文件的存在 而第一种方式则不需要              }          ]]>     </mx:Script>     <mx:Image x="51" y="62" width="298" height="245" autoLoad="true" id="_img"/> </mx:Application>

    Wine 运行 Tm Pv4版本

    wget http://dl_dir.qq.com/qqfile/tm/tm2008preview4_sp2_chs.exe

    用wine运行安装程序: wine tm2008preview4_sp2_chs.exe
    安装完成后,并不能运行,缺少一些dll。将tm2008目录下SysDir目录下的各个子目录(Microsoft.VC80.ATL等5个子目录)下的所有dll文件拷贝到tm2008下的Bin目录中。将windows
    xp下的system32目录下的msxml3.dll, msxml3r.dll, riched32.dll,
    riched20.dll文件拷贝到.wine/drive_c/windows/system32/目录中。
    运行winecfg,在library标签页下,添加msxml3、riched32、riched20。
    然后就可以运行tm2008了。

    如果遇到中文乱码,注意做如下配置:
    1 如果用的英文locale,记得改成中文再启动wine。即export LANG=zh_CN.UTF-8
    2 配置中文字体。将windows下的simsun.ttc拷贝到~/.fonts/目录下,然后运行regedit,修改HKEY_LOCAL_MACHINE\Software\Microsoft\Windows
    NT\CurrentVersion\FontSubstitutes\ 下的所有键值,将他们都改成SimSun。

    Ubuntu 7.10 安装wine记录

    cz@cz-desktop:~$ wget -q http://wine.budgetdedicated.com/apt/387EE263.gpg -O- | sudo apt-key add -
    OK
    cz@cz-desktop:~$ sudo wget http://wine.budgetdedicated.com/apt/sources.list.d/gutsy.list -O /etc/apt/sources.list.d/winehq.list

    cz@cz-desktop:~$ sudo apt-get update

    cz@cz-desktop:~$ sudo apt-get install wine

    64位ubuntu wine1.0 安装qq

    环境比较特殊 注意是64的i386就不要看了
    {安装wine:}
    1.添加签名
    wget -q http://wine.budgetdedicated.com/apt/387EE263.gpg -O- | sudo apt-key add -
    2.更新WINE源
    sudo wget http://wine.budgetdedicated.com/apt/sources.list.d/hardy.list -O /etc/apt/sources.list.d/winehq.list
    3.更新软件包
    sudo apt-get update
    4.安装WINE
    sudo apt-get install wine

    {设置wine:}

    Wine快速设置 deb包 for amd64的下载地址是:

    http://ubuntu-tweak.code.com/files/wine-ubuntu_amd64.deb

    顺便再加上之前的for i386的:

    http://ubuntu-tweak.code.com/files/wine-ubuntu.deb {使用QQ} Wine的版本:
    Wine 1.0 (默认中文补丁,有打过补丁的Wine1.0下载,见下面)
    windowssux已经把8.04-32bits的deb包(包括中文补丁)做出来了,在http://ftp.ubuntu.org.cn/home/windowssux/Wine-CN/
    登录的用户名和密码在http://forum.ubuntu.org.cn/viewtopic.php?t=9685

    Wine的注册表 修改过的内容如下,请给这个文件保存成QQ2007.reg
    REGEDIT4
    [HKEY_CURRENT_USER\Software\Wine\AppDefaults\QQ.exe]
    "Version"="vista"
    [HKEY_CURRENT_USER\Software\Wine\AppDefaults\QQ.exe\DllOverrides]
    "riched20"="native"
    "riched32"="native"

    并使用下列命令导入
    #regedit QQ2007.reg

    替换DLL文件 需要的 dll:: mfc42.dll msvcp60.dll 给上面的这二个dll放到~/.wine/drive_c/windows/system32/目录中
    下面下载的那个qq2007beta1kb5_0.0.2007_x86.tgz中也有,也可以从windows的系统中找

    安装方法 下载:http://linuxfire.com.cn/~huahua/zero/qq2007beta1kb5_0.0.2007_x86.tgz 解压后,只使用这个中的那个QQ,原wine之类的配置文件不要了.

    运行 可以建一个下面这样的快捷方式,注意修复你的路径为你自己的.
    env WINEPREFIX="/home/fukai/.wine" wine "Z:\home\fukai\qq2007beta1kb5\QQ\QQ.exe"

    在安装和使用程序时的注意事项 现发现的bug有快捷键不能用,视频有时会死机,传文件之类都非常正常

    ==================
    有空的时候再研究下一键安装 linux qq
    为今天听到的马化腾说linux qq是假消息的消息默哀