kgzip.c revision 64214
1115013Smarcel/* 2121642Smarcel * Copyright (c) 1999 Global Technology Associates, Inc. 3121642Smarcel * All rights reserved. 4121642Smarcel * 5121642Smarcel * Redistribution and use in source and binary forms, with or without 6121642Smarcel * modification, are permitted provided that the following conditions 7121642Smarcel * are met: 8121642Smarcel * 1. Redistributions of source code must retain the above copyright 9121642Smarcel * notice, this list of conditions and the following disclaimer. 10121642Smarcel * 2. Redistributions in binary form must reproduce the above copyright 11115013Smarcel * notice, this list of conditions and the following disclaimer in the 12121642Smarcel * documentation and/or other materials provided with the distribution. 13121642Smarcel * 14121642Smarcel * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS``AS IS'' AND 15121642Smarcel * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16121642Smarcel * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 17121642Smarcel * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS 18121642Smarcel * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 19121642Smarcel * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 20121642Smarcel * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 21121642Smarcel * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 22121642Smarcel * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 23121642Smarcel * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 24121642Smarcel * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25115013Smarcel */ 26115013Smarcel 27115013Smarcel#ifndef lint 28115013Smarcelstatic const char rcsid[] = 29115013Smarcel "$FreeBSD: head/usr.sbin/kgzip/kgzip.c 64214 2000-08-03 23:44:43Z kris $"; 30115013Smarcel#endif /* not lint */ 31115013Smarcel 32115013Smarcel#include <sys/types.h> 33115013Smarcel#include <err.h> 34115013Smarcel#include <paths.h> 35115013Smarcel#include <stdio.h> 36115013Smarcel#include <stdlib.h> 37115013Smarcel#include <string.h> 38115013Smarcel#include <unistd.h> 39115013Smarcel 40115013Smarcel#include "kgzip.h" 41115013Smarcel 42115013Smarcel#define FN_SRC 0 /* Filename: source */ 43115013Smarcel#define FN_OBJ 1 /* Filename: relocatable */ 44120925Smarcel#define FN_KGZ 2 /* Filename: executable */ 45115013Smarcel#define FN_CNT 3 /* Number of filenames */ 46115013Smarcel 47115013Smarcel#define SFX_OBJ ".o" /* Filename suffix: relocatable */ 48115013Smarcel#define SFX_KGZ ".kgz" /* Filename suffix: executable */ 49115013Smarcel#define SFX_MAX 5 /* Size of larger filename suffix */ 50115013Smarcel 51115013Smarcelconst char *loader = "/usr/lib/kgzldr.o"; /* Default loader */ 52115013Smarcel 53115013Smarcelchar *tname; /* Name of temporary file */ 54115013Smarcel 55115013Smarcelstatic void cleanup(void); 56115013Smarcelstatic void mk_fn(int, const char *, const char *, char *[]); 57115013Smarcelstatic void usage(void); 58115013Smarcel 59115013Smarcel/* 60115013Smarcel * Compress a kernel. 61115013Smarcel */ 62115013Smarcelint 63115013Smarcelmain(int argc, char *argv[]) 64115013Smarcel{ 65115013Smarcel static char *fn[FN_CNT]; 66120925Smarcel struct kgz_hdr kh; 67120925Smarcel const char *output; 68115013Smarcel char *tmpdir; 69115013Smarcel int cflag, vflag, c; 70115013Smarcel 71115013Smarcel tmpdir = getenv("TMPDIR"); 72115013Smarcel if (asprintf(&tname, "%s/kgzXXXXXXXXXX", tmpdir == NULL ? _PATH_TMP : tmpdir) == -1) 73115013Smarcel errx(1, "Out of memory"); 74115013Smarcel 75115013Smarcel output = NULL; 76115013Smarcel cflag = vflag = 0; 77115013Smarcel while ((c = getopt(argc, argv, "cvl:o:")) != -1) 78115013Smarcel switch (c) { 79115013Smarcel case 'c': 80115013Smarcel cflag = 1; 81129059Smarcel break; 82115013Smarcel case 'v': 83115013Smarcel vflag = 1; 84115013Smarcel break; 85115013Smarcel case 'l': 86115013Smarcel loader = optarg; 87115013Smarcel break; 88115013Smarcel case 'o': 89115013Smarcel output = optarg; 90115013Smarcel break; 91115013Smarcel default: 92115013Smarcel usage(); 93115013Smarcel } 94115013Smarcel argc -= optind; 95115013Smarcel argv += optind; 96115013Smarcel if (argc != 1) 97115013Smarcel usage(); 98115013Smarcel atexit(cleanup); 99115013Smarcel mk_fn(cflag, *argv, output, fn); 100115013Smarcel memset(&kh, 0, sizeof(kh)); 101115013Smarcel if (fn[FN_SRC]) 102115013Smarcel kgzcmp(&kh, fn[FN_SRC], fn[FN_OBJ]); 103115013Smarcel if (!cflag) 104115013Smarcel kgzld(&kh, fn[FN_OBJ], fn[FN_KGZ]); 105 if (vflag) 106 printf("dload=%#x dsize=%#x isize=%#x entry=%#x nsize=%#x\n", 107 kh.dload, kh.dsize, kh.isize, kh.entry, kh.nsize); 108 return 0; 109} 110 111/* 112 * Clean up after processing. 113 */ 114static void 115cleanup(void) 116{ 117 if (tname) 118 unlink(tname); 119} 120 121/* 122 * Make the required filenames. 123 */ 124static void 125mk_fn(int cflag, const char *f1, const char *f2, char *fn[]) 126{ 127 const char *p, *s; 128 size_t n; 129 int i, fd; 130 131 i = 0; 132 s = strrchr(f1, 0); 133 n = sizeof(SFX_OBJ) - 1; 134 if ((size_t)(s - f1) > n && !memcmp(s - n, SFX_OBJ, n)) { 135 s -= n; 136 i++; 137 } 138 fn[i++] = (char *)f1; 139 if (i == FN_OBJ && !cflag) { 140 if ((fd = mkstemp(tname)) == -1) 141 err(1, NULL); 142 close(fd); 143 fn[i++] = (char *)tname; 144 } 145 if (!(fn[i] = (char *)f2)) { 146 p = (p = strrchr(f1, '/')) ? p + 1 : f1; 147 n = (size_t)(s - p); 148 if (!(fn[i] = malloc(n + SFX_MAX))) 149 err(1, NULL); 150 memcpy(fn[i], p, n); 151 strcpy(fn[i] + n, i == FN_OBJ ? SFX_OBJ : SFX_KGZ); 152 } 153} 154 155/* 156 * Display usage information. 157 */ 158static void 159usage(void) 160{ 161 fprintf(stderr, 162 "usage: kgzip [-cv] [-l file] [-o filename] file\n"); 163 exit(1); 164} 165