OSSP CVS Repository

ossp - Check-in [197]
Not logged in
[Honeypot]  [Browse]  [Home]  [Login]  [Reports
[Search]  [Ticket]  [Timeline
  [Patchset]  [Tagging/Branching

Check-in Number: 197
Date: 2000-Dec-12 14:19:22 (local)
2000-Dec-12 13:19:22 (UTC)
User:simons
Branch:
Comment: Initial revision
Tickets:
Inspections:
Files:
ossp-pkg/petidomo/acl.y      added-> 1.1
ossp-pkg/petidomo/acl_scan.l      added-> 1.1
ossp-pkg/petidomo/archive.c      added-> 1.1
ossp-pkg/petidomo/authen.c      added-> 1.1
ossp-pkg/petidomo/config.c      added-> 1.1

ossp-pkg/petidomo/acl.y -> 1.1

*** /dev/null    Sat Nov 23 01:13:20 2024
--- -    Sat Nov 23 01:13:38 2024
***************
*** 0 ****
--- 1,326 ----
+ /*
+  *      $Source: /v/ossp/cvs/ossp-pkg/petidomo/acl.y,v $
+  *      $Revision: 1.1 $
+  *      $Date: 2000/12/13 13:19:22 $
+  *
+  *      Copyright (C) 1997 by CyberSolutions GmbH.
+  *      All rights reserved.
+  */
+ 
+ %{
+         /* Definitions we need in the parser. */
+ 
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include <sys/wait.h>
+ #include <errno.h>
+ 
+ #include <text.h>
+ #include <petidomo.h>
+ 
+ static int yyerror(char *);
+ static int yylex(void);
+ static int domatch(int, int, char *);
+ static int dofilter(const char *);
+ 
+ unsigned int lineno;
+ int operation, g_rc;
+ char * g_parameter = NULL;
+ struct Mail * g_MailStruct;
+ 
+ #include "acl_scan.c"
+ 
+ #define YYERROR_VERBOSE
+ %}
+ %token TOK_IF TOK_EQUAL TOK_EQUAL TOK_FROM TOK_SUBJECT
+ %token TOK_ENVELOPE TOK_HEADER TOK_BODY TOK_AND TOK_OR TOK_NOT
+ %token TOK_THEN TOK_MATCH TOK_STRING TOK_DROP TOK_PASS
+ %token TOK_REDIRECT TOK_FORWARD TOK_REJECT TOK_REJECTWITH
+ %token TOK_FILTER
+ %left TOK_AND
+ %left TOK_OR
+ %right TOK_NOT
+ %%
+ 
+ input:    /* empty */
+         | input statmt
+ ;
+ 
+ statmt:   ';'
+         | TOK_IF exp TOK_THEN action ';'  { if ($2 == TRUE) {
+                                                  operation = $4;
+                                                  YYACCEPT;
+                                             }
+                                           }
+ ;
+ 
+ exp:      qualifier TOK_EQUAL TOK_STRING  {
+                                             g_rc = domatch($1, TOK_EQUAL, yytext);
+                                             if (g_rc == -1)
+                                                YYABORT;
+                                             $$ = g_rc;
+                                           }
+         | qualifier TOK_MATCH TOK_STRING  {
+                                             g_rc = domatch($1, TOK_MATCH, yytext);
+                                             if (g_rc == -1)
+                                                YYABORT;
+                                             $$ = g_rc;
+                                           }
+         | TOK_STRING                      {
+                                             g_rc = dofilter(yytext);
+                                             if (g_rc == -1)
+                                                YYABORT;
+                                             $$ = g_rc;
+                                           }
+         | exp TOK_OR exp                  { $$ = $1 || $3; }
+         | exp TOK_AND exp                 { $$ = $1 && $3; }
+         | TOK_NOT exp                     { $$ = ! $2; }
+         | '(' exp ')'                     { $$ = $2; }
+ ;
+ 
+ qualifier: TOK_FROM                       { $$ = TOK_FROM; }
+         | TOK_SUBJECT                     { $$ = TOK_SUBJECT; }
+         | TOK_ENVELOPE                    { $$ = TOK_ENVELOPE; }
+         | TOK_HEADER                      { $$ = TOK_HEADER; }
+         | TOK_BODY                        { $$ = TOK_BODY; }
+ ;
+ 
+ action:   TOK_PASS                        { $$ = ACL_PASS; }
+         | TOK_DROP                        { $$ = ACL_DROP; }
+         | TOK_REJECT                      { $$ = ACL_REJECT; }
+         | TOK_REJECTWITH TOK_STRING       {
+                                             $$ = ACL_REJECTWITH;
+                                             if (g_parameter != NULL)
+                                               free(g_parameter);
+                                             g_parameter = strdup(yytext);
+                                             if (g_parameter == NULL)
+                                               YYABORT;
+                                           }
+         | TOK_REDIRECT TOK_STRING         {
+                                             $$ = ACL_REDIRECT;
+                                             if (g_parameter != NULL)
+                                               free(g_parameter);
+                                             g_parameter = strdup(yytext);
+                                             if (g_parameter == NULL)
+                                               YYABORT;
+                                           }
+         | TOK_FORWARD TOK_STRING          {
+                                             $$ = ACL_FORWARD;
+                                             if (g_parameter != NULL)
+                                               free(g_parameter);
+                                             g_parameter = strdup(yytext);
+                                             if (g_parameter == NULL)
+                                               YYABORT;
+                                           }
+         | TOK_FILTER TOK_STRING           {
+                                             $$ = ACL_FILTER;
+                                             if (g_parameter != NULL)
+                                               free(g_parameter);
+                                             g_parameter = strdup(yytext);
+                                             if (g_parameter == NULL)
+                                               YYABORT;
+                                           }
+ ;
+ %%
+ /***** internal routines *****/
+ 
+ int
+ yywrap(void)
+ {
+     return 1;
+ }
+ 
+ static int
+ yyerror(char * string)
+ {
+     syslog(LOG_ERR, "Syntax error in line %u: %s\n", lineno, string);
+     return 0;
+ }
+ 
+ 
+ static int
+ dofilter(const char * filter)
+ {
+     FILE *  fh;
+     int     rc;
+ 
+     debug((DEBUG_ACL, 2, "Starting ACL-filter \"%s\".", filter));
+     fh = popen(filter, "w");
+     if (fh == NULL) {
+         syslog(LOG_ERR, "Failed to open ACL-filter \"%s\": %m", filter);
+         return -1;
+     }
+     fprintf(fh, "%s\n", g_MailStruct->Header);
+     fprintf(fh, "%s", g_MailStruct->Body);
+     rc = pclose(fh);
+ 
+     if (!WIFEXITED(rc))
+       return -1;
+ 
+     rc = WEXITSTATUS(rc);
+     switch(rc) {
+       case 0:
+           debug((DEBUG_ACL, 2, "Filter returned %d (TRUE).", rc));
+           return TRUE;
+       case 1:
+           debug((DEBUG_ACL, 2, "Filter returned %d (FALSE).", rc));
+           return FALSE;
+       default:
+           syslog(LOG_ERR, "ACL-filter \"%s\" returned unexpected value %d.", filter, rc);
+           return -1;
+     }
+ }
+ 
+ 
+ static int
+ domatch(int qualifier, int oper, char * string)
+ {
+     char *   left;
+ 
+     switch(qualifier) {
+       case TOK_FROM:
+           left = g_MailStruct->From;
+           break;
+       case TOK_SUBJECT:
+           left = g_MailStruct->Subject;
+           break;
+       case TOK_ENVELOPE:
+           left = g_MailStruct->Envelope;
+           break;
+       case TOK_HEADER:
+           left = g_MailStruct->Header;
+           break;
+       case TOK_BODY:
+           left = g_MailStruct->Body;
+           break;
+       default:
+           syslog(LOG_CRIT, "Internal error in the ACL parser. Unknown qualifier %d.",
+               qualifier);
+           return -1;
+     }
+ 
+     switch(oper) {
+       case TOK_EQUAL:
+           if (left != NULL && strcasecmp(left, string) == 0) {
+               debug((DEBUG_ACL, 1, "ACL: \"%s\" == \"%s\" == TRUE", left, string));
+               return TRUE;
+           }
+           else {
+               debug((DEBUG_ACL, 1, "ACL: \"%s\" == \"%s\" == FALSE", left, string));
+               return FALSE;
+           }
+       case TOK_MATCH:
+           if (left != NULL && text_easy_pattern_match(left, string) == TRUE) {
+               debug((DEBUG_ACL, 1, "ACL: \"%s\" match \"%s\" == TRUE", left, string));
+               return TRUE;
+           }
+           else {
+               debug((DEBUG_ACL, 1, "ACL: \"%s\" match \"%s\" == FALSE", left, string));
+               return FALSE;
+           }
+       default:
+           syslog(LOG_CRIT, "Internal error in the ACL parser. Unknown operator %d.", oper);
+           return -1;
+     }
+ }
+ 
+ 
+ /****** public routines ******/
+ 
+ int checkACL(struct Mail *   MailStruct,
+              const char *    listname,
+              int *           operation_ptr,
+              char **         parameter_ptr)
+ {
+     char *  filename;
+     int     rc;
+ 
+     assert(MailStruct != NULL);
+     assert(operation_ptr != NULL);
+     assert(parameter_ptr != NULL);
+ 
+     g_MailStruct = MailStruct;
+     g_parameter = NULL;
+ 
+     /* Set up the lex scanner. */
+ 
+     BEGIN(INITIAL);
+     lineno = 1; operation = ACL_NONE;
+ 
+     /* First check the mail against the master acl file. */
+ 
+     debug((DEBUG_ACL, 2, "Testing mail against \"~petidomo/etc/acl\"."));
+     yyin = fopen("etc/acl", "r");
+     if (yyin == NULL) {
+         switch(errno) {
+           case ENOENT:
+               /* no master acl file */
+               debug((DEBUG_ACL, 1, "No master acl file found."));
+               goto check_local_acl_file;
+           default:
+               syslog(LOG_ERR, "Couldn't open \"~petidomo/etc/acl\" acl file.: %m");
+               return -1;
+         }
+     }
+ 
+     /* Parse the acl file. */
+ 
+     rc = yyparse();
+     if (yyin != NULL) {
+         fclose(yyin);
+         yyin = NULL;
+     }
+     if (rc != 0) {
+         syslog(LOG_ERR, "Parsing \"~petidomo/etc/acl\" file returned with an error.");
+         return -1;
+     }
+ 
+     /* If we had a hit, return now. */
+ 
+     if (operation != ACL_NONE)
+       goto finished;
+ 
+ 
+ 
+ check_local_acl_file:
+ 
+     /* Set up the lex scanner. */
+ 
+     BEGIN(INITIAL);
+     lineno = 1; operation = ACL_NONE;
+ 
+     /* Do we have a local acl file to test? */
+ 
+     if (listname == NULL)
+       goto finished;
+ 
+     filename = text_easy_sprintf("lists/%s/acl", listname);
+     debug((DEBUG_ACL, 2, "Testing mail against \"~petidomo/%s\".", filename));
+     yyin = fopen(filename, "r");
+     if (yyin == NULL) {
+         switch(errno) {
+           case ENOENT:
+               /* no list acl file */
+               debug((DEBUG_ACL, 1, "No acl file for list \"%s\".", listname));
+              goto finished;
+           default:
+               syslog(LOG_ERR, "Couldn't open \"~petidomo/%s\" file: %m", filename);
+               return -1;
+         }
+     }
+ 
+     rc = yyparse();
+     fclose(yyin);
+     yyin = NULL;
+     if (rc != 0) {
+         syslog(LOG_ERR, "Parsing \"~petidomo/etc/acl\" file returned with an error.");
+         return -1;
+     }
+ 
+     /* Return to the caller. */
+ finished:
+     *operation_ptr = operation;
+     *parameter_ptr = g_parameter;
+     return 0;
+ }


ossp-pkg/petidomo/acl_scan.l -> 1.1

*** /dev/null    Sat Nov 23 01:13:20 2024
--- -    Sat Nov 23 01:13:38 2024
***************
*** 0 ****
--- 1,47 ----
+ /*
+  *      $Source: /v/ossp/cvs/ossp-pkg/petidomo/Attic/acl_scan.l,v $
+  *      $Revision: 1.1 $
+  *      $Date: 2000/12/13 13:19:22 $
+  *
+  *      Copyright (C) 1997 by CyberSolutions GmbH.
+  *      All rights reserved.
+  */
+ 
+ %{
+ #include <ctype.h>
+ #include "acl_scan.h"
+ %}
+ %%
+ ^[ \t]*#.*$    /* ignore comments */
+ [ \t]          /* ignore whitespace */
+ \n             lineno++;
+ 
+ if             return TOK_IF;
+ =              return TOK_EQUAL;
+ ==             return TOK_EQUAL;
+ from           return TOK_FROM;
+ subject                return TOK_SUBJECT;
+ envelope       return TOK_ENVELOPE;
+ header         return TOK_HEADER;
+ body           return TOK_BODY;
+ and            return TOK_AND;
+ or             return TOK_OR;
+ not            return TOK_NOT;
+ then           return TOK_THEN;
+ match(es)?     return TOK_MATCH;
+ \"[^\"]*\"     {
+                        yytext[yyleng-1] = '\0';
+                        yytext++;
+                        yyleng -= 2;
+                        return TOK_STRING;
+                }
+ drop           return TOK_DROP;
+ pass           return TOK_PASS;
+ redirect       return TOK_REDIRECT;
+ forward                return TOK_FORWARD;
+ reject         return TOK_REJECT;
+ rejectwith     return TOK_REJECTWITH;
+ filter         return TOK_FILTER;
+ 
+ .              { yylval = yytext[0]; return yylval; } /* literal */
+ %%


ossp-pkg/petidomo/archive.c -> 1.1

*** /dev/null    Sat Nov 23 01:13:20 2024
--- -    Sat Nov 23 01:13:38 2024
***************
*** 0 ****
--- 1,152 ----
+ /*
+  *      $Source: /v/ossp/cvs/ossp-pkg/petidomo/archive.c,v $
+  *      $Revision: 1.1 $
+  *      $Date: 2000/12/13 13:19:22 $
+  *
+  *      Copyright (C) 1996 by CyberSolutions GmbH.
+  *      All rights reserved.
+  */
+ 
+ #include <stdlib.h>
+ #include <string.h>
+ #include <errno.h>
+ #include <time.h>
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ 
+ #include <text.h>
+ #include <petidomo.h>
+ 
+ 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;
+     char *        date;
+     time_t        clock;
+ 
+     assert(MailStruct != NULL);
+     assert(listname != NULL);
+ 
+     /* Initialize internals. */
+ 
+     ListConfig = getListConfig(listname);
+     clock = time(NULL);
+     timeptr = localtime(&clock);
+     date = asctime(timeptr);
+     rc = -1;
+ 
+     /* 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);
+     }
+     debug((DEBUG_ARCHIVE, 2, "Our archive path is \"%s\".", path));
+ 
+     /* Check whether we have a file or a directory. */
+ 
+     if (stat(path, &sb) == 0 && (sb.st_mode & S_IFDIR) != 0) {
+ 
+        /* Store the article to the current number into the directory. */
+ 
+        debug((DEBUG_ARCHIVE, 3, "\"%s\" is a directory.", path));
+ 
+        /* Read the "active"-file to see at what article number we
+            were. */
+ 
+        filename = text_easy_sprintf("%s/.active", path);
+        fh = fopen(filename, "r");
+        if (fh != NULL) {
+            fscanf(fh, "%u", &counter);
+            debug((DEBUG_ARCHIVE, 5, ".active file contained '%u'.", counter));
+            fclose(fh);
+        }
+        else {
+            if (errno != ENOENT)
+              syslog(LOG_ERR, "Failed to read file \"%s\": %m", filename);
+            else
+              debug((DEBUG_ARCHIVE, 1, "File \".active\" did not exist."));
+            counter = 0;
+        }
+ 
+        /* Store the article. */
+ 
+        do {
+            filename = text_easy_sprintf("%s/%u", path, counter);
+            debug((DEBUG_ARCHIVE, 4, "Testing whether file \"%s\" exists already.",
+                   filename));
+            if (stat(filename, &sb) == -1) {
+                debug((DEBUG_ARCHIVE, 7, "Nope, it doesn't."));
+                if (errno == ENOENT) {
+                    debug((DEBUG_ARCHIVE, 1, "Writing mail to file \"%s\".", filename));
+                    fh = fopen(filename, "a");
+                    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);
+                    break;
+                }
+                else {
+                    syslog(LOG_ERR, "An error while trying to access the log " \
+                             "directory \"%s\": %m", path);
+                    break;
+                }
+            }
+            else
+              debug((DEBUG_ARCHIVE, 7, "Yep, it does."));
+        } while (++counter);    /* until break */
+ 
+        /* Write the current "active" number back to the file. */
+ 
+        counter++;
+        filename = text_easy_sprintf("%s/.active", path);
+        fh = fopen(filename, "w");
+        if (fh != NULL) {
+            fprintf(fh, "%u", counter);
+            debug((DEBUG_ARCHIVE, 5, "Wrote '%u' to .active file.", counter));
+            fclose(fh);
+        }
+        else
+          syslog(LOG_ERR, "Failed to write to file \"%s\": %m", filename);
+     }
+     else {
+ 
+        /* Simply append the article to this file. */
+ 
+        debug((DEBUG_ARCHIVE, 1, "Appending mail to logfile \"%s\".", path));
+        fh = fopen(path, "a");
+        if (fh != NULL) {
+            /* Write an envelope first. */
+ 
+            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", path);
+     }
+ 
+     free(path);
+     return rc;
+ }


ossp-pkg/petidomo/authen.c -> 1.1

*** /dev/null    Sat Nov 23 01:13:20 2024
--- -    Sat Nov 23 01:13:38 2024
***************
*** 0 ****
--- 1,102 ----
+ /*
+  *      $Source: /v/ossp/cvs/ossp-pkg/petidomo/authen.c,v $
+  *      $Revision: 1.1 $
+  *      $Date: 2000/12/13 13:19:22 $
+  *
+  *      Copyright (C) 1996 by CyberSolutions GmbH.
+  *      All rights reserved.
+  */
+ 
+ #include <string.h>
+ #include <ctype.h>
+ 
+ #include <text.h>
+ #include <petidomo.h>
+ 
+ int
+ FindBodyPassword(struct Mail * MailStruct)
+ {
+     char *   currLine;
+ 
+     currLine = MailStruct->Body;
+     while(isspace((int)*currLine))
+       currLine++;
+     if (!strncasecmp(currLine, "Approve", 7) ||
+        !strncasecmp(currLine, "Approved", 8) ||
+        !strncasecmp(currLine, "Passwd", 6) ||
+        !strncasecmp(currLine, "Password", 8)) {
+        MailStruct->Body = text_find_next_line(currLine);
+        (text_find_next_line(currLine))[-1] = '\0';
+        while(!isspace((int)*currLine))
+          currLine++;
+        if (ParseApproveLine(currLine) != 0) {
+            syslog(LOG_ERR, "Failed to parse the approve statement in the mail body.");
+            return -1;
+        }
+        debug((DEBUG_HERMES, 3, "Found password \"%s\" in mail body.", currLine));
+        MailStruct->Approve = currLine;
+     }
+     return 0;
+ }
+ 
+ bool
+ isValidAdminPassword(const char * password, const char * listname)
+ {
+     const struct PD_Config *     MasterConfig;
+     const struct List_Config *   ListConfig;
+ 
+     if (password == NULL)
+       return FALSE;
+ 
+     MasterConfig = getMasterConfig();
+ 
+     if (!strcasecmp(MasterConfig->master_password, password))
+       return TRUE;
+ 
+     if (listname != NULL) {
+        ListConfig = getListConfig(listname);
+ 
+        if (ListConfig->admin_password == NULL)
+          return FALSE;
+ 
+        debug((DEBUG_AUTHEN, 5, "Comparing provided password '%s' to correct one '%s'.",
+               ListConfig->admin_password, password));
+ 
+        if (!strcasecmp(ListConfig->admin_password, password))
+          return TRUE;
+     }
+     return FALSE;
+ }
+ 
+ bool
+ isValidPostingPassword(const char * password, const char * listname)
+ {
+     const struct List_Config *   ListConfig;
+ 
+     if (password == NULL)
+       return FALSE;
+ 
+     if (isValidAdminPassword(password, listname) == TRUE)
+       return TRUE;
+ 
+     if (listname != NULL) {
+        ListConfig = getListConfig(listname);
+ 
+        if (ListConfig->posting_password == NULL)
+          return FALSE;
+ 
+        debug((DEBUG_AUTHEN, 5, "provided password '%s' to correct one '%s'.",
+               ListConfig->posting_password, password));
+ 
+        if (!strcasecmp(ListConfig->posting_password, password)) {
+            debug((DEBUG_AUTHEN, 2, "Provided password is correct!"));
+            return TRUE;
+        }
+        else {
+            debug((DEBUG_AUTHEN, 2, "Provided password is incorrect!"));
+        }
+ 
+     }
+ 
+     return FALSE;
+ }


ossp-pkg/petidomo/config.c -> 1.1

*** /dev/null    Sat Nov 23 01:13:20 2024
--- -    Sat Nov 23 01:13:38 2024
***************
*** 0 ****
--- 1,227 ----
+ /*
+  *      $Source: /v/ossp/cvs/ossp-pkg/petidomo/Attic/config.c,v $
+  *      $Revision: 1.1 $
+  *      $Date: 2000/12/13 13:19:22 $
+  *
+  *      Copyright (C) 1996 by CyberSolutions GmbH.
+  *      All rights reserved.
+  */
+ 
+ #include <stdlib.h>
+ #include <unistd.h>
+ #include <string.h>
+ #include <pwd.h>
+ 
+ #include <lists.h>
+ #include <configfile.h>
+ #include <petidomo.h>
+ 
+ static struct PD_Config *  MasterConfig;
+ List ListConfigs;
+ 
+ /* These variables need to be static/global, so that the addresses as
+    used in MasterCF are known at compile time. */
+ 
+ static char *             fqdn = NULL;
+ static char *             master_password = NULL;
+ static char *             mta = "/usr/sbin/sendmail";
+ static char *             mta_options = "-f%s";
+ static bool               detach = FALSE;
+ static bool               show_stats = TRUE;
+ 
+ int
+ InitPetidomo(void)
+ {
+     struct passwd *    pwd;
+     char *             basedir = "/usr/local/petidomo";
+     int                rc;
+ 
+     /* Format description of our global config file. */
+ 
+     struct ConfigFile  MasterCF[] = {
+        { "Hostname", CF_STRING, &fqdn },
+        { "AdminPassword", CF_STRING, &master_password },
+        { "MTA", CF_STRING, &mta },
+        { "MTA_Options", CF_STRING, &mta_options },
+        { "DetachImmediately", CF_YES_NO, &detach },
+        { "ShowStatistics", CF_YES_NO, &show_stats },
+        { NULL, 0, NULL}
+     };
+ 
+     /* Allocate memory for the global config structure. */
+ 
+     MasterConfig = calloc(sizeof(struct PD_Config), 1);
+     if (MasterConfig == NULL) {
+        syslog(LOG_ERR, "Failed to allocate %d byte of memory.", sizeof(struct PD_Config));
+        return -1;
+     }
+ 
+     /* Init the list of read list configs. */
+ 
+     ListConfigs = InitList(NULL);
+ 
+     /* First of all, determine the home directory of the "petidomo"
+        user. This will be our base directory for all operations. */
+ 
+     debug((DEBUG_CONFIG, 9, "Looking for the home directory of user petidomo."));
+     pwd = getpwnam("petidomo");
+     if (pwd != NULL) {
+        debug((DEBUG_CONFIG, 8, "Home directory of petidomo is \"%s\".", pwd->pw_dir));
+        if (strcmp(basedir, pwd->pw_dir) != 0)
+          basedir = xstrdup(pwd->pw_dir); /* Replace the default above. */
+        endpwent();
+     }
+     else
+       syslog(LOG_WARNING, "User \"petidomo\" not found.");
+     debug((DEBUG_CONFIG, 8, "Will use basedir \"%s\".", basedir));
+ 
+     /* chdir() into the base directory. */
+ 
+     rc = chdir(basedir);
+     if (rc != 0) {
+        syslog(LOG_ERR, "Failed to change current directory to \"%s\": %m", basedir);
+        return -1;
+     }
+ 
+     /* Parse the config file. */
+ 
+     rc = ReadConfig("etc/petidomo.conf", MasterCF);
+     if (rc != 0) {
+        syslog(LOG_ERR, "Failed to parse the master config file \"petidomo.conf\"");
+        return -1;
+     }
+ 
+     /* Do consistency checks. */
+ 
+     if (fqdn == NULL) {
+        syslog(LOG_ERR, "The master config file \"petidomo.conf\" doesn't set the host name.");
+        return -1;
+     }
+     if (master_password == NULL) {
+        syslog(LOG_ERR, "The master config file \"petidomo.conf\" doesn't set the admin password.");
+        return -1;
+     }
+     if (strstr(mta_options, "%s") == NULL) {
+        syslog(LOG_ERR, "The argument to MTA_Options in the master config file is invalid.");
+        return -1;
+     }
+ 
+     /* Copy the results to the structure. */
+ 
+     MasterConfig->basedir = basedir;
+     MasterConfig->fqdn = fqdn;
+     MasterConfig->master_password = master_password;
+     MasterConfig->mta = mta;
+     MasterConfig->mta_options = mta_options;
+     MasterConfig->detach = detach;
+     MasterConfig->show_stats = show_stats;
+ 
+     return 0;
+ }
+ 
+ const struct PD_Config *
+ getMasterConfig(void)
+ {
+     return MasterConfig;
+ }
+ 
+ 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;
+ 
+ const struct List_Config *
+ getListConfig(const char * listname)
+ {
+     const struct PD_Config *  MasterConfig;
+     struct List_Config *      ListConfig;
+     Node                      node;
+     int                       rc;
+     char                      buffer[4096];
+ 
+     /* Format description of our global config file. */
+ 
+     struct ConfigFile ListCF[] = {
+        { "ListType", CF_STRING, &listtype },
+        { "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 },
+        { NULL, 0, NULL}
+     };
+ 
+     /* Get the master configuration. */
+ 
+     MasterConfig = getMasterConfig();
+ 
+     /* Did we read this config file already? */
+ 
+     node = FindNodeByKey(ListConfigs, listname);
+     if (node != NULL)
+       return getNodeData(node);
+ 
+     /* No? Then read the config file. */
+ 
+     sprintf(buffer, "lists/%s/config", listname);
+     debug((DEBUG_CONFIG, 6, "getListConfig(): Loading config file \"%s\".", buffer));
+     rc = ReadConfig(buffer, ListCF);
+     if (rc != 0) {
+        syslog(LOG_ERR, "Failed to parse the list \"%s\"'s config file.", listname);
+        exit(1);
+     }
+ 
+     /* Do consistency checks. */
+ 
+     if (listtype == NULL) {
+        syslog(LOG_ERR, "List \"%s\" doesn't have a valid type in config file.", listname);
+        exit(1);
+     }
+ 
+     /* Set up the list config structure. */
+ 
+     ListConfig = calloc(sizeof(struct List_Config), 1);
+     if (ListConfig == NULL) {
+        syslog(LOG_ERR, "Failed to allocate %d byte of memory.", sizeof(struct List_Config));
+        exit(1);
+     }
+     debug((DEBUG_CONFIG, 6, "Loaded config file successfully."));
+     debug((DEBUG_CONFIG, 4, "Read listtype is \"%s\".", listtype));
+     if (!strcasecmp(listtype, "open"))
+       ListConfig->listtype = LIST_OPEN;
+     else if (!strcasecmp(listtype, "closed"))
+       ListConfig->listtype = LIST_CLOSED;
+     else if (!strcasecmp(listtype, "moderated"))
+       ListConfig->listtype = LIST_MODERATED;
+     else {
+        syslog(LOG_ERR, "List \"%s\" doesn't have a valid type in config file.", listname);
+        exit(1);
+     }
+     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"))
+       CanonizeAddress(&(ListConfig->reply_to), ListConfig->fqdn);
+     ListConfig->admin_password = admin_password;
+     ListConfig->posting_password = posting_password;
+     ListConfig->postingfilter = postingfilter;
+     ListConfig->archivepath = archivepath;
+     AppendNode(ListConfigs, xstrdup(listname), ListConfig);
+ 
+     return ListConfig;
+ }

CVSTrac 2.0.1