hostid.c 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  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. 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. int sethostid(long int new_id)
  27. {
  28. int fd;
  29. int ret;
  30. if (geteuid() || getuid()) return __set_errno(EPERM);
  31. if ((fd=open(HOSTID,O_CREAT|O_WRONLY,0644))<0) return -1;
  32. ret = write(fd,(void *)&new_id,sizeof(new_id)) == sizeof(new_id)
  33. ? 0 : -1;
  34. close (fd);
  35. return ret;
  36. }
  37. long int gethostid(void)
  38. {
  39. char host[MAXHOSTNAMELEN + 1];
  40. int fd, id;
  41. /* If hostid was already set the we can return that value.
  42. * It is not an error if we cannot read this file. It is not even an
  43. * error if we cannot read all the bytes, we just carry on trying...
  44. */
  45. if ((fd=open(HOSTID,O_RDONLY))>=0 && read(fd,(void *)&id,sizeof(id)))
  46. {
  47. close (fd);
  48. return id;
  49. }
  50. if (fd >= 0) close (fd);
  51. /* Try some methods of returning a unique 32 bit id. Clearly IP
  52. * numbers, if on the internet, will have a unique address. If they
  53. * are not on the internet then we can return 0 which means they should
  54. * really set this number via a sethostid() call. If their hostname
  55. * returns the loopback number (i.e. if they have put their hostname
  56. * in the /etc/hosts file with 127.0.0.1) then all such hosts will
  57. * have a non-unique hostid, but it doesn't matter anyway and
  58. * gethostid() will return a non zero number without the need for
  59. * setting one anyway.
  60. * Mitch
  61. */
  62. if (gethostname(host,MAXHOSTNAMELEN)>=0 && *host) {
  63. struct hostent *hp;
  64. struct in_addr in;
  65. if ((hp = gethostbyname(host)) == (struct hostent *)NULL)
  66. /* This is not a error if we get here, as all it means is that
  67. * this host is not on a network and/or they have not
  68. * configured their network properly. So we return the unset
  69. * hostid which should be 0, meaning that they should set it !!
  70. */
  71. return 0;
  72. else {
  73. memcpy((char *) &in, (char *) hp->h_addr, hp->h_length);
  74. /* Just so it doesn't look exactly like the IP addr */
  75. return(in.s_addr<<16|in.s_addr>>16);
  76. }
  77. }
  78. else return 0;
  79. }