File:  [CSRG BSD Unix] / 43BSDReno / contrib / isode-beta / pepsy / fr.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 16:12:56 2018 UTC (8 years, 1 month ago) by root
Branches: MAIN, BSD
CVS tags: HEAD, BSD43reno
BSD 4.3reno

/* fr.c */

#ifndef	lint
static char *rcsid = "$Header: /var/lib/cvsd/repos/CSRG/43BSDReno/contrib/isode-beta/pepsy/fr.c,v 1.1.1.1 2018/04/24 16:12:56 root Exp $";
#endif

/* 
 * $Header: /var/lib/cvsd/repos/CSRG/43BSDReno/contrib/isode-beta/pepsy/fr.c,v 1.1.1.1 2018/04/24 16:12:56 root Exp $
 *
 *
 * $Log: fr.c,v $
 * Revision 1.1.1.1  2018/04/24 16:12:56  root
 * BSD 4.3reno
 *
 * Revision 7.2  90/07/27  08:48:48  mrose
 * update
 * 
 * Revision 7.1  90/07/09  14:52:38  mrose
 * sync
 * 
 * Revision 7.0  90/07/01  19:54:20  mrose
 * *** empty log message ***
 * 
 */

/*
 *				  NOTICE
 *
 *    Acquisition, use, and distribution of this module and related
 *    materials are subject to the restrictions of a license agreement.
 *    Consult the Preface in the User's Manual for the full terms of
 *    this agreement.
 *
 */


/*
 * These routines are the driving routines for freeing of the data
 */
#include	<stdio.h>
#include	"psap.h"
#include	"pepsy.h"


extern tpe *next_tpe();
extern PE pepsylose ();
#define NEXT_TPE(p)	p = next_tpe(p)
#define CHKTAG(mod, p, pe)	ismatch(p, mod, pe->pe_class, pe->pe_id)

/*
 * don't need this fre_f we just generate macros of the form
 * fre_obj(parm, mod->md_dtab[CONST], mod)
 */
#if 0
/*
 * free the data of specified type of the specified module
 */
fre_f(typ, mod, pe, explicit, len, buf, parm)
/* ARGSUSED */
int     typ;			/* which type it is */
modtyp *mod;			/* Module it is from */
PE      pe;
int     explicit;
int    *len;
char  **buf;
char  **parm;
{
    tpe    *p;

    if (typ < 0 || typ >= mod->md_nentries) {
	(void) pepsylose (mod, p, pe, "fre_f:Illegal type %d\n", typ);
	return (NOTOK);
    }

    if (parm == 0)
	return (OK);

    p = mod->md_dtab[typ];
    if (p->pe_type != PE_START) {
	(void) pepsylose (mod, p, pe, "fre_f: missing PE_START\n");
	return (NOTOK);
    }
    fre_obj(parm, p, mod)

    return (OK);
}
#endif

/*
 * free an objects data. Basic algorithm is to walk through it twice
 * first time freeing all the "children" of the data structure - then
 * the second time free the structure itself
 */
