/*
* Remote mail executor <venglin@FreeBSD.lublin.pl>
*
* Use it, if you want to execute via mail some commands. It performs
* simple password test. Add it to .forward (or .qmail).
*
* Usage (qmail): |mailex
* Add your password to $HOME/.mailex-passwd
*
* Mail command: <passwd> <command to execute>
*               <passwd> <another command to execute>
*
* $Log: mailex.c,v $
* Revision 1.1.1.1  2001/05/21 15:38:58  venglin
* initial import into CVS
*
* Revision 1.6  2000/01/30 14:40:17  venglin
* Documentation errata.
*
* Revision 1.5  2000/01/30 14:39:09  venglin
* Better parsing.
*
* Revision 1.4  1999/10/09 19:39:50  venglin
* Yet another improvement.
*
* Revision 1.3  1999/10/09 19:12:45  venglin
* Many improvements!
*
* Revision 1.2  1999/08/13 20:29:48  venglin
* Visible password (ps) were insecure
*
* Revision 1.1  1999/08/13 19:58:10  venglin
* Initial revision
*
*/

#include <sys/param.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pwd.h>
#include <time.h>
#include <syslog.h>
#include <errno.h>
#include <unistd.h>
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <paths.h>

#define	MAXLINE	1024
#define LF	10
#define CR	13
#define SPC	32
#define CONFIG	".mailex-passwd"
#define MAIL	"/usr/sbin/sendmail -oem -t"

static const char rcsid[] =
   "$Id: mailex.c,v 1.1.1.1 2001/05/21 15:38:58 venglin Exp $";

char *firstnonblank(s)
char *s;
{
	char *p;
	
	for (p = s;*p && isblank(*p);p++);

	return p;
}  

void stripnewline(s)
char *s;
{
        char *p;
 
        if (p = index(s, CR))
                *p = '\0';
        if (p = index(s, LF))
                *p = '\0';
 
        return;
}

void parse(buf, passwd, from)
char *buf, *passwd, *from;
{
	char tmp[MAXLINE], *p, *q;
	FILE *sendmail, *comm;

	stripnewline(buf);
	p = firstnonblank(buf);

	for (q = tmp;(*p && (!isblank(*p)));*q++ = *p++);
	*q = '\0';

	printf("Using From: %s\n", from);

	if (!strcmp(tmp, passwd))
	{
		p = firstnonblank(p);

		if (from)
		{
			sendmail = popen(MAIL, "w");

			if (!sendmail)
			{
				perror("popen()");
				exit(-1);
			}

			fprintf(sendmail, "To: %s\n", from);
			fprintf(sendmail, "Subject: mailex report\n\n");

			comm = popen(p, "r");

			if (!comm)
			{
				perror("popen()");
				exit(-1);
			}

			while (fgets(buf, sizeof(buf), comm))
				fprintf(sendmail, "%s", buf);

			pclose(sendmail);
			pclose(comm);
		}
		else
			system(p);
	}

	return;
}

int main(argc, argv)
int argc;
char **argv;
{
	char buf[MAXLINE], passwd[MAXLINE], *from = NULL, *h, *path, *p;
	FILE *phile;

	h = getenv("HOME");
	path = (char *)malloc(strlen(h)+strlen(CONFIG)+1);

	if (!path)
	{
		perror("malloc()");
		exit(-1);
	}

	sprintf(path, "%s/%s", h, CONFIG);  

	if ((phile=fopen(path, "r")) == NULL)
	{
		perror("fopen()");
		exit(-1);
	}
        
	fgets(passwd, sizeof(passwd), phile);
	stripnewline(passwd);

	fclose(phile);
	free(path);

	while (fgets(buf, sizeof(buf), stdin) && *buf != CR && *buf != LF)
	{
		stripnewline(buf);

		if (argc < 2)
		{
			if (!strncmp(buf, "From: ", 6))
			{

				p = firstnonblank(buf+6);
				from = strdup(p);

				if (!from)
				{
					perror("malloc()");
					exit(-1);
				}

			}
		}
	}

	if (argc > 1)
	{
		from = strdup(argv[1]);
		if (!from)
		{
			perror("malloc()");
			return -1;
		}
	}

	while(fgets(buf, sizeof(buf), stdin) != NULL)
		parse(buf, passwd, from);

	exit(0);
}

