No empty .Rs/.Re
[netbsd-mini2440.git] / external / bsd / bind / dist / bin / named / win32 / os.c
blob5343632da75675daa6000b93022b6bbdc7dd39b5
1 /* $NetBSD$ */
3 /*
4 * Copyright (C) 2004, 2005, 2007-2009 Internet Systems Consortium, Inc. ("ISC")
5 * Copyright (C) 1999-2002 Internet Software Consortium.
7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17 * PERFORMANCE OF THIS SOFTWARE.
20 /* Id: os.c,v 1.37 2009/08/05 18:43:37 each Exp */
22 #include <config.h>
23 #include <stdarg.h>
25 #include <sys/types.h>
26 #include <sys/stat.h>
28 #include <ctype.h>
29 #include <errno.h>
30 #include <io.h>
31 #include <process.h>
32 #include <fcntl.h>
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <syslog.h>
37 #include <isc/print.h>
38 #include <isc/result.h>
39 #include <isc/strerror.h>
40 #include <isc/string.h>
41 #include <isc/ntpaths.h>
42 #include <isc/util.h>
43 #include <isc/win32os.h>
45 #include <named/main.h>
46 #include <named/log.h>
47 #include <named/os.h>
48 #include <named/globals.h>
49 #include <named/ntservice.h>
52 static char *pidfile = NULL;
53 static int devnullfd = -1;
55 static BOOL Initialized = FALSE;
57 static char *version_error =
58 "named requires Windows 2000 Service Pack 2 or later to run correctly";
60 void
61 ns_paths_init() {
62 if (!Initialized)
63 isc_ntpaths_init();
65 ns_g_conffile = isc_ntpaths_get(NAMED_CONF_PATH);
66 lwresd_g_conffile = isc_ntpaths_get(LWRES_CONF_PATH);
67 lwresd_g_resolvconffile = isc_ntpaths_get(RESOLV_CONF_PATH);
68 ns_g_conffile = isc_ntpaths_get(NAMED_CONF_PATH);
69 ns_g_defaultpidfile = isc_ntpaths_get(NAMED_PID_PATH);
70 lwresd_g_defaultpidfile = isc_ntpaths_get(LWRESD_PID_PATH);
71 ns_g_keyfile = isc_ntpaths_get(RNDC_KEY_PATH);
72 ns_g_defaultsessionkeyfile = isc_ntpaths_get(SESSION_KEY_PATH);
74 Initialized = TRUE;
78 * Due to Knowledge base article Q263823 we need to make sure that
79 * Windows 2000 systems have Service Pack 2 or later installed and
80 * warn when it isn't.
82 static void
83 version_check(const char *progname) {
85 if(isc_win32os_majorversion() < 5)
86 return; /* No problem with Version 4.0 */
87 if(isc_win32os_versioncheck(5, 0, 2, 0) < 0)
88 if (ntservice_isservice())
89 NTReportError(progname, version_error);
90 else
91 fprintf(stderr, "%s\n", version_error);
94 static void
95 setup_syslog(const char *progname) {
96 int options;
98 options = LOG_PID;
99 #ifdef LOG_NDELAY
100 options |= LOG_NDELAY;
101 #endif
103 openlog(progname, options, LOG_DAEMON);
106 void
107 ns_os_init(const char *progname) {
108 ns_paths_init();
109 setup_syslog(progname);
111 * XXXMPA. We may need to split ntservice_init() in two and
112 * just mark as running in ns_os_started(). If we do that
113 * this is where the first part of ntservice_init() should be
114 * called from.
116 * XXX970 Remove comment if no problems by 9.7.0.
118 * ntservice_init();
120 version_check(progname);
123 void
124 ns_os_daemonize(void) {
126 * Try to set stdin, stdout, and stderr to /dev/null, but press
127 * on even if it fails.
129 if (devnullfd != -1) {
130 if (devnullfd != _fileno(stdin)) {
131 close(_fileno(stdin));
132 (void)_dup2(devnullfd, _fileno(stdin));
134 if (devnullfd != _fileno(stdout)) {
135 close(_fileno(stdout));
136 (void)_dup2(devnullfd, _fileno(stdout));
138 if (devnullfd != _fileno(stderr)) {
139 close(_fileno(stderr));
140 (void)_dup2(devnullfd, _fileno(stderr));
145 void
146 ns_os_opendevnull(void) {
147 devnullfd = open("NUL", O_RDWR, 0);
150 void
151 ns_os_closedevnull(void) {
152 if (devnullfd != _fileno(stdin) &&
153 devnullfd != _fileno(stdout) &&
154 devnullfd != _fileno(stderr)) {
155 close(devnullfd);
156 devnullfd = -1;
160 void
161 ns_os_chroot(const char *root) {
162 if (root != NULL)
163 ns_main_earlyfatal("chroot(): isn't supported by Win32 API");
166 void
167 ns_os_inituserinfo(const char *username) {
170 void
171 ns_os_changeuser(void) {
174 void
175 ns_os_adjustnofile(void) {
178 void
179 ns_os_minprivs(void) {
182 static int
183 safe_open(const char *filename, int mode, isc_boolean_t append) {
184 int fd;
185 struct stat sb;
187 if (stat(filename, &sb) == -1) {
188 if (errno != ENOENT)
189 return (-1);
190 } else if ((sb.st_mode & S_IFREG) == 0)
191 return (-1);
193 if (append)
194 fd = open(filename, O_WRONLY|O_CREAT|O_APPEND, mode);
195 else {
196 (void)unlink(filename);
197 fd = open(filename, O_WRONLY|O_CREAT|O_EXCL, mode);
199 return (fd);
202 static void
203 cleanup_pidfile(void) {
204 if (pidfile != NULL) {
205 (void)unlink(pidfile);
206 free(pidfile);
208 pidfile = NULL;
211 FILE *
212 ns_os_openfile(const char *filename, int mode, isc_boolean_t switch_user) {
213 char strbuf[ISC_STRERRORSIZE];
214 FILE *fp;
215 int fd;
217 UNUSED(switch_user);
218 fd = safe_open(filename, mode, ISC_FALSE);
219 if (fd < 0) {
220 isc__strerror(errno, strbuf, sizeof(strbuf));
221 ns_main_earlywarning("could not open file '%s': %s",
222 filename, strbuf);
225 fp = fdopen(fd, "w");
226 if (fp == NULL) {
227 isc__strerror(errno, strbuf, sizeof(strbuf));
228 ns_main_earlywarning("could not fdopen() file '%s': %s",
229 filename, strbuf);
230 close(fd);
233 return (fp);
236 void
237 ns_os_writepidfile(const char *filename, isc_boolean_t first_time) {
238 FILE *lockfile;
239 pid_t pid;
240 char strbuf[ISC_STRERRORSIZE];
241 void (*report)(const char *, ...);
244 * The caller must ensure any required synchronization.
247 report = first_time ? ns_main_earlyfatal : ns_main_earlywarning;
249 cleanup_pidfile();
251 if (filename == NULL)
252 return;
254 pidfile = strdup(filename);
255 if (pidfile == NULL) {
256 isc__strerror(errno, strbuf, sizeof(strbuf));
257 (*report)("couldn't strdup() '%s': %s", filename, strbuf);
258 return;
261 lockfile = ns_os_openfile(filename, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH,
262 ISC_FALSE);
263 if (lockfile == NULL) {
264 free(pidfile);
265 pidfile = NULL;
266 return;
269 pid = getpid();
271 if (fprintf(lockfile, "%ld\n", (long)pid) < 0) {
272 (*report)("fprintf() to pid file '%s' failed", filename);
273 (void)fclose(lockfile);
274 cleanup_pidfile();
275 return;
277 if (fflush(lockfile) == EOF) {
278 (*report)("fflush() to pid file '%s' failed", filename);
279 (void)fclose(lockfile);
280 cleanup_pidfile();
281 return;
283 (void)fclose(lockfile);
286 void
287 ns_os_shutdown(void) {
288 closelog();
289 cleanup_pidfile();
290 ntservice_shutdown(); /* This MUST be the last thing done */
293 isc_result_t
294 ns_os_gethostname(char *buf, size_t len) {
295 int n;
297 n = gethostname(buf, len);
298 return ((n == 0) ? ISC_R_SUCCESS : ISC_R_FAILURE);
301 void
302 ns_os_shutdownmsg(char *command, isc_buffer_t *text) {
303 UNUSED(command);
304 UNUSED(text);
307 void
308 ns_os_tzset(void) {
309 #ifdef HAVE_TZSET
310 tzset();
311 #endif
314 void
315 ns_os_started(void) {
316 ntservice_init();