コード例 #1
0
ファイル: dotlock.C プロジェクト: MhdAlyan/courier
int DotLock::attemptlock(const char *templock, const char *finallock)
{
Mio	mio;
Buffer	b;
static Buffer   errbuf;

	if (mio.Open(templock, O_CREAT | O_WRONLY, 0644) < 0)
	{
                errbuf="Unable to create a dot-lock at ";
                errbuf += (const char *)templock;
                errbuf += ".\n";
                errbuf += '\0';
                throw (const char *)errbuf;
	}


	b.append( (unsigned long)getpid() );
	b += '\n';
	if (mio.write((const char *)b, b.Length()) < 0 || mio.flush() < 0)
	{
		mio.Close();
		unlink(templock);
		throw "Unable to write to a dot-lock.";
	}
	mio.Close();
	if (mio.errflag())
	{
		unlink(templock);
		throw "Unable to close a dot-lock.";
	}
	try
	{
	struct	stat	buf;

		if (link(templock, finallock) < 0)
			; /* ignored */

	int	rc=stat(templock, &buf);
		if (rc == 0 && buf.st_nlink == 2)
		{
			name(finallock);
			unlink(templock);
			return (0);
		}
		unlink(templock);
	}
	catch (...)
	{
		unlink(templock);
		throw;
	}
	return (-1);
}
コード例 #2
0
ファイル: deliver.C プロジェクト: MhdAlyan/courier
int delivery(const char *mailbox)
{
FormatMbox	format_mbox;

	if (format_mbox.HasMsg())	return (0);

DeliverDotLock	dotlock;
Buffer	b;

	if ( *mailbox == '!' || *mailbox == '|' )
	{
	Buffer	cmdbuf;

		if (*mailbox == '!')
		{
			b="SENDMAIL";

		const char *sendmail=GetVarStr(b);

			cmdbuf=sendmail;

			cmdbuf += " -f '' ";
			cmdbuf += mailbox+1;
		}
		else
			cmdbuf= mailbox+1;

		cmdbuf += '\0';

		if (VerboseLevel() > 0)
			merr << "maildrop: Delivering to |" <<
				(const char *)cmdbuf << "\n";

	PipeFds	pipe;

		if (pipe.Pipe())
			throw "Cannot create pipe.";

	pid_t	pid=fork();

		if (pid < 0)
			throw "Cannot fork.";

		if (pid == 0)
		{
			pipe.close1();
			dup2(pipe.fds[0], 0);
			pipe.close0();

			try
			{
				subshell(cmdbuf);
			}
			catch (const char *p)
			{
				if (write(2, p, strlen(p)) < 0 ||
				    write(2, "\n", 1) < 0)
					; /* ignored */
				_exit(100);
			}
#if NEED_NONCONST_EXCEPTIONS
			catch (char *p)
			{
				if (write(2, p, strlen(p)) < 0 ||
				    write(2, "\n", 1) < 0)
					; /* ignored */
				_exit(100);
			}
#endif
			catch (...)
			{
				_exit(100);
			}
		}

	Mio	pipemio;

		pipe.close0();
		pipemio.fd(pipe.fds[1]);
		pipe.fds[1]= -1;
		format_mbox.Init(0);

	int	rc=format_mbox.DeliverTo(pipemio);
	int	wait_stat;

		while (wait(&wait_stat) != pid)
			;

		if (wait_stat == 0)
			rc=0;

		log(mailbox, rc || wait_stat, format_mbox);

		{
		Buffer	name, val;

			if (rc)	wait_stat= -1;
			else wait_stat= WIFEXITED(wait_stat)
				? WEXITSTATUS(wait_stat):-1;

			val.append( (unsigned long)wait_stat);
			name="EXITCODE";
			SetVar(name, val);
		}

		if (rc)	return (-1);
	}
	else if (Maildir::IsMaildir(mailbox))
	{
	Maildir	deliver_maildir;
	Mio	deliver_file;

		if ( deliver_maildir.MaildirOpen(mailbox, deliver_file,
			maildrop.msgptr->MessageSize()) < 0)
		{
#if HAVE_COURIER
			throw 75;
#else
			throw 77;
#endif
		}

		format_mbox.Init(0);
		if (format_mbox.DeliverTo(deliver_file))
		{
			log(mailbox, -1, format_mbox);
			return (-1);
		}
		deliver_maildir.MaildirSave();
		log(mailbox, 0, format_mbox);
	}
	else		// Delivering to a mailbox (hopefully)
	{
		if (VerboseLevel() > 0)
			merr << "maildrop: Delivering to " << mailbox << "\n";

#if	USE_DOTLOCK
		dotlock.LockMailbox(mailbox);
#endif

		struct	stat	stat_buf;
		Mio	mio;
		Buffer name_buf;

		name_buf="UMASK";
		const char *um=GetVarStr(name_buf);
		unsigned int umask_val=077;

		sscanf(um, "%o", &umask_val);

		umask_val=umask(umask_val);

		if (mio.Open(mailbox, O_CREAT | O_WRONLY, 0666) < 0)
		{
			umask_val=umask(umask_val);
			throw "Unable to open mailbox.";
		}
		umask_val=umask(umask_val);

		if (fstat(mio.fd(), &stat_buf) < 0)
			throw "Unable to open mailbox.";

#if	USE_FLOCK

		if (VerboseLevel() > 4)
			merr << "maildrop: Flock()ing " << mailbox << ".\n";

		FileLock::do_filelock(mio.fd());
#endif
		if (S_ISREG(stat_buf.st_mode))
		{
			if (mio.seek(0L, SEEK_END) < 0)
				throw "Seek error on mailbox.";
			dotlock.trap_truncate(mio.fd(), stat_buf.st_size);
		}

		if (VerboseLevel() > 4)
			merr << "maildrop: Appending to " << mailbox << ".\n";

		try
		{
			format_mbox.Init(1);

			if ((stat_buf.st_size > 0 &&
			     mio.write(
#if	CRLF_TERM
				       "\r\n", 2
#else
				       "\n", 1
#endif
				       ) < 0) ||
			    format_mbox.DeliverTo(mio))
			{
				dotlock.truncate();
				log(mailbox, -1, format_mbox);
				return (-1);
			}
		}
		catch (...)
		{
			dotlock.truncate();
			log(mailbox, -1, format_mbox);
			throw;
		}
		log(mailbox, 0, format_mbox);
	}

	if (VerboseLevel() > 4)
		merr << "maildrop: Delivery complete.\n";

	return (0);
}