hostid.c 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. #define geteuid __geteuid
  2. #define getuid __getuid
  3. #define __FORCE_GLIBC
  4. #include <features.h>
  5. #include <stdio.h>
  6. #include <string.h>
  7. #include <errno.h>
  8. #include <sys/param.h>
  9. #include <netinet/in.h>
  10. #include <netdb.h>
  11. #include <fcntl.h>
  12. #include <unistd.h>
  13. #define HOSTID "/etc/hostid"
  14. int sethostid(long int new_id)
  15. {
  16. int fd;
  17. int ret;
  18. if (geteuid() || getuid()) return __set_errno(EPERM);
  19. if ((fd=__open(HOSTID,O_CREAT|O_WRONLY,0644))<0) return -1;
  20. ret = __write(fd,(void *)&new_id,sizeof(new_id)) == sizeof(new_id)
  21. ? 0 : -1;
  22. __close (fd);
  23. return ret;
  24. }
  25. long int gethostid(void)
  26. {
  27. char host[MAXHOSTNAMELEN + 1];
  28. int fd, id;
  29. /* If hostid was already set the we can return that value.
  30. * It is not an error if we cannot read this file. It is not even an
  31. * error if we cannot read all the bytes, we just carry on trying...
  32. */
  33. if ((fd=__open(HOSTID,O_RDONLY))>=0 && __read(fd,(void *)&id,sizeof(id)))
  34. {
  35. __close (fd);
  36. return id;
  37. }
  38. if (fd >= 0) __close (fd);
  39. /* Try some methods of returning a unique 32 bit id. Clearly IP
  40. * numbers, if on the internet, will have a unique address. If they
  41. * are not on the internet then we can return 0 which means they should
  42. * really set this number via a sethostid() call. If their hostname
  43. * returns the loopback number (i.e. if they have put their hostname
  44. * in the /etc/hosts file with 127.0.0.1) then all such hosts will
  45. * have a non-unique hostid, but it doesn't matter anyway and
  46. * gethostid() will return a non zero number without the need for
  47. * setting one anyway.
  48. * Mitch
  49. */
  50. if (gethostname(host,MAXHOSTNAMELEN)>=0 && *host) {
  51. struct hostent *hp;
  52. struct in_addr in;
  53. if ((hp = gethostbyname(host)) == (struct hostent *)NULL)
  54. /* This is not a error if we get here, as all it means is that
  55. * this host is not on a network and/or they have not
  56. * configured their network properly. So we return the unset
  57. * hostid which should be 0, meaning that they should set it !!
  58. */
  59. return 0;
  60. else {
  61. __memcpy((char *) &in, (char *) hp->h_addr, hp->h_length);
  62. /* Just so it doesn't look exactly like the IP addr */
  63. return(in.s_addr<<16|in.s_addr>>16);
  64. }
  65. }
  66. else return 0;
  67. }