summaryrefslogtreecommitdiffstats
path: root/usr.bin/kzip
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>1995-04-15 08:18:20 +0000
committerphk <phk@FreeBSD.org>1995-04-15 08:18:20 +0000
commit1978ca6d733a0124144c9ae0967af2aa29d8ae07 (patch)
tree4e8eda1b9f04cdf302e5e16da17c4329d1c84515 /usr.bin/kzip
parenta3faef6dde5a705f619e2c8db686823c7eb3fced (diff)
downloadFreeBSD-src-1978ca6d733a0124144c9ae0967af2aa29d8ae07.zip
FreeBSD-src-1978ca6d733a0124144c9ae0967af2aa29d8ae07.tar.gz
This program to compress a kernel with. You loose all the symbols, so
usability is limited. Very useful on fixit floppies &c. Obtained from: Linux via 386BSD
Diffstat (limited to 'usr.bin/kzip')
-rw-r--r--usr.bin/kzip/Makefile9
-rw-r--r--usr.bin/kzip/kzip.c254
2 files changed, 263 insertions, 0 deletions
diff --git a/usr.bin/kzip/Makefile b/usr.bin/kzip/Makefile
new file mode 100644
index 0000000..cc9186c
--- /dev/null
+++ b/usr.bin/kzip/Makefile
@@ -0,0 +1,9 @@
+# $Id$
+
+PROG= kzip
+NOMAN= toobad
+
+# Where we load the compressed stuff to uncompress it
+CFLAGS+= -DKZBASE=\"0x300000\"
+
+.include <bsd.prog.mk>
diff --git a/usr.bin/kzip/kzip.c b/usr.bin/kzip/kzip.c
new file mode 100644
index 0000000..34a8b3e
--- /dev/null
+++ b/usr.bin/kzip/kzip.c
@@ -0,0 +1,254 @@
+/*
+ * ----------------------------------------------------------------------------
+ * "THE BEER-WARE LICENSE" (Revision 42):
+ * <phk@login.dknet.dk> wrote this file. As long as you retain this notice you
+ * can do whatever you want with this stuff. If we meet some day, and you think
+ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
+ * ----------------------------------------------------------------------------
+ *
+ * Copyright (C) 1993 Hannu Savolainen
+ * Ported to 386bsd by Serge Vakulenko
+ * based on tools/build.c by Linus Torvalds
+ * $Id$
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/file.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <a.out.h>
+#include <string.h>
+
+int
+main(int argc, char **argv)
+{
+ pid_t Pext, Pgzip, Ppiggy, Pld;
+ int pipe1[2], pipe2[2];
+ int status,fdi,fdo;
+ char obj[BUFSIZ];
+ char out[BUFSIZ];
+
+ if(argc != 2) {
+ fprintf(stderr,"usage:\n\t%s kernel\n",argv[0]);
+ return 2;
+ }
+
+ strcpy(obj,argv[1]); strcat(obj,".o");
+ strcpy(out,argv[1]); strcat(out,".kz");
+
+ fdi = open(argv[1],O_RDONLY);
+ if(fdi<0) {
+ perror(argv[1]);
+ return 2;
+ }
+ fdo = open(obj,O_WRONLY|O_TRUNC|O_CREAT,0666);
+ if(fdo<0) {
+ perror(obj);
+ return 2;
+ }
+
+ if (pipe(pipe1) < 0) { perror("pipe()"); return 1; }
+
+ if (pipe(pipe2) < 0) { perror("pipe()"); return 1; }
+
+ Pext = fork();
+ if (Pext < 0) { perror("fork()"); return 1; }
+ if (!Pext) {
+ dup2(fdi,0);
+ dup2(pipe1[1],1);
+ close(pipe1[0]); close(pipe1[1]);
+ close(pipe2[0]); close(pipe2[1]);
+ close(fdi); close(fdo);
+ extract(argv[1]);
+ exit(0);
+ }
+
+ Pgzip = fork();
+ if (Pgzip < 0) { perror("fork()"); return 1; }
+ if (!Pgzip) {
+ dup2(pipe1[0],0);
+ dup2(pipe2[1],1);
+ close(pipe1[0]); close(pipe1[1]);
+ close(pipe2[0]); close(pipe2[1]);
+ close(fdi); close(fdo);
+ execlp("gzip", "gzip", "-9", "-n", 0);
+ exit (0);
+ }
+
+ Ppiggy = fork();
+ if (Ppiggy < 0) { perror("fork()"); return 1; }
+ if (!Ppiggy) {
+ dup2(pipe2[0],0);
+ dup2(fdo,1);
+ close(pipe1[0]); close(pipe1[1]);
+ close(pipe2[0]); close(pipe2[1]);
+ close(fdi); close(fdo);
+ piggyback(obj);
+ exit(0);
+ }
+
+ close(pipe1[0]); close(pipe1[1]);
+ close(pipe2[0]); close(pipe2[1]);
+ close(fdi); close(fdo);
+
+ if (waitpid(Pext, &status,0) < 0)
+ { perror("waitpid(Pextract)"); return 1; }
+
+ if(status) {
+ fprintf(stderr,"extract returned %x\n",status);
+ return 3;
+ }
+
+ if (waitpid(Pgzip, &status,0) < 0)
+ { perror("waitpid(Pgzip)"); return 1; }
+
+ if(status) {
+ fprintf(stderr,"gzip returned %x\n",status);
+ return 3;
+ }
+
+ if (waitpid(Ppiggy, &status,0) < 0)
+ { perror("waitpid(Ppiggy)"); return 1; }
+
+ if(status) {
+ fprintf(stderr,"piggyback returned %x\n",status);
+ return 3;
+ }
+
+ Pld = fork();
+ if (Pld < 0) { perror("fork()"); return 1; }
+ if (!Pld) {
+ execlp("ld",
+ "ld",
+ "-Bstatic",
+ "-Z",
+ "-T",
+ KZBASE,
+ "-o",
+ out,
+ "/usr/lib/kzip.o",
+ obj,
+ 0);
+ exit(2);
+ }
+
+ if (waitpid(Pld, &status,0) < 0)
+ { perror("waitpid(Pld)"); return 1; }
+
+ if(status) {
+ fprintf(stderr,"ld returned %x\n",status);
+ return 3;
+ }
+
+ unlink(obj);
+ exit(0);
+}
+
+int
+extract (char *file)
+{
+ int sz;
+ char buf[BUFSIZ];
+ struct exec hdr;
+
+ if (read (0, (char *)&hdr, sizeof(hdr)) != sizeof(hdr)) {
+ perror(file);
+ exit(2);
+ }
+ if (hdr.a_magic != ZMAGIC) {
+ fprintf(stderr,"Bad magic in file %s, probably not a kernel\n",
+ file);
+ exit(2);
+ }
+ if (lseek (0, N_TXTOFF(hdr), 0) < 0) {
+ perror(file);
+ exit(2);
+ }
+
+ sz = N_SYMOFF (hdr) - N_TXTOFF (hdr);
+
+ while (sz) {
+ int l, n;
+
+ l = sz;
+ if (l > sizeof(buf))
+ l = sizeof(buf);
+
+ n = read (0, buf, l);
+ if (n != l) {
+ if (n == -1)
+ perror (file);
+ else
+ fprintf (stderr, "Unexpected EOF\n");
+
+ exit(1);
+ }
+
+ write (1, buf, l);
+ sz -= l;
+ }
+ exit(0);
+}
+
+
+char string_names[] = {"_input_data\0_input_len\0"};
+
+struct nlist var_names[2] = { /* Symbol table */
+ { { (char*) 4 }, N_EXT|N_TEXT, 0, 0, 0 }, /* _input_data */
+ { { (char*) 16 }, N_EXT|N_TEXT, 0, 0, 0 }, /* _input_len */
+};
+
+int
+piggyback(char *file)
+{
+ int n, len;
+ struct exec hdr; /* object header */
+ char image[1024*1024]; /* kernel image buffer */
+
+ len = 0;
+ while ((n = read (0, &image[len], sizeof(image)-len+1)) > 0)
+ len += n;
+
+ if (n < 0) {
+ perror ("stdin");
+ exit (1);
+ }
+
+ if (len >= sizeof(image)) {
+ fprintf (stderr,"Input too large\n");
+ exit (1);
+ }
+
+ /*
+ * Output object header
+ */
+ memset(&hdr,0,sizeof hdr);
+ hdr.a_magic = OMAGIC;
+ hdr.a_text = len + sizeof(long);
+ hdr.a_syms = sizeof(var_names);
+ write (1, (char *)&hdr, sizeof(hdr));
+
+ /*
+ * Output text segment (compressed system & len)
+ */
+ write (1, image, len);
+ write (1, (char *)&len, sizeof(len));
+
+ /*
+ * Output symbol table
+ */
+ var_names[1].n_value = len;
+ write (1, (char *)&var_names, sizeof(var_names));
+
+ /*
+ * Output string table
+ */
+ len = sizeof(string_names) + sizeof(len);
+ write (1, (char *)&len, sizeof(len));
+ write (1, string_names, sizeof(string_names));
+
+ return (0);
+}
OpenPOWER on IntegriCloud