#define	rsts	1
#include <stdio.h>
#include <rsts.h>

extern FILE *$$flun();
extern FILE *$$open();
 
FILE *
fopen(name, mode)
char *name, *mode;
{
    FILE *fp;

    if (!(fp = $$flun())) {
	return(NULL);
    }
    return($$open(name, mode, fp));
}


FILE *
$$flun()
{
    register int i;
    FILE *fp;

    for (i = 0; i < MAXLUN; i++) {
	if (!($$luns[i])) {
	    if (!(fp = malloc(sizeof(FILE)))) {
		$$ferr = NOBUFS;
		return(NULL);
	    }
	    else {
		zero(fp, sizeof(FILE));
		fp->io_lun = i+1;
		fp->io_bptr = fp->io_bbuf;
		return($$luns[i] = fp);
	    }
	}
    }
    $$ferr = NOROOM;
    return(NULL);
}

extern FILE *$dopen();

FILE *
$$open(name, mode, fp)
char *name, *mode;
FILE *fp;
{
    register char c, omode;
    int cmode;

    cmode = 0;
    while (c = *mode++) {
	switch (c) {
	case 'w':
	    omode = 'w';
	    fp->io_flag |= 1;
	    cmode++;
	    break;
	case 'r':
	    omode = 'r';
	    fp->io_bnbr = 1;
	    cmode++;
	    break;
	case 'a':
	    omode = 'a';
	    fp->io_flag |= 2;
	    cmode++;
	    break;
	case 'n':
	    fp->io_flag |= IO_NOS;
	case 'u':
	    break;
	default:
	    $$fero(BADFUO, fp);
	    return(NULL);
	}
    }
    if (cmode != 1) {
	$$fero(BADFUO, fp);
	return(NULL);
    }
    if (!(fp->io_name = malloc(strlen(name)+1))) {
	$$fero(NOBUFS, fp);
	return(NULL);
    }
    strcpy(fp->io_name, name);
    return($dopen(name, omode, fp));
}

FILE *
$dopen(name, omode, fp)
char *name;
char omode;
FILE *fp;
{

retry:
    clrfqx();
    xrb.xrlen	= strlen(name);	/* Length of the file name	*/
    xrb.xrbc	= xrb.xrlen;	/* Another copy of the length	*/
    xrb.xrloc	= name;		/* Name starting address	*/
    if (rstsys(_FSS)) {
	$$fero($$ferr, fp);
	return(NULL);
    }
    firqb.fqfil	= (fp->io_lun) * 2;
    if (omode == 'w') {
	firqb.fqfun = CREFQ;
    }
    else {
	firqb.fqfun = OPNFQ;
	if (((xrb.xrmod & 0377) == DSKHND) && !firqb.fqmode) {
	    firqb.fqmode = 0100002;
	}
    }
    $$ferr = rstsys(CALFIP);
    if (omode == 'a' && $$ferr == NOSUCH) {
	omode = 'w';
	goto retry;
    }
    if ($$ferr) {
	$$fero($$ferr, fp);
	return(NULL);
    }
    else {
	if (firqb.fqflag & FLGFRC) {
	    fp->io_flag |= IO_REC;
	}
	if ((firqb.fqflag & 0377) == TTYHND) {
	    fp->io_flag |= IO_TTY;
	}
	if (firqb.fqflag & FLGRND) {
	    fp->io_bnbr = 1;
	    fp->io_flag |= IO_FIL;
	    if (omode == 'a') {
		fp->io_bnbr = firqb.fqsiz + 1;
	    }
	}
        if (fp->io_bbuf)
            free(fp->io_bbuf);
        if ((fp->io_bbuf = malloc(fp->io_bsiz = firqb.fqbufl)) == NULL) {
            clrfqb();
            firqb.fqfun = RSTFQ;
            firqb.fqfil = (fp->io_lun) * 2;
            rstsys(CALFIP);
            $$fero(NOBUFS, fp);
            fp->io_flag = 0;
            return(NULL);
        }
	fp->io_flag |= IO_OPN;
	return(fp);
    }
}

$$fero(error, fp)
int error;
FILE *fp;
{
    char *stp;

    $$ferr = error;
    if (fp) {
        if (stp = fp->io_name)
            free(stp);
        if (fp->io_bbuf)
            free(fp->io_bbuf);
        $$luns[fp->io_lun - 1] = 0;
        free(fp);
    }
}
