14 #include <sys/param.h> 15 #include <sys/types.h> 41 int offset = 1, len = 0;
42 char *path = strdup(path_c);
45 for (len = strlen(path); offset < len; offset++) {
46 if (path[offset] ==
'/') {
48 if (mkdir(path, mode) < 0 && errno != EEXIST) {
49 crm_perror(LOG_ERR,
"Could not create directory '%s'", path);
55 if (mkdir(path, mode) < 0 && errno != EEXIST) {
56 crm_perror(LOG_ERR,
"Could not create directory '%s'", path);
78 char *filename = NULL;
79 const char *ext =
"raw";
81 CRM_CHECK(directory != NULL,
return NULL);
88 len += strlen(directory);
89 len += strlen(series);
90 filename = malloc(len);
96 sprintf(filename,
"%s/%s-%d.%s", directory, series, sequence, ext);
113 FILE *file_strm = NULL;
114 int start = 0, length = 0, read_len = 0;
115 char *series_file = NULL;
123 len += strlen(directory);
124 len += strlen(series);
125 series_file = malloc(len);
126 CRM_CHECK(series_file != NULL,
return 0);
127 sprintf(series_file,
"%s/%s.last", directory, series);
129 file_strm = fopen(series_file,
"r");
130 if (file_strm == NULL) {
131 crm_debug(
"Series file %s does not exist", series_file);
137 start = ftell(file_strm);
138 fseek(file_strm, 0L, SEEK_END);
139 length = ftell(file_strm);
140 fseek(file_strm, 0L, start);
146 crm_info(
"%s was not valid", series_file);
151 crm_trace(
"Reading %d bytes from file", length);
152 buffer = calloc(1, (length + 1));
153 read_len = fread(buffer, 1, length, file_strm);
154 if (read_len != length) {
155 crm_err(
"Calculated and read bytes differ: %d vs. %d", length, read_len);
164 crm_trace(
"Found %d in %s", seq, series_file);
187 FILE *file_strm = NULL;
188 char *series_file = NULL;
196 if (max > 0 && sequence >= max) {
200 len += strlen(directory);
201 len += strlen(series);
202 series_file = malloc(len);
205 sprintf(series_file,
"%s/%s.last", directory, series);
206 file_strm = fopen(series_file,
"w");
209 if (file_strm != NULL) {
210 rc = fprintf(file_strm,
"%d", sequence);
212 crm_perror(LOG_ERR,
"Cannot write to series file %s", series_file);
216 crm_err(
"Cannot open series file %s for writing", series_file);
219 if (file_strm != NULL) {
224 crm_trace(
"Wrote %d to %s", sequence, series_file);
242 char *series_file = NULL;
245 CRM_CHECK((directory != NULL) && (series != NULL), errno = EINVAL;
return -1);
248 CRM_CHECK(series_file != NULL,
return -1);
250 rc = chown(series_file, uid, gid);
256 pcmk__daemon_user_can_write(
const char *target_name,
struct stat *target_stat)
258 struct passwd *sys_user = NULL;
262 if (sys_user == NULL) {
267 if (target_stat->st_uid != sys_user->pw_uid) {
270 target_stat->st_uid);
273 if ((target_stat->st_mode & (S_IRUSR | S_IWUSR)) == 0) {
274 crm_notice(
"%s is not readable and writable by user %s " 277 (
unsigned long) target_stat->st_mode);
284 pcmk__daemon_group_can_write(
const char *target_name,
struct stat *target_stat)
286 struct group *sys_grp = NULL;
290 if (sys_grp == NULL) {
296 if (target_stat->st_gid != sys_grp->gr_gid) {
299 sys_grp->gr_gid, target_stat->st_gid);
303 if ((target_stat->st_mode & (S_IRGRP | S_IWGRP)) == 0) {
304 crm_notice(
"%s is not readable and writable by group %s " 307 (
unsigned long) target_stat->st_mode);
332 char *full_file = NULL;
333 const char *target = NULL;
343 s_res = stat(full_file, &buf);
350 }
else if (S_ISREG(buf.st_mode) == FALSE) {
352 target, (
unsigned long) buf.st_mode);
359 if (target == NULL) {
361 s_res = stat(dir, &buf);
366 }
else if (S_ISDIR(buf.st_mode) == FALSE) {
368 dir, (
unsigned long) buf.st_mode);
373 if (!pcmk__daemon_user_can_write(target, &buf)
374 && !pcmk__daemon_group_can_write(target, &buf)) {
376 crm_err(
"%s must be owned and writable by either user %s or group %s " 379 (
unsigned long) buf.st_mode);
401 directory = opendir(name);
402 if (directory == NULL) {
403 crm_perror(LOG_ERR,
"Could not open %s for syncing", name);
407 fd = dirfd(directory);
409 crm_perror(LOG_ERR,
"Could not obtain file descriptor for %s", name);
414 crm_perror(LOG_ERR,
"Could not sync %s", name);
416 if (closedir(directory) < 0) {
417 crm_perror(LOG_ERR,
"Could not close %s after fsync", name);
435 char *contents = NULL;
437 int length, read_len;
441 fp = fopen(filename,
"r");
446 fseek(fp, 0L, SEEK_END);
450 contents = calloc(length + 1,
sizeof(
char));
451 if (contents == NULL) {
456 crm_trace(
"Reading %d bytes from %s", length, filename);
458 read_len = fread(contents, 1, length, fp);
459 if (read_len != length) {
482 FILE *fp = fdopen(fd,
"w");
487 if ((contents != NULL) && (fprintf(fp,
"%s", contents) < 0)) {
490 if (fflush(fp) != 0) {
493 if (fsync(fileno(fp)) < 0) {
511 int flag = fcntl(fd, F_GETFL);
516 if (fcntl(fd, F_SETFL, flag | O_NONBLOCK) < 0) {
#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)
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 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)