summaryrefslogtreecommitdiffstats
path: root/shlibs/mount/src/utils.c
diff options
context:
space:
mode:
authorKarel Zak2010-11-08 11:14:44 +0100
committerKarel Zak2011-01-03 12:28:46 +0100
commit1d0cd73f3f8929132e731a821ceb07fa6193c00c (patch)
tree6ef4dd8d0d801baa03a8dcf1a6830d265ef7524b /shlibs/mount/src/utils.c
parentlibmount: fix Makefile and tests (diff)
downloadkernel-qcow2-util-linux-1d0cd73f3f8929132e731a821ceb07fa6193c00c.tar.gz
kernel-qcow2-util-linux-1d0cd73f3f8929132e731a821ceb07fa6193c00c.tar.xz
kernel-qcow2-util-linux-1d0cd73f3f8929132e731a821ceb07fa6193c00c.zip
libmount: rewrite update
Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'shlibs/mount/src/utils.c')
-rw-r--r--shlibs/mount/src/utils.c140
1 files changed, 112 insertions, 28 deletions
diff --git a/shlibs/mount/src/utils.c b/shlibs/mount/src/utils.c
index 924284965..410028fa7 100644
--- a/shlibs/mount/src/utils.c
+++ b/shlibs/mount/src/utils.c
@@ -87,6 +87,18 @@ int startswith(const char *s, const char *sx)
return !strncmp(s, sx, off);
}
+/* returns basename and keeps dirname in the @path, if @path is "/" (root)
+ * then returns empty string */
+static char *stripoff_last_component(char *path)
+{
+ char *p = path ? strrchr(path, '/') : NULL;
+
+ if (!p)
+ return NULL;
+ *p = '\0';
+ return ++p;
+}
+
/**
* mnt_mangle:
* @str: string
@@ -404,32 +416,116 @@ done:
return rc;
}
-/*
- * Returns 1 if /etc/mtab is a reqular file.
+static int try_write(const char *filename)
+{
+ int fd;
+
+ if (!filename)
+ return -EINVAL;
+
+ fd = open(filename, O_RDWR, 0644);
+ if (fd >= 0) {
+ close(fd);
+ return 0;
+ }
+ return -errno;
+}
+
+/**
+ * mnt_has_regular_mtab:
+ * @mtab: returns path to mtab
+ * @writable: returns 1 if the file is writable
+ *
+ * If the file does not exist and @writable argument is not NULL then it will
+ * try to create the file
+ *
+ * Returns: 1 if /etc/mtab is a reqular file, and 0 in case of error (check
+ * errno for more details).
*/
-int mnt_has_regular_mtab(const char **mtab, int *writeable)
+int mnt_has_regular_mtab(const char **mtab, int *writable)
{
struct stat st;
int rc;
- const char *x = mtab && *mtab ? *mtab : mnt_get_mtab_path();
+ const char *filename = mtab && *mtab ? *mtab : mnt_get_mtab_path();
if (mtab && !*mtab)
- *mtab = x;
- rc = (lstat(x, &st) == 0 && S_ISREG(st.st_mode));
+ *mtab = filename;
+
+ DBG(UTILS, mnt_debug("mtab: %s", filename));
+ rc = lstat(filename, &st);
+
+ if (rc == 0) {
+ /* file exist */
+ if (S_ISREG(st.st_mode)) {
+ if (writable)
+ *writable = !try_write(filename);
+ return 1;
+ }
+ return 0; /* it's not regular file */
+ }
+
+ /* try to create the file */
if (writable) {
- if (rc) {
- /* TODO: use utimensat() */
- int fd = open(path, O_RDWR, 0644);
- if (fd >= 0) {
- close(fd);
- *writable = 1;
- return rc;
- }
+ *writable = !try_write(filename);
+ return *writable;
+ }
+
+ return 0;
+}
+/**
+ *
+ * mnt_has_regular_utab:
+ * @utab: returns path to utab (usually /dev/.mount/utab)
+ * @writable: returns 1 if the file is writable
+ *
+ * If the file does not exist and @writable argument is not NULL then it will
+ * try to create the directory (e.g. /dev/.mount) and the file.
+ *
+ * Returns: 1 if /etc/utab is a reqular file, and 0 in case of error (check
+ * errno for more details).
+ */
+
+int mnt_has_regular_utab(const char **utab, int *writable)
+{
+ struct stat st;
+ int rc;
+ const char *filename = utab && *utab ? *utab : mnt_get_utab_path();
+
+ if (utab && !*utab)
+ *utab = filename;
+
+ DBG(UTILS, mnt_debug("utab: %s", filename));
+
+ rc = lstat(filename, &st);
+
+ if (rc == 0) {
+ /* file exist */
+ if (S_ISREG(st.st_mode)) {
+ if (writable)
+ *writable = try_write(filename);
+ return 1;
}
- *writable = 0;
+ return 0; /* it's not regular file */
}
- return rc;
+
+ if (writable) {
+ char *dirname = strdup(filename);
+
+ if (!dirname)
+ return 0;
+
+ stripoff_last_component(dirname); /* remove filename */
+
+ rc = mkdir(dirname, 755);
+ free(dirname);
+ if (rc && errno != EEXIST)
+ return 0; /* probably EACCES */
+
+ *writable = !try_write(filename);
+ return *writable;
+ }
+ return 0;
}
/**
@@ -496,18 +592,6 @@ int mnt_open_uniq_filename(const char *filename, char **name, int flags)
return fd < 0 ? -errno : fd;
}
-/* returns basename and keeps dirname in the @path, if @path is "/" (root)
- * then returns empty string */
-static char *stripoff_last_component(char *path)
-{
- char *p = strrchr(path, '/');
-
- if (!p)
- return NULL;
- *p = '\0';
- return ++p;
-}
-
char *mnt_get_mountpoint(const char *path)
{
char *mnt = strdup(path);