~ubuntu-branches/ubuntu/karmic/asterisk/karmic

« back to all changes in this revision

Viewing changes to main/pbx.c

  • Committer: Bazaar Package Importer
  • Author(s): Faidon Liambotis, Tzafrir Cohen, Faidon Liambotis
  • Date: 2007-12-06 17:20:21 UTC
  • mfrom: (1.1.19 upstream)
  • Revision ID: james.westby@ubuntu.com-20071206172021-pd0wrjirz3os7hia
Tags: 1:1.4.15~dfsg-1
* New upstream release (Closes: #452054)
  - Fix a potential corrupt of voicemail.conf on simultaneous PIN updates
    (Closes: #353227)

[ Tzafrir Cohen ]
* Add some sample/reference config files as documentation.
* Provide asterisk-bristuff for upgrading from Etch.
* Move libc-client to not be last, so debian/backports/xorcom.etch would
  still work.

[ Faidon Liambotis ]
* Really enable the libcap/ToS functionality; the previous patch didn't
  enable the functionality, even though the code and the libcap.so
  dependency were there. (Closes: #454342)
* Fix a minor issue with init script's stop target when running with
  safe_asterisk.
* Add chan_vpb, adding support for VoiceTronix OpenSwitch and OpenLine
  cards. (Closes: #396499)
* Fix debian/watch by using a pkg-voip wrapper to avoid upstream's silly
  redirections. (Closes: #449706)
* Use DEBVERSION as asterisk's version string.
* Disable the MD5 build sum that breaks all out-of-tree plugins (duh!).
* Create /usr/local/share/asterisk/sounds to put all site-specific
  non-modifiable sounds.
* Add a note about bugs.debian.org to the banner.
* Add noload for res_config_* since loading them results in errors and
  doesn't provide any functionality.
* News entries were added but we never shipped the file; ship NEWS.Debian.
* Add an entry to NEWS.Debian warning users about app_voicemail_*.so
  (Closes: #452596)
* Provide options in /etc/default/asterisk for configuring safe_asterisk.
  (Closes: #381786)

[ Tzafrir Cohen ]
* Provide a custom sounds directory under /var/lib - user-modifieble at
  runtime and hence not under /usr. (Closes: #337209)

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
 
26
26
#include "asterisk.h"
27
27
 
28
 
ASTERISK_FILE_VERSION(__FILE__, "$Revision: 82514 $")
 
28
ASTERISK_FILE_VERSION(__FILE__, "$Revision: 90059 $")
29
29
 
30
30
#include <sys/types.h>
31
31
#include <string.h>
1135
1135
        struct varshead *places[2] = { headp, &globals };       /* list of places where we may look */
1136
1136
 
1137
1137
        if (c) {
 
1138
                ast_channel_lock(c);
1138
1139
                places[0] = &c->varshead;
1139
1140
        }
1140
1141
        /*
1232
1233
                if (need_substring)
1233
1234
                        *ret = substring(*ret, offset, length, workspace, workspacelen);
1234
1235
        }
 
1236
 
 
1237
        if (c)
 
1238
                ast_channel_unlock(c);
1235
1239
}
1236
1240
 
1237
1241
/*! \brief CLI function to show installed custom functions
1573
1577
                                nextexp = nextthing;
1574
1578
                                pos = nextexp - whereweare;
1575
1579
                                break;
 
1580
                        default:
 
1581
                                pos = 1;
1576
1582
                        }
1577
1583
                }
1578
1584
 
1731
1737
                                count -= length;
1732
1738
                                cp2 += length;
1733
1739
                        }
1734
 
                } else
1735
 
                        break;
 
1740
                }
1736
1741
        }
1737
1742
}
1738
1743
 
1759
1764
        pbx_substitute_variables_helper(c, e->data, passdata, datalen - 1);
1760
1765
}
1761
1766
 
1762
 
/*! \brief The return value depends on the action:
 
1767
/*! 
 
1768
 * \brief The return value depends on the action:
1763
1769
 *
1764
1770
 * E_MATCH, E_CANMATCH, E_MATCHMORE require a real match,
1765
1771
 *      and return 0 on failure, -1 on match;
1767
1773
 *      the priority on success, ... XXX
1768
1774
 * E_SPAWN, spawn an application,
1769
1775
 *      and return 0 on success, -1 on failure.
 
1776
 *
 
1777
 * \note The channel is auto-serviced in this function, because doing an extension
 
1778
 * match may block for a long time.  For example, if the lookup has to use a network
 
1779
 * dialplan switch, such as DUNDi or IAX2, it may take a while.  However, the channel
 
1780
 * auto-service code will queue up any important signalling frames to be processed
 
1781
 * after this is done.
1770
1782
 */
1771
1783
static int pbx_extension_helper(struct ast_channel *c, struct ast_context *con,
1772
1784
        const char *context, const char *exten, int priority,
1780
1792
 
1781
1793
        int matching_action = (action == E_MATCH || action == E_CANMATCH || action == E_MATCHMORE);
1782
1794
 
 
1795
        if (c)
 
1796
                ast_autoservice_start(c);
 
1797
 
1783
1798
        ast_mutex_lock(&conlock);
1784
1799
        e = pbx_find_extension(c, con, &q, context, exten, priority, label, callerid, action);
1785
1800
        if (e) {
1786
1801
                if (matching_action) {
1787
1802
                        ast_mutex_unlock(&conlock);
 
1803
                        if (c)
 
1804
                                ast_autoservice_stop(c);
1788
1805
                        return -1;      /* success, we found it */
1789
1806
                } else if (action == E_FINDLABEL) { /* map the label to a priority */
1790
1807
                        res = e->priority;
1791
1808
                        ast_mutex_unlock(&conlock);
 
1809
                        if (c)
 
1810
                                ast_autoservice_stop(c);
1792
1811
                        return res;     /* the priority we were looking for */
1793
1812
                } else {        /* spawn */
1794
1813
                        app = pbx_findapp(e->app);
1795
1814
                        ast_mutex_unlock(&conlock);
1796
1815
                        if (!app) {
1797
1816
                                ast_log(LOG_WARNING, "No application '%s' for extension (%s, %s, %d)\n", e->app, context, exten, priority);
 
1817
                                if (c)
 
1818
                                        ast_autoservice_stop(c);
1798
1819
                                return -1;
1799
1820
                        }
1800
1821
                        if (c->context != context)
1804
1825
                        c->priority = priority;
1805
1826
                        pbx_substitute_variables(passdata, sizeof(passdata), c, e);
1806
1827
                        if (option_debug) {
1807
 
                                char atmp[80];
1808
 
                                char atmp2[EXT_DATA_SIZE+100];
1809
1828
                                ast_log(LOG_DEBUG, "Launching '%s'\n", app->name);
1810
 
                                snprintf(atmp, sizeof(atmp), "STACK-%s-%s-%d", context, exten, priority);
1811
 
                                snprintf(atmp2, sizeof(atmp2), "%s(\"%s\", \"%s\") %s",
1812
 
                                        app->name, c->name, passdata, "in new stack");
1813
 
                                pbx_builtin_setvar_helper(c, atmp, atmp2);
1814
1829
                        }
1815
1830
                        if (option_verbose > 2) {
1816
1831
                                char tmp[80], tmp2[80], tmp3[EXT_DATA_SIZE];
1830
1845
                                        "AppData: %s\r\n"
1831
1846
                                        "Uniqueid: %s\r\n",
1832
1847
                                        c->name, c->context, c->exten, c->priority, app->name, passdata, c->uniqueid);
 
1848
                        if (c)
 
1849
                                ast_autoservice_stop(c);
1833
1850
                        return pbx_exec(c, app, passdata);      /* 0 on success, -1 on failure */
1834
1851
                }
1835
1852
        } else if (q.swo) {     /* not found here, but in another switch */
1836
1853
                ast_mutex_unlock(&conlock);
1837
 
                if (matching_action)
 
1854
                if (matching_action) {
 
1855
                        if (c)
 
1856
                                ast_autoservice_stop(c);
1838
1857
                        return -1;
1839
 
                else {
 
1858
                } else {
1840
1859
                        if (!q.swo->exec) {
1841
1860
                                ast_log(LOG_WARNING, "No execution engine for switch %s\n", q.swo->name);
1842
1861
                                res = -1;
1843
1862
                        }
 
1863
                        if (c)
 
1864
                                ast_autoservice_stop(c);
1844
1865
                        return q.swo->exec(c, q.foundcontext ? q.foundcontext : context, exten, priority, callerid, q.data);
1845
1866
                }
1846
1867
        } else {        /* not found anywhere, see what happened */
1867
1888
                                ast_log(LOG_DEBUG, "Shouldn't happen!\n");
1868
1889
                }
1869
1890
 
 
1891
                if (c)
 
1892
                        ast_autoservice_stop(c);
 
1893
 
1870
1894
                return (matching_action) ? 0 : -1;
1871
1895
        }
1872
1896
}
1997
2021
{
1998
2022
        struct ast_hint *hint;
1999
2023
 
 
2024
        ast_mutex_lock(&conlock);
2000
2025
        AST_LIST_LOCK(&hints);
2001
2026
 
2002
2027
        AST_LIST_TRAVERSE(&hints, hint, list) {
2034
2059
        }
2035
2060
 
2036
2061
        AST_LIST_UNLOCK(&hints);
 
2062
        ast_mutex_unlock(&conlock);
2037
2063
}
2038
2064
 
2039
2065
/*! \brief  ast_extension_state_add: Add watcher for extension states */
2291
2317
/* helper function to set extension and priority */
2292
2318
static void set_ext_pri(struct ast_channel *c, const char *exten, int pri)
2293
2319
{
 
2320
        ast_channel_lock(c);
2294
2321
        ast_copy_string(c->exten, exten, sizeof(c->exten));
2295
2322
        c->priority = pri;
 
2323
        ast_channel_unlock(c);
2296
2324
}
2297
2325
 
2298
2326
/*!
3045
3073
"       Describe a particular dialplan function.\n";
3046
3074
 
3047
3075
static char show_dialplan_help[] =
3048
 
"Usage: core show dialplan [exten@][context]\n"
 
3076
"Usage: dialplan show [exten@][context]\n"
3049
3077
"       Show dialplan\n";
3050
3078
 
3051
3079
static char set_global_help[] =
4547
4575
        if (!chan)
4548
4576
                return -1;
4549
4577
 
 
4578
        ast_channel_lock(chan);
 
4579
 
4550
4580
        if (!ast_strlen_zero(context))
4551
4581
                ast_copy_string(chan->context, context, sizeof(chan->context));
4552
4582
        if (!ast_strlen_zero(exten))
4558
4588
                        chan->priority--;
4559
4589
        }
4560
4590
 
 
4591
        ast_channel_unlock(chan);
 
4592
 
4561
4593
        return 0;
4562
4594
}
4563
4595
 
5721
5753
 
5722
5754
        memset(buf, 0, size);
5723
5755
 
 
5756
        ast_channel_lock(chan);
 
5757
 
5724
5758
        AST_LIST_TRAVERSE(&chan->varshead, variables, entries) {
5725
5759
                if ((var=ast_var_name(variables)) && (val=ast_var_value(variables))
5726
5760
                   /* && !ast_strlen_zero(var) && !ast_strlen_zero(val) */
5734
5768
                        break;
5735
5769
        }
5736
5770
 
 
5771
        ast_channel_unlock(chan);
 
5772
 
5737
5773
        return total;
5738
5774
}
5739
5775
 
5746
5782
 
5747
5783
        if (!name)
5748
5784
                return NULL;
5749
 
        if (chan)
 
5785
 
 
5786
        if (chan) {
 
5787
                ast_channel_lock(chan);
5750
5788
                places[0] = &chan->varshead;
 
5789
        }
5751
5790
 
5752
5791
        for (i = 0; i < 2; i++) {
5753
5792
                if (!places[i])
5766
5805
                        break;
5767
5806
        }
5768
5807
 
 
5808
        if (chan)
 
5809
                ast_channel_unlock(chan);
 
5810
 
5769
5811
        return ret;
5770
5812
}
5771
5813
 
5782
5824
                return;
5783
5825
        }
5784
5826
 
5785
 
        headp = (chan) ? &chan->varshead : &globals;
 
5827
        if (chan) {
 
5828
                ast_channel_lock(chan);
 
5829
                headp = &chan->varshead;
 
5830
        } else {
 
5831
                ast_mutex_lock(&globalslock);
 
5832
                headp = &globals;
 
5833
        }
5786
5834
 
5787
5835
        if (value) {
5788
5836
                if ((option_verbose > 1) && (headp == &globals))
5789
5837
                        ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value);
5790
5838
                newvariable = ast_var_assign(name, value);
5791
 
                if (headp == &globals)
5792
 
                        ast_mutex_lock(&globalslock);
5793
5839
                AST_LIST_INSERT_HEAD(headp, newvariable, entries);
5794
 
                if (headp == &globals)
5795
 
                        ast_mutex_unlock(&globalslock);
5796
5840
        }
 
5841
 
 
5842
        if (chan)
 
5843
                ast_channel_unlock(chan);
 
5844
        else
 
5845
                ast_mutex_unlock(&globalslock);
5797
5846
}
5798
5847
 
5799
5848
void pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
5802
5851
        struct varshead *headp;
5803
5852
        const char *nametail = name;
5804
5853
 
5805
 
        /* XXX may need locking on the channel ? */
5806
5854
        if (name[strlen(name)-1] == ')') {
5807
5855
                char *function = ast_strdupa(name);
5808
5856
 
5810
5858
                return;
5811
5859
        }
5812
5860
 
5813
 
        headp = (chan) ? &chan->varshead : &globals;
 
5861
        if (chan) {
 
5862
                ast_channel_lock(chan);
 
5863
                headp = &chan->varshead;
 
5864
        } else {
 
5865
                ast_mutex_lock(&globalslock);
 
5866
                headp = &globals;
 
5867
        }
5814
5868
 
5815
5869
        /* For comparison purposes, we have to strip leading underscores */
5816
5870
        if (*nametail == '_') {
5819
5873
                        nametail++;
5820
5874
        }
5821
5875
 
5822
 
        if (headp == &globals)
5823
 
                ast_mutex_lock(&globalslock);
5824
5876
        AST_LIST_TRAVERSE (headp, newvariable, entries) {
5825
5877
                if (strcasecmp(ast_var_name(newvariable), nametail) == 0) {
5826
5878
                        /* there is already such a variable, delete it */
5837
5889
                AST_LIST_INSERT_HEAD(headp, newvariable, entries);
5838
5890
        }
5839
5891
 
5840
 
        if (headp == &globals)
 
5892
        if (chan)
 
5893
                ast_channel_unlock(chan);
 
5894
        else
5841
5895
                ast_mutex_unlock(&globalslock);
5842
5896
}
5843
5897