fre_obj(parm, p, mod)
modtyp *mod;
tpe    *p;
char   *parm;
{
    char   *malptr = NULL;	/* Have we seen a malloc */

    if (parm == 0)
	return (OK);

    if (p->pe_type != PE_START) {
	(void) pepsylose (mod, p, NULLPE, "fre_obj: missing PE_START\n");
	return (NOTOK);
    }

    for (p++; p->pe_type != PE_END; NEXT_TPE(p)) {

again:
	switch (p->pe_type) {
	case MALLOC:
	    malptr = parm;
	    break;

	case SET_START:
	case SEQ_START:
	    fre_seq(parm, p, mod);
	    break;

	case SETOF_START:
	case SEQOF_START:
	    fre_seqof(parm, p, mod);
	    break;

	case CHOICE_START:
	    fre_choice(parm, p, mod);
	    break;

	case OBJECT:
	case SOBJECT:
	    fre_obj(parm, mod->md_dtab[p->pe_tag], mod);
	    break;

	case SEXTOBJ:
	case EXTOBJ:
	    if (p[1].pe_type != EXTMOD) {
		(void) pepsylose (mod, p, NULLPE, "fre_obj: missing EXTMOD");
		return (NOTOK);
	    }
	    fre_obj(parm, EXT2MOD(mod, (p + 1))->md_dtab[p->pe_tag],
		    EXT2MOD(mod, (p + 1)));
	    break;

	case IMP_OBJ:
	    p++;
	    if (p->pe_type == EXTOBJ || p->pe_type == SEXTOBJ) {
		fre_obj(parm, EXT2MOD(mod, (p + 1))->md_dtab[p->pe_tag],
			EXT2MOD(mod, (p + 1)));
	    } else {
		if (p->pe_type == SOBJECT) {
		    fre_obj(parm, mod->md_dtab[p->pe_tag], mod);
		} else
		    fre_obj(parm, mod->md_dtab[p->pe_tag], mod);
	    }
	    break;

	case INTEGER:
	case BOOLEAN:
	case UCODE:
	case REALTYPE:
	    break;

	case ETAG:
	    p++;
	    goto again;

	default:
	    fre_type(parm, p, mod);
	    break;
	}
    }

    if (malptr)			/* If we saw a malloc free item */
	free(malptr);

    return (OK);
}

/*
 * Handle freeing of single type field. All the more general routines
 * fall back to this so we can put the code to free something just
 * here once and it will handle all the cases else where
 */
static fre_type(parm, p, mod)
char   *parm;
tpe    *p;
modtyp *mod;			/* Module it is from */
{

    if (parm == 0)
	return;

again:
    switch (p->pe_type) {
    case MALLOC:
	break;

    case PE_END:
    case PE_START:
    case UCODE:
	break;

    case DFLT_F:
	p++;
	goto again;

    case ETAG:
	switch (p->pe_ucode) {

	default:
	    p++;
	    fre_type(parm, p, mod);
	}
	break;

    case SEQ_START:
    case SET_START:
	fre_seq(*(char **) (parm + p->pe_ucode), p, mod);
	break;

    case SEQOF_START:
    case SETOF_START:
	fre_seqof(*(char **) (parm + p->pe_ucode), p, mod);
	break;

    case IMP_OBJ:
	p++;
	if (p->pe_type == EXTOBJ || p->pe_type == SEXTOBJ)
	    fre_obj(*(char **) (parm + p->pe_ucode),
		    (EXT2MOD(mod, (p + 1)))->md_dtab[p->pe_tag],
		    EXT2MOD(mod, (p + 1)));
	else if (p->pe_type == SOBJECT) {
	    fre_obj((char *) parm, mod->md_dtab[p->pe_tag], mod);
	} else
	    fre_obj(*(char **) (parm + p->pe_ucode),
		    mod->md_dtab[p->pe_tag], mod);
	break;

    case SOBJECT:
	fre_obj((char *) parm, mod->md_dtab[p->pe_tag], mod);
	break;

    case OBJECT:
	fre_obj(*(char **) (parm + p->pe_ucode),
		mod->md_dtab[p->pe_tag], mod);
	break;

    case CHOICE_START:
	fre_choice(*(char **) (parm + p->pe_ucode), p, mod);
	break;

    case SEXTOBJ:
	if (p[1].pe_type != EXTMOD) {
	    (void) pepsylose (mod, p, NULLPE, "fre_type:missing EXTMOD");
	    return (NOTOK);
	}
	fre_obj(parm, (EXT2MOD(mod, (p + 1)))->md_dtab[p->pe_tag],
		EXT2MOD(mod, (p + 1)));
	break;

    case EXTOBJ:
	if (p[1].pe_type != EXTMOD) {
	    (void) pepsylose (mod, p, NULLPE, "fre_type:missing EXTMOD");
	    return (NOTOK);
	}
	fre_obj(*(char **) (parm + p->pe_ucode),
		(EXT2MOD(mod, (p + 1)))->md_dtab[p->pe_tag],
		EXT2MOD(mod, (p + 1)));
	break;

    case INTEGER:
    case BOOLEAN:
    case T_NULL:
    case REALTYPE:
	break;

    case SANY:
	/*
	 * These tests of the pointer don't appear necessary from the
	 * definition of encoding and decoding but ISODE generates
	 * freeing code that does these checks and ISODE's ps layer
	 * definitely requires it
	 */
	if (parm != NULL)
	    pe_free((PE) parm);
	break;

    case ANY:
	if (*(char **) (parm + p->pe_ucode) != NULL)
	    pe_free(*(PE *) (parm + p->pe_ucode));
	break;

    case SOCTETSTRING:
	if (parm != NULL)
	    qb_free((struct qbuf *) parm);
	break;

    case OCTETSTRING:
	if (*(char **) (parm + p->pe_ucode) != NULL)
	    qb_free(*(struct qbuf **) (parm + p->pe_ucode));
	break;

    case SBITSTRING:
	if (parm != NULL)
	    pe_free((PE) parm);
	break;

    case BITSTRING:
	if (*(char **) (parm + p->pe_ucode) != NULL)
	    pe_free(*(PE *) (parm + p->pe_ucode));
	break;

    case SOBJID:
	if (parm != NULL)
	    oid_free((OID) parm);
	break;

    case OBJID:
	if (*(char **) (parm + p->pe_ucode) != NULL)
	    oid_free(*(OID *) (parm + p->pe_ucode));
	break;

    default:
	(void) pepsylose (mod, p, NULLPE, "fre_type: %d not implemented\n",
	    p->pe_type);
	return (NOTOK);
    }

    return (OK);
}

