#include #include #include #include #include #include #include "netconf.h" #include "netconf.m" #include #include "internal.h" static NETCONF_HELP_FILE help_simul ("simul"); /* #Specification: netconf / simulation mode netconf can probe the environnement and compare to the current configuration. If it find some differences between the active setup and the requiered configuration, it will issue different commands to bring the system in sync with the configuration. One nice feature of netconf is that it can simulate all this and record all commands that would have been executed. This feature is mainly used by netconf which do a simulation before quitting from the interactive mode. If the simulation record any commands, netconf prompt the user and let him do a "netconf --update" interactivly. */ static FILE *fout = NULL; static bool do_close; /* Start the simulation mode. Initialise the record buffer. */ void simul_init() { if (fout == NULL){ do_close = true; fout = xconf_fopen (VAR_RUN_SIMUL,"w"); } } void simul_init (FILE *f) { fout = f; do_close = false; } static char demo_mode = 0; static char hint_mode = 0; /* Set the demo flag. When active, linuxconf always tell that we are doing a simulation. */ void simul_setdemoflag (int on) { demo_mode = (char)(on!=0); } /* Set the hint flag. When active, linuxconf work in simulation and output a set of hint allowing a sysv init script to perform the proper task */ void simul_sethintflag (int on) { hint_mode = (char)(on!=0); } static bool disable_mode = false; /* Set the state of the disable mode When setting this mode, all configuration will be skipped. This is used when a config step notice some problem and is a simple way to tell the complete application to finish without carrying error flag everywhere. */ void simul_setdisable(bool mode) { disable_mode = mode; if (mode && fout != NULL){ if (do_close) fclose (fout); fout = NULL; } } /* Return != 0 if we are running in demo mode */ EXPORT int simul_isdemo() { return demo_mode; } /* Return != 0 if we are running in hint mode */ EXPORT int simul_ishint() { return hint_mode; } /* Return != 0 if we are running the end of a disabled config session */ bool simul_isdisabled() { return disable_mode; } /* Return != 0 if netconf is in simulation mode */ EXPORT int simul_ison() { return fout != NULL || demo_mode || disable_mode || !context_isroot() || hint_mode; } /* Record one comment. */ void simul_addmsg(const char *ctl, ...) { if (fout != NULL){ va_list list; va_start (list,ctl); vfprintf (fout,ctl,list); va_end (list); fflush (fout); } } /* Prompt the user, if needed after the simulation. Return 1 if an update of the system is need and the user has accepted to do it. Return 0 if there was nothing to do at all. Return -1 if there was something to do but the user escaped away. Return 1 if the user want to do it. */ int simul_prompt(bool showdontquit) { int ret = 0; if (fout != NULL){ bool not_empty = ftell(fout) > 0; // This dialog is too short and I don't know why yet, so // here it is if (dialog_mode == DIALOG_GUI) fputs ("\n",fout); if (do_close) fclose (fout); fout = NULL; if (not_empty){ DIALOG_TEXTBOX dia; dia.settype (DIATYPE_POPUP); FILE *fin = fopen (VAR_RUN_SIMUL,"r"); if (fin != NULL){ char line[1000]; while (fgets_strip (line,sizeof(line)-1,fin,NULL)!=NULL){ char *pt = str_skip(line); if (strncmp(pt,"? ",2)==0 && !isspace(pt[2])){ // This is a NETLOG_WHY line. Try to highlit it char lineh[strlen(line)*3+1]; char *src = pt+1; char *dst = lineh; while (*src != '\0'){ char carac = *src++; *dst++ = carac; *dst++ = 8; // Backspace *dst++ = carac; } *dst = '\0'; dia.newf_text ("",lineh); }else{ dia.newf_text ("",line); } } fclose (fin); } int nof = 0; int buttons = MENUBUT_USR1|MENUBUT_USR2; dia.setbutinfo (MENU_USR1,MSG_U(M_DONOTHING,"Do nothing"),MSG_R(M_DONOTHING)); dia.setbutinfo (MENU_USR2,MSG_U(M_DOIT,"Do it"),MSG_R(M_DOIT)); if (showdontquit){ buttons |= MENUBUT_USR3; dia.setbutinfo (MENU_USR3,MSG_U(M_DONTQUIT,"Back to linuxconf") ,MSG_R(M_DONTQUIT)); } while (1){ MENU_STATUS code = dia.edit ( MSG_U(T_STATUS,"Status of the system") ,MSG_U(I_STATUS ,"The state of the system is not in sync with the current/updated\n" "configurations. You are allowed to make it current, or continue with\n" "the current configurations.\n" "\n" "Here are the commands to execute") ,help_simul ,nof,buttons); if (code == MENU_ESCAPE || code == MENU_QUIT || code == MENU_USR1){ ret = -1; }else if (code == MENU_USR2){ ret = 1; }else if (code == MENU_USR3){ ret = 2; } break; } } unlink (VAR_RUN_SIMUL); } return ret; }