|
|
DataMuseum.dkPresents historical artifacts from the history of: Commodore CBM-900 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Commodore CBM-900 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 3483 (0xd9b)
Types: TextFile
Notes: UNIX file
Names: »strip.c«
└─⟦f27320a65⟧ Bits:30001972 Commodore 900 hard disk image with partial source code
└─⟦f4b8d8c84⟧ UNIX Filesystem
└─⟦this⟧ »cmd/strip.c«
/*
* Strip the debug table, the symbol
* table and the relocation information from a
* object file.
*/
#include <stdio.h>
#include "n.out.h"
#include <signal.h>
#include <canon.h>
char tmpnam[] = "/tmp/stripXXXXXX";
char werror[] = "write error";
char rerror[] = "cannot reopen";
char xerror[] = "unexpected end of file";
struct ldheader lh;
FILE *ifp;
FILE *ofp;
int cleanup();
main(argc, argv)
char *argv[];
{
register estat, i;
if (argc < 2)
usage();
mktemp(tmpnam);
if (signal(SIGINT, SIG_IGN) != SIG_IGN)
signal(SIGINT, cleanup);
estat = 0;
for (i=1; i<argc; i++) {
estat |= strip(argv[i]);
if (ifp != NULL) {
fclose(ifp);
ifp = NULL;
}
if (ofp != NULL) {
fclose(ofp);
ofp = NULL;
}
}
cleanup(estat);
}
/*
* Do all the work.
* The external variables `ifp' and `ofp'
* will be closed by the mainline. This makes the
* many error conditions a little easier to
* deal with.
*/
strip(fn)
char *fn;
{
register c;
register size_t nsize;
register short flags;
if ((ifp = fopen(fn, "r")) == NULL) {
diag("cannot open", fn);
return (1);
}
if ((ofp = fopen(tmpnam, "w")) == NULL) {
diag("cannot create", tmpnam);
return (1);
}
if (fread(&lh, sizeof(lh), 1, ifp) != 1) {
diag(xerror, fn);
return (1);
}
canlh();
if (lh.l_magic != L_MAGIC) {
diag("bad format", fn);
return (1);
}
if (stripped())
return (0);
nsize = lh.l_ssize[L_SHRI] + lh.l_ssize[L_SHRD]
+ lh.l_ssize[L_PRVI] + lh.l_ssize[L_PRVD];
lh.l_flag |= LF_NRB;
lh.l_ssize[L_DEBUG] = 0;
lh.l_ssize[L_SYM] = 0;
lh.l_ssize[L_REL] = 0;
flags = lh.l_flag;
canlh();
if ((flags & LF_32) != 0) {
if (fwrite(&lh, sizeof(lh), 1, ofp) != 1) {
diag(werror, tmpnam);
return (1);
}
} else {
if (fwrite(&lh, sizeof(lh)-2*sizeof(short), 1, ofp) != 1) {
diag(werror, tmpnam);
return(1);
}
fseek(ifp, (long)-2*sizeof(short), 1);
}
while (nsize-- > 0) {
if ((c = getc(ifp)) == EOF) {
diag(xerror, fn);
return (1);
}
putc(c, ofp);
}
fflush(ofp);
if (ferror(ofp)) {
diag(werror, tmpnam);
return (1);
}
fclose(ifp);
ifp = NULL;
fclose(ofp);
ofp = NULL;
if ((ifp = fopen(tmpnam, "r")) == NULL) {
diag(rerror, tmpnam);
return (1);
}
if ((ofp = fopen(fn, "w")) == NULL) {
diag(rerror, fn);
return (1);
}
while ((c = getc(ifp)) != EOF)
putc(c, ofp);
fflush(ofp);
if (ferror(ofp)) {
diag(werror, fn);
fprintf(stderr, "strip: file saved in %s\n", tmpnam);
exit(1);
}
return (0);
}
/*
* Convert the l.out header structure
* in the buffer `lh' to and from standard
* ordering.
*/
canlh()
{
register i;
canshort(lh.l_magic);
canshort(lh.l_flag);
for (i=0; i<NLSEG; ++i)
cansize(lh.l_ssize[i]);
}
/*
* Print diagnostics.
*/
diag(s, fn)
char *s;
char *fn;
{
fprintf(stderr, "strip: ");
if (fn != NULL)
fprintf(stderr, "%s: ", fn);
fprintf(stderr, "%s\n", s);
}
/*
* Check if a file has been stripped.
* The header is in `lh' and has been converted
* into machine native format.
*/
stripped()
{
if ((lh.l_flag&LF_NRB) == 0)
return (0);
if (lh.l_ssize[L_DEBUG] || lh.l_ssize[L_SYM] || lh.l_ssize[L_REL])
return (0);
return (1);
}
/*
* Cleanup tempfile and exit.
* The status is the exit status.
* When a signal occurs, it is the signal
* number which is non-zero so
* this will be an acceptable exit status.
*/
cleanup(s)
{
unlink(tmpnam);
exit(s);
}
/*
* Print usage message.
*/
usage()
{
fprintf(stderr, "Usage: strip name ...\n");
exit(1);
}