root/ext/standard/link.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. PHP_FUNCTION
  2. PHP_FUNCTION
  3. PHP_FUNCTION
  4. PHP_FUNCTION

   1 /*
   2    +----------------------------------------------------------------------+
   3    | PHP Version 7                                                        |
   4    +----------------------------------------------------------------------+
   5    | Copyright (c) 1997-2016 The PHP Group                                |
   6    +----------------------------------------------------------------------+
   7    | This source file is subject to version 3.01 of the PHP license,      |
   8    | that is bundled with this package in the file LICENSE, and is        |
   9    | available through the world-wide-web at the following url:           |
  10    | http://www.php.net/license/3_01.txt                                  |
  11    | If you did not receive a copy of the PHP license and are unable to   |
  12    | obtain it through the world-wide-web, please send a note to          |
  13    | license@php.net so we can mail you a copy immediately.               |
  14    +----------------------------------------------------------------------+
  15    | Author:                                                              |
  16    +----------------------------------------------------------------------+
  17  */
  18 
  19 /* $Id$ */
  20 
  21 #include "php.h"
  22 #include "php_filestat.h"
  23 #include "php_globals.h"
  24 
  25 #ifdef HAVE_SYMLINK
  26 
  27 #include <stdlib.h>
  28 #if HAVE_UNISTD_H
  29 #include <unistd.h>
  30 #endif
  31 #include <sys/stat.h>
  32 #include <string.h>
  33 #if HAVE_PWD_H
  34 #ifdef PHP_WIN32
  35 #include "win32/pwd.h"
  36 #else
  37 #include <pwd.h>
  38 #endif
  39 #endif
  40 #if HAVE_GRP_H
  41 #ifdef PHP_WIN32
  42 #include "win32/grp.h"
  43 #else
  44 #include <grp.h>
  45 #endif
  46 #endif
  47 #include <errno.h>
  48 #include <ctype.h>
  49 
  50 #include "php_link.h"
  51 #include "php_string.h"
  52 
  53 /* {{{ proto string readlink(string filename)
  54    Return the target of a symbolic link */
  55 PHP_FUNCTION(readlink)
  56 {
  57         char *link;
  58         size_t link_len;
  59         char buff[MAXPATHLEN];
  60         int ret;
  61 
  62         if (zend_parse_parameters(ZEND_NUM_ARGS(), "p", &link, &link_len) == FAILURE) {
  63                 return;
  64         }
  65 
  66         if (php_check_open_basedir(link)) {
  67                 RETURN_FALSE;
  68         }
  69 
  70         ret = php_sys_readlink(link, buff, MAXPATHLEN-1);
  71 
  72         if (ret == -1) {
  73                 php_error_docref(NULL, E_WARNING, "%s", strerror(errno));
  74                 RETURN_FALSE;
  75         }
  76         /* Append NULL to the end of the string */
  77         buff[ret] = '\0';
  78 
  79         RETURN_STRING(buff);
  80 }
  81 /* }}} */
  82 
  83 /* {{{ proto int linkinfo(string filename)
  84    Returns the st_dev field of the UNIX C stat structure describing the link */
  85 PHP_FUNCTION(linkinfo)
  86 {
  87         char *link;
  88         char *dirname;
  89         size_t link_len;
  90         zend_stat_t sb;
  91         int ret;
  92 
  93         if (zend_parse_parameters(ZEND_NUM_ARGS(), "p", &link, &link_len) == FAILURE) {
  94                 return;
  95         }
  96 
  97         dirname = estrndup(link, link_len);
  98         php_dirname(dirname, link_len);
  99 
 100         if (php_check_open_basedir(dirname)) {
 101                 efree(dirname);
 102                 RETURN_FALSE;
 103         }
 104 
 105         ret = VCWD_LSTAT(link, &sb);
 106         if (ret == -1) {
 107                 php_error_docref(NULL, E_WARNING, "%s", strerror(errno));
 108                 efree(dirname);
 109                 RETURN_LONG(-1L);
 110         }
 111 
 112         efree(dirname);
 113         RETURN_LONG((zend_long) sb.st_dev);
 114 }
 115 /* }}} */
 116 
 117 /* {{{ proto int symlink(string target, string link)
 118    Create a symbolic link */
 119 PHP_FUNCTION(symlink)
 120 {
 121         char *topath, *frompath;
 122         size_t topath_len, frompath_len;
 123         int ret;
 124         char source_p[MAXPATHLEN];
 125         char dest_p[MAXPATHLEN];
 126         char dirname[MAXPATHLEN];
 127         size_t len;
 128 
 129         if (zend_parse_parameters(ZEND_NUM_ARGS(), "pp", &topath, &topath_len, &frompath, &frompath_len) == FAILURE) {
 130                 return;
 131         }
 132 
 133         if (!expand_filepath(frompath, source_p)) {
 134                 php_error_docref(NULL, E_WARNING, "No such file or directory");
 135                 RETURN_FALSE;
 136         }
 137 
 138         memcpy(dirname, source_p, sizeof(source_p));
 139         len = php_dirname(dirname, strlen(dirname));
 140 
 141         if (!expand_filepath_ex(topath, dest_p, dirname, len)) {
 142                 php_error_docref(NULL, E_WARNING, "No such file or directory");
 143                 RETURN_FALSE;
 144         }
 145 
 146         if (php_stream_locate_url_wrapper(source_p, NULL, STREAM_LOCATE_WRAPPERS_ONLY) ||
 147                 php_stream_locate_url_wrapper(dest_p, NULL, STREAM_LOCATE_WRAPPERS_ONLY) )
 148         {
 149                 php_error_docref(NULL, E_WARNING, "Unable to symlink to a URL");
 150                 RETURN_FALSE;
 151         }
 152 
 153         if (php_check_open_basedir(dest_p)) {
 154                 RETURN_FALSE;
 155         }
 156 
 157         if (php_check_open_basedir(source_p)) {
 158                 RETURN_FALSE;
 159         }
 160 
 161         /* For the source, an expanded path must be used (in ZTS an other thread could have changed the CWD).
 162          * For the target the exact string given by the user must be used, relative or not, existing or not.
 163          * The target is relative to the link itself, not to the CWD. */
 164         ret = symlink(topath, source_p);
 165 
 166         if (ret == -1) {
 167                 php_error_docref(NULL, E_WARNING, "%s", strerror(errno));
 168                 RETURN_FALSE;
 169         }
 170 
 171         RETURN_TRUE;
 172 }
 173 /* }}} */
 174 
 175 /* {{{ proto int link(string target, string link)
 176    Create a hard link */
 177 PHP_FUNCTION(link)
 178 {
 179         char *topath, *frompath;
 180         size_t topath_len, frompath_len;
 181         int ret;
 182         char source_p[MAXPATHLEN];
 183         char dest_p[MAXPATHLEN];
 184 
 185         if (zend_parse_parameters(ZEND_NUM_ARGS(), "pp", &topath, &topath_len, &frompath, &frompath_len) == FAILURE) {
 186                 return;
 187         }
 188 
 189         if (!expand_filepath(frompath, source_p) || !expand_filepath(topath, dest_p)) {
 190                 php_error_docref(NULL, E_WARNING, "No such file or directory");
 191                 RETURN_FALSE;
 192         }
 193 
 194         if (php_stream_locate_url_wrapper(source_p, NULL, STREAM_LOCATE_WRAPPERS_ONLY) ||
 195                 php_stream_locate_url_wrapper(dest_p, NULL, STREAM_LOCATE_WRAPPERS_ONLY) )
 196         {
 197                 php_error_docref(NULL, E_WARNING, "Unable to link to a URL");
 198                 RETURN_FALSE;
 199         }
 200 
 201         if (php_check_open_basedir(dest_p)) {
 202                 RETURN_FALSE;
 203         }
 204 
 205         if (php_check_open_basedir(source_p)) {
 206                 RETURN_FALSE;
 207         }
 208 
 209 #ifndef ZTS
 210         ret = link(topath, frompath);
 211 #else
 212         ret = link(dest_p, source_p);
 213 #endif
 214         if (ret == -1) {
 215                 php_error_docref(NULL, E_WARNING, "%s", strerror(errno));
 216                 RETURN_FALSE;
 217         }
 218 
 219         RETURN_TRUE;
 220 }
 221 /* }}} */
 222 
 223 #endif
 224 
 225 /*
 226  * Local variables:
 227  * tab-width: 4
 228  * c-basic-offset: 4
 229  * End:
 230  * vim600: noet sw=4 ts=4 fdm=marker
 231  * vim<600: noet sw=4 ts=4
 232  */

/* [<][>][^][v][top][bottom][index][help] */