예제 #1
0
int maildir_newshared_nextAt(struct maildir_newshared_enum_cb *info,
			     int *eof,
			     int (*cb_func)(struct maildir_newshared_enum_cb*),
			     void *cb_arg)
{
	if (fseek(info->fp, info->startingpos, SEEK_SET) < 0)
		return -1;
	info->linenum= -1;
	return maildir_newshared_next(info, eof, cb_func, cb_arg);
}
예제 #2
0
int maildir_newshared_enum(const char *indexfile,
			   int (*cb_func)(struct maildir_newshared_enum_cb *),
			   void *cb_arg)
{
	struct maildir_newshared_enum_cb cb;
	int eof;
	int rc;

	if (maildir_newshared_open(indexfile, &cb) < 0)
		return -1;

	while ((rc=maildir_newshared_next(&cb, &eof, cb_func, cb_arg)) == 0)
	{
		if (eof)
		{
			maildir_newshared_close(&cb);
			return 0;
		}
	}

	maildir_newshared_close(&cb);
	return rc;
}
예제 #3
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;
}
예제 #4
0
static struct maildir_shindex_cache *do_shared_cache_read(const char *indexfile,
						       const char *subhier)
{
	struct maildir_shindex_temp_record *rec=NULL;
	size_t n;
	struct maildir_shindex_cache *c;
	int eof;
	int rc;

	if ((c=malloc(sizeof(struct maildir_shindex_cache))) == NULL ||
	    (c->hierarchy=strdup(subhier)) == NULL)
	{
		if (c)
			free(c);
		perror("malloc");
		return NULL;
	}

	if (maildir_newshared_open(indexfile, &c->indexfile) < 0)
	{
		free(c->hierarchy);
		free(c);
		return NULL;
	}

	n=0;

	while ((rc=maildir_newshared_next(&c->indexfile, &eof,
					  shared_cache_read_cb, &rec)) == 0)
	{
		if (eof)
			break;
		++n;
	}

	if (rc)
	{
		free(c->hierarchy);
		free(c);
		while (rec)
		{
			struct maildir_shindex_temp_record *r=rec;

			rec=rec->next;

			free(r->rec.name);
			free(r);
		}
		return NULL;
	}

	/* Now, convert from list to array */

	c->nrecords=n;
	c->records=NULL;
	c->next=NULL;

	if (n)
	{
		if ((c->records=malloc(sizeof(*c->records)*n)) == NULL)
		{

			free(c->hierarchy);
			free(c);
			while (rec)
			{
				struct maildir_shindex_temp_record *r=rec;

				rec=rec->next;

				free(r->rec.name);
				free(r);
			}
			return NULL;
		}

		n=0;
		while (rec)
		{
			struct maildir_shindex_temp_record *r=rec;

			rec=rec->next;
			c->records[n]= r->rec;

			free(r);
			++n;
		}
	}

	return c;
}