158a0f0d0SEitan Adler /*
258a0f0d0SEitan Adler * Copyright (c) Christos Zoulas 2017.
358a0f0d0SEitan Adler * All Rights Reserved.
458a0f0d0SEitan Adler *
558a0f0d0SEitan Adler * Redistribution and use in source and binary forms, with or without
658a0f0d0SEitan Adler * modification, are permitted provided that the following conditions
758a0f0d0SEitan Adler * are met:
858a0f0d0SEitan Adler * 1. Redistributions of source code must retain the above copyright
958a0f0d0SEitan Adler * notice immediately at the beginning of the file, without modification,
1058a0f0d0SEitan Adler * this list of conditions, and the following disclaimer.
1158a0f0d0SEitan Adler * 2. Redistributions in binary form must reproduce the above copyright
1258a0f0d0SEitan Adler * notice, this list of conditions and the following disclaimer in the
1358a0f0d0SEitan Adler * documentation and/or other materials provided with the distribution.
1458a0f0d0SEitan Adler *
1558a0f0d0SEitan Adler * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1658a0f0d0SEitan Adler * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1758a0f0d0SEitan Adler * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1858a0f0d0SEitan Adler * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
1958a0f0d0SEitan Adler * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2058a0f0d0SEitan Adler * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2158a0f0d0SEitan Adler * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2258a0f0d0SEitan Adler * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2358a0f0d0SEitan Adler * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2458a0f0d0SEitan Adler * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2558a0f0d0SEitan Adler * SUCH DAMAGE.
2658a0f0d0SEitan Adler */
2758a0f0d0SEitan Adler #include "file.h"
2858a0f0d0SEitan Adler
2958a0f0d0SEitan Adler #ifndef lint
30*898496eeSXin LI FILE_RCSID("@(#)$File: buffer.c,v 1.13 2023/07/02 12:48:39 christos Exp $")
3158a0f0d0SEitan Adler #endif /* lint */
3258a0f0d0SEitan Adler
3358a0f0d0SEitan Adler #include "magic.h"
3458a0f0d0SEitan Adler #include <unistd.h>
3558a0f0d0SEitan Adler #include <string.h>
3658a0f0d0SEitan Adler #include <stdlib.h>
3758a0f0d0SEitan Adler #include <sys/stat.h>
3858a0f0d0SEitan Adler
3958a0f0d0SEitan Adler void
buffer_init(struct buffer * b,int fd,const struct stat * st,const void * data,size_t len)4048c779cdSXin LI buffer_init(struct buffer *b, int fd, const struct stat *st, const void *data,
4148c779cdSXin LI size_t len)
4258a0f0d0SEitan Adler {
4358a0f0d0SEitan Adler b->fd = fd;
4448c779cdSXin LI if (st)
4548c779cdSXin LI memcpy(&b->st, st, sizeof(b->st));
4648c779cdSXin LI else if (b->fd == -1 || fstat(b->fd, &b->st) == -1)
4758a0f0d0SEitan Adler memset(&b->st, 0, sizeof(b->st));
4858a0f0d0SEitan Adler b->fbuf = data;
4958a0f0d0SEitan Adler b->flen = len;
5058a0f0d0SEitan Adler b->eoff = 0;
5158a0f0d0SEitan Adler b->ebuf = NULL;
5258a0f0d0SEitan Adler b->elen = 0;
5358a0f0d0SEitan Adler }
5458a0f0d0SEitan Adler
5558a0f0d0SEitan Adler void
buffer_fini(struct buffer * b)5658a0f0d0SEitan Adler buffer_fini(struct buffer *b)
5758a0f0d0SEitan Adler {
5858a0f0d0SEitan Adler free(b->ebuf);
59*898496eeSXin LI b->ebuf = NULL;
60*898496eeSXin LI b->elen = 0;
6158a0f0d0SEitan Adler }
6258a0f0d0SEitan Adler
6358a0f0d0SEitan Adler int
buffer_fill(const struct buffer * bb)6458a0f0d0SEitan Adler buffer_fill(const struct buffer *bb)
6558a0f0d0SEitan Adler {
6658a0f0d0SEitan Adler struct buffer *b = CCAST(struct buffer *, bb);
6758a0f0d0SEitan Adler
6858a0f0d0SEitan Adler if (b->elen != 0)
692726a701SXin LI return b->elen == FILE_BADSIZE ? -1 : 0;
7058a0f0d0SEitan Adler
7158a0f0d0SEitan Adler if (!S_ISREG(b->st.st_mode))
7258a0f0d0SEitan Adler goto out;
7358a0f0d0SEitan Adler
7448c779cdSXin LI b->elen = CAST(size_t, b->st.st_size) < b->flen ?
7548c779cdSXin LI CAST(size_t, b->st.st_size) : b->flen;
76*898496eeSXin LI if (b->elen == 0) {
77*898496eeSXin LI free(b->ebuf);
78*898496eeSXin LI b->ebuf = NULL;
79*898496eeSXin LI return 0;
80*898496eeSXin LI }
8158a0f0d0SEitan Adler if ((b->ebuf = malloc(b->elen)) == NULL)
8258a0f0d0SEitan Adler goto out;
8358a0f0d0SEitan Adler
8458a0f0d0SEitan Adler b->eoff = b->st.st_size - b->elen;
8558a0f0d0SEitan Adler if (pread(b->fd, b->ebuf, b->elen, b->eoff) == -1) {
8658a0f0d0SEitan Adler free(b->ebuf);
87d38c30c0SXin LI b->ebuf = NULL;
8858a0f0d0SEitan Adler goto out;
8958a0f0d0SEitan Adler }
9058a0f0d0SEitan Adler
9158a0f0d0SEitan Adler return 0;
9258a0f0d0SEitan Adler out:
932726a701SXin LI b->elen = FILE_BADSIZE;
9458a0f0d0SEitan Adler return -1;
9558a0f0d0SEitan Adler }
96