Exemple #1
0
void dump_simtrace( anode_t *head, ptree_t *evar_list, ptree_t *svar_list,
                    FILE *fp )
{
    int j, last_nonzero_env, last_nonzero_sys;
    anode_t *node;
    int node_counter = 0;
    ptree_t *var;
    int num_env, num_sys;

    if (fp == NULL)
        fp = stdout;

    num_env = tree_size( evar_list );
    num_sys = tree_size( svar_list );

    node = head;
    while (node->mode != 0)  /* Find starting state */
        node = node->next;
    while (node->trans_len >= 0) {
        fprintf( fp, "%d: ", node_counter );
        last_nonzero_env = num_env-1;
        last_nonzero_sys = num_sys-1;
        if (last_nonzero_env < 0 && last_nonzero_sys < 0) {
            fprintf( fp, "{}" );
        } else {
            for (j = 0; j < num_env; j++) {
                var = get_list_item( evar_list, j );
                if (j == last_nonzero_env) {
                    fprintf( fp, "%s=%d", var->name, *(node->state+j) );
                    fprintf( fp, ", " );
                } else {
                    fprintf( fp, "%s=%d, ", var->name, *(node->state+j) );
                }
            }
            for (j = 0; j < num_sys; j++) {
                var = get_list_item( svar_list, j );
                if (j == last_nonzero_sys) {
                    fprintf( fp, "%s=%d", var->name, *(node->state+num_env+j) );
                } else {
                    fprintf( fp, "%s=%d, ",
                             var->name, *(node->state+num_env+j) );
                }
            }
        }
        fprintf( fp, "\n" );
        if (node->trans_len == 0)
            break;

        node_counter++;
        node = *(node->trans);
    }
}
Exemple #2
0
void logprint_state( vartype *state ) {
    int i;
    int num_env, num_sys;
    num_env = tree_size( spc.evar_list );
    num_sys = tree_size( spc.svar_list );
    for (i = 0; i < num_env+num_sys; i++) {
        logprint( "\t%s = %d;",
                  (i < num_env ?
                   (get_list_item( spc.evar_list, i ))->name
                   : (get_list_item( spc.svar_list, i-num_env ))->name),
                  *(state+i) );
    }
}
Exemple #3
0
int
get_list_count(dbref player, dbref obj, dbref perms, char *listname, int mesgtyp, int* blessed)
{
	char buf[BUFFER_LEN];
	const char *ptr;
	int i, len = strlen(listname);

	if (listname[len-1] == NUMBER_TOKEN) listname[len-1] = 0;

	snprintf(buf, sizeof(buf), "%.512s#", listname);
	ptr = safegetprop(player, obj, perms, buf, mesgtyp, blessed);
	if (ptr && *ptr)
		return (atoi(ptr));

	snprintf(buf, sizeof(buf), "%.512s/#", listname);
	ptr = safegetprop(player, obj, perms, buf, mesgtyp, blessed);
	if (ptr && *ptr)
		return (atoi(ptr));

	for (i = 1; i < MAX_MFUN_LIST_LEN; i++) {
		ptr = get_list_item(player, obj, perms, listname, i, mesgtyp, blessed);
		if (!ptr)
			return 0;
		if (!*ptr)
			break;
	}
	if (i-- < MAX_MFUN_LIST_LEN)
		return i;
	return MAX_MFUN_LIST_LEN;
}
Exemple #4
0
const char *
mfn_rand(MFUNARGS)
{
	int num = 0;
	dbref trg = (dbref) 0, obj = what;
	const char *pname, *ptr;
	int blessed = 0;

	pname = argv[0];
	if (argc == 2) {
		obj = mesg_dbref(descr, player, what, perms, argv[1], mesgtyp);
	}
	if (obj == PERMDENIED)
		ABORT_MPI("RAND", "Permission denied.");
	if (obj == UNKNOWN || obj == AMBIGUOUS || obj == NOTHING || obj == HOME)
		ABORT_MPI("RAND", "Match failed.");
	num = get_list_count(what, obj, perms, (char *)pname, mesgtyp, &blessed);
	if (!num)
		ABORT_MPI("RAND", "Failed list read.");
	ptr = get_list_item(what, obj, perms, (char *)pname, (((RANDOM() / 256) % num) + 1), mesgtyp, &blessed);
	if (!ptr)
		ABORT_MPI("RAND", "Failed list read.");
	trg = what;
	if (blessed) {
		mesgtyp |= MPI_ISBLESSED;
	} else {
		mesgtyp &= ~MPI_ISBLESSED;
	}
	if (Prop_ReadOnly(ptr) || Prop_Private(ptr) || Prop_SeeOnly(ptr) || Prop_Hidden(ptr))
		trg = obj;
	ptr = mesg_parse(descr, player, obj, trg, ptr, buf, BUFFER_LEN, mesgtyp);
	CHECKRETURN(ptr, "RAND", "listval");
	return ptr;
}
Exemple #5
0
int
rs_read_object_reference(FILE *inf, THING *list, THING **item)
{
    int i;
    
    if (read_error || format_error)
        return(READSTAT);

    rs_read_int(inf, &i);

    *item = get_list_item(list,i);
            
    return(READSTAT);
}
char   *
get_concat_list(dbref player, dbref what, dbref perms, dbref obj, const char *listname, char *buf, int maxchars, int mode)
{
    int line_limit = MAX_MFUN_LIST_LEN;
    int     i;
    const char *ptr;
    char   *pos = buf;
    int     cnt = get_list_count(what, obj, perms, listname);

    if (cnt == 0) {
        return NULL;
    }
    maxchars -= 2;
    *buf = '\0';
    for (i = 1; ((pos - buf) < (maxchars - 1)) && i <= cnt && line_limit--; i++) {
        ptr = get_list_item(what, obj, perms, listname, i);
        if (ptr) {
            while (mode && isspace(*ptr))
                ptr++;
            if (pos > buf) {
                if (!mode) {
                    *(pos++) = '\r';
                    *pos = '\0';
                } else if (mode == 1) {
                    char    ch = *(pos - 1);

                    if ((pos - buf) >= (maxchars - 2))
                        break;
                    if (ch == '.' || ch == '?' || ch == '!')
                        *(pos++) = ' ';
                    *(pos++) = ' ';
                    *pos = '\0';
		} else {
                    *pos = '\0';
                }
            }
            while (((pos - buf) < (maxchars - 1)) && *ptr)
                *(pos++) = *(ptr++);
	    if (mode) {
		while (pos > buf && *(pos - 1) == ' ') pos--;
	    }
            *pos = '\0';
            if ((pos - buf) >= (maxchars - 1))
                break;
        }
    }
    return (buf);
}
Exemple #7
0
int
rs_read_thing_reference(FILE *inf, THING *list, THING **item)
{
    int i;
    
    if (read_error || format_error)
        return(READSTAT);

    rs_read_int(inf, &i);

    if (i == -1)
        *item = NULL;
    else
        *item = get_list_item(list,i);

    return(READSTAT);
}
Exemple #8
0
void
rs_fix_thing(THING *t)
{
    THING *item;
    THING *tp;

    if (t->t_reserved < 0)
        return;

    item = get_list_item(mlist,t->t_reserved);

    if (item != NULL)
    {
        tp = item;
        t->t_dest = &tp->t_pos;
    }
}
Exemple #9
0
const char *
mfn_timesub(MFUNARGS)
{
	int num = 0;
	dbref trg = (dbref) 0, obj = what;
	const char *pname, *ptr;
	int period = 0, offset = 0;
	int blessed = 0;

	period = atoi(argv[0]);
	offset = atoi(argv[1]);
	pname = argv[2];
	if (argc == 4) {
		obj = mesg_dbref(descr, player, what, perms, argv[3], mesgtyp);
	}
	if (obj == PERMDENIED)
		ABORT_MPI("TIMESUB", "Permission denied.");
	if (obj == UNKNOWN || obj == AMBIGUOUS || obj == NOTHING || obj == HOME)
		ABORT_MPI("TIMESUB", "Match failed.");
	num = get_list_count(what, obj, perms, (char *)pname, mesgtyp, &blessed);
	if (!num)
		ABORT_MPI("TIMESUB", "Failed list read.");
	if (period < 1)
		ABORT_MPI("TIMESUB", "Time period too short.");
	offset = (int)((((long) time(NULL) + offset) % period) * num) / period;
	if (offset < 0)
		offset = -offset;
	ptr = get_list_item(what, obj, perms, (char *)pname, offset + 1, mesgtyp, &blessed);
	if (!ptr)
		ABORT_MPI("TIMESUB", "Failed list read.");
	trg = what;
	if (blessed) {
		mesgtyp |= MPI_ISBLESSED;
	} else {
		mesgtyp &= ~MPI_ISBLESSED;
	}
	if (Prop_ReadOnly(ptr) || Prop_Private(ptr) || Prop_SeeOnly(ptr) || Prop_Hidden(ptr))
		trg = obj;
	ptr = mesg_parse(descr, player, obj, trg, ptr, buf, BUFFER_LEN, mesgtyp);
	CHECKRETURN(ptr, "TIMESUB", "listval");
	return ptr;
}
int
get_list_count(dbref player, dbref obj, dbref perms, const char *listname)
{
    char    buf[BUFFER_LEN];
    const char *ptr;
    int i;

    sprintf(buf, "%.512s#", listname);
    ptr = safegetprop(player, obj, perms, buf);
    if (ptr && *ptr) return (atoi(ptr));

    sprintf(buf, "%.512s/#", listname);
    ptr = safegetprop(player, obj, perms, buf);
    if (ptr && *ptr) return (atoi(ptr));

    for (i = 1; i < MAX_MFUN_LIST_LEN; i++) {
	ptr = get_list_item(player, obj, perms, listname, i);
        if (!ptr) return 0;
        if (!*ptr) break;
    }
    if (i-- < MAX_MFUN_LIST_LEN) return i;
    return MAX_MFUN_LIST_LEN;
}
Exemple #11
0
const char *
mfn_select(MFUNARGS)
{
	char origprop[BUFFER_LEN];
	char propname[BUFFER_LEN];
	char bestname[BUFFER_LEN];
	dbref obj = what;
	dbref bestobj = 0;
	char *pname;
	const char *ptr;
	char *out, *in;
	int i, targval, bestval;
	int baselen;
	int limit;
	int blessed = 0;

	pname = argv[1];
	if (argc == 3) {
		obj = mesg_dbref(descr, player, what, perms, argv[2], mesgtyp);
	}
	if (obj == PERMDENIED)
		ABORT_MPI("SELECT", "Permission denied.");
	if (obj == UNKNOWN || obj == AMBIGUOUS || obj == NOTHING || obj == HOME)
		ABORT_MPI("SELECT", "Match failed.");

	/*
	 * Search contiguously for a bit, looking for a best match.
	 * This allows fast hits on LARGE lists.
	 */

	limit = 18;
	i = targval = atoi(argv[0]);
	do {
		ptr = get_list_item(player, obj, perms, (char *)pname, i--, mesgtyp, &blessed);
	} while (limit-->0 && i >= 0 && ptr && !*ptr);
	if (ptr == NULL)
		ABORT_MPI("SELECT", "Failed list read.");
	if (*ptr != '\0')
		return ptr;

	/*
	 * If we didn't find it before, search only existing props.
	 * This gets fast hits on very SPARSE lists.
	 */

	/* First, normalize the base propname */
	out = origprop;
	in = argv[1];
	while (*in != '\0') {
		*out++ = PROPDIR_DELIMITER;
		while (*in == PROPDIR_DELIMITER) in++;
		while (*in && *in != PROPDIR_DELIMITER) *out++ = *in++;
	}
	*out++ = '\0';

	i = targval;
	bestname[0] = '\0';
	bestval = 0;
	baselen = strlen(origprop);
	for (; obj != NOTHING; obj = getparent(obj)) {
		pname = next_prop_name(obj, propname, sizeof(propname), origprop);
		while (pname && string_prefix(pname, origprop)) {
			ptr = pname + baselen;
			if (*ptr == NUMBER_TOKEN) ptr++;
			if (!*ptr && is_propdir(obj, pname)) {
				char propname2[BUFFER_LEN];
				char *pname2;
				int sublen = strlen(pname);

				pname2 = strcpyn(propname2, sizeof(propname2), pname);
				propname2[sublen++] = PROPDIR_DELIMITER;
				propname2[sublen] = '\0';

				pname2 = next_prop_name(obj, propname2, sizeof(propname2), pname2);
				while (pname2) {
					ptr = pname2 + sublen;
					if (number(ptr)) {
						i = atoi(ptr);
						if (bestval < i && i <= targval) {
							bestval = i;
							bestobj = obj;
							strcpyn(bestname, sizeof(bestname), pname2);
						}
					}
					pname2 = next_prop_name(obj, propname2, sizeof(propname2), pname2);
				}
			}
			ptr = pname + baselen;
			if (number(ptr)) {
				i = atoi(ptr);
				if (bestval < i && i <= targval) {
					bestval = i;
					bestobj = obj;
					strcpyn(bestname, sizeof(bestname), pname);
				}
			}
			pname = next_prop_name(obj, propname, sizeof(propname), pname);
		}
	}
	
	if (*bestname) {
		ptr = safegetprop_strict(player, bestobj, perms, bestname, mesgtyp, &blessed);
		if (!ptr)
			ABORT_MPI("SELECT", "Failed property read.");
	} else {
		ptr = "";
	}
	return ptr;
}
Exemple #12
0
char *
get_concat_list(dbref player, dbref what, dbref perms, dbref obj, char *listname,
				char *buf, int maxchars, int mode, int mesgtyp, int* blessed)
{
	int line_limit = MAX_MFUN_LIST_LEN;
	int i, cnt, len;
	const char *ptr;
	char *pos = buf;
	int tmpbless;

	len = strlen(listname);
	if (listname[len-1] == NUMBER_TOKEN) listname[len-1] = 0;
	cnt = get_list_count(what, obj, perms, listname, mesgtyp, &tmpbless);

	*blessed = 1;

	if (!tmpbless) {
		*blessed = 0;
	}

	if (cnt == 0) {
		return NULL;
	}
	maxchars -= 2;
	*buf = '\0';
	for (i = 1; ((pos - buf) < (maxchars - 1)) && i <= cnt && line_limit--; i++) {
		ptr = get_list_item(what, obj, perms, listname, i, mesgtyp, &tmpbless);
		if (ptr) {
			if (!tmpbless) {
				*blessed = 0;
			}
			while (mode && isspace(*ptr))
				ptr++;
			if (pos > buf) {
				if (!mode) {
					*(pos++) = '\r';
					*pos = '\0';
				} else if (mode == 1) {
					char ch = *(pos - 1);

					if ((pos - buf) >= (maxchars - 2))
						break;
					if (ch == '.' || ch == '?' || ch == '!')
						*(pos++) = ' ';
					*(pos++) = ' ';
					*pos = '\0';
				} else {
					*pos = '\0';
				}
			}
			while (((pos - buf) < (maxchars - 1)) && *ptr)
				*(pos++) = *(ptr++);
			if (mode) {
				while (pos > buf && *(pos - 1) == ' ')
					pos--;
			}
			*pos = '\0';
			if ((pos - buf) >= (maxchars - 1))
				break;
		}
	}
	return (buf);
}
static int
authenticate_webid_user(request_rec *request) {
    int r = 0;
    authn_webid_config_rec *conf =
        ap_get_module_config(request->per_dir_config, &authn_webid_module);
    if (!conf->authoritative) r = DECLINED;
    else r = HTTP_UNAUTHORIZED;

    /* Check for AuthType WebID */
    const char *current_auth = ap_auth_type(request);
    if (!current_auth || strcasecmp(current_auth, "WebID") != 0) {
        return DECLINED;
    }
    request->ap_auth_type = "WebID";

    /* Check for WebID cached in SSL session */
    const char *subjAltName = NULL;
    {
        void *data = NULL;
        if (apr_pool_userdata_get(&data, UD_WEBID_KEY, request->connection->pool) == APR_SUCCESS && data != NULL) {
            subjAltName = data;
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, request, "WebID: using cached URI <%s>", subjAltName);
            if (strlen(subjAltName)) {
                request->user = (char *)subjAltName;
                r = OK;
            }
            return r;
        }
    }
