/* Re-coding of advent in C: file i/o and user i/o */
static char sccsid
[] = " io.c 4.1 82/05/11 ";
getin(wrd1
,wrd2
) /* get command from user */
char **wrd1
,**wrd2
; /* no prompt, usually */
static char wd1buf
[MAXSTR
],wd2buf
[MAXSTR
];
*wrd1
=wd1buf
; /* return ptr to internal string*/
wd2buf
[0]=0; /* in case it isn't set here */
for (s
=wd1buf
, first
=1, numch
=0;;)
{ if ((*s
=getchar())>='A' && *s
<='Z') *s
= *s
- ('A' -'a');
/* convert to upper case */
switch(*s
) /* start reading from user */
if (s
==wd1buf
||s
==wd2buf
) /* initial blank */
if (first
) /* finished 1st wd; start 2nd */
else /* finished 2nd word */
if (++numch
>=MAXSTR
) /* string too long */
{ printf("Give me a break!!\n");
confirm(mesg
) /* confirm irreversible action */
printf("%s",mesg
); /* tell him what he did */
if (getchar()=='y') /* was his first letter a 'y'? */
yes(x
,y
,z
) /* confirm with rspeak */
{ rspeak(x
); /* tell him what we want*/
else if (ch
=='n') result
=FALSE
;
if (ch
=='y'|| ch
=='n') break;
printf("Please answer the question.\n");
if (result
==TRUE
) rspeak(y
);
if (result
==FALSE
) rspeak(z
);
yesm(x
,y
,z
) /* confirm with mspeak */
{ mspeak(x
); /* tell him what we want*/
else if (ch
=='n') result
=FALSE
;
if (ch
=='y'|| ch
=='n') break;
printf("Please answer the question.\n");
if (result
==TRUE
) mspeak(y
);
if (result
==FALSE
) mspeak(z
);
int adrptr
; /* current seek adr ptr */
int outsw
= 0; /* putting stuff to data file? */
char iotape
[] = "Ax3F'tt$8hqer*hnGKrX:!l";
char *tape
= iotape
; /* pointer to encryption tape */
next() /* next char frm file, bump adr */
adrptr
++; /* seek address in file */
if (outsw
) /* putting data in tmp file */
{ if (*tape
==0) tape
=iotape
; /* rewind encryption tape */
putc(ch
^ *tape
++,outbuf
); /* encrypt & output char */
char breakch
; /* tell which char ended rnum */
rdata() /* read all data from orig file */
if ((inbuf
=fopen(DATFILE
,"r"))==NULL
) /* all the data lives in here */
{ printf("Cannot open data file %s\n",DATFILE
);
if ((outbuf
=fopen(TMPFILE
,"w"))==NULL
) /* the text lines will go here */
{ printf("Cannot create output file %s\n",TMPFILE
);
for (;;) /* read data sections */
{ sect
=next()-'0'; /* 1st digit of section number */
printf("Section %c",sect
+'0');
if ((ch
=next())!=LF
) /* is there a second digit? */
{ case 0: /* finished reading database */
case 1: /* long form descriptions */
case 2: /* short form descriptions */
case 3: /* travel table */
case 5: /* object descriptions */
case 6: /* arbitrary messages */
case 7: /* object locations */
case 8: /* action defaults */
case 9: /* liquid assets */
case 10: /* class messages */
case 12: /* magic messages */
printf("Invalid data section number: %d\n",sect
);
for (;;) putchar(next());
if (breakch
!=LF
) /* routines return after "-1" */
rnum() /* read initial location num */
tape
= iotape
; /* restart encryption tape */
if ((*s
=next())==TAB
|| *s
=='\n' || *s
==LF
)
breakch
= *s
; /* save char for rtrav() */
*s
=0; /* got the number as ascii */
if (nbf
[0]=='-') return(-1); /* end of data */
return(atoi(nbf
)); /* convert it to integer */
int seekhere
= 1; /* initial seek for output file */
rdesc(sect
) /* read description-format msgs */
int seekstart
, maystart
, adrstart
;
outsw
=1; /* these msgs go into tmp file */
if (sect
==1) putc('X',outbuf
); /* so seekadr > 0 */
for (oldloc
= -1, seekstart
=seekhere
;;)
{ maystart
=adrptr
; /* maybe starting new entry */
if ((locc
=rnum())!=oldloc
&& oldloc
>=0 /* finished msg */
&& ! (sect
==5 && (locc
==0 || locc
>=100)))/* unless sect 5*/
{ switch(sect
) /* now put it into right table */
{ case 1: /* long descriptions */
ltext
[oldloc
].seekadr
=seekhere
;
ltext
[oldloc
].txtlen
=maystart
-seekstart
;
case 2: /* short descriptions */
stext
[oldloc
].seekadr
=seekhere
;
stext
[oldloc
].txtlen
=maystart
-seekstart
;
case 5: /* object descriptions */
ptext
[oldloc
].seekadr
=seekhere
;
ptext
[oldloc
].txtlen
=maystart
-seekstart
;
case 6: /* random messages */
{ printf("Too many random msgs\n");
rtext
[oldloc
].seekadr
=seekhere
;
rtext
[oldloc
].txtlen
=maystart
-seekstart
;
case 10: /* class messages */
ctext
[clsses
].seekadr
=seekhere
;
ctext
[clsses
].txtlen
=maystart
-seekstart
;
case 12: /* magic messages */
{ printf("Too many magic msgs\n");
mtext
[oldloc
].seekadr
=seekhere
;
mtext
[oldloc
].txtlen
=maystart
-seekstart
;
printf("rdesc called with bad section\n");
seekhere
+= maystart
-seekstart
;
{ outsw
=0; /* turn off output */
seekhere
+= 3; /* -1<delimiter> */
if (sect
!=5 || (locc
>0 && locc
<100))
{ if (oldloc
!=locc
)/* starting a new message */
FLUSHLF
; /* scan the line */
rtrav() /* read travel table */
register struct travlist
*t
;
for (oldloc
= -1;;) /* get another line */
{ if ((locc
=rnum())!=oldloc
&& oldloc
>=0) /* end of entry */
t
->next
= 0; /* terminate the old entry */
/* printf("%d:%d entries\n",oldloc,entries); */
if (locc
!=oldloc
) /* getting a new entry */
{ t
=travel
[locc
]=(struct travlist
*) malloc(sizeof (struct travlist
));
/* printf("New travel list for %d\n",locc); */
for (s
=buf
;; *s
++) /* get the newloc number /ASCII */
if ((*s
=next())==TAB
|| *s
==LF
) break;
len
=length(buf
)-1; /* quad long number handling */
/* printf("Newloc: %s (%d chars)\n",buf,len); */
if (len
<4) /* no "m" conditions */
n
=atoi(buf
); /* newloc mod 1000 = newloc */
else /* a long integer */
buf
[len
-3]=0; /* terminate newloc/1000 */
while (breakch
!=LF
) /* only do one line at a time */
{ if (entries
++) t
=t
->next
=(struct travlist
*) malloc(sizeof (struct travlist
));
t
->tverb
=rnum();/* get verb from the file */
t
->tloc
=n
; /* table entry mod 1000 */
t
->conditions
=m
;/* table entry / 1000 */
/* printf("entry %d for %d\n",entries,locc); */
twrite(loq
) /* travel options from this loc */
{ register struct travlist
*t
;
for (t
=travel
[loq
]; t
!=0; t
=t
->next
)
{ printf("verb %d takes you to ",t
->tverb
);
printf("special code %d\n",t
->tloc
-300);
printf("under conditions %d\n",t
->conditions
);
{ register char *s
; /* read the vocabulary */
for (s
=buf
,*s
=0;; s
++) /* get the word */
if ((*s
=next())==TAB
|| *s
=='\n' || *s
==LF
/* terminate word with newline, LF, tab, blank */
if (*s
!='\n' && *s
!=LF
) FLUSHLF
; /* can be comments */
/* printf("\"%s\"=%d\n",buf,index);*/
rlocs() /* initial object locations */
{ if ((obj
=rnum())<0) break;
plac
[obj
]=rnum(); /* initial loc for this obj */
if (breakch
==TAB
) /* there's another entry */
rdflt() /* default verb messages */
{ if ((verb
=rnum())<0) break;
rliq() /* liquid assets &c: cond bits */
for (;;) /* read new bit list */
{ if ((bitnum
=rnum())<0) break;
for (;;) /* read locs for bits */
{ cond
[rnum()] |= setbit
[bitnum
];
{ register int hintnum
,i
;
{ if ((hintnum
=rnum())<0) break;
hints
[hintnum
][i
]=rnum();
if (hintnum
>hntmax
) hntmax
=hintnum
;
{ if (msg
!=0) speak(&rtext
[msg
]);
{ if (msg
!=0) speak(&mtext
[msg
]);
doseek(offset
) /* do 2 seeks to get to right place in the file */
extern unsigned filesize
;
lseek(datfd
,(long)offset
+(long)filesize
, 0);
if (offset
<0) /* right place is offset+filesize*/
{ blockadr
+= 64; /* take off 32768 bytes */
chadr
+= offset
+32768; /* & make them into 64 blocks */
if (filesize
<0) /* data starts after file */
{ blockadr
+= 64; /* which may also be large */
if (chadr
<0) /* and the leftovers may be lge */
seek(datfd
,blockadr
,3); /* get within 32767 */
seek(datfd
,chadr
,1); /* then the rest of the way */
speak(msg
) /* read, decrypt, and print a message (not ptext) */
struct text
*msg
;/* msg is a pointer to seek address and length of mess */
{ register char *s
,nonfirst
;
if ((tbuf
=(char *) malloc(msg
->txtlen
+1))<0) bug(109);
read(datfd
,tbuf
,msg
->txtlen
);
while (s
-tbuf
<msg
->txtlen
) /* read a line at a time */
{ tape
=iotape
; /* restart decryption tape */
while ((*s
++^*tape
++)!=TAB
); /* read past loc num */
/* assume tape is longer than location number */
/* plus the lookahead put together */
(*(s
+1)^*(tape
+1))=='$' &&
(*(s
+2)^*(tape
+2))=='<') break;
if (blklin
&&!nonfirst
++) putchar('\n');
{ if (*tape
==0) tape
=iotape
;/* rewind decryp tape */
} while ((*s
++^*tape
++)!=LF
); /* better end with LF */
pspeak(msg
,skip
) /* read, decrypt an print a ptext message */
int msg
; /* msg is the number of all the p msgs for this place */
int skip
; /* assumes object 1 doesn't have prop 1, obj 2 no prop 2 &c*/
{ register char *s
,nonfirst
;
doseek(ptext
[msg
].seekadr
);
if ((tbuf
=(char *) malloc((lstr
=ptext
[msg
].txtlen
)+1))<0) bug(108);
while (s
-tbuf
<lstr
) /* read a line at a time */
{ tape
=iotape
; /* restart decryption tape */
for (numst
=s
; (*s
^= *tape
++)!=TAB
; s
++); /* get number */
*s
++=0; /* decrypting number within the string */
if (atoi(numst
)!=100*skip
&& skip
>=0)
{ while ((*s
++^*tape
++)!=LF
) /* flush the line */
if (*tape
==0) tape
=iotape
;
if ((*s
^*tape
)=='>' && (*(s
+1)^*(tape
+1))=='$' &&
(*(s
+2)^*(tape
+2))=='<') break;
if (blklin
&& ! nonfirst
++) putchar('\n');
{ if (*tape
==0) tape
=iotape
;
} while ((*s
++^*tape
++)!=LF
); /* better end with LF */