Example #1
1
static struct imaptoken *do_readtoken(int touc)
{
int	c=0;
unsigned l;

#define	appendch(c)	alloc_tokenbuf(l+1); curtoken.tokenbuf[l++]=(c);

	if (curtoken.tokentype == IT_ERROR)	return (&curtoken);

	do
	{
		c=READ();
	} while (c == '\r' || c == ' ' || c == '\t');

	if (c == '\n')
	{
		UNREAD(c);
		curtoken.tokentype=IT_EOL;
		return (&curtoken);
	}
	c=(unsigned char)c;
	if (c == LPAREN_CHAR)
	{
		curtoken.tokentype=IT_LPAREN;
		return (&curtoken);
	}

	if (c == RPAREN_CHAR)
	{
		curtoken.tokentype=IT_RPAREN;
		return (&curtoken);
	}

	if (c == LBRACKET_CHAR)
	{
		curtoken.tokentype=IT_LBRACKET;
		return (&curtoken);
	}

	if (c == RBRACKET_CHAR)
	{
		curtoken.tokentype=IT_RBRACKET;
		return (&curtoken);
	}

	if (c == '"')
	{
		l=0;
		while ((c=READ()) != '"')
		{
			if (c == '\\')
				c=READ();
			if (c == '\r' || c == '\n')
			{
				UNREAD(c);
				curtoken.tokentype=IT_ERROR;
				return (&curtoken);
			}
			if (l < 8192)
			{
				appendch(c);
			}
		}
		appendch(0);
		curtoken.tokentype=IT_QUOTED_STRING;
		return (&curtoken);
	}

	if (c == '{')
	{
		curtoken.tokennum=0;
		while ((c=READ()) != '}')
		{
			if (!isdigit((int)(unsigned char)c))
			{
				UNREAD(c);
				curtoken.tokentype=IT_ERROR;
				return (&curtoken);
			}
			curtoken.tokennum = curtoken.tokennum*10 + (c-'0');
		}
		c=READ();
		if (c == '\r')
		{
			c=READ();
		}
		if (c != '\n')
		{
			curtoken.tokentype=IT_ERROR;
			return (&curtoken);
		}
		curtoken.tokentype=IT_LITERAL_STRING_START;
		return (&curtoken);
	}

	l=0;
	if (c == '\\')
	{
		appendch(c);	/* Message flag */
		c=READ();
	}
	else if (isdigit(c))
	{
		curtoken.tokentype=IT_NUMBER;
		curtoken.tokennum=0;
		do
		{
			appendch(c);
			curtoken.tokennum = curtoken.tokennum*10 +
				(c-'0');
			c=READ();
		} while (isdigit( (int)(unsigned char)c));

		/* Could be stuff like mime.spec, so continue reading. */
	}

	while (c != '\r' && c != '\n'
		&& !isspace((int)(unsigned char)c)
		&& c != '\\' && c != '"' && c != LPAREN_CHAR && c != RPAREN_CHAR
		&& c != '{' && c != '}' && c != LBRACKET_CHAR && c != RBRACKET_CHAR)
	{
		curtoken.tokentype=IT_ATOM;
		if (l < IT_MAX_ATOM_SIZE)
		{
			if (touc)
				c=toupper(c);
			appendch(c);
		}
		else
		{
			write_error_exit("max atom size too small");  
		}
		c=READ();
	}
	if (l == 0)
	{
		curtoken.tokentype=IT_ERROR;
		return (&curtoken);
	}
	appendch(0);
	UNREAD(c);

	if (strcmp(curtoken.tokenbuf, "NIL") == 0)
		curtoken.tokentype=IT_NIL;
	return (&curtoken);
}
Example #2
0
struct rfc2045 *fetch_alloc_rfc2045(unsigned long msgnum, FILE *fp)
{
	if (cached_rfc2045p &&
	    strcmp(cached_filename,
		   current_maildir_info.msgs[msgnum].filename) == 0)
		return (cached_rfc2045p);

	fetch_free_cached();

	if ((cached_filename=strdup(current_maildir_info.
				    msgs[msgnum].filename))
	    == 0) write_error_exit(0);

	if (fseek(fp, 0L, SEEK_SET) == -1)
	{
		write_error_exit(0);
		return (0);
	}
	cached_rfc2045p=rfc2045_fromfp(fp);
	if (!cached_rfc2045p)
	{
		free(cached_filename);
		cached_filename=0;
		write_error_exit(0);
	}
	return (cached_rfc2045p);
}
Example #3
0
static int hasnewmsgs(const char *folder)
{
char *dir=decode_valid_mailbox(folder, 0);
char *subdir;

	if (!dir)	return (0);

	if (is_sharedsubdir(dir))
		maildir_shared_sync(dir);

	subdir=malloc(strlen(dir)+sizeof("/cur"));
	if (!subdir)	write_error_exit(0);
	strcat(strcpy(subdir, dir), "/new");
	if (hasnewmsgs2(subdir))
	{
		free(subdir);
		free(dir);
		return (1);
	}

	strcat(strcpy(subdir, dir), "/cur");
	if (hasnewmsgs2(subdir))
	{
		free(subdir);
		free(dir);
		return (1);
	}

	free(subdir);
	free(dir);
	return (0);
}
Example #4
0
static void maildir_scan(const char *inbox_dir,
			 const char *inbox_name,
			 struct list_sharable_info *shared_info)
{
	DIR	*dirp;
	struct	dirent *de;

	/* Scan maildir, looking for .subdirectories */

	dirp=opendir(inbox_dir && inbox_dir ? inbox_dir:".");
	while (dirp && (de=readdir(dirp)) != 0)
	{
	char	*p;

		if (de->d_name[0] != '.' ||
		    strcmp(de->d_name, "..") == 0)
			continue;

		if ((p=malloc(strlen(de->d_name)+strlen(inbox_name)+10)) == 0)
					/* A bit too much, that's OK */
			write_error_exit(0);

		strcpy(p, inbox_name);

		if (strcmp(de->d_name, "."))
			strcat(p, de->d_name);

		folder_entry(p, shared_info->pattern, shared_info->flags,
			     shared_info->folders,
			     shared_info->hierarchies);
		free(p);
	}

	if (dirp)	closedir(dirp);
}
Example #5
0
static struct fetchinfo *alloc_headerlist(int oneonly)
{
struct fetchinfo *list, **listtail, *p;
struct imaptoken *tok;

	list=0;
	listtail= &list;

