xref: /plan9-contrib/sys/src/cmd/strip.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
1 #include <u.h>
2 #include <libc.h>
3 #include <a.out.h>
4 
5 int	strip(char*);
6 
7 void
8 main(int argc, char *argv[])
9 {
10 	int i;
11 	int rv;
12 
13 	rv = 0;
14 	for(i = 1; i < argc; i++)
15 		rv |= strip(argv[i]);
16 	if(rv)
17 		exits("error");
18 	exits(0);
19 }
20 
21 long
22 ben(long xen)
23 {
24 	union
25 	{
26 		long	xen;
27 		uchar	uch[sizeof(long)];
28 	} u;
29 
30 	u.xen = xen;
31 	return (u.uch[0] << 24) | (u.uch[1] << 16) | (u.uch[2] << 8) | (u.uch[3] << 0);
32 }
33 
34 int
35 strip(char *file)
36 {
37 	int fd;
38 	Exec exec;
39 	char *data;
40 	Dir d;
41 	long n, len;
42 	int i, j;
43 
44 	/*
45 	 *  make sure file is executable
46 	 */
47 	if(dirstat(file, &d) < 0){
48 		perror(file);
49 		return 1;
50 	}
51 	if((d.qid.path & (CHDIR|CHAPPEND|CHEXCL))){
52 		fprint(2, "strip: %s must be executable\n", file);
53 		return 1;
54 	}
55 	/*
56 	 *  read it's header and see if that makes sense
57 	 */
58 	fd = open(file, OREAD);
59 	if(fd < 0){
60 		perror(file);
61 		return 1;
62 	}
63 	n = read(fd, &exec, sizeof exec);
64 	if (n != sizeof(exec)) {
65 		fprint(2, "strip: Unable to read header of %s\n", file);
66 		close(fd);
67 		return 1;
68 	}
69 	i = ben(exec.magic);
70 	for (j = 8; j < 24; j++)
71 		if (i == _MAGIC(j))
72 			break;
73 	if (j >= 24) {
74 		fprint(2, "strip: %s is not a recognizable binary\n", file);
75 		close(fd);
76 		return 1;
77 	}
78 
79 	len = ben(exec.data) + ben(exec.text);
80 	if(len+sizeof(exec) == d.length) {
81 		fprint(2, "strip: %s is already stripped\n", file);
82 		close(fd);
83 		return 0;
84 	}
85 	if(len+sizeof(exec) > d.length) {
86 		fprint(2, "strip: %s has strange length\n", file);
87 		close(fd);
88 		return 1;
89 	}
90 	/*
91 	 *  allocate a huge buffer, copy the header into it, then
92 	 *  read the file.
93 	 */
94 	data = malloc(len+sizeof(exec));
95 	if (!data) {
96 		fprint(2, "strip: Malloc failure. %s too big to strip.\n", file);
97 		close(fd);
98 		return 1;
99 	}
100 	/*
101 	 *  copy exec, text and data
102 	 */
103 	exec.syms = 0;
104 	exec.spsz = 0;
105 	exec.pcsz = 0;
106 	memcpy(data, &exec, sizeof(exec));
107 	n = read(fd, data+sizeof(exec), len);
108 	if (n != len) {
109 		perror(file);
110 		close(fd);
111 		return 1;
112 	}
113 	close(fd);
114 	if(remove(file) < 0) {
115 		perror(file);
116 		free(data);
117 		return 1;
118 	}
119 	fd = create(file, OWRITE, d.mode);
120 	if (fd < 0) {
121 		perror(file);
122 		free(data);
123 		return 1;
124 	}
125 	n = write(fd, data, len+sizeof(exec));
126 	if (n != len+sizeof(exec)) {
127 		perror(file);
128 		close(fd);
129 		free(data);
130 		return 1;
131 	}
132 	close(fd);
133 	free(data);
134 	return 0;
135 }
136