/*
 * free elements of a sequential type. e.g. sequence or set
 */
static fre_seq(parm, p, mod)
char   *parm;
tpe    *p;
modtyp *mod;			/* Module it is from */
{
    int    *popt = NULL;	/* Pointer to optional field */
    int     optcnt = 0;		/* Number of optionals bits so far */
    char   *malptr = NULL;	/* Have we seen a malloc */


    if (parm == 0)
	return;

    if (p->pe_type != SEQ_START && p->pe_type != SET_START) {
	(void) pepsylose (mod, p, NULLPE, "fre_seq: bad starting item %d\n",
	    p->pe_type);
	return (NOTOK);
    }
    p++;

    if (p->pe_type == DFLT_B)
	p++;

    while (p->pe_type != PE_END) {

	if (ISDTYPE(p) && (OPTIONAL(p) || DEFAULT(p))) {
	    switch (p->pe_type) {
	    case INTEGER:
	    case BOOLEAN:
	    case T_NULL:
	    case REALTYPE:
		if (DEFAULT(p)) {
		    /* ISODE doesn't use bit map for defaults */
		    if (p[1].pe_type == DFLT_B && same(p, p + 1, parm, mod)
			|| p[-1].pe_type == DFLT_F && same(p, p - 1, parm, mod))
			goto next;
		    break;
		}
		if (popt == NULL) {
		    (void) pepsylose (mod, p, NULLPE,
			"fre_seq:illegal table: no bitmap for optionals\n");
		    return (NOTOK);
		}
		if (!TESTBIT(*popt, optcnt++))
		    goto next;	/* Missing so skip */
		break;

	    case ETAG:
		if (!hasdata(parm, p + 1, mod, popt, optcnt))
		    goto next;
		break;

	    case IMP_OBJ:
		if (p[1].pe_type == SOBJECT && parm == NULL
		    || *((char **) (parm + p[1].pe_ucode)) == NULL)
		    goto next;
		break;

	    case SOBJECT:
		if (((char *) parm) == NULL)
		    goto next;
		break;

	    default:
		if (*((char **) (parm + p->pe_ucode)) == NULL)
		    goto next;
		break;
	    }
	}
	switch (p->pe_type) {
	case MALLOC:
	    malptr = parm;
	    break;

	case OPTL:
	    popt = (int *) (parm + p->pe_ucode);
	    break;

	case ETAG:
	    p++;
	    continue;

	case UCODE:
	    break;

	case SET_START:
	case SEQ_START:
	    fre_seq(*(char **) (parm + p->pe_ucode), p, mod);
	    break;

	case SETOF_START:
	case SEQOF_START:
	    fre_seqof(*(char **) (parm + p->pe_ucode), p, mod);
	    break;

	case IMP_OBJ:
	    p++;
	    if (p->pe_type == EXTOBJ || p->pe_type == SEXTOBJ)
		fre_obj(*(char **) (parm + p->pe_ucode),
		     (EXT2MOD(mod, (p + 1)))->md_dtab[p->pe_tag],
			EXT2MOD(mod, (p + 1)));

	    else if (p->pe_type == SOBJECT) {
		fre_obj((char *) parm, mod->md_dtab[p->pe_tag],
			mod);
	    } else
		fre_obj(*(char **) (parm + p->pe_ucode),
			mod->md_dtab[p->pe_tag], mod);
	    break;

	case SOBJECT:
	    fre_obj((char *) parm, mod->md_dtab[p->pe_tag], mod);
	    break;

	case OBJECT:
	    fre_obj(*(char **) (parm + p->pe_ucode),
		    mod->md_dtab[p->pe_tag], mod);
	    break;

	case CHOICE_START:
	    fre_choice(*(char **) (parm + p->pe_ucode), p, mod);
	    break;

	case SEXTOBJ:
	    if (p[1].pe_type != EXTMOD) {
		(void) pepsylose (mod, p, NULLPE, "fre_seq:missing EXTMOD");
		return (NOTOK);
	    }
	    fre_obj(parm, (EXT2MOD(mod, (p + 1)))->md_dtab[p->pe_tag],
		    EXT2MOD(mod, (p + 1)));
	    break;

	case EXTOBJ:
	    if (p[1].pe_type != EXTMOD) {
		(void) pepsylose (mod, p, NULLPE, "fre_seq:missing EXTMOD");
		return (NOTOK);
	    }
	    fre_obj(*(char **) (parm + p->pe_ucode),
		    (EXT2MOD(mod, (p + 1)))->md_dtab[p->pe_tag],
		    EXT2MOD(mod, (p + 1)));
	    break;

	default:
	    fre_type(parm, p, mod);
	    break;
	}

next:
	NEXT_TPE(p);
    }
    if (malptr)			/* If we saw a malloc free item */
	free(malptr);
    
    return (OK);

}

