file.c revision fdacf913e123db672888ff6b24a89caea6b12a50
07dcadc6e24f4572f2b7d7cae7d47d0f5256d129Andreas Gustafsson * Copyright (C) 2000, 2001 Internet Software Consortium.
8b7304a34c751e519ede7d00b77f1f962c0a37e4David Lawrence * Permission to use, copy, modify, and distribute this software for any
8b7304a34c751e519ede7d00b77f1f962c0a37e4David Lawrence * purpose with or without fee is hereby granted, provided that the above
8b7304a34c751e519ede7d00b77f1f962c0a37e4David Lawrence * copyright notice and this permission notice appear in all copies.
15a44745412679c30a6d022733925af70a38b715David Lawrence * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
15a44745412679c30a6d022733925af70a38b715David Lawrence * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
15a44745412679c30a6d022733925af70a38b715David Lawrence * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
15a44745412679c30a6d022733925af70a38b715David Lawrence * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
15a44745412679c30a6d022733925af70a38b715David Lawrence * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
15a44745412679c30a6d022733925af70a38b715David Lawrence * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
15a44745412679c30a6d022733925af70a38b715David Lawrence * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
15a44745412679c30a6d022733925af70a38b715David Lawrence * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
fdacf913e123db672888ff6b24a89caea6b12a50Danny Mayer/* $Id: file.c,v 1.26 2001/09/05 04:17:13 mayer Exp $ */
e35c1bb3ecd9a6597360b9160b397c8053af69bfDanny Mayer * Emulate UNIX mkstemp, which returns an open FD to the new file
e35c1bb3ecd9a6597360b9160b397c8053af69bfDanny Mayer /* extra X's get set to 0's */
e35c1bb3ecd9a6597360b9160b397c8053af69bfDanny Mayer * check the target directory; if you have six X's and it
e35c1bb3ecd9a6597360b9160b397c8053af69bfDanny Mayer * doesn't exist this runs for a *very* long time.
e35c1bb3ecd9a6597360b9160b397c8053af69bfDanny Mayer /* tricky little algorithm for backward compatibility */
e35c1bb3ecd9a6597360b9160b397c8053af69bfDanny Mayer /*NOTREACHED*/
e35c1bb3ecd9a6597360b9160b397c8053af69bfDanny Mayer * XXXDCL As the API for accessing file statistics undoubtedly gets expanded,
e35c1bb3ecd9a6597360b9160b397c8053af69bfDanny Mayer * it might be good to provide a mechanism that allows for the results
e35c1bb3ecd9a6597360b9160b397c8053af69bfDanny Mayer * of a previous stat() to be used again without having to do another stat,
e35c1bb3ecd9a6597360b9160b397c8053af69bfDanny Mayer * such as perl's mechanism of using "_" in place of a file name to indicate
e35c1bb3ecd9a6597360b9160b397c8053af69bfDanny Mayer * that the results of the last stat should be used. But then you get into
e35c1bb3ecd9a6597360b9160b397c8053af69bfDanny Mayer * annoying MP issues. BTW, Win32 has stat().
e35c1bb3ecd9a6597360b9160b397c8053af69bfDanny Mayerfile_stats(const char *file, struct stat *stats) {
e76d4c91bfadf823f04dcca1c1c5bcc14c67671dAndreas Gustafsson * isc_file_safemovefile is needed to be defined here to ensure that
e76d4c91bfadf823f04dcca1c1c5bcc14c67671dAndreas Gustafsson * any file with the new name is renamed to a backup name and then the
e76d4c91bfadf823f04dcca1c1c5bcc14c67671dAndreas Gustafsson * rename is done. If all goes well then the backup can be deleted,
e76d4c91bfadf823f04dcca1c1c5bcc14c67671dAndreas Gustafsson * otherwise it gets renamed back.
e35c1bb3ecd9a6597360b9160b397c8053af69bfDanny Mayerisc_file_safemovefile(const char *oldname, const char *newname) {
e35c1bb3ecd9a6597360b9160b397c8053af69bfDanny Mayer * Make sure we have something to do
68c2ccc953059f389cefc0f8a5ce0f83be7458c9Danny Mayer return (-1);
e35c1bb3ecd9a6597360b9160b397c8053af69bfDanny Mayer * Rename to a backup the new file if it still exists
68c2ccc953059f389cefc0f8a5ce0f83be7458c9Danny Mayer /* Now rename the file to the new name
e76d4c91bfadf823f04dcca1c1c5bcc14c67671dAndreas Gustafsson * Try to rename the backup back to the original name
e76d4c91bfadf823f04dcca1c1c5bcc14c67671dAndreas Gustafsson * if the backup got created
e76d4c91bfadf823f04dcca1c1c5bcc14c67671dAndreas Gustafsson * Delete the backup file if it got created
e35c1bb3ecd9a6597360b9160b397c8053af69bfDanny Mayerisc_file_getmodtime(const char *file, isc_time_t *time) {
fdacf913e123db672888ff6b24a89caea6b12a50Danny Mayer if ((fh = open(file, _O_RDONLY | _O_BINARY)) < 0)
bdec94477cc9ecac9ff14d3399f47f3d71cd370aAndreas Gustafsson if (!GetFileTime((HANDLE) _get_osfhandle(fh),
e35c1bb3ecd9a6597360b9160b397c8053af69bfDanny Mayerisc_file_settime(const char *file, isc_time_t *time) {
528baec07b1b9a566d47fc638ba5cbbe01475c74Andreas Gustafsson * Set the date via the filedate system call and return. Failing
b602bf9e8b67cb2b1ff9ee8b2a48793bf6c70e16Danny Mayer * this call implies the new file times are not supported by the
b602bf9e8b67cb2b1ff9ee8b2a48793bf6c70e16Danny Mayer * underlying file system.
528baec07b1b9a566d47fc638ba5cbbe01475c74Andreas Gustafsson if (!SetFileTime((HANDLE) _get_osfhandle(fh),
e35c1bb3ecd9a6597360b9160b397c8053af69bfDanny Mayer#define TEMPLATE "XXXXXXXXXX.tmp" /* 14 characters. */
e35c1bb3ecd9a6597360b9160b397c8053af69bfDanny Mayerisc_file_mktemplate(const char *path, char *buf, size_t buflen) {
e35c1bb3ecd9a6597360b9160b397c8053af69bfDanny Mayer return (isc_file_template(path, TEMPLATE, buf, buflen));
e35c1bb3ecd9a6597360b9160b397c8053af69bfDanny Mayerisc_file_template(const char *path, const char *templet, char *buf,
e35c1bb3ecd9a6597360b9160b397c8053af69bfDanny Mayer if ((s - path + 1 + strlen(templet) + 1) > buflen)
e35c1bb3ecd9a6597360b9160b397c8053af69bfDanny Mayerisc_file_renameunique(const char *file, char *templet) {
68c2ccc953059f389cefc0f8a5ce0f83be7458c9Danny Mayer * Win32 does not have mkstemp. Using emulation above.
e35c1bb3ecd9a6597360b9160b397c8053af69bfDanny Mayerisc_file_rename(const char *oldname, const char *newname) {
e35c1bb3ecd9a6597360b9160b397c8053af69bfDanny Mayer return (ISC_TF(file_stats(pathname, &stats) == ISC_R_SUCCESS));
c4958494a98a59ce25e9fecad76a9ab0e36cc59fDanny Mayer * Look for c:\path\... style, c:/path/... or \\computer\shar\path...
ad38e19578815fc064ea0a5f455fa8beffc99e63Danny Mayer * the UNC style file specs
ad38e19578815fc064ea0a5f455fa8beffc99e63Danny Mayer if ((filename[0] == '\\') && (filename[1] == '\\'))
911533025604975b5548d038ca09cff17c7f534eAndreas Gustafsson if (isalpha(filename[0]) && filename[1] == ':' && filename[2] == '\\')
911533025604975b5548d038ca09cff17c7f534eAndreas Gustafsson if (isalpha(filename[0]) && filename[1] == ':' && filename[2] == '/')
e35c1bb3ecd9a6597360b9160b397c8053af69bfDanny Mayer return (ISC_TF(filename[0] == '.' && filename[1] == '\0'));
ba35e9924e95c45f8ae536f453b9064740e49841Andreas Gustafssonisc_file_ischdiridempotent(const char *filename) {
1e71bc82b8e1a95d423d8db1c136080dc034433dAndreas Gustafsson return (s + 1);
e35c1bb3ecd9a6597360b9160b397c8053af69bfDanny Mayerisc_file_progname(const char *filename, char *progname, size_t namelen) {
e35c1bb3ecd9a6597360b9160b397c8053af69bfDanny Mayer const char *s;
e35c1bb3ecd9a6597360b9160b397c8053af69bfDanny Mayer * Strip the path from the name
e35c1bb3ecd9a6597360b9160b397c8053af69bfDanny Mayer * Strip any and all suffixes
e35c1bb3ecd9a6597360b9160b397c8053af69bfDanny Mayer * Copy the result to the buffer
dee69dd3aafe1339cd62928b858d18fdc0536642Andreas Gustafssonisc_file_absolutepath(const char *filename, char *path, size_t pathlen) {
3bd4083e486d200d4f5992ac9da2dc7131c7b9aeDanny Mayer retval = GetFullPathName(filename, pathlen, path, &ptrname);
3bd4083e486d200d4f5992ac9da2dc7131c7b9aeDanny Mayer /* Something went wrong in getting the path */
3bd4083e486d200d4f5992ac9da2dc7131c7b9aeDanny Mayer /* Caller needs to provide a larger buffer to contain the string */
7c7b389ae01b7953982ed8827cfd6010fce6e575Danny Mayerisc_file_truncate(const char *filename, isc_offset_t size) {
7c7b389ae01b7953982ed8827cfd6010fce6e575Danny Mayer if ((fh = open(filename, _O_RDWR | _O_BINARY)) < 0)