	while ((tok=currenttoken())->tokentype == IT_ATOM ||
	       tok->tokentype == IT_QUOTED_STRING ||
	       tok->tokentype == IT_NUMBER)
	{
		*listtail=p=(struct fetchinfo *)malloc(sizeof(*list));
		if (!p)	write_error_exit(0);
		p->next=0;
		p->name=my_strdup(tok->tokenbuf);
		p->bodysublist=0;
		p->bodysection=0;
		listtail= &p->next;
		if (oneonly)
			break;
		nexttoken_nouc();
	}
	return (list);
}
Example #6
0
char *my_strdup(const char *s)
{
char	*q=strdup(s);

	if (!q)	write_error_exit("malloc");
	return (q);
}
Example #7
0
void writeqs(const char *s)
{
size_t	i=strlen(s), j;

	while (i)
	{
		for (j=0; j<i; j++)
		{
			if ( s[j] == '"' || s[j] == '\\')
			{
				writemem(s, j);
				writemem("\\", 1);
				writemem(s+j, 1);
				++j;
				s += j;
				i -= j;
				j=0;
				break;
			}
#if 0
			if (s[j] == '&')
			{
				writemem(s, j);
				writemem("&-", 2);
				++j;
				s += j;
				i -= j;
				j=0;
				break;
			}

			if (s[j] < ' ' || s[j] >= 0x7F)
			{
			char	*q;

				writemem(s, j);
				++j;
				s += j;
				i -= j;
				for (j=0; j<i; j++)
					if (s[j] >= ' ' && s[j] < 0x7F)
						break;
				q=imap_utf7_encode(s, j);
				if (!q)	write_error_exit(0);
				writemem("&", 1);
				writes(q);
				writemem("-", 1);
				s += j;
				i -= j;
				j=0;
				break;
			}
#endif
		}
		writemem(s, j);
		s += j;
		i -= j;
	}
}
Example #8
0
static void
close_output_file		(FILE *			fp)
{
	if (fp != stdout) {
		if (0 != fclose (fp))
			write_error_exit (/* msg: errno */ NULL);
	} else {
		fflush (fp);
	}
}
Example #9
0
struct searchinfo *alloc_search(struct searchinfo **head)
{
struct searchinfo *si=(struct searchinfo *)malloc(sizeof(**head));

	if (si == 0)	write_error_exit(0);
	memset(si, 0, sizeof(*si));
	maildir_search_init(&si->sei);
	si->next= *head;
	*head=si;
	return (si);
}
Example #10
0
static void
finalize			(void)
{
	const vbi_export_info *xi;

	xi = vbi_export_info_from_export (ex);

	if (xi->open_format && NULL == out_file_name_prefix) {
		if (!vbi_export_stdio (ex, stdout, NULL))
			write_error_exit (vbi_export_errstr (ex));
	}
}
Example #11
0
char *get_reflagged_filename(const char *fn, struct imapflags *newflags)
{
	char *p=malloc(strlen(fn)+20);
	char *q;

	if (!p)	write_error_exit(0);
	strcpy(p, fn);
	if ((q=strrchr(p, MDIRSEP[0])) != 0)	*q=0;
	strcat(p, MDIRSEP "2,");
	append_flags(p, newflags);
	return p;
}
Example #12
0
void msgappends(void (*writefunc)(const char *, size_t),
		const char *s, size_t l)
{
	size_t	i,j;
	char *q=0;

	for (i=0; i<l; i++)
		if (s[i] & 0x80)	/* Illegal 8-bit header content */
		{
			char *p=malloc(l+1);

			if (!p)
				write_error_exit(0);
			if (l)
				memcpy(p, s, l);
			p[l]=0;

			/* Assume UTF-8, if not, well, GIGO */
			q=rfc2047_encode_str(p, "utf-8",
					     rfc2047_qp_allow_any);
			free(p);
			if (!q)
				write_error_exit(0);
			s=q;
			l=strlen(s);
		}

	for (i=j=0; i<l; i++)
	{
		if (s[i] == '"' || s[i] == '\\')
		{
			(*writefunc)(s+j, i-j);
			(*writefunc)("\\", 1);
			j=i;
		}
	}
	(*writefunc)(s+j, i-j);
	if (q)
		free(q);
}
Example #13
0
static void alloc_tokenbuf(unsigned l)
{
	if (l >= curtoken.tokenbuf_size)
	{
	char	*p=curtoken.tokenbuf ? realloc(curtoken.tokenbuf, l + 256):
			malloc(l + 256);

		if (!p)
			write_error_exit("malloc");

		curtoken.tokenbuf_size = l+256;
		curtoken.tokenbuf=p;
	}
}
Example #14
0
int storeinfo_init(struct storeinfo *si)
{
struct imaptoken *t=currenttoken();
const char *p;

	if (t->tokentype != IT_ATOM)	return (-1);
	si->plusminus=0;
	si->silent=0;

	p=t->tokenbuf;
	if (*p == '+' || *p == '-')
		si->plusminus= *p++;
	if (strncmp(p, "FLAGS", 5))	return (-1);
	p += 5;
	if (*p)
	{
		if (strcmp(p, ".SILENT"))	return (-1);
		si->silent=1;
	}

	memset(&si->flags, 0, sizeof(si->flags));

	if ((si->keywords=libmail_kwmCreate()) == NULL)
		write_error_exit(0);

	t=nexttoken_noparseliteral();
	if (t->tokentype == IT_LPAREN)
	{
		if (get_flagsAndKeywords(&si->flags, &si->keywords))
		{
			libmail_kwmDestroy(si->keywords);
			si->keywords=NULL;
			return (-1);
		}
		nexttoken();
	}
	else if (t->tokentype == IT_NIL)
		nexttoken();
	else if (t->tokentype == IT_ATOM)
	{
		if (get_flagname(t->tokenbuf, &si->flags))
			libmail_kwmSetName(current_maildir_info
				       .keywordList,
				       si->keywords,
				       t->tokenbuf);
		nexttoken();
	}
	return (0);
}
Example #15
0
static void list_sharable(const char *n,
	void *voidp)
{
struct list_sharable_info *ip=(struct list_sharable_info *)voidp;
char	*p=malloc(strlen(n)+sizeof("shared."));

	if (!p)	write_error_exit(0);

	strcat(strcpy(p, "shared."), n);

	folder_entry(p, ip->pattern, ip->flags,
		     ip->folders, ip->hierarchies);

	free(p);
}
Example #16
0
static void do_param_list(void (*writefunc)(const char *, size_t),
	struct rfc2045attr *a)
{
int	flag;
char	*p;

