[中秋零献] 神州数码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拔号的情境,待续。。。
原创文章如转载,请注明:转载自五四陈科学院[http://www.54chen.com]
Posted by 54chen linux
« [中秋零献] 神州数码802.1x局域网UDP拔号软件MyNet-Gnome源代码大分析(Part2) [中秋零献续集] 神州数码802.1x局域网UDP拔号软件MyNet-Gnome源代码大分析(Part4)getaccess线程内的故事 »