Diffstat (limited to 'noncore/settings/networksettings/ppp/modem.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | noncore/settings/networksettings/ppp/modem.cpp | 229 |
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 | |||
@@ -28,2 +28,3 @@ | |||
28 | #include <stdlib.h> | 28 | #include <stdlib.h> |
29 | #include <unistd.h> | ||
29 | #include <fcntl.h> | 30 | #include <fcntl.h> |
@@ -35,3 +36,14 @@ | |||
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" |
@@ -85,2 +97,4 @@ Modem::Modem() | |||
85 | modemfd = -1; | 97 | modemfd = -1; |
98 | _pppdExitStatus = -1; | ||
99 | pppdPid = -1; | ||
86 | sn = 0L; | 100 | sn = 0L; |
@@ -757,2 +771,18 @@ bool Modem::createAuthFile(Auth method, const char *username, const char *passwo | |||
757 | 771 | ||
772 | bool 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 | |||
758 | bool Modem::setSecret(int method, const char* name, const char* password) | 788 | bool Modem::setSecret(int method, const char* name, const char* password) |
@@ -780,14 +810,177 @@ bool Modem::setSecret(int method, const char* name, const char* password) | |||
780 | 810 | ||
781 | bool Modem::removeSecret(int) | 811 | bool 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 | ||
786 | void Modem::killPPPDaemon() | 828 | int 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 | ||
790 | int Modem::pppdExitStatus() | 869 | bool 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 | |||
933 | bool 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 | |||
948 | void 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 | } |
@@ -796,3 +989,18 @@ bool 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 | |||
997 | void Modem::killPPPDaemon() | ||
998 | { | ||
999 | PPPData::data()->setpppdRunning(false); | ||
1000 | killpppd(); | ||
1001 | } | ||
1002 | |||
1003 | int Modem::pppdExitStatus() | ||
1004 | { | ||
1005 | return _pppdExitStatus; | ||
798 | } | 1006 | } |
@@ -801,3 +1009,8 @@ int 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 | } |
@@ -806,3 +1019,3 @@ bool Modem::setHostname(const QString & name) | |||
806 | { | 1019 | { |
807 | return true; | 1020 | return sethostname(name, name.length()) == 0; |
808 | } | 1021 | } |