提交 cd1824e1 authored 作者: Anthony Minessale's avatar Anthony Minessale

Adding switch_mprintf (broken out from sqlite)

Adding new %w to mprintf to auto escape both single quote and backslashes
Improve the tab completion a tad and fix some sqlite/odbc compat with new mprintf opts
Change the default stream writer to use switch_vmprintf so %q/%w can be used there too



git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@15875 d0543943-73ff-0310-b7d9-9358b9ac24b2
上级 7803a752
......@@ -67,6 +67,7 @@ src/switch_buffer.c \
src/switch_caller.c \
src/switch_channel.c \
src/switch_console.c \
src/switch_mprintf.c\
src/switch_core_media_bug.c \
src/switch_core_timer.c \
src/switch_core_asr.c \
......@@ -142,6 +143,7 @@ src/include/switch_core_event_hook.h\
src/include/switch_scheduler.h\
src/include/switch_core.h\
src/include/switch_core_db.h\
src/include/switch_mprintf.h\
src/include/switch_config.h\
src/include/switch_event.h\
src/include/switch_frame.h\
......
......@@ -106,7 +106,7 @@
#include "switch_platform.h"
#include "switch_types.h"
#include "switch_apr.h"
#include "switch_mprintf.h"
#include "switch_core_db.h"
#include "switch_dso.h"
#include "switch_regex.h"
......
......@@ -539,12 +539,6 @@ SWITCH_DECLARE(int) switch_core_db_changes(switch_core_db_t *db);
* should always use %q instead of %s when inserting text into a string
* literal.
*/
SWITCH_DECLARE(char *) switch_mprintf(const char *zFormat, ...);
/*!
* \see switch_mprintf
*/
SWITCH_DECLARE(char *) switch_vmprintf(const char *zFormat, va_list ap);
SWITCH_END_EXTERN_C
#endif
......
/*
** 2001 September 22
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
*************************************************************************
*/
#ifndef SWITCH_MPRINTF_H
#define SWITCH_MPRINTF_H
SWITCH_BEGIN_EXTERN_C
/**
* This routine is a variant of the "sprintf()" from the
* standard C library. The resulting string is written into memory
* obtained from malloc() so that there is never a possiblity of buffer
* overflow. This routine also implement some additional formatting
* options that are useful for constructing SQL statements.
*
* The strings returned by this routine should be freed by calling
* switch_core_db_free().
*
* All of the usual printf formatting options apply. In addition, there
* is a "%q" option. %q works like %s in that it substitutes a null-terminated
* string from the argument list. But %q also doubles every '\'' character.
* %q is designed for use inside a string literal. By doubling each '\''
* character it escapes that character and allows it to be inserted into
* the string.
*
* For example, so some string variable contains text as follows:
*
* char *zText = "It's a happy day!";
*
* We can use this text in an SQL statement as follows:
*
* char *z = switch_core_db_mprintf("INSERT INTO TABLES('%q')", zText);
* switch_core_db_exec(db, z, callback1, 0, 0);
* switch_core_db_free(z);
*
* Because the %q format string is used, the '\'' character in zText
* is escaped and the SQL generated is as follows:
*
* INSERT INTO table1 VALUES('It''s a happy day!')
*
* This is correct. Had we used %s instead of %q, the generated SQL
* would have looked like this:
*
* INSERT INTO table1 VALUES('It's a happy day!');
*
* This second example is an SQL syntax error. As a general rule you
* should always use %q instead of %s when inserting text into a string
* literal.
*/
SWITCH_DECLARE(char *) switch_mprintf(const char *zFormat, ...);
SWITCH_DECLARE(char *) switch_vmprintf(const char *zFormat, va_list ap);
SWITCH_END_EXTERN_C
#endif /* SWITCH_MPRINTF_H */
......@@ -3744,6 +3744,18 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_sofia_load)
switch_console_set_complete("add sofia profile");
switch_console_set_complete("add sofia profile restart all");
switch_console_set_complete("add sofia profile _any_ start reloadxml");
switch_console_set_complete("add sofia profile _any_ stop reloadxml");
switch_console_set_complete("add sofia profile _any_ rescan reloadxml");
switch_console_set_complete("add sofia profile _any_ restart reloadxml");
switch_console_set_complete("add sofia profile _any_ flush_inbound_reg");
switch_console_set_complete("add sofia profile _any_ register");
switch_console_set_complete("add sofia profile _any_ killgw");
switch_console_set_complete("add sofia profile _any_ siptrace on");
switch_console_set_complete("add sofia profile _any_ siptrace off");
SWITCH_ADD_API(api_interface, "sofia_contact", "Sofia Contacts", sofia_contact_function, "[profile/]<user>@<domain>");
SWITCH_ADD_CHAT(chat_interface, SOFIA_CHAT_PROTO, sofia_presence_chat_send);
......@@ -3755,6 +3767,8 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_sofia_shutdown)
{
int sanity = 0;
switch_console_set_complete("del sofia");
switch_mutex_lock(mod_sofia_globals.mutex);
if (mod_sofia_globals.running == 1) {
mod_sofia_globals.running = 0;
......
......@@ -1059,7 +1059,7 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void
int sanity;
switch_thread_t *worker_thread;
switch_status_t st;
char cbuf[512] = "";
switch_mutex_lock(mod_sofia_globals.mutex);
......@@ -1226,10 +1226,17 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void
switch_yield(1000000);
switch_snprintf(cbuf, sizeof(cbuf), "add sofia profile %s", profile->name);
switch_console_set_complete(cbuf);
while (mod_sofia_globals.running == 1 && sofia_test_pflag(profile, PFLAG_RUNNING) && sofia_test_pflag(profile, PFLAG_WORKER_RUNNING)) {
su_root_step(profile->s_root, 1000);
}
switch_snprintf(cbuf, sizeof(cbuf), "del sofia profile %s", profile->name);
switch_console_set_complete(cbuf);
sofia_clear_pflag_locked(profile, PFLAG_RUNNING);
switch_core_session_hupall_matching_var("sofia_profile_name", profile->name, SWITCH_CAUSE_MANAGER_REQUEST);
......
......@@ -3644,10 +3644,12 @@ void sofia_glue_release_profile__(const char *file, const char *func, int line,
switch_status_t sofia_glue_add_profile(char *key, sofia_profile_t *profile)
{
switch_status_t status = SWITCH_STATUS_FALSE;
char cbuf[512] = "";
switch_mutex_lock(mod_sofia_globals.hash_mutex);
if (!switch_core_hash_find(mod_sofia_globals.profile_hash, key)) {
status = switch_core_hash_insert(mod_sofia_globals.profile_hash, key, profile);
switch_snprintf(cbuf, sizeof(cbuf), "add sofia profile %s", key);
switch_console_set_complete(cbuf);
}
switch_mutex_unlock(mod_sofia_globals.hash_mutex);
......@@ -3716,13 +3718,16 @@ void sofia_glue_del_profile(sofia_profile_t *profile)
const void *var;
void *val;
sofia_profile_t *pptr;
char cbuf[512] = "";
switch_mutex_lock(mod_sofia_globals.hash_mutex);
if (mod_sofia_globals.profile_hash) {
for (hi = switch_hash_first(NULL, mod_sofia_globals.profile_hash); hi; hi = switch_hash_next(hi)) {
switch_hash_this(hi, &var, NULL, &val);
if ((pptr = (sofia_profile_t *) val) && pptr == profile) {
aliases[i++] = strdup((char *) var);
switch_snprintf(cbuf, sizeof(cbuf), "del sofia profile %s", var);
switch_console_set_complete(cbuf);
if (i == 512) {
abort();
}
......
......@@ -122,7 +122,10 @@ SWITCH_DECLARE_NONSTD(switch_status_t) switch_console_stream_write(switch_stream
}
va_start(ap, fmt);
ret = switch_vasprintf(&data, fmt, ap);
//ret = switch_vasprintf(&data, fmt, ap);
if (!(data = switch_vmprintf(fmt, ap))) {
ret = -1;
}
va_end(ap);
if (data) {
......@@ -205,7 +208,12 @@ char *expand_alias(char *cmd, char *arg)
switch_core_db_handle(&db);
sql = switch_mprintf("select command from aliases where alias='%q'", cmd);
if (db->type == SCDB_TYPE_CORE_DB) {
sql = switch_mprintf("select command from aliases where alias='%q'", cmd);
} else {
sql = switch_mprintf("select command from aliases where alias='%w'", cmd);
}
switch_cache_db_execute_sql_callback(db, sql, alias_callback, &r, &errmsg);
......@@ -217,7 +225,11 @@ char *expand_alias(char *cmd, char *arg)
switch_safe_free(sql);
if (!r) {
sql = switch_mprintf("select command from aliases where alias='%q %q'", cmd, arg);
if (db->type == SCDB_TYPE_CORE_DB) {
sql = switch_mprintf("select command from aliases where alias='%q %q'", cmd, arg);
} else {
sql = switch_mprintf("select command from aliases where alias='%w %w'", cmd, arg);
}
switch_cache_db_execute_sql_callback(db, sql, alias_callback, &r, &errmsg);
......@@ -499,6 +511,7 @@ struct helper {
int hits;
int words;
char last[512];
char partial[512];
FILE *out;
};
......@@ -506,19 +519,37 @@ static int comp_callback(void *pArg, int argc, char **argv, char **columnNames)
{
struct helper *h = (struct helper *) pArg;
char *target = NULL;
switch_size_t x, y;
int i;
target = argv[0];
if (!target) {
return -1;
}
fprintf(h->out, "[%20s]\t", target);
if (!zstr(target)) {
fprintf(h->out, "[%20s]\t", target);
switch_copy_string(h->last, target, sizeof(h->last));
h->hits++;
}
x = strlen(h->last);
y = strlen(h->partial);
switch_copy_string(h->last, target, sizeof(h->last));
if (h->hits > 1) {
for(i = 0; i < x && i < y; i++) {
if (h->last[i] != h->partial[i]) {
h->partial[i] = '\0';
break;
}
}
} else if (h->hits == 1) {
switch_copy_string(h->partial, target, sizeof(h->last));
}
if (!zstr(target)) {
if ((++h->hits % 4) == 0) {
if ((h->hits % 4) == 0) {
fprintf(h->out, "\n");
}
}
......@@ -600,8 +631,20 @@ static unsigned char complete(EditLine * el, int ch)
}
for (x = 0; x < argc; x++) {
stream.write_function(&stream, "(a%d = '' or a%d like '%s%%')%s", x + 1, x + 1, switch_str_nil(argv[x]), x == argc - 1 ? "" : " and ");
for (x = 0; x < argc && x < 11; x++) {
if (h.words + 1 > argc) {
if (db->type == SCDB_TYPE_CORE_DB) {
stream.write_function(&stream, "(a%d = '' or a%d = '%q')%q", x + 1, x + 1, switch_str_nil(argv[x]), x == argc - 1 ? "" : " and ");
} else {
stream.write_function(&stream, "(a%d = '' or a%d = '%w')%w", x + 1, x + 1, switch_str_nil(argv[x]), x == argc - 1 ? "" : " and ");
}
} else {
if (db->type == SCDB_TYPE_CORE_DB) {
stream.write_function(&stream, "(a%d = '' or a%d like '%q%%')%q", x + 1, x + 1, switch_str_nil(argv[x]), x == argc - 1 ? "" : " and ");
} else {
stream.write_function(&stream, "(a%d = '' or a%d like '%w%%')%w", x + 1, x + 1, switch_str_nil(argv[x]), x == argc - 1 ? "" : " and ");
}
}
}
stream.write_function(&stream, " and hostname='%s'", switch_core_get_variable("hostname"));
......@@ -624,9 +667,13 @@ static unsigned char complete(EditLine * el, int ch)
fprintf(h.out, "\n\n");
if (h.hits == 1) {
if (h.hits == 1 && !zstr(h.last)) {
el_deletestr(el, h.len);
el_insertstr(el, h.last);
el_insertstr(el, " ");
} else if (h.hits > 1 && !zstr(h.partial)) {
el_deletestr(el, h.len);
el_insertstr(el, h.partial);
}
end:
......@@ -655,11 +702,19 @@ SWITCH_DECLARE(switch_status_t) switch_console_set_complete(const char *string)
SWITCH_STANDARD_STREAM(mystream);
switch_core_db_handle(&db);
if (!strcasecmp(argv[0], "stickyadd")) {
mystream.write_function(&mystream, "insert into complete values (1,");
for (x = 0; x < 10; x++) {
mystream.write_function(&mystream, "'%s', ", switch_str_nil(argv[x + 1]));
if (argv[x + 1] && !strcasecmp(argv[x + 1], "_any_")) {
mystream.write_function(&mystream, "%s", "'', ");
} else {
if (db->type == SCDB_TYPE_CORE_DB) {
mystream.write_function(&mystream, "'%q', ", switch_str_nil(argv[x + 1]));
} else {
mystream.write_function(&mystream, "'%w', ", switch_str_nil(argv[x + 1]));
}
}
}
mystream.write_function(&mystream, " '%s')", switch_core_get_variable("hostname"));
switch_cache_db_persistant_execute(db, mystream.data, 5);
......@@ -667,9 +722,18 @@ SWITCH_DECLARE(switch_status_t) switch_console_set_complete(const char *string)
} else if (!strcasecmp(argv[0], "add")) {
mystream.write_function(&mystream, "insert into complete values (0,");
for (x = 0; x < 10; x++) {
mystream.write_function(&mystream, "'%s', ", switch_str_nil(argv[x + 1]));
if (argv[x + 1] && !strcasecmp(argv[x + 1], "_any_")) {
mystream.write_function(&mystream, "%s", "'', ");
} else {
if (db->type == SCDB_TYPE_CORE_DB) {
mystream.write_function(&mystream, "'%q', ", switch_str_nil(argv[x + 1]));
} else {
mystream.write_function(&mystream, "'%w', ", switch_str_nil(argv[x + 1]));
}
}
}
mystream.write_function(&mystream, " '%s')", switch_core_get_variable("hostname"));
switch_cache_db_persistant_execute(db, mystream.data, 5);
status = SWITCH_STATUS_SUCCESS;
} else if (!strcasecmp(argv[0], "del")) {
......@@ -679,13 +743,18 @@ SWITCH_DECLARE(switch_status_t) switch_console_set_complete(const char *string)
} else {
mystream.write_function(&mystream, "delete from complete where ");
for (x = 0; x < argc - 1; x++) {
mystream.write_function(&mystream, "a%d = '%s'%s", x + 1, switch_str_nil(argv[x + 1]), x == argc - 2 ? "" : " and ");
if (db->type == SCDB_TYPE_CORE_DB) {
mystream.write_function(&mystream, "a%d = '%q'%q", x + 1, switch_str_nil(argv[x + 1]), x == argc - 2 ? "" : " and ");
} else {
mystream.write_function(&mystream, "a%d = '%w'%w", x + 1, switch_str_nil(argv[x + 1]), x == argc - 2 ? "" : " and ");
}
}
mystream.write_function(&mystream, " and hostname='%s'", switch_core_get_variable("hostname"));
switch_cache_db_persistant_execute(db, mystream.data, 1);
}
status = SWITCH_STATUS_SUCCESS;
}
switch_safe_free(mystream.data);
switch_cache_db_release_db_handle(&db);
}
......@@ -715,16 +784,26 @@ SWITCH_DECLARE(switch_status_t) switch_console_set_alias(const char *string)
sql = switch_mprintf("delete from aliases where alias='%q' and hostname='%q'", argv[1], switch_core_get_variable("hostname"));
switch_cache_db_persistant_execute(db, sql, 5);
switch_safe_free(sql);
sql = switch_mprintf("insert into aliases (sticky, alias, command, hostname) values (1, '%q','%q','%q')",
argv[1], argv[2], switch_core_get_variable("hostname"));
if (db->type == SCDB_TYPE_CORE_DB) {
sql = switch_mprintf("insert into aliases (sticky, alias, command, hostname) values (1, '%q','%q','%q')",
argv[1], argv[2], switch_core_get_variable("hostname"));
} else {
sql = switch_mprintf("insert into aliases (sticky, alias, command, hostname) values (1, '%w','%w','%w')",
argv[1], argv[2], switch_core_get_variable("hostname"));
}
switch_cache_db_persistant_execute(db, sql, 5);
status = SWITCH_STATUS_SUCCESS;
} else if (!strcasecmp(argv[0], "add") && argc == 3) {
sql = switch_mprintf("delete from aliases where alias='%q' and hostname='%q'", argv[1], switch_core_get_variable("hostname"));
switch_cache_db_persistant_execute(db, sql, 5);
switch_safe_free(sql);
sql = switch_mprintf("insert into aliases (sticky, alias, command, hostname) values (0, '%q','%q','%q')",
argv[1], argv[2], switch_core_get_variable("hostname"));
if (db->type == SCDB_TYPE_CORE_DB) {
sql = switch_mprintf("insert into aliases (sticky, alias, command, hostname) values (0, '%q','%q','%q')",
argv[1], argv[2], switch_core_get_variable("hostname"));
} else {
sql = switch_mprintf("insert into aliases (sticky, alias, command, hostname) values (0, '%w','%w','%w')",
argv[1], argv[2], switch_core_get_variable("hostname"));
}
switch_cache_db_persistant_execute(db, sql, 5);
status = SWITCH_STATUS_SUCCESS;
} else if (!strcasecmp(argv[0], "del") && argc == 2) {
......
......@@ -179,22 +179,6 @@ SWITCH_DECLARE(int) switch_core_db_changes(switch_core_db_t *db)
return sqlite3_changes(db);
}
SWITCH_DECLARE(char *) switch_mprintf(const char *zFormat, ...)
{
va_list ap;
char *z;
va_start(ap, zFormat);
z = sqlite3_vmprintf(zFormat, ap);
va_end(ap);
return z;
}
SWITCH_DECLARE(char *) switch_vmprintf(const char *zFormat, va_list ap)
{
return sqlite3_vmprintf(zFormat, ap);
}
SWITCH_DECLARE(switch_core_db_t *) switch_core_db_open_file(const char *filename)
{
switch_core_db_t *db;
......
差异被折叠。
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论