/* * Copyright (c) 2015, 2016 Jonas 'Sortie' Termansen. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, 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. * * fileops.c * File operation utility functions. */ #include #include #include #include #include #include #include #include #include "fileops.h" int mkdir_p(const char* path, mode_t mode) { int saved_errno = errno; if ( !mkdir(path, mode) ) return 0; if ( errno == ENOENT ) { char* prev = strdup(path); if ( !prev ) return -1; int status = mkdir_p(dirname(prev), mode | 0500); free(prev); if ( status < 0 ) return -1; errno = saved_errno; if ( !mkdir(path, mode) ) return 0; } if ( errno == EEXIST ) return errno = saved_errno, 0; return -1; } int access_or_die(const char* path, int mode) { if ( access(path, mode) < 0 ) { if ( errno == EACCES || errno == ENOENT || errno == ELOOP || errno == ENAMETOOLONG || errno == ENOTDIR ) return -1; warn("%s", path); _exit(2); } return 0; } void mkdir_or_chmod_or_die(const char* path, mode_t mode) { if ( mkdir(path, mode) == 0 ) return; if ( errno == EEXIST ) { if ( chmod(path, mode) == 0 ) return; err(2, "chmod: %s", path); } err(2, "mkdir: %s", path); }