/*
 * free all the fields in a SET OF/SEQUENCE OF type structure. We
 * must follow the linked list until the end
 */
static fre_seqof(parm, p, mod)
char   *parm;
tpe    *p;
modtyp *mod;			/* Module it is from */
{
    tpe    *start;		/* first entry in list */
    char   *oparm;

    if (parm == 0)
	return;

    if (p->pe_type != SEQOF_START && p->pe_type != SETOF_START) {
	(void) pepsylose (mod, p, NULLPE, "fre_seqof: illegal field");
	return (NOTOK);
    }
    for (start = p; (char *) parm != NULL; p = start) {
	p++;

	if (p->pe_type == DFLT_B)
	    p++;

	while (p->pe_type != PE_END) {

	    switch (p->pe_type) {
	    case ETAG:
		p++;
		continue;

	    case UCODE:
		break;

	    case SEQ_START:
	    case SET_START:
		fre_seq(*(char **) (parm + p->pe_ucode), p, mod);
		break;

	    case SEQOF_START:
	    case SETOF_START:
		fre_seqof(*(char **) (parm + p->pe_ucode), p, mod);
		break;

	    case IMP_OBJ:
		p++;
		if (p->pe_type == EXTOBJ || p->pe_type == SEXTOBJ)
		    fre_obj(*(char **) (parm + p->pe_ucode),
		     (EXT2MOD(mod, (p + 1)))->md_dtab[p->pe_tag],
			    EXT2MOD(mod, (p + 1)));

		else if (p->pe_type == SOBJECT) {
		    fre_obj((char *) parm, mod->md_dtab[p->pe_tag], mod);
		} else
		    fre_obj(*(char **) (parm + p->pe_ucode),
			    mod->md_dtab[p->pe_tag], mod);
		break;

	    case SOBJECT:
		fre_obj(parm, mod->md_dtab[p->pe_tag], mod);
		break;

	    case OBJECT:
		fre_obj(*(char **) (parm + p->pe_ucode),
			mod->md_dtab[p->pe_tag], mod);
		break;

	    case CHOICE_START:
		fre_choice(*(char **) (parm + p->pe_ucode), p, mod);
		break;

	    case SEXTOBJ:
		if (p[1].pe_type != EXTMOD) {
		    (void) pepsylose (mod, p, NULLPE,
			"fre_seqof: missing EXTMOD");
		    return (NOTOK);
		}
		fre_obj(parm, (EXT2MOD(mod, (p + 1)))->md_dtab[p->pe_tag],
			EXT2MOD(mod, (p + 1)));
		break;

	    case EXTOBJ:
		if (p[1].pe_type != EXTMOD) {
		    (void) pepsylose (mod, p, NULLPE,
			"fre_seqof: missing EXTMOD");
		    return (NOTOK);
		}
		fre_obj(*(char **) (parm + p->pe_ucode),
		     (EXT2MOD(mod, (p + 1)))->md_dtab[p->pe_tag],
			EXT2MOD(mod, (p + 1)));
		break;

	    default:
		fre_type(parm, p, mod);
		break;
	    }

	    NEXT_TPE(p);
	}
	oparm = parm;
	parm = *(char **) (parm + p->pe_ucode);	/* Any more ? */
	free(oparm);
    }

}