#if AP_MODULE_MAGIC_AT_LEAST(20060101,0)
    apr_array_header_t *subjAltName_list = ssl_ext_list(request->pool, request->connection, 1, "2.5.29.17");
#else
    subjAltName = ssl_ext_lookup(request->pool, request->connection, 1, "2.5.29.17");
#endif

    /* Load X509 Public Key + Exponent */
    char *pkey_n = NULL;
    char *pkey_e = NULL;
    unsigned int pkey_e_i = 0;
#if AP_MODULE_MAGIC_AT_LEAST(20060101,0)
    if (subjAltName_list != NULL) {
#else
    if (subjAltName != NULL) {
#endif
        char *c_cert = NULL;
        BIO *bio_cert = NULL;
        X509 *x509 = NULL;
        EVP_PKEY *pkey = NULL;
        RSA *rsa = NULL;

        BIO *bio = NULL;
        BUF_MEM *bptr = NULL;

        if (NULL != (c_cert = ssl_var_lookup(request->pool, request->server, request->connection, request, "SSL_CLIENT_CERT"))
            && NULL != (bio_cert = BIO_new_mem_buf(c_cert, strlen(c_cert)))
            && NULL != (x509 = PEM_read_bio_X509(bio_cert, NULL, NULL, NULL))
            && NULL != (pkey = X509_get_pubkey(x509))
            && NULL != (rsa = EVP_PKEY_get1_RSA(pkey))) {

            // public key modulus
            bio = BIO_new(BIO_s_mem());
            BN_print(bio, rsa->n);
            BIO_get_mem_ptr(bio, &bptr);
            pkey_n = apr_pstrndup(request->pool, bptr->data, bptr->length);
            BIO_free(bio);

            // public key exponent
            bio = BIO_new(BIO_s_mem());
            BN_print(bio, rsa->e);
            BIO_get_mem_ptr(bio, &bptr);
            pkey_e = apr_pstrndup(request->pool, bptr->data, bptr->length);
            pkey_e_i = apr_strtoi64(pkey_e, NULL, 16);
            BIO_free(bio);
        } else {
            ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, request, "WebID: invalid client SSL certificate");
        }

        if (rsa)
            RSA_free(rsa);
        if (pkey)
            EVP_PKEY_free(pkey);
        if (x509)
            X509_free(x509);
        if (bio_cert)
            BIO_free(bio_cert);
    }

    if (pkey_n != NULL && pkey_e != NULL) {
#if AP_MODULE_MAGIC_AT_LEAST(20060101,0)
        const char *san;
        char *tok;
        int i;
        for (i = 0; i < subjAltName_list->nelts; i++) {
            san = APR_ARRAY_IDX(subjAltName_list, i, const char*);
            while ((tok = get_list_item(request->pool, &san)) != NULL) {
                if (strncmp(tok, "URI:", 4) == 0) {
                    if (validate_webid(request, tok+4, pkey_n, pkey_e_i) == OK) {
                        subjAltName = tok+4;
                        r = OK;
                        break;
                    }
                }
            }
        }
#else
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, request, "WebID: subjectAltName = %s", subjAltName);
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, request, "WebID: client pkey.n  = %s", pkey_n);
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, request, "WebID: client pkey.e  = %d (%s)", pkey_e_i, pkey_e);
        const char *san = subjAltName;
        char *tok;
        while ((tok = get_list_item(request->pool, &san)) != NULL) {
            if (strncmp(tok, "URI:", 4) == 0) {
                if (validate_webid(request, tok+4, pkey_n, pkey_e_i) == OK) {
                    subjAltName = tok+4;
                    r = OK;
                    break;
                }
            }
        }
