1*dc958920Schristos /* $NetBSD: buffer.c,v 1.1.1.2 2019/05/22 17:19:56 christos Exp $ */ 252d7030aSchristos 352d7030aSchristos /* 452d7030aSchristos * Copyright (c) Christos Zoulas 2017. 552d7030aSchristos * All Rights Reserved. 652d7030aSchristos * 752d7030aSchristos * Redistribution and use in source and binary forms, with or without 852d7030aSchristos * modification, are permitted provided that the following conditions 952d7030aSchristos * are met: 1052d7030aSchristos * 1. Redistributions of source code must retain the above copyright 1152d7030aSchristos * notice immediately at the beginning of the file, without modification, 1252d7030aSchristos * this list of conditions, and the following disclaimer. 1352d7030aSchristos * 2. Redistributions in binary form must reproduce the above copyright 1452d7030aSchristos * notice, this list of conditions and the following disclaimer in the 1552d7030aSchristos * documentation and/or other materials provided with the distribution. 1652d7030aSchristos * 1752d7030aSchristos * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1852d7030aSchristos * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1952d7030aSchristos * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2052d7030aSchristos * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 2152d7030aSchristos * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2252d7030aSchristos * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2352d7030aSchristos * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2452d7030aSchristos * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2552d7030aSchristos * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2652d7030aSchristos * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2752d7030aSchristos * SUCH DAMAGE. 2852d7030aSchristos */ 2952d7030aSchristos #include "file.h" 3052d7030aSchristos 3152d7030aSchristos #ifndef lint 3252d7030aSchristos #if 0 33*dc958920Schristos FILE_RCSID("@(#)$File: buffer.c,v 1.6 2019/05/07 02:27:11 christos Exp $") 3452d7030aSchristos #else 35*dc958920Schristos __RCSID("$NetBSD: buffer.c,v 1.1.1.2 2019/05/22 17:19:56 christos Exp $"); 3652d7030aSchristos #endif 3752d7030aSchristos #endif /* lint */ 3852d7030aSchristos 3952d7030aSchristos #include "magic.h" 4052d7030aSchristos #include <unistd.h> 4152d7030aSchristos #include <string.h> 4252d7030aSchristos #include <stdlib.h> 4352d7030aSchristos #include <sys/stat.h> 4452d7030aSchristos 4552d7030aSchristos void 46*dc958920Schristos buffer_init(struct buffer *b, int fd, const struct stat *st, const void *data, 47*dc958920Schristos size_t len) 4852d7030aSchristos { 4952d7030aSchristos b->fd = fd; 50*dc958920Schristos if (st) 51*dc958920Schristos memcpy(&b->st, st, sizeof(b->st)); 52*dc958920Schristos else if (b->fd == -1 || fstat(b->fd, &b->st) == -1) 5352d7030aSchristos memset(&b->st, 0, sizeof(b->st)); 5452d7030aSchristos b->fbuf = data; 5552d7030aSchristos b->flen = len; 5652d7030aSchristos b->eoff = 0; 5752d7030aSchristos b->ebuf = NULL; 5852d7030aSchristos b->elen = 0; 5952d7030aSchristos } 6052d7030aSchristos 6152d7030aSchristos void 6252d7030aSchristos buffer_fini(struct buffer *b) 6352d7030aSchristos { 6452d7030aSchristos free(b->ebuf); 6552d7030aSchristos } 6652d7030aSchristos 6752d7030aSchristos int 6852d7030aSchristos buffer_fill(const struct buffer *bb) 6952d7030aSchristos { 7052d7030aSchristos struct buffer *b = CCAST(struct buffer *, bb); 7152d7030aSchristos 7252d7030aSchristos if (b->elen != 0) 73*dc958920Schristos return b->elen == CAST(size_t, ~0) ? -1 : 0; 7452d7030aSchristos 7552d7030aSchristos if (!S_ISREG(b->st.st_mode)) 7652d7030aSchristos goto out; 7752d7030aSchristos 78*dc958920Schristos b->elen = CAST(size_t, b->st.st_size) < b->flen ? 79*dc958920Schristos CAST(size_t, b->st.st_size) : b->flen; 8052d7030aSchristos if ((b->ebuf = malloc(b->elen)) == NULL) 8152d7030aSchristos goto out; 8252d7030aSchristos 8352d7030aSchristos b->eoff = b->st.st_size - b->elen; 8452d7030aSchristos if (pread(b->fd, b->ebuf, b->elen, b->eoff) == -1) { 8552d7030aSchristos free(b->ebuf); 8652d7030aSchristos goto out; 8752d7030aSchristos } 8852d7030aSchristos 8952d7030aSchristos return 0; 9052d7030aSchristos out: 91*dc958920Schristos b->elen = CAST(size_t, ~0); 9252d7030aSchristos return -1; 9352d7030aSchristos } 94