[BACK]Return to funcs.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / file

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: }