Rewrote Petidomo so that virtually any file's path can be configured

at run-time now.
This commit is contained in:
Peter Simons 2001-01-08 20:36:19 +00:00
parent 81d982c82b
commit 88ffd53ded
13 changed files with 249 additions and 216 deletions

8
acl.y
View File

@ -236,6 +236,7 @@ int checkACL(struct Mail * MailStruct,
int * operation_ptr,
char ** parameter_ptr)
{
const struct PD_Config * MasterConfig;
char * filename;
int rc;
@ -243,6 +244,7 @@ int checkACL(struct Mail * MailStruct,
assert(operation_ptr != NULL);
assert(parameter_ptr != NULL);
MasterConfig = getMasterConfig();
g_MailStruct = MailStruct;
g_parameter = NULL;
@ -253,14 +255,14 @@ int checkACL(struct Mail * MailStruct,
/* First check the mail against the master acl file. */
yyin = fopen("etc/acl", "r");
yyin = fopen(MasterConfig->acl_file, "r");
if (yyin == NULL) {
switch(errno) {
case ENOENT:
/* no master acl file */
goto check_local_acl_file;
default:
syslog(LOG_ERR, "Couldn't open \"~petidomo/etc/acl\" acl file.: %m");
syslog(LOG_ERR, "Couldn't open \"%s\" acl file.: %m", MasterConfig->acl_file);
return -1;
}
}
@ -273,7 +275,7 @@ int checkACL(struct Mail * MailStruct,
yyin = NULL;
}
if (rc != 0) {
syslog(LOG_ERR, "Parsing \"~petidomo/etc/acl\" file returned with an error.");
syslog(LOG_ERR, "Parsing \"%s\" file returned with an error.", MasterConfig->acl_file);
return -1;
}

View File

@ -29,12 +29,11 @@
int
ArchiveMail(const struct Mail * MailStruct, const char * listname)
{
{
const struct List_Config * ListConfig;
struct stat sb;
FILE * fh;
char * filename;
char * path;
u_int counter;
int rc;
struct tm * timeptr;
@ -55,25 +54,17 @@ ArchiveMail(const struct Mail * MailStruct, const char * listname)
/* Sanity checks. */
if (ListConfig->archivepath == NULL)
return 0;
/* Construct the path to the log file or directory. */
if (*(ListConfig->archivepath) == '/')
path = xstrdup(ListConfig->archivepath);
else {
path = text_easy_sprintf("lists/%s/%s", listname, ListConfig->archivepath);
path = xstrdup(path);
}
return 0;
/* Check whether we have a file or a directory. */
if (stat(path, &sb) == 0 && (sb.st_mode & S_IFDIR) != 0) {
if (stat(ListConfig->archivepath, &sb) == 0 && (sb.st_mode & S_IFDIR) != 0)
{
/* Read the "active"-file to see at what article number we
were. */
filename = text_easy_sprintf("%s/.active", path);
filename = text_easy_sprintf("%s/.active", ListConfig->archivepath);
fh = fopen(filename, "r");
if (fh != NULL)
{
@ -90,48 +81,57 @@ ArchiveMail(const struct Mail * MailStruct, const char * listname)
/* Store the article. */
do {
filename = text_easy_sprintf("%s/%u", path, counter);
if (stat(filename, &sb) == -1) {
if (errno == ENOENT) {
do
{
filename = text_easy_sprintf("%s/%u", ListConfig->archivepath, counter);
if (stat(filename, &sb) == -1)
{
if (errno == ENOENT)
{
fh = fopen(filename, "a");
if (fh != NULL) {
if (fh != NULL)
{
fprintf(fh, "From %s-owner@%s %s", listname, ListConfig->fqdn, date);
fprintf(fh, "%s\n", MailStruct->Header);
fprintf(fh, "%s\n", MailStruct->Body);
fclose(fh);
rc = 0;
}
}
else
syslog(LOG_ERR, "Failed opening file \"%s\" for writing: %m", filename);
syslog(LOG_ERR, "Failed opening file \"%s\" for writing: %m", filename);
break;
}
else {
}
else
{
syslog(LOG_ERR, "An error while trying to access the log " \
"directory \"%s\": %m", path);
"directory \"%s\": %m", ListConfig->archivepath);
break;
}
}
}
} while (++counter); /* until break */
while (++counter); /* until break */
/* Write the current "active" number back to the file. */
counter++;
filename = text_easy_sprintf("%s/.active", path);
filename = text_easy_sprintf("%s/.active", ListConfig->archivepath);
fh = fopen(filename, "w");
if (fh != NULL) {
if (fh != NULL)
{
fprintf(fh, "%u", counter);
fclose(fh);
}
}
else
syslog(LOG_ERR, "Failed to write to file \"%s\": %m", filename);
}
else {
syslog(LOG_ERR, "Failed to write to file \"%s\": %m", filename);
}
else
{
/* Simply append the article to this file. */
fh = fopen(path, "a");
if (fh != NULL) {
fh = fopen(ListConfig->archivepath, "a");
if (fh != NULL)
{
/* Write an envelope first. */
fprintf(fh, "From %s-owner@%s %s", listname, ListConfig->fqdn, date);
@ -139,11 +139,10 @@ ArchiveMail(const struct Mail * MailStruct, const char * listname)
fprintf(fh, "%s\n", MailStruct->Body);
fclose(fh);
rc = 0;
}
}
else
syslog(LOG_ERR, "Failed opening file \"%s\" for writing: %m", path);
}
syslog(LOG_ERR, "Failed opening file \"%s\" for writing: %m", ListConfig->archivepath);
}
free(path);
return rc;
}
}

120
config.c
View File

@ -20,7 +20,9 @@
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/stat.h>
#include "libtext/text.h"
#include "liblists/lists.h"
#include "libconfigfile/configfile.h"
#include "petidomo.h"
@ -33,8 +35,12 @@ List ListConfigs;
static char* fqdn = NULL;
static char* master_password = NULL;
static char* mta = "/usr/sbin/sendmail";
static char* mta = NULL;
static char* mta_options = "-i -f%s";
static char* help_file = DATADIR "/petidomo.conf";
static char* acl_file = SYSCONFDIR "/petidomo.acl";
static char* index_file = LOCALSTATEDIR "/index";
static char* list_dir = LOCALSTATEDIR;
int InitPetidomo(const char* masterconfig_path)
{
@ -48,6 +54,10 @@ int InitPetidomo(const char* masterconfig_path)
{ "AdminPassword", CF_STRING, &master_password },
{ "MTA", CF_STRING, &mta },
{ "MTA_Options", CF_STRING, &mta_options },
{ "Help_File", CF_STRING, &help_file },
{ "Acl_File", CF_STRING, &acl_file },
{ "Index_File", CF_STRING, &index_file },
{ "List_Directory", CF_STRING, &list_dir },
{ NULL, 0, NULL}
};
@ -80,6 +90,11 @@ int InitPetidomo(const char* masterconfig_path)
syslog(LOG_ERR, "The master config file \"%s\" doesn't set the host name.", masterconfig_path);
return -1;
}
if (mta == NULL)
{
syslog(LOG_ERR, "The master config file \"%s\" doesn't set the MTA.", masterconfig_path);
return -1;
}
if (master_password == NULL)
{
syslog(LOG_ERR, "The master config file \"%s\" doesn't set the admin password.", masterconfig_path);
@ -97,6 +112,10 @@ int InitPetidomo(const char* masterconfig_path)
MasterConfig->master_password = master_password;
MasterConfig->mta = mta;
MasterConfig->mta_options = mta_options;
MasterConfig->help_file = help_file;
MasterConfig->acl_file = acl_file;
MasterConfig->index_file = index_file;
MasterConfig->list_dir = list_dir;
return 0;
}
@ -107,17 +126,22 @@ const struct PD_Config* getMasterConfig(void)
}
static char* list_fqdn = NULL;
static char* admin_password = NULL;
static char* posting_password = NULL;
static char* listtype = NULL;
static char* reply_to = NULL;
static char* postingfilter = NULL;
static char* archivepath = NULL;
static bool allowpubsub = TRUE;
static bool allowaliensub = TRUE;
static bool allowmembers = FALSE;
static bool showonindex = TRUE;
static char* list_fqdn;
static char* admin_password;
static char* posting_password;
static char* listtype;
static char* reply_to;
static char* postingfilter;
static char* archivepath;
static bool allowpubsub;
static bool allowaliensub;
static bool allowmembers;
static char* intro_file;
static char* sig_file;
static char* desc_file;
static char* header_file;
static char* list_acl_file;
static char* address_file;
const struct List_Config* getListConfig(const char * listname)
{
@ -125,7 +149,9 @@ const struct List_Config* getListConfig(const char * listname)
struct List_Config * ListConfig;
Node node;
int rc;
char buffer[4096];
char * buffer;
struct stat sb;
char* list_dir;
/* Format description of our global config file. */
@ -135,16 +161,40 @@ const struct List_Config* getListConfig(const char * listname)
{ "AllowPublicSubscription", CF_YES_NO, &allowpubsub },
{ "AllowAlienSubscription", CF_YES_NO, &allowaliensub },
{ "AllowMembersCommand", CF_YES_NO, &allowmembers },
{ "ShowOnIndex", CF_YES_NO, &showonindex },
{ "ReplyTo", CF_STRING, &reply_to },
{ "Hostname", CF_STRING, &list_fqdn },
{ "AdminPassword", CF_STRING, &admin_password },
{ "PostingPassword", CF_STRING, &posting_password },
{ "PostingFilter", CF_STRING, &postingfilter },
{ "Archive", CF_STRING, &archivepath },
{ "IntroductionFile", CF_STRING, &intro_file },
{ "SignatureFile", CF_STRING, &sig_file },
{ "DescriptionFile", CF_STRING, &desc_file },
{ "HeaderFile", CF_STRING, &header_file },
{ "ListACLFile", CF_STRING, &list_acl_file },
{ "AddressFile", CF_STRING, &address_file },
{ NULL, 0, NULL}
};
/* Set the defaults. */
list_fqdn = NULL;
admin_password = NULL;
posting_password = NULL;
listtype = NULL;
reply_to = NULL;
postingfilter = NULL;
archivepath = NULL;
allowpubsub = TRUE;
allowaliensub = TRUE;
allowmembers = FALSE;
intro_file = "introduction";
sig_file = "signature";
desc_file = "description";
header_file = "header";
list_acl_file = "acl";
address_file = "list";
/* Get the master configuration. */
MasterConfig = getMasterConfig();
@ -157,7 +207,19 @@ const struct List_Config* getListConfig(const char * listname)
/* No? Then read the config file. */
sprintf(buffer, "lists/%s/config", listname);
buffer = text_easy_sprintf("%s/%s/config", MasterConfig->list_dir, listname);
list_dir = text_easy_sprintf("%s/%s", MasterConfig->list_dir, listname);
if (stat(buffer, &sb) != 0)
{
free(buffer);
buffer = text_easy_sprintf("%s/%s.config", MasterConfig->list_dir, listname);
list_dir = MasterConfig->list_dir;
if (stat(buffer, &sb) != 0)
{
syslog(LOG_ERR, "Can't find a config file for list \"%s\".", listname);
exit(1);
}
}
rc = ReadConfig(buffer, ListCF);
if (rc != 0)
{
@ -195,7 +257,6 @@ const struct List_Config* getListConfig(const char * listname)
ListConfig->allowpubsub = allowpubsub;
ListConfig->allowaliensub = allowaliensub;
ListConfig->allowmembers = allowmembers;
ListConfig->showonindex = showonindex;
ListConfig->fqdn = (list_fqdn) ? list_fqdn : MasterConfig->fqdn;
ListConfig->reply_to = reply_to;
if (reply_to != NULL && strcasecmp(reply_to, "none"))
@ -203,7 +264,32 @@ const struct List_Config* getListConfig(const char * listname)
ListConfig->admin_password = admin_password;
ListConfig->posting_password = posting_password;
ListConfig->postingfilter = postingfilter;
ListConfig->archivepath = archivepath;
ListConfig->list_dir = list_dir;
#define EXPAND(dst, src) \
if (src == NULL || src[0] == '/') \
ListConfig->dst = src; \
else \
ListConfig->dst = text_easy_sprintf("%s/%s", ListConfig->list_dir, src);
EXPAND(archivepath, archivepath);
EXPAND(intro_file, intro_file);
EXPAND(desc_file, desc_file);
EXPAND(sig_file, sig_file);
EXPAND(header_file, header_file);
EXPAND(acl_file, list_acl_file);
EXPAND(address_file, address_file);
printf("archivepath: %s\n", ListConfig->archivepath);
printf("intro_file: %s\n", ListConfig->intro_file);
printf("desc_file: %s\n", ListConfig->desc_file);
printf("sig_file: %s\n", ListConfig->sig_file);
printf("header_file: %s\n", ListConfig->header_file);
printf("acl_file: %s\n", ListConfig->acl_file);
printf("address_file: %s\n", ListConfig->address_file);
AppendNode(ListConfigs, xstrdup(listname), ListConfig);
return ListConfig;

7
help.c
View File

@ -67,8 +67,7 @@ SendHelp(struct Mail * MailStruct,
fprintf(fh, "Sender: %s\n", envelope);
fprintf(fh, "\n");
fprintf(fh, "Description of list \"%s\":\n\n", param1);
buffer = text_easy_sprintf("lists/%s/description", param1);
p = loadfile(buffer);
p = loadfile(ListConfig->desc_file);
if (p != NULL) {
fprintf(fh, "%s\n", p);
free(p);
@ -136,7 +135,7 @@ SendHelp(struct Mail * MailStruct,
fprintf(fh, "Precedence: junk\n");
fprintf(fh, "Sender: %s\n", envelope);
fprintf(fh, "\n");
p = loadfile("etc/help");
p = loadfile(MasterConfig->help_file);
if (p != NULL) {
fprintf(fh, "%s\n", p);
free(p);
@ -192,7 +191,7 @@ Indecipherable(struct Mail * MailStruct, const char * defaultlist)
fprintf(fh, "Precedence: junk\n");
fprintf(fh, "Sender: %s\n", envelope);
fprintf(fh, "\n");
p = loadfile("etc/help");
p = loadfile(MasterConfig->help_file);
if (p != NULL) {
fprintf(fh, "%s\n", p);
free(p);

View File

@ -235,12 +235,11 @@ hermes_main(char * incoming_mail, const char * listname)
dst += len;
*dst = '\0';
/* Add custom headers if there are some. */
/* Add custom headers if there are any. */
buffer = text_easy_sprintf("lists/%s/header", listname);
if (stat(buffer, &sb) == 0)
if (stat(ListConfig->header_file, &sb) == 0)
{
char* p = loadfile(buffer);
char* p = loadfile(ListConfig->header_file);
if (p == NULL)
{
syslog(LOG_ERR, "Failed reading the header file for list \"%s\".", listname);
@ -249,14 +248,12 @@ hermes_main(char * incoming_mail, const char * listname)
strcpy(dst, p);
dst += strlen(p);
free(p);
free(buffer);
}
/* Add the signature if there is one. */
buffer = text_easy_sprintf("lists/%s/signature", listname);
if (stat(buffer, &sb) == 0) {
buffer = loadfile(buffer);
if (stat(ListConfig->sig_file, &sb) == 0) {
buffer = loadfile(ListConfig->sig_file);
if (buffer == NULL) {
syslog(LOG_ERR, "Failed reading the signature file for list \"%s\".", listname);
exit(1);

92
index.c
View File

@ -32,18 +32,11 @@ GenIndex(struct Mail * MailStruct,
const char * defaultlist)
{
const struct PD_Config * MasterConfig = getMasterConfig();
const struct List_Config * ListConfig;
FILE * fh;
const char * address = NULL;
char from[4096];
char envelope[4096];
char * description;
char * currLine;
char * nextLine;
char * buffer;
DIR * dirp;
struct dirent * entry;
unsigned int entry_num;
char * p;
address = (MailStruct->Reply_To) ? MailStruct->Reply_To : MailStruct->From;
@ -71,84 +64,17 @@ GenIndex(struct Mail * MailStruct,
fprintf(fh, "Precedence: junk\n");
fprintf(fh, "Sender: %s\n", envelope);
fprintf(fh, "\n");
fprintf(fh, "Index of available lists:\n");
fprintf(fh, "=========================\n\n");
/* Scan the directory. */
entry_num = 0;
dirp = opendir("lists");
if (dirp == NULL) {
fprintf(fh, \
"An internal error has occured while processing your request. The\n" \
"server administrator has been notified. You don't need to re-submit\n" \
"your request, it will be processed as soon as the problem has been\n" \
"remedied.\n");
CloseMailer(fh);
syslog(LOG_ERR, "Failed to read directory \"lists\": %m");
return -1;
}
while((entry = readdir(dirp)) != NULL) {
if (!strcasecmp(entry->d_name, ".") || !strcasecmp(entry->d_name, ".."))
continue;
if (isValidListName(entry->d_name) == FALSE)
continue;
ListConfig = getListConfig(entry->d_name);
if (ListConfig->showonindex == FALSE)
continue;
entry_num++;
/* Print stuff to the mail. */
fprintf(fh, "%s", entry->d_name);
p = loadfile(MasterConfig->index_file);
if (p != NULL)
{
int i;
i = 40 - strlen(entry->d_name);
if (i < 1)
i = 1;
while(i-- > 0)
fputc(' ', fh);
fprintf(fh, "%s\n", p);
free(p);
}
if (ListConfig->allowpubsub == TRUE) {
if (ListConfig->listtype == LIST_MODERATED)
fprintf(fh, "(moderated mailing list)\n");
else
fprintf(fh, "(public mailing list)\n");
else
{
syslog(LOG_ERR, "There is no index file for Petidomo!");
fprintf(fh, "No index available.\n");
}
else
fprintf(fh, "(closed mailing list)\n");
buffer = text_easy_sprintf("lists/%s/description", entry->d_name);
description = loadfile(buffer);
if (description == NULL) {
fprintf(fh, " no description available\n\n");
continue;
}
for (currLine = description; *currLine != '\0'; currLine = nextLine) {
nextLine = text_find_next_line(currLine);
if (nextLine[-1] == '\n')
nextLine[-1] = '\0';
fprintf(fh, " %s\n", currLine);
}
fprintf(fh, "\n");
free(description);
}
closedir(dirp);
switch (entry_num) {
case 0:
fprintf(fh, "No mailing lists found.\n");
break;
case 1:
fprintf(fh, "Found %d mailing list.\n", entry_num);
break;
default:
fprintf(fh, "Found %d mailing lists.\n", entry_num);
}
CloseMailer(fh);
return 0;
}

View File

@ -141,6 +141,7 @@ int
ListMail(const char * envelope, const char * listname, const struct Mail * MailStruct)
{
const struct PD_Config * MasterConfig = getMasterConfig();
const struct List_Config * ListConfig = getListConfig(listname);
char ** arguments;
u_int arguments_num = 256;
char buffer[256];
@ -164,8 +165,7 @@ ListMail(const char * envelope, const char * listname, const struct Mail * MailS
/* Load the list of recipients. */
sprintf(buffer, "lists/%s/list", listname);
listfile = loadfile(buffer);
listfile = loadfile(ListConfig->address_file);
if (listfile == NULL)
return 1;

4
main.c
View File

@ -42,8 +42,8 @@ main(int argc, char * argv[])
argv_t args[] =
{
{ARGV_MAND, "mode", ARGV_CHAR_P, &mode, "mode", "listserv, deliver, or approve."},
{ARGV_MAYBE, "listname", ARGV_CHAR_P, &listname, "listname", "Default mailing list."},
{ARGV_MAYBE, "masterconf", ARGV_CHAR_P, &masterconfig_path, "masterconf", "Path to petidomo.conf."},
{ARGV_MAYBE, 0L, ARGV_CHAR_P, &listname, "listname", "Default mailing list."},
{ARGV_LAST}
};
@ -66,8 +66,6 @@ main(int argc, char * argv[])
}
MasterConfig = getMasterConfig();
return 0;
/* Load the file from standard input and save it, so that it isn't
lost in case of an error. */

View File

@ -99,12 +99,12 @@ SendSubscriberList(struct Mail * MailStruct,
/* Okay, send the address list back. */
buffer = text_easy_sprintf("lists/%s/list", listname);
buffer = loadfile(buffer);
if (buffer == NULL) {
syslog(LOG_ERR, "Failed to open file \"~petidomo/lists/%s/list\"", listname);
buffer = loadfile(ListConfig->address_file);
if (buffer == NULL)
{
syslog(LOG_ERR, "Failed to open file \"%s\"", ListConfig->address_file);
return -1;
}
}
fh = vOpenMailer(envelope, address, NULL);
if (fh != NULL) {

View File

@ -50,32 +50,45 @@
/********** config.c **********/
struct PD_Config {
struct PD_Config
{
char * fqdn;
char * master_password;
char * mta;
char * mta_options;
};
char * list_dir;
char * help_file;
char * acl_file;
char * index_file;
};
enum {
enum
{
LIST_OPEN,
LIST_CLOSED,
LIST_MODERATED
};
};
struct List_Config {
struct List_Config
{
unsigned int listtype;
int allowpubsub;
int allowaliensub;
int allowmembers;
int showonindex;
char * fqdn;
char * admin_password;
char * posting_password;
char * postingfilter;
char * archivepath;
char * reply_to;
};
char * intro_file;
char * desc_file;
char * sig_file;
char * header_file;
char * acl_file;
char * list_dir;
char * address_file;
};
int InitPetidomo(const char* masterconfig_path);
const struct PD_Config *getMasterConfig(void);
@ -83,7 +96,8 @@ const struct List_Config *getListConfig(const char* listname);
/********** rfcparse.c **********/
struct Mail {
struct Mail
{
char * Header;
char * Body;
char * Envelope;
@ -93,7 +107,7 @@ struct Mail {
char * Message_Id;
char * Approve;
char * ListSignature;
};
};
void RemoveCarrigeReturns(char *buffer);
int isRFC822Address(const char *buffer);
@ -128,8 +142,8 @@ int MailFilter(struct Mail *MailStruct, const char *filter);
/********** acl.c **********/
int checkACL(struct Mail *, const char *, int *, char **);
enum {
enum
{
ACL_DROP,
ACL_PASS,
ACL_REDIRECT,
@ -138,7 +152,7 @@ enum {
ACL_REJECTWITH,
ACL_FILTER,
ACL_NONE
};
};
/********** handleacl.c **********/
@ -199,10 +213,11 @@ int AddAddress(struct Mail *MailStruct, const char *param1, const char *param2,
/********** parsearray.c **********/
struct Parse {
struct Parse
{
const char * keyword;
int (*handleCommand)(struct Mail *, const char *, const char *, const char *);
};
};
extern struct Parse ParseArray[];
#endif /* !defined(__PETIDOMO_H__) */

View File

@ -231,10 +231,9 @@ AddAddress(struct Mail * MailStruct,
/* Okay, add the address to the list. */
buffer = text_easy_sprintf("lists/%s/list", listname);
fh = fopen(buffer, "a");
fh = fopen(ListConfig->address_file, "a");
if (fh == NULL) {
syslog(LOG_ERR, "Failed to open file \"%s\" for writing: %m", buffer);
syslog(LOG_ERR, "Failed to open file \"%s\" for writing: %m", ListConfig->address_file);
return -1;
}
fprintf(fh, "%s\n", address);
@ -289,8 +288,7 @@ AddAddress(struct Mail * MailStruct,
/* Send introduction text to the new member. */
buffer = text_easy_sprintf("lists/%s/introduction", listname);
p = loadfile(buffer);
p = loadfile(ListConfig->intro_file);
if (p != NULL) {
fh = vOpenMailer(envelope, address, NULL);
if (fh != NULL) {

76
tool.c
View File

@ -28,40 +28,50 @@
bool
isSubscribed(const char * listname, const char * address,
char ** listfile, char ** subscriber, bool dofuzzy)
{
{
const struct List_Config * ListConfig;
struct stat sb;
char * buffer;
char * list;
char * p;
unsigned int len;
bool rc;
bool rc;
buffer = text_easy_sprintf("lists/%s/list", listname);
if (stat(buffer, &sb) != 0)
return FALSE;
list = loadfile(buffer);
if (isValidListName(listname))
ListConfig = getListConfig(listname);
else
return FALSE;
if (stat(ListConfig->address_file, &sb) != 0)
return FALSE;
list = loadfile(ListConfig->address_file);
if (list == NULL)
return FALSE;
return FALSE;
for (len = strlen(address), p = list; *p != '\0'; p = text_find_next_line(p)) {
for (len = strlen(address), p = list; *p != '\0'; p = text_find_next_line(p))
{
if (strncasecmp(p, address, len) == 0 &&
(p == list || p[-1] == '\n') &&
(isspace((int)p[len]) || p[len] == '\0')) {
(isspace((int)p[len]) || p[len] == '\0'))
{
break;
}
}
}
if (*p == '\0' && dofuzzy == TRUE) {
if (*p == '\0' && dofuzzy == TRUE)
{
address = buildFuzzyMatchAddress(address);
if (address != NULL) {
for (len = strlen(address), p = list; *p != '\0'; p = text_find_next_line(p)) {
if (address != NULL)
{
for (len = strlen(address), p = list; *p != '\0'; p = text_find_next_line(p))
{
if (text_easy_pattern_match(p, address) == TRUE &&
(p == list || p[-1] == '\n')) {
(p == list || p[-1] == '\n'))
{
break;
}
}
}
}
}
/* Save the returncode now, because p may be invalid in a few
@ -71,18 +81,19 @@ isSubscribed(const char * listname, const char * address,
/* Did the caller want results back? Then give them to him. */
if (listfile != NULL) {
if (listfile != NULL)
{
*listfile = list;
if (subscriber != NULL)
*subscriber = (*p != '\0') ? p : NULL;
}
*subscriber = (*p != '\0') ? p : NULL;
}
else
free(list);
free(list);
/* Return the result. */
return rc;
}
}
char *
buildFuzzyMatchAddress(const char * address)
@ -118,24 +129,27 @@ buildFuzzyMatchAddress(const char * address)
bool
isValidListName(const char * listname)
{
{
struct stat sb;
char * buffer;
const struct PD_Config * MasterConfig = getMasterConfig();
assert(listname != NULL);
if ((strchr(listname, '/') != NULL) || (strchr(listname, ':') != NULL))
return FALSE;
buffer = text_easy_sprintf("lists/%s", listname);
buffer = text_easy_sprintf("%s/%s/config", MasterConfig->list_dir, listname);
if (stat(buffer, &sb) != 0)
return FALSE; /* Doesn't exist at all. */
else if ((sb.st_mode & S_IFDIR) == 0)
return FALSE; /* Entry isn't a directory. */
else {
buffer = text_easy_sprintf("lists/%s/config", listname);
{
free(buffer);
buffer = text_easy_sprintf("%s/%s.config", MasterConfig->list_dir, listname);
if (stat(buffer, &sb) != 0)
return FALSE;
}
{
free(buffer);
return FALSE;
}
}
free(buffer);
return TRUE;
}
}

View File

@ -230,10 +230,9 @@ DeleteAddress(struct Mail * MailStruct,
}
}
else {
buffer = text_easy_sprintf("lists/%s/list", listname);
fh = fopen(buffer, "w");
fh = fopen(ListConfig->address_file, "w");
if (fh == NULL) {
syslog(LOG_ERR, "Failed to open file \"%s\" for writing: %m", buffer);
syslog(LOG_ERR, "Failed to open file \"%s\" for writing: %m", ListConfig->address_file);
return -1;
}
*p++ = '\0';