	flag=0;
	p="(";
	for (; a; a=a->next)
	{
		(*writefunc)(p, strlen(p));
		(*writefunc)("\"", 1);
		if (a->name)
			msgappends(writefunc, a->name, strlen(a->name));
		(*writefunc)("\" \"", 3);
		if (a->value)
		{
#if	IMAP_CLIENT_BUGS

		/* NETSCAPE */

		char *u, *v, *w;

			u=strdup(a->value);
			if (!u)	write_error_exit(0);
			strcpy(u, a->value);
			for (v=w=u; *v; v++)
				if (*v != '\\')	*w++ = *v;
			*w=0;
			msgappends(writefunc, u, strlen(u));
			free(u);

#else
			msgappends(writefunc, a->value, strlen(a->value));
#endif
		}
		(*writefunc)("\"", 1);
		flag=1;
		p=" ";
	}
	if (flag)
		(*writefunc)(")", 1);
	else
		(*writefunc)("NIL", 3);
}
Example #17
0
static int add_hier(struct hierlist **h, const char *s)
{
struct hierlist *p;

	for (p= *h; p; p=p->next)
		if (strcmp(p->hier, s) == 0)	return (1);
			/* Seen this one already */

	if ((p=(struct hierlist *)
		malloc( sizeof(struct hierlist)+1+strlen(s))) == 0)
			/* HACK!!!! */
		write_error_exit(0);
	p->flag=0;
	p->hier=(char *)(p+1);
	strcpy(p->hier, s);
	p->next= *h;
	*h=p;
	return (0);
}
Example #18
0
const char *maildir_shared_index_file()
{
	static char *filenamep=NULL;

	if (filenamep == NULL)
	{
		const char *p=getenv("IMAP_SHAREDINDEXFILE");

		if (p && *p)
		{
			const char *q=auth_getoptionenv("sharedgroup");

			if (!q) q="";

			filenamep=malloc(strlen(p)+strlen(q)+1);

			if (!filenamep)
				write_error_exit(0);

			strcat(strcpy(filenamep, p), q);
		}
	}

	if (filenamep && !shared_index_err_reported) /* Bitch just once */
	{
		struct stat stat_buf;

		shared_index_err_reported=1;
		if (stat(filenamep, &stat_buf))
		{
			fprintf(stderr, "ERR: ");
			perror(filenamep);
		}
	}

	return filenamep;
}
Example #19
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;
}
Example #20
0
static void
do_export			(vbi_pgno		pgno,
				 vbi_subno		subno)
{
	vbi_page page;
	vbi_bool success;

	if (option_delay > 1) {
		--option_delay;
		return;
	}

	success = vbi_fetch_vt_page (vbi, &page,
				     pgno, subno,
				     VBI_WST_LEVEL_3p5,
				     /* n_rows */ 25,
				     /* navigation */ TRUE);
	if (!success) {
		/* Shouldn't happen. */
		error_exit (_("Unknown error."));
	}

	if (option_dump_pg) {
		page_dump (&page);
	}

	switch (option_target) {
		char *file_name;
		void *buffer;
		void *buffer2;
		FILE *fp;
		size_t size;
		ssize_t ssize;

	case 1:
		buffer = malloc (1 << 20);
		if (NULL == buffer)
			no_mem_exit ();
		ssize = vbi_export_mem (ex, buffer, 1 << 20, &page);
		success = (ssize >= 0);
		if (success) {
			ssize_t ssize2;

			fp = open_output_file (pgno, subno);
			if (1 != fwrite (buffer, ssize, 1, fp))
				write_error_exit (/* msg: errno */ NULL);
			close_output_file (fp);

			/* Test. */
			ssize2 = vbi_export_mem (ex, buffer, 0, &page);
			assert (ssize == ssize2);
			assert (ssize > 0);
			ssize2 = vbi_export_mem (ex, buffer, ssize - 1, &page);
			assert (ssize == ssize2);
		}
		free (buffer);
		break;

	case 2:
		buffer = NULL;
		buffer2 = vbi_export_alloc (ex, &buffer, &size, &page);
		/* Test. */
		assert (buffer == buffer2);
		success = (NULL != buffer);
		if (success) {
			fp = open_output_file (pgno, subno);
			if (1 != fwrite (buffer, size, 1, fp))
				write_error_exit (/* msg: errno */ NULL);
			close_output_file (fp);
			free (buffer);
		}
		break;

	case 3:
		/* This is the default target. The other cases are only
		   implemented for tests and will be removed when I
		   wrote proper unit tests. */

		fp = open_output_file (pgno, subno);
		success = vbi_export_stdio (ex, fp, &page);
		close_output_file (fp);
		break;

	case 5:
		file_name = output_file_name (pgno, subno);
		success = vbi_export_file (ex, file_name, &page);
		free (file_name);
		break;

	default:
		error_exit ("Invalid target %u.", option_target);
		break;
	}

	if (!success) {
		error_exit (_("Export of page %x failed: %s"),
			    pgno,
			    vbi_export_errstr (ex));
	}

	vbi_unref_page (&page);
}
Example #21
0
int reflag_filename(struct imapscanmessageinfo *mi, struct imapflags *flags,
	int fd)
{
char    *p, *q, *r;
int	rc=0;
struct	imapflags old_flags;
struct	stat	stat_buf;

	get_message_flags(mi, 0, &old_flags);

	p=get_reflagged_filename(mi->filename, flags);

	q=malloc(strlen(current_mailbox)+strlen(mi->filename)+sizeof("/cur/"));
	r=malloc(strlen(current_mailbox)+strlen(p)+sizeof("/cur/"));
	if (!q || !r)	write_error_exit(0);
	strcat(strcat(strcpy(q, current_mailbox), "/cur/"), mi->filename);
	strcat(strcat(strcpy(r, current_mailbox), "/cur/"), p);
	if (strcmp(q, r))
	{
		if (maildirquota_countfolder(current_mailbox)
			&& old_flags.deleted != flags->deleted
			&& fstat(fd, &stat_buf) == 0)
		{
			struct maildirsize quotainfo;
			int64_t	nbytes;
			unsigned long unbytes;
			int	nmsgs=1;

			if (maildir_parsequota(mi->filename, &unbytes) == 0)
				nbytes=unbytes;
			else
				nbytes=stat_buf.st_size;
			if ( flags->deleted )
			{
				nbytes= -nbytes;
				nmsgs= -nmsgs;
			}

			if ( maildir_quota_delundel_start(current_mailbox,
							  &quotainfo,
							  nbytes, nmsgs))
				rc= -1;
			else
				maildir_quota_delundel_end(&quotainfo,
							   nbytes, nmsgs);
		}

		if (rc == 0)
			rename(q, r);

#if SMAP
		snapshot_needed();
#endif
	}
	free(q);
	free(r);
	free(mi->filename);
	mi->filename=p;

#if 0
	if (is_sharedsubdir(current_mailbox))
		maildir_shared_updateflags(current_mailbox, p);
#endif

	return (rc);
}
Example #22
0
int do_imap_command(const char *tag)
{
	struct	imaptoken *curtoken=nexttoken();
	char authservice[40];

#if SMAP
	if (strcmp(tag, "\\SMAP1") == 0)
	{
		const char *p=getenv("SMAP_CAPABILITY");

		if (p && *p)
			putenv("PROTOCOL=SMAP1");
		else
			return -1;
	}
#endif

	courier_authdebug_login( 1, "command=%s", curtoken->tokenbuf );

	if (strcmp(curtoken->tokenbuf, "LOGOUT") == 0)
	{
		if (nexttoken()->tokentype != IT_EOL)   return (-1);
		writes("* BYE Courier-IMAP server shutting down\r\n");
		cmdsuccess(tag, "LOGOUT completed\r\n");
		writeflush();
		fprintf(stderr, "INFO: LOGOUT, ip=[%s], rcvd=%lu, sent=%lu\n",
			getenv("TCPREMOTEIP"), bytes_received_count, bytes_sent_count);
		exit(0);
	}
	if (strcmp(curtoken->tokenbuf, "NOOP") == 0)
	{
		if (nexttoken()->tokentype != IT_EOL)	return (-1);
		cmdsuccess(tag, "NOOP completed\r\n");
		return (0);
	}
	if (strcmp(curtoken->tokenbuf, "CAPABILITY") == 0)
	{
		if (nexttoken()->tokentype != IT_EOL)	return (-1);

		writes("* CAPABILITY ");
		imapcapability();
		writes("\r\n");
		cmdsuccess(tag, "CAPABILITY completed\r\n");
		return (0);
	}

	if (strcmp(curtoken->tokenbuf, "STARTTLS") == 0)
	{
		if (!have_starttls())	return (-1);
		if (starttls(tag))		return (-2);
		putenv("IMAP_STARTTLS=NO");
		putenv("IMAP_TLS_REQUIRED=0");
		putenv("IMAP_TLS=1");

		return (0);
	}

	if (strcmp(curtoken->tokenbuf, "LOGIN") == 0)
	{
	struct imaptoken *tok=nexttoken_nouc();
	char	*userid;
	char	*passwd;
	const char *p;
	int	rc;

		if (have_starttls() && tlsrequired())	/* Not yet */
		{
			cmdfail(tag, "STARTTLS required\r\n");
			return (0);
		}

		switch (tok->tokentype)	{
		case IT_ATOM:
		case IT_NUMBER:
		case IT_QUOTED_STRING:
			break;
		default:
			return (-1);
		}

		userid=strdup(tok->tokenbuf);
		if (!userid)
			write_error_exit(0);
		tok=nexttoken_nouc_okbracket();
		switch (tok->tokentype)	{
		case IT_ATOM:
		case IT_NUMBER:
		case IT_QUOTED_STRING:
			break;
		default:
			free(userid);
			return (-1);
		}

		passwd=my_strdup(tok->tokenbuf);

		if (nexttoken()->tokentype != IT_EOL)
		{
			free(userid);
			free(passwd);
			return (-1);
		}

		strcat(strcpy(authservice, "AUTHSERVICE"),
		       getenv("TCPLOCALPORT"));

		p=getenv(authservice);

		if (!p || !*p)
			p="imap";

		rc=auth_login(p, userid, passwd, login_callback, (void *)tag);
		courier_safe_printf("INFO: LOGIN FAILED, user=%s, ip=[%s]",
				  userid, getenv("TCPREMOTEIP"));
		free(userid);
		free(passwd);
		if (rc > 0)
		{
			perror("ERR: authentication error");
			writes("* BYE Temporary problem, please try again later\r\n");
			writeflush();
			exit(1);
		}
		sleep(5);
		cmdfail(tag, "Login failed.\r\n");
		return (0);
	}

	if (strcmp(curtoken->tokenbuf, "AUTHENTICATE") == 0)
	{
	char	method[32];
	int	rc;

		if (have_starttls() && tlsrequired())	/* Not yet */
		{
			cmdfail(tag, "STARTTLS required\r\n");
			return (0);
		}
		rc=authenticate(tag, method, sizeof(method));
		courier_safe_printf("INFO: LOGIN FAILED, method=%s, ip=[%s]",
				  method, getenv("TCPREMOTEIP"));
		if (rc > 0)
		{
			perror("ERR: authentication error");
			writes("* BYE Temporary problem, please try again later\r\n");
			writeflush();
			exit(1);
		}
		sleep(5);
		cmdfail(tag, "Login failed.\r\n");
		writeflush();
		return (-2);
	}

	return (-1);
}
Example #23
0
struct fetchinfo *fetchinfo_alloc(int oneonly)
{
struct fetchinfo *list, **listtail, *p;
struct imaptoken *tok;

