file.c revision 754cb8a2b33fa6cfaa15d6470f66e5fb0eab4764
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * Copyright (C) 2004, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * Copyright (C) 2000-2002 Internet Software Consortium.
1633838b8255282d10af15c5c84cee5a51466712Bob Halley * Permission to use, copy, modify, and/or distribute this software for any
1633838b8255282d10af15c5c84cee5a51466712Bob Halley * purpose with or without fee is hereby granted, provided that the above
1633838b8255282d10af15c5c84cee5a51466712Bob Halley * copyright notice and this permission notice appear in all copies.
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * PERFORMANCE OF THIS SOFTWARE.
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein/* $Id: file.c,v 1.33 2009/06/11 23:47:55 tbox Exp $ */
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence * Emulate UNIX mkstemp, which returns an open FD to the new file
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley /* extra X's get set to 0's */
70ec7dd74103fa9e92a6d56a0e3b0fc30e17af0dMark Andrews * check the target directory; if you have six X's and it
70ec7dd74103fa9e92a6d56a0e3b0fc30e17af0dMark Andrews * doesn't exist this runs for a *very* long time.
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley /* tricky little algorithm for backward compatibility */
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley /*NOTREACHED*/
585529aaeb95a71cd3d95df2602a4688fc7c3292David Lawrence * XXXDCL As the API for accessing file statistics undoubtedly gets expanded,
585529aaeb95a71cd3d95df2602a4688fc7c3292David Lawrence * it might be good to provide a mechanism that allows for the results
585529aaeb95a71cd3d95df2602a4688fc7c3292David Lawrence * of a previous stat() to be used again without having to do another stat,
232fd751edcb5dd2b1fd2666e039efe83d2e2b55Michael Sawyer * such as perl's mechanism of using "_" in place of a file name to indicate
585529aaeb95a71cd3d95df2602a4688fc7c3292David Lawrence * that the results of the last stat should be used. But then you get into
585529aaeb95a71cd3d95df2602a4688fc7c3292David Lawrence * annoying MP issues. BTW, Win32 has stat().
585529aaeb95a71cd3d95df2602a4688fc7c3292David Lawrencefile_stats(const char *file, struct stat *stats) {
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley * isc_file_safemovefile is needed to be defined here to ensure that
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley * any file with the new name is renamed to a backup name and then the
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley * rename is done. If all goes well then the backup can be deleted,
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley * otherwise it gets renamed back.
df0f58959ed82a2a43ca8d816ce9592541df9f2fMark Andrewsisc_file_safemovefile(const char *oldname, const char *newname) {
94e25967cda41b886e33ec254b917d21df21a187Bob Halley * Make sure we have something to do
94e25967cda41b886e33ec254b917d21df21a187Bob Halley return (-1);
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence * Rename to a backup the new file if it still exists
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence /* Now rename the file to the new name
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley * Try to rename the backup back to the original name
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence * if the backup got created
afdb3abb9b06ed4070ac9021f1f4427b4cb3a286Bob Halley return (-1);
afdb3abb9b06ed4070ac9021f1f4427b4cb3a286Bob Halley * Delete the backup file if it got created
afdb3abb9b06ed4070ac9021f1f4427b4cb3a286Bob Halleyisc_file_getmodtime(const char *file, isc_time_t *time) {
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence if ((fh = open(file, _O_RDONLY | _O_BINARY)) < 0)
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrenceisc_file_settime(const char *file, isc_time_t *time) {
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence if ((fh = open(file, _O_RDWR | _O_BINARY)) < 0)
afdb3abb9b06ed4070ac9021f1f4427b4cb3a286Bob Halley * Set the date via the filedate system call and return. Failing
afdb3abb9b06ed4070ac9021f1f4427b4cb3a286Bob Halley * this call implies the new file times are not supported by the
afdb3abb9b06ed4070ac9021f1f4427b4cb3a286Bob Halley * underlying file system.
94e25967cda41b886e33ec254b917d21df21a187Bob Halley#define TEMPLATE "XXXXXXXXXX.tmp" /* 14 characters. */
26f327f1f53afdb8256affa1c197ed138bf3cb2fAndreas Gustafssonisc_file_mktemplate(const char *path, char *buf, size_t buflen) {
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley return (isc_file_template(path, TEMPLATE, buf, buflen));
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrenceisc_file_template(const char *path, const char *templet, char *buf,
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence if ((s - path + 1 + strlen(templet) + 1) > buflen)
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halleyisc_file_renameunique(const char *file, char *templet) {
4ad9b25e6ddf948ffb3b8198c5540d251f26c52eDavid Lawrenceisc_file_openunique(char *templet, FILE **fp) {
114d0d1642b5ede0ab154532159fe38c30762d82David Lawrence * Win32 does not have mkstemp. Using emulation above.
826c281a05cb89c9c28621937dc83fa676a5b207David Lawrenceisc_file_rename(const char *oldname, const char *newname) {
604a596b5f97f09f6a4de67fe2f076d3c939df33David Lawrence return (ISC_TF(file_stats(pathname, &stats) == ISC_R_SUCCESS));
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence * Look for c:\path\... style, c:/path/... or \\computer\shar\path...
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence * the UNC style file specs
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence if ((filename[0] == '\\') && (filename[1] == '\\'))
26f327f1f53afdb8256affa1c197ed138bf3cb2fAndreas Gustafsson if (isalpha(filename[0]) && filename[1] == ':' && filename[2] == '\\')
585529aaeb95a71cd3d95df2602a4688fc7c3292David Lawrence if (isalpha(filename[0]) && filename[1] == ':' && filename[2] == '/')
c8563aaf86c04f0e2284bcc8e444a0651c157ea0Andreas Gustafssonisc_file_iscurrentdir(const char *filename) {
c8563aaf86c04f0e2284bcc8e444a0651c157ea0Andreas Gustafsson return (ISC_TF(filename[0] == '.' && filename[1] == '\0'));
6184f9fc1e65ef131ea308a1a92882595bb1aeeaAndreas Gustafssonisc_file_ischdiridempotent(const char *filename) {
return (ISC_TRUE);
return (ISC_FALSE);
if (s == NULL)
return (filename);
if (s == NULL) {
return (ISC_R_NOSPACE);
if (p == NULL) {
return (ISC_R_NOSPACE);
return (ISC_R_SUCCESS);
len = p - s;
return (ISC_R_NOSPACE);
return (ISC_R_SUCCESS);
char *ptrname;
if (retval == 0)
return (ISC_R_NOTFOUND);
return (ISC_R_NOSPACE);
return (ISC_R_SUCCESS);
int fh;
return (ISC_R_SUCCESS);
int flags;
FILE *f;
int fd;
return (ISC_R_INVALIDFILE);
return (result);
if (f == NULL) {
return (result);
*fp = f;
return (ISC_R_SUCCESS);