Update blkid to 2.25.0
Break libblkid into 4 libraries: libblkid, libuuid, libutil-linux and libfdisk. This should help in later patch updates. Change-Id: I680d9a7feb031e5c29a603e9c58aff4b65826262
This commit is contained in:
+2
-1
@@ -34,8 +34,9 @@ LOCAL_SRC_FILES := \
|
||||
twrp.cpp \
|
||||
fixPermissions.cpp \
|
||||
twrpTar.cpp \
|
||||
twrpDU.cpp \
|
||||
twrpDU.cpp \
|
||||
twrpDigest.cpp \
|
||||
digest/md5.c \
|
||||
find_file.cpp \
|
||||
infomanager.cpp
|
||||
|
||||
|
||||
+186
-4
@@ -2,12 +2,194 @@ LOCAL_PATH := $(call my-dir)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_MODULE := libutil-linux
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
#LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/sbin
|
||||
LOCAL_CFLAGS = -D_FILE_OFFSET_BITS=64 -DHAVE_LOFF_T -DHAVE_ERR_H -DHAVE_MEMPCPY -DHAVE_FSYNC
|
||||
LOCAL_SRC_FILES = lib/at.c \
|
||||
lib/blkdev.c \
|
||||
lib/canonicalize.c \
|
||||
lib/colors.c \
|
||||
lib/crc32.c \
|
||||
lib/crc64.c \
|
||||
lib/env.c \
|
||||
lib/exec_shell.c \
|
||||
lib/fileutils.c \
|
||||
lib/ismounted.c \
|
||||
lib/langinfo.c \
|
||||
lib/linux_version.c \
|
||||
lib/loopdev.c \
|
||||
lib/mangle.c \
|
||||
lib/match.c \
|
||||
lib/mbsalign.c \
|
||||
lib/md5.c \
|
||||
lib/pager.c \
|
||||
lib/path.c \
|
||||
lib/procutils.c \
|
||||
lib/randutils.c \
|
||||
lib/setproctitle.c \
|
||||
lib/strutils.c \
|
||||
lib/sysfs.c \
|
||||
|
||||
LOCAL_C_INCLUDES += $(LOCAL_PATH)/libfdisk/src \
|
||||
$(LOCAL_PATH)/include \
|
||||
$(LOCAL_PATH)/libuuid/src \
|
||||
$(LOCAL_PATH)/src
|
||||
|
||||
LOCAL_SHARED_LIBRARIES += libc
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_MODULE := libuuid
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
#LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/sbin
|
||||
LOCAL_CFLAGS = -D_FILE_OFFSET_BITS=64 -DHAVE_LOFF_T -DHAVE_ERR_H -DHAVE_MEMPCPY -DHAVE_FSYNC
|
||||
LOCAL_SRC_FILES = libuuid/src/clear.c \
|
||||
libuuid/src/copy.c \
|
||||
libuuid/src/isnull.c \
|
||||
libuuid/src/parse.c \
|
||||
libuuid/src/unpack.c \
|
||||
libuuid/src/uuid_time.c \
|
||||
libuuid/src/compare.c \
|
||||
libuuid/src/gen_uuid.c \
|
||||
libuuid/src/pack.c \
|
||||
libuuid/src/test_uuid.c \
|
||||
libuuid/src/unparse.c
|
||||
|
||||
LOCAL_C_INCLUDES += $(LOCAL_PATH)/libuuid/src \
|
||||
$(LOCAL_PATH)/include \
|
||||
$(LOCAL_PATH)/src
|
||||
|
||||
LOCAL_SHARED_LIBRARIES += libc libutil-linux
|
||||
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_MODULE := libfdisk
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
#LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/sbin
|
||||
LOCAL_CFLAGS = -D_FILE_OFFSET_BITS=64 -DHAVE_LOFF_T -DHAVE_ERR_H -DHAVE_MEMPCPY -DHAVE_FSYNC
|
||||
LOCAL_SRC_FILES = libfdisk/src/alignment.c \
|
||||
libfdisk/src/context.c \
|
||||
libfdisk/src/init.c \
|
||||
libfdisk/src/partition.c \
|
||||
libfdisk/src/sgi.c \
|
||||
libfdisk/src/test.c \
|
||||
libfdisk/src/ask.c \
|
||||
libfdisk/src/dos.c \
|
||||
libfdisk/src/iter.c \
|
||||
libfdisk/src/parttype.c \
|
||||
libfdisk/src/sun.c \
|
||||
libfdisk/src/utils.c \
|
||||
libfdisk/src/bsd.c \
|
||||
libfdisk/src/gpt.c \
|
||||
libfdisk/src/label.c \
|
||||
libfdisk/src/script.c \
|
||||
libfdisk/src/table.c
|
||||
|
||||
LOCAL_C_INCLUDES += $(LOCAL_PATH)/libfdisk/src \
|
||||
$(LOCAL_PATH)/include \
|
||||
$(LOCAL_PATH)/libuuid/src \
|
||||
$(LOCAL_PATH)/src
|
||||
|
||||
LOCAL_SHARED_LIBRARIES += libc libutil-linux libuuid
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_MODULE := libblkid
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
#LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/sbin
|
||||
LOCAL_CFLAGS = -D_FILE_OFFSET_BITS=64 -DHAVE_LOFF_T
|
||||
LOCAL_SRC_FILES = aix.c at.c befs.c bfs.c blkdev.c bsd.c btrfs.c cache.c canonicalize.c colors.c config.c cramfs.c crc32.c ddf_raid.c dev.c devname.c devno.c dm.c dos.c drbd.c drbdproxy_datalog.c encode.c env.c evaluate.c evms.c exec_shell.c exfat.c ext.c f2fs.c fileutils.c getsize.c gfs.c gpt.c hfs.c highpoint_raid.c hpfs.c ioctl.c ismounted.c iso9660.c isw_raid.c jfs.c jmicron_raid.c langinfo.c linux_raid.c linux_version.c llseek.c loopdev.c lsi_raid.c luks.c lvm1.c lvm2.c mac.c mangle.c match.c mbsalign.c md5.c md.c minix1.c minix2.c netware.c nilfs.c ntfs.c nvidia_raid.c ocfs.c pager.c partitions.c path.c probe.c procutils.c promise_raid.c randutils.c read.c reiserfs.c resolve.c romfs.c save.c setproctitle.c sgi.c silicon_raid.c solaris_x86.c squashfs.c sun.c superblocks.c swap.c sysfs1.c sysfs2.c sysv.c tag.c topology.c ubifs.c udf.c ufs.c ultrix.c unixware.c verify.c version.c vfat.c via_raid.c vmfs.c vxfs.c wholedisk.c xfs.c zfs.c adaptec_raid.c
|
||||
LOCAL_C_INCLUDES += $(LOCAL_PATH) \
|
||||
LOCAL_SHARED_LIBRARIES += libc
|
||||
LOCAL_CFLAGS = -D_FILE_OFFSET_BITS=64 -DHAVE_LOFF_T -DHAVE_ERR_H -DHAVE_MEMPCPY -DHAVE_FSYNC
|
||||
LOCAL_SRC_FILES = src/cache.c \
|
||||
src/config.c \
|
||||
src/dev.c \
|
||||
src/devname.c \
|
||||
src/devno.c \
|
||||
src/encode.c \
|
||||
src/evaluate.c \
|
||||
src/getsize.c \
|
||||
src/init.c \
|
||||
src/llseek.c \
|
||||
src/probe.c \
|
||||
src/read.c \
|
||||
src/resolve.c \
|
||||
src/save.c \
|
||||
src/tag.c \
|
||||
src/verify.c \
|
||||
src/version.c \
|
||||
src/partitions/aix.c \
|
||||
src/partitions/bsd.c \
|
||||
src/partitions/dos.c \
|
||||
src/partitions/gpt.c \
|
||||
src/partitions/mac.c \
|
||||
src/partitions/minix.c \
|
||||
src/partitions/partitions.c \
|
||||
src/partitions/sgi.c \
|
||||
src/partitions/solaris_x86.c \
|
||||
src/partitions/sun.c \
|
||||
src/partitions/ultrix.c \
|
||||
src/partitions/unixware.c \
|
||||
src/superblocks/adaptec_raid.c \
|
||||
src/superblocks/bcache.c \
|
||||
src/superblocks/befs.c \
|
||||
src/superblocks/bfs.c \
|
||||
src/superblocks/btrfs.c \
|
||||
src/superblocks/cramfs.c \
|
||||
src/superblocks/ddf_raid.c \
|
||||
src/superblocks/drbd.c \
|
||||
src/superblocks/drbdproxy_datalog.c \
|
||||
src/superblocks/exfat.c \
|
||||
src/superblocks/ext.c \
|
||||
src/superblocks/f2fs.c \
|
||||
src/superblocks/gfs.c \
|
||||
src/superblocks/hfs.c \
|
||||
src/superblocks/highpoint_raid.c \
|
||||
src/superblocks/hpfs.c \
|
||||
src/superblocks/iso9660.c \
|
||||
src/superblocks/isw_raid.c \
|
||||
src/superblocks/jfs.c \
|
||||
src/superblocks/jmicron_raid.c \
|
||||
src/superblocks/linux_raid.c \
|
||||
src/superblocks/lsi_raid.c \
|
||||
src/superblocks/luks.c \
|
||||
src/superblocks/lvm.c \
|
||||
src/superblocks/minix.c \
|
||||
src/superblocks/netware.c \
|
||||
src/superblocks/nilfs.c \
|
||||
src/superblocks/ntfs.c \
|
||||
src/superblocks/nvidia_raid.c \
|
||||
src/superblocks/ocfs.c \
|
||||
src/superblocks/promise_raid.c \
|
||||
src/superblocks/refs.c \
|
||||
src/superblocks/reiserfs.c \
|
||||
src/superblocks/romfs.c \
|
||||
src/superblocks/silicon_raid.c \
|
||||
src/superblocks/squashfs.c \
|
||||
src/superblocks/superblocks.c \
|
||||
src/superblocks/swap.c \
|
||||
src/superblocks/sysv.c \
|
||||
src/superblocks/ubifs.c \
|
||||
src/superblocks/udf.c \
|
||||
src/superblocks/ufs.c \
|
||||
src/superblocks/vfat.c \
|
||||
src/superblocks/via_raid.c \
|
||||
src/superblocks/vmfs.c \
|
||||
src/superblocks/vxfs.c \
|
||||
src/superblocks/xfs.c \
|
||||
src/superblocks/zfs.c \
|
||||
src/topology/dm.c \
|
||||
src/topology/evms.c \
|
||||
src/topology/ioctl.c \
|
||||
src/topology/lvm.c \
|
||||
src/topology/md.c \
|
||||
src/topology/sysfs.c \
|
||||
src/topology/topology.c \
|
||||
|
||||
LOCAL_C_INCLUDES += $(LOCAL_PATH)/include \
|
||||
$(LOCAL_PATH)/src
|
||||
|
||||
LOCAL_SHARED_LIBRARIES += libc libfdisk libutil-linux
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
This 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.
|
||||
|
||||
The complete text of the license is available in the
|
||||
../Documentation/licenses/COPYING.LGPLv2.1 file.
|
||||
@@ -0,0 +1,16 @@
|
||||
if BUILD_LIBBLKID
|
||||
|
||||
include libblkid/src/Makemodule.am
|
||||
include libblkid/samples/Makemodule.am
|
||||
|
||||
if ENABLE_GTK_DOC
|
||||
# Docs uses separate Makefiles
|
||||
SUBDIRS += libblkid/docs
|
||||
endif
|
||||
|
||||
pkgconfig_DATA += libblkid/blkid.pc
|
||||
PATHFILES += libblkid/blkid.pc
|
||||
dist_man_MANS += libblkid/libblkid.3
|
||||
EXTRA_DIST += libblkid/libblkid.3 libblkid/COPYING
|
||||
|
||||
endif # BUILD_LIBBLKID
|
||||
@@ -0,0 +1,11 @@
|
||||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
libdir=@usrlib_execdir@
|
||||
includedir=@includedir@
|
||||
|
||||
Name: blkid
|
||||
Description: Block device id library
|
||||
Version: @LIBBLKID_VERSION@
|
||||
Requires.private: uuid
|
||||
Cflags: -I${includedir}/blkid
|
||||
Libs: -L${libdir} -lblkid
|
||||
@@ -1,121 +0,0 @@
|
||||
/*
|
||||
* Partition types
|
||||
*
|
||||
* This 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.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/* Note, _L32M means <32M (less), for example FAT16_L32M */
|
||||
|
||||
enum {
|
||||
BLKID_EMPTY_PARTITION = 0x00,
|
||||
BLKID_FAT12_PARTITION = 0x01,
|
||||
BLKID_XENIX_ROOT_PARTITION = 0x02,
|
||||
BLKID_XENIX_USR_PARTITION = 0x03,
|
||||
BLKID_FAT16_LESS32M_PARTITION = 0x04,
|
||||
BLKID_DOS_EXTENDED_PARTITION = 0x05,
|
||||
BLKID_FAT16_PARTITION = 0x06, /* DOS 16-bit >=32M */
|
||||
BLKID_HPFS_NTFS_PARTITION = 0x07, /* OS/2 IFS, eg, HPFS or NTFS or QNX */
|
||||
BLKID_AIX_PARTITION = 0x08, /* AIX boot (AIX -- PS/2 port) or SplitDrive */
|
||||
BLKID_AIX_BOOTABLE_PARTITION = 0x09, /* AIX data or Coherent */
|
||||
BLKID_OS2_BOOTMNGR_PARTITION = 0x0a, /* OS/2 Boot Manager */
|
||||
BLKID_W95_FAT32_PARTITION = 0x0b,
|
||||
BLKID_W95_FAT32_LBA_PARTITION = 0x0c, /* LBA really is `Extended Int 13h' */
|
||||
BLKID_W95_FAT16_LBA_PARTITION = 0x0e,
|
||||
BLKID_W95_EXTENDED_PARTITION = 0x0f,
|
||||
BLKID_OPUS_PARTITION = 0x10,
|
||||
BLKID_HIDDEN_FAT12_PARTITION = 0x11,
|
||||
BLKID_COMPAQ_DIAGNOSTICS_PARTITION = 0x12,
|
||||
BLKID_HIDDEN_FAT16_L32M_PARTITION = 0x14,
|
||||
BLKID_HIDDEN_FAT16_PARTITION = 0x16,
|
||||
BLKID_HIDDEN_HPFS_NTFS_PARTITION = 0x17,
|
||||
BLKID_AST_SMARTSLEEP_PARTITION = 0x18,
|
||||
BLKID_HIDDEN_W95_FAT32_PARTITION = 0x1b,
|
||||
BLKID_HIDDEN_W95_FAT32LBA_PARTITION = 0x1c,
|
||||
BLKID_HIDDEN_W95_FAT16LBA_PARTITION = 0x1e,
|
||||
BLKID_NEC_DOS_PARTITION = 0x24,
|
||||
BLKID_PLAN9_PARTITION = 0x39,
|
||||
BLKID_PARTITIONMAGIC_PARTITION = 0x3c,
|
||||
BLKID_VENIX80286_PARTITION = 0x40,
|
||||
BLKID_PPC_PREP_BOOT_PARTITION = 0x41,
|
||||
BLKID_SFS_PARTITION = 0x42,
|
||||
BLKID_QNX_4X_PARTITION = 0x4d,
|
||||
BLKID_QNX_4X_2ND_PARTITION = 0x4e,
|
||||
BLKID_QNX_4X_3RD_PARTITION = 0x4f,
|
||||
BLKID_DM_PARTITION = 0x50,
|
||||
BLKID_DM6_AUX1_PARTITION = 0x51, /* (or Novell) */
|
||||
BLKID_CPM_PARTITION = 0x52, /* CP/M or Microport SysV/AT */
|
||||
BLKID_DM6_AUX3_PARTITION = 0x53,
|
||||
BLKID_DM6_PARTITION = 0x54,
|
||||
BLKID_EZ_DRIVE_PARTITION = 0x55,
|
||||
BLKID_GOLDEN_BOW_PARTITION = 0x56,
|
||||
BLKID_PRIAM_EDISK_PARTITION = 0x5c,
|
||||
BLKID_SPEEDSTOR_PARTITION = 0x61,
|
||||
BLKID_GNU_HURD_PARTITION = 0x63, /* GNU HURD or Mach or Sys V/386 (such as ISC UNIX) */
|
||||
BLKID_UNIXWARE_PARTITION = BLKID_GNU_HURD_PARTITION,
|
||||
BLKID_NETWARE_286_PARTITION = 0x64,
|
||||
BLKID_NETWARE_386_PARTITION = 0x65,
|
||||
BLKID_DISKSECURE_MULTIBOOT_PARTITION = 0x70,
|
||||
BLKID_PC_IX_PARTITION = 0x75,
|
||||
BLKID_OLD_MINIX_PARTITION = 0x80, /* Minix 1.4a and earlier */
|
||||
BLKID_MINIX_PARTITION = 0x81, /* Minix 1.4b and later */
|
||||
BLKID_LINUX_SWAP_PARTITION = 0x82,
|
||||
BLKID_SOLARIS_X86_PARTITION = BLKID_LINUX_SWAP_PARTITION,
|
||||
BLKID_LINUX_DATA_PARTITION = 0x83,
|
||||
BLKID_OS2_HIDDEN_DRIVE_PARTITION = 0x84,
|
||||
BLKID_LINUX_EXTENDED_PARTITION = 0x85,
|
||||
BLKID_NTFS_VOL_SET1_PARTITION = 0x86,
|
||||
BLKID_NTFS_VOL_SET2_PARTITION = 0x87,
|
||||
BLKID_LINUX_PLAINTEXT_PARTITION = 0x88,
|
||||
BLKID_LINUX_LVM_PARTITION = 0x8e,
|
||||
BLKID_AMOEBA_PARTITION = 0x93,
|
||||
BLKID_AMOEBA_BBT_PARTITION = 0x94, /* (bad block table) */
|
||||
BLKID_BSD_OS_PARTITION = 0x9f, /* BSDI */
|
||||
BLKID_THINKPAD_HIBERNATION_PARTITION = 0xa0,
|
||||
BLKID_FREEBSD_PARTITION = 0xa5, /* various BSD flavours */
|
||||
BLKID_OPENBSD_PARTITION = 0xa6,
|
||||
BLKID_NEXTSTEP_PARTITION = 0xa7,
|
||||
BLKID_DARWIN_UFS_PARTITION = 0xa8,
|
||||
BLKID_NETBSD_PARTITION = 0xa9,
|
||||
BLKID_DARWIN_BOOT_PARTITION = 0xab,
|
||||
BLKID_HFS_HFS_PARTITION = 0xaf,
|
||||
BLKID_BSDI_FS_PARTITION = 0xb7,
|
||||
BLKID_BSDI_SWAP_PARTITION = 0xb8,
|
||||
BLKID_BOOTWIZARD_HIDDEN_PARTITION = 0xbb,
|
||||
BLKID_SOLARIS_BOOT_PARTITION = 0xbe,
|
||||
BLKID_SOLARIS_PARTITION = 0xbf,
|
||||
BLKID_DRDOS_FAT12_PARTITION = 0xc1,
|
||||
BLKID_DRDOS_FAT16_L32M_PARTITION = 0xc4,
|
||||
BLKID_DRDOS_FAT16_PARTITION = 0xc6,
|
||||
BLKID_SYRINX_PARTITION = 0xc7,
|
||||
BLKID_NONFS_DATA_PARTITION = 0xda,
|
||||
BLKID_CPM_CTOS_PARTITION = 0xdb, /* CP/M or Concurrent CP/M or Concurrent DOS or CTOS */
|
||||
BLKID_DELL_UTILITY_PARTITION = 0xde, /* Dell PowerEdge Server utilities */
|
||||
BLKID_BOOTIT_PARTITION = 0xdf, /* BootIt EMBRM */
|
||||
BLKID_DOS_ACCESS_PARTITION = 0xe1, /* DOS access or SpeedStor 12-bit FAT extended partition */
|
||||
BLKID_DOS_RO_PARTITION = 0xe3, /* DOS R/O or SpeedStor */
|
||||
BLKID_SPEEDSTOR_EXTENDED_PARTITION = 0xe4, /* SpeedStor 16-bit FAT extended partition < 1024 cyl. */
|
||||
BLKID_BEOS_FS_PARTITION = 0xeb,
|
||||
BLKID_GPT_PARTITION = 0xee, /* Intel EFI GUID Partition Table */
|
||||
BLKID_EFI_SYSTEM_PARTITION = 0xef, /* Intel EFI System Partition */
|
||||
BLKID_LINUX_PARISC_BOOT_PARTITION = 0xf0, /* Linux/PA-RISC boot loader */
|
||||
BLKID_SPEEDSTOR1_PARTITION = 0xf1,
|
||||
BLKID_SPEEDSTOR2_PARTITION = 0xf4, /* SpeedStor large partition */
|
||||
BLKID_DOS_SECONDARY_PARTITION = 0xf2, /* DOS 3.3+ secondary */
|
||||
BLKID_VMWARE_VMFS_PARTITION = 0xfb,
|
||||
BLKID_VMWARE_VMKCORE_PARTITION = 0xfc, /* VMware kernel dump partition */
|
||||
BLKID_LINUX_RAID_PARTITION = 0xfd, /* New (2.2.x) raid partition with autodetect using persistent superblock */
|
||||
BLKID_LANSTEP_PARTITION = 0xfe, /* SpeedStor >1024 cyl. or LANstep */
|
||||
BLKID_XENIX_BBT_PARTITION = 0xff, /* Xenix Bad Block Table */
|
||||
};
|
||||
-243
@@ -1,243 +0,0 @@
|
||||
/*
|
||||
* BSD/OSF partition parsing code
|
||||
*
|
||||
* Copyright (C) 2009 Karel Zak <kzak@redhat.com>
|
||||
*
|
||||
* This file may be redistributed under the terms of the
|
||||
* GNU Lesser General Public License.
|
||||
*
|
||||
* Inspired by fdisk, partx, Linux kernel, libparted and openbsd header files.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "partitions.h"
|
||||
|
||||
#define BSD_MAXPARTITIONS 16
|
||||
#define BSD_FS_UNUSED 0
|
||||
|
||||
struct bsd_disklabel {
|
||||
uint32_t d_magic; /* the magic number */
|
||||
int16_t d_type; /* drive type */
|
||||
int16_t d_subtype; /* controller/d_type specific */
|
||||
char d_typename[16]; /* type name, e.g. "eagle" */
|
||||
char d_packname[16]; /* pack identifier */
|
||||
|
||||
/* disk geometry: */
|
||||
uint32_t d_secsize; /* # of bytes per sector */
|
||||
uint32_t d_nsectors; /* # of data sectors per track */
|
||||
uint32_t d_ntracks; /* # of tracks per cylinder */
|
||||
uint32_t d_ncylinders; /* # of data cylinders per unit */
|
||||
uint32_t d_secpercyl; /* # of data sectors per cylinder */
|
||||
uint32_t d_secperunit; /* # of data sectors per unit */
|
||||
|
||||
/*
|
||||
* Spares (bad sector replacements) below
|
||||
* are not counted in d_nsectors or d_secpercyl.
|
||||
* Spare sectors are assumed to be physical sectors
|
||||
* which occupy space at the end of each track and/or cylinder.
|
||||
*/
|
||||
uint16_t d_sparespertrack; /* # of spare sectors per track */
|
||||
uint16_t d_sparespercyl; /* # of spare sectors per cylinder */
|
||||
|
||||
/*
|
||||
* Alternate cylinders include maintenance, replacement,
|
||||
* configuration description areas, etc.
|
||||
*/
|
||||
uint32_t d_acylinders; /* # of alt. cylinders per unit */
|
||||
|
||||
/* hardware characteristics: */
|
||||
/*
|
||||
* d_interleave, d_trackskew and d_cylskew describe perturbations
|
||||
* in the media format used to compensate for a slow controller.
|
||||
* Interleave is physical sector interleave, set up by the formatter
|
||||
* or controller when formatting. When interleaving is in use,
|
||||
* logically adjacent sectors are not physically contiguous,
|
||||
* but instead are separated by some number of sectors.
|
||||
* It is specified as the ratio of physical sectors traversed
|
||||
* per logical sector. Thus an interleave of 1:1 implies contiguous
|
||||
* layout, while 2:1 implies that logical sector 0 is separated
|
||||
* by one sector from logical sector 1.
|
||||
* d_trackskew is the offset of sector 0 on track N
|
||||
* relative to sector 0 on track N-1 on the same cylinder.
|
||||
* Finally, d_cylskew is the offset of sector 0 on cylinder N
|
||||
* relative to sector 0 on cylinder N-1.
|
||||
*/
|
||||
uint16_t d_rpm; /* rotational speed */
|
||||
uint16_t d_interleave; /* hardware sector interleave */
|
||||
uint16_t d_trackskew; /* sector 0 skew, per track */
|
||||
uint16_t d_cylskew; /* sector 0 skew, per cylinder */
|
||||
uint32_t d_headswitch; /* head switch time, usec */
|
||||
uint32_t d_trkseek; /* track-to-track seek, usec */
|
||||
uint32_t d_flags; /* generic flags */
|
||||
uint32_t d_drivedata[5]; /* drive-type specific information */
|
||||
uint32_t d_spare[5]; /* reserved for future use */
|
||||
uint32_t d_magic2; /* the magic number (again) */
|
||||
uint16_t d_checksum; /* xor of data incl. partitions */
|
||||
|
||||
/* filesystem and partition information: */
|
||||
uint16_t d_npartitions; /* number of partitions in following */
|
||||
uint32_t d_bbsize; /* size of boot area at sn0, bytes */
|
||||
uint32_t d_sbsize; /* max size of fs superblock, bytes */
|
||||
|
||||
struct bsd_partition { /* the partition table */
|
||||
uint32_t p_size; /* number of sectors in partition */
|
||||
uint32_t p_offset; /* starting sector */
|
||||
uint32_t p_fsize; /* filesystem basic fragment size */
|
||||
uint8_t p_fstype; /* filesystem type, see below */
|
||||
uint8_t p_frag; /* filesystem fragments per block */
|
||||
uint16_t p_cpg; /* filesystem cylinders per group */
|
||||
} __attribute__((packed)) d_partitions[BSD_MAXPARTITIONS]; /* actually may be more */
|
||||
} __attribute__((packed));
|
||||
|
||||
|
||||
/* Returns 'blkid_idmag' in 512-sectors */
|
||||
#define BLKID_MAG_SECTOR(_mag) (((_mag)->kboff * 2) + ((_mag)->sboff >> 9))
|
||||
|
||||
/* Returns 'blkid_idmag' in bytes */
|
||||
#define BLKID_MAG_OFFSET(_mag) ((_mag)->kboff >> 10) + ((_mag)->sboff)
|
||||
|
||||
/* Returns 'blkid_idmag' offset in bytes within the last sector */
|
||||
#define BLKID_MAG_LASTOFFSET(_mag) \
|
||||
(BLKID_MAG_OFFSET(_mag) - (BLKID_MAG_SECTOR(_mag) << 9))
|
||||
|
||||
static int probe_bsd_pt(blkid_probe pr, const struct blkid_idmag *mag)
|
||||
{
|
||||
struct bsd_disklabel *l;
|
||||
struct bsd_partition *p;
|
||||
const char *name = "bsd" ;
|
||||
blkid_parttable tab = NULL;
|
||||
blkid_partition parent;
|
||||
blkid_partlist ls;
|
||||
int i, nparts = BSD_MAXPARTITIONS;
|
||||
unsigned char *data;
|
||||
|
||||
if (blkid_partitions_need_typeonly(pr))
|
||||
/* caller does not ask for details about partitions */
|
||||
return 0;
|
||||
|
||||
data = blkid_probe_get_sector(pr, BLKID_MAG_SECTOR(mag));
|
||||
if (!data)
|
||||
goto nothing;
|
||||
|
||||
l = (struct bsd_disklabel *) data + BLKID_MAG_LASTOFFSET(mag);
|
||||
|
||||
ls = blkid_probe_get_partlist(pr);
|
||||
if (!ls)
|
||||
goto err;
|
||||
|
||||
/* try to determine the real type of BSD system according to
|
||||
* (parental) primary partition */
|
||||
parent = blkid_partlist_get_parent(ls);
|
||||
if (parent) {
|
||||
switch(blkid_partition_get_type(parent)) {
|
||||
case BLKID_FREEBSD_PARTITION:
|
||||
name = "freebsd";
|
||||
break;
|
||||
case BLKID_NETBSD_PARTITION:
|
||||
name = "netbsd";
|
||||
break;
|
||||
case BLKID_OPENBSD_PARTITION:
|
||||
name = "openbsd";
|
||||
break;
|
||||
default:
|
||||
DBG(DEBUG_LOWPROBE, printf(
|
||||
"WARNING: BSD label detected on unknown (0x%x) "
|
||||
"primary partition\n",
|
||||
blkid_partition_get_type(parent)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
tab = blkid_partlist_new_parttable(ls, name, BLKID_MAG_OFFSET(mag));
|
||||
if (!tab)
|
||||
goto err;
|
||||
|
||||
if (le16_to_cpu(l->d_npartitions) < BSD_MAXPARTITIONS)
|
||||
nparts = le16_to_cpu(l->d_npartitions);
|
||||
|
||||
else if (le16_to_cpu(l->d_npartitions) > BSD_MAXPARTITIONS)
|
||||
DBG(DEBUG_LOWPROBE, printf(
|
||||
"WARNING: ignore %d more BSD partitions\n",
|
||||
le16_to_cpu(l->d_npartitions) - BSD_MAXPARTITIONS));
|
||||
|
||||
for (i = 0, p = l->d_partitions; i < nparts; i++, p++) {
|
||||
blkid_partition par;
|
||||
uint32_t start, size;
|
||||
|
||||
/* TODO: in fdisk-mode returns all non-zero (p_size) partitions */
|
||||
if (p->p_fstype == BSD_FS_UNUSED)
|
||||
continue;
|
||||
|
||||
start = le32_to_cpu(p->p_offset);
|
||||
size = le32_to_cpu(p->p_size);
|
||||
|
||||
if (parent && !blkid_is_nested_dimension(parent, start, size)) {
|
||||
DBG(DEBUG_LOWPROBE, printf(
|
||||
"WARNING: BSD partition (%d) overflow "
|
||||
"detected, ignore\n", i));
|
||||
continue;
|
||||
}
|
||||
|
||||
par = blkid_partlist_add_partition(ls, tab, start, size);
|
||||
if (!par)
|
||||
goto err;
|
||||
|
||||
blkid_partition_set_type(par, p->p_fstype);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
nothing:
|
||||
return 1;
|
||||
err:
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* All BSD variants use the same magic string (little-endian),
|
||||
* and the same disklabel.
|
||||
*
|
||||
* The difference between {Free,Open,...}BSD is in the (parental)
|
||||
* primary partition type.
|
||||
*
|
||||
* See also: http://en.wikipedia.org/wiki/BSD_disklabel
|
||||
*
|
||||
* The location of BSD disk label is architecture specific and in defined by
|
||||
* LABELSECTOR and LABELOFFSET macros in the disklabel.h file. The location
|
||||
* also depends on BSD variant, FreeBSD uses only one location, NetBSD and
|
||||
* OpenBSD are more creative...
|
||||
*
|
||||
* The basic overview:
|
||||
*
|
||||
* arch | LABELSECTOR | LABELOFFSET
|
||||
* ------------------------+-------------+------------
|
||||
* amd64 arm hppa hppa64 | |
|
||||
* i386, macppc, mvmeppc | 1 | 0
|
||||
* sgi, aviion, sh, socppc | |
|
||||
* ------------------------+-------------+------------
|
||||
* alpha luna88k mac68k | 0 | 64
|
||||
* sparc(OpenBSD) vax | |
|
||||
* ------------------------+-------------+------------
|
||||
* spark64 sparc(NetBSD) | 0 | 128
|
||||
* ------------------------+-------------+------------
|
||||
*
|
||||
* ...and more (see http://fxr.watson.org/fxr/ident?v=NETBSD;i=LABELSECTOR)
|
||||
*
|
||||
*/
|
||||
const struct blkid_idinfo bsd_pt_idinfo =
|
||||
{
|
||||
.name = "bsd",
|
||||
.probefunc = probe_bsd_pt,
|
||||
.magics =
|
||||
{
|
||||
{ .magic = "\x57\x45\x56\x82", .len = 4, .sboff = 512 },
|
||||
{ .magic = "\x57\x45\x56\x82", .len = 4, .sboff = 64 },
|
||||
{ .magic = "\x57\x45\x56\x82", .len = 4, .sboff = 128 },
|
||||
{ NULL }
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,247 +0,0 @@
|
||||
/*
|
||||
* canonicalize.c -- canonicalize pathname by removing symlinks
|
||||
* Copyright (C) 1993 Rick Sladkey <jrs@world.std.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Library Public License as published by
|
||||
* the Free Software Foundation; either version 2, 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 Library Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* This routine is part of libc. We include it nevertheless,
|
||||
* since the libc version has some security flaws.
|
||||
*
|
||||
* TODO: use canonicalize_file_name() when exist in glibc
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "canonicalize.h"
|
||||
|
||||
#ifndef MAXSYMLINKS
|
||||
# define MAXSYMLINKS 256
|
||||
#endif
|
||||
|
||||
static char *
|
||||
myrealpath(const char *path, char *resolved_path, int maxreslth) {
|
||||
int readlinks = 0;
|
||||
char *npath;
|
||||
char link_path[PATH_MAX+1];
|
||||
int n;
|
||||
char *buf = NULL;
|
||||
|
||||
npath = resolved_path;
|
||||
|
||||
/* If it's a relative pathname use getcwd for starters. */
|
||||
if (*path != '/') {
|
||||
if (!getcwd(npath, maxreslth-2))
|
||||
return NULL;
|
||||
npath += strlen(npath);
|
||||
if (npath[-1] != '/')
|
||||
*npath++ = '/';
|
||||
} else {
|
||||
*npath++ = '/';
|
||||
path++;
|
||||
}
|
||||
|
||||
/* Expand each slash-separated pathname component. */
|
||||
while (*path != '\0') {
|
||||
/* Ignore stray "/" */
|
||||
if (*path == '/') {
|
||||
path++;
|
||||
continue;
|
||||
}
|
||||
if (*path == '.' && (path[1] == '\0' || path[1] == '/')) {
|
||||
/* Ignore "." */
|
||||
path++;
|
||||
continue;
|
||||
}
|
||||
if (*path == '.' && path[1] == '.' &&
|
||||
(path[2] == '\0' || path[2] == '/')) {
|
||||
/* Backup for ".." */
|
||||
path += 2;
|
||||
while (npath > resolved_path+1 &&
|
||||
(--npath)[-1] != '/')
|
||||
;
|
||||
continue;
|
||||
}
|
||||
/* Safely copy the next pathname component. */
|
||||
while (*path != '\0' && *path != '/') {
|
||||
if (npath-resolved_path > maxreslth-2) {
|
||||
errno = ENAMETOOLONG;
|
||||
goto err;
|
||||
}
|
||||
*npath++ = *path++;
|
||||
}
|
||||
|
||||
/* Protect against infinite loops. */
|
||||
if (readlinks++ > MAXSYMLINKS) {
|
||||
errno = ELOOP;
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* See if last pathname component is a symlink. */
|
||||
*npath = '\0';
|
||||
n = readlink(resolved_path, link_path, PATH_MAX);
|
||||
if (n < 0) {
|
||||
/* EINVAL means the file exists but isn't a symlink. */
|
||||
if (errno != EINVAL)
|
||||
goto err;
|
||||
} else {
|
||||
int m;
|
||||
char *newbuf;
|
||||
|
||||
/* Note: readlink doesn't add the null byte. */
|
||||
link_path[n] = '\0';
|
||||
if (*link_path == '/')
|
||||
/* Start over for an absolute symlink. */
|
||||
npath = resolved_path;
|
||||
else
|
||||
/* Otherwise back up over this component. */
|
||||
while (*(--npath) != '/')
|
||||
;
|
||||
|
||||
/* Insert symlink contents into path. */
|
||||
m = strlen(path);
|
||||
newbuf = malloc(m + n + 1);
|
||||
if (!newbuf)
|
||||
goto err;
|
||||
memcpy(newbuf, link_path, n);
|
||||
memcpy(newbuf + n, path, m + 1);
|
||||
free(buf);
|
||||
path = buf = newbuf;
|
||||
}
|
||||
*npath++ = '/';
|
||||
}
|
||||
/* Delete trailing slash but don't whomp a lone slash. */
|
||||
if (npath != resolved_path+1 && npath[-1] == '/')
|
||||
npath--;
|
||||
/* Make sure it's null terminated. */
|
||||
*npath = '\0';
|
||||
|
||||
free(buf);
|
||||
return resolved_path;
|
||||
|
||||
err:
|
||||
free(buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Converts private "dm-N" names to "/dev/mapper/<name>"
|
||||
*
|
||||
* Since 2.6.29 (patch 784aae735d9b0bba3f8b9faef4c8b30df3bf0128) kernel sysfs
|
||||
* provides the real DM device names in /sys/block/<ptname>/dm/name
|
||||
*/
|
||||
char *
|
||||
canonicalize_dm_name(const char *ptname)
|
||||
{
|
||||
FILE *f;
|
||||
size_t sz;
|
||||
char path[256], name[256], *res = NULL;
|
||||
|
||||
snprintf(path, sizeof(path), "/sys/block/%s/dm/name", ptname);
|
||||
if (!(f = fopen(path, "r")))
|
||||
return NULL;
|
||||
|
||||
/* read "<name>\n" from sysfs */
|
||||
if (fgets(name, sizeof(name), f) && (sz = strlen(name)) > 1) {
|
||||
name[sz - 1] = '\0';
|
||||
snprintf(path, sizeof(path), "/dev/mapper/%s", name);
|
||||
res = strdup(path);
|
||||
}
|
||||
fclose(f);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *
|
||||
canonicalize_path(const char *path)
|
||||
{
|
||||
char canonical[PATH_MAX+2];
|
||||
char *p;
|
||||
|
||||
if (path == NULL)
|
||||
return NULL;
|
||||
|
||||
if (!myrealpath(path, canonical, PATH_MAX+1))
|
||||
return strdup(path);
|
||||
|
||||
|
||||
p = strrchr(canonical, '/');
|
||||
if (p && strncmp(p, "/dm-", 4) == 0 && isdigit(*(p + 4))) {
|
||||
p = canonicalize_dm_name(p+1);
|
||||
if (p)
|
||||
return p;
|
||||
}
|
||||
|
||||
return strdup(canonical);
|
||||
}
|
||||
|
||||
char *
|
||||
canonicalize_path_restricted(const char *path)
|
||||
{
|
||||
char canonical[PATH_MAX+2];
|
||||
char *p = NULL;
|
||||
int errsv;
|
||||
uid_t euid;
|
||||
gid_t egid;
|
||||
|
||||
if (path == NULL)
|
||||
return NULL;
|
||||
|
||||
euid = geteuid();
|
||||
egid = getegid();
|
||||
|
||||
/* drop permissions */
|
||||
if (setegid(getgid()) < 0 || seteuid(getuid()) < 0)
|
||||
return NULL;
|
||||
|
||||
errsv = errno = 0;
|
||||
|
||||
if (myrealpath(path, canonical, PATH_MAX+1)) {
|
||||
p = strrchr(canonical, '/');
|
||||
if (p && strncmp(p, "/dm-", 4) == 0 && isdigit(*(p + 4)))
|
||||
p = canonicalize_dm_name(p+1);
|
||||
else
|
||||
p = NULL;
|
||||
if (!p)
|
||||
p = strdup(canonical);
|
||||
} else
|
||||
errsv = errno;
|
||||
|
||||
/* restore */
|
||||
if (setegid(egid) < 0 || seteuid(euid) < 0) {
|
||||
free(p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
errno = errsv;
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
#ifdef TEST_PROGRAM_CANONICALIZE
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "usage: %s <device>\n", argv[0]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
fprintf(stdout, "orig: %s\n", argv[1]);
|
||||
fprintf(stdout, "real: %s\n", canonicalize_path(argv[1]));
|
||||
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
#endif
|
||||
@@ -1,29 +0,0 @@
|
||||
#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 */
|
||||
@@ -1,28 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2012 Ondrej Oprala <ooprala@redhat.com>
|
||||
*
|
||||
* This file may be distributed under the terms of the
|
||||
* GNU Lesser General Public License.
|
||||
*/
|
||||
|
||||
#include "colors.h"
|
||||
|
||||
static int ul_color_term_ok;
|
||||
|
||||
int colors_init(void)
|
||||
{
|
||||
ul_color_term_ok = isatty(STDOUT_FILENO);
|
||||
return ul_color_term_ok;
|
||||
}
|
||||
|
||||
void color_enable(const char *color_scheme)
|
||||
{
|
||||
if (ul_color_term_ok)
|
||||
fputs(color_scheme, stdout);
|
||||
}
|
||||
|
||||
void color_disable(void)
|
||||
{
|
||||
if (ul_color_term_ok)
|
||||
fputs(UL_COLOR_RESET, stdout);
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2012 Ondrej Oprala <ooprala@redhat.com>
|
||||
*
|
||||
* This file may be distributed under the terms of the
|
||||
* GNU Lesser General Public License.
|
||||
*/
|
||||
#ifndef UTIL_LINUX_COLORS_H
|
||||
#define UTIL_LINUX_COLORS_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define UL_COLOR_RESET "\033[0m"
|
||||
#define UL_COLOR_BOLD "\033[1m"
|
||||
#define UL_COLOR_HALFBRIGHT "\033[2m"
|
||||
#define UL_COLOR_UNDERSCORE "\033[4m"
|
||||
#define UL_COLOR_BLINK "\033[5m"
|
||||
#define UL_COLOR_REVERSE "\033[7m"
|
||||
|
||||
/* Standard colors */
|
||||
#define UL_COLOR_BLACK "\033[30m"
|
||||
#define UL_COLOR_RED "\033[31m"
|
||||
#define UL_COLOR_GREEN "\033[32m"
|
||||
#define UL_COLOR_YELLOW "\033[33m"
|
||||
#define UL_COLOR_BLUE "\033[34m"
|
||||
#define UL_COLOR_MAGENTA "\033[35m"
|
||||
#define UL_COLOR_CYAN "\033[36m"
|
||||
#define UL_COLOR_GRAY "\033[37m"
|
||||
|
||||
/* Bold variants */
|
||||
#define UL_COLOR_DARK_GRAY "\033[1;30m"
|
||||
#define UL_COLOR_BOLD_RED "\033[1;31m"
|
||||
#define UL_COLOR_BOLD_GREEN "\033[1;32m"
|
||||
#define UL_COLOR_BOLD_YELLOW "\033[1;33m"
|
||||
#define UL_COLOR_BOLD_BLUE "\033[1;34m"
|
||||
#define UL_COLOR_BOLD_MAGENTA "\033[1;35m"
|
||||
#define UL_COLOR_BOLD_CYAN "\033[1;36m"
|
||||
|
||||
#define UL_COLOR_WHITE "\033[1;37m"
|
||||
|
||||
/* Initialize the global variable OUT_IS_TERM */
|
||||
extern int colors_init(void);
|
||||
|
||||
/* Set the color to CLR_SCHEME */
|
||||
extern void color_enable(const char *clr_scheme);
|
||||
|
||||
/* Reset colors to default */
|
||||
extern void color_disable(void);
|
||||
|
||||
#endif /* UTIL_LINUX_COLORS_H */
|
||||
@@ -0,0 +1,18 @@
|
||||
*-decl-list.txt
|
||||
*-decl.txt
|
||||
*-overrides.txt
|
||||
*-undeclared.txt
|
||||
*-undocumented.txt
|
||||
*-unused.txt
|
||||
*.args
|
||||
*.bak
|
||||
*.hierarchy
|
||||
*.interfaces
|
||||
*.prerequisites
|
||||
*.signals
|
||||
*.stamp
|
||||
*.types
|
||||
html/*
|
||||
tmpl/*
|
||||
version.xml
|
||||
xml/*
|
||||
@@ -0,0 +1,95 @@
|
||||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
# We require automake 1.10 at least.
|
||||
AUTOMAKE_OPTIONS = 1.10
|
||||
|
||||
# This is a blank Makefile.am for using gtk-doc.
|
||||
# Copy this to your project's API docs directory and modify the variables to
|
||||
# suit your project. See the GTK+ Makefiles in gtk+/docs/reference for examples
|
||||
# of using the various options.
|
||||
|
||||
# The name of the module, e.g. 'glib'.
|
||||
DOC_MODULE=libblkid
|
||||
|
||||
# Uncomment for versioned docs and specify the version of the module, e.g. '2'.
|
||||
#DOC_MODULE_VERSION=2
|
||||
|
||||
# The top-level SGML file. You can change this if you want to.
|
||||
DOC_MAIN_SGML_FILE=$(DOC_MODULE)-docs.xml
|
||||
|
||||
# The directory containing the source code. Relative to $(srcdir).
|
||||
# gtk-doc will search all .c & .h files beneath here for inline comments
|
||||
# documenting the functions and macros.
|
||||
# e.g. DOC_SOURCE_DIR=../../../gtk
|
||||
DOC_SOURCE_DIR=../src
|
||||
|
||||
# Extra options to pass to gtkdoc-scangobj. Not normally needed.
|
||||
SCANGOBJ_OPTIONS=
|
||||
|
||||
# Extra options to supply to gtkdoc-scan.
|
||||
# e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED"
|
||||
SCAN_OPTIONS=--deprecated-guards="BLKID_DISABLE_DEPRECATED"
|
||||
|
||||
# Extra options to supply to gtkdoc-mkdb.
|
||||
# e.g. MKDB_OPTIONS=--sgml-mode --output-format=xml
|
||||
MKDB_OPTIONS=--sgml-mode --output-format=xml --name-space blkid
|
||||
|
||||
# Extra options to supply to gtkdoc-mktmpl
|
||||
# e.g. MKTMPL_OPTIONS=--only-section-tmpl
|
||||
MKTMPL_OPTIONS=
|
||||
|
||||
# Extra options to supply to gtkdoc-mkhtml
|
||||
MKHTML_OPTIONS=
|
||||
|
||||
# Extra options to supply to gtkdoc-fixref. Not normally needed.
|
||||
# e.g. FIXXREF_OPTIONS=--extra-dir=../gdk-pixbuf/html --extra-dir=../gdk/html
|
||||
FIXXREF_OPTIONS=
|
||||
|
||||
# Used for dependencies. The docs will be rebuilt if any of these change.
|
||||
# e.g. HFILE_GLOB=$(top_srcdir)/gtk/*.h
|
||||
# e.g. CFILE_GLOB=$(top_srcdir)/gtk/*.c
|
||||
HFILE_GLOB=$(top_builddir)/libblkid/src/blkid.h
|
||||
CFILE_GLOB=$(top_srcdir)/libblkid/src/*.c
|
||||
|
||||
# Extra header to include when scanning, which are not under DOC_SOURCE_DIR
|
||||
# e.g. EXTRA_HFILES=$(top_srcdir}/contrib/extra.h
|
||||
EXTRA_HFILES=
|
||||
|
||||
# Header files to ignore when scanning. Use base file name, no paths
|
||||
# e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h
|
||||
IGNORE_HFILES=blkidP.h partitions.h superblocks.h \
|
||||
topology.h aix.h dos.h iso9660.h
|
||||
|
||||
# Images to copy into HTML directory.
|
||||
# e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png
|
||||
HTML_IMAGES=
|
||||
|
||||
# Extra SGML files that are included by $(DOC_MAIN_SGML_FILE).
|
||||
# e.g. content_files=running.sgml building.sgml changes-2.0.sgml
|
||||
content_files = $(builddir)/version.xml $(srcdir)/libblkid-config.xml
|
||||
|
||||
# SGML files where gtk-doc abbrevations (#GtkWidget) are expanded
|
||||
# These files must be listed here *and* in content_files
|
||||
# e.g. expand_content_files=running.sgml
|
||||
expand_content_files=
|
||||
|
||||
# CFLAGS and LDFLAGS for compiling gtkdoc-scangobj with your library.
|
||||
# Only needed if you are using gtkdoc-scangobj to dynamically query widget
|
||||
# signals and properties.
|
||||
# e.g. GTKDOC_CFLAGS=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS)
|
||||
# e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib)
|
||||
GTKDOC_CFLAGS=
|
||||
GTKDOC_LIBS=
|
||||
|
||||
# This includes the standard gtk-doc make rules, copied by gtkdocize.
|
||||
include $(top_srcdir)/config/gtk-doc.make
|
||||
|
||||
# Other files to distribute
|
||||
# e.g. EXTRA_DIST += version.xml.in
|
||||
EXTRA_DIST += version.xml.in $(srcdir)/libblkid-config.xml
|
||||
|
||||
# Files not to distribute
|
||||
# for --rebuild-types in $(SCAN_OPTIONS), e.g. $(DOC_MODULE).types
|
||||
# for --rebuild-sections in $(SCAN_OPTIONS) e.g. $(DOC_MODULE)-sections.txt
|
||||
DISTCLEANFILES += version.xml
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"
|
||||
[
|
||||
<!ENTITY version SYSTEM "version.xml">
|
||||
]>
|
||||
<refentry id="libblkid-config">
|
||||
<refmeta>
|
||||
<refentrytitle role="top_of_page" id="libblkid-config.top_of_page">Config file</refentrytitle>
|
||||
<manvolnum>3</manvolnum>
|
||||
<refmiscinfo>LIBBLKID Library</refmiscinfo>
|
||||
</refmeta>
|
||||
|
||||
<refnamediv>
|
||||
<refname>Config file</refname>
|
||||
<refpurpose>config file to control paths and basic library behavior</refpurpose>
|
||||
</refnamediv>
|
||||
|
||||
<refsect1 id="libblkid-config.description" role="desc">
|
||||
<title role="desc.title">Description</title>
|
||||
<para>
|
||||
The standard location of the
|
||||
/etc/blkid.conf config file can be overridden by the environment variable
|
||||
BLKID_CONF. The following options control the libblkid library:
|
||||
</para>
|
||||
|
||||
<variablelist role="params">
|
||||
<varlistentry>
|
||||
<term>SEND_UEVENT=<parameter>yes|not</parameter></term>
|
||||
<listitem><simpara>
|
||||
Sends uevent when /dev/disk/by-{label,uuid}/
|
||||
symlink does not match with LABEL or UUID on the device. Default is "yes".
|
||||
</simpara></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>CACHE_FILE=<parameter>path</parameter></term>
|
||||
<listitem><simpara>
|
||||
Overrides the standard location of the cache file. This
|
||||
setting can be overridden by the environment variable BLKID_FILE. Default is
|
||||
/etc/blkid.tab.
|
||||
</simpara></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>EVALUATE=<parameter>method</parameter></term>
|
||||
<listitem><simpara>
|
||||
Defines LABEL and UUID evaluation method(s). Currently,
|
||||
the libblkid library supports "udev" and "scan" methods. More than one methods
|
||||
may be specified in a comma separated list. Default is "udev,scan". The "udev"
|
||||
method uses udev /dev/disk/by-* symlinks and the "scan" method scans all
|
||||
block devices from the /proc/partitions file.
|
||||
</simpara></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
||||
</refsect1>
|
||||
|
||||
</refentry>
|
||||
@@ -0,0 +1,70 @@
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"
|
||||
[
|
||||
<!ENTITY version SYSTEM "version.xml">
|
||||
]>
|
||||
<book id="index" xmlns:xi="http://www.w3.org/2003/XInclude">
|
||||
<bookinfo>
|
||||
<title>libblkid Reference Manual</title>
|
||||
<releaseinfo>for libblkid version &version;</releaseinfo>
|
||||
<copyright>
|
||||
<year>2009-2013</year>
|
||||
<holder>Karel Zak <kzak@redhat.com></holder>
|
||||
</copyright>
|
||||
</bookinfo>
|
||||
|
||||
<part id="gtk">
|
||||
<title>libblkid Overview</title>
|
||||
<partintro>
|
||||
<para>
|
||||
The libblkid library is used to identify block devices (disks) as to their
|
||||
content (e.g. filesystem type, partitions) as well as extracting additional
|
||||
information such as filesystem labels/volume names, partitions, unique
|
||||
identifiers/serial numbers, etc. A common use is to allow use of LABEL= and
|
||||
UUID= tags instead of hard-coding specific block device names into
|
||||
configuration files.
|
||||
</para>
|
||||
<para>
|
||||
The libblkid librray
|
||||
was written by Andreas Dilger for the ext2 filesystem utilties, with input
|
||||
from Ted Ts'o. The library was subsequently heavily modified by Ted Ts'o.
|
||||
</para>
|
||||
<para>
|
||||
The low-level probing code, topology and partitions support was written
|
||||
by Karel Zak. Currently, the library is mainatned by Karel Zak.
|
||||
</para>
|
||||
<para>
|
||||
The library is part of the util-linux package since version 2.15 and is
|
||||
available from ftp://ftp.kernel.org/pub/linux/utils/util-linux/.
|
||||
</para>
|
||||
</partintro>
|
||||
<xi:include href="xml/libblkid-config.xml"/>
|
||||
</part>
|
||||
|
||||
<part>
|
||||
<title>High-level</title>
|
||||
<xi:include href="xml/evaluate.xml"/>
|
||||
<xi:include href="xml/cache.xml"/>
|
||||
<xi:include href="xml/search.xml"/>
|
||||
</part>
|
||||
<part>
|
||||
<title>Low-level</title>
|
||||
<xi:include href="xml/init.xml"/>
|
||||
<xi:include href="xml/lowprobe.xml"/>
|
||||
<xi:include href="xml/lowprobe-tags.xml"/>
|
||||
<xi:include href="xml/superblocks.xml"/>
|
||||
<xi:include href="xml/partitions.xml"/>
|
||||
<xi:include href="xml/topology.xml"/>
|
||||
</part>
|
||||
<part>
|
||||
<title>Common utils</title>
|
||||
<xi:include href="xml/encode.xml"/>
|
||||
<xi:include href="xml/misc.xml"/>
|
||||
</part>
|
||||
|
||||
<index id="api-index-full">
|
||||
<title>API Index</title>
|
||||
<xi:include href="xml/api-index-full.xml"><xi:fallback /></xi:include>
|
||||
</index>
|
||||
</book>
|
||||
@@ -0,0 +1,201 @@
|
||||
<SECTION>
|
||||
<FILE>evaluate</FILE>
|
||||
blkid_evaluate_tag
|
||||
blkid_evaluate_spec
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>init</FILE>
|
||||
blkid_init_debug
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>cache</FILE>
|
||||
blkid_cache
|
||||
blkid_gc_cache
|
||||
blkid_get_cache
|
||||
blkid_put_cache
|
||||
blkid_probe_all
|
||||
blkid_probe_all_removable
|
||||
blkid_probe_all_new
|
||||
blkid_verify
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>search</FILE>
|
||||
blkid_dev
|
||||
blkid_dev_devname
|
||||
blkid_dev_has_tag
|
||||
blkid_dev_iterate
|
||||
blkid_dev_iterate_begin
|
||||
blkid_dev_iterate_end
|
||||
blkid_dev_next
|
||||
blkid_dev_set_search
|
||||
blkid_find_dev_with_tag
|
||||
blkid_get_dev
|
||||
blkid_get_devname
|
||||
blkid_get_tag_value
|
||||
blkid_tag_iterate
|
||||
blkid_tag_iterate_begin
|
||||
blkid_tag_iterate_end
|
||||
blkid_tag_next
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>lowprobe</FILE>
|
||||
blkid_probe
|
||||
blkid_free_probe
|
||||
blkid_new_probe
|
||||
blkid_new_probe_from_filename
|
||||
blkid_probe_get_devno
|
||||
blkid_probe_get_fd
|
||||
blkid_probe_get_offset
|
||||
blkid_probe_get_sectors
|
||||
blkid_probe_get_sectorsize
|
||||
blkid_probe_get_size
|
||||
blkid_probe_get_wholedisk_devno
|
||||
blkid_probe_is_wholedisk
|
||||
blkid_probe_set_device
|
||||
blkid_probe_step_back
|
||||
blkid_reset_probe
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>lowprobe-tags</FILE>
|
||||
blkid_do_fullprobe
|
||||
blkid_do_wipe
|
||||
blkid_do_probe
|
||||
blkid_do_safeprobe
|
||||
<SUBSECTION>
|
||||
blkid_probe_get_value
|
||||
blkid_probe_has_value
|
||||
blkid_probe_lookup_value
|
||||
blkid_probe_numof_values
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>partitions</FILE>
|
||||
blkid_partlist
|
||||
blkid_partition
|
||||
blkid_parttable
|
||||
blkid_probe_enable_partitions
|
||||
blkid_probe_set_partitions_flags
|
||||
blkid_probe_filter_partitions_type
|
||||
blkid_probe_invert_partitions_filter
|
||||
blkid_probe_reset_partitions_filter
|
||||
<SUBSECTION>
|
||||
blkid_known_pttype
|
||||
<SUBSECTION>
|
||||
blkid_partition_get_name
|
||||
blkid_partition_get_flags
|
||||
blkid_partition_get_partno
|
||||
blkid_partition_get_size
|
||||
blkid_partition_get_start
|
||||
blkid_partition_get_table
|
||||
blkid_partition_get_type
|
||||
blkid_partition_get_type_string
|
||||
blkid_partition_get_uuid
|
||||
blkid_partition_is_extended
|
||||
blkid_partition_is_logical
|
||||
blkid_partition_is_primary
|
||||
<SUBSECTION>
|
||||
blkid_partlist_get_partition
|
||||
blkid_partlist_get_partition_by_partno
|
||||
blkid_partlist_numof_partitions
|
||||
blkid_partlist_devno_to_partition
|
||||
blkid_partlist_get_table
|
||||
<SUBSECTION>
|
||||
blkid_parttable_get_id
|
||||
blkid_parttable_get_offset
|
||||
blkid_parttable_get_parent
|
||||
blkid_parttable_get_type
|
||||
<SUBSECTION>
|
||||
blkid_probe_get_partitions
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>superblocks</FILE>
|
||||
blkid_probe_enable_superblocks
|
||||
<SUBSECTION>
|
||||
blkid_known_fstype
|
||||
blkid_superblocks_get_name
|
||||
<SUBSECTION>
|
||||
blkid_probe_filter_superblocks_type
|
||||
blkid_probe_filter_superblocks_usage
|
||||
blkid_probe_invert_superblocks_filter
|
||||
blkid_probe_reset_superblocks_filter
|
||||
blkid_probe_set_superblocks_flags
|
||||
<SUBSECTION>
|
||||
blkid_probe_reset_filter
|
||||
blkid_probe_filter_types
|
||||
blkid_probe_filter_usage
|
||||
blkid_probe_invert_filter
|
||||
blkid_probe_set_request
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>topology</FILE>
|
||||
blkid_topology
|
||||
blkid_probe_enable_topology
|
||||
<SUBSECTION>
|
||||
blkid_probe_get_topology
|
||||
blkid_topology_get_alignment_offset
|
||||
blkid_topology_get_logical_sector_size
|
||||
blkid_topology_get_minimum_io_size
|
||||
blkid_topology_get_optimal_io_size
|
||||
blkid_topology_get_physical_sector_size
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>encode</FILE>
|
||||
blkid_encode_string
|
||||
blkid_safe_string
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>misc</FILE>
|
||||
blkid_loff_t
|
||||
blkid_devno_to_devname
|
||||
blkid_devno_to_wholedisk
|
||||
blkid_get_dev_size
|
||||
blkid_get_library_version
|
||||
blkid_parse_tag_string
|
||||
blkid_parse_version_string
|
||||
blkid_send_uevent
|
||||
BLKID_VERSION
|
||||
BLKID_DATE
|
||||
BLKID_FLTR_NOTIN
|
||||
BLKID_FLTR_ONLYIN
|
||||
BLKID_DEV_CREATE
|
||||
BLKID_DEV_FIND
|
||||
BLKID_DEV_NORMAL
|
||||
BLKID_DEV_VERIFY
|
||||
BLKID_PARTS_ENTRY_DETAILS
|
||||
BLKID_PARTS_FORCE_GPT
|
||||
BLKID_PARTS_MAGIC
|
||||
BLKID_PROBREQ_LABEL
|
||||
BLKID_PROBREQ_LABELRAW
|
||||
BLKID_PROBREQ_SECTYPE
|
||||
BLKID_PROBREQ_TYPE
|
||||
BLKID_PROBREQ_USAGE
|
||||
BLKID_PROBREQ_UUID
|
||||
BLKID_PROBREQ_UUIDRAW
|
||||
BLKID_PROBREQ_VERSION
|
||||
BLKID_SUBLKS_BADCSUM
|
||||
BLKID_SUBLKS_DEFAULT
|
||||
BLKID_SUBLKS_LABEL
|
||||
BLKID_SUBLKS_LABELRAW
|
||||
BLKID_SUBLKS_MAGIC
|
||||
BLKID_SUBLKS_SECTYPE
|
||||
BLKID_SUBLKS_TYPE
|
||||
BLKID_SUBLKS_USAGE
|
||||
BLKID_SUBLKS_UUID
|
||||
BLKID_SUBLKS_UUIDRAW
|
||||
BLKID_SUBLKS_VERSION
|
||||
BLKID_USAGE_CRYPTO
|
||||
BLKID_USAGE_FILESYSTEM
|
||||
BLKID_USAGE_OTHER
|
||||
BLKID_USAGE_RAID
|
||||
</SECTION>
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
@VERSION@
|
||||
@@ -1,41 +0,0 @@
|
||||
#ifndef BLKID_PARTITIONS_DOS_H
|
||||
#define BLKID_PARTITIONS_DOS_H
|
||||
|
||||
struct dos_partition {
|
||||
unsigned char boot_ind; /* 0x80 - active */
|
||||
unsigned char bh, bs, bc; /* begin CHS */
|
||||
unsigned char sys_type;
|
||||
unsigned char eh, es, ec; /* end CHS */
|
||||
unsigned char start_sect[4];
|
||||
unsigned char nr_sects[4];
|
||||
} __attribute__((packed));
|
||||
|
||||
#define BLKID_MSDOS_PT_OFFSET 0x1be
|
||||
|
||||
/* assemble badly aligned little endian integer */
|
||||
static inline unsigned int assemble4le(const unsigned char *p)
|
||||
{
|
||||
return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
|
||||
}
|
||||
|
||||
static inline unsigned int dos_partition_start(struct dos_partition *p)
|
||||
{
|
||||
return assemble4le(&(p->start_sect[0]));
|
||||
}
|
||||
|
||||
static inline unsigned int dos_partition_size(struct dos_partition *p)
|
||||
{
|
||||
return assemble4le(&(p->nr_sects[0]));
|
||||
}
|
||||
|
||||
static inline int is_valid_mbr_signature(const unsigned char *mbr)
|
||||
{
|
||||
return mbr[510] == 0x55 && mbr[511] == 0xaa ? 1 : 0;
|
||||
}
|
||||
|
||||
static inline unsigned int dos_parttable_id(const unsigned char *mbr)
|
||||
{
|
||||
return assemble4le(&mbr[440]);
|
||||
}
|
||||
|
||||
#endif /* BLKID_PARTITIONS_DOS_H */
|
||||
@@ -1,27 +0,0 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "nls.h"
|
||||
#include "c.h"
|
||||
#include "xalloc.h"
|
||||
|
||||
#include "exec_shell.h"
|
||||
|
||||
#define DEFAULT_SHELL "/bin/sh"
|
||||
|
||||
void __attribute__((__noreturn__)) exec_shell(void) {
|
||||
const char *shell = getenv("SHELL"), *shell_basename;
|
||||
char *arg0;
|
||||
if (!shell)
|
||||
shell = DEFAULT_SHELL;
|
||||
|
||||
shell_basename = basename(shell);
|
||||
arg0 = xmalloc(strlen(shell_basename) + 2);
|
||||
arg0[0] = '-';
|
||||
strcpy(arg0 + 1, shell_basename);
|
||||
|
||||
execl(shell, arg0, NULL);
|
||||
err(EXIT_FAILURE, _("failed to execute %s"), shell);
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
|
||||
dist_noinst_HEADERS += \
|
||||
include/all-io.h \
|
||||
include/at.h \
|
||||
include/bitops.h \
|
||||
include/blkdev.h \
|
||||
include/monotonic.h \
|
||||
include/c.h \
|
||||
include/canonicalize.h \
|
||||
include/carefulputc.h \
|
||||
include/closestream.h \
|
||||
include/colors.h \
|
||||
include/cpuset.h \
|
||||
include/crc32.h \
|
||||
include/crc64.h \
|
||||
include/debug.h \
|
||||
include/env.h \
|
||||
include/exec_shell.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/namespace.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/readutmp.h \
|
||||
include/rpmatch.h \
|
||||
include/setproctitle.h \
|
||||
include/strutils.h \
|
||||
include/swapprober.h \
|
||||
include/swapheader.h \
|
||||
include/sysfs.h \
|
||||
include/timer.h \
|
||||
include/timeutils.h \
|
||||
include/ttyutils.h \
|
||||
include/widechar.h \
|
||||
include/xalloc.h \
|
||||
include/pt-sgi.h \
|
||||
include/pt-bsd.h \
|
||||
include/pt-mbr.h \
|
||||
include/pt-mbr-partnames.h \
|
||||
include/pt-sun.h \
|
||||
include/statfs_magic.h
|
||||
@@ -29,7 +29,7 @@ static inline int write_all(int fd, const void *buf, size_t count)
|
||||
} else if (errno != EINTR && errno != EAGAIN)
|
||||
return -1;
|
||||
if (errno == EAGAIN) /* Try later, *sigh* */
|
||||
usleep(10000);
|
||||
usleep(250000);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -49,7 +49,7 @@ static inline int fwrite_all(const void *ptr, size_t size,
|
||||
} else if (errno != EINTR && errno != EAGAIN)
|
||||
return -1;
|
||||
if (errno == EAGAIN) /* Try later, *sigh* */
|
||||
usleep(10000);
|
||||
xusleep(250000);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -65,8 +65,10 @@ static inline ssize_t read_all(int fd, char *buf, size_t count)
|
||||
ret = read(fd, buf, count);
|
||||
if (ret <= 0) {
|
||||
if ((errno == EAGAIN || errno == EINTR || ret == 0) &&
|
||||
(tries++ < 5))
|
||||
(tries++ < 5)) {
|
||||
usleep(250000);
|
||||
continue;
|
||||
}
|
||||
return c ? c : -1;
|
||||
}
|
||||
if (ret > 0)
|
||||
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* No copyright is claimed. This code is in the public domain; do with
|
||||
* it what you wish.
|
||||
*
|
||||
* Written by Karel Zak <kzak@redhat.com>
|
||||
*/
|
||||
#ifndef BITOPS_H
|
||||
#define BITOPS_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
#if defined(HAVE_BYTESWAP_H)
|
||||
# include <byteswap.h>
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_ENDIAN_H)
|
||||
# include <endian.h>
|
||||
#elif defined(HAVE_SYS_ENDIAN_H) /* BSDs have them here */
|
||||
# include <sys/endian.h>
|
||||
#endif
|
||||
|
||||
#if defined(__OpenBSD__)
|
||||
# include <sys/types.h>
|
||||
# define be16toh(x) betoh16(x)
|
||||
# define be32toh(x) betoh32(x)
|
||||
# define be64toh(x) betoh64(x)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Fallbacks
|
||||
*/
|
||||
#ifndef bswap_16
|
||||
# define bswap_16(x) ((((x) & 0x00FF) << 8) | \
|
||||
(((x) & 0xFF00) >> 8))
|
||||
#endif
|
||||
|
||||
#ifndef bswap_32
|
||||
# define bswap_32(x) ((((x) & 0x000000FF) << 24) | \
|
||||
(((x) & 0x0000FF00) << 8) | \
|
||||
(((x) & 0x00FF0000) >> 8) | \
|
||||
(((x) & 0xFF000000) >> 24))
|
||||
#endif
|
||||
|
||||
#ifndef bswap_64
|
||||
# define bswap_64(x) ((((x) & 0x00000000000000FFULL) << 56) | \
|
||||
(((x) & 0x000000000000FF00ULL) << 40) | \
|
||||
(((x) & 0x0000000000FF0000ULL) << 24) | \
|
||||
(((x) & 0x00000000FF000000ULL) << 8) | \
|
||||
(((x) & 0x000000FF00000000ULL) >> 8) | \
|
||||
(((x) & 0x0000FF0000000000ULL) >> 24) | \
|
||||
(((x) & 0x00FF000000000000ULL) >> 40) | \
|
||||
(((x) & 0xFF00000000000000ULL) >> 56))
|
||||
#endif
|
||||
|
||||
#ifndef htobe16
|
||||
# if !defined(WORDS_BIGENDIAN)
|
||||
# define htobe16(x) bswap_16 (x)
|
||||
# define htole16(x) (x)
|
||||
# define be16toh(x) bswap_16 (x)
|
||||
# define le16toh(x) (x)
|
||||
# define htobe32(x) bswap_32 (x)
|
||||
# define htole32(x) (x)
|
||||
# define be32toh(x) bswap_32 (x)
|
||||
# define le32toh(x) (x)
|
||||
# define htobe64(x) bswap_64 (x)
|
||||
# define htole64(x) (x)
|
||||
# define be64toh(x) bswap_64 (x)
|
||||
# define le64toh(x) (x)
|
||||
# else
|
||||
# define htobe16(x) (x)
|
||||
# define htole16(x) bswap_16 (x)
|
||||
# define be16toh(x) (x)
|
||||
# define le16toh(x) bswap_16 (x)
|
||||
# define htobe32(x) (x)
|
||||
# define htole32(x) bswap_32 (x)
|
||||
# define be32toh(x) (x)
|
||||
# define le32toh(x) bswap_32 (x)
|
||||
# define htobe64(x) (x)
|
||||
# define htole64(x) bswap_64 (x)
|
||||
# define be64toh(x) (x)
|
||||
# define le64toh(x) bswap_64 (x)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Byte swab macros (based on linux/byteorder/swab.h)
|
||||
*/
|
||||
#define swab16(x) bswap_16(x)
|
||||
#define swab32(x) bswap_32(x)
|
||||
#define swab64(x) bswap_64(x)
|
||||
|
||||
#define cpu_to_le16(x) ((uint16_t) htole16(x))
|
||||
#define cpu_to_le32(x) ((uint32_t) htole32(x))
|
||||
#define cpu_to_le64(x) ((uint64_t) htole64(x))
|
||||
|
||||
#define cpu_to_be16(x) ((uint16_t) htobe16(x))
|
||||
#define cpu_to_be32(x) ((uint32_t) htobe32(x))
|
||||
#define cpu_to_be64(x) ((uint64_t) htobe64(x))
|
||||
|
||||
#define le16_to_cpu(x) ((uint16_t) le16toh(x))
|
||||
#define le32_to_cpu(x) ((uint32_t) le32toh(x))
|
||||
#define le64_to_cpu(x) ((uint64_t) le64toh(x))
|
||||
|
||||
#define be16_to_cpu(x) ((uint16_t) be16toh(x))
|
||||
#define be32_to_cpu(x) ((uint32_t) be32toh(x))
|
||||
#define be64_to_cpu(x) ((uint64_t) be64toh(x))
|
||||
|
||||
/*
|
||||
* Bit map related macros. Usually provided by libc.
|
||||
*/
|
||||
#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
|
||||
|
||||
#endif /* BITOPS_H */
|
||||
|
||||
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
* No copyright is claimed. This code is in the public domain; do with
|
||||
* it what you wish.
|
||||
*
|
||||
* Written by Karel Zak <kzak@redhat.com>
|
||||
*/
|
||||
#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 ioctls, 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/cgit/linux/kernel/git/torvalds/linux.git/tree/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 */
|
||||
@@ -26,13 +26,12 @@
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#define _SC_HOST_NAME_MAX 255
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define BLKID_VERSION "2.22.0"
|
||||
#define BLKID_DATE "04-Sep-2012"
|
||||
#define LIBBLKID_VERSION "2.25.0"
|
||||
#define LIBBLKID_DATE "22-Jul-2014"
|
||||
|
||||
/**
|
||||
* blkid_dev:
|
||||
@@ -139,6 +138,7 @@ typedef struct blkid_struct_dev_iterate *blkid_dev_iterate;
|
||||
#endif
|
||||
|
||||
/* cache.c */
|
||||
extern void blkid_init_debug(int mask);
|
||||
extern void blkid_put_cache(blkid_cache cache);
|
||||
extern int blkid_get_cache(blkid_cache *cache, const char *filename);
|
||||
extern void blkid_gc_cache(blkid_cache cache);
|
||||
@@ -147,8 +147,7 @@ extern void blkid_gc_cache(blkid_cache cache);
|
||||
extern const char *blkid_dev_devname(blkid_dev dev)
|
||||
__ul_attribute__((warn_unused_result));
|
||||
|
||||
extern blkid_dev_iterate blkid_dev_iterate_begin(blkid_cache cache)
|
||||
__ul_attribute__((nonnull));
|
||||
extern blkid_dev_iterate blkid_dev_iterate_begin(blkid_cache cache);
|
||||
extern int blkid_dev_set_search(blkid_dev_iterate iter,
|
||||
char *search_type, char *search_value);
|
||||
extern int blkid_dev_next(blkid_dev_iterate iterate, blkid_dev *dev);
|
||||
@@ -169,8 +168,7 @@ extern int blkid_probe_all_removable(blkid_cache cache);
|
||||
extern blkid_dev blkid_get_dev(blkid_cache cache, const char *devname, int flags);
|
||||
|
||||
/* getsize.c */
|
||||
extern blkid_loff_t blkid_get_dev_size(int fd)
|
||||
__ul_attribute__((warn_unused_result));
|
||||
extern blkid_loff_t blkid_get_dev_size(int fd);
|
||||
|
||||
/* verify.c */
|
||||
extern blkid_dev blkid_verify(blkid_cache cache, blkid_dev dev);
|
||||
@@ -186,25 +184,21 @@ extern char *blkid_get_devname(blkid_cache cache, const char *token,
|
||||
__ul_attribute__((warn_unused_result));
|
||||
|
||||
/* tag.c */
|
||||
extern blkid_tag_iterate blkid_tag_iterate_begin(blkid_dev dev)
|
||||
__ul_attribute__((warn_unused_result));
|
||||
extern blkid_tag_iterate blkid_tag_iterate_begin(blkid_dev dev);
|
||||
extern int blkid_tag_next(blkid_tag_iterate iterate,
|
||||
const char **type, const char **value);
|
||||
extern void blkid_tag_iterate_end(blkid_tag_iterate iterate);
|
||||
extern int blkid_dev_has_tag(blkid_dev dev, const char *type, const char *value)
|
||||
__ul_attribute__((nonnull(1,2)));
|
||||
extern int blkid_dev_has_tag(blkid_dev dev, const char *type, const char *value);
|
||||
|
||||
extern blkid_dev blkid_find_dev_with_tag(blkid_cache cache,
|
||||
const char *type,
|
||||
const char *value)
|
||||
__ul_attribute__((warn_unused_result));
|
||||
const char *value);
|
||||
|
||||
extern int blkid_parse_tag_string(const char *token, char **ret_type, char **ret_val);
|
||||
|
||||
/* version.c */
|
||||
extern int blkid_parse_version_string(const char *ver_string)
|
||||
__ul_attribute__((nonnull))
|
||||
__ul_attribute__((warn_unused_result));
|
||||
__ul_attribute__((nonnull));
|
||||
extern int blkid_get_library_version(const char **ver_string,
|
||||
const char **date_string);
|
||||
|
||||
@@ -233,34 +227,25 @@ extern int blkid_probe_set_device(blkid_probe pr, int fd,
|
||||
blkid_loff_t off, blkid_loff_t size);
|
||||
|
||||
extern dev_t blkid_probe_get_devno(blkid_probe pr)
|
||||
__ul_attribute__((nonnull))
|
||||
__ul_attribute__((warn_unused_result));
|
||||
__ul_attribute__((nonnull));
|
||||
|
||||
extern dev_t blkid_probe_get_wholedisk_devno(blkid_probe pr)
|
||||
__ul_attribute__((nonnull))
|
||||
__ul_attribute__((warn_unused_result));
|
||||
__ul_attribute__((nonnull));
|
||||
|
||||
extern int blkid_probe_is_wholedisk(blkid_probe pr)
|
||||
__ul_attribute__((nonnull))
|
||||
__ul_attribute__((warn_unused_result));
|
||||
__ul_attribute__((nonnull));
|
||||
|
||||
extern blkid_loff_t blkid_probe_get_size(blkid_probe pr)
|
||||
__ul_attribute__((warn_unused_result));
|
||||
extern blkid_loff_t blkid_probe_get_offset(blkid_probe pr)
|
||||
__ul_attribute__((warn_unused_result));
|
||||
extern unsigned int blkid_probe_get_sectorsize(blkid_probe pr)
|
||||
__ul_attribute__((warn_unused_result));
|
||||
extern blkid_loff_t blkid_probe_get_sectors(blkid_probe pr)
|
||||
__ul_attribute__((warn_unused_result));
|
||||
extern blkid_loff_t blkid_probe_get_size(blkid_probe pr);
|
||||
extern blkid_loff_t blkid_probe_get_offset(blkid_probe pr);
|
||||
extern unsigned int blkid_probe_get_sectorsize(blkid_probe pr);
|
||||
extern blkid_loff_t blkid_probe_get_sectors(blkid_probe pr);
|
||||
|
||||
extern int blkid_probe_get_fd(blkid_probe pr)
|
||||
__ul_attribute__((warn_unused_result));
|
||||
extern int blkid_probe_get_fd(blkid_probe pr);
|
||||
|
||||
/*
|
||||
* superblocks probing
|
||||
*/
|
||||
extern int blkid_known_fstype(const char *fstype)
|
||||
__ul_attribute__((warn_unused_result));
|
||||
extern int blkid_known_fstype(const char *fstype);
|
||||
|
||||
extern int blkid_superblocks_get_name(size_t idx, const char **name, int *usage);
|
||||
|
||||
@@ -275,6 +260,7 @@ extern int blkid_probe_enable_superblocks(blkid_probe pr, int enable);
|
||||
#define BLKID_SUBLKS_USAGE (1 << 7) /* define USAGE result value */
|
||||
#define BLKID_SUBLKS_VERSION (1 << 8) /* read FS type from superblock */
|
||||
#define BLKID_SUBLKS_MAGIC (1 << 9) /* define SBMAGIC and SBMAGIC_OFFSET */
|
||||
#define BLKID_SUBLKS_BADCSUM (1 << 10) /* allow a bad checksum */
|
||||
|
||||
#define BLKID_SUBLKS_DEFAULT (BLKID_SUBLKS_LABEL | BLKID_SUBLKS_UUID | \
|
||||
BLKID_SUBLKS_TYPE | BLKID_SUBLKS_SECTYPE)
|
||||
@@ -305,30 +291,23 @@ extern int blkid_probe_filter_superblocks_usage(blkid_probe pr, int flag, int us
|
||||
extern int blkid_probe_enable_topology(blkid_probe pr, int enable);
|
||||
|
||||
/* binary interface */
|
||||
extern blkid_topology blkid_probe_get_topology(blkid_probe pr)
|
||||
__ul_attribute__((warn_unused_result));
|
||||
extern blkid_topology blkid_probe_get_topology(blkid_probe pr);
|
||||
|
||||
extern unsigned long blkid_topology_get_alignment_offset(blkid_topology tp)
|
||||
__ul_attribute__((nonnull))
|
||||
__ul_attribute__((warn_unused_result));
|
||||
__ul_attribute__((nonnull));
|
||||
extern unsigned long blkid_topology_get_minimum_io_size(blkid_topology tp)
|
||||
__ul_attribute__((nonnull))
|
||||
__ul_attribute__((warn_unused_result));
|
||||
__ul_attribute__((nonnull));
|
||||
extern unsigned long blkid_topology_get_optimal_io_size(blkid_topology tp)
|
||||
__ul_attribute__((nonnull))
|
||||
__ul_attribute__((warn_unused_result));
|
||||
__ul_attribute__((nonnull));
|
||||
extern unsigned long blkid_topology_get_logical_sector_size(blkid_topology tp)
|
||||
__ul_attribute__((nonnull))
|
||||
__ul_attribute__((warn_unused_result));
|
||||
__ul_attribute__((nonnull));
|
||||
extern unsigned long blkid_topology_get_physical_sector_size(blkid_topology tp)
|
||||
__ul_attribute__((nonnull))
|
||||
__ul_attribute__((warn_unused_result));
|
||||
__ul_attribute__((nonnull));
|
||||
|
||||
/*
|
||||
* partitions probing
|
||||
*/
|
||||
extern int blkid_known_pttype(const char *pttype)
|
||||
__ul_attribute__((warn_unused_result));
|
||||
extern int blkid_known_pttype(const char *pttype);
|
||||
|
||||
extern int blkid_probe_enable_partitions(blkid_probe pr, int enable);
|
||||
|
||||
@@ -343,62 +322,41 @@ extern int blkid_probe_filter_partitions_type(blkid_probe pr, int flag, char *na
|
||||
extern int blkid_probe_set_partitions_flags(blkid_probe pr, int flags);
|
||||
|
||||
/* binary interface */
|
||||
extern blkid_partlist blkid_probe_get_partitions(blkid_probe pr)
|
||||
__ul_attribute__((warn_unused_result));
|
||||
extern blkid_partlist blkid_probe_get_partitions(blkid_probe pr);
|
||||
|
||||
extern int blkid_partlist_numof_partitions(blkid_partlist ls)
|
||||
__ul_attribute__((warn_unused_result));
|
||||
extern blkid_parttable blkid_partlist_get_table(blkid_partlist ls)
|
||||
__ul_attribute__((warn_unused_result));
|
||||
extern blkid_partition blkid_partlist_get_partition(blkid_partlist ls, int n)
|
||||
__ul_attribute__((warn_unused_result));
|
||||
extern blkid_partition blkid_partlist_devno_to_partition(blkid_partlist ls, dev_t devno)
|
||||
__ul_attribute__((warn_unused_result));
|
||||
extern blkid_parttable blkid_partition_get_table(blkid_partition par)
|
||||
__ul_attribute__((warn_unused_result));
|
||||
extern int blkid_partlist_numof_partitions(blkid_partlist ls);
|
||||
extern blkid_parttable blkid_partlist_get_table(blkid_partlist ls);
|
||||
extern blkid_partition blkid_partlist_get_partition(blkid_partlist ls, int n);
|
||||
extern blkid_partition blkid_partlist_get_partition_by_partno(blkid_partlist ls, int n);
|
||||
extern blkid_partition blkid_partlist_devno_to_partition(blkid_partlist ls, dev_t devno);
|
||||
extern blkid_parttable blkid_partition_get_table(blkid_partition par);
|
||||
|
||||
extern const char *blkid_partition_get_name(blkid_partition par)
|
||||
__ul_attribute__((warn_unused_result));
|
||||
extern const char *blkid_partition_get_uuid(blkid_partition par)
|
||||
__ul_attribute__((warn_unused_result));
|
||||
extern int blkid_partition_get_partno(blkid_partition par)
|
||||
__ul_attribute__((warn_unused_result));
|
||||
extern blkid_loff_t blkid_partition_get_start(blkid_partition par)
|
||||
__ul_attribute__((warn_unused_result));
|
||||
extern blkid_loff_t blkid_partition_get_size(blkid_partition par)
|
||||
__ul_attribute__((warn_unused_result));
|
||||
extern const char *blkid_partition_get_name(blkid_partition par);
|
||||
extern const char *blkid_partition_get_uuid(blkid_partition par);
|
||||
extern int blkid_partition_get_partno(blkid_partition par);
|
||||
extern blkid_loff_t blkid_partition_get_start(blkid_partition par);
|
||||
extern blkid_loff_t blkid_partition_get_size(blkid_partition par);
|
||||
|
||||
extern int blkid_partition_get_type(blkid_partition par)
|
||||
__ul_attribute__((nonnull))
|
||||
__ul_attribute__((warn_unused_result));
|
||||
__ul_attribute__((nonnull));
|
||||
|
||||
extern const char *blkid_partition_get_type_string(blkid_partition par)
|
||||
__ul_attribute__((warn_unused_result));
|
||||
extern const char *blkid_partition_get_type_string(blkid_partition par);
|
||||
|
||||
extern unsigned long long blkid_partition_get_flags(blkid_partition par)
|
||||
__ul_attribute__((nonnull))
|
||||
__ul_attribute__((warn_unused_result));
|
||||
__ul_attribute__((nonnull));
|
||||
|
||||
extern int blkid_partition_is_logical(blkid_partition par)
|
||||
__ul_attribute__((nonnull))
|
||||
__ul_attribute__((warn_unused_result));
|
||||
__ul_attribute__((nonnull));
|
||||
extern int blkid_partition_is_extended(blkid_partition par)
|
||||
__ul_attribute__((nonnull))
|
||||
__ul_attribute__((warn_unused_result));
|
||||
__ul_attribute__((nonnull));
|
||||
extern int blkid_partition_is_primary(blkid_partition par)
|
||||
__ul_attribute__((nonnull))
|
||||
__ul_attribute__((warn_unused_result));
|
||||
__ul_attribute__((nonnull));
|
||||
|
||||
extern const char *blkid_parttable_get_type(blkid_parttable tab)
|
||||
__ul_attribute__((warn_unused_result));
|
||||
extern const char *blkid_parttable_get_type(blkid_parttable tab);
|
||||
extern const char *blkid_parttable_get_id(blkid_parttable tab);
|
||||
|
||||
extern const char *blkid_parttable_get_id(blkid_parttable tab)
|
||||
__ul_attribute__((warn_unused_result));
|
||||
|
||||
extern blkid_loff_t blkid_parttable_get_offset(blkid_parttable tab)
|
||||
__ul_attribute__((warn_unused_result));
|
||||
extern blkid_partition blkid_parttable_get_parent(blkid_parttable tab)
|
||||
__ul_attribute__((warn_unused_result));
|
||||
extern blkid_loff_t blkid_parttable_get_offset(blkid_parttable tab);
|
||||
extern blkid_partition blkid_parttable_get_parent(blkid_parttable tab);
|
||||
|
||||
/*
|
||||
* NAME=value low-level interface
|
||||
@@ -407,15 +365,13 @@ extern int blkid_do_probe(blkid_probe pr);
|
||||
extern int blkid_do_safeprobe(blkid_probe pr);
|
||||
extern int blkid_do_fullprobe(blkid_probe pr);
|
||||
|
||||
extern int blkid_probe_numof_values(blkid_probe pr)
|
||||
__ul_attribute__((warn_unused_result));
|
||||
extern int blkid_probe_numof_values(blkid_probe pr);
|
||||
extern int blkid_probe_get_value(blkid_probe pr, int num, const char **name,
|
||||
const char **data, size_t *len);
|
||||
extern int blkid_probe_lookup_value(blkid_probe pr, const char *name,
|
||||
const char **data, size_t *len);
|
||||
extern int blkid_probe_has_value(blkid_probe pr, const char *name)
|
||||
__ul_attribute__((nonnull))
|
||||
__ul_attribute__((warn_unused_result));
|
||||
__ul_attribute__((nonnull));
|
||||
|
||||
extern int blkid_do_wipe(blkid_probe pr, int dryrun);
|
||||
extern int blkid_probe_step_back(blkid_probe pr);
|
||||
@@ -0,0 +1,67 @@
|
||||
#ifndef UTIL_LINUX_CAREFUULPUTC_H
|
||||
#define UTIL_LINUX_CAREFUULPUTC_H
|
||||
|
||||
/*
|
||||
* A putc() for use in write and wall (that sometimes are sgid tty).
|
||||
* It avoids control characters in our locale, and also ASCII control
|
||||
* characters. Note that the locale of the recipient is unknown.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
static inline int fputc_careful(int c, FILE *fp, const char fail)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (isprint(c) || c == '\a' || c == '\t' || c == '\r' || c == '\n')
|
||||
ret = putc(c, fp);
|
||||
else if (!isascii(c))
|
||||
ret = fprintf(fp, "\\%3o", (unsigned char)c);
|
||||
else {
|
||||
ret = putc(fail, fp);
|
||||
if (ret != EOF)
|
||||
ret = putc(c ^ 0x40, fp);
|
||||
}
|
||||
return (ret < 0) ? EOF : 0;
|
||||
}
|
||||
|
||||
static inline void fputs_quoted(const char *data, FILE *out)
|
||||
{
|
||||
const char *p;
|
||||
|
||||
fputc('"', out);
|
||||
for (p = data; p && *p; p++) {
|
||||
if ((unsigned char) *p == 0x22 || /* " */
|
||||
(unsigned char) *p == 0x5c || /* \ */
|
||||
(unsigned char) *p == 0x60 || /* ` */
|
||||
(unsigned char) *p == 0x24 || /* $ */
|
||||
!isprint((unsigned char) *p) ||
|
||||
iscntrl((unsigned char) *p)) {
|
||||
|
||||
fprintf(out, "\\x%02x", (unsigned char) *p);
|
||||
} else
|
||||
fputc(*p, out);
|
||||
}
|
||||
fputc('"', out);
|
||||
}
|
||||
|
||||
static inline void fputs_nonblank(const char *data, FILE *out)
|
||||
{
|
||||
const char *p;
|
||||
|
||||
for (p = data; p && *p; p++) {
|
||||
if (isblank((unsigned char) *p) ||
|
||||
(unsigned char) *p == 0x5c || /* \ */
|
||||
!isprint((unsigned char) *p) ||
|
||||
iscntrl((unsigned char) *p)) {
|
||||
|
||||
fprintf(out, "\\x%02x", (unsigned char) *p);
|
||||
|
||||
} else
|
||||
fputc(*p, out);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif /* _CAREFUULPUTC_H */
|
||||
@@ -24,8 +24,9 @@ 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)
|
||||
if (!fclose_fail && !(errno == EPIPE))
|
||||
errno = 0;
|
||||
return EOF;
|
||||
}
|
||||
@@ -48,4 +49,23 @@ close_stdout(void)
|
||||
_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
#ifndef HAVE_FSYNC
|
||||
static inline int
|
||||
fsync(int fd __attribute__((__unused__)))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline int
|
||||
close_fd(int fd)
|
||||
{
|
||||
const int fsync_fail = (fsync(fd) != 0);
|
||||
const int close_fail = (close(fd) != 0);
|
||||
|
||||
if (fsync_fail || close_fail)
|
||||
return EOF;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* UTIL_LINUX_CLOSESTREAM_H */
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright (C) 2012 Ondrej Oprala <ooprala@redhat.com>
|
||||
* Copyright (C) 2012-2014 Karel Zak <kzak@redhat.com>
|
||||
*
|
||||
* This file may be distributed under the terms of the
|
||||
* GNU Lesser General Public License.
|
||||
*/
|
||||
#ifndef UTIL_LINUX_COLORS_H
|
||||
#define UTIL_LINUX_COLORS_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define UL_COLOR_RESET "\033[0m"
|
||||
#define UL_COLOR_BOLD "\033[1m"
|
||||
#define UL_COLOR_HALFBRIGHT "\033[2m"
|
||||
#define UL_COLOR_UNDERSCORE "\033[4m"
|
||||
#define UL_COLOR_BLINK "\033[5m"
|
||||
#define UL_COLOR_REVERSE "\033[7m"
|
||||
|
||||
/* Standard colors */
|
||||
#define UL_COLOR_BLACK "\033[30m"
|
||||
#define UL_COLOR_RED "\033[31m"
|
||||
#define UL_COLOR_GREEN "\033[32m"
|
||||
#define UL_COLOR_BROWN "\033[33m" /* well, brown */
|
||||
#define UL_COLOR_BLUE "\033[34m"
|
||||
#define UL_COLOR_MAGENTA "\033[35m"
|
||||
#define UL_COLOR_CYAN "\033[36m"
|
||||
#define UL_COLOR_GRAY "\033[37m"
|
||||
|
||||
/* Bold variants */
|
||||
#define UL_COLOR_DARK_GRAY "\033[1;30m"
|
||||
#define UL_COLOR_BOLD_RED "\033[1;31m"
|
||||
#define UL_COLOR_BOLD_GREEN "\033[1;32m"
|
||||
#define UL_COLOR_BOLD_YELLOW "\033[1;33m"
|
||||
#define UL_COLOR_BOLD_BLUE "\033[1;34m"
|
||||
#define UL_COLOR_BOLD_MAGENTA "\033[1;35m"
|
||||
#define UL_COLOR_BOLD_CYAN "\033[1;36m"
|
||||
|
||||
#define UL_COLOR_WHITE "\033[1;37m"
|
||||
|
||||
/* --color[=WHEN] */
|
||||
enum colortmode {
|
||||
UL_COLORMODE_AUTO = 0,
|
||||
UL_COLORMODE_NEVER,
|
||||
UL_COLORMODE_ALWAYS,
|
||||
UL_COLORMODE_UNDEF,
|
||||
|
||||
__UL_NCOLORMODES /* last */
|
||||
};
|
||||
|
||||
extern int colormode_from_string(const char *str);
|
||||
extern int colormode_or_err(const char *str, const char *errmsg);
|
||||
|
||||
/* Initialize the global variable UL_COLOR_TERM_OK */
|
||||
extern int colors_init(int mode, const char *util_name);
|
||||
|
||||
/* Returns 1 or 0 */
|
||||
extern int colors_wanted(void);
|
||||
|
||||
/* temporary enable/disable colors */
|
||||
extern void colors_off(void);
|
||||
extern void colors_on(void);
|
||||
|
||||
|
||||
/* Set the color */
|
||||
extern void color_fenable(const char *seq, FILE *f);
|
||||
|
||||
extern void color_scheme_fenable(const char *name, const char *dflt, FILE *f);
|
||||
extern const char *color_scheme_get_sequence(const char *name, const char *dflt);
|
||||
|
||||
static inline void color_enable(const char *seq)
|
||||
{
|
||||
color_fenable(seq, stdout);
|
||||
}
|
||||
|
||||
static inline void color_scheme_enable(const char *name, const char *dflt)
|
||||
{
|
||||
color_scheme_fenable(name, dflt, stdout);
|
||||
}
|
||||
|
||||
/* Reset colors to default */
|
||||
extern void color_fdisable(FILE *f);
|
||||
|
||||
static inline void color_disable(void)
|
||||
{
|
||||
color_fdisable(stdout);
|
||||
}
|
||||
|
||||
/* converts "red" to UL_COLOR_RED, etc. */
|
||||
extern const char *color_sequence_from_colorname(const char *str);
|
||||
|
||||
|
||||
#endif /* UTIL_LINUX_COLORS_H */
|
||||
@@ -4,9 +4,15 @@
|
||||
/* Define if building universal (internal helper macro) */
|
||||
/* #undef AC_APPLE_UNIVERSAL_BUILD */
|
||||
|
||||
/* Enable agetty --reload feature */
|
||||
#define AGETTY_RELOAD 1
|
||||
|
||||
/* Should chfn and chsh require the user to enter the password? */
|
||||
#define CHFN_CHSH_PASSWORD 1
|
||||
|
||||
/* Path to hwclock adjtime file */
|
||||
#define CONFIG_ADJTIME_PATH "/etc/adjtime"
|
||||
|
||||
/* Define to 1 if translation of program messages to the user's native
|
||||
language is requested. */
|
||||
#define ENABLE_NLS 1
|
||||
@@ -20,6 +26,17 @@
|
||||
/* Define to 1 if you have the <byteswap.h> header file. */
|
||||
#define HAVE_BYTESWAP_H 1
|
||||
|
||||
/* Define to 1 if you have the Mac OS X function CFLocaleCopyCurrent in the
|
||||
CoreFoundation framework. */
|
||||
/* #undef HAVE_CFLOCALECOPYCURRENT */
|
||||
|
||||
/* Define to 1 if you have the Mac OS X function CFPreferencesCopyAppValue in
|
||||
the CoreFoundation framework. */
|
||||
/* #undef HAVE_CFPREFERENCESCOPYAPPVALUE */
|
||||
|
||||
/* Define to 1 if you have the `clock_gettime' function. */
|
||||
#define HAVE_CLOCK_GETTIME 1
|
||||
|
||||
/* Define to 1 if the system has the type `cpu_set_t'. */
|
||||
#define HAVE_CPU_SET_T 1
|
||||
|
||||
@@ -30,22 +47,6 @@
|
||||
*/
|
||||
#define HAVE_DCGETTEXT 1
|
||||
|
||||
/* Define to 1 if you have the declaration of `ADDR_COMPAT_LAYOUT', and to 0
|
||||
if you don't. */
|
||||
#define HAVE_DECL_ADDR_COMPAT_LAYOUT 1
|
||||
|
||||
/* Define to 1 if you have the declaration of `ADDR_LIMIT_32BIT', and to 0 if
|
||||
you don't. */
|
||||
#define HAVE_DECL_ADDR_LIMIT_32BIT 1
|
||||
|
||||
/* Define to 1 if you have the declaration of `ADDR_LIMIT_3GB', and to 0 if
|
||||
you don't. */
|
||||
#define HAVE_DECL_ADDR_LIMIT_3GB 1
|
||||
|
||||
/* Define to 1 if you have the declaration of `ADDR_NO_RANDOMIZE', and to 0 if
|
||||
you don't. */
|
||||
#define HAVE_DECL_ADDR_NO_RANDOMIZE 1
|
||||
|
||||
/* Define to 1 if you have the declaration of `CPU_ALLOC', and to 0 if you
|
||||
don't. */
|
||||
#define HAVE_DECL_CPU_ALLOC 1
|
||||
@@ -54,30 +55,6 @@
|
||||
*/
|
||||
/* #undef HAVE_DECL_DIRFD */
|
||||
|
||||
/* Define to 1 if you have the declaration of `FDPIC_FUNCPTRS', and to 0 if
|
||||
you don't. */
|
||||
#define HAVE_DECL_FDPIC_FUNCPTRS 1
|
||||
|
||||
/* Define to 1 if you have the declaration of `MMAP_PAGE_ZERO', and to 0 if
|
||||
you don't. */
|
||||
#define HAVE_DECL_MMAP_PAGE_ZERO 1
|
||||
|
||||
/* Define to 1 if you have the declaration of `READ_IMPLIES_EXEC', and to 0 if
|
||||
you don't. */
|
||||
#define HAVE_DECL_READ_IMPLIES_EXEC 1
|
||||
|
||||
/* Define to 1 if you have the declaration of `STICKY_TIMEOUTS', and to 0 if
|
||||
you don't. */
|
||||
#define HAVE_DECL_STICKY_TIMEOUTS 1
|
||||
|
||||
/* Define to 1 if you have the declaration of `UNAME26', and to 0 if you
|
||||
don't. */
|
||||
#define HAVE_DECL_UNAME26 1
|
||||
|
||||
/* Define to 1 if you have the declaration of `WHOLE_SECONDS', and to 0 if you
|
||||
don't. */
|
||||
#define HAVE_DECL_WHOLE_SECONDS 1
|
||||
|
||||
/* Define to 1 if you have the declaration of `_NL_TIME_WEEK_1STDAY', and to 0
|
||||
if you don't. */
|
||||
#define HAVE_DECL__NL_TIME_WEEK_1STDAY 1
|
||||
@@ -145,15 +122,21 @@
|
||||
/* Define to 1 if you have the `getrlimit' function. */
|
||||
#define HAVE_GETRLIMIT 1
|
||||
|
||||
/* Define to 1 if you have the `getsgnam' function. */
|
||||
#define HAVE_GETSGNAM 1
|
||||
|
||||
/* Define if the GNU gettext() function is already present or preinstalled. */
|
||||
#define HAVE_GETTEXT 1
|
||||
|
||||
/* Define if you have the iconv() function. */
|
||||
/* Define if you have the iconv() function and it works. */
|
||||
/* #undef HAVE_ICONV */
|
||||
|
||||
/* Define to 1 if you have the `inotify_init' function. */
|
||||
#define HAVE_INOTIFY_INIT 1
|
||||
|
||||
/* Define to 1 if you have the `inotify_init1' function. */
|
||||
#define HAVE_INOTIFY_INIT1 1
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#define HAVE_INTTYPES_H 1
|
||||
|
||||
@@ -193,13 +176,16 @@
|
||||
/* Define if SELinux is available */
|
||||
/* #undef HAVE_LIBSELINUX */
|
||||
|
||||
/* Define if libsystemd is available */
|
||||
/* #undef HAVE_LIBSYSTEMD */
|
||||
|
||||
/* Define to 1 if you have the `termcap' library (-ltermcap). */
|
||||
#define HAVE_LIBTERMCAP 1
|
||||
|
||||
/* Define to 1 if you have the `udev' library (-ludev). */
|
||||
/* #undef HAVE_LIBUDEV */
|
||||
|
||||
/* Define to 1 if you have the `user' library (-luser). */
|
||||
/* Define if libuser is available */
|
||||
/* #undef HAVE_LIBUSER */
|
||||
|
||||
/* Define to 1 if you have the `utempter' library (-lutempter). */
|
||||
@@ -226,12 +212,18 @@
|
||||
/* Define to 1 if you have the <linux/fd.h> header file. */
|
||||
#define HAVE_LINUX_FD_H 1
|
||||
|
||||
/* Define to 1 if you have the <linux/gsmmux.h> header file. */
|
||||
/* #undef HAVE_LINUX_GSMMUX_H */
|
||||
|
||||
/* Define to 1 if you have the <linux/major.h> header file. */
|
||||
#define HAVE_LINUX_MAJOR_H 1
|
||||
|
||||
/* Define to 1 if you have the <linux/raw.h> header file. */
|
||||
#define HAVE_LINUX_RAW_H 1
|
||||
|
||||
/* Define to 1 if you have the <linux/securebits.h> header file. */
|
||||
#define HAVE_LINUX_SECUREBITS_H 1
|
||||
|
||||
/* Define to 1 if you have the <linux/tiocl.h> header file. */
|
||||
#define HAVE_LINUX_TIOCL_H 1
|
||||
|
||||
@@ -263,7 +255,7 @@
|
||||
#define HAVE_MEMORY_H 1
|
||||
|
||||
/* Define to 1 if you have the `mempcpy' function. */
|
||||
#define HAVE_MEMPCPY 0
|
||||
#define HAVE_MEMPCPY 1
|
||||
|
||||
/* Define to 1 if you have the <mntent.h> header file. */
|
||||
#define HAVE_MNTENT_H 1
|
||||
@@ -292,6 +284,9 @@
|
||||
/* Define to 1 if you have the `openat' function. */
|
||||
#define HAVE_OPENAT 1
|
||||
|
||||
/* Define to 1 if you have the `open_memstream' function. */
|
||||
#define HAVE_OPEN_MEMSTREAM 1
|
||||
|
||||
/* Define to 1 if you have the <paths.h> header file. */
|
||||
#define HAVE_PATHS_H 1
|
||||
|
||||
@@ -313,6 +308,12 @@
|
||||
/* Define to 1 if you have the <pty.h> header file. */
|
||||
#define HAVE_PTY_H 1
|
||||
|
||||
/* Define to 1 if you have the `qsort_r' function. */
|
||||
#define HAVE_QSORT_R 1
|
||||
|
||||
/* Define if curses library has the resizeterm(). */
|
||||
/* #undef HAVE_RESIZETERM */
|
||||
|
||||
/* Define to 1 if you have the `rpmatch' function. */
|
||||
#define HAVE_RPMATCH 1
|
||||
|
||||
@@ -329,10 +330,19 @@
|
||||
#define HAVE_SCANF_MS_MODIFIER 1
|
||||
|
||||
/* Define to 1 if you have the `secure_getenv' function. */
|
||||
/* #undef HAVE_SECURE_GETENV */
|
||||
#define HAVE_SECURE_GETENV 1
|
||||
|
||||
/* Define to 1 if you have the `security_get_initial_context' function. */
|
||||
/* #undef HAVE_SECURITY_GET_INITIAL_CONTEXT */
|
||||
|
||||
/* Define to 1 if you have the <security/openpam.h> header file. */
|
||||
/* #undef HAVE_SECURITY_OPENPAM_H */
|
||||
|
||||
/* Define to 1 if you have the <security/pam_appl.h> header file. */
|
||||
/* #undef HAVE_SECURITY_PAM_APPL_H */
|
||||
|
||||
/* Define to 1 if you have the <security/pam_misc.h> header file. */
|
||||
#define HAVE_SECURITY_PAM_MISC_H 1
|
||||
/* #undef HAVE_SECURITY_PAM_MISC_H */
|
||||
|
||||
/* Define to 1 if you have the `setns' function. */
|
||||
#define HAVE_SETNS 1
|
||||
@@ -343,6 +353,9 @@
|
||||
/* Define to 1 if you have the `setresuid' function. */
|
||||
#define HAVE_SETRESUID 1
|
||||
|
||||
/* Define to 1 if the system has the type `sighandler_t'. */
|
||||
#define HAVE_SIGHANDLER_T 1
|
||||
|
||||
/* Define to 1 if you have the `sigqueue' function. */
|
||||
#define HAVE_SIGQUEUE 1
|
||||
|
||||
@@ -358,6 +371,9 @@
|
||||
/* Define to 1 if you have the <slcurses.h> header file. */
|
||||
/* #undef HAVE_SLCURSES_H */
|
||||
|
||||
/* Add SMACK support */
|
||||
/* #undef HAVE_SMACK */
|
||||
|
||||
/* Define to 1 if you have the `srandom' function. */
|
||||
#define HAVE_SRANDOM 1
|
||||
|
||||
@@ -400,6 +416,9 @@
|
||||
/* Define to 1 if you have the `sysconf' function. */
|
||||
#define HAVE_SYSCONF 1
|
||||
|
||||
/* Define to 1 if you have the `sysinfo' function. */
|
||||
#define HAVE_SYSINFO 1
|
||||
|
||||
/* Define to 1 if you have the <sys/disklabel.h> header file. */
|
||||
/* #undef HAVE_SYS_DISKLABEL_H */
|
||||
|
||||
@@ -451,6 +470,9 @@
|
||||
/* Define to 1 if you have the <sys/time.h> header file. */
|
||||
#define HAVE_SYS_TIME_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/ttydefaults.h> header file. */
|
||||
#define HAVE_SYS_TTYDEFAULTS_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
|
||||
@@ -478,9 +500,15 @@
|
||||
/* Define to 1 if you have the `updwtmp' function. */
|
||||
#define HAVE_UPDWTMP 1
|
||||
|
||||
/* Define if curses library has the use_default_colors(). */
|
||||
/* #undef HAVE_USE_DEFAULT_COLORS */
|
||||
|
||||
/* Define to 1 if you have the `usleep' function. */
|
||||
#define HAVE_USLEEP 1
|
||||
|
||||
/* Define to 1 if you have the `utimensat' function. */
|
||||
#define HAVE_UTIMENSAT 1
|
||||
|
||||
/* Define to 1 if you want to use uuid daemon. */
|
||||
#define HAVE_UUIDD 1
|
||||
|
||||
@@ -500,16 +528,22 @@
|
||||
#define HAVE___PROGNAME 1
|
||||
|
||||
/* Define to 1 if you have the `__secure_getenv' function. */
|
||||
#define HAVE___SECURE_GETENV 1
|
||||
/* #undef HAVE___SECURE_GETENV */
|
||||
|
||||
/* libblkid date string */
|
||||
#define LIBBLKID_DATE "04-Sep-2012"
|
||||
#define LIBBLKID_DATE "22-Jul-2014"
|
||||
|
||||
/* libblkid version string */
|
||||
#define LIBBLKID_VERSION "2.22.0"
|
||||
#define LIBBLKID_VERSION "2.25.0"
|
||||
|
||||
/* libfdisk version string */
|
||||
#define LIBFDISK_VERSION "2.25.0"
|
||||
|
||||
/* libmount version string */
|
||||
#define LIBMOUNT_VERSION "2.22.0"
|
||||
#define LIBMOUNT_VERSION "2.25.0"
|
||||
|
||||
/* libsmartcols version string */
|
||||
#define LIBSMARTCOLS_VERSION "2.25.0"
|
||||
|
||||
/* Should login chown /dev/vcsN? */
|
||||
/* #undef LOGIN_CHOWN_VCS */
|
||||
@@ -521,9 +555,6 @@
|
||||
*/
|
||||
#define LT_OBJDIR ".libs/"
|
||||
|
||||
/* Define to 1 if your C compiler doesn't accept -c and -o together. */
|
||||
/* #undef NO_MINUS_C_MINUS_O */
|
||||
|
||||
/* Should chsh allow only shells in /etc/shells? */
|
||||
#define ONLY_LISTED_SHELLS 1
|
||||
|
||||
@@ -537,7 +568,7 @@
|
||||
#define PACKAGE_NAME "util-linux"
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#define PACKAGE_STRING "util-linux 2.22.552-d48f6"
|
||||
#define PACKAGE_STRING "util-linux 2.25.590-bf6c"
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#define PACKAGE_TARNAME "util-linux"
|
||||
@@ -546,7 +577,7 @@
|
||||
#define PACKAGE_URL "http://www.kernel.org/pub/linux/utils/util-linux/"
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#define PACKAGE_VERSION "2.22.552-d48f6"
|
||||
#define PACKAGE_VERSION "2.25.590-bf6c"
|
||||
|
||||
/* Should pg ring the bell on invalid keys? */
|
||||
#define PG_BELL 1
|
||||
@@ -581,9 +612,6 @@
|
||||
/* Fallback syscall number for unshare */
|
||||
/* #undef SYS_unshare */
|
||||
|
||||
/* Should uuidd support socket activation? */
|
||||
/* #undef USE_SOCKET_ACTIVATION */
|
||||
|
||||
/* Should sulogin use a emergency mount of /dev and /proc? */
|
||||
/* #undef USE_SULOGIN_EMERGENCY_MOUNT */
|
||||
|
||||
@@ -613,7 +641,7 @@
|
||||
#define USE_TTY_GROUP 1
|
||||
|
||||
/* Version number of package */
|
||||
#define VERSION "2.22.552-d48f6"
|
||||
#define VERSION "2.25.590-bf6c"
|
||||
|
||||
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
|
||||
significant byte first (like Motorola and SPARC, unlike Intel). */
|
||||
@@ -627,6 +655,11 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Enable large inode numbers on Mac OS X 10.5. */
|
||||
#ifndef _DARWIN_USE_64_BIT_INODE
|
||||
# define _DARWIN_USE_64_BIT_INODE 1
|
||||
#endif
|
||||
|
||||
/* Number of bits in a file offset, on hosts where this is settable. */
|
||||
/* #undef _FILE_OFFSET_BITS */
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef UL_NG_CRC32_H
|
||||
#define UL_NG_CRC32_H
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdint.h>
|
||||
|
||||
extern uint32_t crc32(uint32_t seed, const unsigned char *buf, size_t len);
|
||||
@@ -0,0 +1,9 @@
|
||||
#ifndef UTIL_LINUX_CRC64_H
|
||||
#define UTIL_LINUX_CRC64_H
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdint.h>
|
||||
|
||||
extern uint64_t crc64(uint64_t seed, const unsigned char *data, size_t len);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,179 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Ondrej Oprala <ooprala@redhat.com>
|
||||
* Copyright (C) 2014 Karel Zak <kzak@redhat.com>
|
||||
*
|
||||
* This file may be distributed under the terms of the
|
||||
* GNU Lesser General Public License.
|
||||
*/
|
||||
#ifndef UTIL_LINUX_DEBUG_H
|
||||
#define UTIL_LINUX_DEBUG_H
|
||||
|
||||
|
||||
/*
|
||||
* util-linux debug macros
|
||||
*
|
||||
* The debug stuff is based on <name>_debug_mask that controls what outputs is
|
||||
* expected. The mask is usually initialized by <NAME>_DEBUG= env.variable
|
||||
*
|
||||
* After successful initialization the flag <PREFIX>_DEBUG_INIT is always set
|
||||
* to the mask (this flag is required). The <PREFIX> is usually library API
|
||||
* prefix (e.g. MNT_) or program name (e.g. CFDISK_)
|
||||
*
|
||||
* In the code is possible to use
|
||||
*
|
||||
* DBG(FOO, ul_debug("this is output for foo"));
|
||||
*
|
||||
* where for the FOO has to be defined <PREFIX>_DEBUG_FOO.
|
||||
*
|
||||
* It's possible to initialize the mask by comma delimited strings with
|
||||
* subsystem names (e.g. "LIBMOUNT_DEBUG=options,tab"). In this case is
|
||||
* necessary to define mask names array. This functionality is optional.
|
||||
*
|
||||
* It's stringly recommended to use UL_* macros to define/declare/use
|
||||
* the debug stuff.
|
||||
*
|
||||
* See disk-utils/cfdisk.c: cfdisk_init_debug() for programs debug
|
||||
* or libmount/src/init.c: mnt_init_debug() for library debug
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
struct ul_debug_maskname {
|
||||
const char *name;
|
||||
int mask;
|
||||
const char *help;
|
||||
};
|
||||
#define UL_DEBUG_EMPTY_MASKNAMES {{ NULL, 0, NULL }}
|
||||
#define UL_DEBUG_DEFINE_MASKNAMES(m) static const struct ul_debug_maskname m ## _masknames[]
|
||||
#define UL_DEBUG_MASKNAMES(m) m ## _masknames
|
||||
|
||||
#define UL_DEBUG_DEFINE_MASK(m) int m ## _debug_mask
|
||||
#define UL_DEBUG_DECLARE_MASK(m) extern UL_DEBUG_DEFINE_MASK(m)
|
||||
|
||||
/* p - flag prefix, m - flag postfix */
|
||||
#define UL_DEBUG_DEFINE_FLAG(p, m) p ## m
|
||||
|
||||
/* l - library name, p - flag prefix, m - flag postfix, x - function */
|
||||
#define __UL_DBG(l, p, m, x) \
|
||||
do { \
|
||||
if ((p ## m) & l ## _debug_mask) { \
|
||||
fprintf(stderr, "%d: %s: %8s: ", getpid(), # l, # m); \
|
||||
x; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define __UL_DBG_CALL(l, p, m, x) \
|
||||
do { \
|
||||
if ((p ## m) & l ## _debug_mask) { \
|
||||
x; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define __UL_DBG_FLUSH(l, p) \
|
||||
do { \
|
||||
if (l ## _debug_mask && \
|
||||
l ## _debug_mask != p ## INIT) { \
|
||||
fflush(stderr); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
#define __UL_INIT_DEBUG(lib, pref, mask, env) \
|
||||
do { \
|
||||
if (lib ## _debug_mask & pref ## INIT) \
|
||||
; \
|
||||
else if (!mask) { \
|
||||
char *str = getenv(# env); \
|
||||
if (str) \
|
||||
lib ## _debug_mask = ul_debug_parse_envmask(lib ## _masknames, str); \
|
||||
} else \
|
||||
lib ## _debug_mask = mask; \
|
||||
lib ## _debug_mask |= pref ## INIT; \
|
||||
} while (0)
|
||||
|
||||
|
||||
static inline void __attribute__ ((__format__ (__printf__, 1, 2)))
|
||||
ul_debug(const char *mesg, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, mesg);
|
||||
vfprintf(stderr, mesg, ap);
|
||||
va_end(ap);
|
||||
fputc('\n', stderr);
|
||||
}
|
||||
|
||||
static inline void __attribute__ ((__format__ (__printf__, 2, 3)))
|
||||
ul_debugobj(void *handler, const char *mesg, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (handler)
|
||||
fprintf(stderr, "[%p]: ", handler);
|
||||
va_start(ap, mesg);
|
||||
vfprintf(stderr, mesg, ap);
|
||||
va_end(ap);
|
||||
fputc('\n', stderr);
|
||||
}
|
||||
|
||||
static inline int ul_debug_parse_envmask(
|
||||
const struct ul_debug_maskname flagnames[],
|
||||
const char *mask)
|
||||
{
|
||||
int res;
|
||||
char *ptr;
|
||||
|
||||
/* let's check for a numeric mask first */
|
||||
res = strtoul(mask, &ptr, 0);
|
||||
|
||||
/* perhaps it's a comma-separated string? */
|
||||
if (ptr && *ptr && flagnames && flagnames[0].name) {
|
||||
char *msbuf, *ms, *name;
|
||||
res = 0;
|
||||
|
||||
ms = msbuf = strdup(mask);
|
||||
if (!ms)
|
||||
return res;
|
||||
|
||||
while ((name = strtok_r(ms, ",", &ptr))) {
|
||||
const struct ul_debug_maskname *d;
|
||||
ms = ptr;
|
||||
|
||||
for (d = flagnames; d && d->name; d++) {
|
||||
if (strcmp(name, d->name) == 0) {
|
||||
res |= d->mask;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* nothing else we can do by OR-ing the mask */
|
||||
if (res == 0xffff)
|
||||
break;
|
||||
}
|
||||
free(msbuf);
|
||||
} else if (ptr && strcmp(ptr, "all") == 0)
|
||||
res = 0xffff;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static inline void ul_debug_print_masks(
|
||||
const char *env,
|
||||
const struct ul_debug_maskname flagnames[])
|
||||
{
|
||||
const struct ul_debug_maskname *d;
|
||||
|
||||
if (!flagnames)
|
||||
return;
|
||||
|
||||
fprintf(stderr, "Available \"%s=<name>[,...]|<mask>\" debug masks:\n",
|
||||
env);
|
||||
for (d = flagnames; d && d->name; d++) {
|
||||
if (!d->help)
|
||||
continue;
|
||||
fprintf(stderr, " %-8s [0x%04x] : %s\n",
|
||||
d->name, d->mask, d->help);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* UTIL_LINUX_DEBUG_H */
|
||||
@@ -1,16 +1,23 @@
|
||||
#ifndef UTIL_LINUX_FILEUTILS
|
||||
#define UTIL_LINUX_FILEUTILS
|
||||
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "c.h"
|
||||
|
||||
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) {
|
||||
if (fd == -1)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(ret = fdopen(fd, "w+"))) {
|
||||
close(fd);
|
||||
return NULL;
|
||||
@@ -20,4 +27,7 @@ static inline FILE *xfmkstemp(char **tmpname, char *dir)
|
||||
|
||||
extern int get_fd_tabsize(void);
|
||||
|
||||
extern int mkdir_p(const char *path, mode_t mode);
|
||||
extern char *stripoff_last_component(char *path);
|
||||
|
||||
#endif /* UTIL_LINUX_FILEUTILS */
|
||||
@@ -0,0 +1,346 @@
|
||||
/*
|
||||
* Copyright (C) 2008 Karel Zak <kzak@redhat.com>
|
||||
* Copyright (C) 1999-2008 by Theodore Ts'o
|
||||
*
|
||||
* This file may be redistributed under the terms of the
|
||||
* GNU Lesser General Public License.
|
||||
*
|
||||
* (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_entry_is_last - tests whether is entry last in the list
|
||||
* @entry: the entry to test.
|
||||
* @head: the list to test.
|
||||
*/
|
||||
_INLINE_ int list_entry_is_last(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) __extension__ ({ \
|
||||
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
|
||||
(type *)( (char *)__mptr - offsetof(type,member) );})
|
||||
|
||||
|
||||
#define list_first_entry(head, type, member) \
|
||||
((head) && (head)->next != (head) ? list_entry((head)->next, type, member) : NULL)
|
||||
|
||||
#define list_last_entry(head, type, member) \
|
||||
((head) && (head)->prev != (head) ? list_entry((head)->prev, 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,
|
||||
void *data),
|
||||
void *data,
|
||||
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, data) <= 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,
|
||||
void *data),
|
||||
void *data,
|
||||
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, data) <= 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, data);
|
||||
|
||||
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,
|
||||
void *data),
|
||||
void *data)
|
||||
{
|
||||
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, data, 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, data, part[lev], list);
|
||||
|
||||
merge_and_restore_back_links(cmp, data, head, part[max_lev], list);
|
||||
}
|
||||
|
||||
#undef _INLINE_
|
||||
|
||||
#endif /* UTIL_LINUX_LIST_H */
|
||||
@@ -45,7 +45,7 @@ enum {
|
||||
#define LO_KEY_SIZE 32
|
||||
|
||||
/*
|
||||
* Linux LOOP_{SET,GET}_STATUS64 ioclt struct
|
||||
* Linux LOOP_{SET,GET}_STATUS64 ioctl struct
|
||||
*/
|
||||
struct loop_info64 {
|
||||
uint64_t lo_device;
|
||||
@@ -97,8 +97,8 @@ struct loopdev_cxt {
|
||||
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 */
|
||||
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 */
|
||||
@@ -144,11 +144,11 @@ extern int loopdev_count_by_backing_file(const char *filename, char **loopdev);
|
||||
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 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);
|
||||
@@ -163,6 +163,7 @@ 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);
|
||||
@@ -1,9 +1,10 @@
|
||||
/* Align/Truncate a string in a given screen width
|
||||
Copyright (C) 2009-2010 Free Software Foundation, Inc.
|
||||
Copyright (C) 2010-2013 Karel Zak <kzak@redhat.com>
|
||||
|
||||
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
|
||||
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.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
@@ -13,8 +14,9 @@
|
||||
|
||||
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>
|
||||
#ifndef UTIL_LINUX_MBSALIGN_H
|
||||
# define UTIL_LINUX_MBSALIGN_H
|
||||
# include <stddef.h>
|
||||
|
||||
typedef enum { MBS_ALIGN_LEFT, MBS_ALIGN_RIGHT, MBS_ALIGN_CENTER } mbs_align_t;
|
||||
|
||||
@@ -43,3 +45,12 @@ 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);
|
||||
|
||||
extern size_t mbs_safe_nwidth(const char *buf, size_t bufsz, size_t *sz);
|
||||
extern size_t mbs_safe_width(const char *s);
|
||||
|
||||
extern char *mbs_safe_encode(const char *s, size_t *width);
|
||||
extern char *mbs_safe_encode_to_buffer(const char *s, size_t *width, char *buf);
|
||||
extern size_t mbs_safe_encode_size(size_t bytes);
|
||||
|
||||
#endif /* UTIL_LINUX_MBSALIGN_H */
|
||||
@@ -73,10 +73,13 @@ struct minix3_super_block {
|
||||
#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 MINIX_SUPER_MAGIC 0x137F /* minix V1 fs, 14 char names */
|
||||
#define MINIX_SUPER_MAGIC2 0x138F /* minix V1 fs, 30 char names */
|
||||
|
||||
#define MINIX2_SUPER_MAGIC 0x2468 /* minix V2 fs, 14 char names */
|
||||
#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 */
|
||||
@@ -0,0 +1,11 @@
|
||||
#ifndef UTIL_LINUX_BOOTTIME_H
|
||||
#define UTIL_LINUX_BOOTTIME_H
|
||||
|
||||
/*
|
||||
* Uses clock_gettime() that requires $CLOCKGETTIME_LIBS
|
||||
*/
|
||||
extern int get_boot_time(struct timeval *boot_time);
|
||||
|
||||
extern int gettime_monotonic(struct timeval *tv);
|
||||
|
||||
#endif /* UTIL_LINUX_BOOTTIME_H */
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
# include <sched.h>
|
||||
|
||||
# ifndef CLONE_NEWSNS
|
||||
# ifndef CLONE_NEWNS
|
||||
# define CLONE_NEWNS 0x00020000
|
||||
# endif
|
||||
# ifndef CLONE_NEWUTS
|
||||
@@ -23,16 +23,18 @@
|
||||
# define CLONE_NEWPID 0x20000000
|
||||
# endif
|
||||
|
||||
# ifndef HAVE_UNSHARE
|
||||
# if !defined(HAVE_UNSHARE) || !defined(HAVE_SETNS)
|
||||
# include <sys/syscall.h>
|
||||
# endif
|
||||
|
||||
# if !defined(HAVE_UNSHARE) && defined(SYS_unshare)
|
||||
static inline int unshare(int flags)
|
||||
{
|
||||
return syscall(SYS_unshare, flags);
|
||||
}
|
||||
# endif
|
||||
|
||||
# ifndef HAVE_SETNS
|
||||
# include <sys/syscall.h>
|
||||
# if !defined(HAVE_SETNS) && defined(SYS_setns)
|
||||
static inline int setns(int fd, int nstype)
|
||||
{
|
||||
return syscall(SYS_setns, fd, nstype);
|
||||
@@ -48,6 +48,9 @@ static inline const char *option_to_longopt(int c, const struct option *opts)
|
||||
* 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 maximal number of the options in the group is 15 (size of the array is
|
||||
* 16, last is zero).
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
@@ -73,16 +76,21 @@ static inline void err_exclusive_options(
|
||||
if (status[e] == 0)
|
||||
status[e] = c;
|
||||
else if (status[e] != c) {
|
||||
fprintf(stderr, _("%s: options "),
|
||||
size_t ct = 0;
|
||||
|
||||
fprintf(stderr, _("%s: these options are "
|
||||
"mutually exclusive:"),
|
||||
program_invocation_short_name);
|
||||
for (op = excl[e]; *op; op++) {
|
||||
if (opts)
|
||||
fprintf(stderr, "--%s ",
|
||||
option_to_longopt(*op, opts));
|
||||
|
||||
for (op = excl[e];
|
||||
ct + 1 < ARRAY_SIZE(excl[0]) && *op;
|
||||
op++, ct++) {
|
||||
const char *n = option_to_longopt(*op, opts);
|
||||
if (n)
|
||||
fprintf(stderr, " --%s", n);
|
||||
else
|
||||
fprintf(stderr, "-%c ", *op);
|
||||
fprintf(stderr, " -%c", *op);
|
||||
}
|
||||
fprintf(stderr, _("are mutually exclusive."));
|
||||
fputc('\n', stderr);
|
||||
exit(OPTUTILS_EXIT_CODE);
|
||||
}
|
||||
@@ -6,7 +6,11 @@
|
||||
*/
|
||||
#ifndef UTIL_LINUX_PAMFAIL_H
|
||||
#include <security/pam_appl.h>
|
||||
#include <security/pam_misc.h>
|
||||
#ifdef HAVE_SECURITY_PAM_MISC_H
|
||||
# include <security/pam_misc.h>
|
||||
#elif defined(HAVE_SECURITY_OPENPAM_H)
|
||||
# include <security/openpam.h>
|
||||
#endif
|
||||
#include "c.h"
|
||||
|
||||
static inline int
|
||||
@@ -4,6 +4,8 @@
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
extern char *path_strdup(const char *path, ...)
|
||||
__attribute__ ((__format__ (__printf__, 1, 2)));
|
||||
extern FILE *path_fopen(const char *mode, int exit_on_err, const char *path, ...)
|
||||
__attribute__ ((__format__ (__printf__, 3, 4)));
|
||||
extern void path_read_str(char *result, size_t len, const char *path, ...)
|
||||
@@ -31,11 +31,14 @@
|
||||
#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"
|
||||
@@ -48,6 +51,9 @@
|
||||
#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 */
|
||||
@@ -63,6 +69,7 @@
|
||||
|
||||
/* used in term-utils/agetty.c */
|
||||
#define _PATH_ISSUE "/etc/issue"
|
||||
#define _PATH_OS_RELEASE "/etc/os-release"
|
||||
#define _PATH_NUMLOCK_ON _PATH_LOCALSTATEDIR "/numlock-on"
|
||||
|
||||
#define _PATH_LOGINDEFS "/etc/login.defs"
|
||||
@@ -84,6 +91,9 @@
|
||||
#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_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"
|
||||
@@ -125,6 +135,8 @@
|
||||
# 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"
|
||||
@@ -139,7 +151,12 @@
|
||||
#define _PATH_DEV_BYPARTUUID "/dev/disk/by-partuuid"
|
||||
|
||||
/* hwclock paths */
|
||||
#define _PATH_ADJPATH "/etc/adjtime"
|
||||
#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"
|
||||
@@ -0,0 +1,32 @@
|
||||
#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);
|
||||
|
||||
struct proc_processes {
|
||||
DIR *dir;
|
||||
|
||||
const char *fltr_name;
|
||||
uid_t fltr_uid;
|
||||
|
||||
unsigned int has_fltr_name : 1,
|
||||
has_fltr_uid : 1;
|
||||
};
|
||||
|
||||
extern struct proc_processes *proc_open_processes(void);
|
||||
extern void proc_close_processes(struct proc_processes *ps);
|
||||
|
||||
extern void proc_processes_filter_by_name(struct proc_processes *ps, const char *name);
|
||||
extern void proc_processes_filter_by_uid(struct proc_processes *ps, uid_t uid);
|
||||
extern int proc_next_pid(struct proc_processes *ps, pid_t *pid);
|
||||
|
||||
|
||||
#endif /* UTIL_LINUX_PROCUTILS */
|
||||
@@ -0,0 +1,156 @@
|
||||
#ifndef UTIL_LINUX_PT_BSD_H
|
||||
#define UTIL_LINUX_PT_BSD_H
|
||||
|
||||
#define BSD_MAXPARTITIONS 16
|
||||
#define BSD_FS_UNUSED 0
|
||||
|
||||
#ifndef BSD_DISKMAGIC
|
||||
# define BSD_DISKMAGIC ((uint32_t) 0x82564557)
|
||||
#endif
|
||||
|
||||
#define BSD_LINUX_BOOTDIR "/usr/ucb/mdec"
|
||||
|
||||
#if defined (__alpha__) || defined (__powerpc__) || \
|
||||
defined (__ia64__) || defined (__hppa__)
|
||||
# define BSD_LABELSECTOR 0
|
||||
# define BSD_LABELOFFSET 64
|
||||
#else
|
||||
# define BSD_LABELSECTOR 1
|
||||
# define BSD_LABELOFFSET 0
|
||||
#endif
|
||||
|
||||
#define BSD_BBSIZE 8192 /* size of boot area, with label */
|
||||
#define BSD_SBSIZE 8192 /* max size of fs superblock */
|
||||
|
||||
struct bsd_disklabel {
|
||||
uint32_t d_magic; /* the magic number */
|
||||
int16_t d_type; /* drive type */
|
||||
int16_t d_subtype; /* controller/d_type specific */
|
||||
char d_typename[16]; /* type name, e.g. "eagle" */
|
||||
char d_packname[16]; /* pack identifier */
|
||||
|
||||
/* disk geometry: */
|
||||
uint32_t d_secsize; /* # of bytes per sector */
|
||||
uint32_t d_nsectors; /* # of data sectors per track */
|
||||
uint32_t d_ntracks; /* # of tracks per cylinder */
|
||||
uint32_t d_ncylinders; /* # of data cylinders per unit */
|
||||
uint32_t d_secpercyl; /* # of data sectors per cylinder */
|
||||
uint32_t d_secperunit; /* # of data sectors per unit */
|
||||
|
||||
/*
|
||||
* Spares (bad sector replacements) below
|
||||
* are not counted in d_nsectors or d_secpercyl.
|
||||
* Spare sectors are assumed to be physical sectors
|
||||
* which occupy space at the end of each track and/or cylinder.
|
||||
*/
|
||||
uint16_t d_sparespertrack; /* # of spare sectors per track */
|
||||
uint16_t d_sparespercyl; /* # of spare sectors per cylinder */
|
||||
|
||||
/*
|
||||
* Alternate cylinders include maintenance, replacement,
|
||||
* configuration description areas, etc.
|
||||
*/
|
||||
uint32_t d_acylinders; /* # of alt. cylinders per unit */
|
||||
|
||||
/* hardware characteristics: */
|
||||
/*
|
||||
* d_interleave, d_trackskew and d_cylskew describe perturbations
|
||||
* in the media format used to compensate for a slow controller.
|
||||
* Interleave is physical sector interleave, set up by the formatter
|
||||
* or controller when formatting. When interleaving is in use,
|
||||
* logically adjacent sectors are not physically contiguous,
|
||||
* but instead are separated by some number of sectors.
|
||||
* It is specified as the ratio of physical sectors traversed
|
||||
* per logical sector. Thus an interleave of 1:1 implies contiguous
|
||||
* layout, while 2:1 implies that logical sector 0 is separated
|
||||
* by one sector from logical sector 1.
|
||||
* d_trackskew is the offset of sector 0 on track N
|
||||
* relative to sector 0 on track N-1 on the same cylinder.
|
||||
* Finally, d_cylskew is the offset of sector 0 on cylinder N
|
||||
* relative to sector 0 on cylinder N-1.
|
||||
*/
|
||||
uint16_t d_rpm; /* rotational speed */
|
||||
uint16_t d_interleave; /* hardware sector interleave */
|
||||
uint16_t d_trackskew; /* sector 0 skew, per track */
|
||||
uint16_t d_cylskew; /* sector 0 skew, per cylinder */
|
||||
uint32_t d_headswitch; /* head switch time, usec */
|
||||
uint32_t d_trkseek; /* track-to-track seek, usec */
|
||||
uint32_t d_flags; /* generic flags */
|
||||
uint32_t d_drivedata[5]; /* drive-type specific information */
|
||||
uint32_t d_spare[5]; /* reserved for future use */
|
||||
uint32_t d_magic2; /* the magic number (again) */
|
||||
uint16_t d_checksum; /* xor of data incl. partitions */
|
||||
|
||||
/* filesystem and partition information: */
|
||||
uint16_t d_npartitions; /* number of partitions in following */
|
||||
uint32_t d_bbsize; /* size of boot area at sn0, bytes */
|
||||
uint32_t d_sbsize; /* max size of fs superblock, bytes */
|
||||
|
||||
struct bsd_partition { /* the partition table */
|
||||
uint32_t p_size; /* number of sectors in partition */
|
||||
uint32_t p_offset; /* starting sector */
|
||||
uint32_t p_fsize; /* filesystem basic fragment size */
|
||||
uint8_t p_fstype; /* filesystem type, see below */
|
||||
uint8_t p_frag; /* filesystem fragments per block */
|
||||
uint16_t p_cpg; /* filesystem cylinders per group */
|
||||
} __attribute__((packed)) d_partitions[BSD_MAXPARTITIONS]; /* actually may be more */
|
||||
} __attribute__((packed));
|
||||
|
||||
|
||||
/* d_type values: */
|
||||
#define BSD_DTYPE_SMD 1 /* SMD, XSMD; VAX hp/up */
|
||||
#define BSD_DTYPE_MSCP 2 /* MSCP */
|
||||
#define BSD_DTYPE_DEC 3 /* other DEC (rk, rl) */
|
||||
#define BSD_DTYPE_SCSI 4 /* SCSI */
|
||||
#define BSD_DTYPE_ESDI 5 /* ESDI interface */
|
||||
#define BSD_DTYPE_ST506 6 /* ST506 etc. */
|
||||
#define BSD_DTYPE_HPIB 7 /* CS/80 on HP-IB */
|
||||
#define BSD_DTYPE_HPFL 8 /* HP Fiber-link */
|
||||
#define BSD_DTYPE_FLOPPY 10 /* floppy */
|
||||
|
||||
/* d_subtype values: */
|
||||
#define BSD_DSTYPE_INDOSPART 0x8 /* is inside dos partition */
|
||||
#define BSD_DSTYPE_DOSPART(s) ((s) & 3) /* dos partition number */
|
||||
#define BSD_DSTYPE_GEOMETRY 0x10 /* drive params in label */
|
||||
|
||||
/*
|
||||
* Filesystem type and version.
|
||||
* Used to interpret other filesystem-specific
|
||||
* per-partition information.
|
||||
*/
|
||||
#define BSD_FS_UNUSED 0 /* unused */
|
||||
#define BSD_FS_SWAP 1 /* swap */
|
||||
#define BSD_FS_V6 2 /* Sixth Edition */
|
||||
#define BSD_FS_V7 3 /* Seventh Edition */
|
||||
#define BSD_FS_SYSV 4 /* System V */
|
||||
#define BSD_FS_V71K 5 /* V7 with 1K blocks (4.1, 2.9) */
|
||||
#define BSD_FS_V8 6 /* Eighth Edition, 4K blocks */
|
||||
#define BSD_FS_BSDFFS 7 /* 4.2BSD fast file system */
|
||||
#define BSD_FS_BSDLFS 9 /* 4.4BSD log-structured file system */
|
||||
#define BSD_FS_OTHER 10 /* in use, but unknown/unsupported */
|
||||
#define BSD_FS_HPFS 11 /* OS/2 high-performance file system */
|
||||
#define BSD_FS_ISO9660 12 /* ISO-9660 filesystem (cdrom) */
|
||||
#define BSD_FS_ISOFS BSD_FS_ISO9660
|
||||
#define BSD_FS_BOOT 13 /* partition contains bootstrap */
|
||||
#define BSD_FS_ADOS 14 /* AmigaDOS fast file system */
|
||||
#define BSD_FS_HFS 15 /* Macintosh HFS */
|
||||
#define BSD_FS_ADVFS 16 /* Digital Unix AdvFS */
|
||||
|
||||
/* this is annoying, but it's also the way it is :-( */
|
||||
#ifdef __alpha__
|
||||
#define BSD_FS_EXT2 8 /* ext2 file system */
|
||||
#else
|
||||
#define BSD_FS_MSDOS 8 /* MS-DOS file system */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* flags shared by various drives:
|
||||
*/
|
||||
#define BSD_D_REMOVABLE 0x01 /* removable media */
|
||||
#define BSD_D_ECC 0x02 /* supports ECC */
|
||||
#define BSD_D_BADSECT 0x04 /* supports bad sector forw. */
|
||||
#define BSD_D_RAMDISK 0x08 /* disk emulator */
|
||||
#define BSD_D_CHAIN 0x10 /* can do back-back transfers */
|
||||
#define BSD_D_DOSPART 0x20 /* within MSDOS partition */
|
||||
|
||||
#endif /* UTIL_LINUX_PT_BSD_H */
|
||||
@@ -0,0 +1,105 @@
|
||||
{0x00, N_("Empty")},
|
||||
{0x01, N_("FAT12")},
|
||||
{0x02, N_("XENIX root")},
|
||||
{0x03, N_("XENIX usr")},
|
||||
{0x04, N_("FAT16 <32M")},
|
||||
{0x05, N_("Extended")}, /* DOS 3.3+ extended partition */
|
||||
{0x06, N_("FAT16")}, /* DOS 16-bit >=32M */
|
||||
{0x07, N_("HPFS/NTFS/exFAT")}, /* OS/2 IFS, eg, HPFS or NTFS or QNX or exFAT */
|
||||
{0x08, N_("AIX")}, /* AIX boot (AIX -- PS/2 port) or SplitDrive */
|
||||
{0x09, N_("AIX bootable")}, /* AIX data or Coherent */
|
||||
{0x0a, N_("OS/2 Boot Manager")},/* OS/2 Boot Manager */
|
||||
{0x0b, N_("W95 FAT32")},
|
||||
{0x0c, N_("W95 FAT32 (LBA)")},/* LBA really is `Extended Int 13h' */
|
||||
{0x0e, N_("W95 FAT16 (LBA)")},
|
||||
{0x0f, N_("W95 Ext'd (LBA)")},
|
||||
{0x10, N_("OPUS")},
|
||||
{0x11, N_("Hidden FAT12")},
|
||||
{0x12, N_("Compaq diagnostics")},
|
||||
{0x14, N_("Hidden FAT16 <32M")},
|
||||
{0x16, N_("Hidden FAT16")},
|
||||
{0x17, N_("Hidden HPFS/NTFS")},
|
||||
{0x18, N_("AST SmartSleep")},
|
||||
{0x1b, N_("Hidden W95 FAT32")},
|
||||
{0x1c, N_("Hidden W95 FAT32 (LBA)")},
|
||||
{0x1e, N_("Hidden W95 FAT16 (LBA)")},
|
||||
{0x24, N_("NEC DOS")},
|
||||
{0x27, N_("Hidden NTFS WinRE")},
|
||||
{0x39, N_("Plan 9")},
|
||||
{0x3c, N_("PartitionMagic recovery")},
|
||||
{0x40, N_("Venix 80286")},
|
||||
{0x41, N_("PPC PReP Boot")},
|
||||
{0x42, N_("SFS")},
|
||||
{0x4d, N_("QNX4.x")},
|
||||
{0x4e, N_("QNX4.x 2nd part")},
|
||||
{0x4f, N_("QNX4.x 3rd part")},
|
||||
{0x50, N_("OnTrack DM")},
|
||||
{0x51, N_("OnTrack DM6 Aux1")}, /* (or Novell) */
|
||||
{0x52, N_("CP/M")}, /* CP/M or Microport SysV/AT */
|
||||
{0x53, N_("OnTrack DM6 Aux3")},
|
||||
{0x54, N_("OnTrackDM6")},
|
||||
{0x55, N_("EZ-Drive")},
|
||||
{0x56, N_("Golden Bow")},
|
||||
{0x5c, N_("Priam Edisk")},
|
||||
{0x61, N_("SpeedStor")},
|
||||
{0x63, N_("GNU HURD or SysV")}, /* GNU HURD or Mach or Sys V/386 (such as ISC UNIX) */
|
||||
{0x64, N_("Novell Netware 286")},
|
||||
{0x65, N_("Novell Netware 386")},
|
||||
{0x70, N_("DiskSecure Multi-Boot")},
|
||||
{0x75, N_("PC/IX")},
|
||||
{0x80, N_("Old Minix")}, /* Minix 1.4a and earlier */
|
||||
{0x81, N_("Minix / old Linux")},/* Minix 1.4b and later */
|
||||
{0x82, N_("Linux swap / Solaris")},
|
||||
{0x83, N_("Linux")},
|
||||
{0x84, N_("OS/2 hidden C: drive")},
|
||||
{0x85, N_("Linux extended")},
|
||||
{0x86, N_("NTFS volume set")},
|
||||
{0x87, N_("NTFS volume set")},
|
||||
{0x88, N_("Linux plaintext")},
|
||||
{0x8e, N_("Linux LVM")},
|
||||
{0x93, N_("Amoeba")},
|
||||
{0x94, N_("Amoeba BBT")}, /* (bad block table) */
|
||||
{0x9f, N_("BSD/OS")}, /* BSDI */
|
||||
{0xa0, N_("IBM Thinkpad hibernation")},
|
||||
{0xa5, N_("FreeBSD")}, /* various BSD flavours */
|
||||
{0xa6, N_("OpenBSD")},
|
||||
{0xa7, N_("NeXTSTEP")},
|
||||
{0xa8, N_("Darwin UFS")},
|
||||
{0xa9, N_("NetBSD")},
|
||||
{0xab, N_("Darwin boot")},
|
||||
{0xaf, N_("HFS / HFS+")},
|
||||
{0xb7, N_("BSDI fs")},
|
||||
{0xb8, N_("BSDI swap")},
|
||||
{0xbb, N_("Boot Wizard hidden")},
|
||||
{0xbe, N_("Solaris boot")},
|
||||
{0xbf, N_("Solaris")},
|
||||
{0xc1, N_("DRDOS/sec (FAT-12)")},
|
||||
{0xc4, N_("DRDOS/sec (FAT-16 < 32M)")},
|
||||
{0xc6, N_("DRDOS/sec (FAT-16)")},
|
||||
{0xc7, N_("Syrinx")},
|
||||
{0xda, N_("Non-FS data")},
|
||||
{0xdb, N_("CP/M / CTOS / ...")},/* CP/M or Concurrent CP/M or
|
||||
Concurrent DOS or CTOS */
|
||||
{0xde, N_("Dell Utility")}, /* Dell PowerEdge Server utilities */
|
||||
{0xdf, N_("BootIt")}, /* BootIt EMBRM */
|
||||
{0xe1, N_("DOS access")}, /* DOS access or SpeedStor 12-bit FAT
|
||||
extended partition */
|
||||
{0xe3, N_("DOS R/O")}, /* DOS R/O or SpeedStor */
|
||||
{0xe4, N_("SpeedStor")}, /* SpeedStor 16-bit FAT extended
|
||||
partition < 1024 cyl. */
|
||||
{0xeb, N_("BeOS fs")},
|
||||
{0xee, N_("GPT")}, /* Intel EFI GUID Partition Table */
|
||||
{0xef, N_("EFI (FAT-12/16/32)")},/* Intel EFI System Partition */
|
||||
{0xf0, N_("Linux/PA-RISC boot")},/* Linux/PA-RISC boot loader */
|
||||
{0xf1, N_("SpeedStor")},
|
||||
{0xf4, N_("SpeedStor")}, /* SpeedStor large partition */
|
||||
{0xf2, N_("DOS secondary")}, /* DOS 3.3+ secondary */
|
||||
{0xfb, N_("VMware VMFS")},
|
||||
{0xfc, N_("VMware VMKCORE")}, /* VMware kernel dump partition */
|
||||
{0xfd, N_("Linux raid autodetect")},/* New (2.2.x) raid partition with
|
||||
autodetect using persistent
|
||||
superblock */
|
||||
{0xfe, N_("LANstep")}, /* SpeedStor >1024 cyl. or LANstep */
|
||||
{0xff, N_("BBT")}, /* Xenix Bad Block Table */
|
||||
|
||||
{ 0, 0 }
|
||||
@@ -0,0 +1,178 @@
|
||||
#ifndef UTIL_LINUX_PT_MBR_H
|
||||
#define UTIL_LINUX_PT_MBR_H
|
||||
|
||||
struct dos_partition {
|
||||
unsigned char boot_ind; /* 0x80 - active */
|
||||
unsigned char bh, bs, bc; /* begin CHS */
|
||||
unsigned char sys_ind;
|
||||
unsigned char eh, es, ec; /* end CHS */
|
||||
unsigned char start_sect[4];
|
||||
unsigned char nr_sects[4];
|
||||
} __attribute__((packed));
|
||||
|
||||
#define MBR_PT_OFFSET 0x1be
|
||||
|
||||
static inline struct dos_partition *mbr_get_partition(unsigned char *mbr, int i)
|
||||
{
|
||||
return (struct dos_partition *)
|
||||
(mbr + MBR_PT_OFFSET + (i * sizeof(struct dos_partition)));
|
||||
}
|
||||
|
||||
/* assemble badly aligned little endian integer */
|
||||
static inline unsigned int __dos_assemble_4le(const unsigned char *p)
|
||||
{
|
||||
return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
|
||||
}
|
||||
|
||||
static inline void __dos_store_4le(unsigned char *p, unsigned int val)
|
||||
{
|
||||
p[0] = (val & 0xff);
|
||||
p[1] = ((val >> 8) & 0xff);
|
||||
p[2] = ((val >> 16) & 0xff);
|
||||
p[3] = ((val >> 24) & 0xff);
|
||||
}
|
||||
|
||||
static inline unsigned int dos_partition_get_start(struct dos_partition *p)
|
||||
{
|
||||
return __dos_assemble_4le(&(p->start_sect[0]));
|
||||
}
|
||||
|
||||
static inline void dos_partition_set_start(struct dos_partition *p, unsigned int n)
|
||||
{
|
||||
__dos_store_4le(p->start_sect, n);
|
||||
}
|
||||
|
||||
static inline unsigned int dos_partition_get_size(struct dos_partition *p)
|
||||
{
|
||||
return __dos_assemble_4le(&(p->nr_sects[0]));
|
||||
}
|
||||
|
||||
static inline void dos_partition_set_size(struct dos_partition *p, unsigned int n)
|
||||
{
|
||||
__dos_store_4le(p->nr_sects, n);
|
||||
}
|
||||
|
||||
static inline int mbr_is_valid_magic(const unsigned char *mbr)
|
||||
{
|
||||
return mbr[510] == 0x55 && mbr[511] == 0xaa ? 1 : 0;
|
||||
}
|
||||
|
||||
static inline void mbr_set_magic(unsigned char *b)
|
||||
{
|
||||
b[510] = 0x55;
|
||||
b[511] = 0xaa;
|
||||
}
|
||||
|
||||
static inline unsigned int mbr_get_id(const unsigned char *mbr)
|
||||
{
|
||||
return __dos_assemble_4le(&mbr[440]);
|
||||
}
|
||||
|
||||
static inline void mbr_set_id(unsigned char *b, unsigned int id)
|
||||
{
|
||||
__dos_store_4le(&b[440], id);
|
||||
}
|
||||
|
||||
enum {
|
||||
MBR_EMPTY_PARTITION = 0x00,
|
||||
MBR_FAT12_PARTITION = 0x01,
|
||||
MBR_XENIX_ROOT_PARTITION = 0x02,
|
||||
MBR_XENIX_USR_PARTITION = 0x03,
|
||||
MBR_FAT16_LESS32M_PARTITION = 0x04,
|
||||
MBR_DOS_EXTENDED_PARTITION = 0x05,
|
||||
MBR_FAT16_PARTITION = 0x06, /* DOS 16-bit >=32M */
|
||||
MBR_HPFS_NTFS_PARTITION = 0x07, /* OS/2 IFS, eg, HPFS or NTFS or QNX */
|
||||
MBR_AIX_PARTITION = 0x08, /* AIX boot (AIX -- PS/2 port) or SplitDrive */
|
||||
MBR_AIX_BOOTABLE_PARTITION = 0x09, /* AIX data or Coherent */
|
||||
MBR_OS2_BOOTMNGR_PARTITION = 0x0a, /* OS/2 Boot Manager */
|
||||
MBR_W95_FAT32_PARTITION = 0x0b,
|
||||
MBR_W95_FAT32_LBA_PARTITION = 0x0c, /* LBA really is `Extended Int 13h' */
|
||||
MBR_W95_FAT16_LBA_PARTITION = 0x0e,
|
||||
MBR_W95_EXTENDED_PARTITION = 0x0f,
|
||||
MBR_OPUS_PARTITION = 0x10,
|
||||
MBR_HIDDEN_FAT12_PARTITION = 0x11,
|
||||
MBR_COMPAQ_DIAGNOSTICS_PARTITION = 0x12,
|
||||
MBR_HIDDEN_FAT16_L32M_PARTITION = 0x14,
|
||||
MBR_HIDDEN_FAT16_PARTITION = 0x16,
|
||||
MBR_HIDDEN_HPFS_NTFS_PARTITION = 0x17,
|
||||
MBR_AST_SMARTSLEEP_PARTITION = 0x18,
|
||||
MBR_HIDDEN_W95_FAT32_PARTITION = 0x1b,
|
||||
MBR_HIDDEN_W95_FAT32LBA_PARTITION = 0x1c,
|
||||
MBR_HIDDEN_W95_FAT16LBA_PARTITION = 0x1e,
|
||||
MBR_NEC_DOS_PARTITION = 0x24,
|
||||
MBR_PLAN9_PARTITION = 0x39,
|
||||
MBR_PARTITIONMAGIC_PARTITION = 0x3c,
|
||||
MBR_VENIX80286_PARTITION = 0x40,
|
||||
MBR_PPC_PREP_BOOT_PARTITION = 0x41,
|
||||
MBR_SFS_PARTITION = 0x42,
|
||||
MBR_QNX_4X_PARTITION = 0x4d,
|
||||
MBR_QNX_4X_2ND_PARTITION = 0x4e,
|
||||
MBR_QNX_4X_3RD_PARTITION = 0x4f,
|
||||
MBR_DM_PARTITION = 0x50,
|
||||
MBR_DM6_AUX1_PARTITION = 0x51, /* (or Novell) */
|
||||
MBR_CPM_PARTITION = 0x52, /* CP/M or Microport SysV/AT */
|
||||
MBR_DM6_AUX3_PARTITION = 0x53,
|
||||
MBR_DM6_PARTITION = 0x54,
|
||||
MBR_EZ_DRIVE_PARTITION = 0x55,
|
||||
MBR_GOLDEN_BOW_PARTITION = 0x56,
|
||||
MBR_PRIAM_EDISK_PARTITION = 0x5c,
|
||||
MBR_SPEEDSTOR_PARTITION = 0x61,
|
||||
MBR_GNU_HURD_PARTITION = 0x63, /* GNU HURD or Mach or Sys V/386 (such as ISC UNIX) */
|
||||
MBR_UNIXWARE_PARTITION = MBR_GNU_HURD_PARTITION,
|
||||
MBR_NETWARE_286_PARTITION = 0x64,
|
||||
MBR_NETWARE_386_PARTITION = 0x65,
|
||||
MBR_DISKSECURE_MULTIBOOT_PARTITION = 0x70,
|
||||
MBR_PC_IX_PARTITION = 0x75,
|
||||
MBR_OLD_MINIX_PARTITION = 0x80, /* Minix 1.4a and earlier */
|
||||
MBR_MINIX_PARTITION = 0x81, /* Minix 1.4b and later */
|
||||
MBR_LINUX_SWAP_PARTITION = 0x82,
|
||||
MBR_SOLARIS_X86_PARTITION = MBR_LINUX_SWAP_PARTITION,
|
||||
MBR_LINUX_DATA_PARTITION = 0x83,
|
||||
MBR_OS2_HIDDEN_DRIVE_PARTITION = 0x84,
|
||||
MBR_LINUX_EXTENDED_PARTITION = 0x85,
|
||||
MBR_NTFS_VOL_SET1_PARTITION = 0x86,
|
||||
MBR_NTFS_VOL_SET2_PARTITION = 0x87,
|
||||
MBR_LINUX_PLAINTEXT_PARTITION = 0x88,
|
||||
MBR_LINUX_LVM_PARTITION = 0x8e,
|
||||
MBR_AMOEBA_PARTITION = 0x93,
|
||||
MBR_AMOEBA_BBT_PARTITION = 0x94, /* (bad block table) */
|
||||
MBR_BSD_OS_PARTITION = 0x9f, /* BSDI */
|
||||
MBR_THINKPAD_HIBERNATION_PARTITION = 0xa0,
|
||||
MBR_FREEBSD_PARTITION = 0xa5, /* various BSD flavours */
|
||||
MBR_OPENBSD_PARTITION = 0xa6,
|
||||
MBR_NEXTSTEP_PARTITION = 0xa7,
|
||||
MBR_DARWIN_UFS_PARTITION = 0xa8,
|
||||
MBR_NETBSD_PARTITION = 0xa9,
|
||||
MBR_DARWIN_BOOT_PARTITION = 0xab,
|
||||
MBR_HFS_HFS_PARTITION = 0xaf,
|
||||
MBR_BSDI_FS_PARTITION = 0xb7,
|
||||
MBR_BSDI_SWAP_PARTITION = 0xb8,
|
||||
MBR_BOOTWIZARD_HIDDEN_PARTITION = 0xbb,
|
||||
MBR_SOLARIS_BOOT_PARTITION = 0xbe,
|
||||
MBR_SOLARIS_PARTITION = 0xbf,
|
||||
MBR_DRDOS_FAT12_PARTITION = 0xc1,
|
||||
MBR_DRDOS_FAT16_L32M_PARTITION = 0xc4,
|
||||
MBR_DRDOS_FAT16_PARTITION = 0xc6,
|
||||
MBR_SYRINX_PARTITION = 0xc7,
|
||||
MBR_NONFS_DATA_PARTITION = 0xda,
|
||||
MBR_CPM_CTOS_PARTITION = 0xdb, /* CP/M or Concurrent CP/M or Concurrent DOS or CTOS */
|
||||
MBR_DELL_UTILITY_PARTITION = 0xde, /* Dell PowerEdge Server utilities */
|
||||
MBR_BOOTIT_PARTITION = 0xdf, /* BootIt EMBRM */
|
||||
MBR_DOS_ACCESS_PARTITION = 0xe1, /* DOS access or SpeedStor 12-bit FAT extended partition */
|
||||
MBR_DOS_RO_PARTITION = 0xe3, /* DOS R/O or SpeedStor */
|
||||
MBR_SPEEDSTOR_EXTENDED_PARTITION = 0xe4, /* SpeedStor 16-bit FAT extended partition < 1024 cyl. */
|
||||
MBR_BEOS_FS_PARTITION = 0xeb,
|
||||
MBR_GPT_PARTITION = 0xee, /* Intel EFI GUID Partition Table */
|
||||
MBR_EFI_SYSTEM_PARTITION = 0xef, /* Intel EFI System Partition */
|
||||
MBR_LINUX_PARISC_BOOT_PARTITION = 0xf0, /* Linux/PA-RISC boot loader */
|
||||
MBR_SPEEDSTOR1_PARTITION = 0xf1,
|
||||
MBR_SPEEDSTOR2_PARTITION = 0xf4, /* SpeedStor large partition */
|
||||
MBR_DOS_SECONDARY_PARTITION = 0xf2, /* DOS 3.3+ secondary */
|
||||
MBR_VMWARE_VMFS_PARTITION = 0xfb,
|
||||
MBR_VMWARE_VMKCORE_PARTITION = 0xfc, /* VMware kernel dump partition */
|
||||
MBR_LINUX_RAID_PARTITION = 0xfd, /* New (2.2.x) raid partition with autodetect using persistent superblock */
|
||||
MBR_LANSTEP_PARTITION = 0xfe, /* SpeedStor >1024 cyl. or LANstep */
|
||||
MBR_XENIX_BBT_PARTITION = 0xff, /* Xenix Bad Block Table */
|
||||
};
|
||||
|
||||
#endif /* UTIL_LINUX_PT_MBR_H */
|
||||
@@ -0,0 +1,110 @@
|
||||
#ifndef UTIL_LINUX_PT_SUN_H
|
||||
#define UTIL_LINUX_PT_SUN_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define SGI_LABEL_MAGIC 0x0be5a941
|
||||
|
||||
#define SGI_MAXPARTITIONS 16
|
||||
#define SGI_MAXVOLUMES 15
|
||||
|
||||
/* partition types */
|
||||
enum {
|
||||
SGI_TYPE_VOLHDR = 0x00,
|
||||
SGI_TYPE_TRKREPL = 0x01,
|
||||
SGI_TYPE_SECREPL = 0x02,
|
||||
SGI_TYPE_SWAP = 0x03,
|
||||
SGI_TYPE_BSD = 0x04,
|
||||
SGI_TYPE_SYSV = 0x05,
|
||||
SGI_TYPE_ENTIRE_DISK = 0x06,
|
||||
SGI_TYPE_EFS = 0x07,
|
||||
SGI_TYPE_LVOL = 0x08,
|
||||
SGI_TYPE_RLVOL = 0x09,
|
||||
SGI_TYPE_XFS = 0x0a,
|
||||
SGI_TYPE_XFSLOG = 0x0b,
|
||||
SGI_TYPE_XLV = 0x0c,
|
||||
SGI_TYPE_XVM = 0x0d
|
||||
};
|
||||
|
||||
struct sgi_device_parameter {
|
||||
unsigned char skew;
|
||||
unsigned char gap1;
|
||||
unsigned char gap2;
|
||||
unsigned char sparecyl;
|
||||
|
||||
uint16_t pcylcount;
|
||||
uint16_t head_vol0;
|
||||
uint16_t ntrks; /* tracks in cyl 0 or vol 0 */
|
||||
|
||||
unsigned char cmd_tag_queue_depth;
|
||||
unsigned char unused0;
|
||||
|
||||
uint16_t unused1;
|
||||
uint16_t nsect; /* sectors/tracks in cyl 0 or vol 0 */
|
||||
uint16_t bytes;
|
||||
uint16_t ilfact;
|
||||
uint32_t flags; /* SGI_DEVPARAM_* controller flags */
|
||||
uint32_t datarate;
|
||||
uint32_t retries_on_error;
|
||||
uint32_t ms_per_word;
|
||||
uint16_t xylogics_gap1;
|
||||
uint16_t xylogics_syncdelay;
|
||||
uint16_t xylogics_readdelay;
|
||||
uint16_t xylogics_gap2;
|
||||
uint16_t xylogics_readgate;
|
||||
uint16_t xylogics_writecont;
|
||||
} __attribute__((packed));
|
||||
|
||||
enum {
|
||||
SGI_DEVPARAM_SECTOR_SLIP = 0x01,
|
||||
SGI_DEVPARAM_SECTOR_FWD = 0x02,
|
||||
SGI_DEVPARAM_TRACK_FWD = 0x04,
|
||||
SGI_DEVPARAM_TRACK_MULTIVOL = 0x08,
|
||||
SGI_DEVPARAM_IGNORE_ERRORS = 0x10,
|
||||
SGI_DEVPARAM_RESEEK = 0x20,
|
||||
SGI_DEVPARAM_CMDTAGQ_ENABLE = 0x40
|
||||
};
|
||||
|
||||
|
||||
struct sgi_disklabel {
|
||||
uint32_t magic; /* magic number */
|
||||
uint16_t root_part_num; /* # root partition */
|
||||
uint16_t swap_part_num; /* # swap partition */
|
||||
unsigned char boot_file[16]; /* name of boot file */
|
||||
|
||||
struct sgi_device_parameter devparam; /* not used now */
|
||||
|
||||
struct sgi_volume {
|
||||
unsigned char name[8]; /* name of volume */
|
||||
uint32_t block_num; /* logical block number */
|
||||
uint32_t num_bytes; /* how big, in bytes */
|
||||
} __attribute__((packed)) volume[SGI_MAXVOLUMES];
|
||||
|
||||
struct sgi_partition {
|
||||
uint32_t num_blocks; /* size in logical blocks */
|
||||
uint32_t first_block; /* first logical block */
|
||||
uint32_t type; /* type of this partition */
|
||||
} __attribute__((packed)) partitions[SGI_MAXPARTITIONS];
|
||||
|
||||
/* checksum is the 32bit 2's complement sum of the disklabel */
|
||||
uint32_t csum; /* disk label checksum */
|
||||
uint32_t padding; /* padding */
|
||||
} __attribute__((packed));
|
||||
|
||||
static inline uint32_t sgi_pt_checksum(struct sgi_disklabel *label)
|
||||
{
|
||||
int i;
|
||||
uint32_t *ptr = (uint32_t *) label;
|
||||
uint32_t sum = 0;
|
||||
|
||||
i = sizeof(*label) / sizeof(*ptr);
|
||||
|
||||
while (i) {
|
||||
i--;
|
||||
sum -= be32_to_cpu(ptr[i]);
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
#endif /* UTIL_LINUX_PT_SUN_H */
|
||||
@@ -0,0 +1,90 @@
|
||||
#ifndef UTIL_LINUX_PT_SUN_H
|
||||
#define UTIL_LINUX_PT_SUN_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define SUN_LABEL_MAGIC 0xDABE
|
||||
|
||||
/* Supported VTOC setting */
|
||||
#define SUN_VTOC_SANITY 0x600DDEEE /* magic number */
|
||||
#define SUN_VTOC_VERSION 1
|
||||
#define SUN_MAXPARTITIONS 8
|
||||
|
||||
struct sun_disklabel {
|
||||
unsigned char label_id[128]; /* Informative text string */
|
||||
|
||||
struct sun_vtoc {
|
||||
uint32_t version; /* version */
|
||||
char volume_id[8];/* volume name */
|
||||
uint16_t nparts; /* num of partitions */
|
||||
|
||||
struct sun_info { /* partition information */
|
||||
uint16_t id; /* SUN_TAG_* */
|
||||
uint16_t flags; /* SUN_FLAG_* */
|
||||
} __attribute__ ((packed)) infos[8];
|
||||
|
||||
uint16_t padding; /* padding */
|
||||
uint32_t bootinfo[3]; /* info needed by mboot */
|
||||
uint32_t sanity; /* magic number */
|
||||
uint32_t reserved[10]; /* padding */
|
||||
uint32_t timestamp[8]; /* partition timestamp */
|
||||
} __attribute__ ((packed)) vtoc;
|
||||
|
||||
uint32_t write_reinstruct; /* sectors to skip, writes */
|
||||
uint32_t read_reinstruct; /* sectors to skip, reads */
|
||||
unsigned char spare[148]; /* padding */
|
||||
uint16_t rpm; /* disk rotational speed */
|
||||
uint16_t pcyl; /* physical cylinder count */
|
||||
uint16_t apc; /* extra sects per cylinder */
|
||||
uint16_t obs1;
|
||||
uint16_t obs2;
|
||||
uint16_t intrlv; /* interleave factor */
|
||||
uint16_t ncyl; /* data cylinder count */
|
||||
uint16_t acyl; /* alt. cylinder count */
|
||||
uint16_t nhead; /* tracks per cylinder <---- */
|
||||
uint16_t nsect; /* sectors per track <---- */
|
||||
uint16_t obs3;
|
||||
uint16_t obs4;
|
||||
|
||||
struct sun_partition { /* partitions */
|
||||
uint32_t start_cylinder;
|
||||
uint32_t num_sectors;
|
||||
} __attribute__ ((packed)) partitions[8];
|
||||
|
||||
uint16_t magic; /* magic number */
|
||||
uint16_t csum; /* label xor'd checksum */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
|
||||
#define SUN_TAG_UNASSIGNED 0x00 /* Unassigned partition */
|
||||
#define SUN_TAG_BOOT 0x01 /* Boot partition */
|
||||
#define SUN_TAG_ROOT 0x02 /* Root filesystem */
|
||||
#define SUN_TAG_SWAP 0x03 /* Swap partition */
|
||||
#define SUN_TAG_USR 0x04 /* /usr filesystem */
|
||||
#define SUN_TAG_WHOLEDISK 0x05 /* Full-disk slice */
|
||||
#define SUN_TAG_STAND 0x06 /* Stand partition */
|
||||
#define SUN_TAG_VAR 0x07 /* /var filesystem */
|
||||
#define SUN_TAG_HOME 0x08 /* /home filesystem */
|
||||
#define SUN_TAG_ALTSCTR 0x09 /* Alt sector partition */
|
||||
#define SUN_TAG_CACHE 0x0a /* Cachefs partition */
|
||||
#define SUN_TAG_RESERVED 0x0b /* SMI reserved data */
|
||||
#define SUN_TAG_LINUX_SWAP 0x82 /* Linux SWAP */
|
||||
#define SUN_TAG_LINUX_NATIVE 0x83 /* Linux filesystem */
|
||||
#define SUN_TAG_LINUX_LVM 0x8e /* Linux LVM */
|
||||
#define SUN_TAG_LINUX_RAID 0xfd /* LInux RAID */
|
||||
|
||||
#define SUN_FLAG_UNMNT 0x01 /* Unmountable partition*/
|
||||
#define SUN_FLAG_RONLY 0x10 /* Read only */
|
||||
|
||||
static inline uint16_t sun_pt_checksum(struct sun_disklabel *label)
|
||||
{
|
||||
uint16_t *ptr = ((uint16_t *) (label + 1)) - 1;
|
||||
uint16_t sum;
|
||||
|
||||
for (sum = 0; ptr >= ((uint16_t *) label);)
|
||||
sum ^= *ptr--;
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
#endif /* UTIL_LINUX_PT_SUN_H */
|
||||
@@ -8,5 +8,6 @@
|
||||
|
||||
extern int random_get_fd(void);
|
||||
extern void random_get_bytes(void *buf, size_t nbytes);
|
||||
extern const char *random_tell_source(void);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,28 @@
|
||||
/* Declarations for GNU's read utmp module.
|
||||
|
||||
Copyright (C) 1992-2007, 2009-2014 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Written by jla; revised by djm */
|
||||
|
||||
#ifndef READUTMP_H
|
||||
#define READUTMP_H
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <utmp.h>
|
||||
|
||||
int read_utmp (char const *file, size_t *n_entries, struct utmp **utmp_buf);
|
||||
|
||||
#endif /* READUTMP_H */
|
||||
@@ -0,0 +1,99 @@
|
||||
#ifndef UTIL_LINUX_STATFS_MAGIC_H
|
||||
#define UTIL_LINUX_STATFS_MAGIC_H
|
||||
|
||||
#include <sys/statfs.h>
|
||||
|
||||
/*
|
||||
* If possible then don't depend on internal libc __SWORD_TYPE type.
|
||||
*/
|
||||
#ifdef __GNUC__
|
||||
#define F_TYPE_EQUAL(a, b) (a == (__typeof__(a)) b)
|
||||
#else
|
||||
#define F_TYPE_EQUAL(a, b) (a == (__SWORD_TYPE) b)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Unfortunately, Linux kernel hedeader file <linux/magic.h> is incomplete
|
||||
* mess and kernel returns by statfs f_type many numbers that are nowhere
|
||||
* specified (in API).
|
||||
*
|
||||
* This is collection of the magic numbers.
|
||||
*/
|
||||
#define STATFS_ADFS_MAGIC 0xadf5
|
||||
#define STATFS_AFFS_MAGIC 0xadff
|
||||
#define STATFS_AFS_MAGIC 0x5346414F
|
||||
#define STATFS_AUTOFS_MAGIC 0x0187
|
||||
#define STATFS_BDEVFS_MAGIC 0x62646576
|
||||
#define STATFS_BEFS_MAGIC 0x42465331
|
||||
#define STATFS_BFS_MAGIC 0x1BADFACE
|
||||
#define STATFS_BINFMTFS_MAGIC 0x42494e4d
|
||||
#define STATFS_BTRFS_MAGIC 0x9123683E
|
||||
#define STATFS_CEPH_MAGIC 0x00c36400
|
||||
#define STATFS_CGROUP_MAGIC 0x27e0eb
|
||||
#define STATFS_CIFS_MAGIC 0xff534d42
|
||||
#define STATFS_CODA_MAGIC 0x73757245
|
||||
#define STATFS_CONFIGFS_MAGIC 0x62656570
|
||||
#define STATFS_CRAMFS_MAGIC 0x28cd3d45
|
||||
#define STATFS_DEBUGFS_MAGIC 0x64626720
|
||||
#define STATFS_DEVPTS_MAGIC 0x1cd1
|
||||
#define STATFS_ECRYPTFS_MAGIC 0xf15f
|
||||
#define STATFS_EFIVARFS_MAGIC 0xde5e81e4
|
||||
#define STATFS_EFS_MAGIC 0x414A53
|
||||
#define STATFS_EXOFS_MAGIC 0x5DF5
|
||||
#define STATFS_EXT2_MAGIC 0xEF53
|
||||
#define STATFS_EXT3_MAGIC 0xEF53
|
||||
#define STATFS_EXT4_MAGIC 0xEF53
|
||||
#define STATFS_F2FS_MAGIC 0xF2F52010
|
||||
#define STATFS_FUSE_MAGIC 0x65735546
|
||||
#define STATFS_FUTEXFS_MAGIC 0xBAD1DEA
|
||||
#define STATFS_GFS2_MAGIC 0x01161970
|
||||
#define STATFS_HFSPLUS_MAGIC 0x482b
|
||||
#define STATFS_HOSTFS_MAGIC 0x00c0ffee
|
||||
#define STATFS_HPFS_MAGIC 0xf995e849
|
||||
#define STATFS_HPPFS_MAGIC 0xb00000ee
|
||||
#define STATFS_HUGETLBFS_MAGIC 0x958458f6
|
||||
#define STATFS_ISOFS_MAGIC 0x9660
|
||||
#define STATFS_JFFS2_MAGIC 0x72b6
|
||||
#define STATFS_JFS_MAGIC 0x3153464a
|
||||
#define STATFS_LOGFS_MAGIC 0xc97e8168
|
||||
#define STATFS_MINIX2_MAGIC 0x2468
|
||||
#define STATFS_MINIX2_MAGIC2 0x2478
|
||||
#define STATFS_MINIX3_MAGIC 0x4d5a
|
||||
#define STATFS_MINIX_MAGIC 0x137F
|
||||
#define STATFS_MINIX_MAGIC2 0x138F
|
||||
#define STATFS_MQUEUE_MAGIC 0x19800202
|
||||
#define STATFS_MSDOS_MAGIC 0x4d44
|
||||
#define STATFS_NCP_MAGIC 0x564c
|
||||
#define STATFS_NFS_MAGIC 0x6969
|
||||
#define STATFS_NILFS_MAGIC 0x3434
|
||||
#define STATFS_NTFS_MAGIC 0x5346544e
|
||||
#define STATFS_OCFS2_MAGIC 0x7461636f
|
||||
#define STATFS_OMFS_MAGIC 0xC2993D87
|
||||
#define STATFS_OPENPROMFS_MAGIC 0x9fa1
|
||||
#define STATFS_PIPEFS_MAGIC 0x50495045
|
||||
#define STATFS_PROC_MAGIC 0x9fa0
|
||||
#define STATFS_PSTOREFS_MAGIC 0x6165676C
|
||||
#define STATFS_QNX4_MAGIC 0x002f
|
||||
#define STATFS_QNX6_MAGIC 0x68191122
|
||||
#define STATFS_RAMFS_MAGIC 0x858458f6
|
||||
#define STATFS_REISERFS_MAGIC 0x52654973
|
||||
#define STATFS_ROMFS_MAGIC 0x7275
|
||||
#define STATFS_SECURITYFS_MAGIC 0x73636673
|
||||
#define STATFS_SELINUXFS_MAGIC 0xf97cff8c
|
||||
#define STATFS_SMACKFS_MAGIC 0x43415d53
|
||||
#define STATFS_SMB_MAGIC 0x517B
|
||||
#define STATFS_SOCKFS_MAGIC 0x534F434B
|
||||
#define STATFS_SQUASHFS_MAGIC 0x73717368
|
||||
#define STATFS_SYSFS_MAGIC 0x62656572
|
||||
#define STATFS_TMPFS_MAGIC 0x01021994
|
||||
#define STATFS_UBIFS_MAGIC 0x24051905
|
||||
#define STATFS_UDF_MAGIC 0x15013346
|
||||
#define STATFS_UFS2_MAGIC 0x19540119
|
||||
#define STATFS_UFS_MAGIC 0x00011954
|
||||
#define STATFS_V9FS_MAGIC 0x01021997
|
||||
#define STATFS_VXFS_MAGIC 0xa501FCF5
|
||||
#define STATFS_XENFS_MAGIC 0xabba1974
|
||||
#define STATFS_XFS_MAGIC 0x58465342
|
||||
|
||||
#endif /* UTIL_LINUX_STATFS_MAGIC_H */
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
#ifndef UTIL_LINUX_STRUTILS
|
||||
#define UTIL_LINUX_STRUTILS
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <inttypes.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <ctype.h>
|
||||
|
||||
/* default strtoxx_or_err() exit code */
|
||||
#ifndef STRTOXX_EXIT_CODE
|
||||
@@ -11,6 +13,7 @@
|
||||
#endif
|
||||
|
||||
|
||||
extern int parse_size(const char *str, uintmax_t *res, int *power);
|
||||
extern int strtosize(const char *str, uintmax_t *res);
|
||||
extern uintmax_t strtosize_or_err(const char *str, const char *errmesg);
|
||||
|
||||
@@ -28,6 +31,11 @@ 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);
|
||||
|
||||
extern void strtotimeval_or_err(const char *str, struct timeval *tv,
|
||||
const char *errmesg);
|
||||
|
||||
extern int isdigit_string(const char *str);
|
||||
|
||||
#ifndef HAVE_MEMPCPY
|
||||
extern void *mempcpy(void *restrict dest, const void *restrict src, size_t n);
|
||||
#endif
|
||||
@@ -48,6 +56,25 @@ static inline void xstrncpy(char *dest, const char *src, size_t n)
|
||||
dest[n-1] = 0;
|
||||
}
|
||||
|
||||
static inline char *strdup_to_offset(void *stru, size_t offset, const char *str)
|
||||
{
|
||||
char *n = NULL;
|
||||
char **o = (char **) ((char *) stru + offset);
|
||||
|
||||
if (str) {
|
||||
n = strdup(str);
|
||||
if (!n)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
free(*o);
|
||||
*o = n;
|
||||
return n;
|
||||
}
|
||||
|
||||
#define strdup_to_struct_member(_s, _m, _str) \
|
||||
strdup_to_offset((void *) _s, offsetof(__typeof__(*(_s)), _m), _str)
|
||||
|
||||
extern void strmode(mode_t mode, char *str);
|
||||
|
||||
/* Options for size_to_human_string() */
|
||||
@@ -76,4 +103,102 @@ 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);
|
||||
|
||||
/*
|
||||
* Match string beginning.
|
||||
*/
|
||||
static inline const char *startswith(const char *s, const char *prefix)
|
||||
{
|
||||
size_t sz = prefix ? strlen(prefix) : 0;
|
||||
|
||||
if (s && sz && strncmp(s, prefix, sz) == 0)
|
||||
return s + sz;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Case insensitive match string beginning.
|
||||
*/
|
||||
static inline const char *startswith_no_case(const char *s, const char *prefix)
|
||||
{
|
||||
size_t sz = prefix ? strlen(prefix) : 0;
|
||||
|
||||
if (s && sz && strncasecmp(s, prefix, sz) == 0)
|
||||
return s + sz;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Match string ending.
|
||||
*/
|
||||
static inline const char *endswith(const char *s, const char *postfix)
|
||||
{
|
||||
size_t sl = s ? strlen(s) : 0;
|
||||
size_t pl = postfix ? strlen(postfix) : 0;
|
||||
|
||||
if (pl == 0)
|
||||
return (char *)s + sl;
|
||||
if (sl < pl)
|
||||
return NULL;
|
||||
if (memcmp(s + sl - pl, postfix, pl) != 0)
|
||||
return NULL;
|
||||
return (char *)s + sl - pl;
|
||||
}
|
||||
|
||||
/*
|
||||
* Skip leading white space.
|
||||
*/
|
||||
static inline const char *skip_space(const char *p)
|
||||
{
|
||||
while (isspace(*p))
|
||||
++p;
|
||||
return p;
|
||||
}
|
||||
|
||||
static inline const char *skip_blank(const char *p)
|
||||
{
|
||||
while (isblank(*p))
|
||||
++p;
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
/* Removes whitespace from the right-hand side of a string (trailing
|
||||
* whitespace).
|
||||
*
|
||||
* Returns size of the new string (without \0).
|
||||
*/
|
||||
static inline size_t rtrim_whitespace(unsigned char *str)
|
||||
{
|
||||
size_t i = strlen((char *) str);
|
||||
|
||||
while (i) {
|
||||
i--;
|
||||
if (!isspace(str[i])) {
|
||||
i++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
str[i] = '\0';
|
||||
return i;
|
||||
}
|
||||
|
||||
/* Removes whitespace from the left-hand side of a string.
|
||||
*
|
||||
* Returns size of the new string (without \0).
|
||||
*/
|
||||
static inline size_t ltrim_whitespace(unsigned char *str)
|
||||
{
|
||||
size_t len;
|
||||
unsigned char *p;
|
||||
|
||||
for (p = str; p && isspace(*p); p++);
|
||||
|
||||
len = strlen((char *) p);
|
||||
|
||||
if (len && p > str)
|
||||
memmove(str, p, len + 1);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,23 @@
|
||||
#ifndef _SWAPHEADER_H
|
||||
#define _SWAPHEADER_H
|
||||
|
||||
#define SWAP_VERSION 1
|
||||
#define SWAP_UUID_LENGTH 16
|
||||
#define SWAP_LABEL_LENGTH 16
|
||||
#define SWAP_SIGNATURE "SWAPSPACE2"
|
||||
#define SWAP_SIGNATURE_SZ (sizeof(SWAP_SIGNATURE) - 1)
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
struct swap_header_v1_2 {
|
||||
char bootbits[1024]; /* Space for disklabel etc. */
|
||||
uint32_t version;
|
||||
uint32_t last_page;
|
||||
uint32_t nr_badpages;
|
||||
unsigned char uuid[SWAP_UUID_LENGTH];
|
||||
char volume_name[SWAP_LABEL_LENGTH];
|
||||
uint32_t padding[117];
|
||||
uint32_t badpages[1];
|
||||
};
|
||||
|
||||
#endif /* _SWAPHEADER_H */
|
||||
@@ -0,0 +1,9 @@
|
||||
#ifndef UTIL_LINUX_SWAP_PROBER_H
|
||||
#define UTIL_LINUX_SWAP_PROBER_H
|
||||
|
||||
#include <blkid.h>
|
||||
|
||||
blkid_probe get_swap_prober(const char *devname);
|
||||
|
||||
#endif /* UTIL_LINUX_SWAP_PROBER_H */
|
||||
|
||||
@@ -58,6 +58,9 @@ 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);
|
||||
@@ -67,12 +70,19 @@ 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,
|
||||
@@ -0,0 +1,31 @@
|
||||
#ifndef UTIL_LINUX_TIMER_H
|
||||
#define UTIL_LINUX_TIMER_H
|
||||
|
||||
#include <signal.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
static inline int setup_timer(
|
||||
struct itimerval *timer,
|
||||
struct itimerval *old_timer,
|
||||
struct sigaction *old_sa,
|
||||
void (*timeout_handler)(int))
|
||||
{
|
||||
struct sigaction sa;
|
||||
|
||||
memset(&sa, 0, sizeof sa);
|
||||
sa.sa_handler = timeout_handler;
|
||||
sa.sa_flags = SA_RESETHAND;
|
||||
sigaction(SIGALRM, &sa, old_sa);
|
||||
|
||||
return setitimer(ITIMER_REAL, timer, old_timer);
|
||||
}
|
||||
|
||||
static inline void cancel_timer(
|
||||
struct itimerval *old_timer,
|
||||
struct sigaction *old_sa)
|
||||
{
|
||||
setitimer(ITIMER_REAL, old_timer, NULL);
|
||||
sigaction(SIGALRM, old_sa, NULL);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,56 @@
|
||||
/***
|
||||
First set of functions in this file are part of systemd, and were
|
||||
copied to util-linux at August 2013.
|
||||
|
||||
Copyright 2010 Lennart Poettering
|
||||
Copyright (C) 2014 Karel Zak <kzak@redhat.com>
|
||||
|
||||
systemd 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.
|
||||
|
||||
systemd 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||
***/
|
||||
#ifndef UTIL_LINUX_TIME_UTIL_H
|
||||
#define UTIL_LINUX_TIME_UTIL_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
typedef uint64_t usec_t;
|
||||
typedef uint64_t nsec_t;
|
||||
|
||||
#define MSEC_PER_SEC 1000ULL
|
||||
#define USEC_PER_SEC 1000000ULL
|
||||
#define USEC_PER_MSEC 1000ULL
|
||||
#define NSEC_PER_SEC 1000000000ULL
|
||||
#define NSEC_PER_MSEC 1000000ULL
|
||||
#define NSEC_PER_USEC 1000ULL
|
||||
|
||||
#define USEC_PER_MINUTE (60ULL*USEC_PER_SEC)
|
||||
#define NSEC_PER_MINUTE (60ULL*NSEC_PER_SEC)
|
||||
#define USEC_PER_HOUR (60ULL*USEC_PER_MINUTE)
|
||||
#define NSEC_PER_HOUR (60ULL*NSEC_PER_MINUTE)
|
||||
#define USEC_PER_DAY (24ULL*USEC_PER_HOUR)
|
||||
#define NSEC_PER_DAY (24ULL*NSEC_PER_HOUR)
|
||||
#define USEC_PER_WEEK (7ULL*USEC_PER_DAY)
|
||||
#define NSEC_PER_WEEK (7ULL*NSEC_PER_DAY)
|
||||
#define USEC_PER_MONTH (2629800ULL*USEC_PER_SEC)
|
||||
#define NSEC_PER_MONTH (2629800ULL*NSEC_PER_SEC)
|
||||
#define USEC_PER_YEAR (31557600ULL*USEC_PER_SEC)
|
||||
#define NSEC_PER_YEAR (31557600ULL*NSEC_PER_SEC)
|
||||
|
||||
#define FORMAT_TIMESTAMP_MAX ((4*4+1)+11+9+4+1) /* weekdays can be unicode */
|
||||
#define FORMAT_TIMESTAMP_RELATIVE_MAX 256
|
||||
#define FORMAT_TIMESPAN_MAX 64
|
||||
|
||||
int parse_timestamp(const char *t, usec_t *usec);
|
||||
|
||||
#endif /* UTIL_LINUX_TIME_UTIL_H */
|
||||
@@ -13,6 +13,9 @@
|
||||
#ifdef HAVE_SYS_IOCTL_H
|
||||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_TTYDEFAULTS_H
|
||||
#include <sys/ttydefaults.h>
|
||||
#endif
|
||||
|
||||
/* Some shorthands for control characters. */
|
||||
#define CTL(x) ((x) ^ 0100) /* Assumes ASCII dialect */
|
||||
@@ -48,7 +51,8 @@ struct chardata {
|
||||
} while (0)
|
||||
|
||||
extern int get_terminal_width(void);
|
||||
extern int get_terminal_name(const char **path, const char **name, const char **number);
|
||||
extern int get_terminal_name(int fd, const char **path, const char **name,
|
||||
const char **number);
|
||||
|
||||
#define UL_TTY_KEEPCFLAGS (1 << 1)
|
||||
#define UL_TTY_UTF8 (1 << 2)
|
||||
@@ -70,13 +74,53 @@ static inline void reset_virtual_console(struct termios *tp, int flags)
|
||||
/* Sane setting, allow eight bit characters, no carriage return delay
|
||||
* the same result as `stty sane cr0 pass8'
|
||||
*/
|
||||
#ifndef IUCLC
|
||||
# define IUCLC 0
|
||||
#endif
|
||||
#ifndef NL0
|
||||
# define NL0 0
|
||||
#endif
|
||||
#ifndef CR0
|
||||
# define CR0 0
|
||||
#endif
|
||||
#ifndef BS0
|
||||
# define BS0 0
|
||||
#endif
|
||||
#ifndef VT0
|
||||
# define VT0 0
|
||||
#endif
|
||||
#ifndef FF0
|
||||
# define FF0 0
|
||||
#endif
|
||||
#ifndef OLCUC
|
||||
# define OLCUC 0
|
||||
#endif
|
||||
#ifndef OFILL
|
||||
# define OFILL 0
|
||||
#endif
|
||||
#ifndef NLDLY
|
||||
# define NLDLY 0
|
||||
#endif
|
||||
#ifndef CRDLY
|
||||
# define CRDLY 0
|
||||
#endif
|
||||
#ifndef BSDLY
|
||||
# define BSDLY 0
|
||||
#endif
|
||||
#ifndef VTDLY
|
||||
# define VTDLY 0
|
||||
#endif
|
||||
#ifndef FFDLY
|
||||
# define FFDLY 0
|
||||
#endif
|
||||
|
||||
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);
|
||||
tp->c_lflag |= (ISIG | ICANON | IEXTEN | ECHO|ECHOE|ECHOK|ECHOKE|ECHOCTL);
|
||||
tp->c_lflag &= ~(ECHONL|ECHOPRT | NOFLSH | TOSTOP);
|
||||
|
||||
if ((flags & UL_TTY_KEEPCFLAGS) == 0) {
|
||||
tp->c_cflag |= (CREAD | CS8 | HUPCL);
|
||||
@@ -121,6 +165,4 @@ static inline void reset_virtual_console(struct termios *tp, int flags)
|
||||
tp->c_cc[VEOL2] = _POSIX_VDISABLE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif /* UTIL_LINUX_TTYUTILS_H */
|
||||
@@ -49,7 +49,7 @@ void *xcalloc(const size_t nelems, const size_t size)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline char *xstrdup(const char *str)
|
||||
static inline char __attribute__((warn_unused_result)) *xstrdup(const char *str)
|
||||
{
|
||||
char *ret;
|
||||
|
||||
@@ -63,6 +63,21 @@ static inline char *xstrdup(const char *str)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline char * __attribute__((warn_unused_result)) xstrndup(const char *str, size_t size)
|
||||
{
|
||||
char *ret;
|
||||
|
||||
if (!str)
|
||||
return NULL;
|
||||
|
||||
ret = strndup(str, size);
|
||||
|
||||
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, ...)
|
||||
{
|
||||
@@ -76,16 +91,26 @@ static inline int __attribute__ ((__format__(printf, 2, 3)))
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int xvasprintf(char **strp, const char *fmt, va_list ap)
|
||||
{
|
||||
int ret = vasprintf(&(*strp), fmt, ap);
|
||||
if (ret < 0)
|
||||
err(XALLOC_EXIT_CODE, "cannot allocate string");
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline char *xgethostname(void)
|
||||
|
||||
static inline char * __attribute__((warn_unused_result)) xgethostname(void)
|
||||
{
|
||||
char *name;
|
||||
size_t sz = get_hostname_max() + 1;
|
||||
|
||||
name = xmalloc(sizeof(char) * sz);
|
||||
if (gethostname(name, sz) != 0)
|
||||
return NULL;
|
||||
|
||||
if (gethostname(name, sz) != 0) {
|
||||
free(name);
|
||||
return NULL;
|
||||
}
|
||||
name[sz - 1] = '\0';
|
||||
return name;
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
|
||||
noinst_LTLIBRARIES += libcommon.la
|
||||
libcommon_la_CFLAGS = $(AM_CFLAGS)
|
||||
libcommon_la_SOURCES = \
|
||||
lib/at.c \
|
||||
lib/blkdev.c \
|
||||
lib/canonicalize.c \
|
||||
lib/colors.c \
|
||||
lib/crc32.c \
|
||||
lib/crc64.c \
|
||||
lib/env.c \
|
||||
lib/fileutils.c \
|
||||
lib/ismounted.c \
|
||||
lib/mangle.c \
|
||||
lib/match.c \
|
||||
lib/mbsalign.c \
|
||||
lib/md5.c \
|
||||
lib/pager.c \
|
||||
lib/path.c \
|
||||
lib/procutils.c \
|
||||
lib/randutils.c \
|
||||
lib/setproctitle.c \
|
||||
lib/strutils.c \
|
||||
lib/sysfs.c \
|
||||
lib/timeutils.c \
|
||||
lib/ttyutils.c \
|
||||
lib/exec_shell.c \
|
||||
lib/readutmp.c
|
||||
|
||||
if LINUX
|
||||
libcommon_la_SOURCES += \
|
||||
lib/linux_version.c \
|
||||
lib/loopdev.c
|
||||
endif
|
||||
|
||||
if !HAVE_LANGINFO
|
||||
libcommon_la_SOURCES += lib/langinfo.c
|
||||
endif
|
||||
|
||||
if HAVE_CPU_SET_T
|
||||
libcommon_la_SOURCES += lib/cpuset.c
|
||||
endif
|
||||
|
||||
dist_man_MANS += lib/terminal-colors.d.5
|
||||
|
||||
check_PROGRAMS += \
|
||||
test_at \
|
||||
test_blkdev \
|
||||
test_canonicalize \
|
||||
test_colors \
|
||||
test_fileutils \
|
||||
test_ismounted \
|
||||
test_mangle \
|
||||
test_procutils \
|
||||
test_randutils \
|
||||
test_strutils \
|
||||
test_ttyutils
|
||||
|
||||
if LINUX
|
||||
if HAVE_CPU_SET_T
|
||||
check_PROGRAMS += test_cpuset
|
||||
endif
|
||||
check_PROGRAMS += \
|
||||
test_sysfs \
|
||||
test_pager
|
||||
endif
|
||||
|
||||
test_ttyutils_SOURCES = lib/ttyutils.c
|
||||
test_ttyutils_CFLAGS = -DTEST_PROGRAM
|
||||
test_ttyutils_LDADD = libcommon.la
|
||||
|
||||
test_blkdev_SOURCES = lib/blkdev.c
|
||||
test_blkdev_CFLAGS = -DTEST_PROGRAM_BLKDEV
|
||||
test_blkdev_LDADD = libcommon.la
|
||||
|
||||
test_ismounted_SOURCES = lib/ismounted.c
|
||||
test_ismounted_CFLAGS = -DTEST_PROGRAM
|
||||
test_ismounted_LDADD = libcommon.la
|
||||
|
||||
test_mangle_SOURCES = lib/mangle.c
|
||||
test_mangle_CFLAGS = -DTEST_PROGRAM
|
||||
|
||||
test_at_SOURCES = lib/at.c
|
||||
test_at_CFLAGS = -DTEST_PROGRAM_AT
|
||||
|
||||
test_strutils_SOURCES = lib/strutils.c
|
||||
test_strutils_CFLAGS = -DTEST_PROGRAM
|
||||
|
||||
test_colors_SOURCES = lib/colors.c
|
||||
test_colors_CFLAGS = -DTEST_PROGRAM
|
||||
|
||||
test_randutils_SOURCES = lib/randutils.c
|
||||
test_randutils_CFLAGS = -DTEST_PROGRAM
|
||||
|
||||
test_procutils_SOURCES = lib/procutils.c lib/at.c
|
||||
test_procutils_CFLAGS = -DTEST_PROGRAM
|
||||
|
||||
if LINUX
|
||||
test_cpuset_SOURCES = lib/cpuset.c
|
||||
test_cpuset_CFLAGS = -DTEST_PROGRAM
|
||||
|
||||
test_sysfs_SOURCES = lib/sysfs.c
|
||||
test_sysfs_CFLAGS = -DTEST_PROGRAM_SYSFS
|
||||
test_sysfs_LDADD = libcommon.la
|
||||
|
||||
test_pager_SOURCES = lib/pager.c
|
||||
test_pager_CFLAGS = -DTEST_PROGRAM
|
||||
endif
|
||||
|
||||
test_fileutils_SOURCES = lib/fileutils.c
|
||||
test_fileutils_CFLAGS = -DTEST_PROGRAM
|
||||
|
||||
test_canonicalize_SOURCES = lib/canonicalize.c
|
||||
test_canonicalize_CFLAGS = -DTEST_PROGRAM_CANONICALIZE
|
||||
|
||||
@@ -25,10 +25,13 @@
|
||||
#include <sys/disk.h>
|
||||
#endif
|
||||
|
||||
#ifdef __FreeBSD_kernel__
|
||||
#include <sys/disk.h>
|
||||
#endif
|
||||
|
||||
#include "blkdev.h"
|
||||
#include "c.h"
|
||||
#include "linux_version.h"
|
||||
#include "xalloc.h"
|
||||
|
||||
static long
|
||||
blkdev_valid_offset (int fd, off_t offset) {
|
||||
@@ -336,7 +339,7 @@ const char *blkdev_scsi_type_to_name(int type)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef TEST_PROGRAM
|
||||
#ifdef TEST_PROGRAM_BLKDEV
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
@@ -353,7 +356,7 @@ main(int argc, char **argv)
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if ((fd = open(argv[1], O_RDONLY)) < 0)
|
||||
if ((fd = open(argv[1], O_RDONLY|O_CLOEXEC)) < 0)
|
||||
err(EXIT_FAILURE, "open %s failed", argv[1]);
|
||||
|
||||
if (blkdev_get_size(fd, &bytes) < 0)
|
||||
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* canonicalize.c -- canonicalize pathname by removing symlinks
|
||||
*
|
||||
* This file may be distributed under the terms of the
|
||||
* GNU Lesser General Public License.
|
||||
*
|
||||
* Copyright (C) 2009-2013 Karel Zak <kzak@redhat.com>
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "canonicalize.h"
|
||||
|
||||
/*
|
||||
* Converts private "dm-N" names to "/dev/mapper/<name>"
|
||||
*
|
||||
* Since 2.6.29 (patch 784aae735d9b0bba3f8b9faef4c8b30df3bf0128) kernel sysfs
|
||||
* provides the real DM device names in /sys/block/<ptname>/dm/name
|
||||
*/
|
||||
char *canonicalize_dm_name(const char *ptname)
|
||||
{
|
||||
FILE *f;
|
||||
size_t sz;
|
||||
char path[256], name[256], *res = NULL;
|
||||
|
||||
if (!ptname || !*ptname)
|
||||
return NULL;
|
||||
|
||||
snprintf(path, sizeof(path), "/sys/block/%s/dm/name", ptname);
|
||||
if (!(f = fopen(path, "r")))
|
||||
return NULL;
|
||||
|
||||
/* read "<name>\n" from sysfs */
|
||||
if (fgets(name, sizeof(name), f) && (sz = strlen(name)) > 1) {
|
||||
name[sz - 1] = '\0';
|
||||
snprintf(path, sizeof(path), "/dev/mapper/%s", name);
|
||||
|
||||
if (access(path, F_OK) == 0)
|
||||
res = strdup(path);
|
||||
}
|
||||
fclose(f);
|
||||
return res;
|
||||
}
|
||||
|
||||
static int is_dm_devname(char *canonical, char **name)
|
||||
{
|
||||
struct stat sb;
|
||||
char *p = strrchr(canonical, '/');
|
||||
|
||||
*name = NULL;
|
||||
|
||||
if (!p
|
||||
|| strncmp(p, "/dm-", 4) != 0
|
||||
|| !isdigit(*(p + 4))
|
||||
|| stat(canonical, &sb) != 0
|
||||
|| !S_ISBLK(sb.st_mode))
|
||||
return 0;
|
||||
|
||||
*name = p + 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
char *canonicalize_path(const char *path)
|
||||
{
|
||||
char *canonical, *dmname;
|
||||
|
||||
if (!path || !*path)
|
||||
return NULL;
|
||||
|
||||
canonical = realpath(path, NULL);
|
||||
if (!canonical)
|
||||
return strdup(path);
|
||||
|
||||
if (is_dm_devname(canonical, &dmname)) {
|
||||
char *dm = canonicalize_dm_name(dmname);
|
||||
if (dm) {
|
||||
free(canonical);
|
||||
return dm;
|
||||
}
|
||||
}
|
||||
|
||||
return canonical;
|
||||
}
|
||||
|
||||
char *canonicalize_path_restricted(const char *path)
|
||||
{
|
||||
char *canonical, *dmname;
|
||||
int errsv;
|
||||
uid_t euid;
|
||||
gid_t egid;
|
||||
|
||||
if (!path || !*path)
|
||||
return NULL;
|
||||
|
||||
euid = geteuid();
|
||||
egid = getegid();
|
||||
|
||||
/* drop permissions */
|
||||
if (setegid(getgid()) < 0 || seteuid(getuid()) < 0)
|
||||
return NULL;
|
||||
|
||||
errsv = errno = 0;
|
||||
|
||||
canonical = realpath(path, NULL);
|
||||
if (!canonical)
|
||||
errsv = errno;
|
||||
else if (is_dm_devname(canonical, &dmname)) {
|
||||
char *dm = canonicalize_dm_name(dmname);
|
||||
if (dm) {
|
||||
free(canonical);
|
||||
canonical = dm;
|
||||
}
|
||||
}
|
||||
|
||||
/* restore */
|
||||
if (setegid(egid) < 0 || seteuid(euid) < 0) {
|
||||
free(canonical);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
errno = errsv;
|
||||
return canonical;
|
||||
}
|
||||
|
||||
|
||||
#ifdef TEST_PROGRAM_CANONICALIZE
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "usage: %s <device>\n", argv[0]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
fprintf(stdout, "orig: %s\n", argv[1]);
|
||||
fprintf(stdout, "real: %s\n", canonicalize_path(argv[1]));
|
||||
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,877 @@
|
||||
/*
|
||||
* Copyright (C) 2012 Ondrej Oprala <ooprala@redhat.com>
|
||||
* Copyright (C) 2012-2014 Karel Zak <kzak@redhat.com>
|
||||
*
|
||||
* This file may be distributed under the terms of the
|
||||
* GNU Lesser General Public License.
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "c.h"
|
||||
#include "colors.h"
|
||||
#include "pathnames.h"
|
||||
#include "strutils.h"
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
/*
|
||||
* terminal-colors.d debug stuff
|
||||
*/
|
||||
UL_DEBUG_DEFINE_MASK(termcolors);
|
||||
UL_DEBUG_DEFINE_MASKNAMES(termcolors) = UL_DEBUG_EMPTY_MASKNAMES;
|
||||
|
||||
#define TERMCOLORS_DEBUG_INIT (1 << 1)
|
||||
#define TERMCOLORS_DEBUG_CONF (1 << 2)
|
||||
#define TERMCOLORS_DEBUG_SCHEME (1 << 3)
|
||||
#define TERMCOLORS_DEBUG_ALL 0xFFFF
|
||||
|
||||
#define DBG(m, x) __UL_DBG(termcolors, TERMCOLORS_DEBUG_, m, x)
|
||||
#define ON_DBG(m, x) __UL_DBG_CALL(termcolors, TERMCOLORS_DEBUG_, m, x)
|
||||
|
||||
/*
|
||||
* terminal-colors.d file types
|
||||
*/
|
||||
enum {
|
||||
UL_COLORFILE_DISABLE, /* .disable */
|
||||
UL_COLORFILE_ENABLE, /* .enable */
|
||||
UL_COLORFILE_SCHEME, /* .scheme */
|
||||
|
||||
__UL_COLORFILE_COUNT
|
||||
};
|
||||
|
||||
struct ul_color_scheme {
|
||||
char *name;
|
||||
char *seq;
|
||||
};
|
||||
|
||||
/*
|
||||
* Global colors control struct
|
||||
*
|
||||
* The terminal-colors.d/ evaluation is based on "scores":
|
||||
*
|
||||
* filename score
|
||||
* ---------------------------------------
|
||||
* type 1
|
||||
* @termname.type 10 + 1
|
||||
* utilname.type 20 + 1
|
||||
* utilname@termname.type 20 + 10 + 1
|
||||
*
|
||||
* the match with higher score wins. The score is per type.
|
||||
*/
|
||||
struct ul_color_ctl {
|
||||
const char *utilname; /* util name */
|
||||
const char *termname; /* terminal name ($TERM) */
|
||||
|
||||
char *sfile; /* path to scheme */
|
||||
|
||||
struct ul_color_scheme *schemes; /* array with color schemes */
|
||||
size_t nschemes; /* number of the items */
|
||||
size_t schemes_sz; /* number of the allocated items */
|
||||
|
||||
int mode; /* UL_COLORMODE_* */
|
||||
unsigned int has_colors : 1, /* based on mode and scores[] */
|
||||
disabled : 1, /* disable colors */
|
||||
cs_configured : 1, /* color schemes read */
|
||||
configured : 1; /* terminal-colors.d parsed */
|
||||
|
||||
int scores[__UL_COLORFILE_COUNT]; /* the best match */
|
||||
};
|
||||
|
||||
/*
|
||||
* Control struct, globally shared.
|
||||
*/
|
||||
static struct ul_color_ctl ul_colors;
|
||||
|
||||
static void colors_free_schemes(struct ul_color_ctl *cc);
|
||||
static int colors_read_schemes(struct ul_color_ctl *cc);
|
||||
|
||||
/*
|
||||
* qsort/bsearch buddy
|
||||
*/
|
||||
static int cmp_scheme_name(const void *a0, const void *b0)
|
||||
{
|
||||
struct ul_color_scheme *a = (struct ul_color_scheme *) a0,
|
||||
*b = (struct ul_color_scheme *) b0;
|
||||
return strcmp(a->name, b->name);
|
||||
}
|
||||
|
||||
/*
|
||||
* Maintains human readable color names
|
||||
*/
|
||||
const char *color_sequence_from_colorname(const char *str)
|
||||
{
|
||||
static const struct ul_color_scheme basic_schemes[] = {
|
||||
{ "black", UL_COLOR_BLACK },
|
||||
{ "blue", UL_COLOR_BLUE },
|
||||
{ "brown", UL_COLOR_BROWN },
|
||||
{ "cyan", UL_COLOR_CYAN },
|
||||
{ "darkgray", UL_COLOR_DARK_GRAY },
|
||||
{ "gray", UL_COLOR_GRAY },
|
||||
{ "green", UL_COLOR_GREEN },
|
||||
{ "lightblue", UL_COLOR_BOLD_BLUE },
|
||||
{ "lightcyan", UL_COLOR_BOLD_CYAN },
|
||||
{ "lightgray,", UL_COLOR_GRAY },
|
||||
{ "lightgreen", UL_COLOR_BOLD_GREEN },
|
||||
{ "lightmagenta", UL_COLOR_BOLD_MAGENTA },
|
||||
{ "lightred", UL_COLOR_BOLD_RED },
|
||||
{ "magenta", UL_COLOR_MAGENTA },
|
||||
{ "red", UL_COLOR_RED },
|
||||
{ "yellow", UL_COLOR_BOLD_YELLOW },
|
||||
};
|
||||
struct ul_color_scheme key = { .name = (char *) str }, *res;
|
||||
|
||||
if (!str)
|
||||
return NULL;
|
||||
|
||||
res = bsearch(&key, basic_schemes, ARRAY_SIZE(basic_schemes),
|
||||
sizeof(struct ul_color_scheme),
|
||||
cmp_scheme_name);
|
||||
return res ? res->seq : NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Resets control struct (note that we don't allocate the struct)
|
||||
*/
|
||||
static void colors_reset(struct ul_color_ctl *cc)
|
||||
{
|
||||
if (!cc)
|
||||
return;
|
||||
|
||||
colors_free_schemes(cc);
|
||||
|
||||
free(cc->sfile);
|
||||
|
||||
cc->sfile = NULL;
|
||||
cc->utilname = NULL;
|
||||
cc->termname = NULL;
|
||||
cc->mode = UL_COLORMODE_UNDEF;
|
||||
|
||||
memset(cc->scores, 0, sizeof(cc->scores));
|
||||
}
|
||||
|
||||
static void colors_debug(struct ul_color_ctl *cc)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (!cc)
|
||||
return;
|
||||
|
||||
printf("Colors:\n");
|
||||
printf("\tutilname = '%s'\n", cc->utilname);
|
||||
printf("\ttermname = '%s'\n", cc->termname);
|
||||
printf("\tscheme file = '%s'\n", cc->sfile);
|
||||
printf("\tmode = %s\n",
|
||||
cc->mode == UL_COLORMODE_UNDEF ? "undefined" :
|
||||
cc->mode == UL_COLORMODE_AUTO ? "auto" :
|
||||
cc->mode == UL_COLORMODE_NEVER ? "never" :
|
||||
cc->mode == UL_COLORMODE_ALWAYS ? "always" : "???");
|
||||
printf("\thas_colors = %d\n", cc->has_colors);
|
||||
printf("\tdisabled = %d\n", cc->disabled);
|
||||
printf("\tconfigured = %d\n", cc->configured);
|
||||
printf("\tcs configured = %d\n", cc->cs_configured);
|
||||
|
||||
fputc('\n', stdout);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(cc->scores); i++)
|
||||
printf("\tscore %s = %d\n",
|
||||
i == UL_COLORFILE_DISABLE ? "disable" :
|
||||
i == UL_COLORFILE_ENABLE ? "enable" :
|
||||
i == UL_COLORFILE_SCHEME ? "scheme" : "???",
|
||||
cc->scores[i]);
|
||||
|
||||
fputc('\n', stdout);
|
||||
|
||||
for (i = 0; i < cc->nschemes; i++) {
|
||||
printf("\tscheme #%02zu ", i);
|
||||
color_scheme_enable(cc->schemes[i].name, NULL);
|
||||
fputs(cc->schemes[i].name, stdout);
|
||||
color_disable();
|
||||
fputc('\n', stdout);
|
||||
}
|
||||
fputc('\n', stdout);
|
||||
}
|
||||
|
||||
/*
|
||||
* Parses [[<utilname>][@<termname>].]<type>
|
||||
*/
|
||||
static int filename_to_tokens(const char *str,
|
||||
const char **name, size_t *namesz,
|
||||
const char **term, size_t *termsz,
|
||||
int *filetype)
|
||||
{
|
||||
const char *type_start, *term_start, *p;
|
||||
|
||||
if (!str || !*str || *str == '.' || strlen(str) > PATH_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
/* parse .type */
|
||||
p = strrchr(str, '.');
|
||||
type_start = p ? p + 1 : str;
|
||||
|
||||
if (strcmp(type_start, "disable") == 0)
|
||||
*filetype = UL_COLORFILE_DISABLE;
|
||||
else if (strcmp(type_start, "enable") == 0)
|
||||
*filetype = UL_COLORFILE_ENABLE;
|
||||
else if (strcmp(type_start, "scheme") == 0)
|
||||
*filetype = UL_COLORFILE_SCHEME;
|
||||
else {
|
||||
DBG(CONF, ul_debug("unknown type '%s'", type_start));
|
||||
return 1; /* unknown type */
|
||||
}
|
||||
|
||||
if (type_start == str)
|
||||
return 0; /* "type" only */
|
||||
|
||||
/* parse @termname */
|
||||
p = strchr(str, '@');
|
||||
term_start = p ? p + 1 : NULL;
|
||||
if (term_start) {
|
||||
*term = term_start;
|
||||
*termsz = type_start - term_start - 1;
|
||||
if (term_start - 1 == str)
|
||||
return 0; /* "@termname.type" */
|
||||
}
|
||||
|
||||
/* parse utilname */
|
||||
p = term_start ? term_start : type_start;
|
||||
*name = str;
|
||||
*namesz = p - str - 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Scans @dirname and select the best matches for UL_COLORFILE_* types.
|
||||
* The result is stored to cc->scores. The path to the best "scheme"
|
||||
* file is stored to cc->scheme.
|
||||
*/
|
||||
static int colors_readdir(struct ul_color_ctl *cc, const char *dirname)
|
||||
{
|
||||
DIR *dir;
|
||||
int rc = 0;
|
||||
struct dirent *d;
|
||||
char sfile[PATH_MAX] = { '\0' };
|
||||
size_t namesz, termsz;
|
||||
|
||||
if (!dirname || !cc || !cc->utilname || !*cc->utilname)
|
||||
return -EINVAL;
|
||||
|
||||
DBG(CONF, ul_debug("reading dir: '%s'", dirname));
|
||||
|
||||
dir = opendir(dirname);
|
||||
if (!dir)
|
||||
return -errno;
|
||||
|
||||
namesz = strlen(cc->utilname);
|
||||
termsz = cc->termname ? strlen(cc->termname) : 0;
|
||||
|
||||
while ((d = readdir(dir))) {
|
||||
int type, score = 1;
|
||||
const char *tk_name = NULL, *tk_term = NULL;
|
||||
size_t tk_namesz = 0, tk_termsz = 0;
|
||||
|
||||
if (*d->d_name == '.')
|
||||
continue;
|
||||
#ifdef _DIRENT_HAVE_D_TYPE
|
||||
if (d->d_type != DT_UNKNOWN && d->d_type != DT_LNK &&
|
||||
d->d_type != DT_REG)
|
||||
continue;
|
||||
#endif
|
||||
if (filename_to_tokens(d->d_name,
|
||||
&tk_name, &tk_namesz,
|
||||
&tk_term, &tk_termsz, &type) != 0)
|
||||
continue;
|
||||
|
||||
/* count teoretical score before we check names to avoid
|
||||
* unnecessary strcmp() */
|
||||
if (tk_name)
|
||||
score += 20;
|
||||
if (tk_term)
|
||||
score += 10;
|
||||
|
||||
DBG(CONF, ul_debug("item '%s': score=%d "
|
||||
"[cur: %d, name(%zu): %s, term(%zu): %s]",
|
||||
d->d_name, score, cc->scores[type],
|
||||
tk_namesz, tk_name,
|
||||
tk_termsz, tk_term));
|
||||
|
||||
|
||||
if (score < cc->scores[type])
|
||||
continue;
|
||||
|
||||
/* filter out by names */
|
||||
if (tk_namesz && (tk_namesz != namesz ||
|
||||
strncmp(tk_name, cc->utilname, namesz) != 0))
|
||||
continue;
|
||||
|
||||
if (tk_termsz && (termsz == 0 || tk_termsz != termsz ||
|
||||
strncmp(tk_term, cc->termname, termsz) != 0))
|
||||
continue;
|
||||
|
||||
DBG(CONF, ul_debug("setting '%s' from %d -to-> %d",
|
||||
type == UL_COLORFILE_SCHEME ? "scheme" :
|
||||
type == UL_COLORFILE_DISABLE ? "disable" :
|
||||
type == UL_COLORFILE_ENABLE ? "enable" : "???",
|
||||
cc->scores[type], score));
|
||||
cc->scores[type] = score;
|
||||
if (type == UL_COLORFILE_SCHEME)
|
||||
strncpy(sfile, d->d_name, sizeof(sfile));
|
||||
}
|
||||
|
||||
if (*sfile) {
|
||||
sfile[sizeof(sfile) - 1] = '\0';
|
||||
if (asprintf(&cc->sfile, "%s/%s", dirname, sfile) <= 0)
|
||||
rc = -ENOMEM;
|
||||
}
|
||||
|
||||
closedir(dir);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* atexit() wrapper */
|
||||
static void colors_deinit(void)
|
||||
{
|
||||
colors_reset(&ul_colors);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns path to $XDG_CONFIG_HOME/terminal-colors.d
|
||||
*/
|
||||
static char *colors_get_homedir(char *buf, size_t bufsz)
|
||||
{
|
||||
char *p = getenv("XDG_CONFIG_HOME");
|
||||
|
||||
if (p) {
|
||||
snprintf(buf, bufsz, "%s/" _PATH_TERMCOLORS_DIRNAME, p);
|
||||
return buf;
|
||||
}
|
||||
|
||||
p = getenv("HOME");
|
||||
if (p) {
|
||||
snprintf(buf, bufsz, "%s/.config/" _PATH_TERMCOLORS_DIRNAME, p);
|
||||
return buf;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* canonicalize sequence */
|
||||
static int cn_sequence(const char *str, char **seq)
|
||||
{
|
||||
char *in, *out;
|
||||
|
||||
if (!str)
|
||||
return -EINVAL;
|
||||
|
||||
*seq = NULL;
|
||||
|
||||
/* convert logical names like "red" to the real sequence */
|
||||
if (*str != '\\' && isalpha(*str)) {
|
||||
const char *s = color_sequence_from_colorname(str);
|
||||
*seq = strdup(s ? s : str);
|
||||
|
||||
return *seq ? 0 : -ENOMEM;
|
||||
}
|
||||
|
||||
/* convert xx;yy sequences to "\033[xx;yy" */
|
||||
if (asprintf(seq, "\033[%sm", str) < 1)
|
||||
return -ENOMEM;
|
||||
|
||||
for (in = *seq, out = *seq; in && *in; in++) {
|
||||
if (*in != '\\') {
|
||||
*out++ = *in;
|
||||
continue;
|
||||
}
|
||||
switch(*(in + 1)) {
|
||||
case 'a':
|
||||
*out++ = '\a'; /* Bell */
|
||||
break;
|
||||
case 'b':
|
||||
*out++ = '\b'; /* Backspace */
|
||||
break;
|
||||
case 'e':
|
||||
*out++ = '\033'; /* Escape */
|
||||
break;
|
||||
case 'f':
|
||||
*out++ = '\f'; /* Form Feed */
|
||||
break;
|
||||
case 'n':
|
||||
*out++ = '\n'; /* Newline */
|
||||
break;
|
||||
case 'r':
|
||||
*out++ = '\r'; /* Carriage Return */
|
||||
break;
|
||||
case 't':
|
||||
*out++ = '\t'; /* Tab */
|
||||
break;
|
||||
case 'v':
|
||||
*out++ = '\v'; /* Vertical Tab */
|
||||
break;
|
||||
case '\\':
|
||||
*out++ = '\\'; /* Backslash */
|
||||
break;
|
||||
case '_':
|
||||
*out++ = ' '; /* Space */
|
||||
break;
|
||||
case '#':
|
||||
*out++ = '#'; /* Hash mark */
|
||||
break;
|
||||
case '?':
|
||||
*out++ = '?'; /* Qestion mark */
|
||||
break;
|
||||
default:
|
||||
*out++ = *in;
|
||||
*out++ = *(in + 1);
|
||||
break;
|
||||
}
|
||||
in++;
|
||||
}
|
||||
*out = '\0';
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Adds one color sequence to array with color scheme.
|
||||
* When returning success (0) this function takes ownership of
|
||||
* @seq and @name, which have to be allocated strings.
|
||||
*/
|
||||
static int colors_add_scheme(struct ul_color_ctl *cc,
|
||||
char *name,
|
||||
char *seq0)
|
||||
{
|
||||
struct ul_color_scheme *cs = NULL;
|
||||
char *seq = NULL;
|
||||
int rc;
|
||||
|
||||
if (!cc || !name || !*name || !seq0 || !*seq0)
|
||||
return -EINVAL;
|
||||
|
||||
DBG(SCHEME, ul_debug("add '%s'", name));
|
||||
|
||||
rc = cn_sequence(seq0, &seq);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = -ENOMEM;
|
||||
|
||||
/* convert logical name (e.g. "red") to real ESC code */
|
||||
if (isalpha(*seq)) {
|
||||
const char *s = color_sequence_from_colorname(seq);
|
||||
char *p;
|
||||
|
||||
if (!s) {
|
||||
DBG(SCHEME, ul_debug("unknown logical name: %s", seq));
|
||||
rc = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
p = strdup(s);
|
||||
if (!p)
|
||||
goto err;
|
||||
free(seq);
|
||||
seq = p;
|
||||
}
|
||||
|
||||
/* enlarge the array */
|
||||
if (cc->nschemes == cc->schemes_sz) {
|
||||
void *tmp = realloc(cc->schemes, (cc->nschemes + 10)
|
||||
* sizeof(struct ul_color_scheme));
|
||||
if (!tmp)
|
||||
goto err;
|
||||
cc->schemes = tmp;
|
||||
cc->schemes_sz = cc->nschemes + 10;
|
||||
}
|
||||
|
||||
/* add a new item */
|
||||
cs = &cc->schemes[cc->nschemes];
|
||||
cs->seq = seq;
|
||||
cs->name = strdup(name);
|
||||
if (!cs->name)
|
||||
goto err;
|
||||
|
||||
cc->nschemes++;
|
||||
return 0;
|
||||
err:
|
||||
if (cs) {
|
||||
free(cs->seq);
|
||||
free(cs->name);
|
||||
cs->seq = cs->name = NULL;
|
||||
} else
|
||||
free(seq);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Deallocates all regards to color schemes
|
||||
*/
|
||||
static void colors_free_schemes(struct ul_color_ctl *cc)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
DBG(SCHEME, ul_debug("free scheme"));
|
||||
|
||||
for (i = 0; i < cc->nschemes; i++) {
|
||||
free(cc->schemes[i].name);
|
||||
free(cc->schemes[i].seq);
|
||||
}
|
||||
|
||||
free(cc->schemes);
|
||||
cc->schemes = NULL;
|
||||
cc->nschemes = 0;
|
||||
cc->schemes_sz = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* The scheme configuration has to be sorted for bsearch
|
||||
*/
|
||||
static void colors_sort_schemes(struct ul_color_ctl *cc)
|
||||
{
|
||||
if (!cc->nschemes)
|
||||
return;
|
||||
|
||||
DBG(SCHEME, ul_debug("sort scheme"));
|
||||
|
||||
qsort(cc->schemes, cc->nschemes,
|
||||
sizeof(struct ul_color_scheme), cmp_scheme_name);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns just one color scheme
|
||||
*/
|
||||
static struct ul_color_scheme *colors_get_scheme(struct ul_color_ctl *cc,
|
||||
const char *name)
|
||||
{
|
||||
struct ul_color_scheme key = { .name = (char *) name}, *res;
|
||||
|
||||
if (!cc || !name || !*name)
|
||||
return NULL;
|
||||
|
||||
if (!cc->cs_configured) {
|
||||
int rc = colors_read_schemes(cc);
|
||||
if (rc)
|
||||
return NULL;
|
||||
}
|
||||
if (!cc->nschemes)
|
||||
return NULL;
|
||||
|
||||
DBG(SCHEME, ul_debug("search '%s'", name));
|
||||
|
||||
res = bsearch(&key, cc->schemes, cc->nschemes,
|
||||
sizeof(struct ul_color_scheme),
|
||||
cmp_scheme_name);
|
||||
|
||||
return res && res->seq ? res : NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parses filenames in terminal-colors.d
|
||||
*/
|
||||
static int colors_read_configuration(struct ul_color_ctl *cc)
|
||||
{
|
||||
int rc = -ENOENT;
|
||||
char *dirname, buf[PATH_MAX];
|
||||
|
||||
cc->termname = getenv("TERM");
|
||||
|
||||
dirname = colors_get_homedir(buf, sizeof(buf));
|
||||
if (dirname)
|
||||
rc = colors_readdir(cc, dirname); /* ~/.config */
|
||||
if (rc == -EPERM || rc == -EACCES || rc == -ENOENT)
|
||||
rc = colors_readdir(cc, _PATH_TERMCOLORS_DIR); /* /etc */
|
||||
|
||||
cc->configured = 1;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reads terminal-colors.d/ scheme file into array schemes
|
||||
*/
|
||||
static int colors_read_schemes(struct ul_color_ctl *cc)
|
||||
{
|
||||
int rc = 0;
|
||||
FILE *f = NULL;
|
||||
char buf[BUFSIZ],
|
||||
cn[129], seq[129];
|
||||
|
||||
if (!cc->configured)
|
||||
rc = colors_read_configuration(cc);
|
||||
|
||||
cc->cs_configured = 1;
|
||||
|
||||
if (rc || !cc->sfile)
|
||||
goto done;
|
||||
|
||||
DBG(SCHEME, ul_debug("reading file '%s'", cc->sfile));
|
||||
|
||||
f = fopen(cc->sfile, "r");
|
||||
if (!f) {
|
||||
rc = -errno;
|
||||
goto done;
|
||||
}
|
||||
|
||||
while (fgets(buf, sizeof(buf), f)) {
|
||||
char *p = strchr(buf, '\n');
|
||||
|
||||
if (!p) {
|
||||
if (feof(f))
|
||||
p = strchr(buf, '\0');
|
||||
else {
|
||||
rc = -errno;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
*p = '\0';
|
||||
p = (char *) skip_blank(buf);
|
||||
if (*p == '\0' || *p == '#')
|
||||
continue;
|
||||
|
||||
rc = sscanf(p, "%128[^ ] %128[^\n ]", cn, seq);
|
||||
if (rc == 2 && *cn && *seq) {
|
||||
rc = colors_add_scheme(cc, cn, seq); /* set rc=0 on success */
|
||||
if (rc)
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
rc = 0;
|
||||
|
||||
done:
|
||||
if (f)
|
||||
fclose(f);
|
||||
colors_sort_schemes(cc);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
static void termcolors_init_debug(void)
|
||||
{
|
||||
__UL_INIT_DEBUG(termcolors, TERMCOLORS_DEBUG_, 0, TERMINAL_COLORS_DEBUG);
|
||||
}
|
||||
|
||||
/**
|
||||
* colors_init:
|
||||
* @mode: UL_COLORMODE_*
|
||||
* @name: util argv[0]
|
||||
*
|
||||
* Initialize private color control struct and initialize the colors
|
||||
* status. The color schemes are parsed on demand by colors_get_scheme().
|
||||
*
|
||||
* Returns: >0 on success.
|
||||
*/
|
||||
int colors_init(int mode, const char *name)
|
||||
{
|
||||
int atty = -1;
|
||||
struct ul_color_ctl *cc = &ul_colors;
|
||||
|
||||
cc->utilname = name;
|
||||
cc->mode = mode;
|
||||
|
||||
termcolors_init_debug();
|
||||
|
||||
if (mode == UL_COLORMODE_UNDEF && (atty = isatty(STDOUT_FILENO))) {
|
||||
int rc = colors_read_configuration(cc);
|
||||
if (rc)
|
||||
cc->mode = UL_COLORMODE_AUTO;
|
||||
else {
|
||||
|
||||
/* evaluate scores */
|
||||
if (cc->scores[UL_COLORFILE_DISABLE] >
|
||||
cc->scores[UL_COLORFILE_ENABLE])
|
||||
cc->mode = UL_COLORMODE_NEVER;
|
||||
else
|
||||
cc->mode = UL_COLORMODE_AUTO;
|
||||
|
||||
atexit(colors_deinit);
|
||||
}
|
||||
}
|
||||
|
||||
switch (cc->mode) {
|
||||
case UL_COLORMODE_AUTO:
|
||||
cc->has_colors = atty == -1 ? isatty(STDOUT_FILENO) : atty;
|
||||
break;
|
||||
case UL_COLORMODE_ALWAYS:
|
||||
cc->has_colors = 1;
|
||||
break;
|
||||
case UL_COLORMODE_NEVER:
|
||||
default:
|
||||
cc->has_colors = 0;
|
||||
}
|
||||
|
||||
ON_DBG(CONF, colors_debug(cc));
|
||||
|
||||
return cc->has_colors;
|
||||
}
|
||||
|
||||
/*
|
||||
* Temporary disable colors (this setting is independent on terminal-colors.d/)
|
||||
*/
|
||||
void colors_off(void)
|
||||
{
|
||||
ul_colors.disabled = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable colors
|
||||
*/
|
||||
void colors_on(void)
|
||||
{
|
||||
ul_colors.disabled = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Is terminal-colors.d/ configured to use colors?
|
||||
*/
|
||||
int colors_wanted(void)
|
||||
{
|
||||
return ul_colors.has_colors;
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable @seq color
|
||||
*/
|
||||
void color_fenable(const char *seq, FILE *f)
|
||||
{
|
||||
if (!ul_colors.disabled && ul_colors.has_colors && seq)
|
||||
fputs(seq, f);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns escape sequence by logical @name, if undefined then returns @dflt.
|
||||
*/
|
||||
const char *color_scheme_get_sequence(const char *name, const char *dflt)
|
||||
{
|
||||
struct ul_color_scheme *cs;
|
||||
|
||||
if (ul_colors.disabled || !ul_colors.has_colors)
|
||||
return NULL;
|
||||
|
||||
cs = colors_get_scheme(&ul_colors, name);
|
||||
return cs && cs->seq ? cs->seq : dflt;
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable color by logical @name, if undefined enable @dflt.
|
||||
*/
|
||||
void color_scheme_fenable(const char *name, const char *dflt, FILE *f)
|
||||
{
|
||||
const char *seq = color_scheme_get_sequence(name, dflt);
|
||||
|
||||
if (!seq)
|
||||
return;
|
||||
color_fenable(seq, f);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Disable previously enabled color
|
||||
*/
|
||||
void color_fdisable(FILE *f)
|
||||
{
|
||||
if (!ul_colors.disabled && ul_colors.has_colors)
|
||||
fputs(UL_COLOR_RESET, f);
|
||||
}
|
||||
|
||||
/*
|
||||
* Parses @str to return UL_COLORMODE_*
|
||||
*/
|
||||
int colormode_from_string(const char *str)
|
||||
{
|
||||
size_t i;
|
||||
static const char *modes[] = {
|
||||
[UL_COLORMODE_AUTO] = "auto",
|
||||
[UL_COLORMODE_NEVER] = "never",
|
||||
[UL_COLORMODE_ALWAYS] = "always",
|
||||
[UL_COLORMODE_UNDEF] = ""
|
||||
};
|
||||
|
||||
if (!str || !*str)
|
||||
return -EINVAL;
|
||||
|
||||
assert(ARRAY_SIZE(modes) == __UL_NCOLORMODES);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(modes); i++) {
|
||||
if (strcasecmp(str, modes[i]) == 0)
|
||||
return i;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parses @str and exit(EXIT_FAILURE) on error
|
||||
*/
|
||||
int colormode_or_err(const char *str, const char *errmsg)
|
||||
{
|
||||
const char *p = str && *str == '=' ? str + 1 : str;
|
||||
int colormode;
|
||||
|
||||
colormode = colormode_from_string(p);
|
||||
if (colormode < 0)
|
||||
errx(EXIT_FAILURE, "%s: '%s'", errmsg, p);
|
||||
|
||||
return colormode;
|
||||
}
|
||||
|
||||
#ifdef TEST_PROGRAM
|
||||
# include <getopt.h>
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
static const struct option longopts[] = {
|
||||
{ "mode", required_argument, 0, 'm' },
|
||||
{ "color", required_argument, 0, 'c' },
|
||||
{ "color-scheme", required_argument, 0, 'C' },
|
||||
{ "name", required_argument, 0, 'n' },
|
||||
{ NULL, 0, 0, 0 }
|
||||
};
|
||||
int c, mode = UL_COLORMODE_UNDEF; /* default */
|
||||
const char *color = "red", *name = NULL, *color_scheme = NULL;
|
||||
const char *seq = NULL;
|
||||
|
||||
while ((c = getopt_long(argc, argv, "C:c:m:n:", longopts, NULL)) != -1) {
|
||||
switch (c) {
|
||||
case 'c':
|
||||
color = optarg;
|
||||
break;
|
||||
case 'C':
|
||||
color_scheme = optarg;
|
||||
break;
|
||||
case 'm':
|
||||
mode = colormode_or_err(optarg, "unsupported color mode");
|
||||
break;
|
||||
case 'n':
|
||||
name = optarg;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "usage: %s [options]\n"
|
||||
" -m, --mode <auto|never|always> default is undefined\n"
|
||||
" -c, --color <red|blue|...> color for the test message\n"
|
||||
" -C, --color-scheme <name> color for the test message\n"
|
||||
" -n, --name <utilname> util name\n",
|
||||
program_invocation_short_name);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
colors_init(mode, name ? name : program_invocation_short_name);
|
||||
|
||||
seq = color_sequence_from_colorname(color);
|
||||
|
||||
if (color_scheme)
|
||||
color_scheme_enable(color_scheme, seq);
|
||||
else
|
||||
color_enable(seq);
|
||||
printf("Hello World!");
|
||||
color_disable();
|
||||
fputc('\n', stdout);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -388,6 +388,7 @@ int main(int argc, char *argv[])
|
||||
printf("[%s]\n", cpulist_create(buf, buflen, set, setsize));
|
||||
|
||||
free(buf);
|
||||
free(mask);
|
||||
free(range);
|
||||
cpuset_free(set);
|
||||
|
||||
@@ -108,8 +108,10 @@ uint32_t crc32(uint32_t seed, const unsigned char *buf, size_t len)
|
||||
uint32_t crc = seed;
|
||||
const unsigned char *p = buf;
|
||||
|
||||
while(len-- > 0)
|
||||
while (len) {
|
||||
crc = crc32_tab[(crc ^ *p++) & 0xff] ^ (crc >> 8);
|
||||
len--;
|
||||
}
|
||||
|
||||
return crc;
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
#include "crc64.h"
|
||||
|
||||
static const uint64_t crc64_tab[256] = {
|
||||
0x0000000000000000ULL, 0x42F0E1EBA9EA3693ULL, 0x85E1C3D753D46D26ULL,
|
||||
0xC711223CFA3E5BB5ULL, 0x493366450E42ECDFULL, 0x0BC387AEA7A8DA4CULL,
|
||||
0xCCD2A5925D9681F9ULL, 0x8E224479F47CB76AULL, 0x9266CC8A1C85D9BEULL,
|
||||
0xD0962D61B56FEF2DULL, 0x17870F5D4F51B498ULL, 0x5577EEB6E6BB820BULL,
|
||||
0xDB55AACF12C73561ULL, 0x99A54B24BB2D03F2ULL, 0x5EB4691841135847ULL,
|
||||
0x1C4488F3E8F96ED4ULL, 0x663D78FF90E185EFULL, 0x24CD9914390BB37CULL,
|
||||
0xE3DCBB28C335E8C9ULL, 0xA12C5AC36ADFDE5AULL, 0x2F0E1EBA9EA36930ULL,
|
||||
0x6DFEFF5137495FA3ULL, 0xAAEFDD6DCD770416ULL, 0xE81F3C86649D3285ULL,
|
||||
0xF45BB4758C645C51ULL, 0xB6AB559E258E6AC2ULL, 0x71BA77A2DFB03177ULL,
|
||||
0x334A9649765A07E4ULL, 0xBD68D2308226B08EULL, 0xFF9833DB2BCC861DULL,
|
||||
0x388911E7D1F2DDA8ULL, 0x7A79F00C7818EB3BULL, 0xCC7AF1FF21C30BDEULL,
|
||||
0x8E8A101488293D4DULL, 0x499B3228721766F8ULL, 0x0B6BD3C3DBFD506BULL,
|
||||
0x854997BA2F81E701ULL, 0xC7B97651866BD192ULL, 0x00A8546D7C558A27ULL,
|
||||
0x4258B586D5BFBCB4ULL, 0x5E1C3D753D46D260ULL, 0x1CECDC9E94ACE4F3ULL,
|
||||
0xDBFDFEA26E92BF46ULL, 0x990D1F49C77889D5ULL, 0x172F5B3033043EBFULL,
|
||||
0x55DFBADB9AEE082CULL, 0x92CE98E760D05399ULL, 0xD03E790CC93A650AULL,
|
||||
0xAA478900B1228E31ULL, 0xE8B768EB18C8B8A2ULL, 0x2FA64AD7E2F6E317ULL,
|
||||
0x6D56AB3C4B1CD584ULL, 0xE374EF45BF6062EEULL, 0xA1840EAE168A547DULL,
|
||||
0x66952C92ECB40FC8ULL, 0x2465CD79455E395BULL, 0x3821458AADA7578FULL,
|
||||
0x7AD1A461044D611CULL, 0xBDC0865DFE733AA9ULL, 0xFF3067B657990C3AULL,
|
||||
0x711223CFA3E5BB50ULL, 0x33E2C2240A0F8DC3ULL, 0xF4F3E018F031D676ULL,
|
||||
0xB60301F359DBE0E5ULL, 0xDA050215EA6C212FULL, 0x98F5E3FE438617BCULL,
|
||||
0x5FE4C1C2B9B84C09ULL, 0x1D14202910527A9AULL, 0x93366450E42ECDF0ULL,
|
||||
0xD1C685BB4DC4FB63ULL, 0x16D7A787B7FAA0D6ULL, 0x5427466C1E109645ULL,
|
||||
0x4863CE9FF6E9F891ULL, 0x0A932F745F03CE02ULL, 0xCD820D48A53D95B7ULL,
|
||||
0x8F72ECA30CD7A324ULL, 0x0150A8DAF8AB144EULL, 0x43A04931514122DDULL,
|
||||
0x84B16B0DAB7F7968ULL, 0xC6418AE602954FFBULL, 0xBC387AEA7A8DA4C0ULL,
|
||||
0xFEC89B01D3679253ULL, 0x39D9B93D2959C9E6ULL, 0x7B2958D680B3FF75ULL,
|
||||
0xF50B1CAF74CF481FULL, 0xB7FBFD44DD257E8CULL, 0x70EADF78271B2539ULL,
|
||||
0x321A3E938EF113AAULL, 0x2E5EB66066087D7EULL, 0x6CAE578BCFE24BEDULL,
|
||||
0xABBF75B735DC1058ULL, 0xE94F945C9C3626CBULL, 0x676DD025684A91A1ULL,
|
||||
0x259D31CEC1A0A732ULL, 0xE28C13F23B9EFC87ULL, 0xA07CF2199274CA14ULL,
|
||||
0x167FF3EACBAF2AF1ULL, 0x548F120162451C62ULL, 0x939E303D987B47D7ULL,
|
||||
0xD16ED1D631917144ULL, 0x5F4C95AFC5EDC62EULL, 0x1DBC74446C07F0BDULL,
|
||||
0xDAAD56789639AB08ULL, 0x985DB7933FD39D9BULL, 0x84193F60D72AF34FULL,
|
||||
0xC6E9DE8B7EC0C5DCULL, 0x01F8FCB784FE9E69ULL, 0x43081D5C2D14A8FAULL,
|
||||
0xCD2A5925D9681F90ULL, 0x8FDAB8CE70822903ULL, 0x48CB9AF28ABC72B6ULL,
|
||||
0x0A3B7B1923564425ULL, 0x70428B155B4EAF1EULL, 0x32B26AFEF2A4998DULL,
|
||||
0xF5A348C2089AC238ULL, 0xB753A929A170F4ABULL, 0x3971ED50550C43C1ULL,
|
||||
0x7B810CBBFCE67552ULL, 0xBC902E8706D82EE7ULL, 0xFE60CF6CAF321874ULL,
|
||||
0xE224479F47CB76A0ULL, 0xA0D4A674EE214033ULL, 0x67C58448141F1B86ULL,
|
||||
0x253565A3BDF52D15ULL, 0xAB1721DA49899A7FULL, 0xE9E7C031E063ACECULL,
|
||||
0x2EF6E20D1A5DF759ULL, 0x6C0603E6B3B7C1CAULL, 0xF6FAE5C07D3274CDULL,
|
||||
0xB40A042BD4D8425EULL, 0x731B26172EE619EBULL, 0x31EBC7FC870C2F78ULL,
|
||||
0xBFC9838573709812ULL, 0xFD39626EDA9AAE81ULL, 0x3A28405220A4F534ULL,
|
||||
0x78D8A1B9894EC3A7ULL, 0x649C294A61B7AD73ULL, 0x266CC8A1C85D9BE0ULL,
|
||||
0xE17DEA9D3263C055ULL, 0xA38D0B769B89F6C6ULL, 0x2DAF4F0F6FF541ACULL,
|
||||
0x6F5FAEE4C61F773FULL, 0xA84E8CD83C212C8AULL, 0xEABE6D3395CB1A19ULL,
|
||||
0x90C79D3FEDD3F122ULL, 0xD2377CD44439C7B1ULL, 0x15265EE8BE079C04ULL,
|
||||
0x57D6BF0317EDAA97ULL, 0xD9F4FB7AE3911DFDULL, 0x9B041A914A7B2B6EULL,
|
||||
0x5C1538ADB04570DBULL, 0x1EE5D94619AF4648ULL, 0x02A151B5F156289CULL,
|
||||
0x4051B05E58BC1E0FULL, 0x87409262A28245BAULL, 0xC5B073890B687329ULL,
|
||||
0x4B9237F0FF14C443ULL, 0x0962D61B56FEF2D0ULL, 0xCE73F427ACC0A965ULL,
|
||||
0x8C8315CC052A9FF6ULL, 0x3A80143F5CF17F13ULL, 0x7870F5D4F51B4980ULL,
|
||||
0xBF61D7E80F251235ULL, 0xFD913603A6CF24A6ULL, 0x73B3727A52B393CCULL,
|
||||
0x31439391FB59A55FULL, 0xF652B1AD0167FEEAULL, 0xB4A25046A88DC879ULL,
|
||||
0xA8E6D8B54074A6ADULL, 0xEA16395EE99E903EULL, 0x2D071B6213A0CB8BULL,
|
||||
0x6FF7FA89BA4AFD18ULL, 0xE1D5BEF04E364A72ULL, 0xA3255F1BE7DC7CE1ULL,
|
||||
0x64347D271DE22754ULL, 0x26C49CCCB40811C7ULL, 0x5CBD6CC0CC10FAFCULL,
|
||||
0x1E4D8D2B65FACC6FULL, 0xD95CAF179FC497DAULL, 0x9BAC4EFC362EA149ULL,
|
||||
0x158E0A85C2521623ULL, 0x577EEB6E6BB820B0ULL, 0x906FC95291867B05ULL,
|
||||
0xD29F28B9386C4D96ULL, 0xCEDBA04AD0952342ULL, 0x8C2B41A1797F15D1ULL,
|
||||
0x4B3A639D83414E64ULL, 0x09CA82762AAB78F7ULL, 0x87E8C60FDED7CF9DULL,
|
||||
0xC51827E4773DF90EULL, 0x020905D88D03A2BBULL, 0x40F9E43324E99428ULL,
|
||||
0x2CFFE7D5975E55E2ULL, 0x6E0F063E3EB46371ULL, 0xA91E2402C48A38C4ULL,
|
||||
0xEBEEC5E96D600E57ULL, 0x65CC8190991CB93DULL, 0x273C607B30F68FAEULL,
|
||||
0xE02D4247CAC8D41BULL, 0xA2DDA3AC6322E288ULL, 0xBE992B5F8BDB8C5CULL,
|
||||
0xFC69CAB42231BACFULL, 0x3B78E888D80FE17AULL, 0x7988096371E5D7E9ULL,
|
||||
0xF7AA4D1A85996083ULL, 0xB55AACF12C735610ULL, 0x724B8ECDD64D0DA5ULL,
|
||||
0x30BB6F267FA73B36ULL, 0x4AC29F2A07BFD00DULL, 0x08327EC1AE55E69EULL,
|
||||
0xCF235CFD546BBD2BULL, 0x8DD3BD16FD818BB8ULL, 0x03F1F96F09FD3CD2ULL,
|
||||
0x41011884A0170A41ULL, 0x86103AB85A2951F4ULL, 0xC4E0DB53F3C36767ULL,
|
||||
0xD8A453A01B3A09B3ULL, 0x9A54B24BB2D03F20ULL, 0x5D45907748EE6495ULL,
|
||||
0x1FB5719CE1045206ULL, 0x919735E51578E56CULL, 0xD367D40EBC92D3FFULL,
|
||||
0x1476F63246AC884AULL, 0x568617D9EF46BED9ULL, 0xE085162AB69D5E3CULL,
|
||||
0xA275F7C11F7768AFULL, 0x6564D5FDE549331AULL, 0x279434164CA30589ULL,
|
||||
0xA9B6706FB8DFB2E3ULL, 0xEB46918411358470ULL, 0x2C57B3B8EB0BDFC5ULL,
|
||||
0x6EA7525342E1E956ULL, 0x72E3DAA0AA188782ULL, 0x30133B4B03F2B111ULL,
|
||||
0xF7021977F9CCEAA4ULL, 0xB5F2F89C5026DC37ULL, 0x3BD0BCE5A45A6B5DULL,
|
||||
0x79205D0E0DB05DCEULL, 0xBE317F32F78E067BULL, 0xFCC19ED95E6430E8ULL,
|
||||
0x86B86ED5267CDBD3ULL, 0xC4488F3E8F96ED40ULL, 0x0359AD0275A8B6F5ULL,
|
||||
0x41A94CE9DC428066ULL, 0xCF8B0890283E370CULL, 0x8D7BE97B81D4019FULL,
|
||||
0x4A6ACB477BEA5A2AULL, 0x089A2AACD2006CB9ULL, 0x14DEA25F3AF9026DULL,
|
||||
0x562E43B4931334FEULL, 0x913F6188692D6F4BULL, 0xD3CF8063C0C759D8ULL,
|
||||
0x5DEDC41A34BBEEB2ULL, 0x1F1D25F19D51D821ULL, 0xD80C07CD676F8394ULL,
|
||||
0x9AFCE626CE85B507ULL
|
||||
};
|
||||
|
||||
/*
|
||||
* This a generic crc64() function, it takes seed as an argument,
|
||||
* and does __not__ xor at the end. Then individual users can do
|
||||
* whatever they need.
|
||||
*/
|
||||
uint64_t crc64(uint64_t seed, const unsigned char *data, size_t len)
|
||||
{
|
||||
uint64_t crc = seed;
|
||||
|
||||
while (len) {
|
||||
int i = ((int) (crc >> 56) ^ *data++) & 0xFF;
|
||||
crc = crc64_tab[i] ^ (crc << 8);
|
||||
len--;
|
||||
}
|
||||
|
||||
return crc;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* exec_shell() - launch a shell, else exit!
|
||||
*
|
||||
* 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, 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, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "nls.h"
|
||||
#include "c.h"
|
||||
#include "xalloc.h"
|
||||
|
||||
#include "exec_shell.h"
|
||||
|
||||
#define DEFAULT_SHELL "/bin/sh"
|
||||
|
||||
void exec_shell(void)
|
||||
{
|
||||
const char *shell = getenv("SHELL"), *shell_basename;
|
||||
char *arg0;
|
||||
if (!shell)
|
||||
shell = DEFAULT_SHELL;
|
||||
|
||||
shell_basename = basename(shell);
|
||||
arg0 = xmalloc(strlen(shell_basename) + 2);
|
||||
arg0[0] = '-';
|
||||
strcpy(arg0 + 1, shell_basename);
|
||||
|
||||
execl(shell, arg0, NULL);
|
||||
err(EXIT_FAILURE, _("failed to execute %s"), shell);
|
||||
}
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <paths.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
@@ -12,9 +13,7 @@
|
||||
#include "c.h"
|
||||
#include "fileutils.h"
|
||||
#include "pathnames.h"
|
||||
#include "xalloc.h"
|
||||
|
||||
#define _PATH_TMP "/tmp"
|
||||
/* Create open temporary file in safe way. Please notice that the
|
||||
* file permissions are -rw------- by default. */
|
||||
int xmkstemp(char **tmpname, char *dir)
|
||||
@@ -22,7 +21,7 @@ int xmkstemp(char **tmpname, char *dir)
|
||||
char *localtmp;
|
||||
char *tmpenv;
|
||||
mode_t old_mode;
|
||||
int fd;
|
||||
int fd, rc;
|
||||
|
||||
/* Some use cases must be capable of being moved atomically
|
||||
* with rename(2), which is the reason why dir is here. */
|
||||
@@ -32,11 +31,15 @@ int xmkstemp(char **tmpname, char *dir)
|
||||
tmpenv = getenv("TMPDIR");
|
||||
|
||||
if (tmpenv)
|
||||
xasprintf(&localtmp, "%s/%s.XXXXXX", tmpenv,
|
||||
rc = asprintf(&localtmp, "%s/%s.XXXXXX", tmpenv,
|
||||
program_invocation_short_name);
|
||||
else
|
||||
xasprintf(&localtmp, "%s/%s.XXXXXX", _PATH_TMP,
|
||||
rc = asprintf(&localtmp, "%s/%s.XXXXXX", _PATH_TMP,
|
||||
program_invocation_short_name);
|
||||
|
||||
if (rc < 0)
|
||||
return -1;
|
||||
|
||||
old_mode = umask(077);
|
||||
fd = mkstemp(localtmp);
|
||||
umask(old_mode);
|
||||
@@ -82,3 +85,51 @@ int main(void)
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
int mkdir_p(const char *path, mode_t mode)
|
||||
{
|
||||
char *p, *dir;
|
||||
int rc = 0;
|
||||
|
||||
if (!path || !*path)
|
||||
return -EINVAL;
|
||||
|
||||
dir = p = strdup(path);
|
||||
if (!dir)
|
||||
return -ENOMEM;
|
||||
|
||||
if (*p == '/')
|
||||
p++;
|
||||
|
||||
while (p && *p) {
|
||||
char *e = strchr(p, '/');
|
||||
if (e)
|
||||
*e = '\0';
|
||||
if (*p) {
|
||||
rc = mkdir(dir, mode);
|
||||
if (rc && errno != EEXIST)
|
||||
break;
|
||||
rc = 0;
|
||||
}
|
||||
if (!e)
|
||||
break;
|
||||
*e = '/';
|
||||
p = e + 1;
|
||||
}
|
||||
|
||||
free(dir);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* returns basename and keeps dirname in the @path, if @path is "/" (root)
|
||||
* then returns empty string */
|
||||
char *stripoff_last_component(char *path)
|
||||
{
|
||||
char *p = path ? strrchr(path, '/') : NULL;
|
||||
|
||||
if (!p)
|
||||
return NULL;
|
||||
*p = '\0';
|
||||
return p + 1;
|
||||
}
|
||||
@@ -156,7 +156,7 @@ static int check_mntent_file(const char *mtab_file, const char *file,
|
||||
is_root:
|
||||
#define TEST_FILE "/.ismount-test-file"
|
||||
*mount_flags |= MF_ISROOT;
|
||||
fd = open(TEST_FILE, O_RDWR|O_CREAT, 0600);
|
||||
fd = open(TEST_FILE, O_RDWR|O_CREAT|O_CLOEXEC, 0600);
|
||||
if (fd < 0) {
|
||||
if (errno == EROFS)
|
||||
*mount_flags |= MF_READONLY;
|
||||
@@ -317,7 +317,8 @@ int check_mount_point(const char *device, int *mount_flags,
|
||||
|
||||
if (is_swap_device(device)) {
|
||||
*mount_flags = MF_MOUNTED | MF_SWAP;
|
||||
strncpy(mtpt, "<swap>", mtlen);
|
||||
if (mtpt && mtlen)
|
||||
strncpy(mtpt, "[SWAP]", mtlen);
|
||||
} else {
|
||||
#ifdef HAVE_MNTENT_H
|
||||
retval = check_mntent(device, mount_flags, mtpt, mtlen);
|
||||
@@ -339,7 +340,7 @@ int check_mount_point(const char *device, int *mount_flags,
|
||||
if ((stat(device, &st_buf) != 0) ||
|
||||
!S_ISBLK(st_buf.st_mode))
|
||||
return 0;
|
||||
fd = open(device, O_RDONLY | O_EXCL);
|
||||
fd = open(device, O_RDONLY|O_EXCL|O_CLOEXEC);
|
||||
if (fd < 0) {
|
||||
if (errno == EBUSY)
|
||||
*mount_flags |= MF_BUSY;
|
||||
@@ -41,33 +41,31 @@
|
||||
#include "loopdev.h"
|
||||
#include "canonicalize.h"
|
||||
#include "at.h"
|
||||
#include "blkdev.h"
|
||||
#include "debug.h"
|
||||
|
||||
#define CONFIG_LOOPDEV_DEBUG
|
||||
/*
|
||||
* Debug stuff (based on include/debug.h)
|
||||
*/
|
||||
UL_DEBUG_DEFINE_MASK(loopdev);
|
||||
UL_DEBUG_DEFINE_MASKNAMES(loopdev) = UL_DEBUG_EMPTY_MASKNAMES;
|
||||
|
||||
#ifdef CONFIG_LOOPDEV_DEBUG
|
||||
# include <stdarg.h>
|
||||
#define LOOPDEV_DEBUG_INIT (1 << 1)
|
||||
#define LOOPDEV_DEBUG_CXT (1 << 2)
|
||||
#define LOOPDEV_DEBUG_ITER (1 << 3)
|
||||
#define LOOPDEV_DEBUG_SETUP (1 << 4)
|
||||
#define SFDISKPROG_DEBUG_ALL 0xFFFF
|
||||
|
||||
# define DBG(l,x) do { \
|
||||
if ((l)->debug) {\
|
||||
fprintf(stderr, "loopdev: [%p]: ", (l)); \
|
||||
x; \
|
||||
} \
|
||||
} while(0)
|
||||
#define DBG(m, x) __UL_DBG(loopdev, LOOPDEV_DEBUG_, m, x)
|
||||
#define ON_DBG(m, x) __UL_DBG_CALL(loopdev, LOOPDEV_DEBUG_, m, x)
|
||||
|
||||
static inline void __attribute__ ((__format__ (__printf__, 1, 2)))
|
||||
loopdev_debug(const char *mesg, ...)
|
||||
static void loopdev_init_debug(void)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, mesg);
|
||||
vfprintf(stderr, mesg, ap);
|
||||
va_end(ap);
|
||||
fputc('\n', stderr);
|
||||
if (loopdev_debug_mask)
|
||||
return;
|
||||
__UL_INIT_DEBUG(loopdev, LOOPDEV_DEBUG_, 0, LOOPDEV_DEBUG);
|
||||
}
|
||||
|
||||
#else /* !CONFIG_LOOPDEV_DEBUG */
|
||||
# define DBG(m,x) do { ; } while(0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* see loopcxt_init()
|
||||
*/
|
||||
@@ -83,6 +81,8 @@ loopdev_debug(const char *mesg, ...)
|
||||
* names ("loop<N>") are converted to the path (/dev/loop<N> or to
|
||||
* /dev/loop/<N>)
|
||||
*
|
||||
* This sets the device name, but does not check if the device exists!
|
||||
*
|
||||
* Returns: <0 on error, 0 on success
|
||||
*/
|
||||
int loopcxt_set_device(struct loopdev_cxt *lc, const char *device)
|
||||
@@ -92,7 +92,7 @@ int loopcxt_set_device(struct loopdev_cxt *lc, const char *device)
|
||||
|
||||
if (lc->fd >= 0) {
|
||||
close(lc->fd);
|
||||
DBG(lc, loopdev_debug("closing old open fd"));
|
||||
DBG(CXT, ul_debugobj(lc, "closing old open fd"));
|
||||
}
|
||||
lc->fd = -1;
|
||||
lc->mode = 0;
|
||||
@@ -119,7 +119,7 @@ int loopcxt_set_device(struct loopdev_cxt *lc, const char *device)
|
||||
strncpy(lc->device, device, sizeof(lc->device));
|
||||
lc->device[sizeof(lc->device) - 1] = '\0';
|
||||
}
|
||||
DBG(lc, loopdev_debug("%s successfully assigned", device));
|
||||
DBG(CXT, ul_debugobj(lc, "%s name assigned", device));
|
||||
}
|
||||
|
||||
sysfs_deinit(&lc->sysfs);
|
||||
@@ -160,12 +160,12 @@ int loopcxt_init(struct loopdev_cxt *lc, int flags)
|
||||
if (!lc)
|
||||
return -EINVAL;
|
||||
|
||||
loopdev_init_debug();
|
||||
DBG(CXT, ul_debugobj(lc, "initialize context"));
|
||||
|
||||
memcpy(lc, &dummy, sizeof(dummy));
|
||||
lc->flags = flags;
|
||||
|
||||
if (getenv("LOOPDEV_DEBUG"))
|
||||
loopcxt_enable_debug(lc, TRUE);
|
||||
|
||||
rc = loopcxt_set_device(lc, NULL);
|
||||
if (rc)
|
||||
return rc;
|
||||
@@ -173,7 +173,7 @@ int loopcxt_init(struct loopdev_cxt *lc, int flags)
|
||||
if (stat(_PATH_SYS_BLOCK, &st) || !S_ISDIR(st.st_mode)) {
|
||||
lc->flags |= LOOPDEV_FL_NOSYSFS;
|
||||
lc->flags &= ~LOOPDEV_FL_NOIOCTL;
|
||||
DBG(lc, loopdev_debug("init: disable /sys usage"));
|
||||
DBG(CXT, ul_debugobj(lc, "init: disable /sys usage"));
|
||||
}
|
||||
|
||||
if (!(lc->flags & LOOPDEV_FL_NOSYSFS) &&
|
||||
@@ -182,12 +182,12 @@ int loopcxt_init(struct loopdev_cxt *lc, int flags)
|
||||
* Use only sysfs for basic information about loop devices
|
||||
*/
|
||||
lc->flags |= LOOPDEV_FL_NOIOCTL;
|
||||
DBG(lc, loopdev_debug("init: ignore ioctls"));
|
||||
DBG(CXT, ul_debugobj(lc, "init: ignore ioctls"));
|
||||
}
|
||||
|
||||
if (!(lc->flags & LOOPDEV_FL_CONTROL) && !stat(_PATH_DEV_LOOPCTL, &st)) {
|
||||
lc->flags |= LOOPDEV_FL_CONTROL;
|
||||
DBG(lc, loopdev_debug("init: loop-control detected "));
|
||||
DBG(CXT, ul_debugobj(lc, "init: loop-control detected "));
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -205,7 +205,7 @@ void loopcxt_deinit(struct loopdev_cxt *lc)
|
||||
if (!lc)
|
||||
return;
|
||||
|
||||
DBG(lc, loopdev_debug("de-initialize"));
|
||||
DBG(CXT, ul_debugobj(lc, "de-initialize"));
|
||||
|
||||
free(lc->filename);
|
||||
lc->filename = NULL;
|
||||
@@ -216,18 +216,6 @@ void loopcxt_deinit(struct loopdev_cxt *lc)
|
||||
errno = errsv;
|
||||
}
|
||||
|
||||
/*
|
||||
* @lc: context
|
||||
* @enable: TRUE/FALSE
|
||||
*
|
||||
* Enabled/disables debug messages
|
||||
*/
|
||||
void loopcxt_enable_debug(struct loopdev_cxt *lc, int enable)
|
||||
{
|
||||
if (lc)
|
||||
lc->debug = enable ? 1 : 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* @lc: context
|
||||
*
|
||||
@@ -235,7 +223,7 @@ void loopcxt_enable_debug(struct loopdev_cxt *lc, int enable)
|
||||
*/
|
||||
char *loopcxt_strdup_device(struct loopdev_cxt *lc)
|
||||
{
|
||||
if (!lc || !lc->device || !*lc->device)
|
||||
if (!lc || !*lc->device)
|
||||
return NULL;
|
||||
return strdup(lc->device);
|
||||
}
|
||||
@@ -247,7 +235,7 @@ char *loopcxt_strdup_device(struct loopdev_cxt *lc)
|
||||
*/
|
||||
const char *loopcxt_get_device(struct loopdev_cxt *lc)
|
||||
{
|
||||
return lc && lc->device && *lc->device ? lc->device : NULL;
|
||||
return lc && *lc->device ? lc->device : NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -263,11 +251,11 @@ struct sysfs_cxt *loopcxt_get_sysfs(struct loopdev_cxt *lc)
|
||||
if (!lc->sysfs.devno) {
|
||||
dev_t devno = sysfs_devname_to_devno(lc->device, NULL);
|
||||
if (!devno) {
|
||||
DBG(lc, loopdev_debug("sysfs: failed devname to devno"));
|
||||
DBG(CXT, ul_debugobj(lc, "sysfs: failed devname to devno"));
|
||||
return NULL;
|
||||
}
|
||||
if (sysfs_init(&lc->sysfs, devno, NULL)) {
|
||||
DBG(lc, loopdev_debug("sysfs: init failed"));
|
||||
DBG(CXT, ul_debugobj(lc, "sysfs: init failed"));
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@@ -289,10 +277,9 @@ int loopcxt_get_fd(struct loopdev_cxt *lc)
|
||||
|
||||
if (lc->fd < 0) {
|
||||
lc->mode = lc->flags & LOOPDEV_FL_RDWR ? O_RDWR : O_RDONLY;
|
||||
lc->fd = open(lc->device, lc->mode);
|
||||
DBG(lc, loopdev_debug("open %s [%s]: %s", lc->device,
|
||||
lc->flags & LOOPDEV_FL_RDWR ? "rw" : "ro",
|
||||
lc->fd < 0 ? "failed" : "ok"));
|
||||
lc->fd = open(lc->device, lc->mode | O_CLOEXEC);
|
||||
DBG(CXT, ul_debugobj(lc, "open %s [%s]: %m", lc->device,
|
||||
lc->flags & LOOPDEV_FL_RDWR ? "rw" : "ro"));
|
||||
}
|
||||
return lc->fd;
|
||||
}
|
||||
@@ -323,9 +310,9 @@ int loopcxt_init_iterator(struct loopdev_cxt *lc, int flags)
|
||||
if (!lc)
|
||||
return -EINVAL;
|
||||
|
||||
DBG(lc, loopdev_debug("iter: initialize"));
|
||||
|
||||
iter = &lc->iter;
|
||||
DBG(ITER, ul_debugobj(iter, "initialize"));
|
||||
|
||||
/* always zeroize
|
||||
*/
|
||||
@@ -359,9 +346,8 @@ int loopcxt_deinit_iterator(struct loopdev_cxt *lc)
|
||||
if (!lc)
|
||||
return -EINVAL;
|
||||
|
||||
DBG(lc, loopdev_debug("iter: de-initialize"));
|
||||
|
||||
iter = &lc->iter;
|
||||
DBG(ITER, ul_debugobj(iter, "de-initialize"));
|
||||
|
||||
free(iter->minors);
|
||||
if (iter->proc)
|
||||
@@ -394,6 +380,13 @@ static int loopiter_set_device(struct loopdev_cxt *lc, const char *device)
|
||||
!(lc->iter.flags & LOOPITER_FL_FREE))
|
||||
return 0; /* caller does not care about device status */
|
||||
|
||||
if (!is_loopdev(lc->device)) {
|
||||
DBG(ITER, ul_debugobj(&lc->iter, "%s does not exist", lc->device));
|
||||
return -errno;
|
||||
}
|
||||
|
||||
DBG(ITER, ul_debugobj(&lc->iter, "%s exist", lc->device));
|
||||
|
||||
used = loopcxt_get_offset(lc, NULL) == 0;
|
||||
|
||||
if ((lc->iter.flags & LOOPITER_FL_USED) && used)
|
||||
@@ -402,7 +395,8 @@ static int loopiter_set_device(struct loopdev_cxt *lc, const char *device)
|
||||
if ((lc->iter.flags & LOOPITER_FL_FREE) && !used)
|
||||
return 0;
|
||||
|
||||
DBG(lc, loopdev_debug("iter: unset device"));
|
||||
DBG(ITER, ul_debugobj(&lc->iter, "failed to use %s device", lc->device));
|
||||
|
||||
ignore_result( loopcxt_set_device(lc, NULL) );
|
||||
return 1;
|
||||
}
|
||||
@@ -426,6 +420,9 @@ static int loop_scandir(const char *dirname, int **ary, int hasprefix)
|
||||
|
||||
if (!dirname || !ary)
|
||||
return 0;
|
||||
|
||||
DBG(ITER, ul_debug("scan dir: %s", dirname));
|
||||
|
||||
dir = opendir(dirname);
|
||||
if (!dir)
|
||||
return 0;
|
||||
@@ -449,6 +446,7 @@ static int loop_scandir(const char *dirname, int **ary, int hasprefix)
|
||||
/* /dev/loop/<N> */
|
||||
char *end = NULL;
|
||||
|
||||
errno = 0;
|
||||
n = strtol(d->d_name, &end, 10);
|
||||
if (d->d_name == end || (end && *end) || errno)
|
||||
continue;
|
||||
@@ -489,7 +487,7 @@ static int loopcxt_next_from_proc(struct loopdev_cxt *lc)
|
||||
struct loopdev_iter *iter = &lc->iter;
|
||||
char buf[BUFSIZ];
|
||||
|
||||
DBG(lc, loopdev_debug("iter: scan /proc/partitions"));
|
||||
DBG(ITER, ul_debugobj(iter, "scan /proc/partitions"));
|
||||
|
||||
if (!iter->proc)
|
||||
iter->proc = fopen(_PATH_PROC_PARTITIONS, "r");
|
||||
@@ -505,7 +503,7 @@ static int loopcxt_next_from_proc(struct loopdev_cxt *lc)
|
||||
&m, name) != 2 || m != LOOPDEV_MAJOR)
|
||||
continue;
|
||||
|
||||
DBG(lc, loopdev_debug("iter: check %s", name));
|
||||
DBG(ITER, ul_debugobj(iter, "checking %s", name));
|
||||
|
||||
if (loopiter_set_device(lc, name) == 0)
|
||||
return 0;
|
||||
@@ -526,7 +524,7 @@ static int loopcxt_next_from_sysfs(struct loopdev_cxt *lc)
|
||||
struct dirent *d;
|
||||
int fd;
|
||||
|
||||
DBG(lc, loopdev_debug("iter: scan /sys/block"));
|
||||
DBG(ITER, ul_debugobj(iter, "scanning /sys/block"));
|
||||
|
||||
if (!iter->sysblock)
|
||||
iter->sysblock = opendir(_PATH_SYS_BLOCK);
|
||||
@@ -540,7 +538,7 @@ static int loopcxt_next_from_sysfs(struct loopdev_cxt *lc)
|
||||
char name[256];
|
||||
struct stat st;
|
||||
|
||||
DBG(lc, loopdev_debug("iter: check %s", d->d_name));
|
||||
DBG(ITER, ul_debugobj(iter, "check %s", d->d_name));
|
||||
|
||||
if (strcmp(d->d_name, ".") == 0
|
||||
|| strcmp(d->d_name, "..") == 0
|
||||
@@ -572,12 +570,13 @@ int loopcxt_next(struct loopdev_cxt *lc)
|
||||
if (!lc)
|
||||
return -EINVAL;
|
||||
|
||||
DBG(lc, loopdev_debug("iter: next"));
|
||||
|
||||
iter = &lc->iter;
|
||||
if (iter->done)
|
||||
return 1;
|
||||
|
||||
DBG(ITER, ul_debugobj(iter, "next"));
|
||||
|
||||
/* A) Look for used loop devices in /proc/partitions ("losetup -a" only)
|
||||
*/
|
||||
if (iter->flags & LOOPITER_FL_USED) {
|
||||
@@ -596,7 +595,7 @@ int loopcxt_next(struct loopdev_cxt *lc)
|
||||
* of loop devices). This is enough for 99% of all cases.
|
||||
*/
|
||||
if (iter->default_check) {
|
||||
DBG(lc, loopdev_debug("iter: next: default check"));
|
||||
DBG(ITER, ul_debugobj(iter, "next: default check"));
|
||||
for (++iter->ncur; iter->ncur < LOOPDEV_DEFAULT_NNODES;
|
||||
iter->ncur++) {
|
||||
char name[16];
|
||||
@@ -611,7 +610,7 @@ int loopcxt_next(struct loopdev_cxt *lc)
|
||||
/* C) the worst possibility, scan whole /dev or /dev/loop/<N>
|
||||
*/
|
||||
if (!iter->minors) {
|
||||
DBG(lc, loopdev_debug("iter: next: scan /dev"));
|
||||
DBG(ITER, ul_debugobj(iter, "next: scanning /dev"));
|
||||
iter->nminors = (lc->flags & LOOPDEV_FL_DEVSUBDIR) ?
|
||||
loop_scandir(_PATH_DEV_LOOP, &iter->minors, 0) :
|
||||
loop_scandir(_PATH_DEV, &iter->minors, 1);
|
||||
@@ -653,8 +652,11 @@ struct loop_info64 *loopcxt_get_info(struct loopdev_cxt *lc)
|
||||
{
|
||||
int fd;
|
||||
|
||||
if (!lc || lc->info_failed)
|
||||
if (!lc || lc->info_failed) {
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
errno = 0;
|
||||
if (lc->has_info)
|
||||
return &lc->info;
|
||||
|
||||
@@ -665,13 +667,13 @@ struct loop_info64 *loopcxt_get_info(struct loopdev_cxt *lc)
|
||||
if (ioctl(fd, LOOP_GET_STATUS64, &lc->info) == 0) {
|
||||
lc->has_info = 1;
|
||||
lc->info_failed = 0;
|
||||
DBG(lc, loopdev_debug("reading loop_info64 OK"));
|
||||
DBG(CXT, ul_debugobj(lc, "reading loop_info64 OK"));
|
||||
return &lc->info;
|
||||
} else {
|
||||
lc->info_failed = 1;
|
||||
DBG(lc, loopdev_debug("reading loop_info64 FAILED"));
|
||||
}
|
||||
|
||||
lc->info_failed = 1;
|
||||
DBG(CXT, ul_debugobj(lc, "reading loop_info64 FAILED"));
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -703,7 +705,7 @@ char *loopcxt_get_backing_file(struct loopdev_cxt *lc)
|
||||
}
|
||||
}
|
||||
|
||||
DBG(lc, loopdev_debug("get_backing_file [%s]", res));
|
||||
DBG(CXT, ul_debugobj(lc, "get_backing_file [%s]", res));
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -727,10 +729,11 @@ int loopcxt_get_offset(struct loopdev_cxt *lc, uint64_t *offset)
|
||||
if (offset)
|
||||
*offset = lo->lo_offset;
|
||||
rc = 0;
|
||||
}
|
||||
} else
|
||||
rc = -errno;
|
||||
}
|
||||
|
||||
DBG(lc, loopdev_debug("get_offset [rc=%d]", rc));
|
||||
DBG(CXT, ul_debugobj(lc, "get_offset [rc=%d]", rc));
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -754,10 +757,11 @@ int loopcxt_get_sizelimit(struct loopdev_cxt *lc, uint64_t *size)
|
||||
if (size)
|
||||
*size = lo->lo_sizelimit;
|
||||
rc = 0;
|
||||
}
|
||||
} else
|
||||
rc = -errno;
|
||||
}
|
||||
|
||||
DBG(lc, loopdev_debug("get_sizelimit [rc=%d]", rc));
|
||||
DBG(CXT, ul_debugobj(lc, "get_sizelimit [rc=%d]", rc));
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -772,14 +776,17 @@ int loopcxt_get_sizelimit(struct loopdev_cxt *lc, uint64_t *size)
|
||||
int loopcxt_get_encrypt_type(struct loopdev_cxt *lc, uint32_t *type)
|
||||
{
|
||||
struct loop_info64 *lo = loopcxt_get_info(lc);
|
||||
int rc = -EINVAL;
|
||||
int rc;
|
||||
|
||||
/* not provided by sysfs */
|
||||
if (lo) {
|
||||
if (type)
|
||||
*type = lo->lo_encrypt_type;
|
||||
rc = 0;
|
||||
}
|
||||
DBG(lc, loopdev_debug("get_encrypt_type [rc=%d]", rc));
|
||||
} else
|
||||
rc = -errno;
|
||||
|
||||
DBG(CXT, ul_debugobj(lc, "get_encrypt_type [rc=%d]", rc));
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -798,7 +805,7 @@ const char *loopcxt_get_crypt_name(struct loopdev_cxt *lc)
|
||||
if (lo)
|
||||
return (char *) lo->lo_crypt_name;
|
||||
|
||||
DBG(lc, loopdev_debug("get_crypt_name failed"));
|
||||
DBG(CXT, ul_debugobj(lc, "get_crypt_name failed"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -811,14 +818,16 @@ const char *loopcxt_get_crypt_name(struct loopdev_cxt *lc)
|
||||
int loopcxt_get_backing_devno(struct loopdev_cxt *lc, dev_t *devno)
|
||||
{
|
||||
struct loop_info64 *lo = loopcxt_get_info(lc);
|
||||
int rc = -EINVAL;
|
||||
int rc;
|
||||
|
||||
if (lo) {
|
||||
if (devno)
|
||||
*devno = lo->lo_device;
|
||||
rc = 0;
|
||||
}
|
||||
DBG(lc, loopdev_debug("get_backing_devno [rc=%d]", rc));
|
||||
} else
|
||||
rc = -errno;
|
||||
|
||||
DBG(CXT, ul_debugobj(lc, "get_backing_devno [rc=%d]", rc));
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -831,14 +840,16 @@ int loopcxt_get_backing_devno(struct loopdev_cxt *lc, dev_t *devno)
|
||||
int loopcxt_get_backing_inode(struct loopdev_cxt *lc, ino_t *ino)
|
||||
{
|
||||
struct loop_info64 *lo = loopcxt_get_info(lc);
|
||||
int rc = -EINVAL;
|
||||
int rc;
|
||||
|
||||
if (lo) {
|
||||
if (ino)
|
||||
*ino = lo->lo_inode;
|
||||
rc = 0;
|
||||
}
|
||||
DBG(lc, loopdev_debug("get_backing_inode [rc=%d]", rc));
|
||||
} else
|
||||
rc = -errno;
|
||||
|
||||
DBG(CXT, ul_debugobj(lc, "get_backing_inode [rc=%d]", rc));
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -969,7 +980,7 @@ int loopcxt_is_used(struct loopdev_cxt *lc,
|
||||
if (!lc)
|
||||
return 0;
|
||||
|
||||
DBG(lc, loopdev_debug("checking %s vs. %s",
|
||||
DBG(CXT, ul_debugobj(lc, "checking %s vs. %s",
|
||||
loopcxt_get_device(lc),
|
||||
backing_file));
|
||||
|
||||
@@ -1012,7 +1023,7 @@ int loopcxt_set_offset(struct loopdev_cxt *lc, uint64_t offset)
|
||||
return -EINVAL;
|
||||
lc->info.lo_offset = offset;
|
||||
|
||||
DBG(lc, loopdev_debug("set offset=%jd", offset));
|
||||
DBG(CXT, ul_debugobj(lc, "set offset=%jd", offset));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1025,7 +1036,7 @@ int loopcxt_set_sizelimit(struct loopdev_cxt *lc, uint64_t sizelimit)
|
||||
return -EINVAL;
|
||||
lc->info.lo_sizelimit = sizelimit;
|
||||
|
||||
DBG(lc, loopdev_debug("set sizelimit=%jd", sizelimit));
|
||||
DBG(CXT, ul_debugobj(lc, "set sizelimit=%jd", sizelimit));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1043,7 +1054,7 @@ int loopcxt_set_flags(struct loopdev_cxt *lc, uint32_t flags)
|
||||
return -EINVAL;
|
||||
lc->info.lo_flags = flags;
|
||||
|
||||
DBG(lc, loopdev_debug("set flags=%u", (unsigned) flags));
|
||||
DBG(CXT, ul_debugobj(lc, "set flags=%u", (unsigned) flags));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1067,7 +1078,97 @@ int loopcxt_set_backing_file(struct loopdev_cxt *lc, const char *filename)
|
||||
strncpy((char *)lc->info.lo_file_name, lc->filename, LO_NAME_SIZE);
|
||||
lc->info.lo_file_name[LO_NAME_SIZE- 1] = '\0';
|
||||
|
||||
DBG(lc, loopdev_debug("set backing file=%s", lc->info.lo_file_name));
|
||||
DBG(CXT, ul_debugobj(lc, "set backing file=%s", lc->info.lo_file_name));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* In kernels prior to v3.9, if the offset or sizelimit options
|
||||
* are used, the block device's size won't be synced automatically.
|
||||
* blockdev --getsize64 and filesystems will use the backing
|
||||
* file size until the block device has been re-opened or the
|
||||
* LOOP_SET_CAPACITY ioctl is called to sync the sizes.
|
||||
*
|
||||
* Since mount -oloop uses the LO_FLAGS_AUTOCLEAR option and passes
|
||||
* the open file descriptor to the mount system call, we need to use
|
||||
* the ioctl. Calling losetup directly doesn't have this problem since
|
||||
* it closes the device when it exits and whatever consumes the device
|
||||
* next will re-open it, causing the resync.
|
||||
*/
|
||||
static int loopcxt_check_size(struct loopdev_cxt *lc, int file_fd)
|
||||
{
|
||||
uint64_t size, expected_size;
|
||||
int dev_fd;
|
||||
struct stat st;
|
||||
|
||||
if (!lc->info.lo_offset && !lc->info.lo_sizelimit)
|
||||
return 0;
|
||||
|
||||
if (fstat(file_fd, &st)) {
|
||||
DBG(CXT, ul_debugobj(lc, "failed to fstat backing file"));
|
||||
return -errno;
|
||||
}
|
||||
if (S_ISBLK(st.st_mode)) {
|
||||
if (blkdev_get_size(file_fd,
|
||||
(unsigned long long *) &expected_size)) {
|
||||
DBG(CXT, ul_debugobj(lc, "failed to determine device size"));
|
||||
return -errno;
|
||||
}
|
||||
} else
|
||||
expected_size = st.st_size;
|
||||
|
||||
if (expected_size == 0 || expected_size <= lc->info.lo_offset) {
|
||||
DBG(CXT, ul_debugobj(lc, "failed to determine expected size"));
|
||||
return 0; /* ignore this error */
|
||||
}
|
||||
|
||||
if (lc->info.lo_offset > 0)
|
||||
expected_size -= lc->info.lo_offset;
|
||||
|
||||
if (lc->info.lo_sizelimit > 0 && lc->info.lo_sizelimit < expected_size)
|
||||
expected_size = lc->info.lo_sizelimit;
|
||||
|
||||
dev_fd = loopcxt_get_fd(lc);
|
||||
if (dev_fd < 0) {
|
||||
DBG(CXT, ul_debugobj(lc, "failed to get loop FD"));
|
||||
return -errno;
|
||||
}
|
||||
|
||||
if (blkdev_get_size(dev_fd, (unsigned long long *) &size)) {
|
||||
DBG(CXT, ul_debugobj(lc, "failed to determine loopdev size"));
|
||||
return -errno;
|
||||
}
|
||||
|
||||
/* It's block device, so, align to 512-byte sectors */
|
||||
if (expected_size % 512) {
|
||||
DBG(CXT, ul_debugobj(lc, "expected size misaligned to 512-byte sectors"));
|
||||
expected_size = (expected_size >> 9) << 9;
|
||||
}
|
||||
|
||||
if (expected_size != size) {
|
||||
DBG(CXT, ul_debugobj(lc, "warning: loopdev and expected "
|
||||
"size dismatch (%ju/%ju)",
|
||||
size, expected_size));
|
||||
|
||||
if (loopcxt_set_capacity(lc)) {
|
||||
/* ioctl not available */
|
||||
if (errno == ENOTTY || errno == EINVAL)
|
||||
errno = ERANGE;
|
||||
return -errno;
|
||||
}
|
||||
|
||||
if (blkdev_get_size(dev_fd, (unsigned long long *) &size))
|
||||
return -errno;
|
||||
|
||||
if (expected_size != size) {
|
||||
errno = ERANGE;
|
||||
DBG(CXT, ul_debugobj(lc, "failed to set loopdev size, "
|
||||
"size: %ju, expected: %ju",
|
||||
size, expected_size));
|
||||
return -errno;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1091,12 +1192,12 @@ int loopcxt_set_backing_file(struct loopdev_cxt *lc, const char *filename)
|
||||
*/
|
||||
int loopcxt_setup_device(struct loopdev_cxt *lc)
|
||||
{
|
||||
int file_fd, dev_fd, mode = O_RDWR, rc = -1;
|
||||
int file_fd, dev_fd, mode = O_RDWR, rc = -1, cnt = 0;
|
||||
|
||||
if (!lc || !*lc->device || !lc->filename)
|
||||
return -EINVAL;
|
||||
|
||||
DBG(lc, loopdev_debug("device setup requested"));
|
||||
DBG(SETUP, ul_debugobj(lc, "device setup requested"));
|
||||
|
||||
/*
|
||||
* Open backing file and device
|
||||
@@ -1104,19 +1205,19 @@ int loopcxt_setup_device(struct loopdev_cxt *lc)
|
||||
if (lc->info.lo_flags & LO_FLAGS_READ_ONLY)
|
||||
mode = O_RDONLY;
|
||||
|
||||
if ((file_fd = open(lc->filename, mode)) < 0) {
|
||||
if ((file_fd = open(lc->filename, mode | O_CLOEXEC)) < 0) {
|
||||
if (mode != O_RDONLY && (errno == EROFS || errno == EACCES))
|
||||
file_fd = open(lc->filename, mode = O_RDONLY);
|
||||
|
||||
if (file_fd < 0) {
|
||||
DBG(lc, loopdev_debug("open backing file failed: %m"));
|
||||
DBG(SETUP, ul_debugobj(lc, "open backing file failed: %m"));
|
||||
return -errno;
|
||||
}
|
||||
}
|
||||
DBG(lc, loopdev_debug("setup: backing file open: OK"));
|
||||
DBG(SETUP, ul_debugobj(lc, "backing file open: OK"));
|
||||
|
||||
if (lc->fd != -1 && lc->mode != mode) {
|
||||
DBG(lc, loopdev_debug("closing already open device (mode mismatch)"));
|
||||
DBG(SETUP, ul_debugobj(lc, "closing already open device (mode mismatch)"));
|
||||
close(lc->fd);
|
||||
lc->fd = -1;
|
||||
lc->mode = 0;
|
||||
@@ -1131,51 +1232,83 @@ int loopcxt_setup_device(struct loopdev_cxt *lc)
|
||||
lc->flags &= ~LOOPDEV_FL_RDONLY;
|
||||
}
|
||||
|
||||
dev_fd = loopcxt_get_fd(lc);
|
||||
do {
|
||||
errno = 0;
|
||||
dev_fd = loopcxt_get_fd(lc);
|
||||
if (dev_fd >= 0 || lc->control_ok == 0)
|
||||
break;
|
||||
if (errno != EACCES && errno != ENOENT)
|
||||
break;
|
||||
/* We have permissions to open /dev/loop-control, but open
|
||||
* /dev/loopN failed with EACCES, it's probably because udevd
|
||||
* does not applied chown yet. Let's wait a moment. */
|
||||
usleep(25000);
|
||||
} while (cnt++ < 16);
|
||||
|
||||
if (dev_fd < 0) {
|
||||
rc = -errno;
|
||||
goto err;
|
||||
}
|
||||
|
||||
DBG(lc, loopdev_debug("setup: device open: OK"));
|
||||
DBG(SETUP, ul_debugobj(lc, "device open: OK"));
|
||||
|
||||
/*
|
||||
* Set FD
|
||||
*/
|
||||
if (ioctl(dev_fd, LOOP_SET_FD, file_fd) < 0) {
|
||||
rc = -errno;
|
||||
DBG(lc, loopdev_debug("LOOP_SET_FD failed: %m"));
|
||||
DBG(SETUP, ul_debugobj(lc, "LOOP_SET_FD failed: %m"));
|
||||
goto err;
|
||||
}
|
||||
|
||||
DBG(lc, loopdev_debug("setup: LOOP_SET_FD: OK"));
|
||||
|
||||
close(file_fd);
|
||||
file_fd = -1;
|
||||
DBG(SETUP, ul_debugobj(lc, "LOOP_SET_FD: OK"));
|
||||
|
||||
if (ioctl(dev_fd, LOOP_SET_STATUS64, &lc->info)) {
|
||||
DBG(lc, loopdev_debug("LOOP_SET_STATUS64 failed: %m"));
|
||||
DBG(SETUP, ul_debugobj(lc, "LOOP_SET_STATUS64 failed: %m"));
|
||||
goto err;
|
||||
}
|
||||
|
||||
DBG(lc, loopdev_debug("setup: LOOP_SET_STATUS64: OK"));
|
||||
DBG(SETUP, ul_debugobj(lc, "LOOP_SET_STATUS64: OK"));
|
||||
|
||||
if ((rc = loopcxt_check_size(lc, file_fd)))
|
||||
goto err;
|
||||
|
||||
close(file_fd);
|
||||
|
||||
memset(&lc->info, 0, sizeof(lc->info));
|
||||
lc->has_info = 0;
|
||||
lc->info_failed = 0;
|
||||
|
||||
DBG(lc, loopdev_debug("setup success [rc=0]"));
|
||||
DBG(SETUP, ul_debugobj(lc, "success [rc=0]"));
|
||||
return 0;
|
||||
err:
|
||||
if (file_fd >= 0)
|
||||
close(file_fd);
|
||||
if (dev_fd >= 0)
|
||||
if (dev_fd >= 0 && rc != -EBUSY)
|
||||
ioctl(dev_fd, LOOP_CLR_FD, 0);
|
||||
|
||||
DBG(lc, loopdev_debug("setup failed [rc=%d]", rc));
|
||||
DBG(SETUP, ul_debugobj(lc, "failed [rc=%d]", rc));
|
||||
return rc;
|
||||
}
|
||||
|
||||
int loopcxt_set_capacity(struct loopdev_cxt *lc)
|
||||
{
|
||||
int fd = loopcxt_get_fd(lc);
|
||||
|
||||
if (fd < 0)
|
||||
return -EINVAL;
|
||||
|
||||
/* Kernels prior to v2.6.30 don't support this ioctl */
|
||||
if (ioctl(fd, LOOP_SET_CAPACITY, 0) < 0) {
|
||||
int rc = -errno;
|
||||
DBG(CXT, ul_debugobj(lc, "LOOP_SET_CAPACITY failed: %m"));
|
||||
return rc;
|
||||
}
|
||||
|
||||
DBG(CXT, ul_debugobj(lc, "capacity set"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int loopcxt_delete_device(struct loopdev_cxt *lc)
|
||||
{
|
||||
int fd = loopcxt_get_fd(lc);
|
||||
@@ -1184,14 +1317,45 @@ int loopcxt_delete_device(struct loopdev_cxt *lc)
|
||||
return -EINVAL;
|
||||
|
||||
if (ioctl(fd, LOOP_CLR_FD, 0) < 0) {
|
||||
DBG(lc, loopdev_debug("LOOP_CLR_FD failed: %m"));
|
||||
DBG(CXT, ul_debugobj(lc, "LOOP_CLR_FD failed: %m"));
|
||||
return -errno;
|
||||
}
|
||||
|
||||
DBG(lc, loopdev_debug("device removed"));
|
||||
DBG(CXT, ul_debugobj(lc, "device removed"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int loopcxt_add_device(struct loopdev_cxt *lc)
|
||||
{
|
||||
int rc = -EINVAL;
|
||||
int ctl, nr = -1;
|
||||
const char *p, *dev = loopcxt_get_device(lc);
|
||||
|
||||
if (!dev)
|
||||
goto done;
|
||||
|
||||
if (!(lc->flags & LOOPDEV_FL_CONTROL)) {
|
||||
rc = -ENOSYS;
|
||||
goto done;
|
||||
}
|
||||
|
||||
p = strrchr(dev, '/');
|
||||
if (!p || (sscanf(p, "/loop%d", &nr) != 1 && sscanf(p, "/%d", &nr) != 1)
|
||||
|| nr < 0)
|
||||
goto done;
|
||||
|
||||
ctl = open(_PATH_DEV_LOOPCTL, O_RDWR|O_CLOEXEC);
|
||||
if (ctl >= 0) {
|
||||
DBG(CXT, ul_debugobj(lc, "add_device %d", nr));
|
||||
rc = ioctl(ctl, LOOP_CTL_ADD, nr);
|
||||
close(ctl);
|
||||
}
|
||||
lc->control_ok = rc >= 0 ? 1 : 0;
|
||||
done:
|
||||
DBG(CXT, ul_debugobj(lc, "add_device done [rc=%d]", rc));
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Note that LOOP_CTL_GET_FREE ioctl is supported since kernel 3.1. In older
|
||||
* kernels we have to check all loop devices to found unused one.
|
||||
@@ -1202,10 +1366,10 @@ int loopcxt_find_unused(struct loopdev_cxt *lc)
|
||||
{
|
||||
int rc = -1;
|
||||
|
||||
DBG(lc, loopdev_debug("find_unused requested"));
|
||||
DBG(CXT, ul_debugobj(lc, "find_unused requested"));
|
||||
|
||||
if (lc->flags & LOOPDEV_FL_CONTROL) {
|
||||
int ctl = open(_PATH_DEV_LOOPCTL, O_RDWR);
|
||||
int ctl = open(_PATH_DEV_LOOPCTL, O_RDWR|O_CLOEXEC);
|
||||
|
||||
if (ctl >= 0)
|
||||
rc = ioctl(ctl, LOOP_CTL_GET_FREE);
|
||||
@@ -1215,9 +1379,10 @@ int loopcxt_find_unused(struct loopdev_cxt *lc)
|
||||
|
||||
rc = loopiter_set_device(lc, name);
|
||||
}
|
||||
lc->control_ok = ctl >= 0 && rc == 0 ? 1 : 0;
|
||||
if (ctl >= 0)
|
||||
close(ctl);
|
||||
DBG(lc, loopdev_debug("find_unused by loop-control [rc=%d]", rc));
|
||||
DBG(CXT, ul_debugobj(lc, "find_unused by loop-control [rc=%d]", rc));
|
||||
}
|
||||
|
||||
if (rc < 0) {
|
||||
@@ -1227,7 +1392,7 @@ int loopcxt_find_unused(struct loopdev_cxt *lc)
|
||||
|
||||
rc = loopcxt_next(lc);
|
||||
loopcxt_deinit_iterator(lc);
|
||||
DBG(lc, loopdev_debug("find_unused by scan [rc=%d]", rc));
|
||||
DBG(CXT, ul_debugobj(lc, "find_unused by scan [rc=%d]", rc));
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
@@ -1405,155 +1570,3 @@ int loopdev_count_by_backing_file(const char *filename, char **loopdev)
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
#ifdef TEST_PROGRAM_LOOPDEV
|
||||
#include <errno.h>
|
||||
#include <err.h>
|
||||
|
||||
static void test_loop_info(const char *device, int flags, int debug)
|
||||
{
|
||||
struct loopdev_cxt lc;
|
||||
char *p;
|
||||
uint64_t u64;
|
||||
|
||||
if (loopcxt_init(&lc, flags))
|
||||
return;
|
||||
loopcxt_enable_debug(&lc, debug);
|
||||
|
||||
if (loopcxt_set_device(&lc, device))
|
||||
err(EXIT_FAILURE, "failed to set device");
|
||||
|
||||
p = loopcxt_get_backing_file(&lc);
|
||||
printf("\tBACKING FILE: %s\n", p);
|
||||
free(p);
|
||||
|
||||
if (loopcxt_get_offset(&lc, &u64) == 0)
|
||||
printf("\tOFFSET: %jd\n", u64);
|
||||
|
||||
if (loopcxt_get_sizelimit(&lc, &u64) == 0)
|
||||
printf("\tSIZE LIMIT: %jd\n", u64);
|
||||
|
||||
printf("\tAUTOCLEAR: %s\n", loopcxt_is_autoclear(&lc) ? "YES" : "NOT");
|
||||
|
||||
loopcxt_deinit(&lc);
|
||||
}
|
||||
|
||||
static void test_loop_scan(int flags, int debug)
|
||||
{
|
||||
struct loopdev_cxt lc;
|
||||
int rc;
|
||||
|
||||
if (loopcxt_init(&lc, 0))
|
||||
return;
|
||||
loopcxt_enable_debug(&lc, debug);
|
||||
|
||||
if (loopcxt_init_iterator(&lc, flags))
|
||||
err(EXIT_FAILURE, "iterator initlization failed");
|
||||
|
||||
while((rc = loopcxt_next(&lc)) == 0) {
|
||||
const char *device = loopcxt_get_device(&lc);
|
||||
|
||||
if (flags & LOOPITER_FL_USED) {
|
||||
char *backing = loopcxt_get_backing_file(&lc);
|
||||
printf("\t%s: %s\n", device, backing);
|
||||
free(backing);
|
||||
} else
|
||||
printf("\t%s\n", device);
|
||||
}
|
||||
|
||||
if (rc < 0)
|
||||
err(EXIT_FAILURE, "loopdevs scanning failed");
|
||||
|
||||
loopcxt_deinit(&lc);
|
||||
}
|
||||
|
||||
static int test_loop_setup(const char *filename, const char *device, int debug)
|
||||
{
|
||||
struct loopdev_cxt lc;
|
||||
int rc;
|
||||
|
||||
rc = loopcxt_init(&lc, 0);
|
||||
if (rc)
|
||||
return rc;
|
||||
loopcxt_enable_debug(&lc, debug);
|
||||
|
||||
if (device) {
|
||||
rc = loopcxt_set_device(&lc, device);
|
||||
if (rc)
|
||||
err(EXIT_FAILURE, "failed to set device: %s", device);
|
||||
}
|
||||
|
||||
do {
|
||||
if (!device) {
|
||||
rc = loopcxt_find_unused(&lc);
|
||||
if (rc)
|
||||
err(EXIT_FAILURE, "failed to find unused device");
|
||||
printf("Trying to use '%s'\n", loopcxt_get_device(&lc));
|
||||
}
|
||||
|
||||
if (loopcxt_set_backing_file(&lc, filename))
|
||||
err(EXIT_FAILURE, "failed to set backing file");
|
||||
|
||||
rc = loopcxt_setup_device(&lc);
|
||||
if (rc == 0)
|
||||
break; /* success */
|
||||
|
||||
if (device || rc != -EBUSY)
|
||||
err(EXIT_FAILURE, "failed to setup device for %s",
|
||||
lc.filename);
|
||||
|
||||
printf("device stolen...trying again\n");
|
||||
} while (1);
|
||||
|
||||
loopcxt_deinit(&lc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int dbg;
|
||||
|
||||
if (argc < 2)
|
||||
goto usage;
|
||||
|
||||
dbg = getenv("LOOPDEV_DEBUG") == NULL ? 0 : 1;
|
||||
|
||||
if (argc == 3 && strcmp(argv[1], "--info") == 0) {
|
||||
printf("---sysfs & ioctl:---\n");
|
||||
test_loop_info(argv[2], 0, dbg);
|
||||
printf("---sysfs only:---\n");
|
||||
test_loop_info(argv[2], LOOPDEV_FL_NOIOCTL, dbg);
|
||||
printf("---ioctl only:---\n");
|
||||
test_loop_info(argv[2], LOOPDEV_FL_NOSYSFS, dbg);
|
||||
|
||||
} else if (argc == 2 && strcmp(argv[1], "--used") == 0) {
|
||||
printf("---all used devices---\n");
|
||||
test_loop_scan(LOOPITER_FL_USED, dbg);
|
||||
|
||||
} else if (argc == 2 && strcmp(argv[1], "--free") == 0) {
|
||||
printf("---all free devices---\n");
|
||||
test_loop_scan(LOOPITER_FL_FREE, dbg);
|
||||
|
||||
} else if (argc >= 3 && strcmp(argv[1], "--setup") == 0) {
|
||||
test_loop_setup(argv[2], argv[3], dbg);
|
||||
|
||||
} else if (argc == 3 && strcmp(argv[1], "--delete") == 0) {
|
||||
if (loopdev_delete(argv[2]))
|
||||
errx(EXIT_FAILURE, "failed to deinitialize device %s", argv[2]);
|
||||
} else
|
||||
goto usage;
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
|
||||
usage:
|
||||
errx(EXIT_FAILURE, "usage: \n"
|
||||
" %1$s --info <device>\n"
|
||||
" %1$s --free\n"
|
||||
" %1$s --used\n"
|
||||
" %1$s --setup <filename> [<device>]\n"
|
||||
" %1$s --delete\n",
|
||||
argv[0]);
|
||||
}
|
||||
|
||||
#endif /* TEST_PROGRAM */
|
||||
@@ -2,8 +2,8 @@
|
||||
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 3 of the License, or
|
||||
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.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
@@ -23,17 +23,193 @@
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <limits.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "c.h"
|
||||
#include "mbsalign.h"
|
||||
#include "widechar.h"
|
||||
|
||||
|
||||
#ifdef HAVE_WIDECHAR
|
||||
/* Replace non printable chars.
|
||||
Note \t and \n etc. are non printable.
|
||||
Return 1 if replacement made, 0 otherwise. */
|
||||
|
||||
/*
|
||||
* Counts number of cells in multibyte string. For all control and
|
||||
* non-printable chars is the result width enlarged to store \x?? hex
|
||||
* sequence. See mbs_safe_encode().
|
||||
*
|
||||
* Returns: number of cells, @sz returns number of bytes.
|
||||
*/
|
||||
size_t mbs_safe_nwidth(const char *buf, size_t bufsz, size_t *sz)
|
||||
{
|
||||
mbstate_t st;
|
||||
const char *p = buf, *last = buf;
|
||||
size_t width = 0, bytes = 0;
|
||||
|
||||
memset(&st, 0, sizeof(st));
|
||||
|
||||
if (p && *p && bufsz)
|
||||
last = p + (bufsz - 1);
|
||||
|
||||
while (p && *p && p <= last) {
|
||||
if (iscntrl((unsigned char) *p)) {
|
||||
width += 4, bytes += 4; /* *p encoded to \x?? */
|
||||
p++;
|
||||
}
|
||||
#ifdef HAVE_WIDECHAR
|
||||
else {
|
||||
wchar_t wc;
|
||||
size_t len = mbrtowc(&wc, p, MB_CUR_MAX, &st);
|
||||
|
||||
if (len == 0)
|
||||
break;
|
||||
|
||||
if (len == (size_t) -1 || len == (size_t) -2) {
|
||||
len = 1;
|
||||
if (isprint((unsigned char) *p))
|
||||
width += 1, bytes += 1;
|
||||
else
|
||||
width += 4, bytes += 4;
|
||||
|
||||
} else if (!iswprint(wc)) {
|
||||
width += len * 4; /* hex encode whole sequence */
|
||||
bytes += len * 4;
|
||||
} else {
|
||||
width += wcwidth(wc); /* number of cells */
|
||||
bytes += len; /* number of bytes */
|
||||
}
|
||||
p += len;
|
||||
}
|
||||
#else
|
||||
else if (!isprint((unsigned char) *p)) {
|
||||
width += 4, bytes += 4; /* *p encoded to \x?? */
|
||||
p++;
|
||||
} else {
|
||||
width++, bytes++;
|
||||
p++;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (sz)
|
||||
*sz = bytes;
|
||||
return width;
|
||||
}
|
||||
|
||||
size_t mbs_safe_width(const char *s)
|
||||
{
|
||||
if (!s || !*s)
|
||||
return 0;
|
||||
return mbs_safe_nwidth(s, strlen(s), NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy @s to @buf and replace control and non-printable chars with
|
||||
* \x?? hex sequence. The @width returns number of cells.
|
||||
*
|
||||
* The @buf has to be big enough to store mbs_safe_encode_size(strlen(s)))
|
||||
* bytes.
|
||||
*/
|
||||
char *mbs_safe_encode_to_buffer(const char *s, size_t *width, char *buf)
|
||||
{
|
||||
mbstate_t st;
|
||||
const char *p = s;
|
||||
char *r;
|
||||
size_t sz = s ? strlen(s) : 0;
|
||||
|
||||
if (!sz || !buf)
|
||||
return NULL;
|
||||
|
||||
memset(&st, 0, sizeof(st));
|
||||
|
||||
r = buf;
|
||||
*width = 0;
|
||||
|
||||
while (p && *p) {
|
||||
if (iscntrl((unsigned char) *p)) {
|
||||
sprintf(r, "\\x%02x", (unsigned char) *p);
|
||||
r += 4;
|
||||
*width += 4;
|
||||
p++;
|
||||
}
|
||||
#ifdef HAVE_WIDECHAR
|
||||
else {
|
||||
wchar_t wc;
|
||||
size_t len = mbrtowc(&wc, p, MB_CUR_MAX, &st);
|
||||
|
||||
if (len == 0)
|
||||
break; /* end of string */
|
||||
|
||||
if (len == (size_t) -1 || len == (size_t) -2) {
|
||||
len = 1;
|
||||
/*
|
||||
* Not valid multibyte sequence -- maybe it's
|
||||
* printable char according to the current locales.
|
||||
*/
|
||||
if (!isprint((unsigned char) *p)) {
|
||||
sprintf(r, "\\x%02x", (unsigned char) *p);
|
||||
r += 4;
|
||||
*width += 4;
|
||||
} else {
|
||||
width++;
|
||||
*r++ = *p;
|
||||
}
|
||||
} else if (!iswprint(wc)) {
|
||||
size_t i;
|
||||
for (i = 0; i < len; i++) {
|
||||
sprintf(r, "\\x%02x", (unsigned char) *p);
|
||||
r += 4;
|
||||
*width += 4;
|
||||
}
|
||||
} else {
|
||||
memcpy(r, p, len);
|
||||
r += len;
|
||||
*width += wcwidth(wc);
|
||||
}
|
||||
p += len;
|
||||
}
|
||||
#else
|
||||
else if (!isprint((unsigned char) *p)) {
|
||||
sprintf(r, "\\x%02x", (unsigned char) *p);
|
||||
p++;
|
||||
r += 4;
|
||||
*width += 4;
|
||||
} else {
|
||||
*r++ = *p++;
|
||||
*width++;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
*r = '\0';
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
size_t mbs_safe_encode_size(size_t bytes)
|
||||
{
|
||||
return (bytes * 4) + 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns allocated string where all control and non-printable chars are
|
||||
* replaced with \x?? hex sequence.
|
||||
*/
|
||||
char *mbs_safe_encode(const char *s, size_t *width)
|
||||
{
|
||||
size_t sz = s ? strlen(s) : 0;
|
||||
char *buf;
|
||||
|
||||
if (!sz)
|
||||
return NULL;
|
||||
buf = malloc(mbs_safe_encode_size(sz));
|
||||
if (!buf)
|
||||
return NULL;
|
||||
|
||||
return mbs_safe_encode_to_buffer(s, width, buf);
|
||||
}
|
||||
|
||||
static bool
|
||||
wc_ensure_printable (wchar_t *wchars)
|
||||
{
|
||||
@@ -143,7 +319,7 @@ mbs_align_pad (char *dest, const char* dest_end, size_t n_spaces)
|
||||
{
|
||||
/* FIXME: Should we pad with "figure space" (\u2007)
|
||||
if non ascii data present? */
|
||||
while (n_spaces-- && (dest < dest_end))
|
||||
for (/* nothing */; n_spaces && (dest < dest_end); n_spaces--)
|
||||
*dest++ = ' ';
|
||||
*dest = '\0';
|
||||
return dest;
|
||||
@@ -173,7 +349,7 @@ mbsalign (const char *src, char *dest, size_t dest_size,
|
||||
const char *str_to_print = src;
|
||||
size_t n_cols = src_size - 1;
|
||||
size_t n_used_bytes = n_cols; /* Not including NUL */
|
||||
size_t n_spaces = 0;
|
||||
size_t n_spaces = 0, space_left;
|
||||
bool conversion = false;
|
||||
bool wc_enabled = false;
|
||||
|
||||
@@ -254,8 +430,8 @@ mbsalign_unibyte:
|
||||
if (dest_size != 0)
|
||||
{
|
||||
char *dest_end = dest + dest_size - 1;
|
||||
size_t start_spaces = n_spaces / 2 + n_spaces % 2;
|
||||
size_t end_spaces = n_spaces / 2;
|
||||
size_t start_spaces;
|
||||
size_t end_spaces;
|
||||
|
||||
switch (align)
|
||||
{
|
||||
@@ -276,9 +452,8 @@ mbsalign_unibyte:
|
||||
}
|
||||
|
||||
dest = mbs_align_pad (dest, dest_end, start_spaces);
|
||||
size_t space_left = dest_end - dest;
|
||||
//dest = mempcpy (dest, str_to_print, min (n_used_bytes, space_left));
|
||||
memcpy (dest, str_to_print, min (n_used_bytes, space_left));
|
||||
space_left = dest_end - dest;
|
||||
dest = memcpy (dest, str_to_print, min (n_used_bytes, space_left));
|
||||
mbs_align_pad (dest, dest_end, end_spaces);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Please, don't add this file to libcommon because clock_gettime() requires
|
||||
* -lrt on systems with old libc.
|
||||
*/
|
||||
#include <time.h>
|
||||
#include <sys/sysinfo.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include "c.h"
|
||||
#include "nls.h"
|
||||
#include "monotonic.h"
|
||||
|
||||
int get_boot_time(struct timeval *boot_time)
|
||||
{
|
||||
#ifdef CLOCK_BOOTTIME
|
||||
struct timespec hires_uptime;
|
||||
struct timeval lores_uptime;
|
||||
#endif
|
||||
struct timeval now;
|
||||
#ifdef HAVE_SYSINFO
|
||||
struct sysinfo info;
|
||||
#endif
|
||||
|
||||
if (gettimeofday(&now, NULL) != 0) {
|
||||
warn(_("gettimeofday failed"));
|
||||
return -errno;
|
||||
}
|
||||
#ifdef CLOCK_BOOTTIME
|
||||
if (clock_gettime(CLOCK_BOOTTIME, &hires_uptime) == 0) {
|
||||
TIMESPEC_TO_TIMEVAL(&lores_uptime, &hires_uptime);
|
||||
timersub(&now, &lores_uptime, boot_time);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_SYSINFO
|
||||
/* fallback */
|
||||
if (sysinfo(&info) != 0)
|
||||
warn(_("sysinfo failed"));
|
||||
|
||||
boot_time->tv_sec = now.tv_sec - info.uptime;
|
||||
boot_time->tv_usec = 0;
|
||||
return 0;
|
||||
#else
|
||||
return -ENOSYS;
|
||||
#endif
|
||||
}
|
||||
|
||||
int gettime_monotonic(struct timeval *tv)
|
||||
{
|
||||
#ifdef CLOCK_MONOTONIC
|
||||
/* Can slew only by ntp and adjtime */
|
||||
int ret;
|
||||
struct timespec ts;
|
||||
|
||||
# ifdef CLOCK_MONOTONIC_RAW
|
||||
/* Linux specific, cant slew */
|
||||
if (!(ret = clock_gettime(CLOCK_MONOTONIC_RAW, &ts))) {
|
||||
# else
|
||||
if (!(ret = clock_gettime(CLOCK_MONOTONIC, &ts))) {
|
||||
# endif
|
||||
tv->tv_sec = ts.tv_sec;
|
||||
tv->tv_usec = ts.tv_nsec / 1000;
|
||||
}
|
||||
return ret;
|
||||
#else
|
||||
return gettimeofday(tv, NULL);
|
||||
#endif
|
||||
}
|
||||
@@ -40,16 +40,6 @@ static inline void close_pair(int fd[2])
|
||||
close(fd[1]);
|
||||
}
|
||||
|
||||
static inline void dup_devnull(int to)
|
||||
{
|
||||
int fd = open(NULL_DEVICE, O_RDWR);
|
||||
|
||||
if (fd < 0)
|
||||
err(EXIT_FAILURE, _("cannot open %s"), NULL_DEVICE);
|
||||
dup2(fd, to);
|
||||
close(fd);
|
||||
}
|
||||
|
||||
static int start_command(struct child_process *cmd)
|
||||
{
|
||||
int need_in;
|
||||
@@ -73,10 +63,10 @@ static int start_command(struct child_process *cmd)
|
||||
cmd->pid = fork();
|
||||
if (!cmd->pid) {
|
||||
if (need_in) {
|
||||
dup2(fdin[0], 0);
|
||||
dup2(fdin[0], STDIN_FILENO);
|
||||
close_pair(fdin);
|
||||
} else if (cmd->in > 0) {
|
||||
dup2(cmd->in, 0);
|
||||
dup2(cmd->in, STDIN_FILENO);
|
||||
close(cmd->in);
|
||||
}
|
||||
|
||||
@@ -144,7 +134,7 @@ static void pager_preexec(void)
|
||||
fd_set in;
|
||||
|
||||
FD_ZERO(&in);
|
||||
FD_SET(0, &in);
|
||||
FD_SET(STDIN_FILENO, &in);
|
||||
select(1, &in, NULL, &in, NULL);
|
||||
|
||||
setenv("LESS", "FRSX", 0);
|
||||
@@ -155,8 +145,8 @@ static void wait_for_pager(void)
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
/* signal EOF to pager */
|
||||
close(1);
|
||||
close(2);
|
||||
close(STDOUT_FILENO);
|
||||
close(STDERR_FILENO);
|
||||
finish_command(&pager_process);
|
||||
}
|
||||
|
||||
@@ -170,7 +160,7 @@ void setup_pager(void)
|
||||
{
|
||||
const char *pager = getenv("PAGER");
|
||||
|
||||
if (!isatty(1))
|
||||
if (!isatty(STDOUT_FILENO))
|
||||
return;
|
||||
|
||||
if (!pager)
|
||||
@@ -188,9 +178,9 @@ void setup_pager(void)
|
||||
return;
|
||||
|
||||
/* original process continues, but writes to the pipe */
|
||||
dup2(pager_process.in, 1);
|
||||
if (isatty(2))
|
||||
dup2(pager_process.in, 2);
|
||||
dup2(pager_process.in, STDOUT_FILENO);
|
||||
if (isatty(STDERR_FILENO))
|
||||
dup2(pager_process.in, STDERR_FILENO);
|
||||
close(pager_process.in);
|
||||
|
||||
/* this makes sure that the parent terminates after the pager */
|
||||
@@ -49,6 +49,19 @@ path_vcreate(const char *path, va_list ap)
|
||||
return pathbuf;
|
||||
}
|
||||
|
||||
char *
|
||||
path_strdup(const char *path, ...)
|
||||
{
|
||||
const char *p;
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, path);
|
||||
p = path_vcreate(path, ap);
|
||||
va_end(ap);
|
||||
|
||||
return p ? strdup(p) : NULL;
|
||||
}
|
||||
|
||||
static FILE *
|
||||
path_vfopen(const char *mode, int exit_on_error, const char *path, va_list ap)
|
||||
{
|
||||
@@ -97,7 +110,7 @@ path_read_str(char *result, size_t len, const char *path, ...)
|
||||
va_end(ap);
|
||||
|
||||
if (!fgets(result, len, fd))
|
||||
err(EXIT_FAILURE, _("failed to read: %s"), pathbuf);
|
||||
err(EXIT_FAILURE, _("cannot read %s"), pathbuf);
|
||||
fclose(fd);
|
||||
|
||||
len = strlen(result);
|
||||
@@ -118,7 +131,7 @@ path_read_s32(const char *path, ...)
|
||||
|
||||
if (fscanf(fd, "%d", &result) != 1) {
|
||||
if (ferror(fd))
|
||||
err(EXIT_FAILURE, _("failed to read: %s"), pathbuf);
|
||||
err(EXIT_FAILURE, _("cannot read %s"), pathbuf);
|
||||
else
|
||||
errx(EXIT_FAILURE, _("parse error: %s"), pathbuf);
|
||||
}
|
||||
@@ -139,7 +152,7 @@ path_read_u64(const char *path, ...)
|
||||
|
||||
if (fscanf(fd, "%"SCNu64, &result) != 1) {
|
||||
if (ferror(fd))
|
||||
err(EXIT_FAILURE, _("failed to read: %s"), pathbuf);
|
||||
err(EXIT_FAILURE, _("cannot read %s"), pathbuf);
|
||||
else
|
||||
errx(EXIT_FAILURE, _("parse error: %s"), pathbuf);
|
||||
}
|
||||
@@ -154,7 +167,7 @@ path_write_str(const char *str, const char *path, ...)
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, path);
|
||||
fd = path_vopen(O_WRONLY, path, ap);
|
||||
fd = path_vopen(O_WRONLY|O_CLOEXEC, path, ap);
|
||||
va_end(ap);
|
||||
result = write_all(fd, str, strlen(str));
|
||||
close(fd);
|
||||
@@ -187,7 +200,7 @@ path_cpuparse(int maxcpus, int islist, const char *path, va_list ap)
|
||||
fd = path_vfopen("r", 1, path, ap);
|
||||
|
||||
if (!fgets(buf, len, fd))
|
||||
err(EXIT_FAILURE, _("failed to read: %s"), pathbuf);
|
||||
err(EXIT_FAILURE, _("cannot read %s"), pathbuf);
|
||||
fclose(fd);
|
||||
|
||||
len = strlen(buf);
|
||||
@@ -0,0 +1,264 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Davidlohr Bueso <dave@gnu.org>
|
||||
*
|
||||
* procutils.c: General purpose procfs parsing utilities
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Library Public License as published by
|
||||
* the Free Software Foundation; either version 2, 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 Library Public License for more details.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "procutils.h"
|
||||
#include "at.h"
|
||||
#include "c.h"
|
||||
|
||||
/*
|
||||
* @pid: process ID for which we want to obtain the threads group
|
||||
*
|
||||
* Returns: newly allocated tasks structure
|
||||
*/
|
||||
struct proc_tasks *proc_open_tasks(pid_t pid)
|
||||
{
|
||||
struct proc_tasks *tasks;
|
||||
char path[PATH_MAX];
|
||||
|
||||
sprintf(path, "/proc/%d/task/", pid);
|
||||
|
||||
tasks = malloc(sizeof(struct proc_tasks));
|
||||
if (tasks) {
|
||||
tasks->dir = opendir(path);
|
||||
if (tasks->dir)
|
||||
return tasks;
|
||||
}
|
||||
|
||||
free(tasks);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* @tasks: allocated tasks structure
|
||||
*
|
||||
* Returns: nothing
|
||||
*/
|
||||
void proc_close_tasks(struct proc_tasks *tasks)
|
||||
{
|
||||
if (tasks && tasks->dir)
|
||||
closedir(tasks->dir);
|
||||
free(tasks);
|
||||
}
|
||||
|
||||
/*
|
||||
* @tasks: allocated task structure
|
||||
* @tid: [output] one of the thread IDs belonging to the thread group
|
||||
* If when an error occurs, it is set to 0.
|
||||
*
|
||||
* Returns: 0 on success, 1 on end, -1 on failure or no more threads
|
||||
*/
|
||||
int proc_next_tid(struct proc_tasks *tasks, pid_t *tid)
|
||||
{
|
||||
struct dirent *d;
|
||||
char *end;
|
||||
|
||||
if (!tasks || !tid)
|
||||
return -EINVAL;
|
||||
|
||||
*tid = 0;
|
||||
errno = 0;
|
||||
|
||||
do {
|
||||
d = readdir(tasks->dir);
|
||||
if (!d)
|
||||
return errno ? -1 : 1; /* error or end-of-dir */
|
||||
|
||||
if (!isdigit((unsigned char) *d->d_name))
|
||||
continue;
|
||||
errno = 0;
|
||||
*tid = (pid_t) strtol(d->d_name, &end, 10);
|
||||
if (errno || d->d_name == end || (end && *end))
|
||||
return -1;
|
||||
|
||||
} while (!*tid);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct proc_processes *proc_open_processes(void)
|
||||
{
|
||||
struct proc_processes *ps;
|
||||
|
||||
ps = calloc(1, sizeof(struct proc_processes));
|
||||
if (ps) {
|
||||
ps->dir = opendir("/proc");
|
||||
if (ps->dir)
|
||||
return ps;
|
||||
}
|
||||
|
||||
free(ps);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void proc_close_processes(struct proc_processes *ps)
|
||||
{
|
||||
if (ps && ps->dir)
|
||||
closedir(ps->dir);
|
||||
free(ps);
|
||||
}
|
||||
|
||||
void proc_processes_filter_by_name(struct proc_processes *ps, const char *name)
|
||||
{
|
||||
ps->fltr_name = name;
|
||||
ps->has_fltr_name = name ? 1 : 0;
|
||||
}
|
||||
|
||||
void proc_processes_filter_by_uid(struct proc_processes *ps, uid_t uid)
|
||||
{
|
||||
ps->fltr_uid = uid;
|
||||
ps->has_fltr_uid = 1;
|
||||
}
|
||||
|
||||
int proc_next_pid(struct proc_processes *ps, pid_t *pid)
|
||||
{
|
||||
struct dirent *d;
|
||||
|
||||
if (!ps || !pid)
|
||||
return -EINVAL;
|
||||
|
||||
*pid = 0;
|
||||
errno = 0;
|
||||
|
||||
do {
|
||||
char buf[BUFSIZ], *p;
|
||||
|
||||
d = readdir(ps->dir);
|
||||
if (!d)
|
||||
return errno ? -1 : 1; /* error or end-of-dir */
|
||||
|
||||
|
||||
if (!isdigit((unsigned char) *d->d_name))
|
||||
continue;
|
||||
|
||||
/* filter out by UID */
|
||||
if (ps->has_fltr_uid) {
|
||||
struct stat st;
|
||||
|
||||
if (fstat_at(dirfd(ps->dir), "/proc", d->d_name, &st, 0))
|
||||
continue;
|
||||
if (ps->fltr_uid != st.st_uid)
|
||||
continue;
|
||||
}
|
||||
|
||||
/* filter out by NAME */
|
||||
if (ps->has_fltr_name) {
|
||||
char procname[256];
|
||||
FILE *f;
|
||||
|
||||
snprintf(buf, sizeof(buf), "%s/stat", d->d_name);
|
||||
f = fopen_at(dirfd(ps->dir), "/proc", buf,
|
||||
O_CLOEXEC|O_RDONLY, "r");
|
||||
if (!f)
|
||||
continue;
|
||||
|
||||
p = fgets(buf, sizeof(buf), f);
|
||||
fclose(f);
|
||||
if (!p)
|
||||
continue;
|
||||
|
||||
if (sscanf(buf, "%*d (%255[^)])", procname) != 1)
|
||||
continue;
|
||||
|
||||
/* ok, we got the process name. */
|
||||
if (strcmp(procname, ps->fltr_name) != 0)
|
||||
continue;
|
||||
}
|
||||
|
||||
p = NULL;
|
||||
errno = 0;
|
||||
*pid = (pid_t) strtol(d->d_name, &p, 10);
|
||||
if (errno || d->d_name == p || (p && *p))
|
||||
return errno ? -errno : -1;
|
||||
|
||||
return 0;
|
||||
} while (1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef TEST_PROGRAM
|
||||
|
||||
static int test_tasks(int argc, char *argv[])
|
||||
{
|
||||
pid_t tid, pid;
|
||||
struct proc_tasks *ts;
|
||||
|
||||
if (argc != 2)
|
||||
return EXIT_FAILURE;
|
||||
|
||||
pid = strtol(argv[1], (char **) NULL, 10);
|
||||
printf("PID=%d, TIDs:", pid);
|
||||
|
||||
ts = proc_open_tasks(pid);
|
||||
if (!ts)
|
||||
err(EXIT_FAILURE, "open list of tasks failed");
|
||||
|
||||
while (proc_next_tid(ts, &tid) == 0)
|
||||
printf(" %d", tid);
|
||||
|
||||
printf("\n");
|
||||
proc_close_tasks(ts);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
static int test_processes(int argc, char *argv[])
|
||||
{
|
||||
pid_t pid;
|
||||
struct proc_processes *ps;
|
||||
|
||||
ps = proc_open_processes();
|
||||
if (!ps)
|
||||
err(EXIT_FAILURE, "open list of processes failed");
|
||||
|
||||
if (argc >= 3 && strcmp(argv[1], "--name") == 0)
|
||||
proc_processes_filter_by_name(ps, argv[2]);
|
||||
|
||||
if (argc >= 3 && strcmp(argv[1], "--uid") == 0)
|
||||
proc_processes_filter_by_uid(ps, (uid_t) atol(argv[2]));
|
||||
|
||||
while (proc_next_pid(ps, &pid) == 0)
|
||||
printf(" %d", pid);
|
||||
|
||||
printf("\n");
|
||||
proc_close_processes(ps);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "usage: %1$s --tasks <pid>\n"
|
||||
" %1$s --processes [---name <name>] [--uid <uid>]\n",
|
||||
program_invocation_short_name);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (strcmp(argv[1], "--tasks") == 0)
|
||||
return test_tasks(argc - 1, argv + 1);
|
||||
if (strcmp(argv[1], "--processes") == 0)
|
||||
return test_processes(argc - 1, argv + 1);
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
#endif /* TEST_PROGRAM */
|
||||
@@ -15,7 +15,9 @@
|
||||
|
||||
#include <sys/syscall.h>
|
||||
|
||||
#include "c.h"
|
||||
#include "randutils.h"
|
||||
#include "nls.h"
|
||||
|
||||
#ifdef HAVE_TLS
|
||||
#define THREAD_LOCAL static __thread
|
||||
@@ -34,9 +36,9 @@ int random_get_fd(void)
|
||||
struct timeval tv;
|
||||
|
||||
gettimeofday(&tv, 0);
|
||||
fd = open("/dev/urandom", O_RDONLY);
|
||||
fd = open("/dev/urandom", O_RDONLY | O_CLOEXEC);
|
||||
if (fd == -1)
|
||||
fd = open("/dev/random", O_RDONLY | O_NONBLOCK);
|
||||
fd = open("/dev/random", O_RDONLY | O_NONBLOCK | O_CLOEXEC);
|
||||
if (fd >= 0) {
|
||||
i = fcntl(fd, F_GETFD);
|
||||
if (i >= 0)
|
||||
@@ -108,6 +110,26 @@ void random_get_bytes(void *buf, size_t nbytes)
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Tell source of randomness.
|
||||
*/
|
||||
const char *random_tell_source(void)
|
||||
{
|
||||
size_t i;
|
||||
static const char *random_sources[] = {
|
||||
"/dev/urandom",
|
||||
"/dev/random"
|
||||
};
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(random_sources); i++) {
|
||||
if (!access(random_sources[i], R_OK))
|
||||
return random_sources[i];
|
||||
}
|
||||
|
||||
return _("libc pseudo-random functions");
|
||||
}
|
||||
|
||||
#ifdef TEST_PROGRAM
|
||||
int main(int argc __attribute__ ((__unused__)),
|
||||
char *argv[] __attribute__ ((__unused__)))
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user