1 /* 2 * Copyright (C) 2004-2007, 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") 3 * Copyright (C) 2000, 2001 Internet Software Consortium. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 11 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 15 * PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 /* $Id$ */ 19 20 #ifndef ISC_FILE_H 21 #define ISC_FILE_H 1 22 23 /*! \file isc/file.h */ 24 25 #include <stdio.h> 26 27 #include <isc/lang.h> 28 #include <isc/types.h> 29 30 ISC_LANG_BEGINDECLS 31 32 isc_result_t 33 isc_file_settime(const char *file, isc_time_t *itime); 34 35 isc_result_t 36 isc_file_getmodtime(const char *file, isc_time_t *itime); 37 /*!< 38 * \brief Get the time of last modification of a file. 39 * 40 * Notes: 41 *\li The time that is set is relative to the (OS-specific) epoch, as are 42 * all isc_time_t structures. 43 * 44 * Requires: 45 *\li file != NULL. 46 *\li time != NULL. 47 * 48 * Ensures: 49 *\li If the file could not be accessed, 'time' is unchanged. 50 * 51 * Returns: 52 *\li #ISC_R_SUCCESS 53 * Success. 54 *\li #ISC_R_NOTFOUND 55 * No such file exists. 56 *\li #ISC_R_INVALIDFILE 57 * The path specified was not usable by the operating system. 58 *\li #ISC_R_NOPERM 59 * The file's metainformation could not be retrieved because 60 * permission was denied to some part of the file's path. 61 *\li #ISC_R_EIO 62 * Hardware error interacting with the filesystem. 63 *\li #ISC_R_UNEXPECTED 64 * Something totally unexpected happened. 65 * 66 */ 67 68 isc_result_t 69 isc_file_mktemplate(const char *path, char *buf, size_t buflen); 70 /*!< 71 * \brief Generate a template string suitable for use with isc_file_openunique(). 72 * 73 * Notes: 74 *\li This function is intended to make creating temporary files 75 * portable between different operating systems. 76 * 77 *\li The path is prepended to an implementation-defined string and 78 * placed into buf. The string has no path characters in it, 79 * and its maximum length is 14 characters plus a NUL. Thus 80 * buflen should be at least strlen(path) + 15 characters or 81 * an error will be returned. 82 * 83 * Requires: 84 *\li buf != NULL. 85 * 86 * Ensures: 87 *\li If result == #ISC_R_SUCCESS: 88 * buf contains a string suitable for use as the template argument 89 * to isc_file_openunique(). 90 * 91 *\li If result != #ISC_R_SUCCESS: 92 * buf is unchanged. 93 * 94 * Returns: 95 *\li #ISC_R_SUCCESS Success. 96 *\li #ISC_R_NOSPACE buflen indicates buf is too small for the catenation 97 * of the path with the internal template string. 98 */ 99 100 101 isc_result_t 102 isc_file_openunique(char *templet, FILE **fp); 103 isc_result_t 104 isc_file_openuniqueprivate(char *templet, FILE **fp); 105 isc_result_t 106 isc_file_openuniquemode(char *templet, int mode, FILE **fp); 107 /*!< 108 * \brief Create and open a file with a unique name based on 'templet'. 109 * 110 * Notes: 111 *\li 'template' is a reserved work in C++. If you want to complain 112 * about the spelling of 'templet', first look it up in the 113 * Merriam-Webster English dictionary. (http://www.m-w.com/) 114 * 115 *\li This function works by using the template to generate file names. 116 * The template must be a writable string, as it is modified in place. 117 * Trailing X characters in the file name (full file name on Unix, 118 * basename on Win32 -- eg, tmp-XXXXXX vs XXXXXX.tmp, respectively) 119 * are replaced with ASCII characters until a non-existent filename 120 * is found. If the template does not include pathname information, 121 * the files in the working directory of the program are searched. 122 * 123 *\li isc_file_mktemplate is a good, portable way to get a template. 124 * 125 * Requires: 126 *\li 'fp' is non-NULL and '*fp' is NULL. 127 * 128 *\li 'template' is non-NULL, and of a form suitable for use by 129 * the system as described above. 130 * 131 * Ensures: 132 *\li If result is #ISC_R_SUCCESS: 133 * *fp points to an stream opening in stdio's "w+" mode. 134 * 135 *\li If result is not #ISC_R_SUCCESS: 136 * *fp is NULL. 137 * 138 * No file is open. Even if one was created (but unable 139 * to be reopened as a stdio FILE pointer) then it has been 140 * removed. 141 * 142 *\li This function does *not* ensure that the template string has not been 143 * modified, even if the operation was unsuccessful. 144 * 145 * Returns: 146 *\li #ISC_R_SUCCESS 147 * Success. 148 *\li #ISC_R_EXISTS 149 * No file with a unique name could be created based on the 150 * template. 151 *\li #ISC_R_INVALIDFILE 152 * The path specified was not usable by the operating system. 153 *\li #ISC_R_NOPERM 154 * The file could not be created because permission was denied 155 * to some part of the file's path. 156 *\li #ISC_R_IOERROR 157 * Hardware error interacting with the filesystem. 158 *\li #ISC_R_UNEXPECTED 159 * Something totally unexpected happened. 160 */ 161 162 isc_result_t 163 isc_file_remove(const char *filename); 164 /*!< 165 * \brief Remove the file named by 'filename'. 166 */ 167 168 isc_result_t 169 isc_file_rename(const char *oldname, const char *newname); 170 /*!< 171 * \brief Rename the file 'oldname' to 'newname'. 172 */ 173 174 isc_boolean_t 175 isc_file_exists(const char *pathname); 176 /*!< 177 * \brief Return #ISC_TRUE if the calling process can tell that the given file exists. 178 * Will not return true if the calling process has insufficient privileges 179 * to search the entire path. 180 */ 181 182 isc_boolean_t 183 isc_file_isabsolute(const char *filename); 184 /*!< 185 * \brief Return #ISC_TRUE if the given file name is absolute. 186 */ 187 188 isc_result_t 189 isc_file_isplainfile(const char *name); 190 /*!< 191 * \brief Check that the file is a plain file 192 * 193 * Returns: 194 *\li #ISC_R_SUCCESS 195 * Success. The file is a plain file. 196 *\li #ISC_R_INVALIDFILE 197 * The path specified was not usable by the operating system. 198 *\li #ISC_R_FILENOTFOUND 199 * The file does not exist. This return code comes from 200 * errno=ENOENT when stat returns -1. This code is mentioned 201 * here, because in logconf.c, it is the one rcode that is 202 * permitted in addition to ISC_R_SUCCESS. This is done since 203 * the next call in logconf.c is to isc_stdio_open(), which 204 * will create the file if it can. 205 *\li #other ISC_R_* errors translated from errno 206 * These occur when stat returns -1 and an errno. 207 */ 208 209 isc_boolean_t 210 isc_file_iscurrentdir(const char *filename); 211 /*!< 212 * \brief Return #ISC_TRUE if the given file name is the current directory ("."). 213 */ 214 215 isc_boolean_t 216 isc_file_ischdiridempotent(const char *filename); 217 /*%< 218 * Return #ISC_TRUE if calling chdir(filename) multiple times will give 219 * the same result as calling it once. 220 */ 221 222 const char * 223 isc_file_basename(const char *filename); 224 /*%< 225 * Return the final component of the path in the file name. 226 */ 227 228 isc_result_t 229 isc_file_progname(const char *filename, char *buf, size_t buflen); 230 /*!< 231 * \brief Given an operating system specific file name "filename" 232 * referring to a program, return the canonical program name. 233 * 234 * 235 * Any directory prefix or executable file name extension (if 236 * used on the OS in case) is stripped. On systems where program 237 * names are case insensitive, the name is canonicalized to all 238 * lower case. The name is written to 'buf', an array of 'buflen' 239 * chars, and null terminated. 240 * 241 * Returns: 242 *\li #ISC_R_SUCCESS 243 *\li #ISC_R_NOSPACE The name did not fit in 'buf'. 244 */ 245 246 isc_result_t 247 isc_file_template(const char *path, const char *templet, char *buf, 248 size_t buflen); 249 /*%< 250 * Create an OS specific template using 'path' to define the directory 251 * 'templet' to describe the filename and store the result in 'buf' 252 * such that path can be renamed to buf atomically. 253 */ 254 255 isc_result_t 256 isc_file_renameunique(const char *file, char *templet); 257 /*%< 258 * Rename 'file' using 'templet' as a template for the new file name. 259 */ 260 261 isc_result_t 262 isc_file_absolutepath(const char *filename, char *path, size_t pathlen); 263 /*%< 264 * Given a file name, return the fully qualified path to the file. 265 */ 266 267 /* 268 * XXX We should also have a isc_file_writeeopen() function 269 * for safely open a file in a publicly writable directory 270 * (see write_open() in BIND 8's ns_config.c). 271 */ 272 273 isc_result_t 274 isc_file_truncate(const char *filename, isc_offset_t size); 275 /*%< 276 * Truncate/extend the file specified to 'size' bytes. 277 */ 278 279 isc_result_t 280 isc_file_safecreate(const char *filename, FILE **fp); 281 /*%< 282 * Open 'filename' for writing, truncating if necessary. Ensure that 283 * if it existed it was a normal file. If creating the file, ensure 284 * that only the owner can read/write it. 285 */ 286 287 isc_result_t 288 isc_file_splitpath(isc_mem_t *mctx, char *path, 289 char **dirname, char **basename); 290 /*%< 291 * Split a path into dirname and basename. If 'path' contains no slash 292 * (or, on windows, backslash), then '*dirname' is set to ".". 293 * 294 * Allocates memory for '*dirname', which can be freed with isc_mem_free(). 295 * 296 * Returns: 297 * - ISC_R_SUCCESS on success 298 * - ISC_R_INVALIDFILE if 'path' is empty or ends with '/' 299 * - ISC_R_NOMEMORY if unable to allocate memory 300 */ 301 302 ISC_LANG_ENDDECLS 303 304 #endif /* ISC_FILE_H */ 305