#include #include #include "inittab.h" #include "inittab.m" #include #include static CONFIG_FILE f_inittab ("/etc/inittab",help_nil ,CONFIGF_MANAGED|CONFIGF_NOARCH ,"root","root",0644); class INITTAB_REC{ public: char id[5]; char runlevels[7]; char verb[20]; // respawn or other inittab verb char command[PATH_MAX]; // Path of the command char arg1[PATH_MAX]; // First argument char end[PATH_MAX]; // other args /*~PROTOBEG~ INITTAB_REC */ public: INITTAB_REC (void); private: void init (void); public: int parse (const char *line); bool reformat (SSTRING&line); /*~PROTOEND~ INITTAB_REC */ }; PRIVATE void INITTAB_REC::init() { id[0] = verb[0] = command[0] = arg1[0] = end[0] = '\0'; memset (runlevels,0,sizeof(runlevels)); } PUBLIC INITTAB_REC::INITTAB_REC() { init(); } /* Parse a line of the inittab file return -1 if the line is not valid. */ PUBLIC int INITTAB_REC::parse (const char *line) { int ret = -1; init(); char tmp[strlen(line)+1]; strcpy (tmp,line); char *pt = strchr(tmp,':'); if (pt != NULL){ *pt++ = '\0'; strcpy_cut (id,tmp,sizeof(id)); char *start = pt; pt = strchr(pt,':'); if (pt != NULL){ *pt++ = '\0'; while (*start != '\0'){ char car = *start++; if (isdigit(car)){ car -= '0'; runlevels[car] = 1; } } start = pt; pt = strchr(pt,':'); if (pt != NULL){ *pt++ = '\0'; strcpy_cut (verb,start,sizeof(verb)); pt = str_copyword (command,pt,sizeof(command)); pt = str_copyword (arg1,pt,sizeof(arg1)); pt = str_skip(pt); strcpy_cut (end,pt,sizeof(end)); ret = 0; } } } return ret; } /* Format back a parse /etc/inittab record Return true if the line was changed */ PUBLIC bool INITTAB_REC::reformat (SSTRING &line) { char tmp[3*PATH_MAX]; char levels[7]; char *pt = levels; for (int i=1; i<7; i++){ if (runlevels[i]) *pt++ = '0' + i; } *pt = '\0'; snprintf (tmp,sizeof(tmp)-1,"%s:%s:%s:%s %s %s" ,id,levels,verb,command,arg1,end); bool ret = line.cmp(tmp)!=0; line.setfrom (tmp); return ret; } class INITTAB{ VIEWITEMS items; /*~PROTOBEG~ INITTAB */ public: INITTAB (void); int getdefaultlevel (void); private: VIEWITEM *locatedefaultlevel (INITTAB_REC&rec); public: int setdefaultlevel (int newlevel); /*~PROTOEND~ INITTAB */ }; PUBLIC INITTAB::INITTAB() { items.read (f_inittab); } static const char K_INITDEFAULT[]="initdefault"; PRIVATE VIEWITEM *INITTAB::locatedefaultlevel(INITTAB_REC &rec) { VIEWITEM *ret = NULL; for (int i=0; iline.get()); if (strcmp(rec.verb,K_INITDEFAULT)==0){ ret = it; break; } } return ret; } /* Set the default run level in /etc/inittab Return -1 if if can't be set */ PUBLIC int INITTAB::setdefaultlevel (int newlevel) { int ret = -1; if (newlevel > 0 && newlevel < 7){ INITTAB_REC rec; VIEWITEM *def = locatedefaultlevel(rec); if (def == NULL){ strcpy (rec.id,"id"); strcpy (rec.verb,K_INITDEFAULT); def = new VIEWITEM(""); items.insert (0,def); } memset (rec.runlevels,0,sizeof(rec.runlevels)); rec.runlevels[newlevel] = 1; SSTRING line; rec.reformat(line); def->line.setfrom (line.get()); ret = items.write (f_inittab,NULL); } return ret; } /* Return the current default runlevel */ PUBLIC int INITTAB::getdefaultlevel() { int ret = -1; INITTAB_REC rec; VIEWITEM *def = locatedefaultlevel(rec); if (def != NULL){ for (int i=1; i<7; i++){ if (rec.runlevels[i]){ ret = i; break; } } } return ret; } static int inittab_getdefaultlevel() { INITTAB init; return init.getdefaultlevel(); } int inittab_setdefaultlevel (int newlevel) { INITTAB init; return init.setdefaultlevel(newlevel); } void *inittab_api_get () { INITTAB_API *api = new INITTAB_API; api->getdefaultlevel = inittab_getdefaultlevel; api->setdefaultlevel = inittab_setdefaultlevel; return api; } void inittab_api_release (void *api) { delete (INITTAB_API*)api; } void inittab_menu() { DIALOG dia; char def = inittab_getdefaultlevel(); SSTRINGS tb; int text_mode = distrib_getvalnum("runlevel_text",-1); int graph_mode = distrib_getvalnum("runlevel_graph",-1); int single_mode = distrib_getvalnum("runlevel_single",-1); for (int i=1; i<6; i++){ SSTRING level; level.setfromf (MSG_U(F_RUNLEVEL,"Run level %d"),i); if (i == text_mode){ level.appendf (" %s",MSG_U(I_TEXTMODE,"Text console")); }else if (i == graph_mode){ level.appendf (" %s",MSG_U(I_GRAPHICMODE,"Graphical workstation")); }else if (i == single_mode){ level.appendf (" %s",MSG_U(I_SINGLEMODE,"Single user/Maintenance")); } dia.newf_radio (i==1 ? MSG_U(F_DEFAULTLEVEL,"Default runlevel") : "" ,def,i,level.get()); } int nof = 0; if (dia.edit (MSG_U(T_DEFLEVEL,"Init default runlevel") ,"",help_nil,nof)==MENU_ACCEPT){ inittab_setdefaultlevel (def); } }