kgzip.c revision 112048
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 */ 2648905Srnordier 2748905Srnordier#ifndef lint 2848905Srnordierstatic const char rcsid[] = 2950479Speter "$FreeBSD: head/usr.sbin/kgzip/kgzip.c 112048 2003-03-09 21:41:30Z ru $"; 3048905Srnordier#endif /* not lint */ 3148905Srnordier 3248905Srnordier#include <sys/types.h> 3348905Srnordier#include <err.h> 3464214Skris#include <paths.h> 3548905Srnordier#include <stdio.h> 3648905Srnordier#include <stdlib.h> 3748905Srnordier#include <string.h> 3848905Srnordier#include <unistd.h> 3948905Srnordier 4048905Srnordier#include "kgzip.h" 4148905Srnordier 4248905Srnordier#define FN_SRC 0 /* Filename: source */ 4348905Srnordier#define FN_OBJ 1 /* Filename: relocatable */ 4448905Srnordier#define FN_KGZ 2 /* Filename: executable */ 4548905Srnordier#define FN_CNT 3 /* Number of filenames */ 4648905Srnordier 4748905Srnordier#define SFX_OBJ ".o" /* Filename suffix: relocatable */ 4848905Srnordier#define SFX_KGZ ".kgz" /* Filename suffix: executable */ 4948905Srnordier#define SFX_MAX 5 /* Size of larger filename suffix */ 5048905Srnordier 5148905Srnordierconst char *loader = "/usr/lib/kgzldr.o"; /* Default loader */ 5268313Srnordierint format; /* Output format */ 5348905Srnordier 5456128Skrischar *tname; /* Name of temporary file */ 5548905Srnordier 5648905Srnordierstatic void cleanup(void); 5748905Srnordierstatic void mk_fn(int, const char *, const char *, char *[]); 5848905Srnordierstatic void usage(void); 5948905Srnordier 6048905Srnordier/* 6148905Srnordier * Compress a kernel. 6248905Srnordier */ 6348905Srnordierint 6448905Srnordiermain(int argc, char *argv[]) 6548905Srnordier{ 6648905Srnordier static char *fn[FN_CNT]; 6748905Srnordier struct kgz_hdr kh; 6848905Srnordier const char *output; 6964214Skris char *tmpdir; 7048905Srnordier int cflag, vflag, c; 7148905Srnordier 7264214Skris tmpdir = getenv("TMPDIR"); 7368966Srnordier if (asprintf(&tname, "%s/kgzXXXXXXXXXX", 7468966Srnordier tmpdir == NULL ? _PATH_TMP : tmpdir) == -1) 7568313Srnordier errx(1, "Out of memory"); 7648905Srnordier output = NULL; 7748905Srnordier cflag = vflag = 0; 7868313Srnordier while ((c = getopt(argc, argv, "cvf:l:o:")) != -1) 7948905Srnordier switch (c) { 8048905Srnordier case 'c': 8148905Srnordier cflag = 1; 8248905Srnordier break; 8348905Srnordier case 'v': 8448905Srnordier vflag = 1; 8548905Srnordier break; 8668313Srnordier case 'f': 8768313Srnordier if (!strcmp(optarg, "aout")) 8868313Srnordier format = F_AOUT; 8968313Srnordier else if (!strcmp(optarg, "elf")) 9068313Srnordier format = F_ELF; 9168313Srnordier else 9268313Srnordier errx(1, "%s: Unknown format", optarg); 9368313Srnordier break; 9448905Srnordier case 'l': 9548905Srnordier loader = optarg; 9648905Srnordier break; 9748905Srnordier case 'o': 9848905Srnordier output = optarg; 9948905Srnordier break; 10048905Srnordier default: 10148905Srnordier usage(); 10248905Srnordier } 10348905Srnordier argc -= optind; 10448905Srnordier argv += optind; 10548905Srnordier if (argc != 1) 10648905Srnordier usage(); 10748905Srnordier atexit(cleanup); 10848905Srnordier mk_fn(cflag, *argv, output, fn); 10948905Srnordier memset(&kh, 0, sizeof(kh)); 11068313Srnordier if (fn[FN_SRC]) { 11168313Srnordier if (!format) 11268313Srnordier format = F_ELF; 11348905Srnordier kgzcmp(&kh, fn[FN_SRC], fn[FN_OBJ]); 11468313Srnordier } 11548905Srnordier if (!cflag) 11648905Srnordier kgzld(&kh, fn[FN_OBJ], fn[FN_KGZ]); 11748905Srnordier if (vflag) 11848905Srnordier printf("dload=%#x dsize=%#x isize=%#x entry=%#x nsize=%#x\n", 11948905Srnordier kh.dload, kh.dsize, kh.isize, kh.entry, kh.nsize); 12048905Srnordier return 0; 12148905Srnordier} 12248905Srnordier 12348905Srnordier/* 12448905Srnordier * Clean up after processing. 12548905Srnordier */ 12648905Srnordierstatic void 12748905Srnordiercleanup(void) 12848905Srnordier{ 12948905Srnordier if (tname) 13048905Srnordier unlink(tname); 13148905Srnordier} 13248905Srnordier 13348905Srnordier/* 13448905Srnordier * Make the required filenames. 13548905Srnordier */ 13648905Srnordierstatic void 13748905Srnordiermk_fn(int cflag, const char *f1, const char *f2, char *fn[]) 13848905Srnordier{ 13948905Srnordier const char *p, *s; 14048905Srnordier size_t n; 14156128Skris int i, fd; 14248905Srnordier 14348905Srnordier i = 0; 14448905Srnordier s = strrchr(f1, 0); 14548905Srnordier n = sizeof(SFX_OBJ) - 1; 14648905Srnordier if ((size_t)(s - f1) > n && !memcmp(s - n, SFX_OBJ, n)) { 14748905Srnordier s -= n; 14848905Srnordier i++; 14948905Srnordier } 15048905Srnordier fn[i++] = (char *)f1; 15148905Srnordier if (i == FN_OBJ && !cflag) { 15256128Skris if ((fd = mkstemp(tname)) == -1) 15348905Srnordier err(1, NULL); 15456128Skris close(fd); 15548905Srnordier fn[i++] = (char *)tname; 15648905Srnordier } 15748905Srnordier if (!(fn[i] = (char *)f2)) { 15848905Srnordier p = (p = strrchr(f1, '/')) ? p + 1 : f1; 15948905Srnordier n = (size_t)(s - p); 16048905Srnordier if (!(fn[i] = malloc(n + SFX_MAX))) 16148905Srnordier err(1, NULL); 16248905Srnordier memcpy(fn[i], p, n); 16348905Srnordier strcpy(fn[i] + n, i == FN_OBJ ? SFX_OBJ : SFX_KGZ); 16448905Srnordier } 16548905Srnordier} 16648905Srnordier 16748905Srnordier/* 16848905Srnordier * Display usage information. 16948905Srnordier */ 17048905Srnordierstatic void 17148905Srnordierusage(void) 17248905Srnordier{ 17348905Srnordier fprintf(stderr, 174112048Sru "usage: kgzip [-cv] [-f format] [-l loader] [-o output] file\n"); 17548905Srnordier exit(1); 17648905Srnordier} 177