]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/strip.c
Import sources from 2011-03-30 iso image
[plan9front.git] / sys / src / cmd / strip.c
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 }