找回密码
 注册
查看: 2358|回复: 16

关于重写一个拔号器的MXD想法

[复制链接]
发表于 2008-10-11 10:22:32 | 显示全部楼层 |阅读模式
声明: 个人习惯,此帖不需要某管理员移动到我管辖之外的技术区,请尊重我的意愿。

我最终还是想自己写一个拔号器,这样可以把多年综合掌握的知识点汇总起来,从一个用户、打包兼测试员的转向一个准程序员。
这是练习写的代码,大概重写rp-pppoe的gui界面应当从这个思路开始
  1. #include
  2. #include
  3. #include
  4. int main(int argc,char *argv[])
  5. {
  6. uid_t uid;
  7. uid=getuid();
  8. int opt;
  9. opt=getopt(argc,argv,"do");
  10. if(opt!=-1)
  11. {
  12. switch(opt){
  13.         case 'd':
  14.                 if(uid==0)
  15.                 {
  16.                         system("/usr/sbin/adsl-stop");
  17.                         }
  18.                 else
  19.                 {       
  20.                         system("/usr/sbin/pppoe-wrapper stop haulm");
  21.                         }
  22.                 break;
  23.         case 'o':
  24.                 if(uid==0)
  25.                 {
  26.                         system("/usr/sbin/adsl-start");
  27.                         }
  28.                 else
  29.                 {       
  30.                         system("/usr/sbin/pppoe-wrapper start haulm");
  31.                         }
  32.                 break;
  33.         }
  34. }
  35.         exit(0);
  36. }
复制代码
界面我可能用Qt4来写,界面可能不会太复杂,一个用户框加密码框,对文件进行读写操作,拔号后直接退出程序,所有的连接状态我打包knetstats来显示,因为knetstats比较专业一些,有专门的人在维护。其它比如无线网络的拔号设置如果能整理出来,也会纳入新的MXD进行设置。大家有什么意见没有?

[ 本帖最后由 haulm 于 2008-10-19 08:13 编辑 ]
发表于 2008-10-12 10:45:10 | 显示全部楼层
我不会c语言,听楼主说的都不懂。不过支持了……
现在的拨号器在kde4.1里就不能用了,希望楼主测试的时候考虑这方面,
还有就是普通用户登录问题,呵呵。也许我说的都是废话了。
再一次强烈支持!
回复

使用道具 举报

 楼主| 发表于 2008-10-12 11:20:01 | 显示全部楼层
原帖由 marry100 于 2008-10-12 10:45 发表
我不会c语言,听楼主说的都不懂。不过支持了……
现在的拨号器在kde4.1里就不能用了,希望楼主测试的时候考虑这方面,
还有就是普通用户登录问题,呵呵。也许我说的都是废话了。
再一次强烈支持! ...

就是用Qt4写的,配置界面和配置写入还没实现,不过现在托盘菜单倒是好了,可以直接进行拔号,复杂的功用可能没有能力去实现,需要参照一下knetstart对网络状态的实现(原mxd并不能非常正确的分析网络状态)。
回复

使用道具 举报

 楼主| 发表于 2008-10-15 08:16:19 | 显示全部楼层
