// vim: nowrap #include #include #include "postfixconf.h" #include "postfixconf.m" #include "alias.h" #include "virtuals.h" #include "canonical.h" /* DESCRIPTION: This DIALOG contains settings of Postfix configuration that control the PATH for tables RETURN: 0 - case the user accept the changes 1 - case the user cancel the changes */ PUBLIC int MODULE_postfixconf::tablelocations_edit(DATAMAIN &data){ int ret = 0; int nof = 0; DIALOG dia; SSTRING *st = NULL; // transport_maps st = data.getvarvariable(V_TRANSPORT_MAPS); char tmp_transpmaps[512]; strncpy (tmp_transpmaps,st->get(), sizeof(tmp_transpmaps)-1); dia.newf_str(MSG_U(F_TRANSPMAPS,"Transport maps"),*st); // relocated_maps st = data.getvarvariable(V_RELOCATED_MAPS); char tmp_relocmaps[512]; strncpy (tmp_relocmaps,st->get(), sizeof(tmp_relocmaps)-1); dia.newf_str(MSG_U(F_RELOCMAPS,"Relocated maps"),*st); // virtual_maps st = data.getvarvariable(V_VIRTUAL_MAPS); char tmp_vrtmap[512]; strncpy (tmp_vrtmap,st->get(), sizeof(tmp_vrtmap)-1); dia.newf_str(MSG_U(F_VIRTUALMAPS,"Virtual maps"),*st); // canonical_maps st = data.getvarvariable(V_CANONICAL_MAPS); char tmp_canmaps[512]; strncpy (tmp_canmaps,st->get(), sizeof(tmp_canmaps)-1); dia.newf_str(MSG_U(F_CANONICALMAPS,"Canonical maps"),*st); // recipient_canonical_maps st = data.getvarvariable(V_RECIPIENT_CANONICAL_MAPS); dia.newf_str(MSG_U(F_RECCANONICALMAPS,"Recipient canonical maps"),*st); // sender_canonical_maps st = data.getvarvariable(V_SENDER_CANONICAL_MAPS); dia.newf_str(MSG_U(F_SNDCANONICALMAPS,"Sender canonical maps"),*st); // alias_maps st = data.getvarvariable(V_ALIAS_MAPS); char tmp_aliasmaps[512]; strncpy (tmp_aliasmaps,st->get(), sizeof(tmp_aliasmaps)-1); dia.newf_str(MSG_U(F_ALIASMAPS,"Alias maps"),*st); // alias_database st = data.getvarvariable(V_ALIAS_DATABASE); char tmp_aliasdatabase[512]; strncpy (tmp_aliasdatabase,st->get(), sizeof(tmp_aliasdatabase)-1); dia.newf_str(MSG_U(F_ALIASDATABASE,"Alias database"),*st); dia.setbutinfo (MENU_USR1, MSG_R(B_SETTODEFAULT), MSG_R(B_SETTODEFAULT)); while (1){ MENU_STATUS code = dia.edit( MSG_U(T_TABLELOCATIONS,"Configure path tables") ,MSG_U(I_TABLELOCATIONS,"Here you can configure the postfix tables path") ,help_postfix_tablelocations ,nof ,MENUBUT_CANCEL|MENUBUT_ACCEPT|MENUBUT_USR1); if (code == MENU_CANCEL || code == MENU_ESCAPE){ break; }else if (code == MENU_ACCEPT){ // validacoes gerais // transport_maps st = data.getvarvariable(V_TRANSPORT_MAPS); char buffer[500]; if (st->cmp(tmp_transpmaps)!=0){ sprintf (buffer,MSG_U(N_DATABASECHANGED,"The '%s' parameter was changed.\n" "You must run 'postmap [file type:]file name'\n" "to rebuild needed binary files. The module can\n" "run such command only to try to generate DB,\n" "DBM and HASH tables pointed by the parameter\n" "\n" "Other possible tables must be generated by the user\n" "Do you want the module to try to generate the tables now?") ,"Transport map"); if (dialog_yesno (MSG_U(N_ALERT,"Alert!"), buffer, help_postfix_tablelocations)==MENU_YES){ SSTRING notice; const char *comm = "postmap"; if (data.execall(comm, V_TRANSPORT_MAPS, notice)==0) xconf_error (MSG_U(E_DATABASECHANGED, "An error occurred while executing '%s' command\n" "Command was not executed."), comm); else if (!notice.is_empty()) xconf_notice (MSG_U(N_LOG,"Log:\n%s"), notice.get()); } } // relocated_maps st = data.getvarvariable(V_RELOCATED_MAPS); if (st->cmp(tmp_relocmaps)!=0){ // test if the variable was changed sprintf(buffer,MSG_R(N_DATABASECHANGED),"Relocated maps"); if (dialog_yesno (MSG_R(N_ALERT), buffer, help_postfix_tablelocations)==MENU_YES){ SSTRING notice; const char *comm = "postmap"; if (data.execall(comm, V_RELOCATED_MAPS, notice)==0) xconf_error (MSG_R(E_DATABASECHANGED), comm); else if (!notice.is_empty()) xconf_notice (MSG_R(N_LOG), notice.get()); } } // virtual_maps st = data.getvarvariable(V_VIRTUAL_MAPS); if (st->cmp(tmp_vrtmap)!=0){ sprintf(buffer,MSG_R(N_DATABASECHANGED),"Virtual maps"); if (dialog_yesno (MSG_R(N_ALERT),buffer,help_postfix_tablelocations)==MENU_YES){ SSTRING notice; const char *comm = "postmap"; if (data.execall(comm, V_VIRTUAL_MAPS, notice)==0) xconf_error (MSG_R(E_DATABASECHANGED),comm); else if (!notice.is_empty()) xconf_notice (MSG_R(N_LOG), notice.get()); } } // canonical_maps st = data.getvarvariable(V_CANONICAL_MAPS); if (st->cmp(tmp_canmaps)!=0){ sprintf (buffer,MSG_R(N_DATABASECHANGED),"Canonical maps"); if (dialog_yesno (MSG_R(N_ALERT),buffer,help_postfix_tablelocations)==MENU_YES){ SSTRING notice; const char *comm = "postmap"; if (data.execall(comm, V_CANONICAL_MAPS, notice)==0) xconf_error (MSG_R(E_DATABASECHANGED), comm); else if (!notice.is_empty()) xconf_notice (MSG_R(N_LOG), notice.get()); } } // alias_maps st = data.getvarvariable(V_ALIAS_MAPS); if (st->cmp(tmp_aliasmaps)!=0){ sprintf (buffer,MSG_R(N_DATABASECHANGED),"Alias maps"); if (dialog_yesno (MSG_R(N_ALERT),buffer,help_postfix_tablelocations)==MENU_YES){ SSTRING notice; const char *comm = "postmap"; if (data.execall(comm, V_ALIAS_MAPS, notice)==0) xconf_error (MSG_R(E_DATABASECHANGED), comm); else if (!notice.is_empty()) xconf_notice (MSG_R(N_LOG), notice.get()); } } // alias_database st = data.getvarvariable(V_ALIAS_DATABASE); if (st->cmp(tmp_aliasdatabase)!=0){ if (st->is_empty()){ nof=7; xconf_notice (MSG_R(N_NOTEMPTY)); continue; } sprintf (buffer,MSG_R(N_DATABASECHANGED),"Alias database"); if (dialog_yesno (MSG_R(N_ALERT),buffer,help_postfix_tablelocations)==MENU_YES){ SSTRING notice; const char *comm = "newaliases"; const char *arg = ""; if (!execute(comm, arg, notice)){ xconf_error (MSG_U(E_DATABASECHANGEDII,"An error occurred while executing \"%s%s\"\n" "Command was not executed."), comm, arg); } if (!notice.is_empty()) xconf_notice (MSG_R(N_LOG), notice.get()); } } ret = 1; break; }else if (code == MENU_USR1){ if ( dialog_yesno(MSG_R(T_RESTORETODEFAULT) ,MSG_R(N_RESTORETODEFAULT) ,help_postfix_basic) == MENU_YES ){ int values[]={ V_TRANSPORT_MAPS, V_RELOCATED_MAPS, V_VIRTUAL_MAPS, V_CANONICAL_MAPS, V_RECIPIENT_CANONICAL_MAPS, V_SENDER_CANONICAL_MAPS, V_ALIAS_MAPS, V_ALIAS_DATABASE, -1 }; data.setdefaultvarvalues(values); dia.reload(); } } } return ret; } /* DESCRIPTION: Show btree, dbm and hash virtual tables types where its path is on 'virtual_maps' variable. Virtual tables can be erased. If table is erased, the module looks for its path in 'virtual_maps' variable and erase them. RETURN: 0 - no table is selected 1 - if table is selected */ PUBLIC int MODULE_postfixconf::virtualtable_edit(DATAMAIN &data){ int ret = 0; int choice = 0; int nb=0; DIALOG_LISTE *dia=NULL; SSTRINGS st; while (1){ if (dia==NULL){ // if dialog isn't created, generate an SSTRINGs that contain only the table paths // for possibles table types (filtered by 'checktables'). SSTRINGS *str = data.checktables(data.getvarvariable(V_VIRTUAL_MAPS)); st.remove_all(); if (str!=NULL) st.append(*str); if (st.getnb()==0){ xconf_notice (MSG_U(N_VIRTUALTABLEEMPTY, "No valid path found\n" "You can add a valid path in\n" "Table locations -> Virtual maps\n\n" "See helpfile on this items")); return ret; } dia = new DIALOG_LISTE; dia->newf_head ("",MSG_U(H_VIRTTABLEPATHS,"Virtual table paths")); nb = st.getnb(); for (int i=0; inew_menuitem (*(st.getitem(i)),""); } bool must_delete = false; MENU_STATUS code = dia->editmenu (MSG_U(T_VIRTUALEDIT,"Virtual table edit") ,MSG_U(I_DESCVIRTUALTABLE,"You are allowed to edit/add/delete\n" "virtual tables") ,help_postfix_virtual ,choice,0); if (code == MENU_ESCAPE || code == MENU_QUIT) break; // parse tha selected path and pass to 'tbse' tje table type and edit them if (choice >=0 && choice < nb){ ret = 1; const char *str = st.getitem(choice)->get(); char *p = (char *)str; int tbase = DEFAULT_DATABASE; if (!(*str=='/')){ // for each table format the p is pointed to init of path if (strstr(str,"btree:")){ p+=6; tbase = BTREE_DATABASE; }if (strstr(str,"dbm:")){ p+=4; tbase = DBM_DATABASE; }else if (strstr(str,"hash:")){ p+=5; tbase = HASH_DATABASE; } }else{ if (strstr (data.getvarvariable(V_DEFAULT_DATABASE_TYPE)->get(), "hash")) tbase = HASH_DATABASE; else if (strstr (data.getvarvariable(V_DEFAULT_DATABASE_TYPE)->get(), "dbm")) tbase = DBM_DATABASE; } VIRTUALS vrt(p,NULL,true,tbase); // create the virtual object if (vrt.edit()==0){ // if table entry is 0, table can be erased char buf[100]; sprintf (buf,MSG_U(N_TABLEEMPTY,"The '%s' table is empty.\n" "Do you want to remove it?"),p); if (dialog_yesno( MSG_U(T_REMOVETABLE,"remove table") ,buf ,help_postfix_virtual) == MENU_YES){ if (unlink(p)==0){ xconf_notice (MSG_U(N_REMOVETABLE,"The '%s' file was removed!"),str); must_delete = true; if ( data.removeitemfromvar(str, V_VIRTUAL_MAPS)==1 ){ must_delete = true; }else xconf_error (MSG_U(E_REMOVEPATHTABLE,"Couldn't remove PATH in '%s'") ,MSG_R(F_VIRTUALMAPS)); }else xconf_error (MSG_U(E_REMOVEFILETABLE,"Couldn't remove '%s' file\n" "The file could be removed before"),str); } } } if (must_delete){ // reset dialog delete (dia); dia = NULL; } } delete (dia); return ret; } /* DESCRIPTION: Show btree, dbm and hash alias tables types where its path is on 'alias_maps' and 'alias_database' variable. Alias tables can be erased. If table is erased, the module looks for its path in variables commented end erase them. RETURN: 0 - no table is selected 1 - if table is selected */ PUBLIC int MODULE_postfixconf::aliastable_edit(DATAMAIN &data){ int ret = 0; int choice = 0; int nb = 0; DIALOG_LISTE *dia = NULL; SSTRINGS st; while (1){ // if dialog isn't created, generate an SSTRINGs that contain only the table paths // for possibles table types (filtered by 'checktables'). if (dia==NULL){ SSTRINGS *st1 = data.checktables(data.getvarvariable(V_ALIAS_MAPS)); SSTRINGS *st2 = data.checktables(data.getvarvariable(V_ALIAS_DATABASE)); st.remove_all(); if (st1!=NULL) st.append (*st1); if (st2!=NULL) st.append (*st2); if (st.getnb()==0){ xconf_notice (MSG_U(N_ALIASTABLEEMPTY, "No valid path found\n" "You can add a valid path in\n" "Table locations -> Alias maps\n" "Table locations -> Alias database\n\n" "See helpfile on this items")); return ret; } // order PAHTS, erase duplicated paths and add to dialog. st.remove_empty (); st.sort(); st.remove_dups (); dia = new DIALOG_LISTE; dia->newf_head ("",MSG_U(H_ALIASTABLEPATHS,"Alias table paths")); nb = st.getnb(); for (int i=0; inew_menuitem (*(st.getitem(i)),""); } bool must_delete=false; MENU_STATUS code = dia->editmenu (MSG_U(T_ALIASTABLEEDIT,"Alias table edit") ,MSG_U(I_DESCALIASTABLE,"You are allowed to edit/add/delete\n" "system wide aliases for electronic mail") ,help_postfix_aliases ,choice,0); if (code == MENU_ESCAPE || code == MENU_QUIT) break; if (choice >=0 && choice < nb){ ret = 1; const char *str = st.getitem(choice)->get(); char *p = (char *)str; int tbase = DEFAULT_DATABASE; if (!(*str=='/')){ // for each table p is pointed to init of path if (strstr(str,"btree:")){ p+=6; tbase = DB_DATABASE; }if (strstr(str,"dbm:")){ p+=4; tbase = DBM_DATABASE; }else if (strstr(str,"hash:")){ p+=5; tbase = HASH_DATABASE; } }else{ if (strstr (data.getvarvariable(V_DEFAULT_DATABASE_TYPE)->get(), "hash")) tbase = HASH_DATABASE; else if (strstr (data.getvarvariable(V_DEFAULT_DATABASE_TYPE)->get(), "dbm")) tbase = DBM_DATABASE; } ALIASES ali(p,NULL,true,tbase); // create tha alias table object if( ali.edit()==0 ){ // if table entry is 0 its can be erased char buf[100]; sprintf (buf,MSG_R(N_TABLEEMPTY),p); if (dialog_yesno( MSG_R(T_REMOVETABLE) ,buf ,help_postfix_tablelocations) == MENU_YES){ if (unlink(p)==0){ // if the file was erased, remove its path on //'alias_maps' and 'alias_database' case exist. xconf_notice (MSG_R(N_REMOVETABLE),str); must_delete = true; if ( data.removeitemfromvar(str, V_ALIAS_MAPS)==1 ){ must_delete = true; }else xconf_error (MSG_R(E_REMOVEPATHTABLE),MSG_R(F_ALIASMAPS)); if ( data.removeitemfromvar(str, V_ALIAS_DATABASE)==1 ){ must_delete = true; }else xconf_error (MSG_R(E_REMOVEPATHTABLE),MSG_R(F_ALIASDATABASE)); }else xconf_error (MSG_R(E_REMOVEFILETABLE),str); } } } if (must_delete){ // reset dialog delete (dia); dia = NULL; } } delete (dia); return ret; } /* DESCRIPTION: Show btree, dbm and hash canonical tables types where its path is on 'canonical_maps' variable. Canonical tables can be erased. If table is erased, the module looks for its path in variables commented end erase them. RETURN: 0 - no table is selected 1 - if table is selected */ PUBLIC int MODULE_postfixconf::canonicaltables_edit(DATAMAIN &data){ int ret = 0; int choice = 0; int nb = 0; DIALOG_LISTE *dia=NULL; SSTRINGS st; while (1){ // if dialog isn't created, generate an SSTRINGs that contain only the table paths // for possibles table types (filtered by 'checktables'). if (dia==NULL){ SSTRINGS *st1 = data.checktables(data.getvarvariable(V_CANONICAL_MAPS)); SSTRINGS *st2 = data.checktables(data.getvarvariable(V_RECIPIENT_CANONICAL_MAPS)); SSTRINGS *st3 = data.checktables(data.getvarvariable(V_SENDER_CANONICAL_MAPS)); st.remove_all(); if (st1!=NULL) st.append (*st1); if (st2!=NULL) st.append (*st2); if (st3!=NULL) st.append (*st3); if (st.getnb()==0){ xconf_notice (MSG_U(N_CANTABLEEMPTY, "No valid path found\n" "You can add a valid path in\n" "Table locations -> Canonical maps\n" "Table locations -> Recipient canonical maps\n" "Table locations -> Sender canonical maps\n\n" "See helpfile on this items")); return ret; } st.remove_empty (); st.sort(); st.remove_dups (); dia = new DIALOG_LISTE; dia->newf_head ("",MSG_U(H_CANTABLEPATHS,"Canonical table paths")); nb = st.getnb(); for (int i=0; inew_menuitem (*(st.getitem(i)),""); } bool must_delete = false; MENU_STATUS code = dia->editmenu (MSG_U(T_CANTABLEEDIT,"Canonical table edit") ,MSG_U(I_DESCCANONICALTABLE,"You are allowed to edit/add/delete\n" "canonical tables") ,help_postfix_canonical ,choice,0); if (code == MENU_ESCAPE || code == MENU_QUIT) break; if (choice >=0 && choice < nb){ ret = 1; const char *str = st.getitem(choice)->get(); char *p = (char *)str; int tbase = DEFAULT_DATABASE; if (!(*str=='/')){ if (strstr(str,"btree:")){ p+=6; tbase = DB_DATABASE; }if (strstr(str,"dbm:")){ p+=4; tbase = DBM_DATABASE; }else if (strstr(str,"hash:")){ p+=5; tbase = HASH_DATABASE; } }else{ if (strstr (data.getvarvariable(V_DEFAULT_DATABASE_TYPE)->get(), "hash")) tbase = HASH_DATABASE; else if (strstr (data.getvarvariable(V_DEFAULT_DATABASE_TYPE)->get(), "dbm")) tbase = DBM_DATABASE; } CANONICAL can(p,NULL,true,tbase); if (can.edit()==0){ char buf[100]; sprintf (buf,MSG_R(N_TABLEEMPTY),p); if (dialog_yesno( MSG_R(T_REMOVETABLE) ,buf ,help_postfix_tablelocations) == MENU_YES){ must_delete = true; if (unlink(p)==0){ xconf_notice (MSG_R(N_REMOVETABLE),str); must_delete = true; if ( data.removeitemfromvar(str, V_CANONICAL_MAPS)==1 ){ must_delete = true; }else xconf_notice (MSG_R(E_REMOVEPATHTABLE),MSG_R(F_CANONICALMAPS)); }else xconf_notice (MSG_R(E_REMOVEFILETABLE),str); } } } if (must_delete){ delete (dia); dia = NULL; } } delete (dia); return ret; }