Annotation of src/usr.bin/file/funcs.c, Revision 1.2
1.2 ! tedu 1: /* $OpenBSD$ */
1.1 tedu 2: /*
3: * Copyright (c) Christos Zoulas 2003.
4: * All Rights Reserved.
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: * 3. The name of the author may not be used to endorse or promote products
16: * derived from this software without specific prior written permission.
17: *
18: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21: * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
22: * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28: * SUCH DAMAGE.
29: */
30: #include "file.h"
31: #include "magic.h"
32: #include <stdarg.h>
33: #include <stdlib.h>
34: #include <string.h>
35: #include <ctype.h>
36:
37: #ifndef lint
1.2 ! tedu 38: FILE_RCSID("@(#)$Id: funcs.c,v 1.1 2004/05/19 02:32:35 tedu Exp $")
1.1 tedu 39: #endif /* lint */
40: /*
41: * Like printf, only we print to a buffer and advance it.
42: */
43: protected int
44: file_printf(struct magic_set *ms, const char *fmt, ...)
45: {
46: va_list ap;
47: size_t len;
48: char *buf;
49:
50: va_start(ap, fmt);
51:
52: if ((len = vsnprintf(ms->o.ptr, ms->o.len, fmt, ap)) >= ms->o.len) {
53: va_end(ap);
54: if ((buf = realloc(ms->o.buf, len + 1024)) == NULL) {
55: file_oomem(ms);
56: return -1;
57: }
58: ms->o.ptr = buf + (ms->o.ptr - ms->o.buf);
59: ms->o.buf = buf;
60: ms->o.len = ms->o.size - (ms->o.ptr - ms->o.buf);
61: ms->o.size = len + 1024;
62:
63: va_start(ap, fmt);
64: len = vsnprintf(ms->o.ptr, ms->o.len, fmt, ap);
65: }
66: ms->o.ptr += len;
67: ms->o.len -= len;
68: va_end(ap);
69: return 0;
70: }
71:
72: /*
73: * error - print best error message possible
74: */
75: /*VARARGS*/
76: protected void
77: file_error(struct magic_set *ms, int error, const char *f, ...)
78: {
79: va_list va;
80: /* Only the first error is ok */
81: if (ms->haderr)
82: return;
83: va_start(va, f);
84: (void)vsnprintf(ms->o.buf, ms->o.size, f, va);
85: va_end(va);
86: if (error > 0) {
87: size_t len = strlen(ms->o.buf);
88: (void)snprintf(ms->o.buf + len, ms->o.size - len, " (%s)",
89: strerror(error));
90: }
91: ms->haderr++;
92: ms->error = error;
93: }
94:
95:
96: protected void
97: file_oomem(struct magic_set *ms)
98: {
99: file_error(ms, errno, "cannot allocate memory");
100: }
101:
102: protected void
103: file_badseek(struct magic_set *ms)
104: {
105: file_error(ms, errno, "error seeking");
106: }
107:
108: protected void
109: file_badread(struct magic_set *ms)
110: {
111: file_error(ms, errno, "error reading");
112: }
113:
114: protected int
115: file_buffer(struct magic_set *ms, const void *buf, size_t nb)
116: {
117: int m;
118: /* try compression stuff */
119: if ((m = file_zmagic(ms, buf, nb)) == 0) {
120: /* Check if we have a tar file */
121: if ((m = file_is_tar(ms, buf, nb)) == 0) {
122: /* try tests in /etc/magic (or surrogate magic file) */
123: if ((m = file_softmagic(ms, buf, nb)) == 0) {
124: /* try known keywords, check whether it is ASCII */
125: if ((m = file_ascmagic(ms, buf, nb)) == 0) {
126: /* abandon hope, all ye who remain here */
127: if (file_printf(ms, ms->flags & MAGIC_MIME ?
128: "application/octet-stream" : "data") == -1)
129: return -1;
130: m = 1;
131: }
132: }
133: }
134: }
135: return m;
136: }
137:
138: protected int
139: file_reset(struct magic_set *ms)
140: {
141: if (ms->mlist == NULL) {
142: file_error(ms, 0, "no magic files loaded");
143: return -1;
144: }
145: ms->o.ptr = ms->o.buf;
146: ms->haderr = 0;
147: ms->error = -1;
148: return 0;
149: }
150:
151: protected const char *
152: file_getbuffer(struct magic_set *ms)
153: {
154: char *nbuf, *op, *np;
155: size_t nsize;
156:
157: if (ms->haderr)
158: return NULL;
159:
160: if (ms->flags & MAGIC_RAW)
161: return ms->o.buf;
162:
163: nsize = ms->o.len * 4 + 1;
164: if (ms->o.psize < nsize) {
165: if ((nbuf = realloc(ms->o.pbuf, nsize)) == NULL) {
166: file_oomem(ms);
167: return NULL;
168: }
169: ms->o.psize = nsize;
170: ms->o.pbuf = nbuf;
171: }
172:
173: for (np = ms->o.pbuf, op = ms->o.buf; *op; op++) {
174: if (isprint((unsigned char)*op)) {
175: *np++ = *op;
176: } else {
177: *np++ = '\\';
178: *np++ = ((*op >> 6) & 3) + '0';
179: *np++ = ((*op >> 3) & 7) + '0';
180: *np++ = ((*op >> 0) & 7) + '0';
181: }
182: }
183: *np = '\0';
184: return ms->o.pbuf;
185: }