brandelf.c revision 35364
118962Ssos/*-
218962Ssos * Copyright (c) 1996 S�ren Schmidt
318962Ssos * All rights reserved.
418962Ssos *
518962Ssos * Redistribution and use in source and binary forms, with or without
618962Ssos * modification, are permitted provided that the following conditions
718962Ssos * are met:
818962Ssos * 1. Redistributions of source code must retain the above copyright
918962Ssos *    notice, this list of conditions and the following disclaimer
1018962Ssos *    in this position and unchanged.
1118962Ssos * 2. Redistributions in binary form must reproduce the above copyright
1218962Ssos *    notice, this list of conditions and the following disclaimer in the
1318962Ssos *    documentation and/or other materials provided with the distribution.
1418962Ssos * 3. The name of the author may not be used to endorse or promote products
1518962Ssos *    derived from this software withough specific prior written permission
1618962Ssos *
1718962Ssos * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1818962Ssos * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1918962Ssos * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2018962Ssos * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2118962Ssos * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2218962Ssos * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2318962Ssos * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2418962Ssos * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2518962Ssos * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2618962Ssos * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2718962Ssos *
2835364Seivind *  $Id: brandelf.c,v 1.8 1997/08/23 15:51:14 joerg Exp $
2918962Ssos */
3018962Ssos
3125984Sjdp#include <elf.h>
3225984Sjdp#include <fcntl.h>
3325984Sjdp#include <stdio.h>
3418962Ssos#include <stdlib.h>
3522499Sjoerg#include <string.h>
3622499Sjoerg#include <unistd.h>
3726837Scharnier#include <err.h>
3818962Ssos
3935364Seivindstatic int iselftype(const char *);
4026837Scharnierstatic void usage __P((void));
4118962Ssos
4222499Sjoergint
4318962Ssosmain(int argc, char **argv)
4418962Ssos{
4518962Ssos
4622499Sjoerg	const char *type = "FreeBSD";
4722499Sjoerg	int retval = 0;
4835364Seivind	int ch, change = 0, verbose = 0, force = 0;
4918962Ssos
5035364Seivind	while ((ch = getopt(argc, argv, "ft:v")) != -1)
5118962Ssos		switch (ch) {
5235364Seivind		case 'f':
5335364Seivind			force = 1;
5435364Seivind			break;
5518962Ssos		case 'v':
5618962Ssos			verbose = 1;
5718962Ssos			break;
5818962Ssos		case 't':
5918962Ssos			change = 1;
6022499Sjoerg			type = optarg;
6118962Ssos			break;
6218962Ssos		default:
6318962Ssos			usage();
6418962Ssos	}
6518962Ssos	argc -= optind;
6618962Ssos	argv += optind;
6726837Scharnier	if (!argc)
6826837Scharnier		errx(1, "no file(s) specified");
6935364Seivind
7035364Seivind	if (!force && !iselftype(type))
7135364Seivind		errx(1, "invalid ELF type '%s'", type);
7235364Seivind
7318962Ssos	while (argc) {
7418962Ssos		int fd;
7525984Sjdp		char buffer[EI_NIDENT];
7625984Sjdp		char string[(EI_NIDENT-EI_BRAND)+1];
7718962Ssos
7828620Sjoerg		if ((fd = open(argv[0], change? O_RDWR: O_RDONLY, 0)) < 0) {
7928620Sjoerg			warn("error opening file %s", argv[0]);
8022499Sjoerg			retval = 1;
8118962Ssos			goto fail;
8218962Ssos		}
8325984Sjdp		if (read(fd, buffer, EI_NIDENT) < EI_NIDENT) {
8426837Scharnier			warnx("file '%s' too short", argv[0]);
8522499Sjoerg			retval = 1;
8618962Ssos			goto fail;
8718962Ssos		}
8818962Ssos		if (buffer[0] != ELFMAG0 || buffer[1] != ELFMAG1 ||
8918962Ssos		    buffer[2] != ELFMAG2 || buffer[3] != ELFMAG3) {
9026837Scharnier			warnx("file '%s' is not ELF format", argv[0]);
9122499Sjoerg			retval = 1;
9218962Ssos			goto fail;
9335364Seivind		}
9418962Ssos		if (!change) {
9518962Ssos			bzero(string, sizeof(string));
9625984Sjdp			strncpy(string, &buffer[EI_BRAND], EI_NIDENT-EI_BRAND);
9718962Ssos			if (strlen(string)) {
9835364Seivind				fprintf(stdout,
9935364Seivind					"File '%s' is of brand '%s'.\n",
10018962Ssos					argv[0], string);
10135364Seivind				if (!force && !iselftype(string))
10235364Seivind					warnx("Brand '%s' is unknown",
10335364Seivind					      string);
10418962Ssos			}
10518962Ssos			else
10618962Ssos				fprintf(stdout, "File '%s' has no branding.\n",
10718962Ssos					argv[0]);
10818962Ssos		}
10918962Ssos		else {
11025984Sjdp			strncpy(&buffer[EI_BRAND], type, EI_NIDENT-EI_BRAND);
11118962Ssos			lseek(fd, 0, SEEK_SET);
11225984Sjdp			if (write(fd, buffer, EI_NIDENT) != EI_NIDENT) {
11326837Scharnier				warnx("error writing %s", argv[0]);
11426837Scharnier				retval = 1;
11518962Ssos				goto fail;
11618962Ssos			}
11718962Ssos		}
11818962Ssosfail:
11918962Ssos		argc--;
12018962Ssos		argv++;
12118962Ssos	}
12222499Sjoerg
12322499Sjoerg	return retval;
12418962Ssos}
12518962Ssos
12626837Scharnierstatic void
12726837Scharnierusage()
12818962Ssos{
12935364Seivind	fprintf(stderr, "usage: brandelf [-f] [-v] [-t string] file ...\n");
13022499Sjoerg	exit(1);
13118962Ssos}
13235364Seivind
13335364Seivindint
13435364Seivindiselftype(const char *elftype) {
13535364Seivind	/* XXX - any more types? */
13635364Seivind	const char *elftypes[] = { "FreeBSD", "Linux" };
13735364Seivind	int elfwalk;
13835364Seivind
13935364Seivind	for (elfwalk = 0;
14035364Seivind	     elfwalk < sizeof(elftypes)/sizeof(elftypes[0]);
14135364Seivind	     elfwalk++)
14235364Seivind		if (strcmp(elftype, elftypes[elfwalk]) == 0)
14335364Seivind			return 1;
14435364Seivind	return 0;
14535364Seivind}
146