#include "asterisk.h"
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>
#include "asterisk/file.h"
#include "asterisk/paths.h"
#include "asterisk/pbx.h"
#include "asterisk/cli.h"
#include "asterisk/module.h"
#include "asterisk/http.h"
#include "asterisk/utils.h"
#include "asterisk/app.h"
#include "asterisk/strings.h"
#include "asterisk/stringfields.h"
#include "asterisk/options.h"
#include "asterisk/config.h"
#include "asterisk/acl.h"
#include "asterisk/astobj2.h"
#include "asterisk/ast_version.h"

Go to the source code of this file.
Data Structures | |
| struct | http_route |
| structure to hold http routes (valid URIs, and the files they link to) More... | |
| struct | phone_profile |
| structure to hold phone profiles read from phoneprov.conf More... | |
| struct | phoneprov_file |
| structure to hold file data More... | |
| struct | pp_variable_lookup |
| Lookup table to translate between users.conf property names and variables for use in phoneprov templates. More... | |
| struct | user |
| structure to hold users read from users.conf More... | |
| struct | users |
| list of users found in the config file More... | |
Defines | |
| #define | FORMAT "%-40.40s %-30.30s\n" |
| #define | MAX_PROFILE_BUCKETS 17 |
| #define | MAX_ROUTE_BUCKETS 563 |
| #define | VAR_BUF_SIZE 4096 |
Enumerations | |
| enum | pp_variables { PP_MACADDRESS, PP_USERNAME, PP_FULLNAME, PP_SECRET, PP_LABEL, PP_CALLERID, PP_TIMEZONE, PP_VAR_LIST_LENGTH } |
Functions | |
| static void | __fini_users (void) |
| static void | __init_users (void) |
| static void | __reg_module (void) |
| static void | __unreg_module (void) |
| static void | build_profile (const char *name, struct ast_variable *v) |
| Build a phone profile and add it to the list of phone profiles. | |
| static void | build_route (struct phoneprov_file *pp_file, struct user *user, char *uri) |
| Build a route structure and add it to the list of available http routes. | |
| static struct user * | build_user (struct ast_config *cfg, const char *name, const char *mac, struct phone_profile *profile) |
| Build and return a user structure based on gathered config data. | |
| static int | build_user_routes (struct user *user) |
| Add an http route for dynamic files attached to the profile of the user. | |
| static void | delete_file (struct phoneprov_file *file) |
| static void | delete_profiles (void) |
| Delete all phone profiles, freeing their memory. | |
| static void | delete_routes (void) |
| Delete all http routes, freeing their memory. | |
| static void | delete_user (struct user *user) |
| Free all memory associated with a user. | |
| static void | delete_users (void) |
| Destroy entire user list. | |
| static struct phone_profile * | find_profile (const char *name) |
| Return a phone profile looked up by name. | |
| static char * | ftype2mtype (const char *ftype) |
| Return mime type based on extension. | |
| static char * | handle_show_routes (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| CLI command to list static and dynamic routes. | |
| static int | load_file (const char *filename, char **ret) |
| Read a TEXT file into a string and return the length. | |
| static int | load_module (void) |
| static int | lookup_iface (const char *iface, struct in_addr *address) |
| static struct ast_str * | phoneprov_callback (struct ast_tcptls_session_instance *ser, const char *uri, struct ast_variable *vars, int *status, char **title, int *contentlength) |
| Callback that is executed everytime an http request is received by this module. | |
| static int | pp_each_user_exec (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len) |
| A dialplan function that can be used to print a string for each phoneprov user. | |
| static int | profile_cmp_fn (void *obj, void *arg, int flags) |
| static void | profile_destructor (void *obj) |
| static int | profile_hash_fn (const void *obj, const int flags) |
| static int | reload (void) |
| static void | route_destructor (void *obj) |
| static int | routes_cmp_fn (void *obj, void *arg, int flags) |
| static int | routes_hash_fn (const void *obj, const int flags) |
| static int | set_config (void) |
| static void | set_timezone_variables (struct varshead *headp, const char *zone) |
| Set all timezone-related variables based on a zone (i.e. America/New_York). | |
| static int | unload_module (void) |
| static struct phone_profile * | unref_profile (struct phone_profile *prof) |
| static struct http_route * | unref_route (struct http_route *route) |
Variables | |
| static struct ast_module_info | __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS , .description = "HTTP Phone Provisioning" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .reload = reload, } |
| static struct in_addr | __ourip = { .s_addr = 0x00000000, } |
| for use in lookup_iface | |
| static const struct ast_module_info * | ast_module_info = &__mod_info |
| char | global_default_profile [80] = "" |
| char | global_server [80] = "" |
| char | global_serverport [6] = "" |
| struct varshead | global_variables |
| List of global variables currently available: VOICEMAIL_EXTEN, EXTENSION_LENGTH. | |
| static struct ao2_container * | http_routes |
| struct { | |
| char * ext | |
| char * mtype | |
| } | mimetypes [] |
| Extensions whose mime types we think we know. | |
| static struct ast_http_uri | phoneprovuri |
| static struct ast_cli_entry | pp_cli [] |
| static struct ast_custom_function | pp_each_user_function |
| static struct pp_variable_lookup | pp_variable_list [] |
| Lookup table to translate between users.conf property names and variables for use in phoneprov templates. | |
| static struct ao2_container * | profiles |
Definition in file res_phoneprov.c.
| #define FORMAT "%-40.40s %-30.30s\n" |
| #define MAX_PROFILE_BUCKETS 17 |
| #define MAX_ROUTE_BUCKETS 563 |
| #define VAR_BUF_SIZE 4096 |
Definition at line 63 of file res_phoneprov.c.
| enum pp_variables |
| PP_MACADDRESS | |
| PP_USERNAME | |
| PP_FULLNAME | |
| PP_SECRET | |
| PP_LABEL | |
| PP_CALLERID | |
| PP_TIMEZONE | |
| PP_VAR_LIST_LENGTH |
Definition at line 70 of file res_phoneprov.c.
00070 { 00071 PP_MACADDRESS, 00072 PP_USERNAME, 00073 PP_FULLNAME, 00074 PP_SECRET, 00075 PP_LABEL, 00076 PP_CALLERID, 00077 PP_TIMEZONE, 00078 PP_VAR_LIST_LENGTH, /* This entry must always be the last in the list */ 00079 };
| static void __fini_users | ( | void | ) | [static] |
| static void __init_users | ( | void | ) | [static] |
| static void __reg_module | ( | void | ) | [static] |
Definition at line 1057 of file res_phoneprov.c.
| static void __unreg_module | ( | void | ) | [static] |
Definition at line 1057 of file res_phoneprov.c.
| static void build_profile | ( | const char * | name, | |
| struct ast_variable * | v | |||
| ) | [static] |
Build a phone profile and add it to the list of phone profiles.
| name | the name of the profile | |
| v | ast_variable from parsing phoneprov.conf |
Definition at line 494 of file res_phoneprov.c.
References ao2_alloc(), ao2_link(), AST_APP_ARG, ast_calloc, AST_DECLARE_APP_ARGS, ast_free, AST_LIST_HEAD_INIT_NOLOCK, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, AST_NONSTANDARD_APP_ARGS, AST_STANDARD_APP_ARGS, ast_strdupa, ast_string_field_build, ast_string_field_init, ast_string_field_set, ast_strip(), ast_strlen_zero(), ast_var_assign(), build_route(), phone_profile::default_mime_type, phone_profile::dynamic_files, ast_var_t::entries, phoneprov_file::format, ftype2mtype(), global_variables, phone_profile::headp, phoneprov_file::mime_type, ast_var_t::name, ast_variable::name, ast_variable::next, profile_destructor(), S_OR, phone_profile::static_files, phone_profile::staticdir, unref_profile(), ast_var_t::value, ast_variable::value, and var.
Referenced by set_config().
00495 { 00496 struct phone_profile *profile; 00497 struct ast_var_t *var; 00498 00499 if (!(profile = ao2_alloc(sizeof(*profile), profile_destructor))) 00500 return; 00501 00502 if (ast_string_field_init(profile, 32)) { 00503 profile = unref_profile(profile); 00504 return; 00505 } 00506 00507 if (!(profile->headp = ast_calloc(1, sizeof(*profile->headp)))) { 00508 profile = unref_profile(profile); 00509 return; 00510 } 00511 00512 AST_LIST_HEAD_INIT_NOLOCK(&profile->static_files); 00513 AST_LIST_HEAD_INIT_NOLOCK(&profile->dynamic_files); 00514 00515 ast_string_field_set(profile, name, name); 00516 for (; v; v = v->next) { 00517 if (!strcasecmp(v->name, "mime_type")) { 00518 ast_string_field_set(profile, default_mime_type, v->value); 00519 } else if (!strcasecmp(v->name, "setvar")) { 00520 struct ast_var_t *var; 00521 char *value_copy = ast_strdupa(v->value); 00522 00523 AST_DECLARE_APP_ARGS(args, 00524 AST_APP_ARG(varname); 00525 AST_APP_ARG(varval); 00526 ); 00527 00528 AST_NONSTANDARD_APP_ARGS(args, value_copy, '='); 00529 do { 00530 if (ast_strlen_zero(args.varname) || ast_strlen_zero(args.varval)) 00531 break; 00532 args.varname = ast_strip(args.varname); 00533 args.varval = ast_strip(args.varval); 00534 if (ast_strlen_zero(args.varname) || ast_strlen_zero(args.varval)) 00535 break; 00536 if ((var = ast_var_assign(args.varname, args.varval))) 00537 AST_LIST_INSERT_TAIL(profile->headp, var, entries); 00538 } while (0); 00539 } else if (!strcasecmp(v->name, "staticdir")) { 00540 ast_string_field_set(profile, staticdir, v->value); 00541 } else { 00542 struct phoneprov_file *pp_file; 00543 char *file_extension; 00544 char *value_copy = ast_strdupa(v->value); 00545 00546 AST_DECLARE_APP_ARGS(args, 00547 AST_APP_ARG(filename); 00548 AST_APP_ARG(mimetype); 00549 ); 00550 00551 if (!(pp_file = ast_calloc(1, sizeof(*pp_file)))) { 00552 profile = unref_profile(profile); 00553 return; 00554 } 00555 if (ast_string_field_init(pp_file, 32)) { 00556 ast_free(pp_file); 00557 profile = unref_profile(profile); 00558 return; 00559 } 00560 00561 if ((file_extension = strrchr(pp_file->format, '.'))) 00562 file_extension++; 00563 00564 AST_STANDARD_APP_ARGS(args, value_copy); 00565 00566 /* Mime type order of preference 00567 * 1) Specific mime-type defined for file in profile 00568 * 2) Mime determined by extension 00569 * 3) Default mime type specified in profile 00570 * 4) text/plain 00571 */ 00572 ast_string_field_set(pp_file, mime_type, S_OR(args.mimetype, (S_OR(S_OR(ftype2mtype(file_extension), profile->default_mime_type), "text/plain")))); 00573 00574 if (!strcasecmp(v->name, "static_file")) { 00575 ast_string_field_set(pp_file, format, args.filename); 00576 ast_string_field_build(pp_file, template, "%s%s", profile->staticdir, args.filename); 00577 AST_LIST_INSERT_TAIL(&profile->static_files, pp_file, entry); 00578 /* Add a route for the static files, as their filenames won't change per-user */ 00579 build_route(pp_file, NULL, NULL); 00580 } else { 00581 ast_string_field_set(pp_file, format, v->name); 00582 ast_string_field_set(pp_file, template, args.filename); 00583 AST_LIST_INSERT_TAIL(&profile->dynamic_files, pp_file, entry); 00584 } 00585 } 00586 } 00587 00588 /* Append the global variables to the variables list for this profile. 00589 * This is for convenience later, when we need to provide a single 00590 * variable list for use in substitution. */ 00591 AST_LIST_TRAVERSE(&global_variables, var, entries) { 00592 struct ast_var_t *new_var; 00593 if ((new_var = ast_var_assign(var->name, var->value))) 00594 AST_LIST_INSERT_TAIL(profile->headp, new_var, entries); 00595 } 00596 00597 ao2_link(profiles, profile); 00598 00599 profile = unref_profile(profile); 00600 }
| static void build_route | ( | struct phoneprov_file * | pp_file, | |
| struct user * | user, | |||
| char * | uri | |||
| ) | [static] |
Build a route structure and add it to the list of available http routes.
| pp_file | File to link to the route | |
| user | User to link to the route (NULL means static route) | |
| uri | URI of the route |
Definition at line 468 of file res_phoneprov.c.
References ao2_alloc(), ao2_link(), ast_log(), ast_string_field_init, ast_string_field_set, http_route::file, phoneprov_file::format, LOG_ERROR, route_destructor(), S_OR, unref_route(), and http_route::user.
00469 { 00470 struct http_route *route; 00471 00472 if (!(route = ao2_alloc(sizeof(*route), route_destructor))) 00473 return; 00474 00475 if (ast_string_field_init(route, 32)) { 00476 ast_log(LOG_ERROR, "Couldn't create string fields for %s\n", pp_file->format); 00477 route = unref_route(route); 00478 return; 00479 } 00480 00481 ast_string_field_set(route, uri, S_OR(uri, pp_file->format)); 00482 route->user = user; 00483 route->file = pp_file; 00484 00485 ao2_link(http_routes, route); 00486 00487 route = unref_route(route); 00488 }
| static struct user* build_user | ( | struct ast_config * | cfg, | |
| const char * | name, | |||
| const char * | mac, | |||
| struct phone_profile * | profile | |||
| ) | [static, read] |
Build and return a user structure based on gathered config data.
Definition at line 688 of file res_phoneprov.c.
References ast_calloc, ast_free, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ast_var_assign(), ast_variable_retrieve(), delete_user(), ast_var_t::entries, phone_profile::headp, user::headp, ast_var_t::name, user::name, pbx_substitute_variables_varshead(), PP_TIMEZONE, PP_USERNAME, PP_VAR_LIST_LENGTH, pp_variable_list, user::profile, set_timezone_variables(), unref_profile(), ast_var_t::value, var, and VAR_BUF_SIZE.
00689 { 00690 struct user *user; 00691 struct ast_var_t *var; 00692 const char *tmp; 00693 int i; 00694 00695 if (!(user = ast_calloc(1, sizeof(*user)))) { 00696 profile = unref_profile(profile); 00697 return NULL; 00698 } 00699 00700 if (!(user->headp = ast_calloc(1, sizeof(*user->headp)))) { 00701 profile = unref_profile(profile); 00702 ast_free(user); 00703 return NULL; 00704 } 00705 00706 if (ast_string_field_init(user, 32)) { 00707 profile = unref_profile(profile); 00708 delete_user(user); 00709 return NULL; 00710 } 00711 00712 ast_string_field_set(user, name, name); 00713 ast_string_field_set(user, macaddress, mac); 00714 user->profile = profile; /* already ref counted by find_profile */ 00715 00716 for (i = 0; i < PP_VAR_LIST_LENGTH; i++) { 00717 tmp = ast_variable_retrieve(cfg, name, pp_variable_list[i].user_var); 00718 00719 /* If we didn't get a USERNAME variable, set it to the user->name */ 00720 if (i == PP_USERNAME && !tmp) { 00721 if ((var = ast_var_assign(pp_variable_list[PP_USERNAME].template_var, user->name))) { 00722 AST_LIST_INSERT_TAIL(user->headp, var, entries); 00723 } 00724 continue; 00725 } else if (i == PP_TIMEZONE) { 00726 /* perfectly ok if tmp is NULL, will set variables based on server's time zone */ 00727 set_timezone_variables(user->headp, tmp); 00728 } 00729 00730 if (tmp && (var = ast_var_assign(pp_variable_list[i].template_var, tmp))) 00731 AST_LIST_INSERT_TAIL(user->headp, var, entries); 00732 } 00733 00734 if (!ast_strlen_zero(global_server)) { 00735 if ((var = ast_var_assign("SERVER", global_server))) 00736 AST_LIST_INSERT_TAIL(user->headp, var, entries); 00737 } 00738 00739 if (!ast_strlen_zero(global_serverport)) { 00740 if ((var = ast_var_assign("SERVER_PORT", global_serverport))) 00741 AST_LIST_INSERT_TAIL(user->headp, var, entries); 00742 } 00743 00744 /* Append profile variables here, and substitute variables on profile 00745 * setvars, so that we can use user specific variables in them */ 00746 AST_LIST_TRAVERSE(user->profile->headp, var, entries) { 00747 char expand_buf[VAR_BUF_SIZE] = {0,}; 00748 struct ast_var_t *var2; 00749 00750 pbx_substitute_variables_varshead(user->headp, var->value, expand_buf, sizeof(expand_buf)); 00751 if ((var2 = ast_var_assign(var->name, expand_buf))) 00752 AST_LIST_INSERT_TAIL(user->headp, var2, entries); 00753 } 00754 00755 return user; 00756 }
| static int build_user_routes | ( | struct user * | user | ) | [static] |
Add an http route for dynamic files attached to the profile of the user.
Definition at line 759 of file res_phoneprov.c.
References AST_LIST_TRAVERSE, build_route(), phone_profile::dynamic_files, phoneprov_file::format, user::headp, pbx_substitute_variables_varshead(), user::profile, and VAR_BUF_SIZE.
Referenced by set_config().
00760 { 00761 struct phoneprov_file *pp_file; 00762 00763 AST_LIST_TRAVERSE(&user->profile->dynamic_files, pp_file, entry) { 00764 char expand_buf[VAR_BUF_SIZE] = { 0, }; 00765 00766 pbx_substitute_variables_varshead(user->headp, pp_file->format, expand_buf, sizeof(expand_buf)); 00767 build_route(pp_file, user, expand_buf); 00768 } 00769 00770 return 0; 00771 }
| static void delete_file | ( | struct phoneprov_file * | file | ) | [static] |
Definition at line 242 of file res_phoneprov.c.
References ast_string_field_free_memory, and free.
Referenced by profile_destructor().
00243 { 00244 ast_string_field_free_memory(file); 00245 free(file); 00246 }
| static void delete_profiles | ( | void | ) | [static] |
Delete all phone profiles, freeing their memory.
Definition at line 898 of file res_phoneprov.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next(), ao2_unlink(), and unref_profile().
Referenced by reload(), and unload_module().
00899 { 00900 struct ao2_iterator i; 00901 struct phone_profile *profile; 00902 00903 i = ao2_iterator_init(profiles, 0); 00904 while ((profile = ao2_iterator_next(&i))) { 00905 ao2_unlink(profiles, profile); 00906 profile = unref_profile(profile); 00907 } 00908 ao2_iterator_destroy(&i); 00909 }
| static void delete_routes | ( | void | ) | [static] |
Delete all http routes, freeing their memory.
Definition at line 884 of file res_phoneprov.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next(), ao2_unlink(), and unref_route().
Referenced by reload(), and unload_module().
00885 { 00886 struct ao2_iterator i; 00887 struct http_route *route; 00888 00889 i = ao2_iterator_init(http_routes, 0); 00890 while ((route = ao2_iterator_next(&i))) { 00891 ao2_unlink(http_routes, route); 00892 route = unref_route(route); 00893 } 00894 ao2_iterator_destroy(&i); 00895 }
| static void delete_user | ( | struct user * | user | ) | [static] |
Free all memory associated with a user.
Definition at line 603 of file res_phoneprov.c.
References ast_free, AST_LIST_REMOVE_HEAD, ast_string_field_free_memory, ast_var_delete(), ast_var_t::entries, free, user::headp, user::profile, unref_profile(), and var.
Referenced by build_user(), delete_users(), and set_config().
00604 { 00605 struct ast_var_t *var; 00606 00607 while ((var = AST_LIST_REMOVE_HEAD(user->headp, entries))) 00608 ast_var_delete(var); 00609 00610 ast_free(user->headp); 00611 ast_string_field_free_memory(user); 00612 user->profile = unref_profile(user->profile); 00613 free(user); 00614 }
| static void delete_users | ( | void | ) | [static] |
Destroy entire user list.
Definition at line 617 of file res_phoneprov.c.
References AST_LIST_REMOVE_HEAD, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, and delete_user().
00618 { 00619 struct user *user; 00620 00621 AST_RWLIST_WRLOCK(&users); 00622 while ((user = AST_LIST_REMOVE_HEAD(&users, entry))) 00623 delete_user(user); 00624 AST_RWLIST_UNLOCK(&users); 00625 }
| static struct phone_profile* find_profile | ( | const char * | name | ) | [static, read] |
Return a phone profile looked up by name.
Definition at line 219 of file res_phoneprov.c.
References ao2_find(), phone_profile::name, and OBJ_POINTER.
Referenced by set_config().
00220 { 00221 struct phone_profile tmp = { 00222 .name = name, 00223 }; 00224 00225 return ao2_find(profiles, &tmp, OBJ_POINTER); 00226 }
| static char* ftype2mtype | ( | const char * | ftype | ) | [static] |
Return mime type based on extension.
Definition at line 165 of file res_phoneprov.c.
References ARRAY_LEN, ast_strlen_zero(), ext, mimetypes, and mtype.
00166 { 00167 int x; 00168 00169 if (ast_strlen_zero(ftype)) 00170 return NULL; 00171 00172 for (x = 0;x < ARRAY_LEN(mimetypes);x++) { 00173 if (!strcasecmp(ftype, mimetypes[x].ext)) 00174 return mimetypes[x].mtype; 00175 } 00176 00177 return NULL; 00178 }
| static char* handle_show_routes | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
CLI command to list static and dynamic routes.
Definition at line 952 of file res_phoneprov.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next(), ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, http_route::file, FORMAT, phoneprov_file::template, unref_route(), http_route::uri, ast_cli_entry::usage, and http_route::user.
00953 { 00954 #define FORMAT "%-40.40s %-30.30s\n" 00955 struct ao2_iterator i; 00956 struct http_route *route; 00957 00958 switch(cmd) { 00959 case CLI_INIT: 00960 e->command = "phoneprov show routes"; 00961 e->usage = 00962 "Usage: phoneprov show routes\n" 00963 " Lists all registered phoneprov http routes.\n"; 00964 return NULL; 00965 case CLI_GENERATE: 00966 return NULL; 00967 } 00968 00969 /* This currently iterates over routes twice, but it is the only place I've needed 00970 * to really separate static an dynamic routes, so I've just left it this way. */ 00971 ast_cli(a->fd, "Static routes\n\n"); 00972 ast_cli(a->fd, FORMAT, "Relative URI", "Physical location"); 00973 i = ao2_iterator_init(http_routes, 0); 00974 while ((route = ao2_iterator_next(&i))) { 00975 if (!route->user) 00976 ast_cli(a->fd, FORMAT, route->uri, route->file->template); 00977 route = unref_route(route); 00978 } 00979 ao2_iterator_destroy(&i); 00980 00981 ast_cli(a->fd, "\nDynamic routes\n\n"); 00982 ast_cli(a->fd, FORMAT, "Relative URI", "Template"); 00983 00984 i = ao2_iterator_init(http_routes, 0); 00985 while ((route = ao2_iterator_next(&i))) { 00986 if (route->user) 00987 ast_cli(a->fd, FORMAT, route->uri, route->file->template); 00988 route = unref_route(route); 00989 } 00990 ao2_iterator_destroy(&i); 00991 00992 return CLI_SUCCESS; 00993 }
| static int load_file | ( | const char * | filename, | |
| char ** | ret | |||
| ) | [static] |
Read a TEXT file into a string and return the length.
Definition at line 296 of file res_phoneprov.c.
References ast_malloc, f, free, and len().
Referenced by phoneprov_callback().
00297 { 00298 int len = 0; 00299 FILE *f; 00300 00301 if (!(f = fopen(filename, "r"))) { 00302 *ret = NULL; 00303 return -1; 00304 } 00305 00306 fseek(f, 0, SEEK_END); 00307 len = ftell(f); 00308 fseek(f, 0, SEEK_SET); 00309 if (!(*ret = ast_malloc(len + 1))) 00310 return -2; 00311 00312 if (len != fread(*ret, sizeof(char), len, f)) { 00313 free(*ret); 00314 *ret = NULL; 00315 return -3; 00316 } 00317 00318 fclose(f); 00319 00320 (*ret)[len] = '\0'; 00321 00322 return len; 00323 }
| static int load_module | ( | void | ) | [static] |
Definition at line 1006 of file res_phoneprov.c.
References ao2_container_alloc(), ARRAY_LEN, ast_cli_register_multiple(), ast_custom_function_register, ast_http_uri_link(), AST_LIST_HEAD_INIT_NOLOCK, global_variables, MAX_PROFILE_BUCKETS, MAX_ROUTE_BUCKETS, profile_cmp_fn(), profile_hash_fn(), routes_cmp_fn(), routes_hash_fn(), and set_config().
01007 { 01008 profiles = ao2_container_alloc(MAX_PROFILE_BUCKETS, profile_hash_fn, profile_cmp_fn); 01009 01010 http_routes = ao2_container_alloc(MAX_ROUTE_BUCKETS, routes_hash_fn, routes_cmp_fn); 01011 01012 AST_LIST_HEAD_INIT_NOLOCK(&global_variables); 01013 01014 ast_custom_function_register(&pp_each_user_function); 01015 ast_cli_register_multiple(pp_cli, ARRAY_LEN(pp_cli)); 01016 01017 set_config(); 01018 ast_http_uri_link(&phoneprovuri); 01019 01020 return 0; 01021 }
| static int lookup_iface | ( | const char * | iface, | |
| struct in_addr * | address | |||
| ) | [static] |
Definition at line 181 of file res_phoneprov.c.
References ast_copy_string(), ast_log(), errno, LOG_ERROR, and LOG_WARNING.
Referenced by set_config().
00182 { 00183 int mysock, res = 0; 00184 struct ifreq ifr; 00185 struct sockaddr_in *sin; 00186 00187 memset(&ifr, 0, sizeof(ifr)); 00188 ast_copy_string(ifr.ifr_name, iface, sizeof(ifr.ifr_name)); 00189 00190 mysock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP); 00191 if (mysock < 0) { 00192 ast_log(LOG_ERROR, "Failed to create socket: %s\n", strerror(errno)); 00193 return -1; 00194 } 00195 00196 res = ioctl(mysock, SIOCGIFADDR, &ifr); 00197 00198 close(mysock); 00199 00200 if (res < 0) { 00201 ast_log(LOG_WARNING, "Unable to get IP of %s: %s\n", iface, strerror(errno)); 00202 memcpy(address, &__ourip, sizeof(__ourip)); 00203 return -1; 00204 } else { 00205 sin = (struct sockaddr_in *)&ifr.ifr_addr; 00206 memcpy(address, &sin->sin_addr, sizeof(*address)); 00207 return 0; 00208 } 00209 }
| static struct ast_str* phoneprov_callback | ( | struct ast_tcptls_session_instance * | ser, | |
| const char * | uri, | |||
| struct ast_variable * | vars, | |||
| int * | status, | |||
| char ** | title, | |||
| int * | contentlength | |||
| ) | [static, read] |
Callback that is executed everytime an http request is received by this module.
Definition at line 326 of file res_phoneprov.c.
References ao2_find(), ast_calloc, ast_config_AST_DATA_DIR, ast_debug, ast_free, ast_get_version(), ast_http_error(), ast_inet_ntoa(), AST_LIST_INSERT_TAIL, ast_localtime(), ast_log(), ast_str_append(), ast_str_create(), ast_strftime(), ast_strlen_zero(), ast_tvnow(), ast_var_assign(), buf, ast_var_t::entries, errno, ast_tcptls_session_instance::f, ast_tcptls_session_instance::fd, http_route::file, user::headp, len(), load_file(), LOG_WARNING, phoneprov_file::mime_type, name, OBJ_POINTER, pbx_substitute_variables_varshead(), strdup, phoneprov_file::template, unref_route(), http_route::uri, http_route::user, var, and VAR_BUF_SIZE.
00327 { 00328 struct http_route *route; 00329 struct http_route search_route = { 00330 .uri = uri, 00331 }; 00332 struct ast_str *result = ast_str_create(512); 00333 char path[PATH_MAX]; 00334 char *file = NULL; 00335 int len; 00336 int fd; 00337 char buf[256]; 00338 struct timeval tv = ast_tvnow(); 00339 struct ast_tm tm; 00340 00341 if (!(route = ao2_find(http_routes, &search_route, OBJ_POINTER))) 00342 goto out404; 00343 00344 snprintf(path, sizeof(path), "%s/phoneprov/%s", ast_config_AST_DATA_DIR, route->file->template); 00345 00346 if (!route->user) { /* Static file */ 00347 00348 fd = open(path, O_RDONLY); 00349 if (fd < 0) 00350 goto out500; 00351 00352 len = lseek(fd, 0, SEEK_END); 00353 lseek(fd, 0, SEEK_SET); 00354 if (len < 0) { 00355 ast_log(LOG_WARNING, "Could not load file: %s (%d)\n", path, len); 00356 close(fd); 00357 goto out500; 00358 } 00359 00360 ast_strftime(buf, sizeof(buf), "%a, %d %b %Y %H:%M:%S %Z", ast_localtime(&tv, &tm, "GMT")); 00361 fprintf(ser->f, "HTTP/1.1 200 OK\r\n" 00362 "Server: Asterisk/%s\r\n" 00363 "Date: %s\r\n" 00364 "Connection: close\r\n" 00365 "Cache-Control: no-cache, no-store\r\n" 00366 "Content-Length: %d\r\n" 00367 "Content-Type: %s\r\n\r\n", 00368 ast_get_version(), buf, len, route->file->mime_type); 00369 00370 while ((len = read(fd, buf, sizeof(buf))) > 0) 00371 if (fwrite(buf, 1, len, ser->f) != len) { 00372 if (errno != EPIPE) { 00373 ast_log(LOG_WARNING, "fwrite() failed: %s\n", strerror(errno)); 00374 } else { 00375 ast_debug(3, "Requester closed the connection while downloading '%s'\n", path); 00376 } 00377 break; 00378 } 00379 00380 close(fd); 00381 route = unref_route(route); 00382 return NULL; 00383 } else { /* Dynamic file */ 00384 int bufsize; 00385 char *tmp; 00386 00387 len = load_file(path, &file); 00388 if (len < 0) { 00389 ast_log(LOG_WARNING, "Could not load file: %s (%d)\n", path, len); 00390 if (file) 00391 ast_free(file); 00392 goto out500; 00393 } 00394 00395 if (!file) 00396 goto out500; 00397 00398 /* XXX This is a hack -- maybe sum length of all variables in route->user->headp and add that? */ 00399 bufsize = len + VAR_BUF_SIZE; 00400 00401 /* malloc() instead of alloca() here, just in case the file is bigger than 00402 * we have enough stack space for. */ 00403 if (!(tmp = ast_calloc(1, bufsize))) { 00404 if (file) 00405 ast_free(file); 00406 goto out500; 00407 } 00408 00409 /* Unless we are overridden by serveriface or serveraddr, we set the SERVER variable to 00410 * the IP address we are listening on that the phone contacted for this config file */ 00411 if (ast_strlen_zero(global_server)) { 00412 union { 00413 struct sockaddr sa; 00414 struct sockaddr_in sa_in; 00415 } name; 00416 socklen_t namelen = sizeof(name.sa); 00417 int res; 00418 00419 if ((res = getsockname(ser->fd, &name.sa, &namelen))) 00420 ast_log(LOG_WARNING, "Could not get server IP, breakage likely.\n"); 00421 else { 00422 struct ast_var_t *var; 00423 00424 if ((var = ast_var_assign("SERVER", ast_inet_ntoa(name.sa_in.sin_addr)))) 00425 if ((var = ast_var_assign("SERVER", ast_inet_ntoa(((struct sockaddr_in *)&name)->sin_addr)))) 00426 AST_LIST_INSERT_TAIL(route->user->headp, var, entries); 00427 } 00428 } 00429 00430 pbx_substitute_variables_varshead(route->user->headp, file, tmp, bufsize); 00431 00432 if (file) 00433 ast_free(file); 00434 00435 ast_str_append(&result, 0, 00436 "Content-Type: %s\r\n" 00437 "Content-length: %d\r\n" 00438 "\r\n" 00439 "%s", route->file->mime_type, (int) strlen(tmp), tmp); 00440 00441 if (tmp) 00442 ast_free(tmp); 00443 00444 route = unref_route(route); 00445 00446 return result; 00447 } 00448 00449 out404: 00450 *status = 404; 00451 *title = strdup("Not Found"); 00452 *contentlength = 0; 00453 return ast_http_error(404, "Not Found", NULL, "Nothing to see here. Move along."); 00454 00455 out500: 00456 route = unref_route(route); 00457 *status = 500; 00458 *title = strdup("Internal Server Error"); 00459 *contentlength = 0; 00460 return ast_http_error(500, "Internal Error", NULL, "An internal error has occured."); 00461 }
| static int pp_each_user_exec | ( | struct ast_channel * | chan, | |
| const char * | cmd, | |||
| char * | data, | |||
| char * | buf, | |||
| size_t | len | |||
| ) | [static] |
A dialplan function that can be used to print a string for each phoneprov user.
Definition at line 912 of file res_phoneprov.c.
References AST_APP_ARG, ast_build_string(), AST_DECLARE_APP_ARGS, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, AST_STANDARD_APP_ARGS, ast_strlen_zero(), user::headp, user::macaddress, pbx_substitute_variables_varshead(), and VAR_BUF_SIZE.
00913 { 00914 char *tmp, expand_buf[VAR_BUF_SIZE] = {0,}; 00915 struct user *user; 00916 AST_DECLARE_APP_ARGS(args, 00917 AST_APP_ARG(string); 00918 AST_APP_ARG(exclude_mac); 00919 ); 00920 AST_STANDARD_APP_ARGS(args, data); 00921 00922 /* Fix data by turning %{ into ${ */ 00923 while ((tmp = strstr(args.string, "%{"))) 00924 *tmp = '$'; 00925 00926 AST_RWLIST_RDLOCK(&users); 00927 AST_RWLIST_TRAVERSE(&users, user, entry) { 00928 if (!ast_strlen_zero(args.exclude_mac) && !strcasecmp(user->macaddress, args.exclude_mac)) 00929 continue; 00930 pbx_substitute_variables_varshead(user->headp, args.string, expand_buf, sizeof(expand_buf)); 00931 ast_build_string(&buf, &len, "%s", expand_buf); 00932 } 00933 AST_RWLIST_UNLOCK(&users); 00934 00935 return 0; 00936 }
| static int profile_cmp_fn | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 235 of file res_phoneprov.c.
References CMP_MATCH, and phone_profile::name.
Referenced by load_module().
00236 { 00237 const struct phone_profile *profile1 = obj, *profile2 = arg; 00238 00239 return !strcasecmp(profile1->name, profile2->name) ? CMP_MATCH : 0; 00240 }
| static void profile_destructor | ( | void * | obj | ) | [static] |
Definition at line 248 of file res_phoneprov.c.
References AST_LIST_REMOVE_HEAD, ast_string_field_free_memory, ast_var_delete(), delete_file(), phone_profile::dynamic_files, ast_var_t::entries, free, phone_profile::headp, phone_profile::static_files, and var.
Referenced by build_profile().
00249 { 00250 struct phone_profile *profile = obj; 00251 struct phoneprov_file *file; 00252 struct ast_var_t *var; 00253 00254 while ((file = AST_LIST_REMOVE_HEAD(&profile->static_files, entry))) 00255 delete_file(file); 00256 00257 while ((file = AST_LIST_REMOVE_HEAD(&profile->dynamic_files, entry))) 00258 delete_file(file); 00259 00260 while ((var = AST_LIST_REMOVE_HEAD(profile->headp, entries))) 00261 ast_var_delete(var); 00262 00263 free(profile->headp); 00264 ast_string_field_free_memory(profile); 00265 }
| static int profile_hash_fn | ( | const void * | obj, | |
| const int | flags | |||
| ) | [static] |
Definition at line 228 of file res_phoneprov.c.
References ast_str_hash(), and phone_profile::name.
Referenced by load_module().
00229 { 00230 const struct phone_profile *profile = obj; 00231 00232 return ast_str_hash(profile->name); 00233 }
| static int reload | ( | void | ) | [static] |
Definition at line 1043 of file res_phoneprov.c.
References delete_profiles(), delete_routes(), delete_users(), and set_config().
01044 { 01045 delete_routes(); 01046 delete_users(); 01047 delete_profiles(); 01048 set_config(); 01049 01050 return 0; 01051 }
| static void route_destructor | ( | void * | obj | ) | [static] |
Definition at line 288 of file res_phoneprov.c.
References ast_string_field_free_memory.
Referenced by build_route().
00289 { 00290 struct http_route *route = obj; 00291 00292 ast_string_field_free_memory(route); 00293 }
| static int routes_cmp_fn | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 281 of file res_phoneprov.c.
References CMP_MATCH, and http_route::uri.
Referenced by load_module().
00282 { 00283 const struct http_route *route1 = obj, *route2 = arg; 00284 00285 return !strcmp(route1->uri, route2->uri) ? CMP_MATCH : 0; 00286 }
| static int routes_hash_fn | ( | const void * | obj, | |
| const int | flags | |||
| ) | [static] |
Definition at line 274 of file res_phoneprov.c.
References ast_str_hash(), and http_route::uri.
Referenced by load_module().
00275 { 00276 const struct http_route *route = obj; 00277 00278 return ast_str_hash(route->uri); 00279 }
| static int set_config | ( | void | ) | [static] |
Definition at line 774 of file res_phoneprov.c.
References ast_category_browse(), ast_config_destroy(), ast_config_load, ast_copy_string(), ast_inet_ntoa(), AST_LIST_INSERT_TAIL, ast_log(), AST_RWLIST_INSERT_TAIL, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_strlen_zero(), ast_true(), ast_var_assign(), ast_variable_browse(), ast_variable_retrieve(), build_profile(), build_user(), build_user_routes(), delete_user(), ast_var_t::entries, find_profile(), global_variables, LOG_ERROR, LOG_WARNING, lookup_iface(), user::name, ast_variable::name, ast_variable::next, S_OR, ast_variable::value, and var.
00775 { 00776 struct ast_config *cfg; 00777 char *cat; 00778 struct ast_variable *v; 00779 struct ast_flags config_flags = { 0 }; 00780 00781 /* Try to grab the port from sip.conf. If we don't get it here, we'll set it 00782 * to whatever is set in phoneprov.conf or default to 5060 */ 00783 if ((cfg = ast_config_load("sip.conf", config_flags))) { 00784 ast_copy_string(global_serverport, S_OR(ast_variable_retrieve(cfg, "general", "bindport"), "5060"), sizeof(global_serverport)); 00785 ast_config_destroy(cfg); 00786 } 00787 00788 if (!(cfg = ast_config_load("phoneprov.conf", config_flags))) { 00789 ast_log(LOG_ERROR, "Unable to load config phoneprov.conf\n"); 00790 ast_config_destroy(cfg); 00791 return -1; 00792 } 00793 00794 cat = NULL; 00795 while ((cat = ast_category_browse(cfg, cat))) { 00796 if (!strcasecmp(cat, "general")) { 00797 for (v = ast_variable_browse(cfg, cat); v; v = v->next) { 00798 if (!strcasecmp(v->name, "serveraddr")) 00799 ast_copy_string(global_server, v->value, sizeof(global_server)); 00800 else if (!strcasecmp(v->name, "serveriface")) { 00801 struct in_addr addr; 00802 lookup_iface(v->value, &addr); 00803 ast_copy_string(global_server, ast_inet_ntoa(addr), sizeof(global_server)); 00804 } else if (!strcasecmp(v->name, "serverport")) 00805 ast_copy_string(global_serverport, v->value, sizeof(global_serverport)); 00806 else if (!strcasecmp(v->name, "default_profile")) 00807 ast_copy_string(global_default_profile, v->value, sizeof(global_default_profile)); 00808 } 00809 } else 00810 build_profile(cat, ast_variable_browse(cfg, cat)); 00811 } 00812 00813 ast_config_destroy(cfg); 00814 00815 if (!(cfg = ast_config_load("users.conf", config_flags))) { 00816 ast_log(LOG_WARNING, "Unable to load users.cfg\n"); 00817 return 0; 00818 } 00819 00820 cat = NULL; 00821 while ((cat = ast_category_browse(cfg, cat))) { 00822 const char *tmp, *mac; 00823 struct user *user; 00824 struct phone_profile *profile; 00825 struct ast_var_t *var; 00826 00827 if (!strcasecmp(cat, "general")) { 00828 for (v = ast_variable_browse(cfg, cat); v; v = v->next) { 00829 if (!strcasecmp(v->name, "vmexten")) { 00830 if ((var = ast_var_assign("VOICEMAIL_EXTEN", v->value))) 00831 AST_LIST_INSERT_TAIL(&global_variables, var, entries); 00832 } 00833 if (!strcasecmp(v->name, "localextenlength")) { 00834 if ((var = ast_var_assign("EXTENSION_LENGTH", v->value))) 00835 AST_LIST_INSERT_TAIL(&global_variables, var, entries); 00836 } 00837 } 00838 } 00839 00840 if (!strcasecmp(cat, "authentication")) 00841 continue; 00842 00843 if (!((tmp = ast_variable_retrieve(cfg, cat, "autoprov")) && ast_true(tmp))) 00844 continue; 00845 00846 if (!(mac = ast_variable_retrieve(cfg, cat, "macaddress"))) { 00847 ast_log(LOG_WARNING, "autoprov set for %s, but no mac address - skipping.\n", cat); 00848 continue; 00849 } 00850 00851 tmp = S_OR(ast_variable_retrieve(cfg, cat, "profile"), global_default_profile); 00852 if (ast_strlen_zero(tmp)) { 00853 ast_log(LOG_WARNING, "No profile for user [%s] with mac '%s' - skipping\n", cat, mac); 00854 continue; 00855 } 00856 00857 if (!(profile = find_profile(tmp))) { 00858 ast_log(LOG_WARNING, "Could not look up profile '%s' - skipping.\n", tmp); 00859 continue; 00860 } 00861 00862 if (!(user = build_user(cfg, cat, mac, profile))) { 00863 ast_log(LOG_WARNING, "Could not create user %s - skipping.\n", cat); 00864 continue; 00865 } 00866 00867 if (build_user_routes(user)) { 00868 ast_log(LOG_WARNING, "Could not create http routes for %s - skipping\n", user->name); 00869 delete_user(user); 00870 continue; 00871 } 00872 00873 AST_RWLIST_WRLOCK(&users); 00874 AST_RWLIST_INSERT_TAIL(&users, user, entry); 00875 AST_RWLIST_UNLOCK(&users); 00876 } 00877 00878 ast_config_destroy(cfg); 00879 00880 return 0; 00881 }
| static void set_timezone_variables | ( | struct varshead * | headp, | |
| const char * | zone | |||
| ) | [static] |
Set all timezone-related variables based on a zone (i.e. America/New_York).
| headp | pointer to list of user variables | |
| zone | A time zone. NULL sets variables based on timezone of the machine |
Definition at line 631 of file res_phoneprov.c.
References ast_get_dst_info(), AST_LIST_INSERT_TAIL, ast_localtime(), ast_var_assign(), ast_tm::tm_hour, ast_tm::tm_mday, ast_tm::tm_mon, and var.
Referenced by build_user().
00632 { 00633 time_t utc_time; 00634 int dstenable; 00635 time_t dststart; 00636 time_t dstend; 00637 struct ast_tm tm_info; 00638 int tzoffset; 00639 char buffer[21]; 00640 struct ast_var_t *var; 00641 struct timeval tv; 00642 00643 time(&utc_time); 00644 ast_get_dst_info(&utc_time, &dstenable, &dststart, &dstend, &tzoffset, zone); 00645 snprintf(buffer, sizeof(buffer), "%d", tzoffset); 00646 var = ast_var_assign("TZOFFSET", buffer); 00647 if (var) 00648 AST_LIST_INSERT_TAIL(headp, var, entries); 00649 00650 if (!dstenable) 00651 return; 00652 00653 if ((var = ast_var_assign("DST_ENABLE", "1"))) 00654 AST_LIST_INSERT_TAIL(headp, var, entries); 00655 00656 tv.tv_sec = dststart; 00657 ast_localtime(&tv, &tm_info, zone); 00658 00659 snprintf(buffer, sizeof(buffer), "%d", tm_info.tm_mon+1); 00660 if ((var = ast_var_assign("DST_START_MONTH", buffer))) 00661 AST_LIST_INSERT_TAIL(headp, var, entries); 00662 00663 snprintf(buffer, sizeof(buffer), "%d", tm_info.tm_mday); 00664 if ((var = ast_var_assign("DST_START_MDAY", buffer))) 00665 AST_LIST_INSERT_TAIL(headp, var, entries); 00666 00667 snprintf(buffer, sizeof(buffer), "%d", tm_info.tm_hour); 00668 if ((var = ast_var_assign("DST_START_HOUR", buffer))) 00669 AST_LIST_INSERT_TAIL(headp, var, entries); 00670 00671 tv.tv_sec = dstend; 00672 ast_localtime(&tv, &tm_info, zone); 00673 00674 snprintf(buffer, sizeof(buffer), "%d", tm_info.tm_mon + 1); 00675 if ((var = ast_var_assign("DST_END_MONTH", buffer))) 00676 AST_LIST_INSERT_TAIL(headp, var, entries); 00677 00678 snprintf(buffer, sizeof(buffer), "%d", tm_info.tm_mday); 00679 if ((var = ast_var_assign("DST_END_MDAY", buffer))) 00680 AST_LIST_INSERT_TAIL(headp, var, entries); 00681 00682 snprintf(buffer, sizeof(buffer), "%d", tm_info.tm_hour); 00683 if ((var = ast_var_assign("DST_END_HOUR", buffer))) 00684 AST_LIST_INSERT_TAIL(headp, var, entries); 00685 }
| static int unload_module | ( | void | ) | [static] |
Definition at line 1023 of file res_phoneprov.c.
References ao2_ref(), ARRAY_LEN, ast_cli_unregister_multiple(), ast_custom_function_unregister(), ast_http_uri_unlink(), AST_LIST_REMOVE_HEAD, ast_var_delete(), delete_profiles(), delete_routes(), delete_users(), ast_var_t::entries, global_variables, and var.
01024 { 01025 struct ast_var_t *var; 01026 01027 ast_http_uri_unlink(&phoneprovuri); 01028 ast_custom_function_unregister(&pp_each_user_function); 01029 ast_cli_unregister_multiple(pp_cli, ARRAY_LEN(pp_cli)); 01030 01031 delete_routes(); 01032 delete_users(); 01033 delete_profiles(); 01034 ao2_ref(profiles, -1); 01035 ao2_ref(http_routes, -1); 01036 01037 while ((var = AST_LIST_REMOVE_HEAD(&global_variables, entries))) 01038 ast_var_delete(var); 01039 01040 return 0; 01041 }
| static struct phone_profile* unref_profile | ( | struct phone_profile * | prof | ) | [static, read] |
Definition at line 211 of file res_phoneprov.c.
References ao2_ref().
Referenced by build_profile(), build_user(), delete_profiles(), and delete_user().
00212 { 00213 ao2_ref(prof, -1); 00214 00215 return NULL; 00216 }
| static struct http_route* unref_route | ( | struct http_route * | route | ) | [static, read] |
Definition at line 267 of file res_phoneprov.c.
References ao2_ref().
Referenced by build_route(), delete_routes(), handle_show_routes(), and phoneprov_callback().
00268 { 00269 ao2_ref(route, -1); 00270 00271 return NULL; 00272 }
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS , .description = "HTTP Phone Provisioning" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .reload = reload, } [static] |
Definition at line 1057 of file res_phoneprov.c.
struct in_addr __ourip = { .s_addr = 0x00000000, } [static] |
const struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 1057 of file res_phoneprov.c.
| char* ext |
Definition at line 146 of file res_phoneprov.c.
| char global_default_profile[80] = "" |
Default profile to use if one isn't specified
Definition at line 159 of file res_phoneprov.c.
| char global_server[80] = "" |
Server to substitute into templates
Definition at line 157 of file res_phoneprov.c.
| char global_serverport[6] = "" |
Server port to substitute into templates
Definition at line 158 of file res_phoneprov.c.
| struct varshead global_variables |
List of global variables currently available: VOICEMAIL_EXTEN, EXTENSION_LENGTH.
Definition at line 162 of file res_phoneprov.c.
Referenced by build_profile(), load_module(), set_config(), and unload_module().
struct ao2_container* http_routes [static] |
Definition at line 141 of file res_phoneprov.c.
struct { ... } mimetypes[] [static] |
Extensions whose mime types we think we know.
| char* mtype |
Definition at line 147 of file res_phoneprov.c.
struct ast_http_uri phoneprovuri [static] |
Definition at line 999 of file res_phoneprov.c.
struct ast_cli_entry pp_cli[] [static] |
Initial value:
{
AST_CLI_DEFINE(handle_show_routes, "Show registered phoneprov http routes"),
}
Definition at line 995 of file res_phoneprov.c.
struct ast_custom_function pp_each_user_function [static] |
Definition at line 938 of file res_phoneprov.c.
struct pp_variable_lookup pp_variable_list[] [static] |
Lookup table to translate between users.conf property names and variables for use in phoneprov templates.
Referenced by build_user().
struct ao2_container* profiles [static] |
Definition at line 140 of file res_phoneprov.c.
1.5.6