16fca56fbSSascha Wildner /*
26fca56fbSSascha Wildner * Copyright (c) Christos Zoulas 2017.
36fca56fbSSascha Wildner * All Rights Reserved.
46fca56fbSSascha Wildner *
56fca56fbSSascha Wildner * Redistribution and use in source and binary forms, with or without
66fca56fbSSascha Wildner * modification, are permitted provided that the following conditions
76fca56fbSSascha Wildner * are met:
86fca56fbSSascha Wildner * 1. Redistributions of source code must retain the above copyright
96fca56fbSSascha Wildner * notice immediately at the beginning of the file, without modification,
106fca56fbSSascha Wildner * this list of conditions, and the following disclaimer.
116fca56fbSSascha Wildner * 2. Redistributions in binary form must reproduce the above copyright
126fca56fbSSascha Wildner * notice, this list of conditions and the following disclaimer in the
136fca56fbSSascha Wildner * documentation and/or other materials provided with the distribution.
146fca56fbSSascha Wildner *
156fca56fbSSascha Wildner * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
166fca56fbSSascha Wildner * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
176fca56fbSSascha Wildner * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
186fca56fbSSascha Wildner * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
196fca56fbSSascha Wildner * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
206fca56fbSSascha Wildner * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
216fca56fbSSascha Wildner * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
226fca56fbSSascha Wildner * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
236fca56fbSSascha Wildner * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
246fca56fbSSascha Wildner * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
256fca56fbSSascha Wildner * SUCH DAMAGE.
266fca56fbSSascha Wildner */
276fca56fbSSascha Wildner #include "file.h"
286fca56fbSSascha Wildner
296fca56fbSSascha Wildner #ifndef lint
30*c990e5baSDaniel Fojt FILE_RCSID("@(#)$File: buffer.c,v 1.8 2020/02/16 15:52:49 christos Exp $")
316fca56fbSSascha Wildner #endif /* lint */
326fca56fbSSascha Wildner
336fca56fbSSascha Wildner #include "magic.h"
346fca56fbSSascha Wildner #include <unistd.h>
356fca56fbSSascha Wildner #include <string.h>
366fca56fbSSascha Wildner #include <stdlib.h>
376fca56fbSSascha Wildner #include <sys/stat.h>
386fca56fbSSascha Wildner
396fca56fbSSascha Wildner void
buffer_init(struct buffer * b,int fd,const struct stat * st,const void * data,size_t len)406fca56fbSSascha Wildner buffer_init(struct buffer *b, int fd, const struct stat *st, const void *data,
416fca56fbSSascha Wildner size_t len)
426fca56fbSSascha Wildner {
436fca56fbSSascha Wildner b->fd = fd;
446fca56fbSSascha Wildner if (st)
456fca56fbSSascha Wildner memcpy(&b->st, st, sizeof(b->st));
466fca56fbSSascha Wildner else if (b->fd == -1 || fstat(b->fd, &b->st) == -1)
476fca56fbSSascha Wildner memset(&b->st, 0, sizeof(b->st));
486fca56fbSSascha Wildner b->fbuf = data;
496fca56fbSSascha Wildner b->flen = len;
506fca56fbSSascha Wildner b->eoff = 0;
516fca56fbSSascha Wildner b->ebuf = NULL;
526fca56fbSSascha Wildner b->elen = 0;
536fca56fbSSascha Wildner }
546fca56fbSSascha Wildner
556fca56fbSSascha Wildner void
buffer_fini(struct buffer * b)566fca56fbSSascha Wildner buffer_fini(struct buffer *b)
576fca56fbSSascha Wildner {
586fca56fbSSascha Wildner free(b->ebuf);
596fca56fbSSascha Wildner }
606fca56fbSSascha Wildner
616fca56fbSSascha Wildner int
buffer_fill(const struct buffer * bb)626fca56fbSSascha Wildner buffer_fill(const struct buffer *bb)
636fca56fbSSascha Wildner {
646fca56fbSSascha Wildner struct buffer *b = CCAST(struct buffer *, bb);
656fca56fbSSascha Wildner
666fca56fbSSascha Wildner if (b->elen != 0)
67*c990e5baSDaniel Fojt return b->elen == FILE_BADSIZE ? -1 : 0;
686fca56fbSSascha Wildner
696fca56fbSSascha Wildner if (!S_ISREG(b->st.st_mode))
706fca56fbSSascha Wildner goto out;
716fca56fbSSascha Wildner
726fca56fbSSascha Wildner b->elen = CAST(size_t, b->st.st_size) < b->flen ?
736fca56fbSSascha Wildner CAST(size_t, b->st.st_size) : b->flen;
746fca56fbSSascha Wildner if ((b->ebuf = malloc(b->elen)) == NULL)
756fca56fbSSascha Wildner goto out;
766fca56fbSSascha Wildner
776fca56fbSSascha Wildner b->eoff = b->st.st_size - b->elen;
786fca56fbSSascha Wildner if (pread(b->fd, b->ebuf, b->elen, b->eoff) == -1) {
796fca56fbSSascha Wildner free(b->ebuf);
806fca56fbSSascha Wildner b->ebuf = NULL;
816fca56fbSSascha Wildner goto out;
826fca56fbSSascha Wildner }
836fca56fbSSascha Wildner
846fca56fbSSascha Wildner return 0;
856fca56fbSSascha Wildner out:
86*c990e5baSDaniel Fojt b->elen = FILE_BADSIZE;
876fca56fbSSascha Wildner return -1;
886fca56fbSSascha Wildner }
89