Mercurial > masqmail
comparison src/mservdetect.c @ 188:bfa7a8b566da
refactoring and simplifications in mservdetect
author | meillo@marmaro.de |
---|---|
date | Thu, 15 Jul 2010 00:33:09 +0200 |
parents | bd7c52a36b0c |
children | 41958685480d |
comparison
equal
deleted
inserted
replaced
187:bd7c52a36b0c | 188:bfa7a8b566da |
---|---|
16 along with this program; if not, write to the Free Software | 16 along with this program; if not, write to the Free Software |
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | 17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
18 */ | 18 */ |
19 | 19 |
20 | 20 |
21 #include "config.h" | |
22 #include "masqmail.h" | 21 #include "masqmail.h" |
23 #include "readsock.h" | 22 #include "readsock.h" |
24 | 23 |
25 | 24 |
26 | |
27 gboolean | 25 gboolean |
28 init_sockaddr(struct sockaddr_in * name, interface * iface) | 26 init_sockaddr2(struct sockaddr_in * name, gchar* addr, int port) |
29 { | 27 { |
30 struct hostent *he; | 28 struct hostent *he; |
31 struct in_addr ia; | 29 struct in_addr ia; |
32 | 30 |
33 if (inet_aton(iface->address, &ia) != 0) { | 31 if (inet_aton(addr, &ia) != 0) { |
34 /* IP address */ | 32 /* IP address */ |
35 memcpy(&(name->sin_addr), &ia, sizeof(name->sin_addr)); | 33 memcpy(&(name->sin_addr), &ia, sizeof(name->sin_addr)); |
36 } else { | 34 } else { |
37 if ((he = gethostbyname(iface->address)) == NULL) { | 35 if ((he = gethostbyname(addr)) == NULL) { |
38 logwrite(LOG_ALERT, "local address '%s' unknown. (deleting)\n", iface->address); | 36 fprintf(stderr, "local address '%s' unknown. (deleting)\n", addr); |
39 return FALSE; | 37 return FALSE; |
40 } | 38 } |
41 memcpy(&(name->sin_addr), he->h_addr, sizeof(name->sin_addr)); | 39 memcpy(&(name->sin_addr), he->h_addr, sizeof(name->sin_addr)); |
42 } | 40 } |
43 name->sin_family = AF_INET; | 41 name->sin_family = AF_INET; |
44 name->sin_port = htons(iface->port); | 42 name->sin_port = htons(port); |
45 | 43 |
46 return TRUE; | 44 return TRUE; |
47 } | 45 } |
48 | 46 |
49 | 47 |
50 int | |
51 make_server_socket(interface * iface) | |
52 { | |
53 int sock = -1; | |
54 struct sockaddr_in server; | |
55 | |
56 memset(&server, 0, sizeof(struct sockaddr_in)); | |
57 | |
58 /* Create the socket. */ | |
59 sock = socket(PF_INET, SOCK_STREAM, 0); | |
60 if (sock < 0) { | |
61 logwrite(LOG_ALERT, "socket: %s\n", strerror(errno)); | |
62 return -1; | |
63 } | |
64 | |
65 if (init_sockaddr(&server, iface)) { | |
66 /* bind the socket */ | |
67 if (bind(sock, (struct sockaddr *) &server, sizeof(server)) < 0) { | |
68 logwrite(LOG_ALERT, "bind: %s\n", strerror(errno)); | |
69 return -1; | |
70 } | |
71 } else { | |
72 close(sock); | |
73 return -1; | |
74 } | |
75 | |
76 return sock; | |
77 } | |
78 | |
79 | |
80 | |
81 | |
82 gchar* | 48 gchar* |
83 mserver_detect_online(interface * iface) | 49 mserver_detect_online(gchar* addr, int port) |
84 { | 50 { |
85 struct sockaddr_in saddr; | 51 struct sockaddr_in saddr; |
86 gchar *ret = NULL; | 52 gchar *ret = NULL; |
87 | 53 |
88 if (!init_sockaddr(&saddr, iface)) { | 54 if (!init_sockaddr2(&saddr, addr, port)) { |
89 return NULL; | 55 return NULL; |
90 } | 56 } |
91 | 57 |
92 int sock = socket(PF_INET, SOCK_STREAM, 0); | 58 int sock = socket(PF_INET, SOCK_STREAM, 0); |
93 int dup_sock; | 59 int dup_sock; |
105 if (!read_sockline(in, buf, 256, 15, READSOCKL_CHUG)) { | 71 if (!read_sockline(in, buf, 256, 15, READSOCKL_CHUG)) { |
106 return NULL; | 72 return NULL; |
107 } | 73 } |
108 | 74 |
109 /* this is the protocol (reverse engineered): | 75 /* this is the protocol (reverse engineered): |
110 S: READY | 76 |
111 C: STAT | 77 S: READY |
112 S: DOWN | 78 C: STAT |
113 C: QUIT | 79 | |
114 -> offline | 80 +----------------+-----------------+ |
115 | 81 | | | |
116 S: READY | 82 S: DOWN S: UP foo:-1 S: UP foo:1 |
117 C: STAT | 83 C: QUIT C: QUIT C: QUIT |
118 S: UP foo:-1 | 84 |
119 C: QUIT | 85 -> offline -> offline -> online |
120 -> offline | 86 `foo' gets printed |
121 | 87 |
122 S: READY | |
123 C: STAT | |
124 S: UP foo:1 | |
125 C: QUIT | |
126 -> online, `foo' gets printed | |
127 */ | 88 */ |
128 | 89 |
129 if (strncmp(buf, "READY", 5) == 0) { | 90 if (strncmp(buf, "READY", 5) == 0) { |
130 fprintf(out, "STAT\n"); | 91 fprintf(out, "STAT\n"); |
131 fflush(out); | 92 fflush(out); |
162 | 123 |
163 return ret; | 124 return ret; |
164 } | 125 } |
165 | 126 |
166 | 127 |
167 void | |
168 logwrite(int pri, const char *fmt, ...) | |
169 { | |
170 va_list args; | |
171 va_start(args, fmt); | |
172 | |
173 vfprintf(stderr, fmt, args); | |
174 | |
175 va_end(args); | |
176 } | |
177 | |
178 | |
179 int | 128 int |
180 main(int argc, char *argv[]) | 129 main(int argc, char *argv[]) |
181 { | 130 { |
182 interface iface; | 131 gchar* addr; |
132 int port; | |
183 gchar *name; | 133 gchar *name; |
184 | 134 |
185 if (argc != 3) { | 135 if (argc != 3) { |
186 fprintf(stderr, "usage: %s HOST PORT\n", argv[0]); | 136 fprintf(stderr, "usage: %s HOST PORT\n", argv[0]); |
187 return 1; | 137 return 1; |
188 } | 138 } |
189 | 139 |
190 iface.address = g_strdup(argv[1]); | 140 addr = argv[1]; |
191 iface.port = atoi(argv[2]); | 141 port = atoi(argv[2]); |
192 | 142 |
193 name = mserver_detect_online(&iface); | 143 name = mserver_detect_online(addr, port); |
194 | 144 |
195 if (name) { | 145 if (name) { |
196 printf("%s\n", name); | 146 printf("%s\n", name); |
197 return 0; | 147 return 0; |
198 } | 148 } |