	list=0;
	listtail= &list;

	while ((tok=currenttoken())->tokentype == IT_ATOM)
	{
		if (oneonly && list)	break;
		*listtail=p=(struct fetchinfo *)malloc(sizeof(*list));
		if (!p)	write_error_exit(0);
		p->next=0;
		p->name=my_strdup(tok->tokenbuf);
		p->bodysection=0;
		p->bodysublist=0;
		p->ispartial=0;
		listtail= &p->next;

		if (strcmp(p->name, "ALL") == 0 ||
			strcmp(p->name, "BODYSTRUCTURE") == 0 ||
			strcmp(p->name, "ENVELOPE") == 0 ||
			strcmp(p->name, "FLAGS") == 0 ||
			strcmp(p->name, "FAST") == 0 ||
			strcmp(p->name, "FULL") == 0 ||
			strcmp(p->name, "INTERNALDATE") == 0 ||
			strcmp(p->name, "RFC822") == 0 ||
			strcmp(p->name, "RFC822.HEADER") == 0 ||
			strcmp(p->name, "RFC822.SIZE") == 0 ||
			strcmp(p->name, "RFC822.TEXT") == 0 ||
			strcmp(p->name, "UID") == 0)
		{
			nexttoken();
			continue;
		}
		if (strcmp(p->name, "BODY") && strcmp(p->name, "BODY.PEEK"))
			break;
		if (nexttoken()->tokentype != IT_LBRACKET)	continue;

		/* Parse BODY[ ... ] */

		if ((tok=nexttoken())->tokentype != IT_RBRACKET)
		{
		char	*s;

			if ( (tok->tokentype != IT_ATOM &&
				tok->tokentype != IT_NUMBER) ||
				!(s=good_section(tok->tokenbuf)))
			{
				fetchinfo_free(list);
				return (0);
			}
			p->bodysection=my_strdup(tok->tokenbuf);

			if (strcmp(s, "HEADER.FIELDS") == 0 ||
				strcmp(s, "HEADER.FIELDS.NOT") == 0)
			{
				/* Must be followed by header list */

				if ((tok=nexttoken_nouc())->tokentype
						!= IT_LPAREN)
				{
					p->bodysublist=alloc_headerlist(1);
					if (p->bodysublist == 0)
					{
						fetchinfo_free(list);
						return (0);
					}
				}
				else
				{
					nexttoken_nouc();
					p->bodysublist=alloc_headerlist(0);
					if ( currenttoken()->tokentype
						!= IT_RPAREN)
					{
						fetchinfo_free(list);
						return (0);
					}
				}
			}
			tok=nexttoken();
			
		}
		else p->bodysection=my_strdup("");

		if (tok->tokentype != IT_RBRACKET)
		{
			fetchinfo_free(list);
			return (0);
		}
		tok=nexttoken();
		if (tok->tokentype == IT_ATOM && tok->tokenbuf[0] == '<' &&
			tok->tokenbuf[strlen(tok->tokenbuf)-1] == '>' &&
			(p->ispartial=sscanf(tok->tokenbuf+1, "%lu.%lu",
				&p->partialstart, &p->partialend)) > 0)
			nexttoken();
	}
	return (list);
}
Example #24
0
int do_store(unsigned long n, int byuid, void *voidptr)
{
struct storeinfo *si=(struct storeinfo *)voidptr;
int	fd;
 struct imapflags new_flags, old_flags;
int changedKeywords;
struct libmail_kwMessageEntry *kme;
int kwAllowed=1;

	--n;
	fd=imapscan_openfile(current_mailbox, &current_maildir_info, n);
	if (fd < 0)	return (0);

	changedKeywords=0;
	get_message_flags(current_maildir_info.msgs+n, 0, &new_flags);

	old_flags=new_flags;

	if (current_mailbox_acl)
	{
		if (strchr(current_mailbox_acl, ACL_WRITE[0]) == NULL)
			kwAllowed=0;
	}


	if (si->plusminus == '+')
	{
		if (si->flags.drafts)	new_flags.drafts=1;
		if (si->flags.seen)	new_flags.seen=1;
		if (si->flags.answered)	new_flags.answered=1;
		if (si->flags.deleted)	new_flags.deleted=1;
		if (si->flags.flagged)	new_flags.flagged=1;

		for (kme=si->keywords ? si->keywords->firstEntry:NULL;
		     kme; kme=kme->next)
		{
			int rc;

			if (!kwAllowed)
			{
				current_maildir_info.msgs[n].changedflags=1;
				continue;
			}

			imapscan_createKeyword(&current_maildir_info, n);

			if ((rc=libmail_kwmSet(current_maildir_info.msgs[n]
					       .keywordMsg,
					       kme->libmail_keywordEntryPtr))
			    < 0)
			{
				write_error_exit(0);
				return 0;
			}

			if (rc == 0)
			{
				if (fastkeywords())
					changedKeywords=1;
				current_maildir_info.msgs[n].changedflags=1;
			}
		}
	}
	else if (si->plusminus == '-')
	{
		if (si->flags.drafts)	new_flags.drafts=0;
		if (si->flags.seen)	new_flags.seen=0;
		if (si->flags.answered)	new_flags.answered=0;
		if (si->flags.deleted)	new_flags.deleted=0;
		if (si->flags.flagged)	new_flags.flagged=0;

		if (current_maildir_info.msgs[n].keywordMsg && kwAllowed)
			for (kme=si->keywords ?
				     si->keywords->firstEntry:NULL;
			     kme; kme=kme->next)
			{
				if (!kwAllowed)
				{
					current_maildir_info.msgs[n]
						.changedflags=1;
					continue;
				}

				if (libmail_kwmClear(current_maildir_info.msgs[n]
						 .keywordMsg,
						 kme->libmail_keywordEntryPtr)==0)
				{
					if (fastkeywords())
						changedKeywords=1;
					current_maildir_info.msgs[n]
						.changedflags=1;
				}
			}

		if (current_maildir_info.msgs[n].keywordMsg &&
		    !current_maildir_info.msgs[n].keywordMsg->firstEntry)
		{
			libmail_kwmDestroy(current_maildir_info.msgs[n]
					      .keywordMsg);
			current_maildir_info.msgs[n].keywordMsg=NULL;
		}
	}
	else
	{
		struct libmail_kwMessage *kw;

		new_flags=si->flags;

		kw=current_maildir_info.msgs[n].keywordMsg;

		if (kw && kw->firstEntry == NULL)
			kw=NULL;

		if (si->keywords && si->keywords->firstEntry == NULL)
			si->keywords=NULL;

		if ((si->keywords && !kw) ||
		    (!si->keywords && kw) ||
		    (si->keywords && kw && libmail_kwmCmp(si->keywords, kw)))
		{
			if (kwAllowed)
			{
				kw=current_maildir_info.msgs[n].keywordMsg;

				if (kw)
					libmail_kwmDestroy(kw);

				current_maildir_info.msgs[n].keywordMsg=NULL;

				if (si->keywords && si->keywords->firstEntry)
				{
					struct libmail_kwMessageEntry *kme;

					kw=imapscan_createKeyword(&current_maildir_info,
								  n);

					for (kme=si->keywords->lastEntry; kme;
					     kme=kme->prev)
						if (libmail_kwmSet(kw,
								   kme->libmail_keywordEntryPtr)
						    < 0)
							write_error_exit(0);
					current_maildir_info.msgs[n].keywordMsg=kw;
				}
			}

			changedKeywords=1;
		}
	}

	if (current_mailbox_acl)
	{
		if (strchr(current_mailbox_acl, ACL_WRITE[0]) == NULL)
		{
			new_flags.drafts=old_flags.drafts;
			new_flags.answered=old_flags.answered;
			new_flags.flagged=old_flags.flagged;
		}

		if (strchr(current_mailbox_acl, ACL_SEEN[0]) == NULL)
		{
			new_flags.seen=old_flags.seen;
		}

		if (strchr(current_mailbox_acl, ACL_DELETEMSGS[0])
		    == NULL)
		{
			new_flags.deleted=old_flags.deleted;
		}
	}

	if (changedKeywords)
	{
		current_maildir_info.msgs[n].changedflags=1;
		if (imapscan_updateKeywords(current_maildir_info.msgs[n]
					    .filename,
					    current_maildir_info.msgs[n]
					    .keywordMsg))
		{
			close(fd);
			return -1;
		}
	}

	if (reflag_filename(current_maildir_info.msgs+n, &new_flags, fd))
	{
		close(fd);
		return (-1);
	}
	close(fd);
	if (si->silent)
		current_maildir_info.msgs[n].changedflags=0;
	else
	{
#if SMAP
		/* SMAP flag notification is handled elsewhere */

		if (!smapflag)
#endif
		{
			if (byuid)
				fetchflags_byuid(n);
			else
				fetchflags(n);
		}
	}

	return (0);
}
Example #25
0
FILE *open_cached_fp(unsigned long msgnum)
{
	int	fd;

	if (cached_fp && strcmp(cached_fp_filename,
				current_maildir_info.msgs[msgnum].filename)
	    == 0)
		return (cached_fp);

	if (cached_fp)
	{
		fclose(cached_fp);
		free(cached_fp_filename);
		cached_fp_filename=0;
		cached_fp=0;
	}

	fd=imapscan_openfile(current_mailbox, &current_maildir_info, msgnum);
	if (fd < 0 || (cached_fp=fdopen(fd, "r")) == 0)
	{
		if (fd >= 0)	close(fd);

		if ((cached_fp=tmpfile()) != 0)
		{
			fprintf(cached_fp, unavailable);
			if (fseek(cached_fp, 0L, SEEK_SET) < 0 ||
			    ferror(cached_fp))
			{
				fclose(cached_fp);
				cached_fp=0;
			}
		}

		if (cached_fp == 0)
		{
			fprintf(stderr, "ERR: %s: %s\n",
				getenv("AUTHENTICATED"),
#if	HAVE_STRERROR
				strerror(errno)
#else
				"error"
#endif

				);
			fflush(stderr);
			_exit(1);
		}
	}

	if ((cached_fp_filename=strdup(current_maildir_info.
				       msgs[msgnum].filename))
	    == 0)
	{
		fclose(cached_fp);
		cached_fp=0;
		write_error_exit(0);
	}
	cached_base_offset=0;
	cached_virtual_offset=0;
	cached_phys_offset=0;
	return (cached_fp);
}
Example #26
0
static struct searchinfo *alloc_search_key(struct searchinfo **head)
{
struct imaptoken *t=currenttoken();
struct searchinfo *si;
const char *keyword;

