minix/commands/ackstrip/ackstrip.c
Ben Gras 453be3b530 rename nm and strip to acknm and ackstrip
this is to force invocations of these utils for ack to be
explicitly named such, so in the future binutils can be installed
in /usr/pkg without the g- prefix.
2010-08-02 16:09:19 +00:00

169 lines
3.6 KiB
C

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