Ejemplo n.º 1
0
Archivo: main.c Proyecto: Zabrane/SPOCP
int
main(int argc, char **argv)
{
	int             debug = 0, conftest = 0, nodaemon = 0;
	int             i = 0;
	unsigned int    clilen;
	struct sockaddr_in cliaddr;
	struct timeval  start, end;
	char           *cnfg = DEF_CNFG;
	char		localhost[MAXNAMLEN + 1], path[MAXNAMLEN + 1];
	FILE           *pidfp;
	octet_t         oct;
	ruleset_t      *rs;

	/*
	 * Who am I running as ? 
	 */

	uname(&myname);

	/*
	 * spocp_err = 0 ;
	 */

	memset(&srv, 0, sizeof(srv_t));

	pthread_mutex_init(&(srv.mutex), NULL);
	pthread_mutex_init(&(srv.mlock), NULL);

	gethostname(localhost, MAXNAMLEN);
#ifdef HAVE_GETDOMAINNAME
	getdomainname(path, MAXNAMLEN);
#else
	{
		char *pos;
		if(pos = strstr(localhost, ".")) strncpy(path, pos+1, MAXNAMLEN);
		else strcpy(path, "");
	}
#endif

	if (0)
		printf("Domain: %s\n", path);

	srv.hostname = Strdup(localhost);

	/*
	 * truncating input strings to reasonable length
	 */
	for (i = 0; i < argc; i++)
		if (strlen(argv[i]) > 512)
			argv[i][512] = '\0';

	while ((i = getopt(argc, argv, "Dhrtf:d:")) != EOF) {
		switch (i) {

		case 'D':
			nodaemon = 1;
			break;

		case 'f':
			cnfg = Strdup(optarg);
			break;

		case 'd':
			debug = atoi(optarg);
			if (debug < 0)
				debug = 0;
			break;

		case 't':
			conftest = 1;
			break;

		case 'r':
			srv.readonly = 1;

		case 'h':
		default:
			fprintf(stderr, "Usage: %s [-t] ", argv[0]);
			fprintf(stderr, "[-f configfile] ");
			fprintf(stderr, "[-D] [-d debuglevel]\n");
			exit(0);
		}
	}

	srv.root = ruleset_new(0);

	if (srv_init(&srv, cnfg) < 0)
		exit(1);

	if (srv.port && srv.uds) {
		fprintf(stderr,
			"Sorry are not allowed to listen on both a unix domain socket and a port\n");
		exit(1);
	}

	if (srv.logfile)
		spocp_open_log(srv.logfile, debug);
	else if (debug)
		spocp_open_log(0, debug);

	if (srv.name){
		localcontext = (char *) Calloc(strlen(srv.name) + strlen("//") + 1,
				       sizeof(char));

		/* Flawfinder: ignore */
		sprintf(localcontext, "//%s", srv.name);		
	}
	else {
		localcontext = (char *) Calloc(strlen(localhost) + strlen("//") + 1,
				       sizeof(char));

		/* Flawfinder: ignore */
		sprintf(localcontext, "//%s", localhost);
	}

	/*
	 * where I put the access rules for access to this server and its
	 * rules 
	 */
	snprintf(path, MAXNAMLEN, "%s/server", localcontext);
	oct_assign(&oct, path);
	if ((rs = ruleset_create(&oct, srv.root)) == 0)
		exit(1);

	rs->db = db_new();

	/*
	 * access rules for operations 
	 */
	snprintf(path, MAXNAMLEN, "%s/operation", localcontext);
	oct_assign(&oct, path);
	if ((rs = ruleset_create(&oct, srv.root)) == 0)
		exit(1);

	rs->db = db_new();


	LOG(SPOCP_INFO) {
		traceLog(LOG_INFO, "Local context: \"%s\"", localcontext);
		traceLog(LOG_INFO, "initializing backends");
		if (srv.root->db)
			plugin_display(srv.plugin);
	}

	if (srv.plugin) {
		run_plugin_init(&srv);
	}

	if ( get_rules( &srv ) != SPOCP_SUCCESS ) 
		exit(1);

	/*ruleset_tree( srv.root, 0);*/

	/* If only testing configuration and rulefile this is as far as I go */
	if (conftest) {
		traceLog(LOG_INFO,"Configuration was OK");
		exit(0);
	}

	gettimeofday(&start, NULL);

	if (srv.port || srv.uds) {

		/*
		 * stdin and stdout will not be used from here on, close to
		 * save file descriptors 
		 */

		fclose(stdin);
		fclose(stdout);

#ifdef HAVE_SSL
		/*
		 * ---------------------------------------------------------- 
		 */
		/*
		 * build our SSL context, whether it will ever be used or not 
		 */

		/*
		 * mutex'es for openSSL to use 
		 */
		THREAD_setup();

		if (srv.certificateFile && srv.privateKey && srv.caList) {
			traceLog(LOG_INFO,"Initializing the TLS/SSL environment");
			if (!(srv.ctx = tls_init(&srv))) {
				return FALSE;
			}
		}

		/*
		 * ---------------------------------------------------------- 
		 */
#endif

#ifdef HAVE_SASL
		{
			int             r = sasl_server_init(sasl_cb, "spocp");
			if (r != SASL_OK) {
				traceLog( LOG_ERR,
				    "Unable to initialized SASL library: %s",
				     sasl_errstring(r, NULL, NULL));
				return FALSE;
			}
		}
#endif

		saci_init();
		if( nodaemon == 0 ) { 
#ifdef HAVE_DAEMON
			if (daemon(1, 1) < 0) {
				fprintf(stderr, "couldn't go daemon\n");
				exit(1);
			}
#else
			daemon_init("spocp", 0);
#endif
		}

		if (srv.pidfile) {
			/*
			 * Write the PID file. 
			 */
			pidfp = fopen(srv.pidfile, "w");

			if (pidfp == (FILE *) 0) {
				fprintf(stderr,
					"Couldn't open pidfile \"%s\"\n",
					srv.pidfile);
				exit(1);
			}
			fprintf(pidfp, "%d\n", (int) getpid());
			fclose(pidfp);
		}

		if (srv.port) {
			LOG(SPOCP_INFO) traceLog( LOG_INFO,
				"Asked to listen on port %d", srv.port);

			if ((srv.listen_fd =
			     spocp_stream_socket(srv.port)) < 0)
				exit(1);

			srv.id = (char *) Malloc(16);
			sprintf(srv.id, "spocp-%d", srv.port);

			srv.type = AF_INET;
		} else {
			LOG(SPOCP_INFO)
			    traceLog(LOG_INFO,"Asked to listen on unix domain socket");
			if ((srv.listen_fd =
			     spocp_unix_domain_socket(srv.uds)) < 0)
				exit(1);

			srv.id = (char *) Malloc(7 + strlen(srv.uds));
			/* Flawfinder: ignore */
			sprintf(srv.id, "spocp-%s", srv.uds);

			srv.type = AF_UNIX;
		}

		xsignal(SIGCHLD, sig_chld);
		xsignal(SIGPIPE, sig_pipe);
		xsignal(SIGINT, sig_int);
		xsignal(SIGTERM, sig_term);
		xsignal(SIGUSR1, sig_usr1);

		clilen = sizeof(cliaddr);

		DEBUG(SPOCP_DSRV) traceLog(LOG_DEBUG,"Creating threads");
		/*
		 * returns the pool the threads are picking work from 
		 */
		srv.work = tpool_init(srv.threads, 64, 1);

		spocp_srv_run(&srv);

	} else {
		conn_t         *conn;

		saci_init();
		DEBUG(SPOCP_DSRV) traceLog(LOG_DEBUG,"---->");

		LOG(SPOCP_INFO) traceLog(LOG_INFO,"Reading STDIN");

		/*
		 * If I want to use this I have to do init_server() first
		 * conn = spocp_open_connection( STDIN_FILENO, &srv ) ; 
		 */
		/*
		 * this is much simpler 
		 */
		conn = conn_new();
		conn_setup(conn, &srv, STDIN_FILENO, "localhost", "127.0.0.1");

		LOG(SPOCP_INFO) traceLog(LOG_INFO,"Running server");

		spocp_server((void *) conn);

		gettimeofday(&end, NULL);

		print_elapsed("query time:", start, end);

		conn_free( conn );
	}

	srv_free( &srv );
	if (cnfg != DEF_CNFG)
		Free( cnfg );

	exit(0);
}
Ejemplo n.º 2
0
solitaire* solitaire_theidiot(mem_context *context, visual_settings *settings) {
	visual_pile *deck, *pile1, *pile2, *pile3, *pile4, *done;
	rule *rule1, *rule2;
	condition *pile1_4_cond;

	/* The one solitaire instance we have.*/
	solitaire* s = mem_alloc(context, sizeof(solitaire));

	/* This is the internal data representation of this
	 * solitaire. This is a local struct hidden from other
	 * members. */
	internal* i = mem_alloc(context, sizeof(internal));
	s->data = i;

	s->visual = visual_create(context, settings);

	i->deck = pile_create(context, 52);
	deck = visual_pile_create(context, i->deck);
	deck->origin[0] = 0 - (settings->card_width / 2 + settings->card_spacing / 2 + settings->card_width * 2 + settings->card_spacing * 2 + settings->card_width / 2);
	deck->origin[1] = 40.0f;
	deck->rotation = 45.0f;
	deck->action = action_deal(context, s, i);
	visual_add_pile(context, s->visual, deck);

	i->pile1 = pile_create(context, 13);
	pile1 = visual_pile_create(context, i->pile1);
	pile1->origin[0] = 0 - (settings->card_width / 2 + settings->card_spacing / 2 + settings->card_width + settings->card_spacing);
	pile1->origin[1] = 70.0f;
	pile1->translateY = 0 - settings->card_height / 5;
	visual_add_pile(context, s->visual, pile1);

	i->pile2 = pile_create(context, 13);
	pile2 = visual_pile_create(context, i->pile2);
	pile2->origin[0] = 0 - (settings->card_width / 2 + settings->card_spacing / 2);
	pile2->origin[1] = 70.0f;
	pile2->translateY = 0 - settings->card_height / 5;
	visual_add_pile(context, s->visual, pile2);

	i->pile3 = pile_create(context, 13);
	pile3 = visual_pile_create(context, i->pile3);
	pile3->origin[0] = settings->card_width / 2 + settings->card_spacing / 2;
	pile3->origin[1] = 70.0f;
	pile3->translateY = 0 - settings->card_height / 5;
	visual_add_pile(context, s->visual, pile3);

	i->pile4 = pile_create(context, 13);
	pile4 = visual_pile_create(context, i->pile4);
	pile4->origin[0] = settings->card_width / 2 + settings->card_spacing / 2 + settings->card_width + settings->card_spacing;
	pile4->origin[1] = 70.0f;
	pile4->translateY = 0 - settings->card_height / 5;
	visual_add_pile(context, s->visual, pile4);

	i->done = pile_create(context, 48);
	done = visual_pile_create(context, i->done);
	done->origin[0] = settings->card_width / 2 + settings->card_spacing / 2 + settings->card_width * 2 + settings->card_spacing * 2 + settings->card_width / 2;
	done->origin[1] = 40.0f;
	done->rotation = -45.0f;
	visual_add_pile(context, s->visual, done);

	card_create_deck(context, i->deck, 14);
	card_shuffle(i->deck);

	visual_sync(s->visual);

	s->ruleset = ruleset_create(context);

	/* Shared condition between several rules. */
	pile1_4_cond = condition_source_array(
		context, 4, i->pile1, i->pile2, i->pile3, i->pile4);

	/* Move card to done pile if source is pile1-pile4 and there is
	   a higher card in same suit in those piles. */
	rule1 = rule_create(context);
	rule_add_condition(context, rule1, pile1_4_cond);
	rule_add_condition(context, rule1, condition_destination(context, i->done));
	rule_add_condition(
		context,
		rule1,
		condition_or_array(
			context, 4,
			condition_top_card_compare(context, i->pile1,
									   e_dest_higher_value | e_follow_suit),
			condition_top_card_compare(context, i->pile2,
									   e_dest_higher_value | e_follow_suit),
			condition_top_card_compare(context, i->pile3,
									   e_dest_higher_value | e_follow_suit),
			condition_top_card_compare(context, i->pile4,
									   e_dest_higher_value | e_follow_suit)));
	rule_add_condition(context, rule1, condition_top_card(context));
	ruleset_add_rule(context, s->ruleset, rule1);

	/* Allow move to a top card to an empty pile. */
	rule2 = rule_create(context);
	rule_add_condition(context, rule2, pile1_4_cond);
	rule_add_condition(context, rule2, condition_top_card(context));
	rule_add_condition(context, rule2, condition_destination_empty(context));
	rule_add_condition(
		context, rule2,
		condition_destination_array(
			context, 4, i->pile1, i->pile2, i->pile3, i->pile4));
	ruleset_add_rule(context, s->ruleset, rule2);

	/* Solved rule */
	s->ruleset->solved = rule_create(context);
	rule_add_condition(
		context, s->ruleset->solved,
		condition_source_card_equal(
			context, e_suit_none, 14, e_equal_value, i->pile1));
	rule_add_condition(
		context, s->ruleset->solved,
		condition_source_card_equal(
			context, e_suit_none, 14, e_equal_value, i->pile2));
	rule_add_condition(
		context, s->ruleset->solved,
		condition_source_card_equal(
			context, e_suit_none, 14, e_equal_value, i->pile3));
	rule_add_condition(
		context, s->ruleset->solved,
		condition_source_card_equal(
			context, e_suit_none, 14, e_equal_value, i->pile4));
	rule_add_condition(
		context, s->ruleset->solved,
		condition_card_count_array(
			context, 1, 4, i->pile1, i->pile2, i->pile3, i->pile4));
	return s;
}
Ejemplo n.º 3
0
static void setup_rules(mem_context *context, solitaire *s, internal *i) {
	condition *ace1_4_cond;
	rule *rule1, *rule2, *rule3, *rule4, *rule5;

	s->ruleset = ruleset_create(context);

	/* Shared condition for the aces. */
	ace1_4_cond = condition_destination_array(
		context, 4, i->ace[0], i->ace[1], i->ace[2], i->ace[3]);

	/* Allow move of ace to an empty pile among the ace piles. */
	rule1 = rule_create(context);
	rule_add_condition(context, rule1, ace1_4_cond);
	rule_add_condition(context, rule1, condition_destination_empty(context));
	rule_add_condition(context, rule1, condition_top_card(context));
	rule_add_condition(
		context, rule1,
		condition_source_card_equal(context, e_suit_none,
								 1, e_equal_value, 0));
	rule_add_action(context, rule1, action_reveal_source_top_card(context));
	ruleset_add_rule(context, s->ruleset, rule1);

	/* Allow card to be placed on top of the ace
	   piles following suit and ascending order. */
	rule2 = rule_create(context);
	rule_add_condition(context, rule2, ace1_4_cond);
	rule_add_condition(context, rule2, condition_top_card(context));
	rule_add_condition(context, rule2,
					   condition_top_card_compare(
						   context, 0, e_dest_1lower_value|e_follow_suit));
	rule_add_action(context, rule2, action_reveal_source_top_card(context));
	ruleset_add_rule(context, s->ruleset, rule2);

	/* Allow moving several cards to a top card of the opposite suit. */
	rule3 = rule_create(context);
	rule_add_condition(
		context, rule3,
		condition_top_card_compare(
			context, 0, e_dest_1higher_value|e_suit_opposite));
	rule_add_condition(context, rule3,
					   condition_source_array(
						   context, 8, i->build[0], i->build[1], i->build[2],
						   i->build[3], i->build[4], i->build[5], i->build[6],
						   i->build[7]));
	rule_add_condition(context, rule3,
					   condition_destination_array(
						   context, 8, i->build[0], i->build[1], i->build[2],
						   i->build[3], i->build[4], i->build[5], i->build[6],
						   i->build[7]));
	rule_add_condition(context, rule3, condition_source_card_revealed(context));
	rule_add_condition(context, rule3, condition_rest_of_pile(context));
	rule_add_condition(
		context, rule3, condition_source_not_equal_destination(context));
	rule_add_action(context, rule3, action_reveal_source_top_card(context));
	ruleset_add_rule(context, s->ruleset, rule3);

	/* Allow moving of kings to an empty pile. */
	rule4 = rule_create(context);
	rule_add_condition(context,
					   rule4,
					   condition_destination_array(
						   context, 8, i->build[0], i->build[1], i->build[2],
						   i->build[3], i->build[4], i->build[5], i->build[6],
						   i->build[7]));
	rule_add_condition(context, rule4, condition_destination_empty(context));
	rule_add_condition(context, rule4,
					   condition_source_card_equal(
						   context, e_suit_none, 13, e_equal_value, 0));
	rule_add_condition(context, rule4, condition_rest_of_pile(context));
	rule_add_action(context, rule4, action_reveal_source_top_card(context));
	ruleset_add_rule(context, s->ruleset, rule4);

	/* Allow moving a single card to the build piles from the ace piles. */
	rule5 = rule_create(context);
	rule_add_condition(context, rule5, condition_top_card(context));
	rule_add_condition(
		context, rule5, condition_source_array(context, 4, i->ace[0],
											   i->ace[1], i->ace[2], i->ace[3]));
	rule_add_condition(context,
					   rule5,
					   condition_destination_array(
						   context, 8, i->build[0], i->build[1], i->build[2],
						   i->build[3], i->build[4], i->build[5], i->build[6],
						   i->build[7]));
	rule_add_condition(
		context, rule5,
		condition_top_card_compare(
			context, 0, e_dest_1higher_value|e_suit_opposite));
	ruleset_add_rule(context, s->ruleset, rule5);

	/* Solved rule */
	s->ruleset->solved = rule_create(context);
	rule_add_condition(
		context, s->ruleset->solved,
		condition_card_count_array(
			context, 13, 4, i->ace[0], i->ace[1], i->ace[2], i->ace[3]));
}
Ejemplo n.º 4
0
SymbolRef pattern_to_grammar(PatternNode *node)
{
    GrammarRuleSet *ruleset;

    switch (node->type)
    {
    case PN_WORD:
        {
            int nwords = (int)AR_size(&ar_words);
            const char **words = AR_data(&ar_words);

            /* Try to find an existing equal terminal symbol */
            SymbolRef res = { SYM_TERMINAL, 0 };
            for (res.index = 0; res.index < nwords; ++res.index)
                if (strcmp(words[res.index], node->text) == 0)
                    break;

            /* Add a new terminal symbol if none existed. */
            if (res.index == nwords)
            {
                char *str = strdup(node->text);
                AR_push(&ar_words, &str);
            }

            return res;
        }

    case PN_SEQ:
        {
            ruleset = ruleset_create(1);
            assert(ruleset != NULL);
            ruleset->rules[0] = symrefs_create(2);
            assert(ruleset->rules[0] != NULL);
            ruleset->rules[0]->refs[0] = pattern_to_grammar(node->left);
            ruleset->rules[0]->refs[1] = pattern_to_grammar(node->right);
        } break;

    case PN_ALT:
        {
            ruleset = ruleset_create(2);
            assert(ruleset != NULL);
            ruleset->rules[0] = symrefs_create(1);
            assert(ruleset->rules[0] != NULL);
            ruleset->rules[1] = symrefs_create(1);
            assert(ruleset->rules[1] != NULL);
            ruleset->rules[0]->refs[0] = pattern_to_grammar(node->left);
            ruleset->rules[1]->refs[0] = pattern_to_grammar(node->right);
        } break;

    case PN_OPT:
        {
            ruleset = ruleset_create(2);
            assert(ruleset != NULL);
            ruleset->rules[0] = symrefs_create(0);
            assert(ruleset->rules[0] != NULL);
            ruleset->rules[1] = symrefs_create(1);
            assert(ruleset->rules[1] != NULL);
            ruleset->rules[1]->refs[0] = pattern_to_grammar(node->left);
        } break;

    default:
        assert(false);
    }

    ruleset_sort(ruleset);

    /* See if the rule set matches an existing symbol's rule set */
    GrammarRuleSet **rulesets = AR_data(&ar_grammar);
    size_t nruleset = AR_size(&ar_grammar), n;
    for (n = 0; n < nruleset; ++n)
        if (ruleset_cmp(rulesets[n], ruleset) == 0)
            break;

    if (n < nruleset)
        ruleset_destroy(ruleset);
    else
        AR_push(&ar_grammar, &ruleset);

    SymbolRef res = { SYM_NONTERMINAL, (int)n };
    return res;
}
Ejemplo n.º 5
0
Archivo: read.c Proyecto: Zabrane/SPOCP
int
read_rules(srv_t * srv, char *file, dbcmd_t * dbc)
{
	FILE           *fp;
	char           *sp, *tmp;
	int             n = 0, f = 0, r;
	octet_t         *op;
	octarr_t       *oa = 0;
	ruleset_t      *rs = 0, *trs, *prs;
	spocp_result_t  rc = SPOCP_SUCCESS;
	spocp_charbuf_t	*buf;
	spocp_chunk_t	*chunk = 0, *ck;
	spocp_chunkwrap_t   *cw;
	spocp_ruledef_t	rdef;
	struct stat	statbuf;

	if ((fp = fopen(file, "r")) == 0) {
		LOG(SPOCP_EMERG) traceLog(LOG_ERR,"couldn't open rule file \"%s\"",
					  file);
		op = oct_new( 256, NULL);
		sp = getcwd(op->val, op->size);
		traceLog(LOG_ERR,"I'm in \"%s\"", sp);
		oct_free(op);
		return -1;
	}

	stat( file, &statbuf);

	srv->mtime = statbuf.st_mtime;
 
	/*
	 * The default ruleset should already be set 
	 */

	if (srv->root == 0) {
		srv->root = rs = ruleset_new(0);
	} else
		rs = srv->root;

	if (rs->db == 0)
		rs->db = db_new();

	buf = charbuf_new( fp, BUFSIZ );

	if (get_more(buf) == 0) return 0;

	/*
	 * have to escape CR since fgets stops reading when it hits a newline
	 * NUL also has to be escaped since I have problem otherwise finding
	 * the length of the 'string'. '\' hex hex is probably going to be the 
	 * choice 
	 */
	while (rc == SPOCP_SUCCESS ) {
	    cw = get_object( buf, 0 );
	    if (cw->status == 0) {
	        Free(cw);
	        break;
	    }
	    else if (cw->status == -1) {
	        rc = SPOCP_LOCAL_ERROR;
            Free(cw);
            break;
        }
        else {
            chunk = cw->chunk;
            Free(cw);
        }
	    
		if (oct2strcmp(chunk->val, ";include ") == 0) {	/* include
								 * file */
			ck = chunk->next;
			tmp = oct2strdup( ck->val, 0 ) ;
			LOG(SPOCP_DEBUG) traceLog(LOG_DEBUG,"include directive \"%s\"",
						  tmp);
			if ((rc = read_rules(srv, tmp, dbc)) < 0) {
				traceLog(LOG_ERR,"Include problem");
			}
		}
		else if (*chunk->val->val == '/' || *chunk->val->val == '(') {
			trs = rs;
			if (*chunk->val->val == '/') {
#ifdef AVLUS
				oct_print(LOG_INFO,"ruleset", chunk->val);
#endif
				if ((trs = ruleset_find( chunk->val, rs)) == NULL) {
					octet_t oct;

					octln( &oct, chunk->val);
					rs = ruleset_create(chunk->val, rs);
					trs = ruleset_find(&oct, rs);
					trs->db = db_new();
				}

				ck = chunk->next;
			}
			else {
				ck = chunk;
			}

			ruledef_return( &rdef, ck ) ;
			if( rdef.rule ) {
				op = chunk2sexp( rdef.rule ) ;
				oa = octarr_add(oa, op) ;
				LOG(SPOCP_DEBUG) {
					traceLog(LOG_DEBUG,"We've got a rule");
				}
			}
			
			if( rdef.bcond) {
				op = chunk2sexp( rdef.bcond ) ;
				oa = octarr_add(oa, op) ;
				LOG(SPOCP_DEBUG) {
					traceLog(LOG_DEBUG,"We've got a boundary condition");
				}
			}