2.11BSD/src/new/l11/in.c
/* Input functions */
# include "link.h"
/* define maximum size of checksum contents */
# define MAXSIZE 40
static char *Fname = NULL; /* name of current input file */
static FILE *Fp = NULL; /* file pointer of current file */
static char Buff[MAXSIZE]; /* buffer for current checksum module */
static char *Next; /* next byte to be popped from buffer */
static int Count; /* number of bytes left */
static int Type; /* type of checksum module */
static char No_code = 0; /* flag set if a code section was attempted to
** be found but was not there */
/*************************** ch_input ************************************/
ch_input(newfile, newmod) /* change input checksum buffer contents */
char *newfile;
int newmod;
{
FILE *fopen();
if (Fname == NULL || strcmp(Fname, newfile)) /* new file is
** different */
{
Fname = newfile;
if (Fp != NULL)
fclose(Fp);
if ((Fp = fopen(Fname, "r")) == NULL)
inerror("not found");
Type = 0;
}
if (newmod != Type) /* if not right module type already */
while (newmod != read_mod()) /* read until correct module type */
{
/* check for missing code section */
if ( newmod == CODE && Type == SYMBOLS)
{
No_code = 1;
break;
}
if (Type == 6) /* check for EOF module */
{
No_code = 1;
break;
}
/*
inerror("EOF \(linker error\)");
*/
}
}
/************************** morebytes ************************************/
morebytes() /* returns 1 if there are unread bytes of the current */
/* checksum module type, returns 0 if not */
{
register int temptype;
if (No_code) /* if no code section, return 0 and reset */
{
No_code = 0;
return (0);
}
else if (Count > 0)
return (1);
else
{
/* read next module and check for same type */
temptype = Type;
if (temptype == read_mod())
return (1);
else
return (0);
}
}
/****************************** getbyte ************************************/
getbyte() /* return next byte of current checksum module type */
{
/* check for empty buffer, if so check if next module is */
/* the same type */
if ((Count == 0) && !morebytes())
{
lerror("End of checksum module");
/* NOTREACHED */
}
else
{
Count--;
return (*Next++ & 0377);
}
}
/**************************** getword ************************************/
WORD getword() /* return next word */
{
register int temp;
temp = 0377 & getbyte();
return (0400 * getbyte() + temp);
}
/**************************** inerror **********************************/
inerror(mess) /* print error message and filename then exit. */
/* called when a user error has occurred concerning the */
/* input file */
char *mess;
{
fprintf(stderr, "%s: %s\n", Fname, mess);
bail_out();
}
/****************************************************************************/
int sum; /* sum of input bytes */
/*************************** read_mod **************************************/
read_mod() /* read a checksum module and return type */
{
register int i;
sum = 0;
if (getb() != 1)
{
if (feof(Fp) && No_code)
return ( 6 );
else
inerror("Not in object file format");
}
/* clear zero byte */
getb();
/* Count = next word - 6 (# of bytes in header) */
Count = getb();
Count += 0400 * getb() - 6;
if (Count > MAXSIZE)
lerror("checksum size too large");
Type = getb();
/* clear zero byte */
getb();
/* read checksum contents into buffer */
for (i = 0; i < Count; i++)
Buff[i] = getb();
/* read checksum */
getb();
if (sum % 0400 != 0)
inerror("Checksum error, reassemble");
/* clear zero trailer byte if Count even */
if (Count % 2 == 0)
getb();
/* set pointer to next character to be read */
Next = Buff;
return (Type);
}
/************************* getb ***************************************/
getb() /* get a byte from input file, add to "sum" */
/* check for EOF, return the byte */
{
register int k;
sum += (k = getc(Fp));
if (k == EOF)
No_code = 1;
return (0377 & k);
}