magic.c 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  1. /*
  2. * Copyright (c) Christos Zoulas 2003.
  3. * All Rights Reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions
  7. * are met:
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice immediately at the beginning of the file, without modification,
  10. * this list of conditions, and the following disclaimer.
  11. * 2. Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in the
  13. * documentation and/or other materials provided with the distribution.
  14. *
  15. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  16. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  17. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  18. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
  19. * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  20. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  21. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  22. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  23. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  24. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  25. * SUCH DAMAGE.
  26. */
  27. #include "file.h"
  28. #include "magic.h"
  29. #include <stdio.h>
  30. #include <stdlib.h>
  31. #include <unistd.h>
  32. #include <string.h>
  33. #include <sys/types.h>
  34. #include <sys/param.h> /* for MAXPATHLEN */
  35. #include <sys/stat.h>
  36. #include <fcntl.h> /* for open() */
  37. #ifdef QUICK
  38. #include <sys/mman.h>
  39. #endif
  40. #if defined(HAVE_UTIMES)
  41. # include <sys/time.h>
  42. #elif defined(HAVE_UTIME)
  43. # if defined(HAVE_SYS_UTIME_H)
  44. # include <sys/utime.h>
  45. # elif defined(HAVE_UTIME_H)
  46. # include <utime.h>
  47. # endif
  48. #endif
  49. #ifdef HAVE_UNISTD_H
  50. #include <unistd.h> /* for read() */
  51. #endif
  52. #ifdef HAVE_LOCALE_H
  53. #include <locale.h>
  54. #endif
  55. #include <netinet/in.h> /* for byte swapping */
  56. #include "patchlevel.h"
  57. #ifndef lint
  58. FILE_RCSID("@(#)$Id: magic.c,v 1.28 2005/06/25 15:52:14 christos Exp $")
  59. #endif /* lint */
  60. #ifdef __EMX__
  61. private char *apptypeName = NULL;
  62. protected int file_os2_apptype(struct magic_set *ms, const char *fn,
  63. const void *buf, size_t nb);
  64. #endif /* __EMX__ */
  65. private void free_mlist(struct mlist *);
  66. private void close_and_restore(const struct magic_set *, const char *, int,
  67. const struct stat *);
  68. public struct magic_set *
  69. magic_open(int flags)
  70. {
  71. struct magic_set *ms;
  72. if ((ms = malloc(sizeof(struct magic_set))) == NULL)
  73. return NULL;
  74. if (magic_setflags(ms, flags) == -1) {
  75. errno = EINVAL;
  76. goto free1;
  77. }
  78. ms->o.ptr = ms->o.buf = malloc(ms->o.size = 1024);
  79. if (ms->o.buf == NULL)
  80. goto free1;
  81. ms->o.pbuf = malloc(ms->o.psize = 1024);
  82. if (ms->o.pbuf == NULL)
  83. goto free2;
  84. ms->c.off = malloc((ms->c.len = 10) * sizeof(*ms->c.off));
  85. if (ms->c.off == NULL)
  86. goto free3;
  87. ms->o.len = 0;
  88. ms->haderr = 0;
  89. ms->error = -1;
  90. ms->mlist = NULL;
  91. return ms;
  92. free3:
  93. free(ms->o.pbuf);
  94. free2:
  95. free(ms->o.buf);
  96. free1:
  97. free(ms);
  98. return NULL;
  99. }
  100. private void
  101. free_mlist(struct mlist *mlist)
  102. {
  103. struct mlist *ml;
  104. if (mlist == NULL)
  105. return;
  106. for (ml = mlist->next; ml != mlist;) {
  107. struct mlist *next = ml->next;
  108. struct magic *mg = ml->magic;
  109. file_delmagic(mg, ml->mapped, ml->nmagic);
  110. free(ml);
  111. ml = next;
  112. }
  113. free(ml);
  114. }
  115. public void
  116. magic_close(ms)
  117. struct magic_set *ms;
  118. {
  119. free_mlist(ms->mlist);
  120. free(ms->o.pbuf);
  121. free(ms->o.buf);
  122. free(ms->c.off);
  123. free(ms);
  124. }
  125. /*
  126. * load a magic file
  127. */
  128. public int
  129. magic_load(struct magic_set *ms, const char *magicfile)
  130. {
  131. struct mlist *ml = file_apprentice(ms, magicfile, FILE_LOAD);
  132. if (ml) {
  133. free_mlist(ms->mlist);
  134. ms->mlist = ml;
  135. return 0;
  136. }
  137. return -1;
  138. }
  139. public int
  140. magic_compile(struct magic_set *ms, const char *magicfile)
  141. {
  142. struct mlist *ml = file_apprentice(ms, magicfile, FILE_COMPILE);
  143. free_mlist(ml);
  144. return ml ? 0 : -1;
  145. }
  146. public int
  147. magic_check(struct magic_set *ms, const char *magicfile)
  148. {
  149. struct mlist *ml = file_apprentice(ms, magicfile, FILE_CHECK);
  150. free_mlist(ml);
  151. return ml ? 0 : -1;
  152. }
  153. private void
  154. close_and_restore(const struct magic_set *ms, const char *name, int fd,
  155. const struct stat *sb)
  156. {
  157. (void) close(fd);
  158. if (fd != STDIN_FILENO && (ms->flags & MAGIC_PRESERVE_ATIME) != 0) {
  159. /*
  160. * Try to restore access, modification times if read it.
  161. * This is really *bad* because it will modify the status
  162. * time of the file... And of course this will affect
  163. * backup programs
  164. */
  165. #ifdef HAVE_UTIMES
  166. struct timeval utsbuf[2];
  167. utsbuf[0].tv_sec = sb->st_atime;
  168. utsbuf[1].tv_sec = sb->st_mtime;
  169. (void) utimes(name, utsbuf); /* don't care if loses */
  170. #elif defined(HAVE_UTIME_H) || defined(HAVE_SYS_UTIME_H)
  171. struct utimbuf utbuf;
  172. utbuf.actime = sb->st_atime;
  173. utbuf.modtime = sb->st_mtime;
  174. (void) utime(name, &utbuf); /* don't care if loses */
  175. #endif
  176. }
  177. }
  178. #ifndef COMPILE_ONLY
  179. /*
  180. * find type of named file
  181. */
  182. public const char *
  183. magic_file(struct magic_set *ms, const char *inname)
  184. {
  185. int fd = 0;
  186. int rv = -1;
  187. unsigned char *buf;
  188. struct stat sb;
  189. ssize_t nbytes = 0; /* number of bytes read from a datafile */
  190. /*
  191. * one extra for terminating '\0', and
  192. * some overlapping space for matches near EOF
  193. */
  194. #define SLOP (1 + sizeof(union VALUETYPE))
  195. if ((buf = malloc(HOWMANY + SLOP)) == NULL)
  196. return NULL;
  197. if (file_reset(ms) == -1)
  198. goto done;
  199. switch (file_fsmagic(ms, inname, &sb)) {
  200. case -1:
  201. goto done;
  202. case 0:
  203. break;
  204. default:
  205. rv = 0;
  206. goto done;
  207. }
  208. #ifndef STDIN_FILENO
  209. #define STDIN_FILENO 0
  210. #endif
  211. if (inname == NULL)
  212. fd = STDIN_FILENO;
  213. else if ((fd = open(inname, O_RDONLY)) < 0) {
  214. /* We cannot open it, but we were able to stat it. */
  215. if (sb.st_mode & 0222)
  216. if (file_printf(ms, "writable, ") == -1)
  217. goto done;
  218. if (sb.st_mode & 0111)
  219. if (file_printf(ms, "executable, ") == -1)
  220. goto done;
  221. if (S_ISREG(sb.st_mode))
  222. if (file_printf(ms, "regular file, ") == -1)
  223. goto done;
  224. if (file_printf(ms, "no read permission") == -1)
  225. goto done;
  226. rv = 0;
  227. goto done;
  228. }
  229. /*
  230. * try looking at the first HOWMANY bytes
  231. */
  232. if ((nbytes = read(fd, (char *)buf, HOWMANY)) == -1) {
  233. file_error(ms, errno, "cannot read `%s'", inname);
  234. goto done;
  235. }
  236. if (nbytes == 0) {
  237. if (file_printf(ms, (ms->flags & MAGIC_MIME) ?
  238. "application/x-empty" : "empty") == -1)
  239. goto done;
  240. } else if (nbytes == 1) {
  241. if (file_printf(ms, "very short file (no magic)") == -1)
  242. goto done;
  243. } else {
  244. (void)memset(buf + nbytes, 0, SLOP); /* NUL terminate */
  245. #ifdef __EMX__
  246. switch (file_os2_apptype(ms, inname, buf, nbytes)) {
  247. case -1:
  248. goto done;
  249. case 0:
  250. break;
  251. default:
  252. rv = 0;
  253. goto done;
  254. }
  255. #endif
  256. if (file_buffer(ms, fd, buf, (size_t)nbytes) == -1)
  257. goto done;
  258. #ifdef BUILTIN_ELF
  259. if (nbytes > 5) {
  260. /*
  261. * We matched something in the file, so this *might*
  262. * be an ELF file, and the file is at least 5 bytes
  263. * long, so if it's an ELF file it has at least one
  264. * byte past the ELF magic number - try extracting
  265. * information from the ELF headers that cannot easily
  266. * be extracted with rules in the magic file.
  267. */
  268. file_tryelf(ms, fd, buf, (size_t)nbytes);
  269. }
  270. #endif
  271. }
  272. rv = 0;
  273. done:
  274. free(buf);
  275. close_and_restore(ms, inname, fd, &sb);
  276. return rv == 0 ? file_getbuffer(ms) : NULL;
  277. }
  278. public const char *
  279. magic_buffer(struct magic_set *ms, const void *buf, size_t nb)
  280. {
  281. if (file_reset(ms) == -1)
  282. return NULL;
  283. /*
  284. * The main work is done here!
  285. * We have the file name and/or the data buffer to be identified.
  286. */
  287. if (file_buffer(ms, -1, buf, nb) == -1) {
  288. return NULL;
  289. }
  290. return file_getbuffer(ms);
  291. }
  292. #endif
  293. public const char *
  294. magic_error(struct magic_set *ms)
  295. {
  296. return ms->haderr ? ms->o.buf : NULL;
  297. }
  298. public int
  299. magic_errno(struct magic_set *ms)
  300. {
  301. return ms->haderr ? ms->error : 0;
  302. }
  303. public int
  304. magic_setflags(struct magic_set *ms, int flags)
  305. {
  306. #if !defined(HAVE_UTIME) && !defined(HAVE_UTIMES)
  307. if (flags & MAGIC_PRESERVE_ATIME)
  308. return -1;
  309. #endif
  310. ms->flags = flags;
  311. return 0;
  312. }