/*1* Copyright (c) Christos Zoulas 2017.2* All Rights Reserved.3*4* Redistribution and use in source and binary forms, with or without5* modification, are permitted provided that the following conditions6* are met:7* 1. Redistributions of source code must retain the above copyright8* notice immediately at the beginning of the file, without modification,9* this list of conditions, and the following disclaimer.10* 2. Redistributions in binary form must reproduce the above copyright11* notice, this list of conditions and the following disclaimer in the12* documentation and/or other materials provided with the distribution.13*14* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND15* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE16* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE17* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR18* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL19* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS20* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)21* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT22* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY23* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF24* SUCH DAMAGE.25*/26#include "file.h"2728#ifndef lint29FILE_RCSID("@(#)$File: buffer.c,v 1.13 2023/07/02 12:48:39 christos Exp $")30#endif /* lint */3132#include "magic.h"33#include <unistd.h>34#include <string.h>35#include <stdlib.h>36#include <sys/stat.h>3738void39buffer_init(struct buffer *b, int fd, const struct stat *st, const void *data,40size_t len)41{42b->fd = fd;43if (st)44memcpy(&b->st, st, sizeof(b->st));45else if (b->fd == -1 || fstat(b->fd, &b->st) == -1)46memset(&b->st, 0, sizeof(b->st));47b->fbuf = data;48b->flen = len;49b->eoff = 0;50b->ebuf = NULL;51b->elen = 0;52}5354void55buffer_fini(struct buffer *b)56{57free(b->ebuf);58b->ebuf = NULL;59b->elen = 0;60}6162int63buffer_fill(const struct buffer *bb)64{65struct buffer *b = CCAST(struct buffer *, bb);6667if (b->elen != 0)68return b->elen == FILE_BADSIZE ? -1 : 0;6970if (!S_ISREG(b->st.st_mode))71goto out;7273b->elen = CAST(size_t, b->st.st_size) < b->flen ?74CAST(size_t, b->st.st_size) : b->flen;75if (b->elen == 0) {76free(b->ebuf);77b->ebuf = NULL;78return 0;79}80if ((b->ebuf = malloc(b->elen)) == NULL)81goto out;8283b->eoff = b->st.st_size - b->elen;84if (pread(b->fd, b->ebuf, b->elen, b->eoff) == -1) {85free(b->ebuf);86b->ebuf = NULL;87goto out;88}8990return 0;91out:92b->elen = FILE_BADSIZE;93return -1;94}959697