Problems of PHP as system-wide scripting tool

From: Date: Tue, 14 Dec 1999 00:20:41 +0000
Subject: Problems of PHP as system-wide scripting tool
Groups: php.dev 
Request: Send a blank email to php-dev+get-14434@lists.php.net to get a copy of this message
PHP is great language and I wanted to use it as system-wide scripting tool. Ok, it looks easy: CGI version with -q will give you such functionality. But there are few glitches with argument handling. I'll show them with trivial script: -- cut -- #!/usr/bin/php -q <?php while ( list( $argnum, $argval ) = each ( $argv ) ) { echo "argv[$argnum]=\"$argval\"\n"; } ?> -- cut -- 1. You can not use arguments with "+". "php-demo A+B" will give you the following result: -- cut -- argv[0]="/home/khim/bin/php-demo" argv[1]="A" argv[2]="B" -- cut -- 2. If you have QUERY_STRING in your system environment then you can not access script parameters from your PHP-script at all :-/ On first glance it does not look like a big problem but if PHP-scripts are used as "plain" system programs then evntually someone will call script from some other CGI-script and will get strange and unexpected result. 3. Options handling. All options known to PHP will be hidden from script view while processed by PHP ! "php-demo -s" will give you nicely formatted source of script :-/ 4. Current directory. Current directory is not what it was before starting of script but directory where script is placed instead ! If reletave path is used (like ../bin/test.php) then executing will fail... All problems are minor but annoying. I created patch to make PHP more usable as system-wide scripting language. When you are using -q option (or -f option) QUERY_STRING will not be parsed and "+" will not be treated specially. And addition of "+" in getopt call will make safe usage of script arguments possible ... What to do with "4" I'm not know: I removed chdir() call at all but may be it's not best solution...

--- main.c Fri Nov 5 20:52:00 1999 +++ main.c Mon Nov 29 23:34:08 1999 @@ -104,6 +104,9 @@ void _php3_build_argv(char * ELS_DC); +#if ! APACHE +void _php3_build_argv_from_real_argv(int argc, char *argv[] ELS_DC); +#endif static void php3_timeout(int dummy); static void php3_set_timeout(long seconds); @@ -1086,13 +1089,56 @@ } #endif - +#if ! APACHE + if (SG(request_info).use_real_argv) + _php3_build_argv_from_real_argv(SG(request_info).argc, SG(request_info).argv ELS_CC); + else +#endif /* need argc/argv support as well */ _php3_build_argv(SG(request_info).query_string ELS_CC); return SUCCESS; } +#if ! APACHE +void _php3_build_argv_from_real_argv(int argc, char *argv[] ELS_DC) +{ + pval *arr, *tmp; + int count = 0; + int i, len; + + arr = (pval *) emalloc(sizeof(pval)); + arr->value.ht = (HashTable *) emalloc(sizeof(HashTable)); + if (zend_hash_init(arr->value.ht, 0, NULL, PVAL_PTR_DTOR, 0) == FAILURE) { + php_error(E_WARNING, "Unable to create argv array"); + } else { + arr->type = IS_ARRAY; + INIT_PZVAL(arr); + zend_hash_update(&EG(symbol_table), "argv", sizeof("argv"), &arr, sizeof(pval *), NULL); + } + /* now pick out individual entries */ + for (i = optind, len = 0; i < argc; i++) { + /* auto-type */ + tmp = (pval *) emalloc(sizeof(pval)); + tmp->type = IS_STRING; + tmp->value.str.len = strlen(argv[i]); + tmp->value.str.val = estrndup(argv[i], tmp->value.str.len); + INIT_PZVAL(tmp); + count++; + if (zend_hash_next_index_insert(arr->value.ht, &tmp, sizeof(pval *), NULL)==FAILURE) { + if (tmp->type == IS_STRING) { + efree(tmp->value.str.val); + } + } + } + tmp = (pval *) emalloc(sizeof(pval)); + tmp->value.lval = count; + tmp->type = IS_LONG; + INIT_PZVAL(tmp); + zend_hash_add(&EG(symbol_table), "argc", sizeof("argc"), &tmp, sizeof(pval *), NULL); +} +#endif + void _php3_build_argv(char *s ELS_DC) { pval *arr, *tmp; --- SAPI.h Fri Sep 17 03:18:15 1999 +++ SAPI.h Mon Nov 29 23:29:09 1999 @@ -75,6 +75,11 @@ /* for HTTP authentication */ char *auth_user; char *auth_password; +#if ! APACHE + /* Will be used when query_string or when -q is used */ + int argc; char **argv; + unsigned char use_real_argv; +#endif } sapi_request_info; --- sapi/cgi/cgi_main.c Sat Oct 16 15:57:52 1999 +++ sapi/cgi/cgi_main.c Mon Nov 29 23:31:17 1999 @@ -164,7 +164,8 @@ " [-s]" " [-v] [-i] [-f <file>] | " "{<file> [args...]}\n" - " -q Quiet-mode. Suppress HTTP Header output.\n" + " -q Quiet-mode. Suppress HTTP Header output. Do not parse\n" + " QUERY_STRING to get argv. Use \"real\" argv instead.\n" " -s Display colour syntax highlighted source.\n" " -f<file> Parse <file>. Implies `-q'\n" " -v Version number\n" @@ -179,7 +180,7 @@ } -static void init_request_info(SLS_D) +static void init_request_info(int argc, char *argv[] SLS_DC) { char *content_length = getenv("CONTENT_LENGTH"); @@ -193,6 +194,10 @@ /* CGI does not support HTTP authentication */ SG(request_info).auth_user = NULL; SG(request_info).auth_password = NULL; + + SG(request_info).use_real_argv = 0; + SG(request_info).argc = argc; + SG(request_info).argv = argv; } @@ -301,13 +306,13 @@ #endif SG(request_info).path_translated = NULL; - init_request_info(SLS_C); + init_request_info(argc, argv SLS_CC); SG(server_context) = (void *) 1; /* avoid server_context==NULL checks */ CG(extended_info) = 0; if (!cgi) { /* never execute the arguments if you are a CGI */ request_info.php_argv0 = NULL; - while ((c = getopt(argc, argv, "c:d:qvisnaeh?vf:")) != -1) { + while ((c = getopt(argc, argv, "+c:d:qvisnaeh?vf:")) != -1) { switch (c) { case 'f': if (!cgi_started){ @@ -323,6 +328,7 @@ SG(request_info).path_translated = estrdup(optarg); /* break missing intentionally */ case 'q': + SG(request_info).use_real_argv = 1; no_headers = 1; break; case 'v': --- fopen-wrappers.c Thu Nov 11 16:49:42 1999 +++ fopen-wrappers.c Mon Nov 29 23:31:17 1999 @@ -212,7 +212,7 @@ { FILE *fp; struct stat st; - char *temp, *path_info, *fn; + char *path_info, *fn; int l; PLS_FETCH(); SLS_FETCH(); @@ -294,12 +294,6 @@ return NULL; } - temp = estrdup(fn); - php_dirname(temp, strlen(temp)); - if (*temp) { - chdir(temp); - } - efree(temp); SG(request_info).path_translated = fn; return fp;
« previous php.dev (#14434) next »