예제 #1
0
int do_copy_quota_calc(unsigned long n, int byuid, void *voidptr)
{
struct copyquotainfo *info=(struct copyquotainfo *)voidptr;
const char *filename;
unsigned long nbytes;
struct	stat	stat_buf;
int	fd;
struct imapflags flags;
char *ff;

	--n;

	fd=imapscan_openfile(current_mailbox, &current_maildir_info, n);
	if (fd < 0)	return (0);
	filename=current_maildir_info.msgs[n].filename;

	get_message_flags(&current_maildir_info.msgs[n], NULL, &flags);

	(void)acl_flags_adjust(info->acls, &flags);

	ff=get_reflagged_filename(filename, &flags);

	if (maildirquota_countfile(ff))
	{
		if (maildir_parsequota(ff, &nbytes))
		{
			if (fstat(fd, &stat_buf) < 0)
			{
				close(fd);
				free(ff);
				return (0);
			}
			nbytes=stat_buf.st_size;
		}
		info->nbytes += nbytes;
		info->nfiles += 1;
	}
	close(fd);
	free(ff);
	return (0);
}
예제 #2
0
static void cleanup()
{
	unsigned i;

	int64_t deleted_bytes=0;
	int64_t deleted_messages=0;

	for (i=0; i<msglist_cnt; i++)
		if (msglist_a[i]->isdeleted)
		{
			unsigned long un=0;

			const char *filename=msglist_a[i]->filename;

			if (maildirquota_countfile(filename))
			{
				if (maildir_parsequota(filename, &un))
				{
					struct stat stat_buf;

					if (stat(filename, &stat_buf) == 0)
						un=stat_buf.st_size;
				}
			}

			if (unlink(msglist_a[i]->filename))
				un=0;

			if (un)
			{
				deleted_bytes -= un;
				deleted_messages -= 1;
			}
		}

	if (deleted_messages < 0)
		maildir_quota_deleted(".", deleted_bytes, deleted_messages);

	return;
}
예제 #3
0
파일: newmsg.c 프로젝트: zixia/wmail
static int dosendmsg(const char *origdraft)
{
pid_t	pid;
const	char *returnaddr;
int	pipefd1[2];
char	*filename;
const char *line;
char	*draftmessage;
int	isgpgerr;
unsigned long filesize;
struct stat stat_buf;
int dsn;

	if (tokencheck()) /* Duplicate submission - message was already sent */
	{
		sendmsg_done();
		return (1);
	}

	if (strcmp(cgi("form"), "doattach") == 0)
	{
		/* When called from the attachment window, we do NOT create
		** a new draft message */

		draftmessage=strdup(origdraft);
	}
	else
		draftmessage=newmsg_createdraft(origdraft);
	if (!draftmessage)
		enomem();

	filename=newmsg_createsentmsg(draftmessage, &isgpgerr, 1);

	if (!filename)
	{
		char *draftbase=maildir_basename(draftmessage);

		if (isgpgerr)
		{
			cgi_put("draftmessage", draftbase);
			output_form("gpgerr.html");
		}
		else
		{
			http_redirect_argss("&form=newmsg&pos=%s"
					    "&draft=%s&error=quota",
					    cgi("pos"), draftbase);
		}
		free(draftmessage);
		free(draftbase);
		return (1);
	}

	if (pipe(pipefd1) != 0)
	{
		cgi_put("foldermsg", "ERROR: pipe() failed.");
		maildir_msgpurgefile(SENT, filename);
		free(filename);
		free(draftmessage);
		return (0);
	}

	returnaddr=login_returnaddr();

	dsn= *cgi("dsn") != 0;

	pid=fork();
	if (pid < 0)
	{
		cgi_put("foldermsg", "ERROR: fork() failed.");
		close(pipefd1[0]);
		close(pipefd1[1]);
		maildir_msgpurgefile(SENT, filename);
		free(filename);
		free(draftmessage);
		return (0);
	}

	if (pid == 0)
	{
	static const char noexec[]="ERROR: Unable to execute sendit.sh.\n";
	static const char nofile[]="ERROR: Temp file not available - probably exceeded quota.\n";
	char	*tmpfile=maildir_find(SENT, filename);
	int	fd;

		if (!tmpfile)
		{
			fwrite((char*)nofile, 1, sizeof(nofile)-1, stderr);
			_exit(1);
		}

		close(0);

		fd=maildir_safeopen(tmpfile, O_RDONLY, 0);
		close(1);
		close(2);
		dup(pipefd1[1]);
		dup(pipefd1[1]);
		close(pipefd1[0]);
		close(pipefd1[1]);

		if (dsn)
			putenv("DSN=-Nsuccess,delay,fail");
		else
			putenv("DSN=");

		if (fd == 0)
			execl(SENDITSH, "sendit.sh", returnaddr,
				sqwebmail_mailboxid, NULL);

		fwrite(noexec, 1, sizeof(noexec)-1, stderr);
		_exit(1);
	}
	close(pipefd1[1]);

	line=geterrbuf(pipefd1[0]);
	close(pipefd1[0]);

	if (waitfor(pid))
	{
		if (!*line)
			line="Unable to send message.\n";
	}
	else
		line="";

	if (*line == 0)	/* Succesfully sent message */
	{
		if (*draftmessage)
		{
		char	*base=maildir_basename(draftmessage);
		char	*draftfile=maildir_find(DRAFTS, base);

			free(base);

			/* Remove draft file */

			if (draftfile)
			{
			char	*replytofolder=0, *replytomsg=0;
			char	*header, *value;
			FILE	*fp;
			int	x;

				fp=0;
				x=maildir_safeopen(draftfile, O_RDONLY, 0);
				if ( maildir_parsequota(draftfile, &filesize))
				{
					if (x < 0 || fstat(x, &stat_buf))
						stat_buf.st_size=0;
					filesize=stat_buf.st_size;
				}

				if (x >= 0)
					if ((fp=fdopen(x, "r")) == 0)
						close(x);

				/* First, look for a message that we should
				** mark as replied */

				while (fp && (header=maildir_readheader(fp,
						&value, 0)) != 0)
				{
					if (strcmp(header,"x-reply-to-folder")
						== 0 && !replytofolder)
					{
						replytofolder=strdup(value);
						if (!replytofolder)
							enomem();
					}
					if (strcmp(header,"x-reply-to-msg")
						== 0 && !replytomsg)
					{
						replytomsg=strdup(value);
						if (!replytomsg)
							enomem();
					}
					if (replytofolder && replytomsg)
						break;
				}
				if (fp)	fclose(fp);

				if (replytofolder && replytomsg)
					maildir_markreplied(replytofolder,
							replytomsg);
				if (replytofolder)	free(replytofolder);
				if (replytomsg)	free(replytomsg);
				
				maildir_quota_deleted(".",
						      -(long)filesize, -1);

				unlink(draftfile);
				free(draftfile);
			}
		}

		tokensave();

		if (*cgi("fcc") == 0)
		{
			unsigned long filesize=0;
			char	*tmpfile=maildir_find(SENT, filename);

			if (tmpfile)
			{
				maildir_parsequota(tmpfile, &filesize);
				unlink(tmpfile);
				maildir_quota_deleted(".", -(long)filesize,-1);
				free(tmpfile);
			}
		}

		free(filename);
		free(draftmessage);
		sendmsg_done();
		return (1);
	}

	if (stat(filename, &stat_buf) == 0)
		maildir_quota_deleted(".", -(long)stat_buf.st_size, -1);
	maildir_msgpurgefile(SENT, filename);
	free(filename);

	{
	char *draftbase=maildir_basename(draftmessage);

		http_redirect_argsss("&form=newmsg&pos=%s&draft=%s&foldermsg=%s",
			cgi("pos"), draftbase, line);
		free(draftmessage);
		free(draftbase);
	}
	return (1);
}
예제 #4
0
파일: fetch.c 프로젝트: MhdAlyan/courier
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);
}