示例#1
0
/*-----------------------------------------------------------------------------------*/
void
ctk_vncserver_appcall(void *state)
{
  static struct vnc_server_state *vs;

  vs = (struct vnc_server_state *)(state);

  if(uip_connected()) {

    /* Since we've just been connected, the state pointer should be
       NULL and we need to allocate a new state object. If we have run
       out of memory for state objects, we'll have to abort the
       connection and return. */
    if(vs == NULL) {
      vs = alloc_state();
      if(vs == NULL) {
	uip_close();
	return;
      }
      tcp_markconn(uip_conn, (void *)vs);
    }
  } else if(uip_closed() || uip_aborted()) {
    if(vs != NULL) {
      dealloc_state(vs);
    }
    return;
  }
  vnc_server_appcall(vs);
}
示例#2
0
文件: sph.c 项目: runiteking1/sph
/*@T
 *
 * The [[place_particles]] routine fills a region (indicated by the
 * [[indicatef]] argument) with fluid particles.  The fluid particles
 * are placed at points inside the domain that lie on a regular mesh
 * with cell sizes of $h/1.3$.  This is close enough to allow the
 * particles to overlap somewhat, but not too much.
 *@c*/
sim_state_t* place_particles(sim_param_t* param, 
                             domain_fun_t indicatef)
{
    float h  = param->h;
    float hh = h/1.3;

    // Count mesh points that fall in indicated region.
    int count = 0;
    for (float x = 0; x < 1; x += hh)
        for (float y = 0; y < 1; y += hh)
        	for (float z = 0; z < 1; z += hh)
        		count += indicatef(x,y,z);

    // Populate the particle data structure
    sim_state_t* s = alloc_state(count);
    int p = 0;
    for (float x = 0; x < 1; x += hh) {
        for (float y = 0; y < 1; y += hh) {
            for (float z = 0; z < 1; z += hh) {
                if (indicatef(x,y,z)) {
                    vec3_set(s->part[p].x, x, y, z);
                    vec3_set(s->part[p].v, 0, 0, 0);
                    ++p;
                }
            }
        }
    }
    return s;    
}
示例#3
0
文件: make1.c 项目: CarterTsai/clasp
static state * push_state( stack * const pStack, TARGET * const t,
    TARGET * const parent, int const curstate )
{
    state * const pState = alloc_state();
    pState->t = t;
    pState->parent = parent;
    pState->prev = pStack->stack;
    pState->curstate = curstate;
    return pStack->stack = pState;
}
示例#4
0
文件: fstate.c 项目: antdvid/FronTier
EXPORT	ConstantFlowRegion	*SetConstantFlowRegion(
	COMPONENT	comp,
	Locstate	state,
	INTERFACE	*intfc)
{
	ConstantFlowRegion *cfr;
	FlowSpecifiedRegion *fsr;

	fsr = FSR_for_comp(comp,NULL,intfc);
	if (fsr != NULL)
	{
	    size_t sizest = size_of_state(intfc);
	    if (strcmp(fsr->type,"CONSTANT_REGION") != 0)
	    {
		screen("ERROR in SetConstantFlowRegion(), "
		       "attempt to respecify a flow specified region\n");
		clean_up(ERROR);
	    }
	    cfr = (ConstantFlowRegion*)fsr;
	    if (sizest != 0)
	    {
		if (memcmp(state,cfr->state,sizest) != 0)
		{
		    screen("ERROR in SetConstantFlowRegion(), "
		           "attempt to respecify a constant region state\n");
		    clean_up(ERROR);
		}
	    }
	    return cfr;
	}
	scalar(&cfr,sizeof(ConstantFlowRegion));
	cfr->Fsr.comp = comp;
	sprintf(cfr->Fsr.type,"CONSTANT_REGION");
	cfr->Fsr._ComponentsMatch = equivalent_comps;
	cfr->Fsr._SetFlowSpecifiedState = SetConstantRegionState;
	cfr->Fsr._fprint_FlowSpecifiedRegion_data =
				fprint_ConstantFlowRegion_data;
	cfr->Fsr._DestroyFlowSpecifiedRegion = DestroyConstantFlowRegion;
	alloc_state(intfc,&cfr->state,size_of_state(intfc));
	ft_assign(cfr->state,state,size_of_state(intfc));
	(void) AddToFsrList(&cfr->Fsr);
	return cfr;
}		/*end SetConstantFlowRegion*/
示例#5
0
EXPORT	void	set_rt_kh_comp_type(
	COMP_TYPE	*comp_type,
	Front		*front)
{
	_RT_KH		*extra;

	if (comp_type->type == RT_KH) /*ALREADY SET*/
	    return;

	if (comp_type->free_comp_type_extra != NULL)
	    (*comp_type->free_comp_type_extra)(comp_type);

	comp_type->type = RT_KH;
	comp_type->_get_state = get_state_rt_kh;
	scalar(&extra,sizeof(_RT_KH));
	extra->stratification_type = CONSTANT;
	alloc_state(front->interf,&extra->ref_state,front->sizest);
	comp_type->extra = (POINTER)extra;
	comp_type->free_comp_type_extra = free_rt_kh_comp_type;
}		/*end set_rt_kh_comp_type*/
示例#6
0
/*ARGSUSED*/
EXPORT	void	set_up_riemann_problem_region(
	int		layer_label,
	int		region_label,
	int		surf_label,
	int		ellip_label,
	float		*coords,
	float		*nor,
	SIDE            ahead_side,
	Locstate	ahead_st,
	Locstate	st,
	LAYER_SYS	*layer_sys,
	INIT_PHYSICS	*ip,
	INIT_DATA	*init)
{
	COMP_TYPE		 *ct;
	_RAREFACTION_WAVE_1D	 *rw1d;
	LAYER                    *lyr, *llyr, *ulyr;
	Front	                 *front = layer_sys->front;
	INTERFACE                *intfc = front->interf;
	ELLIPSOID                *ellip;
	LAYER_SURF               *lsurf;
	Locstate		 sl, sr;
	Locstate                 left, right;
	Locstate                 sml, smr;
	float                    vl, vr;
	float                    pjump;
	float                    pml, pmr, uml, umr, ml, mr;
	float                    cl, cr, cml, cmr, Wl, Wr;
	float                    W, V;
	float                    dt, dh;
	RIEMANN_SOLVER_WAVE_TYPE l_wave, r_wave;
	int                      i, dim = front->rect_grid->dim;
	int                      w_type;
	size_t                   sizest = front->sizest;

	debug_print("layer","Entered set_up_riemann_problem_region()\n");

	alloc_state(intfc,&left,max(sizeof(VGas),sizest));
	alloc_state(intfc,&right,max(sizeof(VGas),sizest));
	alloc_state(intfc,&sml,sizest);
	alloc_state(intfc,&smr,sizest);

	if (ahead_side == POSITIVE_SIDE)
	{
	    sl = st;
	    sr = ahead_st;
	}
	else
	{
	    sl = ahead_st;
	    sr = st;
	}
	set_state(right,TGAS_STATE,sr);
	set_state(left,TGAS_STATE,sl);
	lyr = layer_sys->layer[layer_label];
	if (ellip_label > 0)
	{
	    if (ellip_label <= lyr->num_ellips)
	        ellip = lyr->ellip[ellip_label];
	    else
	    {
	        screen("ERROR in set_up_riemann_problem_region(), "
		       "invalid ellip_label %d > num_ellips %d\n",
		       ellip_label,lyr->num_ellips);
		clean_up(ERROR);
	    }
	    lsurf = NULL;
	}
	else
	{
	    ellip = NULL;
	    if (surf_label == layer_label)
	    {
	        lsurf = lyr->upper_surf;
		llyr = lyr;
		ulyr = layer_sys->layer[layer_label+1];
	    }
	    else if (surf_label == layer_label-1)
	    {
	        lsurf = lyr->lower_surf;
		ulyr = lyr;
		llyr = layer_sys->layer[layer_label-1];
	    }
	    else
	    {
	        screen("ERROR in set_up_riemann_problem_region(), "
		       "invalid surf_label %d layer_label %d\n",
		       surf_label,layer_label);
		clean_up(ERROR);
	    }
	}

	if (ellip != NULL)
	{
	    vr = Vel(right)[0];
	    vl = Vel(left)[0];
	    pjump = -ellip->surf_tension/
	             distance_between_positions(coords,ellip->cen,dim);
	}
	else
	{
	    vr = scalar_product(Vel(right),nor,dim);
	    vl = scalar_product(Vel(left),nor,dim);
	    pjump = 0.0;
	}
	zero_state_velocity(right,dim);
	Vel(right)[0] = vr;
	zero_state_velocity(left,dim);
	Vel(right)[0] = vl;
	set_state_for_find_mid_state(right,right);
	set_state_for_find_mid_state(left,left);
	if (find_mid_state(left,right,pjump,&pml,&pmr,&uml,&umr,&ml,&mr,
	                       &l_wave,&r_wave) != FUNCTION_SUCCEEDED)
	{
	    screen("ERROR in set_up_riemann_problem_region(), "
	           "find_mid_state() did not converge\n");
	    verbose_print_state("left",left);
	    verbose_print_state("right",right);
	    (void) printf("pjump = %g\n"
	                  "pml = %g, pmr = %g\n"
	                  "uml = %g, umr = %g\n"
	                  "ml = %g, mr = %g\n",
	                  pjump,pml,pmr,uml,umr,ml,mr);
	    (void) printf("l_wave = %s, r_wave = %s\n",
	                  rsoln_wave_name(l_wave),rsoln_wave_name(r_wave));
	    clean_up(ERROR);
	}

	w_type = (l_wave == RAREFACTION) ?
	    BACKWARD_SOUND_WAVE_TE : BACKWARD_SHOCK_WAVE;
	state_behind_sound_wave(left,sml,&cml,&Wl,0.0,ml,uml,pml,TGAS_STATE,
	                        w_type,l_wave,LEFT_FAMILY);
	w_type = (r_wave == RAREFACTION) ?
	    FORWARD_SOUND_WAVE_TE : FORWARD_SHOCK_WAVE;
	state_behind_sound_wave(right,smr,&cmr,&Wr,0.0,mr,umr,pmr,TGAS_STATE,
	                        w_type,r_wave,RIGHT_FAMILY);

	cl = sound_speed(left);
	cr = sound_speed(right);
	W = max(fabs(Wl),fabs(Wr));
	V = fabs(vl) + cl;
	W = max(W,V);
	V = fabs(vr) + cr;
	W = max(W,V);
	V = fabs(uml) + cml;
	W = max(W,V);
	V = fabs(umr) + cmr;
	W = max(W,V);
	for (dh = HUGE_VAL, i = 0; i < dim; ++i)
	    dh = min(dh,front->rect_grid->h[i]);
	dt = 0.1*dh/W;/*TOLERANCE*/
	layer_sys->dt = min(layer_sys->dt,dt);

	if (debugging("layer"))
	{
	    (void) printf("States from Riemann solution\n");
	    verbose_print_state("left state",left);
	    verbose_print_state("left mid state",sml);
	    verbose_print_state("right mid state",smr);
	    verbose_print_state("right state",right);
	    (void) printf("l_wave = %s, r_wave = %s\n",
	                  rsoln_wave_name(l_wave),rsoln_wave_name(r_wave));
	    (void) printf("Wave speeds\n");
	    if (l_wave == RAREFACTION)
	    {
	        (void) printf("Left rarefaction leading edge speed = %g\n",
		              vl-cl);
	        (void) printf("Left rarefaction trailing edge speed = %g\n",
		              uml-cml);
	    }
	    else if (l_wave == SHOCK)
	        (void) printf("Left shock speed = %g\n",Wl);
	    (void) printf("Contact speed = %g (uml = %g, umr = %g)\n",
	                  0.5*(uml+umr),uml,umr);
	    if (r_wave == RAREFACTION)
	    {
	        (void) printf("Right rarefaction trailing edge speed = %g\n",
		              umr+cmr);
	        (void) printf("Right rarefaction leading edge speed = %g\n",
		              vr+cr);
	    }
	    else if (r_wave == SHOCK)
	        (void) printf("Right shock speed = %g\n",Wr);

	}

	if (ellip == NULL)
	{
	    LAYER      *rlyr, *mlyr;
	    LAYER_SURF *rlyr_le, *rlyr_te, *shock;
	    float      *nor = lsurf->nor;
	    float      vml, vmr;

	    vml = Vel(sml)[0];
	    vmr = Vel(smr)[0];
	    for (i = 0; i < dim; ++i)
	    {
		Vel(sml)[i] = vel(i,sl) + (vml-vl)*nor[i];
		Vel(smr)[i] = vel(i,sr) + (vmr-vr)*nor[i];
	    }
	    if (l_wave == RAREFACTION)
	    {
	        rlyr = add_new_layer(layer_sys,new_component(NEW_COMP));
	        rlyr->lower_surf = alloc_layer_surf();
	        rlyr->upper_surf = alloc_layer_surf();
	        *rlyr->upper_surf = *lsurf;
	        *rlyr->lower_surf = *lsurf;
		rlyr->lower_surf->reset_position = YES;
		rlyr->upper_surf->reset_position = YES;
	        rlyr->lower_surf->surf_ten = 0.0;
	        rlyr->upper_surf->surf_ten = 0.0;

		ct = comp_type(rlyr->comp);
	        set_rarefaction_wave_1d_comp_type(ct,front);
	        rw1d = Rarefaction_wave_1d(ct);
		rw1d->l_or_r = LEFT_FAMILY;
		rw1d->zbar = lsurf->pbar[dim-1];
		rw1d->tbar = -HUGE_VAL; /*To be set later */
		rw1d->el_lead = rw1d->el_trail = NULL;
		set_state(rw1d->stl,TGAS_STATE,sl);
		set_state(rw1d->stt,TGAS_STATE,sml);
		rw1d->spl = vl-cl;
		rw1d->spt = vml-cml;

	        mlyr = add_new_layer(layer_sys,new_component(NEW_COMP));

	        if (nor[dim-1] < 0.0)
	        {
	    	    rlyr_le = rlyr->upper_surf;
	    	    rlyr_te = rlyr->lower_surf;
	    	    mlyr->upper_surf = rlyr_te;
	    	    mlyr->lower_surf = lsurf;
		    rw1d->zt = rw1d->zmin = -HUGE_VAL;/*To be set later*/
	            rw1d->stmin = rw1d->stt;
		    rw1d->zl = rw1d->zmax =  HUGE_VAL;/*To be set later*/
	            rw1d->stmax = rw1d->stl;
		    ulyr->lower_surf = rlyr_le;
	        }
	        else
	        {
	    	    rlyr_le = rlyr->lower_surf;
	    	    rlyr_te = rlyr->upper_surf;
	    	    mlyr->lower_surf = rlyr_te;
	    	    mlyr->upper_surf = lsurf;
		    rw1d->zl = rw1d->zmin = -HUGE_VAL;/*To be set later*/
	            rw1d->stmin = rw1d->stl;
		    rw1d->zt = rw1d->zmax =  HUGE_VAL;/*To be set later*/
	            rw1d->stmax = rw1d->stt;
		    llyr->upper_surf = rlyr_le;
	        }
		rw1d->lead = rlyr_le;
		rw1d->trail = rlyr_te;
	        rlyr_le->l_comp = lsurf->l_comp;
	        rlyr_le->r_comp = rlyr_te->l_comp = rlyr->comp;
	        rlyr_le->wv_type = BACKWARD_SOUND_WAVE_LE;
	        rlyr_te->wv_type = BACKWARD_SOUND_WAVE_TE;
	        rlyr_te->r_comp = lsurf->l_comp = mlyr->comp;
	        for (i = 0; i < dim; ++i)
		{
		    rlyr_le->velocity[i] = rw1d->spl*nor[i];
		    rlyr_te->velocity[i] = rw1d->spt*nor[i];
		}
	    }
	    else
	    {
	        mlyr = add_new_layer(layer_sys,new_component(NEW_COMP));
	        shock = alloc_layer_surf();
	        *shock = *lsurf;
	        if (nor[dim-1] < 0.0)
	        {
	    	    mlyr->upper_surf = shock;
	    	    mlyr->lower_surf = lsurf;
		    ulyr->lower_surf = shock;
	        }
	        else
	        {
	    	    mlyr->lower_surf = shock;
	    	    mlyr->upper_surf = lsurf;
		    llyr->upper_surf = shock;
	        }
	        shock->l_comp = lsurf->l_comp;
	        shock->wv_type = BACKWARD_SHOCK_WAVE;
	        shock->r_comp = lsurf->l_comp = mlyr->comp;
		shock->reset_position = YES;
	        for (i = 0; i < dim; ++i)
		    shock->velocity[i] = Wl*nor[i];
	    }
	    ct = comp_type(mlyr->comp);
	    set_ambient_comp_type(ct,front);
	    set_state(Ambient(ct),GAS_STATE,sml);
	    if (r_wave == RAREFACTION)
	    {
	        rlyr = add_new_layer(layer_sys,new_component(NEW_COMP));
	        rlyr->lower_surf = alloc_layer_surf();
	        rlyr->upper_surf = alloc_layer_surf();
	        *rlyr->upper_surf = *lsurf;
	        *rlyr->lower_surf = *lsurf;
		rlyr->lower_surf->reset_position = YES;
		rlyr->upper_surf->reset_position = YES;
	        rlyr->lower_surf->surf_ten = 0.0;
	        rlyr->upper_surf->surf_ten = 0.0;

		ct = comp_type(rlyr->comp);
	        set_rarefaction_wave_1d_comp_type(ct,front);
	        rw1d = Rarefaction_wave_1d(ct);
		rw1d->l_or_r = RIGHT_FAMILY;
		rw1d->zbar = lsurf->pbar[dim-1];
		rw1d->tbar = -HUGE_VAL; /*To be set later */
		rw1d->el_lead = rw1d->el_trail = NULL;
		set_state(rw1d->stl,TGAS_STATE,sr);
		set_state(rw1d->stt,TGAS_STATE,smr);
		rw1d->spl = vr+cr;
		rw1d->spt = vmr+cmr;
		rw1d->lead = rlyr_le;
		rw1d->trail = rlyr_te;

	        mlyr = add_new_layer(layer_sys,new_component(NEW_COMP));

	        if (nor[dim-1] < 0.0)
	        {
	    	    rlyr_le = rlyr->lower_surf;
	    	    rlyr_te = rlyr->upper_surf;
	    	    mlyr->lower_surf = rlyr_te;
	    	    mlyr->upper_surf = lsurf;
		    rw1d->zl = rw1d->zmin = -HUGE_VAL;/*To be set later*/
	            rw1d->stmin = rw1d->stl;
		    rw1d->zt = rw1d->zmax =  HUGE_VAL;/*To be set later*/
	            rw1d->stmax = rw1d->stt;
		    llyr->upper_surf = rlyr_le;
	        }
	        else
	        {
	    	    rlyr_le = rlyr->upper_surf;
	    	    rlyr_te = rlyr->lower_surf;
	    	    mlyr->upper_surf = rlyr_te;
	    	    mlyr->lower_surf = lsurf;
		    rw1d->zt = rw1d->zmin = -HUGE_VAL;/*To be set later*/
	            rw1d->stmin = rw1d->stt;
		    rw1d->zl = rw1d->zmax =  HUGE_VAL;/*To be set later*/
	            rw1d->stmax = rw1d->stl;
		    ulyr->lower_surf = rlyr_le;
	        }
	        rlyr_le->r_comp = lsurf->r_comp;
	        rlyr_le->l_comp = rlyr_te->r_comp = rlyr->comp;
	        rlyr_le->wv_type = FORWARD_SOUND_WAVE_LE;
	        rlyr_te->wv_type = FORWARD_SOUND_WAVE_TE;
	        rlyr_te->l_comp = lsurf->r_comp = mlyr->comp;
	        for (i = 0; i < dim; ++i)
	        {
	    	    rlyr_le->velocity[i] = rw1d->spl*nor[i];
	    	    rlyr_te->velocity[i] = rw1d->spt*nor[i];
	        }
	    }
	    else
	    {
	        mlyr = add_new_layer(layer_sys,new_component(NEW_COMP));
	        shock = alloc_layer_surf();
	        *shock = *lsurf;
	        if (nor[dim-1] < 0.0)
	        {
	    	    mlyr->lower_surf = shock;
	    	    mlyr->upper_surf = lsurf;
		    llyr->upper_surf = shock;
	        }
	        else
	        {
	    	    mlyr->upper_surf = shock;
	    	    mlyr->lower_surf = lsurf;
		    ulyr->lower_surf = shock;
	        }
	        shock->r_comp = lsurf->r_comp;
	        shock->wv_type = FORWARD_SHOCK_WAVE;
	        shock->l_comp = lsurf->r_comp = mlyr->comp;
		shock->reset_position = YES;
	        for (i = 0; i < dim; ++i)
	    	    shock->velocity[i] = Wr*nor[i];
	    }
	    ct = comp_type(mlyr->comp);
	    set_ambient_comp_type(ct,front);
	    set_state(Ambient(ct),GAS_STATE,smr);

	    lsurf->wv_type = CONTACT;
	    lsurf->reset_position = YES;
	    for (i = 0; i < dim; ++i)
	        lsurf->velocity[i] = 0.5*(vml+vmr)*nor[i];
	}
	else
	{
	    set_riemann_problem_ellipsoid(front,lyr,ellip,l_wave,r_wave,
	                                  Wl,Wr,sl,sml,smr,sr,ip);
	}


	free_these(4,left,right,sml,smr);
	debug_print("layer","Left set_up_riemann_problem_region()\n");
}		/*end set_up_riemann_problem_region*/
示例#7
0
文件: pip_db.c 项目: Martoni/debit
static void do_state(pip_ref_t *ref, state_t *state, void *dat) {
  alloc_state(state, dat);
  init_state(state);
}
示例#8
0
文件: httpd.c 项目: jaseg/avr-uip
/*---------------------------------------------------------------------------*/
void
httpd_appcall(void)
{
#if PORT_APP_MAPPER
	struct httpd_state *s;
#else
	struct httpd_state *s = (struct httpd_state *)&(uip_conn->appstate);
#endif


	if(uip_closed() || uip_aborted() || uip_timedout()) {
#if PORT_APP_MAPPER
//sendString("uip close/abort/timeout\r\n");
		if (uip_conn->appstate != -1)
		{
//sendString("uip close/abort/timeout - cleanup\r\n");
			httpd_state_list[((int8_t)uip_conn->appstate)].state = STATE_UNUSED;
			uip_conn->appstate = -1;
		}
#endif
	} else if(uip_connected()) {
#if PORT_APP_MAPPER
		if ((uip_conn->appstate = alloc_state()) == -1)
		{
			// we are out of state space.  close the connection
			// hope the client tries back again
//sendString("Out of http stats\r\n");
			uip_abort();
			return;
		}
		// set the app state
		s = &(httpd_state_list[((int8_t)uip_conn->appstate)]);
#endif
		PSOCK_INIT(&s->sin, s->inputbuf, sizeof(s->inputbuf) - 1);
		PSOCK_INIT(&s->sout, s->inputbuf, sizeof(s->inputbuf) - 1);
		PT_INIT(&s->outputpt);
		s->state = STATE_WAITING;
	    /*    timer_set(&s->timer, CLOCK_SECOND * 100);*/
		s->timer = 0;
		handle_connection(s);
#if PORT_APP_MAPPER
	} else if (uip_conn->appstate != -1) {
		s = &(httpd_state_list[((int8_t)uip_conn->appstate)]);
#else
	} else if(s != NULL) {
#endif
		if(uip_poll()) {
			++s->timer;
			// if the client just hasn't sent
			// anything in a while we end up here
			// this is where we can clean up dead connections.
			// 20 seems like a long time - if(s->timer >= 20) {
			// 16 seems to be a good number wtih 5 status
			if(s->timer >= 16) {
#if PORT_APP_MAPPER
				if (uip_conn->appstate != -1)
				{
					httpd_state_list[((int8_t)uip_conn->appstate)].state = STATE_UNUSED;
					uip_conn->appstate = -1;
				}
#endif
				uip_abort();
			}
    	} else {
			s->timer = 0;
		}
		handle_connection(s);
	} else {
#if PORT_APP_MAPPER
		if (uip_conn->appstate != -1)
		{
			httpd_state_list[((int8_t)uip_conn->appstate)].state = STATE_UNUSED;
			uip_conn->appstate = -1;
		}
#endif
		uip_abort();
	}
}
示例#9
0
/*-----------------------------------------------------------------------------------*/
DISPATCHER_UIPCALL(httpd_appcall, state)
{
  struct httpd_fs_file fsfile;  
  u8_t i;
  DISPATCHER_UIPCALL_ARG(state);

  hs = (struct httpd_state *)(state);
  
  /* We use the uip_ test functions to deduce why we were
     called. If uip_connected() is non-zero, we were called
     because a remote host has connected to us. If
     uip_newdata() is non-zero, we were called because the
     remote host has sent us new data, and if uip_acked() is
     non-zero, the remote host has acknowledged the data we
     previously sent to it. */
  if(uip_connected()) {

    /* Since we've just been connected, the state pointer should be
       NULL and we need to allocate a new state object. If we have run
       out of memory for state objects, we'll have to abort the
       connection and return. */
    if(hs == NULL) {
      hs = alloc_state();
      if(hs == NULL) {
	uip_close();
	return;
      }
      dispatcher_markconn(uip_conn, (void *)hs);
    }
    /* Since we have just been connected with the remote host, we
       reset the state for this connection. The ->count variable
       contains the amount of data that is yet to be sent to the
       remote host, and the ->state is set to HTTP_NOGET to signal
       that we haven't received any HTTP GET request for this
       connection yet. */
    hs->state = HTTP_NOGET;
    hs->count = 0;
    hs->poll = 0;
  } else if(uip_closed() || uip_aborted()) {
    if(hs != NULL) {
      dealloc_state(hs);
    }
    return;
  } else if(uip_poll()) {
    /* If we are polled ten times, we abort the connection. This is
       because we don't want connections lingering indefinately in
       the system. */
    if(hs != NULL) {
      if(hs->state == HTTP_DEALLOCATED) {
	uip_abort();
      } else if(hs->poll++ >= 100) {
	uip_abort();
	dealloc_state(hs);
      }
    }
    return;
  }


  if(uip_newdata() && hs->state == HTTP_NOGET) {
    hs->poll = 0;
    /* This is the first data we receive, and it should contain a
       GET. */
      
    /* Check for GET. */
    if(uip_appdata[0] != ISO_G ||
       uip_appdata[1] != ISO_E ||
       uip_appdata[2] != ISO_T ||
       uip_appdata[3] != ISO_space) {
      /* If it isn't a GET, we abort the connection. */
      uip_abort();
      dealloc_state(hs);
      return;
    }

    beep();
    
    /* Find the file we are looking for. */
    for(i = 4; i < 40; ++i) {
      if(uip_appdata[i] == ISO_space ||
	 uip_appdata[i] == ISO_cr ||
	 uip_appdata[i] == ISO_nl) {
	uip_appdata[i] = 0;
	break;
      }
    }

    PRINT("request for file ");
    PRINTLN(&uip_appdata[4]);
    webserver_log_file(uip_conn->ripaddr, &uip_appdata[4]);
    /* Check for a request for "/". */
    if(uip_appdata[4] == ISO_slash &&
       uip_appdata[5] == 0) {
      httpd_fs_open(file_index_html.name, &fsfile);    
    } else {
      if(!httpd_fs_open((const char *)&uip_appdata[4], &fsfile)) {
	PRINTLN("couldn't open file");
	httpd_fs_open(file_404_html.name, &fsfile);
      }
    } 

    if(uip_appdata[4] == ISO_slash &&
       uip_appdata[5] == ISO_c &&
       uip_appdata[6] == ISO_g &&
       uip_appdata[7] == ISO_i &&
       uip_appdata[8] == ISO_slash) {
      /* If the request is for a file that starts with "/cgi/", we
	 prepare for invoking a script. */	
      hs->script = fsfile.data;
      next_scriptstate();
    } else {
      hs->script = NULL;
      /* The web server is now no longer in the HTTP_NOGET state, but
	 in the HTTP_FILE state since is has now got the GET from
	 the client and will start transmitting the file. */
      hs->state = HTTP_FILE;

      /* Point the file pointers in the connection state to point to
	 the first byte of the file. */
      hs->dataptr = fsfile.data;
      hs->count = fsfile.len;	
    }     
  }

    
  if(hs->state != HTTP_FUNC) {
    /* Check if the client (remote end) has acknowledged any data that
       we've previously sent. If so, we move the file pointer further
       into the file and send back more data. If we are out of data to
       send, we close the connection. */
    if(uip_acked()) {
      hs->poll = 0;	
      if(hs->count >= uip_mss()) {
	hs->count -= uip_mss();
	hs->dataptr += uip_mss();
      } else {
	hs->count = 0;
      }
	
      if(hs->count == 0) {
	if(hs->script != NULL) {
	  next_scriptline();
	  next_scriptstate();
	} else {
	  uip_close();
	  dealloc_state(hs);
	}
      }
    }         
  }
    
  if(hs->state == HTTP_FUNC) {
    /* Call the CGI function. */
#if 1
    if(httpd_cgitab[hs->script[2] - ISO_a]()) {
      /* If the function returns non-zero, we jump to the next line
	 in the script. */
      next_scriptline();
      next_scriptstate();
    }
#endif
  }

  if(hs->state != HTTP_FUNC && !uip_poll()) {
    hs->poll = 0;
    /* Send a piece of data, but not more than the MSS of the
       connection. */
    uip_send(hs->dataptr,
	     hs->count > uip_mss()? uip_mss(): hs->count);
  }

  /* Finally, return to uIP. Our outgoing packet will soon be on its
     way... */
}