25 #include <sys/param.h>
26 #include <sys/types.h>
52 int offset = 1, len = 0;
53 char *path = strdup(path_c);
56 for (len = strlen(path); offset < len; offset++) {
57 if (path[offset] ==
'/') {
59 if (mkdir(path, mode) < 0 && errno != EEXIST) {
60 crm_perror(LOG_ERR,
"Could not create directory '%s'", path);
66 if (mkdir(path, mode) < 0 && errno != EEXIST) {
67 crm_perror(LOG_ERR,
"Could not create directory '%s'", path);
89 char *filename = NULL;
90 const char *ext =
"raw";
92 CRM_CHECK(directory != NULL,
return NULL);
99 len += strlen(directory);
100 len += strlen(series);
101 filename = malloc(len);
102 CRM_CHECK(filename != NULL,
return NULL);
107 sprintf(filename,
"%s/%s-%d.%s", directory, series, sequence, ext);
124 FILE *file_strm = NULL;
125 int start = 0, length = 0, read_len = 0;
126 char *series_file = NULL;
134 len += strlen(directory);
135 len += strlen(series);
136 series_file = malloc(len);
137 CRM_CHECK(series_file != NULL,
return 0);
138 sprintf(series_file,
"%s/%s.last", directory, series);
140 file_strm = fopen(series_file,
"r");
141 if (file_strm == NULL) {
142 crm_debug(
"Series file %s does not exist", series_file);
148 start = ftell(file_strm);
149 fseek(file_strm, 0L, SEEK_END);
150 length = ftell(file_strm);
151 fseek(file_strm, 0L, start);
157 crm_info(
"%s was not valid", series_file);
162 crm_trace(
"Reading %d bytes from file", length);
163 buffer = calloc(1, (length + 1));
164 read_len = fread(buffer, 1, length, file_strm);
165 if (read_len != length) {
166 crm_err(
"Calculated and read bytes differ: %d vs. %d", length, read_len);
175 crm_trace(
"Found %d in %s", seq, series_file);
198 FILE *file_strm = NULL;
199 char *series_file = NULL;
207 if (max > 0 && sequence >= max) {
211 len += strlen(directory);
212 len += strlen(series);
213 series_file = malloc(len);
216 sprintf(series_file,
"%s/%s.last", directory, series);
217 file_strm = fopen(series_file,
"w");
220 if (file_strm != NULL) {
221 rc = fprintf(file_strm,
"%d", sequence);
223 crm_perror(LOG_ERR,
"Cannot write to series file %s", series_file);
227 crm_err(
"Cannot open series file %s for writing", series_file);
230 if (file_strm != NULL) {
235 crm_trace(
"Wrote %d to %s", sequence, series_file);
253 char *series_file = NULL;
256 CRM_CHECK((directory != NULL) && (series != NULL), errno = EINVAL;
return -1);
259 CRM_CHECK(series_file != NULL,
return -1);
261 rc = chown(series_file, uid, gid);
280 const char *user,
const char *group, gboolean need_both)
284 char *full_file = NULL;
285 const char *target = NULL;
287 gboolean pass = TRUE;
288 gboolean readwritable = FALSE;
294 s_res = stat(full_file, &buf);
295 if (s_res == 0 && S_ISREG(buf.st_mode) == FALSE) {
296 crm_err(
"%s must be a regular file", target);
304 s_res = stat(dir, &buf);
306 crm_err(
"%s must exist and be a directory", dir);
310 }
else if (S_ISDIR(buf.st_mode) == FALSE) {
311 crm_err(
"%s must be a directory", dir);
317 struct passwd *sys_user = NULL;
319 sys_user = getpwnam(user);
320 readwritable = (sys_user != NULL
321 && buf.st_uid == sys_user->pw_uid && (buf.st_mode & (S_IRUSR | S_IWUSR)));
322 if (readwritable == FALSE) {
323 crm_err(
"%s must be owned and r/w by user %s", target, user);
331 struct group *sys_grp = getgrnam(group);
333 readwritable = (sys_grp != NULL
334 && buf.st_gid == sys_grp->gr_gid && (buf.st_mode & (S_IRGRP | S_IWGRP)));
335 if (readwritable == FALSE) {
336 if (need_both || user == NULL) {
338 crm_err(
"%s must be owned and r/w by group %s", target, group);
340 crm_warn(
"%s should be owned and r/w by group %s", target, group);
363 directory = opendir(name);
364 if (directory == NULL) {
365 crm_perror(LOG_ERR,
"Could not open %s for syncing", name);
369 fd = dirfd(directory);
371 crm_perror(LOG_ERR,
"Could not obtain file descriptor for %s", name);
376 crm_perror(LOG_ERR,
"Could not sync %s", name);
378 if (closedir(directory) < 0) {
379 crm_perror(LOG_ERR,
"Could not close %s after fsync", name);
397 char *contents = NULL;
399 int length, read_len;
403 fp = fopen(filename,
"r");
408 fseek(fp, 0L, SEEK_END);
412 contents = calloc(length + 1,
sizeof(
char));
413 if (contents == NULL) {
418 crm_trace(
"Reading %d bytes from %s", length, filename);
420 read_len = fread(contents, 1, length, fp);
421 if (read_len != length) {
444 FILE *fp = fdopen(fd,
"w");
449 if ((contents != NULL) && (fprintf(fp,
"%s", contents) < 0)) {
452 if (fflush(fp) != 0) {
455 if (fsync(fileno(fp)) < 0) {
473 int flag = fcntl(fd, F_GETFL);
478 if (fcntl(fd, F_SETFL, flag | O_NONBLOCK) < 0) {
#define CRM_CHECK(expr, failure_action)
void crm_build_path(const char *path_c, mode_t mode)
Create a directory, including any parent directories needed.
int get_last_sequence(const char *directory, const char *series)
int crm_parse_int(const char *text, const char *default_text)
char * generate_series_filename(const char *directory, const char *series, int sequence, gboolean bzip)
char * crm_read_contents(const char *filename)
#define crm_warn(fmt, args...)
#define crm_debug(fmt, args...)
#define crm_trace(fmt, args...)
int crm_set_nonblocking(int fd)
gboolean crm_is_writable(const char *dir, const char *file, const char *user, const char *group, gboolean need_both)
void write_last_sequence(const char *directory, const char *series, int sequence, int max)
#define crm_perror(level, fmt, args...)
Log a system error message.
#define crm_err(fmt, args...)
int crm_write_sync(int fd, const char *contents)
int crm_chown_last_sequence(const char *directory, const char *series, uid_t uid, gid_t gid)
void crm_sync_directory(const char *name)
char * crm_concat(const char *prefix, const char *suffix, char join)
char * crm_strdup_printf(char const *format,...) __attribute__((__format__(__printf__
#define crm_info(fmt, args...)