mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-13 10:02:38 +00:00
kgzip is a kzip(8) replacement able to compress and link bootable
32-bit binaries in both ELF and a.out format. Development sponsored by Global Technology Associates, Inc. Reviewed/tested by: abial
This commit is contained in:
parent
a2dca20711
commit
4566a1d1d3
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/cvs2svn/branches/RNORDIER/; revision=48905
12
usr.sbin/kgzip/Makefile
Normal file
12
usr.sbin/kgzip/Makefile
Normal file
@ -0,0 +1,12 @@
|
||||
# $Id: $
|
||||
|
||||
PROG= kgzip
|
||||
SRCS= kgzip.c elfhdr.c kgzcmp.c kgzld.c xio.c
|
||||
MAN8= kgzip.8
|
||||
CFLAGS+=-pedantic \
|
||||
-W -Wall -Waggregate-return -Wbad-function-cast -Wcast-align \
|
||||
-Wmissing-declarations -Wmissing-prototypes -Wnested-externs \
|
||||
-Wpointer-arith -Wredundant-decls -Wshadow -Wstrict-prototypes \
|
||||
-Wwrite-strings
|
||||
|
||||
.include <bsd.prog.mk>
|
163
usr.sbin/kgzip/elfhdr.c
Normal file
163
usr.sbin/kgzip/elfhdr.c
Normal file
@ -0,0 +1,163 @@
|
||||
/*
|
||||
* Copyright (c) 1999 Global Technology Associates, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id:$
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include "elfhdr.h"
|
||||
|
||||
#define KGZ_FIX_NSIZE 0 /* Run-time fixup */
|
||||
|
||||
/*
|
||||
* Relocatable header template.
|
||||
*/
|
||||
const struct kgz_elfhdr elfhdr = {
|
||||
/* ELF header */
|
||||
{
|
||||
{
|
||||
ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3, /* e_ident */
|
||||
ELFCLASS32, ELFDATA2LSB, EV_CURRENT, 0,
|
||||
'F', 'r', 'e', 'e', 'B', 'S', 'D', 0
|
||||
},
|
||||
ET_EXEC, /* e_type */
|
||||
EM_386, /* e_machine */
|
||||
EV_CURRENT, /* e_version */
|
||||
0, /* e_entry */
|
||||
0, /* e_phoff */
|
||||
offsetof(struct kgz_elfhdr, sh), /* e_shoff */
|
||||
0, /* e_flags */
|
||||
sizeof(Elf32_Ehdr), /* e_ehsize */
|
||||
0, /* e_phentsize */
|
||||
0, /* e_phnum */
|
||||
sizeof(Elf32_Shdr), /* e_shentsize */
|
||||
KGZ_SHNUM, /* e_shnum */
|
||||
KGZ_SH_SHSTRTAB /* e_shstrndx */
|
||||
},
|
||||
/* Section header */
|
||||
{
|
||||
{
|
||||
0, /* sh_name */
|
||||
SHT_NULL, /* sh_type */
|
||||
0, /* sh_flags */
|
||||
0, /* sh_addr */
|
||||
0, /* sh_offset */
|
||||
0, /* sh_size */
|
||||
SHN_UNDEF, /* sh_link */
|
||||
0, /* sh_info */
|
||||
0, /* sh_addralign */
|
||||
0 /* sh_entsize */
|
||||
},
|
||||
{
|
||||
offsetof(struct kgz_shstrtab, symtab), /* sh_name */
|
||||
SHT_SYMTAB, /* sh_type */
|
||||
0, /* sh_flags */
|
||||
0, /* sh_addr */
|
||||
offsetof(struct kgz_elfhdr, st), /* sh_offset */
|
||||
sizeof(Elf32_Sym) * KGZ_STNUM, /* sh_size */
|
||||
KGZ_SH_STRTAB, /* sh_link */
|
||||
1, /* sh_info */
|
||||
4, /* sh_addralign */
|
||||
sizeof(Elf32_Sym) /* sh_entsize */
|
||||
},
|
||||
{
|
||||
offsetof(struct kgz_shstrtab, shstrtab), /* sh_name */
|
||||
SHT_STRTAB, /* sh_type */
|
||||
0, /* sh_flags */
|
||||
0, /* sh_addr */
|
||||
offsetof(struct kgz_elfhdr, shstrtab), /* sh_offset */
|
||||
sizeof(struct kgz_shstrtab), /* sh_size */
|
||||
SHN_UNDEF, /* sh_link */
|
||||
0, /* sh_info */
|
||||
1, /* sh_addralign */
|
||||
0 /* sh_entsize */
|
||||
},
|
||||
{
|
||||
offsetof(struct kgz_shstrtab, strtab), /* sh_name */
|
||||
SHT_STRTAB, /* sh_type */
|
||||
0, /* sh_flags */
|
||||
0, /* sh_addr */
|
||||
offsetof(struct kgz_elfhdr, strtab), /* sh_offset */
|
||||
sizeof(struct kgz_strtab), /* sh_size */
|
||||
SHN_UNDEF, /* sh_link */
|
||||
0, /* sh_info */
|
||||
1, /* sh_addralign */
|
||||
0 /* sh_entsize */
|
||||
},
|
||||
{
|
||||
offsetof(struct kgz_shstrtab, data), /* sh_name */
|
||||
SHT_PROGBITS, /* sh_type */
|
||||
SHF_ALLOC | SHF_WRITE, /* sh_flags */
|
||||
0, /* sh_addr */
|
||||
sizeof(struct kgz_elfhdr), /* sh_offset */
|
||||
sizeof(struct kgz_hdr) + KGZ_FIX_NSIZE, /* sh_size */
|
||||
SHN_UNDEF, /* sh_link */
|
||||
0, /* sh_info */
|
||||
4, /* sh_addralign */
|
||||
0 /* sh_entsize */
|
||||
}
|
||||
},
|
||||
/* Symbol table */
|
||||
{
|
||||
{
|
||||
0, /* st_name */
|
||||
0, /* st_value */
|
||||
0, /* st_size */
|
||||
0, /* st_info */
|
||||
0, /* st_other */
|
||||
SHN_UNDEF /* st_shndx */
|
||||
},
|
||||
{
|
||||
offsetof(struct kgz_strtab, kgz), /* st_name */
|
||||
0, /* st_value */
|
||||
sizeof(struct kgz_hdr), /* st_size */
|
||||
ELF32_ST_INFO(STB_GLOBAL, STT_OBJECT), /* st_info */
|
||||
0, /* st_other */
|
||||
KGZ_SH_DATA /* st_shndx */
|
||||
},
|
||||
{
|
||||
offsetof(struct kgz_strtab, kgz_ndata), /* st_name */
|
||||
sizeof(struct kgz_hdr), /* st_value */
|
||||
KGZ_FIX_NSIZE, /* st_size */
|
||||
ELF32_ST_INFO(STB_GLOBAL, STT_OBJECT), /* st_info */
|
||||
0, /* st_other */
|
||||
KGZ_SH_DATA /* st_shndx */
|
||||
}
|
||||
},
|
||||
/* Section header string table */
|
||||
{
|
||||
KGZ_SHSTR_ZERO, /* zero */
|
||||
KGZ_SHSTR_SYMTAB, /* symtab */
|
||||
KGZ_SHSTR_SHSTRTAB, /* shstrtab */
|
||||
KGZ_SHSTR_STRTAB, /* strtab */
|
||||
KGZ_SHSTR_DATA /* data */
|
||||
},
|
||||
/* String table */
|
||||
{
|
||||
KGZ_STR_ZERO, /* zero */
|
||||
KGZ_STR_KGZ, /* kgz */
|
||||
KGZ_STR_KGZ_NDATA /* kgz_ndata */
|
||||
}
|
||||
};
|
81
usr.sbin/kgzip/elfhdr.h
Normal file
81
usr.sbin/kgzip/elfhdr.h
Normal file
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (c) 1999 Global Technology Associates, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id:$
|
||||
*/
|
||||
|
||||
#include <elf.h>
|
||||
#include "kgz.h"
|
||||
|
||||
/* Section header indices */
|
||||
#define KGZ_SH_SYMTAB 1
|
||||
#define KGZ_SH_SHSTRTAB 2
|
||||
#define KGZ_SH_STRTAB 3
|
||||
#define KGZ_SH_DATA 4
|
||||
#define KGZ_SHNUM 5
|
||||
|
||||
/* Section header strings */
|
||||
#define KGZ_SHSTR_ZERO ""
|
||||
#define KGZ_SHSTR_SYMTAB ".symtab"
|
||||
#define KGZ_SHSTR_SHSTRTAB ".shstrtab"
|
||||
#define KGZ_SHSTR_STRTAB ".strtab"
|
||||
#define KGZ_SHSTR_DATA ".data"
|
||||
|
||||
/* Section header string table */
|
||||
struct kgz_shstrtab {
|
||||
char zero[sizeof(KGZ_SHSTR_ZERO)];
|
||||
char symtab[sizeof(KGZ_SHSTR_SYMTAB)];
|
||||
char shstrtab[sizeof(KGZ_SHSTR_SHSTRTAB)];
|
||||
char strtab[sizeof(KGZ_SHSTR_STRTAB)];
|
||||
char data[sizeof(KGZ_SHSTR_DATA)];
|
||||
};
|
||||
|
||||
/* Symbol table indices */
|
||||
#define KGZ_ST_KGZ 1
|
||||
#define KGZ_ST_KGZ_NDATA 2
|
||||
#define KGZ_STNUM 3
|
||||
|
||||
/* Symbol table strings */
|
||||
#define KGZ_STR_ZERO ""
|
||||
#define KGZ_STR_KGZ "kgz"
|
||||
#define KGZ_STR_KGZ_NDATA "kgz_ndata"
|
||||
|
||||
/* String table */
|
||||
struct kgz_strtab {
|
||||
char zero[sizeof(KGZ_STR_ZERO)];
|
||||
char kgz[sizeof(KGZ_STR_KGZ)];
|
||||
char kgz_ndata[sizeof(KGZ_STR_KGZ_NDATA)];
|
||||
};
|
||||
|
||||
/* Relocatable header format */
|
||||
struct kgz_elfhdr {
|
||||
Elf32_Ehdr e;
|
||||
Elf32_Shdr sh[KGZ_SHNUM];
|
||||
Elf32_Sym st[KGZ_STNUM];
|
||||
struct kgz_shstrtab shstrtab;
|
||||
struct kgz_strtab strtab;
|
||||
};
|
||||
|
||||
extern const struct kgz_elfhdr elfhdr;
|
57
usr.sbin/kgzip/kgz.h
Normal file
57
usr.sbin/kgzip/kgz.h
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 1999 Global Technology Associates, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id:$
|
||||
*/
|
||||
|
||||
#ifndef _KGZ_H_
|
||||
#define _KGZ_H_
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
/*
|
||||
* KGZ definitions: kgzip(8) output.
|
||||
*/
|
||||
|
||||
/* Values for ident[]. */
|
||||
#define KGZ_ID0 'K'
|
||||
#define KGZ_ID1 'G'
|
||||
#define KGZ_ID2 'Z'
|
||||
#define KGZ_ID3 '\0'
|
||||
|
||||
/* KGZ header. */
|
||||
struct kgz_hdr {
|
||||
char ident[4]; /* identification */
|
||||
uint32_t dload; /* decoded image load address */
|
||||
uint32_t dsize; /* decoded image size */
|
||||
uint32_t isize; /* image size in memory */
|
||||
uint32_t entry; /* program entry point */
|
||||
uint32_t nsize; /* encoded image size */
|
||||
};
|
||||
|
||||
extern struct kgz_hdr kgz; /* header */
|
||||
extern uint8_t kgz_ndata[]; /* encoded image */
|
||||
|
||||
#endif /* !_KGZ_H_ */
|
215
usr.sbin/kgzip/kgzcmp.c
Normal file
215
usr.sbin/kgzip/kgzcmp.c
Normal file
@ -0,0 +1,215 @@
|
||||
/*
|
||||
* Copyright (c) 1999 Global Technology Associates, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id:$
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <a.out.h>
|
||||
#include <elf.h>
|
||||
|
||||
#include "elfhdr.h"
|
||||
#include "kgzip.h"
|
||||
|
||||
#define KGZOFF (sizeof(struct kgz_elfhdr) + sizeof(struct kgz_hdr))
|
||||
|
||||
#define F_AOUT 1 /* Input format: a.out */
|
||||
#define F_ELF 2 /* Input format: ELF32 */
|
||||
|
||||
static void mk_data(const struct iodesc *i, const struct iodesc *,
|
||||
struct kgz_hdr *);
|
||||
static int ld_elf(const struct iodesc *, const struct iodesc *,
|
||||
struct kgz_hdr *, const Elf32_Ehdr *);
|
||||
static int ld_aout(const struct iodesc *, const struct iodesc *,
|
||||
struct kgz_hdr *, const struct exec *);
|
||||
|
||||
/*
|
||||
* Compress executable and output it in relocatable object format.
|
||||
*/
|
||||
void
|
||||
kgzcmp(struct kgz_hdr *kh, const char *f1, const char *f2)
|
||||
{
|
||||
struct iodesc idi, ido;
|
||||
struct kgz_elfhdr ehdr;
|
||||
|
||||
if ((idi.fd = open(idi.fname = f1, O_RDONLY)) == -1)
|
||||
err(1, "%s", idi.fname);
|
||||
if ((ido.fd = open(ido.fname = f2, O_CREAT | O_TRUNC | O_WRONLY,
|
||||
0666)) == -1)
|
||||
err(1, "%s", ido.fname);
|
||||
kh->ident[0] = KGZ_ID0;
|
||||
kh->ident[1] = KGZ_ID1;
|
||||
kh->ident[2] = KGZ_ID2;
|
||||
kh->ident[3] = KGZ_ID3;
|
||||
xseek(&ido, KGZOFF);
|
||||
mk_data(&idi, &ido, kh);
|
||||
kh->dload &= 0xffffff;
|
||||
kh->entry &= 0xffffff;
|
||||
xseek(&ido, 0);
|
||||
ehdr = elfhdr;
|
||||
ehdr.st[KGZ_ST_KGZ_NDATA].st_size = kh->nsize;
|
||||
ehdr.sh[KGZ_SH_DATA].sh_size += kh->nsize;
|
||||
xwrite(&ido, &ehdr, sizeof(ehdr));
|
||||
xwrite(&ido, kh, sizeof(*kh));
|
||||
xclose(&ido);
|
||||
xclose(&idi);
|
||||
}
|
||||
|
||||
/*
|
||||
* Make encoded (compressed) data.
|
||||
*/
|
||||
static void
|
||||
mk_data(const struct iodesc * idi, const struct iodesc * ido,
|
||||
struct kgz_hdr * kh)
|
||||
{
|
||||
union {
|
||||
struct exec ex;
|
||||
Elf32_Ehdr ee;
|
||||
} hdr;
|
||||
struct stat sb;
|
||||
struct iodesc idp;
|
||||
int fd[2];
|
||||
pid_t pid;
|
||||
size_t n;
|
||||
int fmt, status, e;
|
||||
|
||||
n = xread(idi, &hdr, sizeof(hdr), 0);
|
||||
fmt = 0;
|
||||
if (n >= sizeof(hdr.ee) && IS_ELF(hdr.ee))
|
||||
fmt = F_ELF;
|
||||
else if (n >= sizeof(hdr.ex) && N_GETMAGIC(hdr.ex) == ZMAGIC)
|
||||
fmt = F_AOUT;
|
||||
if (!fmt)
|
||||
errx(1, "%s: Format not supported", idi->fname);
|
||||
if (pipe(fd))
|
||||
err(1, NULL);
|
||||
switch (pid = fork()) {
|
||||
case -1:
|
||||
err(1, NULL);
|
||||
case 0:
|
||||
close(fd[1]);
|
||||
dup2(fd[0], STDIN_FILENO);
|
||||
close(fd[0]);
|
||||
close(idi->fd);
|
||||
dup2(ido->fd, STDOUT_FILENO);
|
||||
close(ido->fd);
|
||||
execlp("gzip", "gzip", "-9", NULL);
|
||||
warn(NULL);
|
||||
_exit(1);
|
||||
default:
|
||||
close(fd[0]);
|
||||
idp.fname = "(pipe)";
|
||||
idp.fd = fd[1];
|
||||
e = fmt == F_ELF ? ld_elf(idi, &idp, kh, &hdr.ee) :
|
||||
fmt == F_AOUT ? ld_aout(idi, &idp, kh, &hdr.ex) : -1;
|
||||
close(fd[1]);
|
||||
if ((pid = waitpid(pid, &status, 0)) == -1)
|
||||
err(1, NULL);
|
||||
if (WIFSIGNALED(status) || WEXITSTATUS(status))
|
||||
exit(1);
|
||||
}
|
||||
if (e)
|
||||
errx(1, "%s: Invalid format", idi->fname);
|
||||
if (fstat(ido->fd, &sb))
|
||||
err(1, ido->fname);
|
||||
kh->nsize = sb.st_size - KGZOFF;
|
||||
}
|
||||
|
||||
/*
|
||||
* "Load" an ELF-format executable.
|
||||
*/
|
||||
static int
|
||||
ld_elf(const struct iodesc * idi, const struct iodesc * ido,
|
||||
struct kgz_hdr * kh, const Elf32_Ehdr * e)
|
||||
{
|
||||
Elf32_Phdr p;
|
||||
size_t load, addr, n;
|
||||
unsigned x, i;
|
||||
|
||||
load = addr = n = 0;
|
||||
for (x = i = 0; i < e->e_phnum; i++) {
|
||||
if (xread(idi, &p, sizeof(p),
|
||||
e->e_phoff + i * e->e_phentsize) != e->e_phentsize)
|
||||
return -1;
|
||||
if (p.p_type != PT_LOAD)
|
||||
continue;
|
||||
if (!x)
|
||||
load = addr = p.p_vaddr;
|
||||
else {
|
||||
if (p.p_vaddr < addr)
|
||||
return -1;
|
||||
n = p.p_vaddr - addr;
|
||||
if (n) {
|
||||
xzero(ido, n);
|
||||
addr += n;
|
||||
}
|
||||
}
|
||||
if (p.p_memsz < p.p_filesz)
|
||||
return -1;
|
||||
n = p.p_memsz - p.p_filesz;
|
||||
xcopy(idi, ido, p.p_filesz, p.p_offset);
|
||||
addr += p.p_filesz;
|
||||
x++;
|
||||
}
|
||||
if (!x)
|
||||
return -1;
|
||||
kh->dload = load;
|
||||
kh->dsize = addr - load;
|
||||
kh->isize = kh->dsize + n;
|
||||
kh->entry = e->e_entry;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* "Load" an a.out-format executable.
|
||||
*/
|
||||
static int
|
||||
ld_aout(const struct iodesc * idi, const struct iodesc * ido,
|
||||
struct kgz_hdr * kh, const struct exec * a)
|
||||
{
|
||||
size_t load, addr;
|
||||
|
||||
load = addr = N_TXTADDR(*a);
|
||||
xcopy(idi, ido, a->a_text, N_TXTOFF(*a));
|
||||
addr += a->a_text;
|
||||
if (N_DATADDR(*a) != addr)
|
||||
return -1;
|
||||
xcopy(idi, ido, a->a_data, N_DATOFF(*a));
|
||||
addr += a->a_data;
|
||||
kh->dload = load;
|
||||
kh->dsize = addr - load;
|
||||
kh->isize = kh->dsize + a->a_bss;
|
||||
kh->entry = a->a_entry;
|
||||
return 0;
|
||||
}
|
130
usr.sbin/kgzip/kgzip.8
Normal file
130
usr.sbin/kgzip/kgzip.8
Normal file
@ -0,0 +1,130 @@
|
||||
.\" Copyright (c) 1999 Global Technology Associates, Inc.
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
|
||||
.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
.\" OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
.\" OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
.\" BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
.\" WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
.\" OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
.\" EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $Id:$
|
||||
.\"
|
||||
.Dd July 19, 1999
|
||||
.Dt KGZIP 8
|
||||
.Os FreeBSD
|
||||
.Sh NAME
|
||||
.Nm kgzip
|
||||
.Nd compress a kernel
|
||||
.Sh SYNOPSIS
|
||||
.Nm kgzip
|
||||
.Op Fl cv
|
||||
.Op Fl l Ar loader
|
||||
.Op Fl o Ar output
|
||||
.Ar file
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
utility compresses a kernel or some other bootable binary. Operation
|
||||
is in two phases as follows:
|
||||
.Bl -enum
|
||||
.It
|
||||
A load image of the executable file is built which omits all but
|
||||
the
|
||||
.Sq text
|
||||
and
|
||||
.Sq data
|
||||
segments. This image is compressed using
|
||||
.Xr gzip 1
|
||||
and output as data in relocatable object format.
|
||||
.It
|
||||
The object file is linked with a special self-hosting loader, producing
|
||||
an executable suitable for booting with either the second- or
|
||||
third-level bootstraps.
|
||||
.El
|
||||
.Pp
|
||||
Supported input formats are ELF and a.out ZMAGIC; the output format
|
||||
is always ELF. Only 32-bit objects are supported.
|
||||
.Pp
|
||||
If the
|
||||
.Ar file
|
||||
operand has a
|
||||
.Sq .o
|
||||
suffix, input is assumed to be for the link phase, and the first phase
|
||||
is omitted.
|
||||
.Pp
|
||||
The options are:
|
||||
.Bl -tag -width Fl
|
||||
.It Fl c
|
||||
Omit the link phase.
|
||||
.It Fl v
|
||||
Display object file information.
|
||||
.It Fl l Ar loader
|
||||
Link
|
||||
.Ar loader
|
||||
as the loader.
|
||||
.It Fl o Ar output
|
||||
Name the output file
|
||||
.Ar output .
|
||||
The default is to use the input name with the suffix
|
||||
.Sq .o
|
||||
(for relocatables) or
|
||||
.Sq .kgz
|
||||
(for executables).
|
||||
.El
|
||||
.Sh NOTES
|
||||
Global variables equivalent to the following are defined in the output:
|
||||
.Bd -literal
|
||||
struct kgz_hdr {
|
||||
char ident[4]; /* identification: "KGZ" */
|
||||
uint32_t dload; /* decoded image load address */
|
||||
uint32_t dsize; /* decoded image size */
|
||||
uint32_t isize; /* image size in memory */
|
||||
uint32_t entry; /* entry point */
|
||||
uint32_t nsize; /* encoded image size */
|
||||
} kgz;
|
||||
|
||||
uint8_t kgz_ndata[]; /* encoded data */
|
||||
.Ed
|
||||
.Pp
|
||||
The encoded data is simply
|
||||
.Xr gzip 1
|
||||
output: a header (with no optional fields); compressed data; and 32-bit
|
||||
CRC and size values.
|
||||
.Sh FILES
|
||||
.Bl -tag -width /usr/lib/kgzldr.o -compact
|
||||
.It Pa /usr/lib/kgzldr.o
|
||||
The default loader
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr gzip 1 ,
|
||||
.Xr ld 1 ,
|
||||
.Xr a.out 5 ,
|
||||
.Xr boot 8 ,
|
||||
.Xr loader 8
|
||||
.Sh DIAGNOSTICS
|
||||
Exit status is 0 on success and >0 on error.
|
||||
.Sh AUTHORS
|
||||
.An Robert Nordier Aq rnordier@FreeBSD.org .
|
||||
.Sh BUGS
|
||||
As symbols are lost, the usefulness of this utility for compressing
|
||||
kernels is limited to situations where
|
||||
.Xr loader 8
|
||||
cannot be used; otherwise the preferred method of compressing a kernel
|
||||
is simply to
|
||||
.Xr gzip 1
|
||||
it.
|
159
usr.sbin/kgzip/kgzip.c
Normal file
159
usr.sbin/kgzip/kgzip.c
Normal file
@ -0,0 +1,159 @@
|
||||
/*
|
||||
* Copyright (c) 1999 Global Technology Associates, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid[] =
|
||||
"$Id:$";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <err.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "kgzip.h"
|
||||
|
||||
#define FN_SRC 0 /* Filename: source */
|
||||
#define FN_OBJ 1 /* Filename: relocatable */
|
||||
#define FN_KGZ 2 /* Filename: executable */
|
||||
#define FN_CNT 3 /* Number of filenames */
|
||||
|
||||
#define SFX_OBJ ".o" /* Filename suffix: relocatable */
|
||||
#define SFX_KGZ ".kgz" /* Filename suffix: executable */
|
||||
#define SFX_MAX 5 /* Size of larger filename suffix */
|
||||
|
||||
#define TMP_PREFIX "kgz" /* Temporary file prefix */
|
||||
|
||||
const char *loader = "/usr/lib/kgzldr.o"; /* Default loader */
|
||||
|
||||
static const char *tname; /* Name of temporary file */
|
||||
|
||||
static void cleanup(void);
|
||||
static void mk_fn(int, const char *, const char *, char *[]);
|
||||
static void usage(void);
|
||||
|
||||
/*
|
||||
* Compress a kernel.
|
||||
*/
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
static char *fn[FN_CNT];
|
||||
struct kgz_hdr kh;
|
||||
const char *output;
|
||||
int cflag, vflag, c;
|
||||
|
||||
output = NULL;
|
||||
cflag = vflag = 0;
|
||||
while ((c = getopt(argc, argv, "cvl:o:")) != -1)
|
||||
switch (c) {
|
||||
case 'c':
|
||||
cflag = 1;
|
||||
break;
|
||||
case 'v':
|
||||
vflag = 1;
|
||||
break;
|
||||
case 'l':
|
||||
loader = optarg;
|
||||
break;
|
||||
case 'o':
|
||||
output = optarg;
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
if (argc != 1)
|
||||
usage();
|
||||
atexit(cleanup);
|
||||
mk_fn(cflag, *argv, output, fn);
|
||||
memset(&kh, 0, sizeof(kh));
|
||||
if (fn[FN_SRC])
|
||||
kgzcmp(&kh, fn[FN_SRC], fn[FN_OBJ]);
|
||||
if (!cflag)
|
||||
kgzld(&kh, fn[FN_OBJ], fn[FN_KGZ]);
|
||||
if (vflag)
|
||||
printf("dload=%#x dsize=%#x isize=%#x entry=%#x nsize=%#x\n",
|
||||
kh.dload, kh.dsize, kh.isize, kh.entry, kh.nsize);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Clean up after processing.
|
||||
*/
|
||||
static void
|
||||
cleanup(void)
|
||||
{
|
||||
if (tname)
|
||||
unlink(tname);
|
||||
}
|
||||
|
||||
/*
|
||||
* Make the required filenames.
|
||||
*/
|
||||
static void
|
||||
mk_fn(int cflag, const char *f1, const char *f2, char *fn[])
|
||||
{
|
||||
const char *p, *s;
|
||||
size_t n;
|
||||
int i;
|
||||
|
||||
i = 0;
|
||||
s = strrchr(f1, 0);
|
||||
n = sizeof(SFX_OBJ) - 1;
|
||||
if ((size_t)(s - f1) > n && !memcmp(s - n, SFX_OBJ, n)) {
|
||||
s -= n;
|
||||
i++;
|
||||
}
|
||||
fn[i++] = (char *)f1;
|
||||
if (i == FN_OBJ && !cflag) {
|
||||
if (!(tname = tempnam(NULL, TMP_PREFIX)))
|
||||
err(1, NULL);
|
||||
fn[i++] = (char *)tname;
|
||||
}
|
||||
if (!(fn[i] = (char *)f2)) {
|
||||
p = (p = strrchr(f1, '/')) ? p + 1 : f1;
|
||||
n = (size_t)(s - p);
|
||||
if (!(fn[i] = malloc(n + SFX_MAX)))
|
||||
err(1, NULL);
|
||||
memcpy(fn[i], p, n);
|
||||
strcpy(fn[i] + n, i == FN_OBJ ? SFX_OBJ : SFX_KGZ);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Display usage information.
|
||||
*/
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"usage: kgzip [-cv] [-l file] [-o filename] file\n");
|
||||
exit(1);
|
||||
}
|
47
usr.sbin/kgzip/kgzip.h
Normal file
47
usr.sbin/kgzip/kgzip.h
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 1999 Global Technology Associates, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id:$
|
||||
*/
|
||||
|
||||
#include "kgz.h"
|
||||
|
||||
/* Used by I/O routines */
|
||||
struct iodesc {
|
||||
const char *fname; /* File name */
|
||||
int fd; /* File descriptor */
|
||||
};
|
||||
|
||||
extern const char *loader; /* Default loader */
|
||||
|
||||
void kgzcmp(struct kgz_hdr *, const char *, const char *);
|
||||
void kgzld(struct kgz_hdr *, const char *, const char *);
|
||||
|
||||
void xclose(const struct iodesc *);
|
||||
void xcopy(const struct iodesc *, const struct iodesc *, size_t, off_t);
|
||||
void xzero(const struct iodesc *, size_t);
|
||||
size_t xread(const struct iodesc *, void *, size_t, off_t);
|
||||
void xwrite(const struct iodesc *, const void *, size_t);
|
||||
void xseek(const struct iodesc *, off_t);
|
80
usr.sbin/kgzip/kgzld.c
Normal file
80
usr.sbin/kgzip/kgzld.c
Normal file
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright (c) 1999 Global Technology Associates, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id:$
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "elfhdr.h"
|
||||
#include "kgzip.h"
|
||||
|
||||
#define KGZOFF sizeof(struct kgz_elfhdr)
|
||||
|
||||
#define align(x, y) (((x) + (y) - 1) & ~((y) - 1))
|
||||
|
||||
/*
|
||||
* Link KGZ file and loader.
|
||||
*/
|
||||
void
|
||||
kgzld(struct kgz_hdr * kh, const char *f1, const char *f2)
|
||||
{
|
||||
char addr[16];
|
||||
struct iodesc idi;
|
||||
pid_t pid;
|
||||
size_t n;
|
||||
int status;
|
||||
|
||||
if (strcmp(kh->ident, "KGZ")) {
|
||||
if ((idi.fd = open(idi.fname = f1, O_RDONLY)) == -1)
|
||||
err(1, "%s", idi.fname);
|
||||
n = xread(&idi, kh, sizeof(*kh), KGZOFF);
|
||||
xclose(&idi);
|
||||
if (n != sizeof(*kh) || strcmp(kh->ident, "KGZ"))
|
||||
errx(1, "%s: Invalid format", idi.fname);
|
||||
}
|
||||
sprintf(addr, "%#x", align(kh->dload + kh->dsize, 0x1000));
|
||||
switch (pid = fork()) {
|
||||
case -1:
|
||||
err(1, NULL);
|
||||
case 0:
|
||||
execlp("ld", "ld", "-Ttext", addr, "-o", f2, loader, f1, NULL);
|
||||
warn(NULL);
|
||||
_exit(1);
|
||||
default:
|
||||
if ((pid = waitpid(pid, &status, 0)) == -1)
|
||||
err(1, NULL);
|
||||
if (WIFSIGNALED(status) || WEXITSTATUS(status))
|
||||
exit(1);
|
||||
}
|
||||
}
|
122
usr.sbin/kgzip/xio.c
Normal file
122
usr.sbin/kgzip/xio.c
Normal file
@ -0,0 +1,122 @@
|
||||
/*
|
||||
* Copyright (c) 1999 Global Technology Associates, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id:$
|
||||
*/
|
||||
|
||||
#include <err.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "kgzip.h"
|
||||
|
||||
/*
|
||||
* Close a file.
|
||||
*/
|
||||
void
|
||||
xclose(const struct iodesc *id)
|
||||
{
|
||||
if (close(id->fd))
|
||||
err(1, "%s", id->fname);
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy bytes from one file to another.
|
||||
*/
|
||||
void
|
||||
xcopy(const struct iodesc * idi, const struct iodesc * ido,
|
||||
size_t nbyte, off_t offset)
|
||||
{
|
||||
char buf[8192];
|
||||
size_t n;
|
||||
|
||||
while (nbyte) {
|
||||
if ((n = sizeof(buf)) > nbyte)
|
||||
n = nbyte;
|
||||
if (xread(idi, buf, n, offset) != n)
|
||||
errx(1, "%s: Short read", idi->fname);
|
||||
xwrite(ido, buf, n);
|
||||
nbyte -= n;
|
||||
offset = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Write binary zeroes to a file.
|
||||
*/
|
||||
void
|
||||
xzero(const struct iodesc * id, size_t nbyte)
|
||||
{
|
||||
char buf[8192];
|
||||
size_t n;
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
while (nbyte) {
|
||||
if ((n = sizeof(buf)) > nbyte)
|
||||
n = nbyte;
|
||||
xwrite(id, buf, n);
|
||||
nbyte -= n;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Read from a file.
|
||||
*/
|
||||
size_t
|
||||
xread(const struct iodesc * id, void *buf, size_t nbyte, off_t offset)
|
||||
{
|
||||
ssize_t n;
|
||||
|
||||
if (offset != -1 && lseek(id->fd, offset, SEEK_SET) != offset)
|
||||
err(1, "%s", id->fname);
|
||||
if ((n = read(id->fd, buf, nbyte)) == -1)
|
||||
err(1, "%s", id->fname);
|
||||
return (size_t)n;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write to a file.
|
||||
*/
|
||||
void
|
||||
xwrite(const struct iodesc * id, const void *buf, size_t nbyte)
|
||||
{
|
||||
ssize_t n;
|
||||
|
||||
if ((n = write(id->fd, buf, nbyte)) == -1)
|
||||
err(1, "%s", id->fname);
|
||||
if ((size_t)n != nbyte)
|
||||
errx(1, "%s: Short write", id->fname);
|
||||
}
|
||||
|
||||
/*
|
||||
* Reposition within a file.
|
||||
*/
|
||||
void
|
||||
xseek(const struct iodesc *id, off_t offset)
|
||||
{
|
||||
if (lseek(id->fd, offset, SEEK_SET) != offset)
|
||||
err(1, "%s", id->fname);
|
||||
}
|
Loading…
Reference in New Issue
Block a user