Пример #1
0
static void _make_roots_arrays(void) {
/*======================================================*/
  int size;
  char *fstr = "_make_roots_array()";

  size  = SXW.NGrps * SXW.NTrLyrs;
  _roots_max     = (RealD *) Mem_Calloc(size, sizeof(RealD), fstr);

  size = SXW.NGrps * SXW.NPds * SXW.NTrLyrs;
  _rootsXphen       = (RealD *) Mem_Calloc(size, sizeof(RealD), fstr);
  _roots_active     = (RealD *) Mem_Calloc(size, sizeof(RealD), fstr);
  _roots_active_rel = (RealD *) Mem_Calloc(size, sizeof(RealD), fstr);

  size = SXW.NPds * SXW.NTrLyrs;
  _roots_active_sum = (RealD *) Mem_Calloc(size, sizeof(RealD), fstr);
}
Пример #2
0
bool kexBinFile::Open(const char *file, kexHeapBlock &heapBlock) {
    FILE *fp;

    if((fp = fopen(file, "rb"))) {
        size_t length;

        fseek(fp, 0, SEEK_END);
        length = ftell(fp);
        fseek(fp, 0, SEEK_SET);

        buffer = (byte*)Mem_Calloc(length+1, heapBlock);

        if(fread(buffer, 1, length, fp) == length) {
            fclose(fp);
            if(length > 0) {
                bOpened = true;
                bufferOffset = 0;
                return true;
            }
        }
        
        Mem_Free(buffer);
        buffer = NULL;
        fclose(fp);
   }

    return false;
}
void SW_VES_read(void) {
    /* =================================================== */

    FILE *f;
    IntU i;

    MyFileName = SW_F_name(eVegEstab);
    f = OpenFile(MyFileName, "r");
    SW_VegEstab.use = TRUE;

    /* if data file empty or useflag=0, assume no
    * establishment checks and just continue the model run. */
    if (!GetALine(f, inbuf) || *inbuf == '0' ) {
        SW_VegEstab.use = FALSE;
        if (EchoInits)
            LogError(logfp, LOGNOTE, "Establishment not used.\n");
        return;
    }
    while(GetALine(f, inbuf) ) {
        _read_spp(inbuf);
    }
    CloseFile(&f);

    for (i=0; i < SW_VegEstab.count; i++)
        _spp_init(i);

    if ( SW_VegEstab.count > 0)
        SW_VegEstab.yrsum.days = (TimeInt *)
                                 Mem_Calloc(SW_VegEstab.count,
                                            sizeof(TimeInt),
                                            "SW_VES_read()");
    if (EchoInits) _echo_inits();
}
Пример #4
0
unsigned int _new_species(void) {
	/* --------------------------------------------------- */
	/* first time called with no species defined so
	 SW_VegEstab.count==0 and SW_VegEstab.parms is
	 not initialized yet, malloc() required.  For each
	 species thereafter realloc() is called.
	 */
	const char *me = "SW_VegEstab_newspecies()";
	SW_VEGESTAB *v = &SW_VegEstab;

	v->parms =
			(!v->count) ?
					(SW_VEGESTAB_INFO **) Mem_Calloc(v->count + 1, sizeof(SW_VEGESTAB_INFO *), me) :
					(SW_VEGESTAB_INFO **) Mem_ReAlloc(v->parms, sizeof(SW_VEGESTAB_INFO *) * (v->count + 1));
	v->parms[v->count] = (SW_VEGESTAB_INFO *) Mem_Calloc(1, sizeof(SW_VEGESTAB_INFO), me);

	return (++v->count) - 1;
}
Пример #5
0
static void _make_phen_arrays(void) {
/*======================================================*/
  int size;
  char *fstr = "_make_phen_arrays()";

  size = SXW.NGrps * MAX_MONTHS;
  _phen = (RealD *) Mem_Calloc(size, sizeof(RealD), fstr);

}
Пример #6
0
void Init_SW_VegEstab(void)
{
	IntU i;

	for (i = 0; i < SW_VegEstab.count; i++)
		_spp_init(i);

	if (SW_VegEstab.count > 0) {
		SW_VegEstab.p_accu[eSW_Year]->days = (TimeInt *) Mem_Calloc(
			SW_VegEstab.count, sizeof(TimeInt), "Init_SW_VegEstab()");
	}
}
Пример #7
0
static void _make_swc_array(void) {
/*======================================================*/
/* SXW.swc holds year-to-year values and is populated in SOILWAT.
 * it is indexed by the macro Ilp(). only used if soilwat option
 * specified with debugfile
 */
  char *fstr = "_make_swc_array()";
  int size = SXW.NPds * SXW.NSoLyrs;
  SXW.swc   = (RealF *) Mem_Calloc( size, sizeof(RealF *), fstr);


}
Пример #8
0
void SW_VES_construct(void) {
	/* =================================================== */
	/* note that an initializer that is called during
	 * execution (better called clean() or something)
	 * will need to free all allocated memory first
	 * before clearing structure.
	 */
	OutPeriod pd;

	// Clear the module structure:
	memset(&SW_VegEstab, 0, sizeof(SW_VegEstab));

	// Allocate output structures:
	ForEachOutPeriod(pd)
	{
		SW_VegEstab.p_accu[pd] = (SW_VEGESTAB_OUTPUTS *) Mem_Calloc(1,
			sizeof(SW_VEGESTAB_OUTPUTS), "SW_VES_construct()");
		if (pd > eSW_Day) {
			SW_VegEstab.p_oagg[pd] = (SW_VEGESTAB_OUTPUTS *) Mem_Calloc(1,
				sizeof(SW_VEGESTAB_OUTPUTS), "SW_VES_construct()");
		}
	}
}
Пример #9
0
static void _make_transp_arrays(void) {
/*======================================================*/
/* SXW.transp holds year-to-year values and is populated in SOILWAT.
 * _transp_base holds the "normal" values and is read from a file.
 * both are indexed by the macro Ilp().
 */
  char *fstr = "_make_transp_array()";
  int size;

  size = SXW.NPds * SXW.NTrLyrs;
  SXW.transp   = (RealD *) Mem_Calloc( size, sizeof(RealD), fstr);


}
Пример #10
0
/* <83669> ../engine/r_studio.c:663 */
mstudioanim_t *R_GetAnim(model_t *psubmodel, mstudioseqdesc_t *pseqdesc)
{
	mstudioseqgroup_t *pseqgroup;
	cache_user_t *paSequences;

	pseqgroup = (mstudioseqgroup_t *)((char *)pstudiohdr + pstudiohdr->seqgroupindex);
	pseqgroup += pseqdesc->seqgroup;
	if (!pseqdesc->seqgroup)
		return (mstudioanim_t *)((char *)pstudiohdr + pseqdesc->animindex);

	paSequences = (cache_user_t *)psubmodel->submodels;
	if (!paSequences)
	{
		paSequences = (cache_user_t *)Mem_Calloc(16, 4);
		psubmodel->submodels = (dmodel_t *)paSequences;
	}
	if (!Cache_Check(&paSequences[pseqdesc->seqgroup]))
	{
		Con_DPrintf("loading %s\n", pseqgroup->name);
		COM_LoadCacheFile(pseqgroup->name, &paSequences[pseqdesc->seqgroup]);
	}

	return (mstudioanim_t *)((char *)paSequences[pseqdesc->seqgroup].data + pseqdesc->animindex);
}
Пример #11
0
void *kexObject::operator new(size_t s) {
    return Mem_Calloc(s, hb_object);
}
Пример #12
0
void SW_WTH_read(void) {
/* =================================================== */
SW_WEATHER *w = &SW_Weather;
const int nitems=18;
FILE *f;
int lineno=0, month, x;
RealF sppt,stmax,stmin;

MyFileName = SW_F_name(eWeather);
f = OpenFile(MyFileName, "r");

while( GetALine(f,inbuf) ) {

	switch(lineno) {
		case 0:  w->use_snow = itob(atoi(inbuf));         	break;
		case 1:  w->pct_snowdrift = atoi(inbuf);		  	break;
		case 2:  w->pct_runoff = atoi(inbuf);				break;
		case 3:  w->use_markov = itob(atoi(inbuf));       	break;
		case 4:  w->yr.first = YearTo4Digit(atoi(inbuf));	break;
		case 5:  w->days_in_runavg = atoi(inbuf);
					runavg_list = (RealD *) Mem_Calloc(w->days_in_runavg, sizeof(RealD), "SW_WTH_read()");
															break;
		default:
			if (lineno == 6 + MAX_MONTHS) break;

			x = sscanf(inbuf, "%d %f %f %f", &month, &sppt, &stmax, &stmin);
			if (x < 4) {
				LogError(logfp, LOGFATAL, "%s : Bad record %d.", MyFileName, lineno);
			}

			w->scale_precip[month-1] = sppt;
			w->scale_temp_max[month-1] = stmax;
			w->scale_temp_min[month-1] = stmin;
	}
	
	lineno++;
}

SW_WeatherPrefix(w->name_prefix);

CloseFile(&f);

if (lineno < nitems-1) {
	LogError(logfp, LOGFATAL, "%s : Too few input lines.",MyFileName);
}

w->yr.last = SW_Model.endyr;
w->yr.total = w->yr.last - w->yr.first +1;



if (w->use_markov) {
	SW_MKV_construct();

	if (!SW_MKV_read_prob()) {
		LogError(logfp, LOGFATAL, "%s: Markov weather requested but could not open %s",
		MyFileName, SW_F_name(eMarkovProb));
	}

	if (!SW_MKV_read_cov()) {
		LogError(logfp, LOGFATAL, "%s: Markov weather requested but could not open %s",
		MyFileName, SW_F_name(eMarkovCov));
	}

	} else if (SW_Model.startyr < w->yr.first) {
		LogError(logfp, LOGFATAL,
		"%s : Model year (%d) starts before weather files (%d)"
		" and use_Markov=FALSE.\nPlease synchronize the years"
		" or set up the Markov weather files",
		MyFileName, SW_Model.startyr, w->yr.first);
	}
/* else we assume weather files match model run years */

/* required for PET */
SW_SKY_read();
SW_SKY_init();

}
Пример #13
0
enum auth_stat
Gssrpc__svcauth_gss(struct svc_req *rqst, struct rpc_msg *msg, bool_t * no_dispatch)
{
  enum auth_stat retstat;
  XDR xdrs;
  SVCAUTH *auth;
  struct svc_rpc_gss_data *gd;
  struct rpc_gss_cred *gc;
  struct rpc_gss_init_res gr;
  int call_stat, offset;
  OM_uint32 min_stat;
  gss_union_ctx_id_desc *gss_ctx_data;
  char ctx_str[64];

  /* Used to update the hashtable entries. 
   * These should not be used for purposes other than updating
   * hashtable entries. */
  bool_t *p_established = NULL;
  u_int *p_seqlast = NULL;
  uint32_t *p_seqmask = NULL;

  /* Initialize reply. */
  LogFullDebug(COMPONENT_RPCSEC_GSS, "Gssrpc__svcauth_gss called");

  /* Allocate and set up server auth handle. */
  if(rqst->rq_xprt->xp_auth == NULL || rqst->rq_xprt->xp_auth == &Svc_auth_none)
    {
      if((auth = (SVCAUTH *)Mem_Calloc(1, sizeof(*auth))) == NULL)
        {
          LogCrit(COMPONENT_RPCSEC_GSS, "svcauth_gss: out_of_memory");
          return (AUTH_FAILED);
        }
      if((gd = (struct svc_rpc_gss_data *)Mem_Calloc(1, sizeof(*gd))) == NULL)
        {
          LogCrit(COMPONENT_RPCSEC_GSS, "svcauth_gss: out_of_memory");
          Mem_Free(auth);
          return (AUTH_FAILED);
        }
      auth->svc_ah_ops = &Svc_auth_gss_ops;
      auth->svc_ah_private = (void *)gd;
      rqst->rq_xprt->xp_auth = auth;
    }
  else
    gd = SVCAUTH_PRIVATE(rqst->rq_xprt->xp_auth);

  /* Deserialize client credentials. */
  if(rqst->rq_cred.oa_length <= 0)
    return (AUTH_BADCRED);

  gc = (struct rpc_gss_cred *)rqst->rq_clntcred;
  memset(gc, 0, sizeof(*gc));

  xdrmem_create(&xdrs, rqst->rq_cred.oa_base, rqst->rq_cred.oa_length, XDR_DECODE);

  if(!xdr_rpc_gss_cred(&xdrs, gc))
    {
      XDR_DESTROY(&xdrs);
      return (AUTH_BADCRED);
    }
  XDR_DESTROY(&xdrs);

  if(gc->gc_ctx.length != 0)
    gss_ctx_data = (gss_union_ctx_id_desc *)(gc->gc_ctx.value);
  else
    gss_ctx_data = NULL;

  if(isFullDebug(COMPONENT_RPCSEC_GSS))
    {
      sprint_ctx(ctx_str, (char *)gc->gc_ctx.value, gc->gc_ctx.length);
      LogFullDebug(COMPONENT_RPCSEC_GSS,
                   "Gssrpc__svcauth_gss gc_proc (%u) %s context %s",
                   gc->gc_proc, str_gc_proc(gc->gc_proc), ctx_str);
    }

  /* If we do not retrieve gss data from the cache, then this important
   * variables could not possibly be meaningful. */
  gd->seqlast = 0;
  gd->seqmask = 0;
  gd->established = 0;

  /** @todo Think about restoring the correct lines */
  //if( gd->established == 0 && gc->gc_proc == RPCSEC_GSS_DATA   )
  if(gc->gc_proc == RPCSEC_GSS_DATA || gc->gc_proc == RPCSEC_GSS_DESTROY)
    {
      if(isFullDebug(COMPONENT_RPCSEC_GSS))
        {
          LogFullDebug(COMPONENT_RPCSEC_GSS,
                       "Dump context hash table");
          Gss_ctx_Hash_Print();
        }
      
      LogFullDebug(COMPONENT_RPCSEC_GSS, "Getting gss data struct from hashtable.");
      
      /* Fill in svc_rpc_gss_data from cache */
      if(!Gss_ctx_Hash_Get(gss_ctx_data,
			   gd,
			   &p_established,
			   &p_seqlast,
			   &p_seqmask))
	{
          LogCrit(COMPONENT_RPCSEC_GSS, "Could not find gss context ");
          ret_freegc(AUTH_REJECTEDCRED);
        }
      else
        {
          /* If you 'mount -o sec=krb5i' you will have gc->gc_proc > RPCSEC_GSS_SVN_NONE, but the
           * negociation will have been made as if option was -o sec=krb5, the value of sec.svc has to be updated
           * id the stored gd that we got fromn the hash */
          if(gc->gc_svc != gd->sec.svc)
            gd->sec.svc = gc->gc_svc;
        }
    }

  if(isFullDebug(COMPONENT_RPCSEC_GSS))
    {
      char ctx_str_2[64];

      sprint_ctx(ctx_str_2, (unsigned char *)gd->ctx, sizeof(gss_ctx_data));
      sprint_ctx(ctx_str, (unsigned char *)gc->gc_ctx.value, gc->gc_ctx.length);

      LogFullDebug(COMPONENT_RPCSEC_GSS,
                   "Call to Gssrpc__svcauth_gss ----> Client=%s length=%lu (GD: established=%u ctx=%s) (RQ:sock=%u) (GC: Proc=%u Svc=%u ctx=%s)",
                   (char *)gd->cname.value,
                   (long unsigned int)gd->cname.length,
                   gd->established,
                   ctx_str_2,
                   rqst->rq_xprt->XP_SOCK,
                   gc->gc_proc,
                   gc->gc_svc,
                   ctx_str);
    }

  retstat = AUTH_FAILED;

  /* Check version. */
  if(gc->gc_v != RPCSEC_GSS_VERSION)
    {
      LogDebug(COMPONENT_RPCSEC_GSS, "BAD AUTH: bad GSS version.");
      ret_freegc(AUTH_BADCRED);
    }

  /* Check RPCSEC_GSS service. */
  if(gc->gc_svc != RPCSEC_GSS_SVC_NONE &&
     gc->gc_svc != RPCSEC_GSS_SVC_INTEGRITY && gc->gc_svc != RPCSEC_GSS_SVC_PRIVACY)
    {
      LogDebug(COMPONENT_RPCSEC_GSS, "BAD AUTH: bad GSS service (krb5, krb5i, krb5p)");
      ret_freegc(AUTH_BADCRED);
    }

  /* Check sequence number. */
  if(gd->established)
    {
      /* Sequence should be less than the max sequence number */
      if(gc->gc_seq > MAXSEQ)
	{
	  LogDebug(COMPONENT_RPCSEC_GSS, "BAD AUTH: max sequence number exceeded.");
	  ret_freegc(RPCSEC_GSS_CTXPROBLEM);
	}

      /* Check the difference between the current sequence number 
       * and the last sequence number. */
      LogFullDebug(COMPONENT_RPCSEC_GSS, "seqlast: %d  seqnum: %d offset: %d seqwin: %d seqmask: %x",
		   gd->seqlast, gc->gc_seq, gd->seqlast - gc->gc_seq, gd->win, gd->seqmask);

      if((offset = gd->seqlast - gc->gc_seq) < 0)
        {
          gd->seqlast = gc->gc_seq;
          offset = 0 - offset;
          gd->seqmask <<= offset;
          offset = 0;
        }
      else if((unsigned int)offset >= gd->win
              || (gd->seqmask & (1 << (unsigned int)offset)))
        {
	  if ((unsigned int)offset >= gd->win)
	    LogDebug(COMPONENT_RPCSEC_GSS, "BAD AUTH: the current seqnum is lower"
		     " than seqlast by %d and out of the seq window of size %d.", offset, gd->win);
	  else
	    LogDebug(COMPONENT_RPCSEC_GSS, "BAD AUTH: the current seqnum has already been used.");

          *no_dispatch = TRUE;
          ret_freegc(RPCSEC_GSS_CTXPROBLEM);
        }
      gd->seq = gc->gc_seq;
      gd->seqmask |= (1 << offset);
    }

  if(gd->established)
    {
      rqst->rq_clntname = (char *)gd->client_name;
#ifndef _USE_TIRPC
      rqst->rq_svccred = (char *)gd->ctx;
#else
      rqst->rq_svcname = (char *)gd->ctx;
#endif
    }

  /* Handle RPCSEC_GSS control procedure. */
  switch (gc->gc_proc)
    {

    case RPCSEC_GSS_INIT:
      LogFullDebug(COMPONENT_RPCSEC_GSS, "Reached RPCSEC_GSS_INIT:");
    case RPCSEC_GSS_CONTINUE_INIT:
      LogFullDebug(COMPONENT_RPCSEC_GSS, "Reached RPCSEC_GSS_CONTINUE_INIT:");
      if(rqst->rq_proc != NULLPROC)
	{
	  LogFullDebug(COMPONENT_RPCSEC_GSS, "BAD AUTH: request proc != NULL during INIT request");
	  ret_freegc(AUTH_FAILED);        /* XXX ? */
	}

      if(!Svcauth_gss_acquire_cred())
	{
	  LogFullDebug(COMPONENT_RPCSEC_GSS, "BAD AUTH: Can't acquire credentials from RPC request.");
	  ret_freegc(AUTH_FAILED);
	}

      if(!Svcauth_gss_accept_sec_context(rqst, &gr))
	{
	  LogFullDebug(COMPONENT_RPCSEC_GSS, "BAD AUTH: Can't accept the security context.");
	  ret_freegc(AUTH_REJECTEDCRED);
	}

      if(!Svcauth_gss_nextverf(rqst, htonl(gr.gr_win)))
        {
          gss_release_buffer(&min_stat, &gr.gr_token);
          Mem_Free(gr.gr_ctx.value);
	  LogFullDebug(COMPONENT_RPCSEC_GSS, "BAD AUTH: Checksum verification failed");
          ret_freegc(AUTH_FAILED);
        }
      *no_dispatch = TRUE;

      if(isFullDebug(COMPONENT_RPCSEC_GSS))
        {
          sprint_ctx(ctx_str, (unsigned char *)gr.gr_ctx.value, gr.gr_ctx.length);
          LogFullDebug(COMPONENT_RPCSEC_GSS,
                       "Call to Gssrpc__svcauth_gss ----> Client=%s length=%lu (GD: established=%u) (RQ:sock=%u) (GR: maj=%u min=%u ctx=%s)",
                       (char *)gd->cname.value,
                       (long unsigned int)gd->cname.length,
                       gd->established,
                       rqst->rq_xprt->XP_SOCK,
                       gr.gr_major,
                       gr.gr_minor,
                       ctx_str);
        }
      call_stat = svc_sendreply(rqst->rq_xprt, (xdrproc_t)xdr_rpc_gss_init_res, (caddr_t) & gr);

      gss_release_buffer(&min_stat, &gr.gr_token);
      gss_release_buffer(&min_stat, &gd->checksum);
      Mem_Free(gr.gr_ctx.value);

      if(!call_stat)
	{
	  LogFullDebug(COMPONENT_RPCSEC_GSS, "BAD AUTH: svc_sendreply failed.");
	  ret_freegc(AUTH_FAILED);
	}

      if(gr.gr_major == GSS_S_COMPLETE)
        {
          gss_union_ctx_id_desc *gss_ctx_data2 = (gss_union_ctx_id_desc *)gd->ctx;

          gd->established = TRUE;

          /* Keep the gss context in a hash, gr.gr_ctx.value is used as key */
          (void) Gss_ctx_Hash_Set(gss_ctx_data2, gd);
        }

      break;

    case RPCSEC_GSS_DATA:
      LogFullDebug(COMPONENT_RPCSEC_GSS, "Reached RPCSEC_GSS_DATA:");
      if(!Svcauth_gss_validate(rqst, gd, msg))
	{
	  LogFullDebug(COMPONENT_RPCSEC_GSS, "BAD AUTH: Couldn't validate request.");
	  ret_freegc(RPCSEC_GSS_CREDPROBLEM);
	}

      if(!Svcauth_gss_nextverf(rqst, htonl(gc->gc_seq)))
	{
	  LogFullDebug(COMPONENT_RPCSEC_GSS, "BAD AUTH: Checksum verification failed.");
	  ret_freegc(AUTH_FAILED);
	}

      /* Update a few important values in the hashtable entry */
      if ( p_established != NULL)
	*p_established = gd->established;
      if ( p_seqlast != NULL)
	*p_seqlast = gd->seqlast;
      if (p_seqmask != NULL)
	*p_seqmask = gd->seqmask;

      break;

    case RPCSEC_GSS_DESTROY:
      LogFullDebug(COMPONENT_RPCSEC_GSS, "Reached RPCSEC_GSS_DESTROY:");
      if(rqst->rq_proc != NULLPROC)
        ret_freegc(AUTH_FAILED);        /* XXX ? */

      if(!Svcauth_gss_validate(rqst, gd, msg))
        ret_freegc(RPCSEC_GSS_CREDPROBLEM);

      if(!Svcauth_gss_nextverf(rqst, htonl(gc->gc_seq)))
	{
	  LogFullDebug(COMPONENT_RPCSEC_GSS, "BAD AUTH: Checksum verification failed.");
	  ret_freegc(AUTH_FAILED);
	}

      *no_dispatch = TRUE;

      call_stat = svc_sendreply(rqst->rq_xprt, (xdrproc_t)xdr_void, (caddr_t) NULL);

      if(!Gss_ctx_Hash_Del(gss_ctx_data))
        {
          LogCrit(COMPONENT_RPCSEC_GSS,
                  "Could not delete Gss Context from hash");
        }
      else
        LogFullDebug(COMPONENT_RPCSEC_GSS, "Gss_ctx_Hash_Del OK");

      if(!Svcauth_gss_release_cred())
	{
	  LogFullDebug(COMPONENT_RPCSEC_GSS, "BAD AUTH: Failed to release credentials.");
	  ret_freegc(AUTH_FAILED);
	}

      if(rqst->rq_xprt->xp_auth)
        SVCAUTH_DESTROY(rqst->rq_xprt->xp_auth);
      rqst->rq_xprt->xp_auth = &Svc_auth_none;

      break;

    default:
      LogFullDebug(COMPONENT_RPCSEC_GSS, "BAD AUTH: Request is not INIT, INIT_CONTINUE, DATA, OR DESTROY.");
      ret_freegc(AUTH_REJECTEDCRED);
      break;
    }

  LogFullDebug(COMPONENT_RPCSEC_GSS,
               "Call to Gssrpc__svcauth_gss - OK ---> (RQ:sock=%u)",
               rqst->rq_xprt->XP_SOCK);

  retstat = AUTH_OK;
 freegc:
  if(retstat != AUTH_OK)
    LogCrit(COMPONENT_RPCSEC_GSS,
            "Call to Gssrpc__svcauth_gss - FAILED ---> (RQ:sock=%u)",
            rqst->rq_xprt->XP_SOCK);

  xdr_free((xdrproc_t)xdr_rpc_gss_cred, gc);
  return (retstat);
}