完成了整个界面、配置、拔号、断开、提示功能,代码如下:
尚缺网络状态判断并显示的功能,正在查询方法。
  1. #include <QtGui>
  2. #include "hello.h"
  3. myclass::myclass()
  4. {      
  5.         uid=getuid();
  6.         FILE *in=NULL;
  7.         char sl[128];
  8.         in=fopen("/etc/ppp/pap-secrets","r");
  9.         if(in==NULL){printf("can't open the /etc/ppp/pap-secrets");}       
  10.         while(fgets(sl,128,in))
  11.         {
  12.                 if(strstr(sl,"mxd_connect"))
  13.                 {
  14.                 break;               
  15.                         }
  16.                                 }
  17.         char *a,*b;
  18.         a=strtok(sl,"\t*");
  19.         if(a!=NULL)
  20.                 {a=strtok(NULL,"\t*");}
  21.         if(a!=NULL)
  22.                 {b=strtok(NULL,"\t*");}
  23.         fclose(in);
  24.         QTextCodec::setCodecForTr(QTextCodec::codecForName("GB2312"));
  25.         setMinimumSize(200,100);
  26.         setMaximumSize(200,100);
  27.         this->move(400,200);
  28.         QString aText,bText;
  29.         lee1=new QLineEdit(this);
  30.         lee1->setContextMenuPolicy(Qt::NoContextMenu);
  31.         lee1->setAlignment(Qt::AlignLeft|Qt::AlignVCenter);
  32.         lee1->setGeometry(10,10,180,20);
  33.         aText=a;
  34.         lee1->setText(aText);
  35.         lee2=new QLineEdit(this);
  36.         lee2->setContextMenuPolicy(Qt::NoContextMenu);
  37.         lee2->setAlignment(Qt::AlignLeft|Qt::AlignVCenter);
  38.         lee2->setGeometry(10,40,180,20);
  39.         bText=b;
  40.         lee2->setText(bText);
  41.         lee2->setEchoMode(QLineEdit::Password);
  42.         b1=new QPushButton(tr("拔号"),this);
  43.         b1->setGeometry(90,70,40,25);
  44.         savebutton=new QPushButton(tr("保存"),this);
  45.         savebutton->setGeometry(140,70,40,25);
  46.         QIcon icon = QIcon("./images/status_error.png");
  47.         setWindowIcon(icon);
  48.         trayIcon = new QSystemTrayIcon(this);
  49.         trayIcon->setIcon(icon);
  50.         trayIcon->setToolTip(tr("Magic Linux 拔号器"));
  51.         createActions();
  52.         createTrayIcon();
  53.         trayIcon->show();
  54.         setWindowTitle(tr("Magic Linux 拔号器"));
  55.         connect(trayIcon,SIGNAL(activated(QSystemTrayIcon::ActivationReason)),this,SLOT(iconActivated(QSystemTrayIcon::ActivationReason)));
  56. connect(b1,SIGNAL(clicked()),this,SLOT(showM()));
  57. connect(b1, SIGNAL(clicked()), this, SLOT(pppoeStart()));
  58. connect(savebutton, SIGNAL(clicked()), this, SLOT(saveconf()));
  59. }

  60. void myclass::showM()
  61. {
  62.         QString titlec=tr("请稍候");
  63.         QString textc=QString::fromLocal8Bit("正在尝试PPPOE拔号");
  64.         trayIcon->showMessage(titlec,textc,QSystemTrayIcon::Information,5000);
  65.         this->hide();
  66.       }
  67.                
  68. void myclass::saveconf()
  69. {
  70. QString titlec,textc;
  71. if(uid==0)
  72. {
  73.         titlec=tr("请稍候");
  74.         textc=QString::fromLocal8Bit("保存新的账号密码");
  75. //配置1
  76.         FILE *out=NULL;
  77.         out=fopen("/etc/ppp/mxd-secrets","w+");
  78.         if(out==NULL){printf("can't create the /etc/ppp/mxd-secrets");}
  79.         char *a,*b;
  80.         QString aText,bText;
  81.         aText=lee1->text();
  82.         a=aText.toLocal8Bit().data();
  83.         bText=lee2->text();
  84.         b=bText.toLocal8Bit().data();
  85.         char c[40]="mxd_connect\t*\t";
  86.         strcat(c,a);
  87.         strcat(c,"\t*\t");
  88.         strcat(c,b);
  89.         strcat(c,"\t*\n");
  90.         fputs(c,out);
  91.         strcpy(c,a);
  92.         strcat(c,"\t*\t");
  93.         strcat(c,b);
  94.         strcat(c,"\t*\n");
  95.         fputs(c,out);
  96.         fclose(out);
  97.         unlink("/etc/ppp/pap-secrets");
  98.         rename("/etc/ppp/mxd-secrets","/etc/ppp/pap-secrets");
  99. //配置2
  100. out=fopen("/etc/ppp/rp-pppoe-gui/conf.mxd_connect","w+");
  101. if(out==NULL){printf("can't create the conf.mxd_connect");}
  102. strcpy(c,"USER=");
  103. strcat(c,a);
  104. fputs(c,out);
  105. fputs("\nETH=eth0",out);
  106. fputs("\nDNSTYPE=SERVER",out);
  107. fputs("\nPEERDNS=yes",out);
  108. fputs("\nDNS1=",out);
  109. fputs("\nDNS2=",out);
  110. fputs("\nNONROOT=OK",out);
  111. fputs("\nSYNCHRONOUS=yes",out);
  112. fputs("\nFIREWALL=STANDALONE",out);
  113. fputs("\nSERVICENAME=",out);
  114. fputs("\nACNAME=",out);
  115. fputs("\nCONNECT_TIMEOUT=30",out);
  116. fputs("\nCONNECT_POLL=1",out);
  117. fputs("\nFORCEPING="."",out);
  118. fputs("\nPIDFILE=/var/run/pppoe-mxd.pid",out);
  119. fputs("\nCLAMPMSS=1412",out);
  120. fputs("\nLCP_INTERVAL=20",out);
  121. fputs("\nLCP_FAILURE=3",out);
  122. fputs("\nPPPOE_TIMEOUT=80",out);
  123. fputs("\nLINUX_PLUGIN=",out);
  124. fputs("\nDEMAND=no",out);
  125. fputs("\nDEFAULTROUTE=yes\n",out);
  126. fclose(out);
  127. //配置3
  128. out=fopen("/etc/ppp/rp-pppoe-gui/passwd","w+");
  129. if(out==NULL){printf("can't create the conf.mxd_connect");}
  130. strcpy(c,"\{ConnectionName mxd_connect Password ");
  131. strcat(c,b);
  132. strcat(c,"}\n");
  133. fputs(c,out);
  134. fclose(out);
  135. }else
  136.         {titlec=tr("非法操作");
  137.          textc=QString::fromLocal8Bit("请用root账号进行保存");
  138.                                                                 }
  139. trayIcon->showMessage(titlec,textc,QSystemTrayIcon::Information,5000);
  140. }
  141.                
  142. void myclass::iconActivated(QSystemTrayIcon::ActivationReason reason)
  143. {
  144.      switch (reason) {
  145.         case QSystemTrayIcon::DoubleClick:
  146.         this->showNormal();
  147.          break;
  148.      default:
  149.          ;
  150.      }
  151. }

  152. void myclass::createActions()
  153. {
  154.      minimizeAction = new QAction(tr("隐藏 (&I)"), this);
  155.      connect(minimizeAction, SIGNAL(triggered()), this, SLOT(hide()));

  156.      conn1 = new QAction(tr("拔号 (&X)"), this);
  157.      connect(conn1, SIGNAL(triggered()), this, SLOT(pppoeStart()));

  158.      conn2 = new QAction(tr("断开 (&R)"), this);
  159.      connect(conn2, SIGNAL(triggered()), this, SLOT(pppoeStop()));

  160.      quitAction = new QAction(tr("退出 (&Q)"), this);
  161.      connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
  162. }

  163. void myclass::createTrayIcon()
  164. {
  165.      trayIconMenu = new QMenu(this);
  166.      trayIconMenu->addAction(minimizeAction);
  167.      trayIconMenu->addAction(conn1);
  168.      trayIconMenu->addAction(conn2);
  169.      trayIconMenu->addSeparator();
  170.      trayIconMenu->addAction(quitAction);
  171.      trayIcon->setContextMenu(trayIconMenu);
  172. }

  173. void myclass::pppoeStart()
  174. {
  175.         if(uid==0)
  176.                 {
  177.                         system("/usr/sbin/adsl-start");
  178.                         }
  179.                 else
  180.                 {       
  181.                         system("/usr/sbin/pppoe-wrapper start mxd_connect");
  182.                         }
  183.         QIcon icon2 = QIcon("./images/status_both.png");
  184.         trayIcon->setIcon(icon2);
  185.         this->hide();
  186.         }
  187. void myclass::pppoeStop()
  188. {
  189.         if(uid==0)
  190.                 {
  191.                         system("/usr/sbin/adsl-stop");
  192.                         }
  193.                 else
  194.                 {       
  195.                         system("/usr/sbin/pppoe-wrapper stop haulm");
  196.                         }
  197.         QIcon icon1 = QIcon("./images/status_error.png");
  198.         trayIcon->setIcon(icon1);
  199. }

  200. int main(int argc,char **argv)
  201. {
  202.         QApplication testc(argc,argv);
  203.         myclass newc;
  204.         newc.show();
  205.         return testc.exec();
  206. }
