root/ext/fileinfo/libmagic/fsmagic.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. handle_mime
  2. file_fsmagic

   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.74 2014/10/13 20:21:49 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 #ifdef WIN32
  57 # define WIN32_LEAN_AND_MEAN
  58 # include <windows.h>
  59 #endif
  60 
  61 #ifndef HAVE_MAJOR
  62 # define major(dev)  (((dev) >> 8) & 0xff)
  63 # define minor(dev)  ((dev) & 0xff)
  64 #endif
  65 #undef HAVE_MAJOR
  66 
  67 #ifdef PHP_WIN32
  68 
  69 # undef S_IFIFO
  70 #endif
  71 
  72 
  73 #ifndef S_ISDIR
  74 #define S_ISDIR(mode) ((mode) & _S_IFDIR)
  75 #endif
  76 
  77 #ifndef S_ISREG
  78 #define S_ISREG(mode) ((mode) & _S_IFREG)
  79 #endif
  80 
  81 private int
  82 handle_mime(struct magic_set *ms, int mime, const char *str)
  83 {
  84         if ((mime & MAGIC_MIME_TYPE)) {
  85                 if (file_printf(ms, "inode/%s", str) == -1)
  86                         return -1;
  87                 if ((mime & MAGIC_MIME_ENCODING) && file_printf(ms,
  88                     "; charset=") == -1)
  89                         return -1;
  90         }
  91         if ((mime & MAGIC_MIME_ENCODING) && file_printf(ms, "binary") == -1)
  92                 return -1;
  93         return 0;
  94 }
  95 
  96 protected int
  97 file_fsmagic(struct magic_set *ms, const char *fn, zend_stat_t *sb, php_stream *stream)
  98 {
  99         int ret, did = 0;
 100         int mime = ms->flags & MAGIC_MIME;
 101 
 102         if (ms->flags & MAGIC_APPLE)
 103                 return 0;
 104 
 105         if (fn == NULL && !stream) {
 106                 return 0;
 107         }
 108 
 109 #define COMMA   (did++ ? ", " : "")
 110 
 111         if (stream) {
 112                 php_stream_statbuf ssb;
 113                 if (php_stream_stat(stream, &ssb) < 0) {
 114                         if (ms->flags & MAGIC_ERROR) {
 115                                 file_error(ms, errno, "cannot stat `%s'", fn);
 116                                 return -1;
 117                         }
 118                         return 0;
 119                 }
 120                 memcpy(sb, &ssb.sb, sizeof(struct stat));
 121         } else {
 122                 if (php_sys_stat(fn, sb) != 0) {
 123                         if (ms->flags & MAGIC_ERROR) {
 124                                 file_error(ms, errno, "cannot stat `%s'", fn);
 125                                 return -1;
 126                         }
 127                         return 0;
 128                 }
 129         }
 130 
 131         ret = 1;
 132         if (!mime) {
 133 #ifdef S_ISUID
 134                 if (sb->st_mode & S_ISUID)
 135                         if (file_printf(ms, "%ssetuid", COMMA) == -1)
 136                                 return -1;
 137 #endif
 138 #ifdef S_ISGID
 139                 if (sb->st_mode & S_ISGID) 
 140                         if (file_printf(ms, "%ssetgid", COMMA) == -1)
 141                                 return -1;
 142 #endif
 143 #ifdef S_ISVTX
 144                 if (sb->st_mode & S_ISVTX) 
 145                         if (file_printf(ms, "%ssticky", COMMA) == -1)
 146                                 return -1;
 147 #endif
 148         }
 149         
 150         switch (sb->st_mode & S_IFMT) {
 151 #ifndef PHP_WIN32
 152 # ifdef S_IFCHR
 153                 case S_IFCHR:
 154                         /*
 155                          * If -s has been specified, treat character special files
 156                          * like ordinary files.  Otherwise, just report that they
 157                          * are block special files and go on to the next file.
 158                          */
 159                         if ((ms->flags & MAGIC_DEVICES) != 0) {
 160                                 ret = 0;
 161                                 break;
 162                         }
 163                         if (mime) {
 164                                 if (handle_mime(ms, mime, "chardevice") == -1)
 165                                         return -1;
 166                         } else {
 167 #  ifdef HAVE_STAT_ST_RDEV
 168 #   ifdef dv_unit
 169                         if (file_printf(ms, "%scharacter special (%d/%d/%d)",
 170                             COMMA, major(sb->st_rdev), dv_unit(sb->st_rdev),
 171                                         dv_subunit(sb->st_rdev)) == -1)
 172                                 return -1;
 173 # else
 174                         if (file_printf(ms, "%scharacter special (%ld/%ld)",
 175                             COMMA, (long)major(sb->st_rdev),
 176                             (long)minor(sb->st_rdev)) == -1)
 177                                 return -1;
 178 # endif
 179 #else
 180                         if (file_printf(ms, "%scharacter special", COMMA) == -1)
 181                                 return -1;
 182 #endif
 183         }
 184                         return 1;
 185 # endif
 186 #endif
 187 
 188 #ifdef  S_IFIFO
 189         case S_IFIFO:
 190                 if((ms->flags & MAGIC_DEVICES) != 0)
 191                         break;
 192                 if (mime) {
 193                         if (handle_mime(ms, mime, "fifo") == -1)
 194                                 return -1;
 195                 } else if (file_printf(ms, "%sfifo (named pipe)", COMMA) == -1)
 196                         return -1;
 197                 break;
 198 #endif
 199 #ifdef  S_IFDOOR
 200         case S_IFDOOR:
 201                 if (mime) {
 202                         if (handle_mime(ms, mime, "door") == -1)
 203                                 return -1;
 204                 } else if (file_printf(ms, "%sdoor", COMMA) == -1)
 205                         return -1;
 206                 break;
 207 #endif
 208 #ifdef  S_IFLNK
 209         case S_IFLNK:
 210                 /* stat is used, if it made here then the link is broken */
 211                         if (ms->flags & MAGIC_ERROR) {
 212                             file_error(ms, errno, "unreadable symlink `%s'", fn);
 213                             return -1;
 214                         }
 215         return 1;
 216 #endif
 217 
 218 #ifdef  S_IFSOCK
 219 #ifndef __COHERENT__
 220         case S_IFSOCK:
 221                 if (mime) {
 222                         if (handle_mime(ms, mime, "socket") == -1)
 223                                 return -1;
 224                 } else if (file_printf(ms, "%ssocket", COMMA) == -1)
 225                         return -1;
 226                 break;
 227 #endif
 228 #endif
 229         case S_IFREG:
 230                 /*
 231                  * regular file, check next possibility
 232                  *
 233                  * If stat() tells us the file has zero length, report here that
 234                  * the file is empty, so we can skip all the work of opening and
 235                  * reading the file.
 236                  * But if the -s option has been given, we skip this
 237                  * optimization, since on some systems, stat() reports zero
 238                  * size for raw disk partitions. (If the block special device
 239                  * really has zero length, the fact that it is empty will be
 240                  * detected and reported correctly when we read the file.)
 241          */
 242         if ((ms->flags & MAGIC_DEVICES) == 0 && sb->st_size == 0) {
 243                 if (mime) {
 244                         if (handle_mime(ms, mime, "x-empty") == -1)
 245                                 return -1;
 246                         } else if (file_printf(ms, "%sempty", COMMA) == -1)
 247                         return -1;
 248                         break;
 249         }
 250                 ret = 0;
 251                 break;
 252 
 253         default:
 254                 file_error(ms, 0, "invalid mode 0%o", sb->st_mode);
 255                 return -1;
 256                 /*NOTREACHED*/
 257         }
 258 
 259         return ret;
 260 }

/* [<][>][^][v][top][bottom][index][help] */