1 /* $NetBSD: file.h,v 1.9 2014/12/10 04:38:00 christos Exp $ */ 2 3 /* 4 * Copyright (C) 2004-2007, 2009, 2011, 2012, 2014 Internet Systems Consortium, Inc. ("ISC") 5 * Copyright (C) 2000, 2001 Internet Software Consortium. 6 * 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. 10 * 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. 18 */ 19 20 /* Id */ 21 22 #ifndef ISC_FILE_H 23 #define ISC_FILE_H 1 24 25 /*! \file isc/file.h */ 26 27 #include <stdio.h> 28 29 #include <isc/lang.h> 30 #include <isc/stat.h> 31 #include <isc/types.h> 32 33 ISC_LANG_BEGINDECLS 34 35 isc_result_t 36 isc_file_settime(const char *file, isc_time_t *time); 37 38 isc_result_t 39 isc_file_mode(const char *file, mode_t *modep); 40 41 isc_result_t 42 isc_file_getmodtime(const char *file, isc_time_t *time); 43 /*!< 44 * \brief Get the time of last modification of a file. 45 * 46 * Notes: 47 *\li The time that is set is relative to the (OS-specific) epoch, as are 48 * all isc_time_t structures. 49 * 50 * Requires: 51 *\li file != NULL. 52 *\li time != NULL. 53 * 54 * Ensures: 55 *\li If the file could not be accessed, 'time' is unchanged. 56 * 57 * Returns: 58 *\li #ISC_R_SUCCESS 59 * Success. 60 *\li #ISC_R_NOTFOUND 61 * No such file exists. 62 *\li #ISC_R_INVALIDFILE 63 * The path specified was not usable by the operating system. 64 *\li #ISC_R_NOPERM 65 * The file's metainformation could not be retrieved because 66 * permission was denied to some part of the file's path. 67 *\li #ISC_R_IOERROR 68 * Hardware error interacting with the filesystem. 69 *\li #ISC_R_UNEXPECTED 70 * Something totally unexpected happened. 71 * 72 */ 73 74 isc_result_t 75 isc_file_mktemplate(const char *path, char *buf, size_t buflen); 76 /*!< 77 * \brief Generate a template string suitable for use with isc_file_openunique(). 78 * 79 * Notes: 80 *\li This function is intended to make creating temporary files 81 * portable between different operating systems. 82 * 83 *\li The path is prepended to an implementation-defined string and 84 * placed into buf. The string has no path characters in it, 85 * and its maximum length is 14 characters plus a NUL. Thus 86 * buflen should be at least strlen(path) + 15 characters or 87 * an error will be returned. 88 * 89 * Requires: 90 *\li buf != NULL. 91 * 92 * Ensures: 93 *\li If result == #ISC_R_SUCCESS: 94 * buf contains a string suitable for use as the template argument 95 * to isc_file_openunique(). 96 * 97 *\li If result != #ISC_R_SUCCESS: 98 * buf is unchanged. 99 * 100 * Returns: 101 *\li #ISC_R_SUCCESS Success. 102 *\li #ISC_R_NOSPACE buflen indicates buf is too small for the catenation 103 * of the path with the internal template string. 104 */ 105 106 isc_result_t 107 isc_file_openunique(char *templet, FILE **fp); 108 isc_result_t 109 isc_file_openuniqueprivate(char *templet, FILE **fp); 110 isc_result_t 111 isc_file_openuniquemode(char *templet, int mode, FILE **fp); 112 isc_result_t 113 isc_file_bopenunique(char *templet, FILE **fp); 114 isc_result_t 115 isc_file_bopenuniqueprivate(char *templet, FILE **fp); 116 isc_result_t 117 isc_file_bopenuniquemode(char *templet, int mode, FILE **fp); 118 /*!< 119 * \brief Create and open a file with a unique name based on 'templet'. 120 * isc_file_bopen*() open the file in binary mode in Windows. 121 * isc_file_open*() open the file in text mode in Windows. 122 * 123 * Notes: 124 *\li 'template' is a reserved work in C++. If you want to complain 125 * about the spelling of 'templet', first look it up in the 126 * Merriam-Webster English dictionary. (http://www.m-w.com/) 127 * 128 *\li This function works by using the template to generate file names. 129 * The template must be a writable string, as it is modified in place. 130 * Trailing X characters in the file name (full file name on Unix, 131 * basename on Win32 -- eg, tmp-XXXXXX vs XXXXXX.tmp, respectively) 132 * are replaced with ASCII characters until a non-existent filename 133 * is found. If the template does not include pathname information, 134 * the files in the working directory of the program are searched. 135 * 136 *\li isc_file_mktemplate is a good, portable way to get a template. 137 * 138 * Requires: 139 *\li 'fp' is non-NULL and '*fp' is NULL. 140 * 141 *\li 'template' is non-NULL, and of a form suitable for use by 142 * the system as described above. 143 * 144 * Ensures: 145 *\li If result is #ISC_R_SUCCESS: 146 * *fp points to an stream opening in stdio's "w+" mode. 147 * 148 *\li If result is not #ISC_R_SUCCESS: 149 * *fp is NULL. 150 * 151 * No file is open. Even if one was created (but unable 152 * to be reopened as a stdio FILE pointer) then it has been 153 * removed. 154 * 155 *\li This function does *not* ensure that the template string has not been 156 * modified, even if the operation was unsuccessful. 157 * 158 * Returns: 159 *\li #ISC_R_SUCCESS 160 * Success. 161 *\li #ISC_R_EXISTS 162 * No file with a unique name could be created based on the 163 * template. 164 *\li #ISC_R_INVALIDFILE 165 * The path specified was not usable by the operating system. 166 *\li #ISC_R_NOPERM 167 * The file could not be created because permission was denied 168 * to some part of the file's path. 169 *\li #ISC_R_IOERROR 170 * Hardware error interacting with the filesystem. 171 *\li #ISC_R_UNEXPECTED 172 * Something totally unexpected happened. 173 */ 174 175 isc_result_t 176 isc_file_remove(const char *filename); 177 /*!< 178 * \brief Remove the file named by 'filename'. 179 */ 180 181 isc_result_t 182 isc_file_rename(const char *oldname, const char *newname); 183 /*!< 184 * \brief Rename the file 'oldname' to 'newname'. 185 */ 186 187 isc_boolean_t 188 isc_file_exists(const char *pathname); 189 /*!< 190 * \brief Return #ISC_TRUE if the calling process can tell that the given file exists. 191 * Will not return true if the calling process has insufficient privileges 192 * to search the entire path. 193 */ 194 195 isc_boolean_t 196 isc_file_isabsolute(const char *filename); 197 /*!< 198 * \brief Return #ISC_TRUE if the given file name is absolute. 199 */ 200 201 isc_result_t 202 isc_file_isplainfile(const char *name); 203 204 isc_result_t 205 isc_file_isplainfilefd(int fd); 206 /*!< 207 * \brief Check that the file is a plain file 208 * 209 * Returns: 210 *\li #ISC_R_SUCCESS 211 * Success. The file is a plain file. 212 *\li #ISC_R_INVALIDFILE 213 * The path specified was not usable by the operating system. 214 *\li #ISC_R_FILENOTFOUND 215 * The file does not exist. This return code comes from 216 * errno=ENOENT when stat returns -1. This code is mentioned 217 * here, because in logconf.c, it is the one rcode that is 218 * permitted in addition to ISC_R_SUCCESS. This is done since 219 * the next call in logconf.c is to isc_stdio_open(), which 220 * will create the file if it can. 221 *\li other ISC_R_* errors translated from errno 222 * These occur when stat returns -1 and an errno. 223 */ 224 225 isc_result_t 226 isc_file_isdirectory(const char *name); 227 /*!< 228 * \brief Check that 'name' exists and is a directory. 229 * 230 * Returns: 231 *\li #ISC_R_SUCCESS 232 * Success, file is a directory. 233 *\li #ISC_R_INVALIDFILE 234 * File is not a directory. 235 *\li #ISC_R_FILENOTFOUND 236 * File does not exist. 237 *\li other ISC_R_* errors translated from errno 238 * These occur when stat returns -1 and an errno. 239 */ 240 241 isc_boolean_t 242 isc_file_iscurrentdir(const char *filename); 243 /*!< 244 * \brief Return #ISC_TRUE if the given file name is the current directory ("."). 245 */ 246 247 isc_boolean_t 248 isc_file_ischdiridempotent(const char *filename); 249 /*%< 250 * Return #ISC_TRUE if calling chdir(filename) multiple times will give 251 * the same result as calling it once. 252 */ 253 254 const char * 255 isc_file_basename(const char *filename); 256 /*%< 257 * Return the final component of the path in the file name. 258 */ 259 260 isc_result_t 261 isc_file_progname(const char *filename, char *buf, size_t buflen); 262 /*!< 263 * \brief Given an operating system specific file name "filename" 264 * referring to a program, return the canonical program name. 265 * 266 * 267 * Any directory prefix or executable file name extension (if 268 * used on the OS in case) is stripped. On systems where program 269 * names are case insensitive, the name is canonicalized to all 270 * lower case. The name is written to 'buf', an array of 'buflen' 271 * chars, and null terminated. 272 * 273 * Returns: 274 *\li #ISC_R_SUCCESS 275 *\li #ISC_R_NOSPACE The name did not fit in 'buf'. 276 */ 277 278 isc_result_t 279 isc_file_template(const char *path, const char *templet, char *buf, 280 size_t buflen); 281 /*%< 282 * Create an OS specific template using 'path' to define the directory 283 * 'templet' to describe the filename and store the result in 'buf' 284 * such that path can be renamed to buf atomically. 285 */ 286 287 isc_result_t 288 isc_file_renameunique(const char *file, char *templet); 289 /*%< 290 * Rename 'file' using 'templet' as a template for the new file name. 291 */ 292 293 isc_result_t 294 isc_file_absolutepath(const char *filename, char *path, size_t pathlen); 295 /*%< 296 * Given a file name, return the fully qualified path to the file. 297 */ 298 299 /* 300 * XXX We should also have a isc_file_writeeopen() function 301 * for safely open a file in a publicly writable directory 302 * (see write_open() in BIND 8's ns_config.c). 303 */ 304 305 isc_result_t 306 isc_file_truncate(const char *filename, isc_offset_t size); 307 /*%< 308 * Truncate/extend the file specified to 'size' bytes. 309 */ 310 311 isc_result_t 312 isc_file_safecreate(const char *filename, FILE **fp); 313 /*%< 314 * Open 'filename' for writing, truncating if necessary. Ensure that 315 * if it existed it was a normal file. If creating the file, ensure 316 * that only the owner can read/write it. 317 */ 318 319 isc_result_t 320 isc_file_splitpath(isc_mem_t *mctx, char *path, 321 char **dirname, char **basename); 322 /*%< 323 * Split a path into dirname and basename. If 'path' contains no slash 324 * (or, on windows, backslash), then '*dirname' is set to ".". 325 * 326 * Allocates memory for '*dirname', which can be freed with isc_mem_free(). 327 * 328 * Returns: 329 * - ISC_R_SUCCESS on success 330 * - ISC_R_INVALIDFILE if 'path' is empty or ends with '/' 331 * - ISC_R_NOMEMORY if unable to allocate memory 332 */ 333 334 isc_result_t 335 isc_file_getsize(const char *file, off_t *size); 336 /*%< 337 * Return the size of the file (stored in the parameter pointed 338 * to by 'size') in bytes. 339 * 340 * Returns: 341 * - ISC_R_SUCCESS on success 342 */ 343 344 isc_result_t 345 isc_file_getsizefd(int fd, off_t *size); 346 /*%< 347 * Return the size of the file (stored in the parameter pointed 348 * to by 'size') in bytes. 349 * 350 * Returns: 351 * - ISC_R_SUCCESS on success 352 */ 353 354 void * 355 isc_file_mmap(void *addr, size_t len, int prot, 356 int flags, int fd, off_t offset); 357 /*%< 358 * Portable front-end to mmap(). If mmap() is not defined on this 359 * platform, then we simulate it by calling malloc() and read(). 360 * (In this event, the addr, prot, and flags parameters are ignored). 361 */ 362 363 int 364 isc_file_munmap(void *addr, size_t len); 365 /*%< 366 * Portable front-end to munmap(). If munmap() is not defined on 367 * this platform, then we simply free the memory. 368 */ 369 370 ISC_LANG_ENDDECLS 371 372 #endif /* ISC_FILE_H */ 373