meillo@367: /* meillo@367: ** MasqMail meillo@367: ** Copyright (C) 1999-2001 Oliver Kurth meillo@367: ** Copyright (C) 2010 markus schnalke meillo@367: ** meillo@367: ** This program is free software; you can redistribute it and/or modify meillo@367: ** it under the terms of the GNU General Public License as published by meillo@367: ** the Free Software Foundation; either version 2 of the License, or meillo@367: ** (at your option) any later version. meillo@367: ** meillo@367: ** This program is distributed in the hope that it will be useful, meillo@367: ** but WITHOUT ANY WARRANTY; without even the implied warranty of meillo@367: ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the meillo@367: ** GNU General Public License for more details. meillo@367: ** meillo@367: ** You should have received a copy of the GNU General Public License meillo@367: ** along with this program; if not, write to the Free Software meillo@367: ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. meillo@0: */ meillo@0: meillo@164: meillo@0: #include "masqmail.h" meillo@0: #include "readsock.h" meillo@0: meillo@0: meillo@187: gboolean meillo@366: init_sockaddr2(struct sockaddr_in *name, gchar *addr, int port) meillo@187: { meillo@187: struct hostent *he; meillo@187: struct in_addr ia; meillo@187: meillo@188: if (inet_aton(addr, &ia) != 0) { meillo@187: /* IP address */ meillo@187: memcpy(&(name->sin_addr), &ia, sizeof(name->sin_addr)); meillo@187: } else { meillo@188: if ((he = gethostbyname(addr)) == NULL) { meillo@188: fprintf(stderr, "local address '%s' unknown. (deleting)\n", addr); meillo@187: return FALSE; meillo@187: } meillo@187: memcpy(&(name->sin_addr), he->h_addr, sizeof(name->sin_addr)); meillo@187: } meillo@187: name->sin_family = AF_INET; meillo@188: name->sin_port = htons(port); meillo@187: meillo@187: return TRUE; meillo@187: } meillo@187: meillo@187: meillo@164: gchar* meillo@366: mserver_detect_online(gchar *addr, int port) meillo@164: { meillo@164: struct sockaddr_in saddr; meillo@164: gchar *ret = NULL; meillo@164: meillo@188: if (!init_sockaddr2(&saddr, addr, port)) { meillo@187: return NULL; meillo@187: } meillo@164: meillo@187: int sock = socket(PF_INET, SOCK_STREAM, 0); meillo@187: int dup_sock; meillo@187: if (connect(sock, (struct sockaddr *) (&saddr), sizeof(saddr)) != 0) { meillo@187: return NULL; meillo@187: } meillo@164: meillo@187: FILE *in, *out; meillo@187: char buf[256]; meillo@187: meillo@187: dup_sock = dup(sock); meillo@187: out = fdopen(sock, "w"); meillo@187: in = fdopen(dup_sock, "r"); meillo@187: meillo@187: if (!read_sockline(in, buf, 256, 15, READSOCKL_CHUG)) { meillo@187: return NULL; meillo@187: } meillo@187: meillo@367: /* meillo@367: ** this is the protocol (reverse engineered): meillo@367: ** meillo@367: ** S: READY meillo@367: ** C: STAT meillo@367: ** | meillo@367: ** +----------------+-----------------+ meillo@367: ** | | | meillo@367: ** S: DOWN S: UP foo:-1 S: UP foo:1 meillo@367: ** C: QUIT C: QUIT C: QUIT meillo@367: ** meillo@367: ** -> offline -> offline -> online meillo@367: ** `foo' gets printed meillo@367: ** meillo@187: */ meillo@187: meillo@187: if (strncmp(buf, "READY", 5) == 0) { meillo@187: fprintf(out, "STAT\n"); meillo@187: fflush(out); meillo@187: if (read_sockline(in, buf, 256, 15, READSOCKL_CHUG)) { meillo@187: if (strncmp(buf, "DOWN", 4) == 0) { meillo@187: ret = NULL; meillo@187: } else if (strncmp(buf, "UP", 2) == 0) { meillo@187: gchar *p = buf + 3; meillo@187: while ((*p != ':') && *p) { meillo@187: p++; meillo@187: } meillo@187: if (*p) { meillo@187: *p = '\0'; meillo@187: p++; meillo@187: if ((atoi(p) >= 0) && *p) { meillo@187: /* `UP foo:N', where `N' is a non-negative number */ meillo@187: ret = g_strdup(buf + 3); meillo@164: } meillo@187: } else { meillo@187: fprintf(stderr, "unexpected response from mserver after STAT cmd: %s", buf); meillo@164: } meillo@187: } else { meillo@187: fprintf(stderr, "unexpected response from mserver after STAT cmd: %s", buf); meillo@164: } meillo@164: } meillo@164: } meillo@187: fprintf(out, "QUIT"); meillo@187: fflush(out); meillo@187: meillo@187: close(sock); meillo@187: close(dup_sock); meillo@187: fclose(in); meillo@187: fclose(out); meillo@187: meillo@164: return ret; meillo@164: } meillo@164: meillo@0: meillo@10: int meillo@10: main(int argc, char *argv[]) meillo@0: { meillo@366: gchar *addr; meillo@188: int port; meillo@187: gchar *name; meillo@0: meillo@187: if (argc != 3) { meillo@187: fprintf(stderr, "usage: %s HOST PORT\n", argv[0]); meillo@187: return 1; meillo@187: } meillo@0: meillo@188: addr = argv[1]; meillo@188: port = atoi(argv[2]); meillo@0: meillo@188: name = mserver_detect_online(addr, port); meillo@187: meillo@187: if (name) { meillo@10: printf("%s\n", name); meillo@187: return 0; meillo@10: } meillo@187: return 1; meillo@0: }