r7002: added support for getting at loadparm config parameters via lpGet() in esp...
authorAndrew Tridgell <tridge@samba.org>
Fri, 27 May 2005 03:58:12 +0000 (03:58 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:17:04 +0000 (13:17 -0500)
lpGet takes 4 forms
    v = lpGet("type:parm");             gets a parametric variable
    v = lpGet("share", "type:parm");    gets a parametric variable on a share
    v = lpGet("parm");                  gets a global variable
    v = lpGet("share", "parm");         gets a share variable

in all cases a ejs object of the appropriate type for the variable is returned.

This commit also adds the function typeof() which returns the type of an object
(This used to be commit 5537a0d38d4805cbc2dad0d6f76db15173b1fd60)

source4/include/structs.h
source4/param/loadparm.c
source4/web_server/calls.c [new file with mode: 0644]
source4/web_server/config.mk
source4/web_server/ejs/ejs.c
source4/web_server/ejs/ejs.h
source4/web_server/esp/esp.c
source4/web_server/esp/esp.h
source4/web_server/http.c

index b34dbff663b0c8b23bb76eb67e8c9628a197e875..9a6c534c099bc96bd776c5a20dea67e05cbde0e4 100644 (file)
@@ -212,3 +212,4 @@ struct arcfour_state;
 
 union libnet_SamDump;
 struct websrv_context;
+struct EspRequest;
index 4b55db8aabafd632c6abebcb72842b51c607a93b..ceb73e99581851f83ef243964a53e83c17c8d61f 100644 (file)
@@ -63,6 +63,7 @@
 #include "librpc/gen_ndr/ndr_samr.h"
 #include "librpc/gen_ndr/ndr_nbt.h"
 #include "dlinklist.h"
+#include "web_server/esp/esp.h"
 
 BOOL in_client = False;                /* Not in the client by default */
 static BOOL bLoaded = False;
@@ -105,8 +106,7 @@ static BOOL defaults_saved = False;
 /* the following are used by loadparm for option lists */
 typedef enum
 {
-  P_BOOL,P_BOOLREV,P_CHAR,P_INTEGER,P_OCTAL,P_LIST,
-  P_STRING,P_USTRING,P_ENUM,P_SEP
+  P_BOOL,P_INTEGER,P_LIST,P_STRING,P_USTRING,P_ENUM,P_SEP
 } parm_type;
 
 typedef enum
@@ -1853,20 +1853,14 @@ static void copy_service(service * pserviceDest, service * pserviceSource, BOOL
 
                        switch (parm_table[i].type) {
                                case P_BOOL:
-                               case P_BOOLREV:
                                        *(BOOL *)dest_ptr = *(BOOL *)src_ptr;
                                        break;
 
                                case P_INTEGER:
                                case P_ENUM:
-                               case P_OCTAL:
                                        *(int *)dest_ptr = *(int *)src_ptr;
                                        break;
 
-                               case P_CHAR:
-                                       *(char *)dest_ptr = *(char *)src_ptr;
-                                       break;
-
                                case P_STRING:
                                        string_set(dest_ptr,
                                                   *(char **)src_ptr);
@@ -2374,23 +2368,10 @@ BOOL lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue
                        set_boolean(parm_ptr, pszParmValue);
                        break;
 
-               case P_BOOLREV:
-                       set_boolean(parm_ptr, pszParmValue);
-                       *(BOOL *)parm_ptr = !*(BOOL *)parm_ptr;
-                       break;
-
                case P_INTEGER:
                        *(int *)parm_ptr = atoi(pszParmValue);
                        break;
 
-               case P_CHAR:
-                       *(char *)parm_ptr = *pszParmValue;
-                       break;
-
-               case P_OCTAL:
-                       sscanf(pszParmValue, "%o", (int *)parm_ptr);
-                       break;
-
                case P_LIST:
                        *(const char ***)parm_ptr = str_list_make(talloc_autofree_context(), 
                                                                  pszParmValue, NULL);
@@ -2557,26 +2538,10 @@ static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
                        fprintf(f, "%s", BOOLSTR(*(BOOL *)ptr));
                        break;
 
-               case P_BOOLREV:
-                       fprintf(f, "%s", BOOLSTR(!*(BOOL *)ptr));
-                       break;
-
                case P_INTEGER:
                        fprintf(f, "%d", *(int *)ptr);
                        break;
 
-               case P_CHAR:
-                       fprintf(f, "%c", *(char *)ptr);
-                       break;
-
-               case P_OCTAL:
-                       if (*(int *)ptr == -1) {
-                               fprintf(f, "-1");
-                       } else {
-                               fprintf(f, "0%o", *(int *)ptr);
-                       }
-                       break;
-
                case P_LIST:
                        if ((char ***)ptr && *(char ***)ptr) {
                                char **list = *(char ***)ptr;
@@ -2606,17 +2571,12 @@ static BOOL equal_parameter(parm_type type, void *ptr1, void *ptr2)
 {
        switch (type) {
                case P_BOOL:
-               case P_BOOLREV:
                        return (*((BOOL *)ptr1) == *((BOOL *)ptr2));
 
                case P_INTEGER:
                case P_ENUM:
-               case P_OCTAL:
                        return (*((int *)ptr1) == *((int *)ptr2));
 
-               case P_CHAR:
-                       return (*((char *)ptr1) == *((char *)ptr2));
-               
                case P_LIST:
                        return str_list_equal((const char **)(*(char ***)ptr1), 
                                              (const char **)(*(char ***)ptr2));
@@ -2702,14 +2662,9 @@ static BOOL is_default(int i)
                        return strequal(parm_table[i].def.svalue,
                                        *(char **)parm_table[i].ptr);
                case P_BOOL:
-               case P_BOOLREV:
                        return parm_table[i].def.bvalue ==
                                *(BOOL *)parm_table[i].ptr;
-               case P_CHAR:
-                       return parm_table[i].def.cvalue ==
-                               *(char *)parm_table[i].ptr;
                case P_INTEGER:
-               case P_OCTAL:
                case P_ENUM:
                        return parm_table[i].def.ivalue ==
                                *(int *)parm_table[i].ptr;
@@ -2965,16 +2920,10 @@ static void lp_save_defaults(void)
                                }
                                break;
                        case P_BOOL:
-                       case P_BOOLREV:
                                parm_table[i].def.bvalue =
                                        *(BOOL *)parm_table[i].ptr;
                                break;
-                       case P_CHAR:
-                               parm_table[i].def.cvalue =
-                                       *(char *)parm_table[i].ptr;
-                               break;
                        case P_INTEGER:
-                       case P_OCTAL:
                        case P_ENUM:
                                parm_table[i].def.ivalue =
                                        *(int *)parm_table[i].ptr;
@@ -3355,3 +3304,117 @@ int lp_maxprintjobs(int snum)
 
        return maxjobs;
 }
+
+
+/*
+  allow access to loadparm variables from inside esp scripts in swat
+  
+  can be called in 4 ways:
+
+    v = lpGet("type:parm");             gets a parametric variable
+    v = lpGet("share", "type:parm");    gets a parametric variable on a share
+    v = lpGet("parm");                  gets a global variable
+    v = lpGet("share", "parm");         gets a share variable
+
+  the returned variable is a ejs object. It is an array object for lists.  
+*/
+int esp_lpGet(struct EspRequest *ep, int argc, char **argv)
+{
+       struct parm_struct *parm = NULL;
+       void *parm_ptr = NULL;
+       int i;
+
+       if (argc < 1) return -1;
+
+       if (argc == 2) {
+               /* its a share parameter */
+               int parmnum, snum = lp_servicenumber(argv[0]);
+               if (snum == -1) {
+                       return -1;
+               }
+               if (strchr(argv[1], ':')) {
+                       /* its a parametric option on a share */
+                       const char *type = talloc_strndup(ep, argv[1], strcspn(argv[1], ":"));
+                       const char *option = strchr(argv[1], ':') + 1;
+                       const char *value;
+                       if (type == NULL || option == NULL) return -1;
+                       value = get_parametrics(snum, type, option);
+                       if (value == NULL) return -1;
+                       espSetReturnString(ep, value);
+                       return 0;
+               }
+
+               /* find a share parameter */
+               parmnum = map_parameter(argv[1]);
+               if (parmnum == -1) {
+                       return -1;
+               }
+               parm = &parm_table[parmnum];
+               if (parm->class == P_GLOBAL) {
+                       return -1;
+               }
+               parm_ptr = ((char *)ServicePtrs[snum]) + PTR_DIFF(parm->ptr, &sDefault);
+       } else if (strchr(argv[0], ':')) {
+               /* its a global parametric option */
+               const char *type = talloc_strndup(ep, argv[0], strcspn(argv[0], ":"));
+               const char *option = strchr(argv[0], ':') + 1;
+               const char *value;
+               if (type == NULL || option == NULL) return -1;
+               value = get_parametrics(-1, type, option);
+               if (value == NULL) return -1;
+               espSetReturnString(ep, value);
+               return 0;
+       } else {
+               /* its a global parameter */
+               int parmnum = map_parameter(argv[0]);
+               if (parmnum == -1) {
+                       return -1;
+               }
+               parm = &parm_table[parmnum];
+               parm_ptr = parm->ptr;
+       }
+
+       if (parm == NULL || parm_ptr == NULL) {
+               return -1;
+       }
+
+       /* construct and return the right type of ejs object */
+       switch (parm->type) {
+       case P_STRING:
+       case P_USTRING:
+               espSetReturnString(ep, *(char **)parm_ptr);
+               break;
+       case P_BOOL:
+               espSetReturn(ep, mprCreateBoolVar(*(BOOL *)parm_ptr));
+               break;
+       case P_INTEGER:
+               espSetReturn(ep, mprCreateIntegerVar(*(int *)parm_ptr));
+               break;
+       case P_ENUM:
+               for (i=0; parm->enum_list[i].name; i++) {
+                       if (*(int *)parm_ptr == parm->enum_list[i].value) {
+                               espSetReturnString(ep, parm->enum_list[i].name);
+                               return 0;
+                       }
+               }
+               return -1;
+       
+       case P_LIST: {
+               const char **list = *(const char ***)parm_ptr;
+               struct MprVar var;
+               var = mprCreateObjVar(parm->label, 10);
+               for (i=0;list[i];i++) {
+                       char idx[16];
+                       struct MprVar val;
+                       mprItoa(i, idx, sizeof(idx));
+                       val = mprCreateStringVar(list[i], 1);
+                       mprCreateProperty(&var, idx, &val);
+               }
+               espSetReturn(ep, var);
+               break;
+       case P_SEP:
+               return -1;
+       }
+       }
+       return 0;
+}
diff --git a/source4/web_server/calls.c b/source4/web_server/calls.c
new file mode 100644 (file)
index 0000000..8cd0c21
--- /dev/null
@@ -0,0 +1,72 @@
+/* 
+   Unix SMB/CIFS implementation.
+
+   provide hooks into C calls from esp scripts
+
+   Copyright (C) Andrew Tridgell 2005
+   
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "web_server/esp/esp.h"
+
+
+/*
+  return the type of a variable
+*/
+static int esp_typeof(struct EspRequest *ep, int argc, struct MprVar **argv)
+{
+       const struct {
+               MprType type;
+               const char *name;
+       } types[] = {
+               { MPR_TYPE_UNDEFINED, "undefined" },
+               { MPR_TYPE_NULL, "null" },
+               { MPR_TYPE_BOOL, "boolean" },
+               { MPR_TYPE_CFUNCTION, "function" },
+               { MPR_TYPE_FLOAT, "float" },
+               { MPR_TYPE_INT, "int" },
+               { MPR_TYPE_INT64, "int64" },
+               { MPR_TYPE_OBJECT, "object" },
+               { MPR_TYPE_FUNCTION, "function" },
+               { MPR_TYPE_STRING, "string" },
+               { MPR_TYPE_STRING_CFUNCTION, "function" }
+       };
+       int i;
+       const char *type = "unknown";
+
+       if (argc != 1) return -1;
+       
+       for (i=0;i<ARRAY_SIZE(types);i++) {
+               if (argv[0]->type == types[i].type) {
+                       type = types[i].name;
+                       break;
+               }
+       }
+
+       espSetReturnString(ep, type);
+       return 0;
+}
+
+
+/*
+  setup the C functions that be called from ejs
+*/
+void http_setup_ejs_functions(void)
+{
+       espDefineStringCFunction(NULL, "lpGet", esp_lpGet, NULL);
+       espDefineCFunction(NULL, "typeof", esp_typeof, NULL);
+}
index 34d8aff1e621c71a7e1574becddfd543c0df9cc5..b287b4f153f2e626e03565b25652aeda77e6eb34 100644 (file)
@@ -33,7 +33,8 @@ NOPROTO=YES
 INIT_OBJ_FILES = \
                web_server/web_server.o
 ADD_OBJ_FILES = \
-               web_server/http.o
+               web_server/http.o \
+               web_server/calls.o
 REQUIRED_SUBSYSTEMS = ESP
 # End SUBSYSTEM WEB
 #######################
index 2d85ad13300877247d5993cc50a27b5f323530ff..4f5eb6b1292302d4963c91f0208512eefded6ce2 100644 (file)
@@ -754,7 +754,7 @@ MprVar *ejsGetReturnValue(EjsId eid)
  *     or "[]".  
  */
 
-void ejsDefineCFunction(EjsId eid, char *functionName, MprCFunction fn, 
+void ejsDefineCFunction(EjsId eid, const char *functionName, MprCFunction fn, 
        void *thisPtr, int flags)
 {
        if (eid < 0) {
@@ -793,7 +793,7 @@ void ejsDefineStringCFunction(EjsId eid, const char *functionName,
  *     Body should not contain braces.
  */
 
-void ejsDefineFunction(EjsId eid, char *functionName, char *args, char *body)
+void ejsDefineFunction(EjsId eid, const char *functionName, char *args, char *body)
 {
        MprVar          v;
 
index c1d087cf610cde5048fe5d258c133fd00651bf10..60aa93a4089175374d92d52c397888e74300f98a 100644 (file)
@@ -99,9 +99,9 @@ extern MprVar *ejsGetGlobalObject(EjsId eid);
 /*
  *     Function routines
  */
-extern void    ejsDefineFunction(EjsId eid, char *functionName, char *args, 
+extern void    ejsDefineFunction(EjsId eid, const char *functionName, char *args, 
                                        char *body);
-extern void    ejsDefineCFunction(EjsId eid, char *functionName, 
+extern void    ejsDefineCFunction(EjsId eid, const char *functionName, 
                                        MprCFunction fn, void *thisPtr, int flags);
 extern void            ejsDefineStringCFunction(EjsId eid, const char *functionName, 
                                        MprStringCFunction fn, void *thisPtr, int flags);
index 3e370cb0202a973f3e828d6b0dd4e7b681b4307f..c90e4afe4292ae9e9ef703a465f48ef222ff1839 100644 (file)
@@ -218,7 +218,7 @@ void espDestroyRequest(EspRequest *ep)
  *             rq = (requiredCast) espGetHandle(ep);
  */
 
-void espDefineCFunction(EspRequest *ep, char *functionName, EspCFunction fn, 
+void espDefineCFunction(EspRequest *ep, const char *functionName, EspCFunction fn, 
        void *thisPtr)
 {
        mprAssert(functionName && *functionName);
@@ -389,7 +389,7 @@ void espSetReturn(EspRequest *ep, MprVar value)
 
 /******************************************************************************/
 
-void espSetReturnString(EspRequest *ep, char *str)
+void espSetReturnString(EspRequest *ep, const char *str)
 {
        mprAssert(ep);
 
@@ -866,7 +866,7 @@ MprVar *espCreatePropertyValue(MprVar *obj, char *property, MprVar newValue)
 
 /******************************************************************************/
 
-void espDefineFunction(EspRequest *ep, char *functionName, char *args, char *body)
+void espDefineFunction(EspRequest *ep, const char *functionName, char *args, char *body)
 {
        ejsDefineFunction(ep->eid, functionName, args, body);
 }
index 9e58bdf066fd0f508ad376c276cdad77a485c394..a6cac1e85266136c0581cacfbd3aae80a93a30de 100644 (file)
@@ -159,9 +159,9 @@ extern int                  espProcessRequest(EspRequest *ep, const char *docPath,
 /*
  *     Method invocation
  */
-extern void                    espDefineCFunction(EspRequest *ep, char *functionName, 
+extern void                    espDefineCFunction(EspRequest *ep, const char *functionName, 
                                                EspCFunction fn, void *thisPtr);
-extern void            espDefineFunction(EspRequest *ep, char *functionName, 
+extern void            espDefineFunction(EspRequest *ep, const char *functionName, 
                                                char *args, char *body);
 extern void                    espDefineStringCFunction(EspRequest *ep, 
                                                const char *functionName, EspStringCFunction fn, 
@@ -188,7 +188,7 @@ extern EjsId                espGetScriptHandle(EspRequest *ep);
 extern void                    espRedirect(EspRequest *ep, int code, char *url);
 extern void                    espSetHeader(EspRequest *ep, char *header, 
                                                bool allowMultiple);
-extern void                    espSetReturnString(EspRequest *ep, char *str);
+extern void                    espSetReturnString(EspRequest *ep, const char *str);
 extern int                     espWrite(EspRequest *ep, char *buf, int size);
 extern int                     espWriteString(EspRequest *ep, char *buf);
 extern int                     espWriteFmt(EspRequest *ep, char *fmt, ...);
index fd9b1be67f9605f231e9918203842840675a30fc..d9d441f765bd49747bd8e5395b1f645da47140c5 100644 (file)
@@ -720,6 +720,8 @@ void http_process_input(struct websrv_context *web)
 
        talloc_set_destructor(esp, esp_destructor);
 
+       http_setup_ejs_functions();
+
        esp->req = espCreateRequest(web, web->input.url, esp->variables);
        if (esp->req == NULL) goto internal_error;