2 * Copyright (c) 2005 Christophe Varoqui
3 * Copyright (c) 2005 Benjamin Marzinski, Redhat
22 * significant parts of this file were taken from iscsi-bindings.c of the
23 * linux-iscsi project.
24 * Copyright (C) 2002 Cisco Systems, Inc.
26 * This program is free software; you can redistribute it and/or modify
27 * it under the terms of the GNU General Public License as published
28 * by the Free Software Foundation; either version 2 of the License, or
29 * (at your option) any later version.
31 * This program is distributed in the hope that it will be useful, but
32 * WITHOUT ANY WARRANTY; without even the implied warranty of
33 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
34 * General Public License for more details.
36 * See the file COPYING included with this distribution for more details.
40 ensure_directories_exist(char *str, mode_t dir_mode)
46 pathname = strdup(str);
48 condlog(0, "Cannot copy file pathname %s : %s",
49 str, strerror(errno));
53 /* skip leading slashes */
54 while (end && *end && (*end == '/'))
57 while ((end = strchr(end, '/'))) {
58 /* if there is another slash, make the dir. */
60 err = mkdir(pathname, dir_mode);
61 if (err && errno != EEXIST) {
62 condlog(0, "Cannot make directory [%s] : %s",
63 pathname, strerror(errno));
68 condlog(3, "Created dir [%s]", pathname);
83 lock_file(int fd, char *file_name)
85 struct sigaction act, oldact;
90 memset(&lock, 0, sizeof(lock));
91 lock.l_type = F_WRLCK;
92 lock.l_whence = SEEK_SET;
94 act.sa_handler = sigalrm;
95 sigemptyset(&act.sa_mask);
98 sigaddset(&set, SIGALRM);
100 sigaction(SIGALRM, &act, &oldact);
101 sigprocmask(SIG_UNBLOCK, &set, &oldset);
104 err = fcntl(fd, F_SETLKW, &lock);
109 condlog(0, "Cannot lock %s : %s", file_name,
112 condlog(0, "%s is locked. Giving up.", file_name);
115 sigprocmask(SIG_SETMASK, &oldset, NULL);
116 sigaction(SIGALRM, &oldact, NULL);
121 open_file(char *file, int *can_write, char *header)
126 if (ensure_directories_exist(file, 0700))
129 fd = open(file, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
131 if (errno == EROFS) {
133 condlog(3, "Cannot open file [%s] read/write. "
134 " trying readonly", file);
135 fd = open(file, O_RDONLY);
137 condlog(0, "Cannot open file [%s] "
138 "readonly : %s", file, strerror(errno));
143 condlog(0, "Cannot open file [%s] : %s", file,
148 if (*can_write && lock_file(fd, file) < 0)
151 memset(&s, 0, sizeof(s));
152 if (fstat(fd, &s) < 0){
153 condlog(0, "Cannot stat file %s : %s", file, strerror(errno));
156 if (s.st_size == 0) {
159 /* If file is empty, write the header */
160 size_t len = strlen(header);
161 if (write_all(fd, header, len) != len) {
163 "Cannot write header to file %s : %s", file,
165 /* cleanup partially written header */
166 if (ftruncate(fd, 0))
167 condlog(0, "Cannot truncate header : %s",
172 condlog(3, "Initialized new file [%s]", file);