kgzip.c revision 330449
1/*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright (c) 1999 Global Technology Associates, Inc. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 21 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 22 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 26 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29#ifndef lint 30static const char rcsid[] = 31 "$FreeBSD: stable/11/usr.sbin/kgzip/kgzip.c 330449 2018-03-05 07:26:05Z eadler $"; 32#endif /* not lint */ 33 34#include <sys/types.h> 35#include <err.h> 36#include <paths.h> 37#include <stdio.h> 38#include <stdlib.h> 39#include <string.h> 40#include <unistd.h> 41 42#include "kgzip.h" 43 44#define FN_SRC 0 /* Filename: source */ 45#define FN_OBJ 1 /* Filename: relocatable */ 46#define FN_KGZ 2 /* Filename: executable */ 47#define FN_CNT 3 /* Number of filenames */ 48 49#define SFX_OBJ ".o" /* Filename suffix: relocatable */ 50#define SFX_KGZ ".kgz" /* Filename suffix: executable */ 51#define SFX_MAX 5 /* Size of larger filename suffix */ 52 53const char *loader = "/usr/lib/kgzldr.o"; /* Default loader */ 54int format; /* Output format */ 55 56char *tname; /* Name of temporary file */ 57 58static void cleanup(void); 59static void mk_fn(int, const char *, const char *, char *[]); 60static void usage(void); 61 62/* 63 * Compress a kernel. 64 */ 65int 66main(int argc, char *argv[]) 67{ 68 static char *fn[FN_CNT]; 69 struct kgz_hdr kh; 70 const char *output; 71 char *tmpdir; 72 int cflag, vflag, c; 73 74 tmpdir = getenv("TMPDIR"); 75 if (asprintf(&tname, "%s/kgzXXXXXXXXXX", 76 tmpdir == NULL ? _PATH_TMP : tmpdir) == -1) 77 errx(1, "Out of memory"); 78 output = NULL; 79 cflag = vflag = 0; 80 while ((c = getopt(argc, argv, "cvf:l:o:")) != -1) 81 switch (c) { 82 case 'c': 83 cflag = 1; 84 break; 85 case 'v': 86 vflag = 1; 87 break; 88 case 'f': 89 if (!strcmp(optarg, "aout")) 90 format = F_AOUT; 91 else if (!strcmp(optarg, "elf")) 92 format = F_ELF; 93 else 94 errx(1, "%s: Unknown format", optarg); 95 break; 96 case 'l': 97 loader = optarg; 98 break; 99 case 'o': 100 output = optarg; 101 break; 102 default: 103 usage(); 104 } 105 argc -= optind; 106 argv += optind; 107 if (argc != 1) 108 usage(); 109 atexit(cleanup); 110 mk_fn(cflag, *argv, output, fn); 111 memset(&kh, 0, sizeof(kh)); 112 if (fn[FN_SRC]) { 113 if (!format) 114 format = F_ELF; 115 kgzcmp(&kh, fn[FN_SRC], fn[FN_OBJ]); 116 } 117 if (!cflag) 118 kgzld(&kh, fn[FN_OBJ], fn[FN_KGZ]); 119 if (vflag) 120 printf("dload=%#x dsize=%#x isize=%#x entry=%#x nsize=%#x\n", 121 kh.dload, kh.dsize, kh.isize, kh.entry, kh.nsize); 122 return 0; 123} 124 125/* 126 * Clean up after processing. 127 */ 128static void 129cleanup(void) 130{ 131 if (tname) 132 unlink(tname); 133} 134 135/* 136 * Make the required filenames. 137 */ 138static void 139mk_fn(int cflag, const char *f1, const char *f2, char *fn[]) 140{ 141 const char *p, *s; 142 size_t n; 143 int i, fd; 144 145 i = 0; 146 s = strrchr(f1, 0); 147 n = sizeof(SFX_OBJ) - 1; 148 if ((size_t)(s - f1) > n && !memcmp(s - n, SFX_OBJ, n)) { 149 s -= n; 150 i++; 151 } 152 fn[i++] = (char *)f1; 153 if (i == FN_OBJ && !cflag) { 154 if ((fd = mkstemp(tname)) == -1) 155 err(1, NULL); 156 close(fd); 157 fn[i++] = tname; 158 } 159 if (!(fn[i] = (char *)f2)) { 160 p = (p = strrchr(f1, '/')) ? p + 1 : f1; 161 n = (size_t)(s - p); 162 if (!(fn[i] = malloc(n + SFX_MAX))) 163 err(1, NULL); 164 memcpy(fn[i], p, n); 165 strcpy(fn[i] + n, i == FN_OBJ ? SFX_OBJ : SFX_KGZ); 166 } 167} 168 169/* 170 * Display usage information. 171 */ 172static void 173usage(void) 174{ 175 fprintf(stderr, 176 "usage: kgzip [-cv] [-f format] [-l loader] [-o output] file\n"); 177 exit(1); 178} 179