Initial win32 Release
This commit is contained in:
@@ -15,15 +15,17 @@
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: condition.c,v 1.15 2001/01/09 21:58:48 bwelling Exp $ */
|
||||
/* $Id: condition.c,v 1.16 2001/07/06 05:05:51 mayer Exp $ */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <isc/condition.h>
|
||||
#include <isc/assertions.h>
|
||||
#include <isc/util.h>
|
||||
#include <isc/time.h>
|
||||
|
||||
#define SIGNAL 0
|
||||
#define BROADCAST 1
|
||||
#define LSIGNAL 0
|
||||
#define LBROADCAST 1
|
||||
|
||||
isc_result_t
|
||||
isc_condition_init(isc_condition_t *cond) {
|
||||
@@ -37,14 +39,14 @@ isc_condition_init(isc_condition_t *cond) {
|
||||
/* XXX */
|
||||
return (ISC_R_UNEXPECTED);
|
||||
}
|
||||
cond->events[SIGNAL] = h;
|
||||
cond->events[LSIGNAL] = h;
|
||||
h = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
if (h == NULL) {
|
||||
(void)CloseHandle(cond->events[SIGNAL]);
|
||||
(void)CloseHandle(cond->events[LSIGNAL]);
|
||||
/* XXX */
|
||||
return (ISC_R_UNEXPECTED);
|
||||
}
|
||||
cond->events[BROADCAST] = h;
|
||||
cond->events[LBROADCAST] = h;
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
@@ -59,7 +61,7 @@ isc_condition_signal(isc_condition_t *cond) {
|
||||
REQUIRE(cond != NULL);
|
||||
|
||||
if (cond->waiters > 0 &&
|
||||
!SetEvent(cond->events[SIGNAL])) {
|
||||
!SetEvent(cond->events[LSIGNAL])) {
|
||||
/* XXX */
|
||||
return (ISC_R_UNEXPECTED);
|
||||
}
|
||||
@@ -77,7 +79,7 @@ isc_condition_broadcast(isc_condition_t *cond) {
|
||||
REQUIRE(cond != NULL);
|
||||
|
||||
if (cond->waiters > 0 &&
|
||||
!SetEvent(cond->events[BROADCAST])) {
|
||||
!SetEvent(cond->events[LBROADCAST])) {
|
||||
/* XXX */
|
||||
return (ISC_R_UNEXPECTED);
|
||||
}
|
||||
@@ -90,8 +92,8 @@ isc_condition_destroy(isc_condition_t *cond) {
|
||||
|
||||
REQUIRE(cond != NULL);
|
||||
|
||||
(void)CloseHandle(cond->events[SIGNAL]);
|
||||
(void)CloseHandle(cond->events[BROADCAST]);
|
||||
(void)CloseHandle(cond->events[LSIGNAL]);
|
||||
(void)CloseHandle(cond->events[LBROADCAST]);
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
@@ -110,7 +112,7 @@ wait(isc_condition_t *cond, isc_mutex_t *mutex, DWORD milliseconds) {
|
||||
EnterCriticalSection(mutex);
|
||||
cond->waiters--;
|
||||
if (cond->waiters == 0 &&
|
||||
!ResetEvent(cond->events[BROADCAST])) {
|
||||
!ResetEvent(cond->events[LBROADCAST])) {
|
||||
/* XXX */
|
||||
LeaveCriticalSection(mutex);
|
||||
return (ISC_R_UNEXPECTED);
|
||||
|
||||
@@ -15,14 +15,30 @@
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: dir.c,v 1.8 2001/06/04 19:33:37 tale Exp $ */
|
||||
/* $Id: dir.c,v 1.9 2001/07/06 05:06:11 mayer Exp $ */
|
||||
|
||||
/* Principal Authors: DCL */
|
||||
|
||||
/*
|
||||
* isc_dir_chroot is currently stubbed out for Win32
|
||||
* This will need to be revisited
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <direct.h>
|
||||
#include <process.h>
|
||||
#include <io.h>
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <isc/dir.h>
|
||||
#include <isc/magic.h>
|
||||
#include <isc/assertions.h>
|
||||
#include <isc/util.h>
|
||||
|
||||
#include "errno2result.h"
|
||||
|
||||
#define ISC_DIR_MAGIC ISC_MAGIC('D', 'I', 'R', '*')
|
||||
#define VALID_DIR(dir) ISC_MAGIC_VALID(dir, ISC_DIR_MAGIC)
|
||||
@@ -218,5 +234,112 @@ isc_dir_chdir(const char *dirname) {
|
||||
|
||||
REQUIRE(dirname != NULL);
|
||||
|
||||
return (ISC_R_NOTIMPLEMENTED);
|
||||
if (chdir(dirname) < 0)
|
||||
return (isc__errno2result(errno));
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_dir_chroot(const char *dirname) {
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
isc_result_t
|
||||
isc_dir_current(char *dirname, size_t length, isc_boolean_t end_sep) {
|
||||
char *cwd;
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
|
||||
/*
|
||||
* XXXDCL Could automatically allocate memory if dirname == NULL.
|
||||
*/
|
||||
REQUIRE(dirname != NULL);
|
||||
REQUIRE(length > 0);
|
||||
|
||||
cwd = getcwd(dirname, length);
|
||||
|
||||
if (cwd == NULL) {
|
||||
if (errno == ERANGE)
|
||||
result = ISC_R_NOSPACE;
|
||||
else
|
||||
result = isc__errno2result(errno);
|
||||
} else if (end_sep) {
|
||||
if (strlen(dirname) + 1 == length)
|
||||
result = ISC_R_NOSPACE;
|
||||
else if (dirname[1] != '\0')
|
||||
strcat(dirname, "/");
|
||||
}
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_dir_createunique(char *templet) {
|
||||
isc_result_t result;
|
||||
char *x;
|
||||
char *p;
|
||||
int i;
|
||||
int pid;
|
||||
|
||||
REQUIRE(templet != NULL);
|
||||
|
||||
/*
|
||||
* mkdtemp is not portable, so this emulates it.
|
||||
*/
|
||||
|
||||
pid = getpid();
|
||||
|
||||
/*
|
||||
* Replace trailing Xs with the process-id, zero-filled.
|
||||
*/
|
||||
for (x = templet + strlen(templet) - 1; *x == 'X' && x >= templet;
|
||||
x--, pid /= 10)
|
||||
*x = pid % 10 + '0';
|
||||
|
||||
x++; /* Set x to start of ex-Xs. */
|
||||
|
||||
do {
|
||||
i = mkdir(templet);
|
||||
i = chmod(templet, 0700);
|
||||
|
||||
if (i == 0 || errno != EEXIST)
|
||||
break;
|
||||
|
||||
/*
|
||||
* The BSD algorithm.
|
||||
*/
|
||||
p = x;
|
||||
while (*p != '\0') {
|
||||
if (isdigit(*p & 0xff))
|
||||
*p = 'a';
|
||||
else if (*p != 'z')
|
||||
++*p;
|
||||
else {
|
||||
/*
|
||||
* Reset character and move to next.
|
||||
*/
|
||||
*p++ = 'a';
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (*p == '\0') {
|
||||
/*
|
||||
* Tried all combinations. errno should already
|
||||
* be EEXIST, but ensure it is anyway for
|
||||
* isc__errno2result().
|
||||
*/
|
||||
errno = EEXIST;
|
||||
break;
|
||||
}
|
||||
} while (1);
|
||||
|
||||
if (i == -1)
|
||||
result = isc__errno2result(errno);
|
||||
else
|
||||
result = ISC_R_SUCCESS;
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2000, 2001 Internet Software Consortium.
|
||||
* Copyright (C) 2000 Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@@ -15,41 +15,419 @@
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: file.c,v 1.6 2001/01/09 21:58:50 bwelling Exp $ */
|
||||
/* $Id: file.c,v 1.7 2001/07/06 05:06:25 mayer Exp $ */
|
||||
|
||||
#include <string.h>
|
||||
#include <config.h>
|
||||
|
||||
#undef TEMPLATE
|
||||
#define TEMPLATE "tXXXXXXX.tmp"
|
||||
#undef rename
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
#include <io.h>
|
||||
#include <process.h>
|
||||
|
||||
isc_result_t
|
||||
isc_file_mktemplate(const char *file, char *buf, size_t buflen) {
|
||||
char *s;
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/utime.h>
|
||||
|
||||
s = ;
|
||||
if ((s = strrchr(file, '\\')) != NULL) {
|
||||
if ((s - file + 1 + sizeof(TEMPLATE)) > buflen)
|
||||
return (ISC_R_NOSPACE);
|
||||
#include <isc/file.h>
|
||||
#include <isc/result.h>
|
||||
#include <isc/time.h>
|
||||
#include <isc/util.h>
|
||||
#include <isc/stat.h>
|
||||
|
||||
strncpy(buf, file, s - file + 1);
|
||||
buf[s - file + 1] = '\0';
|
||||
strcat(buf, TEMPLATE);
|
||||
#include "errno2result.h"
|
||||
|
||||
} else if ((s = strrchr(file, ':')) != NULL) {
|
||||
if ((s - file + 2 + sizeof(TEMPLATE)) > buflen)
|
||||
return (ISC_R_NOSPACE);
|
||||
/*
|
||||
* Emulate UNIX mkstemp, which returns an open FD to the new file
|
||||
*
|
||||
*/
|
||||
static int
|
||||
gettemp(char *path, int *doopen) {
|
||||
char *start, *trv;
|
||||
struct stat sbuf;
|
||||
int pid;
|
||||
|
||||
strncpy(buf, file, s - file + 1);
|
||||
buf[s - file + 1] = '\\';
|
||||
buf[s - file + 2] = '\0';
|
||||
strcat(buf, TEMPLATE);
|
||||
|
||||
} else {
|
||||
if (sizeof(TEMPLATE) > buflen)
|
||||
return (ISC_R_NOSPACE);
|
||||
|
||||
strcpy(buf, TEMPLATE);
|
||||
trv = strrchr(path, 'X');
|
||||
trv++;
|
||||
pid = getpid();
|
||||
/* extra X's get set to 0's */
|
||||
while (*--trv == 'X') {
|
||||
*trv = (pid % 10) + '0';
|
||||
pid /= 10;
|
||||
}
|
||||
/*
|
||||
* check the target directory; if you have six X's and it
|
||||
* doesn't exist this runs for a *very* long time.
|
||||
*/
|
||||
for (start = trv + 1;; --trv) {
|
||||
if (trv <= path)
|
||||
break;
|
||||
if (*trv == '\\') {
|
||||
*trv = '\0';
|
||||
if (stat(path, &sbuf))
|
||||
return(0);
|
||||
if (!S_ISDIR(sbuf.st_mode)) {
|
||||
errno = ENOTDIR;
|
||||
return(0);
|
||||
}
|
||||
*trv = '\\';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
if (doopen) {
|
||||
if ((*doopen =
|
||||
open(path, O_CREAT|O_EXCL|O_RDWR, _S_IREAD | _S_IWRITE)) >= 0)
|
||||
return(1);
|
||||
if (errno != EEXIST)
|
||||
return(0);
|
||||
}
|
||||
else if (stat(path, &sbuf))
|
||||
return(errno == ENOENT ? 1 : 0);
|
||||
|
||||
/* tricky little algorithm for backward compatibility */
|
||||
for (trv = start;;) {
|
||||
if (!*trv)
|
||||
return(0);
|
||||
if (*trv == 'z')
|
||||
*trv++ = 'a';
|
||||
else {
|
||||
if (isdigit(*trv))
|
||||
*trv = 'a';
|
||||
else
|
||||
++*trv;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
int
|
||||
mkstemp(char *path) {
|
||||
int fd;
|
||||
|
||||
return (gettemp(path, &fd) ? fd : -1);
|
||||
}
|
||||
|
||||
/*
|
||||
* XXXDCL As the API for accessing file statistics undoubtedly gets expanded,
|
||||
* it might be good to provide a mechanism that allows for the results
|
||||
* of a previous stat() to be used again without having to do another stat,
|
||||
* such as perl's mechanism of using "_" in place of a file name to indicate
|
||||
* that the results of the last stat should be used. But then you get into
|
||||
* annoying MP issues. BTW, Win32 has stat().
|
||||
*/
|
||||
static isc_result_t
|
||||
file_stats(const char *file, struct stat *stats) {
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
|
||||
if (stat(file, stats) != 0)
|
||||
result = isc__errno2result(errno);
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
/* isc_file_safemovefile is needed to be defined here to ensure that any file with
|
||||
* the new name is renamed to a backup name and then the rename is done. If all goes
|
||||
* well then the backup can be deleted, otherwise it gets renamed back.
|
||||
*/
|
||||
|
||||
int
|
||||
isc_file_safemovefile(const char *oldname, const char *newname) {
|
||||
BOOL filestatus;
|
||||
char buf[512];
|
||||
struct stat sbuf;
|
||||
BOOL exists = FALSE;
|
||||
int tmpfd;
|
||||
|
||||
/*
|
||||
* Make sure we have something to do
|
||||
*/
|
||||
if(stat(oldname, &sbuf) != 0) {
|
||||
errno = ENOENT;
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Rename to a backup the new file if it still exists
|
||||
*/
|
||||
if(stat(newname, &sbuf) == 0)
|
||||
exists = TRUE;
|
||||
|
||||
strcpy(buf, newname);
|
||||
strcat(buf, ".XXXXX");
|
||||
tmpfd = mkstemp(buf);
|
||||
if(tmpfd > 0)
|
||||
_close(tmpfd);
|
||||
DeleteFile(buf);
|
||||
|
||||
if(exists == TRUE) {
|
||||
_chmod(newname, _S_IREAD | _S_IWRITE);
|
||||
}
|
||||
|
||||
filestatus = MoveFile(newname, buf);
|
||||
if(filestatus == 0) {
|
||||
}
|
||||
|
||||
/* Now rename the file to the new name
|
||||
*/
|
||||
_chmod(oldname, _S_IREAD | _S_IWRITE);
|
||||
|
||||
filestatus = MoveFile(oldname, newname);
|
||||
if(filestatus == 0) {
|
||||
|
||||
/* Try and rename the backup back to the original name if the backup got created
|
||||
*/
|
||||
if(exists == TRUE) {
|
||||
filestatus = MoveFile(buf, newname);
|
||||
if(filestatus == 0) {
|
||||
errno = EACCES;
|
||||
}
|
||||
}
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/* Delete the backup file if it got created
|
||||
*/
|
||||
if(exists == TRUE) {
|
||||
filestatus = DeleteFile(buf);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_file_getmodtime(const char *file, isc_time_t *time) {
|
||||
isc_result_t result;
|
||||
struct stat stats;
|
||||
|
||||
REQUIRE(file != NULL && time != NULL);
|
||||
|
||||
result = file_stats(file, &stats);
|
||||
|
||||
if (result == ISC_R_SUCCESS)
|
||||
/*
|
||||
* XXXDCL some operating systems provide nanoseconds, too,
|
||||
* such as BSD/OS via st_mtimespec.
|
||||
*/
|
||||
isc_time_set(time, stats.st_mtime, 0);
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_file_settime(const char *file, isc_time_t *time) {
|
||||
struct utimbuf timem;
|
||||
|
||||
REQUIRE(file != NULL && time != NULL);
|
||||
|
||||
/*
|
||||
* tv_sec is at least a 32 bit quantity on all platforms we're
|
||||
* dealing with, but it is signed on most (all?) of them,
|
||||
* so we need to make sure the high bit isn't set. This unfortunately
|
||||
* loses when either:
|
||||
* * tv_sec becomes a signed 64 bit integer but long is 32 bits
|
||||
* and isc_time_seconds > LONG_MAX, or
|
||||
* * isc_time_seconds is changed to be > 32 bits but long is 32 bits
|
||||
* and isc_time_seconds has at least 33 significant bits.
|
||||
*/
|
||||
timem.actime = timem.modtime = (long)isc_time_seconds(time);
|
||||
|
||||
/*
|
||||
* Here is the real check for the high bit being set.
|
||||
*/
|
||||
if ((timem.actime &
|
||||
(1UL << (sizeof(timem.actime) * CHAR_BIT - 1))) != 0)
|
||||
return (ISC_R_RANGE);
|
||||
|
||||
if (utime(file, &timem) < 0)
|
||||
return (isc__errno2result(errno));
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
|
||||
}
|
||||
|
||||
#undef TEMPLATE
|
||||
#define TEMPLATE "XXXXXXXXXX.tmp" /* 14 characters. */
|
||||
|
||||
isc_result_t
|
||||
isc_file_mktemplate(const char *path, char *buf, size_t buflen) {
|
||||
return (isc_file_template(path, TEMPLATE, buf, buflen));
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_file_template(const char *path, const char *templet, char *buf,
|
||||
size_t buflen) {
|
||||
char *s;
|
||||
|
||||
REQUIRE(buf != NULL);
|
||||
|
||||
s = strrchr(templet, '\\');
|
||||
if (s != NULL)
|
||||
templet = s + 1;
|
||||
|
||||
s = strrchr(path, '\\');
|
||||
|
||||
if (s != NULL) {
|
||||
if ((s - path + 1 + strlen(templet) + 1) > buflen)
|
||||
return (ISC_R_NOSPACE);
|
||||
|
||||
strncpy(buf, path, s - path + 1);
|
||||
buf[s - path + 1] = '\0';
|
||||
strcat(buf, templet);
|
||||
} else {
|
||||
if ((strlen(templet) + 1) > buflen)
|
||||
return (ISC_R_NOSPACE);
|
||||
|
||||
strcpy(buf, templet);
|
||||
}
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_file_renameunique(const char *file, char *templet) {
|
||||
int fd = -1;
|
||||
int res = 0;
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
|
||||
fd = mkstemp(templet);
|
||||
if (fd == -1) {
|
||||
result = isc__errno2result(errno);
|
||||
}
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
res = isc_file_safemovefile(file, templet);
|
||||
if (res != 0) {
|
||||
result = isc__errno2result(errno);
|
||||
(void)unlink(templet);
|
||||
}
|
||||
}
|
||||
if (fd != -1)
|
||||
close(fd);
|
||||
return (result);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_file_openunique(char *templet, FILE **fp) {
|
||||
int fd;
|
||||
FILE *f;
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
|
||||
REQUIRE(templet != NULL);
|
||||
REQUIRE(fp != NULL && *fp == NULL);
|
||||
|
||||
/*
|
||||
* Win32 does not have mkstemp.
|
||||
*/
|
||||
fd = mkstemp(templet);
|
||||
|
||||
if (fd == -1)
|
||||
result = isc__errno2result(errno);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
f = fdopen(fd, "w+");
|
||||
if (f == NULL) {
|
||||
result = isc__errno2result(errno);
|
||||
(void)remove(templet);
|
||||
(void)close(fd);
|
||||
|
||||
} else
|
||||
*fp = f;
|
||||
}
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_file_remove(const char *filename) {
|
||||
int r;
|
||||
|
||||
r = unlink(filename);
|
||||
if (r == 0)
|
||||
return (ISC_R_SUCCESS);
|
||||
else
|
||||
return (isc__errno2result(errno));
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_file_rename(const char *oldname, const char *newname) {
|
||||
int r;
|
||||
|
||||
r = isc_file_safemovefile(oldname, newname);
|
||||
if (r == 0)
|
||||
return (ISC_R_SUCCESS);
|
||||
else
|
||||
return (isc__errno2result(errno));
|
||||
}
|
||||
|
||||
isc_boolean_t
|
||||
isc_file_exists(const char *pathname) {
|
||||
struct stat stats;
|
||||
|
||||
return (ISC_TF(file_stats(pathname, &stats) == ISC_R_SUCCESS));
|
||||
}
|
||||
|
||||
isc_boolean_t
|
||||
isc_file_isabsolute(const char *filename) {
|
||||
|
||||
/*
|
||||
* Look for c:\path\... style or \\computer\shar\path... UNC style file specs
|
||||
*/
|
||||
return ((ISC_TF(filename[1] == ':') && ISC_TF(filename[2] == '\\')) ||
|
||||
(ISC_TF(filename[0] == '\\') && ISC_TF(filename[1] == '\\')));
|
||||
}
|
||||
|
||||
isc_boolean_t
|
||||
isc_file_iscurrentdir(const char *filename) {
|
||||
return (ISC_TF(filename[0] == '.' && filename[1] == '\0'));
|
||||
}
|
||||
|
||||
const char *
|
||||
isc_file_basename(const char *filename) {
|
||||
char *s;
|
||||
|
||||
s = strrchr(filename, '\\');
|
||||
if(s == NULL)
|
||||
return(filename);
|
||||
return(s + 1);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_file_progname(const char *filename, char *progname, size_t namelen) {
|
||||
const char *s;
|
||||
char *p;
|
||||
size_t len;
|
||||
|
||||
REQUIRE(filename != NULL);
|
||||
/*
|
||||
* Strip the path from the name
|
||||
*/
|
||||
s = isc_file_basename(filename);
|
||||
if(s == NULL) {
|
||||
return(ISC_R_NOSPACE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Strip any and all suffixes
|
||||
*/
|
||||
p = strchr(s, '.');
|
||||
if(p == NULL) {
|
||||
if(namelen <= strlen(s))
|
||||
return(ISC_R_NOSPACE);
|
||||
|
||||
strcpy(progname, s);
|
||||
return(ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy the result to the buffer
|
||||
*/
|
||||
len = p - s;
|
||||
if(len >= namelen)
|
||||
return(ISC_R_NOSPACE);
|
||||
|
||||
strncpy(progname, s, len);
|
||||
progname[len] = '\0';
|
||||
return(ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
@@ -15,18 +15,29 @@
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: fsaccess.c,v 1.6 2001/01/09 21:58:51 bwelling Exp $ */
|
||||
|
||||
#include <windows.h>
|
||||
#include <winerror.h>
|
||||
#include <aclapi.h>
|
||||
/* $Id: fsaccess.c,v 1.8 2001/07/08 05:09:01 mayer Exp $ */
|
||||
|
||||
/*
|
||||
* This file is entirely theoretical. It has never been compiled or tested.
|
||||
* At the very least, even if this is all perfect (HAH!), isc__winerror2result
|
||||
* needs to be written.
|
||||
* Note that Win32 does not have the concept of files having access and ownership
|
||||
* bits. The FAT File system only has a readonly flag for everyone and that's
|
||||
* all. NTFS uses ACL's which is a totally different concept of controlling
|
||||
* access.
|
||||
*
|
||||
* This code needs to be revisited to set up proper access control for NTFS file systems.
|
||||
* Nothing can be done for FAT file systems.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <io.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <isc/stat.h>
|
||||
|
||||
#include "errno2result.h"
|
||||
|
||||
/*
|
||||
* The OS-independent part of the API is in lib/isc.
|
||||
*/
|
||||
@@ -34,145 +45,64 @@
|
||||
|
||||
isc_result_t
|
||||
isc_fsaccess_set(const char *path, isc_fsaccess_t access) {
|
||||
isc_result_t result;
|
||||
isc_fsaccess_t bits, mask;
|
||||
struct stat statb;
|
||||
int mode;
|
||||
isc_boolean_t is_dir = ISC_FALSE;
|
||||
int i;
|
||||
DWORD winerror;
|
||||
PACL dacl;
|
||||
PSID psid[3];
|
||||
#define owner psid[0]
|
||||
#define group psid[1]
|
||||
#define world psid[2]
|
||||
PSECURITY_DESCRIPTOR sd;
|
||||
EXPLICIT_ACCESS ea[3], *pea;
|
||||
TRUSTEETYPE trustee_type[3] = {
|
||||
TRUSTEE_IS_USER, TRUSTEE_IS_GROUP, TRUSTEE_IS_WELL_KNOWN_GROUP
|
||||
};
|
||||
isc_fsaccess_t bits;
|
||||
isc_result_t result;
|
||||
|
||||
owner = group = world = dacl = sd = NULL;
|
||||
if (stat(path, &statb) != 0)
|
||||
return (isc__errno2result(errno));
|
||||
|
||||
if ((statb.st_mode & S_IFDIR) != 0)
|
||||
is_dir = ISC_TRUE;
|
||||
else if ((statb.st_mode & S_IFREG) == 0)
|
||||
return (ISC_R_INVALIDFILE);
|
||||
|
||||
/* XXXDCL -- NEED TO SET is_dir! Maybe use stat; what is native way? */
|
||||
result = check_bad_bits(access, is_dir);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return (result);
|
||||
|
||||
winerror = GetNamedSecurityInfo(path, SE_FILE_OBJECT,
|
||||
OWNER_SECURITY_INFORMATION |
|
||||
GROUP_SECURITY_INFORMATION,
|
||||
&owner, &group, NULL, NULL, &sd);
|
||||
/*
|
||||
* "ERROR_SUCCESS". Heh heh heh.
|
||||
* Done with checking bad bits. Set mode_t.
|
||||
*/
|
||||
if (winerror != ERROR_SUCCESS)
|
||||
return (isc__winerror2result(winerror));
|
||||
mode = 0;
|
||||
|
||||
ZeroMemory(&ea, sizeof(ea));
|
||||
ea.grfAccessMode = SET_ACCESS;
|
||||
ea.grfInheritance = NO_INHERITANCE;
|
||||
#define SET_AND_CLEAR1(modebit) \
|
||||
if ((access & bits) != 0) { \
|
||||
mode |= modebit; \
|
||||
access &= ~bits; \
|
||||
}
|
||||
#define SET_AND_CLEAR(user, group, other) \
|
||||
SET_AND_CLEAR1(user); \
|
||||
bits <<= STEP; \
|
||||
SET_AND_CLEAR1(group); \
|
||||
bits <<= STEP; \
|
||||
SET_AND_CLEAR1(other);
|
||||
|
||||
bits = ISC_FSACCESS_READ | ISC_FSACCESS_LISTDIRECTORY;
|
||||
|
||||
SET_AND_CLEAR(S_IRUSR, S_IRGRP, S_IROTH);
|
||||
|
||||
bits = ISC_FSACCESS_WRITE |
|
||||
ISC_FSACCESS_CREATECHILD |
|
||||
ISC_FSACCESS_DELETECHILD;
|
||||
|
||||
SET_AND_CLEAR(S_IWUSR, S_IWGRP, S_IWOTH);
|
||||
|
||||
/*
|
||||
* Make a mask for the number of bits per owner/group/other.
|
||||
*/
|
||||
for (i = mask = 0; i < ISC__FSACCESS_PERMISSIONBITS; i++) {
|
||||
mask <<= 1;
|
||||
mask |= 1;
|
||||
}
|
||||
* WIN32 doesn't have the concept of execute bits. We leave this here
|
||||
* for when we review this module.
|
||||
*
|
||||
bits = ISC_FSACCESS_EXECUTE |
|
||||
ISC_FSACCESS_ACCESSCHILD;
|
||||
|
||||
#define MAP(isc, win32) \
|
||||
if ((bits & (isc)) != 0) { \
|
||||
ea.grfAccessPermissions |= (win32); \
|
||||
bits &= ~(isc); \
|
||||
}
|
||||
SET_AND_CLEAR(S_IXUSR, S_IXGRP, S_IXOTH);
|
||||
*/
|
||||
INSIST(access == 0);
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
bits = access & mask;
|
||||
if (_chmod(path, mode) < 0)
|
||||
return (isc__errno2result(errno));
|
||||
|
||||
pea = &ea[i];
|
||||
|
||||
pea->grfAccessPermissions =
|
||||
SYNCHRONIZE | READ_CONTROL | FILE_READ_ATTRIBUTES;
|
||||
if (i == 0)
|
||||
/*
|
||||
* Owner-only permissions.
|
||||
*/
|
||||
pea->grfAccessPermissions |= WRITE_DAC | DELETE;
|
||||
|
||||
/*
|
||||
* File access rights.
|
||||
*/
|
||||
MAP(ISC_FSACCESS_READ, FILE_READ_DATA | FILE_READ_EA);
|
||||
MAP(ISC_FSACCESS_WRITE,
|
||||
FILE_WRITE_DATA | FILE_WRITE_EA | FILE_APPEND_DATA);
|
||||
MAP(ISC_FSACCESS_EXECUTE, FILE_EXECUTE);
|
||||
|
||||
/*
|
||||
* Directory access rights.
|
||||
*/
|
||||
MAP(ISC_FSACCESS_LISTDIRECTORY, FILE_LIST_DIRECTORY);
|
||||
MAP(ISC_FSACCESS_CREATECHILD, FILE_CREATE_CHILD);
|
||||
MAP(ISC_FSACCESS_DELETECHILD, FILE_DELETE_CHILD);
|
||||
MAP(ISC_FSACCESS_ACCESSCHILD, FILE_TRAVERSE);
|
||||
|
||||
/*
|
||||
* Ensure no other bits were set.
|
||||
*/
|
||||
INSIST(bits == 0);
|
||||
|
||||
if (i == 2) {
|
||||
/*
|
||||
* Setting world.
|
||||
*/
|
||||
SID_IDENTIFIER_AUTHORITY authworld =
|
||||
SECURITY_WORLD_SID_AUTHORITY;
|
||||
|
||||
if (AllocateAndInitializeSid(&authworld, 1,
|
||||
SECURITY_WORLD_RID,
|
||||
0, 0, 0, 0, 0, 0, 0,
|
||||
&world)
|
||||
== 0)
|
||||
winerror = GetLastError();
|
||||
else
|
||||
/*
|
||||
* This should already be ERROR_SUCCESS.
|
||||
*/
|
||||
ENSURE(winerror == ERROR_SUCCESS);
|
||||
|
||||
}
|
||||
|
||||
if (winerror == ERROR_SUCCESS) {
|
||||
BuildTrusteeWithSid(&pea->Trustee, psid[i]);
|
||||
pea->Trustee.Trusteetype = trustee_type[i];
|
||||
|
||||
winerror = SetEntriesInAcl(3, ea, NULL, &dacl);
|
||||
}
|
||||
|
||||
if (winerror == ERROR_SUCCESS)
|
||||
winerror =
|
||||
SetNamedSecurityInfo(path, SE_FILE_OBJECT,
|
||||
DACL_SECURITY_INFORMATION,
|
||||
NULL, NULL, dacl, NULL);
|
||||
|
||||
if (winerror == ERROR_SUCCESS)
|
||||
access >> shift;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
if (sd != NULL)
|
||||
LocalFree(sd);
|
||||
if (dacl != NULL)
|
||||
LocalFree(dacl);
|
||||
if (world != NULL)
|
||||
FreeSid(world);
|
||||
|
||||
if (winerror == ERROR_SUCCESS) {
|
||||
/*
|
||||
* Ensure no other bits were set.
|
||||
*/
|
||||
INSIST(access == 0);
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
} else
|
||||
return (isc__winerror2result(winerror));
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
@@ -15,14 +15,17 @@
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: once.c,v 1.6 2001/01/09 21:58:52 bwelling Exp $ */
|
||||
/* $Id: once.c,v 1.8 2001/07/08 05:09:10 mayer Exp $ */
|
||||
|
||||
/* Principal Authors: DCL */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <isc/once.h>
|
||||
#include <isc/assertions.h>
|
||||
#include <isc/util.h>
|
||||
|
||||
isc_result_t
|
||||
isc_once_do(isc_once_t *controller, void(*function)(void))
|
||||
|
||||
@@ -15,12 +15,15 @@
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: stdtime.c,v 1.7 2001/01/09 21:58:53 bwelling Exp $ */
|
||||
/* $Id: stdtime.c,v 1.9 2001/07/08 05:09:14 mayer Exp $ */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#include <isc/assertions.h>
|
||||
#include <isc/stdtime.h>
|
||||
#include <isc/util.h>
|
||||
|
||||
void
|
||||
isc_stdtime_get(isc_stdtime_t *t) {
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: thread.c,v 1.14 2001/01/09 21:58:55 bwelling Exp $ */
|
||||
/* $Id: thread.c,v 1.15 2001/07/06 05:07:54 mayer Exp $ */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
@@ -58,3 +58,11 @@ isc_thread_join(isc_thread_t thread, isc_threadresult_t *rp) {
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
void
|
||||
isc_thread_setconcurrency(unsigned int level) {
|
||||
|
||||
/*
|
||||
* This is unnecessary on Win32 systems
|
||||
*/
|
||||
}
|
||||
|
||||
@@ -15,7 +15,18 @@
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: time.c,v 1.20 2001/01/09 21:58:56 bwelling Exp $ */
|
||||
/* $Id: time.c,v 1.21 2001/07/06 05:07:44 mayer Exp $ */
|
||||
|
||||
/*
|
||||
* Windows has a different epoch than Unix. Therefore this code sets the epoch
|
||||
* value to the Unix epoch. Care should be used when using these routines to
|
||||
* ensure that this difference is taken into account. System and File times
|
||||
* may require adjusting for this when modifying any time value that needs
|
||||
* to be an absolute Windows time.
|
||||
*
|
||||
* Currently only epoch-specific code and the isc_time_seconds
|
||||
* and isc_time_secondsastimet use the epoch-adjusted code.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
@@ -30,6 +41,7 @@
|
||||
|
||||
#include <isc/assertions.h>
|
||||
#include <isc/time.h>
|
||||
#include <isc/util.h>
|
||||
|
||||
/*
|
||||
* struct FILETIME uses "100-nanoseconds intervals".
|
||||
@@ -40,8 +52,23 @@
|
||||
#define NS_PER_S 1000000000
|
||||
#define NS_INTERVAL 100
|
||||
#define INTERVALS_PER_S (NS_PER_S / NS_INTERVAL)
|
||||
#define UINT64_MAX 0xffffffffffffffffui64
|
||||
#define UINT64_MAX _UI64_MAX
|
||||
|
||||
/***
|
||||
*** Absolute Times
|
||||
***/
|
||||
|
||||
static isc_time_t epoch = { 0, 0 };
|
||||
isc_time_t *isc_time_epoch = &epoch;
|
||||
|
||||
void
|
||||
TimetToFileTime(time_t t, LPFILETIME pft) {
|
||||
LONGLONG i;
|
||||
|
||||
i = Int32x32To64(t, 10000000) + 116444736000000000;
|
||||
pft->dwLowDateTime = (DWORD) i;
|
||||
pft->dwHighDateTime = (DWORD) (i >>32);
|
||||
}
|
||||
/***
|
||||
*** Intervals
|
||||
***/
|
||||
@@ -60,7 +87,7 @@ isc_interval_set(isc_interval_t *i,
|
||||
*/
|
||||
|
||||
REQUIRE(i != NULL);
|
||||
REQUIRE(nanoseconds < 1000000000);
|
||||
REQUIRE(nanoseconds < NS_PER_S);
|
||||
|
||||
i->interval = (LONGLONG)seconds * INTERVALS_PER_S
|
||||
+ nanoseconds / NS_INTERVAL;
|
||||
@@ -81,13 +108,6 @@ isc_interval_iszero(isc_interval_t *i) {
|
||||
}
|
||||
|
||||
|
||||
/***
|
||||
*** Absolute Times
|
||||
***/
|
||||
|
||||
static isc_time_t epoch = { 0, 0 };
|
||||
isc_time_t *isc_time_epoch = &epoch;
|
||||
|
||||
void
|
||||
isc_time_set(isc_time_t *t, unsigned int seconds, unsigned int nanoseconds) {
|
||||
ULARGE_INTEGER i;
|
||||
@@ -97,7 +117,7 @@ isc_time_set(isc_time_t *t, unsigned int seconds, unsigned int nanoseconds) {
|
||||
* epoch.
|
||||
*/
|
||||
REQUIRE(t != NULL);
|
||||
REQUIRE(nanoseconds < 1000000000);
|
||||
REQUIRE(nanoseconds < NS_PER_S);
|
||||
|
||||
i.QuadPart = (LONGLONG)seconds * INTERVALS_PER_S
|
||||
+ nanoseconds / NS_INTERVAL;
|
||||
@@ -107,6 +127,11 @@ isc_time_set(isc_time_t *t, unsigned int seconds, unsigned int nanoseconds) {
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
isc_time_initepoch() {
|
||||
TimetToFileTime(0, &epoch.absolute);
|
||||
}
|
||||
|
||||
void
|
||||
isc_time_settoepoch(isc_time_t *t) {
|
||||
/*
|
||||
@@ -115,20 +140,21 @@ isc_time_settoepoch(isc_time_t *t) {
|
||||
|
||||
REQUIRE(t != NULL);
|
||||
|
||||
t->absolute.dwLowDateTime = 0;
|
||||
t->absolute.dwHighDateTime = 0;
|
||||
t->absolute.dwLowDateTime = epoch.absolute.dwLowDateTime;
|
||||
t->absolute.dwHighDateTime = epoch.absolute.dwHighDateTime;
|
||||
}
|
||||
|
||||
isc_boolean_t
|
||||
isc_time_isepoch(isc_time_t *t) {
|
||||
|
||||
/*
|
||||
* Returns ISC_TRUE iff. 't' is the epoch ("time zero").
|
||||
*/
|
||||
|
||||
REQUIRE(t != NULL);
|
||||
|
||||
if (t->absolute.dwLowDateTime == 0 &&
|
||||
t->absolute.dwHighDateTime == 0)
|
||||
if (t->absolute.dwLowDateTime == epoch.absolute.dwLowDateTime &&
|
||||
t->absolute.dwHighDateTime == epoch.absolute.dwHighDateTime)
|
||||
return (ISC_TRUE);
|
||||
|
||||
return (ISC_FALSE);
|
||||
@@ -136,6 +162,8 @@ isc_time_isepoch(isc_time_t *t) {
|
||||
|
||||
isc_result_t
|
||||
isc_time_now(isc_time_t *t) {
|
||||
|
||||
char dtime[10];
|
||||
/*
|
||||
* Set *t to the current absolute time.
|
||||
*/
|
||||
@@ -144,6 +172,7 @@ isc_time_now(isc_time_t *t) {
|
||||
|
||||
GetSystemTimeAsFileTime(&t->absolute);
|
||||
|
||||
_strtime(dtime);
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
@@ -163,7 +192,7 @@ isc_time_nowplusinterval(isc_time_t *t, isc_interval_t *i) {
|
||||
i1.LowPart = t->absolute.dwLowDateTime;
|
||||
i1.HighPart = t->absolute.dwHighDateTime;
|
||||
|
||||
if (UINT64_MAX - i1.QuadPart < i->interval)
|
||||
if (UINT64_MAX - i1.QuadPart < (unsigned __int64)i->interval)
|
||||
return (ISC_R_RANGE);
|
||||
|
||||
i1.QuadPart += i->interval;
|
||||
@@ -198,7 +227,7 @@ isc_time_add(isc_time_t *t, isc_interval_t *i, isc_time_t *result) {
|
||||
i1.LowPart = t->absolute.dwLowDateTime;
|
||||
i1.HighPart = t->absolute.dwHighDateTime;
|
||||
|
||||
if (UINT64_MAX - i1.QuadPart < i->interval)
|
||||
if (UINT64_MAX - i1.QuadPart < (unsigned __int64)i->interval)
|
||||
return (ISC_R_RANGE);
|
||||
|
||||
i1.QuadPart += i->interval;
|
||||
@@ -222,13 +251,15 @@ isc_time_subtract(isc_time_t *t, isc_interval_t *i, isc_time_t *result) {
|
||||
i1.LowPart = t->absolute.dwLowDateTime;
|
||||
i1.HighPart = t->absolute.dwHighDateTime;
|
||||
|
||||
if (i.QuadPart < i->interval)
|
||||
if (i1.QuadPart < (unsigned __int64) i->interval)
|
||||
return (ISC_R_RANGE);
|
||||
|
||||
i1.QuadPart -= i->interval;
|
||||
|
||||
result->absolute.dwLowDateTime = i1.LowPart;
|
||||
result->absolute.dwHighDateTime = i1.HighPart;
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
isc_uint64_t
|
||||
@@ -254,16 +285,21 @@ isc_time_microdiff(isc_time_t *t1, isc_time_t *t2) {
|
||||
return (i3);
|
||||
}
|
||||
|
||||
/*
|
||||
* Note that the value returned is the seconds relative to the Unix epoch rather than
|
||||
* the seconds since Windows epoch.
|
||||
* This is for compatibility with the Unix side.
|
||||
*/
|
||||
isc_uint32_t
|
||||
isc_time_seconds(isc_time_t *t) {
|
||||
ULARGE_INTEGER i;
|
||||
|
||||
REQUIRE(t != NULL);
|
||||
|
||||
i.LowPart = t->absolute.dwLowDateTime;
|
||||
i.HighPart = t->absolute.dwHighDateTime;
|
||||
i.LowPart = t->absolute.dwLowDateTime - epoch.absolute.dwLowDateTime;
|
||||
i.HighPart = t->absolute.dwHighDateTime - epoch.absolute.dwHighDateTime;
|
||||
|
||||
INSIST(i.QuadPart / INTERVALS_PER_S <= (isc_uint32_t)-1);
|
||||
// INSIST(i.QuadPart / INTERVALS_PER_S <= (isc_uint32_t)-1);
|
||||
|
||||
return ((isc_uint32_t)(i.QuadPart / INTERVALS_PER_S));
|
||||
}
|
||||
@@ -278,6 +314,14 @@ isc_time_secondsastimet(isc_time_t *t, time_t *secondsp) {
|
||||
i1.LowPart = t->absolute.dwLowDateTime;
|
||||
i1.HighPart = t->absolute.dwHighDateTime;
|
||||
|
||||
/*
|
||||
* Get the time_t zero equivalent in FILETIME
|
||||
* The zero point for FILETIME is 1 January, 1601
|
||||
* while for timet it is 1 January, 1970
|
||||
*/
|
||||
i1.LowPart -= epoch.absolute.dwLowDateTime;
|
||||
i1.HighPart -= epoch.absolute.dwHighDateTime;
|
||||
|
||||
i1.QuadPart /= INTERVALS_PER_S;
|
||||
|
||||
/*
|
||||
@@ -363,16 +407,13 @@ isc_time_secondsastimet(isc_time_t *t, time_t *secondsp) {
|
||||
|
||||
isc_uint32_t
|
||||
isc_time_nanoseconds(isc_time_t *t) {
|
||||
ULARGE_INTEGER i;
|
||||
SYSTEMTIME st;
|
||||
|
||||
REQUIRE(t != NULL);
|
||||
/*
|
||||
* Convert the time to a SYSTEMTIME structure and the grab the
|
||||
* milliseconds
|
||||
*/
|
||||
FileTimeToSystemTime(&t->absolute, &st);
|
||||
|
||||
i.LowPart = t->absolute.dwLowDateTime;
|
||||
i.HighPart = t->absolute.dwHighDateTime;
|
||||
|
||||
i.QuadPart -= isc_time_seconds(t);
|
||||
|
||||
ENSURE(i.QuadPart * NS_INTERVAL < NS);
|
||||
|
||||
return ((isc_uint32_t)(i.QuadPart * NS_INTERVAL));
|
||||
return ((isc_uint32_t)(st.wMilliseconds * 1000000));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user