2 * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
4 * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
12 #include <sys/param.h>
13 #include <netinet/in.h>
18 libc_hidden_proto(memcpy)
19 libc_hidden_proto(open)
20 libc_hidden_proto(close)
21 libc_hidden_proto(read)
22 libc_hidden_proto(write)
23 libc_hidden_proto(getuid)
24 libc_hidden_proto(geteuid)
25 libc_hidden_proto(gethostbyname)
26 libc_hidden_proto(gethostname)
28 #define HOSTID "/etc/hostid"
30 int sethostid(long int new_id)
35 if (geteuid() || getuid()) return __set_errno(EPERM);
36 if ((fd=open(HOSTID,O_CREAT|O_WRONLY,0644))<0) return -1;
37 ret = write(fd,(void *)&new_id,sizeof(new_id)) == sizeof(new_id)
43 long int gethostid(void)
45 char host[MAXHOSTNAMELEN + 1];
48 /* If hostid was already set the we can return that value.
49 * It is not an error if we cannot read this file. It is not even an
50 * error if we cannot read all the bytes, we just carry on trying...
52 if ((fd=open(HOSTID,O_RDONLY))>=0 && read(fd,(void *)&id,sizeof(id)))
57 if (fd >= 0) close (fd);
59 /* Try some methods of returning a unique 32 bit id. Clearly IP
60 * numbers, if on the internet, will have a unique address. If they
61 * are not on the internet then we can return 0 which means they should
62 * really set this number via a sethostid() call. If their hostname
63 * returns the loopback number (i.e. if they have put their hostname
64 * in the /etc/hosts file with 127.0.0.1) then all such hosts will
65 * have a non-unique hostid, but it doesn't matter anyway and
66 * gethostid() will return a non zero number without the need for
70 if (gethostname(host,MAXHOSTNAMELEN)>=0 && *host) {
74 if ((hp = gethostbyname(host)) == (struct hostent *)NULL)
76 /* This is not a error if we get here, as all it means is that
77 * this host is not on a network and/or they have not
78 * configured their network properly. So we return the unset
79 * hostid which should be 0, meaning that they should set it !!
83 memcpy((char *) &in, (char *) hp->h_addr, hp->h_length);
85 /* Just so it doesn't look exactly like the IP addr */
86 return(in.s_addr<<16|in.s_addr>>16);