masqmail

annotate src/mservdetect.c @ 388:aa40710f09fe

Refactoring and code layouting.
author markus schnalke <meillo@marmaro.de>
date Sat, 18 Feb 2012 13:37:40 +0100
parents 41958685480d
children
rev   line source
meillo@367 1 /*
meillo@367 2 ** MasqMail
meillo@367 3 ** Copyright (C) 1999-2001 Oliver Kurth
meillo@367 4 ** Copyright (C) 2010 markus schnalke <meillo@marmaro.de>
meillo@367 5 **
meillo@367 6 ** This program is free software; you can redistribute it and/or modify
meillo@367 7 ** it under the terms of the GNU General Public License as published by
meillo@367 8 ** the Free Software Foundation; either version 2 of the License, or
meillo@367 9 ** (at your option) any later version.
meillo@367 10 **
meillo@367 11 ** This program is distributed in the hope that it will be useful,
meillo@367 12 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
meillo@367 13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
meillo@367 14 ** GNU General Public License for more details.
meillo@367 15 **
meillo@367 16 ** You should have received a copy of the GNU General Public License
meillo@367 17 ** along with this program; if not, write to the Free Software
meillo@367 18 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
meillo@0 19 */
meillo@0 20
meillo@164 21
meillo@0 22 #include "masqmail.h"
meillo@0 23 #include "readsock.h"
meillo@0 24
meillo@0 25
meillo@187 26 gboolean
meillo@366 27 init_sockaddr2(struct sockaddr_in *name, gchar *addr, int port)
meillo@187 28 {
meillo@187 29 struct hostent *he;
meillo@187 30 struct in_addr ia;
meillo@187 31
meillo@188 32 if (inet_aton(addr, &ia) != 0) {
meillo@187 33 /* IP address */
meillo@187 34 memcpy(&(name->sin_addr), &ia, sizeof(name->sin_addr));
meillo@187 35 } else {
meillo@188 36 if ((he = gethostbyname(addr)) == NULL) {
meillo@188 37 fprintf(stderr, "local address '%s' unknown. (deleting)\n", addr);
meillo@187 38 return FALSE;
meillo@187 39 }
meillo@187 40 memcpy(&(name->sin_addr), he->h_addr, sizeof(name->sin_addr));
meillo@187 41 }
meillo@187 42 name->sin_family = AF_INET;
meillo@188 43 name->sin_port = htons(port);
meillo@187 44
meillo@187 45 return TRUE;
meillo@187 46 }
meillo@187 47
meillo@187 48
meillo@164 49 gchar*
meillo@366 50 mserver_detect_online(gchar *addr, int port)
meillo@164 51 {
meillo@164 52 struct sockaddr_in saddr;
meillo@164 53 gchar *ret = NULL;
meillo@164 54
meillo@188 55 if (!init_sockaddr2(&saddr, addr, port)) {
meillo@187 56 return NULL;
meillo@187 57 }
meillo@164 58
meillo@187 59 int sock = socket(PF_INET, SOCK_STREAM, 0);
meillo@187 60 int dup_sock;
meillo@187 61 if (connect(sock, (struct sockaddr *) (&saddr), sizeof(saddr)) != 0) {
meillo@187 62 return NULL;
meillo@187 63 }
meillo@164 64
meillo@187 65 FILE *in, *out;
meillo@187 66 char buf[256];
meillo@187 67
meillo@187 68 dup_sock = dup(sock);
meillo@187 69 out = fdopen(sock, "w");
meillo@187 70 in = fdopen(dup_sock, "r");
meillo@187 71
meillo@187 72 if (!read_sockline(in, buf, 256, 15, READSOCKL_CHUG)) {
meillo@187 73 return NULL;
meillo@187 74 }
meillo@187 75
meillo@367 76 /*
meillo@367 77 ** this is the protocol (reverse engineered):
meillo@367 78 **
meillo@367 79 ** S: READY
meillo@367 80 ** C: STAT
meillo@367 81 ** |
meillo@367 82 ** +----------------+-----------------+
meillo@367 83 ** | | |
meillo@367 84 ** S: DOWN S: UP foo:-1 S: UP foo:1
meillo@367 85 ** C: QUIT C: QUIT C: QUIT
meillo@367 86 **
meillo@367 87 ** -> offline -> offline -> online
meillo@367 88 ** `foo' gets printed
meillo@367 89 **
meillo@187 90 */
meillo@187 91
meillo@187 92 if (strncmp(buf, "READY", 5) == 0) {
meillo@187 93 fprintf(out, "STAT\n");
meillo@187 94 fflush(out);
meillo@187 95 if (read_sockline(in, buf, 256, 15, READSOCKL_CHUG)) {
meillo@187 96 if (strncmp(buf, "DOWN", 4) == 0) {
meillo@187 97 ret = NULL;
meillo@187 98 } else if (strncmp(buf, "UP", 2) == 0) {
meillo@187 99 gchar *p = buf + 3;
meillo@187 100 while ((*p != ':') && *p) {
meillo@187 101 p++;
meillo@187 102 }
meillo@187 103 if (*p) {
meillo@187 104 *p = '\0';
meillo@187 105 p++;
meillo@187 106 if ((atoi(p) >= 0) && *p) {
meillo@187 107 /* `UP foo:N', where `N' is a non-negative number */
meillo@187 108 ret = g_strdup(buf + 3);
meillo@164 109 }
meillo@187 110 } else {
meillo@187 111 fprintf(stderr, "unexpected response from mserver after STAT cmd: %s", buf);
meillo@164 112 }
meillo@187 113 } else {
meillo@187 114 fprintf(stderr, "unexpected response from mserver after STAT cmd: %s", buf);
meillo@164 115 }
meillo@164 116 }
meillo@164 117 }
meillo@187 118 fprintf(out, "QUIT");
meillo@187 119 fflush(out);
meillo@187 120
meillo@187 121 close(sock);
meillo@187 122 close(dup_sock);
meillo@187 123 fclose(in);
meillo@187 124 fclose(out);
meillo@187 125
meillo@164 126 return ret;
meillo@164 127 }
meillo@164 128
meillo@0 129
meillo@10 130 int
meillo@10 131 main(int argc, char *argv[])
meillo@0 132 {
meillo@366 133 gchar *addr;
meillo@188 134 int port;
meillo@187 135 gchar *name;
meillo@0 136
meillo@187 137 if (argc != 3) {
meillo@187 138 fprintf(stderr, "usage: %s HOST PORT\n", argv[0]);
meillo@187 139 return 1;
meillo@187 140 }
meillo@0 141
meillo@188 142 addr = argv[1];
meillo@188 143 port = atoi(argv[2]);
meillo@0 144
meillo@188 145 name = mserver_detect_online(addr, port);
meillo@187 146
meillo@187 147 if (name) {
meillo@10 148 printf("%s\n", name);
meillo@187 149 return 0;
meillo@10 150 }
meillo@187 151 return 1;
meillo@0 152 }