From 5537a0d38d4805cbc2dad0d6f76db15173b1fd60 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 27 May 2005 03:58:12 +0000 Subject: [PATCH] r7002: added support for getting at loadparm config parameters via lpGet() in esp scripts 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 --- source/include/structs.h | 1 + source/param/loadparm.c | 169 +++++++++++++++++++++++++----------- source/web_server/calls.c | 72 +++++++++++++++ source/web_server/config.mk | 3 +- source/web_server/ejs/ejs.c | 4 +- source/web_server/ejs/ejs.h | 4 +- source/web_server/esp/esp.c | 6 +- source/web_server/esp/esp.h | 6 +- source/web_server/http.c | 2 + 9 files changed, 203 insertions(+), 64 deletions(-) create mode 100644 source/web_server/calls.c diff --git a/source/include/structs.h b/source/include/structs.h index b34dbff663b..9a6c534c099 100644 --- a/source/include/structs.h +++ b/source/include/structs.h @@ -212,3 +212,4 @@ struct arcfour_state; union libnet_SamDump; struct websrv_context; +struct EspRequest; diff --git a/source/param/loadparm.c b/source/param/loadparm.c index 4b55db8aaba..ceb73e99581 100644 --- a/source/param/loadparm.c +++ b/source/param/loadparm.c @@ -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/source/web_server/calls.c b/source/web_server/calls.c new file mode 100644 index 00000000000..8cd0c21b1ce --- /dev/null +++ b/source/web_server/calls.c @@ -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;itype == 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); +} diff --git a/source/web_server/config.mk b/source/web_server/config.mk index 34d8aff1e62..b287b4f153f 100644 --- a/source/web_server/config.mk +++ b/source/web_server/config.mk @@ -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 ####################### diff --git a/source/web_server/ejs/ejs.c b/source/web_server/ejs/ejs.c index 2d85ad13300..4f5eb6b1292 100644 --- a/source/web_server/ejs/ejs.c +++ b/source/web_server/ejs/ejs.c @@ -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; diff --git a/source/web_server/ejs/ejs.h b/source/web_server/ejs/ejs.h index c1d087cf610..60aa93a4089 100644 --- a/source/web_server/ejs/ejs.h +++ b/source/web_server/ejs/ejs.h @@ -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); diff --git a/source/web_server/esp/esp.c b/source/web_server/esp/esp.c index 3e370cb0202..c90e4afe429 100644 --- a/source/web_server/esp/esp.c +++ b/source/web_server/esp/esp.c @@ -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); } diff --git a/source/web_server/esp/esp.h b/source/web_server/esp/esp.h index 9e58bdf066f..a6cac1e8526 100644 --- a/source/web_server/esp/esp.h +++ b/source/web_server/esp/esp.h @@ -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, ...); diff --git a/source/web_server/http.c b/source/web_server/http.c index fd9b1be67f9..d9d441f765b 100644 --- a/source/web_server/http.c +++ b/source/web_server/http.c @@ -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; -- 2.34.1