Пример #1
0
PUSS_EXPORT void* puss_plugin_create(Puss* app) {
	GTree* sections;
	GtkSourceLanguageManager* lm;
	const gchar* const* ids;
	const gchar* const* id;
	GtkSourceLanguage* lang;
	const gchar* name;
	gchar* action_name;
	GtkAction* action;
	const gchar* section;
	GList* section_list;
	GtkUIManager* ui_mgr;
	IToolMenuAction* tool_menu_interface;

	GString* gstr;
	gchar* ui_info;
	GError* err;

	tool_menu_interface = app->extend_query("puss_controls", INTERFACE_TOOL_MENU_ACTION);
	if( !tool_menu_interface )
		return 0;

	bindtextdomain(TEXT_DOMAIN, app->get_locale_path());
	bind_textdomain_codeset(TEXT_DOMAIN, "UTF-8");

	g_self = g_new0(LanguageSelector, 1);
	g_self->app = app;
	g_self->action_group = gtk_action_group_new("puss_language_selector_action_group");

	// set select language menu
	sections = g_tree_new_full((GCompareDataFunc)&g_ascii_strcasecmp, 0, 0, (GDestroyNotify)g_list_free);
	lm = gtk_source_language_manager_get_default();
	ids = gtk_source_language_manager_get_language_ids(lm);
	g_self->last_favory_lang = gtk_source_language_manager_get_language(lm, "cpp");
	for( id=ids; *id; ++id ) {
		lang = gtk_source_language_manager_get_language(lm, *id);
		if( lang ) {
			name = gtk_source_language_get_name(lang);
			action_name = g_strdup_printf("pls_lang_%s", name);
			action = gtk_action_new(action_name, name, NULL, NULL);
			g_signal_connect(action, "activate", G_CALLBACK(&pls_lang_active), lang);
			gtk_action_group_add_action(g_self->action_group, action);
			g_object_unref(action);
			g_free(action_name);

			section = gtk_source_language_get_section(lang);

			section_list = (GList*)g_tree_lookup(sections, section);
			if( section_list ) {
				g_tree_steal(sections, section);
			} else {
				action_name = g_strdup_printf("pls_sec_%s", section);
				action = GTK_ACTION(gtk_action_new(action_name, section, NULL, NULL));
				gtk_action_group_add_action(g_self->action_group, action);
				g_object_unref(action);
				g_free(action_name);
			}

			section_list = g_list_insert_sorted(section_list, (gchar*)name, (GCompareFunc)&g_ascii_strcasecmp);
			
			g_tree_insert(sections, (gchar*)section, section_list);
		}
	}

	// insert language selector menu-tool-button
	// 
	action = gtk_action_new("language_selector_open", _("Language"), _("select high-light source language, default use last"), GTK_STOCK_SELECT_COLOR);
	gtk_action_group_add_action(g_self->action_group, action);
	g_object_unref(action);

	action = GTK_ACTION( g_object_new(tool_menu_interface->get_type ()
			, "name", "language_selector_toolmenu_open"
			, "label", _("Language")
			, "tooltip", _("select high-light source language, default use last")
			, "stock-id", GTK_STOCK_SELECT_COLOR
			, NULL) );
	g_signal_connect(action, "activate", G_CALLBACK(&pls_lang_active), 0);
	gtk_action_group_add_action(g_self->action_group, action);
	g_object_unref(action);

	ui_mgr = GTK_UI_MANAGER(gtk_builder_get_object(app->get_ui_builder(), "main_ui_manager"));
	gtk_ui_manager_insert_action_group(ui_mgr, g_self->action_group, 0);

	// main selector menu
	gstr= g_string_new(NULL);
	g_tree_foreach(sections, (GTraverseFunc)&fill_language_section, gstr);
	g_tree_destroy(sections);

	ui_info = g_strdup_printf(
		"<ui>"
		"  <menubar name='main_menubar'>"
		"     <menu action='view_menu'>\n"
		"      <placeholder name='view_menu_extend_place'>"
		"        <menu action='language_selector_open'>"
		"          %s"
		"          <placeholder name='pls_favory_menu_place'>"
		"          </placeholder>"
		"        </menu>"
		"      </placeholder>"
		"    </menu>"
		"  </menubar>"
		""
		"  <toolbar name='main_toolbar'>"
		"    <placeholder name='main_toolbar_view_place'>"
		"      <toolitem action='language_selector_toolmenu_open'>"
		"        <menu action='language_selector_toolmenu_open'>"
		"          %s"
		"          <placeholder name='pls_favory_toolmenu_place'>"
		"          </placeholder>"
		"        </menu>"
		"      </toolitem>"
		"    </placeholder>"
        "  </toolbar>"
		"</ui>"
		, gstr->str
		, gstr->str
	);

	//g_print(ui_info);
	err = 0;
	g_self->merge_id = gtk_ui_manager_add_ui_from_string(ui_mgr, ui_info, -1, &err);
	if( err ) {
		g_printerr("%s", err->message);
		g_error_free(err);
	}
	g_free(ui_info);
	g_string_free(gstr, TRUE);

	gtk_ui_manager_ensure_update(ui_mgr);

	fill_favory_language_menu();

	return g_self;
}
Пример #2
0
Файл: syntax.c Проект: BrEacK/mc
static int
edit_read_syntax_rules (WEdit * edit, FILE * f, char **args, int args_size)
{
    FILE *g = NULL;
    char *fg, *bg, *attrs;
    char last_fg[32] = "", last_bg[32] = "", last_attrs[64] = "";
    char whole_right[512];
    char whole_left[512];
    char *l = 0;
    int save_line = 0, line = 0;
    struct context_rule **r, *c = NULL;
    int num_words = -1, num_contexts = -1;
    int result = 0;
    int argc;
    int i, j;
    int alloc_contexts = MAX_CONTEXTS,
        alloc_words_per_context = MAX_WORDS_PER_CONTEXT,
        max_alloc_words_per_context = MAX_WORDS_PER_CONTEXT;

    args[0] = NULL;
    edit->is_case_insensitive = FALSE;

    strcpy (whole_left, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_01234567890");
    strcpy (whole_right, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_01234567890");

    r = edit->rules = g_malloc0 (alloc_contexts * sizeof (struct context_rule *));

    if (!edit->defines)
        edit->defines = g_tree_new ((GCompareFunc) strcmp);

    for (;;)
    {
        char **a;
        size_t len;

        line++;
        l = 0;

        len = read_one_line (&l, f);
        if (len == 0)
        {
            if (g)
            {
                fclose (f);
                f = g;
                g = 0;
                line = save_line + 1;
                MC_PTR_FREE (error_file_name);
                MC_PTR_FREE (l);
                len = read_one_line (&l, f);
                if (len == 0)
                    break;
                else
                    xx_lowerize_line (edit, l, len);
            }
            else
            {
                break;
            }
        }
        else
        {
            xx_lowerize_line (edit, l, len);
        }
        argc = get_args (l, args, args_size);
        a = args + 1;
        if (!args[0])
        {
            /* do nothing */
        }
        else if (!strcmp (args[0], "include"))
        {
            if (g || argc != 2)
            {
                result = line;
                break;
            }
            g = f;
            f = open_include_file (args[1]);
            if (!f)
            {
                MC_PTR_FREE (error_file_name);
                result = line;
                break;
            }
            save_line = line;
            line = 0;
        }
        else if (!strcmp (args[0], "caseinsensitive"))
        {
            edit->is_case_insensitive = TRUE;
        }
        else if (!strcmp (args[0], "wholechars"))
        {
            check_a;
            if (!strcmp (*a, "left"))
            {
                a++;
                g_strlcpy (whole_left, *a, sizeof (whole_left));
            }
            else if (!strcmp (*a, "right"))
            {
                a++;
                g_strlcpy (whole_right, *a, sizeof (whole_right));
            }
            else
            {
                g_strlcpy (whole_left, *a, sizeof (whole_left));
                g_strlcpy (whole_right, *a, sizeof (whole_right));
            }
            a++;
            check_not_a;
        }
        else if (!strcmp (args[0], "context"))
        {
            check_a;
            if (num_contexts == -1)
            {
                if (strcmp (*a, "default"))
                {               /* first context is the default */
                    break_a;
                }
                a++;
                c = r[0] = g_malloc0 (sizeof (struct context_rule));
                c->left = g_strdup (" ");
                c->right = g_strdup (" ");
                num_contexts = 0;
            }
            else
            {
                /* Terminate previous context.  */
                r[num_contexts - 1]->keyword[num_words] = NULL;
                c = r[num_contexts] = g_malloc0 (sizeof (struct context_rule));
                if (!strcmp (*a, "exclusive"))
                {
                    a++;
                    c->between_delimiters = 1;
                }
                check_a;
                if (!strcmp (*a, "whole"))
                {
                    a++;
                    c->whole_word_chars_left = g_strdup (whole_left);
                    c->whole_word_chars_right = g_strdup (whole_right);
                }
                else if (!strcmp (*a, "wholeleft"))
                {
                    a++;
                    c->whole_word_chars_left = g_strdup (whole_left);
                }
                else if (!strcmp (*a, "wholeright"))
                {
                    a++;
                    c->whole_word_chars_right = g_strdup (whole_right);
                }
                check_a;
                if (!strcmp (*a, "linestart"))
                {
                    a++;
                    c->line_start_left = 1;
                }
                check_a;
                c->left = g_strdup (*a++);
                check_a;
                if (!strcmp (*a, "linestart"))
                {
                    a++;
                    c->line_start_right = 1;
                }
                check_a;
                c->right = g_strdup (*a++);
                c->first_left = *c->left;
                c->first_right = *c->right;
            }
            c->keyword = g_malloc (alloc_words_per_context * sizeof (struct key_word *));
            num_words = 1;
            c->keyword[0] = g_malloc0 (sizeof (struct key_word));
            subst_defines (edit->defines, a, &args[1024]);
            fg = *a;
            if (*a)
                a++;
            bg = *a;
            if (*a)
                a++;
            attrs = *a;
            if (*a)
                a++;
            g_strlcpy (last_fg, fg ? fg : "", sizeof (last_fg));
            g_strlcpy (last_bg, bg ? bg : "", sizeof (last_bg));
            g_strlcpy (last_attrs, attrs ? attrs : "", sizeof (last_attrs));
            c->keyword[0]->color = this_try_alloc_color_pair (fg, bg, attrs);
            c->keyword[0]->keyword = g_strdup (" ");
            check_not_a;

            alloc_words_per_context = MAX_WORDS_PER_CONTEXT;
            if (++num_contexts >= alloc_contexts)
            {
                struct context_rule **tmp;

                alloc_contexts += 128;
                tmp = g_realloc (r, alloc_contexts * sizeof (struct context_rule *));
                r = tmp;
            }
        }
        else if (!strcmp (args[0], "spellcheck"))
        {
            if (!c)
            {
                result = line;
                break;
            }
            c->spelling = 1;
        }
        else if (!strcmp (args[0], "keyword"))
        {
            struct key_word *k;

            if (num_words == -1)
                break_a;
            check_a;
            k = r[num_contexts - 1]->keyword[num_words] = g_malloc0 (sizeof (struct key_word));
            if (!strcmp (*a, "whole"))
            {
                a++;
                k->whole_word_chars_left = g_strdup (whole_left);
                k->whole_word_chars_right = g_strdup (whole_right);
            }
            else if (!strcmp (*a, "wholeleft"))
            {
                a++;
                k->whole_word_chars_left = g_strdup (whole_left);
            }
            else if (!strcmp (*a, "wholeright"))
            {
                a++;
                k->whole_word_chars_right = g_strdup (whole_right);
            }
            check_a;
            if (!strcmp (*a, "linestart"))
            {
                a++;
                k->line_start = 1;
            }
            check_a;
            if (!strcmp (*a, "whole"))
            {
                break_a;
            }
            k->keyword = g_strdup (*a++);
            k->first = *k->keyword;
            subst_defines (edit->defines, a, &args[1024]);
            fg = *a;
            if (*a)
                a++;
            bg = *a;
            if (*a)
                a++;
            attrs = *a;
            if (*a)
                a++;
            if (!fg)
                fg = last_fg;
            if (!bg)
                bg = last_bg;
            if (!attrs)
                attrs = last_attrs;
            k->color = this_try_alloc_color_pair (fg, bg, attrs);
            check_not_a;

            if (++num_words >= alloc_words_per_context)
            {
                struct key_word **tmp;

                alloc_words_per_context += 1024;

                if (alloc_words_per_context > max_alloc_words_per_context)
                    max_alloc_words_per_context = alloc_words_per_context;

                tmp = g_realloc (c->keyword, alloc_words_per_context * sizeof (struct key_word *));
                c->keyword = tmp;
            }
        }
        else if (*(args[0]) == '#')
        {
            /* do nothing for comment */
        }
        else if (!strcmp (args[0], "file"))
        {
            break;
        }
        else if (!strcmp (args[0], "define"))
        {
            char *key = *a++;
            char **argv;

            if (argc < 3)
                break_a;
            argv = g_tree_lookup (edit->defines, key);
            if (argv != NULL)
                mc_defines_destroy (NULL, argv, NULL);
            else
                key = g_strdup (key);

            argv = g_new (char *, argc - 1);
            g_tree_insert (edit->defines, key, argv);
            while (*a != NULL)
            {
                *argv++ = g_strdup (*a++);
            }
            *argv = NULL;
        }
        else
        {                       /* anything else is an error */
Пример #3
0
static event_response_t cb(drakvuf_t drakvuf, drakvuf_trap_info_t* info)
{
    poolmon* p = (poolmon*)info->trap->data;
    page_mode_t pm = drakvuf_get_page_mode(drakvuf);
    reg_t pool_type, size;
    char tag[5] = { [0 ... 4] = '\0' };
    struct pooltag* s = NULL;
    const char* pool_type_str;

    access_context_t ctx;
    ctx.translate_mechanism = VMI_TM_PROCESS_DTB;
    ctx.dtb = info->regs->cr3;

    if (pm == VMI_PM_IA32E)
    {
        pool_type = info->regs->rcx;
        size = info->regs->rdx;
        *(reg_t*)tag = info->regs->r8;
    }
    else
    {
        vmi_lock_guard vmi_lg(drakvuf);
        vmi_instance_t& vmi = vmi_lg.vmi;

        ctx.addr = info->regs->rsp+12;
        if ( VMI_FAILURE == vmi_read_32(vmi, &ctx, (uint32_t*)tag) )
            return 0;

        ctx.addr = info->regs->rsp+8;
        if ( VMI_FAILURE == vmi_read_32(vmi, &ctx, (uint32_t*)&size) )
            return 0;

        ctx.addr = info->regs->rsp+4;
        if ( VMI_FAILURE == vmi_read_32(vmi, &ctx, (uint32_t*)&pool_type) )
            return 0;
    }

    s = (struct pooltag*)g_tree_lookup(p->pooltag_tree, tag);

    pool_type_str = pool_type<MaxPoolType ? pool_types[pool_type] : "unknown_pool_type";

    switch (p->format)
    {
        case OUTPUT_CSV:
            printf("poolmon," FORMAT_TIMEVAL ",%" PRIu32 ",0x%" PRIx64 ",\"%s\",%" PRIi64 ",%s,%s,%" PRIu64 "",
                   UNPACK_TIMEVAL(info->timestamp), info->vcpu, info->regs->cr3, info->proc_data.name, info->proc_data.userid, tag,
                   pool_type_str, size);
            if (s)
                printf(",%s,%s", s->source, s->description);
            break;

        case OUTPUT_KV:
            printf("poolmon Time=" FORMAT_TIMEVAL ",PID=%d,PPID=%d,ProcessName=\"%s\","
                   "Tag=%s,Type=%s,Size=%" PRIu64,
                   UNPACK_TIMEVAL(info->timestamp), info->proc_data.pid, info->proc_data.ppid, info->proc_data.name,
                   tag, pool_type_str, size);
            if (s)
                printf(",Source=%s,Description=%s", s->source, s->description);
            break;

        default:
        case OUTPUT_DEFAULT:
            printf("[POOLMON] TIME:" FORMAT_TIMEVAL " VCPU:%" PRIu32 " CR3:0x%" PRIx64 ",\"%s\" %s:%" PRIi64 " %s (type: %s, size: %" PRIu64 ")",
                   UNPACK_TIMEVAL(info->timestamp), info->vcpu, info->regs->cr3, info->proc_data.name,
                   USERIDSTR(drakvuf), info->proc_data.userid, tag,
                   pool_type_str, size);
            if (s)
                printf(": %s,%s", s->source, s->description);
            break;
    }

    printf("\n");

    return 0;
}
int BLEIO_gatt_read_char_by_uuid(
    BLEIO_GATT_HANDLE bleio_gatt_handle,
    const char* ble_uuid,
    ON_BLEIO_GATT_ATTRIB_READ_COMPLETE on_bleio_gatt_attrib_read_complete,
    void* callback_context
)
{
    int result;
    BLEIO_GATT_HANDLE_DATA* handle_data = (BLEIO_GATT_HANDLE_DATA*)bleio_gatt_handle;

    /*Codes_SRS_BLEIO_GATT_13_027: [ BLEIO_gatt_read_char_by_uuid shall return a non-zero value if bleio_gatt_handle is NULL. ]*/
    /*Codes_SRS_BLEIO_GATT_13_028: [ BLEIO_gatt_read_char_by_uuid shall return a non-zero value if on_bleio_gatt_attrib_read_complete is NULL. ]*/
    /*Codes_SRS_BLEIO_GATT_13_051: [BLEIO_gatt_read_char_by_uuid shall return a non - zero value if ble_uuid is NULL. ] */
    /*Codes_SRS_BLEIO_GATT_13_052: [BLEIO_gatt_read_char_by_uuid shall return a non - zero value if the object is not in a connected state. ] */
    if (
            bleio_gatt_handle != NULL &&
            ble_uuid != NULL &&
            on_bleio_gatt_attrib_read_complete != NULL &&
            handle_data->state == BLEIO_GATT_STATE_CONNECTED
       )
    {
        GString* uuid = g_string_new(ble_uuid);
        if(uuid != NULL)
        {
            GString* object_path = g_tree_lookup(handle_data->char_object_path_map, uuid);
            if(object_path != NULL)
            {
                // now that we have the object path we don't need the UUID anymore
                g_string_free(uuid, TRUE);

                READ_CONTEXT *context = (READ_CONTEXT *)malloc(sizeof(READ_CONTEXT));
                if (context != NULL)
                {
                    // create async sequence
                    context->async_seq = GIO_Async_Seq_Create(
                        context,
                        on_sequence_error,
                        on_sequence_complete
                    );
                    if (context->async_seq != NULL)
                    {
                        // setup call sequence
                        GIO_ASYNCSEQ_RESULT seq_result = GIO_Async_Seq_Add(
                            context->async_seq, NULL,

                            // create an instance of the characteristic
                            create_characteristic, create_characteristic_finish,

                            // read the characteristic
                            read_characteristic, read_characteristic_finish,

                            // sentinel value to signal end of sequence
                            NULL
                        );
                        if (seq_result == GIO_ASYNCSEQ_OK)
                        {
                            context->handle_data = handle_data;
                            context->object_path = object_path;
                            context->characteristic = NULL;
                            context->on_read_complete = on_bleio_gatt_attrib_read_complete;
                            context->callback_context = callback_context;

                            /*Codes_SRS_BLEIO_GATT_13_031: [ BLEIO_gatt_read_char_by_uuid shall asynchronously initiate a read characteristic operation using the specified UUID. ]*/
                            // kick-off the sequence
                            if(GIO_Async_Seq_Run_Async(context->async_seq) == GIO_ASYNCSEQ_OK)
                            {
                                /*Codes_SRS_BLEIO_GATT_13_030: [ BLEIO_gatt_read_char_by_uuid shall return 0 (zero) if the read characteristic operation is successful. ]*/
                                result = 0;
                            }
                            else
                            {
                                result = __LINE__;
                                GIO_Async_Seq_Destroy(context->async_seq);
                                free(context);
                                LogError("GIO_Async_Seq_Run failed.");
                            }
                        }
                        else
                        {
                            /*Codes_SRS_BLEIO_GATT_13_029: [ BLEIO_gatt_read_char_by_uuid shall return a non-zero value if an underlying platform call fails. ]*/
                            result = __LINE__;
                            GIO_Async_Seq_Destroy(context->async_seq);
                            free(context);
                            LogError("GIO_Async_Seq_Add failed.");
                        }
                    }
                    else
                    {
                        /*Codes_SRS_BLEIO_GATT_13_029: [ BLEIO_gatt_read_char_by_uuid shall return a non-zero value if an underlying platform call fails. ]*/
                        result = __LINE__;
                        free(context);
                        LogError("GIO_Async_Seq_Create failed.");
                    }
                }
                else
                {
                    /*Codes_SRS_BLEIO_GATT_13_029: [ BLEIO_gatt_read_char_by_uuid shall return a non-zero value if an underlying platform call fails. ]*/
                    result = __LINE__;
                    LogError("malloc failed.");
                }
            }
            else
            {
                /*Codes_SRS_BLEIO_GATT_13_029: [ BLEIO_gatt_read_char_by_uuid shall return a non-zero value if an underlying platform call fails. ]*/
                result = __LINE__;
                g_string_free(uuid, TRUE);
                LogError("g_tree_lookup() failed.");
            }
        }
        else
        {
            /*Codes_SRS_BLEIO_GATT_13_029: [ BLEIO_gatt_read_char_by_uuid shall return a non-zero value if an underlying platform call fails. ]*/
            result = __LINE__;
            LogError("g_string_new() failed.");
        }
    }
    else
    {
        result = __LINE__;
        LogError("Invalid args or the state of the object is unexpected.");
    }

    return result;
}
Пример #5
0
//--------------------------------------------------------------------------------------//
void Http_getMailboxes(T R)
{
	const char *mailbox = Request_getId(R);

	TRACE(TRACE_DEBUG,"mailbox [%s]", mailbox);
	char *endptr = NULL;
	struct evbuffer *buf;
	u64_t id = 0;

	if (! mailbox) {
		Request_error(R, HTTP_SERVUNAVAIL, "Server error");
		return;
	}	

	if (! (id = strtoull(mailbox, &endptr, 10))) {
		Request_error(R, HTTP_NOTFOUND, "Not found");
		return;
	}

	TRACE(TRACE_DEBUG,"mailbox id [%llu]", id);
	buf = evbuffer_new();
	Request_setContentType(R,"application/json; charset=utf-8");

	if (Request_getMethod(R) == NULL) {

		/*
		 * retrieve mailbox meta-data
		 * C < GET /mailboxes/876
		 *
		 * or
		 *
		 * append a new message
		 * C < POST /mailboxes/876 
		 */

		const char *msg;
		u64_t msg_id = 0;
		MailboxState_T b = MailboxState_new(id);
		unsigned exists = MailboxState_getExists(b);

		if ((msg = evhttp_find_header(Request_getPOST(R),"message"))) {
			if (! db_append_msg(msg, MailboxState_getId(b), MailboxState_getOwner(b), NULL, &msg_id, TRUE))
				exists++;		
		}
		evbuffer_add_printf(buf, "{\"mailboxes\": {\n");
		evbuffer_add_printf(buf, "    \"%llu\":{\"name\":\"%s\",\"exists\":%d}", MailboxState_getId(b), MailboxState_getName(b), exists);
		evbuffer_add_printf(buf, "\n}}\n");
		MailboxState_free(&b);

	} else if (MATCH(Request_getMethod(R),"messages")) {

		/*
		 * list messages in mailbox
		 * C < GET /mailboxes/876/messages
		 */

		MailboxState_T b = MailboxState_new(id);
		GTree *msns = MailboxState_getMsn(b);
		GList *ids = g_tree_keys(msns);
		GTree *msginfo = MailboxState_getMsginfo(b);

		evbuffer_add_printf(buf, "{\"messages\": {\n");
		while (ids && ids->data) {
			u64_t *msn = (u64_t *)ids->data;
			u64_t *uid = (u64_t *)g_tree_lookup(msns, msn);
			MessageInfo *info = (MessageInfo *)g_tree_lookup(msginfo, uid);
			evbuffer_add_printf(buf, "    \"%llu\":{\"size\":%llu}", *uid, info->rfcsize);
			if (! g_list_next(ids)) break;
			ids = g_list_next(ids);
			evbuffer_add_printf(buf,",\n");
		}
		evbuffer_add_printf(buf, "\n}}\n");
	
		if (ids) g_list_free(g_list_first(ids));
		MailboxState_free(&b);
	}

	if (EVBUFFER_LENGTH(buf))
		Request_send(R, HTTP_OK, "OK", buf);
	else		
		Request_error(R, HTTP_SERVUNAVAIL, "Server error");
	evbuffer_free(buf);
}
Пример #6
0
static gint
sqlx_lookup_id(sqlx_cache_t *cache, const hashstr_t *hs)
{
	gpointer lookup_result = g_tree_lookup(cache->bases_by_name, hs);
	return !lookup_result ? -1 : (GPOINTER_TO_INT(lookup_result) - 1);
}
Пример #7
0
void rpc_service_handle(rpc_service_t *service, zmq_msg_t *request) {
  /* Parse the msgpack */
  zmq_msg_t response;
  int rc;
  msgpack_unpacked request_msg;
  msgpack_unpacked_init(&request_msg);
  rc = msgpack_unpack_next(&request_msg, zmq_msg_data(request),
                           zmq_msg_size(request), NULL);
  insist_return(rc, (void)(0), "Failed to unpack message '%.*s'",
                (int)zmq_msg_size(request), (char *)zmq_msg_data(request));

  msgpack_object request_obj = request_msg.data;

  /* Find the method name */
  char *method = NULL;
  size_t method_len = -1;
  rc = obj_get(&request_obj, "method", MSGPACK_OBJECT_RAW, &method, &method_len);

  msgpack_sbuffer *response_buffer = msgpack_sbuffer_new();
  msgpack_sbuffer *result_buffer = msgpack_sbuffer_new();
  msgpack_sbuffer *error_buffer = msgpack_sbuffer_new();

  msgpack_packer *response_msg = msgpack_packer_new(response_buffer, msgpack_sbuffer_write);
  msgpack_packer *result = msgpack_packer_new(result_buffer, msgpack_sbuffer_write);
  msgpack_packer *error = msgpack_packer_new(error_buffer, msgpack_sbuffer_write);

  //printf("Method: %.*s\n", method_len, method);

  void *clock = zmq_stopwatch_start();
  double duration;

  if (rc != 0) { /* method not found */
    msgpack_pack_nil(result); /* result is nil on error */
    msgpack_pack_map(error, 2);
    msgpack_pack_string(error, "error", -1);
    msgpack_pack_string(error, "Message had no 'method' field", -1);
    msgpack_pack_string(error, "request", -1);
    msgpack_pack_object(error, request_obj);
  } else { /* valid method, keep going */
    //printf("The method is: '%.*s'\n", (int)method_len, method);
    rpc_name name;
    name.name = method;
    name.len = method_len;

    rpc_method *rpcmethod = g_tree_lookup(service->methods, &name);

    /* if we found a valid rpc method and the args check passed ... */
    if (rpcmethod != NULL) {
      /* the callback is responsible for filling in the 'result' and 'error' 
       * objects. */
      rpcmethod->callback(NULL, &request_obj, result, error, rpcmethod->data);
    } else {
      msgpack_pack_nil(result); /* result is nil on error */

      /* TODO(sissel): allow methods to register themselves */
      //fprintf(stderr, "Invalid request '%.*s' (unknown method): ",
              //method_len, method);
      //msgpack_object_print(stderr, request_obj);
      //fprintf(stderr, "\n");

      msgpack_pack_map(error, 2);
      msgpack_pack_string(error, "error", -1);
      msgpack_pack_string(error, "No such method requested", -1);
      msgpack_pack_string(error, "request", -1);
      msgpack_pack_object(error, request_obj);
    }
  } /* valid/invalid method handling */

  duration = zmq_stopwatch_stop(clock) / 1000000.;
  //printf("method '%.*s' took %lf seconds\n", (int)method_len, method);

  msgpack_unpacked result_unpacked;
  msgpack_unpacked error_unpacked;
  msgpack_unpacked response_unpacked;
  msgpack_unpacked_init(&result_unpacked);
  msgpack_unpacked_init(&error_unpacked);
  msgpack_unpacked_init(&response_unpacked);

  /* TODO(sissel): If this unpack test fails, we should return an error to the calling
   * client indicating that some internal error has occurred */
  //fprintf(stderr, "Result payload: '%.*s'\n", result_buffer->size,
  //result_buffer->data);
  rc = msgpack_unpack_next(&result_unpacked, result_buffer->data,
                           result_buffer->size, NULL);
  insist(rc == true, "msgpack_unpack_next failed on 'result' buffer"
         " of request '%.*s'", (int)method_len, method);
  rc = msgpack_unpack_next(&error_unpacked, error_buffer->data,
                           error_buffer->size, NULL);
  insist(rc == true, "msgpack_unpack_next failed on 'error' buffer"
         " of request '%.*s'", (int)method_len, method);

  msgpack_pack_map(response_msg, 3); /* result, error, duration */
  msgpack_pack_string(response_msg, "result", 6);
  msgpack_pack_object(response_msg, result_unpacked.data);
  msgpack_pack_string(response_msg, "error", 5);
  msgpack_pack_object(response_msg, error_unpacked.data);
  msgpack_pack_string(response_msg, "duration", 8);
  msgpack_pack_double(response_msg, duration);

  rc = msgpack_unpack_next(&response_unpacked, response_buffer->data,
                           response_buffer->size, NULL);
  insist(rc == true, "msgpack_unpack_next failed on full response buffer"
         " of request '%.*s'", (int)method_len, method);

  //printf("request: ");
  //msgpack_object_print(stdout, request_obj);
  //printf("\n");
  //printf("response: ");
  //msgpack_object_print(stdout, response_unpacked.data);
  //printf("\n");

  zmq_msg_init_data(&response, response_buffer->data, response_buffer->size,
                    free_msgpack_buffer, response_buffer);
  zmq_send(service->socket, &response, 0);
  zmq_msg_close(&response);

  msgpack_packer_free(error);
  msgpack_packer_free(result);
  msgpack_sbuffer_free(error_buffer);
  msgpack_sbuffer_free(result_buffer);
  msgpack_packer_free(response_msg);
  msgpack_unpacked_destroy(&request_msg);
} /* rpc_service_handle */
Пример #8
0
/**
 * @brief Function that will run the thread associated with a particular interface
 * instance.
 *
 * Since multiple different command line a graphical user interfaces
 * can exists simultaneously, this allows the scheduler to quickly perform any
 * requests.
 *
 * Handle commands:
 *
 * | Command | Description |
 * | ---: | :--- |
 * |     exit | Close connection with scheduler |
 * |     kill | Kill a particular job |
 * |     load | Get the host status |
 * |    close | Shutdown the scheduler |
 * |    pause | Pause a job that is currently running |
 * |   reload | Reload configuration information |
 * |   status | Request status for scheduler or job |
 * |  restart | Restart a paused job |
 * |  verbose | Change verbose level for scheduler or job |
 * | priority | Change the priority of job |
 * | database | Check the database job queue |
 *
 * @param  conn      Pointer to the interface_connection structure
 * @param  scheduler Pointer to the relevant scheduler structure
 * @return not currently used
 */
void interface_thread(interface_connection* conn, scheduler_t* scheduler)
{
  GMatchInfo* regex_match;
  job_t* job;
  char buffer[BUFFER_SIZE];
  char org[sizeof(buffer)];
  char* arg1, * arg2, * arg3;
  char* cmd;
  arg_int* params;
  int i;

  memset(buffer, '\0', sizeof(buffer));

  while(g_input_stream_read(conn->istr, buffer, sizeof(buffer), scheduler->cancel, NULL) > 0)
  {
    V_INTERFACE("INTERFACE: received \"%s\"\n", buffer);
    /* convert all characters before first ' ' to lower case */
    memcpy(org, buffer, sizeof(buffer));
    for(cmd = buffer; *cmd; cmd++)
      *cmd = g_ascii_tolower(*cmd);
    g_regex_match(scheduler->parse_interface_cmd, buffer, 0, &regex_match);
    cmd = g_match_info_fetch(regex_match, 1);

    if(cmd == NULL)
    {
      g_output_stream_write(conn->ostr, "Invalid command: \"", 18, NULL, NULL);
      g_output_stream_write(conn->ostr, buffer, strlen(buffer), NULL, NULL);
      g_output_stream_write(conn->ostr, "\"\n", 2, NULL, NULL);
      g_match_info_free(regex_match);
      WARNING("INTERFACE: invalid command: \"%s\"", buffer);
      continue;
    }

    /* acknowledge that you have received the command */
    V_INTERFACE("INTERFACE: send \"received\"\n");
    g_output_stream_write(conn->ostr, "received\n", 9, NULL, NULL);

    /* command: "close"
     *
     * The interface has chosen to close the connection. Return the command
     * in acknowledgment of the command and end this thread.
     */
    if(strcmp(cmd, "close") == 0)
    {
      g_output_stream_write(conn->ostr, "CLOSE\n", 6, NULL, NULL);
      V_INTERFACE("INTERFACE: closing connection to user interface\n");

      g_match_info_free(regex_match);
      g_free(cmd);
      return;
    }

    /* command: "stop"
     *
     * The interface has instructed the scheduler to shut down gracefully. The
     * scheduler will wait for all currently executing agents to finish
     * running, then exit the vent loop.
     */
    else if(strcmp(cmd, "stop") == 0)
    {
      g_output_stream_write(conn->ostr, "CLOSE\n", 6, NULL, NULL);
      V_INTERFACE("INTERFACE: shutting down scheduler gracefully\n");
      event_signal(scheduler_close_event, (void*)0);

      g_match_info_free(regex_match);
      g_free(cmd);
      return;
    }

    /* command: "die"
     *
     * The interface has instructed the scheduler to shut down. The scheduler
     * should acknowledge the command and proceed to kill all current executing
     * agents and exit the event loop
     */
    else if(strcmp(cmd, "die") == 0)
    {
      g_output_stream_write(conn->ostr, "CLOSE\n", 6, NULL, NULL);
      V_INTERFACE("INTERFACE: killing the scheduler\n");
      event_signal(scheduler_close_event, (void*)1);

      g_match_info_free(regex_match);
      g_free(cmd);
      return;
    }

    /* command: "load"
     *
     * The interface has requested information about the load that the different
     * hosts are under. The scheduler should respond with the status of all the
     * hosts.
     */
    else if(strcmp(cmd, "load") == 0)
    {
      print_host_load(scheduler->host_list, conn->ostr);
    }

    /* command: "kill <job_id> <"message">"
     *
     * The interface has instructed the scheduler to kill and fail a particular
     * job. Both arguments are required for this command.
     *
     * job_id: The jq_pk for the job that needs to be killed
     * message: A message that will be in the email notification and the
     *          jq_endtext field of the job queue
     */
    else if(strcmp(cmd, "kill") == 0)
    {
      arg1 = g_match_info_fetch(regex_match, 3);
      arg2 = g_match_info_fetch(regex_match, 8);

      if(arg1)
        i = atoi(arg1);
      if(arg1 == NULL || arg2 == NULL || strlen(arg1) == 0 || strlen(arg2) == 0)
      {
        g_free(cmd);
        cmd = g_strdup_printf("Invalid kill command: \"%s\"\n", buffer);
        g_output_stream_write(conn->ostr, cmd, strlen(cmd), NULL, NULL);
      }
      else if((job = g_tree_lookup(scheduler->job_list, &i)) == NULL)
      {
        arg3 = g_strdup_printf(jobsql_failed, arg2, i);
        event_signal(database_exec_event, arg3);
      }
      else
      {
        if(job->message)
          g_free(job->message);
        job->message = strdup(((arg2 == NULL) ? "no message" : arg2));
        event_signal(job_fail_event, job);
      }

      g_free(arg1);
      g_free(arg2);
    }

    /* command: "pause <job_id>"
     *
     * The interface has instructed the scheduler to pause a job. This is used
     * to free up resources on a particular host. The argument is required and
     * is the jq_pk for the job that needs to be paused.
     */
    else if(strcmp(cmd, "pause") == 0)
    {
      arg1 = g_match_info_fetch(regex_match, 3);

      if(arg1 == NULL || strlen(arg1) == 0)
      {
        arg1 = g_strdup_printf("Invalid pause command: \"%s\"\n", buffer);
        WARNING("received invalid pause command: %s", buffer);
        g_output_stream_write(conn->ostr, arg1, strlen(arg1), NULL, NULL);
        g_free(arg1);
      }
      else
      {
        params = g_new0(arg_int, 1);
        params->second = atoi(arg1);
        params->first = g_tree_lookup(scheduler->job_list, &params->second);
        event_signal(job_pause_event, params);
        g_free(arg1);
      }
    }

    /* command: "reload"
     *
     * The scheduler should reload its configuration information. This should
     * be used if a change to an agent or fossology.conf has been made since
     * the scheduler started running.
     */
    else if(strcmp(cmd, "reload") == 0)
    {
      event_signal(scheduler_config_event, NULL);
    }

    /* command: "agents"
     *
     * The interface has requested a list of agents that the scheduler is able
     * to run correctly.
     */
    else if(strcmp(cmd, "agents") == 0)
    {
      event_signal(list_agents_event, conn->ostr);
    }

    /* command: "status [job_id]"
     *
     * fetches the status of the a particular job or the scheduler. The
     * argument is not required for this command.
     *
     * with job_id:
     *   print job status followed by status of agent belonging to the job
     * without job_id:
     *   print scheduler statsu followed by status of every job
     */
    else if(strcmp(cmd, "status") == 0)
    {
      arg1 = g_match_info_fetch(regex_match, 3);

      params = g_new0(arg_int, 1);
      params->first = conn->ostr;
      params->second = (arg1 == NULL) ? 0 : atoi(arg1);
      event_signal(job_status_event, params);

      g_free(arg1);
    }

    /* command: "restart <job_id>"
     *
     * The interface has instructed the scheduler to restart a job that has been
     * paused. The argument for this command is required and is the jq_pk for
     * the job that should be restarted.
     */
    else if(strcmp(cmd, "restart") == 0)
    {
      arg1 = g_match_info_fetch(regex_match, 3);

      if(arg1 == NULL)
      {
        arg1 = g_strdup(buffer);
        WARNING("received invalid restart command: %s", buffer);
        snprintf(buffer, sizeof(buffer) - 1,
                    "ERROR: Invalid restart command: %s\n", arg1);
        g_output_stream_write(conn->ostr, buffer, strlen(buffer), NULL, NULL);
        g_free(arg1);
      }
      else
      {
        params = g_new0(arg_int, 1);
        params->second = atoi(arg1);
        params->first = g_tree_lookup(scheduler->job_list, &params->second);
        event_signal(job_restart_event, params);
        g_free(arg1);
      }
    }

    /* command: "verbose <job_id|level> [level]"
     *
     * The interface has either requested a change in a verbose level, or it
     * has requested the current verbose level. This command can have no
     * arguments, 1 argument or 2 arguments.
     *
     * no arguments: respond with the verbose level of the scheduler
     *  1 argument:  change the verbose level of the scheduler to the argument
     *  2 arguments: change the verbose level of the job with the jq_pk of the
     *               first arguement to the second argument
     */
    else if(strcmp(cmd, "verbose") == 0)
    {
      arg1 = g_match_info_fetch(regex_match, 3);
      arg2 = g_match_info_fetch(regex_match, 5);

      if(arg1 == NULL)
      {
        if(verbose < 8)
        {
          sprintf(buffer, "level: %d\n", verbose);
        }
        else
        {
          strcpy(buffer, "mask:       h d i e s a j\nmask: ");
          for(i = 1; i < 0x10000; i <<= 1)
            strcat(buffer, i & verbose ? "1 " : "0 ");
          strcat(buffer, "\n");
        }
        g_output_stream_write(conn->ostr, buffer, strlen(buffer), NULL, NULL);
      }
      else if(arg2 == NULL)
      {
        verbose = atoi(arg1);
        g_free(arg1);
      }
      else
      {
        i = atoi(arg1);
        if((job = g_tree_lookup(scheduler->job_list, &i)) == NULL)
        {
          g_free(cmd);
          cmd = g_strdup_printf("Invalid verbose command: \"%s\"\n", buffer);
          g_output_stream_write(conn->ostr, cmd, strlen(cmd), NULL, NULL);
        }
        else
        {
          job->verbose = atoi(arg2);
          event_signal(job_verbose_event, job);
        }

        g_free(arg1);
        g_free(arg2);
      }
    }

    /* command: "priority <job_id> <level>"
     *
     * Scheduler should change the priority of a job. This will change the
     * systems priority of the relevant job and change the priority of the job
     * in the database to match. Both arguments are required for this command.
     */
    else if(strcmp(cmd, "priority") == 0)
    {
      arg1 = g_match_info_fetch(regex_match, 3);
      arg2 = g_match_info_fetch(regex_match, 5);

      if(arg1 != NULL && arg2 != NULL)
      {
        i = atoi(arg1);

        params = g_new0(arg_int, 1);
        params->first = g_tree_lookup(scheduler->job_list, &i);
        params->second = atoi(arg2);
        event_signal(job_priority_event, params);
        g_free(arg1);
        g_free(arg2);
      }
      else
      {
        if(arg1) g_free(arg1);
        if(arg2) g_free(arg2);

        arg1 = g_strdup(buffer);
        WARNING("Invalid priority command: %s\n", buffer);
        snprintf(buffer, sizeof(buffer) - 1,
            "ERROR: Invalid priority command: %s\n", arg1);
        g_output_stream_write(conn->ostr, buffer, strlen(buffer), NULL, NULL);
        g_free(arg1);
      }
    }

    /* command: "database"
     *
     * The scheduler should check the database. This will normaly be sent by
     * the ui when a new job has been queue and must be run.
     */
    else if(strcmp(cmd, "database") == 0)
    {
      event_signal(database_update_event, NULL);
    }

    /* command: unknown
     *
     * The command sent does not match any of the known commands, log an error
     * and inform the interface that this wasn't a command.
     */
    else
    {
      g_output_stream_write(conn->ostr, "Invalid command: \"", 18, NULL, NULL);
      g_output_stream_write(conn->ostr, buffer, strlen(buffer), NULL, NULL);
      g_output_stream_write(conn->ostr, "\"\n", 2, NULL, NULL);
      con_printf(main_log, "ERROR %s.%d: Interface received invalid command: %s\n", __FILE__, __LINE__, cmd);
    }

    g_match_info_free(regex_match);
    g_free(cmd);
    memset(buffer, '\0', sizeof(buffer));
  }

  interface_conn_destroy(conn);
  return;
}
Пример #9
0
static enum http_rc_e
handler_action (struct http_request_s *rq, struct http_reply_ctx_s *rp)
{
    gboolean _boolhdr (const gchar * n) {
        return metautils_cfg_get_bool (
            (gchar *) g_tree_lookup (rq->tree_headers, n), FALSE);
    }

    // Get a request id for the current request
    const gchar *reqid = g_tree_lookup (rq->tree_headers, PROXYD_HEADER_REQID);
    if (reqid)
        oio_ext_set_reqid(reqid);
    else
        oio_ext_set_random_reqid();

    // Then parse the request to find a handler
    struct oio_url_s *url = NULL;
    struct oio_requri_s ruri = {NULL, NULL, NULL, NULL};
    oio_requri_parse (rq->req_uri, &ruri);

    struct path_matching_s **matchings = _metacd_match (rq->cmd, ruri.path);

    GRID_TRACE2("URI path[%s] query[%s] fragment[%s] matches[%u]",
                ruri.path, ruri.query, ruri.fragment,
                g_strv_length((gchar**)matchings));

    GQuark gq_count = gq_count_unexpected;
    GQuark gq_time = gq_time_unexpected;

    enum http_rc_e rc;
    if (!*matchings) {
        rp->set_content_type ("application/json");
        rp->set_body_gstr (g_string_new("{\"status\":404,\"message\":\"No handler found\"}"));
        rp->set_status (HTTP_CODE_NOT_FOUND, "No handler found");
        rp->finalize ();
        rc = HTTPRC_DONE;
    } else {
        struct req_args_s args = {NULL,NULL,NULL, NULL,NULL, 0};
        args.req_uri = &ruri;
        args.matchings = matchings;
        args.rq = rq;
        args.rp = rp;

        if (_boolhdr (PROXYD_HEADER_NOEMPTY))
            args.flags |= FLAG_NOEMPTY;

        args.url = url = _metacd_load_url (&args);
        rp->subject(oio_url_get(url, OIOURL_HEXID));
        gq_count = (*matchings)->last->gq_count;
        gq_time = (*matchings)->last->gq_time;
        GRID_TRACE("URL %s", oio_url_get(args.url, OIOURL_WHOLE));
        req_handler_f handler = (*matchings)->last->u;
        rc = (*handler) (&args);
    }

    gint64 spent = oio_ext_monotonic_time () - rq->client->time.evt_in;

    network_server_stat_push4 (rq->client->server, TRUE,
                               gq_count, 1, gq_count_all, 1,
                               gq_time, spent, gq_time_all, spent);

    path_matching_cleanv (matchings);
    oio_requri_clear (&ruri);
    oio_url_pclean (&url);
    return rc;
}
Пример #10
0
static void GCC_INLINE freecell_solver_cache_stacks(
        freecell_solver_hard_thread_t * hard_thread,
        fcs_state_with_locations_t * new_state
        )
{
    int a;
#if (FCS_STACK_STORAGE == FCS_STACK_STORAGE_INTERNAL_HASH)
    SFO_hash_value_t hash_value_int;
#endif
    void * cached_stack;
    char * new_ptr;
    freecell_solver_instance_t * instance = hard_thread->instance;
    int stacks_num = instance->stacks_num;
    

    for(a=0 ; a<stacks_num ; a++)
    {
        /* 
         * If the stack is not a copy - it is already cached so skip
         * to the next stack
         * */
        if (! (new_state->stacks_copy_on_write_flags & (1 << a)))
        {
            continue;
        }
        /* new_state->s.stacks[a] = realloc(new_state->s.stacks[a], fcs_stack_len(new_state->s, a)+1); */
        fcs_compact_alloc_typed_ptr_into_var(new_ptr, char, hard_thread->stacks_allocator, (fcs_stack_len(new_state->s, a)+1));
        memcpy(new_ptr, new_state->s.stacks[a], (fcs_stack_len(new_state->s, a)+1));
        new_state->s.stacks[a] = new_ptr;

#if FCS_STACK_STORAGE == FCS_STACK_STORAGE_INTERNAL_HASH
        /* Calculate the hash value for the stack */
        /* This hash function was ripped from the Perl source code.
         * (It is not derived work however). */
        {
            const char * s_ptr = (char*)(new_state->s.stacks[a]);
            const char * s_end = s_ptr+fcs_stack_len(new_state->s, a)+1;
            hash_value_int = 0;
            while (s_ptr < s_end)
            {
                hash_value_int += (hash_value_int << 5) + *(s_ptr++);
            }
            hash_value_int += (hash_value_int >> 5);
        }

        if (hash_value_int < 0)
        {
            /*
             * This is a bit mask that nullifies the sign bit of the
             * number so it will always be positive
             * */
            hash_value_int &= (~(1<<((sizeof(hash_value_int)<<3)-1)));
        }

        cached_stack = (void *)freecell_solver_hash_insert(
            instance->stacks_hash,
            new_state->s.stacks[a],
            freecell_solver_lookup2_hash_function(
                (ub1 *)new_state->s.stacks[a],
                (fcs_stack_len(new_state->s, a)+1),
                24
                ),
            hash_value_int,
            1
            );

#define replace_with_cached(condition_expr) \
        if (cached_stack != NULL)     \
        {      \
            fcs_compact_alloc_release(hard_thread->stacks_allocator);    \
            new_state->s.stacks[a] = cached_stack;       \
        }

        replace_with_cached(cached_stack != NULL);
        
#elif (FCS_STACK_STORAGE == FCS_STACK_STORAGE_LIBAVL_AVL_TREE) || (FCS_STACK_STORAGE == FCS_STACK_STORAGE_LIBAVL_REDBLACK_TREE)
        cached_stack =
#if (FCS_STACK_STORAGE == FCS_STACK_STORAGE_LIBAVL_AVL_TREE)
            avl_insert(
#elif (FCS_STACK_STORAGE == FCS_STACK_STORAGE_LIBAVL_REDBLACK_TREE)
            rb_insert(
#endif
            instance->stacks_tree,
            new_state->s.stacks[a]
            );
#if 0
            )        /* In order to settle gvim and other editors that
                         are keen on parenthesis matching */
#endif

        replace_with_cached(cached_stack != NULL);

#elif (FCS_STACK_STORAGE == FCS_STACK_STORAGE_LIBREDBLACK_TREE)
        cached_stack = (void *)rbsearch(
            new_state->s.stacks[a],
            instance->stacks_tree
            );

        replace_with_cached(cached_stack != new_state->s.stacks[a]);
#elif (FCS_STACK_STORAGE == FCS_STACK_STORAGE_GLIB_TREE)
        cached_stack = g_tree_lookup(
             instance->stacks_tree,
             (gpointer)new_state->s.stacks[a]
             );

        /* replace_with_cached contains an if statement */
        replace_with_cached(cached_stack != NULL)
        else
        {
            g_tree_insert(
                instance->stacks_tree,
                (gpointer)new_state->s.stacks[a],
                (gpointer)new_state->s.stacks[a]
                );
        }
#elif (FCS_STACK_STORAGE == FCS_STACK_STORAGE_GLIB_HASH)
        cached_stack = g_hash_table_lookup(
            instance->stacks_hash,
            (gconstpointer)new_state->s.stacks[a]
            );
        replace_with_cached(cached_stack != NULL)
        else
        {
            g_hash_table_insert(
                instance->stacks_hash,
                (gpointer)new_state->s.stacks[a],
                (gpointer)new_state->s.stacks[a]
                );
        }
#endif
    }
Пример #11
0
int req_parser_add_text(req_parser *r, const char *data, size_t len)
{
	const char *end;
	if (!g_utf8_validate(data, len, &end))
	{
		return REQ_PARSER_PARSE_INVALID_REQUEST;
	}

	int result = REQ_PARSER_PARSE_PARTIAL_REQUEST;

	int mode = (r->method == REQ_PARSER_METHOD_INVALID) ? MODE_REQUEST_LINE : MODE_HEADER_LINE;
	const gchar *headerQuark = NULL;

	char buf[HEADER_BUF_SIZE];
	const char *token_start = data;
	const char *i;
	for (i = data; (i < end) && *i; i = g_utf8_next_char(i))
	{
		result = REQ_PARSER_PARSE_PARTIAL_REQUEST;
		gunichar c = g_utf8_get_char(i);

		if (c == '\r')
		{
			i = g_utf8_next_char(i);
			c = g_utf8_get_char(i);
		}
		if ((c == '\n') && (*g_utf8_prev_char(i) != '\r'))
		{
			fprintf(stderr, "ERROR - Encountered a newline without a preceding carriage return.\n");
			req_parser_reset(r);
			return REQ_PARSER_PARSE_INVALID_REQUEST;
		}

		switch (mode)
		{
		case MODE_REQUEST_LINE:
			if (c == ' ')
			{
				if (r->method == REQ_PARSER_METHOD_INVALID)
				{
					if (strncmp("GET", token_start, 3) == 0) r->method = REQ_PARSER_METHOD_GET;
					else if (strncmp("HEAD", token_start, 4) == 0) r->method = REQ_PARSER_METHOD_HEAD;
					else if (strncmp("POST", token_start, 4) == 0) r->method = REQ_PARSER_METHOD_POST;
					else if (strncmp("OPTIONS", token_start, 7) == 0) r->method = REQ_PARSER_METHOD_OPTIONS;
					else
					{
						fprintf(stderr, "ERROR - Unknown method\n");
						req_parser_reset(r);
						return REQ_PARSER_PARSE_INVALID_REQUEST;
					}

					// skip over the separating space
					i = g_utf8_next_char(i);
					token_start = i;
				}
				else if (r->path == NULL)
				{
					parse_uri(r, token_start, (i - token_start));

					// skip over the separating space
					i = g_utf8_next_char(i);
					token_start = i;
				}
				else
				{
					fprintf(stderr, "ERROR - Too many spaces in request line\n");
					req_parser_reset(r);
					return REQ_PARSER_PARSE_INVALID_REQUEST;
				}
			}
			else if (c == '\n')
			{
				if (strncmp("HTTP/1.1", token_start, min(8, i - token_start)) != 0)
				{
					fprintf(stderr, "ERROR - Unsupported HTTP version\n");
					req_parser_reset(r);
					return REQ_PARSER_PARSE_INVALID_REQUEST;
				}
				token_start = NULL;
				mode = MODE_HEADER_LINE;
			}
			break;

		case MODE_HEADER_LINE:
			if (token_start == NULL)
			{
				token_start = i;
			}

			if ((token_start == i) && (c == '\n'))
			{
				result = REQ_PARSER_PARSE_OK;
				mode = MODE_REQUEST_BODY;
			}
			else if ((headerQuark == NULL) && (c == ':'))
			{
				memset(buf, 0, HEADER_BUF_SIZE);
				memcpy(buf, token_start, min((i - token_start), HEADER_BUF_SIZE - 1));
				headerQuark = g_intern_string(buf);
				token_start = NULL;

				// skip over the separating space
				i = g_utf8_next_char(i);
			}
			else if (c == '\n')
			{
				if (!r->headers)
				{
					r->headers = g_tree_new_full(quarkcmp, NULL, NULL, gstring_destroy_notify);
				}

				// Subtract one since we don't want the "\r" in the header
				g_tree_insert(r->headers, (gpointer)headerQuark, g_string_new_len(token_start, (i - token_start) - 1));
				token_start = NULL;
				headerQuark = NULL;
			}
			break;

		case MODE_REQUEST_BODY:
			if (r->body == NULL)
			{
				token_start = i;

				if (!r->headers)
				{
					r->headers = g_tree_new_full(quarkcmp, NULL, NULL, gstring_destroy_notify);
				}

				GString *length_header = g_tree_lookup(r->headers, g_intern_static_string("Content-Length"));
				if (length_header)
				{
					int length = atoi(length_header->str);
					size_t bytes_remaining = len - (data - i);

					if (bytes_remaining < (size_t)length)
					{
						fprintf(stderr, "ERROR - Body incomplete.\n");
						req_parser_reset(r);
						return REQ_PARSER_PARSE_INVALID_REQUEST;
					}

					r->body = g_string_new_len(i, length);
					i = i + length;
				}
				else
				{
					size_t length = len - (data - i);
					r->body = g_string_new_len(i, length);
					i = i + length;
				}
				result = REQ_PARSER_PARSE_OK;
			}
			else if (c == '\n')
			{
				result = REQ_PARSER_PARSE_OK;
			}
			break;
		}
	}

	r->status = result;
	return result;
}
static void GCC_INLINE fc_solve_cache_stacks(
        fc_solve_hard_thread_t * hard_thread,
        fcs_state_t * new_state_key,
        fcs_state_extra_info_t * new_state_val
        )
{
    int a;
#if (FCS_STACK_STORAGE == FCS_STACK_STORAGE_INTERNAL_HASH)
#ifdef FCS_ENABLE_SECONDARY_HASH_VALUE
    SFO_hash_value_t hash_value_int;
#endif
#elif (FCS_STACK_STORAGE == FCS_STACK_STORAGE_JUDY)
    PWord_t * PValue;
#endif
    void * cached_stack;
    char * new_ptr;
    fc_solve_instance_t * instance = hard_thread->instance;
#ifndef HARD_CODED_NUM_STACKS
    DECLARE_AND_SET_GAME_PARAMS();
#endif
    fcs_cards_column_t column;
    register int col_len;
    fcs_compact_allocator_t * stacks_allocator;
    
    stacks_allocator = &(hard_thread->allocator);

    for(a=0 ; a < LOCAL_STACKS_NUM ; a++)
    {
        /*
         * If the stack is not a copy - it is already cached so skip
         * to the next stack
         * */
        if (! (new_state_val->stacks_copy_on_write_flags & (1 << a)))
        {
            continue;
        }

        column = fcs_state_get_col(*new_state_key, a);
        col_len = (fcs_col_len(column)+1);

        new_ptr = (char*)fcs_compact_alloc_ptr(stacks_allocator, col_len);
        memcpy(new_ptr, column, col_len);
        new_state_key->stacks[a] = new_ptr;

#if FCS_STACK_STORAGE == FCS_STACK_STORAGE_INTERNAL_HASH
#ifdef FCS_ENABLE_SECONDARY_HASH_VALUE
        /* Calculate the hash value for the stack */
        /* This hash function was ripped from the Perl source code.
         * (It is not derived work however). */
        {
            const char * s_ptr = (char*)(new_state_key->stacks[a]);
            const char * s_end = s_ptr+fcs_col_len(s_ptr)+1;
            hash_value_int = 0;
            while (s_ptr < s_end)
            {
                hash_value_int += (hash_value_int << 5) + *(s_ptr++);
            }
            hash_value_int += (hash_value_int >> 5);
        }

        if (hash_value_int < 0)
        {
            /*
             * This is a bit mask that nullifies the sign bit of the
             * number so it will always be positive
             * */
            hash_value_int &= (~(1<<((sizeof(hash_value_int)<<3)-1)));
        }
#endif

        {
            void * dummy;
            int verdict;

            column = fcs_state_get_col(*new_state_key, a);

            verdict = fc_solve_hash_insert(
                &(instance->stacks_hash),
                column,
                column,
                &cached_stack,
                &dummy,
                perl_hash_function(
                    (ub1 *)new_state_key->stacks[a],
                    col_len
                    )
#ifdef FCS_ENABLE_SECONDARY_HASH_VALUE
                , hash_value_int
#endif
                );

            replace_with_cached(verdict);
        }

#elif (FCS_STACK_STORAGE == FCS_STACK_STORAGE_GOOGLE_DENSE_HASH)
        {
            int verdict;
            void * dummy;

            column = fcs_state_get_col(*new_state_key, a);

            verdict = fc_solve_columns_google_hash_insert(
                    instance->stacks_hash,
                    column,
                    column,
                    &cached_stack,
                    &dummy
                    );

            replace_with_cached(verdict);
        }
#elif (FCS_STACK_STORAGE == FCS_STACK_STORAGE_LIBAVL2_TREE)

        cached_stack =
            fcs_libavl2_stacks_tree_insert(
                instance->stacks_tree,
                new_state_key->stacks[a]
            );

        replace_with_cached(cached_stack != NULL);

#elif (FCS_STACK_STORAGE == FCS_STACK_STORAGE_LIBREDBLACK_TREE)
        cached_stack = (void *)rbsearch(
            new_state_key->stacks[a],
            instance->stacks_tree
            );

        replace_with_cached(cached_stack != new_state_key->stacks[a]);
#elif (FCS_STACK_STORAGE == FCS_STACK_STORAGE_GLIB_TREE)
        cached_stack = g_tree_lookup(
             instance->stacks_tree,
             (gpointer)new_state_key->stacks[a]
             );

        /* replace_with_cached contains an if statement */
        replace_with_cached(cached_stack != NULL)
        else
        {
            g_tree_insert(
                instance->stacks_tree,
                (gpointer)new_state_key->stacks[a],
                (gpointer)new_state_key->stacks[a]
                );
        }
#elif (FCS_STACK_STORAGE == FCS_STACK_STORAGE_GLIB_HASH)
        cached_stack = g_hash_table_lookup(
            instance->stacks_hash,
            (gconstpointer)new_state_key->stacks[a]
            );
        replace_with_cached(cached_stack != NULL)
        else
        {
            g_hash_table_insert(
                instance->stacks_hash,
                (gpointer)new_state_key->stacks[a],
                (gpointer)new_state_key->stacks[a]
                );
        }
#elif (FCS_STACK_STORAGE == FCS_STACK_STORAGE_JUDY)
        column = fcs_state_get_col(*new_state_key, a);

        JHSI(
            PValue,
            instance->stacks_judy_array,
            column,
            (1+fcs_col_len(column))
        );
        /* later_todo : Handle out-of-memory. */
        if (*PValue == 0)
        {
            /*  A new stack */
            *PValue = (PWord_t)column;
        }
        else
        {
            cached_stack = (void *)(*PValue);
            replace_with_cached(1);
        }
#else
#error FCS_STACK_STORAGE is not set to a good value.
#endif
    }
}
GCC_INLINE int fc_solve_check_and_add_state(
    fc_solve_soft_thread_t * soft_thread,
    fcs_state_extra_info_t * new_state_val,
    fcs_state_extra_info_t * * existing_state_val
    )
{
#if (FCS_STATE_STORAGE == FCS_STATE_STORAGE_INTERNAL_HASH)
#ifdef FCS_ENABLE_SECONDARY_HASH_VALUE
    SFO_hash_value_t hash_value_int;
#endif
#endif
#if (FCS_STATE_STORAGE == FCS_STATE_STORAGE_INDIRECT)
    fcs_standalone_state_ptrs_t * pos_ptr;
    int found;
#endif
    fc_solve_hard_thread_t * hard_thread = soft_thread->hard_thread;
    fc_solve_instance_t * instance = hard_thread->instance;
    fcs_state_t * new_state_key = new_state_val->key;

    int is_state_new;

    if (check_if_limits_exceeded())
    {
        return FCS_STATE_BEGIN_SUSPEND_PROCESS;
    }

    if ((instance->max_depth >= 0) &&
        (new_state_val->depth >= instance->max_depth))
    {
        return FCS_STATE_EXCEEDS_MAX_DEPTH;
    }


    fc_solve_cache_stacks(hard_thread, new_state_key, new_state_val);

    fc_solve_canonize_state(new_state_val,
            INSTANCE_FREECELLS_NUM,
            INSTANCE_STACKS_NUM
            );

/*
    The objective of this part of the code is:
    1. To check if new_state_key / new_state_val is already in the prev_states
       collection.
    2. If not, to add it and to set check to true.
    3. If so, to set check to false.
  */

#if (FCS_STATE_STORAGE == FCS_STATE_STORAGE_INTERNAL_HASH)
#ifdef FCS_ENABLE_SECONDARY_HASH_VALUE
    {
        const char * s_ptr = (char*)new_state_key;
        const char * s_end = s_ptr+sizeof(*new_state_key);
        hash_value_int = 0;
        while (s_ptr < s_end)
        {
            hash_value_int += (hash_value_int << 5) + *(s_ptr++);
        }
        hash_value_int += (hash_value_int>>5);
    }
    if (hash_value_int < 0)
    {
        /*
         * This is a bit mask that nullifies the sign bit of the
         * number so it will always be positive
         * */
        hash_value_int &= (~(1<<((sizeof(hash_value_int)<<3)-1)));
    }
#endif
    {
        void * existing_key_void, * existing_val_void;
    is_state_new = (fc_solve_hash_insert(
        &(instance->hash),
        new_state_key,
        new_state_val,
        &existing_key_void,
        &existing_val_void,
        perl_hash_function(
            (ub1 *)new_state_key,
            sizeof(*new_state_key)
            )
#ifdef FCS_ENABLE_SECONDARY_HASH_VALUE
        , hash_value_int
#endif
        ) == 0);
        if (! is_state_new)
        {
            *existing_state_val = existing_val_void;
        }
    }
#elif (FCS_STATE_STORAGE == FCS_STATE_STORAGE_GOOGLE_DENSE_HASH)
    {
        void * existing_key_void, * existing_val_void;

        is_state_new = (fc_solve_states_google_hash_insert(
            instance->hash,
            new_state_key,
            new_state_val,
            &existing_key_void,
            &existing_val_void
            ) == 0);

        if (! is_state_new)
        {
            *existing_state_val = existing_val_void;
        }
    }
#elif (FCS_STATE_STORAGE == FCS_STATE_STORAGE_INDIRECT)
    /* Try to see if the state is found in indirect_prev_states */
    if ((pos_ptr = (fcs_standalone_state_ptrs_t *)bsearch(&new_state_key,
                instance->indirect_prev_states,
                instance->num_indirect_prev_states,
                sizeof(instance->indirect_prev_states[0]),
                fc_solve_state_compare_indirect)) == NULL)
    {
        /* It isn't in prev_states, but maybe it's in the sort margin */
        pos_ptr = (fcs_standalone_state_ptrs_t *)fc_solve_bsearch(
            &new_state_key,
            instance->indirect_prev_states_margin,
            instance->num_prev_states_margin,
            sizeof(instance->indirect_prev_states_margin[0]),
            fc_solve_state_compare_indirect_with_context,
            NULL,
            &found);

        if (found)
        {
            is_state_new = 0;
            *existing_state_val = pos_ptr->val;
        }
        else
        {
            /* Insert the state into its corresponding place in the sort
             * margin */
            memmove((void*)(pos_ptr+1),
                    (void*)pos_ptr,
                    sizeof(*pos_ptr) *
                    (instance->num_prev_states_margin-
                      (pos_ptr-instance->indirect_prev_states_margin)
                    ));
            pos_ptr->key = new_state_key;
            pos_ptr->val = new_state_val;

            instance->num_prev_states_margin++;

            if (instance->num_prev_states_margin >= PREV_STATES_SORT_MARGIN)
            {
                /* The sort margin is full, let's combine it with the main array */

                instance->indirect_prev_states = 
                    realloc(
                        instance->indirect_prev_states,
                        sizeof(instance->indirect_prev_states[0])
                        * (instance->num_indirect_prev_states
                            + instance->num_prev_states_margin
                        )
                    );

                fc_solve_merge_large_and_small_sorted_arrays(
                    instance->indirect_prev_states,
                    instance->num_indirect_prev_states,
                    instance->indirect_prev_states_margin,
                    instance->num_prev_states_margin,
                    sizeof(instance->indirect_prev_states[0]),
                    fc_solve_state_compare_indirect_with_context,
                    NULL
                );

                instance->num_indirect_prev_states += instance->num_prev_states_margin;

                instance->num_prev_states_margin=0;
            }
            is_state_new = 1;
        }

    }
    else
    {
        *existing_state_val = pos_ptr->val;
        is_state_new = 0;
    }

#elif (FCS_STATE_STORAGE == FCS_STATE_STORAGE_LIBREDBLACK_TREE)
    *existing_state_val = (fcs_state_extra_info_t *)rbsearch(new_state_val,
            instance->tree
            );
    is_state_new = ((*existing_state_val) == new_state_val);

#elif (FCS_STATE_STORAGE == FCS_STATE_STORAGE_LIBAVL2_TREE)

    *existing_state_val = (fcs_state_extra_info_t *)
        fcs_libavl2_states_tree_insert(instance->tree, new_state_val);
    is_state_new = ((*existing_state_val) == NULL);

#elif (FCS_STATE_STORAGE == FCS_STATE_STORAGE_GLIB_TREE)
    *existing_state_val = g_tree_lookup(instance->tree, (gpointer)new_state_key);
    if (*existing_state_val == NULL)
    {
        /* The new state was not found. Let's insert it.
         * The value must be the same as the key, so g_tree_lookup()
         * will return it. */
        g_tree_insert(
            instance->tree,
            (gpointer)new_state_key,
            (gpointer)new_state_val
            );
        is_state_new = 1;
    }
    else
    {
        is_state_new = 0;
    }



#elif (FCS_STATE_STORAGE == FCS_STATE_STORAGE_GLIB_HASH)
    *existing_state_val = g_hash_table_lookup(instance->hash, 
            (gpointer)new_state_key);
    if (*existing_state_val == NULL)
    {
        /* The new state was not found. Let's insert it.
         * The value must be the same as the key, so g_tree_lookup()
         * will return it. */
        g_hash_table_insert(
            instance->hash,
            (gpointer)new_state_key,
            (gpointer)new_state_val

            );
        is_state_new = 1;
    }
    else
    {
        is_state_new = 0;
    }

#elif (FCS_STATE_STORAGE == FCS_STATE_STORAGE_DB_FILE)
    {
        DBT key, value;
        key.data = new_state;
        key.size = sizeof(*new_state);
        if (instance->db->get(
            instance->db,
            NULL,
            &key,
            &value,
            0
            ) == 0)
        {
            /* The new state was not found. Let's insert it.
             * The value must be the same as the key, so g_tree_lookup()
             * will return it. */

            value.data = key.data;
            value.size = key.size;
            instance->db->put(
                instance->db,
                NULL,
                &key,
                &value,
                0);
            is_state_new = 1;
        }
        else
        {
            is_state_new = 0;
        }
    }
#elif (FCS_STATE_STORAGE == FCS_STATE_STORAGE_JUDY)
    {
        PWord_t * PValue;

        JHSI(PValue, instance->judy_array, new_state_key, sizeof(*new_state_key));

        /* later_todo : Handle out-of-memory. */
        if (*PValue == 0)
        {
            /* A new state. */
            is_state_new = 1;
            *PValue = (PWord_t)(*existing_state_val = new_state_val);
        }
        else
        {
            /* Already exists. */
            is_state_new = 0;
            *existing_state_val = (fcs_state_extra_info_t *)(*PValue);
        }
    }
#else
#error no define
#endif
    if (is_state_new)
    {
        /* The new state was not found in the cache, and it was already inserted */
        if (new_state_val->parent_val)
        {
            new_state_val->parent_val->num_active_children++;
        }
        instance->num_states_in_collection++;

        if (new_state_val->moves_to_parent != NULL)
        {
            new_state_val->moves_to_parent =
                fc_solve_move_stack_compact_allocate(
                    hard_thread,
                    new_state_val->moves_to_parent
                    );
        }

        return FCS_STATE_DOES_NOT_EXIST;
    }
    else
    {
        return FCS_STATE_ALREADY_EXISTS;
    }
}
Пример #14
0
static void
process_msg (xmms_ipc_client_t *client, xmms_ipc_msg_t *msg)
{
	xmms_object_t *object;
	xmms_object_cmd_desc_t *cmd = NULL;
	xmms_object_cmd_arg_t arg;
	xmms_ipc_msg_t *retmsg;
	xmmsv_t *error, *arguments;
	uint32_t objid, cmdid;
	gint i;

	g_return_if_fail (msg);

	objid = xmms_ipc_msg_get_object (msg);
	cmdid = xmms_ipc_msg_get_cmd (msg);

	if (!xmms_ipc_msg_get_value (msg, &arguments)) {
		xmms_log_error ("Cannot read command arguments. "
		                "Ignoring command.");

		return;
	}

	if (objid == XMMS_IPC_OBJECT_SIGNAL) {
	    if (cmdid == XMMS_IPC_CMD_SIGNAL) {
			xmms_ipc_register_signal (client, msg, arguments);
		} else if (cmdid == XMMS_IPC_CMD_BROADCAST) {
			xmms_ipc_register_broadcast (client, msg, arguments);
		} else {
			xmms_log_error ("Bad command id (%d) for signal object", cmdid);
		}

		goto out;
	}

	if (objid >= XMMS_IPC_OBJECT_END) {
		xmms_log_error ("Bad object id (%d)", objid);
		goto out;
	}

	g_mutex_lock (ipc_object_pool_lock);
	object = ipc_object_pool->objects[objid];
	g_mutex_unlock (ipc_object_pool_lock);
	if (!object) {
		xmms_log_error ("Object %d was not found!", objid);
		goto out;
	}

	if (object->cmds)
		cmd = g_tree_lookup (object->cmds, GUINT_TO_POINTER (cmdid));

	if (!cmd) {
		xmms_log_error ("No such cmd %d on object %d", cmdid, objid);
		goto out;
	}

	xmms_object_cmd_arg_init (&arg);

	for (i = 0; i < XMMS_OBJECT_CMD_MAX_ARGS; i++) {
		if (!type_and_msg_to_arg (cmd->args[i], arguments, &arg, i)) {
			xmms_log_error ("Error parsing args");

			if (objid == XMMS_IPC_OBJECT_MAIN &&
			    cmdid == XMMS_IPC_CMD_HELLO) {
				xmms_log_error ("Couldn't parse hello message. "
				                "Maybe the client or libxmmsclient "
				                "needs to be updated.");
			}

			retmsg = xmms_ipc_msg_new (objid, XMMS_IPC_CMD_ERROR);

			error = xmmsv_new_error ("Corrupt msg");
			xmms_ipc_msg_put_value (retmsg, error);
			xmmsv_unref (error);

			goto err;
		}

	}

	xmms_object_cmd_call (object, cmdid, &arg);
	if (xmms_error_isok (&arg.error)) {
		retmsg = xmms_ipc_msg_new (objid, XMMS_IPC_CMD_REPLY);
		xmms_ipc_handle_cmd_value (retmsg, arg.retval);
	} else {
		/* FIXME: or we could omit setting the command to _CMD_ERROR
		 * and let the client check whether the value it got is an
		 * error xmmsv_t. If so, don't forget to
		 * update the client-side of IPC too. */
		retmsg = xmms_ipc_msg_new (objid, XMMS_IPC_CMD_ERROR);

		error = xmmsv_new_error (xmms_error_message_get (&arg.error));
		xmms_ipc_msg_put_value (retmsg, error);
		xmmsv_unref (error);

/*
		retmsg = xmms_ipc_msg_new (objid, XMMS_IPC_CMD_REPLY);
		xmms_ipc_handle_cmd_value (retmsg, arg.retval);
*/
	}

	if (arg.retval)
		xmmsv_unref (arg.retval);

err:
	for (i = 0; i < XMMS_OBJECT_CMD_MAX_ARGS; i++) {
		if (arg.values[i])
			xmmsv_unref (arg.values[i]);
	}
	xmms_ipc_msg_set_cookie (retmsg, xmms_ipc_msg_get_cookie (msg));
	g_mutex_lock (client->lock);
	xmms_ipc_client_msg_write (client, retmsg);
	g_mutex_unlock (client->lock);

out:
	if (arguments) {
		xmmsv_unref (arguments);
	}
}
Пример #15
0
static void
process_msg (xmms_ipc_client_t *client, xmms_ipc_msg_t *msg)
{
	xmms_object_t *object;
	xmms_object_cmd_desc_t *cmd = NULL;
	xmms_object_cmd_arg_t arg;
	xmms_ipc_msg_t *retmsg;
	uint32_t objid, cmdid;
	gint i;

	g_return_if_fail (msg);

	objid = xmms_ipc_msg_get_object (msg);
	cmdid = xmms_ipc_msg_get_cmd (msg);

	if (objid == XMMS_IPC_OBJECT_SIGNAL &&
	    cmdid == XMMS_IPC_CMD_SIGNAL) {
		gint32 signalid;

		if (!xmms_ipc_msg_get_int32 (msg, &signalid)) {
			xmms_log_error ("No signalid in this msg?!");
			return;
		}

		if (signalid < 0 || signalid >= XMMS_IPC_SIGNAL_END) {
			xmms_log_error ("Bad signal id (%d)", signalid);
			return;
		}

		g_mutex_lock (client->lock);
		client->pendingsignals[signalid] = xmms_ipc_msg_get_cookie (msg);
		g_mutex_unlock (client->lock);
		return;
	} else if (objid == XMMS_IPC_OBJECT_SIGNAL &&
	           cmdid == XMMS_IPC_CMD_BROADCAST) {
		gint32 broadcastid;

		if (!xmms_ipc_msg_get_int32 (msg, &broadcastid)) {
			xmms_log_error ("No broadcastid in this msg?!");
			return;
		}

		if (broadcastid < 0 || broadcastid >= XMMS_IPC_SIGNAL_END) {
			xmms_log_error ("Bad broadcast id (%d)", broadcastid);
			return;
		}

		g_mutex_lock (client->lock);
		client->broadcasts[broadcastid] =
			g_list_append (client->broadcasts[broadcastid],
			               GUINT_TO_POINTER (xmms_ipc_msg_get_cookie (msg)));

		g_mutex_unlock (client->lock);
		return;
	}

	if (objid >= XMMS_IPC_OBJECT_END) {
		xmms_log_error ("Bad object id (%d)", objid);
		return;
	}

	g_mutex_lock (ipc_object_pool_lock);
	object = ipc_object_pool->objects[objid];
	g_mutex_unlock (ipc_object_pool_lock);
	if (!object) {
		xmms_log_error ("Object %d was not found!", objid);
		return;
	}

	if (cmdid >= XMMS_IPC_CMD_END) {
		xmms_log_error ("Bad command id (%d)", cmdid);
		return;
	}

	if (object->cmds)
		cmd = g_tree_lookup (object->cmds, GUINT_TO_POINTER (cmdid));

	if (!cmd) {
		xmms_log_error ("No such cmd %d on object %d", cmdid, objid);
		return;
	}

	xmms_object_cmd_arg_init (&arg);

	for (i = 0; i < XMMS_OBJECT_CMD_MAX_ARGS; i++) {
		if (!type_and_msg_to_arg (cmd->args[i], msg, &arg, i)) {
			xmms_log_error ("Error parsing args");
			retmsg = xmms_ipc_msg_new (objid, XMMS_IPC_CMD_ERROR);
			xmms_ipc_msg_put_string (retmsg, "Corrupt msg");
			goto err;
		}

	}

	xmms_object_cmd_call (object, cmdid, &arg);
	if (xmms_error_isok (&arg.error)) {
		retmsg = xmms_ipc_msg_new (objid, XMMS_IPC_CMD_REPLY);
		xmms_ipc_handle_cmd_value (retmsg, arg.retval);
	} else {
		/* FIXME: or we could change the client code to transform
		 * CMD_ERROR to an error value_t. If so, don't forget to
		 * update the client-side of IPC too. */
		retmsg = xmms_ipc_msg_new (objid, XMMS_IPC_CMD_ERROR);
		xmms_ipc_msg_put_string (retmsg, xmms_error_message_get (&arg.error));
/*
		retmsg = xmms_ipc_msg_new (objid, XMMS_IPC_CMD_REPLY);
		xmms_ipc_handle_cmd_value (retmsg, arg.retval);
*/
	}

	if (arg.retval)
		xmmsv_unref (arg.retval);

err:
	for (i = 0; i < XMMS_OBJECT_CMD_MAX_ARGS; i++) {
		xmmsv_unref (arg.values[i]);
	}
	xmms_ipc_msg_set_cookie (retmsg, xmms_ipc_msg_get_cookie (msg));
	g_mutex_lock (client->lock);
	xmms_ipc_client_msg_write (client, retmsg);
	g_mutex_unlock (client->lock);
}
Пример #16
0
gpointer tgenpool_getRandom(TGenPool* pool) {
    TGEN_ASSERT(pool);
    const gint position = (gint) (rand() % g_tree_nnodes(pool->items));
    return (gpointer)g_tree_lookup(pool->items, &position);
}