summaryrefslogtreecommitdiff
path: root/noncore/settings/networksettings/ppp/modem.cpp
Unidiff
Diffstat (limited to 'noncore/settings/networksettings/ppp/modem.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/settings/networksettings/ppp/modem.cpp229
1 files changed, 221 insertions, 8 deletions
diff --git a/noncore/settings/networksettings/ppp/modem.cpp b/noncore/settings/networksettings/ppp/modem.cpp
index cd5d21c..5139482 100644
--- a/noncore/settings/networksettings/ppp/modem.cpp
+++ b/noncore/settings/networksettings/ppp/modem.cpp
@@ -26,6 +26,7 @@
26 26
27#include <errno.h> 27#include <errno.h>
28#include <stdlib.h> 28#include <stdlib.h>
29#include <unistd.h>
29#include <fcntl.h> 30#include <fcntl.h>
30#include <signal.h> 31#include <signal.h>
31#include <sys/ioctl.h> 32#include <sys/ioctl.h>
@@ -33,7 +34,18 @@
33#include <regex.h> 34#include <regex.h>
34#include <qregexp.h> 35#include <qregexp.h>
35#include <assert.h> 36#include <assert.h>
37#include <string.h>
36 38
39#ifdef HAVE_RESOLV_H
40# include <arpa/nameser.h>
41# include <resolv.h>
42#endif
43
44#ifndef _PATH_RESCONF
45#define _PATH_RESCONF "/etc/resolv.conf"
46#endif
47
48#define strlcpy strcpy
37#include "auth.h" 49#include "auth.h"
38#include "modem.h" 50#include "modem.h"
39#include "pppdata.h" 51#include "pppdata.h"
@@ -83,6 +95,8 @@ Modem::Modem()
83{ 95{
84 if (Modem::modem != 0) return; //CORRECT? 96 if (Modem::modem != 0) return; //CORRECT?
85 modemfd = -1; 97 modemfd = -1;
98 _pppdExitStatus = -1;
99 pppdPid = -1;
86 sn = 0L; 100 sn = 0L;
87 data_mode = false; 101 data_mode = false;
88 modem_is_locked = false; 102 modem_is_locked = false;
@@ -755,6 +769,22 @@ bool Modem::createAuthFile(Auth method, const char *username, const char *passwo
755} 769}
756 770
757 771
772bool Modem::removeAuthFile(Auth method) {
773 const char *authfile, *oldName;
774
775 if(!(authfile = authFile(method)))
776 return false;
777 if(!(oldName = authFile(method, Old)))
778 return false;
779
780 if(access(oldName, F_OK) == 0) {
781 unlink(authfile);
782 return (rename(oldName, authfile) == 0);
783 } else
784 return false;
785}
786
787
758bool Modem::setSecret(int method, const char* name, const char* password) 788bool Modem::setSecret(int method, const char* name, const char* password)
759{ 789{
760 790
@@ -778,32 +808,215 @@ bool Modem::setSecret(int method, const char* name, const char* password)
778 808
779} 809}
780 810
781bool Modem::removeSecret(int) 811bool Modem::removeSecret(int method)
782{ 812{
783 return true; 813 Auth auth;
814
815 switch(method) {
816 case AUTH_PAP:
817 auth = Modem::PAP;
818 break;
819 case AUTH_CHAP:
820 auth = Modem::CHAP;
821 break;
822 default:
823 return false;
824 }
825 return removeAuthFile( auth );
784} 826}
785 827
786void Modem::killPPPDaemon() 828int checkForInterface()
787{ 829{
830// I don't know if Linux needs more initialization to get the ioctl to
831// work, pppd seems to hint it does. But BSD doesn't, and the following
832// code should compile.
833#if (defined(HAVE_NET_IF_PPP_H) || defined(HAVE_LINUX_IF_PPP_H)) && !defined(__svr4__)
834 int s, ok;
835 struct ifreq ifr;
836 // extern char *no_ppp_msg;
837
838 if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
839 return 1; /* can't tell */
840
841 strlcpy(ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
842 ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
843 close(s);
844
845 if (ok == -1) {
846// This is ifdef'd FreeBSD, because FreeBSD is the only BSD that supports
847// KLDs, the old LKM interface couldn't handle loading devices
848// dynamically, and thus can't load ppp support on the fly
849#ifdef __FreeBSD__
850 // If we failed to load ppp support and don't have it already.
851 if (kldload("if_ppp") == -1) {
852 return -1;
853 }
854 return 0;
855#else
856 return -1;
857#endif
858 }
859 return 0;
860#else
861// We attempt to use the SunOS/SysVr4 method and stat /dev/ppp
862 struct stat buf;
863
864 memset(&buf, 0, sizeof(buf));
865 return stat("/dev/ppp", &buf);
866#endif
788} 867}
789 868
790int Modem::pppdExitStatus() 869bool Modem::execpppd(const char *arguments) {
791{ 870 char buf[MAX_CMDLEN];
792 return -1; 871 char *args[MaxArgs];
872 pid_t pgrpid;
873
874 if(modemfd<0)
875 return false;
876
877 _pppdExitStatus = -1;
878
879 switch(pppdPid = fork())
880 {
881 case -1:
882 fprintf(stderr,"In parent: fork() failed\n");
883 return false;
884 break;
885
886 case 0:
887 // let's parse the arguments the user supplied into UNIX suitable form
888 // that is a list of pointers each pointing to exactly one word
889 strlcpy(buf, arguments);
890 parseargs(buf, args);
891 // become a session leader and let /dev/ttySx
892 // be the controlling terminal.
893 pgrpid = setsid();
894#ifdef TIOCSCTTY
895 if(ioctl(modemfd, TIOCSCTTY, 0)<0)
896 fprintf(stderr, "ioctl() failed.\n");
897#elif defined (TIOCSPGRP)
898 if(ioctl(modemfd, TIOCSPGRP, &pgrpid)<0)
899 fprintf(stderr, "ioctl() failed.\n");
900#endif
901 if(tcsetpgrp(modemfd, pgrpid)<0)
902 fprintf(stderr, "tcsetpgrp() failed.\n");
903
904 dup2(modemfd, 0);
905 dup2(modemfd, 1);
906
907 switch (checkForInterface()) {
908 case 1:
909 fprintf(stderr, "Cannot determine if kernel supports ppp.\n");
910 break;
911 case -1:
912 fprintf(stderr, "Kernel does not support ppp, oops.\n");
913 break;
914 case 0:
915 fprintf(stderr, "Kernel supports ppp alright.\n");
916 break;
917 }
918
919 execve(pppdPath(), args, 0L);
920 _exit(0);
921 break;
922
923 default:
924 qDebug("In parent: pppd pid %d\n",pppdPid);
925 close(modemfd);
926 modemfd = -1;
927 return true;
928 break;
929 }
930}
931
932
933bool Modem::killpppd() {
934 if(pppdPid > 0) {
935 qDebug("In killpppd(): Sending SIGTERM to %d\n", pppdPid);
936 if(kill(pppdPid, SIGTERM) < 0) {
937 qDebug("Error terminating %d. Sending SIGKILL\n", pppdPid);
938 if(kill(pppdPid, SIGKILL) < 0) {
939 qDebug("Error killing %d\n", pppdPid);
940 return false;
941 }
942 }
943 }
944 return true;
945}
946
947
948void Modem::parseargs(char* buf, char** args) {
949 int nargs = 0;
950 int quotes;
951
952 while(nargs < MaxArgs-1 && *buf != '\0') {
953
954 quotes = 0;
955
956 // Strip whitespace. Use nulls, so that the previous argument is
957 // terminated automatically.
958
959 while ((*buf == ' ' ) || (*buf == '\t' ) || (*buf == '\n' ) )
960 *buf++ = '\0';
961
962 // detect begin of quoted argument
963 if (*buf == '"' || *buf == '\'') {
964 quotes = *buf;
965 *buf++ = '\0';
966 }
967
968 // save the argument
969 if(*buf != '\0') {
970 *args++ = buf;
971 nargs++;
972 }
973
974 if (!quotes)
975 while ((*buf != '\0') && (*buf != '\n') &&
976 (*buf != '\t') && (*buf != ' '))
977 buf++;
978 else {
979 while ((*buf != '\0') && (*buf != quotes))
980 buf++;
981 *buf++ = '\0';
982 }
983 }
984
985 *args = 0L;
793} 986}
794 987
795bool Modem::execPPPDaemon(const QString & arguments) 988bool Modem::execPPPDaemon(const QString & arguments)
796{ 989{
990 if(execpppd(arguments)==0) {
991 PPPData::data()->setpppdRunning(true);
797 return true; 992 return true;
993 } else
994 return false;
995}
996
997void Modem::killPPPDaemon()
998{
999 PPPData::data()->setpppdRunning(false);
1000 killpppd();
1001}
1002
1003int Modem::pppdExitStatus()
1004{
1005 return _pppdExitStatus;
798} 1006}
799 1007
800int Modem::openResolv(int flags) 1008int Modem::openResolv(int flags)
801{ 1009{
802 return -1; 1010 int fd;
1011 if ((fd = open(_PATH_RESCONF, flags)) == -1) {
1012 qDebug("error opening resolv.conf!");
1013 fd = open(DEVNULL, O_RDONLY);
1014 }
1015 return fd;
803} 1016}
804 1017
805bool Modem::setHostname(const QString & name) 1018bool Modem::setHostname(const QString & name)
806{ 1019{
807 return true; 1020 return sethostname(name, name.length()) == 0;
808} 1021}
809 1022