core: core pvars added for $?/$retcode/$rc
authorAndrei Pelinescu-Onciul <andrei@iptel.org>
Wed, 7 Oct 2009 21:57:45 +0000 (23:57 +0200)
committerAndrei Pelinescu-Onciul <andrei@iptel.org>
Wed, 7 Oct 2009 22:18:12 +0000 (00:18 +0200)
- added core pvars (registered before script parsing) for the
  return code ($?, $retcode, $rc). This solves script conflicts
  between the different return code handling (kamailio - pvars and
   ser built-in expr. elem).
- removed ser expr. elem for retcode (not needed anymore)
- added '?' as a valid pvar char (needed so that $? will be
  accepted)

cfg.lex
cfg.y
main.c
pv_core.c [new file with mode: 0644]
pv_core.h [new file with mode: 0644]
pvapi.c

diff --git a/cfg.lex b/cfg.lex
index 8490364..105df4b 100644 (file)
--- a/cfg.lex
+++ b/cfg.lex
@@ -78,7 +78,8 @@
  *  2008-11-28  added support for kamailio pvars and avp/pvar guessing (andrei)
  *  2008-12-11  added support for "string1" "string2" (andrei)
  *  2009-03-10  added SET_USERPHONE action (Miklos)
- *  2009-04-24  addd strlen, strempty and defined operators (andrei)
+ *  2009-04-24  add strlen, strempty and defined operators (andrei)
+ *  2009-03-07  RETCODE, it's now  a core pvar (andrei)
 */
 
 
@@ -256,7 +257,7 @@ PROTO       proto
 AF             af
 MYSELF myself
 MSGLEN                 "msg:len"
-RETCODE        \$\?|\$retcode
+RETCODE        \$\?|\$retcode|\$rc
 /* operators */
 EQUAL  =
 EQUAL_T        ==
@@ -535,7 +536,6 @@ EAT_ABLE    [\ \t\b\r]
 <INITIAL>{ISAVPFLAGSET}        { count(); yylval.strval=yytext; return ISAVPFLAGSET; }
 <INITIAL>{AVPFLAGS_DECL}       { count(); yylval.strval=yytext; return AVPFLAGS_DECL; }
 <INITIAL>{MSGLEN}      { count(); yylval.strval=yytext; return MSGLEN; }
-<INITIAL>{RETCODE}     { count(); yylval.strval=yytext; return RETCODE; }
 <INITIAL>{ROUTE}       { count(); yylval.strval=yytext; return ROUTE; }
 <INITIAL>{ROUTE_ONREPLY}       { count(); yylval.strval=yytext;
                                                                return ROUTE_ONREPLY; }
@@ -969,6 +969,8 @@ EAT_ABLE    [\ \t\b\r]
                                                                return PVAR;
                                                        }
 
