14 #include <sys/param.h> 15 #include <sys/types.h> 17 #include <sys/resource.h> 42 int offset = 1, len = 0;
43 char *path = strdup(path_c);
46 for (len = strlen(path); offset < len; offset++) {
47 if (path[offset] ==
'/') {
49 if (mkdir(path, mode) < 0 && errno != EEXIST) {
50 crm_perror(LOG_ERR,
"Could not create directory '%s'", path);
56 if (mkdir(path, mode) < 0 && errno != EEXIST) {
57 crm_perror(LOG_ERR,
"Could not create directory '%s'", path);
79 char *filename = NULL;
80 const char *ext =
"raw";
82 CRM_CHECK(directory != NULL,
return NULL);
89 len += strlen(directory);
90 len += strlen(series);
91 filename = malloc(len);
97 sprintf(filename,
"%s/%s-%d.%s", directory, series, sequence, ext);
114 FILE *file_strm = NULL;
115 int start = 0, length = 0, read_len = 0;
116 char *series_file = NULL;
124 len += strlen(directory);
125 len += strlen(series);
126 series_file = malloc(len);
127 CRM_CHECK(series_file != NULL,
return 0);
128 sprintf(series_file,
"%s/%s.last", directory, series);
130 file_strm = fopen(series_file,
"r");
131 if (file_strm == NULL) {
132 crm_debug(
"Series file %s does not exist", series_file);
138 start = ftell(file_strm);
139 fseek(file_strm, 0L, SEEK_END);
140 length = ftell(file_strm);
141 fseek(file_strm, 0L, start);
147 crm_info(
"%s was not valid", series_file);
152 crm_trace(
"Reading %d bytes from file", length);
153 buffer = calloc(1, (length + 1));
154 read_len = fread(buffer, 1, length, file_strm);
155 if (read_len != length) {
156 crm_err(
"Calculated and read bytes differ: %d vs. %d", length, read_len);
165 crm_trace(
"Found %d in %s", seq, series_file);
188 FILE *file_strm = NULL;
189 char *series_file = NULL;
197 if (max > 0 && sequence >= max) {
201 len += strlen(directory);
202 len += strlen(series);
203 series_file = malloc(len);
206 sprintf(series_file,
"%s/%s.last", directory, series);
207 file_strm = fopen(series_file,
"w");
210 if (file_strm != NULL) {
211 rc = fprintf(file_strm,
"%d", sequence);
213 crm_perror(LOG_ERR,
"Cannot write to series file %s", series_file);
217 crm_err(
"Cannot open series file %s for writing", series_file);
220 if (file_strm != NULL) {
225 crm_trace(
"Wrote %d to %s", sequence, series_file);
243 char *series_file = NULL;
246 CRM_CHECK((directory != NULL) && (series != NULL), errno = EINVAL;
return -1);
249 CRM_CHECK(series_file != NULL,
return -1);
251 rc = chown(series_file, uid, gid);
257 pcmk__daemon_user_can_write(
const char *target_name,
struct stat *target_stat)
259 struct passwd *sys_user = NULL;
263 if (sys_user == NULL) {
268 if (target_stat->st_uid != sys_user->pw_uid) {
271 target_stat->st_uid);
274 if ((target_stat->st_mode & (S_IRUSR | S_IWUSR)) == 0) {
275 crm_notice(
"%s is not readable and writable by user %s " 278 (
unsigned long) target_stat->st_mode);
285 pcmk__daemon_group_can_write(
const char *target_name,
struct stat *target_stat)
287 struct group *sys_grp = NULL;
291 if (sys_grp == NULL) {
297 if (target_stat->st_gid != sys_grp->gr_gid) {
300 sys_grp->gr_gid, target_stat->st_gid);
304 if ((target_stat->st_mode & (S_IRGRP | S_IWGRP)) == 0) {
305 crm_notice(
"%s is not readable and writable by group %s " 308 (
unsigned long) target_stat->st_mode);
333 char *full_file = NULL;
334 const char *target = NULL;
344 s_res = stat(full_file, &buf);
351 }
else if (S_ISREG(buf.st_mode) == FALSE) {
353 target, (
unsigned long) buf.st_mode);
360 if (target == NULL) {
362 s_res = stat(dir, &buf);
367 }
else if (S_ISDIR(buf.st_mode) == FALSE) {
369 dir, (
unsigned long) buf.st_mode);
374 if (!pcmk__daemon_user_can_write(target, &buf)
375 && !pcmk__daemon_group_can_write(target, &buf)) {
377 crm_err(
"%s must be owned and writable by either user %s or group %s " 380 (
unsigned long) buf.st_mode);
402 directory = opendir(name);
403 if (directory == NULL) {
404 crm_perror(LOG_ERR,
"Could not open %s for syncing", name);
408 fd = dirfd(directory);
410 crm_perror(LOG_ERR,
"Could not obtain file descriptor for %s", name);
415 crm_perror(LOG_ERR,
"Could not sync %s", name);
417 if (closedir(directory) < 0) {
418 crm_perror(LOG_ERR,
"Could not close %s after fsync", name);
436 char *contents = NULL;
438 int length, read_len;
442 fp = fopen(filename,
"r");
447 fseek(fp, 0L, SEEK_END);
451 contents = calloc(length + 1,
sizeof(
char));
452 if (contents == NULL) {
457 crm_trace(
"Reading %d bytes from %s", length, filename);
459 read_len = fread(contents, 1, length, fp);
460 if (read_len != length) {
483 FILE *fp = fdopen(fd,
"w");
488 if ((contents != NULL) && (fprintf(fp,
"%s", contents) < 0)) {
491 if (fflush(fp) != 0) {
494 if (fsync(fileno(fp)) < 0) {
512 int flag = fcntl(fd, F_GETFL);
517 if (fcntl(fd, F_SETFL, flag | O_NONBLOCK) < 0) {
539 int min_fd = (all? 0 : (STDERR_FILENO + 1));
544 if (getrlimit(RLIMIT_NOFILE, &rlim) == 0) {
545 max_fd = rlim.rlim_cur - 1;
547 long conf_max = sysconf(_SC_OPEN_MAX);
549 max_fd = (conf_max > 0)? conf_max : 1024;
558 dir = opendir(
"/proc/self/fd");
560 dir = opendir(
"/dev/fd");
563 dir = opendir(
"/dev/fd");
566 struct dirent *entry;
567 int dir_fd = dirfd(dir);
569 while ((entry = readdir(dir)) != NULL) {
570 int lpc = atoi(entry->d_name);
578 if ((lpc >= min_fd) && (lpc <= max_fd) && (lpc != dir_fd)) {
589 for (
int lpc = max_fd; lpc >= min_fd; lpc--) {
#define CRM_CHECK(expr, failure_action)
void write_last_sequence(const char *directory, const char *series, int sequence, int max)
#define crm_notice(fmt, args...)
const char * pcmk_strerror(int rc)
int crm_parse_int(const char *text, const char *default_text)
Parse an integer value from a string.
bool pcmk__daemon_can_write(const char *dir, const char *file)
int crm_chown_last_sequence(const char *directory, const char *series, uid_t uid, gid_t gid)
#define crm_debug(fmt, args...)
void crm_build_path(const char *path_c, mode_t mode)
Create a directory, including any parent directories needed.
#define crm_trace(fmt, args...)
int get_last_sequence(const char *directory, const char *series)
int crm_write_sync(int fd, const char *contents)
#define crm_perror(level, fmt, args...)
Log a system error message.
#define crm_err(fmt, args...)
void pcmk__close_fds_in_child(bool all)
void crm_sync_directory(const char *name)
char * crm_read_contents(const char *filename)
char * crm_concat(const char *prefix, const char *suffix, char join)
char * crm_strdup_printf(char const *format,...) __attribute__((__format__(__printf__
int crm_set_nonblocking(int fd)
#define crm_info(fmt, args...)
char * generate_series_filename(const char *directory, const char *series, int sequence, gboolean bzip)