]> diplodocus.org Git - nmh/blob - sbr/client.c
d3374ad4862b934c4a62df3aeeed9bf124c3698a
[nmh] / sbr / client.c
1
2 /*
3 * client.c -- connect to a server
4 *
5 * $Id$
6 *
7 * This code is Copyright (c) 2002, by the authors of nmh. See the
8 * COPYRIGHT file in the root directory of the nmh distribution for
9 * complete copyright information.
10 */
11
12 #include <h/mh.h>
13 #include <h/mts.h>
14 #include <h/utils.h>
15 #include <errno.h>
16 #include <sys/socket.h>
17 #include <netinet/in.h>
18 #include <netdb.h>
19
20 #ifdef HAVE_ARPA_INET_H
21 # include <arpa/inet.h>
22 #endif
23
24 #define TRUE 1
25 #define FALSE 0
26
27 #define MAXARGS 1000
28
29 /*
30 * static prototypes
31 */
32
33 /* client's own static version of several nmh subroutines */
34 static char **client_brkstring (char *, char *, char *);
35 static int client_brkany (char, char *);
36 static char **client_copyip (char **, char **, int);
37 static char *client_getcpy (char *);
38 static void client_freelist(char **);
39
40
41 int
42 client (char *args, char *service, char *response, int len_response, int debug)
43 {
44 int sd, rc;
45 char **ap, *arguments[MAXARGS];
46 struct addrinfo hints, *res, *ai;
47
48 ap = arguments;
49 if (args != NULL && *args != 0) {
50 ap = client_copyip (client_brkstring (client_getcpy (args), " ", "\n"),
51 ap, MAXARGS);
52 } else {
53 if (servers != NULL && *servers != 0)
54 ap = client_copyip (client_brkstring (client_getcpy (servers), " ", "\n"),
55 ap, MAXARGS);
56 }
57 if (ap == arguments) {
58 *ap++ = client_getcpy ("localhost");
59 *ap = NULL;
60 }
61
62 memset(&hints, 0, sizeof(hints));
63 #ifdef AI_ADDRCONFIG
64 hints.ai_flags = AI_ADDRCONFIG;
65 #endif
66 hints.ai_family = PF_UNSPEC;
67 hints.ai_socktype = SOCK_STREAM;
68
69 for (ap = arguments; *ap; ap++) {
70
71 if (debug) {
72 fprintf(stderr, "Trying to connect to \"%s\" ...\n", *ap);
73 }
74
75 rc = getaddrinfo(*ap, service, &hints, &res);
76
77 if (rc) {
78 if (debug) {
79 fprintf(stderr, "Lookup of \"%s\" failed: %s\n", *ap,
80 gai_strerror(rc));
81 }
82 continue;
83 }
84
85 for (ai = res; ai != NULL; ai = ai->ai_next) {
86 if (debug) {
87 char address[NI_MAXHOST];
88
89 rc = getnameinfo(ai->ai_addr, ai->ai_addrlen, address,
90 sizeof(address), NULL, 0, NI_NUMERICHOST);
91
92 fprintf(stderr, "Connecting to %s...\n",
93 rc ? "unknown" : address);
94 }
95
96 sd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
97
98 if (sd < 0) {
99 if (debug)
100 fprintf(stderr, "socket() failed: %s\n", strerror(errno));
101 continue;
102 }
103
104 if (connect(sd, ai->ai_addr, ai->ai_addrlen) == 0) {
105 freeaddrinfo(res);
106 client_freelist(ap);
107 return sd;
108 }
109
110 if (debug) {
111 fprintf(stderr, "Connection failed: %s\n", strerror(errno));
112 }
113
114 close(sd);
115 }
116
117 freeaddrinfo(res);
118 }
119
120 client_freelist(ap);
121 strncpy (response, "no servers available", len_response);
122 return NOTOK;
123 }
124
125
126 /*
127 * Free a list of strings
128 */
129
130 static void
131 client_freelist(char **list)
132 {
133 while (*list++ != NULL)
134 free(*list);
135 }
136
137
138 /*
139 * static copies of three nmh subroutines
140 */
141
142 static char *broken[MAXARGS + 1];
143
144 static char **
145 client_brkstring (char *strg, char *brksep, char *brkterm)
146 {
147 register int bi;
148 register char c, *sp;
149
150 sp = strg;
151
152 for (bi = 0; bi < MAXARGS; bi++) {
153 while (client_brkany (c = *sp, brksep))
154 *sp++ = 0;
155 if (!c || client_brkany (c, brkterm)) {
156 *sp = 0;
157 broken[bi] = 0;
158 return broken;
159 }
160
161 broken[bi] = sp;
162 while ((c = *++sp) && !client_brkany (c, brksep) && !client_brkany (c, brkterm))
163 continue;
164 }
165 broken[MAXARGS] = 0;
166
167 return broken;
168 }
169
170
171 /*
172 * returns 1 if chr in strg, 0 otherwise
173 */
174 static int
175 client_brkany (char chr, char *strg)
176 {
177 register char *sp;
178
179 if (strg)
180 for (sp = strg; *sp; sp++)
181 if (chr == *sp)
182 return 1;
183 return 0;
184 }
185
186
187 /*
188 * copy a string array and return pointer to end
189 */
190 static char **
191 client_copyip (char **p, char **q, int len_q)
192 {
193 while (*p && --len_q > 0)
194 *q++ = *p++;
195
196 *q = NULL;
197
198 return q;
199 }
200
201
202 static char *
203 client_getcpy (char *str)
204 {
205 char *cp;
206 size_t len;
207
208 len = strlen(str) + 1;
209 cp = mh_xmalloc(len);
210
211 memcpy (cp, str, len);
212 return cp;
213 }
214