#include #include #include #include #include #include #include #include "pppdialin.h" #include "pppdialin.m" #include "../../paths.h" #include #include static HELP_FILE help_ipup ("pppdialin","ip-up"); extern HELP_FILE help_dialin; static const char ppp_dialout[]="dialout"; static const char ppppostcon[]="/usr/lib/linuxconf/lib/ppppostlogin"; static const char ppppostdis[]="/usr/lib/linuxconf/lib/ppppostlogout"; static CONFIG_FILE f_ipup (ETC_PPP_IPUP ,help_ipup ,CONFIGF_MANAGED|CONFIGF_OPTIONAL ,"root","root",0755,ppp_dialout); static CONFIG_FILE f_ipdown (ETC_PPP_IPDOWN ,help_ipup ,CONFIGF_MANAGED|CONFIGF_OPTIONAL ,"root","root",0755,ppp_dialout); /* Make sure the config file has one call to the script */ static bool ipupupd_checkone( CONFIG_FILE &cf, const char *script, bool doit) { bool ret = false; FILE_CFG *fin = cf.fopen ("r"); if (fin != NULL){ char buf[1000]; int len = strlen(script); bool first = true; bool copy_sh = false; while (fgets(buf,sizeof(buf)-1,fin)!=NULL){ strip_end (buf); if (first){ if (strcmp(buf,"#!/bin/sh")==0 || strcmp(buf,"#!/bin/bash")==0){ copy_sh = true; } first = false; } if (strncmp(buf,script,len)==0 && isspace(buf[len])){ ret = true; break; } } if (!ret && doit){ /* #Specification: pppdialin / updating ip-up ip-down We must register a script in that file, but we can't put it at the end because some scripts ends with "exit 0". So we put it at the beginning, after the #!/bin/sh if there. */ const char *cfpath = cf.getpath(); char pathnew[PATH_MAX]; snprintf (pathnew,sizeof(pathnew)-1,"%s.NEW",cfpath); FILE_CFG *fout = cf.fopen (pathnew,"w"); if (fout != NULL){ rewind (fin); if (copy_sh){ if (fgets(buf,sizeof(buf)-1,fin)!=NULL) fputs (buf,fout); } fprintf (fout,"%s \"$@\"\n",script); while (fgets(buf,sizeof(buf)-1,fin)!=NULL) fputs (buf,fout); if (fclose (fout)!=-1){ char pathbak[PATH_MAX]; snprintf (pathbak,sizeof(pathbak)-1,"%s.BAK",cfpath); rename (cfpath,pathbak); rename (pathnew,cfpath); } } } fclose (fin); }else if (doit){ FILE_CFG *fout = cf.fopen ("w"); if (fout != NULL){ fprintf (fout,"#!/bin/sh\n"); fprintf (fout,"%s \"$@\"\n",script); fclose (fout); } } return ret; } void ipupupd_check() { if (!ipupupd_checkone (f_ipup,ppppostcon,false) || !ipupupd_checkone (f_ipdown,ppppostdis,false)){ if (dialog_yesno (MSG_U(T_MODIPUP,"Modify ip-up/ip-down") ,MSG_U(I_MODIPUP ,"The files /etc/ppp/ip-up and /etc/ppp/ip-down\n" "must be modified to support the pppdialin module\n" "\n" "The following lines must be added respectivly to\n" "each file:\n" "\n" "ip-up : /usr/lib/linuxconf/lib/ppppostlogin \"$@\"\n" "ip-down: /usr/lib/linuxconf/lib/ppppostlogout \"$@\"\n" "\n" "Do you want to do it ?") ,help_dialin)==MENU_YES){ ipupupd_checkone (f_ipup,ppppostcon,true); ipupupd_checkone (f_ipdown,ppppostdis,true); } } } static bool ipupupd_devexist (const char *devname) { bool ret = false; if (strncmp(devname,"pppdialin/",10)==0){ devname += 10; struct passwd *p = getpwnam(devname); ret = p != NULL; } return ret; } static int ipupupd_getdevlist (SSTRINGS &devs, SSTRINGS &descs) { devs.add (new SSTRING("pppdialin/account")); descs.add (new SSTRING(MSG_U(I_PPPDEV,"One PPP account"))); return 1; } static int pppcon_readpid(const char *path) { int ret = -1; FILE *fin = fopen (path,"r"); if (fin != NULL){ int pid; if (fscanf (fin,"%d",&pid)==1) ret = pid; fclose (fin); } return ret; } /* Return the PID and the PPP device of the pppd process owned by a ppp account Return -1 if the connection is not active. */ static int ipupupd_getinfo (const char *user, SSTRING &kerneldev) { int ret = -1; char pathdev[PATH_MAX]; snprintf (pathdev,sizeof(pathdev)-1,"/var/run/pppdialin.%s",user); FILE *fin = fopen (pathdev,"r"); if (fin != NULL){ char dev[100]; if (fscanf (fin,"%s\n",dev)==1){ char pathpid[PATH_MAX]; sprintf (pathpid,"/var/run/%s.pid",dev); kerneldev.setfrom (dev); ret = pppcon_readpid (pathpid); } fclose (fin); } if (ret != -1 && kill(ret,0)==-1) ret = -1; return ret; } int ipupupd_disconnect (const char *user) { int ret = -1; SSTRING dev; int pid = ipupupd_getinfo(user,dev); if (pid != -1){ ret = kill (pid,SIGTERM); } return ret; } static int ipupupd_getdevinfo (const char *devname, SSTRINGS &kerneldevs) { int ret = -1; if (strncmp(devname,"pppdialin/",10)==0){ SSTRING kerneldev; ret = ipupupd_getinfo (devname+10,kerneldev); if (ret != -1){ kerneldevs.add (new SSTRING(kerneldev)); } } return ret; } // THe dialout module does not define any logical HOST static bool ipupupd_hostexist (const char *hostname) { return ipupupd_devexist (hostname); } static int ipupupd_gethostlist (SSTRINGS &hosts, SSTRINGS &descs) { return ipupupd_getdevlist (hosts,descs); } static int ipupupd_gethostinfo (const char *host, SSTRINGS &ips) { int ret = -1; SSTRINGS devs; if (ipupupd_getdevinfo(host,devs)!=-1){ // We need the IP number associated with the device IFCONFIG_INFO info; const char *dev = devs.getitem(0)->get(); if (ifconfig_getinfo_nocheck(dev,info)!=-1){ ips.add (new SSTRING(info.ip_addr)); ret = 0; } } return ret; } void *ipupupd_fwinfo_api_get() { FWINFO_API *api = new FWINFO_API; api->devexist = ipupupd_devexist; api->getdevlist = ipupupd_getdevlist; api->getdevinfo = ipupupd_getdevinfo; api->hostexist = ipupupd_hostexist; api->gethostlist = ipupupd_gethostlist; api->gethostinfo = ipupupd_gethostinfo; return api; } void ipupupd_fwinfo_api_release(void *api) { delete (FWINFO_API*)api; }