Annotation of embedaddon/php/ext/fileinfo/libmagic/fsmagic.c, revision 1.1.1.3
1.1 misho 1: /*
2: * Copyright (c) Ian F. Darwin 1986-1995.
3: * Software written by Ian F. Darwin and others;
4: * maintained 1995-present by Christos Zoulas and others.
5: *
6: * Redistribution and use in source and binary forms, with or without
7: * modification, are permitted provided that the following conditions
8: * are met:
9: * 1. Redistributions of source code must retain the above copyright
10: * notice immediately at the beginning of the file, without modification,
11: * this list of conditions, and the following disclaimer.
12: * 2. Redistributions in binary form must reproduce the above copyright
13: * notice, this list of conditions and the following disclaimer in the
14: * documentation and/or other materials provided with the distribution.
15: *
16: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19: * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
20: * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26: * SUCH DAMAGE.
27: */
28: /*
29: * fsmagic - magic based on filesystem info - directory, special files, etc.
30: */
31:
32: #include "file.h"
33:
34: #ifndef lint
1.1.1.3 ! misho 35: FILE_RCSID("@(#)$File: fsmagic.c,v 1.67 2013/03/17 15:43:20 christos Exp $")
1.1 misho 36: #endif /* lint */
37:
38: #include "magic.h"
39: #include <string.h>
40: #ifdef HAVE_UNISTD_H
41: #include <unistd.h>
42: #endif
43: #include <stdlib.h>
44: /* Since major is a function on SVR4, we cannot use `ifndef major'. */
45: #ifdef MAJOR_IN_MKDEV
46: # include <sys/mkdev.h>
47: # define HAVE_MAJOR
48: #endif
49: #ifdef MAJOR_IN_SYSMACROS
50: # include <sys/sysmacros.h>
51: # define HAVE_MAJOR
52: #endif
53: #ifdef major /* Might be defined in sys/types.h. */
54: # define HAVE_MAJOR
55: #endif
56:
57: #ifndef HAVE_MAJOR
58: # define major(dev) (((dev) >> 8) & 0xff)
59: # define minor(dev) ((dev) & 0xff)
60: #endif
61: #undef HAVE_MAJOR
62:
63: #ifdef PHP_WIN32
64:
65: # undef S_IFIFO
66: #endif
67:
68:
69: #ifndef S_ISDIR
70: #define S_ISDIR(mode) ((mode) & _S_IFDIR)
71: #endif
72:
73: #ifndef S_ISREG
74: #define S_ISREG(mode) ((mode) & _S_IFREG)
75: #endif
76:
77: private int
78: handle_mime(struct magic_set *ms, int mime, const char *str)
79: {
80: if ((mime & MAGIC_MIME_TYPE)) {
1.1.1.2 misho 81: if (file_printf(ms, "inode/%s", str) == -1)
1.1 misho 82: return -1;
83: if ((mime & MAGIC_MIME_ENCODING) && file_printf(ms,
84: "; charset=") == -1)
85: return -1;
86: }
87: if ((mime & MAGIC_MIME_ENCODING) && file_printf(ms, "binary") == -1)
88: return -1;
89: return 0;
90: }
91:
92: protected int
93: file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb, php_stream *stream)
94: {
1.1.1.3 ! misho 95: int ret, did = 0;
1.1 misho 96: int mime = ms->flags & MAGIC_MIME;
97: TSRMLS_FETCH();
98:
99: if (ms->flags & MAGIC_APPLE)
100: return 0;
101:
1.1.1.3 ! misho 102: if (fn == NULL && !stream) {
1.1 misho 103: return 0;
104: }
105:
1.1.1.3 ! misho 106: #define COMMA (did++ ? ", " : "")
! 107:
1.1 misho 108: if (stream) {
109: php_stream_statbuf ssb;
110: if (php_stream_stat(stream, &ssb) < 0) {
111: if (ms->flags & MAGIC_ERROR) {
112: file_error(ms, errno, "cannot stat `%s'", fn);
113: return -1;
114: }
115: return 1;
116: }
117: memcpy(sb, &ssb.sb, sizeof(struct stat));
118: } else {
119: if (php_sys_stat(fn, sb) != 0) {
120: if (ms->flags & MAGIC_ERROR) {
121: file_error(ms, errno, "cannot stat `%s'", fn);
122: return -1;
123: }
124: return 1;
125: }
126: }
127:
1.1.1.3 ! misho 128: ret = 1;
1.1 misho 129: if (!mime) {
130: #ifdef S_ISUID
131: if (sb->st_mode & S_ISUID)
1.1.1.3 ! misho 132: if (file_printf(ms, "%ssetuid", COMMA) == -1)
1.1 misho 133: return -1;
134: #endif
135: #ifdef S_ISGID
136: if (sb->st_mode & S_ISGID)
1.1.1.3 ! misho 137: if (file_printf(ms, "%ssetgid", COMMA) == -1)
1.1 misho 138: return -1;
139: #endif
140: #ifdef S_ISVTX
141: if (sb->st_mode & S_ISVTX)
1.1.1.3 ! misho 142: if (file_printf(ms, "%ssticky", COMMA) == -1)
1.1 misho 143: return -1;
144: #endif
145: }
1.1.1.2 misho 146:
1.1 misho 147: switch (sb->st_mode & S_IFMT) {
148: #ifndef PHP_WIN32
149: # ifdef S_IFCHR
150: case S_IFCHR:
151: /*
152: * If -s has been specified, treat character special files
153: * like ordinary files. Otherwise, just report that they
154: * are block special files and go on to the next file.
155: */
156: if ((ms->flags & MAGIC_DEVICES) != 0) {
1.1.1.3 ! misho 157: ret = 0;
1.1 misho 158: break;
159: }
160: if (mime) {
161: if (handle_mime(ms, mime, "x-character-device") == -1)
162: return -1;
163: } else {
164: # ifdef HAVE_STAT_ST_RDEV
165: # ifdef dv_unit
1.1.1.3 ! misho 166: if (file_printf(ms, "%scharacter special (%d/%d/%d)",
! 167: COMMA, major(sb->st_rdev), dv_unit(sb->st_rdev),
1.1 misho 168: dv_subunit(sb->st_rdev)) == -1)
169: return -1;
170: # else
1.1.1.3 ! misho 171: if (file_printf(ms, "%scharacter special (%ld/%ld)",
! 172: COMMA, (long)major(sb->st_rdev),
! 173: (long)minor(sb->st_rdev)) == -1)
1.1 misho 174: return -1;
175: # endif
176: # else
1.1.1.3 ! misho 177: if (file_printf(ms, "%scharacter special", COMMA) == -1)
1.1 misho 178: return -1;
179: # endif
180: }
181: return 1;
182: # endif
183: #endif
184:
185: #ifdef S_IFIFO
1.1.1.2 misho 186: case S_IFIFO:
187: if((ms->flags & MAGIC_DEVICES) != 0)
188: break;
189: if (mime) {
190: if (handle_mime(ms, mime, "fifo") == -1)
191: return -1;
1.1.1.3 ! misho 192: } else if (file_printf(ms, "%sfifo (named pipe)", COMMA) == -1)
1.1.1.2 misho 193: return -1;
1.1.1.3 ! misho 194: break;
1.1 misho 195: #endif
196: #ifdef S_IFDOOR
1.1.1.2 misho 197: case S_IFDOOR:
198: if (mime) {
199: if (handle_mime(ms, mime, "door") == -1)
200: return -1;
1.1.1.3 ! misho 201: } else if (file_printf(ms, "%sdoor", COMMA) == -1)
1.1.1.2 misho 202: return -1;
1.1.1.3 ! misho 203: break;
1.1 misho 204: #endif
205: #ifdef S_IFLNK
206: case S_IFLNK:
207: /* stat is used, if it made here then the link is broken */
208: if (ms->flags & MAGIC_ERROR) {
209: file_error(ms, errno, "unreadable symlink `%s'", fn);
210: return -1;
211: }
212: return 1;
213: #endif
214:
215: #ifdef S_IFSOCK
216: #ifndef __COHERENT__
217: case S_IFSOCK:
218: if (mime) {
1.1.1.2 misho 219: if (handle_mime(ms, mime, "socket") == -1)
1.1 misho 220: return -1;
1.1.1.3 ! misho 221: } else if (file_printf(ms, "%ssocket", COMMA) == -1)
1.1 misho 222: return -1;
1.1.1.3 ! misho 223: break;
1.1 misho 224: #endif
225: #endif
226: case S_IFREG:
227: /*
228: * regular file, check next possibility
229: *
230: * If stat() tells us the file has zero length, report here that
231: * the file is empty, so we can skip all the work of opening and
232: * reading the file.
1.1.1.3 ! misho 233: * But if the -s option has been given, we skip this
! 234: * optimization, since on some systems, stat() reports zero
! 235: * size for raw disk partitions. (If the block special device
! 236: * really has zero length, the fact that it is empty will be
! 237: * detected and reported correctly when we read the file.)
1.1 misho 238: */
239: if ((ms->flags & MAGIC_DEVICES) == 0 && sb->st_size == 0) {
240: if (mime) {
241: if (handle_mime(ms, mime, "x-empty") == -1)
242: return -1;
1.1.1.3 ! misho 243: } else if (file_printf(ms, "%sempty", COMMA) == -1)
1.1 misho 244: return -1;
1.1.1.3 ! misho 245: break;
1.1 misho 246: }
1.1.1.3 ! misho 247: ret = 0;
! 248: break;
! 249:
! 250: default:
! 251: file_error(ms, 0, "invalid mode 0%o", sb->st_mode);
! 252: return -1;
! 253: /*NOTREACHED*/
! 254: }
! 255:
! 256: return ret;
1.1 misho 257: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>