00001 /* 00002 * Copyright (C) 2004-2007, 2009, 2011, 2012, 2014 Internet Systems Consortium, Inc. ("ISC") 00003 * Copyright (C) 2000, 2001 Internet Software Consortium. 00004 * 00005 * Permission to use, copy, modify, and/or distribute this software for any 00006 * purpose with or without fee is hereby granted, provided that the above 00007 * copyright notice and this permission notice appear in all copies. 00008 * 00009 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 00010 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 00011 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 00012 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 00013 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 00014 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 00015 * PERFORMANCE OF THIS SOFTWARE. 00016 */ 00017 00018 /* $Id$ */ 00019 00020 #ifndef ISC_FILE_H 00021 #define ISC_FILE_H 1 00022 00023 /*! \file isc/file.h */ 00024 00025 #include <stdio.h> 00026 00027 #include <isc/lang.h> 00028 #include <isc/stat.h> 00029 #include <isc/types.h> 00030 00031 ISC_LANG_BEGINDECLS 00032 00033 isc_result_t 00034 isc_file_settime(const char *file, isc_time_t *time); 00035 00036 isc_result_t 00037 isc_file_mode(const char *file, mode_t *modep); 00038 00039 isc_result_t 00040 isc_file_getmodtime(const char *file, isc_time_t *time); 00041 /*!< 00042 * \brief Get the time of last modification of a file. 00043 * 00044 * Notes: 00045 *\li The time that is set is relative to the (OS-specific) epoch, as are 00046 * all isc_time_t structures. 00047 * 00048 * Requires: 00049 *\li file != NULL. 00050 *\li time != NULL. 00051 * 00052 * Ensures: 00053 *\li If the file could not be accessed, 'time' is unchanged. 00054 * 00055 * Returns: 00056 *\li #ISC_R_SUCCESS 00057 * Success. 00058 *\li #ISC_R_NOTFOUND 00059 * No such file exists. 00060 *\li #ISC_R_INVALIDFILE 00061 * The path specified was not usable by the operating system. 00062 *\li #ISC_R_NOPERM 00063 * The file's metainformation could not be retrieved because 00064 * permission was denied to some part of the file's path. 00065 *\li #ISC_R_IOERROR 00066 * Hardware error interacting with the filesystem. 00067 *\li #ISC_R_UNEXPECTED 00068 * Something totally unexpected happened. 00069 * 00070 */ 00071 00072 isc_result_t 00073 isc_file_mktemplate(const char *path, char *buf, size_t buflen); 00074 /*!< 00075 * \brief Generate a template string suitable for use with isc_file_openunique(). 00076 * 00077 * Notes: 00078 *\li This function is intended to make creating temporary files 00079 * portable between different operating systems. 00080 * 00081 *\li The path is prepended to an implementation-defined string and 00082 * placed into buf. The string has no path characters in it, 00083 * and its maximum length is 14 characters plus a NUL. Thus 00084 * buflen should be at least strlen(path) + 15 characters or 00085 * an error will be returned. 00086 * 00087 * Requires: 00088 *\li buf != NULL. 00089 * 00090 * Ensures: 00091 *\li If result == #ISC_R_SUCCESS: 00092 * buf contains a string suitable for use as the template argument 00093 * to isc_file_openunique(). 00094 * 00095 *\li If result != #ISC_R_SUCCESS: 00096 * buf is unchanged. 00097 * 00098 * Returns: 00099 *\li #ISC_R_SUCCESS Success. 00100 *\li #ISC_R_NOSPACE buflen indicates buf is too small for the catenation 00101 * of the path with the internal template string. 00102 */ 00103 00104 isc_result_t 00105 isc_file_openunique(char *templet, FILE **fp); 00106 isc_result_t 00107 isc_file_openuniqueprivate(char *templet, FILE **fp); 00108 isc_result_t 00109 isc_file_openuniquemode(char *templet, int mode, FILE **fp); 00110 isc_result_t 00111 isc_file_bopenunique(char *templet, FILE **fp); 00112 isc_result_t 00113 isc_file_bopenuniqueprivate(char *templet, FILE **fp); 00114 isc_result_t 00115 isc_file_bopenuniquemode(char *templet, int mode, FILE **fp); 00116 /*!< 00117 * \brief Create and open a file with a unique name based on 'templet'. 00118 * isc_file_bopen*() open the file in binary mode in Windows. 00119 * isc_file_open*() open the file in text mode in Windows. 00120 * 00121 * Notes: 00122 *\li 'template' is a reserved work in C++. If you want to complain 00123 * about the spelling of 'templet', first look it up in the 00124 * Merriam-Webster English dictionary. (http://www.m-w.com/) 00125 * 00126 *\li This function works by using the template to generate file names. 00127 * The template must be a writable string, as it is modified in place. 00128 * Trailing X characters in the file name (full file name on Unix, 00129 * basename on Win32 -- eg, tmp-XXXXXX vs XXXXXX.tmp, respectively) 00130 * are replaced with ASCII characters until a non-existent filename 00131 * is found. If the template does not include pathname information, 00132 * the files in the working directory of the program are searched. 00133 * 00134 *\li isc_file_mktemplate is a good, portable way to get a template. 00135 * 00136 * Requires: 00137 *\li 'fp' is non-NULL and '*fp' is NULL. 00138 * 00139 *\li 'template' is non-NULL, and of a form suitable for use by 00140 * the system as described above. 00141 * 00142 * Ensures: 00143 *\li If result is #ISC_R_SUCCESS: 00144 * *fp points to an stream opening in stdio's "w+" mode. 00145 * 00146 *\li If result is not #ISC_R_SUCCESS: 00147 * *fp is NULL. 00148 * 00149 * No file is open. Even if one was created (but unable 00150 * to be reopened as a stdio FILE pointer) then it has been 00151 * removed. 00152 * 00153 *\li This function does *not* ensure that the template string has not been 00154 * modified, even if the operation was unsuccessful. 00155 * 00156 * Returns: 00157 *\li #ISC_R_SUCCESS 00158 * Success. 00159 *\li #ISC_R_EXISTS 00160 * No file with a unique name could be created based on the 00161 * template. 00162 *\li #ISC_R_INVALIDFILE 00163 * The path specified was not usable by the operating system. 00164 *\li #ISC_R_NOPERM 00165 * The file could not be created because permission was denied 00166 * to some part of the file's path. 00167 *\li #ISC_R_IOERROR 00168 * Hardware error interacting with the filesystem. 00169 *\li #ISC_R_UNEXPECTED 00170 * Something totally unexpected happened. 00171 */ 00172 00173 isc_result_t 00174 isc_file_remove(const char *filename); 00175 /*!< 00176 * \brief Remove the file named by 'filename'. 00177 */ 00178 00179 isc_result_t 00180 isc_file_rename(const char *oldname, const char *newname); 00181 /*!< 00182 * \brief Rename the file 'oldname' to 'newname'. 00183 */ 00184 00185 isc_boolean_t 00186 isc_file_exists(const char *pathname); 00187 /*!< 00188 * \brief Return #ISC_TRUE if the calling process can tell that the given file exists. 00189 * Will not return true if the calling process has insufficient privileges 00190 * to search the entire path. 00191 */ 00192 00193 isc_boolean_t 00194 isc_file_isabsolute(const char *filename); 00195 /*!< 00196 * \brief Return #ISC_TRUE if the given file name is absolute. 00197 */ 00198 00199 isc_result_t 00200 isc_file_isplainfile(const char *name); 00201 00202 isc_result_t 00203 isc_file_isplainfilefd(int fd); 00204 /*!< 00205 * \brief Check that the file is a plain file 00206 * 00207 * Returns: 00208 *\li #ISC_R_SUCCESS 00209 * Success. The file is a plain file. 00210 *\li #ISC_R_INVALIDFILE 00211 * The path specified was not usable by the operating system. 00212 *\li #ISC_R_FILENOTFOUND 00213 * The file does not exist. This return code comes from 00214 * errno=ENOENT when stat returns -1. This code is mentioned 00215 * here, because in logconf.c, it is the one rcode that is 00216 * permitted in addition to ISC_R_SUCCESS. This is done since 00217 * the next call in logconf.c is to isc_stdio_open(), which 00218 * will create the file if it can. 00219 *\li other ISC_R_* errors translated from errno 00220 * These occur when stat returns -1 and an errno. 00221 */ 00222 00223 isc_result_t 00224 isc_file_isdirectory(const char *name); 00225 /*!< 00226 * \brief Check that 'name' exists and is a directory. 00227 * 00228 * Returns: 00229 *\li #ISC_R_SUCCESS 00230 * Success, file is a directory. 00231 *\li #ISC_R_INVALIDFILE 00232 * File is not a directory. 00233 *\li #ISC_R_FILENOTFOUND 00234 * File does not exist. 00235 *\li other ISC_R_* errors translated from errno 00236 * These occur when stat returns -1 and an errno. 00237 */ 00238 00239 isc_boolean_t 00240 isc_file_iscurrentdir(const char *filename); 00241 /*!< 00242 * \brief Return #ISC_TRUE if the given file name is the current directory ("."). 00243 */ 00244 00245 isc_boolean_t 00246 isc_file_ischdiridempotent(const char *filename); 00247 /*%< 00248 * Return #ISC_TRUE if calling chdir(filename) multiple times will give 00249 * the same result as calling it once. 00250 */ 00251 00252 const char * 00253 isc_file_basename(const char *filename); 00254 /*%< 00255 * Return the final component of the path in the file name. 00256 */ 00257 00258 isc_result_t 00259 isc_file_progname(const char *filename, char *buf, size_t buflen); 00260 /*!< 00261 * \brief Given an operating system specific file name "filename" 00262 * referring to a program, return the canonical program name. 00263 * 00264 * 00265 * Any directory prefix or executable file name extension (if 00266 * used on the OS in case) is stripped. On systems where program 00267 * names are case insensitive, the name is canonicalized to all 00268 * lower case. The name is written to 'buf', an array of 'buflen' 00269 * chars, and null terminated. 00270 * 00271 * Returns: 00272 *\li #ISC_R_SUCCESS 00273 *\li #ISC_R_NOSPACE The name did not fit in 'buf'. 00274 */ 00275 00276 isc_result_t 00277 isc_file_template(const char *path, const char *templet, char *buf, 00278 size_t buflen); 00279 /*%< 00280 * Create an OS specific template using 'path' to define the directory 00281 * 'templet' to describe the filename and store the result in 'buf' 00282 * such that path can be renamed to buf atomically. 00283 */ 00284 00285 isc_result_t 00286 isc_file_renameunique(const char *file, char *templet); 00287 /*%< 00288 * Rename 'file' using 'templet' as a template for the new file name. 00289 */ 00290 00291 isc_result_t 00292 isc_file_absolutepath(const char *filename, char *path, size_t pathlen); 00293 /*%< 00294 * Given a file name, return the fully qualified path to the file. 00295 */ 00296 00297 /* 00298 * XXX We should also have a isc_file_writeeopen() function 00299 * for safely open a file in a publicly writable directory 00300 * (see write_open() in BIND 8's ns_config.c). 00301 */ 00302 00303 isc_result_t 00304 isc_file_truncate(const char *filename, isc_offset_t size); 00305 /*%< 00306 * Truncate/extend the file specified to 'size' bytes. 00307 */ 00308 00309 isc_result_t 00310 isc_file_safecreate(const char *filename, FILE **fp); 00311 /*%< 00312 * Open 'filename' for writing, truncating if necessary. Ensure that 00313 * if it existed it was a normal file. If creating the file, ensure 00314 * that only the owner can read/write it. 00315 */ 00316 00317 isc_result_t 00318 isc_file_splitpath(isc_mem_t *mctx, char *path, 00319 char **dirname, char **basename); 00320 /*%< 00321 * Split a path into dirname and basename. If 'path' contains no slash 00322 * (or, on windows, backslash), then '*dirname' is set to ".". 00323 * 00324 * Allocates memory for '*dirname', which can be freed with isc_mem_free(). 00325 * 00326 * Returns: 00327 * - ISC_R_SUCCESS on success 00328 * - ISC_R_INVALIDFILE if 'path' is empty or ends with '/' 00329 * - ISC_R_NOMEMORY if unable to allocate memory 00330 */ 00331 00332 isc_result_t 00333 isc_file_getsize(const char *file, off_t *size); 00334 /*%< 00335 * Return the size of the file (stored in the parameter pointed 00336 * to by 'size') in bytes. 00337 * 00338 * Returns: 00339 * - ISC_R_SUCCESS on success 00340 */ 00341 00342 isc_result_t 00343 isc_file_getsizefd(int fd, off_t *size); 00344 /*%< 00345 * Return the size of the file (stored in the parameter pointed 00346 * to by 'size') in bytes. 00347 * 00348 * Returns: 00349 * - ISC_R_SUCCESS on success 00350 */ 00351 00352 void * 00353 isc_file_mmap(void *addr, size_t len, int prot, 00354 int flags, int fd, off_t offset); 00355 /*%< 00356 * Portable front-end to mmap(). If mmap() is not defined on this 00357 * platform, then we simulate it by calling malloc() and read(). 00358 * (In this event, the addr, prot, and flags parameters are ignored). 00359 */ 00360 00361 int 00362 isc_file_munmap(void *addr, size_t len); 00363 /*%< 00364 * Portable front-end to munmap(). If munmap() is not defined on 00365 * this platform, then we simply free the memory. 00366 */ 00367 00368 isc_result_t 00369 isc_file_sanitize(const char *dir, const char *base, const char *ext, 00370 char *path, size_t length); 00371 /*%< 00372 * Generate a sanitized filename, such as for MKEYS or NZF files. 00373 * 00374 * Historically, MKEYS and NZF files used SHA256 hashes of the view 00375 * name for the filename; this was to deal with the possibility of 00376 * forbidden characters such as "/" being in a view name, and to 00377 * avoid problems with case-insensitive file systems. 00378 * 00379 * Given a basename 'base' and an extension 'ext', this function checks 00380 * for the existence of file using the old-style name format in directory 00381 * 'dir'. If found, it returns the path to that file. If there is no 00382 * file already in place, a new pathname is generated; if the basename 00383 * contains any excluded characters, then a truncated SHA256 hash is 00384 * used, otherwise the basename is used. The path name is copied 00385 * into 'path', which must point to a buffer of at least 'length' 00386 * bytes. 00387 * 00388 * Requires: 00389 * - base != NULL 00390 * - path != NULL 00391 * 00392 * Returns: 00393 * - ISC_R_SUCCESS on success 00394 * - ISC_R_NOSPACE if the resulting path would be longer than 'length' 00395 */ 00396 00397 ISC_LANG_ENDDECLS 00398 00399 #endif /* ISC_FILE_H */