mirror of
https://github.com/rcornwell/sims.git
synced 2026-02-23 07:32:50 +00:00
175 lines
5.5 KiB
C
175 lines
5.5 KiB
C
/*
|
|
* mpxblk.c
|
|
*
|
|
* This program converts a unix/dos ascii file to an mpx blocked file
|
|
* trailing blanks are not deleted from the source file
|
|
* input - stdin
|
|
* output - stdout
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#define MPXMAX 254
|
|
int mpxbb();
|
|
int getloi();
|
|
#define BLKSIZE 768
|
|
|
|
int main (argc, argv)
|
|
int argc;
|
|
char *argv[];
|
|
{
|
|
char s[MPXMAX];
|
|
int i;
|
|
int fn = fileno(stdout);
|
|
|
|
while (1) {
|
|
if ((i = getloi(s, MPXMAX)) == 0) {
|
|
mpxbb(fn, s, 0, 1); /* last write to output */
|
|
exit(0);
|
|
}
|
|
if (i == 1 && s[0] == '\n')
|
|
s[0] = ' '; /* replace single n/l with blank */
|
|
if (s[i-1] == '\n')
|
|
i--; /* remove trailing n/l */
|
|
if (mpxbb(fn, s, i, 0) < 0) { /* last data record out */
|
|
fprintf(stderr, "output file error\n");
|
|
exit(1);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* get a line of input. */
|
|
/* terminate line on \n or \r\n */
|
|
/* allow max of 254 chars in a line */
|
|
|
|
int getloi(s, lim)
|
|
char s[];
|
|
int lim;
|
|
{
|
|
int c, i;
|
|
|
|
for(i = 0; --lim > 0; ) {
|
|
c = getchar();
|
|
switch (c) {
|
|
case '\n':
|
|
/* terminate on \n */
|
|
s[i++] = c;
|
|
goto linedone;
|
|
case '\r':
|
|
c = getchar();
|
|
/* terminate on \r\n */
|
|
if (c == '\n') {
|
|
s[i++] = c;
|
|
goto linedone;
|
|
}
|
|
/* put back the character */
|
|
ungetc(c, stdin);
|
|
/* output the \r to the stream */
|
|
c = '\r';
|
|
/* drop through */
|
|
default:
|
|
s[i++] = c;
|
|
break;
|
|
case EOF:
|
|
return (0);
|
|
break;
|
|
}
|
|
}
|
|
linedone:
|
|
return (i);
|
|
}
|
|
|
|
/*
|
|
** output line of text from the source
|
|
*/
|
|
|
|
static unsigned char bb[BLKSIZE]; /* blocking buffer */
|
|
static char first = 0; /* 1st time thru flag */
|
|
|
|
/*
|
|
* mpxbb - make up mpx block file output
|
|
* input - buffer address
|
|
* - byte count
|
|
* - last write flag
|
|
*/
|
|
|
|
int
|
|
mpxbb(fd, buf, cnt, last)
|
|
int fd;
|
|
unsigned char *buf;
|
|
int cnt;
|
|
int last;
|
|
{
|
|
int boff; /* next write address offset */
|
|
|
|
if (!first) { /* is this 1st time thru */
|
|
first = 1; /* set the flag */
|
|
memset (bb, '\0', BLKSIZE); /* zero the buffer */
|
|
bb[3] = 4; /* next write byte offset */
|
|
bb[4] = 0x60; /* set beg/end of block */
|
|
bb[5] = 0; /* 1st block count is 0 bytes */
|
|
}
|
|
boff = (bb[2] << 8) | (bb[3]); /* get next write address offset */
|
|
if (last)
|
|
goto alldone; /* close out the file */
|
|
|
|
/* see if enough room in buffer for this record */
|
|
/* add current offset + 2 (for last record info) plus new */
|
|
/* record size plus 4 (2 for this rec, 2 for last) */
|
|
if ((boff + 2 + cnt + 4) >= BLKSIZE) {
|
|
/* not enough space, write out this record */
|
|
if (write(fd, bb, BLKSIZE) < 0)
|
|
return(-1);
|
|
memset (bb, '\0', BLKSIZE); /* zero the buffer */
|
|
bb[4] = 0x60; /* set beg/end of block */
|
|
bb[5] = 0; /* 1st block count is 0 bytes */
|
|
/* after 1st write */
|
|
boff = 4; /* init count at 4 bytes */
|
|
}
|
|
/* we have enough room, move in the record */
|
|
/* clear last record end of block flag, set up this record */
|
|
/* info and last rec info at end of data, and update cnt */
|
|
bb[boff] &= ~0x20; /* clear end of block flag */
|
|
bb[boff+2] = 0x00; /* clear this blocks flags */
|
|
bb[boff+3] = cnt; /* set this record count */
|
|
memcpy(&bb[boff+4], buf, cnt); /* copy in the data */
|
|
boff += (cnt+4); /* update count */
|
|
bb[boff] = 0x20; /* set eob status flag */
|
|
bb[boff+1] = cnt; /* set last rec byte count */
|
|
bb[2] = (boff & 0xff00) >> 8; /* set hi byte of count */
|
|
bb[3] = (boff & 0xff); /* set lo byte of count */
|
|
return(cnt); /* done */
|
|
|
|
alldone:
|
|
/* that was the last record, set eof flag in bb, write it and exit */
|
|
/* see if enough room in buffer for EOM record */
|
|
/* add current offset + 2 (for last record info) plus new */
|
|
/* EOF record size of 4 (2 for this rec, 2 for last) */
|
|
if ((boff + 2 + 4) >= BLKSIZE) {
|
|
/* not enough space, write out this record */
|
|
if (write(fd, bb, BLKSIZE) < 0)
|
|
return(-1);
|
|
memset (bb, '\0', BLKSIZE); /* zero the buffer */
|
|
bb[4] = 0x60; /* set beg/end of block */
|
|
bb[5] = 0; /* 1st block count is 0 bytes */
|
|
/* after 1st write */
|
|
boff = 4; /* init count at 4 bytes */
|
|
}
|
|
bb[boff] &= ~0x20; /* clear end of block flag */
|
|
/* bb[boff+2] = 0xa0; /* clear this blocks flags */
|
|
bb[boff+2] = 0x80; /* clear this blocks flags */
|
|
bb[boff+3] = 0; /* set record count of 0 */
|
|
bb[boff+4] = 0xa0; /* set EOF/EOB flags */
|
|
boff += 4; /* 4 more bytes */
|
|
bb[2] = (boff & 0xff00) >> 8; /* set hi byte of count */
|
|
bb[3] = (boff & 0xff); /* set lo byte of count */
|
|
/* write out EOF record */
|
|
if (write(fd, bb, BLKSIZE) < 0)
|
|
return(-1);
|
|
first = 0; /* reset 1st time flag */
|
|
return(cnt); /* get out, done */
|
|
}
|
|
|