[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.4

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