12 #include <sys/param.h>    13 #include <sys/types.h>    15 #include <sys/resource.h>    43     int offset = 1, len = 0;
    45     char *
path = strdup(path_c);
    50     for (len = strlen(
path); offset < len; offset++) {
    51         if (
path[offset] == 
'/') {
    53             if ((mkdir(
path, mode) < 0) && (errno != EEXIST)) {
    60     if ((mkdir(
path, mode) < 0) && (errno != EEXIST)) {
    83     CRM_CHECK((
path != NULL) && (resolved_path != NULL), 
return EINVAL);
    85 #if _POSIX_VERSION >= 200809L    87     *resolved_path = realpath(
path, NULL);
    88     return (*resolved_path == NULL)? errno : 
pcmk_rc_ok;
    90 #elif defined(PATH_MAX)    93     *resolved_path = malloc(PATH_MAX);
    94     if ((*resolved_path == NULL) || (realpath(
path, *resolved_path) == NULL)) {
    99     *resolved_path = NULL;
   118                       unsigned int sequence, 
bool bzip)
   122                              (bzip? 
"bz2" : 
"raw"));
   141     char *series_file = NULL;
   143     if ((directory == NULL) || (series == NULL) || (seq == NULL)) {
   148     fp = fopen(series_file, 
"r");
   151         crm_debug(
"Could not open series file %s: %s",
   152                   series_file, strerror(rc));
   157     if (fscanf(fp, 
"%u", seq) != 1) {
   158         rc = (errno == 0)? 
ENODATA : errno;
   159         crm_debug(
"Could not read sequence number from series file %s: %s",
   165     crm_trace(
"Found last sequence number %u in series file %s",
   184                             unsigned int sequence, 
int max)
   187     FILE *file_strm = NULL;
   188     char *series_file = NULL;
   196     if (max > 0 && sequence >= max) {
   201     file_strm = fopen(series_file, 
"w");
   202     if (file_strm != NULL) {
   203         rc = fprintf(file_strm, 
"%u", sequence);
   205             crm_perror(LOG_ERR, 
"Cannot write to series file %s", series_file);
   209         crm_err(
"Cannot open series file %s for writing", series_file);
   212     if (file_strm != NULL) {
   217     crm_trace(
"Wrote %d to %s", sequence, series_file);
   235                             uid_t uid, gid_t gid)
   237     char *series_file = NULL;
   240     if ((directory == NULL) || (series == NULL)) {
   244     if (chown(series_file, uid, gid) < 0) {
   252 pcmk__daemon_user_can_write(
const char *target_name, 
struct stat *target_stat)
   254     struct passwd *sys_user = NULL;
   258     if (sys_user == NULL) {
   263     if (target_stat->st_uid != sys_user->pw_uid) {
   264         crm_notice(
"%s is not owned by user %s " QB_XS 
" uid %d != %d",
   266                    target_stat->st_uid);
   269     if ((target_stat->st_mode & (S_IRUSR | S_IWUSR)) == 0) {
   270         crm_notice(
"%s is not readable and writable by user %s "   271                    QB_XS 
" st_mode=0%lo",
   273                    (
unsigned long) target_stat->st_mode);
   280 pcmk__daemon_group_can_write(
const char *target_name, 
struct stat *target_stat)
   282     struct group *sys_grp = NULL;
   286     if (sys_grp == NULL) {
   292     if (target_stat->st_gid != sys_grp->gr_gid) {
   293         crm_notice(
"%s is not owned by group %s " QB_XS 
" uid %d != %d",
   295                    sys_grp->gr_gid, target_stat->st_gid);
   299     if ((target_stat->st_mode & (S_IRGRP | S_IWGRP)) == 0) {
   300         crm_notice(
"%s is not readable and writable by group %s "   301                    QB_XS 
" st_mode=0%lo",
   303                    (
unsigned long) target_stat->st_mode);
   328     char *full_file = NULL;
   329     const char *
target = NULL;
   339         s_res = stat(full_file, &buf);
   346         } 
else if (S_ISREG(buf.st_mode) == FALSE) {
   347             crm_err(
"%s must be a regular file " QB_XS 
" st_mode=0%lo",
   348                     target, (
unsigned long) buf.st_mode);
   357         s_res = stat(dir, &buf);
   362         } 
else if (S_ISDIR(buf.st_mode) == FALSE) {
   363             crm_err(
"%s must be a directory " QB_XS 
" st_mode=0%lo",
   364                     dir, (
unsigned long) buf.st_mode);
   369     if (!pcmk__daemon_user_can_write(
target, &buf)
   370         && !pcmk__daemon_group_can_write(
target, &buf)) {
   372         crm_err(
"%s must be owned and writable by either user %s or group %s "   373                 QB_XS 
" st_mode=0%lo",
   375                 (
unsigned long) buf.st_mode);
   397     directory = opendir(
name);
   398     if (directory == NULL) {
   403     fd = dirfd(directory);
   405         crm_perror(LOG_ERR, 
"Could not obtain file descriptor for %s", 
name);
   412     if (closedir(directory) < 0) {
   431     int length, read_len;
   434     if ((filename == NULL) || (contents == NULL)) {
   438     fp = fopen(filename, 
"r");
   439     if ((fp == NULL) || (fseek(fp, 0L, SEEK_END) < 0)) {
   453         *contents = calloc(length + 1, 
sizeof(
char));
   454         if (*contents == NULL) {
   460         read_len = fread(*contents, 1, length, fp);
   461         if (read_len != length) {
   469             (*contents)[length] = 
'\0';
   493     FILE *fp = fdopen(fd, 
"w");
   498     if ((contents != NULL) && (fprintf(fp, 
"%s", contents) < 0)) {
   501     if (fflush(fp) != 0) {
   504     if (fsync(fileno(fp)) < 0) {
   522     int flag = fcntl(fd, F_GETFL);
   527     if (fcntl(fd, F_SETFL, flag | O_NONBLOCK) < 0) {
   545     const char *dir = getenv(
"TMPDIR");
   547     return (dir && (*dir == 
'/'))? dir : 
"/tmp";
   566     int min_fd = (all? 0 : (STDERR_FILENO + 1));
   571     if (getrlimit(RLIMIT_NOFILE, &rlim) == 0) {
   572         max_fd = rlim.rlim_cur - 1;
   574         long conf_max = sysconf(_SC_OPEN_MAX);
   576         max_fd = (conf_max > 0)? conf_max : 1024;
   584 #if HAVE_LINUX_PROCFS   585     dir = opendir(
"/proc/self/fd");
   587         dir = opendir(
"/dev/fd");
   590     dir = opendir(
"/dev/fd");
   591 #endif // HAVE_LINUX_PROCFS   593         struct dirent *entry;
   594         int dir_fd = dirfd(dir);
   596         while ((entry = readdir(dir)) != NULL) {
   597             int lpc = atoi(entry->d_name);
   605             if ((lpc >= min_fd) && (lpc <= max_fd) && (lpc != dir_fd)) {
   616     for (
int lpc = max_fd; lpc >= min_fd; lpc--) {
   634     if (filename[0] == 
'/') {
 #define CRM_CHECK(expr, failure_action)
 
#define crm_notice(fmt, args...)
 
int pcmk__real_path(const char *path, char **resolved_path)
 
int pcmk__chown_series_sequence(const char *directory, const char *series, uid_t uid, gid_t gid)
 
void pcmk__write_series_sequence(const char *directory, const char *series, unsigned int sequence, int max)
 
const char * pcmk_rc_str(int rc)
Get a user-friendly description of a return code. 
 
bool pcmk__daemon_can_write(const char *dir, const char *file)
 
const char * pcmk__get_tmpdir(void)
 
#define crm_debug(fmt, args...)
 
#define crm_trace(fmt, args...)
 
#define pcmk__str_copy(str)
 
int pcmk__build_path(const char *path_c, mode_t mode)
 
#define pcmk__assert(expr)
 
#define crm_perror(level, fmt, args...)
Send a system error message to both the log and stderr. 
 
char * pcmk__series_filename(const char *directory, const char *series, unsigned int sequence, bool bzip)
 
#define crm_err(fmt, args...)
 
int pcmk__read_series_sequence(const char *directory, const char *series, unsigned int *seq)
 
char * pcmk__full_path(const char *filename, const char *dirname)
Duplicate a file path, inserting a prefix if not absolute. 
 
void pcmk__close_fds_in_child(bool all)
 
void pcmk__sync_directory(const char *name)
 
int pcmk__write_sync(int fd, const char *contents)
 
int pcmk__set_nonblocking(int fd)
 
int pcmk__file_contents(const char *filename, char **contents)
 
char * crm_strdup_printf(char const *format,...) G_GNUC_PRINTF(1