You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

100 lines
2.7 KiB

  1. /*
  2. * Management of the rdnssd instance that we use to get DNS info out of
  3. * RAs.
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write to the Free Software
  17. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  18. */
  19. #include "netcfg.h"
  20. #include <errno.h>
  21. #include <string.h>
  22. #include <stdlib.h>
  23. #include <sys/types.h>
  24. #include <signal.h>
  25. #include <debian-installer.h>
  26. static pid_t rdnssd_pid;
  27. /* Spawn an rdnssd child process.
  28. *
  29. * Returns 1 on a successful start, and 0 on error. Stores the child pid in
  30. * a module-internal global variable, as this is easier than trying to pass
  31. * it around everywhere (given that we'll need to get at it in a signal
  32. * handler...)
  33. */
  34. int start_rdnssd(struct debconfclient *client)
  35. {
  36. if ((rdnssd_pid = fork()) == 0) { /* Child */
  37. /* Dissociate from debconf */
  38. fclose(client->out);
  39. /* Kick things off */
  40. execlp("rdnssd", "rdnssd", "-f", "-u", "root", "-r", "/tmp/rdnssd_resolv", NULL);
  41. /* If we get here, something went wrong */
  42. di_error("Could not exec dnssd: %s", strerror(errno));
  43. exit(1);
  44. } else if (rdnssd_pid == -1) {
  45. di_warning("rdnssd fork failed: %s", strerror(errno));
  46. return 0;
  47. } else {
  48. di_debug("rdnssd started; PID: %i", rdnssd_pid);
  49. return 1;
  50. }
  51. }
  52. /* Cleanup after the rdnssd process if/when it exits
  53. *
  54. * This gets called from the SIGCHLD handler to see if it was rdnssd that
  55. * exited, and if so, perform whatever cleanup tasks were necessary.
  56. */
  57. void cleanup_rdnssd()
  58. {
  59. int exit_status;
  60. if (rdnssd_pid == -1)
  61. /* Definitely wasn't us */
  62. return;
  63. if (waitpid(rdnssd_pid, &exit_status, WNOHANG) != rdnssd_pid)
  64. /* Not us either */
  65. return;
  66. if (WIFEXITED(exit_status))
  67. /* Yep, that was me */
  68. rdnssd_pid = -1;
  69. }
  70. /* Read the nameserver entries that rdnssd may have written out into the
  71. * interface struct.
  72. */
  73. void read_rdnssd_nameservers(struct netcfg_interface *interface)
  74. {
  75. read_resolv_conf_nameservers("/tmp/rdnssd_resolv", interface);
  76. }
  77. /* Stop the rdnssd client process.
  78. */
  79. void stop_rdnssd()
  80. {
  81. if (rdnssd_pid == -1) {
  82. /* We're not running... that would be bad */
  83. return;
  84. }
  85. di_debug("Stopping rdnssd, PID %i", rdnssd_pid);
  86. kill(rdnssd_pid, SIGTERM);
  87. }