Annotation of embedaddon/php/ext/fileinfo/libmagic/fsmagic.c, revision 1.1
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
! 35: FILE_RCSID("@(#)$File: fsmagic.c,v 1.59 2009/02/03 20:27:51 christos Exp $")
! 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)) {
! 81: if (file_printf(ms, "application/%s", str) == -1)
! 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: {
! 95: int mime = ms->flags & MAGIC_MIME;
! 96: TSRMLS_FETCH();
! 97:
! 98: if (ms->flags & MAGIC_APPLE)
! 99: return 0;
! 100:
! 101: if (!fn && !stream) {
! 102: return 0;
! 103: }
! 104:
! 105: if (stream) {
! 106: php_stream_statbuf ssb;
! 107: if (php_stream_stat(stream, &ssb) < 0) {
! 108: if (ms->flags & MAGIC_ERROR) {
! 109: file_error(ms, errno, "cannot stat `%s'", fn);
! 110: return -1;
! 111: }
! 112: return 1;
! 113: }
! 114: memcpy(sb, &ssb.sb, sizeof(struct stat));
! 115: } else {
! 116: if (php_sys_stat(fn, sb) != 0) {
! 117: if (ms->flags & MAGIC_ERROR) {
! 118: file_error(ms, errno, "cannot stat `%s'", fn);
! 119: return -1;
! 120: }
! 121: return 1;
! 122: }
! 123: }
! 124:
! 125: if (!mime) {
! 126: #ifdef S_ISUID
! 127: if (sb->st_mode & S_ISUID)
! 128: if (file_printf(ms, "setuid ") == -1)
! 129: return -1;
! 130: #endif
! 131: #ifdef S_ISGID
! 132: if (sb->st_mode & S_ISGID)
! 133: if (file_printf(ms, "setgid ") == -1)
! 134: return -1;
! 135: #endif
! 136: #ifdef S_ISVTX
! 137: if (sb->st_mode & S_ISVTX)
! 138: if (file_printf(ms, "sticky ") == -1)
! 139: return -1;
! 140: #endif
! 141: }
! 142:
! 143: switch (sb->st_mode & S_IFMT) {
! 144: #ifndef PHP_WIN32
! 145: # ifdef S_IFCHR
! 146: case S_IFCHR:
! 147: /*
! 148: * If -s has been specified, treat character special files
! 149: * like ordinary files. Otherwise, just report that they
! 150: * are block special files and go on to the next file.
! 151: */
! 152: if ((ms->flags & MAGIC_DEVICES) != 0) {
! 153: break;
! 154: }
! 155: if (mime) {
! 156: if (handle_mime(ms, mime, "x-character-device") == -1)
! 157: return -1;
! 158: } else {
! 159: # ifdef HAVE_STAT_ST_RDEV
! 160: # ifdef dv_unit
! 161: if (file_printf(ms, "character special (%d/%d/%d)",
! 162: major(sb->st_rdev), dv_unit(sb->st_rdev),
! 163: dv_subunit(sb->st_rdev)) == -1)
! 164: return -1;
! 165: # else
! 166: if (file_printf(ms, "character special (%ld/%ld)",
! 167: (long)major(sb->st_rdev), (long)minor(sb->st_rdev))
! 168: == -1)
! 169: return -1;
! 170: # endif
! 171: # else
! 172: if (file_printf(ms, "character special") == -1)
! 173: return -1;
! 174: # endif
! 175: }
! 176: return 1;
! 177: # endif
! 178: #endif
! 179:
! 180: #ifdef S_IFIFO
! 181: case S_IFIFO:
! 182: if((ms->flags & MAGIC_DEVICES) != 0)
! 183: break;
! 184: if (mime) {
! 185: if (handle_mime(ms, mime, "x-fifo") == -1)
! 186: return -1;
! 187: } else if (file_printf(ms, "fifo (named pipe)") == -1)
! 188: return -1;
! 189: return 1;
! 190: #endif
! 191: #ifdef S_IFDOOR
! 192: case S_IFDOOR:
! 193: if (mime) {
! 194: if (handle_mime(ms, mime, "x-door") == -1)
! 195: return -1;
! 196: } else if (file_printf(ms, "door") == -1)
! 197: return -1;
! 198: return 1;
! 199: #endif
! 200:
! 201: #ifdef S_IFLNK
! 202: case S_IFLNK:
! 203: /* stat is used, if it made here then the link is broken */
! 204: if (ms->flags & MAGIC_ERROR) {
! 205: file_error(ms, errno, "unreadable symlink `%s'", fn);
! 206: return -1;
! 207: }
! 208: return 1;
! 209: #endif
! 210:
! 211: #ifdef S_IFSOCK
! 212: #ifndef __COHERENT__
! 213: case S_IFSOCK:
! 214: if (mime) {
! 215: if (handle_mime(ms, mime, "x-socket") == -1)
! 216: return -1;
! 217: } else if (file_printf(ms, "socket") == -1)
! 218: return -1;
! 219: return 1;
! 220: #endif
! 221: #endif
! 222:
! 223: case S_IFREG:
! 224: break;
! 225:
! 226: default:
! 227: file_error(ms, 0, "invalid mode 0%o", sb->st_mode);
! 228: return -1;
! 229: /*NOTREACHED*/
! 230: }
! 231:
! 232: /*
! 233: * regular file, check next possibility
! 234: *
! 235: * If stat() tells us the file has zero length, report here that
! 236: * the file is empty, so we can skip all the work of opening and
! 237: * reading the file.
! 238: * But if the -s option has been given, we skip this optimization,
! 239: * since on some systems, stat() reports zero size for raw disk
! 240: * partitions. (If the block special device really has zero length,
! 241: * the fact that it is empty will be detected and reported correctly
! 242: * when we read the file.)
! 243: */
! 244: if ((ms->flags & MAGIC_DEVICES) == 0 && sb->st_size == 0) {
! 245: if (mime) {
! 246: if (handle_mime(ms, mime, "x-empty") == -1)
! 247: return -1;
! 248: } else if (file_printf(ms, "empty") == -1)
! 249: return -1;
! 250: return 1;
! 251: }
! 252: return 0;
! 253: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>