source: branches/prototype-v0/zoo-project/zoo-kernel/service_internal_php7.c @ 896

Last change on this file since 896 was 896, checked in by knut, 5 years ago

Added some recent changes from trunk (r889), including some new utility functions and exception handling and new (conditional) definition of type bool. Added some new logic concerning Python and Mono environment and search paths. Fixed problem with Mono updateStatus function. Changed response_print.h to #include locale.h unconditionally and xlocale.h conditionally; xlocale.h is non-standard and can probably be dropped.

File size: 10.4 KB
Line 
1/*
2 * Author : Gérald FENOY, Knut LANDMARK
3 *
4 * Copyright (c) 2009-2016 GeoLabs SARL
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24
25#ifdef WIN32
26  #define NO_FCGI_DEFINES
27  #define ZEND_WIN32_KEEP_INLINE
28#endif
29
30#ifndef ZEND_DEBUG
31  #define ZEND_DEBUG 0
32#endif 
33
34#include <sapi/embed/php_embed.h>
35#include <zend_stream.h>
36
37#include "service_internal_php.h"
38#include "response_print.h"
39
40map* php_hashtable_to_map(HashTable* tab);
41maps* php_array_to_maps(HashTable* arr);
42void php_map_to_array(map* src, zval* arr);
43void php_maps_to_array(maps* src, zval* arr);
44
45#define zval_make_ref_array(zv,len) for (int elem = 0; elem < len; elem++) ZVAL_MAKE_REF(&zv[elem]);
46#define zval_unref_array(zv,len)    for (int elem = 0; elem < len; elem++) ZVAL_UNREF(&zv[elem]);       
47
48#ifdef ZTS
49void ***tsrm_ls;
50#endif
51
52ZEND_BEGIN_MODULE_GLOBALS(zoo)
53long _SERVICE_SUCCEEDED;
54long _SERVICE_FAILED;
55ZEND_END_MODULE_GLOBALS(zoo)
56
57#ifdef ZTS
58#define ZOO_G(v) TSRMG(zoo_globals_id, zend_zoo_globals *, v)
59#else
60#define ZOO_G(v) (zoo_globals.v)
61#endif
62
63#define PHP_ZOO_VERSION "1.0"
64#define PHP_ZOO_EXTNAME "ZOO"
65
66PHP_MINIT_FUNCTION(zoo);
67PHP_MSHUTDOWN_FUNCTION(zoo);
68PHP_RINIT_FUNCTION(zoo);
69
70PHP_FUNCTION(zoo_Translate);
71PHP_FUNCTION(zoo_UpdateStatus);
72PHP_FUNCTION(zoo_SERVICE_SUCCEEDED);
73PHP_FUNCTION(zoo_SERVICE_FAILED);
74
75extern zend_module_entry zoo_module_entry;
76#define phpext_zoo_ptr &zoo_entry
77
78ZEND_DECLARE_MODULE_GLOBALS(zoo)
79
80static zend_function_entry zoo_functions[] = {
81  PHP_FE(zoo_Translate, NULL)
82  PHP_FE(zoo_UpdateStatus, NULL)
83  PHP_FE(zoo_SERVICE_SUCCEEDED, NULL)
84  PHP_FE(zoo_SERVICE_FAILED, NULL)
85  {NULL, NULL, NULL}
86};
87
88zend_module_entry zoo_module_entry = {
89#if ZEND_MODULE_API_NO >= 20010901
90    STANDARD_MODULE_HEADER,
91#endif
92    PHP_ZOO_EXTNAME,
93    zoo_functions,
94    PHP_MINIT(zoo),
95    PHP_MSHUTDOWN(zoo),
96    PHP_RINIT(zoo),
97    NULL,
98    NULL,
99#if ZEND_MODULE_API_NO >= 20010901
100    PHP_ZOO_VERSION,
101#endif
102    STANDARD_MODULE_PROPERTIES
103};
104
105ZEND_GET_MODULE(zoo)
106
107PHP_INI_BEGIN()
108PHP_INI_END()
109
110static void
111php_zoo_init_globals(zend_zoo_globals *zoo_globals)
112{
113  zoo_globals->_SERVICE_SUCCEEDED=3;
114  zoo_globals->_SERVICE_FAILED=4;
115}
116
117PHP_RINIT_FUNCTION(zoo)
118{
119  return SUCCESS;
120}
121
122PHP_MINIT_FUNCTION(zoo)
123{
124  ZEND_INIT_MODULE_GLOBALS(zoo, php_zoo_init_globals,NULL);
125  REGISTER_INI_ENTRIES();
126  return SUCCESS;
127}
128
129PHP_MSHUTDOWN_FUNCTION(zoo)
130{
131  UNREGISTER_INI_ENTRIES();
132  return SUCCESS;
133}
134
135PHP_FUNCTION(zoo_Translate)
136{
137  char *value;
138  size_t value_len;
139  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &value, &value_len) == FAILURE) {
140    RETURN_NULL();
141  }
142  //RETURN_STRING(_ss(value), 1);
143  RETURN_STRINGL(_ss(value), 1);
144}
145
146PHP_FUNCTION(zoo_UpdateStatus)
147{
148  zval *arr;
149  char *message;
150  size_t message_len;
151  zend_long pourcent;
152  char *status=(char*)malloc(4*sizeof(char));
153  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "asl", &arr, &message, &message_len,&pourcent) == FAILURE) {
154    RETURN_NULL();
155  }
156  HashTable* t=HASH_OF(arr);
157  maps* conf = php_array_to_maps(t);
158   
159  setMapInMaps(conf,"lenv","message",message);
160  sprintf(status,"%d",pourcent);
161  setMapInMaps(conf,"lenv","status",status); 
162  _updateStatus(conf); 
163  freeMaps(&conf); 
164  free(conf);
165  free(status);
166 
167  RETURN_NULL();
168}
169
170PHP_FUNCTION(zoo_SERVICE_SUCCEEDED)
171{
172  RETURN_LONG(ZOO_G(_SERVICE_SUCCEEDED));
173}
174
175PHP_FUNCTION(zoo_SERVICE_FAILED)
176{
177  RETURN_LONG(ZOO_G(_SERVICE_FAILED));
178}
179
180/**
181 * Load a PHP script then run the function corresponding to the service by
182 * passing the conf, inputs and outputs parameters by reference.
183 *
184 * @param main_conf the conf maps containing the main.cfg settings
185 * @param request the map containing the HTTP request
186 * @param s the service structure
187 * @param real_inputs the maps containing the inputs
188 * @param real_outputs the maps containing the outputs
189 */
190int zoo_php_support(maps** main_conf, map* request, service* s, maps **real_inputs, maps **real_outputs) {     
191  maps* m = *main_conf;
192  maps* inputs = *real_inputs;
193  maps* outputs = *real_outputs;
194   
195  map* libp = getMapFromMaps(m, "main", "libPath"); 
196  int res=SERVICE_FAILED;
197
198  map* tmp = getMap(s->content, "serviceProvider");
199  if (tmp == NULL || tmp->value == NULL) {
200    return errorException(m, "Missing serviceProvider (library file)", "NoApplicableCode", NULL);
201  } 
202 
203  #ifdef IGNORE_METAPATH
204  map* mp = createMap("metapath", "");
205  #else 
206  map* mp = getMap(request, "metapath");
207  #endif
208 
209  map* cwd = getMapFromMaps(m,"lenv","cwd");
210  char *scriptName;
211 
212  if (libp != NULL && libp->value != NULL) {
213    scriptName = (char*) malloc((strlen(libp->value) + strlen(tmp->value) + 2)*sizeof(char));
214    sprintf (scriptName, "%s/%s", libp->value, tmp->value);     
215  }
216  else {       
217    if(mp != NULL && strlen(mp->value) > 0) {
218      scriptName = (char*) malloc((strlen(cwd->value)+strlen(mp->value)+strlen(tmp->value)+3)*sizeof(char));
219      sprintf(scriptName, "%s/%s/%s", cwd->value, mp->value, tmp->value);
220    } 
221          else {
222      scriptName = (char*) malloc((strlen(cwd->value)+strlen(tmp->value)+2)*sizeof(char));
223      sprintf(scriptName, "%s/%s", cwd->value, tmp->value);
224    }
225  }
226 
227  zend_file_handle iscript;
228  iscript.type = ZEND_HANDLE_FD;
229  iscript.opened_path = NULL;
230  iscript.filename = tmp->value;
231  iscript.free_filename = 0;
232 
233  FILE* temp = fopen(scriptName, "rb");
234  if(temp == NULL) {
235    char tmp1[1024];
236    sprintf(tmp1, _("Unable to load the PHP file %s"), tmp->value);
237    free(scriptName);
238    return errorException(m, tmp1, "NoApplicableCode", NULL);
239  }
240  iscript.handle.fd = fileno(temp);
241
242  php_embed_init(0, NULL);
243
244  zend_try {
245    zend_startup_module(&zoo_module_entry);
246    php_execute_script(&iscript TSRMLS_CC);
247
248          zval iargs[3];
249    zval iret, ifunc;   
250                     
251          ZVAL_STRING(&ifunc, s->name);
252       
253          php_maps_to_array(*main_conf, iargs);   
254    php_maps_to_array(*real_inputs, iargs+1);   
255    php_maps_to_array(*real_outputs, iargs+2);
256    zval_make_ref_array(iargs,3);
257   
258    if((res = call_user_function(EG(function_table), NULL, &ifunc, &iret, 3, iargs)) == SUCCESS) {     
259               
260            zval_unref_array(iargs,3);           
261            zend_string_release(Z_STR_P(&ifunc));
262     
263      HashTable* t = HASH_OF(iargs+2);
264      HashTable* t1 = HASH_OF(iargs);
265      freeMaps(real_outputs);
266      free(*real_outputs);
267      freeMaps(main_conf);
268      free(*main_conf);
269     
270      *real_outputs = php_array_to_maps(t);       
271      *main_conf = php_array_to_maps(t1);
272
273      res = Z_LVAL(iret);
274    }
275    else {
276      free(scriptName);
277      fclose(temp);
278      return errorException(m, "Unable to process.", "NoApplicableCode", NULL);;
279    }
280  } 
281  zend_catch { 
282    free(scriptName);
283    fclose(temp);
284    return errorException(m, "Unable to process.", "NoApplicableCode", NULL);;
285  } 
286  zend_end_try();
287 
288  free(scriptName);
289  fclose(temp);
290  php_embed_shutdown(TSRMLS_C);
291
292  return res;
293}
294
295/**
296 * Convert a Zoo struct maps to a php array
297 *
298 * @param src the struct maps* to convert (source data structure)
299 * @param arr pointer to zval that is to hold the php array
300 */
301void php_maps_to_array(maps* src, zval* arr) {
302       
303  int tres = array_init(arr);
304  maps* pm = src;
305               
306  while (pm != NULL) {
307    zval zv; // allocate on heap??
308    php_map_to_array(pm->content, &zv);
309    add_assoc_zval(arr, pm->name, &zv); 
310    pm = pm->next;
311        }
312}
313
314/**
315 * Convert a Zoo map to a php array
316 *
317 * @param src the struct map* to convert (source data structure)
318 * @param arr pointer to zval that is to hold the php array
319 */
320void php_map_to_array(map* src, zval* arr) {
321       
322  int tres = array_init(arr);
323  map* pm = src;
324       
325  while(pm != NULL) {
326    map* sMap = getMapArray(pm, "size", 0);
327               
328    if (pm->value != NULL && strncmp(pm->name, "value", 5) == 0 && sMap != NULL) {                       
329      tres = add_assoc_stringl(arr, pm->name, pm->value, atoi(sMap->value));
330                }
331    else {
332      tres = add_assoc_string(arr, pm->name, pm->value);                       
333                }                                               
334    pm = pm->next;                     
335  }     
336}
337
338/**
339 * Convert a php hashtable (array) to a Zoo maps
340 *
341 * @param arr the php hashtable to convert
342 * @return the created struct maps*
343 */
344maps* php_array_to_maps(HashTable* arr) {
345
346  maps* res = NULL;
347  zval* data;
348  zend_string* key = NULL;
349  ulong num_key;       
350       
351  ZEND_HASH_FOREACH_KEY_VAL(arr, num_key, key, data)
352    if (!key) { // HASH_KEY_IS_LONG                     
353      key = strpprintf(64, "%lu", num_key);
354          }     
355    zval copy;
356    ZVAL_DUP(&copy, data);
357    HashTable* tab = HASH_OF(&copy);
358               
359    maps* node = createMaps(ZSTR_VAL(key));                                     
360    node->content = php_hashtable_to_map(tab);
361               
362    if(res == NULL) {
363      res = node;
364    }
365    else {
366      addMapsToMaps(&res, node);
367      freeMaps(&node);
368      free(node);
369    }
370    zval_dtor(&copy);           
371  ZEND_HASH_FOREACH_END();
372       
373  return res;
374}
375
376/**
377 * Convert a php hashtable (array) to a Zoo map
378 *
379 * @param tab the php hashtable to convert
380 * @return the created struct map*
381 */
382map* php_hashtable_to_map(HashTable* tab) {
383
384  map* res = NULL;
385  zval* data;
386  zend_string* key = NULL;
387  ulong num_key;
388       
389  ZEND_HASH_FOREACH_KEY_VAL(tab, num_key, key, data)
390    if (!key) { // HASH_KEY_IS_LONG                     
391      key = strpprintf(64, "%lu", num_key);
392    }
393    zval copy;
394    ZVAL_DUP(&copy, data);
395    convert_to_string(&copy);
396               
397    if(strncmp(ZSTR_VAL(key), "value", 5) == 0) {                       
398      size_t len = Z_STRLEN(copy);                             
399      res = addToMapWithSize(res, ZSTR_VAL(key), Z_STRVAL(copy), len);
400    }
401    else {
402      if (res == NULL) {                               
403        res = createMap(ZSTR_VAL(key), Z_STRVAL(copy));
404                        }
405      else {                           
406        addToMap(res, ZSTR_VAL(key), Z_STRVAL(copy));
407      }
408    }                           
409    zval_dtor(&copy);                   
410  ZEND_HASH_FOREACH_END();
411       
412  return res;   
413}       
Note: See TracBrowser for help on using the repository browser.

Search

Context Navigation

ZOO Sponsors

http://www.zoo-project.org/trac/chrome/site/img/geolabs-logo.pnghttp://www.zoo-project.org/trac/chrome/site/img/neogeo-logo.png http://www.zoo-project.org/trac/chrome/site/img/apptech-logo.png http://www.zoo-project.org/trac/chrome/site/img/3liz-logo.png http://www.zoo-project.org/trac/chrome/site/img/gateway-logo.png

Become a sponsor !

Knowledge partners

http://www.zoo-project.org/trac/chrome/site/img/ocu-logo.png http://www.zoo-project.org/trac/chrome/site/img/gucas-logo.png http://www.zoo-project.org/trac/chrome/site/img/polimi-logo.png http://www.zoo-project.org/trac/chrome/site/img/fem-logo.png http://www.zoo-project.org/trac/chrome/site/img/supsi-logo.png http://www.zoo-project.org/trac/chrome/site/img/cumtb-logo.png

Become a knowledge partner

Related links

http://zoo-project.org/img/ogclogo.png http://zoo-project.org/img/osgeologo.png