	if (t->tokentype == IT_LPAREN)
	{
		nexttoken();
		if ((si=alloc_search_andlist(head)) == 0 ||
			currenttoken()->tokentype != IT_RPAREN)
			return (0);
		nexttoken();
		return (si);
	}

	if (t->tokentype != IT_ATOM && t->tokentype != IT_NUMBER)
		return (0);

	keyword=t->tokenbuf;

	if (strcmp(keyword, "ALL") == 0)
	{
	struct searchinfo *si;

		(si=alloc_search(head))->type=search_all;
		nexttoken();
		return (si);
	}

	if (strcmp(keyword, "OR") == 0)
	{
	struct searchinfo *si;

		si=alloc_search(head);
		si->type=search_or;
		nexttoken();
		if ((si->a=alloc_search_notkey(head)) == 0 ||
			(si->b=alloc_search_notkey(head)) == 0)	return (0);
		return (si);
	}

	if (strcmp(keyword, "HEADER") == 0)
	{
	struct imaptoken *t;
	struct searchinfo *si;

		si=alloc_search(head);
		si->type=search_header;
		t=nexttoken_okbracket();
		if (t->tokentype != IT_ATOM &&
		    t->tokentype != IT_NUMBER &&
		    t->tokentype != IT_QUOTED_STRING)
			return (0);
		si->cs=strdup(t->tokenbuf);
		if (!si->cs)
			write_error_exit(0);
		t=nexttoken_okbracket();
		if (t->tokentype != IT_ATOM &&
		    t->tokentype != IT_NUMBER &&
		    t->tokentype != IT_QUOTED_STRING)
			return (0);
		si->as=my_strdup(t->tokenbuf);
		nexttoken();
		return (si);
	}

