Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include <u.h>
2
#include <libc.h>
3
#include <bio.h>
4
#include <mach.h>
5
 
6
void
7
error(char* fmt, ...)
8
{
9
	va_list arg;
10
	char *e, s[256];
11
 
12
	va_start(arg, fmt);
13
	e = seprint(s, s+sizeof(s), "%s: ", argv0);
14
	e = vseprint(e, s+sizeof(s), fmt, arg);
15
	e = seprint(e, s+sizeof(s), "\n");
16
	va_end(arg);
17
 
18
	write(2, s, e-s);
19
}
20
 
21
static void
22
usage(void)
23
{
24
	error("usage: %s -o ofile file\n\t%s file ...\n", argv0, argv0);
25
	exits("usage");
26
}
27
 
28
static int
29
strip(char* file, char* out)
30
{
31
	Dir *dir;
32
	int fd, i;
33
	Fhdr fhdr;
34
	Exec *exec;
35
	ulong mode;
36
	void *data;
37
	vlong length;
38
 
39
	if((fd = open(file, OREAD)) < 0){
40
		error("%s: open: %r", file);
41
		return 1;
42
	}
43
 
44
	if(!crackhdr(fd, &fhdr)){
45
		error("%s: %r", file);
46
		close(fd);
47
		return 1;
48
	}
49
	for(i = MIN_MAGIC; i <= MAX_MAGIC; i++){
50
		if(fhdr.magic == _MAGIC(0, i) || fhdr.magic == _MAGIC(HDR_MAGIC, i))
51
			break;
52
	}
53
	if(i > MAX_MAGIC){
54
		error("%s: not a recognizeable binary", file);
55
		close(fd);
56
		return 1;
57
	}
58
 
59
	if((dir = dirfstat(fd)) == nil){
60
		error("%s: stat: %r", file);
61
		close(fd);
62
		return 1;
63
	}
64
 
65
	length = fhdr.datoff+fhdr.datsz;
66
	if(length == dir->length){
67
		if(out == nil){	/* nothing to do */
68
			error("%s: already stripped", file);
69
			free(dir);
70
			close(fd);
71
			return 0;
72
		}
73
	}
74
	if(length > dir->length){
75
		error("%s: strange length", file);
76
		close(fd);
77
		free(dir);
78
		return 1;
79
	}
80
 
81
	mode = dir->mode;
82
	free(dir);
83
 
84
	if((data = malloc(length)) == nil){
85
		error("%s: malloc failure", file);
86
		close(fd);
87
		return 1;
88
	}
89
	seek(fd, 0LL, 0);
90
	if(read(fd, data, length) != length){
91
		error("%s: read: %r", file);
92
		close(fd);
93
		free(data);
94
		return 1;
95
	}
96
	close(fd);
97
 
98
	exec = data;
99
	exec->syms = 0;
100
	exec->spsz = 0;
101
	exec->pcsz = 0;
102
 
103
	if(out == nil){
104
		if(remove(file) < 0) {
105
			error("%s: remove: %r", file);
106
			free(data);
107
			return 1;
108
		}
109
		out = file;
110
	}
111
	if((fd = create(out, OWRITE, mode)) < 0){
112
		error("%s: create: %r", out);
113
		free(data);
114
		return 1;
115
	}
116
	if(write(fd, data, length) != length){
117
		error("%s: write: %r", out);
118
		close(fd);
119
		free(data);
120
		return 1;
121
	}
122
	close(fd);
123
	free(data);
124
 
125
	return 0;
126
}
127
 
128
void
129
main(int argc, char* argv[])
130
{
131
	int r;
132
	char *p;
133
 
134
	p = nil;
135
 
136
	ARGBEGIN{
137
	default:
138
		usage();
139
		break;
140
	case 'o':
141
		p = ARGF();
142
		if(p == nil)
143
			usage();
144
		break;
145
	}ARGEND;
146
 
147
	switch(argc){
148
	case 0:
149
		usage();
150
		return;
151
	case 1:
152
		if(p != nil){
153
			r = strip(*argv, p);
154
			break;
155
		}
156
		/*FALLTHROUGH*/
157
	default:
158
		r = 0;
159
		while(argc > 0){
160
			r |= strip(*argv, nil);
161
			argc--;
162
			argv++;
163
		}
164
		break;
165
	}
166
 
167
	if(r)
168
		exits("error");
169
	exits(0);
170
}