/* +----------------------------------------------------------------------+ | PHP HTML Embedded Scripting Language Version 3.0 | +----------------------------------------------------------------------+ | Copyright (c) 1997-1999 PHP Development Team (See Credits file) | +----------------------------------------------------------------------+ | This program is free software; you can redistribute it and/or modify | | it under the terms of one of the following licenses: | | | | A) 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. | | | | B) the PHP License as published by the PHP Development Team and | | included in the distribution in the file: LICENSE | | | | 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 both licenses referred to here. | | If you did not, or have any questions about PHP licensing, please | | contact core@php.net. | +----------------------------------------------------------------------+ | Authors: Kristian Koehntopp | +----------------------------------------------------------------------+ */ /* $Id$ */ #include "php.h" #include "ext/standard/info.h" #if !defined(PHP_API_VERSION) || PHP_API_VERSION < 19990421 #include "internal_functions.h" #endif #if PHP_31 || PHP_API_VERSION >= 19990421 # include "ext/standard/php_string.h" #else # include "php_string.h" #endif #include "php_posix.h" #if HAVE_POSIX #ifdef HAVE_SYS_TIME_H #include #endif #include #include #include #include #include #include #include #include #include #include #if !defined(PHP_API_VERSION) || PHP_API_VERSION < 19990421 #include "php3_list.h" #endif #define SAFE_STRING(s) ((s)?(s):"") function_entry posix_functions[] = { /* POSIX.1, 3.3 */ PHP_FE(posix_kill, NULL) /* POSIX.1, 4.1 */ PHP_FE(posix_getpid, NULL) PHP_FE(posix_getppid, NULL) /* POSIX.1, 4.2 */ PHP_FE(posix_getuid, NULL) PHP_FE(posix_setuid, NULL) PHP_FE(posix_geteuid, NULL) PHP_FE(posix_seteuid, NULL) PHP_FE(posix_getgid, NULL) PHP_FE(posix_setgid, NULL) PHP_FE(posix_getegid, NULL) PHP_FE(posix_setegid, NULL) PHP_FE(posix_getgroups, NULL) PHP_FE(posix_getlogin, NULL) /* POSIX.1, 4.3 */ PHP_FE(posix_getpgrp, NULL) PHP_FE(posix_setsid, NULL) PHP_FE(posix_setpgid, NULL) /* Non-Posix functions which are common */ PHP_FE(posix_getpgid, NULL) PHP_FE(posix_getsid, NULL) /* POSIX.1, 4.4 */ PHP_FE(posix_uname, NULL) /* POSIX.1, 4.5 */ PHP_FE(posix_times, NULL) /* POSIX.1, 4.7 */ PHP_FE(posix_ctermid, NULL) PHP_FE(posix_ttyname, NULL) PHP_FE(posix_isatty, NULL) /* POSIX.1, 5.2 */ PHP_FE(posix_getcwd, NULL) /* POSIX.1, 5.4 */ PHP_FE(posix_mkfifo, NULL) /* POSIX.1, 9.2 */ PHP_FE(posix_getgrnam, NULL) PHP_FE(posix_getgrgid, NULL) PHP_FE(posix_getpwnam, NULL) PHP_FE(posix_getpwuid, NULL) PHP_FE(posix_getrlimit, NULL) {NULL, NULL, NULL} }; static PHP_MINFO_FUNCTION(posix); zend_module_entry posix_module_entry = { "posix", posix_functions, NULL, NULL, NULL, NULL, PHP_MINFO(posix), STANDARD_MODULE_PROPERTIES }; #ifdef COMPILE_DL_POSIX ZEND_GET_MODULE(posix) #endif static PHP_MINFO_FUNCTION(posix) { php_info_print_table_start(); php_info_print_table_row(2, "Revision", "$Revision$"); php_info_print_table_end(); } /* {{{ proto int posix_kill(int pid, int sig) Send a signal to a process (POSIX.1, 3.3.2) */ PHP_FUNCTION(posix_kill) { pval *pid; pval *sig; int result; if (ZEND_NUM_ARGS() != 2 || zend_get_parameters(ht, 2, &pid, &sig)==FAILURE) { WRONG_PARAM_COUNT; } convert_to_long(pid); convert_to_long(sig); result = kill(pid->value.lval, sig->value.lval); if (result< 0) { php_error(E_WARNING, "posix_kill(%d, %d) failed with '%s'", pid->value.lval, sig->value.lval, strerror(errno)); RETURN_FALSE; } RETURN_TRUE; } /* }}} */ /* {{{ proto long posix_getpid(void) Get the current process id (POSIX.1, 4.1.1) */ PHP_FUNCTION(posix_getpid) { pid_t pid; pid = getpid(); RETURN_LONG(pid); } /* }}} */ /* {{{ proto long posix_getppid(void) Get the parent process id (POSIX.1, 4.1.1) */ PHP_FUNCTION(posix_getppid) { pid_t ppid; ppid = getppid(); RETURN_LONG(ppid); } /* }}} */ /* {{{ proto long posix_getuid(void) Get the current user id (POSIX.1, 4.2.1) */ PHP_FUNCTION(posix_getuid) { uid_t uid; uid = getuid(); RETURN_LONG(uid); } /* }}} */ /* {{{ proto long posix_getgid(void) Get the current group id (POSIX.1, 4.2.1) */ PHP_FUNCTION(posix_getgid) { gid_t gid; gid = getgid(); RETURN_LONG(gid); } /* }}} */ /* {{{ proto long posix_geteuid(void) Get the current effective user id (POSIX.1, 4.2.1) */ PHP_FUNCTION(posix_geteuid) { uid_t uid; uid = geteuid(); RETURN_LONG(uid); } /* }}} */ /* {{{ proto long posix_getegid(void) Get the current effective group id (POSIX.1, 4.2.1) */ PHP_FUNCTION(posix_getegid) { gid_t gid; gid = getegid(); RETURN_LONG(gid); } /* }}} */ /* {{{ proto long posix_setuid(long uid) Set user id (POSIX.1, 4.2.2) */ PHP_FUNCTION(posix_setuid) { pval *uid; int result; if (ZEND_NUM_ARGS() != 1 || zend_get_parameters(ht, 1, &uid)==FAILURE) { WRONG_PARAM_COUNT; } convert_to_long(uid); result = setuid(uid->value.lval); if (result < 0) { php_error(E_WARNING, "posix_setuid(%d) failed with '%s'. Must be root", uid->value.lval, strerror(errno)); RETURN_FALSE; } RETURN_TRUE; } /* }}} */ /* {{{ proto long posix_setgid(long uid) Set group id (POSIX.1, 4.2.2) */ PHP_FUNCTION(posix_setgid) { pval *gid; int result; if (ZEND_NUM_ARGS() != 1 || zend_get_parameters(ht, 1, &gid)==FAILURE) { WRONG_PARAM_COUNT; } convert_to_long(gid); result = setgid(gid->value.lval); if (result < 0) { php_error(E_WARNING, "posix_setgid(%d) failed with '%s'. Must be root", gid->value.lval, strerror(errno)); RETURN_FALSE; } RETURN_TRUE; } /* }}} */ /* {{{ proto long posix_seteuid(long uid) Set effective user id */ PHP_FUNCTION(posix_seteuid) { #ifdef HAVE_SETEUID pval *uid; int result; if (ZEND_NUM_ARGS() != 1 || zend_get_parameters(ht, 1, &uid)==FAILURE) { WRONG_PARAM_COUNT; } convert_to_long(uid); result = seteuid(uid->value.lval); if (result < 0) { php_error(E_WARNING, "posix_setuid(%d) failed with '%s'.", uid->value.lval, strerror(errno)); RETURN_FALSE; } RETURN_TRUE; #else RETURN_FALSE; #endif } /* }}} */ /* {{{ proto long posix_setegid(long uid) Set effective group id */ PHP_FUNCTION(posix_setegid) { #ifdef HAVE_SETEGID pval *gid; int result; if (ZEND_NUM_ARGS() != 1 || zend_get_parameters(ht, 1, &gid)==FAILURE) { WRONG_PARAM_COUNT; } convert_to_long(gid); result = setegid(gid->value.lval); if (result < 0) { php_error(E_WARNING, "posix_setgid(%d) failed with '%s'.", gid->value.lval, strerror(errno)); RETURN_FALSE; } RETURN_TRUE; #else RETURN_FALSE; #endif } /* }}} */ /* {{{ proto long posix_getgroups(void) Get supplementary group id's (POSIX.1, 4.2.3) */ PHP_FUNCTION(posix_getgroups) { gid_t gidlist[NGROUPS_MAX]; int result; int i; result = getgroups(NGROUPS_MAX, gidlist); if (result < 0) { php_error(E_WARNING, "posix_getgroups() failed with '%s'", strerror(errno)); RETURN_FALSE; } if (array_init(return_value) == FAILURE) { RETURN_FALSE; } for (i=0; ivalue.lval, pgid->value.lval); if (result< 0) { php_error(E_WARNING, "posix_setpgid(%d, %d) failed with '%s'", pid->value.lval, pgid->value.lval, strerror(errno)); RETURN_FALSE; } RETURN_LONG(result); } /* }}} */ /* {{{ proto long posix_getpgid(void) Get the process group id of the specified process (This is not a POSIX function, but a SVR4ism, so we compile conditionally) */ PHP_FUNCTION(posix_getpgid) { #ifdef HAVE_GETPGID pid_t pgid; pval *pid; if (ZEND_NUM_ARGS() != 1 || zend_get_parameters(ht, 1, &pid)==FAILURE) { WRONG_PARAM_COUNT; } convert_to_long(pid); pgid = getpgid(pid->value.lval); if (pgid < 0) { php_error(E_WARNING, "posix_getpgid(%d) failed with '%s'", pid->value.lval, strerror(errno)); RETURN_FALSE; } return_value->type= IS_LONG; return_value->value.lval = pgid; #else RETURN_FALSE; #endif } /* }}} */ /* {{{ proto long posix_getsid(void) Get process group id of session leader (This is not a POSIX function, but a SVR4ism, so be compile conditionally) */ PHP_FUNCTION(posix_getsid) { #ifdef HAVE_GETSID pid_t sid; pval *pid; if (ZEND_NUM_ARGS() != 1 || zend_get_parameters(ht, 1, &pid)==FAILURE) { WRONG_PARAM_COUNT; } convert_to_long(pid); sid = getsid(pid->value.lval); if (sid < 0) { php_error(E_WARNING, "posix_getsid(%d) failed with '%s'", pid->value.lval, strerror(errno)); RETURN_FALSE; } return_value->type= IS_LONG; return_value->value.lval = sid; #else RETURN_FALSE; #endif } /* }}} */ /* {{{ proto array posix_uname(void) Get system name (POSIX.1, 4.4.1) */ PHP_FUNCTION(posix_uname) { struct utsname u; uname(&u); if (array_init(return_value) == FAILURE) { RETURN_FALSE; } add_assoc_string(return_value, "sysname", u.sysname, 1); add_assoc_string(return_value, "nodename", u.nodename, 1); add_assoc_string(return_value, "release", u.release, 1); add_assoc_string(return_value, "version", u.version, 1); add_assoc_string(return_value, "machine", u.machine, 1); } /* }}} */ /* POSIX.1, 4.5.1 time() - Get System Time already covered by PHP */ /* {{{ proto array posix_times(void) Get process times (POSIX.1, 4.5.2) */ PHP_FUNCTION(posix_times) { struct tms t; clock_t ticks; ticks = times(&t); if (ticks < 0) { php_error(E_WARNING, "posix_times failed with '%s'", strerror(errno)); } if (array_init(return_value) == FAILURE) { RETURN_FALSE; } add_assoc_long(return_value, "ticks", ticks); add_assoc_long(return_value, "utime", t.tms_utime); add_assoc_long(return_value, "stime", t.tms_stime); add_assoc_long(return_value, "cutime", t.tms_cutime); add_assoc_long(return_value, "cstime", t.tms_cstime); } /* }}} */ /* POSIX.1, 4.6.1 getenv() - Environment Access already covered by PHP */ /* {{{ proto string posix_ctermid(void) Generate terminal path name (POSIX.1, 4.7.1) */ PHP_FUNCTION(posix_ctermid) { #ifdef HAVE_CTERMID char buffer[L_ctermid]; char *p; p = ctermid(buffer); if (p == NULL) { php_error(E_WARNING, "posix_ctermid() failed with '%s'", strerror(errno)); RETURN_FALSE; } RETURN_STRING(buffer, 1); #else RETURN_FALSE; #endif } /* }}} */ /* {{{ proto string posix_ttyname(int fd) Determine terminal device name (POSIX.1, 4.7.2) */ PHP_FUNCTION(posix_ttyname) { pval *fd; char *p; if (ZEND_NUM_ARGS() != 1 || zend_get_parameters(ht, 1, &fd)==FAILURE) { WRONG_PARAM_COUNT; } convert_to_long(fd); p = ttyname(fd->value.lval); if (p == NULL) { php_error(E_WARNING, "posix_ttyname(%d) failed with '%s'", fd->value.lval, strerror(errno)); RETURN_FALSE; } RETURN_STRING(p, 1); } /* }}} */ /* {{{ proto bool posix_isatty(int fd) Determine if filedesc is a tty (POSIX.1, 4.7.1) */ PHP_FUNCTION(posix_isatty) { pval *fd; int result; if (ZEND_NUM_ARGS() != 1 || zend_get_parameters(ht, 1, &fd)==FAILURE) { WRONG_PARAM_COUNT; } convert_to_long(fd); result = isatty(fd->value.lval); if (!result) RETURN_FALSE; RETURN_TRUE; } /* }}} */ /* POSIX.1, 4.8.1 sysconf() - TODO POSIX.1, 5.7.1 pathconf(), fpathconf() - TODO POSIX.1, 5.1.2 opendir(), readdir(), rewinddir(), closedir() POSIX.1, 5.2.1 chdir() already supported by PHP */ /* {{{ proto string posix_getcwd(void) Get working directory pathname (POSIX.1, 5.2.2) */ PHP_FUNCTION(posix_getcwd) { char buffer[MAXPATHLEN]; char *p; p = V_GETCWD(buffer, MAXPATHLEN); if (!p) { php_error(E_WARNING, "posix_getcwd() failed with '%s'", strerror(errno)); RETURN_FALSE; } RETURN_STRING(buffer, 1); } /* }}} */ /* POSIX.1, 5.3.x open(), creat(), umask() POSIX.1, 5.4.1 link() already supported by PHP. */ /* {{{ proto string posix_mkfifo(void) Make a FIFO special file (POSIX.1, 5.4.2) */ PHP_FUNCTION(posix_mkfifo) { #ifdef HAVE_MKFIFO pval *path; pval *mode; int result; PLS_FETCH(); if (ZEND_NUM_ARGS() != 2 || zend_get_parameters(ht, 2, &path, &mode) == FAILURE) { WRONG_PARAM_COUNT; } convert_to_string(path); convert_to_long(mode); if (PG(safe_mode) && (!php_checkuid(path->value.str.val, NULL, 3))) { RETURN_FALSE; } result = mkfifo(path->value.str.val, mode->value.lval); if (result < 0) { php_error(E_WARNING, "posix_mkfifo(%s) failed with '%s'", path->value.str.val, strerror(errno)); RETURN_FALSE; } RETURN_TRUE; #else RETURN_FALSE; #endif } /* POSIX.1, 5.5.1 unlink() POSIX.1, 5.5.2 rmdir() POSIX.1, 5.5.3 rename() POSIX.1, 5.6.x stat(), access(), chmod(), utime() already supported by PHP (access() not supported, because it is braindead and dangerous and gives outdated results). POSIX.1, 6.x most I/O functions already supported by PHP. POSIX.1, 7.x tty functions, TODO POSIX.1, 8.x interactions with other C language functions POSIX.1, 9.x system database access */ /* {{{ proto array posix_getgrnam(string groupname) Group database access (POSIX.1, 9.2.1) */ PHP_FUNCTION(posix_getgrnam) { pval *name; char buffer[10]; struct group *g; char **p; int count; if (ZEND_NUM_ARGS() != 1 || zend_get_parameters(ht, 1, &name)==FAILURE) { WRONG_PARAM_COUNT; } convert_to_string(name); g = getgrnam(name->value.str.val); if (!g) { php_error(E_WARNING, "posix_getgrnam(%s) failed with '%s'", name->value.str.val, strerror(errno)); RETURN_FALSE; } if (array_init(return_value) == FAILURE) { RETURN_FALSE; } add_assoc_string(return_value, "name", g->gr_name, 1); add_assoc_long (return_value, "gid", g->gr_gid); for (count=0, p=g->gr_mem; p[count] != NULL; count++) { snprintf(buffer, 10, "%d", count); add_assoc_string(return_value, buffer, p[count], 1); } add_assoc_long(return_value, "members", count); } /* }}} */ /* {{{ proto array posix_getgrgid(long gid) Group database access (POSIX.1, 9.2.1) */ PHP_FUNCTION(posix_getgrgid) { pval *gid; char buffer[10]; struct group *g; char **p; int count; if (ZEND_NUM_ARGS() != 1 || zend_get_parameters(ht, 1, &gid)==FAILURE) { WRONG_PARAM_COUNT; } convert_to_long(gid); g = getgrgid(gid->value.lval); if (!g) { php_error(E_WARNING, "posix_getgrgid(%d) failed with '%s'", gid->value.lval, strerror(errno)); RETURN_FALSE; } if (array_init(return_value) == FAILURE) { RETURN_FALSE; } add_assoc_string(return_value, "name", g->gr_name, 1); add_assoc_long (return_value, "gid", g->gr_gid); for (count=0, p=g->gr_mem; p[count] != NULL; count++) { snprintf(buffer, 10, "%d", count); add_assoc_string(return_value, buffer, p[count], 1); } add_assoc_long(return_value, "members", count); } /* }}} */ /* {{{ proto array posix_getpwnam(string groupname) User database access (POSIX.1, 9.2.2) */ PHP_FUNCTION(posix_getpwnam) { pval *name; struct passwd *pw; if (ZEND_NUM_ARGS() != 1 || zend_get_parameters(ht, 1, &name)==FAILURE) { WRONG_PARAM_COUNT; } convert_to_string(name); pw = getpwnam(name->value.str.val); if (!pw) { php_error(E_WARNING, "posix_getpwnam(%s) failed with '%s'", name->value.str.val, strerror(errno)); RETURN_FALSE; } if (array_init(return_value) == FAILURE) { RETURN_FALSE; } add_assoc_string(return_value, "name", pw->pw_name, 1); add_assoc_string(return_value, "passwd", pw->pw_passwd, 1); add_assoc_long (return_value, "uid", pw->pw_uid); add_assoc_long (return_value, "gid", pw->pw_gid); add_assoc_string(return_value, "gecos", pw->pw_gecos, 1); add_assoc_string(return_value, "dir", pw->pw_dir, 1); add_assoc_string(return_value, "shell", pw->pw_shell, 1); } /* }}} */ /* {{{ proto array posix_getpwuid(long uid) User database access (POSIX.1, 9.2.2) */ PHP_FUNCTION(posix_getpwuid) { pval *uid; struct passwd *pw; if (ZEND_NUM_ARGS() != 1 || zend_get_parameters(ht, 1, &uid)==FAILURE) { WRONG_PARAM_COUNT; } convert_to_long(uid); pw = getpwuid(uid->value.lval); if (!pw) { php_error(E_WARNING, "posix_getpwuid(%d) failed with '%s'", uid->value.lval, strerror(errno)); RETURN_FALSE; } if (array_init(return_value) == FAILURE) { RETURN_FALSE; } add_assoc_string(return_value, "name", pw->pw_name, 1); add_assoc_string(return_value, "passwd", pw->pw_passwd, 1); add_assoc_long (return_value, "uid", pw->pw_uid); add_assoc_long (return_value, "gid", pw->pw_gid); add_assoc_string(return_value, "gecos", pw->pw_gecos, 1); add_assoc_string(return_value, "dir", pw->pw_dir, 1); add_assoc_string(return_value, "shell", pw->pw_shell, 1); } /* }}} */ #ifdef HAVE_GETRLIMIT static int posix_addlimit(int limit, char *name, pval *return_value) { int result; struct rlimit rl; char hard[80]; char soft[80]; snprintf(hard, 80, "hard %s", name); snprintf(soft, 80, "soft %s", name); result = getrlimit(limit, &rl); if (result < 0) { php_error(E_WARNING, "posix_getrlimit failed to getrlimit(RLIMIT_CORE with '%s'", strerror(errno)); return FAILURE; } if (rl.rlim_cur == RLIM_INFINITY) add_assoc_string(return_value,soft,"unlimited", 1); else add_assoc_long(return_value,soft,rl.rlim_cur); if (rl.rlim_max == RLIM_INFINITY) add_assoc_string(return_value,hard,"unlimited", 1); else add_assoc_long(return_value,hard,rl.rlim_max); return SUCCESS; } struct limitlist { int limit; char *name; } limits[] = { #ifdef RLIMIT_CORE { RLIMIT_CORE, "core" }, #endif #ifdef RLIMIT_DATA { RLIMIT_DATA, "data" }, #endif #ifdef RLIMIT_STACK { RLIMIT_STACK, "stack" }, #endif #ifdef RLIMIT_VMEM { RLIMIT_VMEM, "virtualmem" }, #endif #ifdef RLIMIT_AS { RLIMIT_AS, "totalmem" }, #endif #ifdef RLIMIT_RSS { RLIMIT_RSS, "rss" }, #endif #ifdef RLIMIT_NPROC { RLIMIT_NPROC, "maxproc" }, #endif #ifdef RLIMIT_MEMLOCK { RLIMIT_MEMLOCK, "memlock" }, #endif #ifdef RLIMIT_CPU { RLIMIT_CPU, "cpu" }, #endif #ifdef RLIMIT_FSIZE { RLIMIT_FSIZE, "filesize" }, #endif #ifdef RLIMIT_NOFILE { RLIMIT_NOFILE, "openfiles" }, #endif #ifdef RLIMIT_OFILE { RLIMIT_OFILE, "openfiles" }, #endif { 0, NULL } }; #endif /* HAVE_GETRLIMIT */ /* {{{ proto long posix_getrlimit(void) Get system resource consumption limits (This is not a POSIX function, but a BSDism and a SVR4ism. We compile conditionally) */ PHP_FUNCTION(posix_getrlimit) { #ifdef HAVE_GETRLIMIT struct limitlist *l = NULL; if (array_init(return_value) == FAILURE) { RETURN_FALSE; } for (l=limits; l->name; l++) { if (posix_addlimit(l->limit, l->name, return_value) == FAILURE) RETURN_FALSE; } #else RETURN_FALSE; #endif } /* }}} */ #endif /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: */