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