OverlayIIgs

This commit is contained in:
Kelvin Sherlock 2013-07-29 02:02:50 -04:00
parent e6f0a12ef0
commit f05c774f3e
4 changed files with 362 additions and 2 deletions

99
OverlayIIgs-flags.c Normal file
View File

@ -0,0 +1,99 @@
#ifdef __ORCAC__
#pragma optimize 79
#pragma noroot
#endif
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "OverlayIIgs-flags.h"
void FlagsHelp(void)
{
fputs("OverlayIIgs [options] infile outfile\n", stdout);
fputs("-a address set the address\n", stdout);
fputs("\n", stdout);
exit(0);
}
struct Flags flags;
int FlagsParse(int argc, char **argv)
{
char *cp;
char *optarg;
char c;
int i;
int j;
int eof; // end-of-flags
int mindex; // mutation index.
memset(&flags, 0, sizeof(flags));
for (i = 1, mindex = 1, eof = 0; i < argc; ++i)
{
cp = argv[i];
c = cp[0];
if (c != '-' || eof)
{
if (i != mindex) argv[mindex] = argv[i];
mindex++;
continue;
}
// -- = end of options.
if (cp[1] == '-' && cp[2] == 0)
{
eof = 1;
continue;
}
// now scan all the flags in the string...
optarg = NULL;
for (j = 1; ; ++j)
{
c = cp[j];
if (c == 0) break;
switch (c)
{
case 'h':
FlagsHelp();
break;
case 'a':
// -xarg or -x arg
++j;
if (cp[j])
{
optarg = cp + j;
}
else
{
if (++i >= argc)
{
fputs("option requires an argument -- a\n", stderr);
exit(1);
}
optarg = argv[i];
}
flags._a = optarg;
break;
case 'p':
flags._p = 1;
break;
default:
fprintf(stderr, "illegal option -- %c\n", c);
exit(1);
}
if (optarg) break;
}
}
return mindex;
}

20
OverlayIIgs-flags.h Normal file
View File

@ -0,0 +1,20 @@
#ifndef __flags_h__
#define __flags_h__
typedef struct Flags {
char *_a;
unsigned _p:1;
} Flags;
extern struct Flags flags;
int FlagsParse(int argc, char **argv);
void FlagsHelp(void);
#endif

237
OverlayIIgs.c Normal file
View File

@ -0,0 +1,237 @@
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <ctype.h>
#include <errno.h>
#include <string.h>
#include "OverlayIIgs-flags.h"
int tox(char c)
{
c |= 0x20;
if (c >='0' && c <= '9') return c - '0';
if (c >= 'a' && c <= 'f') return c - 'a' + 10;
return 0;
}
off_t hex(const char *in)
{
off_t rv = 0;
int i;
for (i = 0; ; ++i)
{
off_t tmp;
char c;
c = *in++;
if (!c) break;
if (!isxdigit(c)) return -1;
tmp = rv;
rv <<= 4;
rv |= tox(c);
// numver too large.
if (rv < tmp)
{
return -1;
}
}
if (i == 0) return -1;
return rv;
}
off_t dec(const char *in)
{
off_t rv = 0;
int i;
for (i = 0; ; ++i)
{
off_t tmp;
char c;
c = *in++;
if (!c) break;
if (!isdigit(c)) return -1;
tmp = rv;
rv = rv * 10;
rv += c - '0';
// numver too large.
if (rv < tmp)
{
return -1;
}
}
if (i == 0) return -1;
return rv;
}
off_t getnum(const char *cp)
{
if (!cp) return -1;
if (cp[0] == '$')
{
return hex(cp + 1);
}
if (cp[0] == '0' && cp[1] == 'x')
{
return hex(cp + 2);
}
return dec(cp);
}
int seek_to(int fd, off_t address)
{
// posix lseek(2) will seek past the eof and zero-fill
// when a write occurs.
// mpw lseek will fail (ENXIO) in such situations.
// SetEOF will not zero-fill.
// to compensate, manually zero-fill to the address
// if address > eof.
off_t eof;
eof = lseek(fd, 0, SEEK_END);
if (eof < 0)
return -1;
while (eof < address)
{
static char buffer[512] = { 0 };
off_t size = address - eof;
if (size > 512) size = 512;
size = write(fd, buffer, size);
if (size < 0) return -1;
eof += size;
}
eof = lseek(fd, address, SEEK_SET);
if (eof < 0)
return -1;
return 0;
}
int main(int argc, char **argv)
{
char *src;
char *dest;
int srcFD, destFD;
off_t address;
int rv;
argc = FlagsParse(argc, argv);
if (argc != 3)
{
FlagsHelp();
return 1;
}
if (!flags._a)
{
FlagsHelp();
return 1;
}
address = getnum(flags._a);
if (address == -1)
{
fprintf(stderr, "Invalid address: %s\n", flags._a);
return 1;
}
src = argv[1];
dest = argv[2];
srcFD = open(src, O_RDONLY | O_BINARY);
if (srcFD < 0)
{
fprintf(stderr, "Unable to open input file %s: %s",
src, strerror(errno));
return 1;
}
destFD = open(dest, O_WRONLY | O_CREAT | O_BINARY);
if (destFD < 0)
{
fprintf(stderr, "Unable to open input file %s: %s",
dest, strerror(errno));
close(srcFD);
return 1;
}
//if (lseek(destFD, address, SEEK_SET) < 0)
if (seek_to(destFD, address) < 0)
{
fprintf(stderr, "Error seeking %s: %s",
dest, strerror(errno));
close(srcFD);
close(destFD);
return 1;
}
// copy it
rv = 0;
for (;;)
{
unsigned char buffer[4096];
ssize_t rsize;
ssize_t wsize;
rsize = read(srcFD, buffer, 4096);
if (rsize == 0) break;
if (rsize < 0)
{
fprintf(stderr, "Error reading %s: %s\n",
src, strerror(errno));
rv = 1;
break;
}
wsize = write(destFD, buffer, rsize);
if (wsize < 0 || wsize != rsize)
{
fprintf(stderr, "Error writing %s: %s\n",
dest, strerror(errno));
rv = 1;
break;
}
}
close(srcFD);
close(destFD);
return rv;
}

View File

@ -26,11 +26,11 @@ LDFLAGS = -w -c 'MPS ' -t MPST \
# LDFLAGS = -d -c 'MPS ' -t MPST
all: Help GetEnv Duplicate SetFile
all: Help GetEnv Duplicate SetFile OverlayIIgs
clean:
rm -f *.c.o
rm -f Help GetEnv Duplicate SetFile
rm -f Help GetEnv Duplicate SetFile OverlayIIgs
GetEnv: GetEnv.c.o
mpw Link $(LDFLAGS) -o $@ $^ $(LIBS)
@ -47,6 +47,10 @@ SetFile: SetFile.c.o SetFile-flags.c.o
mpw Link $(LDFLAGS) -o $@ $^ $(LIBS)
OverlayIIgs: OverlayIIgs.c.o OverlayIIgs-flags.c.o
mpw Link $(LDFLAGS) -o $@ $^ $(LIBS)
#SetFile.c : SetFile.rl
# ragel -G2 -p -m -o $@ $<