masqmail

annotate src/connect.c @ 421:f37384470855

Changed lockdir to /var/lock/masqmail; Create lockdir and piddir on startup. Moved the lockdir out of the spool dir. (When /var/lock is a ramdisk we do well to have the lock files there.) Added the new configure option --with-lockdir to change that location. Nontheless, if we run_as_user, then lock files are always stored in the spool dir directly. Instead of installing the lockdir and piddir at installation time, we create them on startup time now if they are missing. This is necessary if lockdir or piddir are a tmpfs.
author markus schnalke <meillo@marmaro.de>
date Wed, 30 May 2012 09:38:38 +0200
parents 6500db550a03
children
rev   line source
meillo@367 1 /*
meillo@367 2 ** MasqMail
meillo@367 3 ** Copyright (C) 1999 Oliver Kurth
meillo@367 4 **
meillo@367 5 ** This program is free software; you can redistribute it and/or modify
meillo@367 6 ** it under the terms of the GNU General Public License as published by
meillo@367 7 ** the Free Software Foundation; either version 2 of the License, or
meillo@367 8 ** (at your option) any later version.
meillo@367 9 **
meillo@367 10 ** This program is distributed in the hope that it will be useful,
meillo@367 11 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
meillo@367 12 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
meillo@367 13 ** GNU General Public License for more details.
meillo@367 14 **
meillo@367 15 ** You should have received a copy of the GNU General Public License
meillo@367 16 ** along with this program; if not, write to the Free Software
meillo@367 17 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
meillo@0 18 */
meillo@0 19 #include "masqmail.h"
meillo@0 20
meillo@10 21 static GList*
meillo@400 22 resolve_ip(gchar *ip)
meillo@0 23 {
meillo@10 24 struct in_addr ia;
meillo@400 25 mxip_addr mxip;
meillo@10 26
meillo@400 27 if (!inet_aton(ip, &ia)) {
meillo@400 28 /* No dots-and-numbers notation. */
meillo@400 29 return NULL;
meillo@10 30 }
meillo@400 31 mxip.name = g_strdup(ip);
meillo@400 32 mxip.pref = 0;
meillo@400 33 mxip.ip = (guint32) * (guint32 *) (&ia);
meillo@400 34 return g_list_append(NULL, g_memdup(&mxip, sizeof(mxip)));
meillo@0 35 }
meillo@0 36
meillo@10 37 mxip_addr*
meillo@366 38 connect_hostlist(int *psockfd, gchar *host, guint port, GList *addr_list)
meillo@0 39 {
meillo@10 40 GList *addr_node;
meillo@10 41 struct sockaddr_in saddr;
meillo@401 42 int saved_errno;
meillo@0 43
meillo@10 44 DEBUG(5) debugf("connect_hostlist entered\n");
meillo@0 45
meillo@401 46 for (addr_node = g_list_first(addr_list); addr_node;
meillo@401 47 addr_node = g_list_next(addr_node)) {
meillo@10 48 mxip_addr *addr = (mxip_addr *) (addr_node->data);
meillo@10 49 *psockfd = socket(PF_INET, SOCK_STREAM, 0);
meillo@0 50
meillo@10 51 memset(&saddr, 0, sizeof(saddr));
meillo@10 52 saddr.sin_family = AF_INET;
meillo@10 53 saddr.sin_port = htons(port);
meillo@10 54 /* clumsy, but makes compiler happy: */
meillo@10 55 saddr.sin_addr = *(struct in_addr *) (&(addr->ip));
meillo@401 56
meillo@401 57 DEBUG(5) debugf(" trying ip %s port %d\n",
meillo@401 58 inet_ntoa(saddr.sin_addr), port);
meillo@401 59
meillo@401 60 if (connect(*psockfd, (struct sockaddr *) &saddr,
meillo@401 61 sizeof(saddr))==0) {
meillo@401 62 DEBUG(5) debugf(" connected to %s\n",
meillo@401 63 inet_ntoa(saddr.sin_addr));
meillo@10 64 return addr;
meillo@401 65 }
meillo@0 66
meillo@401 67 saved_errno = errno;
meillo@401 68 close(*psockfd);
meillo@401 69 logwrite(LOG_WARNING, "connection to %s failed: %s\n",
meillo@401 70 inet_ntoa(saddr.sin_addr), strerror(errno));
meillo@401 71 errno = saved_errno;
meillo@0 72
meillo@401 73 if ((saved_errno != ECONNREFUSED) &&
meillo@401 74 (saved_errno != ETIMEDOUT) &&
meillo@401 75 (saved_errno != ENETUNREACH) &&
meillo@401 76 (saved_errno != EHOSTUNREACH)) {
meillo@401 77 return NULL;
meillo@10 78 }
meillo@10 79 }
meillo@0 80 return NULL;
meillo@0 81 }
meillo@0 82
meillo@367 83 /*
meillo@367 84 ** Given a list of resolver functions, this function
meillo@367 85 ** resolve the host and tries to connect to the addresses
meillo@367 86 ** returned. If a connection attemp is timed out or refused,
meillo@367 87 ** the next address is tried.
meillo@367 88 **
meillo@367 89 ** TODO: the resolver functions might return duplicate addresses,
meillo@367 90 ** if attempt failed for one it should not be tried again.
meillo@0 91 */
meillo@10 92 mxip_addr*
meillo@401 93 connect_resolvelist(int *psockfd, gchar *host, guint port,
meillo@401 94 GList *res_func_list)
meillo@0 95 {
meillo@10 96 GList *res_node;
meillo@10 97 GList *addr_list;
meillo@0 98
meillo@10 99 DEBUG(5) debugf("connect_resolvelist entered\n");
meillo@0 100
meillo@10 101 h_errno = 0;
meillo@400 102 if (isdigit(*host)) {
meillo@10 103 mxip_addr *addr;
meillo@0 104
meillo@400 105 if ((addr_list = resolve_ip(host))) {
meillo@401 106 addr = connect_hostlist(psockfd, host, port,
meillo@401 107 addr_list);
meillo@10 108 g_list_free(addr_list);
meillo@10 109 return addr;
meillo@10 110 }
meillo@367 111 /*
meillo@400 112 ** Probably a hostname that begins with a digit.
meillo@400 113 ** E.g. '3dwars.de'. Thus fall ...
meillo@367 114 */
meillo@10 115 }
meillo@0 116
meillo@401 117 if (!res_func_list) {
meillo@401 118 logwrite(LOG_ALERT, "res_funcs not set!\n");
meillo@262 119 exit(1);
meillo@10 120 }
meillo@0 121
meillo@10 122 foreach(res_func_list, res_node) {
meillo@10 123 resolve_func res_func;
meillo@114 124 DEBUG(6) debugf(" foreach() body\n");
meillo@10 125
meillo@401 126 res_func = (resolve_func) res_node->data;
meillo@401 127 if (!res_func) {
meillo@401 128 logwrite(LOG_ALERT, "Empty res_func!\n");
meillo@262 129 exit(1);
meillo@10 130 }
meillo@10 131
meillo@10 132 errno = 0;
meillo@10 133 if ((addr_list = res_func(NULL, host))) {
meillo@10 134
meillo@10 135 mxip_addr *addr;
meillo@401 136 if ((addr = connect_hostlist(psockfd, host, port,
meillo@401 137 addr_list))) {
meillo@10 138 return addr;
meillo@10 139 }
meillo@401 140 DEBUG(5) debugf("connect_hostlist failed: %s\n",
meillo@401 141 strerror(errno));
meillo@10 142 g_list_free(addr_list);
meillo@369 143 } else if (!g_list_next(res_node)) {
meillo@401 144 logwrite(LOG_ALERT, "could not resolve %s: %s\n",
meillo@401 145 host, hstrerror(h_errno));
meillo@10 146 }
meillo@10 147 }
meillo@10 148 return NULL;
meillo@0 149
meillo@0 150 }