	if (strcmp(keyword, "BCC") == 0 ||
		strcmp(keyword, "CC") == 0 ||
		strcmp(keyword, "FROM") == 0 ||
		strcmp(keyword, "TO") == 0 ||
		strcmp(keyword, "SUBJECT") == 0)
	{
	struct imaptoken *t;
	struct searchinfo *si;

		si=alloc_search(head);
		si->type=search_header;
		si->cs=my_strdup(keyword);
		t=nexttoken_okbracket();
		if (t->tokentype != IT_ATOM &&
		    t->tokentype != IT_NUMBER &&
		    t->tokentype != IT_QUOTED_STRING)
			return (0);
		si->as=my_strdup(t->tokenbuf);
		nexttoken();
		return (si);
	}

	if (strcmp(keyword, "BEFORE") == 0)
	{
	struct imaptoken *t;
	struct searchinfo *si;

		si=alloc_search(head);
		si->type=search_before;
		t=nexttoken();
		if (t->tokentype != IT_ATOM &&
		    t->tokentype != IT_NUMBER &&
		    t->tokentype != IT_QUOTED_STRING)
			return (0);
		si->as=my_strdup(t->tokenbuf);
		nexttoken();
		return (si);
	}

	if (strcmp(keyword, "BODY") == 0)
	{
	struct imaptoken *t;
	struct searchinfo *si;

		si=alloc_search(head);
		si->type=search_body;
		t=nexttoken_okbracket();
		if (t->tokentype != IT_ATOM &&
		    t->tokentype != IT_NUMBER &&
		    t->tokentype != IT_QUOTED_STRING)
			return (0);
		si->as=my_strdup(t->tokenbuf);
		nexttoken();
		return (si);
	}
	if (strcmp(keyword, "LARGER") == 0)
	{
	struct imaptoken *t;
	struct searchinfo *si;

		si=alloc_search(head);
		si->type=search_larger;
		t=nexttoken();
		if (t->tokentype != IT_NUMBER)
			return (0);
		si->as=my_strdup(t->tokenbuf);
		nexttoken();
		return (si);
	}

	if (strcmp(keyword, "ON") == 0)
	{
	struct imaptoken *t;
	struct searchinfo *si;

		si=alloc_search(head);
		si->type=search_on;
		t=nexttoken();
		if (t->tokentype != IT_ATOM &&
		    t->tokentype != IT_NUMBER &&
		    t->tokentype != IT_QUOTED_STRING)
			return (0);
		si->as=my_strdup(t->tokenbuf);
		nexttoken();
		return (si);
	}

