// vim: nowrap /* *********** Module: Pnp Created: 15/05/2000 Last Modified: 19/06/2000 Author: Cristiano Otto Von Trompczynski e-mail: cris@conectiva.com.br Description: Main file containing all the functions which work with windows to the user and handle all the functions in other files. "This module is for you, Penguin!" *********** */ #pragma implementation #include #include #include #include #include #include #include "isapnpconf.h" MODULE_DEFINE_VERSION(isapnpconf); PUBLIC MODULE_isapnpconf::MODULE_isapnpconf() : LINUXCONF_MODULE("isapnpconf") { linuxconf_loadmsg ("isapnpconf",PACKAGE_REV); } static const char *keymenu=NULL; PUBLIC void MODULE_isapnpconf::setmenu ( DIALOG &dia, MENU_CONTEXT context) { if (context == MENU_HARDWARE){ keymenu = MSG_U(M_ISAPNPCONF,"Isa Plug and Play"); dia.new_menuitem ("isapnpconf","",keymenu); } } PUBLIC int MODULE_isapnpconf::domenu ( MENU_CONTEXT context, const char *key) { if (context == MENU_HARDWARE){ if (key == keymenu){ // ### Place the call to the edit function here isapnpconf_start(); } } return 0; } PUBLIC int MODULE_isapnpconf::dohtml (const char *key) { int ret = LNCF_NOT_APPLICABLE; if (strcmp(key,"isapnpconf")==0){ // ### Insert any menu and dialog here ret = 0; } return ret; } static void usage() { xconf_error (MSG_U(T_USAGE ,"linuxconf --modulemain isapnpconf usage\n" "\n" " isapnpconf --option ...\n") ); } PUBLIC void MODULE_isapnpconf::usage (SSTRINGS &tb) { tb.add (new SSTRING (MSG_R(T_USAGE))); } PUBLIC int MODULE_isapnpconf::execmain (int argc , char *argv[], bool) { int ret = LNCF_NOT_APPLICABLE; const char *pt = strrchr(argv[0],'/'); if (pt != NULL){ pt++; }else{ pt = argv[0]; } if (strcmp(pt,"isapnpconf")==0){ ret = -1; if (argc == 1){ // ### Place call to main menu of the module isapnpconf_start (); }else{ // ### Add some option parsing for the module ::usage(); } } return ret; } static MODULE_isapnpconf isapnpconf; /* void MODULE_isapnpconf::isapnpconf_start () This is the main function. It's responsible to treat the main errors which could be generated during the program execution. RETURN: Nothing */ PUBLIC void MODULE_isapnpconf::isapnpconf_start (){ bool valid = true; while ( valid ){ switch ( isapnpconf_edit() ){ case OK: valid = false; break; case ERROR: xconf_notice (MSG_U(E_INTERNAL,"Internal ERROR !")); valid = false; break; case ERROR1: xconf_notice (MSG_U(N_NOISA,"No ISA device found !")); if ( dialog_yesno ("Alert!",MSG_U(Q_WISHGENCFGDETECTION,"Do you wish to generate once more the config file and re-do the detection ?"),help_isapnpconf_default)==MENU_YES ){ if (file_copy ("/etc/isapnp.conf","/etc/isapnp.conf.bkp") == ERROR){ if (dialog_yesno ("Alert!",MSG_U(Q_NOTGENBKPFILES,"Couldn't generate a backup copy!\nDetect anyway ?"),help_isapnpconf_copseg)==MENU_NO){ valid = false; break; } } if (rewrite_isapnp()==ERROR){ xconf_notice (MSG_U(Q_NOTGENISAPNPFILE,"Couldn't generate the 'isapnp.conf' file!")); valid = false; break; } xconf_notice (MSG_U(N_BKPFILE,"The file 'isapnp.conf' was archived with the name 'isapnp.bkp'\nAnother config file was generated !")); }else valid = false; break; case ERROR2: xconf_notice (MSG_U(E_EXECISAPNPCMD,"Error on executing the 'isapnp' command !")); valid = false; break; case ERROR3: xconf_notice (MSG_R(E_INTERNAL)); valid = false; break; case ERROR4: xconf_notice (MSG_U(E_OPENCLOSECFGFILE,"Error in opening or closing config file!")); valid = false; break; case ERROR6: xconf_notice (MSG_U(E_MEMALLOC,"Memory allocation error!")); valid = false; break; case ERROR7: if ( dialog_yesno ("Alert!",MSG_U(Q_NECGENCFGDETECTION,"It's necessary to generate once more the config file 'isapnp.conf'!\n\nWould you like to generate a new config file ?"),help_isapnpconf_default)==MENU_YES ){ if (file_copy ("/etc/isapnp.conf","/etc/isapnp.bkp") == ERROR){ xconf_notice (MSG_U(N_COULDNOTGENBKPFILE,"Couldn't generate backup copy!")); valid = false; break; } if (rewrite_isapnp()==ERROR){ xconf_notice (MSG_R(Q_NOTGENISAPNPFILE)); valid = false; break; } xconf_notice (MSG_R(N_BKPFILE)); }else valid = false; break; case ERROR8: xconf_notice (MSG_R(E_INTERNAL)); valid = false; break; } clean_struct(); } clean_struct (); return; } /* PUBLIC int MODULE_isapnpconf::detec (SSTRINGS &isapnp) This function executes ISAPNP and treats the result setting the configuration of each CARD found. 1 - In case CONFIGURE has obtained success; 0 - In case it hasn't RETURN: OK - if success ERROR2 - POPEN isn't OK ERROR5 - file ISAPNP.CONF not found */ PUBLIC int MODULE_isapnpconf::detec (SSTRINGS &isapnp, SSTRINGS &log){ if(!cf_pnp.exist()){ // the isapnp.conf file exist? return ERROR5; } //do detection const char *args="/etc/isapnp.conf"; const char *isap="/sbin/isapnp"; char buffer[512]; char bufferr[512]; POPEN pop (isap, args); SSTRINGS ss; SSTRINGS serr; if (pop.isok()){ while (pop.wait(100)==0); while ( pop.readout(buffer,511)!=-1 ) ss.add (new SSTRING(buffer)); while ( pop.readerr(bufferr,511)!=-1 ) serr.add (new SSTRING(bufferr)); log.append (ss); log.append (serr); }else return ERROR2; pop.close(); int nCard=get_n_card(); for (int i=0; ivendor_Id+j)!='\0'; j++) //Store in BUFFER the vendor_Id/serial buffer[j]=*(c->vendor_Id+j); buffer[j]='/'; j++; for (int m=0; *(c->serial+m)!='\0'; j++,m++) buffer[j]=*(c->serial+m); buffer[j]='\0'; int nCfg=get_n_configure (c); for (int p=0; psuccess=-1; } for (int k=0; kget(); if ( !(strstr(s,buffer)) ){ continue; } //Exist! get the integer ID of the line char b[4]; int q = strlen (buffer); int o; if (*(s+q)=='[' && strchr(s,']') ){ for (++q,o=0; *(s+q)!=']'; q++,o++) b[o]=*(s+q); }else continue; b[o]='\0'; int ldd = atoi(b); //So, get the CONFIGURE with this ID struct configure *cfg = get_configure (c,ldd); if (cfg) cfg->success = 1; } } return OK; } /* PUBLIC int MODULE_isapnpconf::add(SSTRINGS &isapnp) Receives the structure and looks for changes in the SETTING flags. In case changes exist. modifies the lines to each SETTING commenting or not RETURN:: OK - sucesso ERROR3 - the ISAPNP.CONF file must be generated again ERROR4 - error trying open/close file */ PUBLIC int MODULE_isapnpconf::add(SSTRINGS &isapnp){ int nCard=get_n_card(); char buffer[512]; for (int i=0; iinUseCg == set->inUse){ continue; }else if (set->inUseCg==1 && set->inUse==0){ //enable SETTING int nio=get_n_io (set); for (int l=0; lline_io); s->copy(buffer); int m; for (m=0;buffer[m]!='#'; m++ ) if (buffer[m]=='\0' || buffer[m]=='(') return ERROR3; buffer[m]=' '; s->setfrom(buffer); } int nirq=get_n_irq (set); for (int l=0; lline_irq); s->copy(buffer); int m; for (m=0;buffer[m]!='#'; m++ ) if (buffer[m]=='\0' || buffer[m]=='(') return ERROR3; buffer[m]=' '; s->setfrom(buffer); } int ndma=get_n_dma (set); for (int l=0; lline_dma); s->copy(buffer); int m; for (m=0;buffer[m]!='#'; m++ ) if (buffer[m]=='\0' || buffer[m]=='(') return ERROR3; buffer[m]=' '; s->setfrom(buffer); } set->inUse=1; continue; }else if (set->inUseCg==0 && set->inUse==1){ //disable SETTING int nio=get_n_io (set); for (int l=0; lline_io); s->copy(buffer); int m; for (m=0;buffer[m]!=' ' && buffer[m]!='('; m++ ) if (buffer[m]=='\0' || buffer[m]=='#') return ERROR3; if (buffer[m]=='('){ char tbuf[512]; strcpy (tbuf+2, buffer); strcpy (buffer,tbuf); } buffer[1]=' '; buffer[0]='#'; s->setfrom(buffer); } int nirq=get_n_irq (set); for (int l=0; lline_irq); s->copy(buffer); int m; for (m=0;buffer[m]!=' ' && buffer[m]!='('; m++ ) if (buffer[m]=='\0' || buffer[m]=='#') return ERROR3; if (buffer[m]=='('){ char tbuf[512]; strcpy (tbuf+2, buffer); strcpy (buffer,tbuf); } buffer[1]=' '; buffer[0]='#'; s->setfrom(buffer); } //for DMA int ndma=get_n_dma (set); for (int l=0; lline_dma); s->copy(buffer); int m; for (m=0;buffer[m]!=' ' && buffer[m]!='('; m++ ) if (buffer[m]=='\0' || buffer[m]=='#') return ERROR3; if (buffer[m]=='('){ char tbuf[512]; strcpy (tbuf+2, buffer); strcpy (buffer,tbuf); } buffer[1]=' '; buffer[0]='#'; s->setfrom(buffer); } set->inUse=0; } } } } if (save_file(isapnp)==ERROR) //save File return ERROR4; return OK; } /* PUBLIC int MODULE_isapnpconf::isapnpconf_edit(){ This is the main function, responsible by mounting all the DIALOGs, calling different functions for creation, manipulation and update the structure. RETURN: OK - se sucesso ERROR - general ERROR ERROR 1 - Cards not found ERROR 4 - error trying open/close file ERROR 6 - allocation error ERROR 7 - changed data ISAPNP.CONF ERROR 8 - error acessing 'get()' */ PUBLIC int MODULE_isapnpconf::isapnpconf_edit(){ SSTRINGS isapnp; SSTRINGS log; // Creating Structure switch ( create_struct(isapnp) ){ case ERROR4: return ERROR4; case ERROR6: clean_struct (); return ERROR6; case ERROR7: clean_struct (); return ERROR7; } bool detect=false; bool must_delete=false; int nCard=get_n_card(); if (nCard>0){ SSTRINGS str_dev; DIALOG_LISTE *diadev = NULL; // create the dialog that will contain the list of devices int nof=0; while (1){ if (diadev == NULL){ // if NULL generate the dialog str_dev.remove_all(); must_delete=false; diadev = new DIALOG_LISTE; diadev->setbutinfo (MENU_USR2, MSG_U(B_DEFAULT,"Default"), MSG_R(B_DEFAULT)); diadev->setbutinfo (MENU_USR3, MSG_U(B_LOG,"Log"), MSG_R(B_LOG)); diadev->newf_head ("",MSG_U(F_HEADER,"Serial\tDescription\t\tVendor Id\tStatus")); for (int i=0; isetfrom (c->description); onedev->append ("\t\t"); onedev->append (c->vendor_Id); if (detect){ int nCfg=get_n_configure (c); bool failure=false; for (int j=0; jsuccess==-1) failure=true; } onedev->append ("\t"); onedev->append (" "); if (failure) onedev->append (MSG_U(X_FAIL,"Failure")); else onedev->append (MSG_U(X_OK,"Ok")); } diadev->new_menuitem (c->serial,onedev->get()); } } int but_opt = MENUBUT_ACCEPT|MENUBUT_USR2; if (log.getnb()>0) but_opt |= MENUBUT_USR3; MENU_STATUS code = diadev->editmenu (MSG_U(T_ISAPNPCFG,"Isa Plug and Play Configuration"),MSG_U(I_PRINCDIALOG,"version 1.3\n" "You will find below all the isa plug and play devices which\n" "you have in your system." "You can select, accept or restore the standard configuration.\n" "Select any configuration to obtain its information or change it.\n" "Select [Accept] to make all the changes effective and validate" "the current configuration.\n" "Select [Default] to restore the original configuration."),help_isapnpconf_princ, nof, but_opt); if (code == MENU_QUIT || code == MENU_ESCAPE){ break; } if (nof >=0 && nof0){ DIALOG dia_conf; SSTRINGS str_conf; SSTRINGS str_descs; SSTRINGS allsettings; int set_in_use=0; for (int i=0; idescription==NULL || *(cfg->description)==0 ) strdesc->setfrom (c->description); else strdesc->setfrom (cfg->description); if (detect){ strdesc->append (" "); if (cfg->success==1) strdesc->append (MSG_R(X_OK)); if (cfg->success==-1) strdesc->append (MSG_R(X_FAIL)); } dia_conf.newf_title(strdesc->get(),0,"",strdesc->get()); //populate SETTINGs SSTRINGS *settings=NULL; SSTRING *current=NULL; int nSet=get_n_settings (cfg); if (nSet>0){ set_in_use = -1; settings = populate_settings(cfg, nSet, set_in_use); if (!settings){ delete diadev; return ERROR8; } for (int i=0; igetnb(); i++) allsettings.add(settings->getitem(i)); if (set_in_use==-1){ current = new SSTRING ("-1"); } else current = new SSTRING ( *(settings->getitem(set_in_use)) ); }else current = new SSTRING ("-1"); str_conf.add(current); if (settings){ FIELD_LIST *flist = dia_conf.newf_list("", *(current)); for (int j=0; jgetnb(); j++){ SSTRING *ts = settings->getitem(j); char x[4]; sprintf(x,"%d",j); flist->addopt (x,ts->get(),""); } } } int nof2=0; MENU_STATUS menu_cfg = dia_conf.editmenu (MSG_U(T_SELECTCFG,"Select the Configuration"),MSG_U(I_SECDIALOG,"You have below all the configuration for the selected device.\n" "You can change each configuration.\n" "To confirme the changes choose [Accept]."),help_isapnpconf_conf, nof2, MENUBUT_ACCEPT); if (menu_cfg == MENU_ACCEPT){ for (int i=0; iget()); // r stores the choosen SETTING number if (r==-1) continue; //the struct must be updated //go across all settings of the choosen card and set new states! struct configure *cfg=get_configure (c,i); if (cfg==NULL) break; int k=get_n_settings(cfg); if (k<=0) break; for (int l=0;linUseCg=false; if (l==r) s->inUseCg=true; } } } } } if (code == MENU_USR2){ if ( dialog_yesno ("Alert!",MSG_U(Q_GENISAPNPAGAIN,"Would you like to generate the 'isapnpfile' file again?"),help_isapnpconf_default)==MENU_YES ){ if (file_copy ("/etc/isapnp.conf","/etc/isapnp.bkp") == ERROR){ if ( dialog_yesno ("Alert!",MSG_U(Q_COULDNOTGENBKPGENANYWAY,"Couldn't generate backup copy! Should we generate the file anyway?"),help_isapnpconf_copseg)==MENU_NO ) continue; } if (rewrite_isapnp()==ERROR){ xconf_notice (MSG_U(N_COULDNOTGENDEFAULTISAPNP,"Couldn't generate default 'isapnp.conf'!")); continue; } clean_struct(); isapnp.remove_all(); //cleaning struct //rebuilding struct switch ( create_struct(isapnp) ){ case ERROR4: return ERROR4; case ERROR6: clean_struct (); return ERROR6; case ERROR7: clean_struct (); return ERROR7; } nCard=get_n_card(); detect=false; must_delete=true; }else continue; } if (code == MENU_USR3){ SSTRING ts; int size=0; for (int i=0; igetmaxsiz() ); ts.append ( (log.getitem(i))->get() ); } xconf_notice ("%s",ts.get()); } if (code == MENU_ACCEPT){ //change the file and validate switch ( add(isapnp) ){ case ERROR3: return ERROR3; case ERROR4: return ERROR4; } log.remove_all(); switch ( detec(isapnp, log) ){ case ERROR2: return ERROR2; case ERROR5: return ERROR5; } detect=true; must_delete=true; } if (must_delete){ delete diadev; diadev = NULL; } } delete diadev; return OK; }else return ERROR1; clean_struct (); return OK; } /* PUBLIC SSTRINGS *MODULE_isapnpconf::populate_settings(){ Populate the SETTINGs of a configuration RETURN: SSTRINGS */ PUBLIC SSTRINGS *MODULE_isapnpconf::populate_settings(struct configure *cfg, int nSet, int &set_in_use){ SSTRINGS *strs = new SSTRINGS(); for (int j=0; jadd(st); if (s->inUseCg==1 ) set_in_use=j; st->appendf ("%d:",j); int nio=get_n_io (s); if (nio>0){ for (int k=0; kappend (" "); struct s_io *io=NULL; io=get_io(s,k); if (io==NULL){ delete (strs); return NULL; } st->appendf ("IO %d:%s",k,io->io); } } int nirq=get_n_irq (s); if (nirq>0){ for (int l=0; lappend (" "); struct s_irq *irq=NULL; irq=get_irq(s,l); if (irq==NULL){ delete (strs); return NULL; } st->appendf ("IRQ %d:%s",l,irq->irq); } } int ndma=get_n_dma (s); if (ndma>0){ for (int m=0; mappend (" "); struct s_dma *dma=NULL; dma=get_dma(s,m); if (dma==NULL){ delete (strs); return NULL; } st->appendf ("DMA %d:%s",m,dma->dma); } } } return strs; }