funcs.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  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 <stdarg.h>
  30. #include <stdlib.h>
  31. #include <string.h>
  32. #include <ctype.h>
  33. #ifndef lint
  34. FILE_RCSID("@(#)$Id: funcs.c,v 1.15 2005/07/12 20:05:38 christos Exp $")
  35. #endif /* lint */
  36. #ifndef HAVE_VSNPRINTF
  37. int vsnprintf(char *, size_t, const char *, va_list);
  38. #endif
  39. /*
  40. * Like printf, only we print to a buffer and advance it.
  41. */
  42. protected int
  43. file_printf(struct magic_set *ms, const char *fmt, ...)
  44. {
  45. va_list ap;
  46. size_t len;
  47. char *buf;
  48. va_start(ap, fmt);
  49. if ((len = vsnprintf(ms->o.ptr, ms->o.len, fmt, ap)) >= ms->o.len) {
  50. va_end(ap);
  51. if ((buf = realloc(ms->o.buf, len + 1024)) == NULL) {
  52. file_oomem(ms);
  53. return -1;
  54. }
  55. ms->o.ptr = buf + (ms->o.ptr - ms->o.buf);
  56. ms->o.buf = buf;
  57. ms->o.len = ms->o.size - (ms->o.ptr - ms->o.buf);
  58. ms->o.size = len + 1024;
  59. va_start(ap, fmt);
  60. len = vsnprintf(ms->o.ptr, ms->o.len, fmt, ap);
  61. }
  62. ms->o.ptr += len;
  63. ms->o.len -= len;
  64. va_end(ap);
  65. return 0;
  66. }
  67. /*
  68. * error - print best error message possible
  69. */
  70. /*VARARGS*/
  71. protected void
  72. file_error(struct magic_set *ms, int error, const char *f, ...)
  73. {
  74. va_list va;
  75. /* Only the first error is ok */
  76. if (ms->haderr)
  77. return;
  78. va_start(va, f);
  79. (void)vsnprintf(ms->o.buf, ms->o.size, f, va);
  80. va_end(va);
  81. if (error > 0) {
  82. size_t len = strlen(ms->o.buf);
  83. (void)snprintf(ms->o.buf + len, ms->o.size - len, " (%s)",
  84. strerror(error));
  85. }
  86. ms->haderr++;
  87. ms->error = error;
  88. }
  89. protected void
  90. file_oomem(struct magic_set *ms)
  91. {
  92. file_error(ms, errno, "cannot allocate memory");
  93. }
  94. protected void
  95. file_badseek(struct magic_set *ms)
  96. {
  97. file_error(ms, errno, "error seeking");
  98. }
  99. protected void
  100. file_badread(struct magic_set *ms)
  101. {
  102. file_error(ms, errno, "error reading");
  103. }
  104. #ifndef COMPILE_ONLY
  105. protected int
  106. file_buffer(struct magic_set *ms, int fd, const void *buf, size_t nb)
  107. {
  108. int m;
  109. /* try compression stuff */
  110. if ((m = file_zmagic(ms, fd, buf, nb)) == 0) {
  111. /* Check if we have a tar file */
  112. if ((m = file_is_tar(ms, buf, nb)) == 0) {
  113. /* try tests in /etc/magic (or surrogate magic file) */
  114. if ((m = file_softmagic(ms, buf, nb)) == 0) {
  115. /* try known keywords, check whether it is ASCII */
  116. if ((m = file_ascmagic(ms, buf, nb)) == 0) {
  117. /* abandon hope, all ye who remain here */
  118. if (file_printf(ms, ms->flags & MAGIC_MIME ?
  119. "application/octet-stream" : "data") == -1)
  120. return -1;
  121. m = 1;
  122. }
  123. }
  124. }
  125. }
  126. return m;
  127. }
  128. #endif
  129. protected int
  130. file_reset(struct magic_set *ms)
  131. {
  132. if (ms->mlist == NULL) {
  133. file_error(ms, 0, "no magic files loaded");
  134. return -1;
  135. }
  136. ms->o.ptr = ms->o.buf;
  137. ms->haderr = 0;
  138. ms->error = -1;
  139. return 0;
  140. }
  141. protected const char *
  142. file_getbuffer(struct magic_set *ms)
  143. {
  144. char *nbuf, *op, *np;
  145. size_t nsize;
  146. if (ms->haderr)
  147. return NULL;
  148. if (ms->flags & MAGIC_RAW)
  149. return ms->o.buf;
  150. nsize = ms->o.len * 4 + 1;
  151. if (ms->o.psize < nsize) {
  152. if ((nbuf = realloc(ms->o.pbuf, nsize)) == NULL) {
  153. file_oomem(ms);
  154. return NULL;
  155. }
  156. ms->o.psize = nsize;
  157. ms->o.pbuf = nbuf;
  158. }
  159. for (np = ms->o.pbuf, op = ms->o.buf; *op; op++) {
  160. if (isprint((unsigned char)*op)) {
  161. *np++ = *op;
  162. } else {
  163. *np++ = '\\';
  164. *np++ = ((*op >> 6) & 3) + '0';
  165. *np++ = ((*op >> 3) & 7) + '0';
  166. *np++ = ((*op >> 0) & 7) + '0';
  167. }
  168. }
  169. *np = '\0';
  170. return ms->o.pbuf;
  171. }
  172. /*
  173. * Yes these suffer from buffer overflows, but if your OS does not have
  174. * these functions, then maybe you should consider replacing your OS?
  175. */
  176. #ifndef HAVE_VSNPRINTF
  177. int
  178. vsnprintf(char *buf, size_t len, const char *fmt, va_list ap)
  179. {
  180. vsprintf(buf, fmt, ap);
  181. }
  182. #endif
  183. #ifndef HAVE_SNPRINTF
  184. /*ARGSUSED*/
  185. int
  186. snprintf(char *buf, size_t len, const char *fmt, ...)
  187. {
  188. va_list ap;
  189. va_start(ap, fmt);
  190. vsprintf(buf, fmt, ap);
  191. va_end(ap);
  192. }
  193. #endif