#include "listserv.h"

static char rcsid[] = "$Header: /usr/local/src/mail/listserv/RCS/listsearch.c,v 1.3 92/02/24 12:54:25 andy Exp Locker: andy $";

extern FILE *msg;
extern FILE *mailer;

listsearch(from,command)
char *from,*command;
	{
	FILE *list;
	FILE *listtmp;
	FILE *subslist;
	DIR *listdir;
	struct dirent *entry;
 	struct stat statbuf;	
	char *s, *p;
	char *template = "/tmp/listservXXXXXX";
	char adr[256];
	char tmp[512];
	char request[256];
	char buf[BUFSIZ];
	int i;

	printf("listsearch %s %s \n", from, command);
	i = sscanf(command,"%s%s", request, adr);
	if ((i < 1) || (i > 2))
		sendhelp(from, command);
	if (i == 1)
		strcpy(adr, from);
	cleanup(adr,&i);
	listdir = opendir(SERVDIR);
	if (listdir == NULL)
		{
		perror(SERVDIR);
		exit(1);
		}
	i = mkstemp(template);
	if ( i == -1)
		{
		callmailer(LISTSERVMANAGER, from, "");
		fprintf(mailer,"Error[5] processing request. Please try later.\n");
		fprintf(mailer,">%s\n", command);
		fflush(mailer);
		pclose(mailer);
		return(-1);
		}
	else
		{
		subslist = fdopen(i, "w+");
		if (subslist == NULL)
			{
			callmailer(LISTSERVMANAGER, from, "");
			fprintf(mailer,"Error[5] processing request. Please try later.\n");
			fprintf(mailer,">%s\n", command);
			fflush(mailer);
			pclose(mailer);
			return(-1);
			}
		}

	while (entry = readdir(listdir))	
		{
		if ((index(entry->d_name, '.'))
		|| (isupper(entry->d_name[0])))
			continue;
		sprintf(tmp, "%s/%s", SERVDIR, entry->d_name);
		if (stat(tmp,&statbuf))
			{
			perror(tmp);
			exit(1);
			}
		/*If it's a directory, go to next entry*/
		else if ((statbuf.st_mode & S_IFMT) == S_IFDIR)
			continue;
		/*Skip the restricted access ones*/
		if (access(tmp,R_OK) != 0)
			{
			callmailer(LISTSERVMANAGER, from, "");
			p = rindex(tmp, '/');
			fprintf(mailer,"Unable to access %s\n", p+1);
			fprintf(mailer,">%s\n", command);
			fflush(mailer);
			pclose(mailer);
			continue;
			}
		
		list = fopen(tmp, "r");
		if (list == NULL)
			{
			callmailer(LISTSERVMANAGER, from, "");
			fprintf(mailer,"Error[6] processing request. Please try later.\n");
			fprintf(mailer,">%s\n", command);
			fflush(mailer);
			pclose(mailer);
			return(-1);
			}
     	        flock(fileno(list), LOCK_EX);
		while(fgets(buf, sizeof(buf), list))
			{
			buf[strlen(buf)-1] = '\0';
			if (!strcasecmp(buf, adr))
				{
				fputs(entry->d_name, subslist);
				fputs("\n", subslist);
				}	
			}
		fflush(list);
		flock(fileno(list), LOCK_UN);
		fclose(list);	
		}
	closedir(listdir);
	if (!strcasecmp(request, "delete-all")
	|| !strcasecmp(request, "unsubscribe-all")
	|| !strcasecmp(request, "unsub-all")
	|| !strcasecmp(request, "del-all"))
		{
		rewind(subslist);
		while(fgets(tmp, sizeof(tmp), subslist))
			{
			strcpy(buf, SERVDIR);
			strcat(buf, "/");
			strcat(buf, tmp);
			buf[strlen(buf) -1] = '\0';
			list = fopen(buf, "r");
			if (list == NULL)
				{
				callmailer(LISTSERVMANAGER, from, "");
				fprintf(mailer, "Error[7] processing request. Please try later.\n");				
				fprintf(mailer, ">%s\n", command);
				fflush(mailer);
				pclose(mailer);
				return(-1);
				}
			flock(fileno(list), LOCK_EX);
	
			strcat(buf, ".tmp");
			listtmp = fopen(buf, "w");
			if (listtmp == NULL)
				{
				callmailer(LISTSERVMANAGER, from, "");
				fprintf(mailer,"Error[8] processing request. Please try later.\n");
				fprintf(mailer,">%s\n", command);
				fflush(mailer);
				pclose(mailer);
				return(-1);
				}
			/* copy the list, omitting the one address */
			while (fgets(tmp, sizeof(tmp), list))
				{
				tmp[strlen(tmp)-1] = '\0';
				if (strcasecmp(tmp, adr))
					{
					fputs(tmp, listtmp);
					fputs("\n", listtmp);
					}
				}
			fflush(listtmp);
			fclose(listtmp);

			/* replace the old list with the shortened one */
			strcpy(tmp, buf);
			s = rindex(buf, '.');
			*s = '\0';
			unlink(buf);
			rename(tmp, buf);	/* put updated one in place */
			flock(fileno(list), LOCK_UN);	/* release lock */
			}
		}
#ifndef DEBUG
	if (strcmp(from, adr))
		{
		callmailer(adr, from, command);
		fprintf(mailer,"Per request by %s\n", from);
		}
	else
		{
		callmailer("", from, command);
		fprintf(mailer,"Per your request\n");
		}
#else
	callmailer("", from, command);
	fprintf(mailer,"Per your request\n");

#endif
	fprintf(mailer,"\t\"%s\"\n", command);
	rewind(subslist);
	if ((i = getc(subslist)) == EOF)
		fprintf(mailer, "'%s' is not subscribed to any mailing lists.\n", adr);
	else
		{
		if (strcasecmp(request, "delete-all")
		&& strcasecmp(request, "unsubscribe-all")
		&& strcasecmp(request, "unsub-all")
		&& strcasecmp(request, "del-all"))
			fprintf(mailer,"'%s' is subscribed to the following mailing lists:\n", adr);
		else
			fprintf(mailer,"'%s' was DELETED from the following mailing lists:\n", adr);
		mailcat(template, "\t");
		}
	fflush(mailer);
	pclose(mailer);
	unlink(template);
	fflush(subslist);
	fclose(subslist);
	}


