source: trunk/zoo-project/zoo-kernel/service_internal_php.c @ 780

Last change on this file since 780 was 738, checked in by knut, 9 years ago

Redefined the API function addToMapWithSize to fix problem with Python/PHP support. Added some variable initializations and NULL pointer checks.

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc
File size: 11.5 KB
Line 
1/*
2 * Author : Gérald FENOY
3 *
4 * Copyright (c) 2009-2010 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#endif
28
29#ifndef ZEND_DEBUG
30  #define ZEND_DEBUG 0
31#endif 
32
33#include <sapi/embed/php_embed.h>
34#include <zend_stream.h>
35
36#include "service_internal_php.h"
37#include "response_print.h"
38
39zval *php_Array_from_maps(maps* t);
40zval*  php_Array_from_map(map*);
41maps* php_maps_from_Array(HashTable* t);
42map* php_map_from_HasTable(HashTable* t);
43
44#ifdef ZTS
45void ***tsrm_ls;
46#endif
47
48ZEND_BEGIN_MODULE_GLOBALS(zoo)
49long _SERVICE_SUCCEEDED;
50long _SERVICE_FAILED;
51ZEND_END_MODULE_GLOBALS(zoo)
52
53#ifdef ZTS
54#define ZOO_G(v) TSRMG(zoo_globals_id, zend_zoo_globals *, v)
55#else
56#define ZOO_G(v) (zoo_globals.v)
57#endif
58
59#define PHP_ZOO_VERSION "1.0"
60#define PHP_ZOO_EXTNAME "ZOO"
61
62PHP_MINIT_FUNCTION(zoo);
63PHP_MSHUTDOWN_FUNCTION(zoo);
64PHP_RINIT_FUNCTION(zoo);
65
66PHP_FUNCTION(zoo_Translate);
67PHP_FUNCTION(zoo_UpdateStatus);
68PHP_FUNCTION(zoo_SERVICE_SUCCEEDED);
69PHP_FUNCTION(zoo_SERVICE_FAILED);
70
71extern zend_module_entry zoo_module_entry;
72#define phpext_zoo_ptr &zoo_entry
73
74ZEND_DECLARE_MODULE_GLOBALS(zoo)
75
76static zend_function_entry zoo_functions[] = {
77  PHP_FE(zoo_Translate, NULL)
78  PHP_FE(zoo_UpdateStatus, NULL)
79  PHP_FE(zoo_SERVICE_SUCCEEDED, NULL)
80  PHP_FE(zoo_SERVICE_FAILED, NULL)
81  {NULL, NULL, NULL}
82};
83
84zend_module_entry zoo_module_entry = {
85#if ZEND_MODULE_API_NO >= 20010901
86    STANDARD_MODULE_HEADER,
87#endif
88    PHP_ZOO_EXTNAME,
89    zoo_functions,
90    PHP_MINIT(zoo),
91    PHP_MSHUTDOWN(zoo),
92    PHP_RINIT(zoo),
93    NULL,
94    NULL,
95#if ZEND_MODULE_API_NO >= 20010901
96    PHP_ZOO_VERSION,
97#endif
98    STANDARD_MODULE_PROPERTIES
99};
100
101ZEND_GET_MODULE(zoo)
102
103PHP_INI_BEGIN()
104PHP_INI_END()
105
106static void
107php_zoo_init_globals(zend_zoo_globals *zoo_globals)
108{
109  zoo_globals->_SERVICE_SUCCEEDED=3;
110  zoo_globals->_SERVICE_FAILED=4;
111}
112
113PHP_RINIT_FUNCTION(zoo)
114{
115  return SUCCESS;
116}
117
118PHP_MINIT_FUNCTION(zoo)
119{
120  ZEND_INIT_MODULE_GLOBALS(zoo, php_zoo_init_globals,NULL);
121  REGISTER_INI_ENTRIES();
122  return SUCCESS;
123}
124
125PHP_MSHUTDOWN_FUNCTION(zoo)
126{
127  UNREGISTER_INI_ENTRIES();
128  return SUCCESS;
129}
130
131PHP_FUNCTION(zoo_Translate)
132{
133  char *value;
134  int value_len;
135  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &value, &value_len) == FAILURE) {
136    RETURN_NULL();
137  }
138  RETURN_STRING(_ss(value), 1);
139}
140
141PHP_FUNCTION(zoo_UpdateStatus)
142{
143  zval *arr;
144  char *message;
145  int message_len;
146  long pourcent;
147  char *status=(char*)malloc(4*sizeof(char));
148  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "asl", &arr, &message, &message_len,&pourcent) == FAILURE) {
149    RETURN_NULL();
150  }
151  HashTable* t=HASH_OF(arr);
152  maps* conf=php_maps_from_Array(t);
153  setMapInMaps(conf,"lenv","message",message);
154  sprintf(status,"%d",pourcent);
155  setMapInMaps(conf,"lenv","status",status);
156  _updateStatus(conf);
157  freeMaps(&conf);
158  free(conf);
159  free(status);
160  RETURN_NULL();
161}
162
163PHP_FUNCTION(zoo_SERVICE_SUCCEEDED)
164{
165  RETURN_LONG(ZOO_G(_SERVICE_SUCCEEDED));
166}
167
168PHP_FUNCTION(zoo_SERVICE_FAILED)
169{
170  RETURN_LONG(ZOO_G(_SERVICE_FAILED));
171}
172
173/**
174 * Load a PHP script then run the function corresponding to the service by
175 * passing the conf, inputs and outputs parameters by reference.
176 *
177 * @param main_conf the conf maps containing the main.cfg settings
178 * @param request the map containing the HTTP request
179 * @param s the service structure
180 * @param real_inputs the maps containing the inputs
181 * @param real_outputs the maps containing the outputs
182 */
183int zoo_php_support(maps** main_conf,map* request,service* s,maps **real_inputs,maps **real_outputs){   
184  maps* m=*main_conf;
185  maps* inputs=*real_inputs;
186  maps* outputs=*real_outputs;
187  char ntmp[1024];
188  getcwd(ntmp,1024);
189   
190  map* libp = getMapFromMaps(m, "main", "libPath"); 
191  int res=SERVICE_FAILED;
192
193  map* tmp=getMap(s->content,"serviceProvider");
194  if (tmp == NULL || tmp->value == NULL) {
195          return errorException(m, "Missing serviceProvider (library file)", "NoApplicableCode", NULL);
196  }
197 
198  map* cwd=getMapFromMaps(m,"lenv","cwd");
199#ifdef IGNORE_METAPATH
200  map* mp = createMap("metapath", "");
201#else 
202  map* mp = getMap(request, "metapath");
203#endif
204  char *scriptName;
205 
206  if (libp != NULL && libp->value != NULL) {
207        scriptName = (char*) malloc((strlen(libp->value) + strlen(tmp->value) + 2)*sizeof(char));
208    sprintf (scriptName, "%s/%s", libp->value, tmp->value);     
209  }
210  else {       
211    if(mp!=NULL && strlen(mp->value)>0){
212      scriptName=(char*)malloc((strlen(cwd->value)+strlen(mp->value)+strlen(tmp->value)+3)*sizeof(char));
213      sprintf(scriptName,"%s/%s/%s",cwd->value,mp->value,tmp->value);
214    }else{
215      scriptName=(char*)malloc((strlen(cwd->value)+strlen(tmp->value)+2)*sizeof(char));
216      sprintf(scriptName,"%s/%s",cwd->value,tmp->value);
217    }
218  } 
219  zend_file_handle iscript;
220  iscript.type=ZEND_HANDLE_FD;
221  iscript.opened_path=NULL;
222  iscript.filename=tmp->value;
223  iscript.free_filename=0;
224  FILE* temp=fopen(scriptName,"rb");
225  if(temp==NULL){
226    char tmp1[1024];
227    sprintf(tmp1,_("Unable to load the PHP file %s"),tmp->value);
228    free(scriptName);
229    return errorException(m,tmp1,"NoApplicableCode",NULL);
230  }
231  iscript.handle.fd=fileno(temp);
232
233  php_embed_init(0,NULL PTSRMLS_CC);
234   
235  zend_try {
236    zend_startup_module(&zoo_module_entry);
237    php_execute_script(&iscript TSRMLS_CC);
238    zval *iargs[3];
239    zval iret, ifunc,ifile;
240     
241    ZVAL_STRING(&ifunc, s->name, 0);
242    iargs[0] = php_Array_from_maps(*main_conf);
243    iargs[1] = php_Array_from_maps(*real_inputs);
244    iargs[2] = php_Array_from_maps(*real_outputs);
245     
246    if((res=call_user_function(EG(function_table), NULL, &ifunc, &iret, 3, iargs TSRMLS_CC))==SUCCESS){
247     
248      HashTable* t=HASH_OF(iargs[2]);
249      HashTable* t1=HASH_OF(iargs[0]);
250      freeMaps(real_outputs);
251      free(*real_outputs);
252      freeMaps(main_conf);
253      free(*main_conf);
254      *real_outputs=php_maps_from_Array(t);
255      *main_conf=php_maps_from_Array(t1);
256
257      res=Z_LVAL(iret);
258    }else{
259      free(scriptName);
260      fclose(temp);
261      return errorException(m,"Unable to process.","NoApplicableCode",NULL);;
262    }
263  } zend_catch { 
264    free(scriptName);
265    fclose(temp);
266    return errorException(m,"Unable to process.","NoApplicableCode",NULL);;
267  } zend_end_try();
268  free(scriptName);
269  fclose(temp);
270  php_embed_shutdown(TSRMLS_C);
271
272  return res;
273}
274
275/**
276 * Convert a maps to a php Array
277 *
278 * @param t the maps to convert
279 * @return the php Array
280 */
281zval *php_Array_from_maps(maps* t){
282  zval *mapArray;
283  zval *mapArrayTmp;
284  maps* tmp=t;
285  int tres=0;
286  MAKE_STD_ZVAL(mapArray);
287  tres=array_init(mapArray);
288  while(tmp!=NULL){
289    add_assoc_zval(mapArray,tmp->name,php_Array_from_map(tmp->content));
290    tmp=tmp->next;
291  }
292  return mapArray;
293}
294
295/**
296 * Convert a map to a php Array
297 *
298 * @param t the map to convert
299 * @return the php Array
300 */
301zval *php_Array_from_map(map* t){
302  zval *mapArray;
303  zval *mapArrayTmp;
304  map* tmp=t;
305  int tres=0;
306  MAKE_STD_ZVAL(mapArray);
307  tres=array_init(mapArray);
308  while(tmp!=NULL){
309    map* sMap=getMapArray(tmp,"size",0);   
310        if(strncmp(tmp->name,"value",5)==0 && sMap!=NULL && tmp->value != NULL){
311      tres=add_assoc_stringl(mapArray,tmp->name,tmp->value,atoi(sMap->value),1);
312        } 
313        else if (tmp->value != NULL) {
314      tres=add_assoc_string(mapArray,tmp->name,tmp->value,1);
315        }
316    tmp=tmp->next;
317  }
318  return mapArray;
319}
320
321/**
322 * Convert a php Array to a maps
323 *
324 * @param t the php Array to convert
325 * @return the created maps
326 */
327maps* php_maps_from_Array(HashTable *t){
328  maps* final_res=NULL;
329  maps* cursor=final_res;
330  char key[1024];
331  for(zend_hash_internal_pointer_reset(t); 
332      zend_hash_has_more_elements(t) == SUCCESS; 
333      zend_hash_move_forward(t)) { 
334    char *key; 
335    uint keylen; 
336    ulong idx; 
337    int type; 
338    zval **ppzval, tmpcopy; 
339    type = zend_hash_get_current_key_ex(t, &key, &keylen, &idx, 0, NULL); 
340    if (zend_hash_get_current_data(t, (void**)&ppzval) == FAILURE) { 
341      /**
342       * Should never actually fail since the key is known to exist.
343       */
344      continue; 
345    }
346    /**
347     * Duplicate the zval so that * the orignal’s contents are not destroyed
348     */
349    tmpcopy = **ppzval;
350#ifdef DEBUG
351    fprintf(stderr,"key : %s\n",key);
352#endif
353    zval_copy_ctor(&tmpcopy); 
354#ifdef DEBUG
355    fprintf(stderr,"key : %s\n",key);
356#endif
357    /**
358     * Reset refcount & Convert
359     */
360    INIT_PZVAL(&tmpcopy); 
361    //convert_to_string(&tmpcopy);
362    if (type == HASH_KEY_IS_STRING) { 
363      /**
364       * String Key / Associative
365       */
366      cursor=(maps*)malloc(MAPS_SIZE);
367      cursor->name=strdup(key);
368    }
369#ifdef DEBUG   
370    fprintf(stderr,"key : %s\n",key);
371#endif 
372    HashTable* t=HASH_OF(*ppzval);
373#ifdef DEBUG
374    fprintf(stderr,"key : %s\n",key);
375#endif
376    cursor->content=php_map_from_HasTable(t);
377    cursor->next=NULL;
378    if(final_res==NULL)
379      final_res=cursor;
380    else{
381      addMapsToMaps(&final_res,cursor);
382      freeMaps(&cursor);
383      free(cursor);
384    }
385#ifdef DEBUG
386    fprintf(stderr,"key : %s\n",key);
387#endif
388    /**
389     * Toss out old copy
390     */
391    zval_dtor(&tmpcopy);
392  }
393  return final_res;
394}
395
396/**
397 * Convert a php Array to a map
398 *
399 * @param t the php Array to convert
400 * @return the created map
401 */
402map* php_map_from_HasTable(HashTable* t){
403#ifdef DEBUG
404  fprintf(stderr,"mapsFromPHPArray start\n");
405#endif
406  map* final_res=(map*)malloc(MAP_SIZE);
407  final_res=NULL;
408  char key[1024];
409  for(zend_hash_internal_pointer_reset(t);
410      zend_hash_has_more_elements(t) == SUCCESS;
411      zend_hash_move_forward(t)) {
412    char *key;
413    uint keylen;
414    ulong idx;
415    int type;
416    int len;
417    zval **ppzval, tmpcopy;
418    type = zend_hash_get_current_key_ex(t, &key, &keylen, &idx, 0, NULL); 
419    if (zend_hash_get_current_data(t, (void**)&ppzval) == FAILURE) { 
420      /* Should never actually fail * since the key is known to exist. */ 
421      continue; 
422    }
423    /**
424     * Duplicate the zval so that * the orignal’s contents are not destroyed
425     */ 
426    tmpcopy = **ppzval; 
427    zval_copy_ctor(&tmpcopy); 
428    /**
429     * Reset refcount & Convert
430     */ 
431    INIT_PZVAL(&tmpcopy); 
432    convert_to_string(&tmpcopy);
433    if(strncmp(key,"value",5)==0){
434      len=Z_STRLEN_P(&tmpcopy);     
435          final_res = addToMapWithSize(final_res,key,Z_STRVAL_P(&tmpcopy),len);
436    }
437    else{
438      if(final_res==NULL){
439#ifdef DEBUG
440        fprintf(stderr,"%s => %s\n",key,Z_STRVAL(tmpcopy));
441#endif
442        final_res=createMap(key,Z_STRVAL(tmpcopy));
443      }
444      else{
445#ifdef DEBUG
446        fprintf(stderr,"%s => %s\n",key,Z_STRVAL(tmpcopy));
447#endif
448        addToMap(final_res,key,Z_STRVAL(tmpcopy));
449      }
450    }
451    /* Toss out old copy */ 
452    zval_dtor(&tmpcopy); 
453  }
454  return final_res;
455}
Note: See TracBrowser for help on using the repository browser.

Search

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