1333917Seadler/* 2333917Seadler * Copyright (c) Christos Zoulas 2017. 3333917Seadler * All Rights Reserved. 4333917Seadler * 5333917Seadler * Redistribution and use in source and binary forms, with or without 6333917Seadler * modification, are permitted provided that the following conditions 7333917Seadler * are met: 8333917Seadler * 1. Redistributions of source code must retain the above copyright 9333917Seadler * notice immediately at the beginning of the file, without modification, 10333917Seadler * this list of conditions, and the following disclaimer. 11333917Seadler * 2. Redistributions in binary form must reproduce the above copyright 12333917Seadler * notice, this list of conditions and the following disclaimer in the 13333917Seadler * documentation and/or other materials provided with the distribution. 14333917Seadler * 15333917Seadler * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16333917Seadler * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17333917Seadler * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18333917Seadler * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 19333917Seadler * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20333917Seadler * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21333917Seadler * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22333917Seadler * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23333917Seadler * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24333917Seadler * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25333917Seadler * SUCH DAMAGE. 26333917Seadler */ 27333917Seadler#include "file.h" 28333917Seadler 29333917Seadler#ifndef lint 30362844SdelphijFILE_RCSID("@(#)$File: buffer.c,v 1.8 2020/02/16 15:52:49 christos Exp $") 31333917Seadler#endif /* lint */ 32333917Seadler 33333917Seadler#include "magic.h" 34333917Seadler#include <unistd.h> 35333917Seadler#include <string.h> 36333917Seadler#include <stdlib.h> 37333917Seadler#include <sys/stat.h> 38333917Seadler 39333917Seadlervoid 40354939Sdelphijbuffer_init(struct buffer *b, int fd, const struct stat *st, const void *data, 41354939Sdelphij size_t len) 42333917Seadler{ 43333917Seadler b->fd = fd; 44354939Sdelphij if (st) 45354939Sdelphij memcpy(&b->st, st, sizeof(b->st)); 46354939Sdelphij else if (b->fd == -1 || fstat(b->fd, &b->st) == -1) 47333917Seadler memset(&b->st, 0, sizeof(b->st)); 48333917Seadler b->fbuf = data; 49333917Seadler b->flen = len; 50333917Seadler b->eoff = 0; 51333917Seadler b->ebuf = NULL; 52333917Seadler b->elen = 0; 53333917Seadler} 54333917Seadler 55333917Seadlervoid 56333917Seadlerbuffer_fini(struct buffer *b) 57333917Seadler{ 58333917Seadler free(b->ebuf); 59333917Seadler} 60333917Seadler 61333917Seadlerint 62333917Seadlerbuffer_fill(const struct buffer *bb) 63333917Seadler{ 64333917Seadler struct buffer *b = CCAST(struct buffer *, bb); 65333917Seadler 66333917Seadler if (b->elen != 0) 67362844Sdelphij return b->elen == FILE_BADSIZE ? -1 : 0; 68333917Seadler 69333917Seadler if (!S_ISREG(b->st.st_mode)) 70333917Seadler goto out; 71333917Seadler 72354939Sdelphij b->elen = CAST(size_t, b->st.st_size) < b->flen ? 73354939Sdelphij CAST(size_t, b->st.st_size) : b->flen; 74333917Seadler if ((b->ebuf = malloc(b->elen)) == NULL) 75333917Seadler goto out; 76333917Seadler 77333917Seadler b->eoff = b->st.st_size - b->elen; 78333917Seadler if (pread(b->fd, b->ebuf, b->elen, b->eoff) == -1) { 79333917Seadler free(b->ebuf); 80360521Sdelphij b->ebuf = NULL; 81333917Seadler goto out; 82333917Seadler } 83333917Seadler 84333917Seadler return 0; 85333917Seadlerout: 86362844Sdelphij b->elen = FILE_BADSIZE; 87333917Seadler return -1; 88333917Seadler} 89