1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
|
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <errno.h>
#include <unistd.h>
#include <limits.h>
#include "zdtmtst.h"
#include "fs.h"
mnt_info_t *mnt_info_alloc(void)
{
mnt_info_t *m = malloc(sizeof(*m));
if (m)
memset(m, 0, sizeof(*m));
return m;
}
void mnt_info_free(mnt_info_t **m)
{
if (m && *m) {
free(*m);
*m = NULL;
}
}
mnt_info_t *get_cwd_mnt_info(void)
{
int mnt_id, parent_mnt_id;
unsigned int kmaj, kmin;
char str[1024], *cwd;
int ret;
FILE *f;
mnt_info_t *m = NULL;
char mountpoint[PATH_MAX];
char root[PATH_MAX];
char *fsname = NULL;
size_t len = 0, best_len = 0;
f = fopen("/proc/self/mountinfo", "r");
if (!f)
return NULL;
cwd = get_current_dir_name();
if (!cwd)
goto err;
m = mnt_info_alloc();
if (!m)
goto err;
while (fgets(str, sizeof(str), f)) {
char *hyphen = strchr(str, '-');
ret = sscanf(str, "%i %i %u:%u %s %s", &mnt_id, &parent_mnt_id, &kmaj, &kmin, root, mountpoint);
if (ret != 6 || !hyphen)
goto err;
ret = sscanf(hyphen + 1, " %ms", &fsname);
if (ret != 1)
goto err;
len = strlen(mountpoint);
if (!strncmp(mountpoint, cwd, len)) {
if (len > best_len) {
best_len = len;
m->mnt_id = mnt_id;
m->parent_mnt_id = parent_mnt_id;
m->s_dev = MKKDEV(kmaj, kmin);
strncpy(m->root, root, sizeof(m->root));
strncpy(m->mountpoint, mountpoint, sizeof(m->mountpoint));
strncpy(m->fsname, fsname, sizeof(m->fsname) - 1);
m->fsname[sizeof(m->fsname) - 1] = 0;
}
}
free(fsname);
fsname = NULL;
}
out:
free(cwd);
fclose(f);
return m;
err:
mnt_info_free(&m);
goto out;
}
int get_cwd_check_perm(char **result)
{
char *cwd;
*result = 0;
cwd = get_current_dir_name();
if (!cwd) {
pr_perror("failed to get current directory");
return -1;
}
if (access(cwd, X_OK)) {
pr_err("access check for bit X for current dir path '%s' "
"failed for uid:%d,gid:%d, error: %d(%s). "
"Bit 'x' should be set in all path components of "
"this directory\n",
cwd, getuid(), getgid(), errno, strerror(errno));
free(cwd);
return -1;
}
*result = cwd;
return 0;
}
|