masqmail

annotate src/mservdetect.c @ 237:5f9f3a65032e

refactoring: new function split_rcpts() replaces two others split_rcpts() merges rcptlist_with_one_of_hostlist() and rcptlist_with_addr_is_local() into one with hardly adding complexity I'd actually say that the overall complexity decreased. Have a look at the comment for split_rcpts() in route.c
author markus schnalke <meillo@marmaro.de>
date Fri, 22 Oct 2010 11:56:47 -0300
parents bd7c52a36b0c
children 41958685480d
rev   line source
meillo@0 1 /* MasqMail
meillo@0 2 Copyright (C) 1999-2001 Oliver Kurth
meillo@187 3 Copyright (C) 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@164 20
meillo@0 21 #include "masqmail.h"
meillo@0 22 #include "readsock.h"
meillo@0 23
meillo@0 24
meillo@187 25 gboolean
meillo@188 26 init_sockaddr2(struct sockaddr_in * name, gchar* addr, int port)
meillo@187 27 {
meillo@187 28 struct hostent *he;
meillo@187 29 struct in_addr ia;
meillo@187 30
meillo@188 31 if (inet_aton(addr, &ia) != 0) {
meillo@187 32 /* IP address */
meillo@187 33 memcpy(&(name->sin_addr), &ia, sizeof(name->sin_addr));
meillo@187 34 } else {
meillo@188 35 if ((he = gethostbyname(addr)) == NULL) {
meillo@188 36 fprintf(stderr, "local address '%s' unknown. (deleting)\n", addr);
meillo@187 37 return FALSE;
meillo@187 38 }
meillo@187 39 memcpy(&(name->sin_addr), he->h_addr, sizeof(name->sin_addr));
meillo@187 40 }
meillo@187 41 name->sin_family = AF_INET;
meillo@188 42 name->sin_port = htons(port);
meillo@187 43
meillo@187 44 return TRUE;
meillo@187 45 }
meillo@187 46
meillo@187 47
meillo@164 48 gchar*
meillo@188 49 mserver_detect_online(gchar* addr, int port)
meillo@164 50 {
meillo@164 51 struct sockaddr_in saddr;
meillo@164 52 gchar *ret = NULL;
meillo@164 53
meillo@188 54 if (!init_sockaddr2(&saddr, addr, port)) {
meillo@187 55 return NULL;
meillo@187 56 }
meillo@164 57
meillo@187 58 int sock = socket(PF_INET, SOCK_STREAM, 0);
meillo@187 59 int dup_sock;
meillo@187 60 if (connect(sock, (struct sockaddr *) (&saddr), sizeof(saddr)) != 0) {
meillo@187 61 return NULL;
meillo@187 62 }
meillo@164 63
meillo@187 64 FILE *in, *out;
meillo@187 65 char buf[256];
meillo@187 66
meillo@187 67 dup_sock = dup(sock);
meillo@187 68 out = fdopen(sock, "w");
meillo@187 69 in = fdopen(dup_sock, "r");
meillo@187 70
meillo@187 71 if (!read_sockline(in, buf, 256, 15, READSOCKL_CHUG)) {
meillo@187 72 return NULL;
meillo@187 73 }
meillo@187 74
meillo@187 75 /* this is the protocol (reverse engineered):
meillo@188 76
meillo@188 77 S: READY
meillo@188 78 C: STAT
meillo@188 79 |
meillo@188 80 +----------------+-----------------+
meillo@188 81 | | |
meillo@188 82 S: DOWN S: UP foo:-1 S: UP foo:1
meillo@188 83 C: QUIT C: QUIT C: QUIT
meillo@188 84
meillo@188 85 -> offline -> offline -> online
meillo@188 86 `foo' gets printed
meillo@188 87
meillo@187 88 */
meillo@187 89
meillo@187 90 if (strncmp(buf, "READY", 5) == 0) {
meillo@187 91 fprintf(out, "STAT\n");
meillo@187 92 fflush(out);
meillo@187 93 if (read_sockline(in, buf, 256, 15, READSOCKL_CHUG)) {
meillo@187 94 if (strncmp(buf, "DOWN", 4) == 0) {
meillo@187 95 ret = NULL;
meillo@187 96 } else if (strncmp(buf, "UP", 2) == 0) {
meillo@187 97 gchar *p = buf + 3;
meillo@187 98 while ((*p != ':') && *p) {
meillo@187 99 p++;
meillo@187 100 }
meillo@187 101 if (*p) {
meillo@187 102 *p = '\0';
meillo@187 103 p++;
meillo@187 104 if ((atoi(p) >= 0) && *p) {
meillo@187 105 /* `UP foo:N', where `N' is a non-negative number */
meillo@187 106 ret = g_strdup(buf + 3);
meillo@164 107 }
meillo@187 108 } else {
meillo@187 109 fprintf(stderr, "unexpected response from mserver after STAT cmd: %s", buf);
meillo@164 110 }
meillo@187 111 } else {
meillo@187 112 fprintf(stderr, "unexpected response from mserver after STAT cmd: %s", buf);
meillo@164 113 }
meillo@164 114 }
meillo@164 115 }
meillo@187 116 fprintf(out, "QUIT");
meillo@187 117 fflush(out);
meillo@187 118
meillo@187 119 close(sock);
meillo@187 120 close(dup_sock);
meillo@187 121 fclose(in);
meillo@187 122 fclose(out);
meillo@187 123
meillo@164 124 return ret;
meillo@164 125 }
meillo@164 126
meillo@0 127
meillo@10 128 int
meillo@10 129 main(int argc, char *argv[])
meillo@0 130 {
meillo@188 131 gchar* addr;
meillo@188 132 int port;
meillo@187 133 gchar *name;
meillo@0 134
meillo@187 135 if (argc != 3) {
meillo@187 136 fprintf(stderr, "usage: %s HOST PORT\n", argv[0]);
meillo@187 137 return 1;
meillo@187 138 }
meillo@0 139
meillo@188 140 addr = argv[1];
meillo@188 141 port = atoi(argv[2]);
meillo@0 142
meillo@188 143 name = mserver_detect_online(addr, port);
meillo@187 144
meillo@187 145 if (name) {
meillo@10 146 printf("%s\n", name);
meillo@187 147 return 0;
meillo@10 148 }
meillo@187 149 return 1;
meillo@0 150 }