复制代码
回复

使用道具 举报

发表于 2008-10-18 08:28:47 | 显示全部楼层
QT 那里用designer 就可以啊,很简单的。

写成KDE 程序或者applet也应该不成问题的。

我还会有后续意见的。
回复

使用道具 举报

发表于 2008-10-18 09:15:45 | 显示全部楼层
system 那里最好独立成一个线程,

或者专门写一个类来实现系统调用

那样不会因为子进程没有响应而把主进程弄僵

网络状态分析参考一下 kde applet 那个就可以
回复

使用道具 举报

 楼主| 发表于 2008-10-18 15:26:21 | 显示全部楼层
原帖由 stdio 于 2008-10-18 09:15 发表
system 那里最好独立成一个线程,

或者专门写一个类来实现系统调用

那样不会因为子进程没有响应而把主进程弄僵

网络状态分析参考一下 kde applet 那个就可以 ...

在书上也是不建议使用system的,我在程序有进展后才会考虑使用其它方法的调用。
回复

使用道具 举报

 楼主| 发表于 2008-10-19 08:08:15 | 显示全部楼层
昨天研究了半天的libpcap的应用,该库用于监听网络的,但很奇怪的是pcap_lookupnet函数经常返回空,昨晚偶而返回了网卡定义的IP和MASK值纯属于人品,今早又不行了只好注释掉。
pcap_next函数似乎不会马上返回,运行后如果没有接收到数据包就不会退出,这样对我来说还是有点麻烦,因为我不可能直接按pcap_next返回的值来判断是否在线,如果断开了,很可能陷入了长时间的等待。
这几天大量地搜索网络这方面的资料,有努力还是有收获,不过还是希望有能力的朋友指导和一起进步。

  1. #include <pcap.h>
  2. #include <stdio.h>

  3. int main()
  4.     {
  5.         pcap_t *handle;                        /* Session handle */
  6.         char *dev;                                /* The device to sniff on */
  7.         char errbuf[PCAP_ERRBUF_SIZE]; /* Error string */
  8.         struct bpf_program filter;            /* The compiled filter */
  9.         char filter_app[] = "";       /* The filter expression */
  10.         bpf_u_int32 mask;                     /* Our netmask */
  11.         bpf_u_int32 net;                        /* Our IP */
  12.         struct pcap_pkthdr header;          /* The header that pcap gives us */
  13.         const u_char *packet;                 /* The actual packet */
  14.         /* Define the device */
  15.          if(!(dev = pcap_lookupdev(errbuf)))
  16.     {
  17.       perror(errbuf);
  18.       exit(-1);
  19.     }
  20.         /* Find the properties for the device */
  21. //        pcap_lookupnet(dev, &net, &mask, errbuf);
  22.         /* Open the session in promiscuous mode */
  23.         handle = pcap_open_live(dev, BUFSIZ, 1, 0, errbuf);
  24. if (handle == NULL)
  25.                 {perror(errbuf);
  26.                  exit(-1);}

  27.         /* Compile and apply the filter */
  28.         if(pcap_compile(handle, &filter, filter_app, 0, net)==-1)
  29.         {fprintf(stderr, "pcap_compile: %s\n", pcap_geterr(handle));
  30.                 exit(1);}
  31.         if(pcap_setfilter(handle, &filter)==-1)
  32.         {fprintf(stderr, "pcap_compile: %s\n", pcap_geterr(handle));
  33.                 exit(1);}
  34.         /* Grab a packet */

  35.         packet = pcap_next(handle, &header);
  36.                    /* Print its length */
  37.         printf("Jacked a packet with length of [%d]\n",header.len);
  38.         /* And close the session */

  39.         struct pcap_stat {
  40.         u_int ps_recv; /* number of packets received */
  41.         u_int ps_drop; /* number of packets dropped */
  42.         u_int ps_ifdrop; /* drops by interface XXX not yet supported */
  43. };

  44.         struct pcap_stat ps;
  45.         pcap_stats (handle,&ps);
  46.         printf("%d\n",ps.ps_recv);
  47.         pcap_close(handle);
  48.         return(0);
  49.     }

