From 88ffd53dedfd067fd0e7c0fb597a7cb70c44f541 Mon Sep 17 00:00:00 2001 From: Peter Simons Date: Mon, 8 Jan 2001 20:36:19 +0000 Subject: [PATCH] Rewrote Petidomo so that virtually any file's path can be configured at run-time now. --- acl.y | 8 ++-- archive.c | 75 ++++++++++++++++--------------- config.c | 120 +++++++++++++++++++++++++++++++++++++++++++------- help.c | 7 ++- hermes.c | 13 +++--- index.c | 92 ++++---------------------------------- mailer.c | 4 +- main.c | 4 +- members.c | 10 ++--- petidomo.h | 43 ++++++++++++------ subscribe.c | 8 ++-- tool.c | 76 +++++++++++++++++++------------- unsubscribe.c | 5 +-- 13 files changed, 249 insertions(+), 216 deletions(-) diff --git a/acl.y b/acl.y index b6b9ba6..ed72b2c 100644 --- a/acl.y +++ b/acl.y @@ -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; } diff --git a/archive.c b/archive.c index fab31e7..628c567 100644 --- a/archive.c +++ b/archive.c @@ -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; -} + } diff --git a/config.c b/config.c index 56320db..9786356 100644 --- a/config.c +++ b/config.c @@ -20,7 +20,9 @@ #include #include #include +#include +#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; diff --git a/help.c b/help.c index d4dce2e..dcc833e 100644 --- a/help.c +++ b/help.c @@ -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); diff --git a/hermes.c b/hermes.c index d117258..a619686 100644 --- a/hermes.c +++ b/hermes.c @@ -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); diff --git a/index.c b/index.c index 8c972d5..ecdfb4d 100644 --- a/index.c +++ b/index.c @@ -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; } diff --git a/mailer.c b/mailer.c index 4061018..1208773 100644 --- a/mailer.c +++ b/mailer.c @@ -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; diff --git a/main.c b/main.c index 01ecd79..c8e9a4e 100644 --- a/main.c +++ b/main.c @@ -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. */ diff --git a/members.c b/members.c index 47e8b31..96de8d3 100644 --- a/members.c +++ b/members.c @@ -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) { diff --git a/petidomo.h b/petidomo.h index 4ce897e..074ff0e 100644 --- a/petidomo.h +++ b/petidomo.h @@ -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__) */ diff --git a/subscribe.c b/subscribe.c index 2ab8400..1bc50de 100644 --- a/subscribe.c +++ b/subscribe.c @@ -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) { diff --git a/tool.c b/tool.c index fb736d7..17ed4bb 100644 --- a/tool.c +++ b/tool.c @@ -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; -} + } diff --git a/unsubscribe.c b/unsubscribe.c index c1f1d90..66906ab 100644 --- a/unsubscribe.c +++ b/unsubscribe.c @@ -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';