Beispiel #1
0
void
feedlist_node_added (nodePtr node)
{
	gint	position = -1;
	
	g_assert (NULL == node->parent);
	
	if (SELECTED && !IS_FOLDER(SELECTED)) {
		position = g_slist_index (SELECTED->parent->children, SELECTED);
		if (position > -1)
			position++;	/* insert after selected child index */
	}

	node_set_parent (node, feedlist_get_parent_node (), position);
	
	if (node->subscription)
		db_subscription_update (node->subscription);
	
	db_node_update(node);

	feedlist_node_imported (node);
	
	feed_list_view_select (node);
}
Beispiel #2
0
/* process node register request */
static int __node_xml_register(xmlDoc * doc, xmlNode * node, int ent_id)
{
    if (ly_entity_is_registered(ent_id)) {
        logwarn(_("received node register request again, ignored\n"));
        return -1;
    }

    LYNodeData * nd = ly_entity_data(ent_id);
    if (nd == NULL ) {
        logerror(_("error in %s(%d)\n"), __func__, __LINE__);
        return -1;
    }
    NodeInfo * nf = &nd->node;

    /* Create xpath evaluation context */
    xmlXPathContextPtr xpathCtx = xmlXPathNewContext(doc);
    if (xpathCtx == NULL) {
        logerror(_("unable to create new XPath context %s, %d\n"),
                 __func__, __LINE__);
        return -1;
    }
    int ret = -1;

    char *str;
    str = xml_xpath_text_from_ctx(xpathCtx,
                         "/" LYXML_ROOT "/request/parameters/status");
    if (str == NULL)
        goto xml_err;
    nf->status = atoi(str);
    free(str);
    str = xml_xpath_text_from_ctx(xpathCtx,
                         "/" LYXML_ROOT "/request/parameters/hypervisor");
    if (str == NULL)
        goto xml_err;
    nf->hypervisor = atoi(str);
    free(str);
    str = xml_xpath_text_from_ctx(xpathCtx,
                         "/" LYXML_ROOT "/request/parameters/host/tag");
    int tag = -1;
    if (str) {
        tag = atoi(str); /* NULL str is allowed for new node */
        free(str);
    }
    str = xml_xpath_text_from_ctx(xpathCtx,
                         "/" LYXML_ROOT "/request/parameters/host/name");
    if (str == NULL)
        goto xml_err;
    nf->host_name = str;
    str = xml_xpath_text_from_ctx(xpathCtx,
                         "/" LYXML_ROOT "/request/parameters/host/ip");
    if (str == NULL)
        goto xml_err;
    nf->host_ip = str;
    str = xml_xpath_text_from_ctx(xpathCtx,
                         "/" LYXML_ROOT "/request/parameters/cpu/arch");
    if (str == NULL)
        goto xml_err;
    nf->cpu_arch = atoi(str);
    free(str);
    str = xml_xpath_text_from_ctx(xpathCtx,
                         "/" LYXML_ROOT "/request/parameters/cpu/model");
    if (str == NULL)
        goto xml_err;
    nf->cpu_model = str;
    str = xml_xpath_text_from_ctx(xpathCtx,
                         "/" LYXML_ROOT "/request/parameters/cpu/mhz");
    if (str == NULL)
        goto xml_err;
    nf->cpu_mhz = atoi(str);
    free(str);
    str = xml_xpath_text_from_ctx(xpathCtx,
                         "/" LYXML_ROOT "/request/parameters/cpu/max");
    if (str == NULL)
        goto xml_err;
    nf->cpu_max = atoi(str);
    nf->cpu_vlimit = NODE_SCHEDULE_CPU_LIMIT(nf->cpu_max);
    free(str);
    str = xml_xpath_text_from_ctx(xpathCtx,
                         "/" LYXML_ROOT "/request/parameters/cpu/commit");
    if (str == NULL)
        goto xml_err;
    nf->cpu_commit = atoi(str);
    free(str);
    str = xml_xpath_text_from_ctx(xpathCtx,
                         "/" LYXML_ROOT "/request/parameters/memory/total");
    if (str == NULL)
        goto xml_err;
    nf->mem_max = atoi(str);
    nf->mem_vlimit = NODE_SCHEDULE_MEM_LIMIT(nf->mem_max);
    free(str);
    str = xml_xpath_text_from_ctx(xpathCtx,
                         "/" LYXML_ROOT "/request/parameters/memory/free");
    if (str == NULL)
        goto xml_err;
    nf->mem_free = atoi(str);
    free(str);
    str = xml_xpath_text_from_ctx(xpathCtx,
                         "/" LYXML_ROOT "/request/parameters/memory/commit");
    if (str == NULL)
        goto xml_err;
    nf->mem_commit = atoi(str);
    free(str);
    str = xml_xpath_text_from_ctx(xpathCtx,
                         "/" LYXML_ROOT "/request/parameters/storage/total");
    if (str == NULL)
        goto xml_err;
    nf->storage_total = atoi(str);
    free(str);
    str = xml_xpath_text_from_ctx(xpathCtx,
                         "/" LYXML_ROOT "/request/parameters/storage/free");
    if (str == NULL)
        goto xml_err;
    nf->storage_free = atoi(str);
    free(str);
    str = xml_xpath_text_from_ctx(xpathCtx,
                          "/" LYXML_ROOT "/request/parameters/load/average");
    if (str == NULL)
        goto xml_err;
    nf->load_average = atoi(str);
    free(str);

    if (nf->status >= NODE_STATUS_REGISTERED) {
        logwarn(_("node(%d, %s) tries to register from wrong status(%d)\n"),
                 nf->host_tag, nf->host_ip, nf->status);
        ly_entity_release(ent_id);
        ret = 0; /* no need to continue node registration */
        goto done;
    }
        
    if (ly_entity_node_active(nf->host_ip)) {
        logwarn(_("duplicate node ip received. something is wrong...\n"));
        ly_entity_release(ent_id);
        ret = 0; /* no need to continue node registration */
        goto done;
    }
   
    if (tag > 0) {
        /* check authentication result */
        if (nf->host_tag > 0 && tag != nf->host_tag) {
            logerror(_("node tag changed, %d -> %d. something is wrong.\n"),
                       nf->host_tag, tag);
            goto done;
        }
        nf->host_tag = tag;
        ret = __node_register_auth(nf, ent_id);
        if (ret == LY_S_REGISTERING_DONE_SUCCESS) {
            AuthConfig * ac = ly_entity_auth(ent_id);
            if (db_node_update_secret(DB_NODE_FIND_BY_ID, &tag,
                                      ac->secret) < 0 ||
                db_node_update_status(DB_NODE_FIND_BY_ID, &tag,
                                      NODE_STATUS_REGISTERED) < 0) {
                logerror(_("error in %s(%d)\n"), __func__, __LINE__);
                ret = -1;
                goto done;
            }
            loginfo(_("node(tag:%d) registered\n"), tag);
            ly_entity_update(ent_id, tag, LY_ENTITY_FLAG_STATUS_REGISTERED);
        }
        goto done;
    }

    /* new node */
    DBNodeRegInfo db_nf;
    bzero(&db_nf, sizeof(DBNodeRegInfo));
    ret = db_node_find(DB_NODE_FIND_BY_IP, nf->host_ip, &db_nf);
    if (ret < 0 || ret > 1) {
        logerror(_("error in %s(%d)\n"), __func__, __LINE__);
        ret = -1;
        goto done;
    }

    if (ret == 0 || db_nf.secret) {
        /* new node */
        logdebug(_("new node\n"));
        if (nf->status != NODE_STATUS_UNINITIALIZED) {
            logwarn(_("node(%d, %s) tries to register from unexpected status(%d)\n"),
                       nf->host_tag, nf->host_ip, nf->status);
            nf->status = NODE_STATUS_UNINITIALIZED;
        }
        if (db_nf.secret) {
            logwarn(_("new node takes ip(%s) used by tagged node\n"), nf->host_ip);
            db_node_reginfo_free(&db_nf);
            bzero(&db_nf, sizeof(DBNodeRegInfo));
        }
            
        ret = db_node_insert(nf);
        if (ret < 0) {
            logerror(_("error in %s(%d)\n"), __func__, __LINE__);
            goto new_done;
        }
        db_nf.id = ret;
        loginfo(_("new node %s added in db(%d)\n"), nf->host_ip, ret);

        /* enable node if node is control server */
        if (ly_is_clc_ip(nf->host_ip)) {
            if (db_node_enable(ret, 1) != 0 ||
                db_node_find(DB_NODE_FIND_BY_ID, &ret, &db_nf) != 1) {
                logerror(_("error in %s(%d)\n"), __func__, __LINE__);
                ret = -1;
                goto new_done;
            }
        }
    }
    else
        logdebug(_("untagged node for ip(%s) found in db\n"), nf->host_ip);

    ly_entity_update(ent_id, db_nf.id, LY_ENTITY_FLAG_STATUS_ONLINE);
    if (db_nf.enabled) {
        AuthConfig * ac = ly_entity_auth(ent_id);
        ret = -1;
        if (ac->secret) {
            logerror(_("error in %s(%d)\n"), __func__, __LINE__);
            goto new_done;
        }
        ac->secret = lyauth_secret();
        if (ac->secret == NULL) {
            logerror(_("error in %s(%d)\n"), __func__, __LINE__);
            goto new_done;
        }
        nf->host_tag = db_nf.id;
        ret = LY_S_REGISTERING_CONFIG;
    }
    else {
        logdebug(_("register request done, node %s not enabled\n"), nf->host_ip);
        ret = LY_S_REGISTERING_INIT;
    }
    nf->status = NODE_STATUS_ONLINE;
    if (db_node_update(DB_NODE_FIND_BY_ID, &db_nf.id, nf) < 0) {
        logerror(_("error in %s(%d)\n"), __func__, __LINE__);
        ret = -1;
    }

new_done:
    db_node_reginfo_free(&db_nf);
    goto done;
xml_err:
    logerror(_("invalid node xml register request\n"));
done:
    xmlXPathFreeContext(xpathCtx);
    logdebug(_("end of %s, node status %d\n"), __func__, nf->status);
    return ret;
}
Beispiel #3
0
/* process node info query reply */
static int __node_info_update(xmlDoc * doc, xmlNode * node,
                              int ent_id, int * j_status)
{
    logdebug(_("%s called\n"), __func__);

    if (!ly_entity_is_online(ent_id)) {
        /* shouldn't come here */
        logerror(_("error in %s(%d)\n"), __func__, __LINE__);
        *j_status = LY_S_FINISHED_FAILURE_NODE_NOT_AVAIL;
        return 0;
    }

    LYNodeData * nd = ly_entity_data(ent_id);
    if (nd == NULL) {
        logerror(_("error in %s(%d)\n"), __func__, __LINE__);
        goto failed;
    }
    NodeInfo * nf = &nd->node;

    /* Create xpath evaluation context */
    xmlXPathContextPtr xpathCtx = xmlXPathNewContext(doc);
    if (xpathCtx == NULL) {
        logerror(_("unable to create new XPath context %s, %d\n"),
                 __func__, __LINE__);
        *j_status = LY_S_FINISHED_FAILURE;
        return 0;
    }

    char *str;
    str = xml_xpath_text_from_ctx(xpathCtx,
                         "/" LYXML_ROOT "/response/data/status");
    if (str == NULL)
        goto failed;
    nf->status = atoi(str);
    free(str);

    str = xml_xpath_text_from_ctx(xpathCtx,
                         "/" LYXML_ROOT "/response/data/cpu/commit");
    if (str == NULL)
        goto failed;
    nf->cpu_commit = atoi(str);
    free(str);

    str = xml_xpath_text_from_ctx(xpathCtx,
                         "/" LYXML_ROOT "/response/data/memory/free");
    if (str == NULL)
        goto failed;
    nf->mem_free = atoi(str);
    free(str);

    str = xml_xpath_text_from_ctx(xpathCtx,
                         "/" LYXML_ROOT "/response/data/storage/free");
    if (str == NULL)
        goto failed;
    nf->storage_free = atoi(str);
    free(str);

    str = xml_xpath_text_from_ctx(xpathCtx,
                         "/" LYXML_ROOT "/response/data/memory/commit");
    if (str == NULL)
        goto failed;
    nf->mem_commit = atoi(str);
    free(str);

    str = xml_xpath_text_from_ctx(xpathCtx,
                          "/" LYXML_ROOT "/response/data/load/average");
    if (str == NULL)
        goto failed;
    nf->load_average = atoi(str);
    free(str);

    int node_id = ly_entity_db_id(ent_id);
    logdebug(_("update info for node %d: %d %d %d %d %d\n"), node_id,
                nf->status, nf->cpu_commit, 
                nf->mem_free, nf->mem_commit, nf->load_average);

    if (db_node_update(DB_NODE_FIND_BY_ID, &node_id, nf) < 0) {
        logerror(_("error in %s(%d)\n"), __func__, __LINE__);
        goto failed;
    }

    /* no need to update j_status */
    goto done;

failed:
    *j_status = LY_S_FINISHED_FAILURE;
done:
    xmlXPathFreeContext(xpathCtx);
    return 0;
}
Beispiel #4
0
static void
subscription_process_update_result (const struct updateResult * const result, gpointer user_data, guint32 flags)
{
	subscriptionPtr subscription = (subscriptionPtr)user_data;
	nodePtr		node = subscription->node;
	gboolean	processing = FALSE;
	GTimeVal	now;

	/* 1. preprocessing */

	g_assert (subscription->updateJob);
	/* update the subscription URL on permanent redirects */
	if ((301 == result->httpstatus) && result->source && !g_str_equal (result->source, subscription->updateJob->request->source)) {
		debug2 (DEBUG_UPDATE, "The URL of \"%s\" has changed permanently and was updated with \"%s\"", node_get_title(node), result->source);
		subscription_set_source (subscription, result->source);
		liferea_shell_set_status_bar (_("The URL of \"%s\" has changed permanently and was updated"), node_get_title(node));
	}

	if (401 == result->httpstatus) { /* unauthorized */
		auth_dialog_new (subscription, flags);
	} else if (410 == result->httpstatus) { /* gone */
		subscription->discontinued = TRUE;
		node->available = TRUE;
		liferea_shell_set_status_bar (_("\"%s\" is discontinued. Liferea won't updated it anymore!"), node_get_title (node));
	} else if (304 == result->httpstatus) {
		node->available = TRUE;
		liferea_shell_set_status_bar (_("\"%s\" has not changed since last update"), node_get_title(node));
	} else {
		processing = TRUE;
	}

	subscription_update_error_status (subscription, result->httpstatus, result->returncode, result->filterErrors);

	subscription->updateJob = NULL;

	/* 2. call subscription type specific processing */
	if (processing)
		SUBSCRIPTION_TYPE (subscription)->process_update_result (subscription, result, flags);

	/* 3. call favicon updating after subscription processing
	      to ensure we have valid baseUrl for feed nodes... */
	g_get_current_time (&now);
	if (favicon_update_needed (subscription->node->id, subscription->updateState, &now))
		subscription_update_favicon (subscription);
	
	/* 4. generic postprocessing */
	update_state_set_lastmodified (subscription->updateState, update_state_get_lastmodified (result->updateState));
	update_state_set_cookies (subscription->updateState, update_state_get_cookies (result->updateState));
	update_state_set_etag (subscription->updateState, update_state_get_etag (result->updateState));
	g_get_current_time (&subscription->updateState->lastPoll);

	// FIXME: use new-items signal in itemview class	
	itemview_update_node_info (subscription->node);
	itemview_update ();

	db_subscription_update (subscription);
	db_node_update (subscription->node);

	if (subscription->node->newCount > 0)
		feedlist_new_items (subscription->node);
}
Beispiel #5
0
static gboolean
ui_dnd_feed_drag_data_received (GtkTreeDragDest *drag_dest, GtkTreePath *dest, GtkSelectionData *selection_data)
{
	GtkTreeIter	iter, iter2, parentIter;
	nodePtr		node, oldParent, newParent;
	gboolean	result, valid, added;
	gint		oldPos, pos;

	result = old_feed_drag_data_received (drag_dest, dest, selection_data);
	if (result) {
		if (gtk_tree_model_get_iter (GTK_TREE_MODEL (drag_dest), &iter, dest)) {
			gtk_tree_model_get (GTK_TREE_MODEL (drag_dest), &iter, FS_PTR, &node, -1);

			/* If we don't do anything, then because DnD is implemented by removal and
			   re-insertion, and the removed node is selected, the treeview selects
			   the next row after the removal, which is supremely irritating.
			   But setting a selection at this point is pointless, because the treeview
			   will reset it as soon as the DnD callback returns. Instead, we set
			   the cursor, which controls where treeview resets the selection later.
			 */
			gtk_tree_view_set_cursor(GTK_TREE_VIEW (liferea_shell_lookup ("feedlist")),
			    dest, NULL, FALSE);

			/* remove from old parents child list */
			oldParent = node->parent;
			g_assert (oldParent);
			oldPos = g_slist_index (oldParent->children, node);
			oldParent->children = g_slist_remove (oldParent->children, node);
			node_update_counters (oldParent);
			
			if (0 == g_slist_length (oldParent->children))
				feed_list_node_add_empty_node (feed_list_node_to_iter (oldParent->id));
			
			/* and rebuild new parents child list */
			if (gtk_tree_model_iter_parent (GTK_TREE_MODEL (drag_dest), &parentIter, &iter)) {
				gtk_tree_model_get (GTK_TREE_MODEL (drag_dest), &parentIter, FS_PTR, &newParent, -1);
			} else {
				gtk_tree_model_get_iter_first (GTK_TREE_MODEL (drag_dest), &parentIter);
				newParent = feedlist_get_root ();
			}

			/* drop old list... */
			debug3 (DEBUG_GUI, "old parent is %s (%d, position=%d)", oldParent->title, g_slist_length (oldParent->children), oldPos);
			debug2 (DEBUG_GUI, "new parent is %s (%d)", newParent->title, g_slist_length (newParent->children));
			g_slist_free (newParent->children);
			newParent->children = NULL;
			node->parent = newParent;
			
			debug0 (DEBUG_GUI, "new newParent child list:");
				
			/* and rebuild it from the tree model */
			if (feedlist_get_root() != newParent)
				valid = gtk_tree_model_iter_children (GTK_TREE_MODEL (drag_dest), &iter2, &parentIter);
			else
				valid = gtk_tree_model_iter_children (GTK_TREE_MODEL (drag_dest), &iter2, NULL);
				
			pos = 0;
			added = FALSE;
			while (valid) {
				nodePtr	child;			
				gtk_tree_model_get (GTK_TREE_MODEL (drag_dest), &iter2, FS_PTR, &child, -1);
				if (child) {
					/* Well this is a bit complicated... If we move a feed inside a folder
					   we need to skip the old insertion point (oldPos). This is easy if the
					   feed is added behind this position. If it is dropped before the flag
					   added is set once the new copy is encountered. The remaining copy
					   is skipped automatically when the flag is set.
					 */
					 
					/* check if this is a copy of the dragged node or the original itself */
					if ((newParent == oldParent) && !strcmp(node->id, child->id)) {
						if ((pos == oldPos) || added) {
							/* it is the original */
							debug2 (DEBUG_GUI, "   -> %d: skipping old insertion point %s", pos, child->title);
						} else {
							/* it is a copy inserted before the original */
							added = TRUE;
							debug2 (DEBUG_GUI, "   -> %d: new insertion point of %s", pos, child->title);
							newParent->children = g_slist_append (newParent->children, child);
						}
					} else {
						/* all other nodes */
						debug2 (DEBUG_GUI, "   -> %d: adding %s", pos, child->title);
						newParent->children = g_slist_append (newParent->children, child);
					}
				} else {
					debug0 (DEBUG_GUI, "   -> removing empty node");
					/* remove possible existing "(empty)" node from newParent */
					feed_list_node_remove_empty_node (&parentIter);
				}
				valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (drag_dest), &iter2);
				pos++;
			}
			
			db_node_update (node);
			node_update_counters (newParent);
			
			feedlist_schedule_save ();
		}
	}
						      
	return result;
}