CamelNNTPStoreInfo *
camel_nntp_store_summary_add_from_full (CamelNNTPStoreSummary *s, const char *full, char dir_sep)
{
	CamelNNTPStoreInfo *info;
	char *pathu8;
	int len;
	char *full_name;

	d(printf("adding full name '%s' '%c'\n", full, dir_sep));

	len = strlen (full);
	full_name = g_alloca (len+1);
	strcpy(full_name, full);
	if (full_name[len-1] == dir_sep)
		full_name[len-1] = 0;

	info = camel_nntp_store_summary_full_name (s, full_name);
	if (info) {
		camel_store_summary_info_free ((CamelStoreSummary *) s, (CamelStoreInfo *) info);
		d(printf("  already there\n"));
		return info;
	}

	pathu8 = camel_nntp_store_summary_full_to_path (s, full_name, dir_sep);

	info = (CamelNNTPStoreInfo *) camel_store_summary_add_from_path ((CamelStoreSummary *) s, pathu8);
	if (info) {
		d(printf("  '%s' -> '%s'\n", pathu8, full_name));
		camel_store_info_set_string((CamelStoreSummary *)s, (CamelStoreInfo *)info, CAMEL_NNTP_STORE_INFO_FULL_NAME, full_name);
	} else
		d(printf("  failed\n"));

	return info;
}
CamelFolder *
camel_nntp_folder_new (CamelStore *parent, const char *folder_name, CamelException *ex)
{
	CamelFolder *folder;
	CamelNNTPFolder *nntp_folder;
	char *root;
	CamelService *service;
	CamelStoreInfo *si;
	gboolean subscribed = TRUE;

	service = (CamelService *) parent;
	root = camel_session_get_storage_path (service->session, service, ex);
	if (root == NULL)
		return NULL;

	/* If this doesn't work, stuff wont save, but let it continue anyway */
	g_mkdir_with_parents (root, 0777);

	folder = (CamelFolder *) camel_object_new (CAMEL_NNTP_FOLDER_TYPE);
	nntp_folder = (CamelNNTPFolder *)folder;

	camel_folder_construct (folder, parent, folder_name, folder_name);
	folder->folder_flags |= CAMEL_FOLDER_HAS_SUMMARY_CAPABILITY|CAMEL_FOLDER_HAS_SEARCH_CAPABILITY;

	nntp_folder->storage_path = g_build_filename (root, folder->full_name, NULL);
	g_free (root);

	root = g_strdup_printf ("%s.cmeta", nntp_folder->storage_path);
	camel_object_set(nntp_folder, NULL, CAMEL_OBJECT_STATE_FILE, root, NULL);
	camel_object_state_read(nntp_folder);
	g_free(root);

	root = g_strdup_printf("%s.ev-summary", nntp_folder->storage_path);
	folder->summary = (CamelFolderSummary *) camel_nntp_summary_new (folder, root);
	g_free(root);
	camel_folder_summary_load (folder->summary);

	si = camel_store_summary_path ((CamelStoreSummary *) ((CamelNNTPStore*) parent)->summary, folder_name);
	if (si) {
		subscribed = (si->flags & CAMEL_STORE_INFO_FOLDER_SUBSCRIBED) != 0;
		camel_store_summary_info_free ((CamelStoreSummary *) ((CamelNNTPStore*) parent)->summary, si);
	}

	if (subscribed) {
		camel_folder_refresh_info(folder, ex);
		if (camel_exception_is_set(ex)) {
			camel_object_unref (folder);
			folder = NULL;
		}
        }

	return folder;
}
static CamelStoreInfo *
store_info_load (CamelStoreSummary *s, FILE *in)
{
	CamelNNTPStoreInfo *ni;

	ni = (CamelNNTPStoreInfo *) camel_nntp_store_summary_parent->store_info_load (s, in);
	if (ni) {
		if (camel_file_util_decode_string (in, &ni->full_name) == -1) {
			camel_store_summary_info_free (s, (CamelStoreInfo *) ni);
			return NULL;
		}
		if (((CamelNNTPStoreSummary *)s)->version >= CAMEL_NNTP_STORE_SUMMARY_VERSION_1) {
			if (camel_file_util_decode_uint32(in, &ni->first) == -1
			    || camel_file_util_decode_uint32(in, &ni->last) == -1) {
				camel_store_summary_info_free (s, (CamelStoreInfo *) ni);
				return NULL;
			}
		}
		/* set the URL */
	}

	return (CamelStoreInfo *) ni;
}
/**
 * camel_nntp_store_summary_full_name:
 * @s:
 * @path:
 *
 * Retrieve a summary item by full name.
 *
 * A referenced to the summary item is returned, which may be
 * ref'd or free'd as appropriate.
 *
 * Return value: The summary item, or NULL if the @full_name name
 * is not available.
 * It must be freed using camel_store_summary_info_free().
 **/
