/* Asterisk INI to Property List File Conversion Utility -- Version 1.10 * * keyords.c * aini2plist * * Keyword dictionary * * Author: Benjamin Kowarsch * * (C) 2006 Sunrise Telephone Systems Ltd. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * * In countries and territories where the above no-warranty disclaimer is * not permissible by applicable law, the following terms apply: * * NO PERMISSION TO USE THE SOFTWARE IS GRANTED AND THE SOFTWARE MUST NOT BE * USED AT ALL IN SUCH COUNTRIES AND TERRITORIES WHERE THE ABOVE NO-WARRANTY * DISCLAIMER IS NOT PERMISSIBLE AND INVALIDATED BY APPLICABLE LAW. HOWEVER, * THE COPYRIGHT HOLDERS HEREBY WAIVE THEIR RIGHT TO PURSUE OFFENDERS AS LONG * AS THEY OTHERWISE ABIDE BY THE TERMS OF THE LICENSE AS APPLICABLE FOR USE * OF THE SOFTWARE IN COUNTRIES AND TERRITORIES WHERE THE ABOVE NO-WARRANTY * DISCLAIMER IS PERMITTED BY APPLICABLE LAW. THIS WAIVER DOES NOT CONSTITUTE * A LICENSE TO USE THE SOFTWARE IN COUNTRIES AND TERRITORIES WHERE THE ABOVE * NO-WARRANTY DISCLAIMER IS NOT PERMISSIBLE AND INVALIDATED BY APPLICABLE * LAW. ANY LIABILITY OF ANY KIND IS CATEGORICALLY RULED OUT AT ALL TIMES. */ #include #include #include "keywords.h" #include "globaldefs.h" // -------------------------------------------------------------------------- // Keyword Dictionary Entry type // -------------------------------------------------------------------------- struct _keyword_dict_entry { CARDINAL hash; char translation[MAX_KEYWORD_LENGTH]; KeywordAttribute attribute; CARDINAL relocation; }; typedef struct _keyword_dict_entry KeywordDictEntry; // -------------------------------------------------------------------------- // Dictionary of known keywords // -------------------------------------------------------------------------- #define NO_TRANSLATION EMPTY_STRING #define NO_RELOCATION 0 /* keep this zero */ #define RELOCATE_TO_DIRECTORIES KEYWORD_DIRECTORIES #define RELOCATE_TO_OPTIONS KEYWORD_OPTIONS static KeywordDictEntry _plugin_mode_dict[] = { { KEYWORD_AGENT, NO_TRANSLATION , MULTIPLE_ASSIGNMENTS_UNIQUE_VALUES, NO_RELOCATION }, { KEYWORD_ALLOW, NO_TRANSLATION, MULTIPLE_ASSIGNMENTS_UNIQUE_VALUES, NO_RELOCATION }, { KEYWORD_AUTH, NO_TRANSLATION, MULTIPLE_ASSIGNMENTS_UNIQUE_VALUES, NO_RELOCATION }, { KEYWORD_CHANNEL, NO_TRANSLATION, MULTIPLE_ASSIGNMENTS_UNIQUE_VALUES, NO_RELOCATION }, { KEYWORD_CONF, NO_TRANSLATION, MULTIPLE_ASSIGNMENTS_UNIQUE_VALUES, NO_RELOCATION }, { KEYWORD_CONTEXT, NO_TRANSLATION, MULTIPLE_ASSIGNMENTS_UNIQUE_VALUES, NO_RELOCATION }, { KEYWORD_DISALLOW, NO_TRANSLATION, MULTIPLE_ASSIGNMENTS_UNIQUE_VALUES, NO_RELOCATION }, { KEYWORD_FORMAT, NO_TRANSLATION, MULTIPLE_ASSIGNMENTS_UNIQUE_VALUES, NO_RELOCATION }, { KEYWORD_GROUP, NO_TRANSLATION, MULTIPLE_ASSIGNMENTS_UNIQUE_VALUES, NO_RELOCATION }, { KEYWORD_INKEYS, NO_TRANSLATION, MULTIPLE_ASSIGNMENTS_UNIQUE_VALUES, NO_RELOCATION }, { KEYWORD_MEMBER, NO_TRANSLATION, MULTIPLE_ASSIGNMENTS_UNIQUE_VALUES, NO_RELOCATION }, { KEYWORD_NETWORK, NO_TRANSLATION, MULTIPLE_ASSIGNMENTS_UNIQUE_VALUES, NO_RELOCATION }, { KEYWORD_NOTRANSFER, "transfer", TOGGLE_BOOLEAN_VALUE, NO_RELOCATION }, { KEYWORD_REGEXTEN, NO_TRANSLATION, MULTIPLE_ASSIGNMENTS_UNIQUE_VALUES, NO_RELOCATION }, { KEYWORD_REGISTER, NO_TRANSLATION, MULTIPLE_ASSIGNMENTS, NO_RELOCATION }, { KEYWORD_RINGCADANCE, "ringcadence", NO_ATTRIBUTE, NO_RELOCATION }, { KEYWORD_SECRET, "password", NO_ATTRIBUTE, NO_RELOCATION }, { KEYWORD_SEARCH, NO_TRANSLATION, MULTIPLE_ASSIGNMENTS_UNIQUE_VALUES, NO_RELOCATION }, { KEYWORD_USER, NO_TRANSLATION, MULTIPLE_ASSIGNMENTS_UNIQUE_VALUES, NO_RELOCATION } }; // end _plugin_mode_dict #define KEYWORD_COUNT sizeof(_plugin_mode_dict)/sizeof(KeywordDictEntry) static KeywordDictEntry _master_mode_dict[] = { /* section names in asterisk.conf */ { KEYWORD_DIRECTORIES, "Directories" , SECTION_NAME, NO_RELOCATION }, { KEYWORD_OPTIONS, "Options", SECTION_NAME, NO_RELOCATION }, /* keys in section "directories" of asterisk.conf */ { KEYWORD_ASTETCDIR, "EtcDir", NO_ATTRIBUTE, NO_RELOCATION }, { KEYWORD_ASTSPOOLDIR, "SpoolDir", NO_ATTRIBUTE, NO_RELOCATION }, { KEYWORD_ASTVARLIBDIR, "VarLibDir", NO_ATTRIBUTE, NO_RELOCATION }, { KEYWORD_ASTLOGDIR, "LogDir", NO_ATTRIBUTE, NO_RELOCATION }, { KEYWORD_ASTAGIDIR, "AGIDir", NO_ATTRIBUTE, NO_RELOCATION }, { KEYWORD_ASTRUNDIR, "RunDir", NO_ATTRIBUTE, NO_RELOCATION }, { KEYWORD_ASTMODDIR, "ModDir", NO_ATTRIBUTE, NO_RELOCATION }, /* keys in section "directories" of openpbx.conf */ { KEYWORD_OPBXETCDIR, "EtcDir", NO_ATTRIBUTE, NO_RELOCATION }, { KEYWORD_OPBXSPOOLDIR, "SpoolDir", NO_ATTRIBUTE, NO_RELOCATION }, { KEYWORD_OPBXVARLIBDIR, "LibDir", NO_ATTRIBUTE, NO_RELOCATION }, { KEYWORD_OPBXLOGDIR, "LogDir", NO_ATTRIBUTE, NO_RELOCATION }, { KEYWORD_OPBXAGIDIR, "AGIDir", NO_ATTRIBUTE, NO_RELOCATION }, { KEYWORD_OPBXRUNDIR, "RunDir", NO_ATTRIBUTE, NO_RELOCATION }, { KEYWORD_OPBXMODDIR, "ModDir", NO_ATTRIBUTE, NO_RELOCATION }, { KEYWORD_OPBXDBDIR, "DBDir", NO_ATTRIBUTE, NO_RELOCATION }, { KEYWORD_OPBXSOUNDSDIR, "SoundsDir", NO_ATTRIBUTE, NO_RELOCATION }, /* keys in section "options" of asterisk.conf */ { KEYWORD_VERBOSE, "ConsoleVerbosity" , NO_ATTRIBUTE, NO_RELOCATION }, { KEYWORD_DEBUG, "LaunchInDebugMode", NO_ATTRIBUTE, NO_RELOCATION }, { KEYWORD_NOFORK, NO_TRANSLATION, NO_ATTRIBUTE, NO_RELOCATION }, { KEYWORD_QUIET, "LaunchInQuietMode", NO_ATTRIBUTE, NO_RELOCATION }, { KEYWORD_HIGHPRIORITY, "LaunchInPseudoRealtimeMode", NO_ATTRIBUTE, NO_RELOCATION }, { KEYWORD_INITCRYPTO, "InitCryptoKeysOnLaunch", NO_ATTRIBUTE, NO_RELOCATION }, { KEYWORD_NOCOLOR, "UseColorWhenInConsoleMode", TOGGLE_BOOLEAN_VALUE, NO_RELOCATION }, { KEYWORD_DUMPCORE, "WriteCoreDumpOnCrash", NO_ATTRIBUTE, NO_RELOCATION }, { KEYWORD_CACHE_RECORD_FILES, "RecordSoundsAsTempFiles", NO_ATTRIBUTE, NO_RELOCATION }, { KEYWORD_RECORD_CACHE_DIR, "TempDir", NO_ATTRIBUTE, RELOCATE_TO_DIRECTORIES }, /* keys in indications.conf */ { KEYWORD_COUNTRY, NO_TRANSLATION, NO_ATTRIBUTE, NO_RELOCATION }, { KEYWORD_DESCRIPTION, NO_TRANSLATION, NO_ATTRIBUTE, NO_RELOCATION }, { KEYWORD_ALIAS, NO_TRANSLATION, MULTIPLE_ASSIGNMENTS, NO_RELOCATION }, { KEYWORD_RINGCADANCE, "ringcadence", MULTIPLE_ASSIGNMENTS, NO_RELOCATION }, { KEYWORD_RINGCADENCE, NO_TRANSLATION, MULTIPLE_ASSIGNMENTS, NO_RELOCATION }, { KEYWORD_DIAL, NO_TRANSLATION, MULTIPLE_ASSIGNMENTS, NO_RELOCATION }, { KEYWORD_BUSY, NO_TRANSLATION, MULTIPLE_ASSIGNMENTS, NO_RELOCATION }, { KEYWORD_CONGESTION, NO_TRANSLATION, MULTIPLE_ASSIGNMENTS, NO_RELOCATION }, { KEYWORD_CALLWAITING, NO_TRANSLATION, MULTIPLE_ASSIGNMENTS, NO_RELOCATION }, { KEYWORD_DIALRECALL, NO_TRANSLATION, MULTIPLE_ASSIGNMENTS, NO_RELOCATION }, { KEYWORD_RECORD, NO_TRANSLATION, MULTIPLE_ASSIGNMENTS, NO_RELOCATION }, { KEYWORD_INFO, NO_TRANSLATION, MULTIPLE_ASSIGNMENTS, NO_RELOCATION }, /* section names in logger.conf */ { KEYWORD_LOGFILES, "Logfiles", SECTION_NAME, NO_RELOCATION }, /* keys in logger.conf */ { KEYWORD_DATEFORMAT, "TimestampFormatString", NO_ATTRIBUTE, RELOCATE_TO_OPTIONS }, { KEYWORD_APPENDHOSTNAME, "AppendHostToLogfiles", NO_ATTRIBUTE, RELOCATE_TO_OPTIONS }, { KEYWORD_CONSOLE, NO_TRANSLATION, MULTIPLE_ASSIGNMENTS_UNIQUE_VALUES, NO_RELOCATION }, { KEYWORD_MESSAGES, NO_TRANSLATION, MULTIPLE_ASSIGNMENTS_UNIQUE_VALUES, NO_RELOCATION }, /* keys in manager.conf */ { KEYWORD_ENABLED, NO_TRANSLATION, NO_ATTRIBUTE, NO_RELOCATION }, { KEYWORD_PORT, NO_TRANSLATION, NO_ATTRIBUTE, NO_RELOCATION }, { KEYWORD_BINDADDR, NO_TRANSLATION, NO_ATTRIBUTE, NO_RELOCATION }, { KEYWORD_DENY, NO_TRANSLATION, NO_ATTRIBUTE, NO_RELOCATION }, { KEYWORD_PERMIT, NO_TRANSLATION, NO_ATTRIBUTE, NO_RELOCATION }, { KEYWORD_SECRET, "password", NO_ATTRIBUTE, NO_RELOCATION }, { KEYWORD_READ, NO_TRANSLATION, MULTIPLE_ASSIGNMENTS_UNIQUE_VALUES, NO_RELOCATION }, { KEYWORD_WRITE, NO_TRANSLATION, MULTIPLE_ASSIGNMENTS_UNIQUE_VALUES, NO_RELOCATION }, /* section names in modules.conf */ { KEYWORD_MODULES, "Modules", SECTION_NAME, NO_RELOCATION }, /* keys in modules.conf */ { KEYWORD_AUTOLOAD, "AutoLoadAll", NO_ATTRIBUTE, NO_RELOCATION }, { KEYWORD_LOAD, NO_TRANSLATION, NO_ATTRIBUTE, NO_RELOCATION }, { KEYWORD_NOLOAD, NO_TRANSLATION, NO_ATTRIBUTE, NO_RELOCATION }, /* section names in extconfig.conf */ { KEYWORD_SETTINGS, NO_TRANSLATION, SECTION_NAME, NO_RELOCATION } }; // end _master_mode_dict static KeywordDictEntry _dialplan_mode_dict[] = { { KEYWORD_EXTEN, NO_TRANSLATION , NO_ATTRIBUTE, NO_RELOCATION }, { KEYWORD_INCLUDE, NO_TRANSLATION , MULTIPLE_ASSIGNMENTS_UNIQUE_VALUES, NO_RELOCATION } }; // end _dialplan_mode_dict // -------------------------------------------------------------------------- // Current keyword dictionary // -------------------------------------------------------------------------- static KeywordDictEntry *currentDict = _plugin_mode_dict; static CARDINAL KeywordCount = sizeof(_plugin_mode_dict)/sizeof(KeywordDictEntry); // -------------------------------------------------------------------------- // Keyword search cache // -------------------------------------------------------------------------- static struct { CARDINAL hash; CARDINAL index; } _last_found_keyword = { 0, 0 }; // -------------------------------------------------------------------------- // Obsolete keyword table entry type // -------------------------------------------------------------------------- struct _obsolete_keyword_entry { CARDINAL hash; // hash value of obsolete keyword CARDINAL section; // hash value of section in which keyword is obsolete }; typedef struct _obsolete_keyword_entry ObsoleteKeywordEntry; // -------------------------------------------------------------------------- // Obsolete keyword table // -------------------------------------------------------------------------- static ObsoleteKeywordEntry _obsolete_keyword_table[] = { { KEYWORD_NOFORK, /* is obsolete in section: */ KEYWORD_OPTIONS }, { KEYWORD_CONSOLE, /* is obsolete in section: */ KEYWORD_OPTIONS } }; // end _obsolete_keyword_table static ObsoleteKeywordEntry *obsoleteKeywordTable = _obsolete_keyword_table; static CARDINAL ObsoleteKeywordCount = sizeof(_obsolete_keyword_table)/sizeof(ObsoleteKeywordEntry); // -------------------------------------------------------------------------- // function init_keywords_with_dict(dict) // -------------------------------------------------------------------------- // // Sets the built-in keyword dictionary 'dict' to be used for keyword lookup. int init_keywords_with_dict(KeywordDictionary dict) { switch (dict) { case NO_DICTIONARY : currentDict = NULL; KeywordCount = 0; obsoleteKeywordTable = NULL; ObsoleteKeywordCount = 0; break; case CORE_DICTIONARY : currentDict = _master_mode_dict; KeywordCount = sizeof(_master_mode_dict)/sizeof(KeywordDictEntry); obsoleteKeywordTable = _obsolete_keyword_table; ObsoleteKeywordCount = sizeof(_obsolete_keyword_table)/sizeof(ObsoleteKeywordEntry); break; case PLUGIN_DICTIONARY : currentDict = _plugin_mode_dict; KeywordCount = sizeof(_plugin_mode_dict)/sizeof(KeywordDictEntry); obsoleteKeywordTable = _obsolete_keyword_table; ObsoleteKeywordCount = sizeof(_obsolete_keyword_table)/sizeof(ObsoleteKeywordEntry); break; case DIALPLAN_DICTIONARY : currentDict = _dialplan_mode_dict; KeywordCount = sizeof(_dialplan_mode_dict)/sizeof(KeywordDictEntry); obsoleteKeywordTable = _obsolete_keyword_table; ObsoleteKeywordCount = sizeof(_obsolete_keyword_table)/sizeof(ObsoleteKeywordEntry); break; default : return 0; } // end switch _last_found_keyword.hash = 0; _last_found_keyword.index = 0; return 1; } // end init_keywords_with_dict // -------------------------------------------------------------------------- // function init_keywords_from_file(path) // -------------------------------------------------------------------------- // // FOR FUTURE USE -- NOT YET IMPLEMENTED // int init_keywords_from_file(const char *path) { return 0; } // end init_keywords_from_file // -------------------------------------------------------------------------- // function is_known_keyword(hash) // -------------------------------------------------------------------------- // // Returns true if indentifier with hash value 'hash' is a known keyword, // otherwise false. bool is_known_keyword(CARDINAL hash) { CARDINAL index = 0; if ((KeywordCount == 0) && (hash == 0)) { return false; } // end if if (hash == _last_found_keyword.hash) { return true; } // end if // for now let's just do linear search while (index < KeywordCount) { if (currentDict[index].hash == hash) { _last_found_keyword.hash = hash; _last_found_keyword.index = index; return true; } // end if index++; } // end while return false; } // end is_known_keyword // -------------------------------------------------------------------------- // function is_obsolete_keyword(section, key) // -------------------------------------------------------------------------- // // Returns true if indentifier with hash value 'key' is obsolete in section // with hash value 'section', otherwise false. bool is_obsolete_keyword(CARDINAL section, CARDINAL key) { CARDINAL index = 0; if ((ObsoleteKeywordCount == 0) || (key == 0)) { return false; } // end if // for now let's just do linear search, obsolete keys are few while (index < ObsoleteKeywordCount) { if ((_obsolete_keyword_table[index].hash == key) && (_obsolete_keyword_table[index].section == section)) { return true; } // end if index++; } // end while return false; } // end is_obsolete_keyword // -------------------------------------------------------------------------- // function get_translation_for_keyword(hash) // -------------------------------------------------------------------------- // // Returns a pointer to a C string with the translation of the keyword whose // hash value is 'hash'. Returns NULL if the keyword is not known or if there // is no translation for the keyword. const char *get_translation_for_keyword(CARDINAL hash) { bool found = false; char *translation = NULL; if (hash == 0) { return translation; } // end if found = is_known_keyword(hash); //if ((found == true) && // (_plugin_mode_dict[_last_found_keyword.index].translation[0] != 0)) { // translation = (char *) &(_plugin_mode_dict[_last_found_keyword.index].translation); //} // end if if ((found == true) && (currentDict[_last_found_keyword.index].translation[0] != 0)) { translation = (char *) &(currentDict[_last_found_keyword.index].translation); } // end if return translation; } // end get_translation_for_keyword // -------------------------------------------------------------------------- // function get_attribute_for_keyword(hash) // -------------------------------------------------------------------------- // // Returns the attribute of the keyword whose hash value is 'hash'. Returns // the attribute NO_ATTRIBUTE if the keyword is not known. KeywordAttribute get_attribute_for_keyword(CARDINAL hash) { bool found = false; KeywordAttribute attribute = NO_ATTRIBUTE; if (hash == 0) { return attribute; } // end if found = is_known_keyword(hash); //if (found == true) { // attribute = _plugin_mode_dict[_last_found_keyword.index].attribute; //} // end if if (found == true) { attribute = currentDict[_last_found_keyword.index].attribute; } // end if return attribute; } // end get_attribute_for_keyword // -------------------------------------------------------------------------- // function get_relocation_for_keyword(hash) // -------------------------------------------------------------------------- // // Returns the hash value of a section to which the key whose hash value is // 'hash' should be relocated. Returns zero if the keyword is not known or if // there is no relocation value for the keyword. CARDINAL get_relocation_for_keyword(CARDINAL hash) { bool found = false; CARDINAL relocation = NO_RELOCATION; if (hash == 0) { return 0; } // end if found = is_known_keyword(hash); if (found == true) { relocation = currentDict[_last_found_keyword.index].relocation; } // end if return relocation; } // end get_relocation_for_keyword // END OF FILE