#include #include #include #include #include #include "../askrunlevel/askrunlevel.h" #include #include #include #include #include #include #include #include "main.h" #include "../paths.h" #include #include "main.m" #include HELP_FILE help_mainintro (HELP_MAIN,"intro"); static HELP_FILE help_control (HELP_MAIN,"control"); static HELP_FILE help_features (HELP_MAIN,"features"); static HELP_FILE help_logs (HELP_MAIN,"logs"); static HELP_FILE help_ctrlfile (HELP_MAIN,"ctrlfile"); static HELP_FILE help_keymap(HELP_MAIN,"keymap"); static PRIVILEGE p_actchg ("actchg" ,P_MSG_U(T_PACTCHG,"May activate config changes") ,P_MSG_U(T_PSYSCONTROL,"0-General system control")); static PRIVILEGE p_netlevel ("netlevel" ,P_MSG_U(T_PNETLEVEL,"May switch network mode") ,P_MSG_R(T_PSYSCONTROL)); static PRIVILEGE p_logs ("viewlogs" ,P_MSG_U(T_PVIEWLOGS,"May view system logs") ,P_MSG_R(T_PSYSCONTROL)); CONFIG_FILE f_treemenu (VAR_STATE_TREEMENU_CACHE,help_nil ,CONFIGF_GENERATED|CONFIGF_OPTIONAL|CONFIGF_NOARCH); CONFIG_FILE f_treemenu_log (VAR_RUN_TREEMENU_LOG,help_nil ,CONFIGF_GENERATED|CONFIGF_OPTIONAL|CONFIGF_NOARCH); static CONFIG_FILE f_dmesg (VAR_LOG_DMESG,help_nil ,CONFIGF_OPTIONAL|CONFIGF_NOARCH); /* control panel to activate different things, not to configure. Return != 0 if the last task done was an "update" of the system state */ static int linuxconf_control() { int choice = 0; int was_checked = 0; static const char *runlevel = MSG_U(M_NETLEVEL,"Switch network runlevel"); static const char *initrunlevel = MSG_U(M_RUNLEVEL,"init Run Level"); static const char *reboot = MSG_U(M_REBOOT,"Shutdown/Reboot"); static const char *update = MSG_U(M_UPDATE,"Activate configuration"); static const char *reload = MSG_U(M_RESTART,"Restart linuxconf"); static const char *service = MSG_U(M_SERVICE,"Control service activity"); static const char *mount = MSG_U(M_MOUNTFS,"Mount/Unmount file systems"); static const char *tasks = MSG_U(M_TASKS,"Configure superuser scheduled tasks"); static const char *archive = MSG_U(M_ARCHIVE,"Archive configurations"); static const char *cfgversion = MSG_U(M_CFGVERSION,"Switch system profile"); static const char *menuopt[]={ "", update, "", reboot, "", service, "", mount, "", tasks, "", archive, "", cfgversion, NULL }; DIALOG_MENU dia; if (!distrib_isenhanced()){ dia.new_menuitem ("",runlevel); } dia.new_menuitems (menuopt); module_setmenu (dia,MENU_CONTROL_PANEL); if (dialog_mode == DIALOG_HTML) dia.new_menuitem ("",reload); while (1){ MENU_STATUS code = dia.editmenu (MSG_U(T_CONTROL,"Control panel") ,!simul_isdemo() ? MSG_U(I_CONTROL ,"This menu lets you do things, not configure.") : MSG_U(I_CONTROLDEMO ,"This menu lets you do things, not configure\n\n." "*** Not operational in DEMO mode ***") ,help_control ,choice,0); if (code != MENU_OK){ break; }else{ was_checked = 0; const char *key = dia.getmenustr (choice); module_domenu (MENU_CONTROL_PANEL,key); if (!simul_isdemo()){ if (key == update){ if (perm_access (&p_actchg,MSG_U(P_ACTIVATECHG ,"enable configuration changes"))){ int status = netconf_checkupdate(false); was_checked = status != -1; if (status == 0){ xconf_notice (MSG_U(N_NOJOB,"Nothing to do!")); } } }else if (key == reboot){ shutdown_control(); }else if (key == runlevel){ if (perm_access (&p_netlevel,MSG_U(P_NETLEVEL ,"switch network operation level"))){ netconf_editrunlevel(); } }else if (key == initrunlevel){ //init_editrunlevel(); }else if (key == reload){ if (perm_rootaccess (MSG_U(Q_SYSTASK,"to perform system task"))){ html_printf ("done!"); html_flush (); exit (0); } }else if (key == service){ if (perm_rootaccess (MSG_U(Q_SERVICE ,"to enable/disable some services"))){ service_control(); } }else if (key == mount){ fstab_control(); }else if (key == tasks){ cron_edit ("root"); }else if (key == archive){ if (perm_rootaccess(MSG_R(P_ARCHIVE))){ subsys_archive(); } }else if (key == cfgversion){ if (perm_rootaccess(MSG_R(P_ARCHIVE))){ confver_selnewver(); } } } } } return was_checked; } static const char LINUXCONF[]="linuxconf"; static const char HTMLTIMEOUT[]="htmltimeout"; static const char K_KEYMAP[]="keymap"; /* Get the selected keyboard map or NULL if none */ const char *linuxconf_getkeymap() { return linuxconf_getval (LINUXCONF,K_KEYMAP); } int linuxconf_gethtmltimeout() { return linuxconf_getvalnum (LINUXCONF,HTMLTIMEOUT,10); } /* Install the keyboard map if needed */ int linuxconf_setkeymap() { const char *km = linuxconf_getkeymap(); if (km != NULL){ /* #Specification: loadkeys / argument User can specify either a name of a keymap (without extension) as suggested by the help list. Or he can enter a full path which will be used as is. Mostly if the user enter "fr", the command # /usr/bin/loadkeys /usr/lib/kbd/keytables/fr.map # will be called. If the user enter anything starting with a /, this will be used as is. For example, if he enter /a/phony/path/file.with.any.extension, the following command will be called. # /usr/bin/loadkeys /a/phony/path/file.with.any.extension # */ }else{ km = "-d"; } return netconf_system_if ("loadkeys",km); } #if defined(i386) || defined (__x86_64__) static const char keymap_arch[]="i386"; #elif defined(__sparc__) static const char keymap_arch[]="sparc"; #elif defined(__alpha__) static const char keymap_arch[]="alpha"; #elif defined(__mips__) // Just so it compiles on Cobalt. I have not seen a real // Mips/Linux workstation static const char keymap_arch[]="mips"; #elif defined(__powerpc__) static const char keymap_arch[]="ppc"; #elif defined(__mc68000__) // directory determined dynamically later static const char *keymap_arch = NULL; static struct m68k_model_map { const char *long_name, *short_name; } m68k_models[] = { { "Amiga", "amiga" }, { "Atari", "atari" }, { "Macintosh", "mac" }, { "Motorola", "mvme" }, { NULL, NULL } }; #elif defined(__ia64__) static const char keymap_arch[]="ia64"; #elif defined(__s390__) || defined(__s390x__) static const char keymap_arch[]="s390"; #else #error Need a ifdef for your architecture here #endif static void init_keymap_arch( void ) { #if defined(__mc68000__) if (keymap_arch) // already defined return; char line[200]; char *model_line = NULL; FILE *f = fopen( "/proc/hardware", "r" ); if (f != NULL){ // look for Model: line while( !feof(f) ) { line[0] = '\0'; fgets( line, sizeof(line)-1, f ); if (strncmp( line, "Model:", 6 ) == 0) { model_line = line; break; } } fclose( f ); } if (model_line) { // extract first word after Model: char *p = model_line+6; while( *p && isspace(*p) ) ++p; char *q = p; while( *q && !isspace(*q) ) ++q; *q = 0; // compare with long model names and use short name as the keymap // directory name struct m68k_model_map *mm; for( mm = m68k_models; mm->long_name; ++mm ) { if (strcmp( p, mm->long_name ) == 0) keymap_arch = mm->short_name; } if (!keymap_arch) { keymap_arch = ""; xconf_error (MSG_U(E_BADM68KMODEL,"Unknown m68k model")); } } else { keymap_arch = ""; xconf_error (MSG_U(E_NOM68KMODEL,"Cannot determine m68k model (/proc not mounted?)")); } #endif } static int linuxconf_dirmap(const char *subdir, SSTRINGS &tb) { char path[PATH_MAX]; init_keymap_arch(); snprintf (path,sizeof(path)-1,"%s/%s",USR_LIB_KBD_KEYMAPS,keymap_arch); if (subdir[0] != '\0'){ strcat (path,"/"); strcat (path,subdir); } int nb = dir_getlist (path,".kmap",tb); nb += dir_getlist (path,".kmap.gz",tb); nb += dir_getlist (path,".map",tb); nb += dir_getlist (path,".map.gz",tb); return nb; } static void linuxconf_features() { int html_timeout = linuxconf_gethtmltimeout(); DIALOG dia; dia.newf_title (MSG_U(T_UIFEATURE,"User interface"),1,"",MSG_R(T_UIFEATURE)); SSTRING kmap; kmap.setfrom (linuxconf_getkeymap()); SSTRING old_kmap(kmap); FIELD_COMBO *comb = dia.newf_combo (MSG_U(F_KBDMAP,"Keyboard map"),kmap); { SSTRINGS dirs; char path[PATH_MAX]; init_keymap_arch(); snprintf (path,sizeof(path)-1,"%s/%s",USR_LIB_KBD_KEYMAPS,keymap_arch); dir_getlist (path,dirs); SSTRINGS tb; int nb = linuxconf_dirmap ("",tb); for (int i=0; iget(),tb); } tb.sort(); comb->addopt ("",MSG_U(F_NONE,"Use default keymap")); for (int i=0; iaddopt (tb.getitem(i)->get()); } } SSTRING lang; char langmode = linuxconf_getlangmode() ? 1 : 0; dia.newf_chk ("",langmode,MSG_U(I_LANGMODE,"Automatic language selection")); lang.setfrom (linuxconf_getlangmanual()); comb = dia.newf_list (MSG_U(F_LANGAGE,"Language"),lang); { SSTRINGS tb; int nb = dir_getlist_p (USR_LIB_LINUXCONF "/lang_intro",tb); tb.sort(); for (int i=0; iget(); const char *pt = strchr(s,'.'); if (pt != NULL){ FILE *fin = fopen (s,"r"); if (fin != NULL){ char line[100]; line[0] = '\0'; fgets(line,sizeof(line)-1,fin); fclose (fin); strip_end (line), comb->addopt (pt+1,line); } } } } dia.newf_num (MSG_U(F_HTMLTIMEOUT,"Html timeout"),html_timeout); char usegui = linuxconf_getguimode() ? 1 : 0; dia.newf_chk ("",usegui,MSG_U(F_USEGUI,"May use the GUI mode")); char usecol = (char)linuxconf_getcolormode() ? 1 : 0; dia.newf_chk ("",usecol,MSG_U(F_USECOLORS ,"May use colors in text mode")); int trig = linuxconf_getprefixtrig(); dia.newf_num (MSG_U(F_PREFIXTRIG,"Trigger for filter"),trig); SSTRING bodyparm,headparm; html_getpageparm(bodyparm,headparm); dia.newf_str (MSG_U(F_HTMLHEADPARM,"HTML HEAD parameters"),headparm); dia.newf_str (MSG_U(F_HTMLBODYPARM,"HTML BODY parameters"),bodyparm); char uselynx = dialog_usinglynx(); dia.newf_chk ("",uselynx,MSG_U(F_USELYNX,"Use lynx to display help")); USERACCT_COMNGS comngs; comngs.getall ("features"); comngs.setupdia (dia); int nof = 0; while (1){ MENU_STATUS code = dia.edit (MSG_U(T_FEATURES,"Features") ,MSG_U(I_FEATURES,"This screen defines some special behavior\n" "of linuxconf.") ,help_features ,nof); if (code == MENU_CANCEL || code == MENU_ESCAPE){ break; }else if (code == MENU_MESSAGE){ comngs.message (dia); }else if (html_timeout < 5){ xconf_error (MSG_U(E_HTMLTIMEOUT,"The html timeout must be 5 minutes or higher")); }else if (comngs.validate(dia,nof) != -1){ comngs.save (NULL); linuxconf_replace (LINUXCONF,HTMLTIMEOUT,html_timeout); if (kmap.cmp(MSG_R(F_NONE))==0) kmap.setfrom (""); if (kmap.is_empty()){ linuxconf_removeall (LINUXCONF,K_KEYMAP); }else{ linuxconf_replace (LINUXCONF,K_KEYMAP,kmap); } char pathlang[PATH_MAX]; snprintf (pathlang,sizeof(pathlang)-1,"%s/help.%s" ,USR_LIB_LINUXCONF,lang.get()); if (file_type(pathlang)!=1){ xconf_notice (MSG_U(E_RESOURCELANG ,"The resource files for the language %s\n" "are not installed. You must install the package\n" "linuxconf-lang-%s. Linuxconf will continue to operate\n" "using English messages."),lang.get(),lang.get()); } linuxconf_setlang (lang.get()); linuxconf_setlangmode (langmode); linuxconf_setguimode(usegui != 0); linuxconf_setcolormode(usecol != 0); linuxconf_setprefixtrig(trig); html_setpageparm (bodyparm.get(),headparm.get()); dialog_setuselynx (uselynx != 0); linuxconf_save(); if (kmap.cmp(old_kmap)!=0 && dialog_yesno(MSG_U(T_CHGKMAP,"Changing keyboard map") ,MSG_U(I_CHGMAP ,"You have changed the keyboard mapping specification.\n" "Do you want to activate the change now ?\n" "It will be activated at each reboot") ,help_keymap)==MENU_YES){ linuxconf_setkeymap(); } break; } } } void linuxconf_recordkeymap(const char *map) { if (map == NULL || map[0] == '\0'){ linuxconf_removeall (LINUXCONF,K_KEYMAP); }else{ linuxconf_replace (LINUXCONF,K_KEYMAP,map); } linuxconf_save(); } static void linuxconf_logs() { int choice = 0; static const char *dmesg = MSG_U(M_DMESGLOGS,"Kernel boot messages"); static const char *bootlogs = MSG_U(M_BOOTLOGS,"Boot messages"); static const char *mylogs = MSG_U(M_LINUXCONFLOGS,"Linuxconf logs"); static const char *menuopt[]={ "bootlogs:", bootlogs, "mylogs:", mylogs, NULL }; DIALOG_MENU dia; if (f_dmesg.exist()) dia.new_menuitem ("dmesg","",dmesg); dia.new_menuitems (menuopt); module_setmenu (dia,MENU_LOGS); while (1){ MENU_STATUS code = dia.editmenu (MSG_U(T_SYSLOGS,"System logs") ,MSG_U(I_SYSLOGS ,"This menu lets you see the different messages generated\n" "by the system. These messages are normally checked to\n" "either detect some problems or as a proof that some event\n" "happened.") ,help_logs ,choice,0); if (code != MENU_OK){ break; }else if (perm_access (&p_logs,MSG_U(P_VIEWLOGS ,"view system logs"))){ const char *key = dia.getmenustr(choice); module_domenu (MENU_LOGS,key); if (key == dmesg){ dialog_textbox (dmesg,f_dmesg.getpath()); }else if (key == bootlogs){ boot_showlog(); }else if (key == mylogs){ net_showlog(); } } } } void linuxconf_editctrl() { static const char *config_file = MSG_U(MNU_CONFIGS,"Configuration files"); static const char *commands = MSG_U(MNU_COMMANDS,"Commands and daemons"); static const char *perms = MSG_U(MNU_PERMS,"Permission and ownership"); static const char *config_module = MSG_U(MNU_MODULE,"Modules"); static const char *add_on_local = MSG_U(MNU_ADD_ON,"Override addons"); static const char *add_on_orig = MSG_U(MNU_ADD_ON_ORIG,"Create addons"); static const char *config_version = MSG_U(M_CONFVER,"System profiles"); static const char *config_features = MSG_U(M_FEATURES,"Miscellaneous"); static const char *htmlaccess = MSG_U(M_HTMLACCES,"Linuxconf network access"); int choice = 0; static const char *menuopt[]={ " ", config_file, " ", commands, " ", perms, " ", config_module, " ", config_version, " ", add_on_local, " ", add_on_orig, " ", config_features, " ", htmlaccess, NULL }; DIALOG_MENU dia; dia.new_menuitems (menuopt); module_setmenu (dia,MENU_CTRL_FILE); while(1){ MENU_STATUS code = dia.editmenu ( MSG_U(T_CTRLFILE,"Linuxconf management") ,MSG_U(I_CTRLFILE ,"This menu lets you manage Linuxconf's\n" "behavior\n") ,help_ctrlfile ,choice,0); if (code != MENU_OK){ break; }else{ const char *key = dia.getmenustr(choice); if (key == config_file){ configf_show(); }else if (key == commands){ daemon_config(); }else if (key == perms){ fstab_editperm(); }else if (key == config_module){ module_config(); }else if (key == add_on_local){ dropin_editlocal(); }else if (key == add_on_orig){ dropin_editorig(); }else if (key == config_version){ confver_edit(); }else if (key == config_features){ linuxconf_features(); }else if (key == htmlaccess){ html_access_edit(); }else{ module_domenu (MENU_CTRL_FILE,key); } } } } static void linuxconf_somemenu( MENU_CONTEXT ctx, const char *title, const char *error) { DIALOG_MENU dia; module_setmenu (dia,ctx); if (dia.getnb()==0){ xconf_error (error); }else{ int nof = 0; while (1){ MENU_STATUS code = dia.editmenu (title ,"" ,help_nil ,nof,0); if (code == MENU_QUIT || code == MENU_ESCAPE){ break; }else{ const char *key = dia.getmenustr(nof); module_domenu (ctx,key); } } } } static int was_checked; static const char *config_askrun ; static const char *view_logs ; static const char *config_fstab ; static const char *config_misc ; static const char *config_hard ; static const char *config_graphic; static const char *config_net ; static const char *config_user ; static const char *config_datetime ; static const char *control ; static const char *ctrlfile ; static void ft(void *p){ const char *key = (const char *)p; module_domenu(MENU_MAIN_CONFIG,key); module_domenu(MENU_MAIN_CONTROL,key); module_domenu(MENU_MAIN_STATUS,key); module_domenu(MENU_GURUS,key); if (key == config_fstab){ fstab_edit (); }else if (key == config_misc){ linuxconf_somemenu (MENU_MISCSERV ,MSG_U(T_MISCSERV,"Miscellaneous services") ,MSG_U(E_NOMISCSERV,"No misc services registered")); }else if (key == config_hard){ linuxconf_somemenu (MENU_HARDWARE ,MSG_U(T_PERIPHERAL,"Peripherals/hardware configuration") ,MSG_U(E_NOPERIPHERAL,"No module registered")); }else if (key == config_graphic){ xconf_edit (); }else if (key == config_net){ netconf_edit (); }else if (key == config_askrun){ askrunlevel_config(); }else if (key == view_logs){ linuxconf_logs(); }else if (key == config_user){ userconf_edit(); }else if (key == config_datetime){ datetime_edit(); }else if (key == control){ was_checked = linuxconf_control(); }else if (key == ctrlfile){ linuxconf_editctrl(); } } void linuxconf_formatversion (char version[80]) { extern char *revision; #if LINUXCONF_SUBSUBREVISION > 0 snprintf (version,79,"%s %s (%s %d-%d)" ,MSG_U(TITLE,"Linuxconf") ,revision ,MSG_U(SUBREV,"subrev") ,LINUXCONF_SUBREVISION,LINUXCONF_SUBSUBREVISION); #elif LINUXCONF_SUBREVISION > 0 snprintf (version,79,"%s %s (%s %d)" ,MSG_R(TITLE) ,revision ,MSG_R(SUBREV) ,LINUXCONF_SUBREVISION); #else snprintf (version,79,"%s %s" ,MSG_R(TITLE),revision); #endif } void linuxconf_setmaintitle(char title[80],char sidetitle[80]) { if (dialog_mode == DIALOG_HTML){ strcpy_cut (title,MSG_U(M_MAINMENU,"Main menu"),79); sidetitle[0] = '\0'; }else{ extern char *revision; THISHOST host; const char *name = host.getname1(); char version[80]; linuxconf_formatversion(version); snprintf (title,79,"%s: %s",name,version); #if LINUXCONF_SUBSUBREVISION > 0 sprintf (sidetitle,"LINUXCONF %s.%d",revision,LINUXCONF_SUBREVISION); #elif LINUXCONF_SUBREVISION > 0 sprintf (sidetitle,"LINUXCONF %s.%d",revision,LINUXCONF_SUBREVISION); #else sprintf (sidetitle,"LINUXCONF %s",revision); #endif } } /* Main dispatcher to all other configs */ void linuxconf_mainmenu(bool dontcheck) { int choice = 0; config_askrun = MSG_U(MNU_BOOT,"Boot"); view_logs = MSG_U(MNU_LOGS,"Logs"); config_fstab = MSG_U(MNU_FILESYS,"File systems"); config_misc = MSG_U(MNU_MISCSERV,"Miscellaneous"); config_hard = MSG_U(MNU_HARDWARE,"Peripherals"); config_graphic= MSG_U(MNU_GRAPH,"Graphic mode (X)"); config_net = MSG_U(MNU_NET,"Networking"); config_user = MSG_U(MNU_USERS,"Users"); config_datetime = MSG_U(MNU_DATE,"Date & time"); control = MSG_U(MNU_CONTROL,"Control panel"); ctrlfile = MSG_U(MNU_CTRLFILE,"Linuxconf management"); static const char *menuopt1[]={ "-", MSG_U(M_CONFIG,"Config"), "network:", config_net, "users:", config_user, "file:", config_fstab, "misc:", config_misc, "hardware:", config_hard, //"", config_graphic, NULL }; static const char *menuopt2[]={ "-", MSG_U(M_CONTROL,"Control"), "controlpanel:", control, "controlfile:", ctrlfile, "time:", config_datetime, NULL }; static const char *menuopt3[]={ "-", MSG_U(M_STATUS,"Status"), "log:", view_logs, NULL }; static const char *menuopt4[]={ "-", MSG_U(M_COMMONTASKS,"Tasks"), NULL }; DIALOG_MENU dia; dia.new_menuitems (menuopt1); dia.new_menuitem ("boot","",config_askrun); module_setmenu (dia,MENU_MAIN_CONFIG); if (context_isroot()){ dia.new_menuitems (menuopt2); module_setmenu (dia,MENU_MAIN_CONTROL); dia.new_menuitems (menuopt3); module_setmenu (dia,MENU_MAIN_STATUS); int nbopt4 = dia.getnb(); dia.new_menuitems (menuopt4); module_setmenu (dia,MENU_GURUS); if (dia.getnb()==nbopt4+1) dia.remove_last (nbopt4); } dialog_clear(); char title[80],sidetitle[80]; linuxconf_setmaintitle(title,sidetitle); dia.setsidetitle (sidetitle); dia.html_intro ( MSG_U(I_HTMLINTRO,"\n" "This is the main entry to Linux configuration.\n" "Check out the help for this screen. It is an\n" "introduction to Linuxconf" "\n")); while(1){ while (1){ MENU_STATUS code = dia.editmenu (title ,MSG_U(MNU_INTRO,"This is the main entry to Linux configuration.\n" "\n" "Use the TAB key to navigate between the field\n" "section and the button bar at the bottom.\n" "Check out the help for this screen. It is an\n" "introduction to Linuxconf") ,help_mainintro ,choice,0); if (code != MENU_OK){ break; }else{ was_checked = 0; const char *key = dia.getmenustr(choice); uithread (ft,(void*)key); } } if (!dontcheck && !was_checked){ if (netconf_checkupdate(true) != 2) break; }else{ break; } } } void linuxconf_main(bool dontcheck) { notice_show(); const char *argv[]={ dontcheck ? "1" : "0", NULL }; if (module_sendmessage ("mainmenu",1,argv)==LNCF_NOT_APPLICABLE){ linuxconf_mainmenu (dontcheck); } } void linuxconf_premain() { if (!netconf_mainaccess()) return; static bool done = false; if (!done){ dialog_clear(); dialog_splash (NULL); done = true; } HELP_CONTEXT h1 (MSG_U(T_ABOUTLNX,"About Linuxconf"),"main","about_linuxconf"); HELP_CONTEXT *hui = NULL; if (dialog_mode == DIALOG_CURSES){ hui = new HELP_CONTEXT (MSG_U(T_TEXTKBD,"Text mode key binding") ,"main","textmode"); } linuxconf_main (false); delete hui; } static SSTRINGS tree_keys,tree_titles,tree_icons,tree_modules,tree_others; static SSTRING tree_version,tree_lang; static FILE_CFG *collect_fout = NULL; static DIALOG *diatree = NULL; static SSTRING *diatitle = NULL; static DIALOG_MODE curmode; static void linuxconf_show(const char *title) { if (diatree != NULL){ diatitle->setfrom (title); diatree->reload(); int nof = 0; DIALOG_MODE old = dialog_setmode (curmode); diatree->show (MSG_U(T_BUILDINGTREE,"Building Tree menu") ,MSG_U(I_BUILDINGTREE ,"Linuxconf is currently visiting all modules\n" "to learn about their menu structure.") ,help_none,nof,0); diagui_flush(); dialog_setmode (old); } } static void linuxconf_collect (const char *key, const char *title, const char *icon) { if (collect_fout != NULL){ fprintf (collect_fout,"Will execute menu %s %s\n",key,title); fflush (collect_fout); } linuxconf_show (title); tree_keys.add (new SSTRING (key)); tree_titles.add (new SSTRING (title)); tree_icons.add (new SSTRING (icon)); } /* Check if two table contain the same strings */ static bool linuxconf_diffmod ( const SSTRINGS &tb1, SSTRINGS &tb2) { bool differ = true; int n1 = tb1.getnb(); if (n1 == tb2.getnb()){ differ = false; for (int i=0; iget())==-1){ differ = true; break; } } } return differ; } void linuxconf_gettree ( SSTRINGS &keys, SSTRINGS &titles, SSTRINGS &icons) { static const char K_TREE[]="tree"; static const char K_KEY[]="key"; static const char K_TITLE[]="title"; static const char K_ICON[]="icon"; static const char K_MODULE[]="module"; static const char K_OTHER[]="other"; static const char K_VERSION[]="version"; static const char K_LANG[]="lang"; if (tree_keys.getnb()==0){ CONFDB db (f_treemenu); db.getall (K_TREE,K_KEY,tree_keys,1); db.getall (K_TREE,K_TITLE,tree_titles,1); db.getall (K_TREE,K_ICON,tree_icons,1); db.getall (K_TREE,K_MODULE,tree_modules,1); db.getall (K_TREE,K_OTHER,tree_others,1); tree_version.setfrom (db.getval (K_TREE,K_VERSION)); tree_lang.setfrom (db.getval (K_TREE,K_LANG)); } const SSTRINGS *curloaded = module_getlist(); SSTRINGS curothers; { const char *arg[1]={(const char*)&curothers}; module_sendmessage ("treemenu-depend",1,arg); curothers.sort(); } if (linuxconf_diffmod (*curloaded,tree_modules) || linuxconf_diffmod (curothers,tree_others) || tree_version.cmp(PACKAGE_REV)!=0 || tree_lang.cmp(linuxconf_getlang())!=0){ xconf_notice (MSG_U(N_BUILDTREE ,"Linuxconf will now compute its menu tree.\n" "This may take a few seconds.\n" "Linuxconf does this either because you have upgraded linuxconf\n" "itself or because you have installed a new module.")); tree_keys.remove_all(); tree_titles.remove_all(); tree_icons.remove_all(); tree_modules.remove_all(); collect_fout = f_treemenu_log.fopen ("w"); curmode = dialog_setmode (DIALOG_TREE); dialog_resettree(); menubox_setcollect (linuxconf_collect); perm_setbypass(true); DIALOG diashow; diashow.settype (DIATYPE_POPUP); diatree = &diashow; SSTRING title; diatitle = &title; diashow.newf_str (MSG_U(F_MENU,"Visiting menu:"),title); diashow.set_lastreadonly(); linuxconf_show (""); linuxconf_mainmenu (true); diatree = NULL; diatitle = NULL; perm_setbypass(false); dialog_setmode (curmode); html_resetpopup(); if (collect_fout != NULL){ fclose (collect_fout); collect_fout = NULL; } CONFDB db (f_treemenu); db.remove_all(); db.replace (K_TREE,K_KEY,tree_keys); db.replace (K_TREE,K_TITLE,tree_titles); db.replace (K_TREE,K_ICON,tree_icons); for (int i=0; igetnb(); i++){ const char *mod = curloaded->getitem(i)->get(); tree_modules.add (new SSTRING(mod)); } db.replace (K_TREE,K_MODULE,tree_modules); db.replace (K_TREE,K_OTHER,curothers); db.replace (K_TREE,K_VERSION,PACKAGE_REV); tree_version.setfrom (PACKAGE_REV); db.replace (K_TREE,K_LANG,linuxconf_getlang()); tree_lang.setfrom (linuxconf_getlang()); file_mkdirp (VAR_STATE_LINUXCONF,"root","root",0755); db.save(); } keys.remove_all(); titles.remove_all(); icons.remove_all(); keys.neverdelete(); titles.neverdelete(); icons.neverdelete(); int n = tree_keys.getnb(); for (int i=0; i static PUBLISH_VARIABLES_MSG main_var_list1[]={ {"keyboardmap",P_MSG_R(F_KBDMAP)}, {"autolang",P_MSG_R(I_LANGMODE)}, {"language",P_MSG_R(F_LANGAGE)}, {"htmltimeout",P_MSG_R(F_HTMLTIMEOUT)}, {"usegui",P_MSG_R(F_USEGUI)}, {"usecolors",P_MSG_R(F_USECOLORS)}, {"trigger",P_MSG_R(F_PREFIXTRIG)}, {"htmlhead",P_MSG_R(F_HTMLHEADPARM)}, {"htmlbody",P_MSG_R(F_HTMLBODYPARM)}, {"uselynx",P_MSG_R(F_USELYNX)}, { NULL, NULL } }; static REGISTER_VARIABLES main_registry1("lnxmisc",main_var_list1 ,NULL,linuxconf_features);