Example #1
0
struct maildir_shindex_cache *
maildir_shared_cache_read(struct maildir_shindex_cache *parent,
			  const char *indexfile,
			  const char *subhierarchy)
{
	struct maildir_shindex_cache *p;

	if (parent && parent->next && subhierarchy &&
	    strcmp(parent->next->hierarchy, subhierarchy) == 0)
	{
		return parent->next; /* That was easy */
	}

	if (!parent && shared_cache)
	{
		return shared_cache;
	}

	if (!indexfile)
	{
		indexfile=maildir_shared_index_file();
		if (!indexfile)
			return NULL;
		subhierarchy="";
	}


	if (!subhierarchy)
		return NULL;
	/* Should not happen, bad usage. subhierarchy allowed to be NULL only
	** when indexfile is also NULL */

	p=do_shared_cache_read(indexfile, subhierarchy);

	if (!p)
		return NULL;

	if (!parent)
	{
		shared_cache_free(shared_cache);
		shared_cache=p;
	}
	else
	{
		shared_cache_free(parent->next);
		parent->next=p;
	}
	return p;
}
Example #2
0
static int list_newshared_shortcut(const char *skipped_pattern,
				   struct list_sharable_info *shared_info,
				   const char *acc_pfix,
				   struct maildir_shindex_cache *parentCache,
				   const char *indexfile,
				   const char *subhierarchy)
{
	struct list_newshared_info lni;
	int rc;
	struct maildir_shindex_cache *curcache=NULL;

	lni.acc_pfix=acc_pfix;
	lni.skipped_pattern=skipped_pattern;
	lni.shared_info=shared_info;
	lni.dorecurse=1;

	/* Try for some common optimization, to avoid expanding the
	** entire #shared hierarchy, taking advantage of the cache list.
	*/

	for (;;)
	{
		const char *p;
		size_t i;
		char *q;
		int eof;

		if (strcmp(skipped_pattern, "%") == 0)
		{
			lni.dorecurse=0;
			break;
		}

		if (strncmp(skipped_pattern, "%" HIERCHS,
			    sizeof("%" HIERCHS)-1) == 0)
		{
			curcache=maildir_shared_cache_read(parentCache,
							   indexfile,
							   subhierarchy);
			if (!curcache)
				return 0;

			lni.acc_pfix=acc_pfix;
			lni.skipped_pattern=skipped_pattern
				+ sizeof("%" HIERCHS)-1;
			lni.parentCache=curcache;

			for (i=0; i<curcache->nrecords; i++)
			{
				if (i == 0)
				{
					curcache->indexfile.startingpos=0;
					rc=maildir_newshared_nextAt(&curcache->indexfile,
								    &eof,
								    list_newshared_skiplevel,
								    &lni);
				}
				else
					rc=maildir_newshared_next(&curcache->indexfile,
								  &eof,
								  list_newshared_skiplevel,
								  &lni);

				if (rc || eof)
				{
					fprintf(stderr, "ERR:maildir_newshared_next failed: %s\n",
						strerror(errno));
					break;
				}
			}
			return 0;
		}

		for (p=skipped_pattern; *p; p++)
			if (*p == HIERCH ||
			    ((lni.shared_info->flags & LIST_CHECK1FOLDER) == 0
			     && (*p == '*' || *p == '%')))
				break;

		if (*p && *p != HIERCH)
			break;

		curcache=maildir_shared_cache_read(parentCache, indexfile,
						   subhierarchy);
		if (!curcache)
			return 0;

		for (i=0; i < curcache->nrecords; i++)
		{
			char *n=maildir_info_imapmunge(curcache->records[i]
						       .name);

			if (!n)
				write_error_exit(0);

			if (strlen(n) == p-skipped_pattern &&
			    strncmp(n, skipped_pattern, p-skipped_pattern) == 0)
			{
				free(n);
				break;
			}
			free(n);
		}

		if (i >= curcache->nrecords) /* not found */
			return 0;

		if (*p)
			++p;


		q=malloc(strlen(acc_pfix)+(p-skipped_pattern)+1);
		if (!q)
		{
			write_error_exit(0);
		}
		strcpy(q, acc_pfix);
		strncat(q, skipped_pattern, p-skipped_pattern);

		lni.acc_pfix=q;
		lni.skipped_pattern=p;
		lni.parentCache=curcache;

		curcache->indexfile.startingpos=curcache->records[i].offset;

		rc=maildir_newshared_nextAt(&curcache->indexfile, &eof,
					    list_newshared_skipcb, &lni);
		free(q);
		return rc;

	}

	if (!indexfile)
		indexfile=maildir_shared_index_file();

	rc=maildir_newshared_enum(indexfile, list_newshared_cb, &lni);

	return rc;
}