file.h revision 290001
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
30ISC_LANG_BEGINDECLS
31
32isc_result_t
33isc_file_settime(const char *file, isc_time_t *itime);
34
35isc_result_t
36isc_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
68isc_result_t
69isc_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
101isc_result_t
102isc_file_openunique(char *templet, FILE **fp);
103isc_result_t
104isc_file_openuniqueprivate(char *templet, FILE **fp);
105isc_result_t
106isc_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
162isc_result_t
163isc_file_remove(const char *filename);
164/*!<
165 * \brief Remove the file named by 'filename'.
166 */
167
168isc_result_t
169isc_file_rename(const char *oldname, const char *newname);
170/*!<
171 * \brief Rename the file 'oldname' to 'newname'.
172 */
173
174isc_boolean_t
175isc_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
182isc_boolean_t
183isc_file_isabsolute(const char *filename);
184/*!<
185 * \brief Return #ISC_TRUE if the given file name is absolute.
186 */
187
188isc_result_t
189isc_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
209isc_boolean_t
210isc_file_iscurrentdir(const char *filename);
211/*!<
212 * \brief Return #ISC_TRUE if the given file name is the current directory (".").
213 */
214
215isc_boolean_t
216isc_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
222const char *
223isc_file_basename(const char *filename);
224/*%<
225 * Return the final component of the path in the file name.
226 */
227
228isc_result_t
229isc_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
246isc_result_t
247isc_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
255isc_result_t
256isc_file_renameunique(const char *file, char *templet);
257/*%<
258 * Rename 'file' using 'templet' as a template for the new file name.
259 */
260
261isc_result_t
262isc_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
273isc_result_t
274isc_file_truncate(const char *filename, isc_offset_t size);
275/*%<
276 * Truncate/extend the file specified to 'size' bytes.
277 */
278
279isc_result_t
280isc_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
287isc_result_t
288isc_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
302ISC_LANG_ENDDECLS
303
304#endif /* ISC_FILE_H */
305