strip.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <a.out.h>
  4. int strip(char*);
  5. int stripfilt(int, int);
  6. void
  7. main(int argc, char *argv[])
  8. {
  9. int i;
  10. int rv;
  11. rv = 0;
  12. if(argc == 1) {
  13. if(stripfilt(0, 1))
  14. exits("error");
  15. exits(0);
  16. }
  17. for(i = 1; i < argc; i++)
  18. rv |= strip(argv[i]);
  19. if(rv)
  20. exits("error");
  21. exits(0);
  22. }
  23. long
  24. ben(long xen)
  25. {
  26. union
  27. {
  28. long xen;
  29. uchar uch[sizeof(long)];
  30. } u;
  31. u.xen = xen;
  32. return (u.uch[0] << 24) | (u.uch[1] << 16) | (u.uch[2] << 8) | (u.uch[3] << 0);
  33. }
  34. int
  35. stripfilt(int in, int out)
  36. {
  37. Exec exec;
  38. int i, j, n, m, len;
  39. char buf[8192];
  40. /*
  41. * read header
  42. */
  43. if(readn(in, &exec, sizeof(Exec)) != sizeof(Exec)) {
  44. fprint(2, "strip: short read\n");
  45. return 1;
  46. }
  47. i = ben(exec.magic);
  48. for (j = 8; j < 24; j++)
  49. if (i == _MAGIC(j))
  50. break;
  51. if (j >= 24) {
  52. fprint(2, "strip: not a recognizable binary\n");
  53. return 1;
  54. }
  55. len = ben(exec.data) + ben(exec.text);
  56. /*
  57. * copy exec, text and data
  58. */
  59. exec.syms = 0;
  60. exec.spsz = 0;
  61. exec.pcsz = 0;
  62. write(out, &exec, sizeof(exec));
  63. for(n=0; n<len; n+=m) {
  64. m = len - n;
  65. if(m > sizeof(buf))
  66. m = sizeof(buf);
  67. if((m = read(in, buf, m)) < 0) {
  68. fprint(2, "strip: premature eof: %r\n");
  69. return 1;
  70. }
  71. if(write(out, buf, m) != m) {
  72. fprint(2, "strip: write error; %r\n");
  73. return 1;
  74. }
  75. }
  76. return 0;
  77. }
  78. int
  79. strip(char *file)
  80. {
  81. int fd;
  82. Exec exec;
  83. char *data;
  84. Dir *d;
  85. long n, len;
  86. int i, j;
  87. /*
  88. * make sure file is executable
  89. */
  90. d = dirstat(file);
  91. if(d == nil){
  92. perror(file);
  93. return 1;
  94. }
  95. if((d->qid.path & (DMDIR|DMAPPEND|DMEXCL))){
  96. fprint(2, "strip: %s must be executable\n", file);
  97. return 1;
  98. }
  99. /*
  100. * read its header and see if that makes sense
  101. */
  102. fd = open(file, OREAD);
  103. if(fd < 0){
  104. perror(file);
  105. free(d);
  106. return 1;
  107. }
  108. n = read(fd, &exec, sizeof exec);
  109. if (n != sizeof(exec)) {
  110. fprint(2, "strip: Unable to read header of %s\n", file);
  111. close(fd);
  112. free(d);
  113. return 1;
  114. }
  115. i = ben(exec.magic);
  116. for (j = 8; j < 24; j++)
  117. if (i == _MAGIC(j))
  118. break;
  119. if (j >= 24) {
  120. fprint(2, "strip: %s is not a recognizable binary\n", file);
  121. close(fd);
  122. free(d);
  123. return 1;
  124. }
  125. len = ben(exec.data) + ben(exec.text);
  126. if(len+sizeof(exec) == d->length) {
  127. fprint(2, "strip: %s is already stripped\n", file);
  128. close(fd);
  129. free(d);
  130. return 0;
  131. }
  132. if(len+sizeof(exec) > d->length) {
  133. fprint(2, "strip: %s has strange length\n", file);
  134. close(fd);
  135. free(d);
  136. return 1;
  137. }
  138. /*
  139. * allocate a huge buffer, copy the header into it, then
  140. * read the file.
  141. */
  142. data = malloc(len+sizeof(exec));
  143. if (!data) {
  144. fprint(2, "strip: Malloc failure. %s too big to strip.\n", file);
  145. close(fd);
  146. free(d);
  147. return 1;
  148. }
  149. /*
  150. * copy exec, text and data
  151. */
  152. exec.syms = 0;
  153. exec.spsz = 0;
  154. exec.pcsz = 0;
  155. memcpy(data, &exec, sizeof(exec));
  156. n = read(fd, data+sizeof(exec), len);
  157. if (n != len) {
  158. perror(file);
  159. close(fd);
  160. free(d);
  161. return 1;
  162. }
  163. close(fd);
  164. if(remove(file) < 0) {
  165. perror(file);
  166. free(data);
  167. free(d);
  168. return 1;
  169. }
  170. fd = create(file, OWRITE, d->mode);
  171. if (fd < 0) {
  172. perror(file);
  173. free(data);
  174. free(d);
  175. return 1;
  176. }
  177. n = write(fd, data, len+sizeof(exec));
  178. if (n != len+sizeof(exec)) {
  179. perror(file);
  180. close(fd);
  181. free(data);
  182. free(d);
  183. return 1;
  184. }
  185. close(fd);
  186. free(data);
  187. free(d);
  188. return 0;
  189. }