复制代码
回复

使用道具 举报

 楼主| 发表于 2008-10-19 08:19:49 | 显示全部楼层
原帖由 stdio 于 2008-10-18 08:28 发表
QT 那里用designer 就可以啊,很简单的。

写成KDE 程序或者applet也应该不成问题的。

我还会有后续意见的。

主要是我根本看不懂或很难看懂写的是什么,不少开源软件没有明显的注释,很难拿来主义或是下手修改。
另外这几天的C编程学习,总的感受是库函数也不是说没有毛病的,一些奇奇怪怪的事也会发生的。编译过程中出现最多的是段错误,以前打包编译程序时遇到过段错误,现在明白了该种错误是非常低级的错误,往往就是将函数返回值未经判断将NULL或-1值或完全不匹配的值应用到新的函数中去了。
回复

使用道具 举报

发表于 2008-10-19 08:31:43 | 显示全部楼层
楼上。尝试 shell 编程吧……
回复

使用道具 举报

 楼主| 发表于 2008-10-19 08:59:06 | 显示全部楼层
原帖由 jiangtao9999 于 2008-10-19 08:31 发表
楼上。尝试 shell 编程吧……

兄台不会是想让我改用wxPython来写吧,晕倒。
回复

使用道具 举报

 楼主| 发表于 2008-10-20 10:57:21 | 显示全部楼层
