Add ismounted.c and related from util-linux.

These are supposed to be LGPL or GPL 2 or later. The licensing is
unclear but in util-linux the relevant files are treated as LGPL.
is_mounted is wrapped in helpers.h
Compared to libparted, this has the benefit of not requiring a
PedPartition object, and it's supposed to be reliable and
cross-platform.
This commit is contained in:
Teo Mrnjavac 2015-08-18 18:22:30 +02:00
parent 1135a36b68
commit 815cb3caad
8 changed files with 959 additions and 2 deletions

View File

@ -1,3 +1,5 @@
set_source_files_properties( util/ismounted.c PROPERTIES LANGUAGE CXX )
set(UTIL_SRC
util/capacity.cpp
util/externalcommand.cpp
@ -5,6 +7,7 @@ set(UTIL_SRC
util/helpers.cpp
util/htmlreport.cpp
util/report.cpp
util/ismounted.c
)
set(UTIL_LIB_HDRS

View File

@ -17,6 +17,7 @@
#include "util/helpers.h"
#include "../util/globallog.h"
#include "../util/ismounted.h"
#include "../ops/operation.h"
@ -66,3 +67,8 @@ void showColumnsContextMenu(const QPoint& p, QTreeWidget& tree)
tree.resizeColumnToContents(action->data().toInt());
}
}
bool isMounted(const QString& deviceNode)
{
return is_mounted(deviceNode.toLatin1().constData());
}

View File

