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>