#pragma implementation #include #include #include #include #include #include #include #include #include #include #include "fetchmailconf.h" #include "fetchmailconf.m" #include "keyword.h" #include "serveredit.h" static HELP_FILE help_server ("fetchmailconf","server"); static PRIVILEGE p_server ("fetchmailconf_server" ,P_MSG_U(T_PRIVFETCHMAILSERVER,"Server") ,P_MSG_R(T_PRIVILEGE)); /* * SERVER */ PRIVATE void SERVER::init() { //fprintf(stderr,"SERVER::init\n"); protocol = "AUTO"; dns = 0; authenticate = 0; poll = 1; } PUBLIC SERVER::SERVER(const char *_server_name) { //fprintf(stderr,"SERVER::SERVER _server_name=%s\n", _server_name); server_name.setfrom (_server_name); init(); } PUBLIC SERVER::SERVER( ) { //fprintf(stderr,"SERVER::SERVER\n"); init(); } PUBLIC int SERVER::write( int button ) { //fprintf(stderr,"SERVER::write\n"); int ret = -1; if ( ! perm_access( &p_server, MSG_U(P_EDITSERVER, "change server configuration") ) ) { return( ret ); } if ( new_server && button != MENU_DEL) { FILE_CFG *fout = f_config_file->fopen (&p_server,"a"); if (fout != NULL) { write_server( fout ); ret = fclose (fout); } return( ret ); } VIEWITEMS items; items.read( *f_config_file ); // Read current version of config file FILE_CFG *fout = f_config_file->fopen (&p_server,"w"); if ( fout == NULL ) return( ret ); bool thisServer = false; char word[WORD]; KEYWORD *null = NULL; KEYWORD *keyword; KEYWORDLIST keywordlist; for ( int i=0; iline.get()); keywordlist.clean_option( ); keyword = keywordlist.option( word, item->line.get(), WORD ); if ( keyword == null ) { if ( ! thisServer ) { //fprintf(stderr,"SERVER::write: (null) write_item: %s\n", item->line.get()); write_item(fout,items,item,false); } continue; } //fprintf(stderr,"SERVER::write:keyword->id=%d keyword->word=%s: %s\n", keyword->id,keyword->word.get(), word); switch ( keyword->id ) { case KEY_POLL: case KEY_SKIP: if ( thisServer ) { thisServer = false; break; } if ( strcmp( server_name.get(), word ) == 0 ) { thisServer = true; if ( button == MENU_ACCEPT ) { //comment_write(item->comment,fout); write_item(fout,items,item,true); write_server( fout ); } } break; case KEY_USERNAME: if ( button == MENU_ACCEPT ) { thisServer = false; } break; } if ( ! thisServer ) { //fprintf(stderr,"SERVER::write: write_item: %s\n", item->line.get()); write_item(fout,items,item,false); } } keywordlist.clean_option( ); ret = fclose( fout ); return( ret ); } PUBLIC void SERVER::write_item( FILE_CFG *fout, const VIEWITEMS &items, VIEWITEM *item, bool comments_only) { int virtpos = items.lookup(item); int realpos = items.lookup(item,true); int prev_item = items.realpos(virtpos-1,VIEWITEM_VARIABLE); int next_item = items.realpos(virtpos+1,VIEWITEM_VARIABLE); if (prev_item == -1){ prev_item = 0; }else{ prev_item++; } if (next_item == -1){ next_item = items.getnb(); }else{ next_item--; } // Print comments before this item for (int i = prev_item; i < realpos; i++){ fprintf(fout, "%s\n", items.getitem(i,-1)->line.get()); } if (!comments_only){ // Print the item and... fprintf(fout, "%s\n", item->line.get()); // ...comments after it, if this is the last item for (int i = realpos+1; iline.get()); } } } /** * Write this server entry */ PUBLIC int SERVER::write_server( FILE_CFG *fout ) { //fprintf(stderr,"SERVER::write_server\n"); int i; fprintf( fout, "%s %s with protocol %s, with options\n", poll ? "poll" : "skip", server_name.get(), protocol.get() ); if ( aka.getnb() > 0 ) { fprintf( fout, "\taka " ); for ( i=0; iget() ); fprintf( fout, "\n" ); } if ( localdomains.getnb() > 0 ) { fprintf( fout, "\tlocaldomains " ); for ( i=0; iget() ); fprintf( fout, "\n" ); } switch ( dns ) { case 0: fprintf( fout, "\tdns\n" ); break; case 1: fprintf( fout, "\tdns checkalias\n" ); break; case 2: fprintf( fout, "\tno dns\n" ); break; } if ( ! qvirtual.is_empty() ) fprintf( fout, "\tqvirtual %s\n", qvirtual.get() ); if ( ! envelope.is_empty() ) fprintf( fout, "\tenvelope %s\n", envelope.get() ); switch ( authenticate ) { case 1: fprintf( fout, "\tauthenticate kerberos\n" ); break; } if ( ! interface.is_empty() && ! monitor.is_empty() ) { fprintf( fout, "\tinterface %s/%s/%s\n", interface.get(), monitor.get(), mask.get() ); } else if ( ! interface.is_empty() ) fprintf( fout, "\tmonitor %s\n", interface.get() ); return( 0 ); } /** * Edit server entry */ PUBLIC int SERVER::edit() { //fprintf(stderr,"SERVER::edit\n"); DIALOG dia; if ( new_server ) dia.newf_str (MSG_U(F_SERVER,"Mail server to access"),server_name); else dia.newf_info (MSG_R(F_SERVER),server_name.get()); dia.newf_chk ("",poll,MSG_U(F_POLL, "Server is active")); { FIELD_LIST *combo = dia.newf_list(MSG_U(F_PROTOCOLS ,"Protocol"),protocol); combo->addopt ("POP2",MSG_U(F_POP2,"(Post Office Protocol 2)")); combo->addopt ("POP3",MSG_U(F_POP3,"(Post Office Protocol 3)")); combo->addopt ("APOP",MSG_U(F_APOP,"(POP3 MD5 authentication)")); combo->addopt ("RPOP",MSG_U(F_RPOP,"(POP3 RPOP authentication)")); combo->addopt ("KPOP",MSG_U(F_KPOP,"(POP3 Kerberos V4 on port 1109)")); combo->addopt ("SDPS",MSG_U(F_SDPS,"(POP3 SDPS extensions)")); combo->addopt ("IMAP",MSG_U(F_IMAP,"(IMAP2bis, IMAP4, IMAP4rev1)")); combo->addopt ("IMAP-K4",MSG_U(F_IMAP_K4,"(IMAP4rev1, RFC1731 Kerberos V4)")); combo->addopt ("IMAP-GSS",MSG_U(F_IMAP_GSS,"(IMAP4rev1, RFC1731 GSSAPI)")); combo->addopt ("ETRN",MSG_U(F_ETRN,"ETRN (ESMTP ETRN)")); combo->addopt ("AUTO",MSG_U(F_AUTO,"AUTO (Automatic)")); } dia.newf_title ("",MSG_R(T_OPTIONAL)); { dia.newf_title (MSG_U(T_SECURITY,"Security"),1,"",MSG_R(T_SECURITY)); { static const char *authenticate_use[]={ MSG_U(F_PASSWORD,"Password"), MSG_U(F_KERBEROS,"Kerberos"), NULL }; dia.newf_chkm (MSG_U(F_AUTHENTICATE,"Authentication"),authenticate,authenticate_use); } dia.newf_str (MSG_U(F_INTERFACE,"Interface"),interface); dia.newf_str (MSG_U(F_IP_ADDRESS,"IP address"),monitor); dia.newf_str (MSG_U(F_IP_MASK,"IP address mask"),mask); } { dia.newf_title (MSG_U(T_MULTIDROP,"Multidrop"),1,"",MSG_R(T_MULTIDROP)); dia.newf_title ("", MSG_U(T_MULTIDROP_TITLE,"Single mailbox for many users")); dia.newf_title (MSG_U(T_OPTIONS,"Options"),2,"",MSG_R(T_OPTIONS)); dia.newf_str (MSG_U(F_ENVELOPE,"Envelope address header"),envelope); dia.newf_str (MSG_U(F_QVIRTUAL,"Name prefix to strip"),qvirtual); } { dia.newf_title (MSG_U(T_DNS,"DNS"),2,"",MSG_R(T_DNS)); { static const char *dns_use[]={ MSG_U(F_ENABLE_DNS,"Enable DNS"), MSG_U(F_CHECK_ALIAS,"Check alias"), MSG_U(F_NO_DNS,"No DNS"), NULL }; dia.newf_chkm (MSG_U(F_DNS_LOOKUP,"DNS lookup"),dns,dns_use); } aka.add (new SSTRING); const char *title = MSG_U(F_DNS_ALIAS,"DNS aliases"); int nb_empty = 3; for (int i=0; iis_empty()) nb_empty--; } for (int e=0; eis_empty()) nb_empty--; } for (int e=0; eserver_name.cmp(server_name)==0){ ret = server; break; } } return ret; } /** * SERVERLIST */ PUBLIC SERVERLIST::SERVERLIST( ) { //fprintf(stderr,"SERVERLIST::SERVERLIST\n"); } /** * Read config file and parse servers */ PUBLIC void SERVERLIST::read() { //fprintf(stderr,"SERVERLIST::read\n"); SSTRING string; VIEWITEMS items; items.read( *f_config_file ); // Read config file for ( int i=0; iline.get() ); // Concatenate all lines string.append( " " ); // with spaces } SERVER *server = NULL; KEYWORD *null = NULL; KEYWORD *keyword; KEYWORDLIST keywordlist; const char *config = string.get(); char word[WORD]; while ( 1 ) { keyword = keywordlist.option( word, config, WORD ); if ( keyword == null ) break; //fprintf(stderr,"read:keyword->id=%d keyword->word=%s: %s %s\n", keyword->id,keyword->word.get(), word, keyword->value?"":""); switch ( keyword->id ) { case KEY_POLL: server = new SERVER( ); add( server ); server->server_name.setfrom( word ); break; case KEY_SKIP: server = new SERVER( ); add( server ); server->server_name.setfrom( word ); server->poll = 0; break; case KEY_PROTOCOL: server->protocol.setfrom( word ); break; case KEY_ENVELOPE: if ( keyword->value ) server->envelope.setfrom( word ); else server->envelope.setfrom( "no envelope" ); break; case KEY_QVIRTUAL: server->qvirtual.setfrom( word ); break; case KEY_AKA: server->aka.add( new SSTRING( word ) ); break; case KEY_AUTHENTICATE: if ( strcmp( word, "kerberos" ) == 0 ) { server->authenticate = 1; } else { server->authenticate = 0; } break; case KEY_INTERFACE: server->interface.setfrom( word ); /* * Parse interface argument and split in interface, monitor and mask. */ if ( ! server->interface.is_empty() ) { SSTRING interface; SSTRING monitor; SSTRING mask; char *p, *s; for ( s = p = (char *)server->interface.get(); *p; p++ ) { if ( *p == '/' ) { *p++ = '\0'; interface.setfrom( s ); break; } } for ( s = p; *p; p++ ) { if ( *p == '/' ) { *p++ = '\0'; monitor.setfrom( s ); break; } } mask.setfrom( p ); server->interface.setfrom( interface ); server->monitor.setfrom( monitor ); server->mask.setfrom( mask ); //fprintf(stderr,"server->interface=%s server->monitor=%s server->mask=%s\n", server->interface.get(), server->monitor.get(), server->mask.get()); } break; case KEY_MONITOR: server->interface.setfrom( word ); break; case KEY_LOCALDOMAINS: server->localdomains.add( new SSTRING( word ) ); break; case KEY_DNS: if ( ! keyword->value ) server->dns = 2; else server->dns = 0; break; case KEY_CHECKALIAS: if ( keyword->value ) server->dns = 1; break; } } keywordlist.clean_option( ); } /** * Edit serverlist */ PUBLIC int SERVERLIST::edit() { //fprintf(stderr,"SERVERLIST::edit\n"); DIALOG_LISTE *dia = NULL; int nof = 0; while (1) { if (dia == NULL) { dia = new DIALOG_LISTE; dia->newf_head ("",MSG_U(H_FETCHMAIL,"Server\tStatus")); for (int i=0; inew_menuitem (server->server_name,server->poll?MSG_U(T_ACTIVE,"Active"):MSG_U(T_INACTIVE,"Inactive")); } dia->addwhat (MSG_U(I_ADDSERVER,"Select [Add] to add a new server")); } MENU_STATUS code = dia->editmenu (MSG_U(T_SERVERLIST,"Mail server list") ,MSG_U(I_SERVERLIST,"This is the list of all configured mail servers.") ,help_server ,nof,0); bool mustdelete=false; if (code == MENU_QUIT || code == MENU_ESCAPE) { break; } else if (code == MENU_ADD) { SERVER *server = new SERVER; server->new_server = true; if ( editone(server) != -1 ) mustdelete = true; } else { SERVER *server = getitem( nof ); char poll = server->poll; server->new_server = false; switch ( editone(nof) ) { case -1: mustdelete = false; break; case 1: mustdelete = true; break; case 0: if ( poll == server->poll ) { mustdelete = false; } else { mustdelete = true; } break; } } if (mustdelete){ delete dia; dia = NULL; } } delete dia; return 0; } /** * Select server */ PUBLIC SERVER * SERVERLIST::select() { //fprintf(stderr,"SERVERLIST::select\n"); read( ); SERVER *server; DIALOG_LISTE *dia = NULL; int nof = 0; dia = new DIALOG_LISTE; dia->newf_head ("",MSG_R(H_FETCHMAIL)); for (int i=0; inew_menuitem (server->server_name,server->poll?MSG_R(T_ACTIVE):MSG_R(T_INACTIVE)); } MENU_STATUS code = dia->editmenu (MSG_R(T_SERVERLIST) ,MSG_U(I_SERVERLISTSELECT, "This is a list of all configured mail servers.\n" "Please select a server." ) ,help_server ,nof,0); if (code == MENU_QUIT || code == MENU_ESCAPE) { server = NULL; } else { server = getitem( nof ); } delete dia; return( server ); }