[asterisk-commits] russell: branch russell/chan_refcount r104109 - in /team/russell/chan_refcoun...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Mon Feb 25 17:49:58 CST 2008
Author: russell
Date: Mon Feb 25 17:49:57 2008
New Revision: 104109
URL: http://svn.digium.com/view/asterisk?view=rev&rev=104109
Log:
sync with trunk
Modified:
team/russell/chan_refcount/ (props changed)
team/russell/chan_refcount/CHANGES
team/russell/chan_refcount/UPGRADE.txt
team/russell/chan_refcount/apps/app_voicemail.c
team/russell/chan_refcount/cdr/cdr_pgsql.c
team/russell/chan_refcount/channels/chan_agent.c
team/russell/chan_refcount/channels/chan_iax2.c
team/russell/chan_refcount/channels/chan_sip.c
team/russell/chan_refcount/channels/chan_zap.c
team/russell/chan_refcount/configs/sip.conf.sample
team/russell/chan_refcount/configure
team/russell/chan_refcount/configure.ac
team/russell/chan_refcount/doc/manager_1_1.txt
team/russell/chan_refcount/doc/siptls.txt
team/russell/chan_refcount/funcs/func_global.c
team/russell/chan_refcount/include/asterisk/autoconfig.h.in
team/russell/chan_refcount/include/asterisk/manager.h
team/russell/chan_refcount/main/config.c
team/russell/chan_refcount/main/manager.c
team/russell/chan_refcount/main/utils.c
team/russell/chan_refcount/res/res_agi.c
team/russell/chan_refcount/res/res_config_pgsql.c
team/russell/chan_refcount/utils/astman.c
Propchange: team/russell/chan_refcount/
------------------------------------------------------------------------------
Binary property 'branch-1.4-blocked' - no diff available.
Propchange: team/russell/chan_refcount/
------------------------------------------------------------------------------
Binary property 'branch-1.4-merged' - no diff available.
Propchange: team/russell/chan_refcount/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Mon Feb 25 17:49:57 2008
@@ -1,1 +1,1 @@
-/trunk:1-104009
+/trunk:1-104106,104108
Modified: team/russell/chan_refcount/CHANGES
URL: http://svn.digium.com/view/asterisk/team/russell/chan_refcount/CHANGES?view=diff&rev=104109&r1=104108&r2=104109
==============================================================================
--- team/russell/chan_refcount/CHANGES (original)
+++ team/russell/chan_refcount/CHANGES Mon Feb 25 17:49:57 2008
@@ -48,6 +48,9 @@
* Updated action newcat to allow new category to be inserted in file above another
existing category.
* Added new event "JitterBufStats" in the IAX2 channel
+ * Originate now requires the Originate privilege and, if you want to call out
+ to a subshell, it requires the System privilege, as well. This was done to
+ enhance manager security.
Dialplan functions
------------------
@@ -447,6 +450,29 @@
and to ensure that the oldest log file gets deleted.
* Added realtime support for the queue log
+Call Detail Records
+-------------------
+ * The cdr_manager module has a [mappings] feature, like cdr_custom,
+ to add fields to the manager event from the CDR variables.
+ * Added cdr_adaptive_odbc, a new module that adapts to the structure of your
+ backend database CDR table. Specifically, additional, non-standard
+ columns are supported, merely by setting the corresponding CDR variable in
+ your dialplan. In addition, you may alias any column to another name (for
+ example, if you want the 'src' CDR variable to be column 'ANI' in the DB,
+ simply "alias src => ANI" in the configuration file). Records may be
+ posted to more than one backend, simply by specifying multiple categories
+ in the configuration file. And finally, you may filter which CDRs get
+ posted to each backend, by specifying a filter (which the record must
+ match) for the particular category. Filters are additive (meaning all
+ rules must match to post that CDR).
+ * The Postgres CDR module now supports some features of the cdr_adaptive_odbc
+ module. Specifically, you may add additional columns into the table and
+ they will be set, if you set the corresponding CDR variable name. Also,
+ if you omit columns in your database table, they will be silently skipped
+ (but a record will still be inserted, based on what columns remain). Note
+ that the other two features from cdr_adaptive_odbc (alias and filter) are
+ not currently supported.
+
Miscellaneous New Modules
-------------------------
* Added a new CDR module, cdr_sqlite3_custom.
@@ -491,8 +517,6 @@
* Added maxfiles option to options section of asterisk.conf which allows you to specify
what Asterisk should set as the maximum number of open files when it loads.
* Added the jittertargetextra configuration option.
- * The cdr_manager module has a [mappings] feature, like cdr_custom,
- to add fields to the manager event from the CDR variables.
* Added support for setting the CoS for VLAN traffic (802.1p). See the sample
configuration files for the IP channel drivers. The new option is "cos".
This information is also documented in doc/qos.tex, or the IP Quality of Service
@@ -520,3 +544,4 @@
* Added a compiler flag, CHANNEL_TRACE, which permits channel tracing to be
turned on, via the CHANNEL(trace) dialplan function. Could be useful for
dialplan debugging.
+
Modified: team/russell/chan_refcount/UPGRADE.txt
URL: http://svn.digium.com/view/asterisk/team/russell/chan_refcount/UPGRADE.txt?view=diff&rev=104109&r1=104108&r2=104109
==============================================================================
--- team/russell/chan_refcount/UPGRADE.txt (original)
+++ team/russell/chan_refcount/UPGRADE.txt Mon Feb 25 17:49:57 2008
@@ -178,3 +178,6 @@
change your manager.conf to add the level to existing AMI users, if they
want to see the CDR events generated.
+* The Originate command now requires the Originate write permission. For
+ Originate with the Application parameter, you need the additional System
+ privilege if you want to do anything that calls out to a subshell.
Modified: team/russell/chan_refcount/apps/app_voicemail.c
URL: http://svn.digium.com/view/asterisk/team/russell/chan_refcount/apps/app_voicemail.c?view=diff&rev=104109&r1=104108&r2=104109
==============================================================================
--- team/russell/chan_refcount/apps/app_voicemail.c (original)
+++ team/russell/chan_refcount/apps/app_voicemail.c Mon Feb 25 17:49:57 2008
@@ -222,6 +222,7 @@
#define VM_TEMPGREETWARN (1 << 15) /*!< Remind user tempgreeting is set */
#define VM_MOVEHEARD (1 << 16) /*!< Move a "heard" message to Old after listening to it */
#define ERROR_LOCK_PATH -100
+#define ERROR_MAILBOX_FULL -200
enum {
@@ -3522,7 +3523,7 @@
} else {
if (x >= vmu->maxmsg) {
ast_unlock_path(ddir);
- return -1;
+ return ERROR_MAILBOX_FULL;
}
}
make_file(sfn, sizeof(sfn), dir, msg);
@@ -5336,8 +5337,9 @@
} else if (!strcasecmp(vms->curbox, "INBOX") && vms->heard[x] && ast_test_flag(vmu, VM_MOVEHEARD) && !vms->deleted[x]) {
/* Move to old folder before deleting */
res = save_to_folder(vmu, vms, x, 1);
- if (res == ERROR_LOCK_PATH) {
+ if (res == ERROR_LOCK_PATH || res == ERROR_MAILBOX_FULL) {
/* If save failed do not delete the message */
+ ast_log(LOG_WARNING, "Save failed. Not moving message: %s.\n", res == ERROR_LOCK_PATH ? "unable to lock path" : "destination folder full");
vms->deleted[x] = 0;
vms->heard[x] = 0;
--x;
Modified: team/russell/chan_refcount/cdr/cdr_pgsql.c
URL: http://svn.digium.com/view/asterisk/team/russell/chan_refcount/cdr/cdr_pgsql.c?view=diff&rev=104109&r1=104108&r2=104109
==============================================================================
--- team/russell/chan_refcount/cdr/cdr_pgsql.c (original)
+++ team/russell/chan_refcount/cdr/cdr_pgsql.c Mon Feb 25 17:49:57 2008
@@ -50,28 +50,67 @@
#include "asterisk/cdr.h"
#include "asterisk/module.h"
-#define DATE_FORMAT "%Y-%m-%d %T"
+#define DATE_FORMAT "'%Y-%m-%d %T'"
static char *name = "pgsql";
static char *config = "cdr_pgsql.conf";
static char *pghostname = NULL, *pgdbname = NULL, *pgdbuser = NULL, *pgpassword = NULL, *pgdbport = NULL, *table = NULL;
static int connected = 0;
+static int maxsize = 512, maxsize2 = 512;
AST_MUTEX_DEFINE_STATIC(pgsql_lock);
static PGconn *conn = NULL;
+
+struct columns {
+ char *name;
+ char *type;
+ int len;
+ AST_RWLIST_ENTRY(columns) list;
+};
+
+static AST_RWLIST_HEAD_STATIC(psql_columns, columns);
+
+#define LENGTHEN_BUF1(size) \
+ do { \
+ /* Lengthen buffer, if necessary */ \
+ if ((newsize = lensql + (size) + 3) > sizesql) { \
+ if ((tmp = ast_realloc(sql, (newsize / 512 + 1) * 512))) { \
+ sql = tmp; \
+ sizesql = (newsize / 512 + 1) * 512; \
+ } else { \
+ ast_log(LOG_ERROR, "Unable to allocate sufficient memory. Insert CDR failed.\n"); \
+ ast_free(sql); \
+ ast_free(sql2); \
+ AST_RWLIST_UNLOCK(&psql_columns); \
+ return -1; \
+ } \
+ } \
+ } while (0)
+
+#define LENGTHEN_BUF2(size) \
+ do { \
+ if ((newsize = lensql2 + (size) + 3) > sizesql2) { \
+ if ((tmp = ast_realloc(sql2, (newsize / 512 + 1) * 512))) { \
+ sql2 = tmp; \
+ sizesql2 = (newsize / 512 + 1) * 512; \
+ } else { \
+ ast_log(LOG_ERROR, "Unable to allocate sufficient memory. Insert CDR failed.\n"); \
+ ast_free(sql); \
+ ast_free(sql2); \
+ AST_RWLIST_UNLOCK(&psql_columns); \
+ return -1; \
+ } \
+ } \
+ } while (0)
static int pgsql_log(struct ast_cdr *cdr)
{
struct ast_tm tm;
- char sqlcmd[2048] = "", timestr[128];
char *pgerror;
PGresult *result;
ast_mutex_lock(&pgsql_lock);
-
- ast_localtime(&cdr->start, &tm, NULL);
- ast_strftime(timestr, sizeof(timestr), DATE_FORMAT, &tm);
if ((!connected) && pghostname && pgdbuser && pgpassword && pgdbname) {
conn = PQsetdbLogin(pghostname, pgdbport, NULL, NULL, pgdbname, pgdbuser, pgpassword);
@@ -87,49 +126,135 @@
}
if (connected) {
- char *clid=NULL, *dcontext=NULL, *channel=NULL, *dstchannel=NULL, *lastapp=NULL, *lastdata=NULL;
- char *src=NULL, *dst=NULL, *uniqueid=NULL, *userfield=NULL;
- int pgerr;
-
- /* Maximum space needed would be if all characters needed to be escaped, plus a trailing NULL */
- if ((clid = alloca(strlen(cdr->clid) * 2 + 1)) != NULL)
- PQescapeStringConn(conn, clid, cdr->clid, strlen(cdr->clid), &pgerr);
- if ((dcontext = alloca(strlen(cdr->dcontext) * 2 + 1)) != NULL)
- PQescapeStringConn(conn, dcontext, cdr->dcontext, strlen(cdr->dcontext), &pgerr);
- if ((channel = alloca(strlen(cdr->channel) * 2 + 1)) != NULL)
- PQescapeStringConn(conn, channel, cdr->channel, strlen(cdr->channel), &pgerr);
- if ((dstchannel = alloca(strlen(cdr->dstchannel) * 2 + 1)) != NULL)
- PQescapeStringConn(conn, dstchannel, cdr->dstchannel, strlen(cdr->dstchannel), &pgerr);
- if ((lastapp = alloca(strlen(cdr->lastapp) * 2 + 1)) != NULL)
- PQescapeStringConn(conn, lastapp, cdr->lastapp, strlen(cdr->lastapp), &pgerr);
- if ((lastdata = alloca(strlen(cdr->lastdata) * 2 + 1)) != NULL)
- PQescapeStringConn(conn, lastdata, cdr->lastdata, strlen(cdr->lastdata), &pgerr);
- if ((uniqueid = alloca(strlen(cdr->uniqueid) * 2 + 1)) != NULL)
- PQescapeStringConn(conn, uniqueid, cdr->uniqueid, strlen(cdr->uniqueid), &pgerr);
- if ((userfield = alloca(strlen(cdr->userfield) * 2 + 1)) != NULL)
- PQescapeStringConn(conn, userfield, cdr->userfield, strlen(cdr->userfield), &pgerr);
- if ((src = alloca(strlen(cdr->src) * 2 + 1)) != NULL)
- PQescapeStringConn(conn, src, cdr->src, strlen(cdr->src), &pgerr);
- if ((dst = alloca(strlen(cdr->dst) * 2 + 1)) != NULL)
- PQescapeStringConn(conn, dst, cdr->dst, strlen(cdr->dst), &pgerr);
-
- /* Check for all alloca failures above at once */
- if ((!clid) || (!dcontext) || (!channel) || (!dstchannel) || (!lastapp) || (!lastdata) || (!uniqueid) || (!userfield) || (!src) || (!dst)) {
- ast_log(LOG_ERROR, "cdr_pgsql: Out of memory error (insert fails)\n");
- ast_mutex_unlock(&pgsql_lock);
- return -1;
- }
+ struct columns *cur;
+ int lensql, lensql2, sizesql = maxsize, sizesql2 = maxsize2, newsize;
+ char *sql = ast_calloc(sizeof(char), sizesql), *sql2 = ast_calloc(sizeof(char), sizesql2), *tmp, *value;
+ char buf[257], escapebuf[513];
+
+ lensql = snprintf(sql, sizesql, "INSERT INTO %s (", table);
+ lensql2 = snprintf(sql2, sizesql2, " VALUES (");
+
+ AST_RWLIST_RDLOCK(&psql_columns);
+ AST_RWLIST_TRAVERSE(&psql_columns, cur, list) {
+ /* For fields not set, simply skip them */
+ ast_cdr_getvar(cdr, cur->name, &value, buf, sizeof(buf), 0, 0);
+ if (!value)
+ continue;
+
+ LENGTHEN_BUF1(strlen(cur->name));
+ lensql += snprintf(sql + lensql, sizesql - lensql, "%s,", cur->name);
+
+ if (strcmp(cur->name, "start") == 0 || strcmp(cur->name, "calldate") == 0) {
+ if (strncmp(cur->type, "int", 3) == 0) {
+ LENGTHEN_BUF2(12);
+ lensql2 += snprintf(sql2 + lensql2, sizesql2 - lensql2, "%ld", cdr->start.tv_sec);
+ } else if (strncmp(cur->type, "float", 5) == 0) {
+ LENGTHEN_BUF2(30);
+ lensql2 += snprintf(sql2 + lensql2, sizesql2 - lensql2, "%f", (double)cdr->start.tv_sec + (double)cdr->start.tv_usec / 1000000.0);
+ } else {
+ /* char, hopefully */
+ LENGTHEN_BUF2(30);
+ ast_localtime(&cdr->start, &tm, NULL);
+ lensql2 += ast_strftime(sql2 + lensql2, sizesql2 - lensql2, DATE_FORMAT, &tm);
+ }
+ } else if (strcmp(cur->name, "answer") == 0) {
+ if (strncmp(cur->type, "int", 3) == 0) {
+ LENGTHEN_BUF2(12);
+ lensql2 += snprintf(sql2 + lensql2, sizesql2 - lensql2, "%ld", cdr->answer.tv_sec);
+ } else if (strncmp(cur->type, "float", 5) == 0) {
+ LENGTHEN_BUF2(30);
+ lensql2 += snprintf(sql2 + lensql2, sizesql2 - lensql2, "%f", (double)cdr->answer.tv_sec + (double)cdr->answer.tv_usec / 1000000.0);
+ } else {
+ /* char, hopefully */
+ LENGTHEN_BUF2(30);
+ ast_localtime(&cdr->start, &tm, NULL);
+ lensql2 += ast_strftime(sql2 + lensql2, sizesql2 - lensql2, DATE_FORMAT, &tm);
+ }
+ } else if (strcmp(cur->name, "end") == 0) {
+ if (strncmp(cur->type, "int", 3) == 0) {
+ LENGTHEN_BUF2(12);
+ lensql2 += snprintf(sql2 + lensql2, sizesql2 - lensql2, "%ld", cdr->end.tv_sec);
+ } else if (strncmp(cur->type, "float", 5) == 0) {
+ LENGTHEN_BUF2(30);
+ lensql2 += snprintf(sql2 + lensql2, sizesql2 - lensql2, "%f", (double)cdr->end.tv_sec + (double)cdr->end.tv_usec / 1000000.0);
+ } else {
+ /* char, hopefully */
+ LENGTHEN_BUF2(30);
+ ast_localtime(&cdr->end, &tm, NULL);
+ lensql2 += ast_strftime(sql2 + lensql2, sizesql2 - lensql2, DATE_FORMAT, &tm);
+ }
+ } else if (strcmp(cur->name, "duration") == 0 || strcmp(cur->name, "billsec") == 0) {
+ if (cur->type[0] == 'i') {
+ /* Get integer, no need to escape anything */
+ ast_cdr_getvar(cdr, cur->name, &value, buf, sizeof(buf), 0, 0);
+ LENGTHEN_BUF2(12);
+ lensql2 += snprintf(sql2 + lensql2, sizesql2 - lensql2, "%s", value);
+ } else if (strncmp(cur->type, "float", 5) == 0) {
+ struct timeval *tv = cur->name[0] == 'd' ? &cdr->start : &cdr->answer;
+ LENGTHEN_BUF2(30);
+ lensql2 += snprintf(sql2 + lensql2, sizesql2 - lensql2, "%f", (double)cdr->end.tv_sec - tv->tv_sec + cdr->end.tv_usec / 1000000.0 - tv->tv_usec / 1000000.0);
+ } else {
+ /* Char field, probably */
+ struct timeval *tv = cur->name[0] == 'd' ? &cdr->start : &cdr->answer;
+ LENGTHEN_BUF2(30);
+ lensql2 += snprintf(sql2 + lensql2, sizesql2 - lensql2, "'%f'", (double)cdr->end.tv_sec - tv->tv_sec + cdr->end.tv_usec / 1000000.0 - tv->tv_usec / 1000000.0);
+ }
+ } else if (strcmp(cur->name, "disposition") == 0 || strcmp(cur->name, "amaflags") == 0) {
+ if (strncmp(cur->type, "int", 3) == 0) {
+ /* Integer, no need to escape anything */
+ ast_cdr_getvar(cdr, cur->name, &value, buf, sizeof(buf), 0, 1);
+ LENGTHEN_BUF2(12);
+ lensql2 += snprintf(sql2 + lensql2, sizesql2 - lensql2, "%s", value);
+ } else {
+ /* Although this is a char field, there are no special characters in the values for these fields */
+ ast_cdr_getvar(cdr, cur->name, &value, buf, sizeof(buf), 0, 0);
+ LENGTHEN_BUF2(30);
+ lensql2 += snprintf(sql2 + lensql2, sizesql2 - lensql2, "'%s'", value);
+ }
+ } else {
+ /* Arbitrary field, could be anything */
+ ast_cdr_getvar(cdr, cur->name, &value, buf, sizeof(buf), 0, 0);
+ if (strncmp(cur->type, "int", 3) == 0) {
+ long long whatever;
+ if (value && sscanf(value, "%lld", &whatever) == 1) {
+ LENGTHEN_BUF2(25);
+ lensql2 += snprintf(sql2 + lensql2, sizesql2 - lensql2, "%lld", whatever);
+ } else {
+ LENGTHEN_BUF2(1);
+ lensql2 += snprintf(sql2 + lensql2, sizesql2 - lensql2, "0");
+ }
+ } else if (strncmp(cur->type, "float", 5) == 0) {
+ long double whatever;
+ if (value && sscanf(value, "%Lf", &whatever) == 1) {
+ LENGTHEN_BUF2(50);
+ lensql2 += snprintf(sql2 + lensql2, sizesql2 - lensql2, "%30Lf", whatever);
+ } else {
+ LENGTHEN_BUF2(1);
+ lensql2 += snprintf(sql2 + lensql2, sizesql2 - lensql2, "0");
+ }
+ /* XXX Might want to handle dates, times, and other misc fields here XXX */
+ } else {
+ if (value)
+ PQescapeStringConn(conn, escapebuf, value, strlen(value), NULL);
+ else
+ escapebuf[0] = '\0';
+ LENGTHEN_BUF2(strlen(escapebuf) + 2);
+ lensql2 += snprintf(sql2 + lensql2, sizesql2 - lensql2, "'%s'", escapebuf);
+ }
+ }
+ LENGTHEN_BUF2(1);
+ strcat(sql2 + lensql2, ",");
+ lensql2++;
+ }
+ AST_RWLIST_UNLOCK(&psql_columns);
+ LENGTHEN_BUF1(lensql2);
+ sql[lensql - 1] = ')';
+ sql2[lensql2 - 1] = ')';
+ strcat(sql + lensql, sql2);
+ ast_verb(11, "[%s]\n", sql);
ast_debug(2, "cdr_pgsql: inserting a CDR record.\n");
- snprintf(sqlcmd,sizeof(sqlcmd),"INSERT INTO %s (calldate,clid,src,dst,dcontext,channel,dstchannel,"
- "lastapp,lastdata,duration,billsec,disposition,amaflags,accountcode,uniqueid,userfield) VALUES"
- " ('%s','%s','%s','%s','%s', '%s','%s','%s','%s',%ld,%ld,'%s',%ld,'%s','%s','%s')",
- table, timestr, clid, src, dst, dcontext, channel, dstchannel, lastapp, lastdata,
- cdr->duration,cdr->billsec,ast_cdr_disp2str(cdr->disposition),cdr->amaflags, cdr->accountcode, uniqueid, userfield);
-
- ast_debug(3, "cdr_pgsql: SQL command executed: %s\n",sqlcmd);
-
/* Test to be sure we're still connected... */
/* If we're connected, and connection is working, good. */
/* Otherwise, attempt reconnect. If it fails... sorry... */
@@ -152,7 +277,7 @@
return -1;
}
}
- result = PQexec(conn, sqlcmd);
+ result = PQexec(conn, sql);
if (PQresultStatus(result) != PGRES_COMMAND_OK) {
pgerror = PQresultErrorMessage(result);
ast_log(LOG_ERROR,"cdr_pgsql: Failed to insert call detail record into database!\n");
@@ -163,7 +288,7 @@
ast_log(LOG_ERROR, "cdr_pgsql: Connection reestablished.\n");
connected = 1;
PQclear(result);
- result = PQexec(conn, sqlcmd);
+ result = PQexec(conn, sql);
if (PQresultStatus(result) != PGRES_COMMAND_OK) {
pgerror = PQresultErrorMessage(result);
ast_log(LOG_ERROR,"cdr_pgsql: HARD ERROR! Attempted reconnection failed. DROPPING CALL RECORD!\n");
@@ -181,8 +306,14 @@
}
static int unload_module(void)
-{
+{
+ struct columns *cur;
+ ast_cdr_unregister(name);
+
+ /* Give all threads time to finish */
+ usleep(1);
PQfinish(conn);
+
if (pghostname)
ast_free(pghostname);
if (pgdbname)
@@ -195,7 +326,13 @@
ast_free(pgdbport);
if (table)
ast_free(table);
- ast_cdr_unregister(name);
+
+ AST_RWLIST_WRLOCK(&psql_columns);
+ while ((cur = AST_RWLIST_REMOVE_HEAD(&psql_columns, list))) {
+ ast_free(cur);
+ }
+ AST_RWLIST_UNLOCK(&psql_columns);
+
return 0;
}
@@ -203,6 +340,8 @@
{
struct ast_variable *var;
char *pgerror;
+ struct columns *cur;
+ PGresult *result;
const char *tmp;
struct ast_config *cfg;
struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
@@ -304,8 +443,40 @@
conn = PQsetdbLogin(pghostname, pgdbport, NULL, NULL, pgdbname, pgdbuser, pgpassword);
if (PQstatus(conn) != CONNECTION_BAD) {
+ char sqlcmd[256];
+ char *fname, *ftype, *flen;
+ int i, rows;
ast_debug(1, "Successfully connected to PostgreSQL database.\n");
connected = 1;
+
+ /* Query the columns */
+ snprintf(sqlcmd, sizeof(sqlcmd), "select a.attname, t.typname, a.attlen from pg_class c, pg_attribute a, pg_type t where c.oid = a.attrelid and a.atttypid = t.oid and (a.attnum > 0) and c.relname = '%s' order by c.relname, attnum", table);
+ result = PQexec(conn, sqlcmd);
+ if (PQresultStatus(result) != PGRES_TUPLES_OK) {
+ pgerror = PQresultErrorMessage(result);
+ ast_log(LOG_ERROR, "cdr_pgsql: Failed to query database columns: %s\n", pgerror);
+ PQclear(result);
+ unload_module();
+ return AST_MODULE_LOAD_DECLINE;
+ }
+
+ rows = PQntuples(result);
+ for (i = 0; i < rows; i++) {
+ fname = PQgetvalue(result, i, 0);
+ ftype = PQgetvalue(result, i, 1);
+ flen = PQgetvalue(result, i, 2);
+ ast_verb(4, "Found column '%s' of type '%s'\n", fname, ftype);
+ cur = ast_calloc(1, sizeof(*cur) + strlen(fname) + strlen(ftype) + 2);
+ if (cur) {
+ sscanf(flen, "%d", &cur->len);
+ cur->name = (char *)cur + sizeof(*cur);
+ cur->type = (char *)cur + sizeof(*cur) + strlen(fname) + 1;
+ strcpy(cur->name, fname);
+ strcpy(cur->type, ftype);
+ AST_RWLIST_INSERT_TAIL(&psql_columns, cur, list);
+ }
+ }
+ PQclear(result);
} else {
pgerror = PQerrorMessage(conn);
ast_log(LOG_ERROR, "cdr_pgsql: Unable to connect to database server %s. CALLS WILL NOT BE LOGGED!!\n", pghostname);
Modified: team/russell/chan_refcount/channels/chan_agent.c
URL: http://svn.digium.com/view/asterisk/team/russell/chan_refcount/channels/chan_agent.c?view=diff&rev=104109&r1=104108&r2=104109
==============================================================================
--- team/russell/chan_refcount/channels/chan_agent.c (original)
+++ team/russell/chan_refcount/channels/chan_agent.c Mon Feb 25 17:49:57 2008
@@ -1518,10 +1518,29 @@
ret = 0;
if (p->owner || p->chan) {
if (!soft) {
- if (p->owner)
+ ast_mutex_lock(&p->lock);
+
+ while (p->owner && ast_channel_trylock(p->owner)) {
+ ast_mutex_unlock(&p->lock);
+ usleep(1);
+ ast_mutex_lock(&p->lock);
+ }
+ if (p->owner) {
ast_softhangup(p->owner, AST_SOFTHANGUP_EXPLICIT);
- if (p->chan)
+ ast_channel_unlock(p->owner);
+ }
+
+ while (p->chan && ast_channel_trylock(p->chan)) {
+ ast_mutex_unlock(&p->lock);
+ usleep(1);
+ ast_mutex_lock(&p->lock);
+ }
+ if (p->chan) {
ast_softhangup(p->chan, AST_SOFTHANGUP_EXPLICIT);
+ ast_channel_unlock(p->chan);
+ }
+
+ ast_mutex_unlock(&p->lock);
} else
p->deferlogoff = 1;
} else {
Modified: team/russell/chan_refcount/channels/chan_iax2.c
URL: http://svn.digium.com/view/asterisk/team/russell/chan_refcount/channels/chan_iax2.c?view=diff&rev=104109&r1=104108&r2=104109
==============================================================================
--- team/russell/chan_refcount/channels/chan_iax2.c (original)
+++ team/russell/chan_refcount/channels/chan_iax2.c Mon Feb 25 17:49:57 2008
@@ -7320,7 +7320,7 @@
localooo = jbinfo.frames_ooo;
localpackets = jbinfo.frames_in;
}
- ast_verb(3, "JB STATS:%s ping=%d ljitterms=%d ljbdelayms=%d ltotlost=%d lrecentlosspct=%d ldropped=%d looo=%d lrecvd=%d rjitterms=%d rjbdelayms=%d rtotlost=%d rrecentlosspct=%d rdropped=%d rooo=%d rrecvd=%d\n",
+ ast_debug(3, "JB STATS:%s ping=%d ljitterms=%d ljbdelayms=%d ltotlost=%d lrecentlosspct=%d ldropped=%d looo=%d lrecvd=%d rjitterms=%d rjbdelayms=%d rtotlost=%d rrecentlosspct=%d rdropped=%d rooo=%d rrecvd=%d\n",
iaxs[callno]->owner->name,
iaxs[callno]->pingtime,
localjitter,
Modified: team/russell/chan_refcount/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/russell/chan_refcount/channels/chan_sip.c?view=diff&rev=104109&r1=104108&r2=104109
==============================================================================
--- team/russell/chan_refcount/channels/chan_sip.c (original)
+++ team/russell/chan_refcount/channels/chan_sip.c Mon Feb 25 17:49:57 2008
@@ -729,7 +729,7 @@
* should be used to modify these values. */
static int suserobjs = 0; /*!< Static users */
static int ruserobjs = 0; /*!< Realtime users */
-static int speerobjs = 0; /*!< Statis peers */
+static int speerobjs = 0; /*!< Static peers */
static int rpeerobjs = 0; /*!< Realtime peers */
static int apeerobjs = 0; /*!< Autocreated peer objects */
static int regobjs = 0; /*!< Registry objects */
@@ -1880,7 +1880,7 @@
/*--- Device object handling */
static struct sip_peer *temp_peer(const char *name);
static struct sip_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime);
-static struct sip_user *build_user(const char *name, struct ast_variable *v, int realtime);
+static struct sip_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime);
static int update_call_counter(struct sip_pvt *fup, int event);
static void sip_destroy_peer(struct sip_peer *peer);
static void sip_destroy_user(struct sip_user *user);
@@ -3004,7 +3004,7 @@
break;
}
}
- ast_debug(1, "(Provisional) Stopping retransmission (but retaining packet) on '%s' %s %d: %s\n", p->callid, resp ? "Response" : "Request", seqno, res ? "Not Found" : "Found");
+ ast_debug(1, "(Provisional) Stopping retransmission (but retaining packet) on '%s' %s %d: %s\n", p->callid, resp ? "Response" : "Request", seqno, res == -1 ? "Not Found" : "Found");
return res;
}
@@ -3465,7 +3465,7 @@
apeerobjs--;
else if (peer->is_realtime) {
rpeerobjs--;
- ast_debug(3,"-REALTIME- peer Destroyed. Name: %s. Realtime Peer objects: %d\n", peer->name, rpeerobjs);
+ ast_debug(3, "-REALTIME- peer Destroyed. Name: %s. Realtime Peer objects: %d\n", peer->name, rpeerobjs);
} else
speerobjs--;
clear_realm_authentication(peer->auth);
@@ -3675,15 +3675,15 @@
return NULL;
}
- ast_debug(3,"-REALTIME- loading peer from database to memory. Name: %s. Peer objects: %d\n", peer->name, rpeerobjs);
+ ast_debug(3, "-REALTIME- loading peer from database to memory. Name: %s. Peer objects: %d\n", peer->name, rpeerobjs);
if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
/* Cache peer */
- ast_copy_flags(&peer->flags[1],&global_flags[1], SIP_PAGE2_RTAUTOCLEAR|SIP_PAGE2_RTCACHEFRIENDS);
+ ast_copy_flags(&peer->flags[1], &global_flags[1], SIP_PAGE2_RTAUTOCLEAR|SIP_PAGE2_RTCACHEFRIENDS);
if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTAUTOCLEAR)) {
AST_SCHED_REPLACE(peer->expire, sched, global_rtautoclear * 1000, expire_register, (void *) peer);
}
- ASTOBJ_CONTAINER_LINK(&peerl,peer);
+ ASTOBJ_CONTAINER_LINK(&peerl, peer);
} else {
peer->is_realtime = 1;
}
@@ -3767,7 +3767,7 @@
}
}
- user = build_user(username, var, !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS));
+ user = build_user(username, var, NULL, !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS));
if (!user) { /* No user found */
ast_variables_destroy(var);
@@ -3777,7 +3777,7 @@
if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
ast_set_flag(&user->flags[1], SIP_PAGE2_RTCACHEFRIENDS);
suserobjs++;
- ASTOBJ_CONTAINER_LINK(&userl,user);
+ ASTOBJ_CONTAINER_LINK(&userl, user);
} else {
/* Move counter from s to r... */
suserobjs--;
@@ -4107,7 +4107,7 @@
/* Check whether there is vxml_url, distinctive ring variables */
headp=&ast->varshead;
- AST_LIST_TRAVERSE(headp,current,entries) {
+ AST_LIST_TRAVERSE(headp, current, entries) {
/* Check whether there is a VXML_URL variable */
if (!p->options->vxml_url && !strcasecmp(ast_var_name(current), "VXML_URL")) {
p->options->vxml_url = ast_var_value(current);
@@ -4127,7 +4127,7 @@
p->options->replaces = ast_var_value(current);
} else if (!strcasecmp(ast_var_name(current), "T38CALL")) {
p->t38.state = T38_LOCAL_DIRECT;
- ast_debug(1,"T38State change to %d on channel %s\n", p->t38.state, ast->name);
+ ast_debug(1, "T38State change to %d on channel %s\n", p->t38.state, ast->name);
}
}
@@ -4165,7 +4165,7 @@
int xmitres;
p->t38.jointcapability = p->t38.capability;
- ast_debug(2,"Our T38 capability (%d), joint T38 capability (%d)\n", p->t38.capability, p->t38.jointcapability);
+ ast_debug(2, "Our T38 capability (%d), joint T38 capability (%d)\n", p->t38.capability, p->t38.jointcapability);
xmitres = transmit_invite(p, SIP_INVITE, 1, 2);
if (xmitres == XMIT_ERROR)
@@ -5163,7 +5163,7 @@
if (title)
my_name = title;
- else if ( (my_name = strchr(i->fromdomain,':')) )
+ else if ( (my_name = strchr(i->fromdomain, ':')) )
my_name++; /* skip ':' */
else
my_name = i->fromdomain;
@@ -5558,7 +5558,7 @@
if (faxdetected && ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_UDPTL) && (p->t38.state == T38_DISABLED) && !(ast_bridged_channel(ast))) {
if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) {
if (!p->pendinginvite) {
- ast_debug(3, "Sending reinvite on SIP (%s) for T.38 negotiation.\n",ast->name);
+ ast_debug(3, "Sending reinvite on SIP (%s) for T.38 negotiation.\n", ast->name);
change_t38_state(p, T38_LOCAL_REINVITE);
transmit_reinvite_with_sdp(p, TRUE, FALSE);
}
@@ -5831,7 +5831,7 @@
found = (!strcmp(p->callid, callid));
else
found = (!strcmp(p->callid, callid) &&
- (!pedanticsipchecking || !tag || ast_strlen_zero(p->theirtag) || !strcmp(p->theirtag, tag))) ;
+ (!pedanticsipchecking || ast_strlen_zero(tag) || ast_strlen_zero(p->theirtag) || !strcmp(p->theirtag, tag))) ;
ast_debug(5, "= %s Their Call ID: %s Their Tag %s Our tag: %s\n", found ? "Found" : "No match", p->callid, p->theirtag, p->tag);
@@ -6475,7 +6475,7 @@
sin.sin_port = htons(udptlportno);
ast_udptl_set_peer(p->udptl, &sin);
if (debug)
- ast_debug(1,"Peer T.38 UDPTL is at port %s:%d\n",ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
+ ast_debug(1, "Peer T.38 UDPTL is at port %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
} else {
ast_udptl_stop(p->udptl);
if (debug)
@@ -6608,7 +6608,7 @@
if (debug)
ast_verbose("Found unknown media description format %s for ID %d\n", mimeSubtype, codec);
}
- } else if (!strncasecmp(mimeSubtype, "T140",4)) { /* Text */
+ } else if (!strncasecmp(mimeSubtype, "T140", 4)) { /* Text */
if (p->trtp) {
/* ast_verbose("Adding t140 mimeSubtype to textrtp struct\n"); */
ast_rtp_set_rtpmap_type(newtextrtp, codec, "text", mimeSubtype, 0);
@@ -6640,10 +6640,10 @@
while ((a = get_sdp_iterate(&iterator, req, "a"))[0] != '\0') {
if ((sscanf(a, "T38FaxMaxBuffer:%d", &x) == 1)) {
found = 1;
- ast_debug(3, "MaxBufferSize:%d\n",x);
+ ast_debug(3, "MaxBufferSize:%d\n", x);
} else if ((sscanf(a, "T38MaxBitRate:%d", &x) == 1)) {
found = 1;
- ast_debug(3,"T38MaxBitRate: %d\n",x);
+ ast_debug(3, "T38MaxBitRate: %d\n", x);
switch (x) {
case 14400:
peert38capability |= T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400;
@@ -6666,30 +6666,30 @@
}
} else if ((sscanf(a, "T38FaxVersion:%d", &x) == 1)) {
found = 1;
- ast_debug(3, "FaxVersion: %d\n",x);
+ ast_debug(3, "FaxVersion: %d\n", x);
if (x == 0)
peert38capability |= T38FAX_VERSION_0;
else if (x == 1)
peert38capability |= T38FAX_VERSION_1;
} else if ((sscanf(a, "T38FaxMaxDatagram:%d", &x) == 1)) {
found = 1;
- ast_debug(3, "FaxMaxDatagram: %d\n",x);
+ ast_debug(3, "FaxMaxDatagram: %d\n", x);
ast_udptl_set_far_max_datagram(p->udptl, x);
ast_udptl_set_local_max_datagram(p->udptl, x);
} else if ((sscanf(a, "T38FaxFillBitRemoval:%d", &x) == 1)) {
found = 1;
- ast_debug(3, "FillBitRemoval: %d\n",x);
+ ast_debug(3, "FillBitRemoval: %d\n", x);
if (x == 1)
peert38capability |= T38FAX_FILL_BIT_REMOVAL;
} else if ((sscanf(a, "T38FaxTranscodingMMR:%d", &x) == 1)) {
found = 1;
- ast_debug(3, "Transcoding MMR: %d\n",x);
+ ast_debug(3, "Transcoding MMR: %d\n", x);
if (x == 1)
peert38capability |= T38FAX_TRANSCODING_MMR;
}
if ((sscanf(a, "T38FaxTranscodingJBIG:%d", &x) == 1)) {
found = 1;
- ast_debug(3, "Transcoding JBIG: %d\n",x);
+ ast_debug(3, "Transcoding JBIG: %d\n", x);
if (x == 1)
peert38capability |= T38FAX_TRANSCODING_JBIG;
} else if ((sscanf(a, "T38FaxRateManagement:%255s", s) == 1)) {
@@ -7269,7 +7269,7 @@
}
/* Check for strict or loose router */
- if (p->route && !ast_strlen_zero(p->route->hop) && strstr(p->route->hop,";lr") == NULL) {
+ if (p->route && !ast_strlen_zero(p->route->hop) && strstr(p->route->hop, ";lr") == NULL) {
is_strict = TRUE;
if (sipdebug)
ast_debug(1, "Strict routing enforced for session %s\n", p->callid);
@@ -7795,14 +7795,14 @@
if ((p->t38.jointcapability & T38FAX_VERSION) == T38FAX_VERSION_1)
ast_str_append(&a_modem, 0, "a=T38FaxVersion:1\r\n");
if ((x = t38_get_rate(p->t38.jointcapability)))
- ast_str_append(&a_modem, 0, "a=T38MaxBitRate:%d\r\n",x);
+ ast_str_append(&a_modem, 0, "a=T38MaxBitRate:%d\r\n", x);
ast_str_append(&a_modem, 0, "a=T38FaxFillBitRemoval:%d\r\n", (p->t38.jointcapability & T38FAX_FILL_BIT_REMOVAL) ? 1 : 0);
ast_str_append(&a_modem, 0, "a=T38FaxTranscodingMMR:%d\r\n", (p->t38.jointcapability & T38FAX_TRANSCODING_MMR) ? 1 : 0);
ast_str_append(&a_modem, 0, "a=T38FaxTranscodingJBIG:%d\r\n", (p->t38.jointcapability & T38FAX_TRANSCODING_JBIG) ? 1 : 0);
ast_str_append(&a_modem, 0, "a=T38FaxRateManagement:%s\r\n", (p->t38.jointcapability & T38FAX_RATE_MANAGEMENT_LOCAL_TCF) ? "localTCF" : "transferredTCF");
x = ast_udptl_get_local_max_datagram(p->udptl);
- ast_str_append(&a_modem, 0, "a=T38FaxMaxBuffer:%d\r\n",x);
- ast_str_append(&a_modem, 0, "a=T38FaxMaxDatagram:%d\r\n",x);
+ ast_str_append(&a_modem, 0, "a=T38FaxMaxBuffer:%d\r\n", x);
+ ast_str_append(&a_modem, 0, "a=T38FaxMaxDatagram:%d\r\n", x);
if (p->t38.jointcapability != T38FAX_UDP_EC_NONE)
ast_str_append(&a_modem, 0, "a=T38FaxUdpEC:%s\r\n", (p->t38.jointcapability & T38FAX_UDP_EC_REDUNDANCY) ? "t38UDPRedundancy" : "t38UDPFEC");
len = m_modem->used + a_modem->used;
@@ -8657,7 +8657,7 @@
headp = &chan->varshead;
if (!headp)
- ast_log(LOG_WARNING,"No Headp for the channel...ooops!\n");
+ ast_log(LOG_WARNING, "No Headp for the channel...ooops!\n");
else {
const struct ast_var_t *current;
AST_LIST_TRAVERSE(headp, current, entries) {
@@ -9246,7 +9246,7 @@
ast_string_field_set(p, qop, r->qop);
p->noncecount = ++r->noncecount;
- memset(digest,0,sizeof(digest));
+ memset(digest, 0, sizeof(digest));
if(!build_reply_digest(p, sipmethod, digest, sizeof(digest)))
add_header(&req, "Authorization", digest);
else
@@ -9485,7 +9485,7 @@
Only for realtime peers and autocreated peers
*/
if (peer->is_realtime)
- ast_debug(3,"-REALTIME- peer expired registration. Name: %s. Realtime peer objects now %d\n", peer->name, rpeerobjs);
+ ast_debug(3, "-REALTIME- peer expired registration. Name: %s. Realtime peer objects now %d\n", peer->name, rpeerobjs);
if (peer->selfdestruct ||
ast_test_flag(&peer->flags[1], SIP_PAGE2_RTAUTOCLEAR)) {
@@ -9860,7 +9860,7 @@
}
/* Only append the contact if we are dealing with a strict router */
- if (!head || (!ast_strlen_zero(head->hop) && strstr(head->hop,";lr") == NULL) ) {
+ if (!head || (!ast_strlen_zero(head->hop) && strstr(head->hop, ";lr") == NULL) ) {
/* 2nd append the Contact: if there is one */
/* Can be multiple Contact headers, comma separated values - we just take the first */
contact = get_header(req, "Contact");
@@ -10750,9 +10750,9 @@
}
if (!pedanticsipchecking)
- ast_debug(2,"Attended transfer: Will use Replace-Call-ID : %s (No check of from/to tags)\n", referdata->replaces_callid );
+ ast_debug(2, "Attended transfer: Will use Replace-Call-ID : %s (No check of from/to tags)\n", referdata->replaces_callid );
else
- ast_debug(2,"Attended transfer: Will use Replace-Call-ID : %s F-tag: %s T-tag: %s\n", referdata->replaces_callid, referdata->replaces_callid_fromtag ? referdata->replaces_callid_fromtag : "<none>", referdata->replaces_callid_totag ? referdata->replaces_callid_totag : "<none>" );
+ ast_debug(2, "Attended transfer: Will use Replace-Call-ID : %s F-tag: %s T-tag: %s\n", referdata->replaces_callid, referdata->replaces_callid_fromtag ? referdata->replaces_callid_fromtag : "<none>", referdata->replaces_callid_totag ? referdata->replaces_callid_totag : "<none>" );
}
}
@@ -10862,7 +10862,7 @@
}
if (ast_exists_extension(NULL, transfer_context, c, 1, NULL)) {
/* This is a blind transfer */
- ast_debug(1,"SIP Bye-also transfer to Extension %s@%s \n", c, transfer_context);
+ ast_debug(1, "SIP Bye-also transfer to Extension %s@%s \n", c, transfer_context);
ast_copy_string(referdata->refer_to, c, sizeof(referdata->refer_to));
ast_copy_string(referdata->referred_by, "", sizeof(referdata->referred_by));
ast_copy_string(referdata->refer_contact, "", sizeof(referdata->refer_contact));
@@ -10971,8 +10971,8 @@
/*! \brief Get caller id name from SIP headers */
static char *get_calleridname(const char *input, char *output, size_t outputsize)
{
- const char *end = strchr(input,'<'); /* first_bracket */
- const char *tmp = strchr(input,'"'); /* first quote */
+ const char *end = strchr(input, '<'); /* first_bracket */
+ const char *tmp = strchr(input, '"'); /* first quote */
int bytes = 0;
int maxbytes = outputsize - 1;
@@ -11021,7 +11021,7 @@
char *start;
char *end;
- start = strchr(input,':');
+ start = strchr(input, ':');
if (!start) {
output[0] = '\0';
return 0;
@@ -11029,15 +11029,15 @@
start++;
/* we found "number" */
- ast_copy_string(output,start,maxlen);
+ ast_copy_string(output, start, maxlen);
output[maxlen-1] = '\0';
- end = strchr(output,'@');
+ end = strchr(output, '@');
if (end)
*end = '\0';
else
output[0] = '\0';
- if (strstr(input,"privacy=full") || strstr(input,"privacy=uri"))
+ if (strstr(input, "privacy=full") || strstr(input, "privacy=uri"))
return AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED;
return 0;
@@ -11514,7 +11514,7 @@
ast_queue_frame(p->owner, &f);
transmit_response(p, "202 Accepted", req); /* We respond 202 accepted, since we relay the message */
} else { /* Message outside of a call, we do not support that */
- ast_log(LOG_WARNING,"Received message to %s from %s, dropped it...\n Content-Type:%s\n Message: %s\n", get_header(req,"To"), get_header(req,"From"), content_type, buf);
+ ast_log(LOG_WARNING, "Received message to %s from %s, dropped it...\n Content-Type:%s\n Message: %s\n", get_header(req, "To"), get_header(req, "From"), content_type, buf);
transmit_response(p, "405 Method Not Allowed", req); /* Good enough, or? */
sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
}
@@ -11545,7 +11545,7 @@
if (a->argc < 3)
return CLI_SHOWUSAGE;
- if (a->argc == 4 && !strcmp(a->argv[3],"all"))
+ if (a->argc == 4 && !strcmp(a->argv[3], "all"))
showall = TRUE;
ast_cli(a->fd, FORMAT, "* User name", "In use", "Limit");
[... 1223 lines stripped ...]
More information about the asterisk-commits
mailing list