	if (strcmp(keyword, "SENTBEFORE") == 0)
	{
	struct imaptoken *t;
	struct searchinfo *si;

		si=alloc_search(head);
		si->type=search_sentbefore;
		t=nexttoken();
		if (t->tokentype != IT_ATOM &&
		    t->tokentype != IT_NUMBER &&
		    t->tokentype != IT_QUOTED_STRING)
			return (0);
		si->as=my_strdup(t->tokenbuf);
		nexttoken();
		return (si);
	}

	if (strcmp(keyword, "SENTON") == 0)
	{
	struct imaptoken *t;
	struct searchinfo *si;

		si=alloc_search(head);
		si->type=search_senton;
		t=nexttoken();
		if (t->tokentype != IT_ATOM &&
		    t->tokentype != IT_NUMBER &&
		    t->tokentype != IT_QUOTED_STRING)
			return (0);
		si->as=my_strdup(keyword);
		nexttoken();
		return (si);
	}

	if (strcmp(keyword, "SENTSINCE") == 0)
	{
	struct imaptoken *t;
	struct searchinfo *si;

		si=alloc_search(head);
		si->type=search_sentsince;
		t=nexttoken();
		if (t->tokentype != IT_ATOM &&
		    t->tokentype != IT_NUMBER &&
		    t->tokentype != IT_QUOTED_STRING)
			return (0);
		si->as=my_strdup(t->tokenbuf);
		nexttoken();
		return (si);
	}

	if (strcmp(keyword, "SINCE") == 0)
	{
	struct imaptoken *t;
	struct searchinfo *si;

		si=alloc_search(head);
		si->type=search_since;
		t=nexttoken();
		if (t->tokentype != IT_ATOM &&
		    t->tokentype != IT_NUMBER &&
		    t->tokentype != IT_QUOTED_STRING)
			return (0);
		si->as=my_strdup(t->tokenbuf);
		nexttoken();
		return (si);
	}

	if (strcmp(keyword, "SMALLER") == 0)
	{
	struct imaptoken *t;
	struct searchinfo *si;

		si=alloc_search(head);
		si->type=search_smaller;
		t=nexttoken();
		if (t->tokentype != IT_NUMBER)
			return (0);
		si->as=my_strdup(t->tokenbuf);
		nexttoken();
		return (si);
	}

	if (strcmp(keyword, "TEXT") == 0)
	{
	struct imaptoken *t;
	struct searchinfo *si;

		si=alloc_search(head);
		si->type=search_text;
		t=nexttoken_okbracket();
		if (t->tokentype != IT_ATOM &&
		    t->tokentype != IT_NUMBER &&
		    t->tokentype != IT_QUOTED_STRING)
			return (0);
		si->as=my_strdup(t->tokenbuf);
		nexttoken();
		return (si);
	}

	if (strcmp(keyword, "UID") == 0)
	{
	struct searchinfo *si;
	struct imaptoken *t;

		si=alloc_search(head);
		si->type=search_uid;
		t=nexttoken();
		if (!ismsgset(t))
			return (0);
		si->as=my_strdup(t->tokenbuf);
		nexttoken();
		return (si);
	}

	if (strcmp(keyword, "KEYWORD") == 0
		|| strcmp(keyword, "UNKEYWORD") == 0)
	{
	int	isnot= *keyword == 'U';
	struct imaptoken *t;
	struct searchinfo *si;

		si=alloc_search(head);
		si->type=search_msgkeyword;
		t=nexttoken_okbracket();
		if (t->tokentype != IT_ATOM &&
		    t->tokentype != IT_NUMBER &&
		    t->tokentype != IT_QUOTED_STRING)
			return (0);
		si->as=my_strdup(t->tokenbuf);
		nexttoken();

		if (isnot)
		{
		struct searchinfo *si2=alloc_search(head);

			si2->type=search_not;
			si2->a=si;
			si=si2;
		}
		return (si);
	}
	if (strcmp(keyword, "ANSWERED") == 0 ||
		strcmp(keyword, "DELETED") == 0 ||
		strcmp(keyword, "DRAFT") == 0 ||
		strcmp(keyword, "FLAGGED") == 0 ||
		strcmp(keyword, "RECENT") == 0 ||
		strcmp(keyword, "SEEN") == 0)
	{
	struct searchinfo *si;

		si=alloc_search(head);
		si->type=search_msgflag;
		if ((si->as=malloc(strlen(keyword)+2)) == 0)
			write_error_exit(0);
		si->as[0]='\\';
		strcpy(si->as+1, keyword);
		nexttoken();
		return (si);
	}

	if (strcmp(keyword, "UNANSWERED") == 0 ||
		strcmp(keyword, "UNDELETED") == 0 ||
		strcmp(keyword, "UNDRAFT") == 0 ||
		strcmp(keyword, "UNFLAGGED") == 0 ||
		strcmp(keyword, "UNSEEN") == 0)
	{
	struct searchinfo *si;
	struct searchinfo *si2;

		si=alloc_search(head);
		si->type=search_msgflag;
		if ((si->as=malloc(strlen(keyword))) == 0)
			write_error_exit(0);
		si->as[0]='\\';
		strcpy(si->as+1, keyword+2);
		nexttoken();

		si2=alloc_search(head);
		si2->type=search_not;
		si2->a=si;
		return (si2);
	}

	if (strcmp(keyword, "NEW") == 0)
	{
	struct searchinfo *si, *si2;

		si=alloc_search(head);
		si->type=search_and;
		si2=si->a=alloc_search(head);
		si2->type=search_msgflag;
		si2->as=my_strdup("\\RECENT");
		si2=si->b=alloc_search(head);
		si2->type=search_not;
		si2=si2->a=alloc_search(head);
		si2->type=search_msgflag;
		si2->as=my_strdup("\\SEEN");
		nexttoken();
		return (si);
	}

	if (strcmp(keyword, "OLD") == 0)
	{
	struct searchinfo *si, *si2;

		si=alloc_search(head);
		si->type=search_not;
		si2=si->a=alloc_search(head);
		si2->type=search_msgflag;
		si2->as=my_strdup("\\RECENT");
		nexttoken();
		return (si);
	}

	if (ismsgset(t))
	{
		si=alloc_search(head);
		si->type=search_messageset;
		si->as=my_strdup(t->tokenbuf);
		nexttoken();
		return (si);
	}

