170 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			170 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
| /* strip - remove symbols.		Author: Dick van Veen */
 | |
| 
 | |
| #include <sys/types.h>
 | |
| #include <sys/stat.h>
 | |
| #include <fcntl.h>
 | |
| #include <a.out.h>
 | |
| #include <unistd.h>
 | |
| #include <string.h>
 | |
| #include <stdlib.h>
 | |
| #include <stdio.h>
 | |
| 
 | |
| /* Strip [file] ...
 | |
|  *
 | |
|  *	-	when no file is present, a.out is assumed.
 | |
|  *
 | |
|  */
 | |
| 
 | |
| #define A_OUT		"a.out"
 | |
| #define NAME_LENGTH	128	/* max file path name */
 | |
| 
 | |
| char buffer[BUFSIZ];		/* used to copy executable */
 | |
| char new_file[NAME_LENGTH];	/* contains name of temporary */
 | |
| struct exec header;
 | |
| 
 | |
| _PROTOTYPE(int main, (int argc, char **argv));
 | |
| _PROTOTYPE(void strip, (char *file));
 | |
| _PROTOTYPE(int read_header, (int fd));
 | |
| _PROTOTYPE(int write_header, (int fd));
 | |
| _PROTOTYPE(int make_tmp, (char *new_name, char *name));
 | |
| _PROTOTYPE(int copy_file, (int fd1, int fd2, long size));
 | |
| 
 | |
| int main(argc, argv)
 | |
| int argc;
 | |
| char **argv;
 | |
| {
 | |
|   argv++;
 | |
|   if (*argv == NULL)
 | |
| 	strip(A_OUT);
 | |
|   else
 | |
| 	while (*argv != NULL) {
 | |
| 		strip(*argv);
 | |
| 		argv++;
 | |
| 	}
 | |
|   return(0);
 | |
| }
 | |
| 
 | |
| void strip(file)
 | |
| char *file;
 | |
| {
 | |
|   int fd, new_fd;
 | |
|   struct stat buf;
 | |
|   long symb_size, relo_size;
 | |
| 
 | |
|   fd = open(file, O_RDONLY);
 | |
|   if (fd == -1) {
 | |
| 	fprintf(stderr, "can't open %s\n", file);
 | |
| 	close(fd);
 | |
| 	return;
 | |
|   }
 | |
|   if (read_header(fd)) {
 | |
| 	fprintf(stderr, "%s: not an executable file\n", file);
 | |
| 	close(fd);
 | |
| 	return;
 | |
|   }
 | |
|   if (header.a_syms == 0L) {
 | |
| 	close(fd);		/* no symbol table present */
 | |
| 	return;
 | |
|   }
 | |
|   symb_size = header.a_syms;
 | |
|   header.a_syms = 0L;		/* remove table size */
 | |
|   fstat(fd, &buf);
 | |
|   relo_size = buf.st_size - (A_MINHDR + header.a_text + header.a_data + symb_size);
 | |
|   new_fd = make_tmp(new_file, file);
 | |
|   if (new_fd == -1) {
 | |
| 	fprintf(stderr, "can't create temporary file\n");
 | |
| 	close(fd);
 | |
| 	return;
 | |
|   }
 | |
|   if (write_header(new_fd)) {
 | |
| 	fprintf(stderr, "can't write temporary file\n");
 | |
| 	unlink(new_file);
 | |
| 	close(fd);
 | |
| 	close(new_fd);
 | |
| 	return;
 | |
|   }
 | |
|   if (copy_file(fd, new_fd, header.a_text + header.a_data)) {
 | |
| 	fprintf(stderr, "can't copy %s\n", file);
 | |
| 	unlink(new_file);
 | |
| 	close(fd);
 | |
| 	close(new_fd);
 | |
| 	return;
 | |
|   }
 | |
|   if (relo_size != 0) {
 | |
| 	lseek(fd, symb_size, 1);
 | |
| 	if (copy_file(fd, new_fd, relo_size)) {
 | |
| 	    fprintf(stderr, "can't copy %s\n", file);
 | |
| 	    unlink(new_file);
 | |
| 	    close(fd);
 | |
| 	    close(new_fd);
 | |
| 	    return;
 | |
| 	}
 | |
|   }
 | |
|   close(fd);
 | |
|   close(new_fd);
 | |
|   if (unlink(file) == -1) {
 | |
| 	fprintf(stderr, "can't unlink %s\n", file);
 | |
| 	unlink(new_file);
 | |
| 	return;
 | |
|   }
 | |
|   link(new_file, file);
 | |
|   unlink(new_file);
 | |
|   chmod(file, buf.st_mode);
 | |
| }
 | |
| 
 | |
| int read_header(fd)
 | |
| int fd;
 | |
| {
 | |
|   if (read(fd, (char *) &header, A_MINHDR) != A_MINHDR) return(1);
 | |
|   if (BADMAG(header)) return (1);
 | |
|   if (header.a_hdrlen > sizeof(struct exec)) return (1);
 | |
|   lseek(fd, 0L, SEEK_SET);	/* variable size header */
 | |
|   if (read(fd, (char *)&header, (int)header.a_hdrlen) != (int) header.a_hdrlen)
 | |
| 	return(1);
 | |
|   return(0);
 | |
| }
 | |
| 
 | |
| int write_header(fd)
 | |
| int fd;
 | |
| {
 | |
|   lseek(fd, 0L, SEEK_SET);
 | |
|   if (write(fd, (char *)&header, (int)header.a_hdrlen) != (int)header.a_hdrlen)
 | |
| 	return(1);
 | |
|   return(0);
 | |
| }
 | |
| 
 | |
| int make_tmp(new_name, name)
 | |
| char *new_name, *name;
 | |
| {
 | |
|   int len;
 | |
|   char *nameptr;
 | |
| 
 | |
|   len = strlen(name);
 | |
|   if (len + 1 > NAME_LENGTH) return(-1);
 | |
|   strcpy(new_name, name);
 | |
|   nameptr = strrchr(new_name, '/');
 | |
|   if (nameptr == NULL) nameptr = new_name - 1;
 | |
|   if (nameptr - new_name + 6 + 1 > NAME_LENGTH) return (-1);
 | |
|   strcpy(nameptr + 1, "XXXXXX");
 | |
|   mktemp(new_name);
 | |
|   return(creat(new_name, 0777));
 | |
| }
 | |
| 
 | |
| int copy_file(fd1, fd2, size)
 | |
| int fd1, fd2;
 | |
| long size;
 | |
| {
 | |
|   int length;
 | |
| 
 | |
|   while (size > 0) {
 | |
| 	if (size < sizeof(buffer))
 | |
| 		length = size;
 | |
| 	else
 | |
| 		length = sizeof(buffer);
 | |
| 	if (read(fd1, buffer, length) != length) return(1);
 | |
| 	if (write(fd2, buffer, length) != length) return (1);
 | |
| 	size -= length;
 | |
|   }
 | |
|   return(0);
 | |
| }
 | 
