diff options
Diffstat (limited to 'include')
44 files changed, 2706 insertions, 0 deletions
diff --git a/include/Makemodule.am b/include/Makemodule.am new file mode 100644 index 0000000..9f9b78e --- /dev/null +++ b/include/Makemodule.am @@ -0,0 +1,45 @@ + +dist_noinst_HEADERS += \ + include/all-io.h \ + include/at.h \ + include/bitops.h \ + include/blkdev.h \ + include/c.h \ + include/canonicalize.h \ + include/carefulputc.h \ + include/closestream.h \ + include/cpuset.h \ + include/crc32.h \ + include/env.h \ + include/exitcodes.h \ + include/fileutils.h \ + include/ismounted.h \ + include/linux_reboot.h \ + include/linux_version.h \ + include/list.h \ + include/loopdev.h \ + include/mangle.h \ + include/match.h \ + include/mbsalign.h \ + include/md5.h \ + include/minix.h \ + include/nls.h \ + include/optutils.h \ + include/pager.h \ + include/pamfail.h \ + include/path.h \ + include/pathnames.h \ + include/procutils.h \ + include/randutils.h \ + include/rpmatch.h \ + include/setproctitle.h \ + include/strutils.h \ + include/swapheader.h \ + include/sysfs.h \ + include/tt.h \ + include/ttyutils.h \ + include/usleep.h \ + include/wholedisk.h \ + include/widechar.h \ + include/xalloc.h \ + include/xgetpass.h diff --git a/include/all-io.h b/include/all-io.h new file mode 100644 index 0000000..38a760f --- /dev/null +++ b/include/all-io.h @@ -0,0 +1,72 @@ +#ifndef UTIL_LINUX_ALL_IO_H +#define UTIL_LINUX_ALL_IO_H + +#include <string.h> +#include <unistd.h> +#include <errno.h> + +static inline int write_all(int fd, const void *buf, size_t count) +{ + while (count) { + ssize_t tmp; + + errno = 0; + tmp = write(fd, buf, count); + if (tmp > 0) { + count -= tmp; + if (count) + buf = (void *) ((char *) buf + tmp); + } else if (errno != EINTR && errno != EAGAIN) + return -1; + if (errno == EAGAIN) /* Try later, *sigh* */ + usleep(10000); + } + return 0; +} + +static inline int fwrite_all(const void *ptr, size_t size, + size_t nmemb, FILE *stream) +{ + while (nmemb) { + size_t tmp; + + errno = 0; + tmp = fwrite(ptr, size, nmemb, stream); + if (tmp > 0) { + nmemb -= tmp; + if (nmemb) + ptr = (void *) ((char *) ptr + (tmp * size)); + } else if (errno != EINTR && errno != EAGAIN) + return -1; + if (errno == EAGAIN) /* Try later, *sigh* */ + usleep(10000); + } + return 0; +} + +static inline ssize_t read_all(int fd, char *buf, size_t count) +{ + ssize_t ret; + ssize_t c = 0; + int tries = 0; + + memset(buf, 0, count); + while (count > 0) { + ret = read(fd, buf, count); + if (ret <= 0) { + if ((errno == EAGAIN || errno == EINTR || ret == 0) && + (tries++ < 5)) + continue; + return c ? c : -1; + } + if (ret > 0) + tries = 0; + count -= ret; + buf += ret; + c += ret; + } + return c; +} + + +#endif /* UTIL_LINUX_ALL_IO_H */ diff --git a/include/at.h b/include/at.h new file mode 100644 index 0000000..63a80f0 --- /dev/null +++ b/include/at.h @@ -0,0 +1,32 @@ +/* + * wrappers for "at" functions. + * + * Copyright (C) 2010 Karel Zak <kzak@redhat.com> + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + */ +#ifndef UTIL_LINUX_AT_H +#define UTIL_LINUX_AT_H + +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> + +#include "c.h" + +extern int fstat_at(int dir, const char *dirname, + const char *filename, struct stat *st, int nofollow); + +extern int open_at(int dir, const char *dirname, + const char *filename, int flags); + +extern FILE *fopen_at(int dir, const char *dirname, const char *filename, + int flags, const char *mode); + +extern ssize_t readlink_at(int dir, const char *dirname, const char *pathname, + char *buf, size_t bufsiz); + + +#endif /* UTIL_LINUX_AT_H */ diff --git a/include/bitops.h b/include/bitops.h new file mode 100644 index 0000000..81375d0 --- /dev/null +++ b/include/bitops.h @@ -0,0 +1,84 @@ +#ifndef BITOPS_H +#define BITOPS_H + +#include <stdint.h> + +/* + * Bit map related macros. Usually provided by libc. + */ +#include <sys/param.h> + +#ifndef NBBY +# define NBBY CHAR_BIT +#endif + +#ifndef setbit +# define setbit(a,i) ((a)[(i)/NBBY] |= 1<<((i)%NBBY)) +# define clrbit(a,i) ((a)[(i)/NBBY] &= ~(1<<((i)%NBBY))) +# define isset(a,i) ((a)[(i)/NBBY] & (1<<((i)%NBBY))) +# define isclr(a,i) (((a)[(i)/NBBY] & (1<<((i)%NBBY))) == 0) +#endif + +/* + * Byte swab macros (based on linux/byteorder/swab.h) + */ +#define swab16(x) \ + ((uint16_t)( \ + (((uint16_t)(x) & (uint16_t)0x00ffU) << 8) | \ + (((uint16_t)(x) & (uint16_t)0xff00U) >> 8) )) + +#define swab32(x) \ + ((uint32_t)( \ + (((uint32_t)(x) & (uint32_t)0x000000ffUL) << 24) | \ + (((uint32_t)(x) & (uint32_t)0x0000ff00UL) << 8) | \ + (((uint32_t)(x) & (uint32_t)0x00ff0000UL) >> 8) | \ + (((uint32_t)(x) & (uint32_t)0xff000000UL) >> 24) )) + +#define swab64(x) \ + ((uint64_t)( \ + (uint64_t)(((uint64_t)(x) & (uint64_t)0x00000000000000ffULL) << 56) | \ + (uint64_t)(((uint64_t)(x) & (uint64_t)0x000000000000ff00ULL) << 40) | \ + (uint64_t)(((uint64_t)(x) & (uint64_t)0x0000000000ff0000ULL) << 24) | \ + (uint64_t)(((uint64_t)(x) & (uint64_t)0x00000000ff000000ULL) << 8) | \ + (uint64_t)(((uint64_t)(x) & (uint64_t)0x000000ff00000000ULL) >> 8) | \ + (uint64_t)(((uint64_t)(x) & (uint64_t)0x0000ff0000000000ULL) >> 24) | \ + (uint64_t)(((uint64_t)(x) & (uint64_t)0x00ff000000000000ULL) >> 40) | \ + (uint64_t)(((uint64_t)(x) & (uint64_t)0xff00000000000000ULL) >> 56) )) + + +#ifdef WORDS_BIGENDIAN + +#define cpu_to_le16(x) swab16(x) +#define cpu_to_le32(x) swab32(x) +#define cpu_to_le64(x) swab64(x) +#define cpu_to_be16(x) ((uint16_t)(x)) +#define cpu_to_be32(x) ((uint32_t)(x)) +#define cpu_to_be64(x) ((uint64_t)(x)) + +#define le16_to_cpu(x) swab16(x) +#define le32_to_cpu(x) swab32(x) +#define le64_to_cpu(x) swab64(x) +#define be16_to_cpu(x) ((uint16_t)(x)) +#define be32_to_cpu(x) ((uint32_t)(x)) +#define be64_to_cpu(x) ((uint64_t)(x)) + +#else /* !WORDS_BIGENDIAN */ + +#define cpu_to_le16(x) ((uint16_t)(x)) +#define cpu_to_le32(x) ((uint32_t)(x)) +#define cpu_to_le64(x) ((uint64_t)(x)) +#define cpu_to_be16(x) swab16(x) +#define cpu_to_be32(x) swab32(x) +#define cpu_to_be64(x) swab64(x) + +#define le16_to_cpu(x) ((uint16_t)(x)) +#define le32_to_cpu(x) ((uint32_t)(x)) +#define le64_to_cpu(x) ((uint64_t)(x)) +#define be16_to_cpu(x) swab16(x) +#define be32_to_cpu(x) swab32(x) +#define be64_to_cpu(x) swab64(x) + +#endif /* WORDS_BIGENDIAN */ + +#endif /* BITOPS_H */ + diff --git a/include/blkdev.h b/include/blkdev.h new file mode 100644 index 0000000..93586a0 --- /dev/null +++ b/include/blkdev.h @@ -0,0 +1,140 @@ +#ifndef BLKDEV_H +#define BLKDEV_H + +#include <sys/types.h> +#include <sys/ioctl.h> +#ifdef HAVE_SYS_IOCCOM_H +# include <sys/ioccom.h> /* for _IO macro on e.g. Solaris */ +#endif +#include <fcntl.h> +#include <unistd.h> + +#ifdef HAVE_SYS_MKDEV_H +# include <sys/mkdev.h> /* major and minor on Solaris */ +#endif + +#define DEFAULT_SECTOR_SIZE 512 + +#ifdef __linux__ +/* very basic ioclts, should be available everywhere */ +# ifndef BLKROSET +# define BLKROSET _IO(0x12,93) /* set device read-only (0 = read-write) */ +# define BLKROGET _IO(0x12,94) /* get read-only status (0 = read_write) */ +# define BLKRRPART _IO(0x12,95) /* re-read partition table */ +# define BLKGETSIZE _IO(0x12,96) /* return device size /512 (long *arg) */ +# define BLKFLSBUF _IO(0x12,97) /* flush buffer cache */ +# define BLKRASET _IO(0x12,98) /* set read ahead for block device */ +# define BLKRAGET _IO(0x12,99) /* get current read ahead setting */ +# define BLKFRASET _IO(0x12,100) /* set filesystem (mm/filemap.c) read-ahead */ +# define BLKFRAGET _IO(0x12,101) /* get filesystem (mm/filemap.c) read-ahead */ +# define BLKSECTSET _IO(0x12,102) /* set max sectors per request (ll_rw_blk.c) */ +# define BLKSECTGET _IO(0x12,103) /* get max sectors per request (ll_rw_blk.c) */ +# define BLKSSZGET _IO(0x12,104) /* get block device sector size */ + +/* ioctls introduced in 2.2.16, removed in 2.5.58 */ +# define BLKELVGET _IOR(0x12,106,size_t) /* elevator get */ +# define BLKELVSET _IOW(0x12,107,size_t) /* elevator set */ + +# define BLKBSZGET _IOR(0x12,112,size_t) +# define BLKBSZSET _IOW(0x12,113,size_t) +# endif /* !BLKROSET */ + +# ifndef BLKGETSIZE64 +# define BLKGETSIZE64 _IOR(0x12,114,size_t) /* return device size in bytes (u64 *arg) */ +# endif + +/* block device topology ioctls, introduced in 2.6.32 (commit ac481c20) */ +# ifndef BLKIOMIN +# define BLKIOMIN _IO(0x12,120) +# define BLKIOOPT _IO(0x12,121) +# define BLKALIGNOFF _IO(0x12,122) +# define BLKPBSZGET _IO(0x12,123) +# endif + +/* discard zeroes support, introduced in 2.6.33 (commit 98262f27) */ +# ifndef BLKDISCARDZEROES +# define BLKDISCARDZEROES _IO(0x12,124) +# endif + +/* filesystem freeze, introduced in 2.6.29 (commit fcccf502) */ +# ifndef FIFREEZE +# define FIFREEZE _IOWR('X', 119, int) /* Freeze */ +# define FITHAW _IOWR('X', 120, int) /* Thaw */ +# endif + +/* uniform CD-ROM information */ +# ifndef CDROM_GET_CAPABILITY +# define CDROM_GET_CAPABILITY 0x5331 +# endif + +#endif /* __linux */ + + +#ifdef APPLE_DARWIN +# define BLKGETSIZE DKIOCGETBLOCKCOUNT32 +#endif + +#ifndef HDIO_GETGEO +# ifdef __linux__ +# define HDIO_GETGEO 0x0301 +# endif + +struct hd_geometry { + unsigned char heads; + unsigned char sectors; + unsigned short cylinders; /* truncated */ + unsigned long start; +}; +#endif /* HDIO_GETGEO */ + + +/* are we working with block device? */ +int is_blkdev(int fd); + +/* Determine size in bytes */ +off_t blkdev_find_size (int fd); + +/* get size in bytes */ +int blkdev_get_size(int fd, unsigned long long *bytes); + +/* get 512-byte sector count */ +int blkdev_get_sectors(int fd, unsigned long long *sectors); + +/* get hardware sector size */ +int blkdev_get_sector_size(int fd, int *sector_size); + +/* specifies whether or not the device is misaligned */ +int blkdev_is_misaligned(int fd); + +/* get physical block device size */ +int blkdev_get_physector_size(int fd, int *sector_size); + +/* is the device cdrom capable? */ +int blkdev_is_cdrom(int fd); + +/* get device's geometry - legacy */ +int blkdev_get_geometry(int fd, unsigned int *h, unsigned int *s); + +/* SCSI device types. Copied almost as-is from kernel header. + * http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=blob;f=include/scsi/scsi.h */ +#define SCSI_TYPE_DISK 0x00 +#define SCSI_TYPE_TAPE 0x01 +#define SCSI_TYPE_PRINTER 0x02 +#define SCSI_TYPE_PROCESSOR 0x03 /* HP scanners use this */ +#define SCSI_TYPE_WORM 0x04 /* Treated as ROM by our system */ +#define SCSI_TYPE_ROM 0x05 +#define SCSI_TYPE_SCANNER 0x06 +#define SCSI_TYPE_MOD 0x07 /* Magneto-optical disk - treated as SCSI_TYPE_DISK */ +#define SCSI_TYPE_MEDIUM_CHANGER 0x08 +#define SCSI_TYPE_COMM 0x09 /* Communications device */ +#define SCSI_TYPE_RAID 0x0c +#define SCSI_TYPE_ENCLOSURE 0x0d /* Enclosure Services Device */ +#define SCSI_TYPE_RBC 0x0e +#define SCSI_TYPE_OSD 0x11 +#define SCSI_TYPE_NO_LUN 0x7f + +/* convert scsi type code to name */ +const char *blkdev_scsi_type_to_name(int type); + + +#endif /* BLKDEV_H */ diff --git a/include/c.h b/include/c.h new file mode 100644 index 0000000..64c0138 --- /dev/null +++ b/include/c.h @@ -0,0 +1,269 @@ +/* + * Fundamental C definitions. + */ + +#ifndef UTIL_LINUX_C_H +#define UTIL_LINUX_C_H + +#include <limits.h> +#include <stddef.h> +#include <stdint.h> +#include <stdio.h> +#include <unistd.h> +#include <stdarg.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> + +#ifdef HAVE_ERR_H +# include <err.h> +#endif + +/* + * Compiler specific stuff + */ +#ifndef __GNUC_PREREQ +# if defined __GNUC__ && defined __GNUC_MINOR__ +# define __GNUC_PREREQ(maj, min) \ + ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min)) +# else +# define __GNUC_PREREQ(maj, min) 0 +# endif +#endif + +#ifdef __GNUC__ + +/* &a[0] degrades to a pointer: a different type from an array */ +# define __must_be_array(a) \ + UL_BUILD_BUG_ON_ZERO(__builtin_types_compatible_p(__typeof__(a), __typeof__(&a[0]))) + +# define ignore_result(x) ({ \ + __typeof__(x) __dummy __attribute__((__unused__)) = (x); (void) __dummy; \ +}) + +#else /* !__GNUC__ */ +# define __must_be_array(a) 0 +# define __attribute__(_arg_) +# define ignore_result(x) ((void) (x)) +#endif /* !__GNUC__ */ + +/* + * Function attributes + */ +#ifndef __ul_alloc_size +# if __GNUC_PREREQ (4, 3) +# define __ul_alloc_size(s) __attribute__((alloc_size(s))) +# else +# define __ul_alloc_size(s) +# endif +#endif + +#ifndef __ul_calloc_size +# if __GNUC_PREREQ (4, 3) +# define __ul_calloc_size(n, s) __attribute__((alloc_size(n, s))) +# else +# define __ul_calloc_size(n, s) +# endif +#endif + +/* Force a compilation error if condition is true, but also produce a + * result (of value 0 and type size_t), so the expression can be used + * e.g. in a structure initializer (or where-ever else comma expressions + * aren't permitted). + */ +#define UL_BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); })) +#define BUILD_BUG_ON_NULL(e) ((void *)sizeof(struct { int:-!!(e); })) + +#ifndef ARRAY_SIZE +# define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr)) +#endif + +#ifndef PATH_MAX +# define PATH_MAX 4096 +#endif + +#ifndef TRUE +# define TRUE 1 +#endif + +#ifndef FALSE +# define FALSE 0 +#endif + +#ifndef min +# define min(x, y) ({ \ + __typeof__(x) _min1 = (x); \ + __typeof__(y) _min2 = (y); \ + (void) (&_min1 == &_min2); \ + _min1 < _min2 ? _min1 : _min2; }) +#endif + +#ifndef max +# define max(x, y) ({ \ + __typeof__(x) _max1 = (x); \ + __typeof__(y) _max2 = (y); \ + (void) (&_max1 == &_max2); \ + _max1 > _max2 ? _max1 : _max2; }) +#endif + +#ifndef offsetof +#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) +#endif + +#ifndef container_of +#define container_of(ptr, type, member) ({ \ + const __typeof__( ((type *)0)->member ) *__mptr = (ptr); \ + (type *)( (char *)__mptr - offsetof(type,member) );}) +#endif + +#ifndef HAVE_PROGRAM_INVOCATION_SHORT_NAME +# ifdef HAVE___PROGNAME +extern char *__progname; +# define program_invocation_short_name __progname +# else +# ifdef HAVE_GETEXECNAME +# define program_invocation_short_name \ + prog_inv_sh_nm_from_file(getexecname(), 0) +# else +# define program_invocation_short_name \ + prog_inv_sh_nm_from_file(__FILE__, 1) +# endif +static char prog_inv_sh_nm_buf[256]; +static inline char * +prog_inv_sh_nm_from_file(char *f, char stripext) +{ + char *t; + + if ((t = strrchr(f, '/')) != NULL) + t++; + else + t = f; + + strncpy(prog_inv_sh_nm_buf, t, sizeof(prog_inv_sh_nm_buf) - 1); + prog_inv_sh_nm_buf[sizeof(prog_inv_sh_nm_buf) - 1] = '\0'; + + if (stripext && (t = strrchr(prog_inv_sh_nm_buf, '.')) != NULL) + *t = '\0'; + + return prog_inv_sh_nm_buf; +} +# endif +#endif + + +#ifndef HAVE_ERR_H +static inline void +errmsg(char doexit, int excode, char adderr, const char *fmt, ...) +{ + fprintf(stderr, "%s: ", program_invocation_short_name); + if (fmt != NULL) { + va_list argp; + va_start(argp, fmt); + vfprintf(stderr, fmt, argp); + va_end(argp); + if (adderr) + fprintf(stderr, ": "); + } + if (adderr) + fprintf(stderr, "%m"); + fprintf(stderr, "\n"); + if (doexit) + exit(excode); +} + +#ifndef HAVE_ERR +# define err(E, FMT...) errmsg(1, E, 1, FMT) +#endif + +#ifndef HAVE_ERRX +# define errx(E, FMT...) errmsg(1, E, 0, FMT) +#endif + +#ifndef HAVE_WARN +# define warn(FMT...) errmsg(0, 0, 1, FMT) +#endif + +#ifndef HAVE_WARNX +# define warnx(FMT...) errmsg(0, 0, 0, FMT) +#endif +#endif /* !HAVE_ERR_H */ + + +static inline __attribute__((const)) int is_power_of_2(unsigned long num) +{ + return (num != 0 && ((num & (num - 1)) == 0)); +} + +#ifndef HAVE_LOFF_T +typedef int64_t loff_t; +#endif + +#if !defined(HAVE_DIRFD) && (!defined(HAVE_DECL_DIRFD) || HAVE_DECL_DIRFD == 0) && defined(HAVE_DIR_DD_FD) +#include <sys/types.h> +#include <dirent.h> +static inline int dirfd(DIR *d) +{ + return d->dd_fd; +} +#endif + +/* + * Fallback defines for old versions of glibc + */ +#include <fcntl.h> +#ifndef O_CLOEXEC +#define O_CLOEXEC 0 +#endif + +#ifndef AI_ADDRCONFIG +#define AI_ADDRCONFIG 0x0020 +#endif + +#ifndef IUTF8 +#define IUTF8 0040000 +#endif + +/* + * Fallback for MAXHOSTNAMELEN + */ +#ifndef MAXHOSTNAMELEN +# ifdef HOST_NAME_MAX +# define MAXHOSTNAMELEN HOST_NAME_MAX +# else +# define MAXHOSTNAMELEN 64 +# endif +#endif + +/* + * Constant strings for usage() functions. For more info see + * Documentation/howto-usage-function.txt and sys-utils/arch.c + */ +#define USAGE_HEADER _("\nUsage:\n") +#define USAGE_OPTIONS _("\nOptions:\n") +#define USAGE_SEPARATOR _("\n") +#define USAGE_HELP _(" -h, --help display this help and exit\n") +#define USAGE_VERSION _(" -V, --version output version information and exit\n") +#define USAGE_MAN_TAIL(_man) _("\nFor more details see %s.\n"), _man + +#define UTIL_LINUX_VERSION _("%s from %s\n"), program_invocation_short_name, PACKAGE_STRING + +/* + * scanf modifiers for "strings allocation" + */ +#ifdef HAVE_SCANF_MS_MODIFIER +#define UL_SCNsA "%ms" +#elif defined(HAVE_SCANF_AS_MODIFIER) +#define UL_SCNsA "%as" +#endif + +/* + * seek stuff + */ +#ifndef SEEK_DATA +# define SEEK_DATA 3 +#endif +#ifndef SEEK_HOLE +# define SEEK_HOLE 4 +#endif + +#endif /* UTIL_LINUX_C_H */ diff --git a/include/canonicalize.h b/include/canonicalize.h new file mode 100644 index 0000000..f26df18 --- /dev/null +++ b/include/canonicalize.h @@ -0,0 +1,9 @@ +#ifndef CANONICALIZE_H +#define CANONICALIZE_H + +#include "c.h" /* for PATH_MAX */ + +extern char *canonicalize_path(const char *path); +extern char *canonicalize_dm_name(const char *ptname); + +#endif /* CANONICALIZE_H */ diff --git a/include/carefulputc.h b/include/carefulputc.h new file mode 100644 index 0000000..2d857eb --- /dev/null +++ b/include/carefulputc.h @@ -0,0 +1,29 @@ +#ifndef _CAREFUULPUTC_H +#define _CAREFUULPUTC_H + +/* putc() for use in write and wall (that sometimes are sgid tty) */ +/* Avoid control characters in our locale, and also ASCII control characters. + Note that the locale of the recipient is unknown. */ +#include <stdio.h> +#include <ctype.h> + +#define iso8859x_iscntrl(c) \ + (((c) & 0x7f) < 0x20 || (c) == 0x7f) + +static inline int carefulputc(int c, FILE *fp) { + int ret; + + if (c == '\007' || c == '\t' || c == '\r' || c == '\n' || + (!iso8859x_iscntrl(c) && (isprint(c) || isspace(c)))) + ret = putc(c, fp); + else if ((c & 0x80) || !isprint(c^0x40)) + ret = fprintf(fp, "\\%3o", (unsigned char) c); + else { + ret = putc('^', fp); + if (ret != EOF) + ret = putc(c^0x40, fp); + } + return (ret < 0) ? EOF : 0; +} + +#endif /* _CAREFUULPUTC_H */ diff --git a/include/closestream.h b/include/closestream.h new file mode 100644 index 0000000..d61b83b --- /dev/null +++ b/include/closestream.h @@ -0,0 +1,51 @@ +#ifndef UTIL_LINUX_CLOSESTREAM_H +#define UTIL_LINUX_CLOSESTREAM_H + +#include <stdio.h> +#ifdef HAVE_STDIO_EXT_H +#include <stdio_ext.h> +#endif +#include <unistd.h> + +#include "c.h" +#include "nls.h" + +#ifndef HAVE___FPENDING +static inline int +__fpending(FILE *stream __attribute__((__unused__))) +{ + return 0; +} +#endif + +static inline int +close_stream(FILE * stream) +{ + const int some_pending = (__fpending(stream) != 0); + const int prev_fail = (ferror(stream) != 0); + const int fclose_fail = (fclose(stream) != 0); + if (prev_fail || (fclose_fail && (some_pending || errno != EBADF))) { + if (!fclose_fail) + errno = 0; + return EOF; + } + return 0; +} + +/* Meant to be used atexit(close_stdout); */ +static inline void +close_stdout(void) +{ + if (close_stream(stdout) != 0 && !(errno == EPIPE)) { + if (errno) + warn(_("write error")); + else + warnx(_("write error")); + _exit(EXIT_FAILURE); + } + + if (close_stream(stderr) != 0) + _exit(EXIT_FAILURE); +} + +#endif /* UTIL_LINUX_CLOSESTREAM_H */ diff --git a/include/cpuset.h b/include/cpuset.h new file mode 100644 index 0000000..47ddfe2 --- /dev/null +++ b/include/cpuset.h @@ -0,0 +1,95 @@ +#ifndef UTIL_LINUX_CPUSET_H +#define UTIL_LINUX_CPUSET_H + +#include <sched.h> + +/* + * Fallback for old or obscure libcs without dynamically allocated cpusets + * + * The following macros are based on code from glibc. + * + * The GNU C Library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + */ +#if !HAVE_DECL_CPU_ALLOC + +# define CPU_ZERO_S(setsize, cpusetp) \ + do { \ + size_t __i; \ + size_t __imax = (setsize) / sizeof (__cpu_mask); \ + __cpu_mask *__bits = (cpusetp)->__bits; \ + for (__i = 0; __i < __imax; ++__i) \ + __bits[__i] = 0; \ + } while (0) + +# define CPU_SET_S(cpu, setsize, cpusetp) \ + ({ size_t __cpu = (cpu); \ + __cpu < 8 * (setsize) \ + ? (((__cpu_mask *) ((cpusetp)->__bits))[__CPUELT (__cpu)] \ + |= __CPUMASK (__cpu)) \ + : 0; }) + +# define CPU_ISSET_S(cpu, setsize, cpusetp) \ + ({ size_t __cpu = (cpu); \ + __cpu < 8 * (setsize) \ + ? ((((__cpu_mask *) ((cpusetp)->__bits))[__CPUELT (__cpu)] \ + & __CPUMASK (__cpu))) != 0 \ + : 0; }) + +# define CPU_EQUAL_S(setsize, cpusetp1, cpusetp2) \ + ({ __cpu_mask *__arr1 = (cpusetp1)->__bits; \ + __cpu_mask *__arr2 = (cpusetp2)->__bits; \ + size_t __imax = (setsize) / sizeof (__cpu_mask); \ + size_t __i; \ + for (__i = 0; __i < __imax; ++__i) \ + if (__arr1[__i] != __arr2[__i]) \ + break; \ + __i == __imax; }) + +extern int __cpuset_count_s(size_t setsize, const cpu_set_t *set); +# define CPU_COUNT_S(setsize, cpusetp) __cpuset_count_s(setsize, cpusetp) + +# define CPU_ALLOC_SIZE(count) \ + ((((count) + __NCPUBITS - 1) / __NCPUBITS) * sizeof (__cpu_mask)) +# define CPU_ALLOC(count) (malloc(CPU_ALLOC_SIZE(count))) +# define CPU_FREE(cpuset) (free(cpuset)) + +#endif /* !HAVE_DECL_CPU_ALLOC */ + + +#define cpuset_nbits(setsize) (8 * (setsize)) + +/* + * The @idx parametr returns an index of the first mask from @ary array where + * the @cpu is set. + * + * Returns: 0 if found, otherwise 1. + */ +static inline int cpuset_ary_isset(size_t cpu, cpu_set_t **ary, size_t nmemb, + size_t setsize, size_t *idx) +{ + size_t i; + + for (i = 0; i < nmemb; i++) { + if (CPU_ISSET_S(cpu, setsize, ary[i])) { + *idx = i; + return 0; + } + } + return 1; +} + +extern int get_max_number_of_cpus(void); + +extern cpu_set_t *cpuset_alloc(int ncpus, size_t *setsize, size_t *nbits); +extern void cpuset_free(cpu_set_t *set); + +extern char *cpulist_create(char *str, size_t len, cpu_set_t *set, size_t setsize); +extern int cpulist_parse(const char *str, cpu_set_t *set, size_t setsize, int fail); + +extern char *cpumask_create(char *str, size_t len, cpu_set_t *set, size_t setsize); +extern int cpumask_parse(const char *str, cpu_set_t *set, size_t setsize); + +#endif /* UTIL_LINUX_CPUSET_H */ diff --git a/include/crc32.h b/include/crc32.h new file mode 100644 index 0000000..b454be9 --- /dev/null +++ b/include/crc32.h @@ -0,0 +1,9 @@ +#ifndef UL_NG_CRC32_H +#define UL_NG_CRC32_H + +#include <stdint.h> + +extern uint32_t crc32(uint32_t seed, const unsigned char *buf, size_t len); + +#endif + diff --git a/include/env.h b/include/env.h new file mode 100644 index 0000000..df692bc --- /dev/null +++ b/include/env.h @@ -0,0 +1,17 @@ +#ifndef UTIL_LINUX_ENV_H +#define UTIL_LINUX_ENV_H + +#include "c.h" + +extern void sanitize_env (void); +extern char *safe_getenv(const char *arg); + +static inline void +xsetenv (char const *name, char const *val, int overwrite) +{ + if (setenv (name, val, overwrite) != 0) + err (EXIT_FAILURE, "failed to set the %s environment variable", name); +} + +#endif /* UTIL_LINUX_ENV_H */ + diff --git a/include/exitcodes.h b/include/exitcodes.h new file mode 100644 index 0000000..24ee123 --- /dev/null +++ b/include/exitcodes.h @@ -0,0 +1,35 @@ +#ifndef UTIL_LINUX_EXITCODES_H +#define UTIL_LINUX_EXITCODES_H +/* + * BE CAREFUL + * + * These exit codes are part of the official interface for mount, + * fsck, mkfs, etc. wrappers. + */ + +/* Exit codes used by mkfs-type programs */ +#define MKFS_EX_OK 0 /* No errors */ +#define MKFS_EX_ERROR 8 /* Operational error */ +#define MKFS_EX_USAGE 16 /* Usage or syntax error */ + +/* Exit codes used by fsck-type programs */ +#define FSCK_EX_OK 0 /* No errors */ +#define FSCK_EX_NONDESTRUCT 1 /* File system errors corrected */ +#define FSCK_EX_REBOOT 2 /* System should be rebooted */ +#define FSCK_EX_DESTRUCT FSCK_EX_REBOOT /* Alias */ +#define FSCK_EX_UNCORRECTED 4 /* File system errors left uncorrected */ +#define FSCK_EX_ERROR 8 /* Operational error */ +#define FSCK_EX_USAGE 16 /* Usage or syntax error */ +#define FSCK_EX_LIBRARY 128 /* Shared library error */ + +/* Exit codes used by mount-line programs */ +#define MOUNT_EX_SUCCESS 0 /* No errors */ +#define MOUNT_EX_USAGE 1 /* incorrect invocation or permission */ +#define MOUNT_EX_SYSERR 2 /* out of memory, cannot fork, ... */ +#define MOUNT_EX_SOFTWARE 4 /* internal mount bug or wrong version */ +#define MOUNT_EX_USER 8 /* user interrupt */ +#define MOUNT_EX_FILEIO 16 /* problems writing, locking, ... mtab/fstab */ +#define MOUNT_EX_FAIL 32 /* mount failure */ +#define MOUNT_EX_SOMEOK 64 /* some mount succeeded */ + +#endif /* UTIL_LINUX_EXITCODES_H */ diff --git a/include/fileutils.h b/include/fileutils.h new file mode 100644 index 0000000..cf29e1b --- /dev/null +++ b/include/fileutils.h @@ -0,0 +1,23 @@ +#ifndef UTIL_LINUX_FILEUTILS +#define UTIL_LINUX_FILEUTILS + +extern int xmkstemp(char **tmpname, char *dir); + +static inline FILE *xfmkstemp(char **tmpname, char *dir) +{ + int fd; + FILE *ret; + fd = xmkstemp(tmpname, dir); + if (fd == -1) { + return NULL; + } + if (!(ret = fdopen(fd, "w+"))) { + close(fd); + return NULL; + } + return ret; +} + +extern int get_fd_tabsize(void); + +#endif /* UTIL_LINUX_FILEUTILS */ diff --git a/include/ismounted.h b/include/ismounted.h new file mode 100644 index 0000000..57918cb --- /dev/null +++ b/include/ismounted.h @@ -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 */ diff --git a/include/linux_reboot.h b/include/linux_reboot.h new file mode 100644 index 0000000..9cebc67 --- /dev/null +++ b/include/linux_reboot.h @@ -0,0 +1,72 @@ +#ifndef _LINUX_REBOOT_H +#define _LINUX_REBOOT_H + +/* + * Magic values required to use _reboot() system call. + */ + +#define LINUX_REBOOT_MAGIC1 0xfee1dead +#define LINUX_REBOOT_MAGIC2 672274793 +#define LINUX_REBOOT_MAGIC2A 85072278 +#define LINUX_REBOOT_MAGIC2B 369367448 + + +/* + * Commands accepted by the _reboot() system call. + * + * RESTART Restart system using default command and mode. + * HALT Stop OS and give system control to ROM monitor, if any. + * CAD_ON Ctrl-Alt-Del sequence causes RESTART command. + * CAD_OFF Ctrl-Alt-Del sequence sends SIGINT to init task. + * POWER_OFF Stop OS and remove all power from system, if possible. + * RESTART2 Restart system using given command string. + */ + +#define LINUX_REBOOT_CMD_RESTART 0x01234567 +#define LINUX_REBOOT_CMD_HALT 0xCDEF0123 +#define LINUX_REBOOT_CMD_CAD_ON 0x89ABCDEF +#define LINUX_REBOOT_CMD_CAD_OFF 0x00000000 +#define LINUX_REBOOT_CMD_POWER_OFF 0x4321FEDC +#define LINUX_REBOOT_CMD_RESTART2 0xA1B2C3D4 + +/* Including <unistd.h> makes sure that on a glibc system + <features.h> is included, which again defines __GLIBC__ */ +#include <unistd.h> +#include "linux_reboot.h" + +#define USE_LIBC + +#ifdef USE_LIBC + +/* libc version */ +#if defined __GLIBC__ && __GLIBC__ >= 2 +# include <sys/reboot.h> +# define REBOOT(cmd) reboot(cmd) +#else +extern int reboot(int, int, int); +# define REBOOT(cmd) reboot(LINUX_REBOOT_MAGIC1,LINUX_REBOOT_MAGIC2,(cmd)) +#endif +static inline int my_reboot(int cmd) { + return REBOOT(cmd); +} + +#else /* no USE_LIBC */ + +/* direct syscall version */ +#include <linux/unistd.h> + +#ifdef _syscall3 +_syscall3(int, reboot, int, magic, int, magic_too, int, cmd); +#else +/* Let us hope we have a 3-argument reboot here */ +extern int reboot(int, int, int); +#endif + +static inline int my_reboot(int cmd) { + return reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd); +} + +#endif + + +#endif /* _LINUX_REBOOT_H */ diff --git a/include/linux_version.h b/include/linux_version.h new file mode 100644 index 0000000..a6a1e99 --- /dev/null +++ b/include/linux_version.h @@ -0,0 +1,14 @@ +#ifndef LINUX_VERSION_H +#define LINUX_VERSION_H + +#ifdef HAVE_LINUX_VERSION_H +# include <linux/version.h> +#endif + +#ifndef KERNEL_VERSION +# define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) +#endif + +int get_linux_version(void); + +#endif /* LINUX_VERSION_H */ diff --git a/include/list.h b/include/list.h new file mode 100644 index 0000000..1824af0 --- /dev/null +++ b/include/list.h @@ -0,0 +1,333 @@ +/* + * Copyright (C) 2008 Karel Zak <kzak@redhat.com> + * Copyright (C) 1999-2008 by Theodore Ts'o + * + * (based on list.h from e2fsprogs) + * Merge sort based on kernel's implementation. + */ + +#ifndef UTIL_LINUX_LIST_H +#define UTIL_LINUX_LIST_H + +/* TODO: use AC_C_INLINE */ +#ifdef __GNUC__ +#define _INLINE_ static __inline__ +#else /* For Watcom C */ +#define _INLINE_ static inline +#endif + +/* + * Simple doubly linked list implementation. + * + * Some of the internal functions ("__xxx") are useful when + * manipulating whole lists rather than single entries, as + * sometimes we already know the next/prev entries and we can + * generate better code by using them directly rather than + * using the generic single-entry routines. + */ + +struct list_head { + struct list_head *next, *prev; +}; + +#define LIST_HEAD_INIT(name) { &(name), &(name) } + +#define LIST_HEAD(name) \ + struct list_head name = LIST_HEAD_INIT(name) + +#define INIT_LIST_HEAD(ptr) do { \ + (ptr)->next = (ptr); (ptr)->prev = (ptr); \ +} while (0) + +/* + * Insert a new entry between two known consecutive entries. + * + * This is only for internal list manipulation where we know + * the prev/next entries already! + */ +_INLINE_ void __list_add(struct list_head * add, + struct list_head * prev, + struct list_head * next) +{ + next->prev = add; + add->next = next; + add->prev = prev; + prev->next = add; +} + +/** + * list_add - add a new entry + * @add: new entry to be added + * @head: list head to add it after + * + * Insert a new entry after the specified head. + * This is good for implementing stacks. + */ +_INLINE_ void list_add(struct list_head *add, struct list_head *head) +{ + __list_add(add, head, head->next); +} + +/** + * list_add_tail - add a new entry + * @add: new entry to be added + * @head: list head to add it before + * + * Insert a new entry before the specified head. + * This is useful for implementing queues. + */ +_INLINE_ void list_add_tail(struct list_head *add, struct list_head *head) +{ + __list_add(add, head->prev, head); +} + +/* + * Delete a list entry by making the prev/next entries + * point to each other. + * + * This is only for internal list manipulation where we know + * the prev/next entries already! + */ +_INLINE_ void __list_del(struct list_head * prev, + struct list_head * next) +{ + next->prev = prev; + prev->next = next; +} + +/** + * list_del - deletes entry from list. + * @entry: the element to delete from the list. + * + * list_empty() on @entry does not return true after this, @entry is + * in an undefined state. + */ +_INLINE_ void list_del(struct list_head *entry) +{ + __list_del(entry->prev, entry->next); +} + +/** + * list_del_init - deletes entry from list and reinitialize it. + * @entry: the element to delete from the list. + */ +_INLINE_ void list_del_init(struct list_head *entry) +{ + __list_del(entry->prev, entry->next); + INIT_LIST_HEAD(entry); +} + +/** + * list_empty - tests whether a list is empty + * @head: the list to test. + */ +_INLINE_ int list_empty(struct list_head *head) +{ + return head->next == head; +} + +/** + * list_last_entry - tests whether is entry last in the list + * @entry: the entry to test. + * @head: the list to test. + */ +_INLINE_ int list_last_entry(struct list_head *entry, struct list_head *head) +{ + return head->prev == entry; +} + +/** + * list_splice - join two lists + * @list: the new list to add. + * @head: the place to add it in the first list. + */ +_INLINE_ void list_splice(struct list_head *list, struct list_head *head) +{ + struct list_head *first = list->next; + + if (first != list) { + struct list_head *last = list->prev; + struct list_head *at = head->next; + + first->prev = head; + head->next = first; + + last->next = at; + at->prev = last; + } +} + +/** + * list_entry - get the struct for this entry + * @ptr: the &struct list_head pointer. + * @type: the type of the struct this is embedded in. + * @member: the name of the list_struct within the struct. + */ +#define list_entry(ptr, type, member) \ + ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member))) + + +#define list_first_entry(head, type, member) \ + ((head) && (head)->next != (head) ? list_entry((head)->next, type, member) : NULL) + +/** + * list_for_each - iterate over elements in a list + * @pos: the &struct list_head to use as a loop counter. + * @head: the head for your list. + */ +#define list_for_each(pos, head) \ + for (pos = (head)->next; pos != (head); pos = pos->next) + +/** + * list_for_each_backwardly - iterate over elements in a list in reverse + * @pos: the &struct list_head to use as a loop counter. + * @head: the head for your list. + */ +#define list_for_each_backwardly(pos, head) \ + for (pos = (head)->prev; pos != (head); pos = pos->prev) + +/** + * list_for_each_safe - iterate over elements in a list, but don't dereference + * pos after the body is done (in case it is freed) + * @pos: the &struct list_head to use as a loop counter. + * @pnext: the &struct list_head to use as a pointer to the next item. + * @head: the head for your list (not included in iteration). + */ +#define list_for_each_safe(pos, pnext, head) \ + for (pos = (head)->next, pnext = pos->next; pos != (head); \ + pos = pnext, pnext = pos->next) + +#define MAX_LIST_LENGTH_BITS 20 + +/* + * Returns a list organized in an intermediate format suited + * to chaining of merge() calls: null-terminated, no reserved or + * sentinel head node, "prev" links not maintained. + */ +_INLINE_ struct list_head *merge(int (*cmp)(struct list_head *a, + struct list_head *b), + struct list_head *a, struct list_head *b) +{ + struct list_head head, *tail = &head; + + while (a && b) { + /* if equal, take 'a' -- important for sort stability */ + if ((*cmp)(a, b) <= 0) { + tail->next = a; + a = a->next; + } else { + tail->next = b; + b = b->next; + } + tail = tail->next; + } + tail->next = a ? a : b; + return head.next; +} + +/* + * Combine final list merge with restoration of standard doubly-linked + * list structure. This approach duplicates code from merge(), but + * runs faster than the tidier alternatives of either a separate final + * prev-link restoration pass, or maintaining the prev links + * throughout. + */ +_INLINE_ void merge_and_restore_back_links(int (*cmp)(struct list_head *a, + struct list_head *b), + struct list_head *head, + struct list_head *a, struct list_head *b) +{ + struct list_head *tail = head; + + while (a && b) { + /* if equal, take 'a' -- important for sort stability */ + if ((*cmp)(a, b) <= 0) { + tail->next = a; + a->prev = tail; + a = a->next; + } else { + tail->next = b; + b->prev = tail; + b = b->next; + } + tail = tail->next; + } + tail->next = a ? a : b; + + do { + /* + * In worst cases this loop may run many iterations. + * Continue callbacks to the client even though no + * element comparison is needed, so the client's cmp() + * routine can invoke cond_resched() periodically. + */ + (*cmp)(tail->next, tail->next); + + tail->next->prev = tail; + tail = tail->next; + } while (tail->next); + + tail->next = head; + head->prev = tail; +} + + +/** + * list_sort - sort a list + * @head: the list to sort + * @cmp: the elements comparison function + * + * This function implements "merge sort", which has O(nlog(n)) + * complexity. + * + * The comparison function @cmp must return a negative value if @a + * should sort before @b, and a positive value if @a should sort after + * @b. If @a and @b are equivalent, and their original relative + * ordering is to be preserved, @cmp must return 0. + */ +_INLINE_ void list_sort(struct list_head *head, + int (*cmp)(struct list_head *a, + struct list_head *b)) +{ + struct list_head *part[MAX_LIST_LENGTH_BITS+1]; /* sorted partial lists + -- last slot is a sentinel */ + size_t lev; /* index into part[] */ + size_t max_lev = 0; + struct list_head *list; + + if (list_empty(head)) + return; + + memset(part, 0, sizeof(part)); + + head->prev->next = NULL; + list = head->next; + + while (list) { + struct list_head *cur = list; + list = list->next; + cur->next = NULL; + + for (lev = 0; part[lev]; lev++) { + cur = merge(cmp, part[lev], cur); + part[lev] = NULL; + } + if (lev > max_lev) { + /* list passed to list_sort() too long for efficiency */ + if (lev >= ARRAY_SIZE(part) - 1) + lev--; + max_lev = lev; + } + part[lev] = cur; + } + + for (lev = 0; lev < max_lev; lev++) + if (part[lev]) + list = merge(cmp, part[lev], list); + + merge_and_restore_back_links(cmp, head, part[max_lev], list); +} + +#undef _INLINE_ + +#endif /* UTIL_LINUX_LIST_H */ diff --git a/include/loopdev.h b/include/loopdev.h new file mode 100644 index 0000000..5c45878 --- /dev/null +++ b/include/loopdev.h @@ -0,0 +1,195 @@ +#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 ioclt 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 debug:1; /* debug mode ON/OFF */ + unsigned int info_failed:1; /* LOOP_GET_STATUS ioctl failed */ + + 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 void loopcxt_enable_debug(struct loopdev_cxt *lc, int enable); + +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 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); + +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); +int loopcxt_set_encryption(struct loopdev_cxt *lc, + const char *encryption, + const char *password); + +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 */ diff --git a/include/mangle.h b/include/mangle.h new file mode 100644 index 0000000..ec492b5 --- /dev/null +++ b/include/mangle.h @@ -0,0 +1,26 @@ +#ifndef UTIL_LINUX_MANGLE_H +#define UTIL_LINUX_MANGLE_H + +/* + * Functions for \oct encoding used in mtab/fstab/swaps/etc. + */ + +extern char *mangle(const char *s); + +extern void unmangle_to_buffer(const char *s, char *buf, size_t len); +void unhexmangle_to_buffer(const char *s, char *buf, size_t len); + +extern char *unmangle(const char *s, char **end); + +static inline void unmangle_string(char *s) +{ + unmangle_to_buffer(s, s, strlen(s) + 1); +} + +static inline void unhexmangle_string(char *s) +{ + unhexmangle_to_buffer(s, s, strlen(s) + 1); +} + +#endif /* UTIL_LINUX_MANGLE_H */ + diff --git a/include/match.h b/include/match.h new file mode 100644 index 0000000..94440c2 --- /dev/null +++ b/include/match.h @@ -0,0 +1,12 @@ +/* + * Copyright (C) 2011 Karel Zak <kzak@redhat.com> + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + */ +#ifndef UTIL_LINUX_MATCH_H +#define UTIL_LINUX_MATCH_H + +extern int match_fstype(const char *type, const char *pattern); + +#endif /* UTIL_LINUX_MATCH_H */ diff --git a/include/mbsalign.h b/include/mbsalign.h new file mode 100644 index 0000000..fd957b3 --- /dev/null +++ b/include/mbsalign.h @@ -0,0 +1,45 @@ +/* Align/Truncate a string in a given screen width + Copyright (C) 2009-2010 Free Software Foundation, Inc. + + 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 2 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 <stddef.h> + +typedef enum { MBS_ALIGN_LEFT, MBS_ALIGN_RIGHT, MBS_ALIGN_CENTER } mbs_align_t; + +enum { + /* Use unibyte mode for invalid multibyte strings or + or when heap memory is exhausted. */ + MBA_UNIBYTE_FALLBACK = 0x0001, + +#if 0 /* Other possible options. */ + /* Skip invalid multibyte chars rather than failing */ + MBA_IGNORE_INVALID = 0x0002, + + /* Align multibyte strings using "figure space" (\u2007) */ + MBA_USE_FIGURE_SPACE = 0x0004, + + /* Don't add any padding */ + MBA_TRUNCATE_ONLY = 0x0008, + + /* Don't truncate */ + MBA_PAD_ONLY = 0x0010, +#endif +}; + +extern size_t mbs_truncate(char *str, size_t *width); + +extern size_t mbsalign (const char *src, char *dest, + size_t dest_size, size_t *width, + mbs_align_t align, int flags); diff --git a/include/md5.h b/include/md5.h new file mode 100644 index 0000000..d997e37 --- /dev/null +++ b/include/md5.h @@ -0,0 +1,29 @@ +#ifndef MD5_H +#define MD5_H + +#ifdef HAVE_STDINT_H +#include <stdint.h> +#else +typedef unsigned int uint32_t; +#endif + +#define MD5LENGTH 16 + +struct MD5Context { + uint32_t buf[4]; + uint32_t bits[2]; + unsigned char in[64]; +}; + +void MD5Init(struct MD5Context *context); +void MD5Update(struct MD5Context *context, unsigned char const *buf, + unsigned len); +void MD5Final(unsigned char digest[MD5LENGTH], struct MD5Context *context); +void MD5Transform(uint32_t buf[4], uint32_t const in[16]); + +/* + * This is needed to make RSAREF happy on some MS-DOS compilers. + */ +typedef struct MD5Context MD5_CTX; + +#endif /* !MD5_H */ diff --git a/include/minix.h b/include/minix.h new file mode 100644 index 0000000..57be239 --- /dev/null +++ b/include/minix.h @@ -0,0 +1,82 @@ +#ifndef UTIL_LINUX_MINIX_H +#define UTIL_LINUX_MINIX_H + +#include <stdint.h> + +struct minix_inode { + uint16_t i_mode; + uint16_t i_uid; + uint32_t i_size; + uint32_t i_time; + uint8_t i_gid; + uint8_t i_nlinks; + uint16_t i_zone[9]; +}; + +struct minix2_inode { + uint16_t i_mode; + uint16_t i_nlinks; + uint16_t i_uid; + uint16_t i_gid; + uint32_t i_size; + uint32_t i_atime; + uint32_t i_mtime; + uint32_t i_ctime; + uint32_t i_zone[10]; +}; + +struct minix_super_block { + uint16_t s_ninodes; + uint16_t s_nzones; + uint16_t s_imap_blocks; + uint16_t s_zmap_blocks; + uint16_t s_firstdatazone; + uint16_t s_log_zone_size; + uint32_t s_max_size; + uint16_t s_magic; + uint16_t s_state; + uint32_t s_zones; +}; + +/* V3 minix super-block data on disk */ +struct minix3_super_block { + uint32_t s_ninodes; + uint16_t s_pad0; + uint16_t s_imap_blocks; + uint16_t s_zmap_blocks; + uint16_t s_firstdatazone; + uint16_t s_log_zone_size; + uint16_t s_pad1; + uint32_t s_max_size; + uint32_t s_zones; + uint16_t s_magic; + uint16_t s_pad2; + uint16_t s_blocksize; + uint8_t s_disk_version; +}; + +/* + * Minix subpartitions are always within primary dos partition. + */ +#define MINIX_MAXPARTITIONS 4 + +#define MINIX_BLOCK_SIZE_BITS 10 +#define MINIX_BLOCK_SIZE (1 << MINIX_BLOCK_SIZE_BITS) + +#define MINIX_NAME_MAX 255 /* # chars in a file name */ +#define MINIX_MAX_INODES 65535 + +#define MINIX_INODES_PER_BLOCK ((MINIX_BLOCK_SIZE)/(sizeof (struct minix_inode))) +#define MINIX2_INODES_PER_BLOCK ((MINIX_BLOCK_SIZE)/(sizeof (struct minix2_inode))) + +/* minix_super_block.s_state */ +#define MINIX_VALID_FS 0x0001 /* Clean fs. */ +#define MINIX_ERROR_FS 0x0002 /* fs has errors. */ + +#define MINIX_SUPER_MAGIC 0x137F /* original minix fs */ +#define MINIX_SUPER_MAGIC2 0x138F /* minix fs, 30 char names */ +#define MINIX2_SUPER_MAGIC 0x2468 /* minix V2 fs */ +#define MINIX2_SUPER_MAGIC2 0x2478 /* minix V2 fs, 30 char names */ +#define MINIX3_SUPER_MAGIC 0x4d5a /* minix V3 fs (60 char names) */ + +#endif /* UTIL_LINUX_MINIX_H */ diff --git a/include/nls.h b/include/nls.h new file mode 100644 index 0000000..3eabfe6 --- /dev/null +++ b/include/nls.h @@ -0,0 +1,115 @@ +#ifndef UTIL_LINUX_NLS_H +#define UTIL_LINUX_NLS_H + +int main(int argc, char *argv[]); + +#ifndef LOCALEDIR +#define LOCALEDIR "/usr/share/locale" +#endif + +#ifdef HAVE_LOCALE_H +# include <locale.h> +#else +# undef setlocale +# define setlocale(Category, Locale) /* empty */ +struct lconv +{ + char *decimal_point; +}; +# undef localeconv +# define localeconv() NULL +#endif + +#ifdef ENABLE_NLS +# include <libintl.h> +# define _(Text) gettext (Text) +# ifdef gettext_noop +# define N_(String) gettext_noop (String) +# else +# define N_(String) (String) +# endif +# define P_(Singular, Plural, n) ngettext (Singular, Plural, n) +#else +# undef bindtextdomain +# define bindtextdomain(Domain, Directory) /* empty */ +# undef textdomain +# define textdomain(Domain) /* empty */ +# define _(Text) (Text) +# define N_(Text) (Text) +# define P_(Singular, Plural, n) ((n) == 1 ? (Singular) : (Plural)) +#endif + +#ifdef HAVE_LANGINFO_H +# include <langinfo.h> +#else + +typedef int nl_item; +extern char *langinfo_fallback(nl_item item); + +# define nl_langinfo langinfo_fallback + +enum { + CODESET = 1, + RADIXCHAR, + THOUSEP, + D_T_FMT, + D_FMT, + T_FMT, + T_FMT_AMPM, + AM_STR, + PM_STR, + + DAY_1, + DAY_2, + DAY_3, + DAY_4, + DAY_5, + DAY_6, + DAY_7, + + ABDAY_1, + ABDAY_2, + ABDAY_3, + ABDAY_4, + ABDAY_5, + ABDAY_6, + ABDAY_7, + + MON_1, + MON_2, + MON_3, + MON_4, + MON_5, + MON_6, + MON_7, + MON_8, + MON_9, + MON_10, + MON_11, + MON_12, + + ABMON_1, + ABMON_2, + ABMON_3, + ABMON_4, + ABMON_5, + ABMON_6, + ABMON_7, + ABMON_8, + ABMON_9, + ABMON_10, + ABMON_11, + ABMON_12, + + ERA_D_FMT, + ERA_D_T_FMT, + ERA_T_FMT, + ALT_DIGITS, + CRNCYSTR, + YESEXPR, + NOEXPR +}; + +#endif /* !HAVE_LANGINFO_H */ + +#endif /* UTIL_LINUX_NLS_H */ diff --git a/include/optutils.h b/include/optutils.h new file mode 100644 index 0000000..28a54b2 --- /dev/null +++ b/include/optutils.h @@ -0,0 +1,95 @@ +#ifndef UTIL_LINUX_OPTUTILS_H +#define UTIL_LINUX_OPTUTILS_H + +#include "c.h" +#include "nls.h" + +static inline const char *option_to_longopt(int c, const struct option *opts) +{ + const struct option *o; + + for (o = opts; o->name; o++) + if (o->val == c) + return o->name; + return NULL; +} + +#ifndef OPTUTILS_EXIT_CODE +# define OPTUTILS_EXIT_CODE EXIT_FAILURE +#endif + +/* + * Check collisions between options. + * + * The conflicts between options are described in ul_excl_t array. The + * array contains groups of mutually exclusive options. For example + * + * static const ul_excl_t excl[] = { + * { 'Z','b','c' }, // first group + * { 'b','x' }, // second group + * { 0 } + * }; + * + * int excl_st[ARRAY_SIZE(excl)] = UL_EXCL_STATUS_INIT; + * + * while ((c = getopt_long(argc, argv, "Zbcx", longopts, NULL)) != -1) { + * + * err_exclusive_options(c, longopts, excl, excl_st); + * + * switch (c) { + * case 'Z': + * .... + * } + * } + * + * The array excl[] defines two groups of the mutually exclusive options. The + * option '-b' is in the both groups. + * + * Note that the options in the group have to be in ASCII order (ABC..abc..) and + * groups have to be also in ASCII order. + * + * The current status of options is stored in excl_st array. The size of the array + * must be the same as number of the groups in the ul_excl_t array. + * + * If you're unsure then see sys-utils/mount.c or misc-utils/findmnt.c. + */ +#define UL_EXCL_STATUS_INIT { 0 } +typedef int ul_excl_t[16]; + +static inline void err_exclusive_options( + int c, + const struct option *opts, + const ul_excl_t *excl, + int *status) +{ + int e; + + for (e = 0; excl[e][0] && excl[e][0] <= c; e++) { + const int *op = excl[e]; + + for (; *op && *op <= c; op++) { + if (*op != c) + continue; + if (status[e] == 0) + status[e] = c; + else if (status[e] != c) { + fprintf(stderr, _("%s: options "), + program_invocation_short_name); + for (op = excl[e]; *op; op++) { + if (opts) + fprintf(stderr, "--%s ", + option_to_longopt(*op, opts)); + else + fprintf(stderr, "-%c ", *op); + } + fprintf(stderr, _("are mutually exclusive.")); + fputc('\n', stderr); + exit(OPTUTILS_EXIT_CODE); + } + break; + } + } +} + +#endif + diff --git a/include/pager.h b/include/pager.h new file mode 100644 index 0000000..9ca42eb --- /dev/null +++ b/include/pager.h @@ -0,0 +1,6 @@ +#ifndef UTIL_LINUX_PAGER +#define UTIL_LINUX_PAGER + +void setup_pager(void); + +#endif diff --git a/include/pamfail.h b/include/pamfail.h new file mode 100644 index 0000000..8008ce3 --- /dev/null +++ b/include/pamfail.h @@ -0,0 +1,16 @@ +#ifndef UTIL_LINUX_PAMFAIL_H +#include <security/pam_appl.h> +#include <security/pam_misc.h> +#include "c.h" + +static inline int +pam_fail_check(pam_handle_t *pamh, int retcode) +{ + if (retcode == PAM_SUCCESS) + return 0; + warnx("%s", pam_strerror(pamh, retcode)); + pam_end(pamh, retcode); + return 1; +} + +#endif /* UTIL_LINUX_PAMFAIL_H */ diff --git a/include/path.h b/include/path.h new file mode 100644 index 0000000..8e79a85 --- /dev/null +++ b/include/path.h @@ -0,0 +1,17 @@ +#include <stdio.h> + +extern FILE *path_fopen(const char *mode, int exit_on_err, const char *path, ...) + __attribute__ ((__format__ (__printf__, 3, 4))); +extern void path_getstr(char *result, size_t len, const char *path, ...) + __attribute__ ((__format__ (__printf__, 3, 4))); +extern int path_writestr(const char *str, const char *path, ...) + __attribute__ ((__format__ (__printf__, 2, 3))); +extern int path_getnum(const char *path, ...) + __attribute__ ((__format__ (__printf__, 1, 2))); +extern int path_exist(const char *path, ...) + __attribute__ ((__format__ (__printf__, 1, 2))); +extern cpu_set_t *path_cpuset(int, const char *path, ...) + __attribute__ ((__format__ (__printf__, 2, 3))); +extern cpu_set_t *path_cpulist(int, const char *path, ...) + __attribute__ ((__format__ (__printf__, 2, 3))); +extern void path_setprefix(const char *); diff --git a/include/pathnames.h b/include/pathnames.h new file mode 100644 index 0000000..d0ed7a1 --- /dev/null +++ b/include/pathnames.h @@ -0,0 +1,154 @@ +/* + * 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 +#define _PATH_DEFPATH "/usr/local/bin:/bin:/usr/bin" + +#undef _PATH_DEFPATH_ROOT +#define _PATH_DEFPATH_ROOT "/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin" + +#define _PATH_SECURETTY "/etc/securetty" +#define _PATH_WTMPLOCK "/etc/wtmplock" + +#define _PATH_HUSHLOGIN ".hushlogin" +#define _PATH_HUSHLOGINS "/etc/hushlogins" + +#ifndef _PATH_MAILDIR +#define _PATH_MAILDIR "/var/spool/mail" +#endif +#define _PATH_MOTDFILE "/etc/motd" +#define _PATH_NOLOGIN "/etc/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" + +/* 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_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_SYS_BLOCK "/sys/block" +#define _PATH_SYS_DEVBLOCK "/sys/dev/block" + +#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_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 */ +#define _PATH_ADJPATH "/etc/adjtime" +#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" + +#endif /* PATHNAMES_H */ + diff --git a/include/procutils.h b/include/procutils.h new file mode 100644 index 0000000..ca7087a --- /dev/null +++ b/include/procutils.h @@ -0,0 +1,14 @@ +#ifndef UTIL_LINUX_PROCUTILS +#define UTIL_LINUX_PROCUTILS + +#include <dirent.h> + +struct proc_tasks { + DIR *dir; +}; + +extern struct proc_tasks *proc_open_tasks(pid_t pid); +extern void proc_close_tasks(struct proc_tasks *tasks); +extern int proc_next_tid(struct proc_tasks *tasks, pid_t *tid); + +#endif /* UTIL_LINUX_PROCUTILS */ diff --git a/include/randutils.h b/include/randutils.h new file mode 100644 index 0000000..dec5e35 --- /dev/null +++ b/include/randutils.h @@ -0,0 +1,12 @@ +#ifndef UTIL_LINUX_RANDUTILS +#define UTIL_LINUX_RANDUTILS + +#ifdef HAVE_SRANDOM +#define srand(x) srandom(x) +#define rand() random() +#endif + +extern int random_get_fd(void); +extern void random_get_bytes(void *buf, size_t nbytes); + +#endif diff --git a/include/rpmatch.h b/include/rpmatch.h new file mode 100644 index 0000000..d62634b --- /dev/null +++ b/include/rpmatch.h @@ -0,0 +1,9 @@ +#ifndef UTIL_LINUX_RPMATCH_H +#define UTIL_LINUX_RPMATCH_H + +#ifndef HAVE_RPMATCH +#define rpmatch(r) \ + (*r == 'y' || *r == 'Y' ? 1 : *r == 'n' || *r == 'N' ? 0 : -1) +#endif + +#endif /* UTIL_LINUX_RPMATCH_H */ diff --git a/include/setproctitle.h b/include/setproctitle.h new file mode 100644 index 0000000..70a9efa --- /dev/null +++ b/include/setproctitle.h @@ -0,0 +1,7 @@ +#ifndef UTIL_LINUX_SETPROCTITLE_H +#define UTIL_LINUX_SETPROCTITLE_H + +extern void initproctitle (int argc, char **argv); +extern void setproctitle (const char *prog, const char *txt); + +#endif diff --git a/include/strutils.h b/include/strutils.h new file mode 100644 index 0000000..123907f --- /dev/null +++ b/include/strutils.h @@ -0,0 +1,76 @@ +#ifndef UTIL_LINUX_STRUTILS +#define UTIL_LINUX_STRUTILS + +#include <inttypes.h> +#include <string.h> +#include <sys/types.h> + +/* default strtoxx_or_err() exit code */ +#ifndef STRTOXX_EXIT_CODE +# define STRTOXX_EXIT_CODE EXIT_FAILURE +#endif + + +extern int strtosize(const char *str, uintmax_t *res); +extern uintmax_t strtosize_or_err(const char *str, const char *errmesg); + +extern int16_t strtos16_or_err(const char *str, const char *errmesg); +extern uint16_t strtou16_or_err(const char *str, const char *errmesg); + +extern int32_t strtos32_or_err(const char *str, const char *errmesg); +extern uint32_t strtou32_or_err(const char *str, const char *errmesg); + +extern int64_t strtos64_or_err(const char *str, const char *errmesg); +extern uint64_t strtou64_or_err(const char *str, const char *errmesg); + +extern double strtod_or_err(const char *str, const char *errmesg); + +extern long strtol_or_err(const char *str, const char *errmesg); +extern unsigned long strtoul_or_err(const char *str, const char *errmesg); + +#ifndef HAVE_STRNLEN +extern size_t strnlen(const char *s, size_t maxlen); +#endif +#ifndef HAVE_STRNDUP +extern char *strndup(const char *s, size_t n); +#endif +#ifndef HAVE_STRNCHR +extern char *strnchr(const char *s, size_t maxlen, int c); +#endif + +/* caller guarantees n > 0 */ +static inline void xstrncpy(char *dest, const char *src, size_t n) +{ + strncpy(dest, src, n-1); + dest[n-1] = 0; +} + +extern void strmode(mode_t mode, char *str); + +/* Options for size_to_human_string() */ +enum +{ + SIZE_SUFFIX_1LETTER = 0, + SIZE_SUFFIX_3LETTER = 1, + SIZE_SUFFIX_SPACE = 2 +}; + +extern char *size_to_human_string(int options, uint64_t bytes); + +extern int string_to_idarray(const char *list, int ary[], size_t arysz, + int (name2id)(const char *, size_t)); +extern int string_add_to_idarray(const char *list, int ary[], + size_t arysz, int *ary_pos, + int (name2id)(const char *, size_t)); + +extern int string_to_bitarray(const char *list, char *ary, + int (*name2bit)(const char *, size_t)); + +extern int string_to_bitmask(const char *list, + unsigned long *mask, + long (*name2flag)(const char *, size_t)); +extern int parse_range(const char *str, int *lower, int *upper, int def); + +extern int streq_except_trailing_slash(const char *s1, const char *s2); + +#endif diff --git a/include/swapheader.h b/include/swapheader.h new file mode 100644 index 0000000..42d521a --- /dev/null +++ b/include/swapheader.h @@ -0,0 +1,28 @@ +#ifndef _SWAPHEADER_H +#define _SWAPHEADER_H + +struct swap_header_v1 { + char bootbits[1024]; /* Space for disklabel etc. */ + unsigned int version; + unsigned int last_page; + unsigned int nr_badpages; + unsigned int padding[125]; + unsigned int badpages[1]; +}; + + +#define SWAP_UUID_LENGTH 16 +#define SWAP_LABEL_LENGTH 16 + +struct swap_header_v1_2 { + char bootbits[1024]; /* Space for disklabel etc. */ + unsigned int version; + unsigned int last_page; + unsigned int nr_badpages; + unsigned char uuid[SWAP_UUID_LENGTH]; + char volume_name[SWAP_LABEL_LENGTH]; + unsigned int padding[117]; + unsigned int badpages[1]; +}; + +#endif /* _SWAPHEADER_H */ diff --git a/include/sysfs.h b/include/sysfs.h new file mode 100644 index 0000000..9e47a55 --- /dev/null +++ b/include/sysfs.h @@ -0,0 +1,68 @@ +/* + * 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; +}; + +#define UL_SYSFSCXT_EMPTY { 0, -1, NULL, NULL } + +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 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 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); +#endif /* UTIL_LINUX_SYSFS_H */ diff --git a/include/tt.h b/include/tt.h new file mode 100644 index 0000000..212150a --- /dev/null +++ b/include/tt.h @@ -0,0 +1,93 @@ +/* + * Prints table or tree. See lib/table.c for more details and example. + * + * Copyright (C) 2010 Karel Zak <kzak@redhat.com> + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + */ +#ifndef UTIL_LINUX_TT_H +#define UTIL_LINUX_TT_H + +#include "list.h" + +enum { + /* + * Global flags + */ + TT_FL_RAW = (1 << 1), + TT_FL_ASCII = (1 << 2), + TT_FL_NOHEADINGS = (1 << 3), + TT_FL_EXPORT = (1 << 4), + + /* + * Column flags + */ + TT_FL_TRUNC = (1 << 5), /* truncate fields data if necessary */ + TT_FL_TREE = (1 << 6), /* use tree "ascii art" */ + TT_FL_RIGHT = (1 << 7), /* align to the right */ + TT_FL_STRICTWIDTH = (1 << 8), /* don't reduce width if column is empty */ + TT_FL_NOEXTREMES = (1 << 9) /* ignore extreme fields when count column width*/ +}; + +struct tt { + size_t ncols; /* number of columns */ + size_t termwidth; /* terminal width */ + int flags; + int first_run; + + struct list_head tb_columns; + struct list_head tb_lines; + + const struct tt_symbols *symbols; +}; + +struct tt_column { + const char *name; /* header */ + size_t seqnum; + + size_t width; /* real column width */ + size_t width_min; /* minimal width (usually header width) */ + size_t width_max; /* maximal width */ + size_t width_avg; /* average width, used to detect extreme fields */ + double width_hint; /* hint (N < 1 is in percent of termwidth) */ + + int flags; + int is_extreme; + + struct list_head cl_columns; +}; + +struct tt_line { + struct tt *table; + char const **data; + void *userdata; + size_t data_sz; /* strlen of all data */ + + struct list_head ln_lines; /* table lines */ + + struct list_head ln_branch; /* begin of branch (head of ln_children) */ + struct list_head ln_children; + + struct tt_line *parent; +}; + +extern struct tt *tt_new_table(int flags); +extern void tt_free_table(struct tt *tb); +extern void tt_remove_lines(struct tt *tb); +extern int tt_print_table(struct tt *tb); + +extern struct tt_column *tt_define_column(struct tt *tb, const char *name, + double whint, int flags); + +extern struct tt_column *tt_get_column(struct tt *tb, size_t colnum); + +extern struct tt_line *tt_add_line(struct tt *tb, struct tt_line *parent); + +extern int tt_line_set_data(struct tt_line *ln, int colnum, const char *data); +extern int tt_line_set_userdata(struct tt_line *ln, void *data); + +extern void tt_fputs_quoted(const char *data, FILE *out); +extern void tt_fputs_nonblank(const char *data, FILE *out); + +#endif /* UTIL_LINUX_TT_H */ diff --git a/include/ttyutils.h b/include/ttyutils.h new file mode 100644 index 0000000..3c40d72 --- /dev/null +++ b/include/ttyutils.h @@ -0,0 +1,116 @@ +#ifndef UTIL_LINUX_TTYUTILS_H +#define UTIL_LINUX_TTYUTILS_H + +#include <stdlib.h> +#include <termios.h> +#include <limits.h> +#ifdef HAVE_SYS_IOCTL_H +#include <sys/ioctl.h> +#endif + +#define UL_TTY_KEEPCFLAGS (1 << 1) +#define UL_TTY_UTF8 (1 << 2) + +static inline void reset_virtual_console(struct termios *tp, int flags) +{ + /* Use defaults of <sys/ttydefaults.h> for base settings */ + tp->c_iflag |= TTYDEF_IFLAG; + tp->c_oflag |= TTYDEF_OFLAG; + tp->c_lflag |= TTYDEF_LFLAG; + + if ((flags & UL_TTY_KEEPCFLAGS) == 0) { +#ifdef CBAUD + tp->c_lflag &= ~CBAUD; +#endif + tp->c_cflag |= (B38400 | TTYDEF_CFLAG); + } + + /* Sane setting, allow eight bit characters, no carriage return delay + * the same result as `stty sane cr0 pass8' + */ + tp->c_iflag |= (BRKINT | ICRNL | IMAXBEL); + tp->c_iflag &= ~(IGNBRK | INLCR | IGNCR | IXOFF | IUCLC | IXANY | ISTRIP); + tp->c_oflag |= (OPOST | ONLCR | NL0 | CR0 | TAB0 | BS0 | VT0 | FF0); + tp->c_oflag &= ~(OLCUC | OCRNL | ONOCR | ONLRET | OFILL | \ + NLDLY|CRDLY|TABDLY|BSDLY|VTDLY|FFDLY); + tp->c_lflag |= (ISIG | ICANON | IEXTEN | ECHO|ECHOE|ECHOK|ECHOKE); + tp->c_lflag &= ~(ECHONL|ECHOCTL|ECHOPRT | NOFLSH | TOSTOP); + + if ((flags & UL_TTY_KEEPCFLAGS) == 0) { + tp->c_cflag |= (CREAD | CS8 | HUPCL); + tp->c_cflag &= ~(PARODD | PARENB); + } +#ifdef OFDEL + tp->c_oflag &= ~OFDEL; +#endif +#ifdef XCASE + tp->c_lflag &= ~XCASE; +#endif +#ifdef IUTF8 + if (flags & UL_TTY_UTF8) + tp->c_iflag |= IUTF8; /* Set UTF-8 input flag */ + else + tp->c_iflag &= ~IUTF8; +#endif + /* VTIME and VMIN can overlap with VEOF and VEOL since they are + * only used for non-canonical mode. We just set the at the + * beginning, so nothing bad should happen. + */ + tp->c_cc[VTIME] = 0; + tp->c_cc[VMIN] = 1; + tp->c_cc[VINTR] = CINTR; + tp->c_cc[VQUIT] = CQUIT; + tp->c_cc[VERASE] = CERASE; /* ASCII DEL (0177) */ + tp->c_cc[VKILL] = CKILL; + tp->c_cc[VEOF] = CEOF; +#ifdef VSWTC + tp->c_cc[VSWTC] = _POSIX_VDISABLE; +#elif defined(VSWTCH) + tp->c_cc[VSWTCH] = _POSIX_VDISABLE; +#endif + tp->c_cc[VSTART] = CSTART; + tp->c_cc[VSTOP] = CSTOP; + tp->c_cc[VSUSP] = CSUSP; + tp->c_cc[VEOL] = _POSIX_VDISABLE; + tp->c_cc[VREPRINT] = CREPRINT; + tp->c_cc[VDISCARD] = CDISCARD; + tp->c_cc[VWERASE] = CWERASE; + tp->c_cc[VLNEXT] = CLNEXT; + tp->c_cc[VEOL2] = _POSIX_VDISABLE; +} + +static inline int get_terminal_width(void) +{ +#ifdef TIOCGSIZE + struct ttysize t_win; +#endif +#ifdef TIOCGWINSZ + struct winsize w_win; +#endif + const char *cp; + +#ifdef TIOCGSIZE + if (ioctl (0, TIOCGSIZE, &t_win) == 0) + return t_win.ts_cols; +#endif +#ifdef TIOCGWINSZ + if (ioctl (0, TIOCGWINSZ, &w_win) == 0) + return w_win.ws_col; +#endif + cp = getenv("COLUMNS"); + if (cp) { + char *end = NULL; + long c; + + errno = 0; + c = strtol(cp, &end, 10); + + if (errno == 0 && end && *end == '\0' && end > cp && + c > 0 && c <= INT_MAX) + return c; + } + return 0; +} + + +#endif /* UTIL_LINUX_TTYUTILS_H */ diff --git a/include/usleep.h b/include/usleep.h new file mode 100644 index 0000000..f64477c --- /dev/null +++ b/include/usleep.h @@ -0,0 +1,18 @@ +#ifndef UTIL_LINUX_USLEEP_H +#define UTIL_LINUX_USLEEP_H + +#ifndef HAVE_USLEEP +/* + * This function is marked obsolete in POSIX.1-2001 and removed in + * POSIX.1-2008. It is replaced with nanosleep(). + */ +# define usleep(x) \ + do { \ + struct timespec xsleep; \ + xsleep.tv_sec = x / 1000 / 1000; \ + xsleep.tv_nsec = (x - xsleep.tv_sec * 1000 * 1000) * 1000; \ + nanosleep(&xsleep, NULL); \ + } while (0) +#endif + +#endif /* UTIL_LINUX_USLEEP_H */ diff --git a/include/wholedisk.h b/include/wholedisk.h new file mode 100644 index 0000000..251479e --- /dev/null +++ b/include/wholedisk.h @@ -0,0 +1,8 @@ +#ifndef WHOLEDISK_H +#define WHOLEDISK_H + +extern int is_whole_disk(const char *name); +extern int is_whole_disk_fd(int fd, const char *name); + +#endif /* WHOLEDISK_H */ + diff --git a/include/widechar.h b/include/widechar.h new file mode 100644 index 0000000..b023b5f --- /dev/null +++ b/include/widechar.h @@ -0,0 +1,38 @@ +/* Declarations for wide characters */ +/* This file must be included last because the redefinition of wchar_t may + cause conflicts when system include files were included after it. */ + +#ifdef HAVE_WIDECHAR + +# include <wchar.h> +# include <wctype.h> + +#else /* !HAVE_WIDECHAR */ + +# include <ctype.h> + /* Fallback for types */ +# define wchar_t char +# define wint_t int +# define WEOF EOF + /* Fallback for input operations */ +# define fgetwc fgetc +# define getwc getc +# define getwchar getchar +# define fgetws fgets + /* Fallback for output operations */ +# define fputwc fputc +# define putwc putc +# define putwchar putchar +# define fputws fputs + /* Fallback for character classification */ +# define iswgraph isgraph +# define iswprint isprint +# define iswspace isspace + /* Fallback for string functions */ +# define wcschr strchr +# define wcsdup strdup +# define wcslen strlen + +# define wcwidth(c) 1 + +#endif /* HAVE_WIDECHAR */ diff --git a/include/xalloc.h b/include/xalloc.h new file mode 100644 index 0000000..1704259 --- /dev/null +++ b/include/xalloc.h @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2010 Davidlohr Bueso <dave@gnu.org> + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + * + * General memory allocation wrappers for malloc, realloc, calloc and strdup + */ + +#ifndef UTIL_LINUX_XALLOC_H +#define UTIL_LINUX_XALLOC_H + +#include <stdlib.h> +#include <string.h> + +#include "c.h" + +#ifndef XALLOC_EXIT_CODE +# define XALLOC_EXIT_CODE EXIT_FAILURE +#endif + +static inline __ul_alloc_size(1) +void *xmalloc(const size_t size) +{ + void *ret = malloc(size); + + if (!ret && size) + err(XALLOC_EXIT_CODE, "cannot allocate %zu bytes", size); + return ret; +} + +static inline __ul_alloc_size(2) +void *xrealloc(void *ptr, const size_t size) +{ + void *ret = realloc(ptr, size); + + if (!ret && size) + err(XALLOC_EXIT_CODE, "cannot allocate %zu bytes", size); + return ret; +} + +static inline __ul_calloc_size(1, 2) +void *xcalloc(const size_t nelems, const size_t size) +{ + void *ret = calloc(nelems, size); + + if (!ret && size && nelems) + err(XALLOC_EXIT_CODE, "cannot allocate %zu bytes", size); + return ret; +} + +static inline char *xstrdup(const char *str) +{ + char *ret; + + if (!str) + return NULL; + + ret = strdup(str); + + if (!ret) + err(XALLOC_EXIT_CODE, "cannot duplicate string"); + return ret; +} + +static inline int __attribute__ ((__format__(printf, 2, 3))) + xasprintf(char **strp, const char *fmt, ...) +{ + int ret; + va_list args; + va_start(args, fmt); + ret = vasprintf(&(*strp), fmt, args); + va_end(args); + if (ret < 0) + err(XALLOC_EXIT_CODE, "cannot allocate string"); + return ret; +} +#endif diff --git a/include/xgetpass.h b/include/xgetpass.h new file mode 100644 index 0000000..b5a3c87 --- /dev/null +++ b/include/xgetpass.h @@ -0,0 +1,6 @@ +#ifndef UTIL_LINUX_XGETPASS_H +#define UTIL_LINUX_XGETPASS_H + +extern char *xgetpass(int pfd, const char *prompt); + +#endif /* UTIL_LINUX_XGETPASS_H */ |