#pragma implementation #include #include #include #include #include #include #include "postfixconf.h" #include #include #include #include "postfixconf.m" #include "canonical.h" PUBLIC CAN::CAN() { } PUBLIC CAN::CAN(char *line) { char *p = str_skip(line); // cut white spaces at the end of string if (p[0] == '#'){ // if comment, its stored on coment variable comment.setfrom (p); }else{ // the first content is read char buffer[1000]; int j=0; for (; *p!=' ' && *p!='\0'; j++,p++) buffer[j] = *p; buffer[j] = '\0'; name.setfrom(buffer); buffer[0] = '\0'; p = str_skip(p); // * * * try change this code with splitline //add address for (j=0; *p!='\0';p++){ if (isspace(*p)) continue; buffer[j] = *p; j++; } buffer[j] = '\0'; if (j>0) address.setfrom(buffer); } } PUBLIC const char *CAN::getname() { return name.get(); } PUBLIC int CAN::is_valid() { return !name.is_empty(); } /* Edit an table item definition. Return -1 if the user abort the edition (The record is left unchanged then). Return 0 if the user accepted changes Return 1 if the user request the deletion of this record */ PUBLIC int CAN::edit(PRIVILEGE *privi) { DIALOG dia; dia.newf_str (MSG_U(F_CANNAME,"name"),name); dia.newf_str (MSG_U(F_CANADDRESS,"address"),address); int no = 0; int ret = -1; while (1){ MENU_STATUS code = dia.edit ( MSG_U(T_ONECANONICAL ,"One canonical table item definition") ,MSG_U(I_ONECANONICAL ,"Edit a canonical table item definition") ,help_postfix_canonical ,no ,MENUBUT_ACCEPT|MENUBUT_CANCEL|MENUBUT_DEL); if (code == MENU_ESCAPE || code == MENU_CANCEL){ break; }else if (code == MENU_DEL){ if (xconf_delok ()){ ret = 1; break; } }else if (code == MENU_ACCEPT && perm_access(privi,MSG_U(P_EDITCANONICAL,"edit canonical"))){ if (name.is_empty()){ no = 0; xconf_error (MSG_R(E_NONAME)); }else{ if (address.is_empty()){ no = 1; xconf_error (MSG_U(E_NOADRESS,"You must provide an address")); }else{ ret = 0; break; } } } } if (ret == 0){ setmodified(); }else{ dia.restore(); } return ret; } /* Save the content of object CAN to file */ PUBLIC void CAN::write (FILE_CFG *fout) { if (!name.is_empty()){ fprintf (fout, "%s ",name.get()); fprintf (fout,"%s",address.get()); } fprintf (fout, "%s\n",comment.get()); } PUBLIC CAN *CANONICAL::getitem(int no) { return (CAN*)ARRAY::getitem(no); } PUBLIC CANONICAL::CANONICAL( const char *config, PRIVILEGE *_privi, bool _dodb, int _btype) : f(config,help_postfix_canonical, CONFIGF_OPTIONAL|CONFIGF_MANAGED, subsys_postfix) {// read one line and pass it to new CAN object privi = _privi; dodb = _dodb; btype = _btype; FILE_CFG *fin = f.fopen ("r"); if (fin != NULL){ char line[10000]; line[0] = '\0'; while (fgets(line,sizeof(line)-1,fin)!=NULL){ strip_end (line); if (line[0] != '\0'){ add (new CAN(line)); } } fclose (fin); rstmodified(); } } PUBLIC int CANONICAL::edit() { int choice = 0; DIALOG_LISTE *dia = NULL; SSTRINGS tbsort; SSTRINGS adrs; tbsort.neverdelete(); adrs.neverdelete(); while (1){ if (dia == NULL){ dia = new DIALOG_LISTE; tbsort.remove_all(); adrs.remove_all(); dia->newf_head ("",MSG_U(H_CANITEM,"Canonical items")); for (int i=0; iis_valid()){ SSTRING s(c->name.get()); tbsort.add(&c->name); adrs.add(&c->address); } } for (int i=0; inew_menuitem(tbsort.getitem(i)->get(), adrs.getitem(i)->get()); } dia->addwhat (MSG_U(I_NEWCANINICAL,"Select [Add] to add a new canonical item")); } MENU_STATUS code = dia->editmenu ( MSG_U(T_CANTABLEEDIT2,"Here, you can find a list of canonical maps.") ,MSG_U(I_CANTABLEEDIT ,"You are allowed to edit/add/delete\n" "canonical items") ,help_postfix_canonical ,choice,0); CAN *item = NULL; if (choice >=0 && choice get()); item = getitem(no); } bool must_delete = false; if (code == MENU_ESCAPE || code == MENU_QUIT){ break; }else if (code == MENU_OK){ if (item != NULL){ int ok = item->edit (privi); if (manage_edit (item,ok) >= 0){ must_delete = true; } } }else if (perm_access(privi,MSG_R(P_WRITE),f.getpath())){ if (code == MENU_ADD){ addnew(); must_delete = true; } } if (must_delete){ delete dia; dia = NULL; } } delete dia; return nb; } /* Find an canonical item in the table. Return -1 if not found. Return the index otherwise. */ PUBLIC int CANONICAL::locate (const char *name) { int ret = -1; int nb = getnb(); for (int i=0; igetname(),name)==0){ ret = i; break; } } return ret; } PUBLIC void CANONICAL::addnew() { CAN *a = new CAN; int v; while ( (v=(a->edit(privi)))==0){ /*if (locate(a->getname())!=-1){ xconf_error ("Duplicate virtual item, rejected"); }else{*/ add (a); write(); a = NULL; break; //} } delete a; } PUBLIC int CANONICAL::write () { int ret = -1; FILE_CFG *fout = f.fopen (privi,"w"); if (fout != NULL){ for (int i=0; iwrite(fout); } ret = fclose (fout); rstmodified(); // insert here the execution necessary to create the table if (dodb){ SSTRING notice; const char *cmd = "postmap"; char *buf = type(btype); char path[50]; sprintf (path,"%s%s",buf,f.getpath()); if (execute (cmd,path,notice)){ xconf_notice ("%s",notice.get()); }else xconf_notice (MSG_R(E_EXECCOMM),cmd,path); } } return ret; } // insert the type of table for 'postmap' command PRIVATE char *CANONICAL::type (int nametable) { char *buf; switch (nametable){ case BTREE_DATABASE: buf = "btree:"; break; case DBM_DATABASE: buf = "dbm:"; break; case HASH_DATABASE: buf = "hash:"; break; default: buf = ""; } return buf; }