关于重写一个拔号器的MXD想法
声明: 个人习惯,此帖不需要某管理员移动到我管辖之外的技术区,请尊重我的意愿。我最终还是想自己写一个拔号器,这样可以把多年综合掌握的知识点汇总起来,从一个用户、打包兼测试员的转向一个准程序员。
这是练习写的代码,大概重写rp-pppoe的gui界面应当从这个思路开始#include
#include
#include
int main(int argc,char *argv[])
{
uid_t uid;
uid=getuid();
int opt;
opt=getopt(argc,argv,"do");
if(opt!=-1)
{
switch(opt){
case 'd':
if(uid==0)
{
system("/usr/sbin/adsl-stop");
}
else
{
system("/usr/sbin/pppoe-wrapper stop haulm");
}
break;
case 'o':
if(uid==0)
{
system("/usr/sbin/adsl-start");
}
else
{
system("/usr/sbin/pppoe-wrapper start haulm");
}
break;
}
}
exit(0);
}界面我可能用Qt4来写,界面可能不会太复杂,一个用户框加密码框,对文件进行读写操作,拔号后直接退出程序,所有的连接状态我打包knetstats来显示,因为knetstats比较专业一些,有专门的人在维护。其它比如无线网络的拔号设置如果能整理出来,也会纳入新的MXD进行设置。大家有什么意见没有?
[ 本帖最后由 haulm 于 2008-10-19 08:13 编辑 ] 我不会c语言,听楼主说的都不懂。不过支持了……
现在的拨号器在kde4.1里就不能用了,希望楼主测试的时候考虑这方面,
还有就是普通用户登录问题,呵呵。也许我说的都是废话了。
再一次强烈支持! 原帖由 marry100 于 2008-10-12 10:45 发表 http://www.linuxfans.org/bbs/images/common/back.gif
我不会c语言,听楼主说的都不懂。不过支持了……
现在的拨号器在kde4.1里就不能用了,希望楼主测试的时候考虑这方面,
还有就是普通用户登录问题,呵呵。也许我说的都是废话了。
再一次强烈支持! ...
就是用Qt4写的,配置界面和配置写入还没实现,不过现在托盘菜单倒是好了,可以直接进行拔号,复杂的功用可能没有能力去实现,需要参照一下knetstart对网络状态的实现(原mxd并不能非常正确的分析网络状态)。 完成了整个界面、配置、拔号、断开、提示功能,代码如下:
尚缺网络状态判断并显示的功能,正在查询方法。#include <QtGui>
#include "hello.h"
myclass::myclass()
{
uid=getuid();
FILE *in=NULL;
char sl;
in=fopen("/etc/ppp/pap-secrets","r");
if(in==NULL){printf("can't open the /etc/ppp/pap-secrets");}
while(fgets(sl,128,in))
{
if(strstr(sl,"mxd_connect"))
{
break;
}
}
char *a,*b;
a=strtok(sl,"\t*");
if(a!=NULL)
{a=strtok(NULL,"\t*");}
if(a!=NULL)
{b=strtok(NULL,"\t*");}
fclose(in);
QTextCodec::setCodecForTr(QTextCodec::codecForName("GB2312"));
setMinimumSize(200,100);
setMaximumSize(200,100);
this->move(400,200);
QString aText,bText;
lee1=new QLineEdit(this);
lee1->setContextMenuPolicy(Qt::NoContextMenu);
lee1->setAlignment(Qt::AlignLeft|Qt::AlignVCenter);
lee1->setGeometry(10,10,180,20);
aText=a;
lee1->setText(aText);
lee2=new QLineEdit(this);
lee2->setContextMenuPolicy(Qt::NoContextMenu);
lee2->setAlignment(Qt::AlignLeft|Qt::AlignVCenter);
lee2->setGeometry(10,40,180,20);
bText=b;
lee2->setText(bText);
lee2->setEchoMode(QLineEdit::Password);
b1=new QPushButton(tr("拔号"),this);
b1->setGeometry(90,70,40,25);
savebutton=new QPushButton(tr("保存"),this);
savebutton->setGeometry(140,70,40,25);
QIcon icon = QIcon("./images/status_error.png");
setWindowIcon(icon);
trayIcon = new QSystemTrayIcon(this);
trayIcon->setIcon(icon);
trayIcon->setToolTip(tr("Magic Linux 拔号器"));
createActions();
createTrayIcon();
trayIcon->show();
setWindowTitle(tr("Magic Linux 拔号器"));
connect(trayIcon,SIGNAL(activated(QSystemTrayIcon::ActivationReason)),this,SLOT(iconActivated(QSystemTrayIcon::ActivationReason)));
connect(b1,SIGNAL(clicked()),this,SLOT(showM()));
connect(b1, SIGNAL(clicked()), this, SLOT(pppoeStart()));
connect(savebutton, SIGNAL(clicked()), this, SLOT(saveconf()));
}
void myclass::showM()
{
QString titlec=tr("请稍候");
QString textc=QString::fromLocal8Bit("正在尝试PPPOE拔号");
trayIcon->showMessage(titlec,textc,QSystemTrayIcon::Information,5000);
this->hide();
}
void myclass::saveconf()
{
QString titlec,textc;
if(uid==0)
{
titlec=tr("请稍候");
textc=QString::fromLocal8Bit("保存新的账号密码");
//配置1
FILE *out=NULL;
out=fopen("/etc/ppp/mxd-secrets","w+");
if(out==NULL){printf("can't create the /etc/ppp/mxd-secrets");}
char *a,*b;
QString aText,bText;
aText=lee1->text();
a=aText.toLocal8Bit().data();
bText=lee2->text();
b=bText.toLocal8Bit().data();
char c="mxd_connect\t*\t";
strcat(c,a);
strcat(c,"\t*\t");
strcat(c,b);
strcat(c,"\t*\n");
fputs(c,out);
strcpy(c,a);
strcat(c,"\t*\t");
strcat(c,b);
strcat(c,"\t*\n");
fputs(c,out);
fclose(out);
unlink("/etc/ppp/pap-secrets");
rename("/etc/ppp/mxd-secrets","/etc/ppp/pap-secrets");
//配置2
out=fopen("/etc/ppp/rp-pppoe-gui/conf.mxd_connect","w+");
if(out==NULL){printf("can't create the conf.mxd_connect");}
strcpy(c,"USER=");
strcat(c,a);
fputs(c,out);
fputs("\nETH=eth0",out);
fputs("\nDNSTYPE=SERVER",out);
fputs("\nPEERDNS=yes",out);
fputs("\nDNS1=",out);
fputs("\nDNS2=",out);
fputs("\nNONROOT=OK",out);
fputs("\nSYNCHRONOUS=yes",out);
fputs("\nFIREWALL=STANDALONE",out);
fputs("\nSERVICENAME=",out);
fputs("\nACNAME=",out);
fputs("\nCONNECT_TIMEOUT=30",out);
fputs("\nCONNECT_POLL=1",out);
fputs("\nFORCEPING=\".\"",out);
fputs("\nPIDFILE=/var/run/pppoe-mxd.pid",out);
fputs("\nCLAMPMSS=1412",out);
fputs("\nLCP_INTERVAL=20",out);
fputs("\nLCP_FAILURE=3",out);
fputs("\nPPPOE_TIMEOUT=80",out);
fputs("\nLINUX_PLUGIN=",out);
fputs("\nDEMAND=no",out);
fputs("\nDEFAULTROUTE=yes\n",out);
fclose(out);
//配置3
out=fopen("/etc/ppp/rp-pppoe-gui/passwd","w+");
if(out==NULL){printf("can't create the conf.mxd_connect");}
strcpy(c,"\{ConnectionName mxd_connect Password ");
strcat(c,b);
strcat(c,"}\n");
fputs(c,out);
fclose(out);
}else
{titlec=tr("非法操作");
textc=QString::fromLocal8Bit("请用root账号进行保存");
}
trayIcon->showMessage(titlec,textc,QSystemTrayIcon::Information,5000);
}
void myclass::iconActivated(QSystemTrayIcon::ActivationReason reason)
{
switch (reason) {
case QSystemTrayIcon::DoubleClick:
this->showNormal();
break;
default:
;
}
}
void myclass::createActions()
{
minimizeAction = new QAction(tr("隐藏 (&I)"), this);
connect(minimizeAction, SIGNAL(triggered()), this, SLOT(hide()));
conn1 = new QAction(tr("拔号 (&X)"), this);
connect(conn1, SIGNAL(triggered()), this, SLOT(pppoeStart()));
conn2 = new QAction(tr("断开 (&R)"), this);
connect(conn2, SIGNAL(triggered()), this, SLOT(pppoeStop()));
quitAction = new QAction(tr("退出 (&Q)"), this);
connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
}
void myclass::createTrayIcon()
{
trayIconMenu = new QMenu(this);
trayIconMenu->addAction(minimizeAction);
trayIconMenu->addAction(conn1);
trayIconMenu->addAction(conn2);
trayIconMenu->addSeparator();
trayIconMenu->addAction(quitAction);
trayIcon->setContextMenu(trayIconMenu);
}
void myclass::pppoeStart()
{
if(uid==0)
{
system("/usr/sbin/adsl-start");
}
else
{
system("/usr/sbin/pppoe-wrapper start mxd_connect");
}
QIcon icon2 = QIcon("./images/status_both.png");
trayIcon->setIcon(icon2);
this->hide();
}
void myclass::pppoeStop()
{
if(uid==0)
{
system("/usr/sbin/adsl-stop");
}
else
{
system("/usr/sbin/pppoe-wrapper stop haulm");
}
QIcon icon1 = QIcon("./images/status_error.png");
trayIcon->setIcon(icon1);
}
int main(int argc,char **argv)
{
QApplication testc(argc,argv);
myclass newc;
newc.show();
return testc.exec();
}
QT 那里用designer 就可以啊,很简单的。
写成KDE 程序或者applet也应该不成问题的。
我还会有后续意见的。 system 那里最好独立成一个线程,
或者专门写一个类来实现系统调用
那样不会因为子进程没有响应而把主进程弄僵
网络状态分析参考一下 kde applet 那个就可以 原帖由 stdio 于 2008-10-18 09:15 发表 http://www.linuxfans.org/bbs/images/common/back.gif
system 那里最好独立成一个线程,
或者专门写一个类来实现系统调用
那样不会因为子进程没有响应而把主进程弄僵
网络状态分析参考一下 kde applet 那个就可以 ...
在书上也是不建议使用system的,我在程序有进展后才会考虑使用其它方法的调用。 昨天研究了半天的libpcap的应用,该库用于监听网络的,但很奇怪的是pcap_lookupnet函数经常返回空,昨晚偶而返回了网卡定义的IP和MASK值纯属于人品,今早又不行了只好注释掉。
pcap_next函数似乎不会马上返回,运行后如果没有接收到数据包就不会退出,这样对我来说还是有点麻烦,因为我不可能直接按pcap_next返回的值来判断是否在线,如果断开了,很可能陷入了长时间的等待。
这几天大量地搜索网络这方面的资料,有努力还是有收获,不过还是希望有能力的朋友指导和一起进步。
#include <pcap.h>
#include <stdio.h>
int main()
{
pcap_t *handle; /* Session handle */
char *dev; /* The device to sniff on */
char errbuf; /* Error string */
struct bpf_program filter; /* The compiled filter */
char filter_app[] = ""; /* The filter expression */
bpf_u_int32 mask; /* Our netmask */
bpf_u_int32 net; /* Our IP */
struct pcap_pkthdr header; /* The header that pcap gives us */
const u_char *packet; /* The actual packet */
/* Define the device */
if(!(dev = pcap_lookupdev(errbuf)))
{
perror(errbuf);
exit(-1);
}
/* Find the properties for the device */
// pcap_lookupnet(dev, &net, &mask, errbuf);
/* Open the session in promiscuous mode */
handle = pcap_open_live(dev, BUFSIZ, 1, 0, errbuf);
if (handle == NULL)
{perror(errbuf);
exit(-1);}
/* Compile and apply the filter */
if(pcap_compile(handle, &filter, filter_app, 0, net)==-1)
{fprintf(stderr, "pcap_compile: %s\n", pcap_geterr(handle));
exit(1);}
if(pcap_setfilter(handle, &filter)==-1)
{fprintf(stderr, "pcap_compile: %s\n", pcap_geterr(handle));
exit(1);}
/* Grab a packet */
packet = pcap_next(handle, &header);
/* Print its length */
printf("Jacked a packet with length of [%d]\n",header.len);
/* And close the session */
struct pcap_stat {
u_int ps_recv; /* number of packets received */
u_int ps_drop; /* number of packets dropped */
u_int ps_ifdrop; /* drops by interface XXX not yet supported */
};
struct pcap_stat ps;
pcap_stats (handle,&ps);
printf("%d\n",ps.ps_recv);
pcap_close(handle);
return(0);
}
原帖由 stdio 于 2008-10-18 08:28 发表 http://www.linuxfans.org/bbs/images/common/back.gif
QT 那里用designer 就可以啊,很简单的。
写成KDE 程序或者applet也应该不成问题的。
我还会有后续意见的。
主要是我根本看不懂或很难看懂写的是什么,不少开源软件没有明显的注释,很难拿来主义或是下手修改。
另外这几天的C编程学习,总的感受是库函数也不是说没有毛病的,一些奇奇怪怪的事也会发生的。编译过程中出现最多的是段错误,以前打包编译程序时遇到过段错误,现在明白了该种错误是非常低级的错误,往往就是将函数返回值未经判断将NULL或-1值或完全不匹配的值应用到新的函数中去了。 楼上。尝试 shell 编程吧…… 原帖由 jiangtao9999 于 2008-10-19 08:31 发表 http://www.linuxfans.org/bbs/images/common/back.gif
楼上。尝试 shell 编程吧……
兄台不会是想让我改用wxPython来写吧,晕倒。 和kanker再次交流后放弃了用libpacp进行网络分析的想法,因为libpacp在抓包过程如果没有抓到包很可能就处于等待状态,直到你设置的超时时间过了才会返回,如果再加上线程,这个程序变得非常复杂。
/sys/class/net 目录下有着内核存放的网络状态分析文件,这里面提供非常详细的分析,所以重新去抓包分析网络就很可笑了,我现在只需要直接从这个目录中的各个文件中得到数据。 原帖由 haulm 于 2008-10-19 08:59 AM 发表 http://www.linuxfans.org/bbs/images/common/back.gif
兄台不会是想让我改用wxPython来写吧,晕倒。
别晕,听说 php 也能 GTK 了…… 兄台孤陋寡闻了,PHP-GTK很早就有了,直到现在它的应用还是少的可怜。 原帖由 haulm 于 2008-10-20 23:41 发表 http://www.linuxfans.org/bbs/images/common/back.gif
兄台孤陋寡闻了,PHP-GTK很早就有了,直到现在它的应用还是少的可怜。
pyqt
pygtk
wxpython
這些都可以
至少比你用c+qt來的快我覺得
页:
[1]
2