#ifndef lint
static char *rcs = "$Header: qmsquery.c,v 1.1 88/01/15 12:19:30 simpson Rel $";
#endif
#include <stdio.h>
#include <signal.h>
#include <setjmp.h>
#include <local/standard.h>
#include "qms.h"

FILE	*_Ifp, *_Ofp;	/* Input and output file pointer */
Boolean	    _FirstChar;
static int	(*OldAlarm)();	/* Saves the old SIGALRM value */
static jmp_buf	Env;

int qmsopen(writefd, readfd)
int writefd, readfd;
{
    int		    timeout();

    if (!(_Ofp = fdopen(writefd, "w")))
	return FALSE;
    if (!(_Ifp = fdopen(readfd, "r")))
	return FALSE;
    setbuffer(_Ifp, (char *)NULL, 0);	    /* Turn off buffering on input */
    OldAlarm = signal(SIGALRM, timeout);
    return TRUE;
}

int qmsclose()
{
    (void)signal(SIGALRM, OldAlarm);
    (void)fclose(_Ofp), (void)fclose(_Ifp);
    return TRUE;
}

int timedgetc(f)
FILE	*f;
{
    int	    c;

    /* The amount of time to wait until we have decided it is EOF is
     * hard to select.  The printer does not always send the status
     * information out of the debugger port upon immediately receiving the
     * ^INFO command.  It will accept the ^INFO command, put it in its
     * buffer, and send the status information when it finally interprets
     * the ^INFO command.  I have seen it take as long as 11 seconds
     * between the time the ^INFO command was sent and the time the status
     * information is sent out the debugger port.  We don't want to wait 11
     * or 15 seconds each time we wish to read data.  We observe that each
     * ^INFO command returns at least one character and that when the ^INFO
     * command is finally interpreted, all the information is sent out to
     * the debugger port very quickly.  Consequently, we can wait a long
     * time before reading the first character, but after reading the
     * subsequent characters we wait a short time.
     */
    if (_FirstChar)
        (void)alarm(300);	/* Wait 5 minutes maximum */
    else
	(void)alarm(3);
    if (setjmp(Env)) {
	(void)alarm(0);
	return EOF;
    }
    c = getc(f);
    (void)alarm(0);
    _FirstChar = FALSE;
    return c;
}

static timeout()
{
    longjmp(Env, TRUE);
}

void qmsmapfree(mapinfo)
struct qmsmap	*mapinfo;
{
    struct qmsmap   *p;

    for (; mapinfo; mapinfo = p) {
	if (mapinfo->data)
	    free(mapinfo->data);
	p = mapinfo->next;
	free((char *)mapinfo);
    }
}

void qmsovlfree(ovlinfo)
struct qmsovl	*ovlinfo;
{
    struct qmsovl   *p;

    for (; ovlinfo; ovlinfo = p) {
	p = ovlinfo->next;
	free((char *)ovlinfo);
    }
}

void qmspfpfree(pfpinfo)
struct qmspfp	*pfpinfo;
{
    struct qmspfp   *p;

    for (; pfpinfo; pfpinfo = p) {
	if (pfpinfo->module)
	    free(pfpinfo->module);
	p = pfpinfo->next;
	free((char *)pfpinfo);
    }
}

void qmsopcfree(opcinfo)
struct qmsopc	*opcinfo;
{
    struct optnode  *p1, *p2;

    for (p1 = opcinfo->OC1; p1; p1 = p2) {
	p2 = p1->next;
	free((char *)p1);
    }
    for (p1 = opcinfo->OC2; p1; p1 = p2) {
	p2 = p1->next;
	free((char *)p1);
    }
    for (p1 = opcinfo->OC3; p1; p1 = p2) {
	p2 = p1->next;
	free((char *)p1);
    }
    for (p1 = opcinfo->OC4; p1; p1 = p2) {
	p2 = p1->next;
	free((char *)p1);
    }
    for (p1 = opcinfo->OC5; p1; p1 = p2) {
	p2 = p1->next;
	free((char *)p1);
    }
}

void qmsfntfree(fntinfo)
struct qmsfnt	*fntinfo;
{
    struct fontnode *p1, *p2;

    for (p1 = fntinfo->rom; p1; p1 = p2) {
	p2 = p1->next;
	free((char *)p1);
    }
    for (p1 = fntinfo->ram; p1; p1 = p2) {
	p2 = p1->next;
	free((char *)p1);
    }
}