summaryrefslogtreecommitdiffstats
path: root/server/util
diff options
context:
space:
mode:
authorSimo Sorce <ssorce@redhat.com>2009-09-03 19:29:41 -0400
committerStephen Gallagher <sgallagh@redhat.com>2009-09-08 15:10:50 -0400
commit28d9dcbeabdf919506fe59e9d1cbed84fbd6e649 (patch)
tree3d5d878b1adc0ec8af94a52359d219689c763bd8 /server/util
parentaef967dc115c64f0288b8ecc3ff1d927aa42af70 (diff)
downloadsssd-28d9dcbeabdf919506fe59e9d1cbed84fbd6e649.tar.gz
sssd-28d9dcbeabdf919506fe59e9d1cbed84fbd6e649.tar.xz
sssd-28d9dcbeabdf919506fe59e9d1cbed84fbd6e649.zip
Split database in multiple files
The special persistent local database retains the original name. All other backends now have their own cache-NAME.ldb file.
Diffstat (limited to 'server/util')
-rw-r--r--server/util/backup_file.c122
-rw-r--r--server/util/util.h3
2 files changed, 125 insertions, 0 deletions
diff --git a/server/util/backup_file.c b/server/util/backup_file.c
new file mode 100644
index 000000000..cf9ddf303
--- /dev/null
+++ b/server/util/backup_file.c
@@ -0,0 +1,122 @@
+/*
+ SSSD
+
+ Backup files
+
+ Copyright (C) Simo Sorce 2009
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "util/util.h"
+#include <fcntl.h>
+#include <stddef.h>
+#include <stdlib.h>
+
+#define BUFFER_SIZE 65536
+
+int backup_file(const char *src_file, int dbglvl)
+{
+ TALLOC_CTX *tmp_ctx = NULL;
+ char buf[BUFFER_SIZE];
+ int src_fd = -1;
+ int dst_fd = -1;
+ char *dst_file;
+ ssize_t count;
+ ssize_t num;
+ ssize_t pos;
+ int ret, i;
+
+ src_fd = open(src_file, O_RDONLY);
+ if (src_fd < 0) {
+ ret = errno;
+ DEBUG(dbglvl, ("Error (%d [%s]) opening source file %s\n",
+ ret, strerror(ret), src_file));
+ goto done;
+ }
+
+ tmp_ctx = talloc_new(NULL);
+ if (!tmp_ctx) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ /* try a few times to come up with a new backup file, then give up */
+ for (i = 0; i < 10; i++) {
+ if (i == 0) {
+ dst_file = talloc_asprintf(tmp_ctx, "%s.bak", src_file);
+ } else {
+ dst_file = talloc_asprintf(tmp_ctx, "%s.bak%d", src_file, i);
+ }
+ if (!dst_file) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ errno = 0;
+ dst_fd = open(dst_file, O_CREAT|O_EXCL|O_WRONLY, 0600);
+ ret = errno;
+
+ if (dst_fd > 0) break;
+
+ if (ret != EEXIST) {
+ DEBUG(dbglvl, ("Error (%d [%s]) opening destination file %s\n",
+ ret, strerror(ret), dst_file));
+ goto done;
+ }
+ }
+ if (ret != 0) {
+ DEBUG(dbglvl, ("Error (%d [%s]) opening destination file %s\n",
+ ret, strerror(ret), dst_file));
+ goto done;
+ }
+
+ /* copy file contents */
+ while (1) {
+ num = read(src_fd, buf, BUFFER_SIZE);
+ if (num < 0) {
+ if (errno == EINTR) continue;
+ ret = errno;
+ DEBUG(dbglvl, ("Error (%d [%s]) reading from source %s\n",
+ ret, strerror(ret), src_file));
+ goto done;
+ }
+ if (num == 0) break;
+
+ count = num;
+
+ while (count > 0) {
+ pos = 0;
+ errno = 0;
+ num = write(dst_fd, &buf[pos], count);
+ if (num < 0) {
+ if (errno == EINTR) continue;
+ ret = errno;
+ DEBUG(dbglvl, ("Error (%d [%s]) writing to destination %s\n",
+ ret, strerror(ret), dst_file));
+ goto done;
+ }
+ pos += num;
+ count -= num;
+ }
+ }
+
+ ret = EOK;
+
+done:
+ if (src_fd != -1) close(src_fd);
+ if (dst_fd != -1) close(dst_fd);
+ talloc_free(tmp_ctx);
+ return ret;
+}
diff --git a/server/util/util.h b/server/util/util.h
index f289f9c52..93e5dc978 100644
--- a/server/util/util.h
+++ b/server/util/util.h
@@ -157,4 +157,7 @@ int sss_parse_name(TALLOC_CTX *memctx,
struct sss_names_ctx *snctx,
const char *orig, char **domain, char **name);
+/* from backup-file.c */
+int backup_file(const char *src, int dbglvl);
+
#endif /* __SSSD_UTIL_H__ */