minix/commands/simple/strip.c
2005-04-21 14:53:53 +00:00

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);
}