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

Last change on this file since 788 was 784, checked in by djay, 10 years ago

Give the capability to store the main.cfg file in sysconfdir and the services in servicePath if defined in the [main] section.

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc
File size: 11.4 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   
188  map* libp = getMapFromMaps(m, "main", "libPath"); 
189  int res=SERVICE_FAILED;
190
191  map* tmp=getMap(s->content,"serviceProvider");
192  if (tmp == NULL || tmp->value == NULL) {
193          return errorException(m, "Missing serviceProvider (library file)", "NoApplicableCode", NULL);
194  }
195 
196  map* cwd=getMapFromMaps(m,"lenv","cwd");
197#ifdef IGNORE_METAPATH
198  map* mp = createMap("metapath", "");
199#else 
200  map* mp = getMap(request, "metapath");
201#endif
202  char *scriptName;
203 
204  if (libp != NULL && libp->value != NULL) {
205        scriptName = (char*) malloc((strlen(libp->value) + strlen(tmp->value) + 2)*sizeof(char));
206    sprintf (scriptName, "%s/%s", libp->value, tmp->value);     
207  }
208  else {       
209    if(mp!=NULL && strlen(mp->value)>0){
210      scriptName=(char*)malloc((strlen(cwd->value)+strlen(mp->value)+strlen(tmp->value)+3)*sizeof(char));
211      sprintf(scriptName,"%s/%s/%s",cwd->value,mp->value,tmp->value);
212    }else{
213      scriptName=(char*)malloc((strlen(cwd->value)+strlen(tmp->value)+2)*sizeof(char));
214      sprintf(scriptName,"%s/%s",cwd->value,tmp->value);
215    }
216  } 
217  zend_file_handle iscript;
218  iscript.type=ZEND_HANDLE_FD;
219  iscript.opened_path=NULL;
220  iscript.filename=tmp->value;
221  iscript.free_filename=0;
222  FILE* temp=fopen(scriptName,"rb");
223  if(temp==NULL){
224    char tmp1[1024];
225    sprintf(tmp1,_("Unable to load the PHP file %s"),tmp->value);
226    free(scriptName);
227    return errorException(m,tmp1,"NoApplicableCode",NULL);
228  }
229  iscript.handle.fd=fileno(temp);
230
231  php_embed_init(0,NULL PTSRMLS_CC);
232   
233  zend_try {
234    zend_startup_module(&zoo_module_entry);
235    php_execute_script(&iscript TSRMLS_CC);
236    zval *iargs[3];
237    zval iret, ifunc,ifile;
238     
239    ZVAL_STRING(&ifunc, s->name, 0);
240    iargs[0] = php_Array_from_maps(*main_conf);
241    iargs[1] = php_Array_from_maps(*real_inputs);
242    iargs[2] = php_Array_from_maps(*real_outputs);
243     
244    if((res=call_user_function(EG(function_table), NULL, &ifunc, &iret, 3, iargs TSRMLS_CC))==SUCCESS){
245     
246      HashTable* t=HASH_OF(iargs[2]);
247      HashTable* t1=HASH_OF(iargs[0]);
248      freeMaps(real_outputs);
249      free(*real_outputs);
250      freeMaps(main_conf);
251      free(*main_conf);
252      *real_outputs=php_maps_from_Array(t);
253      *main_conf=php_maps_from_Array(t1);
254
255      res=Z_LVAL(iret);
256    }else{
257      free(scriptName);
258      fclose(temp);
259      return errorException(m,"Unable to process.","NoApplicableCode",NULL);;
260    }
261  } zend_catch { 
262    free(scriptName);
263    fclose(temp);
264    return errorException(m,"Unable to process.","NoApplicableCode",NULL);;
265  } zend_end_try();
266  free(scriptName);
267  fclose(temp);
268  php_embed_shutdown(TSRMLS_C);
269
270  return res;
271}
272
273/**
274 * Convert a maps to a php Array
275 *
276 * @param t the maps to convert
277 * @return the php Array
278 */
279zval *php_Array_from_maps(maps* t){
280  zval *mapArray;
281  zval *mapArrayTmp;
282  maps* tmp=t;
283  int tres=0;
284  MAKE_STD_ZVAL(mapArray);
285  tres=array_init(mapArray);
286  while(tmp!=NULL){
287    add_assoc_zval(mapArray,tmp->name,php_Array_from_map(tmp->content));
288    tmp=tmp->next;
289  }
290  return mapArray;
291}
292
293/**
294 * Convert a map to a php Array
295 *
296 * @param t the map to convert
297 * @return the php Array
298 */
299zval *php_Array_from_map(map* t){
300  zval *mapArray;
301  zval *mapArrayTmp;
302  map* tmp=t;
303  int tres=0;
304  MAKE_STD_ZVAL(mapArray);
305  tres=array_init(mapArray);
306  while(tmp!=NULL){
307    map* sMap=getMapArray(tmp,"size",0);   
308        if(strncmp(tmp->name,"value",5)==0 && sMap!=NULL && tmp->value != NULL){
309      tres=add_assoc_stringl(mapArray,tmp->name,tmp->value,atoi(sMap->value),1);
310        } 
311        else if (tmp->value != NULL) {
312      tres=add_assoc_string(mapArray,tmp->name,tmp->value,1);
313        }
314    tmp=tmp->next;
315  }
316  return mapArray;
317}
318
319/**
320 * Convert a php Array to a maps
321 *
322 * @param t the php Array to convert
323 * @return the created maps
324 */
325maps* php_maps_from_Array(HashTable *t){
326  maps* final_res=NULL;
327  maps* cursor=final_res;
328  char key[1024];
329  for(zend_hash_internal_pointer_reset(t); 
330      zend_hash_has_more_elements(t) == SUCCESS; 
331      zend_hash_move_forward(t)) { 
332    char *key; 
333    uint keylen; 
334    ulong idx; 
335    int type; 
336    zval **ppzval, tmpcopy; 
337    type = zend_hash_get_current_key_ex(t, &key, &keylen, &idx, 0, NULL); 
338    if (zend_hash_get_current_data(t, (void**)&ppzval) == FAILURE) { 
339      /**
340       * Should never actually fail since the key is known to exist.
341       */
342      continue; 
343    }
344    /**
345     * Duplicate the zval so that * the orignal’s contents are not destroyed
346     */
347    tmpcopy = **ppzval;
348#ifdef DEBUG
349    fprintf(stderr,"key : %s\n",key);
350#endif
351    zval_copy_ctor(&tmpcopy); 
352#ifdef DEBUG
353    fprintf(stderr,"key : %s\n",key);
354#endif
355    /**
356     * Reset refcount & Convert
357     */
358    INIT_PZVAL(&tmpcopy); 
359    //convert_to_string(&tmpcopy);
360    if (type == HASH_KEY_IS_STRING) { 
361      /**
362       * String Key / Associative
363       */
364      cursor=(maps*)malloc(MAPS_SIZE);
365      cursor->name=strdup(key);
366    }
367#ifdef DEBUG   
368    fprintf(stderr,"key : %s\n",key);
369#endif 
370    HashTable* t=HASH_OF(*ppzval);
371#ifdef DEBUG
372    fprintf(stderr,"key : %s\n",key);
373#endif
374    cursor->content=php_map_from_HasTable(t);
375    cursor->next=NULL;
376    if(final_res==NULL)
377      final_res=cursor;
378    else{
379      addMapsToMaps(&final_res,cursor);
380      freeMaps(&cursor);
381      free(cursor);
382    }
383#ifdef DEBUG
384    fprintf(stderr,"key : %s\n",key);
385#endif
386    /**
387     * Toss out old copy
388     */
389    zval_dtor(&tmpcopy);
390  }
391  return final_res;
392}
393
394/**
395 * Convert a php Array to a map
396 *
397 * @param t the php Array to convert
398 * @return the created map
399 */
400map* php_map_from_HasTable(HashTable* t){
401#ifdef DEBUG
402  fprintf(stderr,"mapsFromPHPArray start\n");
403#endif
404  map* final_res=(map*)malloc(MAP_SIZE);
405  final_res=NULL;
406  char key[1024];
407  for(zend_hash_internal_pointer_reset(t);
408      zend_hash_has_more_elements(t) == SUCCESS;
409      zend_hash_move_forward(t)) {
410    char *key;
411    uint keylen;
412    ulong idx;
413    int type;
414    int len;
415    zval **ppzval, tmpcopy;
416    type = zend_hash_get_current_key_ex(t, &key, &keylen, &idx, 0, NULL); 
417    if (zend_hash_get_current_data(t, (void**)&ppzval) == FAILURE) { 
418      /* Should never actually fail * since the key is known to exist. */ 
419      continue; 
420    }
421    /**
422     * Duplicate the zval so that * the orignal’s contents are not destroyed
423     */ 
424    tmpcopy = **ppzval; 
425    zval_copy_ctor(&tmpcopy); 
426    /**
427     * Reset refcount & Convert
428     */ 
429    INIT_PZVAL(&tmpcopy); 
430    convert_to_string(&tmpcopy);
431    if(strncmp(key,"value",5)==0){
432      len=Z_STRLEN_P(&tmpcopy);     
433          final_res = addToMapWithSize(final_res,key,Z_STRVAL_P(&tmpcopy),len);
434    }
435    else{
436      if(final_res==NULL){
437#ifdef DEBUG
438        fprintf(stderr,"%s => %s\n",key,Z_STRVAL(tmpcopy));
439#endif
440        final_res=createMap(key,Z_STRVAL(tmpcopy));
441      }
442      else{
443#ifdef DEBUG
444        fprintf(stderr,"%s => %s\n",key,Z_STRVAL(tmpcopy));
445#endif
446        addToMap(final_res,key,Z_STRVAL(tmpcopy));
447      }
448    }
449    /* Toss out old copy */ 
450    zval_dtor(&tmpcopy); 
451  }
452  return final_res;
453}
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