@ -19,10 +19,10 @@
#define HELPERS__H
#include "../util/libpartitionmanagerexport.h"
#include "../fs/filesystem.h"
#include "../util/libpartitionmanagerexport.h"
class QString;
class QPoint;
class QTreeWidget;
@ -35,4 +35,6 @@ LIBKPMCORE_EXPORT void showColumnsContextMenu(const QPoint& p, QTreeWidget& tree
LIBKPMCORE_EXPORT bool checkAccessibleDevices();
LIBKPMCORE_EXPORT bool isMounted(const QString& deviceNode);
#endif

400
src/util/ismounted.c Normal file
View File

@ -0,0 +1,400 @@
/*
* ismounted.c --- Check to see if the filesystem was mounted
*
* Copyright (C) 1995,1996,1997,1998,1999,2000,2008 Theodore Ts'o.
*
* This file may be redistributed under the terms of the GNU Public
* License.
*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#ifdef HAVE_MNTENT_H
#include <mntent.h>
#endif
#include <string.h>
#include <sys/stat.h>
#include <ctype.h>
#include <sys/param.h>
#ifdef __APPLE__
#include <sys/ucred.h>
#include <sys/mount.h>
#endif
#include "pathnames.h"
#include "ismounted.h"
#ifdef __linux__
# include "loopdev.h"
#endif
/*
* Fallback defines for old versions of glibc
*/
#ifdef O_CLOEXEC
#define UL_CLOEXECSTR "e"
#else
#define UL_CLOEXECSTR ""
#endif
#ifndef O_CLOEXEC
#define O_CLOEXEC 0
#endif
#ifdef HAVE_MNTENT_H
/*
* Helper function which checks a file in /etc/mtab format to see if a
* filesystem is mounted. Returns an error if the file doesn't exist
* or can't be opened.
*/
static int check_mntent_file(const char *mtab_file, const char *file,
int *mount_flags, char *mtpt, int mtlen)
{
struct mntent *mnt;
struct stat st_buf;
int retval = 0;
dev_t file_dev=0, file_rdev=0;
ino_t file_ino=0;
FILE *f;
int fd;
*mount_flags = 0;
if ((f = setmntent (mtab_file, "r")) == NULL)
return errno;
if (stat(file, &st_buf) == 0) {
if (S_ISBLK(st_buf.st_mode)) {
#ifndef __GNU__ /* The GNU hurd is broken with respect to stat devices */
file_rdev = st_buf.st_rdev;
#endif /* __GNU__ */
} else {
file_dev = st_buf.st_dev;
file_ino = st_buf.st_ino;
}
}
while ((mnt = getmntent (f)) != NULL) {
if (mnt->mnt_fsname[0] != '/')
continue;
if (strcmp(file, mnt->mnt_fsname) == 0)
break;
if (stat(mnt->mnt_fsname, &st_buf) != 0)
continue;
if (S_ISBLK(st_buf.st_mode)) {
#ifndef __GNU__
if (file_rdev && file_rdev == st_buf.st_rdev)
break;
#ifdef __linux__
/* maybe the file is loopdev backing file */
if (file_dev
&& major(st_buf.st_rdev) == LOOPDEV_MAJOR
&& loopdev_is_used(mnt->mnt_fsname, file, 0, 0))
break;
#endif /* __linux__ */
#endif /* __GNU__ */
} else {
if (file_dev && ((file_dev == st_buf.st_dev) &&
(file_ino == st_buf.st_ino)))
break;
}
}
if (mnt == NULL) {
#ifndef __GNU__ /* The GNU hurd is broken with respect to stat devices */
/*
* Do an extra check to see if this is the root device. We
* can't trust /etc/mtab, and /proc/mounts will only list
* /dev/root for the root filesystem. Argh. Instead we
* check if the given device has the same major/minor number
* as the device that the root directory is on.
*/
if (file_rdev && stat("/", &st_buf) == 0 &&
st_buf.st_dev == file_rdev) {
*mount_flags = MF_MOUNTED;
if (mtpt)
strncpy(mtpt, "/", mtlen);
goto is_root;
}
#endif /* __GNU__ */
goto errout;
}
#ifndef __GNU__ /* The GNU hurd is deficient; what else is new? */
/* Validate the entry in case /etc/mtab is out of date */
/*
* We need to be paranoid, because some broken distributions
* (read: Slackware) don't initialize /etc/mtab before checking
* all of the non-root filesystems on the disk.
*/
if (stat(mnt->mnt_dir, &st_buf) < 0) {
retval = errno;
if (retval == ENOENT) {
#ifdef DEBUG
printf("Bogus entry in %s! (%s does not exist)\n",
mtab_file, mnt->mnt_dir);
#endif /* DEBUG */
retval = 0;
}
goto errout;
}
if (file_rdev && (st_buf.st_dev != file_rdev)) {
#ifdef DEBUG
printf("Bogus entry in %s! (%s not mounted on %s)\n",
mtab_file, file, mnt->mnt_dir);
#endif /* DEBUG */
goto errout;
}
#endif /* __GNU__ */
*mount_flags = MF_MOUNTED;
#ifdef MNTOPT_RO
/* Check to see if the ro option is set */
if (hasmntopt(mnt, MNTOPT_RO))
*mount_flags |= MF_READONLY;
#endif
if (mtpt)
strncpy(mtpt, mnt->mnt_dir, mtlen);
/*
* Check to see if we're referring to the root filesystem.
* If so, do a manual check to see if we can open /etc/mtab
* read/write, since if the root is mounted read/only, the
* contents of /etc/mtab may not be accurate.
*/
if (!strcmp(mnt->mnt_dir, "/")) {
is_root:
#define TEST_FILE "/.ismount-test-file"
*mount_flags |= MF_ISROOT;
fd = open(TEST_FILE, O_RDWR|O_CREAT|O_CLOEXEC, 0600);
if (fd < 0) {
if (errno == EROFS)
*mount_flags |= MF_READONLY;
} else
close(fd);
(void) unlink(TEST_FILE);
}
retval = 0;
errout:
endmntent (f);
return retval;
}
static int check_mntent(const char *file, int *mount_flags,
char *mtpt, int mtlen)
{
int retval;
#ifdef DEBUG
retval = check_mntent_file("/tmp/mtab", file, mount_flags,
mtpt, mtlen);
if (retval == 0)
return 0;
#endif /* DEBUG */
#ifdef __linux__
retval = check_mntent_file("/proc/mounts", file, mount_flags,
mtpt, mtlen);
if (retval == 0 && (*mount_flags != 0))
return 0;
if (access("/proc/mounts", R_OK) == 0) {
*mount_flags = 0;
return retval;
}
#endif /* __linux__ */
#if defined(MOUNTED) || defined(_PATH_MOUNTED)
#ifndef MOUNTED
#define MOUNTED _PATH_MOUNTED
#endif /* MOUNTED */
retval = check_mntent_file(MOUNTED, file, mount_flags, mtpt, mtlen);
return retval;
#else
*mount_flags = 0;
return 0;
#endif /* defined(MOUNTED) || defined(_PATH_MOUNTED) */
}
#else
#if defined(HAVE_GETMNTINFO)
static int check_getmntinfo(const char *file, int *mount_flags,
char *mtpt, int mtlen)
{
struct statfs *mp;
int len, n;
const char *s1;
char *s2;
n = getmntinfo(&mp, MNT_NOWAIT);
if (n == 0)
return errno;
len = sizeof(_PATH_DEV) - 1;
s1 = file;
if (strncmp(_PATH_DEV, s1, len) == 0)
s1 += len;
*mount_flags = 0;
while (--n >= 0) {
s2 = mp->f_mntfromname;
if (strncmp(_PATH_DEV, s2, len) == 0) {
s2 += len - 1;
*s2 = 'r';
}
if (strcmp(s1, s2) == 0 || strcmp(s1, &s2[1]) == 0) {
*mount_flags = MF_MOUNTED;
break;
}
++mp;
}
if (mtpt)
strncpy(mtpt, mp->f_mntonname, mtlen);
return 0;
}
#endif /* HAVE_GETMNTINFO */
#endif /* HAVE_MNTENT_H */
/*
* Check to see if we're dealing with the swap device.
*/
static int is_swap_device(const char *file)
{
FILE *f;
char buf[1024], *cp;
dev_t file_dev;
struct stat st_buf;
int ret = 0;
file_dev = 0;
#ifndef __GNU__ /* The GNU hurd is broken with respect to stat devices */
if ((stat(file, &st_buf) == 0) &&
S_ISBLK(st_buf.st_mode))
file_dev = st_buf.st_rdev;
#endif /* __GNU__ */
if (!(f = fopen("/proc/swaps", "r" UL_CLOEXECSTR)))
return 0;
/* Skip the first line */
if (!fgets(buf, sizeof(buf), f))
goto leave;
if (*buf && strncmp(buf, "Filename\t", 9))
/* Linux <=2.6.19 contained a bug in the /proc/swaps
* code where the header would not be displayed
*/
goto valid_first_line;
while (fgets(buf, sizeof(buf), f)) {
valid_first_line:
if ((cp = strchr(buf, ' ')) != NULL)
*cp = 0;
if ((cp = strchr(buf, '\t')) != NULL)
*cp = 0;
if (strcmp(buf, file) == 0) {
ret++;
break;
}
#ifndef __GNU__
if (file_dev && (stat(buf, &st_buf) == 0) &&
S_ISBLK(st_buf.st_mode) &&
file_dev == st_buf.st_rdev) {
ret++;
break;
}
#endif /* __GNU__ */
}
leave:
fclose(f);
return ret;
}
/*
* check_mount_point() fills determines if the device is mounted or otherwise
* busy, and fills in mount_flags with one or more of the following flags:
* MF_MOUNTED, MF_ISROOT, MF_READONLY, MF_SWAP, and MF_BUSY. If mtpt is
* non-NULL, the directory where the device is mounted is copied to where mtpt
* is pointing, up to mtlen characters.
*/
#ifdef __TURBOC__
#pragma argsused
#endif
int check_mount_point(const char *device, int *mount_flags,
char *mtpt, int mtlen)
{
struct stat st_buf;
int retval = 0;
int fd;
if (is_swap_device(device)) {
*mount_flags = MF_MOUNTED | MF_SWAP;
if (mtpt && mtlen)
strncpy(mtpt, "[SWAP]", mtlen);
} else {
#ifdef HAVE_MNTENT_H
retval = check_mntent(device, mount_flags, mtpt, mtlen);
#else
#ifdef HAVE_GETMNTINFO
retval = check_getmntinfo(device, mount_flags, mtpt, mtlen);
#else
#ifdef __GNUC__
#warning "Can't use getmntent or getmntinfo to check for mounted filesystems!"
#endif
*mount_flags = 0;
#endif /* HAVE_GETMNTINFO */
#endif /* HAVE_MNTENT_H */
}
if (retval)
return retval;
#ifdef __linux__ /* This only works on Linux 2.6+ systems */
if ((stat(device, &st_buf) != 0) ||
!S_ISBLK(st_buf.st_mode))
return 0;
fd = open(device, O_RDONLY|O_EXCL|O_CLOEXEC);
if (fd < 0) {
if (errno == EBUSY)
*mount_flags |= MF_BUSY;
} else
close(fd);
#endif
return 0;
}
int is_mounted(const char *file)
{
int retval;
int mount_flags = 0;
retval = check_mount_point(file, &mount_flags, NULL, 0);
if (retval)
return 0;
return mount_flags & MF_MOUNTED;
}
#ifdef TEST_PROGRAM
int main(int argc, char **argv)
{
int flags = 0;
char devname[PATH_MAX];
if (argc < 2) {
fprintf(stderr, "Usage: %s device\n", argv[0]);
return EXIT_FAILURE;
}
if (check_mount_point(argv[1], &flags, devname, sizeof(devname)) == 0 &&
(flags & MF_MOUNTED)) {
if (flags & MF_SWAP)
printf("used swap device\n");
else
printf("mounted on %s\n", devname);
return EXIT_SUCCESS;
}
printf("not mounted\n");
return EXIT_FAILURE;
}
#endif /* DEBUG */

14
src/util/ismounted.h Normal file
View File

@ -0,0 +1,14 @@
#ifndef IS_MOUNTED_H
#define IS_MOUNTED_H
#define MF_MOUNTED 1
#define MF_ISROOT 2
#define MF_READONLY 4
#define MF_SWAP 8
#define MF_BUSY 16
extern int is_mounted(const char *file);
extern int check_mount_point(const char *device, int *mount_flags,
char *mtpt, int mtlen);
#endif /* IS_MOUNTED_H */

193
src/util/loopdev.h Normal file
View File

@ -0,0 +1,193 @@
#ifndef UTIL_LINUX_LOOPDEV_H
#define UTIL_LINUX_LOOPDEV_H
#include "sysfs.h"
/*
* loop_info.lo_encrypt_type
*/
#define LO_CRYPT_NONE 0
#define LO_CRYPT_XOR 1
#define LO_CRYPT_DES 2
#define LO_CRYPT_CRYPTOAPI 18
#define LOOP_SET_FD 0x4C00
#define LOOP_CLR_FD 0x4C01
/*
* Obsolete (kernel < 2.6)
*
* #define LOOP_SET_STATUS 0x4C02
* #define LOOP_GET_STATUS 0x4C03
*/
#define LOOP_SET_STATUS64 0x4C04
#define LOOP_GET_STATUS64 0x4C05
/* #define LOOP_CHANGE_FD 0x4C06 */
#define LOOP_SET_CAPACITY 0x4C07
/* /dev/loop-control interface */
#ifndef LOOP_CTL_ADD
# define LOOP_CTL_ADD 0x4C80
# define LOOP_CTL_REMOVE 0x4C81
# define LOOP_CTL_GET_FREE 0x4C82
#endif
/*
* loop_info.lo_flags
*/
enum {
LO_FLAGS_READ_ONLY = 1,
LO_FLAGS_USE_AOPS = 2,
LO_FLAGS_AUTOCLEAR = 4, /* kernel >= 2.6.25 */
LO_FLAGS_PARTSCAN = 8, /* kernel >= 3.2 */
};
#define LO_NAME_SIZE 64
#define LO_KEY_SIZE 32
/*
* Linux LOOP_{SET,GET}_STATUS64 ioctl struct
*/
struct loop_info64 {
uint64_t lo_device;
uint64_t lo_inode;
uint64_t lo_rdevice;
uint64_t lo_offset;
uint64_t lo_sizelimit; /* bytes, 0 == max available */
uint32_t lo_number;
uint32_t lo_encrypt_type;
uint32_t lo_encrypt_key_size;
uint32_t lo_flags;
uint8_t lo_file_name[LO_NAME_SIZE];
uint8_t lo_crypt_name[LO_NAME_SIZE];
uint8_t lo_encrypt_key[LO_KEY_SIZE];
uint64_t lo_init[2];
};
#define LOOPDEV_MAJOR 7 /* loop major number */
#define LOOPDEV_DEFAULT_NNODES 8 /* default number of loop devices */
struct loopdev_iter {
FILE *proc; /* /proc/partitions */
DIR *sysblock; /* /sys/block */
int ncur; /* current position */
int *minors; /* ary of minor numbers (when scan whole /dev) */
int nminors; /* number of items in *minors */
int ct_perm; /* count permission problems */
int ct_succ; /* count number of detected devices */
unsigned int done:1; /* scanning done */
unsigned int default_check:1;/* check first LOOPDEV_NLOOPS */
int flags; /* LOOPITER_FL_* flags */
};
enum {
LOOPITER_FL_FREE = (1 << 0),
LOOPITER_FL_USED = (1 << 1)
};
/*
* handler for work with loop devices
*/
struct loopdev_cxt {
char device[128]; /* device path (e.g. /dev/loop<N>) */
char *filename; /* backing file for loopcxt_set_... */
int fd; /* open(/dev/looo<N>) */
int mode; /* fd mode O_{RDONLY,RDWR} */
int flags; /* LOOPDEV_FL_* flags */
unsigned int has_info:1; /* .info contains data */
unsigned int extra_check:1; /* unusual stuff for iterator */
unsigned int info_failed:1; /* LOOP_GET_STATUS ioctl failed */
unsigned int control_ok:1; /* /dev/loop-control success */
struct sysfs_cxt sysfs; /* pointer to /sys/dev/block/<maj:min>/ */
struct loop_info64 info; /* for GET/SET ioctl */
struct loopdev_iter iter; /* scans /sys or /dev for used/free devices */
};
#define UL_LOOPDEVCXT_EMPTY { .fd = -1, .sysfs = UL_SYSFSCXT_EMPTY }
/*
* loopdev_cxt.flags
*/
enum {
LOOPDEV_FL_RDONLY = (1 << 0), /* open(/dev/loop) mode; default */
LOOPDEV_FL_RDWR = (1 << 1), /* necessary for loop setup only */
LOOPDEV_FL_OFFSET = (1 << 4),
LOOPDEV_FL_NOSYSFS = (1 << 5),
LOOPDEV_FL_NOIOCTL = (1 << 6),
LOOPDEV_FL_DEVSUBDIR = (1 << 7),
LOOPDEV_FL_CONTROL = (1 << 8), /* system with /dev/loop-control */
LOOPDEV_FL_SIZELIMIT = (1 << 9)
};
/*
* High-level
*/
extern int loopmod_supports_partscan(void);
extern int is_loopdev(const char *device);
extern int loopdev_is_autoclear(const char *device);
extern char *loopdev_get_backing_file(const char *device);
extern int loopdev_is_used(const char *device, const char *filename,
uint64_t offset, int flags);
extern char *loopdev_find_by_backing_file(const char *filename,
uint64_t offset, int flags);
extern int loopcxt_find_unused(struct loopdev_cxt *lc);
extern int loopdev_delete(const char *device);
extern int loopdev_count_by_backing_file(const char *filename, char **loopdev);
/*
* Low-level
*/
extern int loopcxt_init(struct loopdev_cxt *lc, int flags)
__attribute__ ((warn_unused_result));
extern void loopcxt_deinit(struct loopdev_cxt *lc);
extern int loopcxt_set_device(struct loopdev_cxt *lc, const char *device)
__attribute__ ((warn_unused_result));
extern int loopcxt_has_device(struct loopdev_cxt *lc);
extern int loopcxt_add_device(struct loopdev_cxt *lc);
extern char *loopcxt_strdup_device(struct loopdev_cxt *lc);
extern const char *loopcxt_get_device(struct loopdev_cxt *lc);
extern struct sysfs_cxt *loopcxt_get_sysfs(struct loopdev_cxt *lc);
extern struct loop_info64 *loopcxt_get_info(struct loopdev_cxt *lc);
extern int loopcxt_get_fd(struct loopdev_cxt *lc);
extern int loopcxt_set_fd(struct loopdev_cxt *lc, int fd, int mode);
extern int loopcxt_init_iterator(struct loopdev_cxt *lc, int flags);
extern int loopcxt_deinit_iterator(struct loopdev_cxt *lc);
extern int loopcxt_next(struct loopdev_cxt *lc);
extern int loopcxt_setup_device(struct loopdev_cxt *lc);
extern int loopcxt_delete_device(struct loopdev_cxt *lc);
extern int loopcxt_set_capacity(struct loopdev_cxt *lc);
int loopcxt_set_offset(struct loopdev_cxt *lc, uint64_t offset);
int loopcxt_set_sizelimit(struct loopdev_cxt *lc, uint64_t sizelimit);
int loopcxt_set_flags(struct loopdev_cxt *lc, uint32_t flags);
int loopcxt_set_backing_file(struct loopdev_cxt *lc, const char *filename);
extern char *loopcxt_get_backing_file(struct loopdev_cxt *lc);
extern int loopcxt_get_backing_devno(struct loopdev_cxt *lc, dev_t *devno);
extern int loopcxt_get_backing_inode(struct loopdev_cxt *lc, ino_t *ino);
extern int loopcxt_get_offset(struct loopdev_cxt *lc, uint64_t *offset);
extern int loopcxt_get_sizelimit(struct loopdev_cxt *lc, uint64_t *size);
extern int loopcxt_get_encrypt_type(struct loopdev_cxt *lc, uint32_t *type);
extern const char *loopcxt_get_crypt_name(struct loopdev_cxt *lc);
extern int loopcxt_is_autoclear(struct loopdev_cxt *lc);
extern int loopcxt_is_readonly(struct loopdev_cxt *lc);
extern int loopcxt_is_partscan(struct loopdev_cxt *lc);
extern int loopcxt_find_by_backing_file(struct loopdev_cxt *lc,
const char *filename,
uint64_t offset, int flags);
extern int loopcxt_is_used(struct loopdev_cxt *lc,
struct stat *st,
const char *backing_file,
uint64_t offset,
int flags);
#endif /* UTIL_LINUX_LOOPDEV_H */

212
src/util/pathnames.h Normal file
View File

@ -0,0 +1,212 @@
/*
* Vaguely based on
* @(#)pathnames.h 5.3 (Berkeley) 5/9/89
* This code is in the public domain.
*/
#ifndef PATHNAMES_H
#define PATHNAMES_H
#ifdef HAVE_PATHS_H
#include <paths.h>
#endif
#ifndef __STDC__
# error "we need an ANSI compiler"
#endif
/* used by kernel in /proc (e.g. /proc/swaps) for deleted files */
#define PATH_DELETED_SUFFIX "\\040(deleted)"
#define PATH_DELETED_SUFFIX_SZ (sizeof(PATH_DELETED_SUFFIX) - 1)
/* DEFPATHs from <paths.h> don't include /usr/local */
#undef _PATH_DEFPATH
#ifdef USE_USRDIR_PATHS_ONLY
# define _PATH_DEFPATH "/usr/local/bin:/usr/bin"
#else
# define _PATH_DEFPATH "/usr/local/bin:/bin:/usr/bin"
#endif
#undef _PATH_DEFPATH_ROOT
#ifdef USE_USRDIR_PATHS_ONLY
# define _PATH_DEFPATH_ROOT "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin"
#else
# define _PATH_DEFPATH_ROOT "/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin"
#endif
#define _PATH_SECURETTY "/etc/securetty"
#define _PATH_WTMPLOCK "/etc/wtmplock"
#define _PATH_HUSHLOGIN ".hushlogin"
#define _PATH_HUSHLOGINS "/etc/hushlogins"
#define _PATH_NOLOGIN_TXT "/etc/nologin.txt"
#ifndef _PATH_MAILDIR
#define _PATH_MAILDIR "/var/spool/mail"
#endif
#define _PATH_MOTDFILE "/etc/motd"
#define _PATH_NOLOGIN "/etc/nologin"
#define _PATH_VAR_NOLOGIN "/var/run/nologin"
#define _PATH_LOGIN "/bin/login"
#define _PATH_INITTAB "/etc/inittab"
#define _PATH_RC "/etc/rc"
#define _PATH_REBOOT "/sbin/reboot"
#define _PATH_SHUTDOWN "/sbin/shutdown"
#define _PATH_SINGLE "/etc/singleboot"
#define _PATH_SHUTDOWN_CONF "/etc/shutdown.conf"
#define _PATH_SECURE "/etc/securesingle"
#define _PATH_USERTTY "/etc/usertty"
#define _PATH_TERMCOLORS_DIRNAME "terminal-colors.d"
#define _PATH_TERMCOLORS_DIR "/etc/" _PATH_TERMCOLORS_DIRNAME
/* used in login-utils/shutdown.c */
/* used in login-utils/setpwnam.h and login-utils/islocal.c */
#define _PATH_PASSWD "/etc/passwd"
/* used in login-utils/newgrp and login-utils/setpwnam.h*/
#define _PATH_GSHADOW "/etc/gshadow"
/* used in login-utils/setpwnam.h */
#define _PATH_GROUP "/etc/group"
#define _PATH_SHADOW_PASSWD "/etc/shadow"
#define _PATH_SHELLS "/etc/shells"
/* used in term-utils/agetty.c */
#define _PATH_ISSUE "/etc/issue"
#define _PATH_OS_RELEASE_ETC "/etc/os-release"
#define _PATH_OS_RELEASE_USR "/usr/lib/os-release"
#define _PATH_NUMLOCK_ON _PATH_LOCALSTATEDIR "/numlock-on"
#define _PATH_LOGINDEFS "/etc/login.defs"
/* used in misc-utils/look.c */
#define _PATH_WORDS "/usr/share/dict/words"
#define _PATH_WORDS_ALT "/usr/share/dict/web2"
/* mount paths */
#define _PATH_UMOUNT "/bin/umount"
#define _PATH_FILESYSTEMS "/etc/filesystems"
#define _PATH_PROC_SWAPS "/proc/swaps"
#define _PATH_PROC_FILESYSTEMS "/proc/filesystems"
#define _PATH_PROC_MOUNTS "/proc/mounts"
#define _PATH_PROC_PARTITIONS "/proc/partitions"
#define _PATH_PROC_DEVICES "/proc/devices"
#define _PATH_PROC_MOUNTINFO "/proc/self/mountinfo"
#define _PATH_PROC_LOCKS "/proc/locks"
#define _PATH_PROC_CDROMINFO "/proc/sys/dev/cdrom/info"
#define _PATH_PROC_UIDMAP "/proc/self/uid_map"
#define _PATH_PROC_GIDMAP "/proc/self/gid_map"
#define _PATH_PROC_SETGROUPS "/proc/self/setgroups"
#define _PATH_PROC_ATTR_CURRENT "/proc/self/attr/current"
#define _PATH_PROC_ATTR_EXEC "/proc/self/attr/exec"
#define _PATH_PROC_CAPLASTCAP "/proc/sys/kernel/cap_last_cap"
#define _PATH_SYS_BLOCK "/sys/block"
#define _PATH_SYS_DEVBLOCK "/sys/dev/block"
#define _PATH_SYS_CLASS "/sys/class"
#define _PATH_SYS_SCSI "/sys/bus/scsi"
#define _PATH_SYS_SELINUX "/sys/fs/selinux"
#define _PATH_SYS_APPARMOR "/sys/kernel/security/apparmor"
#ifndef _PATH_MOUNTED
# ifdef MOUNTED /* deprecated */
# define _PATH_MOUNTED MOUNTED
# else
# define _PATH_MOUNTED "/etc/mtab"
# endif
#endif
#ifndef _PATH_MNTTAB
# ifdef MNTTAB /* deprecated */
# define _PATH_MNTTAB MNTTAB
# else
# define _PATH_MNTTAB "/etc/fstab"
# endif
#endif
#define _PATH_MNTTAB_DIR _PATH_MNTTAB ".d"
#define _PATH_MOUNTED_LOCK _PATH_MOUNTED "~"
#define _PATH_MOUNTED_TMP _PATH_MOUNTED ".tmp"
#ifndef _PATH_DEV
/*
* The tailing '/' in _PATH_DEV is there for compatibility with libc.
*/
# define _PATH_DEV "/dev/"
#endif
#define _PATH_DEV_MEM "/dev/mem"
#define _PATH_DEV_LOOP "/dev/loop"
#define _PATH_DEV_LOOPCTL "/dev/loop-control"
#define _PATH_DEV_TTY "/dev/tty"
/* udev paths */
#define _PATH_DEV_BYLABEL "/dev/disk/by-label"
#define _PATH_DEV_BYUUID "/dev/disk/by-uuid"
#define _PATH_DEV_BYID "/dev/disk/by-id"
#define _PATH_DEV_BYPATH "/dev/disk/by-path"
#define _PATH_DEV_BYPARTLABEL "/dev/disk/by-partlabel"
#define _PATH_DEV_BYPARTUUID "/dev/disk/by-partuuid"
/* hwclock paths */
#ifdef CONFIG_ADJTIME_PATH
# define _PATH_ADJTIME CONFIG_ADJTIME_PATH
#else
# define _PATH_ADJTIME "/etc/adjtime"
#endif
#define _PATH_LASTDATE "/var/lib/lastdate"
#ifdef __ia64__
# define _PATH_RTC_DEV "/dev/efirtc"
#else
# define _PATH_RTC_DEV "/dev/rtc"
#endif
#ifndef _PATH_BTMP
#define _PATH_BTMP "/var/log/btmp"
#endif
/* raw paths*/
#define _PATH_RAWDEVDIR "/dev/raw/"
#define _PATH_RAWDEVCTL _PATH_RAWDEVDIR "rawctl"
/* deprecated */
#define _PATH_RAWDEVCTL_OLD "/dev/rawctl"
/* wdctl path */
#define _PATH_WATCHDOG_DEV "/dev/watchdog"
/* ipc paths */
#define _PATH_PROC_SYSV_MSG "/proc/sysvipc/msg"
#define _PATH_PROC_SYSV_SEM "/proc/sysvipc/sem"
#define _PATH_PROC_SYSV_SHM "/proc/sysvipc/shm"
#define _PATH_PROC_IPC_MSGMAX "/proc/sys/kernel/msgmax"
#define _PATH_PROC_IPC_MSGMNB "/proc/sys/kernel/msgmnb"
#define _PATH_PROC_IPC_MSGMNI "/proc/sys/kernel/msgmni"
#define _PATH_PROC_IPC_SEM "/proc/sys/kernel/sem"
#define _PATH_PROC_IPC_SHMALL "/proc/sys/kernel/shmall"
#define _PATH_PROC_IPC_SHMMAX "/proc/sys/kernel/shmmax"
#define _PATH_PROC_IPC_SHMMNI "/proc/sys/kernel/shmmni"
/* kernel command line */
#define _PATH_PROC_CMDLINE "/proc/cmdline"
/* logger paths */
#define _PATH_DEVLOG "/dev/log"
#endif /* PATHNAMES_H */

127
src/util/sysfs.h Normal file
View File

@ -0,0 +1,127 @@
/*
* Copyright (C) 2011 Karel Zak <kzak@redhat.com>
*/
#ifndef UTIL_LINUX_SYSFS_H
#define UTIL_LINUX_SYSFS_H
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdint.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <inttypes.h>
#include <dirent.h>
struct sysfs_cxt {
dev_t devno;
int dir_fd; /* /sys/block/<name> */
char *dir_path;
struct sysfs_cxt *parent;
unsigned int scsi_host,
scsi_channel,
scsi_target,
scsi_lun;
unsigned int has_hctl : 1;
};
#define UL_SYSFSCXT_EMPTY { 0, -1, NULL, NULL, 0, 0, 0, 0, 0 }
extern char *sysfs_devno_attribute_path(dev_t devno, char *buf,
size_t bufsiz, const char *attr);
extern int sysfs_devno_has_attribute(dev_t devno, const char *attr);
extern char *sysfs_devno_path(dev_t devno, char *buf, size_t bufsiz);
extern char *sysfs_devno_to_devpath(dev_t devno, char *buf, size_t bufsiz);
extern dev_t sysfs_devname_to_devno(const char *name, const char *parent);
extern int sysfs_init(struct sysfs_cxt *cxt, dev_t devno, struct sysfs_cxt *parent)
__attribute__ ((warn_unused_result));
extern void sysfs_deinit(struct sysfs_cxt *cxt);
extern DIR *sysfs_opendir(struct sysfs_cxt *cxt, const char *attr);
extern int sysfs_stat(struct sysfs_cxt *cxt, const char *attr, struct stat *st);
extern ssize_t sysfs_readlink(struct sysfs_cxt *cxt, const char *attr,
char *buf, size_t bufsiz);
extern int sysfs_has_attribute(struct sysfs_cxt *cxt, const char *attr);
extern int sysfs_scanf(struct sysfs_cxt *cxt, const char *attr,
const char *fmt, ...)
__attribute__ ((format (scanf, 3, 4)));
extern int sysfs_read_s64(struct sysfs_cxt *cxt, const char *attr, int64_t *res);
extern int sysfs_read_u64(struct sysfs_cxt *cxt, const char *attr, uint64_t *res);
extern int sysfs_read_int(struct sysfs_cxt *cxt, const char *attr, int *res);
extern int sysfs_write_string(struct sysfs_cxt *cxt, const char *attr, const char *str);
extern int sysfs_write_u64(struct sysfs_cxt *cxt, const char *attr, uint64_t num);
extern char *sysfs_get_devname(struct sysfs_cxt *cxt, char *buf, size_t bufsiz);
extern char *sysfs_strdup(struct sysfs_cxt *cxt, const char *attr);
extern int sysfs_count_dirents(struct sysfs_cxt *cxt, const char *attr);
extern int sysfs_count_partitions(struct sysfs_cxt *cxt, const char *devname);
extern dev_t sysfs_partno_to_devno(struct sysfs_cxt *cxt, int partno);
extern char *sysfs_get_slave(struct sysfs_cxt *cxt);
extern char *sysfs_get_devchain(struct sysfs_cxt *cxt, char *buf, size_t bufsz);
extern int sysfs_next_subsystem(struct sysfs_cxt *cxt, char *devchain, char **subsys);
extern int sysfs_is_hotpluggable(struct sysfs_cxt *cxt);
extern int sysfs_is_partition_dirent(DIR *dir, struct dirent *d,
const char *parent_name);
extern int sysfs_devno_to_wholedisk(dev_t dev, char *diskname,
size_t len, dev_t *diskdevno);
extern int sysfs_devno_is_lvm_private(dev_t devno);
extern int sysfs_devno_is_wholedisk(dev_t devno);
extern int sysfs_scsi_get_hctl(struct sysfs_cxt *cxt, int *h,
int *c, int *t, int *l);
extern char *sysfs_scsi_host_strdup_attribute(struct sysfs_cxt *cxt,
const char *type, const char *attr);
extern int sysfs_scsi_host_is(struct sysfs_cxt *cxt, const char *type);
extern int sysfs_scsi_has_attribute(struct sysfs_cxt *cxt, const char *attr);
extern int sysfs_scsi_path_contains(struct sysfs_cxt *cxt, const char *pattern);
/**
* sysfs_devname_sys_to_dev:
* @name: devname to be converted in place
*
* Linux kernel linux/drivers/base/core.c: device_get_devnode()
* defines a replacement of '!' in the /sys device name by '/' in the
* /dev device name. This helper replaces all ocurrences of '!' in
* @name by '/' to convert from /sys to /dev.
*/
static inline void sysfs_devname_sys_to_dev(char *name)
{
char *c;
if (name)
while ((c = strchr(name, '!')))
c[0] = '/';
}
/**
* sysfs_devname_dev_to_sys:
* @name: devname to be converted in place
*
* See sysfs_devname_sys_to_dev().
*/
static inline void sysfs_devname_dev_to_sys(char *name)
{
char *c;
if (name)
while ((c = strchr(name, '/')))
c[0] = '!';
}
#endif /* UTIL_LINUX_SYSFS_H */