#pragma implementation #include #include #include #include #include "keyword.h" /** * Keywords and parameters for fetchmail * All known keywords are stored in this list. * Some are implemented. Some are flags with a possible "no" preceeding * and others take one or more parameters. */ struct { int id; // Id of keyword bool implemented; // Whether the keyword is implemented in the code bool parameter; // If keyword take any parameter bool multiparameters; // If keyword take one or more parameter char *word; // Keyword } keywords[] = { // Global options: { 10,1,1,0,"set" }, { 11,1,1,0,"postmaster" }, { 12,1,0,0,"bouncemail" }, { 13,1,1,0,"logfile" }, { 14,0,1,0,"idfile" }, { 15,1,0,0,"syslog" }, { 16,1,0,0,"nosyslog" }, { 17,0,1,0,"properties" }, { 18,1,1,0,"daemon" }, // Server options: { 100,1,1,0,"poll" }, { 100,1,1,0,"server" }, { 101,1,1,0,"skip" }, { 103,0,1,0,"via" }, { 104,1,1,0,"proto" }, { 104,1,1,0,"protocol" }, { 110,0,1,0,"port" }, { 112,1,1,0,"auth" }, { 112,1,1,0,"authenticate" }, { 114,0,1,0,"timeout" }, { 120,1,1,0,"envelope" }, { 123,1,1,0,"qvirtual" }, { 125,1,1,1,"aka" }, { 130,1,1,0,"interface" }, { 132,1,1,0,"monitor" }, { 134,1,1,1,"localdomains" }, { 140,0,1,0,"plugin" }, { 142,0,1,0,"plugout" }, { 144,1,0,0,"dns" }, { 150,1,0,0,"checkalias" }, { 152,0,0,0,"uidl" }, // User options: { 200,1,1,1,"user" }, { 200,1,1,1,"username" }, { 201,1,0,0,"there" }, { 202,1,1,1,"is" }, { 202,1,1,1,"to" }, { 203,1,0,0,"here" }, { 204,1,1,0,"password" }, { 204,1,1,0,"pass" }, { 206,1,1,1,"folder" }, { 206,1,1,1,"folders" }, { 210,1,1,1,"smtphost" }, { 210,1,1,1,"smtp" }, { 212,1,1,0,"smtpaddress" }, { 214,0,1,0,"antispam" }, { 216,1,1,0,"mda" }, { 220,0,1,0,"bsmtp" }, { 222,0,1,0,"preconnect" }, { 223,0,1,0,"postconnect" }, { 230,1,0,0,"keep" }, { 232,1,0,0,"flush" }, { 234,1,0,0,"fetchall" }, { 236,1,0,0,"rewrite" }, { 238,1,0,0,"stripcr" }, { 240,1,0,0,"forcecr" }, { 242,1,0,0,"pass8bits" }, { 244,1,0,0,"dropstatus" }, { 246,1,0,0,"mimedecode" }, { 250,1,1,0,"limit" }, { 251,1,1,0,"warnings" }, { 252,1,1,0,"batchlimit" }, { 253,1,1,0,"fetchlimit" }, { 254,0,0,0,"expunge" }, { 255,0,1,0,"properties" }, // Special words: { 980,1,1,0,"no" }, // Ignored words: { 990,1,0,0,"defaults" }, { 990,1,0,0,"and" }, { 990,1,0,0,"with" }, { 990,1,0,0,"has" }, { 990,1,0,0,"wants" }, { 990,1,0,0,"options" }, { 990,1,0,0,":" }, { 990,1,0,0,";" }, { 990,1,0,0,"," }, { 990,0,0,0,"" }, // Special use { 0,0,0,0,"" } // End of list }; PRIVATE void KEYWORD::init() { // fprintf(stderr,"KEYWORD::init\n"); } PUBLIC void KEYWORD::init( KEYWORD *keyword ) { // fprintf(stderr,"KEYWORD::init: keyword->word=%s\n", keyword->word.get()); word.setfrom( keyword->word ); id = keyword->id; implemented = keyword->implemented; parameter = keyword->parameter; multiparameters = keyword->multiparameters; value = true; } PUBLIC KEYWORD::KEYWORD() { // fprintf(stderr,"KEYWORD::KEYWORD\n"); init(); } PUBLIC KEYWORD *KEYWORDLIST::getitem (int no) const { return (KEYWORD*)ARRAY::getitem (no); } PUBLIC KEYWORD *KEYWORDLIST::getitem (const char *_keyword) const { KEYWORD *ret = NULL; int n = getnb(); for (int i=0; iword.cmp(_keyword)==0){ ret = keyword; break; } } return ret; } PUBLIC KEYWORDLIST::KEYWORDLIST() { // fprintf(stderr,"KEYWORDLIST::KEYWORDLIST\n"); p = NULL; for (int i=0; keywords[i].id; i++ ) { KEYWORD *keyword = new KEYWORD; keyword->word.setfrom( keywords[i].word ); keyword->id = keywords[i].id; keyword->implemented = keywords[i].implemented; keyword->parameter = keywords[i].parameter; keyword->multiparameters = keywords[i].multiparameters; keyword->init( keyword ); add( keyword ); } } PUBLIC void KEYWORDLIST::clean_option( ) { p = NULL; } PRIVATE char * KEYWORDLIST::next_word(char *d, const char *s, int size) { while ( *s ) { switch ( *s ) { case ' ': case '\t': case ',': case ';': case '"': s++; continue; default: break; } break; } for ( size--; *s && size; size-- ) { switch ( *s ) { case ' ': case '\t': case ',': case ';': case '"': *d = '\0'; return( (char *)s); default: *d++ = *s++; break; } } *d = '\0'; return( (char *)s); } /** * Parse routine * With a string as input it parses config until an implemented keyword is found. * If the keyword have a parameter it returns this with the keyword id. The next * search returns the next parameter if the keyword takes more than one. * Otherwise the next implemented keyword is searched for. */ PUBLIC KEYWORD * KEYWORDLIST::option( char *word, const char *config, int size ) { static bool used = false; static KEYWORD *keyword; KEYWORD *new_keyword; KEYWORD *null = NULL; bool value = true; used = false; if ( p == NULL ) { p = (char *)config; while ( 1 ) { p = next_word( word, p, size ); if ( ! *p ) return( null ); keyword = getitem( word ); if ( keyword == null ) continue; //fprintf(stderr,"\tKEYWORDLIST::option: loop: keyword->word=%s\n", keyword->word.get()); if ( keyword->implemented == false ) continue; break; } } else { p = next_word( word, p, size ); if ( strlen( word ) == 0 ) { return( null ); } //fprintf(stderr,"\tKEYWORDLIST::option: loop: next_word=%s\n", word); } while ( 1 ) { if ( ( new_keyword = getitem( word ) ) == null ) { if ( keyword->parameter ) { if ( keyword->multiparameters ) if ( keyword->implemented ) return( keyword ); if ( ! used ) { used = true; if ( keyword->implemented ) return( keyword ); } } new_keyword = getitem( "" ); } else { if ( used && keyword->parameter && ! keyword->multiparameters ) { if ( ! keyword->word.cmp( word ) ) { //fprintf(stderr,"\tKEYWORDLIST: equal: keyword->word=%s & word=%s\n", keyword->word.get(), word ); return( keyword ); } } } //fprintf(stderr,"\tKEYWORDLIST::option: new_keyword->word=%s:%s%s%s%s ", new_keyword->word.get(), new_keyword->implemented?"":"", (new_keyword->id==KEY_IGNORE)?"":"",new_keyword->multiparameters?"":"",used?"":"" ); if ( new_keyword->id != KEY_IGNORE && new_keyword->implemented ) { keyword = new_keyword; if ( keyword->id == KEY_NO ) { value = false; //fprintf(stderr,""); } else { keyword->value = value; if ( keyword->parameter == false ) { //fprintf(stderr,"\n"); word[0] = '\0'; return( keyword ); } value = true; } } p = next_word( word, p, size ); if ( strlen( word ) == 0 ) { //fprintf(stderr,"\n"); return( null ); } //fprintf(stderr,"%s\n", word); } }