148905Srnordier/*
248905Srnordier * Copyright (c) 1999 Global Technology Associates, Inc.
348905Srnordier * All rights reserved.
448905Srnordier *
548905Srnordier * Redistribution and use in source and binary forms, with or without
648905Srnordier * modification, are permitted provided that the following conditions
748905Srnordier * are met:
848905Srnordier * 1. Redistributions of source code must retain the above copyright
948905Srnordier *    notice, this list of conditions and the following disclaimer.
1048905Srnordier * 2. Redistributions in binary form must reproduce the above copyright
1148905Srnordier *    notice, this list of conditions and the following disclaimer in the
1248905Srnordier *    documentation and/or other materials provided with the distribution.
1348905Srnordier *
1448905Srnordier * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS``AS IS'' AND
1548905Srnordier * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1648905Srnordier * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
1748905Srnordier * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
1848905Srnordier * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
1948905Srnordier * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
2048905Srnordier * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
2148905Srnordier * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
2248905Srnordier * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
2348905Srnordier * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
2448905Srnordier * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2548905Srnordier *
2650479Speter * $FreeBSD$
2748905Srnordier */
2848905Srnordier
2948905Srnordier#include <err.h>
3048905Srnordier#include <string.h>
3148905Srnordier#include <unistd.h>
3248905Srnordier
3348905Srnordier#include "kgzip.h"
3448905Srnordier
3548905Srnordier/*
3648905Srnordier * Close a file.
3748905Srnordier */
3848905Srnordiervoid
3948905Srnordierxclose(const struct iodesc *id)
4048905Srnordier{
4148905Srnordier    if (close(id->fd))
4248905Srnordier	err(1, "%s", id->fname);
4348905Srnordier}
4448905Srnordier
4548905Srnordier/*
4648905Srnordier * Copy bytes from one file to another.
4748905Srnordier */
4848905Srnordiervoid
4948905Srnordierxcopy(const struct iodesc * idi, const struct iodesc * ido,
5048905Srnordier      size_t nbyte, off_t offset)
5148905Srnordier{
5248905Srnordier    char buf[8192];
5348905Srnordier    size_t n;
5448905Srnordier
5548905Srnordier    while (nbyte) {
5648905Srnordier	if ((n = sizeof(buf)) > nbyte)
5748905Srnordier	    n = nbyte;
5848905Srnordier	if (xread(idi, buf, n, offset) != n)
5948905Srnordier	    errx(1, "%s: Short read", idi->fname);
6048905Srnordier	xwrite(ido, buf, n);
6148905Srnordier	nbyte -= n;
6248905Srnordier	offset = -1;
6348905Srnordier    }
6448905Srnordier}
6548905Srnordier
6648905Srnordier/*
6748905Srnordier * Write binary zeroes to a file.
6848905Srnordier */
6948905Srnordiervoid
7048905Srnordierxzero(const struct iodesc * id, size_t nbyte)
7148905Srnordier{
7248905Srnordier    char buf[8192];
7348905Srnordier    size_t n;
7448905Srnordier
7548905Srnordier    memset(buf, 0, sizeof(buf));
7648905Srnordier    while (nbyte) {
7748905Srnordier	if ((n = sizeof(buf)) > nbyte)
7848905Srnordier	    n = nbyte;
7948905Srnordier	xwrite(id, buf, n);
8048905Srnordier	nbyte -= n;
8148905Srnordier    }
8248905Srnordier}
8348905Srnordier
8448905Srnordier/*
8548905Srnordier * Read from a file.
8648905Srnordier */
8748905Srnordiersize_t
8848905Srnordierxread(const struct iodesc * id, void *buf, size_t nbyte, off_t offset)
8948905Srnordier{
9048905Srnordier    ssize_t n;
9148905Srnordier
9248905Srnordier    if (offset != -1 && lseek(id->fd, offset, SEEK_SET) != offset)
9348905Srnordier	err(1, "%s", id->fname);
9448905Srnordier    if ((n = read(id->fd, buf, nbyte)) == -1)
9548905Srnordier	err(1, "%s", id->fname);
9648905Srnordier    return (size_t)n;
9748905Srnordier}
9848905Srnordier
9948905Srnordier/*
10048905Srnordier * Write to a file.
10148905Srnordier */
10248905Srnordiervoid
10348905Srnordierxwrite(const struct iodesc * id, const void *buf, size_t nbyte)
10448905Srnordier{
10548905Srnordier    ssize_t n;
10648905Srnordier
10748905Srnordier    if ((n = write(id->fd, buf, nbyte)) == -1)
10848905Srnordier	err(1, "%s", id->fname);
10948905Srnordier    if ((size_t)n != nbyte)
11048905Srnordier	errx(1, "%s: Short write", id->fname);
11148905Srnordier}
11248905Srnordier
11348905Srnordier/*
11448905Srnordier * Reposition within a file.
11548905Srnordier */
11648905Srnordiervoid
11748905Srnordierxseek(const struct iodesc *id, off_t offset)
11848905Srnordier{
11948905Srnordier    if (lseek(id->fd, offset, SEEK_SET) != offset)
12048905Srnordier	err(1, "%s", id->fname);
12148905Srnordier}
122