和kanker再次交流后放弃了用libpacp进行网络分析的想法,因为libpacp在抓包过程如果没有抓到包很可能就处于等待状态,直到你设置的超时时间过了才会返回,如果再加上线程,这个程序变得非常复杂。
/sys/class/net 目录下有着内核存放的网络状态分析文件,这里面提供非常详细的分析,所以重新去抓包分析网络就很可笑了,我现在只需要直接从这个目录中的各个文件中得到数据。
回复

使用道具 举报

发表于 2008-10-20 17:19:43 | 显示全部楼层
原帖由 haulm 于 2008-10-19 08:59 AM 发表

兄台不会是想让我改用wxPython来写吧,晕倒。

别晕,听说 php 也能 GTK 了……
回复

使用道具 举报

 楼主| 发表于 2008-10-20 23:41:42 | 显示全部楼层
兄台孤陋寡闻了,PHP-GTK很早就有了,直到现在它的应用还是少的可怜。
回复

使用道具 举报

发表于 2008-10-21 00:50:36 | 显示全部楼层
原帖由 haulm 于 2008-10-20 23:41 发表
兄台孤陋寡闻了,PHP-GTK很早就有了,直到现在它的应用还是少的可怜。

pyqt
pygtk
wxpython
這些都可以
至少比你用c+qt來的快我覺得
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

GMT+8, 2025-2-7 22:08 , Processed in 0.030239 second(s), 15 queries .

© 2001-2025 Discuz! Team. Powered by Discuz! X3.5.

快速回复 返回顶部 返回列表