CamelNNTPStoreInfo *
camel_nntp_store_summary_full_name(CamelNNTPStoreSummary *s, const char *full_name)
{
	int count, i;
	CamelNNTPStoreInfo *info;

	count = camel_store_summary_count ((CamelStoreSummary *) s);
	for (i = 0; i < count; i++) {
		info = (CamelNNTPStoreInfo *)camel_store_summary_index ((CamelStoreSummary *) s, i);
		if (info) {
			if (strcmp (info->full_name, full_name) == 0)
				return info;
			camel_store_summary_info_free ((CamelStoreSummary *) s, (CamelStoreInfo *)info);
		}
	}

	return NULL;
}
char *
camel_nntp_store_summary_path_to_full (CamelNNTPStoreSummary *s, const char *path, char dir_sep)
{
	char *full, *f;
	guint32 c, v = 0;
	const char *p;
	int state=0;
	char *subpath, *last = NULL;
	CamelStoreInfo *si;

	/* check to see if we have a subpath of path already defined */
	subpath = g_alloca (strlen (path) + 1);
	strcpy (subpath, path);
	do {
		si = camel_store_summary_path ((CamelStoreSummary *) s, subpath);
		if (si == NULL) {
			last = strrchr (subpath, '/');
			if (last)
				*last = 0;
		}
	} while (si == NULL && last);

	/* path is already present, use the raw version we have */
	if (si && strlen (subpath) == strlen (path)) {
		f = g_strdup (camel_nntp_store_info_full_name (s, si));
		camel_store_summary_info_free ((CamelStoreSummary *) s, si);
		return f;
	}

	f = full = g_alloca (strlen (path)*2+1);
	if (si)
		p = path + strlen (subpath);
	else
		p = path;

	while ((c = camel_utf8_getc ((const unsigned char **) &p))) {
		switch (state) {
		case 0:
			if (c == '%') {
				state = 1;
			} else {
				if (c == '/')
					c = dir_sep;
				camel_utf8_putc((unsigned char **) &f, c);
			}
			break;
		case 1:
			state = 2;
			v = hexnib (c) << 4;
			break;
		case 2:
			state = 0;
			v |= hexnib (c);
			camel_utf8_putc ((unsigned char **) &f, v);
			break;
		}
	}
	camel_utf8_putc ((unsigned char **) &f, c);

	/* merge old path part if required */
	f = camel_utf8_utf7 (full);
	if (si) {
		full = g_strdup_printf ("%s%s", camel_nntp_store_info_full_name (s, si), f);
		g_free (f);
		camel_store_summary_info_free ((CamelStoreSummary *) s, si);
		f = full;
	}

	return f;
}
static CamelFolder *
groupwise_store_get_folder_sync (CamelStore *store,
                                 const gchar *folder_name,
                                 CamelStoreGetFolderFlags flags,
                                 GCancellable *cancellable,
                                 GError **error)
{
	CamelGroupwiseStore *gw_store = CAMEL_GROUPWISE_STORE (store);
	CamelGroupwiseStorePrivate *priv = gw_store->priv;
	CamelFolder *folder;
	CamelGroupwiseSummary *summary;
	gchar *container_id, *folder_dir, *storage_path;
	EGwConnectionStatus status;
	GList *list = NULL;
	gboolean done = FALSE, all_ok = TRUE;
	const gchar *position = E_GW_CURSOR_POSITION_END;
	gint count = 0, cursor, summary_count = 0;
	CamelStoreInfo *si = NULL;
	guint total = 0;
	GError *local_error = NULL;

	folder = groupwise_get_folder_from_disk (
		store, folder_name, flags, cancellable, &local_error);
	if (folder) {
		groupwise_store_set_current_folder (gw_store, folder);
		return folder;

	/* Ignore "no such folder" errors, fail on any other error. */
	} else if (!g_error_matches (local_error,
		CAMEL_STORE_ERROR, CAMEL_STORE_ERROR_NO_FOLDER)) {
		g_propagate_error (error, local_error);
		return NULL;
	} else
		g_clear_error (&local_error);

	camel_service_lock (CAMEL_SERVICE (gw_store), CAMEL_SERVICE_REC_CONNECT_LOCK);

	groupwise_store_set_current_folder (gw_store, NULL);

	if (!camel_groupwise_store_connected (gw_store, cancellable, error)) {
		camel_service_unlock (CAMEL_SERVICE (gw_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
		return NULL;
	}

	if (!E_IS_GW_CONNECTION ( priv->cnc)) {
		if (!groupwise_connect_sync (CAMEL_SERVICE (store), cancellable, error)) {
			camel_service_unlock (CAMEL_SERVICE (gw_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
			return NULL;
		}
	}

	container_id =	g_strdup (g_hash_table_lookup (priv->name_hash, folder_name));

	storage_path = g_strdup_printf("%s/folders", priv->storage_path);
	folder_dir = e_path_to_physical (storage_path, folder_name);
	g_free (storage_path);
	folder = camel_gw_folder_new (store, folder_name, folder_dir, cancellable, NULL);
	if (!folder) {
		camel_service_unlock (CAMEL_SERVICE (gw_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
		g_set_error (
			error, CAMEL_SERVICE_ERROR,
			CAMEL_SERVICE_ERROR_INVALID,
			_("Authentication failed"));
		g_free (folder_dir);
		g_free (container_id);
		return NULL;
	}
	g_free (folder_dir);

	si = camel_store_summary_path ((CamelStoreSummary *)gw_store->summary, folder_name);
	if (si) {
		total = si->total;
		camel_store_summary_info_free ((CamelStoreSummary *)(gw_store)->summary, si);
	}

	summary = (CamelGroupwiseSummary *) folder->summary;

	summary_count = camel_folder_summary_count (folder->summary);
	if (!summary_count || !summary->time_string) {
		d(g_print ("\n\n** %s **: No summary as yet : using get cursor request\n\n", folder->name);)
static CamelFolder *
groupwise_get_folder (CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex)
{
	CamelGroupwiseStore *gw_store = CAMEL_GROUPWISE_STORE (store);
	CamelGroupwiseStorePrivate *priv = gw_store->priv;
	CamelFolder *folder;
	CamelGroupwiseSummary *summary;
	char *container_id, *folder_dir, *storage_path;
	EGwConnectionStatus status;
	GList *list = NULL;
	gboolean done = FALSE, all_ok = TRUE;
	const char *position = E_GW_CURSOR_POSITION_END;
	int count = 0, cursor, summary_count = 0;
	CamelStoreInfo *si = NULL;
	guint total = 0;

	folder = groupwise_get_folder_from_disk (store, folder_name, flags, ex);
	if (folder) {
		camel_object_ref (folder);
		return folder;
	}

	camel_exception_clear (ex);

	CAMEL_SERVICE_REC_LOCK (gw_store, connect_lock);

	if (!camel_groupwise_store_connected (gw_store, ex)) {
		CAMEL_SERVICE_REC_UNLOCK (gw_store, connect_lock);
		return NULL;
	}

	if (gw_store->current_folder) {
		camel_object_unref (gw_store->current_folder);
		gw_store->current_folder = NULL;
	}

	if (!E_IS_GW_CONNECTION( priv->cnc)) {
		if (!groupwise_connect (CAMEL_SERVICE(store), ex)) {
			CAMEL_SERVICE_REC_UNLOCK (gw_store, connect_lock);
			return NULL;
		}
	}

	container_id = 	g_strdup (g_hash_table_lookup (priv->name_hash, folder_name));


	storage_path = g_strdup_printf("%s/folders", priv->storage_path);
	folder_dir = e_path_to_physical (storage_path, folder_name);
	g_free(storage_path);
	folder = camel_gw_folder_new (store, folder_name, folder_dir, ex);
	if (!folder) {
		CAMEL_SERVICE_REC_UNLOCK (gw_store, connect_lock);
		camel_exception_set (ex, CAMEL_EXCEPTION_SERVICE_INVALID, _("Authentication failed"));
		g_free (folder_dir);
		g_free (container_id);
		return NULL;
	}
	g_free (folder_dir);

	si = camel_store_summary_path ((CamelStoreSummary *)gw_store->summary, folder_name);
	if (si) {
		total = si->total;
		camel_store_summary_info_free ((CamelStoreSummary *)(gw_store)->summary, si);
	}

	summary = (CamelGroupwiseSummary *) folder->summary;

	summary_count = camel_folder_summary_count (folder->summary);
	if(!summary_count || !summary->time_string) {
		d(g_print ("\n\n** %s **: No summary as yet : using get cursor request\n\n", folder->name);)