/*
* Amanda, The Advanced Maryland Automatic Network Disk Archiver
* Copyright (c) 1997-1998 University of Maryland at College Park
* Copyright (c) 2007-2012 Zmanda, Inc All Rights Reserved.
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of U.M. not be used in advertising or
* publicity pertaining to distribution of the software without specific,
* written prior permission. U.M. makes no representations about the
* suitability of this software for any purpose. It is provided "as is"
* without express or implied warranty.
*
* U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
* BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Author: AMANDA core development group.
*/
#ifndef __AM_FILE_H__
#define __AM_FILE_H__
extern int mkpdir(char *file, mode_t mode, uid_t uid, gid_t gid);
extern int rmpdir(char *file, char *topdir);
/* Given a pathname, convert it to "canonical form" for this system. Currently,
* this means nothing on POSIX, but means substituting /cygdrive, etc. on Cygwin.
*
* @param pathname: the pathname to canonicalize
* @param result_buf (output): the canonicalize pathname; this should be a buffer of
* at least PATH_MAX bytes.
*/
void canonicalize_pathname(char *pathname, char *result_buf);
extern char *sanitise_filename(char *inp);
char *old_sanitise_filename(char *inp);
void safe_fd(int fd_start, int fd_count);
void safe_fd2(int fd_start, int fd_count, int fd1);
void safe_fd3(int fd_start, int fd_count, int fd1, int fd2);
void safe_cd(void);
void save_core(void);
/* Get the uid of CLIENT_LOGIN, or -1 if it doesn't exist. Note that, if
* only running a server, CLIENT_LOGIN may legitimately not exist.
*
* @returns: userid, or -1 if invalid
*/
uid_t get_client_uid(void);
/* Get the gid of CLIENT_LOGIN, or -1 if it doesn't exist. Note that, if
* only running a server, CLIENT_LOGIN may legitimately not exist.
*
* @returns: groupid, or -1 if invalid
*/
gid_t get_client_gid(void);
extern /*@only@*/ /*@null@*/ char *debug_agets(const char *c, int l, FILE *file);
extern /*@only@*/ /*@null@*/ char *debug_pgets(const char *c, int l, FILE *file);
extern /*@only@*/ /*@null@*/ char *debug_areads(const char *c, int l, int fd);
#define agets(f) debug_agets(__FILE__,__LINE__,(f))
#define pgets(f) debug_pgets(__FILE__,__LINE__,(f))
#define areads(f) debug_areads(__FILE__,__LINE__,(f))
ssize_t areads_dataready(int fd);
void areads_relbuf(int fd);
/*
* "Safe" close macros. Close the object then set it to a value that
* will cause an error if referenced.
*
* aclose(fd) -- close a file descriptor and set it to -1.
* afclose(f) -- close a stdio file and set it to NULL.
* apclose(p) -- close a stdio pipe file and set it to NULL.
*
* Note: be careful not to do the following:
*
* for(fd = low; fd < high; fd++) {
* aclose(fd);
* }
*
* Since aclose() sets the argument to -1, this will loop forever.
* Just copy fd to a temp variable and use that with aclose().
*
* Aclose() interacts with areads() to inform it to release any buffer
* it has outstanding on the file descriptor.
*/
#define aclose(fd) do { \
if((fd) >= 0) { \
close(fd); \
} \
(fd) = -1; \
} while(0)
#define aaclose(fd) do { \
if((fd) >= 0) { \
close(fd); \
areads_relbuf(fd); \
} \
(fd) = -1; \
} while(0)
#define afclose(f) do { \
if((f) != NULL) { \
fclose(f); \
} \
(f) = NULL; \
} while(0)
#define apclose(p) do { \
if((p) != NULL) { \
pclose(p); \
} \
(p) = NULL; \
} while(0)
/* Calls system open(), but takes care of interrupted system calls and
* clears the close-on-exec bit. In the failure case, errno is
* retained from the final call to open(). */
extern int robust_open(const char * pathname, int flags, mode_t mode);
/* Same idea but for close. */
extern int robust_close(int fd);
/* Get the original working directory, at application startup
*
* @returns: pointer to statically allocated string
*/
char *get_original_cwd(void);
/**
* Read up to "count" bytes from a file descriptor, optionally collecting the
* read operation status (0 on success, not 0 otherwise).
*
* This function exists to overcome the confusing behavior of full_read():
*
* - unlike read(2), full_read() does not return -1 on failure;
* - errno needs to be explicitly checked for each time the number of bytes
* actually read is less than the "count" argument.
*
* With this function, a full read becomes a one time process. Error collecting
* is optional.
*
* @param fd: the file descriptor to read from
* @param buf: the buffer to write data into
* @param count: the number of bytes to write into the buffer
* @param err (output): 0 if "count" bytes have been read; errno (as set by
* full_read()) otherwise
* @returns: the number of bytes read from the file descriptor
*/
gsize read_fully(int fd, void *buf, gsize count, int *err);
char *untaint_fgets(char *s, int size, FILE *stream);
#endif /* __AM_FILE_H__ */