strip.c (1952B)
1 #include <errno.h> 2 #include <stdarg.h> 3 #include <stdio.h> 4 #include <stdlib.h> 5 #include <string.h> 6 7 #include <scc/arg.h> 8 #include <scc/mach.h> 9 10 static int status; 11 static char tmpname[FILENAME_MAX]; 12 static char *filename; 13 char *argv0; 14 15 static void 16 error(char *fmt, ...) 17 { 18 va_list va; 19 20 va_start(va, fmt); 21 fprintf(stderr, "strip: %s: ", filename); 22 vfprintf(stderr, fmt, va); 23 putc('\n', stderr); 24 va_end(va); 25 26 status = EXIT_FAILURE; 27 } 28 29 static void 30 doit(char *fname) 31 { 32 int type; 33 size_t r; 34 FILE *src, *dst; 35 Map *map; 36 Obj *obj; 37 38 errno = 0; 39 filename = fname; 40 r = snprintf(tmpname, sizeof(tmpname), "%s.tmp", fname); 41 if (r >= sizeof(tmpname)) { 42 error("%s: name too long", fname); 43 return; 44 } 45 if ((src = fopen(fname, "rb")) == NULL) { 46 error("opening src file"); 47 return; 48 } 49 if ((type = objprobe(src, NULL)) < 0) { 50 error("getting object type"); 51 goto err1; 52 } 53 if ((obj = newobj(type)) == NULL) { 54 error("creating object"); 55 goto err1; 56 } 57 if (readobj(obj, src) < 0) { 58 error("reading object"); 59 goto err2; 60 } 61 if ((map = loadmap(obj, src)) == NULL) { 62 error("loading map"); 63 goto err3; 64 } 65 if (strip(obj) < 0) { 66 error("stripping"); 67 goto err3; 68 } 69 if ((dst = fopen(tmpname, "wb")) == NULL) { 70 error("opening dst"); 71 goto err3; 72 } 73 if (writeobj(obj, map, dst) < 0) { 74 error("writing object"); 75 goto err5; 76 } 77 if (fclose(dst) == EOF) { 78 error("closing dst"); 79 goto err4; 80 } 81 if (remove(fname) == EOF) { 82 error("removing fname"); 83 goto err4; 84 } 85 if (rename(tmpname, fname) == EOF) { 86 error("rename fname"); 87 goto err4; 88 } 89 90 goto err3; 91 92 err5: 93 fclose(dst); 94 err4: 95 remove(tmpname); 96 err3: 97 free(map); 98 err2: 99 delobj(obj); 100 err1: 101 fclose(src); 102 } 103 104 static void 105 usage(void) 106 { 107 fputs("usage: strip [file...]\n", stderr); 108 exit(EXIT_FAILURE); 109 } 110 111 int 112 main(int argc, char *argv[]) 113 { 114 ARGBEGIN { 115 default: 116 usage(); 117 } ARGEND 118 119 if (argc == 0) { 120 doit("a.out"); 121 } else { 122 for (; *argv; ++argv) 123 doit(*argv); 124 } 125 126 return status; 127 }