Index: ossp-pkg/petidomo/subscribe.c RCS File: /v/ossp/cvs/ossp-pkg/petidomo/subscribe.c,v co -q -kk -p'1.1' '/v/ossp/cvs/ossp-pkg/petidomo/subscribe.c,v' | diff -u /dev/null - -L'ossp-pkg/petidomo/subscribe.c' 2>/dev/null --- ossp-pkg/petidomo/subscribe.c +++ - 2024-05-17 10:15:12.322570382 +0200 @@ -0,0 +1,324 @@ +/* + * $Source$ + * $Revision$ + * $Date$ + * + * Copyright (C) 1996 by CyberSolutions GmbH. + * All rights reserved. + */ + +#include +#include +#include + +int +AddAddress(struct Mail * MailStruct, + const char * param1, + const char * param2, + const char * defaultlist) +{ + const struct List_Config * ListConfig; + FILE * fh; + const char * address = NULL; + const char * listname = NULL; + char owner[4096]; + char envelope[4096]; + char * buffer; + char * originator; + char * p; + + debug((DEBUG_COMMAND, 3, "AddAddress(\"%s\", \"%s\") with default list \"%s\".", + param1, param2, defaultlist)); + + /* Try to find out, which parameter is what. */ + + if (param1 != NULL) { + if (isValidListName(param1) == TRUE) + listname = param1; + else if (isRFC822Address(param1) == TRUE) + address = param1; + + if (param2 != NULL) { + if (isValidListName(param2) == TRUE) + listname = param2; + else if (isRFC822Address(param2) == TRUE) + address = param2; + } + } + + if (address == NULL) + address = (MailStruct->Reply_To) ? MailStruct->Reply_To : MailStruct->From; + if (listname == NULL && defaultlist != NULL) + listname = defaultlist; + + if (address == NULL || listname == NULL) { + syslog(LOG_NOTICE, "%s: subscribe-command invalid: No list specified.", + MailStruct->From); + return 0; + } + + /* Initialize internal stuff. */ + + ListConfig = getListConfig(listname); + sprintf(owner, "%s-owner@%s", listname, ListConfig->fqdn); + sprintf(envelope, "%s-owner@%s", listname, ListConfig->fqdn); + originator = (MailStruct->Reply_To) ? MailStruct->Reply_To : MailStruct->From; + + debug((DEBUG_COMMAND, 1, "Subscribing \"%s\" to list \"%s\".", address, listname)); + + /* Check whether the request is authorized at all. */ + + if (isValidAdminPassword(getPassword(), listname) == FALSE) { + + /* No valid password, check further. */ + + debug((DEBUG_COMMAND, 5, "The mail didn't contain any admin password. " \ + "Checking for authorization...")); + + if (ListConfig->allowpubsub == FALSE) { + + /* Access was unauthorized, notify the originator. */ + + syslog(LOG_INFO, "\"%s\" tried to subscribe \"%s\" to list \"%s\", but couldn't " \ + "provide the correct password.", originator, address, listname); + + fh = vOpenMailer(envelope, originator, NULL); + if (fh != NULL) { + fprintf(fh, "From: %s-request@%s (Petidomo Mailing List Server)\n", + listname, ListConfig->fqdn); + fprintf(fh, "To: %s\n", originator); + fprintf(fh, "Subject: Your request \"subscribe %s %s\"\n", address, listname); + if (MailStruct->Message_Id != NULL) + fprintf(fh, "In-Reply-To: %s\n", MailStruct->Message_Id); + fprintf(fh, "Precedence: junk\n"); + fprintf(fh, "Sender: %s\n", envelope); + fprintf(fh, "\n"); + buffer = text_easy_sprintf( +"The mailing list \"%s\" is a closed forum and only the maintainer may " \ +"subscribe addresses. Your request has been forwarded to the " \ +"appropriate person, so please don't send any further mail. You will " \ +"be notified as soon as possible.", listname); + text_wordwrap(buffer, 75); + fprintf(fh, "%s\n", buffer); + AppendSignature(fh); + CloseMailer(fh); + } + else + syslog(LOG_ERR, "Failed to send email to \"%s\" concerning his request.", + originator); + + /* Notify the owner. */ + + fh = vOpenMailer(envelope, owner, NULL); + if (fh != NULL) { + fprintf(fh, "From: %s-request@%s (Petidomo Mailing List Server)\n", + listname, ListConfig->fqdn); + fprintf(fh, "To: %s\n", owner); + fprintf(fh, "Subject: Unauthorized request from \"%s\"\n", originator); + fprintf(fh, "Precedence: junk\n"); + fprintf(fh, "Sender: %s\n", envelope); + fprintf(fh, "\n"); + buffer = text_easy_sprintf( +"\"%s\" tried to subscribe the address \"%s\" to the \"%s\" mailing list, " \ +"but couldn't provide the correct password. To subscribe him, send the " \ +"following commands to the server:", originator, address, listname); + text_wordwrap(buffer, 75); + fprintf(fh, "%s\n\n", buffer); + fprintf(fh, "password \n"); + fprintf(fh, "subscribe %s %s\n", address, listname); + AppendSignature(fh); + CloseMailer(fh); + } + else { + syslog(LOG_ERR, "Failed to send email to \"%s\"!", owner); + return -1; + } + return 0; + } + + if (ListConfig->allowaliensub == FALSE && + (MailStruct->From == NULL || !strcasecmp(address, MailStruct->From) == FALSE) && + (MailStruct->Reply_To == NULL || !strcasecmp(address, MailStruct->Reply_To) == FALSE)) { + + /* Trying to subscribe something different than himself. */ + + syslog(LOG_INFO, "\"%s\" tried to subscribe \"%s\" to list \"%s\", but the list " \ + "type doesn't allow this.", originator, address, listname); + + fh = vOpenMailer(envelope, originator, NULL); + if (fh != NULL) { + fprintf(fh, "From: %s-request@%s (Petidomo Mailing List Server)\n", + listname, ListConfig->fqdn); + fprintf(fh, "To: %s\n", originator); + fprintf(fh, "Subject: Your request \"subscribe %s %s\"\n", address, listname); + if (MailStruct->Message_Id != NULL) + fprintf(fh, "In-Reply-To: %s\n", MailStruct->Message_Id); + fprintf(fh, "Precedence: junk\n"); + fprintf(fh, "Sender: %s\n", envelope); + fprintf(fh, "\n"); + buffer = text_easy_sprintf( +"The mailing list \"%s\" does not allow to automatically subscribe or unsubscribe an " \ +"address not equal to the one, you are mailing from. Your request has been forwarded " \ +"to the list administrator, so please don't send any futher mail. You will be notified " \ +"as soon as possible.", listname); + text_wordwrap(buffer, 75); + fprintf(fh, "%s\n", buffer); + AppendSignature(fh); + CloseMailer(fh); + } + else + syslog(LOG_ERR, "Failed to send email to \"%s\" concerning his request.", + originator); + + /* Notify the owner. */ + + fh = vOpenMailer(envelope, owner, NULL); + if (fh != NULL) { + fprintf(fh, "From: %s-request@%s (Petidomo Mailing List Server)\n", + listname, ListConfig->fqdn); + fprintf(fh, "To: %s\n", owner); + fprintf(fh, "Subject: Unauthorized request from \"%s\"\n", originator); + fprintf(fh, "Precedence: junk\n"); + fprintf(fh, "Sender: %s\n", envelope); + fprintf(fh, "\n"); + buffer = text_easy_sprintf( +"\"%s\" tried to subscribe the address \"%s\" to the \"%s\" mailing list. " \ +"The list type does not allow subscribing addresses not equal to the From: " \ +"address, though, so the request has been denied. To subscribe this person " \ +"manually, send the following commands to the server:", originator, address, listname); + text_wordwrap(buffer, 75); + fprintf(fh, "%s\n\n", buffer); + fprintf(fh, "password \n"); + fprintf(fh, "subscribe %s %s\n", address, listname); + AppendSignature(fh); + CloseMailer(fh); + } + else { + syslog(LOG_ERR, "Failed to send email to \"%s\"!", owner); + return -1; + } + return 0; + } + } + + /* Check whether the address is subscribed already. */ + + if (isSubscribed(listname, address, NULL, NULL, FALSE) == TRUE) { + debug((DEBUG_COMMAND, 2, "\"%s\" is already subscribed to list \"%s\".", + address, listname)); + + /* Notify the originator, that the address is already a + member. */ + + fh = vOpenMailer(envelope, originator, NULL); + if (fh != NULL) { + fprintf(fh, "From: %s-request@%s (Petidomo Mailing List Server)\n", + listname, ListConfig->fqdn); + fprintf(fh, "To: %s\n", originator); + fprintf(fh, "Subject: Your request \"subscribe %s %s\"\n", + address, listname); + if (MailStruct->Message_Id != NULL) + fprintf(fh, "In-Reply-To: %s\n", MailStruct->Message_Id); + fprintf(fh, "Precedence: junk\n"); + fprintf(fh, "Sender: %s\n", envelope); + fprintf(fh, "\n"); + fprintf(fh, "The address is subscribed to this list already.\n"); + AppendSignature(fh); + CloseMailer(fh); + } + else { + syslog(LOG_ERR, "Failed to send email to \"%s\" concerning his request.", originator); + return -1; + } + return 0; + } + + /* Okay, add the address to the list. */ + + buffer = text_easy_sprintf("lists/%s/list", listname); + fh = fopen(buffer, "a"); + if (fh == NULL) { + syslog(LOG_ERR, "Failed to open file \"%s\" for writing: %m", buffer); + return -1; + } + fprintf(fh, "%s\n", address); + fclose(fh); + + /* Send success notification to the originator, the new + subscriber, and the owner. */ + + if (!strcasecmp(address, originator) == TRUE) + fh = vOpenMailer(envelope, address, owner, NULL); + else + fh = vOpenMailer(envelope, address, originator, owner, NULL); + if (fh != NULL) { + fprintf(fh, "From: %s-request@%s (Petidomo Mailing List Server)\n", + listname, ListConfig->fqdn); + fprintf(fh, "To: %s\n", address); + if (!strcasecmp(address, originator) == TRUE) + fprintf(fh, "Cc: %s\n", owner); + else + fprintf(fh, "Cc: %s, %s\n", originator, owner); + fprintf(fh, "Subject: Request \"subscribe %s %s\"\n", address, listname); + if (MailStruct->Message_Id != NULL) + fprintf(fh, "In-Reply-To: %s\n", MailStruct->Message_Id); + fprintf(fh, "Precedence: junk\n"); + fprintf(fh, "Sender: %s\n", envelope); + fprintf(fh, "\n"); + if (!strcasecmp(address, originator) == TRUE) { + buffer = text_easy_sprintf( +"Per your request, the address \"%s\" has been subscribed to the " \ +"\"%s\" mailing list. If you want to unsubscribe later, you can " \ +"do so by sending the following command to \"%s-request@%s\":", + address, listname, listname, ListConfig->fqdn); + } + else { + buffer = text_easy_sprintf( +"Per request from \"%s\", the address \"%s\" has been subscribed to the " \ +"\"%s\" mailing list. If you want to unsubscribe later, you can " \ +"do so by sending the following command to \"%s-request@%s\":", + originator, address, listname, listname, ListConfig->fqdn); + } + text_wordwrap(buffer, 75); + fprintf(fh, "%s\n\n", buffer); + fprintf(fh, "unsubscribe %s\n\n", address); + fprintf(fh, "Please save a copy of this mail, to make sure you remember how " \ + "to\nunsubscribe!\n"); + AppendSignature(fh); + CloseMailer(fh); + } + else { + syslog(LOG_ERR, "Failed to send email to \"%s\"!", owner); + return -1; + } + + /* Send introduction text to the new member. */ + + buffer = text_easy_sprintf("lists/%s/introduction", listname); + p = loadfile(buffer); + if (p != NULL) { + fh = vOpenMailer(envelope, address, NULL); + if (fh != NULL) { + debug((DEBUG_COMMAND, 5, "Sending \"%s\" as welcome mail to the new " \ + "subscriber.", buffer)); + fprintf(fh, "From: %s-request@%s (Petidomo Mailing List Server)\n", + listname, ListConfig->fqdn); + fprintf(fh, "To: %s\n", address); + fprintf(fh, "Subject: Welcome to the \"%s\" mailing list!\n", listname); + if (MailStruct->Message_Id != NULL) + fprintf(fh, "In-Reply-To: %s\n", MailStruct->Message_Id); + fprintf(fh, "Precedence: junk\n"); + fprintf(fh, "Sender: %s\n", envelope); + fprintf(fh, "\n"); + fprintf(fh, "%s\n", p); + CloseMailer(fh); + free(p); + } + else { + free(p); + syslog(LOG_ERR, "Failed to send introduction mail to \"%s\"!", address); + return -1; + } + } + return 0; +} Index: ossp-pkg/petidomo/tool.c RCS File: /v/ossp/cvs/ossp-pkg/petidomo/tool.c,v co -q -kk -p'1.1' '/v/ossp/cvs/ossp-pkg/petidomo/tool.c,v' | diff -u /dev/null - -L'ossp-pkg/petidomo/tool.c' 2>/dev/null --- ossp-pkg/petidomo/tool.c +++ - 2024-05-17 10:15:12.325577466 +0200 @@ -0,0 +1,149 @@ +/* + * $Source$ + * $Revision$ + * $Date$ + * + * Copyright (C) 1996 by CyberSolutions GmbH. + * All rights reserved. + */ + +#include +#include +#include +#include + +#include +#include + +bool +isSubscribed(const char * listname, const char * address, + char ** listfile, char ** subscriber, bool dofuzzy) +{ + struct stat sb; + char * buffer; + char * list; + char * p; + unsigned int len; + bool rc; + + buffer = text_easy_sprintf("lists/%s/list", listname); + if (stat(buffer, &sb) != 0) + return FALSE; + list = loadfile(buffer); + if (list == NULL) + return FALSE; + + debug((DEBUG_COMMAND, 3, "Searching for subscriber \"%s\" in list \"%s\".", + address, listname)); + + 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')) { + break; + } + } + + if (*p == '\0' && dofuzzy == TRUE) { + debug((DEBUG_COMMAND, 3, "No success, trying fuzzy matching.")); + address = buildFuzzyMatchAddress(address); + 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')) { + break; + } + } + } + } + +#if DEBUG + if (*p != '\0') { + debug((DEBUG_COMMAND, 3, "Found address: \"%s\".", p)); + } + else { + debug((DEBUG_COMMAND, 3, "Nope, couldn't find address.")); + } +#endif + + /* Save the returncode now, because p may be invalid in a few + moments. */ + + rc = ((*p != '\0') ? TRUE : FALSE); + + /* Did the caller want results back? Then give them to him. */ + + if (listfile != NULL) { + *listfile = list; + if (subscriber != NULL) + *subscriber = (*p != '\0') ? p : NULL; + } + else + free(list); + + /* Return the result. */ + + return rc; +} + +char * +buildFuzzyMatchAddress(const char * address) +{ + char * fuzzyaddress; + int rc; + + debug((DEBUG_COMMAND, 5, "Turning \"%s\" into a fuzzy match address.", address)); + + fuzzyaddress = xmalloc(strlen(address)+16); + rc = text_transform_text(fuzzyaddress, address, "([^@]+)@[^\\.]+\\.([^\\.]+\\..*)", + "\\1@([^\\\\.]+\\\\.)?\\2"); + if (rc == TEXT_REGEX_TRANSFORM_DIDNT_MATCH) { + rc = text_transform_text(fuzzyaddress, address, "([^@]+)@([^\\.]+\\.[^\\.]+)", + "\\1@([^\\\\.]+\\\\.)?\\2"); + } + + switch (rc) { + case TEXT_REGEX_ERROR: + syslog(LOG_CRIT, "Internal error in buildFuzzyMatchAddress(): "\ + "Regular expression can't be compiled."); + break; + case TEXT_REGEX_TRANSFORM_DIDNT_MATCH: + break; + case TEXT_REGEX_OK: + debug((DEBUG_COMMAND, 4, "Fuzzy-match address is \"%s\".", fuzzyaddress)); + return fuzzyaddress; + default: + syslog(LOG_CRIT, "Internal error: Unexpected returncode in ParseMessageIdLine()."); + } + debug((DEBUG_COMMAND, 3, "No fuzzy match address could be built.")); + free(fuzzyaddress); + return NULL; +} + + + +bool +isValidListName(const char * listname) +{ + struct stat sb; + char * buffer; + + assert(listname != NULL); + + if ((strchr(listname, '/') != NULL) || (strchr(listname, ':') != NULL)) { + debug((DEBUG_COMMAND, 1, "listname '%s' contains a slash or colon!", listname)); + return FALSE; + } + + buffer = text_easy_sprintf("lists/%s", 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); + if (stat(buffer, &sb) != 0) + return FALSE; + } + return TRUE; +} Index: ossp-pkg/petidomo/unsubscribe.c RCS File: /v/ossp/cvs/ossp-pkg/petidomo/unsubscribe.c,v co -q -kk -p'1.1' '/v/ossp/cvs/ossp-pkg/petidomo/unsubscribe.c,v' | diff -u /dev/null - -L'ossp-pkg/petidomo/unsubscribe.c' 2>/dev/null --- ossp-pkg/petidomo/unsubscribe.c +++ - 2024-05-17 10:15:12.328250538 +0200 @@ -0,0 +1,293 @@ +/* + * $Source$ + * $Revision$ + * $Date$ + * + * Copyright (C) 1996 by CyberSolutions GmbH. + * All rights reserved. + */ + +#include +#include +#include + +int +DeleteAddress(struct Mail * MailStruct, + const char * param1, + const char * param2, + const char * defaultlist) +{ + const struct List_Config * ListConfig; + FILE * fh; + const char * address = NULL; + const char * listname = NULL; + char owner[4096]; + char envelope[4096]; + char * buffer; + char * originator; + char * p; + char * list; + + debug((DEBUG_COMMAND, 3, "DeleteAddress(\"%s\", \"%s\") with default list \"%s\".", + param1, param2, defaultlist)); + + /* Try to find out, which parameter is what. */ + + if (param1 != NULL) { + if (isValidListName(param1) == TRUE) + listname = param1; + else if (isRFC822Address(param1) == TRUE) + address = param1; + + if (param2 != NULL) { + if (isValidListName(param2) == TRUE) + listname = param2; + else if (isRFC822Address(param2) == TRUE) + address = param2; + } + } + + if (address == NULL) + address = (MailStruct->Reply_To) ? MailStruct->Reply_To : MailStruct->From; + if (listname == NULL && defaultlist != NULL) + listname = defaultlist; + + if (address == NULL || listname == NULL) { + syslog(LOG_NOTICE, "%s: unsubscribe-command invalid: No list specified.", + MailStruct->From); + return 0; + } + + /* Initialize internal stuff. */ + + ListConfig = getListConfig(listname); + sprintf(owner, "%s-owner@%s", listname, ListConfig->fqdn); + sprintf(envelope, "%s-owner@%s", listname, ListConfig->fqdn); + originator = (MailStruct->Reply_To) ? MailStruct->Reply_To : MailStruct->From; + + debug((DEBUG_COMMAND, 1, "Unsubscribing \"%s\" to list \"%s\".", address, listname)); + + /* Check whether the request is authorized at all. */ + + if (isValidAdminPassword(getPassword(), listname) == FALSE) { + + /* No valid password, check further. */ + + if (ListConfig->allowpubsub == FALSE) { + + /* Access was unauthorized, notify the originator. */ + + syslog(LOG_INFO, "\"%s\" tried to unsubscribe \"%s\" from list \"%s\", but " \ + "couldn't provide the correct password.", originator, address, listname); + + fh = vOpenMailer(envelope, originator, NULL); + if (fh != NULL) { + fprintf(fh, "From: %s-request@%s (Petidomo Mailing List Server)\n", + listname, ListConfig->fqdn); + fprintf(fh, "To: %s\n", originator); + fprintf(fh, "Subject: Your request \"unsubscribe %s %s\"\n", + address, listname); + if (MailStruct->Message_Id != NULL) + fprintf(fh, "In-Reply-To: %s\n", MailStruct->Message_Id); + fprintf(fh, "Precedence: junk\n"); + fprintf(fh, "Sender: %s\n", envelope); + fprintf(fh, "\n"); + buffer = text_easy_sprintf( +"The mailing list \"%s\" is a closed forum and only the maintainer may " \ +"unsubscribe addresses. Your request has been forwarded to the " \ +"appropriate person, so please don't send any further mail. You will " \ +"be notified as soon as possible.", listname); + text_wordwrap(buffer, 75); + fprintf(fh, "%s\n", buffer); + AppendSignature(fh); + CloseMailer(fh); + } + else + syslog(LOG_ERR, "Failed to send email to \"%s\" concerning his request.", + originator); + + /* Notify the owner. */ + + fh = vOpenMailer(envelope, owner, NULL); + if (fh != NULL) { + fprintf(fh, "From: %s-request@%s (Petidomo Mailing List Server)\n", + listname, ListConfig->fqdn); + fprintf(fh, "To: %s\n", owner); + fprintf(fh, "Subject: Unauthorized request from \"%s\"\n", originator); + fprintf(fh, "Precedence: junk\n"); + fprintf(fh, "Sender: %s\n", envelope); + fprintf(fh, "\n"); + buffer = text_easy_sprintf( +"\"%s\" tried to unsubscribe the address \"%s\" from the \"%s\" mailing list, " \ +"but couldn't provide the correct password. To unsubscribe him, send the " \ +"following commands to the server:", originator, address, listname); + text_wordwrap(buffer, 75); + fprintf(fh, "%s\n\n", buffer); + fprintf(fh, "password \n"); + fprintf(fh, "unsubscribe %s %s\n", address, listname); + AppendSignature(fh); + CloseMailer(fh); + } + else { + syslog(LOG_ERR, "Failed to send email to \"%s\"!", owner); + return -1; + } + return 0; + } + if (ListConfig->allowaliensub == FALSE && + (MailStruct->From == NULL || !strcasecmp(address, MailStruct->From) == FALSE) && + (MailStruct->Reply_To == NULL || !strcasecmp(address, MailStruct->Reply_To) == FALSE)) { + + /* Trying to unsubscribe something different than himself. */ + + syslog(LOG_INFO, "\"%s\" tried to unsubscribe \"%s\" from list \"%s\", but the " \ + "list type doesn't allow this.", originator, address, listname); + + fh = vOpenMailer(envelope, originator, NULL); + if (fh != NULL) { + fprintf(fh, "From: %s-request@%s (Petidomo Mailing List Server)\n", + listname, ListConfig->fqdn); + fprintf(fh, "To: %s\n", originator); + fprintf(fh, "Subject: Your request \"unsubscribe %s %s\"\n", + address, listname); + if (MailStruct->Message_Id != NULL) + fprintf(fh, "In-Reply-To: %s\n", MailStruct->Message_Id); + fprintf(fh, "Precedence: junk\n"); + fprintf(fh, "Sender: %s\n", envelope); + fprintf(fh, "\n"); + buffer = text_easy_sprintf( +"The mailing list \"%s\" does not allow to automatically subscribe or unsubscribe an " \ +"address not equal to the one, you are mailing from. Your request has been forwarded " \ +"to the list administrator, so please don't send any futher mail. You will be notified " \ +"as soon as possible.", listname); + text_wordwrap(buffer, 75); + fprintf(fh, "%s\n", buffer); + AppendSignature(fh); + CloseMailer(fh); + } + else + syslog(LOG_ERR, "Failed to send email to \"%s\" concerning his request.", + originator); + + /* Notify the owner. */ + + fh = vOpenMailer(envelope, owner, NULL); + if (fh != NULL) { + fprintf(fh, "From: %s-request@%s (Petidomo Mailing List Server)\n", + listname, ListConfig->fqdn); + fprintf(fh, "To: %s\n", owner); + fprintf(fh, "Subject: Unauthorized request from \"%s\"\n", originator); + fprintf(fh, "Precedence: junk\n"); + fprintf(fh, "Sender: %s\n", envelope); + fprintf(fh, "\n"); + buffer = text_easy_sprintf( +"\"%s\" tried to unsubscribe the address \"%s\" from the \"%s\" mailing list. " \ +"The list type does not allow unsubscribing addresses not equal to the From: " \ +"address, though, so the request has been denied. To unsubscribe this person " \ +"manually, send the following commands to the server:", originator, address, listname); + text_wordwrap(buffer, 75); + fprintf(fh, "%s\n\n", buffer); + fprintf(fh, "password \n"); + fprintf(fh, "unsubscribe %s %s\n", address, listname); + AppendSignature(fh); + CloseMailer(fh); + } + else { + syslog(LOG_ERR, "Failed to send email to \"%s\"!", owner); + return -1; + } + return 0; + } + } + + /* Okay, remove the address from the list. */ + + if (isSubscribed(listname, address, &list, &p, FALSE) == FALSE) { + + /* Address is not subscribed. */ + + debug((DEBUG_COMMAND, 2, "\"%s\" is not subscribed to list \"%s\".", + address, listname)); + + /* Notify the originator, that the address is not subscribed at + all. */ + + fh = vOpenMailer(envelope, originator, NULL); + if (fh != NULL) { + fprintf(fh, "From: %s-request@%s (Petidomo Mailing List Server)\n", + listname, ListConfig->fqdn); + fprintf(fh, "To: %s\n", originator); + fprintf(fh, "Subject: Your request \"unsubscribe %s %s\"\n", + address, listname); + if (MailStruct->Message_Id != NULL) + fprintf(fh, "In-Reply-To: %s\n", MailStruct->Message_Id); + fprintf(fh, "Precedence: junk\n"); + fprintf(fh, "Sender: %s\n", envelope); + fprintf(fh, "\n"); + fprintf(fh, "The address is not subscribed to this list.\n"); + AppendSignature(fh); + CloseMailer(fh); + } + else { + syslog(LOG_ERR, "Failed to send email to \"%s\" concerning his request.", + originator); + return -1; + } + } + else { + buffer = text_easy_sprintf("lists/%s/list", listname); + fh = fopen(buffer, "w"); + if (fh == NULL) { + syslog(LOG_ERR, "Failed to open file \"%s\" for writing: %m", buffer); + return -1; + } + *p++ = '\0'; + fprintf(fh, "%s", list); + p = text_find_next_line(p); /* skip address in question */ + fprintf(fh, "%s", p); + fclose(fh); + + /* Send success notification to the originator, and the + unsubscribed address. */ + + if (!strcasecmp(address, originator) == TRUE) + fh = vOpenMailer(envelope, address, owner, NULL); + else + fh = vOpenMailer(envelope, address, originator, owner, NULL); + if (fh != NULL) { + fprintf(fh, "From: %s-request@%s (Petidomo Mailing List Server)\n", + listname, ListConfig->fqdn); + fprintf(fh, "To: %s\n", address); + if (!strcasecmp(address, originator) == TRUE) + fprintf(fh, "Cc: %s\n", owner); + else + fprintf(fh, "Cc: %s, %s\n", originator, owner); + fprintf(fh, "Subject: Request \"unsubscribe %s %s\"\n", address, listname); + if (MailStruct->Message_Id != NULL) + fprintf(fh, "In-Reply-To: %s\n", MailStruct->Message_Id); + fprintf(fh, "Precedence: junk\n"); + fprintf(fh, "Sender: %s\n", envelope); + fprintf(fh, "\n"); + if (!strcasecmp(address, originator) == TRUE) { + buffer = text_easy_sprintf( +"Per your request, the address \"%s\" has been unsubscribed from the " \ +"\"%s\" mailing list.\n\n", address, listname); + } + else { + buffer = text_easy_sprintf( +"Per request from \"%s\", the address \"%s\" has been unsubscribed from the " \ +"\"%s\" mailing list.\n\n", originator, address, listname); + } + text_wordwrap(buffer, 75); + fprintf(fh, "%s", buffer); + AppendSignature(fh); + CloseMailer(fh); + } + else { + syslog(LOG_ERR, "Failed to send email to \"%s\"!", owner); + return -1; + } + } + free(list); + return 0; +}