hostid.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. /*
  2. * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
  3. *
  4. * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  5. */
  6. #define __FORCE_GLIBC
  7. #include <features.h>
  8. #include <stdio.h>
  9. #include <string.h>
  10. #include <errno.h>
  11. #include <sys/param.h>
  12. #include <netinet/in.h>
  13. #include <netdb.h>
  14. #include <fcntl.h>
  15. #include <unistd.h>
  16. /* Experimentally off - libc_hidden_proto(memcpy) */
  17. libc_hidden_proto(open)
  18. libc_hidden_proto(close)
  19. libc_hidden_proto(read)
  20. libc_hidden_proto(write)
  21. libc_hidden_proto(getuid)
  22. libc_hidden_proto(geteuid)
  23. libc_hidden_proto(gethostbyname)
  24. libc_hidden_proto(gethostname)
  25. #define HOSTID "/etc/hostid"
  26. #ifdef __USE_BSD
  27. int sethostid(long int new_id)
  28. {
  29. int fd;
  30. int ret;
  31. if (geteuid() || getuid()) return __set_errno(EPERM);
  32. if ((fd=open(HOSTID,O_CREAT|O_WRONLY,0644))<0) return -1;
  33. ret = write(fd,(void *)&new_id,sizeof(new_id)) == sizeof(new_id)
  34. ? 0 : -1;
  35. close (fd);
  36. return ret;
  37. }
  38. #endif
  39. long int gethostid(void)
  40. {
  41. char host[MAXHOSTNAMELEN + 1];
  42. int fd, id;
  43. /* If hostid was already set then we can return that value.
  44. * It is not an error if we cannot read this file. It is not even an
  45. * error if we cannot read all the bytes, we just carry on trying...
  46. */
  47. if ((fd=open(HOSTID,O_RDONLY))>=0 && read(fd,(void *)&id,sizeof(id)))
  48. {
  49. close (fd);
  50. return id;
  51. }
  52. if (fd >= 0) close (fd);
  53. /* Try some methods of returning a unique 32 bit id. Clearly IP
  54. * numbers, if on the internet, will have a unique address. If they
  55. * are not on the internet then we can return 0 which means they should
  56. * really set this number via a sethostid() call. If their hostname
  57. * returns the loopback number (i.e. if they have put their hostname
  58. * in the /etc/hosts file with 127.0.0.1) then all such hosts will
  59. * have a non-unique hostid, but it doesn't matter anyway and
  60. * gethostid() will return a non zero number without the need for
  61. * setting one anyway.
  62. * Mitch
  63. */
  64. if (gethostname(host,MAXHOSTNAMELEN)>=0 && *host) {
  65. struct hostent *hp;
  66. struct in_addr in;
  67. struct hostent ghbn_h;
  68. char ghbn_buf[sizeof(struct in_addr) +
  69. sizeof(struct in_addr *)*2 +
  70. sizeof(char *)*((2 + 5/*MAX_ALIASES*/ +
  71. 1)/*ALIAS_DIM*/) +
  72. 256/*namebuffer*/ + 32/* margin */];
  73. int ghbn_errno;
  74. /* replace gethostbyname() with gethostbyname_r() - ron@zing.net */
  75. /*if ((hp = gethostbyname(host)) == (struct hostent *)NULL)*/
  76. gethostbyname_r(host, &ghbn_h, ghbn_buf, sizeof(ghbn_buf), &hp, &ghbn_errno);
  77. if (hp == (struct hostent *)NULL)
  78. /* This is not a error if we get here, as all it means is that
  79. * this host is not on a network and/or they have not
  80. * configured their network properly. So we return the unset
  81. * hostid which should be 0, meaning that they should set it !!
  82. */
  83. return 0;
  84. else {
  85. memcpy((char *) &in, (char *) hp->h_addr, hp->h_length);
  86. /* Just so it doesn't look exactly like the IP addr */
  87. return(in.s_addr<<16|in.s_addr>>16);
  88. }
  89. }
  90. else return 0;
  91. }