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