#pragma implementation #include #include #include #include #include #include #include "netconf.h" #include "pppdial.h" static char ATZOK[]="ATZ OK ATDT"; const char PPP_CHANNEL[]="channel"; #include "pppkeyw.h" static int (*fct_load)(PPPONE &, const char *) = NULL; static int (*fct_save)(PPPONE &, const char *) = NULL; static int (*fct_del)(const char *) = NULL; static int (*fct_list)(SSTRINGS &)=NULL; int (*ppphook_status)(const char *, char [20])=NULL; int (*ppphook_control)(const char *, bool)=NULL; EXPORT void ppp_sethook ( int (*load)(PPPONE &, const char *), int (*save)(PPPONE &, const char *), int (*del)(const char *), int (*list)(SSTRINGS &), int (*status)(const char *, char [20]), int (*control)(const char *, bool)) { fct_load = load; fct_save = save; fct_del = del; fct_list = list; ppphook_status = status; ppphook_control = control; } /* Obtain the distribution specific PPP config files */ void pppdial_getlist (SSTRINGS &lst) { if (fct_list != NULL) (*fct_list)(lst); } /* Initialise 3 tables to simplify loading/clearing and saving */ PRIVATE void PPPONE::setuptbdb() { memset (strs,0,sizeof(strs)); memset (chars,0,sizeof(chars)); memset (nums,0,sizeof(nums)); strs[0].key = PHONE; strs[0].str = ☎ strs[1].key = LOGIN; strs[1].str = &login; strs[2].key = PASSWD; strs[2].str = &passwd; strs[3].key = DEVICE; strs[3].str = &device; strs[4].key = MODEMINIT; strs[4].str = &modeminit; strs[4].defval = ATZOK; strs[5].key = OPTIONS; strs[5].str = &options; strs[6].key = ASYNCMAP; strs[6].str = &asyncmap; strs[6].defval = "0"; strs[7].key = OURIP; strs[7].str = &ourip; strs[8].key = REMOTEIP; strs[8].str = &remoteip; strs[9].key = LOGINOK; strs[9].str = &loginok; strs[10].key = LOGINCHAT; strs[10].str = &loginchat; strs[11].key = LOGINFAIL; strs[11].str = &loginfail; strs[12].key = LOGINKEY; strs[12].str = &loginkey; strs[12].defval = "ogin:--ogin:"; strs[13].key = PASSWDKEY; strs[13].str = &passwdkey; strs[13].defval = "assword:"; strs[14].key = LCPECHO; strs[14].str = &lcpecho; strs[14].defval = ""; strs[15].key = SSH_HOST; strs[15].str = &ssh.host; strs[15].defval = ""; strs[16].key = SSH_USER; strs[16].str = &ssh.user; strs[16].defval = ""; strs[17].key = SSH_ENCRYPT; strs[17].str = &ssh.encrypt; strs[17].defval = ""; strs[18].key = SSH_PPPDPATH; strs[18].str = &ssh.pppd_path; strs[18].defval = "/usr/sbin/pppd"; strs[19].key = TRIGGER; strs[19].str = &trigger; strs[20].key = POSTCONCMD; strs[20].str = &postconcmd; strs[21].key = POSTDISCMD; strs[21].str = &postdiscmd; strs[22].key = IPXOPTIONS; strs[22].str = &ipx.options; strs[23].key = PREDISCMD; strs[23].str = &prediscmd; strs[24].key = CHATSCRIPT; strs[24].str = &chatscript; strs[25].key = PRECONCMD; strs[25].str = &preconcmd; strs[26].key = NULL; chars[0].key = TYPE; chars[0].num = &type; chars[0].defval = 0; chars[1].key = MODEM; chars[1].num = &modem; chars[1].defval = 1; chars[2].key = DEFAULTROUTE; chars[2].num = &defaultroute; chars[2].defval = 1; chars[3].key = LOCK; chars[3].num = &lock; chars[3].defval = 1; chars[4].key = DBGPPP; chars[4].num = &dbgppp; chars[4].defval = 0; chars[5].key = DBGCHAT; chars[5].num = &dbgchat; chars[5].defval = 0; chars[6].key = PROXYARP; chars[6].num = &proxyarp; chars[6].defval = 0; chars[7].key = PPPAUTH; chars[7].num = &pppauth; chars[7].defval = 0; chars[8].key = SSH_COMPRESS; chars[8].num = &ssh.compress; chars[8].defval = 0; chars[9].key = SSH_VIASHELL; chars[9].num = &ssh.via_shell; chars[9].defval = 0; chars[10].key = USETYPE; chars[10].num = &usetype; chars[10].defval = 0; chars[11].key = IPXENABLE; chars[11].num = &ipx.enable; chars[11].defval = 0; chars[12].key = IPXROUTINGRIP; chars[12].num = &ipx.routingrip; chars[12].defval = 0; chars[13].key = IPXROUTINGNLSP; chars[13].num = &ipx.routingnlsp; chars[13].defval = 0; chars[14].key = FIREWALL; chars[14].num = &firewall; chars[14].defval = 0; chars[15].key = SSH_USEPATCH; chars[15].num = &ssh.use_patch; chars[15].defval = 0; chars[16].key = NULL; nums[0].key = BAUD; nums[0].num = &baud; nums[0].defval = 38400; nums[1].key = MRU; nums[1].num = &mru; nums[1].defval = 1500; nums[2].key = IDLETIME; nums[2].num = &idletime; nums[2].defval = 0; nums[3].key = MTU; nums[3].num = &mtu; nums[3].defval = 0; nums[4].key = IPXNETNUM; nums[4].num = &ipx.netnum; nums[4].defval = 0; nums[5].key = IPXLOCALNUM; nums[5].num = &ipx.localnum; nums[5].defval = 0; nums[6].key = IPXREMOTENUM; nums[6].num = &ipx.remotenum; nums[6].defval = 0; nums[7].key = NULL; } /* Open configuration database */ PRIVATE void PPPONE::opencfg() { if (cfg == NULL && !name.is_empty()){ char path[PATH_MAX]; sprintf (path,"%s/%s.dconf",ETC_PPP,name.get()); cfile = new CONFIG_FILE (path ,help_nil ,CONFIGF_OPTIONAL|CONFIGF_MANAGED ,"root","root",0600); cfg = new CONFDB (*cfile); } } PUBLIC PPPONE::PPPONE(const char *_name) { cfg = NULL; cfile = NULL; setuptbdb(); exist = false; if (_name != NULL){ name.setfrom (_name); opencfg(); /* #Specification: PPP / ___.dconf files Linuxconf stores PPP dialout configuration in /etc/ppp/___.dconf files. On some distribution, linuxconf will store the information in distribution specific files. The logic goes like this. At load time, priority is given to the *.dconf file. At write time the configuration is saved in the distribution specific file */ if (!cfile->exist() && fct_load != NULL){ exist = (*fct_load)(*this,_name) != -1; }else{ exist = cfile->exist(); for (LK_STR *ps = strs; ps->key != NULL; ps++){ ps->str->setfrom (cfg->getval(_name,ps->key ,ps->defval)); } for (LK_INT *pn = nums; pn->key != NULL; pn++){ *pn->num = cfg->getvalnum(_name,pn->key ,pn->defval); } for (LK_CHAR *pc = chars; pc->key != NULL; pc++){ *pc->num = cfg->getvalnum(_name,pc->key ,pc->defval); } SSTRINGS tbr; cfg->getall (_name,IPROUTES,tbr,1); for (int i=0; iget(); iproutes.add (new PPPIPROUTE (s)); } } }else{ for (LK_STR *ps = strs; ps->key != NULL; ps++){ ps->str->setfrom (ps->defval); } for (LK_INT *pn = nums; pn->key != NULL; pn++){ *pn->num = pn->defval; } for (LK_CHAR *pc = chars; pc->key != NULL; pc++){ *pc->num = pc->defval; } /* #Specification: ppp over ssh / default behavior To support older configuration using a patched ssh (option -E) the default when reading a config file is "use_patch=1". When creating a new config, we default to the new strategy with pty-redir since it does not need a special non-standard ssh. */ ssh.use_patch = 0; } if (type == TYPE_PPP_PAP){ type = TYPE_PPP_SERIAL; pppauth = PPP_AUTH_PAP; }else if (type == TYPE_PPP_CHAP){ type = TYPE_PPP_SERIAL; pppauth = PPP_AUTH_CHAP; } } PUBLIC PPPONE::~PPPONE() { delete cfg; delete cfile; } /* Update the CONFDB object and save it on disk */ PUBLIC int PPPONE::save() { int ret = -1; opencfg(); const char *_name = name.get(); if (fct_save != NULL){ ret = (*fct_save)(*this,_name); if (ret != -1) cfile->unlink(); }else{ SSTRINGS lst; cfg->getall ("",PPP_CHANNEL,lst,1); if (lst.lookup(name.get())==-1){ lst.add (new SSTRING(name)); cfg->replace ("",PPP_CHANNEL,lst); } for (LK_STR *ps = strs; ps->key != NULL; ps++){ cfg->replace (_name,ps->key,*ps->str); } for (LK_INT *pn = nums; pn->key != NULL; pn++){ cfg->replace (_name,pn->key,*pn->num); } for (LK_CHAR *pc = chars; pc->key != NULL; pc++){ cfg->replace (_name,pc->key,*pc->num); } cfg->removeall (_name,IPROUTES); for (int r=0; rdest.is_empty()){ char buf[200]; sprintf (buf,"%s %s",ir->dest.get(),ir->mask.get()); cfg->add (_name,IPROUTES,buf); } } ret = cfg->save(); } return ret; } /* Return the connection usage (PPP_USE_xxxx) of this config */ PUBLIC int PPPONE::getusetype() { return usetype; } /* Remove this configuration from the configuration file */ PROTECTED void PPPONE::del(const char *_name) { if (_name[0] != '\0'){ if (fct_del != NULL){ (*fct_del)(_name); }else{ char path[PATH_MAX]; sprintf (path,"%s/%s.dconf",ETC_PPP,_name); unlink (path); } } }