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