+       /* if found retcode => it's a built-in pvar */
+<INITIAL>{RETCODE}                     { count(); yylval.strval=yytext; return PVAR; }
 
 <INITIAL>{VAR_MARK}                    {
                                                                switch(sr_cfg_compat){
diff --git a/cfg.y b/cfg.y
index b0cb2a5..585edf5 100644 (file)
--- a/cfg.y
+++ b/cfg.y
@@ -354,7 +354,6 @@ extern char *finame;
 %token AF
 %token MYSELF
 %token MSGLEN
-%token RETCODE
 %token UDP
 %token TCP
 %token TLS
@@ -1824,7 +1823,6 @@ eint_op:  SRCPORT         { $$=SRCPORT_O; }
                |       DSTPORT         { $$=DSTPORT_O; }
                |       AF                      { $$=AF_O; }
                |       MSGLEN          { $$=MSGLEN_O; }
-               |       RETCODE         { $$=RETCODE_O; }
                | eint_op_onsend
        ;
 
@@ -2418,7 +2416,7 @@ pvar:     PVAR {
                        memset(pv_spec, 0, sizeof(*pv_spec));
                        s_tmp.s=$1; s_tmp.len=strlen($1);
                        if (pv_parse_spec(&s_tmp, pv_spec)==0){
-                               yyerror("unknown script pseudo variable");
+                               yyerror("unknown script pseudo variable %s", $1 );
                                pkg_free(pv_spec);
                                pv_spec=0;
                                YYABORT;
diff --git a/main.c b/main.c
index fb9ba93..c1f9d07 100644 (file)
--- a/main.c
+++ b/main.c
 #include "cfg_core.h"
 #include "endianness.h" /* init */
 #include "basex.h" /* init */
+#include "pv_core.h" /* register core pvars */
 
 #ifdef DEBUG_DMALLOC
 #include <dmalloc.h>
@@ -1760,6 +1761,7 @@ int main(int argc, char** argv)
        if (init_script_cb()<0) goto error;
        if (init_rpcs()<0) goto error;
        if (register_core_rpcs()!=0) goto error;
+       if (pv_register_core_vars()!=0) goto error;
 
        /* Fix the value of cfg_file variable.*/
        if (fix_cfg_file() < 0) goto error;
diff --git a/pv_core.c b/pv_core.c
new file mode 100644 (file)
index 0000000..43ae4d9
--- /dev/null
+++ b/pv_core.c
@@ -0,0 +1,63 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2009 iptelorg GmbH
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+/*
+ * pv_core.c - pvars needed in the core, e.g. $?, $retcode
+ *
+ * Note: in general please avoid adding pvars directly to the core, unless
+ * absolutely necessary (use/create a new module instead).
+ */
+
+#include "pv_core.h"
+#include "pvar.h"
+#include "str.h"
+
+static int pv_get_retcode(struct sip_msg*, pv_param_t*, pv_value_t*);
+
+static pv_export_t core_pvs[] = {
+       /* return code, various synonims */
+       { STR_STATIC_INIT("?"), PVT_OTHER, pv_get_retcode, 0, 0, 0, 0, 0 },
+       { STR_STATIC_INIT("rc"), PVT_OTHER, pv_get_retcode, 0, 0, 0, 0, 0 },
+       { STR_STATIC_INIT("retcode"), PVT_OTHER, pv_get_retcode, 0, 0, 0, 0, 0 },
+       
+       { {0, 0}, 0, 0, 0, 0, 0, 0, 0 }
+};
+
+
+/* ugly hack to get the return code, needed because the PVs do not know (yet)
+   about the script context */
+extern int _last_returned_code;
+
+static int pv_get_retcode(struct sip_msg* msg, pv_param_t* p, pv_value_t* res)
+{
+       /* FIXME: as soon as PVs support script context, use it instead of the
+                 return in global variable hack */
+       return pv_get_sintval(msg, p, res, _last_returned_code);
+}
+
+
+
+/** register built-in core pvars.
+ * should be called before parsing the config script.
+ * @return 0 on success 
+ */
+int pv_register_core_vars(void)
+{
+       return register_pvars_mod("core", core_pvs);
+}
+
+/* vi: set ts=4 sw=4 tw=79:ai:cindent: */
diff --git a/pv_core.h b/pv_core.h
new file mode 100644 (file)
index 0000000..e98480b
--- /dev/null
+++ b/pv_core.h
@@ -0,0 +1,30 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2009 iptelorg GmbH
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+/*
+ * pv_core.h
+ */
+
+#ifndef __pv_core_h
+#define __pv_core_h
+
+/* register core pvars */
+int pv_register_core_vars(void);
+
+#endif /*__pv_core_h*/
+
+/* vi: set ts=4 sw=4 tw=79:ai:cindent: */
diff --git a/pvapi.c b/pvapi.c
index dbae078..34ef819 100644 (file)
--- a/pvapi.c
+++ b/pvapi.c
@@ -73,7 +73,7 @@ void pv_init_table(void)
 static int is_pv_valid_char(char c)
 {
        if((c>='0' && c<='9') || (c>='a' && c<='z') || (c>='A' && c<='Z')
-                       || (c=='_') || (c=='.'))
+                       || (c=='_') || (c=='.') || (c=='?') /* ser $? */)
                return 1;
        return 0;
 }