#include <u.h>#include <libc.h>#include <bio.h>#include <mach.h> voiderror(char* fmt, ...){ va_list arg; char *e, s[256]; va_start(arg, fmt); e = seprint(s, s+sizeof(s), "%s: ", argv0); e = vseprint(e, s+sizeof(s), fmt, arg); e = seprint(e, s+sizeof(s), "\n"); va_end(arg); write(2, s, e-s);} static voidusage(void){ error("usage: %s -o ofile file\n\t%s file ...\n", argv0, argv0); exits("usage");} static intstrip(char* file, char* out){ Dir *dir; int fd, i; Fhdr fhdr; Exec *exec; ulong mode; void *data; vlong length; if((fd = open(file, OREAD)) < 0){ error("%s: open: %r", file); return 1; } if(!crackhdr(fd, &fhdr)){ error("%s: %r", file); close(fd); return 1; } for(i = MIN_MAGIC; i <= MAX_MAGIC; i++){ if(fhdr.magic == _MAGIC(0, i) || fhdr.magic == _MAGIC(HDR_MAGIC, i)) break; } if(i > MAX_MAGIC){ error("%s: not a recognizeable binary", file); close(fd); return 1; } if((dir = dirfstat(fd)) == nil){ error("%s: stat: %r", file); close(fd); return 1; } length = fhdr.datoff+fhdr.datsz; if(length == dir->length){ if(out == nil){ /* nothing to do */ error("%s: already stripped", file); free(dir); close(fd); return 0; } } if(length > dir->length){ error("%s: strange length", file); close(fd); free(dir); return 1; } mode = dir->mode; free(dir); if((data = malloc(length)) == nil){ error("%s: malloc failure", file); close(fd); return 1; } seek(fd, 0LL, 0); if(read(fd, data, length) != length){ error("%s: read: %r", file); close(fd); free(data); return 1; } close(fd); exec = data; exec->syms = 0; exec->spsz = 0; exec->pcsz = 0; if(out == nil){ if(remove(file) < 0) { error("%s: remove: %r", file); free(data); return 1; } out = file; } if((fd = create(out, OWRITE, mode)) < 0){ error("%s: create: %r", out); free(data); return 1; } if(write(fd, data, length) != length){ error("%s: write: %r", out); close(fd); free(data); return 1; } close(fd); free(data); return 0;} voidmain(int argc, char* argv[]){ int r; char *p; p = nil; ARGBEGIN{ default: usage(); break; case 'o': p = ARGF(); if(p == nil) usage(); break; }ARGEND; switch(argc){ case 0: usage(); return; case 1: if(p != nil){ r = strip(*argv, p); break; } /*FALLTHROUGH*/ default: r = 0; while(argc > 0){ r |= strip(*argv, nil); argc--; argv++; } break; } if(r) exits("error"); exits(0);}
#include <u.h>
#include <libc.h>
#include <bio.h>
#include <mach.h>
void
error(char* fmt, ...)
{
va_list arg;
char *e, s[256];
va_start(arg, fmt);
e = seprint(s, s+sizeof(s), "%s: ", argv0);
e = vseprint(e, s+sizeof(s), fmt, arg);
e = seprint(e, s+sizeof(s), "\n");
va_end(arg);
write(2, s, e-s);
}
static void
usage(void)
{
error("usage: %s -o ofile file\n\t%s file ...\n", argv0, argv0);
exits("usage");
}
static int
strip(char* file, char* out)
{
Dir *dir;
int fd, i;
Fhdr fhdr;
Exec *exec;
ulong mode;
void *data;
vlong length;
if((fd = open(file, OREAD)) < 0){
error("%s: open: %r", file);
return 1;
}
if(!crackhdr(fd, &fhdr)){
error("%s: %r", file);
close(fd);
return 1;
}
for(i = MIN_MAGIC; i <= MAX_MAGIC; i++){
if(fhdr.magic == _MAGIC(0, i) || fhdr.magic == _MAGIC(HDR_MAGIC, i))
break;
}
if(i > MAX_MAGIC){
error("%s: not a recognizeable binary", file);
close(fd);
return 1;
}
if((dir = dirfstat(fd)) == nil){
error("%s: stat: %r", file);
close(fd);
return 1;
}
length = fhdr.datoff+fhdr.datsz;
if(length == dir->length){
if(out == nil){ /* nothing to do */
error("%s: already stripped", file);
free(dir);
close(fd);
return 0;
}
}
if(length > dir->length){
error("%s: strange length", file);
close(fd);
free(dir);
return 1;
}
mode = dir->mode;
free(dir);
if((data = malloc(length)) == nil){
error("%s: malloc failure", file);
close(fd);
return 1;
}
seek(fd, 0LL, 0);
if(read(fd, data, length) != length){
error("%s: read: %r", file);
close(fd);
free(data);
return 1;
}
close(fd);
exec = data;
exec->syms = 0;
exec->spsz = 0;
exec->pcsz = 0;
if(out == nil){
if(remove(file) < 0) {
error("%s: remove: %r", file);
free(data);
return 1;
}
out = file;
}
if((fd = create(out, OWRITE, mode)) < 0){
error("%s: create: %r", out);
free(data);
return 1;
}
if(write(fd, data, length) != length){
error("%s: write: %r", out);
close(fd);
free(data);
return 1;
}
close(fd);
free(data);
return 0;
}
void
main(int argc, char* argv[])
{
int r;
char *p;
p = nil;
ARGBEGIN{
default:
usage();
break;
case 'o':
p = ARGF();
if(p == nil)
usage();
break;
}ARGEND;
switch(argc){
case 0:
usage();
return;
case 1:
if(p != nil){
r = strip(*argv, p);
break;
}
/*FALLTHROUGH*/
default:
r = 0;
while(argc > 0){
r |= strip(*argv, nil);
argc--;
argv++;
}
break;
}
if(r)
exits("error");
exits(0);
}