summaryrefslogtreecommitdiffstats
path: root/plugins/netutils.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/netutils.c')
-rw-r--r--plugins/netutils.c64
1 files changed, 42 insertions, 22 deletions
diff --git a/plugins/netutils.c b/plugins/netutils.c
index 0824527..6f3a151 100644
--- a/plugins/netutils.c
+++ b/plugins/netutils.c
@@ -155,42 +155,46 @@ process_request (const char *server_address, int server_port, int proto,
155} 155}
156 156
157 157
158/* opens a tcp or udp connection to a remote host */ 158/* opens a tcp or udp connection to a remote host or local socket */
159int 159int
160np_net_connect (const char *host_name, int port, int *sd, int proto) 160np_net_connect (const char *host_name, int port, int *sd, int proto)
161{ 161{
162 struct addrinfo hints; 162 struct addrinfo hints;
163 struct addrinfo *res, *res0; 163 struct addrinfo *r, *res;
164 struct sockaddr_un su;
164 char port_str[6]; 165 char port_str[6];
165 int result; 166 int socktype, result;
166 167
167 memset (&hints, 0, sizeof (hints)); 168 socktype = (proto == IPPROTO_UDP) ? SOCK_DGRAM : SOCK_STREAM;
168 hints.ai_family = address_family;
169 hints.ai_protocol = proto;
170 hints.ai_socktype = (proto == IPPROTO_UDP) ? SOCK_DGRAM : SOCK_STREAM;
171 169
172 snprintf (port_str, sizeof (port_str), "%d", port); 170 /* as long as it doesn't start with a '/', it's assumed a host or ip */
173 result = getaddrinfo (host_name, port_str, &hints, &res0); 171 if(host_name[0] != '/'){
172 memset (&hints, 0, sizeof (hints));
173 hints.ai_family = address_family;
174 hints.ai_protocol = proto;
175 hints.ai_socktype = socktype;
174 176
175 if (result != 0) { 177 snprintf (port_str, sizeof (port_str), "%d", port);
176 printf ("%s\n", gai_strerror (result)); 178 result = getaddrinfo (host_name, port_str, &hints, &res);
177 return STATE_UNKNOWN; 179
178 } 180 if (result != 0) {
179 else { 181 printf ("%s\n", gai_strerror (result));
180 res = res0; 182 return STATE_UNKNOWN;
181 while (res) { 183 }
184
185 r = res;
186 while (r) {
182 /* attempt to create a socket */ 187 /* attempt to create a socket */
183 *sd = socket (res->ai_family, (proto == IPPROTO_UDP) ? 188 *sd = socket (r->ai_family, socktype, r->ai_protocol);
184 SOCK_DGRAM : SOCK_STREAM, res->ai_protocol);
185 189
186 if (*sd < 0) { 190 if (*sd < 0) {
187 printf (_("Socket creation failed\n")); 191 printf (_("Socket creation failed\n"));
188 freeaddrinfo (res); 192 freeaddrinfo (r);
189 return STATE_UNKNOWN; 193 return STATE_UNKNOWN;
190 } 194 }
191 195
192 /* attempt to open a connection */ 196 /* attempt to open a connection */
193 result = connect (*sd, res->ai_addr, res->ai_addrlen); 197 result = connect (*sd, r->ai_addr, r->ai_addrlen);
194 198
195 if (result == 0) { 199 if (result == 0) {
196 was_refused = FALSE; 200 was_refused = FALSE;
@@ -206,9 +210,25 @@ np_net_connect (const char *host_name, int port, int *sd, int proto)
206 } 210 }
207 211
208 close (*sd); 212 close (*sd);
209 res = res->ai_next; 213 r = r->ai_next;
214 }
215 freeaddrinfo (res);
216 }
217 /* else the hostname is interpreted as a path to a unix socket */
218 else {
219 if(strlen(host_name) >= UNIX_PATH_MAX){
220 die(_("Supplied path too long unix domain socket"));
221 }
222 memset(&su, 0, sizeof(su));
223 su.sun_family = AF_UNIX;
224 strncpy(su.sun_path, host_name, UNIX_PATH_MAX);
225 *sd = socket(PF_UNIX, SOCK_STREAM, 0);
226 if(sd < 0){
227 die(_("Socket creation failed"));
210 } 228 }
211 freeaddrinfo (res0); 229 result = connect(*sd, (struct sockaddr *)&su, sizeof(su));
230 if (result < 0 && errno == ECONNREFUSED)
231 was_refused = TRUE;
212 } 232 }
213 233
214 if (result == 0) 234 if (result == 0)