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>