#include #include #include #include #include #include #include #include #include #include #include #include #include "../../paths.h" #include "conectiva.h" #include "conectiva.m" /* Parse a ifcfg-dev path and return the file name and eliminate all the special devices, aliases and point to point stuff Return the name of the script only if */ static const char *devinfo_filtername ( const char *path, bool filter_alias) // Remove alias devices { const char *ret = NULL; const char *fname = strrchr (path,'/'); if (fname != NULL){ fname++; char last = fname[strlen(fname)-1]; // Avoid file ending with ~ if (last != '~' && strcmp(fname,"ifcfg-lo")!=0 && (strchr(fname,':')==NULL || !filter_alias) && strncmp(fname+6,"ppp",3) != 0 && strncmp(fname+6,"ippp",4) != 0 && strncmp(fname+6,"slip",4) != 0 && strncmp(fname+6,"plip",4) != 0){ // Avoid file ending with .bak char *pt = strstr(fname,".bak"); if (pt == NULL) pt = strstr(fname,".OLD"); if (pt == NULL || pt[4] != '\0'){ ret = fname; } } } return ret; } const char scripts_path[]="/etc/sysconfig/network-scripts/ifcfg-"; /* Extract the list of ifcfg files related to LAN devices */ static int devinfo_getlist( SSTRINGS &tb, bool filter_alias) // Remove alias devices { dir_getlist_p (scripts_path,tb); // Remove the ifcfg file which are not LAN devices for (int i=0; iget(),filter_alias) == NULL){ tb.remove_del (s); i--; } } tb.sort(); return tb.getnb(); } static const char DEVICE[]="DEVICE"; static const char IPADDR[]="IPADDR"; static const char NETMASK[]="NETMASK"; static const char NETWORK[]="NETWORK"; static const char BROADCAST[]="BROADCAST"; static const char BOOTPROTO[]="BOOTPROTO"; static const char ONBOOT[]="ONBOOT"; static const char PCMCIA[]="PCMCIA"; static const char YES[]="yes"; static const char NO[]="no"; static const char *tbipxframe[]={ "802_2","802_3","ETHERII","SNAP" }; static const char K_IPXNETNUM[]="IPXNETNUM"; static const char K_IPXPRIMARY[]="IPXPRIMARY"; static const char K_IPXACTIVE[]="IPXACTIVE"; static void devinfo_setipxvars ( int noframe, char varnetnum[20], char varprimary[20], char varactive[20]) { sprintf (varnetnum,"%s_%s",K_IPXNETNUM,tbipxframe[noframe]); sprintf (varprimary,"%s_%s",K_IPXPRIMARY,tbipxframe[noframe]); sprintf (varactive,"%s_%s",K_IPXACTIVE,tbipxframe[noframe]); } static void devinfo_ipx_loadinter (VIEWITEMS &items, IPX_INTER_INFO &itf) { for (int f=0; fnetnum = items.locatehval (varnetnum); fra->primary = items.locatebval (varprimary); fra->active = items.locatebval (varactive); } } int devinfo_load(HOSTS &hosts, HOSTINFO &info) { SSTRINGS tb; int n = devinfo_getlist (tb,true); int nbdev = 0; char hostname[PATH_MAX]; filter_gethostname (hostname); info.hostname.setfrom (hostname); for (int i=0; iget(); VIEWITEMS items; CONFIG_FILE file(path,help_nil ,CONFIGF_MANAGED|CONFIGF_OPTIONAL ,"root","root",0755); if (items.read (file) != -1){ char tmp[1000]; const char *ipnum = items.locateval(IPADDR,tmp); INTER_INFO *itf = &info.a[nbdev++]; itf->ipaddr.setfrom (ipnum); itf->device.setfrom (items.locateval(DEVICE,tmp)); itf->netmask.setfrom (items.locateval(NETMASK,tmp)); /* #Specification: conectiva ifcfg file / network and bcast The files /etc/sysconfig/network-scripts/ifcfg-DEV (eth0,...) had originally NETWORK and BROADCAST field. Linuxconf never update those fields and computes the value using the IP address and the netmask. So those value are ignored. Some conectiva utilities still write them (the installation I think). */ //itf->network.setfrom (items.locateval(NETWORK,tmp)); //itf->bcast.setfrom (items.locateval(BROADCAST,tmp)); const char *proto = items.locateval(BOOTPROTO,tmp); if (proto == NULL || strcmp(proto,"none")==0){ itf->confmode = INTER_MANUAL; }else if (strcmp(proto,"bootp")==0){ itf->confmode = INTER_BOOTP; }else if (strcmp(proto,"dhcp")==0){ itf->confmode = INTER_DHCP; } itf->enable = items.locatebval(ONBOOT,1); itf->pcmcia = items.locatebval(PCMCIA); devinfo_ipx_loadinter (items,itf->ipx); } } info.nbdev = nbdev; for (int j=0; jipaddr.get()); if (hst != NULL){ pti->name.setfrom (hst->getname1()); pti->others.setfrom (hst->getothers()); } } return nbdev; } static void devinfo_ipx_saveinter (VIEWITEMS &items, IPX_INTER_INFO &itf) { for (int f=0; fnetnum == 0){ items.update (varnetnum,""); }else{ items.updatehval (varnetnum,fra->netnum); } items.updatebval (varprimary,fra->primary); items.updatebval (varactive,fra->active); } } void devinfo_remove ( VIEWITEMS &items, const char *var) { VIEWITEM *it = items.locateassign(var); items.remove_del (it); } int devinfo_save(HOSTS &hosts, HOSTINFO &info) { int ret = 0; SSTRINGS tb; int n = devinfo_getlist (tb,true); // First, remove all ifcfg-device which are not configured any more for (int i=0; iget(); VIEWITEMS items; CONFIG_FILE file(path,help_nil ,CONFIGF_MANAGED|CONFIGF_OPTIONAL ,"root","root",0755); if (items.read (file) != -1){ char tmp[1000]; const char *dev = items.locateval(DEVICE,tmp); bool found = false; for (int d=0; dipaddr.is_empty() || itf->confmode != INTER_MANUAL) && itf->device.cmp(dev)==0){ found = true; break; } } if (!found){ file.unlink (); } } } // Now update or create the information for (int d=0; ddevice.is_empty()){ const char *ipaddr = itf->ipaddr.get(); bool validip = ipaddr[0] != '\0'; if (validip || itf->confmode != INTER_MANUAL){ char path[PATH_MAX]; sprintf (path,"%s%s",scripts_path,itf->device.get()); VIEWITEMS items; CONFIG_FILE file(path,help_nil ,CONFIGF_MANAGED|CONFIGF_OPTIONAL ,"root","root",0755); if (!file.exist() || items.read (file) != -1){ char tmp[1000]; const char *old_ipaddr = items.locateval(IPADDR,tmp); if (old_ipaddr == NULL || strcmp(old_ipaddr, ipaddr) != 0) { // if IP address has changed, remove obsolete items devinfo_remove (items,BROADCAST); devinfo_remove (items,NETWORK); } items.update (DEVICE,itf->device); items.update (IPADDR,ipaddr); items.update (NETMASK,itf->netmask); items.update (ONBOOT,itf->enable ? YES : NO); static const char *tbproto[]={ "none","dhcp","bootp" }; items.update (BOOTPROTO,tbproto[itf->confmode]); devinfo_ipx_saveinter (items,itf->ipx); ret |= items.write (file,NULL); } } HOST *hst = NULL; const char *name = itf->name.get(); if (name[0] != '\0'){ hst = hosts.getitem (name); } const char *others = itf->others.get(); if (hst == NULL && others[0] != '\0'){ char first[PATH_MAX]; str_copyword (first,others,PATH_MAX-1); hst = hosts.getitem (first); } if (validip){ if (hst == NULL){ hst = hosts.getbyip (ipaddr); } if (name[0] != '\0' || others[0] != '\0'){ if (hst == NULL){ hst = new HOST; hosts.add (hst); } hst->setipnum (ipaddr); hst->setname1 (name); hst->setothers (others); }else if (hst != NULL){ hosts.remove_del (hst); } }else if (hst != NULL){ // No IP number supplied hosts.remove_del (hst); } } } hosts.write (); filter_sethostname (info.hostname.get()); return ret; } class CONFIG_FILE_DEVLIST: public CONFIG_FILE{ /*~PROTOBEG~ CONFIG_FILE_DEVLIST */ public: CONFIG_FILE_DEVLIST (void); int archive (SSTREAM&ss)const; int extract (SSTREAM&ss); /*~PROTOEND~ CONFIG_FILE_DEVLIST */ }; PUBLIC CONFIG_FILE_DEVLIST::CONFIG_FILE_DEVLIST() : CONFIG_FILE ("/etc/sysconfig/landev.list",help_nil,CONFIGF_VIRTUAL ,subsys_stationid) { } PUBLIC int CONFIG_FILE_DEVLIST::archive(SSTREAM &ss) const { configf_sendexist (ss,true); SSTRINGS tb; int n = devinfo_getlist (tb,false); for (int i=0; iget(); ss.printf ("%s\n",path); } return 0; } PUBLIC int CONFIG_FILE_DEVLIST::extract(SSTREAM &ss) { SSTRINGS tbold; devinfo_getlist (tbold,false); SSTRINGS tb; char path[PATH_MAX]; while (ss.gets(path,sizeof(path)-1) != NULL){ strip_end (path); tb.add (new SSTRING (path)); } for (int i=0; iget(); CONFIG_FILE conf (path,help_nil,CONFIGF_MANAGED|CONFIGF_OPTIONAL ,subsys_stationid); conf.extract(); } // Erase the config files which were not part of the archive for (int j=0; jget(); if (tb.lookup(path)==-1){ net_prtlog (NETLOG_CMD,MSG_U(I_REMOVING,"Removing device configuration: %s\n") ,path); ::unlink (path); } } return 0; } static CONFIG_FILE_DEVLIST devlist; static void devinfo_listcfg() { SSTRINGS lst; int n = devinfo_getlist (lst,false); for (int i=0; iget(),help_nil ,CONFIGF_MANAGED|CONFIGF_OPTIONAL ,subsys_stationid); } } static CONFIG_FILE_LISTER lister (devinfo_listcfg); /* Extract the list of ifcfg alias files related to one LAN devices */ static int devinfo_ipalias_getlist(const char *devname, SSTRINGS &tb) { char path[PATH_MAX]; sprintf (path,"%s%s:",scripts_path,devname); dir_getlist_p (path,tb); for (int i=0; iget(); if (strstr(fname,".OLD")!=NULL || strstr(fname,".bak")!=NULL || strchr(fname,'~')!=NULL){ tb.remove_del(i); i--; } } tb.sort(); return tb.getnb(); } /* Read all the ifcfg-xxx:y file and store the IP address in tb Return the number of items collected. */ int devinfo_ipalias_load ( const char *devname, SSTRINGS &tb, SSTRINGS &masks) { SSTRINGS tbf; int n = devinfo_ipalias_getlist (devname,tbf); for (int i=0; iget(); CONFIG_FILE conf (path,help_nil,CONFIGF_MANAGED|CONFIGF_OPTIONAL ,subsys_stationid); VIEWITEMS items; if (items.read (conf) != -1){ char tmp[1000]; const char *ip = items.locateval (IPADDR,tmp); tb.add (new SSTRING(ip)); const char *mk = items.locateval (NETMASK,tmp); masks.add (new SSTRING(mk)); } } return tb.getnb(); } /* Update the ifcfg-xxx:y file */ int devinfo_ipalias_save ( const char *devname, const SSTRINGS &tb, const SSTRINGS &masks) { int ret = 0; SSTRINGS tbf; devinfo_ipalias_getlist (devname,tbf); int i; for (i=0; iget()); items.update (NETMASK,masks.getitem(i)->get()); ret = items.write (conf,NULL); int lk = tbf.lookup (path); if (lk != -1) tbf.remove_del (lk); } if (ret != -1){ // Remove all extra ifcfg-xxx:y file for (i=0; iget()); } return ret; }