masqmail

annotate src/online.c @ 281:ea5f86e0a81c

modes are now enforced exclusive Other MTAs (exim, postfix) are more relaxing, but as combinations of exclusive modes are senseless we behave more obvious if we fail early. This makes understanding the behavior easier too.
author markus schnalke <meillo@marmaro.de>
date Tue, 07 Dec 2010 14:04:56 -0300
parents fc1c6425c024
children f10a56dc7481
rev   line source
meillo@0 1 /* MasqMail
meillo@0 2 Copyright (C) 1999-2001 Oliver Kurth
meillo@279 3 Copyright (C) 2008, 2010 markus schnalke <meillo@marmaro.de>
meillo@0 4
meillo@0 5 This program is free software; you can redistribute it and/or modify
meillo@0 6 it under the terms of the GNU General Public License as published by
meillo@0 7 the Free Software Foundation; either version 2 of the License, or
meillo@0 8 (at your option) any later version.
meillo@0 9
meillo@0 10 This program is distributed in the hope that it will be useful,
meillo@0 11 but WITHOUT ANY WARRANTY; without even the implied warranty of
meillo@0 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
meillo@0 13 GNU General Public License for more details.
meillo@0 14
meillo@0 15 You should have received a copy of the GNU General Public License
meillo@0 16 along with this program; if not, write to the Free Software
meillo@0 17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
meillo@0 18 */
meillo@0 19
meillo@0 20 #include <sys/stat.h>
meillo@0 21 #include <sys/wait.h>
meillo@15 22
meillo@0 23 #include "masqmail.h"
meillo@0 24 #include "peopen.h"
meillo@0 25
meillo@0 26 gchar *connection_name;
meillo@0 27
meillo@10 28 void
meillo@10 29 set_online_name(gchar * name)
meillo@0 30 {
meillo@10 31 connection_name = g_strdup(name);
meillo@0 32 }
meillo@0 33
meillo@10 34 static gchar*
meillo@279 35 detect_online_file(const gchar* file)
meillo@279 36 {
meillo@279 37 struct stat st;
meillo@279 38 int err;
meillo@279 39 FILE *fptr;
meillo@279 40 char buf[256];
meillo@279 41
meillo@279 42 err = stat(conf.online_file, &st);
meillo@279 43
meillo@279 44 if (err) {
meillo@279 45 if (errno==ENOENT) {
meillo@279 46 logwrite(LOG_NOTICE, "not online.\n");
meillo@279 47 return NULL;
meillo@279 48 }
meillo@279 49 logwrite(LOG_ALERT, "stat of %s failed: %s\n", conf.online_file, strerror(errno));
meillo@279 50 return NULL;
meillo@279 51 }
meillo@279 52
meillo@279 53 fptr = fopen(conf.online_file, "r");
meillo@279 54 if (!fptr) {
meillo@279 55 logwrite(LOG_ALERT, "opening of %s failed: %s\n", conf.online_file, strerror(errno));
meillo@279 56 return NULL;
meillo@279 57 }
meillo@279 58 if (fgets(buf, 256, fptr) == NULL) {
meillo@279 59 logwrite(LOG_ALERT, "empty online file %s\n", conf.online_file);
meillo@279 60 fclose(fptr);
meillo@279 61 return NULL;
meillo@279 62 }
meillo@279 63 g_strstrip(buf); /* strip whitespace */
meillo@279 64 fclose(fptr);
meillo@279 65 if (strlen(buf) == 0) {
meillo@279 66 logwrite(LOG_ALERT, "only whitespace connection name in %s\n", conf.online_file);
meillo@279 67 return NULL;
meillo@279 68 }
meillo@279 69 return g_strdup(buf);
meillo@279 70 }
meillo@279 71
meillo@279 72 static gchar*
meillo@10 73 detect_online_pipe(const gchar * pipe)
meillo@0 74 {
meillo@10 75 pid_t pid;
meillo@10 76 void (*old_signal) (int);
meillo@10 77 int status;
meillo@10 78 FILE *in;
meillo@10 79 gchar *name = NULL;
meillo@0 80
meillo@10 81 old_signal = signal(SIGCHLD, SIG_DFL);
meillo@0 82
meillo@10 83 in = peopen(pipe, "r", environ, &pid);
meillo@33 84 if (in == NULL) {
meillo@33 85 logwrite(LOG_ALERT, "could not open pipe '%s': %s\n", pipe, strerror(errno));
meillo@33 86 signal(SIGCHLD, old_signal);
meillo@33 87 return NULL;
meillo@33 88 }
meillo@33 89
meillo@33 90 gchar output[256];
meillo@33 91 if (fgets(output, 255, in)) {
meillo@33 92 g_strchomp(g_strchug(output));
meillo@33 93 if (strlen(output) == 0) {
meillo@33 94 logwrite(LOG_ALERT, "only whitespace connection name\n");
meillo@33 95 name = NULL;
meillo@18 96 } else {
meillo@33 97 name = g_strdup(output);
meillo@10 98 }
meillo@33 99 } else {
meillo@33 100 logwrite(LOG_ALERT, "nothing read from pipe %s\n", pipe);
meillo@33 101 name = NULL;
meillo@33 102 }
meillo@33 103 fclose(in);
meillo@33 104 waitpid(pid, &status, 0);
meillo@262 105 if (WEXITSTATUS(status) != 0) {
meillo@33 106 g_free(name);
meillo@33 107 name = NULL;
meillo@33 108 }
meillo@0 109
meillo@10 110 signal(SIGCHLD, old_signal);
meillo@0 111
meillo@10 112 return name;
meillo@0 113 }
meillo@0 114
meillo@10 115 gchar*
meillo@10 116 detect_online()
meillo@0 117 {
meillo@279 118 if (!conf.online_detect) {
meillo@33 119 return NULL;
meillo@33 120 }
meillo@33 121
meillo@33 122 if (strcmp(conf.online_detect, "file") == 0) {
meillo@33 123 DEBUG(3) debugf("online detection method 'file'\n");
meillo@279 124 if (!conf.online_file) {
meillo@33 125 logwrite(LOG_ALERT, "online detection mode is 'file', but online_file is undefined\n");
meillo@33 126 return NULL;
meillo@33 127 }
meillo@279 128 return detect_online_file(conf.online_file);
meillo@33 129
meillo@33 130 } else if (strcmp(conf.online_detect, "pipe") == 0) {
meillo@33 131 DEBUG(3) debugf("connection method 'pipe'\n");
meillo@279 132 if (!conf.online_pipe) {
meillo@33 133 logwrite(LOG_ALERT, "online detection mode is 'pipe', but online_pipe is undefined\n");
meillo@33 134 return NULL;
meillo@33 135 }
meillo@279 136 return detect_online_pipe(conf.online_pipe);
meillo@279 137
meillo@33 138 } else if (strcmp(conf.online_detect, "argument") == 0) {
meillo@279 139 DEBUG(3) debugf("online route literally defined\n");
meillo@279 140 /* use the name set with set_online_name() */
meillo@33 141 return connection_name;
meillo@279 142
meillo@0 143 }
meillo@33 144
meillo@279 145 DEBUG(3) debugf("unknown online detection method `%s'\n", conf.online_detect);
meillo@0 146 return NULL;
meillo@0 147 }