1 : /*
2 : +----------------------------------------------------------------------+
3 : | PHP Version 6 |
4 : +----------------------------------------------------------------------+
5 : | Copyright (c) 1997-2009 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: Jim Winstead <jimw@php.net> |
16 : +----------------------------------------------------------------------+
17 : */
18 :
19 : /* $Id: filestat.c 290190 2009-11-03 21:21:34Z guenter $ */
20 :
21 : #include "php.h"
22 : #include "fopen_wrappers.h"
23 : #include "php_globals.h"
24 : #include "ext/standard/file.h"
25 :
26 : #include <stdlib.h>
27 : #include <sys/stat.h>
28 : #include <string.h>
29 : #include <errno.h>
30 : #include <ctype.h>
31 : #include <time.h>
32 :
33 : #if HAVE_UNISTD_H
34 : # include <unistd.h>
35 : #endif
36 :
37 : #if HAVE_SYS_PARAM_H
38 : # include <sys/param.h>
39 : #endif
40 :
41 : #if HAVE_SYS_VFS_H
42 : # include <sys/vfs.h>
43 : #endif
44 :
45 : #ifdef OS2
46 : # define INCL_DOS
47 : # include <os2.h>
48 : #endif
49 :
50 : #if defined(HAVE_SYS_STATVFS_H) && defined(HAVE_STATVFS)
51 : # include <sys/statvfs.h>
52 : #elif defined(HAVE_SYS_STATFS_H) && defined(HAVE_STATFS)
53 : # include <sys/statfs.h>
54 : #elif defined(HAVE_SYS_MOUNT_H) && defined(HAVE_STATFS)
55 : # include <sys/mount.h>
56 : #endif
57 :
58 : #if HAVE_PWD_H
59 : # ifdef PHP_WIN32
60 : # include "win32/pwd.h"
61 : # else
62 : # include <pwd.h>
63 : # endif
64 : #endif
65 :
66 : #if HAVE_GRP_H
67 : # ifdef PHP_WIN32
68 : # include "win32/grp.h"
69 : # else
70 : # include <grp.h>
71 : # endif
72 : #endif
73 :
74 : #if HAVE_UTIME
75 : # ifdef PHP_WIN32
76 : # include <sys/utime.h>
77 : # else
78 : # include <utime.h>
79 : # endif
80 : #endif
81 :
82 : #ifdef PHP_WIN32
83 : #include "win32/winutil.h"
84 : #endif
85 :
86 : #include "basic_functions.h"
87 : #include "php_filestat.h"
88 :
89 : #ifndef S_ISDIR
90 : #define S_ISDIR(mode) (((mode)&S_IFMT) == S_IFDIR)
91 : #endif
92 : #ifndef S_ISREG
93 : #define S_ISREG(mode) (((mode)&S_IFMT) == S_IFREG)
94 : #endif
95 : #ifndef S_ISLNK
96 : #define S_ISLNK(mode) (((mode)&S_IFMT) == S_IFLNK)
97 : #endif
98 :
99 : #define S_IXROOT ( S_IXUSR | S_IXGRP | S_IXOTH )
100 :
101 : PHP_RINIT_FUNCTION(filestat) /* {{{ */
102 16993 : {
103 16993 : BG(CurrentStatFile)=NULL;
104 16993 : BG(CurrentLStatFile)=NULL;
105 16993 : return SUCCESS;
106 : }
107 : /* }}} */
108 :
109 : PHP_RSHUTDOWN_FUNCTION(filestat) /* {{{ */
110 17025 : {
111 17025 : if (BG(CurrentStatFile)) {
112 366 : efree (BG(CurrentStatFile));
113 366 : BG(CurrentStatFile) = NULL;
114 : }
115 17025 : if (BG(CurrentLStatFile)) {
116 29 : efree (BG(CurrentLStatFile));
117 29 : BG(CurrentLStatFile) = NULL;
118 : }
119 17025 : return SUCCESS;
120 : }
121 : /* }}} */
122 :
123 : static int php_disk_total_space(char *path, double *space TSRMLS_DC) /* {{{ */
124 : #if defined(WINDOWS) /* {{{ */
125 : {
126 : double bytestotal = 0;
127 : HINSTANCE kernel32;
128 : FARPROC gdfse;
129 : typedef BOOL (WINAPI *gdfse_func)(LPCTSTR, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER);
130 : gdfse_func func;
131 :
132 : /* These are used by GetDiskFreeSpaceEx, if available. */
133 : ULARGE_INTEGER FreeBytesAvailableToCaller;
134 : ULARGE_INTEGER TotalNumberOfBytes;
135 : ULARGE_INTEGER TotalNumberOfFreeBytes;
136 :
137 : /* These are used by GetDiskFreeSpace otherwise. */
138 : DWORD SectorsPerCluster;
139 : DWORD BytesPerSector;
140 : DWORD NumberOfFreeClusters;
141 : DWORD TotalNumberOfClusters;
142 :
143 : /* GetDiskFreeSpaceEx is only available in NT and Win95 post-OSR2,
144 : so we have to jump through some hoops to see if the function
145 : exists. */
146 : kernel32 = LoadLibrary("kernel32.dll");
147 : if (kernel32) {
148 : gdfse = GetProcAddress(kernel32, "GetDiskFreeSpaceExA");
149 : /* It's available, so we can call it. */
150 : if (gdfse) {
151 : func = (gdfse_func)gdfse;
152 : if (func(path,
153 : &FreeBytesAvailableToCaller,
154 : &TotalNumberOfBytes,
155 : &TotalNumberOfFreeBytes) == 0) {
156 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", php_win_err());
157 : return FAILURE;
158 : }
159 :
160 : /* i know - this is ugly, but i works <thies@thieso.net> */
161 : bytestotal = TotalNumberOfBytes.HighPart *
162 : (double) (((unsigned long)1) << 31) * 2.0 +
163 : TotalNumberOfBytes.LowPart;
164 : } else { /* If it's not available, we just use GetDiskFreeSpace */
165 : if (GetDiskFreeSpace(path,
166 : &SectorsPerCluster, &BytesPerSector,
167 : &NumberOfFreeClusters, &TotalNumberOfClusters) == 0) {
168 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", php_win_err());
169 : return FAILURE;
170 : }
171 : bytestotal = (double)TotalNumberOfClusters * (double)SectorsPerCluster * (double)BytesPerSector;
172 : }
173 : } else {
174 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to load kernel32.dll");
175 : return FAILURE;
176 : }
177 :
178 : *space = bytestotal;
179 : return SUCCESS;
180 : }
181 : /* }}} */
182 : #elif defined(OS2) /* {{{ */
183 : {
184 : double bytestotal = 0;
185 : FSALLOCATE fsinfo;
186 : char drive = path[0] & 95;
187 :
188 : if (DosQueryFSInfo( drive ? drive - 64 : 0, FSIL_ALLOC, &fsinfo, sizeof( fsinfo ) ) == 0) {
189 : bytestotal = (double)fsinfo.cbSector * fsinfo.cSectorUnit * fsinfo.cUnit;
190 : *space = bytestotal;
191 : return SUCCESS;
192 : }
193 : return FAILURE;
194 : }
195 : /* }}} */
196 : #else /* {{{ if !defined(OS2) && !defined(WINDOWS) */
197 23 : {
198 23 : double bytestotal = 0;
199 : #if defined(HAVE_SYS_STATVFS_H) && defined(HAVE_STATVFS)
200 : struct statvfs buf;
201 : #elif (defined(HAVE_SYS_STATFS_H) || defined(HAVE_SYS_MOUNT_H)) && defined(HAVE_STATFS)
202 : struct statfs buf;
203 : #endif
204 :
205 : #if defined(HAVE_SYS_STATVFS_H) && defined(HAVE_STATVFS)
206 23 : if (statvfs(path, &buf)) {
207 3 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", strerror(errno));
208 3 : return FAILURE;
209 : }
210 20 : if (buf.f_frsize) {
211 20 : bytestotal = (((double)buf.f_blocks) * ((double)buf.f_frsize));
212 : } else {
213 0 : bytestotal = (((double)buf.f_blocks) * ((double)buf.f_bsize));
214 : }
215 :
216 : #elif (defined(HAVE_SYS_STATFS_H) || defined(HAVE_SYS_MOUNT_H)) && defined(HAVE_STATFS)
217 : if (statfs(path, &buf)) {
218 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", strerror(errno));
219 : return FAILURE;
220 : }
221 : bytestotal = (((double)buf.f_bsize) * ((double)buf.f_blocks));
222 : #endif
223 :
224 20 : *space = bytestotal;
225 20 : return SUCCESS;
226 : }
227 : #endif
228 : /* }}} */
229 : /* }}} */
230 :
231 : /* {{{ proto float disk_total_space(string path) U
232 : Get total disk space for filesystem that path is on */
233 : PHP_FUNCTION(disk_total_space)
234 26 : {
235 : char *path;
236 : int path_len;
237 : zend_uchar path_type;
238 : double bytestotal;
239 :
240 26 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "t", &path, &path_len, &path_type) == FAILURE) {
241 3 : return;
242 : }
243 :
244 23 : if (path_type == IS_UNICODE) {
245 22 : if (FAILURE == php_stream_path_encode(NULL, &path, &path_len, (UChar*)path, path_len, REPORT_ERRORS, FG(default_context))) {
246 0 : RETURN_FALSE;
247 : }
248 : }
249 :
250 23 : if (php_check_open_basedir(path TSRMLS_CC)) {
251 0 : goto totalspace_failure;
252 : }
253 :
254 23 : if (php_disk_total_space(path, &bytestotal TSRMLS_CC) == SUCCESS) {
255 20 : if (path_type == IS_UNICODE) {
256 19 : efree(path);
257 : }
258 20 : RETURN_DOUBLE(bytestotal);
259 : }
260 :
261 3 : totalspace_failure:
262 3 : if (path_type == IS_UNICODE) {
263 3 : efree(path);
264 : }
265 3 : RETURN_FALSE;
266 : }
267 : /* }}} */
268 :
269 : static int php_disk_free_space(char *path, double *space TSRMLS_DC) /* {{{ */
270 : #if defined(WINDOWS) /* {{{ */
271 : {
272 : double bytesfree = 0;
273 :
274 : HINSTANCE kernel32;
275 : FARPROC gdfse;
276 : typedef BOOL (WINAPI *gdfse_func)(LPCTSTR, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER);
277 : gdfse_func func;
278 :
279 : /* These are used by GetDiskFreeSpaceEx, if available. */
280 : ULARGE_INTEGER FreeBytesAvailableToCaller;
281 : ULARGE_INTEGER TotalNumberOfBytes;
282 : ULARGE_INTEGER TotalNumberOfFreeBytes;
283 :
284 : /* These are used by GetDiskFreeSpace otherwise. */
285 : DWORD SectorsPerCluster;
286 : DWORD BytesPerSector;
287 : DWORD NumberOfFreeClusters;
288 : DWORD TotalNumberOfClusters;
289 :
290 : /* GetDiskFreeSpaceEx is only available in NT and Win95 post-OSR2,
291 : so we have to jump through some hoops to see if the function
292 : exists. */
293 : kernel32 = LoadLibrary("kernel32.dll");
294 : if (kernel32) {
295 : gdfse = GetProcAddress(kernel32, "GetDiskFreeSpaceExA");
296 : /* It's available, so we can call it. */
297 : if (gdfse) {
298 : func = (gdfse_func)gdfse;
299 : if (func(path,
300 : &FreeBytesAvailableToCaller,
301 : &TotalNumberOfBytes,
302 : &TotalNumberOfFreeBytes) == 0) {
303 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", php_win_err());
304 : return FAILURE;
305 : }
306 :
307 : /* i know - this is ugly, but i works <thies@thieso.net> */
308 : bytesfree = FreeBytesAvailableToCaller.HighPart *
309 : (double) (((unsigned long)1) << 31) * 2.0 +
310 : FreeBytesAvailableToCaller.LowPart;
311 : } else { /* If it's not available, we just use GetDiskFreeSpace */
312 : if (GetDiskFreeSpace(path,
313 : &SectorsPerCluster, &BytesPerSector,
314 : &NumberOfFreeClusters, &TotalNumberOfClusters) == 0) {
315 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", php_win_err());
316 : return FAILURE;
317 : }
318 : bytesfree = (double)NumberOfFreeClusters * (double)SectorsPerCluster * (double)BytesPerSector;
319 : }
320 : } else {
321 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to load kernel32.dll");
322 : return FAILURE;
323 : }
324 :
325 : *space = bytesfree;
326 : return SUCCESS;
327 : }
328 : /* }}} */
329 : #elif defined(OS2) /* {{{ */
330 : {
331 : double bytesfree = 0;
332 : FSALLOCATE fsinfo;
333 : char drive = path[0] & 95;
334 :
335 : if (DosQueryFSInfo( drive ? drive - 64 : 0, FSIL_ALLOC, &fsinfo, sizeof( fsinfo ) ) == 0) {
336 : bytesfree = (double)fsinfo.cbSector * fsinfo.cSectorUnit * fsinfo.cUnitAvail;
337 : *space = bytesfree;
338 : return SUCCESS;
339 : }
340 : return FAILURE;
341 : }
342 : /* }}} */
343 : #else /* {{{ if !defined(OS2) && !defined(WINDOWS) */
344 40 : {
345 40 : double bytesfree = 0;
346 : #if defined(HAVE_SYS_STATVFS_H) && defined(HAVE_STATVFS)
347 : struct statvfs buf;
348 : #elif (defined(HAVE_SYS_STATFS_H) || defined(HAVE_SYS_MOUNT_H)) && defined(HAVE_STATFS)
349 : struct statfs buf;
350 : #endif
351 :
352 : #if defined(HAVE_SYS_STATVFS_H) && defined(HAVE_STATVFS)
353 40 : if (statvfs(path, &buf)) {
354 4 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", strerror(errno));
355 4 : return FAILURE;
356 : }
357 36 : if (buf.f_frsize) {
358 36 : bytesfree = (((double)buf.f_bavail) * ((double)buf.f_frsize));
359 : } else {
360 0 : bytesfree = (((double)buf.f_bavail) * ((double)buf.f_bsize));
361 : }
362 : #elif (defined(HAVE_SYS_STATFS_H) || defined(HAVE_SYS_MOUNT_H)) && defined(HAVE_STATFS)
363 : if (statfs(path, &buf)) {
364 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", strerror(errno));
365 : return FAILURE;
366 : }
367 : #ifdef NETWARE
368 : bytesfree = (((double)buf.f_bsize) * ((double)buf.f_bfree));
369 : #else
370 : bytesfree = (((double)buf.f_bsize) * ((double)buf.f_bavail));
371 : #endif
372 : #endif
373 :
374 36 : *space = bytesfree;
375 36 : return SUCCESS;
376 : }
377 : #endif
378 : /* }}} */
379 : /* }}} */
380 :
381 :
382 : /* {{{ proto float disk_free_space(string path) U
383 : Get free disk space for filesystem that path is on */
384 : PHP_FUNCTION(disk_free_space)
385 53 : {
386 : char *path;
387 : int path_len;
388 : zend_uchar path_type;
389 : double bytesfree;
390 :
391 53 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "t", &path, &path_len, &path_type) == FAILURE) {
392 5 : return;
393 : }
394 :
395 48 : if (path_type == IS_UNICODE) {
396 47 : if (FAILURE == php_stream_path_encode(NULL, &path, &path_len, (UChar*)path, path_len, REPORT_ERRORS, FG(default_context))) {
397 0 : RETURN_FALSE;
398 : }
399 : }
400 :
401 48 : if (php_check_open_basedir(path TSRMLS_CC)) {
402 8 : goto freespace_failure;
403 : }
404 :
405 40 : if (php_disk_free_space(path, &bytesfree TSRMLS_CC) == SUCCESS) {
406 36 : if (path_type == IS_UNICODE) {
407 35 : efree(path);
408 : }
409 36 : RETURN_DOUBLE(bytesfree);
410 : }
411 :
412 12 : freespace_failure:
413 12 : if (path_type == IS_UNICODE) {
414 12 : efree(path);
415 : }
416 12 : RETURN_FALSE;
417 : }
418 : /* }}} */
419 :
420 : #if !defined(WINDOWS) && !defined(NETWARE)
421 : static void php_do_chgrp(INTERNAL_FUNCTION_PARAMETERS, int do_lchgrp) /* {{{ */
422 2 : {
423 : char *filename;
424 : int filename_len;
425 : zend_uchar filename_type;
426 : zval *group;
427 : gid_t gid;
428 : int ret;
429 :
430 2 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "tz/", &filename, &filename_len, &filename_type, &group) == FAILURE) {
431 0 : RETURN_FALSE;
432 : }
433 :
434 2 : if (Z_TYPE_P(group) == IS_LONG) {
435 1 : gid = (gid_t)Z_LVAL_P(group);
436 1 : } else if (Z_TYPE_P(group) == IS_STRING ||
437 : Z_TYPE_P(group) == IS_UNICODE
438 : ) {
439 0 : if (Z_TYPE_P(group) == IS_UNICODE) {
440 0 : zval_unicode_to_string(group TSRMLS_CC);
441 : }
442 : #if defined(ZTS) && defined(HAVE_GETGRNAM_R) && defined(_SC_GETGR_R_SIZE_MAX)
443 : {
444 : struct group gr;
445 : struct group *retgrptr;
446 : long grbuflen = sysconf(_SC_GETGR_R_SIZE_MAX);
447 : char *grbuf;
448 :
449 : if (grbuflen < 1) {
450 : RETURN_FALSE;
451 : }
452 :
453 : grbuf = emalloc(grbuflen);
454 : if (getgrnam_r(Z_STRVAL_P(group), &gr, grbuf, grbuflen, &retgrptr) != 0 || retgrptr == NULL) {
455 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find gid for %s", Z_STRVAL_P(group));
456 : efree(grbuf);
457 : RETURN_FALSE;
458 : }
459 : efree(grbuf);
460 : gid = gr.gr_gid;
461 : }
462 : #else
463 : {
464 0 : struct group *gr = getgrnam(Z_STRVAL_P(group));
465 :
466 0 : if (!gr) {
467 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find gid for %s", Z_STRVAL_P(group));
468 0 : RETURN_FALSE;
469 : }
470 0 : gid = gr->gr_gid;
471 : }
472 : #endif
473 : } else {
474 1 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "parameter 2 should be string or integer, %s given", zend_zval_type_name(group));
475 1 : RETURN_FALSE;
476 : }
477 :
478 1 : if (filename_type == IS_UNICODE) {
479 1 : if (FAILURE == php_stream_path_encode(NULL, &filename, &filename_len, (UChar*)filename, filename_len, REPORT_ERRORS, FG(default_context))) {
480 0 : RETURN_FALSE;
481 : }
482 : }
483 :
484 : /* Check the basedir */
485 1 : if (php_check_open_basedir(filename TSRMLS_CC)) {
486 0 : if (filename_type == IS_UNICODE) {
487 0 : efree(filename);
488 : }
489 0 : RETURN_FALSE;
490 : }
491 :
492 1 : if (do_lchgrp) {
493 : #if HAVE_LCHOWN
494 1 : ret = VCWD_LCHOWN(filename, -1, gid);
495 : #endif
496 : } else {
497 0 : ret = VCWD_CHOWN(filename, -1, gid);
498 : }
499 :
500 1 : if (filename_type == IS_UNICODE) {
501 1 : efree(filename);
502 : }
503 :
504 1 : if (ret == -1) {
505 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", strerror(errno));
506 0 : RETURN_FALSE;
507 : }
508 1 : RETURN_TRUE;
509 : }
510 : /* }}} */
511 : #endif
512 :
513 : #ifndef NETWARE
514 : /* {{{ proto bool chgrp(string filename, mixed group) U
515 : Change file group */
516 : PHP_FUNCTION(chgrp)
517 1 : {
518 : #if !defined(WINDOWS)
519 1 : php_do_chgrp(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
520 : #else
521 : RETURN_FALSE;
522 : #endif
523 1 : }
524 : /* }}} */
525 :
526 : /* {{{ proto bool lchgrp(string filename, mixed group) U
527 : Change symlink group */
528 : #if HAVE_LCHOWN
529 : PHP_FUNCTION(lchgrp)
530 1 : {
531 : # if !defined(WINDOWS)
532 1 : php_do_chgrp(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
533 : # else
534 : RETURN_FALSE;
535 : # endif
536 1 : }
537 : #endif
538 : /* }}} */
539 : #endif /* !NETWARE */
540 :
541 : #if !defined(WINDOWS) && !defined(NETWARE)
542 : static void php_do_chown(INTERNAL_FUNCTION_PARAMETERS, int do_lchown) /* {{{ */
543 8 : {
544 : char *filename;
545 : int filename_len;
546 : zend_uchar filename_type;
547 : zval *user;
548 : uid_t uid;
549 : int ret;
550 :
551 8 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "tz/", &filename, &filename_len, &filename_type, &user) == FAILURE) {
552 4 : return;
553 : }
554 :
555 4 : if (Z_TYPE_P(user) == IS_LONG) {
556 3 : uid = (uid_t) Z_LVAL_P(user);
557 1 : } else if (Z_TYPE_P(user) == IS_STRING ||
558 : Z_TYPE_P(user) == IS_UNICODE
559 : ) {
560 0 : if (Z_TYPE_P(user) == IS_UNICODE) {
561 0 : zval_unicode_to_string(user TSRMLS_CC);
562 : }
563 : #if defined(ZTS) && defined(_SC_GETPW_R_SIZE_MAX) && defined(HAVE_GETPWNAM_R)
564 : {
565 : struct passwd pw;
566 : struct passwd *retpwptr = NULL;
567 : long pwbuflen = sysconf(_SC_GETPW_R_SIZE_MAX);
568 : char *pwbuf;
569 :
570 : if (pwbuflen < 1) {
571 : RETURN_FALSE;
572 : }
573 :
574 : pwbuf = emalloc(pwbuflen);
575 : if (getpwnam_r(Z_STRVAL_P(user), &pw, pwbuf, pwbuflen, &retpwptr) != 0 || retpwptr == NULL) {
576 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find uid for %s", Z_STRVAL_P(user));
577 : efree(pwbuf);
578 : RETURN_FALSE;
579 : }
580 : efree(pwbuf);
581 : uid = pw.pw_uid;
582 : }
583 : #else
584 : {
585 0 : struct passwd *pw = getpwnam(Z_STRVAL_P(user));
586 :
587 0 : if (!pw) {
588 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find uid for %s", Z_STRVAL_P(user));
589 0 : RETURN_FALSE;
590 : }
591 0 : uid = pw->pw_uid;
592 : }
593 : #endif
594 : } else {
595 1 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "parameter 2 should be string or integer, %s given", zend_zval_type_name(user));
596 1 : RETURN_FALSE;
597 : }
598 :
599 3 : if (filename_type == IS_UNICODE) {
600 3 : if (FAILURE == php_stream_path_encode(NULL, &filename, &filename_len, (UChar*)filename, filename_len, REPORT_ERRORS, FG(default_context))) {
601 0 : RETURN_FALSE;
602 : }
603 : }
604 :
605 : /* Check the basedir */
606 3 : if (php_check_open_basedir(filename TSRMLS_CC)) {
607 0 : if (filename_type == IS_UNICODE) {
608 0 : efree(filename);
609 : }
610 0 : RETURN_FALSE;
611 : }
612 :
613 3 : if (do_lchown) {
614 : #if HAVE_LCHOWN
615 3 : ret = VCWD_LCHOWN(filename, uid, -1);
616 : #endif
617 : } else {
618 0 : ret = VCWD_CHOWN(filename, uid, -1);
619 : }
620 3 : if (filename_type == IS_UNICODE) {
621 3 : efree(filename);
622 : }
623 :
624 3 : if (ret == -1) {
625 2 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", strerror(errno));
626 2 : RETURN_FALSE;
627 : }
628 : }
629 : /* }}} */
630 : #endif
631 :
632 : #ifndef NETWARE
633 : /* {{{ proto bool chown (string filename, mixed user) U
634 : Change file owner */
635 : PHP_FUNCTION(chown)
636 1 : {
637 : #if !defined(WINDOWS)
638 1 : RETVAL_TRUE;
639 1 : php_do_chown(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
640 : #else
641 : RETURN_FALSE;
642 : #endif
643 1 : }
644 : /* }}} */
645 :
646 : /* {{{ proto bool lchown (string filename, mixed user) U
647 : Change file owner */
648 : #if HAVE_LCHOWN
649 : PHP_FUNCTION(lchown)
650 7 : {
651 : # if !defined(WINDOWS)
652 7 : RETVAL_TRUE;
653 7 : php_do_chown(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
654 : # else
655 : RETURN_FALSE;
656 : # endif
657 7 : }
658 : #endif
659 : /* }}} */
660 : #endif /* !NETWARE */
661 :
662 : /* {{{ proto bool chmod(string filename, int mode) U
663 : Change file mode */
664 : PHP_FUNCTION(chmod)
665 10334 : {
666 : char *filename;
667 : int filename_len;
668 : zend_uchar filename_type;
669 : long mode;
670 : int ret;
671 : mode_t imode;
672 :
673 10334 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "tl", &filename, &filename_len, &filename_type, &mode) == FAILURE) {
674 31 : return;
675 : }
676 :
677 10303 : if (filename_type == IS_UNICODE) {
678 10303 : if (FAILURE == php_stream_path_encode(NULL, &filename, &filename_len, (UChar*)filename, filename_len, REPORT_ERRORS, FG(default_context))) {
679 0 : RETURN_FALSE;
680 : }
681 : }
682 :
683 : /* Check the basedir */
684 10303 : if (php_check_open_basedir(filename TSRMLS_CC)) {
685 8 : if (filename_type == IS_UNICODE) {
686 8 : efree(filename);
687 : }
688 8 : RETURN_FALSE;
689 : }
690 :
691 10295 : imode = (mode_t) mode;
692 :
693 10295 : ret = VCWD_CHMOD(filename, imode);
694 10295 : if (filename_type == IS_UNICODE) {
695 10295 : efree(filename);
696 : }
697 :
698 10295 : if (ret == -1) {
699 25 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", strerror(errno));
700 25 : RETURN_FALSE;
701 : }
702 10270 : RETURN_TRUE;
703 : }
704 : /* }}} */
705 :
706 : #if HAVE_UTIME
707 : /* {{{ proto bool touch(string filename [, int time [, int atime]]) U
708 : Set modification time of file */
709 : PHP_FUNCTION(touch)
710 252 : {
711 : char *filename;
712 : int filename_len;
713 : zend_uchar filename_type;
714 252 : long filetime = 0, fileatime = 0;
715 252 : int ret, argc = ZEND_NUM_ARGS();
716 : FILE *file;
717 : struct utimbuf newtimebuf;
718 252 : struct utimbuf *newtime = &newtimebuf;
719 :
720 252 : if (zend_parse_parameters(argc TSRMLS_CC, "t|ll", &filename, &filename_len, &filename_type, &filetime, &fileatime) == FAILURE) {
721 31 : return;
722 : }
723 :
724 221 : switch (argc) {
725 : case 1:
726 : #ifdef HAVE_UTIME_NULL
727 167 : newtime = NULL;
728 : #else
729 : newtime->modtime = newtime->actime = time(NULL);
730 : #endif
731 167 : break;
732 : case 2:
733 8 : newtime->modtime = newtime->actime = filetime;
734 8 : break;
735 : case 3:
736 46 : newtime->modtime = filetime;
737 46 : newtime->actime = fileatime;
738 46 : break;
739 : default:
740 : /* Never reached */
741 0 : WRONG_PARAM_COUNT;
742 : }
743 :
744 221 : if (filename_type == IS_UNICODE) {
745 221 : if (FAILURE == php_stream_path_encode(NULL, &filename, &filename_len, (UChar*)filename, filename_len, REPORT_ERRORS, FG(default_context))) {
746 0 : RETURN_FALSE;
747 : }
748 : }
749 :
750 : /* Check the basedir */
751 221 : if (php_check_open_basedir(filename TSRMLS_CC)) {
752 8 : if (filename_type == IS_UNICODE) {
753 8 : efree(filename);
754 : }
755 8 : RETURN_FALSE;
756 : }
757 :
758 : /* create the file if it doesn't exist already */
759 213 : if (VCWD_ACCESS(filename, F_OK) != 0) {
760 128 : file = VCWD_FOPEN(filename, "w");
761 128 : if (file == NULL) {
762 11 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to create file %s because %s", filename, strerror(errno));
763 11 : if (filename_type == IS_UNICODE) {
764 11 : efree(filename);
765 : }
766 11 : RETURN_FALSE;
767 : }
768 117 : fclose(file);
769 : }
770 :
771 202 : ret = VCWD_UTIME(filename, newtime);
772 202 : if (filename_type == IS_UNICODE) {
773 202 : efree(filename);
774 : }
775 :
776 202 : if (ret == -1) {
777 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Utime failed: %s", strerror(errno));
778 0 : RETURN_FALSE;
779 : }
780 202 : RETURN_TRUE;
781 : }
782 : /* }}} */
783 : #endif
784 :
785 : /* {{{ php_clear_stat_cache()
786 : */
787 : PHPAPI void php_clear_stat_cache(zend_bool clear_realpath_cache, const char *filename, int filename_len TSRMLS_DC)
788 32782 : {
789 : /* always clear CurrentStatFile and CurrentLStatFile even if filename is not NULL
790 : * as it may contains outdated data (e.g. "nlink" for a directory when deleting a file
791 : * in this directory, as shown by lstat_stat_variation9.phpt) */
792 32782 : if (BG(CurrentStatFile)) {
793 18206 : efree(BG(CurrentStatFile));
794 18206 : BG(CurrentStatFile) = NULL;
795 : }
796 32782 : if (BG(CurrentLStatFile)) {
797 46 : efree(BG(CurrentLStatFile));
798 46 : BG(CurrentLStatFile) = NULL;
799 : }
800 32782 : if (clear_realpath_cache) {
801 24503 : if (filename != NULL) {
802 3 : realpath_cache_del(filename, filename_len TSRMLS_CC);
803 : } else {
804 24500 : realpath_cache_clean(TSRMLS_C);
805 : }
806 : }
807 32782 : }
808 : /* }}} */
809 :
810 : /* {{{ proto void clearstatcache([bool clear_realpath_cache[, string filename]])
811 : Clear file stat cache */
812 : PHP_FUNCTION(clearstatcache)
813 8284 : {
814 8284 : zend_bool clear_realpath_cache = 0;
815 8284 : char *filename = NULL;
816 8284 : zend_uchar filename_type = 0;
817 8284 : int filename_len = 0;
818 :
819 8284 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|bt", &clear_realpath_cache, &filename, &filename_len, &filename_type) == FAILURE) {
820 1 : return;
821 : }
822 :
823 8283 : if (filename && filename_type == IS_UNICODE) {
824 3 : if (FAILURE == php_stream_path_encode(NULL, &filename, &filename_len, (UChar*)filename, filename_len, REPORT_ERRORS, FG(default_context))) {
825 0 : RETURN_FALSE;
826 : }
827 : }
828 :
829 8283 : php_clear_stat_cache(clear_realpath_cache, filename, filename_len TSRMLS_CC);
830 :
831 8283 : if (filename && filename_type == IS_UNICODE) {
832 3 : efree(filename);
833 : }
834 : }
835 : /* }}} */
836 :
837 : #define IS_LINK_OPERATION(__t) ((__t) == FS_TYPE || (__t) == FS_IS_LINK || (__t) == FS_LSTAT)
838 : #define IS_EXISTS_CHECK(__t) ((__t) == FS_EXISTS || (__t) == FS_IS_W || (__t) == FS_IS_R || (__t) == FS_IS_X || (__t) == FS_IS_FILE || (__t) == FS_IS_DIR || (__t) == FS_IS_LINK)
839 : #define IS_ABLE_CHECK(__t) ((__t) == FS_IS_R || (__t) == FS_IS_W || (__t) == FS_IS_X)
840 : #define IS_ACCESS_CHECK(__t) (IS_ABLE_CHECK(type) || (__t) == FS_EXISTS)
841 :
842 : PHPAPI void php_u_stat(zend_uchar filename_type, const zstr filename, php_stat_len filename_length, int type, php_stream_context *context, zval *return_value TSRMLS_DC) /* {{{ */
843 6484 : {
844 : char *fn;
845 :
846 6484 : if (filename_type == IS_STRING) {
847 329 : php_stat(filename.s, filename_length, type, return_value TSRMLS_CC);
848 : } else {
849 6155 : if (FAILURE == php_stream_path_encode(NULL, &fn, &filename_length, filename.u, filename_length, REPORT_ERRORS, context)) {
850 0 : RETURN_FALSE;
851 : }
852 6155 : php_stat(fn, filename_length, type, return_value TSRMLS_CC);
853 6155 : efree(fn);
854 : }
855 : }
856 : /* }}} */
857 :
858 : /* {{{ php_stat
859 : */
860 : PHPAPI void php_stat(const char *filename, php_stat_len filename_length, int type, zval *return_value TSRMLS_DC)
861 91295 : {
862 : zval *stat_dev, *stat_ino, *stat_mode, *stat_nlink, *stat_uid, *stat_gid, *stat_rdev,
863 : *stat_size, *stat_atime, *stat_mtime, *stat_ctime, *stat_blksize, *stat_blocks;
864 : struct stat *stat_sb;
865 : php_stream_statbuf ssb;
866 91295 : int flags = 0, rmask=S_IROTH, wmask=S_IWOTH, xmask=S_IXOTH; /* access rights defaults to other */
867 : char *stat_sb_names[13] = {
868 : "dev", "ino", "mode", "nlink", "uid", "gid", "rdev",
869 : "size", "atime", "mtime", "ctime", "blksize", "blocks"
870 91295 : };
871 : char *local;
872 : php_stream_wrapper *wrapper;
873 :
874 91295 : if (!filename_length) {
875 65 : RETURN_FALSE;
876 : }
877 :
878 91230 : if ((wrapper = php_stream_locate_url_wrapper(filename, &local, 0 TSRMLS_CC)) == &php_plain_files_wrapper) {
879 90799 : if (php_check_open_basedir(local TSRMLS_CC)) {
880 161 : RETURN_FALSE;
881 : }
882 : }
883 :
884 91069 : if (IS_ACCESS_CHECK(type)) {
885 5615 : if (wrapper == &php_plain_files_wrapper) {
886 :
887 5531 : switch (type) {
888 : #ifdef F_OK
889 : case FS_EXISTS:
890 3159 : RETURN_BOOL(VCWD_ACCESS(local, F_OK) == 0);
891 : break;
892 : #endif
893 : #ifdef W_OK
894 : case FS_IS_W:
895 1093 : RETURN_BOOL(VCWD_ACCESS(local, W_OK) == 0);
896 : break;
897 : #endif
898 : #ifdef R_OK
899 : case FS_IS_R:
900 677 : RETURN_BOOL(VCWD_ACCESS(local, R_OK) == 0);
901 : break;
902 : #endif
903 : #ifdef X_OK
904 : case FS_IS_X:
905 602 : RETURN_BOOL(VCWD_ACCESS(local, X_OK) == 0);
906 : break;
907 : #endif
908 : }
909 : }
910 : }
911 :
912 85538 : if (IS_LINK_OPERATION(type)) {
913 3299 : flags |= PHP_STREAM_URL_STAT_LINK;
914 : }
915 85538 : if (IS_EXISTS_CHECK(type)) {
916 66594 : flags |= PHP_STREAM_URL_STAT_QUIET;
917 : }
918 :
919 85538 : if (php_stream_stat_path_ex((char *)filename, flags, &ssb, NULL)) {
920 : /* Error Occured */
921 220 : if (!IS_EXISTS_CHECK(type)) {
922 81 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "%sstat failed for %s", IS_LINK_OPERATION(type) ? "L" : "", filename);
923 : }
924 220 : RETURN_FALSE;
925 : }
926 :
927 85318 : stat_sb = &ssb.sb;
928 :
929 :
930 : #ifndef NETWARE
931 85318 : if (type >= FS_IS_W && type <= FS_IS_X) {
932 43 : if(ssb.sb.st_uid==getuid()) {
933 0 : rmask=S_IRUSR;
934 0 : wmask=S_IWUSR;
935 0 : xmask=S_IXUSR;
936 43 : } else if(ssb.sb.st_gid==getgid()) {
937 0 : rmask=S_IRGRP;
938 0 : wmask=S_IWGRP;
939 0 : xmask=S_IXGRP;
940 : } else {
941 : int groups, n, i;
942 : gid_t *gids;
943 :
944 43 : groups = getgroups(0, NULL);
945 43 : if(groups > 0) {
946 43 : gids=(gid_t *)safe_emalloc(groups, sizeof(gid_t), 0);
947 43 : n=getgroups(groups, gids);
948 129 : for(i=0;i<n;i++){
949 86 : if(ssb.sb.st_gid==gids[i]) {
950 0 : rmask=S_IRGRP;
951 0 : wmask=S_IWGRP;
952 0 : xmask=S_IXGRP;
953 0 : break;
954 : }
955 : }
956 43 : efree(gids);
957 : }
958 : }
959 : }
960 : #endif
961 :
962 : #ifndef NETWARE
963 85318 : if (IS_ABLE_CHECK(type) && getuid() == 0) {
964 : /* root has special perms on plain_wrapper
965 : But we don't know about root under Netware */
966 0 : if (wrapper == &php_plain_files_wrapper) {
967 0 : if (type == FS_IS_X) {
968 0 : xmask = S_IXROOT;
969 : } else {
970 0 : RETURN_TRUE;
971 : }
972 : }
973 : }
974 : #endif
975 :
976 85318 : switch (type) {
977 : case FS_PERMS:
978 6762 : RETURN_LONG((long)ssb.sb.st_mode);
979 : case FS_INODE:
980 45 : RETURN_LONG((long)ssb.sb.st_ino);
981 : case FS_SIZE:
982 11717 : RETURN_LONG((long)ssb.sb.st_size);
983 : case FS_OWNER:
984 55 : RETURN_LONG((long)ssb.sb.st_uid);
985 : case FS_GROUP:
986 26 : RETURN_LONG((long)ssb.sb.st_gid);
987 : case FS_ATIME:
988 37 : RETURN_LONG((long)ssb.sb.st_atime);
989 : case FS_MTIME:
990 39 : RETURN_LONG((long)ssb.sb.st_mtime);
991 : case FS_CTIME:
992 33 : RETURN_LONG((long)ssb.sb.st_ctime);
993 : case FS_TYPE:
994 26 : if (S_ISLNK(ssb.sb.st_mode)) {
995 2 : RETURN_ASCII_STRING("link", 1);
996 : }
997 24 : switch(ssb.sb.st_mode & S_IFMT) {
998 1 : case S_IFIFO: RETURN_ASCII_STRING("fifo", 1);
999 1 : case S_IFCHR: RETURN_ASCII_STRING("char", 1);
1000 9 : case S_IFDIR: RETURN_ASCII_STRING("dir", 1);
1001 1 : case S_IFBLK: RETURN_ASCII_STRING("block", 1);
1002 12 : case S_IFREG: RETURN_ASCII_STRING("file", 1);
1003 : #if defined(S_IFSOCK) && !defined(ZEND_WIN32)&&!defined(__BEOS__)
1004 0 : case S_IFSOCK: RETURN_ASCII_STRING("socket", 1);
1005 : #endif
1006 : }
1007 0 : php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Unknown file type (%d)", ssb.sb.st_mode&S_IFMT);
1008 0 : RETURN_ASCII_STRING("unknown", 1);
1009 : case FS_IS_W:
1010 9 : RETURN_BOOL((ssb.sb.st_mode & wmask) != 0);
1011 : case FS_IS_R:
1012 18 : RETURN_BOOL((ssb.sb.st_mode&rmask)!=0);
1013 : case FS_IS_X:
1014 16 : RETURN_BOOL((ssb.sb.st_mode&xmask)!=0 && !S_ISDIR(ssb.sb.st_mode));
1015 : case FS_IS_FILE:
1016 982 : RETURN_BOOL(S_ISREG(ssb.sb.st_mode));
1017 : case FS_IS_DIR:
1018 62189 : RETURN_BOOL(S_ISDIR(ssb.sb.st_mode));
1019 : case FS_IS_LINK:
1020 3222 : RETURN_BOOL(S_ISLNK(ssb.sb.st_mode));
1021 : case FS_EXISTS:
1022 19 : RETURN_TRUE; /* the false case was done earlier */
1023 : case FS_LSTAT:
1024 : /* FALLTHROUGH */
1025 : case FS_STAT:
1026 123 : array_init(return_value);
1027 :
1028 123 : MAKE_LONG_ZVAL_INCREF(stat_dev, stat_sb->st_dev);
1029 123 : MAKE_LONG_ZVAL_INCREF(stat_ino, stat_sb->st_ino);
1030 123 : MAKE_LONG_ZVAL_INCREF(stat_mode, stat_sb->st_mode);
1031 123 : MAKE_LONG_ZVAL_INCREF(stat_nlink, stat_sb->st_nlink);
1032 123 : MAKE_LONG_ZVAL_INCREF(stat_uid, stat_sb->st_uid);
1033 123 : MAKE_LONG_ZVAL_INCREF(stat_gid, stat_sb->st_gid);
1034 : #ifdef HAVE_ST_RDEV
1035 123 : MAKE_LONG_ZVAL_INCREF(stat_rdev, stat_sb->st_rdev);
1036 : #else
1037 : MAKE_LONG_ZVAL_INCREF(stat_rdev, -1);
1038 : #endif
1039 123 : MAKE_LONG_ZVAL_INCREF(stat_size, stat_sb->st_size);
1040 123 : MAKE_LONG_ZVAL_INCREF(stat_atime, stat_sb->st_atime);
1041 123 : MAKE_LONG_ZVAL_INCREF(stat_mtime, stat_sb->st_mtime);
1042 123 : MAKE_LONG_ZVAL_INCREF(stat_ctime, stat_sb->st_ctime);
1043 : #ifdef HAVE_ST_BLKSIZE
1044 123 : MAKE_LONG_ZVAL_INCREF(stat_blksize, stat_sb->st_blksize);
1045 : #else
1046 : MAKE_LONG_ZVAL_INCREF(stat_blksize,-1);
1047 : #endif
1048 : #ifdef HAVE_ST_BLOCKS
1049 123 : MAKE_LONG_ZVAL_INCREF(stat_blocks, stat_sb->st_blocks);
1050 : #else
1051 : MAKE_LONG_ZVAL_INCREF(stat_blocks,-1);
1052 : #endif
1053 : /* Store numeric indexes in propper order */
1054 123 : zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_dev, sizeof(zval *), NULL);
1055 123 : zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_ino, sizeof(zval *), NULL);
1056 123 : zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_mode, sizeof(zval *), NULL);
1057 123 : zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_nlink, sizeof(zval *), NULL);
1058 123 : zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_uid, sizeof(zval *), NULL);
1059 123 : zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_gid, sizeof(zval *), NULL);
1060 :
1061 123 : zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_rdev, sizeof(zval *), NULL);
1062 123 : zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_size, sizeof(zval *), NULL);
1063 123 : zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_atime, sizeof(zval *), NULL);
1064 123 : zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_mtime, sizeof(zval *), NULL);
1065 123 : zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_ctime, sizeof(zval *), NULL);
1066 123 : zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_blksize, sizeof(zval *), NULL);
1067 123 : zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_blocks, sizeof(zval *), NULL);
1068 :
1069 : /* Store string indexes referencing the same zval*/
1070 123 : zend_ascii_hash_update(HASH_OF(return_value), stat_sb_names[0], strlen(stat_sb_names[0])+1, (void *) &stat_dev, sizeof(zval *), NULL);
1071 123 : zend_ascii_hash_update(HASH_OF(return_value), stat_sb_names[1], strlen(stat_sb_names[1])+1, (void *) &stat_ino, sizeof(zval *), NULL);
1072 123 : zend_ascii_hash_update(HASH_OF(return_value), stat_sb_names[2], strlen(stat_sb_names[2])+1, (void *) &stat_mode, sizeof(zval *), NULL);
1073 123 : zend_ascii_hash_update(HASH_OF(return_value), stat_sb_names[3], strlen(stat_sb_names[3])+1, (void *) &stat_nlink, sizeof(zval *), NULL);
1074 123 : zend_ascii_hash_update(HASH_OF(return_value), stat_sb_names[4], strlen(stat_sb_names[4])+1, (void *) &stat_uid, sizeof(zval *), NULL);
1075 123 : zend_ascii_hash_update(HASH_OF(return_value), stat_sb_names[5], strlen(stat_sb_names[5])+1, (void *) &stat_gid, sizeof(zval *), NULL);
1076 123 : zend_ascii_hash_update(HASH_OF(return_value), stat_sb_names[6], strlen(stat_sb_names[6])+1, (void *) &stat_rdev, sizeof(zval *), NULL);
1077 123 : zend_ascii_hash_update(HASH_OF(return_value), stat_sb_names[7], strlen(stat_sb_names[7])+1, (void *) &stat_size, sizeof(zval *), NULL);
1078 123 : zend_ascii_hash_update(HASH_OF(return_value), stat_sb_names[8], strlen(stat_sb_names[8])+1, (void *) &stat_atime, sizeof(zval *), NULL);
1079 123 : zend_ascii_hash_update(HASH_OF(return_value), stat_sb_names[9], strlen(stat_sb_names[9])+1, (void *) &stat_mtime, sizeof(zval *), NULL);
1080 123 : zend_ascii_hash_update(HASH_OF(return_value), stat_sb_names[10], strlen(stat_sb_names[10])+1, (void *) &stat_ctime, sizeof(zval *), NULL);
1081 123 : zend_ascii_hash_update(HASH_OF(return_value), stat_sb_names[11], strlen(stat_sb_names[11])+1, (void *) &stat_blksize, sizeof(zval *), NULL);
1082 123 : zend_ascii_hash_update(HASH_OF(return_value), stat_sb_names[12], strlen(stat_sb_names[12])+1, (void *) &stat_blocks, sizeof(zval *), NULL);
1083 :
1084 123 : return;
1085 : }
1086 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Didn't understand stat call");
1087 0 : RETURN_FALSE;
1088 : }
1089 : /* }}} */
1090 :
1091 : /* another quickie macro to make defining similar functions easier */
1092 : /* {{{ FileFunction(name, funcnum) */
1093 : #define FileFunction(name, funcnum) \
1094 : void name(INTERNAL_FUNCTION_PARAMETERS) { \
1095 : char *filename; \
1096 : int filename_len; \
1097 : zend_uchar filename_type; \
1098 : \
1099 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "t", &filename, &filename_len, &filename_type) == FAILURE) { \
1100 : return; \
1101 : } \
1102 : \
1103 : if (filename_type == IS_UNICODE) { \
1104 : if (FAILURE == php_stream_path_encode(NULL, &filename, &filename_len, (UChar*)filename, filename_len, REPORT_ERRORS, FG(default_context))) { \
1105 : RETURN_FALSE; \
1106 : } \
1107 : } \
1108 : \
1109 : php_stat(filename, (php_stat_len) filename_len, funcnum, return_value TSRMLS_CC); \
1110 : \
1111 : if (filename_type == IS_UNICODE) { \
1112 : efree(filename); \
1113 : } \
1114 : }
1115 : /* }}} */
1116 :
1117 : /* {{{ proto int fileperms(string filename) U
1118 : Get file permissions */
1119 6786 : FileFunction(PHP_FN(fileperms), FS_PERMS)
1120 : /* }}} */
1121 :
1122 : /* {{{ proto int fileinode(string filename) U
1123 : Get file inode */
1124 70 : FileFunction(PHP_FN(fileinode), FS_INODE)
1125 : /* }}} */
1126 :
1127 : /* {{{ proto int filesize(string filename) U
1128 : Get file size */
1129 11732 : FileFunction(PHP_FN(filesize), FS_SIZE)
1130 : /* }}} */
1131 :
1132 : /* {{{ proto int fileowner(string filename) U
1133 : Get file owner */
1134 80 : FileFunction(PHP_FN(fileowner), FS_OWNER)
1135 : /* }}} */
1136 :
1137 : /* {{{ proto int filegroup(string filename) U
1138 : Get file group */
1139 51 : FileFunction(PHP_FN(filegroup), FS_GROUP)
1140 : /* }}} */
1141 :
1142 : /* {{{ proto int fileatime(string filename) U
1143 : Get last access time of file */
1144 52 : FileFunction(PHP_FN(fileatime), FS_ATIME)
1145 : /* }}} */
1146 :
1147 : /* {{{ proto int filemtime(string filename) U
1148 : Get last modification time of file */
1149 52 : FileFunction(PHP_FN(filemtime), FS_MTIME)
1150 : /* }}} */
1151 :
1152 : /* {{{ proto int filectime(string filename) U
1153 : Get inode modification time of file */
1154 47 : FileFunction(PHP_FN(filectime), FS_CTIME)
1155 : /* }}} */
1156 :
1157 : /* {{{ proto string filetype(string filename) U
1158 : Get file type */
1159 38 : FileFunction(PHP_FN(filetype), FS_TYPE)
1160 : /* }}} */
1161 :
1162 : /* {{{ proto bool is_writable(string filename) U
1163 : Returns true if file can be written */
1164 1115 : FileFunction(PHP_FN(is_writable), FS_IS_W)
1165 : /* }}} */
1166 :
1167 : /* {{{ proto bool is_readable(string filename) U
1168 : Returns true if file can be read */
1169 694 : FileFunction(PHP_FN(is_readable), FS_IS_R)
1170 : /* }}} */
1171 :
1172 : /* {{{ proto bool is_executable(string filename) U
1173 : Returns true if file is executable */
1174 618 : FileFunction(PHP_FN(is_executable), FS_IS_X)
1175 : /* }}} */
1176 :
1177 : /* {{{ proto bool is_file(string filename) U
1178 : Returns true if file is a regular file */
1179 1019 : FileFunction(PHP_FN(is_file), FS_IS_FILE)
1180 : /* }}} */
1181 :
1182 : /* {{{ proto bool is_dir(string filename) U
1183 : Returns true if file is directory */
1184 58982 : FileFunction(PHP_FN(is_dir), FS_IS_DIR)
1185 : /* }}} */
1186 :
1187 : /* {{{ proto bool is_link(string filename) U
1188 : Returns true if file is symbolic link */
1189 67 : FileFunction(PHP_FN(is_link), FS_IS_LINK)
1190 : /* }}} */
1191 :
1192 : /* {{{ proto bool file_exists(string filename) U
1193 : Returns true if filename exists */
1194 3221 : FileFunction(PHP_FN(file_exists), FS_EXISTS)
1195 : /* }}} */
1196 :
1197 : /* {{{ proto array lstat(string filename) U
1198 : Give information about a file or symbolic link */
1199 46 : FileFunction(php_if_lstat, FS_LSTAT)
1200 : /* }}} */
1201 :
1202 : /* {{{ proto array stat(string filename) U
1203 : Give information about a file */
1204 122 : FileFunction(php_if_stat, FS_STAT)
1205 : /* }}} */
1206 :
1207 : /*
1208 : * Local variables:
1209 : * tab-width: 4
1210 : * c-basic-offset: 4
1211 : * End:
1212 : * vim600: sw=4 ts=4 fdm=marker
1213 : * vim<600: sw=4 ts=4
1214 : */
|