summaryrefslogtreecommitdiff
path: root/libc/inet
diff options
context:
space:
mode:
Diffstat (limited to 'libc/inet')
-rw-r--r--libc/inet/Makefile2
-rw-r--r--libc/inet/hostid.c74
2 files changed, 75 insertions, 1 deletions
diff --git a/libc/inet/Makefile b/libc/inet/Makefile
index e5f11ee51..1e9ac365d 100644
--- a/libc/inet/Makefile
+++ b/libc/inet/Makefile
@@ -41,7 +41,7 @@ MOBJ3= accept.o bind.o connect.o getpeername.o getsockname.o getsockopt.o \
listen.o recv.o recvfrom.o recvmsg.o send.o sendmsg.o sendto.o \
setsockopt.o shutdown.o socket.o socketpair.o
-CSRC =getservice.c getproto.c
+CSRC =getservice.c getproto.c hostid.c
COBJS=$(patsubst %.c,%.o, $(CSRC))
OBJS=$(MOBJ) $(MOBJ2) $(MOBJ3) $(COBJS)
diff --git a/libc/inet/hostid.c b/libc/inet/hostid.c
new file mode 100644
index 000000000..475eaf497
--- /dev/null
+++ b/libc/inet/hostid.c
@@ -0,0 +1,74 @@
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/param.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+
+#define HOSTID "/etc/hostid"
+
+int sethostid(long int new_id)
+{
+ int fd;
+ int ret;
+
+ if (geteuid() || getuid()) return errno=EPERM;
+ if ((fd=open(HOSTID,O_CREAT|O_WRONLY,0644))<0) return -1;
+ ret = write(fd,(void *)&new_id,sizeof(new_id)) == sizeof(new_id)
+ ? 0 : -1;
+ close (fd);
+ return ret;
+}
+
+long int gethostid(void)
+{
+ char host[MAXHOSTNAMELEN + 1];
+ int fd, id;
+
+ /* If hostid was already set the we can return that value.
+ * It is not an error if we cannot read this file. It is not even an
+ * error if we cannot read all the bytes, we just carry on trying...
+ */
+ if ((fd=open(HOSTID,O_RDONLY))>=0 && read(fd,(void *)&id,sizeof(id)))
+ {
+ close (fd);
+ return id;
+ }
+ if (fd >= 0) close (fd);
+
+ /* Try some methods of returning a unique 32 bit id. Clearly IP
+ * numbers, if on the internet, will have a unique address. If they
+ * are not on the internet then we can return 0 which means they should
+ * really set this number via a sethostid() call. If their hostname
+ * returns the loopback number (i.e. if they have put their hostname
+ * in the /etc/hosts file with 127.0.0.1) then all such hosts will
+ * have a non-unique hostid, but it doesn't matter anyway and
+ * gethostid() will return a non zero number without the need for
+ * setting one anyway.
+ * Mitch
+ */
+ if (gethostname(host,MAXHOSTNAMELEN)>=0 && *host) {
+ struct hostent *hp;
+ struct in_addr in;
+
+ if ((hp = gethostbyname(host)) == (struct hostent *)NULL)
+
+ /* This is not a error if we get here, as all it means is that
+ * this host is not on a network and/or they have not
+ * configured their network properly. So we return the unset
+ * hostid which should be 0, meaning that they should set it !!
+ */
+ return 0;
+ else {
+ memcpy((char *) &in, (char *) hp->h_addr, hp->h_length);
+
+ /* Just so it doesn't look exactly like the IP addr */
+ return(in.s_addr<<16|in.s_addr>>16);
+ }
+ }
+ else return 0;
+
+}