#include #include #include #include #include <../../libmodules/guruengine/guruengine.h> #include "xterminals.h" #include "xterminals.m" #include #include #include #include #include "../module_apis/servicectl_api.h" #include static HELP_FILE help_review ("xterminals","review"); static HELP_FILE help_nfs ("xterminals","nfs"); static HELP_FILE help_dns ("xterminals","dns"); static HELP_FILE help_hosts ("xterminals","hosts"); static HELP_FILE help_xfs ("xterminals","xfs"); static HELP_FILE help_dhcp ("xterminals","dhcp"); static HELP_FILE help_xdm ("xterminals","xdm"); static HELP_FILE help_services ("xterminals","services"); static HELP_FILE help_desktop ("xterminals","desktop"); static HELP_FILE help_interfaces ("xterminals","interfaces"); static HELP_FILE help_nis ("xterminals","nis"); static HELP_FILE help_nfshome ("xterminals","nfshome"); static CONFIG_FILE f_xfs ("/etc/X11/fs/config",help_xfs,CONFIGF_MANAGED); static CONFIG_FILE f_sysvxfs ("/etc/rc.d/init.d/xfs",help_xfs,CONFIGF_MANAGED ,"root","root",0755); static CONFIG_FILE f_access ("/etc/X11/xdm/Xaccess",help_xdm,CONFIGF_MANAGED); static CONFIG_FILE f_xdmconfig ("/etc/X11/xdm/xdm-config",help_xdm,CONFIGF_MANAGED); static CONFIG_FILE f_gdmconf ("/etc/X11/gdm/gdm.conf",help_xdm,CONFIGF_MANAGED); static CONFIG_FILE f_kdmrc ("/etc/kde/kdm/kdmrc",help_xdm,CONFIGF_MANAGED|CONFIGF_OPTIONAL); static CONFIG_FILE f_xconfig ("/etc/X11/XF86Config",help_xdm ,CONFIGF_MANAGED|CONFIGF_OPTIONAL); static CONFIG_FILE f_xconfig4 ("/etc/X11/XF86Config-4",help_xdm ,CONFIGF_MANAGED|CONFIGF_OPTIONAL); const char K_XTERMREVIEW[]="xtermreview"; static const char K_STARTIP[]="startip"; static const char K_ENDIP[]="endip"; static const char K_NFSNEEDED[]="nfsneeded"; static const char K_XFSNEEDED[]="xfsneeded"; static const char K_DNSNEEDED[]="dnsneeded"; static const char K_XDMNEEDED[]="xdmneeded"; static const char K_DHCPNEEDED[]="dhcpneeded"; static const char K_NISNEEDED[]="nisneeded"; static SSTRINGS knownpkgs; // Cache the last successful requests static const char *tbargs[]={"generic-package-name",NULL}; static MESSAGE_DEF check_package ("check_package",tbargs); static MESSAGE_DEF install_package ("install_package",tbargs); /* Check if a given logical package is installed. Return true if yes. */ static bool review_checkpkg(const char *pkg) { bool ret = true; if (knownpkgs.lookup(pkg)==-1){ const char *tb[]={pkg}; int ok = module_sendmessage (check_package,1,tb); if (ok == LNCF_NOT_APPLICABLE) ok = 0; ret = ok == 0 ? true : false; if (ret) knownpkgs.add (new SSTRING(pkg)); } return ret; } /* Trigger the installation of a package */ static int review_installpkg (const char *pkg) { const char *tb[]={pkg}; return module_sendmessage (install_package,1,tb); } struct DEVSETUP { SSTRING devname; SSTRING network; unsigned long net,mask; SSTRING netmask; SSTRING startip; SSTRING endip; bool configured; }; static int review_readdev (DEVSETUP devs[10]) { int ret = 0; #if 1 HOSTS hosts; NETWORKS networks; HOSTINFO info; if (netconf_loadinfos(hosts,networks,info)!=-1){ ret = 0; for (int i=0; iconfmode == INTER_MANUAL){ if (a->netmask.is_empty()){ a->netmask.setfrom (ipnum_getdefaultmask( a->ipaddr.get())); } DEVSETUP *dev = devs + ret++; dev->devname.setfrom (a->device); dev->netmask.setfrom (a->netmask); long ipn = ipnum_aip2l (a->ipaddr.get()); dev->mask = ipnum_aip2l (a->netmask.get()); dev->net = ipn & dev->mask; char netstr[LEN_IP_ASC]; ipnum_ip2a (dev->net,netstr); dev->network.setfrom (netstr); SSTRING tmp; tmp.setfromf ("%s-%s",K_STARTIP,netstr); const char *ip = linuxconf_getval(K_XTERMREVIEW,tmp.get()); dev->configured = false; if (ip != NULL){ dev->configured = true; dev->startip.setfrom (ip); tmp.setfromf ("%s-%s",K_ENDIP,netstr); dev->endip.setfrom (linuxconf_getval(K_XTERMREVIEW ,tmp.get())); }else{ int offset = 50; // we leave 50 IP for static allocation // if there is room if ((dev->mask & 0xff)!=0) offset = 1; ipnum_ip2a (dev->net+offset,netstr); dev->startip.setfrom (netstr); ipnum_ip2a ((dev->net|(~dev->mask))-1,netstr); dev->endip.setfrom (netstr); } } } } #else SSTRINGS tb; int nbdev = devlist_read (tb); int nb = 0; for (int i=0; iget(); if (strcmp(devname,"lo")!=0 && strncmp(devname,"brg",3)!=0){ IFCONFIG_INFO info; if (ifconfig_getinfo_nocheck (devname,info)!=-1){ DEVSETUP *dev = devs + nb; dev->devname.setfrom (devname); dev->netmask.setfrom (info.netmask); long ipn = ipnum_aip2l (info.ip_addr); dev->mask = ipnum_aip2l (info.netmask); dev->net = ipn & dev->mask; char netstr[LEN_IP_ASC]; ipnum_ip2a (dev->net,netstr); dev->network.setfrom (netstr); SSTRING tmp; tmp.setfromf ("%s-%s",K_STARTIP,netstr); const char *ip = linuxconf_getval(K_XTERMREVIEW,tmp.get()); dev->configured = false; if (ip != NULL){ dev->configured = true; dev->startip.setfrom (ip); tmp.setfromf ("%s-%s",K_ENDIP,netstr); dev->endip.setfrom (linuxconf_getval(K_XTERMREVIEW ,tmp.get())); }else{ int offset = 50; // we leave 50 IP for static allocation // if there is room if ((dev->mask & 0xff)!=0) offset = 1; ipnum_ip2a (dev->net+offset,netstr); dev->startip.setfrom (netstr); ipnum_ip2a ((dev->net|(~dev->mask))-1,netstr); dev->endip.setfrom (netstr); } nb++; } } } ret = nb; #endif return ret; } /* Check if an IP number is valid and within tne network range */ static bool review_checkip (DEVSETUP *dev, SSTRING &ip) { bool ret = false; const char *ipstr = ip.get(); if (!ipnum_validip(ipstr,true)){ xconf_error (MSG_R(E_IVLDIP),ipstr); }else{ unsigned long num = ipnum_aip2l (ipstr); unsigned long start = dev->net+1; unsigned long end = (dev->net|(~dev->mask))-1; if (num >= start && num <= end){ ret = true; }else{ char startstr[LEN_IP_ASC],endstr[LEN_IP_ASC]; ipnum_ip2a (start,startstr); ipnum_ip2a (end,endstr); xconf_error (MSG_U(E_IPINRANGE ,"IP number %s must in the range\n" "%s to %s"),ipstr,startstr,endstr); } } return ret; } static bool nfs_isok(bool &errors) { bool ret = false; errors = false; master_registry.start_session(); bool root_ro = false; bool root_exist = master_registry.get("nfs.directory./xterminals/root") != NULL; if (root_exist){ const char *s = master_registry.get("nfs.readwrite./xterminals/root"); if (s != NULL && s[0] == '0') root_ro = true; } bool var_rw = false; bool var_squash = false; bool var_exist = master_registry.get("nfs.directory./var/xterminals") != NULL; if (var_exist){ const char *s = master_registry.get("nfs.readwrite./var/xterminals"); if (s != NULL && s[0] == '1') var_rw = true; s = master_registry.get("nfs.norootsquash./var/xterminals"); if (s != NULL && s[0] == '1') var_squash = true; } if (root_exist && root_ro && var_exist && var_rw && var_squash){ ret = true; } master_registry.end_session(); return ret; } static bool nfspkg_isok() { bool ret = review_checkpkg("nfsserver"); if (ret){ ret = review_checkpkg ("portmap"); } return ret; } static bool review_checkservice (const char *name, bool test) { bool ret = false; SERVICES services; SERVICECTL_API *tb[MAX_API_PROVIDERS]; int nb = servicectl_apis_init("xterminals/review",tb); for (int i=0; icollect(services); } for (int i=0; iname.cmp(name)==0){ ret = s->state == 0; if (!test && !ret){ s->edit(); ret = s->state == 0; } break; } } return ret; } static bool nfsserv_isok(bool test) { return review_checkservice ("portmap",test) && review_checkservice ("nfs",test) && review_checkservice ("nfslock",test); } /* #define _TLMP_servcheck struct _F_servcheck{ #define _F_servcheck_evalpkg(nom) void nom evalpkg(GURUPATH_MODE mode, GURUPATH_STATUS &status) virtual _F_servcheck_evalpkg( )=0; #define _F_servcheck_dialogpkg(nom) void nom dialogpkg() virtual _F_servcheck_dialogpkg( )=0; #define _F_servcheck_evalconf(nom) void nom evalconf(GURUPATH_MODE mode, GURUPATH_STATUS &status) virtual _F_servcheck_evalconf( )=0; #define _F_servcheck_dialogconf(nom) void nom dialogconf() virtual _F_servcheck_dialogconf( )=0; #define _F_servcheck_evalserv(nom) void nom evalserv(GURUPATH_MODE mode, GURUPATH_STATUS &status) virtual _F_servcheck_evalserv( )=0; #define _F_servcheck_dialogserv(nom) void nom dialogserv() virtual _F_servcheck_dialogserv( )=0; }; static int servcheck(_F_servcheck &c, GURUPATH_MODE mode, GURUPATH_STATUS &status) { _F_servcheck *c; glocal.c = &c; (mode,status); glocal.c->evalpkg(mode,status); glocal.c->dialogpkg(); glocal.c->evalconf(mode,status); glocal.c->dialogconf(); glocal.c->evalserv(mode,status); glocal.c->dialogserv(); } */ static void review_nfs (char &possible, GURUPATH_MODE mode, GURUPATH_STATUS &status) { char possible; glocal.possible = possible; (mode,status); settitle (MSG_U(T_NFSNEEDED,"Is NFS needed")); status.is_filled = glocal.possible != 255; setintro (MSG_U(I_NFSNEEDED ,"The X terminals are getting their runtime and\n" "configuration files from an NFS server.\n" "This servers publishes two directories\n" "\t/xterminals/root, read only\n" "\t/var/xterminals, read/write during configuration.\n")); char needed = glocal.possible == 255 ? 1 : glocal.possible; dia.newf_chk (MSG_U(F_NFSNEEDED,"Network File Service"),needed,MSG_U(I_ISNEEDED,"is needed")); if (edit (help_nfs)){ glocal.possible = needed; } (mode,status); settitle (MSG_U(T_NFS,"NFS configuration")); status.is_possible = glocal.possible == 1; status.is_filled = nfs_isok (status.some_errors); bool errors; if (nfs_isok(errors) && !errors){ allfine(); setintro (MSG_U(I_NFSOK,"The NFS server is already properly configured")); }else{ attention(); setintro (MSG_U(I_NFSNOTOK ,"The NFS server is not properly configured\n" "We will export the following directories\n" "\t/xterminals/root: read only\n" "\t/var/xterminals : read/write during terminal configuration")); } if (edit (help_nfs)){ master_registry.start_session(); master_registry.set("nfs.directory./xterminals/root","/xterminals/root"); master_registry.set("nfs.readwrite./xterminals/root","0"); master_registry.set("nfs.client./xterminals/root","*"); master_registry.set("nfs.directory./var/xterminals","/var/xterminals"); master_registry.set("nfs.readwrite./var/xterminals","1"); master_registry.set("nfs.norootsquash./var/xterminals","1"); master_registry.set("nfs.client./var/xterminals","*"); master_registry.end_session(); } settitle (MSG_U(T_NFSPACKAGES,"NFS packages")); status.is_possible = glocal.possible; status.is_filled = nfspkg_isok(); if (nfspkg_isok()){ allfine(); setintro (MSG_U(I_NFSPKGOK,"The NFS server is properly installed")); edit (help_nfs); }else{ attention(); setintro (MSG_U(I_NFSPKGNOTOK ,"The NFS server is not properly installed\n" "We will install the appropriate packages")); if (edit (help_nfs)){ module_requestpkg ("nfsserver"); } } settitle (MSG_U(T_NFSSERVICE,"NFS services")); status.is_possible = glocal.possible && nfspkg_isok(); status.is_filled = nfsserv_isok(true); setterminal (MSG_U(T_NFSCONF,"NFS configuration") ,MSG_R(T_NFSCONF)); if (nfsserv_isok(true)){ allfine(); setintro (MSG_U(I_NFSSERVICEOK,"The NFS services are running")); edit (help_nfs); }else{ attention(); setintro (MSG_U(I_NFSSERVICENOTOK ,"The NFS server is not configured to run\n" "We will turn the various services on\n" "These include\n" "\tportmap\n" "\tnfs\n" "\tnfslock")); if (edit (help_nfs)){ nfsserv_isok (false); } } possible = glocal.possible; } /* Check if /etc/hosts contains dummy entries to please the NFS server. */ static bool hosts_filled (DEVSETUP *devs, int nbdev, bool test) { bool ret = true; HOSTS hosts; hosts.read(); for (int i=0; istartip.is_filled()){ unsigned long startip = ipnum_aip2l (dev->startip.get()); unsigned long endip = ipnum_aip2l (dev->endip.get()); for (unsigned long a=startip; a<=endip; a++){ char ip[LEN_IP_ASC]; ipnum_ip2a (a,ip); if (hosts.getbyip(ip)==NULL){ ret = false; if (test){ break; }else{ char name[20]; sprintf (name,"%st%lu",dev->devname.get(),a&0xff); hosts.add (new HOST(ip,name,"","")); // fprintf (stderr,"Add %s %s\n",ip,name); } } } } } if (!test && !ret) hosts.write(); return ret; } static void review_dns ( char &possible, DEVSETUP devs[], int nbdev, GURUPATH_MODE mode, GURUPATH_STATUS &status) { char possible; DEVSETUP *devs; int nbdev; glocal.nbdev = nbdev; glocal.devs = devs; glocal.possible = possible; (mode,status); settitle (MSG_U(T_DNSNEEDED,"Is DNS needed")); status.is_filled = glocal.possible != 255; setintro (""); char needed = glocal.possible == 255 ? 1 : glocal.possible; dia.newf_chk (MSG_U(F_DNSNEEDED,"Domain name server"),needed,MSG_R(I_ISNEEDED)); if (edit (help_dns)){ glocal.possible = needed; } // We want a DNS (mode,status); status.is_possible = glocal.possible == 1; setterminal (MSG_U(T_DNSCONF,"DNS configuration") ,MSG_R(T_DNSCONF)); edit (help_dns); // No DNS we will fill /etc/hosts (mode,status); settitle (MSG_U(T_ETCHOSTS,"/etc/hosts setup")); status.is_possible = glocal.possible == 0; status.is_filled = hosts_filled (glocal.devs,glocal.nbdev,true); setterminal (MSG_U(T_NODNSCONF,"Without DNS configuration") ,MSG_R(T_NODNSCONF)); if (hosts_filled(glocal.devs,glocal.nbdev,true)){ allfine(); setintro (MSG_U(I_ETCHOSTSOK ,"File /etc/hosts already has the entries to please\n" "the NFS server.")); edit (help_hosts); }else{ attention(); setintro (MSG_U(I_ETCHOSTSNOTOK ,"Some entries must be added to /etc/hosts to please\n" "the NFS server.\n" "/etc/hosts will be modified")); if (edit (help_hosts)){ hosts_filled(glocal.devs,glocal.nbdev,false); } } possible = glocal.possible; } /* Is the XFS package installed */ static bool xfspkg_isok() { return review_checkpkg ("xfsserver"); } /* Check the XF86Config file to change the xfs configuration */ static void xconfig_isok (bool test,CONFIG_FILE &conf, bool &ret) { // Check the X configuration file. Originally, this is the way they // used to disabled TCP, by specifying a port of -1, so X had to be told FILE_CFG *fin = conf.fopen ("r"); if (fin != NULL){ FILE_CFG *fout = NULL; if (!test) fout = conf.fopen ("/etc/X11/XF86Config.tmp","w"); char buf[1000]; while (fgets(buf,sizeof(buf)-1,fin)!=NULL){ char *pt = strstr(buf,"unix/:-1"); if (pt != NULL){ // fprintf (stderr,"Find -1 in X config\n"); ret = false; char tmp[1000]; strcpy (tmp,pt+8); strcpy (pt,"unix/:7100"); strcat (pt,tmp); } if (fout != NULL){ fputs (buf,fout); } } if (fout != NULL){ fclose (fout); if (!ret){ rename ("/etc/X11/XF86Config.tmp",conf.getpath()); } } fclose (fin); } } /* Is it configured to support X terminals */ static bool xfsconfig_isok(bool test) { bool ret = true; VIEWITEMS items; items.read (f_xfs); VIEWITEM *it = items.locateassign ("no-listen"); if (it != NULL){ ret = false; // We comment out the line it->line.setfromf ("# %s",it->line.get()); // fprintf (stderr,"Enlevel no-listen\n"); } it = items.locateassign ("clone-self"); if (it == NULL){ ret = false; it = new VIEWITEM("clone-self = on"); items.add (it); // fprintf (stderr,"Ajoute clone-self\n"); }else{ const char *pt = it->line.strchr('='); if (pt != NULL){ pt = str_skip(pt+1); if (strcmp(pt,"on")!=0){ ret = false; it->line.setfrom ("clone-self = on"); // fprintf (stderr,"Patch clone-self\n"); } } } if (!test) items.write (f_xfs,NULL); // Check the sysv service. Originally, this is the way they // used to disabled TCP, by specifying a port of -1 FILE_CFG *fin = f_sysvxfs.fopen ("r"); if (fin != NULL){ FILE_CFG *fout = NULL; if (!test) fout = f_sysvxfs.fopen ("/etc/rc.d/init.d/xfs.tmp","w"); char buf[1000]; while (fgets(buf,sizeof(buf)-1,fin)!=NULL){ char *pt = strstr(buf,"-port"); if (pt != NULL){ pt = str_skip(pt+5); if (strncmp(pt,"-1",2)==0){ // fprintf (stderr,"Find -1 in xfs sysv\n"); ret = false; char tmp[1000]; strcpy (tmp,pt+2); strcpy (pt,"7100"); strcat (pt,tmp); } } if (fout != NULL){ fputs (buf,fout); } } if (fout != NULL){ fclose (fout); if (!ret){ rename ("/etc/rc.d/init.d/xfs.tmp",f_sysvxfs.getpath()); } } fclose (fin); } xconfig_isok (test,f_xconfig,ret); xconfig_isok (test,f_xconfig4,ret); return ret; } /* Is the service configure to run */ static bool xfsserv_isok(bool test) { return review_checkservice ("xfs",test); } static void review_xfs (char &possible, GURUPATH_MODE mode, GURUPATH_STATUS &status) { char possible; glocal.possible = possible; (mode,status); settitle (MSG_U(T_XFSNEEDED,"Is XFS needed")); status.is_filled = glocal.possible != 255; setintro (MSG_U(I_XFSNEEDED ,"The X Font Server (XFS) is used by the server\n" "when run in graphical mode and by the X terminals")); char needed = glocal.possible == 255 ? 1 : glocal.possible; dia.newf_chk (MSG_U(F_XFSNEEDED,"X Font server"),needed,MSG_R(I_ISNEEDED)); if (edit (help_xfs)){ glocal.possible = needed; } (mode,status); settitle (MSG_U(T_FONTPKG,"Font server package")); status.is_possible = glocal.possible; status.is_filled = xfspkg_isok(); if (xfspkg_isok()){ allfine(); setintro (MSG_U(I_FONTPKGOK,"The XFS package is already installed")); edit(help_xfs); }else{ attention(); setintro (MSG_U(I_FONTPKGNOTOK ,"The XFS package is not already installed.\n" "We will install it")); if (edit(help_xfs)){ module_requestpkg ("xfsserver"); } } settitle (MSG_U(T_FONTCONF,"Font server configuration")); status.is_possible = glocal.possible && xfspkg_isok(); status.is_filled = xfsconfig_isok(true); if (xfsconfig_isok(true)){ allfine(); setintro (MSG_U(I_FONTCONFOK,"The font server is properly configured")); edit(help_xfs); }else{ attention(); setintro (MSG_U(I_FONTCONFNOTOK ,"The font server is not properly configured\n" "We will do the following:\n" "\tTurn on process cloning\n" "\tEnable TCP port 7100\n" "\tFix the server X configuration\n" "\tFix the xfs startup script")); if (edit(help_xfs)){ xfsconfig_isok(false); } } settitle (MSG_U(T_XFSSERVICE,"Font server service")); status.is_possible = glocal.possible; status.is_filled = xfsserv_isok(true); setterminal (MSG_U(T_XFSCONF,"Font server configuration") ,MSG_R(T_XFSCONF)); if (xfsserv_isok(true)){ allfine(); setintro (MSG_U(I_XFSSERVICEOK ,"The font server is running")); edit(help_xfs); }else{ attention(); setintro (MSG_U(I_XFSSERVICENOTOK ,"The font server is not configured to run.\n" "We will enable the xfs service")); if (edit(help_xfs)){ xfsserv_isok(false); } } possible = glocal.possible; } /* Is the DHCP package installed */ static bool dhcppkg_isok() { return review_checkpkg ("dhcpserver"); } /* Retrieve a value from a subnet definition in the dhcp configuration */ static const char *dhcp_getregistry (const char *network, const char *var) { char tmp[100]; snprintf (tmp,sizeof(tmp)-1,"dhcpd.%s.%s",var,network); return master_registry.get (tmp); } /* Set a value in a subnet of the dhcp configuration */ static int dhcp_setregistry ( const char *network, const char *var, const char *val) { char tmp[100]; snprintf (tmp,sizeof(tmp)-1,"dhcpd.%s.%s",var,network); return master_registry.set (tmp,val); } /* Is it configured to support X terminals */ static bool dhcpconf_isok(DEVSETUP *devs, int nbdev, bool test) { bool ret = true; master_registry.start_session(); const char *serverid = master_registry.get ("dhcpd.serverid"); if (serverid==NULL || serverid[0] == '\0'){ ret = false; if (!test){ THISHOST th; master_registry.set ("dhcpd.serverid",th.getname1()); master_registry.set ("dhcpd.domain-name",th.getdomain()); master_registry.end_session(); master_registry.start_session(); } } if (ret || !test){ for (int i=0; istartip.get(); if (startip[0] != '\0'){ const char *network = dev->network.get(); const char *startip_cfg = dhcp_getregistry (network,"startip"); const char *endip_cfg = dhcp_getregistry (network,"stopip"); const char *dynbootp_cfg = dhcp_getregistry (network,"dynbootp"); if (startip_cfg == NULL || strcmp(startip_cfg,startip)!=0 || endip_cfg == NULL || dev->endip.cmp(endip_cfg)!=0 || dynbootp_cfg == NULL || dynbootp_cfg[0] != '1'){ ret = false; if (!test){ dhcp_setregistry (network,"network",network); dhcp_setregistry (network,"netmask",dev->netmask.get()); dhcp_setregistry (network,"startip",startip); dhcp_setregistry (network,"stopip",dev->endip.get()); dhcp_setregistry (network,"dynbootp","1"); } } } } } master_registry.end_session(); return ret; } /* Is the service configure to run */ static bool dhcpserv_isok(bool test) { return review_checkservice ("dhcpd",test); } static void review_dhcp ( char &possible, DEVSETUP devs[], int nbdev, GURUPATH_MODE mode, GURUPATH_STATUS &status) { char possible; DEVSETUP *devs; int nbdev; glocal.nbdev = nbdev; glocal.devs = devs; glocal.possible = possible; (mode,status); settitle (MSG_U(T_DHCPNEEDED,"Is DHCP needed")); status.is_filled = glocal.possible != 255; setintro (""); char needed = glocal.possible == 255 ? 1 : glocal.possible; dia.newf_chk (MSG_U(F_DHCPNEEDED,"DHCP server"),needed,MSG_R(I_ISNEEDED)); if (edit (help_dhcp)){ glocal.possible = needed; } // Check if dhcp is installed settitle (MSG_U(T_DHCPPKG,"DHCP server package")); status.is_possible = glocal.possible; status.is_filled = dhcppkg_isok(); if (dhcppkg_isok()){ allfine(); setintro (MSG_U(I_DHCPPKGOK,"The DHCP package is already installed")); edit(help_dhcp); }else{ attention (); setintro (MSG_U(I_DHCPPKGNOTOK ,"The DHCP package is not installed\n" "We will do so now")); if (edit(help_dhcp)){ review_installpkg ("dhcpserver"); } } // Check if the linuxconf dhcpd module is enabled settitle (MSG_U(T_DHCPDMODULE,"Linuxconf dhcpd module")); status.is_possible = true; status.is_filled = module_is_enabled ("dhcpd"); if (module_is_enabled("dhcpd")){ allfine(); setintro (MSG_U(I_DHCPDMODULE,"The DHCP configuration module is already enabled")); edit(help_dhcp); }else{ attention (); setintro (MSG_U(I_DHCPDMODULENOTOK ,"The DHCP configuration module is not enabled.\n" "We will enable it immediatly.")); if (edit(help_dhcp)){ module_setone ("dhcpd",true,true); module_load(); } } // Check if it is configured settitle (MSG_R(T_DHCPCONF)); status.is_possible = glocal.possible && dhcppkg_isok(); status.is_filled = dhcpconf_isok(glocal.devs,glocal.nbdev,true); if (dhcpconf_isok(glocal.devs,glocal.nbdev,true)){ allfine(); setintro (MSG_U(I_DHCPCONFOK,"The DHCP server is already configured")); edit (help_dhcp); }else{ attention (); setintro (MSG_U(I_DHCPCONFNOTOK ,"The DHCP server is not configured\n" "We will add the subnet definition\n" "for all needed interfaces")); if (edit(help_dhcp)){ dhcpconf_isok(glocal.devs,glocal.nbdev,false); } } // Is it configured to run settitle (MSG_U(T_DHCPSERVICE,"DHCP service")); status.is_possible = glocal.possible && dhcpconf_isok(glocal.devs,glocal.nbdev,true); status.is_filled = dhcpserv_isok(true); setterminal (MSG_U(T_DHCPCONF,"DHCP server configuration") ,MSG_R(T_DHCPCONF)); if (dhcpserv_isok(true)){ allfine(); setintro (MSG_U(I_DHCPSERVICEOK,"The DHCP service is configured to run")); edit (help_dhcp); }else{ attention (); setintro (MSG_U(I_DHCPSERVICENOTOK ,"The DHCP service is not configured to run.\n" "Only one DHCP server may run on network.")); if (edit(help_dhcp)){ dhcpserv_isok(false); } } possible = glocal.possible; } static const char K_DESKTOP[]="desktop"; static const char K_DISPLAYMANAGER[]="displaymanager"; static const char *review_getdesktop() { const char *ret = distrib_getval (K_DESKTOP); if (ret == NULL) ret = "KDE"; return ret; } static const char *review_getdmanager() { const char *ret = distrib_getval (K_DISPLAYMANAGER); if (ret == NULL) ret = "KDE"; return ret; } /* Is the Display manager package installed installed */ static bool xdmpkg_isok(const char *desktop) { bool ret = true; if (desktop == NULL){ ret = false; }else if (strcasecmp(desktop,"KDE")==0){ ret = review_checkpkg ("kdebase"); }else if (strcasecmp(desktop,"GNOME")==0){ ret = review_checkpkg ("gdm"); } return ret; } /* Fix gdm.conf or kdmrc to enable xdmcp and other stuff Both files have the same layout (ini file). */ static void xdmconf_isok (CONFIG_FILE &f_conf, bool test, bool &ret) { VIEWITEMS items; items.read (f_conf); bool inxdmcp = false; // Make sure xdmcp is enable and at least 50 sessions available for (int i=0; iline.get(); if (line[0] == '['){ inxdmcp = stricmp(line,"[xdmcp]")==0; }else if (inxdmcp){ if (stricmp(line,"Enable=0")==0){ ret = false; it->line.setfrom ("Enable=1"); }else if(stricmp(line,"Enable=false")==0){ ret = false; it->line.setfrom ("Enable=true"); }else if (strncmp(line,"MaxSessions=",12)==0){ int nb = atoi(line+12); if (nb < 50){ ret = false; it->line.setfrom ("MaxSessions=50"); } } } } if (!ret && !test) items.write (f_conf,NULL); } /* Is it configured to support X terminals */ static bool xdmconf_isok(const char *desktop, bool test) { bool ret = true; if (strcasecmp(desktop,"GNOME")==0){ xdmconf_isok (f_gdmconf,test,ret); }else if (strcmp(desktop,"KDE")==0){ { VIEWITEMS items; items.read (f_access); bool found = false; for (int i=0; iline.get(); if (line[0] == '*'){ line = str_skip(line+1); if (line[0] == '\0' || line[0] == '#'){ found = true; break; } } } if (!found){ ret = false; items.insert (0,new VIEWITEM ("* # Any host may connect")); if (!test) items.write (f_access,NULL); } } { VIEWITEMS items; items.read (f_xdmconfig); VIEWITEM *it = items.locate ("DisplayManager.requestPort:"); if (it != NULL){ const char *pt = it->line.strchr(':'); if (pt != NULL){ pt = str_skip(pt+1); if (pt[0] == '0'){ // We comment out the line ret = false; it->line.setfrom ("#DisplayManager.requestPort:\t0"); if (!test) items.write (f_xdmconfig,NULL); } } } } xdmconf_isok (f_kdmrc,test,ret); } return ret; } #if 0 /* Is the service configure to run */ static bool xdmserv_isok(bool test) { return false; } #endif static void review_xdm (char &possible, GURUPATH_MODE mode, GURUPATH_STATUS &status) { char possible; glocal.possible = possible; (mode,status); settitle (MSG_U(T_XDMNEEDED,"Is XDM/KDM/GDM needed")); status.is_filled = glocal.possible != 255; setintro (""); char needed = glocal.possible == 255 ? 1 : glocal.possible; dia.newf_chk (MSG_U(F_XDMNEEDED,"X login manager"),needed,MSG_R(I_ISNEEDED)); if (edit (help_xdm)){ glocal.possible = needed; } (mode,status); settitle (MSG_U(T_DESKTOP,"Desktop selection")); status.is_possible = glocal.possible; const char *s = review_getdesktop(); status.is_filled = s != NULL && s[0] != '\0'; setintro (MSG_U(I_DESKTOP ,"The terminals may operate with several possible\n" "desktop framework. But you may want to select the default\n" "proposed to users. In general, users pick either\n" "GNOME (see http://www.gnome.org)" "\tor\n" "KDE (see http://www.kde.org)\n")); SSTRING desktop (review_getdesktop()); FIELD_COMBO *comb = dia.newf_combo (MSG_U(F_DESKTOP,"Desktop type"),desktop); comb->addopt ("GNOME"); comb->addopt ("KDE"); dia.newline(); SSTRING dmanager (review_getdmanager()); comb = dia.newf_combo (MSG_U(F_DMSEL,"Display manager"),dmanager); comb->addopt ("GNOME"); comb->addopt ("KDE"); if (edit(help_desktop)){ distrib_replace (K_DESKTOP,desktop.get()); distrib_replace (K_DISPLAYMANAGER,dmanager.get()); linuxconf_save(); } settitle (MSG_U(T_XDMPKG,"X Display Manager package installed")); const char *s = review_getdmanager(); status.is_possible = glocal.possible && s != NULL && s[0] != '\0'; status.is_filled = xdmpkg_isok(s); const char *s = review_getdmanager(); if (xdmpkg_isok(s)){ allfine(); setintro (MSG_U(I_XDMPKGOK,"The X Display manager package is already installed")); edit(help_xdm); }else{ attention(); setintro (MSG_U(I_XDMPKGNOTOK,"The X Display manager package will be installed")); if (edit(help_xdm)){ module_requestpkg ("xdmserver"); } } settitle (MSG_R(T_XDMCONF)); const char *s = review_getdmanager(); status.is_possible = glocal.possible && xdmpkg_isok(s); status.is_filled = xdmconf_isok(s,true); setterminal (MSG_U(T_XDMCONF,"Display manager configuration") ,MSG_R(T_XDMCONF)); const char *s = review_getdmanager(); if (xdmconf_isok(s,true)){ allfine(); setintro (MSG_U(I_XDMCONFOK,"The X Display manager package is already configured")); edit(help_xdm); }else{ attention(); setintro (MSG_U(I_XDMCONFNOTOK ,"The X Display manager package will be configured.\n" "This includes:\n" "\tTurn on TCP port 177\n" "\tEnabling access from anywhere")); if (edit(help_xdm)){ xdmconf_isok(s,false); } } possible = glocal.possible; } /* Check if the nisserver package is installed */ static bool nisservpkg_isok() { return review_checkpkg ("ypserv"); } /* Return true if the NIS server package is configured to run */ static bool nisserv_isok(bool test) { return review_checkservice ("ypserv",test); } /* Return true if the NIS client package is configured to run */ static bool nisclient_isok(bool test) { return review_checkservice ("ypbind",test); } static bool nisclientpkg_isok() { return review_checkpkg ("ypbind"); } /* Check if /home is exported for other servers */ static bool nisserv_home (bool test) { return false; } /* Check if /home is mounted on another server */ static bool nisclient_home (const SSTRING &server, bool test) { bool ret = true; master_registry.start_session(); const char *serv = master_registry.get("fstab-nfs.server./home"); if (serv == NULL || serv[0] == '\0'){ ret = false; if (!test){ master_registry.set ("fstab-nfs.server./home",server.get()); master_registry.set ("fstab-nfs.volume./home","/home"); master_registry.set ("fstab-nfs.mountpoint./home","/home"); } } master_registry.end_session(); return ret; } /* Return true is the NIS server is initialised for a NIS domain */ static bool nisserv_isinit(const SSTRING &domain, bool test) { bool ret = true; // Make sure the NIS domain is setupped in the kernel char kerneldom[1000]; if (getdomainname(kerneldom,1000)!=-1 && domain.cmp(kerneldom)!=0){ ret = false; if (!test) setdomainname (domain.get(),domain.getlen()); } SSTRING tmp; tmp.setfromf ("/var/yp/%s",domain.get()); if (file_type(tmp.get())!=1){ ret = false; if (!test){ netconf_system (15,"make -C /var/yp"); } } return ret; } /* Return true if the module nisconf is enabled. */ static bool review_nisconf() { return module_is_enabled ("nisconf"); } static void review_nis ( char &possible, GURUPATH_MODE mode, GURUPATH_STATUS &status) { char possible; char mainserv; SSTRING domain; SSTRING server; glocal.possible = possible; glocal.mainserv = 255; { master_registry.start_session(); const char *domain = master_registry.get("nis.domain"); const char *server = master_registry.get("nis.server"); glocal.domain.setfrom (domain); glocal.server.setfrom (server); if (domain != NULL && domain[0] != '\0'){ if (server != NULL && server[0] != '\0'){ glocal.mainserv = 0; }else{ glocal.mainserv = 1; } } master_registry.end_session(); } (mode,status); settitle (MSG_U(T_NISNEEDED,"Several X terminal servers")); status.is_filled = glocal.possible != 255; setintro (""); char needed = glocal.possible == 255 ? 0 : glocal.possible; dia.newf_chk (MSG_U(F_NISNEEDED,"User accounts"),needed,MSG_U(I_SHARED,"shared by several servers")); if (edit (help_xdm)){ glocal.possible = needed; } // Is this the NIS server or a client settitle (MSG_U(T_SERVERROLE,"Server role")); status.is_possible = glocal.possible == 1; status.is_filled = glocal.mainserv != 255; setintro (MSG_U(I_SERVERROLE ,"When you share accounts between\n" "several servers, one is the master server\n" "and the other are the satellites.\n" "The master server generally store both the accounts\n" "description as well as the account data (homes).")); char mainserv = glocal.mainserv == 255 ? 1 : glocal.mainserv; dia.newf_chk (MSG_U(F_THISSERVER,"This server"),mainserv ,MSG_U(I_ISMAIN,"is the main server")); if (edit(help_nis)){ glocal.mainserv = mainserv; } // domain NIS settitle (MSG_U(T_NISDOMAIN,"NIS domain")); status.is_possible = glocal.possible == 1; status.is_filled = glocal.domain.is_filled(); setintro (MSG_U(I_NISDOMAIN ,"This NIS domain is a name shared by the main server\n" "and the satellite server. We often use the DNS domain\n" "although this is totally unrelated")); dia.newf_str (MSG_U(F_NISDOMAIN,"NIS domain name"),glocal.domain); dia.last_noempty(); if (edit(help_nis)){ master_registry.start_session(); master_registry.set("nis.domain",glocal.domain); master_registry.end_session(); } // Main server (mode,status); settitle (MSG_U(T_NISPKG,"NIS server package")); status.is_possible = glocal.mainserv == 1; status.is_filled = nisservpkg_isok(); if (nisservpkg_isok()){ allfine(); setintro (MSG_U(I_NISPKGOK,"The NIS server package is installed")); edit (help_nis); }else{ attention(); setintro (MSG_U(I_NISPKGNOTOK,"This NIS server package is not installed")); if (edit(help_nis)){ module_requestpkg ("nisserver"); } } settitle (MSG_U(T_NISISINIT,"Is NIS server initialised")); status.is_possible = glocal.mainserv == 1; status.is_filled = nisserv_isinit (glocal.domain,true); if (nisserv_isinit(glocal.domain,true)){ allfine(); setintro (MSG_U(I_NISISINIT,"The NIS server is already initialised")); edit (help_nis); }else{ attention(); setintro (MSG_U(I_NISNOTINIT ,"This NIS server is not initialised\n" "We will run the script\n" "\tcd /var/yp; make")); if (edit(help_nis)){ nisserv_isinit(glocal.domain,false); } } settitle (MSG_U(T_NISSERV,"NIS service")); status.is_possible = glocal.mainserv == 1; status.is_filled = nisserv_isok(true); if (nisserv_isok(true)){ allfine(); setintro (MSG_U(I_NISSERVOK,"The NIS server is configured to run")); edit (help_nis); }else{ attention(); setintro (MSG_U(I_NISSERVNOTOK,"The NIS server is not configured to run")); if (edit(help_nis)){ nisserv_isok(false); } } settitle (MSG_U(T_EXPORTHOME,"Export the home directories")); // domain status.is_possible = glocal.mainserv == 1; status.is_filled = nisserv_home (true); setterminal (MSG_U(I_MAINNIS,"Master NIS server"),MSG_R(I_MAINNIS)); edit (help_nis); // Satellite (mode,status); settitle (MSG_U(T_NISCLIENTPKG,"NIS client package")); status.is_possible = glocal.mainserv == 0; status.is_filled = nisclientpkg_isok(); if (nisclientpkg_isok()){ allfine(); setintro (MSG_U(I_NISCLIENTPKGOK,"The NIS client package is installed")); edit (help_nis); }else{ attention(); setintro (MSG_U(I_NISCLIENTPKGNOTOK,"The NIS client package is not installed")); if (edit(help_nis)){ module_requestpkg ("nisclient"); } } status.is_possible = true; status.is_filled = review_nisconf(); settitle (MSG_U(T_CHKNISCONF,"Is the nisconf module enabled ?")); if (review_nisconf()){ allfine(); setintro (MSG_U(I_CHKNISCONFOK ,"The nisconf module is currently enabled.\nNothing to do")); edit(); }else{ attention(); setintro (MSG_U(I_CHKNISCONFNOTOK ,"The nisconf module is not currently enabled.\n" "We will enable it")); if (edit()){ module_setone ("nisconf",true,true); module_load(); } } settitle (MSG_U(T_NISSERVER,"NIS server")); status.is_possible = glocal.mainserv == 0; status.is_filled = glocal.server.is_filled(); setintro (MSG_U(I_NISSERVER,"We need the IP number of the NIS server")); dia.newf_str (MSG_U(F_NISSERVER,"NIS server IP number"),glocal.server); dia.last_noempty(); while (1){ if (!edit (help_nis)){ break; }else if (ipnum_validip(glocal.server.get(),true)){ master_registry.start_session(); master_registry.set ("nis.server",glocal.server); master_registry.end_session(); break; }else{ xconf_error (MSG_R(E_IVLDIP),glocal.server.get()); } } settitle (MSG_U(T_NISCLIENT,"NIS client service")); status.is_possible = glocal.mainserv == 0; status.is_filled = nisclient_isok(true); if (nisclient_isok(true)){ allfine(); setintro (MSG_U(I_NISCLIENTVOK,"The NIS client is configured to run")); edit (help_nis); }else{ attention(); setintro (MSG_U(I_NISCLIENTNOTOK,"The NIS client is not configured to run")); if (edit(help_nis)){ nisclient_isok(false); } } settitle (MSG_U(T_HOMESERVER,"Main NFS server (Homes)")); status.is_possible = glocal.mainserv == 0; status.is_filled = nisclient_home (glocal.server,true); setterminal (MSG_U(I_CLIENTNIS,"NIS client (satellite server)"),MSG_R(I_CLIENTNIS)); if (nisclient_home(glocal.server,true)){ allfine(); setintro (MSG_U(I_HOMESERVEROK,"The home directory is already configured")); edit (help_nfshome); }else{ attention(); setintro (MSG_U(I_HOMESERVERNOTOK ,"The home directory has to be configured\n" "to be accessed from master server")); if (edit(help_nfshome)){ nisclient_home(glocal.server,false); } } possible = glocal.possible; } void xterminals_review() { DEVSETUP devs[10]; int nbdev; char dhcp,xfs,dns,nfs,xdm,nis; glocal.nbdev = review_readdev (glocal.devs); glocal.dns = linuxconf_getvalnum (K_XTERMREVIEW,K_DNSNEEDED,255); glocal.nfs = linuxconf_getvalnum (K_XTERMREVIEW,K_NFSNEEDED,255); glocal.xfs = linuxconf_getvalnum (K_XTERMREVIEW,K_XFSNEEDED,255); glocal.dhcp = linuxconf_getvalnum (K_XTERMREVIEW,K_DHCPNEEDED,255); glocal.xdm = linuxconf_getvalnum (K_XTERMREVIEW,K_XDMNEEDED,255); glocal.nis = linuxconf_getvalnum (K_XTERMREVIEW,K_NISNEEDED,255); int ret = (MSG_U(T_XTERMSETUP,"X terminals server setup") ,MSG_U(I_NETSETUP ,"You will be presented with a set of dialog to fully\n" "configure a server to host X terminals.\n" "You will walk through the following confiuration:\n" "\n" "\tDNS: Domain Name server\n" "\tDHCP: Dynamic Host Configuration Protocol\n" "\tNFS: Network FIle System\n" "\tXDM: X Display Manager\n" "\tXFS: X Font Server\n" "\tNIS: Network Information System\n") ,help_review); (mode,status); settitle (MSG_U(T_NETWORKS,"X Terminal networks")); status.is_possible = true; status.is_filled = true; for (int i=0; i setintro (MSG_U(I_NETWORKS ,"Here are the various networks connected to this server.\n" "You have to tell on which networks X terminals will be hooked\n" "Further, for each network with X terminals,\n" "You must define the IP range available to them.")); int tbnof[glocal.nbdev+1]; for (int i=0; idevname.get()); dia.newline(); SSTRING tmp; tmp.setfromf ("%s/%s",dev->network.get(),dev->netmask.get()); dia.newf_info (MSG_U(F_NETSPEC,"Network spec") ,tmp.get()); dia.newline(); dia.newf_str (MSG_U(F_STARTIP,"First available IP number"),dev->startip); dia.newline(); dia.newf_str (MSG_U(F_LASTIP,"Last available IP number"),dev->endip); dia.newline(); } bool ok = false; while (!ok){ if (!edit (help_interfaces)){ break; }else{ ok = true; for (int i=0; istartip.is_empty()){ dev->configured = true; }else if (!review_checkip(dev,dev->startip)){ setcursor (tbnof[i]); ok = false; break; }else if (!review_checkip(dev,dev->endip)){ setcursor (tbnof[i]+1); ok = false; break; } } } } review_nfs(glocal.nfs,mode,status); review_xfs(glocal.xfs,mode,status); review_dhcp(glocal.dhcp,glocal.devs,glocal.nbdev,mode,status); review_xdm(glocal.xdm,mode,status); review_dns(glocal.dns,glocal.devs,glocal.nbdev,mode,status); review_nis(glocal.nis,mode,status); if (ret == 0){ linuxconf_replace (K_XTERMREVIEW,K_DNSNEEDED,glocal.dns); linuxconf_replace (K_XTERMREVIEW,K_NFSNEEDED,glocal.nfs); linuxconf_replace (K_XTERMREVIEW,K_XFSNEEDED,glocal.xfs); linuxconf_replace (K_XTERMREVIEW,K_DHCPNEEDED,glocal.dhcp); linuxconf_replace (K_XTERMREVIEW,K_XDMNEEDED,glocal.xdm); linuxconf_replace (K_XTERMREVIEW,K_NISNEEDED,glocal.nis); for (int i=0; inetwork.get()); linuxconf_replace (K_XTERMREVIEW,tmp.get(),dev->startip); tmp.setfromf ("%s-%s",K_ENDIP,dev->network.get()); linuxconf_replace (K_XTERMREVIEW,tmp.get(),dev->endip); } linuxconf_save(); } knownpkgs.remove_all(); }