1 /* $NetBSD: os.c,v 1.8 2015/07/08 17:28:55 christos Exp $ */
4 * Copyright (C) 2004, 2005, 2007-2009, 2012-2015 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.39 2012/02/06 23:46:44 tbox Exp */
25 #include <sys/types.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>
43 #include <isc/win32os.h>
45 #include <named/main.h>
46 #include <named/log.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";
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
);
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
83 version_check(const char *progname
) {
85 if ((isc_win32os_versioncheck(4, 0, 0, 0) >= 0) &&
86 (isc_win32os_versioncheck(5, 0, 0, 0) < 0))
87 return; /* No problem with Version 4.0 */
88 if (isc_win32os_versioncheck(5, 0, 2, 0) < 0)
89 if (ntservice_isservice())
90 NTReportError(progname
, version_error
);
92 fprintf(stderr
, "%s\n", version_error
);
96 setup_syslog(const char *progname
) {
101 options
|= LOG_NDELAY
;
104 openlog(progname
, options
, LOG_DAEMON
);
108 ns_os_init(const char *progname
) {
110 setup_syslog(progname
);
112 * XXXMPA. We may need to split ntservice_init() in two and
113 * just mark as running in ns_os_started(). If we do that
114 * this is where the first part of ntservice_init() should be
117 * XXX970 Remove comment if no problems by 9.7.0.
121 version_check(progname
);
125 ns_os_daemonize(void) {
127 * Try to set stdin, stdout, and stderr to /dev/null, but press
128 * on even if it fails.
130 if (devnullfd
!= -1) {
131 if (devnullfd
!= _fileno(stdin
)) {
132 close(_fileno(stdin
));
133 (void)_dup2(devnullfd
, _fileno(stdin
));
135 if (devnullfd
!= _fileno(stdout
)) {
136 close(_fileno(stdout
));
137 (void)_dup2(devnullfd
, _fileno(stdout
));
139 if (devnullfd
!= _fileno(stderr
)) {
140 close(_fileno(stderr
));
141 (void)_dup2(devnullfd
, _fileno(stderr
));
147 ns_os_opendevnull(void) {
148 devnullfd
= open("NUL", O_RDWR
, 0);
152 ns_os_closedevnull(void) {
153 if (devnullfd
!= _fileno(stdin
) &&
154 devnullfd
!= _fileno(stdout
) &&
155 devnullfd
!= _fileno(stderr
)) {
162 ns_os_chroot(const char *root
) {
164 ns_main_earlyfatal("chroot(): isn't supported by Win32 API");
168 ns_os_inituserinfo(const char *username
) {
172 ns_os_changeuser(void) {
176 ns_os_adjustnofile(void) {
180 ns_os_minprivs(void) {
184 safe_open(const char *filename
, int mode
, isc_boolean_t append
) {
188 if (stat(filename
, &sb
) == -1) {
191 } else if ((sb
.st_mode
& S_IFREG
) == 0)
195 fd
= open(filename
, O_WRONLY
|O_CREAT
|O_APPEND
, mode
);
197 (void)unlink(filename
);
198 fd
= open(filename
, O_WRONLY
|O_CREAT
|O_EXCL
, mode
);
204 cleanup_pidfile(void) {
205 if (pidfile
!= NULL
) {
206 (void)unlink(pidfile
);
213 ns_os_openfile(const char *filename
, int mode
, isc_boolean_t switch_user
) {
214 char strbuf
[ISC_STRERRORSIZE
];
219 fd
= safe_open(filename
, mode
, ISC_FALSE
);
221 isc__strerror(errno
, strbuf
, sizeof(strbuf
));
222 ns_main_earlywarning("could not open file '%s': %s",
227 fp
= fdopen(fd
, "w");
229 isc__strerror(errno
, strbuf
, sizeof(strbuf
));
230 ns_main_earlywarning("could not fdopen() file '%s': %s",
239 ns_os_writepidfile(const char *filename
, isc_boolean_t first_time
) {
242 char strbuf
[ISC_STRERRORSIZE
];
243 void (*report
)(const char *, ...);
246 * The caller must ensure any required synchronization.
249 report
= first_time
? ns_main_earlyfatal
: ns_main_earlywarning
;
253 if (filename
== NULL
)
256 pidfile
= strdup(filename
);
257 if (pidfile
== NULL
) {
258 isc__strerror(errno
, strbuf
, sizeof(strbuf
));
259 (*report
)("couldn't strdup() '%s': %s", filename
, strbuf
);
263 lockfile
= ns_os_openfile(filename
, S_IRUSR
|S_IWUSR
|S_IRGRP
|S_IROTH
,
265 if (lockfile
== NULL
) {
273 if (fprintf(lockfile
, "%ld\n", (long)pid
) < 0) {
274 (*report
)("fprintf() to pid file '%s' failed", filename
);
275 (void)fclose(lockfile
);
279 if (fflush(lockfile
) == EOF
) {
280 (*report
)("fflush() to pid file '%s' failed", filename
);
281 (void)fclose(lockfile
);
285 (void)fclose(lockfile
);
289 ns_os_shutdown(void) {
292 ntservice_shutdown(); /* This MUST be the last thing done */
296 ns_os_gethostname(char *buf
, size_t len
) {
299 n
= gethostname(buf
, (int)len
);
300 return ((n
== 0) ? ISC_R_SUCCESS
: ISC_R_FAILURE
);
304 ns_os_shutdownmsg(char *command
, isc_buffer_t
*text
) {
317 ns_os_started(void) {