summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gpsd.c178
-rw-r--r--gpsd.h-tail12
-rw-r--r--gpsd.php4
-rw-r--r--gpsdclient.c2
-rw-r--r--gpsmon.c2
-rw-r--r--gpspipe.c2
-rw-r--r--gpspipe.xml2
-rw-r--r--gpxlogger.c5
-rw-r--r--libgps.xml4
-rw-r--r--libgps_core.c10
-rw-r--r--libgpsd_core.c4
-rw-r--r--net_dgpsip.c4
-rw-r--r--net_ntrip.c6
-rw-r--r--netlib.c96
-rwxr-xr-xxgps8
15 files changed, 226 insertions, 113 deletions
diff --git a/gpsd.c b/gpsd.c
index 77e9f098..08007cdd 100644
--- a/gpsd.c
+++ b/gpsd.c
@@ -16,6 +16,8 @@
#ifndef S_SPLINT_S
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
+ #else
+ #define AF_UNSPEC 0
#endif /* HAVE_SYS_SOCKET_H */
#ifdef HAVE_SYS_UN_H
#include <sys/un.h>
@@ -126,6 +128,15 @@
/* Needed because 4.x versions of GCC are really annoying */
#define ignore_return(funcall) assert(funcall != -23)
+/* IP version used by the program */
+/* AF_UNSPEC: all
+ * AF_INET: IPv4 only
+ * AF_INET6: IPv6 only
+ */
+static int af = AF_UNSPEC;
+
+#define AFCOUNT 2
+
static fd_set all_fds;
static int maxfd;
static int debuglevel;
@@ -270,24 +281,17 @@ The following driver types are compiled into this gpsd instance:\n",
}
}
-static int passivesock(char *service, char *protocol, int qlen)
+static int passivesock_af(int af, char *service, char *protocol, int qlen)
{
struct servent *pse;
struct protoent *ppe ; /* splint has a bug here */
- struct sockaddr_in sin;
- int s, type, proto, one = 1;
-
- /*@ -mustfreefresh +matchanyintegral @*/
- memset((char *) &sin, 0, sizeof(sin));
- sin.sin_family = (sa_family_t)AF_INET;
- if (listen_global)
- sin.sin_addr.s_addr = htonl(INADDR_ANY);
- else
- sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+ sockaddr_t sat;
+ int sin_len = 0;
+ int s = -1, port, type, proto, one = 1;
if ((pse = getservbyname(service, protocol)))
- sin.sin_port = htons(ntohs((in_port_t)pse->s_port));
- else if ((sin.sin_port = htons((in_port_t)atoi(service))) == 0) {
+ port = ntohs((in_port_t)pse->s_port);
+ else if ((port = (in_port_t)atoi(service)) == 0) {
gpsd_report(LOG_ERROR, "Can't get \"%s\" service entry.\n", service);
return -1;
}
@@ -299,15 +303,52 @@ static int passivesock(char *service, char *protocol, int qlen)
type = SOCK_STREAM;
/*@i@*/proto = (ppe) ? ppe->p_proto : IPPROTO_TCP;
}
- if ((s = socket(PF_INET, type, proto)) == -1) {
+
+ /*@ -mustfreefresh +matchanyintegral @*/
+ switch(af) {
+ case AF_INET:
+ sin_len = sizeof(sat.sa_in);
+
+ memset((char *) &sat.sa_in, 0, sin_len);
+ sat.sa_in.sin_family = (sa_family_t)AF_INET;
+ if (listen_global)
+ sat.sa_in.sin_addr.s_addr = htonl(INADDR_ANY);
+ else
+ sat.sa_in.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+ sat.sa_in.sin_port = htons(port);
+
+ s = socket(PF_INET, type, proto);
+ break;
+
+ case AF_INET6:
+ sin_len = sizeof(sat.sa_in6);
+
+ memset ((char *) &sat.sa_in6, 0, sin_len);
+ sat.sa_in6.sin6_family = (sa_family_t)AF_INET6;
+ if (listen_global)
+ sat.sa_in6.sin6_addr = in6addr_any;
+ else
+ sat.sa_in6.sin6_addr = in6addr_loopback;
+ sat.sa_in6.sin6_port = htons(port);
+
+ s = socket(PF_INET6, type, proto);
+ break;
+
+ default:
+ gpsd_report(LOG_ERROR, "Unhandled address family %d\n", af);
+ return -1;
+ }
+
+ if (s == -1) {
gpsd_report(LOG_ERROR, "Can't create socket\n");
return -1;
}
- if (setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&one,(int)sizeof(one)) == -1) {
+ if (setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&one,
+ (int)sizeof(one)) == -1) {
gpsd_report(LOG_ERROR, "Error: SETSOCKOPT SO_REUSEADDR\n");
return -1;
}
- if (bind(s, (struct sockaddr *) &sin, (int)sizeof(sin)) == -1) {
+ if (bind(s, &sat.sa, sin_len) < 0) {
gpsd_report(LOG_ERROR, "Can't bind to port %s\n", service);
if (errno == EADDRINUSE) {
gpsd_report(LOG_ERROR, "Maybe gpsd is already running!\n");
@@ -318,10 +359,34 @@ static int passivesock(char *service, char *protocol, int qlen)
gpsd_report(LOG_ERROR, "Can't listen on port %s\n", service);
return -1;
}
+
return s;
/*@ +mustfreefresh -matchanyintegral @*/
}
+static int passivesocks(char *service, char *protocol, int qlen, int socks[AFCOUNT])
+{
+ int numsocks = AFCOUNT;
+ int i;
+
+ for (i=0;i<AFCOUNT;i++)
+ socks[i] = -1;
+
+ if (AF_UNSPEC == af || (AF_INET == af))
+ socks[0] = passivesock_af(AF_INET, service, protocol, qlen);
+
+ if (AF_UNSPEC == af || (AF_INET6 == af))
+ socks[1] = passivesock_af(AF_INET6, service, protocol, qlen);
+
+ for (i=0;i<AFCOUNT;i++)
+ if(socks[i]<0)
+ numsocks--;
+
+ /* Return the number of succesfully openned sockets
+ * The failed ones are identified by negative values */
+ return numsocks;
+}
+
static int filesock(char *filename)
{
struct sockaddr_un addr;
@@ -1809,9 +1874,9 @@ int main(int argc, char *argv[])
static char *gpsd_service = NULL;
static char *control_socket = NULL;
struct gps_device_t *device;
- struct sockaddr_in fsin;
+ sockaddr_t fsin;
fd_set rfds, control_fds;
- int i, option, msock, cfd, dfd;
+ int i, option, msocks[2], cfd, dfd;
bool go_background = true;
struct timeval tv;
struct subscriber_t *sub;
@@ -1933,8 +1998,8 @@ int main(int argc, char *argv[])
if (!gpsd_service)
gpsd_service = getservbyname("gpsd", "tcp") ? "gpsd" : DEFAULT_GPSD_PORT;
/*@ +observertrans @*/
- if ((msock = passivesock(gpsd_service, "tcp", QLEN)) == -1) {
- gpsd_report(LOG_ERR,"command socket create failed, netlib error %d\n",msock);
+ if (passivesocks(gpsd_service, "tcp", QLEN, msocks) < 1) {
+ gpsd_report(LOG_ERR,"command sockets create failed, netlib errors %d, %d\n", msocks[0], msocks[1]);
exit(2);
}
gpsd_report(LOG_INF, "listening on port %s\n", gpsd_service);
@@ -2021,8 +2086,11 @@ int main(int argc, char *argv[])
(void)signal(SIGQUIT, onsig);
(void)signal(SIGPIPE, SIG_IGN);
- FD_SET(msock, &all_fds);
- adjust_max_fd(msock, true);
+ for(i=0; i<AFCOUNT; i++)
+ if (msocks[i] >= 0) {
+ FD_SET(msocks[i], &all_fds);
+ adjust_max_fd(msocks[i], true);
+ }
FD_ZERO(&control_fds);
/* optimization hack to defer having to read subframe data */
@@ -2077,42 +2145,44 @@ int main(int argc, char *argv[])
#endif /* UNUSED */
/* always be open to new client connections */
- if (FD_ISSET(msock, &rfds)) {
- socklen_t alen = (socklen_t)sizeof(fsin);
- char *c_ip;
- /*@i1@*/int ssock = accept(msock, (struct sockaddr *) &fsin, &alen);
-
- if (ssock == -1)
- gpsd_report(LOG_ERROR, "accept: %s\n", strerror(errno));
- else {
- struct subscriber_t *client = NULL;
- int opts = fcntl(ssock, F_GETFL);
-
- if (opts >= 0)
- (void)fcntl(ssock, F_SETFL, opts | O_NONBLOCK);
-
- c_ip = sock2ip(ssock);
- client = allocate_client();
- if (client == NULL) {
- gpsd_report(LOG_ERROR, "Client %s connect on fd %d -"
- "no subscriber slots available\n", c_ip, ssock);
- (void)close(ssock);
- } else {
- char announce[GPS_JSON_RESPONSE_MAX];
- FD_SET(ssock, &all_fds);
- adjust_max_fd(ssock, true);
- client->fd = ssock;
- client->active = timestamp();
+ for(i=0; i<AFCOUNT; i++) {
+ if (msocks[i] >= 0 && FD_ISSET(msocks[i], &rfds)) {
+ socklen_t alen = (socklen_t)sizeof(fsin);
+ char *c_ip;
+ /*@i1@*/int ssock = accept(msocks[i], (struct sockaddr *) &fsin, &alen);
+
+ if (ssock == -1)
+ gpsd_report(LOG_ERROR, "accept: %s\n", strerror(errno));
+ else {
+ struct subscriber_t *client = NULL;
+ int opts = fcntl(ssock, F_GETFL);
+
+ if (opts >= 0)
+ (void)fcntl(ssock, F_SETFL, opts | O_NONBLOCK);
+
+ c_ip = sock2ip(ssock);
+ client = allocate_client();
+ if (client == NULL) {
+ gpsd_report(LOG_ERROR, "Client %s connect on fd %d -"
+ "no subscriber slots available\n", c_ip, ssock);
+ (void)close(ssock);
+ } else {
+ char announce[GPS_JSON_RESPONSE_MAX];
+ FD_SET(ssock, &all_fds);
+ adjust_max_fd(ssock, true);
+ client->fd = ssock;
+ client->active = timestamp();
#ifdef OLDSTYLE_ENABLE
- client->tied = false;
+ client->tied = false;
#endif /* OLDSTYLE_ENABLE */
- gpsd_report(LOG_INF, "client %s (%d) connect on fd %d\n",
- c_ip, sub_index(client), ssock);
- json_version_dump(announce, sizeof(announce));
- (void)throttled_write(client, announce, strlen(announce));
+ gpsd_report(LOG_INF, "client %s (%d) connect on fd %d\n",
+ c_ip, sub_index(client), ssock);
+ json_version_dump(announce, sizeof(announce));
+ (void)throttled_write(client, announce, strlen(announce));
+ }
}
+ FD_CLR(msocks[i], &rfds);
}
- FD_CLR(msock, &rfds);
}
/* also be open to new control-socket connections */
diff --git a/gpsd.h-tail b/gpsd.h-tail
index c8497c65..c8b65d79 100644
--- a/gpsd.h-tail
+++ b/gpsd.h-tail
@@ -489,7 +489,7 @@ extern char /*@observer@*/ *gpsd_id(/*@in@*/struct gps_device_t *);
extern void gpsd_position_fix_dump(struct gps_device_t *, /*@out@*/char[], size_t);
extern void gpsd_error_model(struct gps_device_t *, struct gps_fix_t *, struct gps_fix_t *);
extern void gpsd_clear_data(struct gps_device_t *);
-extern socket_t netlib_connectsock(const char *, const char *, const char *);
+extern socket_t netlib_connectsock(int, const char *, const char *, const char *);
extern char /*@observer@*/ *netlib_errstr(const int);
extern char /*@observer@*/ *sock2ip(int);
@@ -588,6 +588,16 @@ extern float roundf(float x);
void cfmakeraw(struct termios *);
#endif /* defined(__CYGWIN__) */
+/* Conditionnaly define the sockaddr_t union type if the necessary
+ * header files defining the base type have already been included */
+#ifdef _NETINET_IN_H
+typedef union sockaddr_u {
+ struct sockaddr sa;
+ struct sockaddr_in sa_in;
+ struct sockaddr_in6 sa_in6;
+} sockaddr_t;
+#endif /* _NETINET_IN_H */
+
#endif /* _GPSD_H_ */
// Local variables:
// mode: c
diff --git a/gpsd.php b/gpsd.php
index deb668d9..cb1c0ba1 100644
--- a/gpsd.php
+++ b/gpsd.php
@@ -519,8 +519,8 @@ function write_config(){
$buf = <<<EOB
<?PHP
\$title = 'My GPS Server';
-\$server = '127.0.0.1';
-#\$advertise = '127.0.0.1';
+\$server = 'localhost';
+#\$advertise = 'localhost';
\$port = 2947;
\$autorefresh = 0; # number of seconds after which to refresh
\$googlemap = 0; # set to 1 if you want to have a google map
diff --git a/gpsdclient.c b/gpsdclient.c
index 26d88477..1befefd1 100644
--- a/gpsdclient.c
+++ b/gpsdclient.c
@@ -133,7 +133,7 @@ enum unit gpsd_units(void)
void gpsd_source_spec(const char *arg, struct fixsource_t *source)
/* standard parsing of a GPS data source spec */
{
- source->server = "127.0.0.1";
+ source->server = "localhost";
source->port = DEFAULT_GPSD_PORT;
source->device = NULL;
diff --git a/gpsmon.c b/gpsmon.c
index 6627ce2a..1288eae9 100644
--- a/gpsmon.c
+++ b/gpsmon.c
@@ -52,8 +52,6 @@
extern struct tm *localtime_r(const time_t *,/*@out@*/struct tm *tp)/*@modifies tp@*/;
#endif /* S_SPLINT_S */
-extern socket_t netlib_connectsock(const char *, const char *, const char *);
-
#define BUFLEN 2048
/* external capability tables */
diff --git a/gpspipe.c b/gpspipe.c
index 27b04040..41983964 100644
--- a/gpspipe.c
+++ b/gpspipe.c
@@ -168,7 +168,7 @@ int main( int argc, char **argv)
unsigned int flags;
struct fixsource_t source;
- char *port = DEFAULT_GPSD_PORT, *server = "127.0.0.1";
+ char *port = DEFAULT_GPSD_PORT, *server = NULL;
char *serialport = NULL;
char *outfile = NULL;
diff --git a/gpspipe.xml b/gpspipe.xml
index e3fefcea..8176b034 100644
--- a/gpspipe.xml
+++ b/gpspipe.xml
@@ -54,7 +54,7 @@ time stamped. There is also an option to exit gracefully after a
given count of packets.</para>
<para>Optionally a server, TCP/IP port number and remote device can be given.
-If omitted, <application>gpspipe</application> connects to 127.0.0.1 on
+If omitted, <application>gpspipe</application> connects to localhost on
the default port (2947) and watches all devices opened by
<application>gpsd</application>.</para>
diff --git a/gpxlogger.c b/gpxlogger.c
index 4e49f4a7..2e4d1628 100644
--- a/gpxlogger.c
+++ b/gpxlogger.c
@@ -7,7 +7,6 @@
#ifdef HAVE_SYSLOG_H
#include <syslog.h>
#endif /* HAVE_SYSLOG_H */
-#include <syslog.h>
#include <math.h>
#include <time.h>
#include <signal.h>
@@ -337,7 +336,7 @@ static void usage(void)
"Usage: %s [-V] [-h] [-i timeout] [-j casoc] [server[:port:[device]]]\n",
progname);
fprintf(stderr,
- "\tdefaults to '%s -i 5 -j 0 127.0.0.1:2947'\n",
+ "\tdefaults to '%s -i 5 -j 0 localhost:2947'\n",
progname);
exit(1);
}
@@ -395,7 +394,7 @@ int main (int argc, char** argv)
print_gpx_header ();
#ifdef DBUS_ENABLE
- /* To force socket use in the default way just give a '127.0.0.1' arg */
+ /* To force socket use in the default way just give a 'localhost' arg */
if (optind < argc)
return socket_mainloop();
else
diff --git a/libgps.xml b/libgps.xml
index 5993a189..7588bceb 100644
--- a/libgps.xml
+++ b/libgps.xml
@@ -24,11 +24,13 @@ C:
</funcsynopsisinfo>
<funcprototype>
<funcdef>struct gps_data_t *<function>gps_open</function></funcdef>
+ <paramdef>int<parameter>af</parameter></paramdef>
<paramdef>char *<parameter>server</parameter></paramdef>
<paramdef>char * <parameter>port</parameter></paramdef>
</funcprototype>
<funcprototype>
<funcdef>int <function>gps_open_r</function></funcdef>
+ <paramdef>int<parameter>af</parameter></paramdef>
<paramdef>char *<parameter>server</parameter></paramdef>
<paramdef>char * <parameter>port</parameter></paramdef>
<paramdef>struct gps_data_t *<parameter>gpsdata</parameter></paramdef>
@@ -72,7 +74,7 @@ Python:
import gps
-session = gps.gps(host="127.0.0.1", port="2947")
+session = gps.gps(host="localhost", port="2947")
session.set_raw_hook(raw_hook)
diff --git a/libgps_core.c b/libgps_core.c
index 03cfad1f..8d529520 100644
--- a/libgps_core.c
+++ b/libgps_core.c
@@ -21,6 +21,8 @@
#ifndef S_SPLINT_S
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
+#else
+#define AF_UNSPEC 0
#endif
#endif
#if defined (HAVE_SYS_SELECT_H)
@@ -77,19 +79,19 @@ static void gps_trace(int errlevel, const char *fmt, ... )
#endif /* LIBGPS_DEBUG */
/*@-nullderef@*/
-int gps_open_r(const char *host, const char *port,
+int gps_open_r(const char *host, const char *port,
/*@out@*/struct gps_data_t *gpsdata)
{
/*@ -branchstate @*/
if (!gpsdata)
return -1;
if (!host)
- host = "127.0.0.1";
+ host = "localhost";
if (!port)
port = DEFAULT_GPSD_PORT;
- libgps_debug_trace((1, "gps_open_r(%s, %s)\n", host, port));
- if ((gpsdata->gps_fd = netlib_connectsock(host, port, "tcp")) < 0) {
+ libgps_debug_trace((1, "gps_open_r(..., %s, %s)\n", host, port));
+ if ((gpsdata->gps_fd = netlib_connectsock(AF_UNSPEC, host, port, "tcp")) < 0) {
errno = gpsdata->gps_fd;
return -1;
}
diff --git a/libgpsd_core.c b/libgpsd_core.c
index 4d121792..0a79c6d4 100644
--- a/libgpsd_core.c
+++ b/libgpsd_core.c
@@ -9,6 +9,8 @@
#ifndef S_SPLINT_S
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
+ #else
+ #define AF_UNSPEC 0
#endif /* HAVE_SYS_SOCKET_H */
#include <unistd.h>
#endif /* S_SPLINT_S */
@@ -326,7 +328,7 @@ int gpsd_activate(struct gps_device_t *session)
}
*port++ = '\0';
gpsd_report(LOG_INF, "opening AIS feed at %s, port %s.\n", server,port);
- if ((dsock = netlib_connectsock(server, port, "tcp")) < 0) {
+ if ((dsock = netlib_connectsock(AF_UNSPEC, server, port, "tcp")) < 0) {
gpsd_report(LOG_ERROR, "AIS device open error %s.\n",
netlib_errstr(dsock));
return -1;
diff --git a/net_dgpsip.c b/net_dgpsip.c
index 9829d2bb..94f2de4f 100644
--- a/net_dgpsip.c
+++ b/net_dgpsip.c
@@ -6,6 +6,8 @@
#ifndef S_SPLINT_S
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
+ #else
+ #define AF_UNSPEC 0
#endif /* HAVE_SYS_SOCKET_H */
#include <unistd.h>
#endif /* S_SPLINT_S */
@@ -38,7 +40,7 @@ int dgpsip_open(struct gps_context_t *context, const char *dgpsserver)
if (!getservbyname(dgpsport, "tcp"))
dgpsport = DEFAULT_RTCM_PORT;
- context->dsock = netlib_connectsock(dgpsserver, dgpsport, "tcp");
+ context->dsock = netlib_connectsock(AF_UNSPEC, dgpsserver, dgpsport, "tcp");
if (context->dsock >= 0) {
gpsd_report(LOG_PROG,"connection to DGPS server %s established.\n",dgpsserver);
(void)gethostname(hn, sizeof(hn));
diff --git a/net_ntrip.c b/net_ntrip.c
index 55339b54..cc4cfc55 100644
--- a/net_ntrip.c
+++ b/net_ntrip.c
@@ -6,6 +6,8 @@
#ifndef S_SPLINT_S
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
+ #else
+ #define AF_UNSPEC 0
#endif /* HAVE_SYS_SOCKET_H */
#include <unistd.h>
#endif /* S_SPLINT_S */
@@ -289,7 +291,7 @@ static int ntrip_stream_probe(const char *caster,
socket_t dsock;
char buf[BUFSIZ];
- if ((dsock = netlib_connectsock(caster, port, "tcp")) == -1) {
+ if ((dsock = netlib_connectsock(AF_UNSPEC, caster, port, "tcp")) == -1) {
printf("ntrip stream connect error %d\n", dsock);
return -1;
}
@@ -346,7 +348,7 @@ static int ntrip_stream_open(const char *caster,
caster, port, stream->mountpoint);
return -1;
}
- if ((context->dsock = netlib_connectsock(caster, port, "tcp")) < 0)
+ if ((context->dsock = netlib_connectsock(AF_UNSPEC, caster, port, "tcp")) < 0)
return -1;
(void)snprintf(buf, sizeof(buf),
diff --git a/netlib.c b/netlib.c
index 10d4df5b..fb83fc37 100644
--- a/netlib.c
+++ b/netlib.c
@@ -38,29 +38,13 @@
#define INADDR_NONE ((in_addr_t)-1)
#endif
-socket_t netlib_connectsock(const char *host, const char *service, const char *protocol)
+socket_t netlib_connectsock(int af, const char *host, const char *service, const char *protocol)
{
- struct hostent *phe;
- struct servent *pse;
struct protoent *ppe;
- struct sockaddr_in sin;
- int type, proto, one = 1;
- socket_t s;
-
- memset((char *) &sin, 0, sizeof(sin));
- /*@ -type -mustfreefresh @*/
- sin.sin_family = AF_INET;
- if ((pse = getservbyname(service, protocol)))
- sin.sin_port = htons(ntohs((unsigned short) pse->s_port));
- else if ((sin.sin_port = htons((unsigned short) atoi(service))) == 0)
- return NL_NOSERVICE;
-
- if ((phe = gethostbyname(host)))
- memcpy((char *) &sin.sin_addr, phe->h_addr, phe->h_length);
-#ifndef S_SPLINT_S
- else if ((sin.sin_addr.s_addr = inet_addr(host)) == INADDR_NONE)
- return NL_NOHOST;
-#endif /* S_SPLINT_S */
+ struct addrinfo hints;
+ struct addrinfo *result, *rp;
+ int ret, type, proto, one = 1;
+ socket_t s = -1;
ppe = getprotobyname(protocol);
if (strcmp(protocol, "udp") == 0) {
@@ -71,16 +55,41 @@ socket_t netlib_connectsock(const char *host, const char *service, const char *p
proto = (ppe) ? ppe->p_proto : IPPROTO_TCP;
}
- if ((s = socket(PF_INET, type, proto)) == -1)
- return NL_NOSOCK;
- if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one))==-1) {
- (void)close(s);
- return NL_NOSOCKOPT;
+ memset(&hints, 0, sizeof(struct addrinfo));
+ hints.ai_family = af;
+ hints.ai_socktype = type;
+ hints.ai_protocol = proto;
+ if((ret = getaddrinfo(host, service, &hints, &result))) {
+ return NL_NOHOST;
}
- if (connect(s, (struct sockaddr *) &sin, sizeof(sin)) == -1) {
- (void)close(s);
- return NL_NOCONNECT;
+
+ /*
+ * From getaddrinfo(3):
+ * Normally, the application should try using the addresses in the
+ * order in which they are returned. The sorting function used within
+ * getaddrinfo() is defined in RFC 3484).
+ * From RFC 3484 (Section 10.3):
+ * The default policy table gives IPv6 addresses higher precedence than
+ * IPv4 addresses.
+ * Thus, with the default palameters, we get IPv6 addresses first.
+ */
+ for (rp = result; rp != NULL; rp = rp->ai_next) {
+ ret = NL_NOCONNECT;
+ if((s = socket(rp->ai_family, rp->ai_socktype,
+ rp->ai_protocol)) < 0)
+ ret = NL_NOSOCK;
+ else if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one))==-1)
+ ret = NL_NOSOCKOPT;
+ else if (!connect(s, rp->ai_addr, rp->ai_addrlen)) {
+ ret = 0;
+ break;
+ }
+
+ if (s > 0) close(s);
}
+ freeaddrinfo(result);
+ if (ret)
+ return ret;
#ifdef IPTOS_LOWDELAY
{
@@ -113,18 +122,35 @@ char /*@observer@*/ *netlib_errstr(const int err)
char *sock2ip(int fd)
{
- struct sockaddr fsin;
+ sockaddr_t fsin;
socklen_t alen = (socklen_t)sizeof(fsin);
- char *ip;
+ static char ip[INET6_ADDRSTRLEN];
int r;
- r = getpeername(fd, (struct sockaddr *) &fsin, &alen);
+ r = getpeername(fd, &(fsin.sa), &alen);
/*@ -branchstate @*/
if (r == 0) {
- ip = inet_ntoa(((struct sockaddr_in *)(&fsin))->sin_addr);
- } else {
+ switch (fsin.sa.sa_family) {
+ case AF_INET:
+ r = !inet_ntop(fsin.sa_in.sin_family, &(fsin.sa_in.sin_addr),
+ ip, sizeof(ip));
+ break;
+
+ case AF_INET6:
+ r = !inet_ntop(fsin.sa_in6.sin6_family, &(fsin.sa_in6.sin6_addr),
+ ip, sizeof(ip));
+ break;
+
+ default:
+ gpsd_report(LOG_ERROR, "Unhandled address family %d in %s\n",
+ fsin.sa.sa_family, __FUNCTION__);
+ strlcpy(ip,"<unknown AF>", sizeof(ip));
+ return ip;
+ }
+ }
+ if (r != 0){
gpsd_report(LOG_INF, "getpeername() = %d, error = %s (%d)\n", r, strerror(errno), errno);
- ip = "<unknown>";
+ strlcpy(ip,"<unknown>", sizeof(ip));
}
/*@ +branchstate @*/
return ip;
diff --git a/xgps b/xgps
index a5de895c..188ceee4 100755
--- a/xgps
+++ b/xgps
@@ -98,9 +98,9 @@ class SkyView(gtk.DrawingArea):
az *= (math.pi/180) # Degrees to radians
# Exact spherical projection would be like this:
# el = sin((90.0 - el) * DEG_2_RAD);
- el = ((90.0 - el) / 90.0);
- xout = int((self.width / 2) + math.sin(az) * el * (self.diameter / 2))
- yout = int((self.height / 2) - math.cos(az) * el * (self.diameter / 2))
+ el = ((90.0 - el) / 90.0);
+ xout = int((self.width / 2) + math.sin(az) * el * (self.diameter / 2))
+ yout = int((self.height / 2) - math.cos(az) * el * (self.diameter / 2))
return (xout, yout)
def on_expose_event(self, widget, event):
@@ -623,7 +623,7 @@ if __name__ == "__main__":
's':gps.client.deg_ddmmss}[degreefmt]
if len(arguments) == 0:
- host = "127.0.0.1"
+ host = "localhost"
else:
host = arguments[0]