/*
 * free the item of the choice. Use the SCTRL field to determine
 * which item is present and then call the appropriate routine to
 * free it
 */
static fre_choice(parm, p, mod)
char   *parm;
tpe    *p;
modtyp *mod;			/* Module it is from */
{
    int     cnt;
    char   *malptr = NULL;	/* Have we seen a malloc */

    if (parm == 0)
	return;

    if (p->pe_type != CHOICE_START) {
	(void) pepsylose (mod, p, NULLPE,
	    "fre_choice:CHOICE_START missing found %d\n", p->pe_type);
    }
    p++;

    if (p->pe_type == DFLT_B)
	p++;

    if (p->pe_type == MALLOC) {
	malptr = parm;
	p++;
    }
    if (p->pe_type != SCTRL) {
	(void) pepsylose (mod, p, NULLPE,
	    "fre_choice: missing SCTRL information\n");
	return (NOTOK);
    }
    cnt = *(int *) (parm + p->pe_ucode);
    if (cnt != 0)
	cnt--;
    if (cnt < 0) {
	(void) pepsylose (mod, p, NULLPE,"fre_choice:offset negative %d", cnt);
	return (NOTOK);
    }
    for (p++; p->pe_type != PE_END; NEXT_TPE(p)) {
	if (ISDTYPE(p)) {
	    if (cnt == 0) {
		fre_type(parm, p, mod);
		if (malptr)	/* If we saw a malloc free item */
		    free(malptr);
		return;
	    }
	    cnt--;
	}
    }

    (void) pepsylose (mod, p, NULLPE, "fre_choice: no choice taken");
    return (NOTOK);
}

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.