#endif
    }

    if (r == OK) {
        ap_log_rerror(APLOG_MARK, APLOG_INFO | APLOG_TOCLIENT, 0, request, "WebID: authentication (%sauthoritative) succeeded for <%s> pubkey: \"%s\", URI: <%s>", conf->authoritative?"":"non-", subjAltName, pkey_n, request->uri);
        request->user = apr_psprintf(request->connection->pool, "%s", subjAltName);
    } else {
        ap_log_rerror(APLOG_MARK, (conf->authoritative?APLOG_WARNING:APLOG_INFO) | APLOG_TOCLIENT, 0, request, "WebID: authentication (%sauthoritative) failed for <%s> pubkey: \"%s\", URI: <%s>", conf->authoritative?"":"non-", subjAltName, pkey_n, request->uri);
        subjAltName = "";
    }
    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, request, "WebID: setting cached URI <%s>", subjAltName);
    apr_pool_userdata_set(apr_pstrdup(request->connection->pool, subjAltName), UD_WEBID_KEY, NULL, request->connection->pool);

    return r;
}

static void
import_ssl_func() {
    ssl_var_lookup = APR_RETRIEVE_OPTIONAL_FN(ssl_var_lookup);
#if AP_MODULE_MAGIC_AT_LEAST(20060101,0)
    ssl_ext_list = APR_RETRIEVE_OPTIONAL_FN(ssl_ext_list);
#else
    ssl_ext_lookup = APR_RETRIEVE_OPTIONAL_FN(ssl_ext_lookup);
#endif
}
Exemple #14
0
anode_t *synthesize( DdManager *manager,  unsigned char init_flags,
                     unsigned char verbose )
{
    anode_t *strategy = NULL;
    anode_t *this_node_stack = NULL;
    anode_t *node, *new_node;
    bool initial;
    vartype *state;
    vartype **env_moves;
    int emoves_len;

    ptree_t *var_separator;
    DdNode *W;
    DdNode *strans_into_W;

    DdNode *einit, *sinit, *etrans, *strans, **egoals, **sgoals;

    DdNode *ddval;  /* Store result of evaluating a BDD */
    DdNode ***Y = NULL;
    DdNode *Y_i_primed;
    int *num_sublevels;
    DdNode ****X_ijr = NULL;

    DdNode *tmp, *tmp2;
    int i, j, r, k;  /* Generic counters */
    int offset;
    bool env_nogoal_flag = False;  /* Indicate environment has no goals */
    int loop_mode;
    int next_mode;

    int num_env, num_sys;
    int *cube;  /* length will be twice total number of variables (to
                   account for both variables and their primes). */

    /* Variables used during CUDD generation (state enumeration). */
    DdGen *gen;
    CUDD_VALUE_TYPE gvalue;
    int *gcube;

    /* Set environment goal to True (i.e., any state) if none was
       given. This simplifies the implementation below. */
    if (spc.num_egoals == 0) {
        env_nogoal_flag = True;
        spc.num_egoals = 1;
        spc.env_goals = malloc( sizeof(ptree_t *) );
        *spc.env_goals = init_ptree( PT_CONSTANT, NULL, 1 );
    }

    num_env = tree_size( spc.evar_list );
    num_sys = tree_size( spc.svar_list );

    /* State vector (i.e., valuation of the variables) */
    state = malloc( sizeof(vartype)*(num_env+num_sys) );
    if (state == NULL) {
        perror( __FILE__ ",  malloc" );
        exit(-1);
    }

    /* Allocate cube array, used later for quantifying over variables. */
    cube = (int *)malloc( sizeof(int)*2*(num_env+num_sys) );
    if (cube == NULL) {
        perror( __FILE__ ",  malloc" );
        exit(-1);
    }

    /* Chain together environment and system variable lists for
       working with BDD library. */
    if (spc.evar_list == NULL) {
        var_separator = NULL;
        spc.evar_list = spc.svar_list;  /* that this is the deterministic case
                                           is indicated by var_separator = NULL. */
    } else {
        var_separator = get_list_item( spc.evar_list, -1 );
        if (var_separator == NULL) {
            fprintf( stderr,
                     "Error: get_list_item failed on environment variables"
                     " list.\n" );
            free( state );
            free( cube );
            return NULL;
        }
        var_separator->left = spc.svar_list;
    }

    /* Generate BDDs for the various parse trees from the problem spec. */
    if (spc.env_init != NULL) {
        einit = ptree_BDD( spc.env_init, spc.evar_list, manager );
    } else {
        einit = Cudd_ReadOne( manager );
        Cudd_Ref( einit );
    }
    if (spc.sys_init != NULL) {
        sinit = ptree_BDD( spc.sys_init, spc.evar_list, manager );
    } else {
        sinit = Cudd_ReadOne( manager );
        Cudd_Ref( sinit );
    }
    if (verbose > 1)
        logprint( "Building environment transition BDD..." );
    etrans = ptree_BDD( spc.env_trans, spc.evar_list, manager );
    if (verbose > 1) {
        logprint( "Done." );
        logprint( "Building system transition BDD..." );
    }
    strans = ptree_BDD( spc.sys_trans, spc.evar_list, manager );
    if (verbose > 1)
        logprint( "Done." );

    /* Build goal BDDs, if present. */
    if (spc.num_egoals > 0) {
        egoals = malloc( spc.num_egoals*sizeof(DdNode *) );
        for (i = 0; i < spc.num_egoals; i++)
            *(egoals+i) = ptree_BDD( *(spc.env_goals+i), spc.evar_list, manager );
    } else {
        egoals = NULL;
    }
    if (spc.num_sgoals > 0) {
        sgoals = malloc( spc.num_sgoals*sizeof(DdNode *) );
        for (i = 0; i < spc.num_sgoals; i++)
            *(sgoals+i) = ptree_BDD( *(spc.sys_goals+i), spc.evar_list, manager );
    } else {
        sgoals = NULL;
    }

    if (var_separator == NULL) {
        spc.evar_list = NULL;
    } else {
        var_separator->left = NULL;
    }

    W = compute_winning_set_BDD( manager, etrans, strans, egoals, sgoals,
                                 verbose );
    if (W == NULL) {
        fprintf( stderr,
                 "Error synthesize: failed to construct winning set.\n" );
        free( state );
        free( cube );
        return NULL;
    }
    Y = compute_sublevel_sets( manager, W, etrans, strans,
                               egoals, spc.num_egoals,
                               sgoals, spc.num_sgoals,
                               &num_sublevels, &X_ijr, verbose );
    if (Y == NULL) {
        fprintf( stderr,
                 "Error synthesize: failed to construct sublevel sets.\n" );
        free( state );
        free( cube );
        return NULL;
    }

    /* The sublevel sets are exactly as resulting from the vanilla
       fixed point formula.  Thus for each system goal i, Y_0 = \emptyset,
       and Y_1 is a union of i-goal states and environment-blocking states.

       For the purpose of synthesis, it is enough to delete Y_0 and
       replace Y_1 with the intersection of i-goal states and the
       winning set, and then shift the indices down (so that Y_1 is
       now called Y_0, Y_2 is now called Y_1, etc.) */
    for (i = 0; i < spc.num_sgoals; i++) {
        Cudd_RecursiveDeref( manager, *(*(Y+i)) );
        Cudd_RecursiveDeref( manager, *(*(Y+i)+1) );
        for (r = 0; r < spc.num_egoals; r++)
            Cudd_RecursiveDeref( manager, *(*(*(X_ijr+i))+r) );
        free( *(*(X_ijr+i)) );

        *(*(Y+i)+1) = Cudd_bddAnd( manager, *(sgoals+i), W );
        Cudd_Ref( *(*(Y+i)+1) );

        (*(num_sublevels+i))--;
        for (j = 0; j < *(num_sublevels+i); j++) {
            *(*(Y+i)+j) = *(*(Y+i)+j+1);
            *(*(X_ijr+i)+j) = *(*(X_ijr+i)+j+1);
        }

        assert( *(num_sublevels+i) > 0 );
        *(Y+i) = realloc( *(Y+i), (*(num_sublevels+i))*sizeof(DdNode *) );
        *(X_ijr+i) = realloc( *(X_ijr+i),
                              (*(num_sublevels+i))*sizeof(DdNode **) );
        if (*(Y+i) == NULL || *(X_ijr+i) == NULL) {
            perror( __FILE__ ",  realloc" );
            exit(-1);
        }
    }

    /* Make primed form of W and take conjunction with system
       transition (safety) formula, for use while stepping down Y_i
       sets.  Note that we assume the variable map has been
       appropriately defined in the CUDD manager, after the call to
       compute_winning_set_BDD above. */
    tmp = Cudd_bddVarMap( manager, W );
    if (tmp == NULL) {
        fprintf( stderr,
                 "Error synthesize: Error in swapping variables with primed"
                 " forms.\n" );
        free( state );
        free( cube );
        return NULL;
    }
    Cudd_Ref( tmp );
    strans_into_W = Cudd_bddAnd( manager, strans, tmp );
    Cudd_Ref( strans_into_W );
    Cudd_RecursiveDeref( manager, tmp );

    /* From each initial state, build strategy by propagating forward
       toward the next goal (current target goal specified by "mode"
       of a state), and iterating until every reached state and mode
       combination has already been encountered (whence the
       strategy already built). */
    if (init_flags == ALL_INIT
        || (init_flags == ONE_SIDE_INIT && spc.sys_init == NULL)) {
        if (init_flags == ALL_INIT) {
            if (verbose > 1)
                logprint( "Enumerating initial states, given init_flags ="
                          " ALL_INIT" );
            tmp = Cudd_bddAnd( manager, einit, sinit );
        } else {
            if (verbose > 1)
                logprint( "Enumerating initial states, given init_flags ="
                          " ONE_SIDE_INIT and empty SYSINIT" );
            tmp = einit;
            Cudd_Ref( tmp );
        }
        Cudd_Ref( tmp );
        Cudd_AutodynDisable( manager );
        Cudd_ForeachCube( manager, tmp, gen, gcube, gvalue ) {
            initialize_cube( state, gcube, num_env+num_sys );
            while (!saturated_cube( state, gcube, num_env+num_sys )) {
                this_node_stack = insert_anode( this_node_stack, 0, -1, False,
                                                state, num_env+num_sys );
                if (this_node_stack == NULL) {
                    fprintf( stderr,
                             "Error synthesize: building list of initial"
                             " states.\n" );
                    return NULL;
                }
                increment_cube( state, gcube, num_env+num_sys );
            }
            this_node_stack = insert_anode( this_node_stack, 0, -1, False,
                                            state, num_env+num_sys );
            if (this_node_stack == NULL) {
                fprintf( stderr,
                         "Error synthesize: building list of initial"
                         " states.\n" );
                return NULL;
            }
        }
        Cudd_AutodynEnable( manager, CUDD_REORDER_SAME );
        Cudd_RecursiveDeref( manager, tmp );

    } else if (init_flags == ALL_ENV_EXIST_SYS_INIT) {
Exemple #15
0
DdNode *compute_winning_set( DdManager *manager, unsigned char verbose )
{
    int i;
    ptree_t *var_separator;
    DdNode *W;  /* Characteristic function of winning set */
    DdNode *etrans, *strans, **egoals, **sgoals;
    bool env_nogoal_flag = False;  /* Indicate environment has no goals */

    /* Set environment goal to True (i.e., any state) if none was
       given. This simplifies the implementation below. */
    if (spc.num_egoals == 0) {
        env_nogoal_flag = True;
        spc.num_egoals = 1;
        spc.env_goals = malloc( sizeof(ptree_t *) );
        *spc.env_goals = init_ptree( PT_CONSTANT, NULL, 1 );
    }

    /* Chain together environment and system variable lists for
       working with BDD library. */
    if (spc.evar_list == NULL) {
        var_separator = NULL;
        spc.evar_list = spc.svar_list;  /* that this is the deterministic case
                                           is indicated by var_separator = NULL. */
    } else {
        var_separator = get_list_item( spc.evar_list, -1 );
        if (var_separator == NULL) {
            fprintf( stderr,
                     "Error: get_list_item failed on environment variables"
                     " list.\n" );
            return NULL;
        }
        var_separator->left = spc.svar_list;
    }

    /* Generate BDDs for the various parse trees from the problem spec. */
    if (verbose > 1)
        logprint( "Building environment transition BDD..." );
    etrans = ptree_BDD( spc.env_trans, spc.evar_list, manager );
    if (verbose > 1) {
        logprint( "Done." );
        logprint( "Building system transition BDD..." );
    }
    strans = ptree_BDD( spc.sys_trans, spc.evar_list, manager );
    if (verbose > 1)
        logprint( "Done." );

    /* Build goal BDDs, if present. */
    if (spc.num_egoals > 0) {
        egoals = malloc( spc.num_egoals*sizeof(DdNode *) );
        for (i = 0; i < spc.num_egoals; i++)
            *(egoals+i) = ptree_BDD( *(spc.env_goals+i), spc.evar_list, manager );
    } else {
        egoals = NULL;
    }
    if (spc.num_sgoals > 0) {
        sgoals = malloc( spc.num_sgoals*sizeof(DdNode *) );
        for (i = 0; i < spc.num_sgoals; i++)
            *(sgoals+i) = ptree_BDD( *(spc.sys_goals+i), spc.evar_list, manager );
    } else {
        sgoals = NULL;
    }

    /* Break the link that appended the system variables list to the
       environment variables list. */
    if (var_separator == NULL) {
        spc.evar_list = NULL;
    } else {
        var_separator->left = NULL;
    }

    W = compute_winning_set_BDD( manager, etrans, strans, egoals, sgoals,
                                 verbose );

    Cudd_RecursiveDeref( manager, etrans );
    Cudd_RecursiveDeref( manager, strans );
    for (i = 0; i < spc.num_egoals; i++)
        Cudd_RecursiveDeref( manager, *(egoals+i) );
    for (i = 0; i < spc.num_sgoals; i++)
        Cudd_RecursiveDeref( manager, *(sgoals+i) );
    if (spc.num_egoals > 0)
        free( egoals );
    if (spc.num_sgoals > 0)
        free( sgoals );
    if (env_nogoal_flag) {
        spc.num_egoals = 0;
        delete_tree( *spc.env_goals );
        free( spc.env_goals );
    }

    return W;
}
Exemple #16
0
int
rs_read_thing(FILE *inf, THING *t)
{
    int listid = 0, index = -1;
    THING *item;

    if (read_error || format_error)
        return(READSTAT);

    rs_read_marker(inf, RSID_THING);

    rs_read_int(inf, &index);

    if (index == 0)
        return(READSTAT);

    rs_read_coord(inf,&t->_t._t_pos);
    rs_read_boolean(inf,&t->_t._t_turn);
    rs_read_char(inf,&t->_t._t_type);
    rs_read_char(inf,&t->_t._t_disguise);
    rs_read_char(inf,&t->_t._t_oldch);
            
    /* 
        t_dest can be (listid,index):
        0,0: NULL
        0,1: location of hero
        1,i: location of a thing (monster)
        2,i: location of an object
        3,i: location of gold in a room

        We need to remember what we are chasing rather than 
        the current location of what we are chasing.
    */
            
    rs_read_int(inf, &listid);
    rs_read_int(inf, &index);
    t->_t._t_reserved = -1;

    if (listid == 0) /* hero or NULL */
    {
        if (index == 1)
            t->_t._t_dest = &hero;
        else
            t->_t._t_dest = NULL;
    }
    else if (listid == 1) /* monster/thing */
    {
        t->_t._t_dest     = NULL;
        t->_t._t_reserved = index;
    }
    else if (listid == 2) /* object */
    {
        THING *obj;

        item = get_list_item(lvl_obj, index);

        if (item != NULL)
        {
            obj = item;
            t->_t._t_dest = &obj->o_pos;
        }
    }
    else if (listid == 3) /* gold */
    {
        t->_t._t_dest = &rooms[index].r_gold;
    }
    else
        t->_t._t_dest = NULL;
            
    rs_read_short(inf,&t->_t._t_flags);
    rs_read_stats(inf,&t->_t._t_stats);
    rs_read_room_reference(inf, &t->_t._t_room);
    rs_read_object_list(inf,&t->_t._t_pack);
    
    return(READSTAT);
}
Exemple #17
0
void comms_process_data (void)
{

	session_list_data_type
		*current_session;

	connection_list_type
		*this_connection,
		*connection;

	char
		*received_data;

	int
		planner_event,
		frame_id,
		packet_id,
		receive_flag,
		received_size;

	GUID
		received_id = 0;

	entity
		*member;

	send_types
		send_type;

	packet_types
		type;

	// receive all packets in queue

	current_session = get_current_game_session ();

	received_size = MAX_RECEIVE_SIZE;

	connection = get_connection_list_head ();

	while (connection)
	{

		this_connection = connection;

		connection = connection->next;

		send_type = SEND_TYPE_GROUP;

		while (send_type >= SEND_TYPE_PERSONAL)
		{

			receive_flag = TRUE;

			while (receive_flag)
			{

				type = process_packet_list (send_type, this_connection, &received_id, &received_data, &received_size);

				switch (type)
				{

					///////////////////////////////////////////////////////////////////////////////////////////////
					//
					// System packets, used internally
					//
					///////////////////////////////////////////////////////////////////////////////////////////////

					case PACKET_TYPE_INVALID:
					{

						receive_flag = FALSE;

						if (get_comms_model () == COMMS_MODEL_SERVER)
						{

							if (this_connection->packet_rerequested > command_line_comms_packet_rerequest_limit)
							{

								debug_log ("COMM_MAN: REJECTING CONNECTION. CONNECTION TOO BAD (re-request limit %d reached)", command_line_comms_packet_rerequest_limit);

								send_packet (this_connection->connection_id, PACKET_TYPE_SERVER_REJECTED, NULL, 0, SEND_TYPE_PERSONAL);
							}
						}

						break;
					}

					case PACKET_TYPE_RESEND_PACKET:
					{

						send_types
							resend_send_type;

						frame_id = get_list_item (received_data, int);

						packet_id = get_list_item (received_data, int);

						resend_send_type = get_list_item (received_data, send_types);

						#if DEBUG_MODULE

						if (this_connection->pilot_entity)
						{

							debug_log ("COMMS MAN: received RESEND PACKET for frame %d packet %d from %s (dpid %d)",
											frame_id, packet_id,
											get_local_entity_string (this_connection->pilot_entity, STRING_TYPE_PILOTS_NAME),
											received_id);
						}
						else
						{

							debug_log ("COMMS MAN: received RESEND PACKET by unknown (pdid %d)",
											received_id);
						}

						#endif

						resend_packet (received_id, frame_id, packet_id, resend_send_type);

						break;
					}

					///////////////////////////////////////////////////////////////////////////////////////////////
					//
					// Packets for initialisation and joining
					//
					///////////////////////////////////////////////////////////////////////////////////////////////

					case PACKET_TYPE_SESSION_QUERY:
					{

						char
							*ptr;

						int
							server_version_number,
							player_count,
							size;

						connection_list_type
							*new_connection;

						if (get_comms_model () == COMMS_MODEL_SERVER)
						{

							#if DEBUG_MODULE

							if (this_connection->pilot_entity)
							{

								debug_log ("COMMS MAN: RECEIVED SESSION QUERY from %s (dpid %d)",
												get_local_entity_string (this_connection->pilot_entity, STRING_TYPE_PILOTS_NAME),
												received_id);
							}
							else
							{

								debug_log ("COMMS MAN: RECEIVED SESSION QUERY from %d", received_id);
							}

							#endif

							new_connection = get_connection_list_item (received_id);

							if (!new_connection->already_sent_query_data)
							{

								new_connection->already_sent_query_data = TRUE;

								while (TRUE)
								{

									ptr = new_connection->connection_receive_buffer;

									size = 0;

									/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
									//
									// Check both client and server are running same campaign data
									//
									server_version_number = get_local_entity_int_value (get_session_entity (), INT_TYPE_VERSION_NUMBER);

									quick_set_list_item (ptr, int, server_version_number);

									size += sizeof (int);
									//
									/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

									// map details

									quick_set_list_item (ptr, int, NUM_MAP_X_SECTORS);

									quick_set_list_item (ptr, int, NUM_MAP_Z_SECTORS);

									quick_set_list_item (ptr, int, SECTOR_SIDE_LENGTH);

									size += sizeof (int) * 3;

									// data path

									strcpy (ptr, current_session->data_path);

									ptr += strlen (current_session->data_path) + 1;

									size += strlen (current_session->data_path) + 1;

									// population_placement filename

									if (population_placement_filename)
									{

										strcpy (ptr, population_placement_filename);

										ptr += strlen (population_placement_filename) + 1;

										size += strlen (population_placement_filename) + 1;
									}
									else
									{

										strcpy (ptr, "\0");

										ptr += strlen ("\0") + 1;

										size += strlen ("\0") + 1;
									}

									//

									// side_data filename

									if (side_data_filename)
									{

										strcpy (ptr, side_data_filename);

										ptr += strlen (side_data_filename) + 1;

										size += strlen (side_data_filename) + 1;
									}
									else
									{

										strcpy (ptr, "\0");

										ptr += strlen ("\0") + 1;

										size += strlen ("\0") + 1;
									}

									// campaign_population filename

									if (campaign_population_filename)
									{

										strcpy (ptr, campaign_population_filename);

										ptr += strlen (campaign_population_filename) + 1;

										size += strlen (campaign_population_filename) + 1;
									}
									else
									{

										strcpy (ptr, "\0");

										ptr += strlen ("\0") + 1;

										size += strlen ("\0") + 1;
									}

									//
									// planner position and zoom
									//

//									quick_set_list_item (ptr, float, planner_map_data.centre_map_x);

//									quick_set_list_item (ptr, float, planner_map_data.centre_map_z);

//									size += sizeof (float) * 2;

//									quick_set_list_item (ptr, int, planner_map_data.map_zoom);

//									size += sizeof (int);

									//
									// Pilots
									//

									player_count = get_number_of_connected_players ();

									quick_set_list_item (ptr, int, player_count);

									size += sizeof (int);

									//
									//
									//

									#if DEBUG_MODULE

									debug_log ("COMM_MAN: sending data path %s, population placement %s, side data %s, campaign_pop file %s",
													current_session->data_path, population_placement_filename, side_data_filename, campaign_population_filename);

									#endif

									new_connection->connection_receive_buffer_size -= size;

									if (!pack_session (ptr, &new_connection->connection_receive_buffer_size, PACK_MODE_BROWSE_SESSION))
									{

										break;
									}

									new_connection->connection_receive_buffer_size *= 2;

									#if DEBUG_MODULE

									debug_log ("COMMS MAN: Browse: connection_receive_buffer too small, mallocing to %d", new_connection->connection_receive_buffer_size);

									#endif

									free_mem (new_connection->connection_receive_buffer);

									new_connection->connection_receive_buffer = malloc_heap_mem (new_connection->connection_receive_buffer_size);
								}

								//
								//
								//

								send_packet (received_id, PACKET_TYPE_SESSION_INFO, new_connection->connection_receive_buffer, new_connection->connection_receive_buffer_size + size, SEND_TYPE_PERSONAL);

								/*
								{

									FILE
										*test_ptr;

									test_ptr = fopen ("out.txt", "wb");

									fwrite (new_connection->connection_receive_buffer, 1, new_connection->connection_receive_buffer_size + size, test_ptr);

									fclose (test_ptr);
								}
								*/
							}
							else
							{

								debug_log ("COMM_MAN: not resending query data");
							}
						}

						break;
					}

					case PACKET_TYPE_CONNECTION_VALIDATION:
					{

						debug_log ("COMM_MAN: received CONNECTION_VALIDATION, sending RESPONSE");

						send_packet (received_id, PACKET_TYPE_CONNECTION_RESPONSE, NULL, 0, SEND_TYPE_PERSONAL);

						break;
					}

					case PACKET_TYPE_CONNECTION_RESPONSE:
					{

						connection_list_type
							*connection;

						connection = get_connection_list_item (received_id);

						connection->validation_count = 0;

						debug_log ("COMM_MAN: received CONNECTION_RESPONSE, connection still alive");

						break;
					}

					case PACKET_TYPE_SESSION_INFO:
					{

						entity
							*force,
							*pilot;

						int
							client_version_number,
							server_version_number;

						int
							size,
							x_size,
							z_size,
							sector_size,
							player_count,
							loop;

						char
							*ptr,
							warzone_ffp_filename [256],
							temp_campaign_population_filename [256],
							temp_population_placement_filename [256],
							temp_side_data_filename [256],
							buffer [128];

						session_data = FALSE;

						reinitialise_entity_system ();

						ptr = received_data;

						size = 0;

						set_ui_object_redraw (gunships_screen, TRUE);

						ui_force_update ();

						/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
						//
						// Check both client and server are running same campaign data
						//
						client_version_number = get_global_version_number ();

						server_version_number = get_list_item (ptr, int);

						size += sizeof (int);

						if (client_version_number != server_version_number)
						{

							debug_fatal ("COMM_MAN: Incorrect version. Server Version No. %d, Client Version No. %d", server_version_number, client_version_number);
						}
						//
						/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

						// map details

						x_size = get_list_item (ptr, int);

						z_size = get_list_item (ptr, int);

						sector_size = get_list_item (ptr, int);

						size += (sizeof (int) * 3);

						set_entity_world_map_size (x_size, z_size, sector_size);

						// data path

						strncpy (current_session->data_path, ptr, sizeof (current_session->data_path));

						ptr += strlen (current_session->data_path) + 1;

						size += strlen (current_session->data_path) + 1;

						// population_placement_filename

						strncpy (temp_population_placement_filename, ptr, sizeof (temp_population_placement_filename));

						ptr += strlen (temp_population_placement_filename) + 1;

						size += strlen (temp_population_placement_filename) + 1;

						if (population_placement_filename)
						{

							free_mem (population_placement_filename);
						}

						if (strlen (temp_population_placement_filename) > 0)
						{

							population_placement_filename = (char *) malloc_heap_mem (strlen (temp_population_placement_filename) + 1);

							sprintf (population_placement_filename, "%s", temp_population_placement_filename);
						}
						else
						{

							population_placement_filename = NULL;
						}

						// side_data filename

						strncpy (temp_side_data_filename, ptr, sizeof (temp_side_data_filename));

						ptr += strlen (temp_side_data_filename) + 1;

						size += strlen (temp_side_data_filename) + 1;

						if (side_data_filename)
						{

							free_mem (side_data_filename);
						}

						if (strlen (temp_side_data_filename) > 0)
						{

							side_data_filename = (char *) malloc_heap_mem (strlen (temp_side_data_filename) + 1);

							sprintf (side_data_filename, "%s", temp_side_data_filename);
						}
						else
						{

							side_data_filename = NULL;
						}

						// campaign_population_filename

						strncpy (temp_campaign_population_filename, ptr, sizeof (temp_campaign_population_filename));

						ptr += strlen (temp_campaign_population_filename) + 1;

						size += strlen (temp_campaign_population_filename) + 1;

						if (campaign_population_filename)
						{

							free_mem (campaign_population_filename);
						}

						if (strlen (temp_campaign_population_filename) > 0)
						{

							campaign_population_filename = (char *) malloc_heap_mem (strlen (temp_campaign_population_filename) + 1);

							sprintf (campaign_population_filename, "%s", temp_campaign_population_filename);
						}
						else
						{

							campaign_population_filename = NULL;
						}

						//
						//
						//

						player_count = get_list_item (ptr, int);

						size += sizeof (int);

						//
						//
						//

						received_size -= size;

						#if DEBUG_MODULE

						debug_log ("COMM_MAN: data path %s population placement filename %s, side data filename %s", current_session->data_path, population_placement_filename, side_data_filename);

						debug_log ("COMM_MAN: campaign data path = %s", current_session->data_path);

						#endif

						//
						// check we have the correct warzone locally
						//

						sprintf (warzone_ffp_filename, "%s\\terrain\\terrain.ffp", current_session->data_path);

						if (!file_exist (warzone_ffp_filename))
						{

							add_to_pop_up_list_with_word_wrap (get_trans ("UNRECOGNISED_WARZONE"), session_info_list, NULL, 0, UI_FONT_ARIAL_10, sys_col_white);
							//add_to_pop_up_list (get_trans ("Server using unrecognised warzone"), session_info_list, NULL, 0, UI_FONT_ARIAL_10, sys_col_white);

							break;
						}

						//
						//
						//

						create_local_only_entities (PACK_MODE_BROWSE_SESSION);

						if (unpack_session (ptr, received_size, PACK_MODE_BROWSE_SESSION))
						{

							debug_fatal ("COMMS MAN: browse: received size overflow");
						}

						#if DEBUG_MODULE

						if (this_connection->pilot_entity)
						{

							debug_log ("COMMS MAN: received SESSION INFO from %s (dpid %d) (setting server id)",
											get_local_entity_string (this_connection->pilot_entity, STRING_TYPE_PILOTS_NAME),
											received_id);
						}
						else
						{

							debug_log ("COMMS MAN: RECEIVED SESSION INFO from %d", received_id);
						}

						debug_log ("COMMS MAN: session info: time of day = %f",
										get_local_entity_float_value (get_session_entity (), FLOAT_TYPE_TIME_OF_DAY));

						debug_log ("COMMS MAN: map dimensions %d, %d, sector size %d", x_size, z_size, sector_size);

						#endif

						set_ui_object_drawable (session_screen_next_button, TRUE);

						//
						// Display game info
						//

						ui_object_destroy_list_items (session_info_list);

						if (get_local_entity_int_value (get_session_entity (), INT_TYPE_CAMPAIGN_REQUIRES_APACHE_HAVOC))
						{

							// campaign requires apache havoc to be installed
							// check it is...

							if (!get_global_apache_havoc_installed ())
							{

								add_to_pop_up_list_with_word_wrap (get_trans ("REQUIRES_APACHE_HAVOC"), session_info_list, NULL, 0, UI_FONT_ARIAL_10, sys_col_white);

								set_ui_object_drawable (session_screen_next_button, FALSE);

								break;
							}
						}

						loop = 3;

						sprintf (buffer, "%s : %d", get_trans ("Players"), player_count);

						add_to_pop_up_list_with_word_wrap (buffer, session_info_list, NULL, 0, UI_FONT_ARIAL_10, sys_col_white);

						force = get_local_entity_first_child (get_session_entity (), LIST_TYPE_FORCE);

						while (force)
						{

							pilot = get_local_entity_first_child (force, LIST_TYPE_PILOT);

							while (pilot)
							{
								{
									rgb_colour
										col;

									sprintf (buffer, "%2d  ", loop - 2);

									strncat (buffer, get_local_entity_string (pilot, STRING_TYPE_PILOTS_NAME), 64);

									switch (get_local_entity_int_value (pilot, INT_TYPE_SIDE))
									{
										case ENTITY_SIDE_BLUE_FORCE:
										{
											col.r = 120;
											col.g = 158;
											col.b = 255;
											col.a = 255;

											break;
										}
										case ENTITY_SIDE_RED_FORCE:
										{
											col.r = 255;
											col.g = 120;
											col.b = 80;
											col.a = 255;

											break;
										}
										default:
										{
									      col = ui_colour_white;

											break;
										}
									}

									add_to_pop_up_list_with_word_wrap (buffer, session_info_list, NULL, 0, UI_FONT_ARIAL_10, col);

									loop ++;
								}

								pilot = get_local_entity_child_succ (pilot, LIST_TYPE_PILOT);
							}

							force = get_local_entity_child_succ (force, LIST_TYPE_FORCE);
						}

						set_server_id (received_id);

						//
						// destroy all entities created by browse info
						//

						reinitialise_entity_system ();

						break;
					}

					case PACKET_TYPE_CLIENT_PILOT_REQUEST:
					{

						connection_list_type
							*new_connection;

						client_pilot_request_data
							pilot_data;

						entity
							*new_pilot;

						int
							index;

						ASSERT (get_comms_model () == COMMS_MODEL_SERVER);

//						#if DEBUG_MODULE

						debug_log ("COMMS MAN: RECEIVED PILOT REQUEST from %d", received_id);

//						#endif

						//
						// unpack name
						//

						memcpy (&pilot_data, (client_pilot_request_data *) received_data, sizeof (client_pilot_request_data));

						new_pilot = create_new_pilot_entity
										(
											pilot_data.name,
											pilot_data.side,
											pilot_data.rank,
											pilot_data.sub_type,
											pilot_data.unique_id,
											pilot_data.difficulty
										);

						ASSERT (new_pilot);

						index = get_local_entity_safe_index (new_pilot);

						new_connection = get_connection_list_item (received_id);

						transmit_entity_comms_message (ENTITY_COMMS_PILOT_REQUEST_ACCEPTED, NULL, received_id, index);

						new_connection->pilot_entity = new_pilot;

						break;
					}

					case PACKET_TYPE_CLIENT_GUNSHIP_REQUEST:
					{

						connection_list_type
							*new_connection;

						client_gunship_request_data
							pilot_data;

						int
							index_number,
							buffer [2];

						if (get_comms_model () == COMMS_MODEL_SERVER)
						{

//							#if DEBUG_MODULE

							if (this_connection->pilot_entity)
							{

								debug_log ("COMMS MAN: RECEIVED GUNSHIP REQUEST from %s (dpid %d)",
												get_local_entity_string (this_connection->pilot_entity, STRING_TYPE_PILOTS_NAME),
												received_id);
							}
							else
							{

								debug_log ("COMMS MAN: RECEIVED GUNSHIP REQUEST from %d", received_id);
							}

//							#endif

							memcpy (&pilot_data, (client_gunship_request_data *) received_data, sizeof (client_gunship_request_data));

							index_number = pilot_data.gunship_index;

							ASSERT (index_number != ENTITY_INDEX_DONT_CARE);

							member = get_local_entity_safe_ptr (index_number);

							if (!member)
							{
//								#if DEBUG_MODULE

								if (this_connection->pilot_entity)
								{

									debug_log ("COMMS MAN: REFUSING GUNSHIP FOR PLAYER %s (dpid %d) for helicopter %d",
													get_local_entity_string (this_connection->pilot_entity, STRING_TYPE_PILOTS_NAME),
													received_id, pilot_data.gunship_index);
								}
								else
								{

									debug_log ("COMMS MAN: Refusing gunship for player %d to helicopter %d", received_id, pilot_data.gunship_index);
								}

//								#endif

								send_packet (received_id, PACKET_TYPE_GUNSHIP_REQUEST_REFUSED, NULL, 0, SEND_TYPE_PERSONAL);

								break;
							}

							new_connection = get_connection_list_item (received_id);

							//
							// send acceptance
							//

							buffer [0] = index_number;

//							#if DEBUG_MODULE

							debug_log ("COMMS MAN: sending gunship request accepted for gunship %d pilot id %d", index_number, received_id);

//							#endif

							send_packet (received_id, PACKET_TYPE_GUNSHIP_REQUEST_ACCEPTED, (void *) &buffer, 4, SEND_TYPE_PERSONAL);

							new_connection->gunship_number = pilot_data.gunship_index;

							new_connection->gunship_entity = member;
						}

						break;
					}

					case PACKET_TYPE_CLIENT_CAMPAIGN_DATA_REQUEST:
					{

						connection_list_type
							*new_connection;

						int
							index_number;

						if (get_comms_model () == COMMS_MODEL_SERVER)
						{

							#if DEBUG_MODULE

							if (this_connection->pilot_entity)
							{

								debug_log ("COMMS MAN: RECEIVED JOIN REQUEST by %s (dpid %d)",
												get_local_entity_string (this_connection->pilot_entity, STRING_TYPE_PILOTS_NAME),
												received_id);
							}
							else
							{

								debug_log ("COMMS MAN: received JOIN REQUEST by %d", received_id);
							}

							#endif

							//
							// flush group send buffer
							//

							send_comms_data ();

							//
							// pack mission data into packet
							//

							new_connection = get_connection_list_item (received_id);

							//
							// Store entity data
							//

							while (pack_session (new_connection->connection_receive_buffer, &new_connection->connection_receive_buffer_size, PACK_MODE_CLIENT_SESSION))
							{

								new_connection->connection_receive_buffer_size *= 2;

								#if DEBUG_MODULE

								debug_log ("COMMS MAN: Mission data: connection_receive_buffer too small, mallocing to %d", new_connection->connection_receive_buffer_size);

								#endif

								free_mem (new_connection->connection_receive_buffer);

								new_connection->connection_receive_buffer = malloc_heap_mem (new_connection->connection_receive_buffer_size);

								memset (new_connection->connection_receive_buffer, 0, new_connection->connection_receive_buffer_size);
							}

							// add frame id
							index_number = get_group_frame_id ();
							memcpy (&new_connection->connection_receive_buffer [new_connection->connection_receive_buffer_size], (void *) &index_number, sizeof (int));
							new_connection->connection_receive_buffer_size += sizeof (int);

							send_packet (received_id, PACKET_TYPE_MISSION_DATA, new_connection->connection_receive_buffer, new_connection->connection_receive_buffer_size, SEND_TYPE_PERSONAL);

							memset (new_connection->connection_receive_buffer, 0, new_connection->connection_receive_buffer_size);

							//
							// send group frame id
							//

							SDL_Delay (100);

							index_number = get_group_frame_id ();

							//send_packet (received_id, PACKET_TYPE_FRAME_ID, (void *) &index_number, 4, SEND_TYPE_PERSONAL);

							zero_average_pack_size ();
						}

						break;
					}

					case PACKET_TYPE_CLIENT_FRAME_ID:
					{

						int
							loop1,
							loop2,
							index_number;

						stub_packet_type
							*stub_packet;

						connection_list_type
							*new_connection;

						index_number = get_list_item (received_data, int);

						new_connection = get_connection_list_item (received_id);

						//#if DEBUG_MODULE

						if (new_connection)
						{

							debug_log ("COMMS MAN: received CLIENT FRAME ID (%d) by %d %s", index_number, received_id, direct_play_get_player_name (received_id));
						}

						//#endif

						//
						// send all packets between when the client started to join and when it actually joined.
						//

						for (loop1 = index_number; loop1 < get_group_frame_id () - 1; loop1 ++)
						{

							//#if DEBUG_MODULE

							debug_log ("COMMS MAN: sending packet %d frame %d to recently joined client", loop1, 0);

							//#endif

							stub_packet = resend_packet (received_id, loop1, 1, SEND_TYPE_GROUP);

							ASSERT (stub_packet);

							for (loop2 = 2; loop2 <= stub_packet->packet->number_of_packets; loop2 ++)
							{

								//#if DEBUG_MODULE

								debug_log ("COMMS MAN: sending packet %d frame %d to recently joined client", loop1, loop2);

								//#endif

								stub_packet = resend_packet (received_id, loop1, loop2, SEND_TYPE_GROUP);
							}
						}

						break;
					}

					case PACKET_TYPE_GUNSHIP_REQUEST_REFUSED:
					{

//						#if DEBUG_MODULE

						debug_log ("COMMS MAN: Gunship refused");

//						#endif

						set_server_response (SERVER_RESPONSE_REFUSE);

						break;
					}

					case PACKET_TYPE_GUNSHIP_REQUEST_ACCEPTED:
					{

						entity
							*gunship;

						int
							index_number;

//						#if DEBUG_MODULE

						debug_log ("COMMS MAN: received GUNSHIP ACCEPTED by %d", received_id);

//						#endif

						//
						// set gunship
						//

						index_number = get_list_item (received_data, int);

						ASSERT (get_pilot_entity ());

						gunship = get_local_entity_safe_ptr (index_number);

						debug_filtered_log ("COMM_MAN: setting gunship");

						planner_event = FALSE;

						if (get_event_stack_head_function() == ingame_screen_set_events)
						{

							pop_event (ingame_screen_set_events);

							planner_event = TRUE;
						}

						assign_entity_to_user (gunship);

						if (planner_event)
						{

							push_event (ingame_screen_set_events, "ingame screen events");
						}

						debug_filtered_log ("COMM_MAN: gunship set");

						////////////////////////////////////////////////////////////////////////

						break;
					}

					case PACKET_TYPE_PILOT_REQUEST_ACCEPTED:
					{

						int
							index_number;

						ASSERT (get_comms_model () == COMMS_MODEL_CLIENT);

//						#if DEBUG_MODULE

						debug_log ("COMMS MAN: received PILOT ACCEPTED by %d", received_id);

//						#endif

						index_number = get_list_item (received_data, int);

						set_pilot_entity (get_local_entity_safe_ptr (index_number));

						break;
					}

					case PACKET_TYPE_MISSION_DATA:
					{

						#if DEBUG_MODULE

						debug_log ("COMMS MAN: received MISSION DATA by %d", received_id);

						#endif

						set_mouse_graphic_off ();

						//
						// LOAD TERRAIN DATA
						//

						load_3d_terrain_game_data ();

						initialise_population_name_database ();

						load_route_data (); // might need to send what route filename to load...

						//
						// Initialise stuff
						//

						create_local_only_entities (PACK_MODE_CLIENT_SESSION);

						/////////////////////////////////////////////////////////////////
						if (strstr ((char*) stoupper (side_data_filename), "SID"))
						{

							read_sector_side_file (side_data_filename);
						}
						else if (strstr ((char*) stoupper (side_data_filename), "DAT"))
						{

							load_ai_sector_data (side_data_filename);
						}
						/////////////////////////////////////////////////////////////////

						deinitialise_formation_database ();

						initialise_formation_database ();

						deinitialise_formation_component_database ();

						initialise_formation_component_database ();

						if (unpack_session (received_data, received_size - 4, PACK_MODE_CLIENT_SESSION))
						{

							debug_fatal ("COMMS MAN: received size overflow");
						}
/*
						force = get_local_entity_first_child (get_session_entity (), LIST_TYPE_FORCE);

						while (force)
						{

							create_frontline (force);

							force = get_local_entity_child_succ (force, LIST_TYPE_FORCE);
						}

*/
						{
							int
								index_number;

							connection_list_type
								*new_connection;

							received_data += received_size - 4;
							index_number = get_list_item (received_data, int);

							new_connection = get_connection_list_item (received_id);

							new_connection->receive_group_frame_id = index_number;

							send_packet (get_server_id (), PACKET_TYPE_CLIENT_FRAME_ID, (void *) &index_number, 4, SEND_TYPE_PERSONAL);
						}

						session_data = TRUE;

						//direct_play_join_group ();

						set_gunship_waiting_for_connection ( FALSE );

						zero_average_pack_size ();

						set_mouse_graphic_on ();

						break;
					}

					case PACKET_TYPE_FRAME_ID:
					{

						int
							index_number;

						connection_list_type
							*new_connection;

						index_number = get_list_item (received_data, int);

						#if DEBUG_MODULE

						debug_log ("COMMS MAN: received FRAME ID (%d) by %d", index_number, received_id);

						#endif

						new_connection = get_connection_list_item (received_id);

						new_connection->receive_group_frame_id = index_number;

						send_packet (get_server_id (), PACKET_TYPE_CLIENT_FRAME_ID, (void *) &index_number, 4, SEND_TYPE_PERSONAL);

						break;
					}

					///////////////////////////////////////////////////////////////////////////////////////////////
					//
					// In game packets
					//
					///////////////////////////////////////////////////////////////////////////////////////////////

					case PACKET_TYPE_AI_DATA:
					{

						int
							//padding,
							data_size;

						#if DEBUG_MODULE >= 2

						debug_log ("COMMS MAN: received AI DATA by %d", received_id);

						#endif

						if (get_comms_model () == COMMS_MODEL_CLIENT)
						{

							ASSERT (session_data);
						}

						data_size = get_list_item (received_data, int);

						//debug
						//padding = get_list_item (received_data, int);
						//end

						open_unpack_buffer (received_data, received_size);

						process_received_entity_comms_messages ();

						ASSERT (!get_unpack_buffer_overflow ());

						close_unpack_buffer ();

						//debug
						//padding = get_list_item (received_data, int);
						//end

						memset (received_data, 0, this_connection->connection_receive_buffer_size);

						break;
					}

					case PACKET_TYPE_END_GAME:
					{

						debug_log ("COMMS MAN: received END GAME from %d", received_id);

						if (get_comms_model () == COMMS_MODEL_SERVER)
						{
							if (this_connection->gunship_entity)
							{

								set_client_server_entity_int_value (this_connection->gunship_entity, INT_TYPE_PLAYER, ENTITY_PLAYER_AI);
							}

							if (this_connection->pilot_entity)
							{

								debug_log ("	from %s ", get_local_entity_string (this_connection->pilot_entity, STRING_TYPE_PILOTS_NAME));
							}

							unregister_connection (received_id);
						}
						else
						{

							if (received_id == get_server_id ())
							{

								//setup_campaign_over_screen (get_local_force_entity (get_global_gunship_side ()), CAMPAIGN_RESULT_STALEMATE);

								start_game_exit (GAME_EXIT_KICKOUT, FALSE);
							}
						}

						receive_flag = FALSE;

						break;
					}

					case PACKET_TYPE_SERVER_REJECTED:
					{

						debug_log ("COMMS MAN: received SERVER REJECTED (server id %d)", received_id);

						//setup_campaign_over_screen (get_local_force_entity (get_global_gunship_side ()), CAMPAIGN_RESULT_SERVER_REJECTED);

						start_game_exit (GAME_EXIT_KICKOUT, FALSE);

						break;
					}

					default:
					{

						debug_fatal ("ERROR: Data Exchange, unknown packet type %d", type);

						break;
					}
				}
			}

			send_type --;
		}
	}
}