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