Imported reiserfsprogs-3.6.13
This commit is contained in:
1 parent
cccefa4d84
commit
18057cdad6
78 files changed
+1697
-2226
No files matched your search
+227
-258
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1996-2003 by Hans Reiser, licensing governed by
|
||||
* Copyright 1996-2004 by Hans Reiser, licensing governed by
|
||||
* reiserfsprogs/README
|
||||
*/
|
||||
|
||||
@@ -16,29 +16,34 @@
|
||||
#include <stdlib.h>
|
||||
#include <mntent.h>
|
||||
#include <sys/vfs.h>
|
||||
#include <fcntl.h>
|
||||
#include <time.h>
|
||||
#include <utime.h>
|
||||
#include <ctype.h>
|
||||
#include <linux/hdreg.h>
|
||||
#include <dirent.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <asm/ioctl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#if defined(__linux__) && defined(_IOR) && !defined(BLKGETSIZE64)
|
||||
# define BLKGETSIZE64 _IOR(0x12, 114, sizeof(__u64))
|
||||
#endif
|
||||
|
||||
#include "swab.h"
|
||||
|
||||
#include "io.h"
|
||||
#include "misc.h"
|
||||
|
||||
/* Debian modifications by Ed Boraas <ed@debian.org> */
|
||||
#include <sys/mount.h>
|
||||
/* End Debian mods */
|
||||
|
||||
#define STAT_FIELD(Field, Type) \
|
||||
inline Type misc_device_##Field(char *device) { \
|
||||
struct stat st; \
|
||||
\
|
||||
if (stat(device, &st) == 0) \
|
||||
return st.st_##Field; \
|
||||
\
|
||||
fprintf(stderr, "Stat of the device '%s' failed.", device); \
|
||||
exit(8); \
|
||||
}
|
||||
|
||||
STAT_FIELD(mode, mode_t);
|
||||
STAT_FIELD(rdev, dev_t);
|
||||
STAT_FIELD(size, off64_t);
|
||||
STAT_FIELD(blocks, blkcnt64_t);
|
||||
|
||||
void die (char * fmt, ...)
|
||||
{
|
||||
@@ -173,144 +178,174 @@ void freemem (void * vp)
|
||||
|
||||
typedef int (*func_t) (char *);
|
||||
|
||||
static int is_readonly_dir (char * dir)
|
||||
/* Lookup the @file in the @mntfile. @file is mntent.mnt_fsname if @fsname
|
||||
is set; mntent.mnt_dir otherwise. Return the mnt entry from the @mntfile.
|
||||
|
||||
Warning: if the root fs is mounted RO, the content of /etc/mtab may be
|
||||
not correct. */
|
||||
static struct mntent *misc_mntent_lookup(char *mntfile,
|
||||
char *file,
|
||||
int fsname)
|
||||
{
|
||||
/*
|
||||
int fd;
|
||||
char template [1024];
|
||||
struct mntent *mnt;
|
||||
struct stat st;
|
||||
dev_t rdev = 0;
|
||||
dev_t dev = 0;
|
||||
ino_t ino = 0;
|
||||
FILE *fp;
|
||||
|
||||
snprintf (template, 1024, "%s/testXXXXXX", dir);
|
||||
fd = mkstemp (template);
|
||||
if (fd >= 0) {
|
||||
close (fd);
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
if (utime (dir, 0) != -1)
|
||||
/* this is not ro mounted fs */
|
||||
return 0;
|
||||
return (errno == EROFS) ? 1 : 0;
|
||||
}
|
||||
assert(mntfile != NULL);
|
||||
assert(file != NULL);
|
||||
|
||||
|
||||
#ifdef __i386__
|
||||
|
||||
#include <unistd.h>
|
||||
#include <linux/unistd.h>
|
||||
|
||||
#define __NR_bad_stat64 195
|
||||
_syscall2(long, bad_stat64, char *, filename, struct stat64 *, statbuf);
|
||||
|
||||
#else
|
||||
|
||||
#define bad_stat64 stat64
|
||||
|
||||
#endif
|
||||
|
||||
/* yes, I know how ugly it is */
|
||||
#define return_stat_field(field) \
|
||||
struct stat st;\
|
||||
struct stat64 st64;\
|
||||
\
|
||||
if (bad_stat64 (file_name, &st64) == 0) {\
|
||||
return st64.st_##field;\
|
||||
} else if (stat (file_name, &st) == 0)\
|
||||
return st.st_##field;\
|
||||
\
|
||||
perror ("stat failed");\
|
||||
exit (8);\
|
||||
|
||||
|
||||
mode_t get_st_mode (char * file_name)
|
||||
{
|
||||
return_stat_field (mode);
|
||||
}
|
||||
|
||||
|
||||
/* may I look at this undocumented (at least in the info of libc 2.3.1-58)
|
||||
field? */
|
||||
dev_t get_st_rdev (char * file_name)
|
||||
{
|
||||
return_stat_field (rdev);
|
||||
}
|
||||
|
||||
|
||||
off64_t get_st_size (char * file_name)
|
||||
{
|
||||
return_stat_field (size);
|
||||
}
|
||||
|
||||
|
||||
blkcnt64_t get_st_blocks (char * file_name)
|
||||
{
|
||||
return_stat_field (blocks);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int _is_mounted (char * device_name, func_t f)
|
||||
{
|
||||
int retval;
|
||||
FILE *fp;
|
||||
struct mntent *mnt;
|
||||
struct statfs stfs;
|
||||
struct stat root_st;
|
||||
mode_t mode;
|
||||
|
||||
if (stat ("/", &root_st) == -1)
|
||||
die ("is_mounted: could not stat \"/\": %s\n", strerror(errno));
|
||||
|
||||
|
||||
mode = get_st_mode (device_name);
|
||||
if (S_ISREG (mode))
|
||||
/* regular file can not be mounted */
|
||||
return 0;
|
||||
|
||||
if (!S_ISBLK (mode))
|
||||
die ("is_mounted: %s is neither regular file nor block device", device_name);
|
||||
|
||||
if (root_st.st_dev == get_st_rdev (device_name)) {
|
||||
/* device is mounted as root. Check whether it is mounted read-only */
|
||||
return (f ? f ("/") : 1);
|
||||
}
|
||||
|
||||
/* if proc filesystem is mounted */
|
||||
if (statfs ("/proc", &stfs) == -1 || stfs.f_type != 0x9fa0/*procfs magic*/ ||
|
||||
(fp = setmntent ("/proc/mounts", "r")) == NULL) {
|
||||
/* proc filesystem is not mounted, or /proc/mounts does not
|
||||
exist */
|
||||
if (f)
|
||||
return (user_confirmed (stderr,
|
||||
" (could not figure out) Is filesystem mounted read-only? (Yes)",
|
||||
"Yes\n"));
|
||||
else
|
||||
return (user_confirmed (stderr,
|
||||
" (could not figure out) Is filesystem mounted? (Yes)", "Yes\n"));
|
||||
}
|
||||
|
||||
retval = 0;
|
||||
while ((mnt = getmntent (fp)) != NULL)
|
||||
if (strcmp (device_name, mnt->mnt_fsname) == 0) {
|
||||
retval = (f ? f (mnt->mnt_dir) : 1/*mounted*/);
|
||||
break;
|
||||
if (fsname && stat(file, &st) == 0) {
|
||||
/* Devices is stated. */
|
||||
if (S_ISBLK(st.st_mode)) {
|
||||
rdev = st.st_rdev;
|
||||
} else {
|
||||
dev = st.st_dev;
|
||||
ino = st.st_ino;
|
||||
}
|
||||
}
|
||||
endmntent (fp);
|
||||
|
||||
return retval;
|
||||
if ((fp = setmntent(mntfile, "r")) == NULL)
|
||||
return INVAL_PTR;
|
||||
|
||||
while ((mnt = getmntent(fp)) != NULL) {
|
||||
/* Check if names match. */
|
||||
if (fsname) {
|
||||
if (strcmp(file, mnt->mnt_fsname) == 0)
|
||||
break;
|
||||
} else {
|
||||
if (strcmp(file, mnt->mnt_dir) == 0)
|
||||
break;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Check if stats match. */
|
||||
if (stat(mnt->mnt_fsname, &st) == 0) {
|
||||
if (rdev && S_ISBLK(st.st_mode)) {
|
||||
if (rdev == st.st_rdev)
|
||||
break;
|
||||
} else {
|
||||
if (dev == st.st_dev &&
|
||||
ino == st.st_ino)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
endmntent (fp);
|
||||
return mnt;
|
||||
}
|
||||
|
||||
static int misc_root_mounted(char *device) {
|
||||
struct stat rootst, devst;
|
||||
|
||||
assert(device != NULL);
|
||||
|
||||
int is_mounted_read_only (char * device_name)
|
||||
{
|
||||
return _is_mounted (device_name, is_readonly_dir);
|
||||
if (stat("/", &rootst) != 0)
|
||||
return -1;
|
||||
|
||||
if (stat(device, &devst) != 0)
|
||||
return -1;
|
||||
|
||||
if (!S_ISBLK(devst.st_mode) ||
|
||||
devst.st_rdev != rootst.st_dev)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int misc_file_ro(char *file) {
|
||||
if (utime(file, 0) == -1) {
|
||||
if (errno == EROFS)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int is_mounted (char * device_name)
|
||||
{
|
||||
return _is_mounted (device_name, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct mntent *misc_mntent(char *device) {
|
||||
int proc = 0, path = 0, root = 0;
|
||||
|
||||
struct mntent *mnt;
|
||||
struct statfs stfs;
|
||||
|
||||
assert(device != NULL);
|
||||
|
||||
/* Check if the root. */
|
||||
if (misc_root_mounted(device) == 1)
|
||||
root = 1;
|
||||
|
||||
#ifdef __linux__
|
||||
/* Check if /proc is procfs. */
|
||||
if (statfs("/proc", &stfs) == 0 && stfs.f_type == 0x9fa0) {
|
||||
proc = 1;
|
||||
|
||||
if (root) {
|
||||
/* Lookup the "/" entry in /proc/mounts. Special
|
||||
case as root entry can present as:
|
||||
rootfs / rootfs rw 0 0
|
||||
Look up the mount point in this case. */
|
||||
mnt = misc_mntent_lookup("/proc/mounts", "/", 0);
|
||||
} else {
|
||||
/* Lookup the @device /proc/mounts */
|
||||
mnt = misc_mntent_lookup("/proc/mounts", device, 1);
|
||||
}
|
||||
|
||||
if (mnt == INVAL_PTR)
|
||||
proc = 0;
|
||||
else if (mnt)
|
||||
return mnt;
|
||||
}
|
||||
#endif /* __linux__ */
|
||||
|
||||
#if defined(MOUNTED) || defined(_PATH_MOUNTED)
|
||||
|
||||
#ifndef MOUNTED
|
||||
#define MOUNTED _PATH_MOUNTED
|
||||
#endif
|
||||
/* Check in MOUNTED (/etc/mtab) if RW. */
|
||||
if (!misc_file_ro(MOUNTED)) {
|
||||
path = 1;
|
||||
|
||||
if (root) {
|
||||
mnt = misc_mntent_lookup(MOUNTED, "/", 0);
|
||||
} else {
|
||||
mnt = misc_mntent_lookup(MOUNTED, device, 1);
|
||||
}
|
||||
|
||||
if (mnt == INVAL_PTR)
|
||||
path = 0;
|
||||
else if (mnt)
|
||||
return mnt;
|
||||
}
|
||||
#endif /* defined(MOUNTED) || defined(_PATH_MOUNTED) */
|
||||
|
||||
/* If has not been checked in neither /proc/mounts nor /etc/mtab (or
|
||||
errors have occured), return INVAL_PTR, NULL otherwise. */
|
||||
return (!proc && !path) ? INVAL_PTR : NULL;
|
||||
}
|
||||
|
||||
int misc_device_mounted(char *device) {
|
||||
struct mntent *mnt;
|
||||
|
||||
/* Check for the "/" first to avoid any possible problem with
|
||||
reflecting the root fs info in mtab files. */
|
||||
if (misc_root_mounted(device) == 1) {
|
||||
return misc_file_ro("/") ? MF_RO : MF_RW;
|
||||
}
|
||||
|
||||
/* Lookup the mount entry. */
|
||||
if ((mnt = misc_mntent(device)) == NULL) {
|
||||
return MF_NOT_MOUNTED;
|
||||
} else if (mnt == INVAL_PTR) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return hasmntopt(mnt, MNTOPT_RO) ? MF_RO : MF_RW;
|
||||
}
|
||||
|
||||
char buf1 [100];
|
||||
char buf2 [100];
|
||||
@@ -407,19 +442,42 @@ void print_how_far (FILE * fp,
|
||||
fflush (fp);
|
||||
}
|
||||
|
||||
#if defined(__linux__) && defined(_IOR) && !defined(BLKGETSIZE64)
|
||||
# define BLKGETSIZE64 _IOR(0x12, 114, __u64)
|
||||
#endif
|
||||
|
||||
/* To not have problem with last sectors on the block device when switching
|
||||
to smaller one. */
|
||||
#define MAX_BS (64 * 1024)
|
||||
|
||||
int valid_offset( int fd, loff_t offset) {
|
||||
char ch;
|
||||
loff_t res;
|
||||
|
||||
/*res = reiserfs_llseek (fd, offset, 0);*/
|
||||
res = lseek64 (fd, offset, SEEK_SET);
|
||||
if (res < 0)
|
||||
return 0;
|
||||
|
||||
/* if (read (fd, &ch, 1) < 0) does not wirk on files */
|
||||
if (read (fd, &ch, 1) < 1)
|
||||
return 0;
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* calculates number of blocks in a file. Returns 0 for "sparse"
|
||||
regular files and files other than regular files and block devices */
|
||||
unsigned long count_blocks (char * filename, int blocksize)
|
||||
{
|
||||
loff_t high, low;
|
||||
int fd;
|
||||
unsigned long sz;
|
||||
__u64 size;
|
||||
int fd;
|
||||
|
||||
if (!S_ISBLK (get_st_mode (filename)) && !S_ISREG (get_st_mode (filename)))
|
||||
if (!S_ISBLK(misc_device_mode(filename)) &&
|
||||
!S_ISREG(misc_device_mode(filename)))
|
||||
return 0;
|
||||
|
||||
fd = open (filename, O_RDONLY);
|
||||
@@ -429,10 +487,12 @@ unsigned long count_blocks (char * filename, int blocksize)
|
||||
#ifdef BLKGETSIZE64
|
||||
{
|
||||
if (ioctl (fd, BLKGETSIZE64, &size) >= 0) {
|
||||
size = (size / 4096) * 4096 / blocksize;
|
||||
size = (size / MAX_BS) * MAX_BS / blocksize;
|
||||
sz = size;
|
||||
if ((__u64)sz != size)
|
||||
die ("count_blocks: block device too large");
|
||||
|
||||
close(fd);
|
||||
return sz;
|
||||
}
|
||||
}
|
||||
@@ -443,7 +503,9 @@ unsigned long count_blocks (char * filename, int blocksize)
|
||||
{
|
||||
if (ioctl (fd, BLKGETSIZE, &sz) >= 0) {
|
||||
size = sz;
|
||||
return (size * 512 / 4096) * 4096 / blocksize;
|
||||
|
||||
close(fd);
|
||||
return (size * 512 / MAX_BS) * MAX_BS / blocksize;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -459,15 +521,13 @@ unsigned long count_blocks (char * filename, int blocksize)
|
||||
else
|
||||
high = mid;
|
||||
}
|
||||
|
||||
valid_offset (fd, 0);
|
||||
|
||||
close (fd);
|
||||
|
||||
return (low + 1) * 4096 / 4096 / blocksize ;
|
||||
return (low + 1) * MAX_BS / MAX_BS / blocksize;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* there are masks for certain bits */
|
||||
__u16 mask16 (int from, int count)
|
||||
{
|
||||
@@ -570,27 +630,6 @@ int blockdev_list_compare (const void * block1, const void * block2) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* return -1 if smth found, otherwise return position which new item should be inserted into */
|
||||
/*
|
||||
int blocklist__is_block_saved (struct block_handler ** base, __u32 * count,
|
||||
__u32 blocknr, dev_t device, __u32 * position) {
|
||||
struct block_handler block_h;
|
||||
|
||||
*position = 0;
|
||||
|
||||
if (*base == NULL)
|
||||
return 0;
|
||||
|
||||
block_h.blocknr = blocknr;
|
||||
block_h.device = device;
|
||||
|
||||
if (reiserfs_bin_search (&block_h, *base, *count, sizeof (block_h),
|
||||
position, blocklist_compare) == POSITION_FOUND)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
void blocklist__insert_in_position (void *elem, void **base, __u32 *count,
|
||||
int elem_size, __u32 *position)
|
||||
{
|
||||
@@ -614,93 +653,6 @@ void blocklist__insert_in_position (void *elem, void **base, __u32 *count,
|
||||
*count+=1;
|
||||
}
|
||||
|
||||
static int get_random_bytes (void *out, int size) {
|
||||
int fd;
|
||||
|
||||
if ((fd = open("/dev/urandom", O_RDONLY)) == -1)
|
||||
return 1;
|
||||
|
||||
if (read(fd, out, size) <= 0) {
|
||||
close (fd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
close (fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int generate_random_uuid (unsigned char * uuid)
|
||||
{
|
||||
if (get_random_bytes(uuid, 16)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Set the UUID variant to DCE */
|
||||
uuid[8] = (uuid[8] & 0x3F) | 0x80;
|
||||
/* Set UUID version to 4 --- truely random generation */
|
||||
uuid[6] = (uuid[6] & 0x0F) | 0x40;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int uuid_is_correct (unsigned char * uuid)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
if (uuid[i])
|
||||
break;
|
||||
|
||||
if (i == 16)
|
||||
return 0;
|
||||
|
||||
if (!misc_test_bit(7, &uuid[8]) || misc_test_bit(6, &uuid[8]))
|
||||
return 0;
|
||||
|
||||
if (misc_test_bit(7, &uuid[6]) || !misc_test_bit(6, &uuid[6]) ||
|
||||
misc_test_bit(5, &uuid[6]) || misc_test_bit(4, &uuid[6]))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int parse_uuid (const unsigned char * in, unsigned char * uuid)
|
||||
{
|
||||
int i, j = 0;
|
||||
unsigned char frame[3];
|
||||
|
||||
if (strlen(in) != 36)
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < 36; i++) {
|
||||
if ((i == 8) || (i == 13) || (i == 18) || (i == 23)) {
|
||||
if (in[i] != '-')
|
||||
return 0;
|
||||
} else if (!isxdigit(in[i])) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
frame[2] = 0;
|
||||
for (i = 0; i < 36; i ++) {
|
||||
if ((i == 8) || (i == 13) || (i == 18) || (i == 23))
|
||||
continue;
|
||||
|
||||
frame[0] = in[i++];
|
||||
frame[1] = in[i];
|
||||
uuid[j++] = strtoul(frame, NULL, 16);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int set_uuid (const unsigned char * text, unsigned char * UUID)
|
||||
{
|
||||
if (parse_uuid (text, UUID) || !uuid_is_correct(UUID))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 0 - dma is not supported, scsi or regular file */
|
||||
/* 1 - xt drive */
|
||||
/* 2 - ide drive */
|
||||
@@ -971,13 +923,30 @@ inline unsigned long long misc_find_next_set_bit(const void *vaddr,
|
||||
/* Reads the "CREDITS" file and prints one paragraph from it. */
|
||||
void misc_print_credit(FILE *out) {
|
||||
char *line;
|
||||
__u32 num1, num2;
|
||||
|
||||
fprintf(out, "\nA pair of credits:\n");
|
||||
fprintf(out, "A pair of credits:\n");
|
||||
|
||||
line = credits[(random() % CREDITS_COUNT)];
|
||||
fprintf(out, "%s", line);
|
||||
srandom (time (0));
|
||||
|
||||
line = credits[(random() % CREDITS_COUNT)];
|
||||
fprintf(out, "%s", line);
|
||||
num1 = random() % CREDITS_COUNT;
|
||||
line = credits[num1];
|
||||
fprintf(out, "%s\n", line);
|
||||
|
||||
while ((num1 == (num2 = random() % CREDITS_COUNT))) {}
|
||||
|
||||
line = credits[num2];
|
||||
|
||||
fprintf(out, "%s\n", line);
|
||||
}
|
||||
|
||||
int user_confirmed (FILE * fp, char * q, char * yes) {
|
||||
char * answer = 0;
|
||||
size_t n = 0;
|
||||
|
||||
fprintf (fp, "%s", q);
|
||||
if (getline (&answer, &n, stdin) != (ssize_t)strlen (yes) || strcmp (yes, answer))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
Reference in new issue
Block a user