xref: /dflybsd-src/contrib/file/src/buffer.c (revision c990e5ba296a6fc9cca0b70d4c36d67f474f8a61)
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