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