	return (0);
}
Example #27
0
static int list_newshared_cb(struct maildir_newshared_enum_cb *cb)
{
	const char *name=cb->name;
	const char *homedir=cb->homedir;
	const char *maildir=cb->maildir;
	struct list_newshared_info *lni=
		(struct list_newshared_info *)cb->cb_arg;
	char *n=maildir_info_imapmunge(name);
	int rc;

	if (!n)
		write_error_exit(0);

	if (homedir == NULL)
	{
		struct list_newshared_info new_lni= *lni;
		char *new_pfix=malloc(strlen(lni->acc_pfix)+
				      strlen(n)+2);
		if (!new_pfix)
			write_error_exit(0);

		strcat(strcpy(new_pfix, lni->acc_pfix), n);

		free(n);
		n=new_pfix;
		new_lni.acc_pfix=n;
		add_hier(lni->shared_info->hierarchies, n);
		hier_entry(n, lni->shared_info->hierarchies);
		strcat(n, hierchs);
		rc=lni->dorecurse ?
			maildir_newshared_enum(maildir, list_newshared_cb,
					       &new_lni):0;
	}
	else
	{
		char *new_pfix;
		struct stat stat_buf;

		new_pfix=maildir_location(homedir, maildir);

		if (stat(new_pfix, &stat_buf) < 0 ||
		    /* maildir inaccessible, perhaps another server? */

		    (stat_buf.st_dev == homedir_dev &&
		     stat_buf.st_ino == homedir_ino))
		    /* Exclude ourselves from the shared list */
		{
			free(new_pfix);
			free(n);
			return 0;
		}
		free(new_pfix);

		new_pfix=malloc(strlen(lni->acc_pfix)+
				      strlen(n)+1);
		if (!new_pfix)
			write_error_exit(0);

		strcat(strcpy(new_pfix, lni->acc_pfix), n);

		free(n);
		n=new_pfix;

		new_pfix=malloc(strlen(homedir)+strlen(maildir)+2);

		if (!new_pfix)
			write_error_exit(0);

		if (*maildir == '/')
			strcpy(new_pfix, maildir);
		else
			strcat(strcat(strcpy(new_pfix, homedir), "/"),
			       maildir);

		/*		if (lni->dorecurse) */

		maildir_scan(new_pfix, n, lni->shared_info);
#if 0
		else
		{
			folder_entry(n, lni->shared_info->pattern,
				     lni->shared_info->flags,
				     lni->shared_info->folders,
				     lni->shared_info->hierarchies);
		}
#endif

		free(new_pfix);
		rc=0;
	}
Example #28
0
static void
do_export			(vbi_pgno		pgno,
				 vbi_subno		subno,
				 double			timestamp)
{
	vbi_page *pg;
	vbi_bool success;

	if (option_delay > 1) {
		--option_delay;
		return;
	}

	if (pgno >= 0x100) {
		if (0 != option_override_cs) {
			pg = vbi_decoder_get_page
				(vbi, NULL /* current network */,
				 pgno, subno,
				 VBI_HEADER_ONLY, option_header_only, 
				 VBI_PADDING, option_padding,
				 VBI_PANELS, option_panels,
				 VBI_NAVIGATION, option_navigation,
				 VBI_HYPERLINKS, option_hyperlinks,
				 VBI_PDC_LINKS, option_pdc_links,
				 VBI_WST_LEVEL, VBI_WST_LEVEL_3p5,
				 VBI_OVERRIDE_CHARSET_0, option_override_cs,
				 VBI_END);
		} else {
			pg = vbi_decoder_get_page
				(vbi, NULL /* current network */,
				 pgno, subno,
				 VBI_HEADER_ONLY, option_header_only, 
				 VBI_PADDING, option_padding,
				 VBI_PANELS, option_panels,
				 VBI_NAVIGATION, option_navigation,
				 VBI_HYPERLINKS, option_hyperlinks,
				 VBI_PDC_LINKS, option_pdc_links,
				 VBI_WST_LEVEL, VBI_WST_LEVEL_3p5,
				 VBI_DEFAULT_CHARSET_0, option_default_cs,
				 VBI_END);
		}
	} else {
		pg = vbi_decoder_get_page
			(vbi, NULL /* current network */,
			 pgno, subno,
			 VBI_PADDING, option_padding,
			 VBI_DEFAULT_FOREGROUND, option_default_fg,
			 VBI_DEFAULT_BACKGROUND, option_default_bg,
			 VBI_ROW_CHANGE, option_row_update,
			 VBI_END);
	}

	assert (NULL != pg);

	if (option_dump_pg) {
		page_dump (pg);
	}

	switch (option_target) {
		char *file_name;
		void *buffer;
		void *buffer2;
		FILE *fp;
		size_t size;
		ssize_t ssize;

	case 1:
		buffer = malloc (1 << 20);
		if (NULL == buffer)
			no_mem_exit ();
		ssize = vbi_export_mem (ex, buffer, 1 << 20, pg);
		success = (ssize >= 0);
		if (success) {
			ssize_t ssize2;

			fp = open_output_file (pgno, subno);
			if (1 != fwrite (buffer, ssize, 1, fp))
				write_error_exit (/* msg: errno */ NULL);
			close_output_file (fp);

			/* Test. */
			ssize2 = vbi_export_mem (ex, buffer, 0, pg);
			assert (ssize == ssize2);
			assert (ssize > 0);
			ssize2 = vbi_export_mem (ex, buffer, ssize - 1, pg);
			assert (ssize == ssize2);
		}
		free (buffer);
		break;

	case 2:
		buffer = NULL;
		buffer2 = vbi_export_alloc (ex, &buffer, &size, pg);
		/* Test. */
		assert (buffer == buffer2);
		success = (NULL != buffer);
		if (success) {
			fp = open_output_file (pgno, subno);
			if (1 != fwrite (buffer, size, 1, fp))
				write_error_exit (/* msg: errno */ NULL);
			close_output_file (fp);
			free (buffer);
		}
		break;

	case 3:
		/* This is the default target. The other cases are only
		   implemented for tests and will be removed when I
		   wrote proper unit tests. */

	fp = open_output_file (pgno, subno);

	/* For proper timing of subtitles. */
	vbi_export_set_timestamp (ex, timestamp);

		success = vbi_export_stdio (ex, fp, pg);

		close_output_file (fp);

		break;

	case 5:
		file_name = output_file_name (pgno, subno);
		success = vbi_export_file (ex, file_name, pg);
		free (file_name);
		break;

	default:
		error_exit ("Invalid target %u.", option_target);
		break;
	}

	if (!success) {
		error_exit (_("Export of page %x failed: %s"),
			    pgno,
			    vbi_export_errstr (ex));
	}

	if (option_pdc_enum) {
		pdc_dump (pg);
	}

	vbi_page_delete (pg);
	pg = NULL;
}