pmt: e2fsprogs: cleanup
This commit is contained in:
74
e2fsprogs/lib/e2p/crypto_mode.c
Normal file
74
e2fsprogs/lib/e2p/crypto_mode.c
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* crypto_mode.c --- convert between encryption modes and strings
|
||||
*
|
||||
* Copyright (C) 1999 Theodore Ts'o <tytso@mit.edu>
|
||||
*
|
||||
* %Begin-Header%
|
||||
* This file may be redistributed under the terms of the GNU Library
|
||||
* General Public License, version 2.
|
||||
* %End-Header%
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "e2p.h"
|
||||
|
||||
struct mode {
|
||||
int num;
|
||||
const char *string;
|
||||
};
|
||||
|
||||
static struct mode mode_list[] = {
|
||||
{ EXT4_ENCRYPTION_MODE_INVALID, "Invalid"},
|
||||
{ EXT4_ENCRYPTION_MODE_AES_256_XTS, "AES-256-XTS"},
|
||||
{ EXT4_ENCRYPTION_MODE_AES_256_GCM, "AES-256-GCM"},
|
||||
{ EXT4_ENCRYPTION_MODE_AES_256_CBC, "AES-256-CBC"},
|
||||
{ 0, 0 },
|
||||
};
|
||||
|
||||
const char *e2p_encmode2string(int num)
|
||||
{
|
||||
struct mode *p;
|
||||
static char buf[20];
|
||||
|
||||
for (p = mode_list; p->string; p++) {
|
||||
if (num == p->num)
|
||||
return p->string;
|
||||
}
|
||||
sprintf(buf, "ENC_MODE_%d", num);
|
||||
return buf;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the hash algorithm, or -1 on error
|
||||
*/
|
||||
int e2p_string2encmode(char *string)
|
||||
{
|
||||
struct mode *p;
|
||||
char *eptr;
|
||||
int num;
|
||||
|
||||
for (p = mode_list; p->string; p++) {
|
||||
if (!strcasecmp(string, p->string)) {
|
||||
return p->num;
|
||||
}
|
||||
}
|
||||
if (strncasecmp(string, "ENC_MODE_", 9))
|
||||
return -1;
|
||||
|
||||
if (string[9] == 0)
|
||||
return -1;
|
||||
num = strtol(string+9, &eptr, 10);
|
||||
if (num > 255 || num < 0)
|
||||
return -1;
|
||||
if (*eptr)
|
||||
return -1;
|
||||
return num;
|
||||
}
|
||||
|
||||
118
e2fsprogs/lib/e2p/encoding.c
Normal file
118
e2fsprogs/lib/e2p/encoding.c
Normal file
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* encoding.c --- convert between encoding magic numbers and strings
|
||||
*
|
||||
* Copyright (C) 2018 Collabora Ltd.
|
||||
*
|
||||
* %Begin-Header%
|
||||
* This file may be redistributed under the terms of the GNU Library
|
||||
* General Public License, version 2.
|
||||
* %End-Header%
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "e2p.h"
|
||||
|
||||
#define ARRAY_SIZE(array) \
|
||||
(sizeof(array) / sizeof(array[0]))
|
||||
|
||||
static const struct {
|
||||
const char *name;
|
||||
__u16 encoding_magic;
|
||||
__u16 default_flags;
|
||||
|
||||
} ext4_encoding_map[] = {
|
||||
{
|
||||
.encoding_magic = EXT4_ENC_UTF8_12_1,
|
||||
.name = "utf8-12.1",
|
||||
.default_flags = 0,
|
||||
},
|
||||
{
|
||||
.encoding_magic = EXT4_ENC_UTF8_12_1,
|
||||
.name = "utf8",
|
||||
.default_flags = 0,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct enc_flags {
|
||||
__u16 flag;
|
||||
const char *param;
|
||||
} encoding_flags[] = {
|
||||
{ EXT4_ENC_STRICT_MODE_FL, "strict" },
|
||||
};
|
||||
|
||||
/* Return a positive number < 0xff indicating the encoding magic number
|
||||
* or a negative value indicating error. */
|
||||
int e2p_str2encoding(const char *string)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0 ; i < ARRAY_SIZE(ext4_encoding_map); i++)
|
||||
if (!strcmp(string, ext4_encoding_map[i].name))
|
||||
return ext4_encoding_map[i].encoding_magic;
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Return the name of an encoding or NULL */
|
||||
const char *e2p_encoding2str(int encoding)
|
||||
{
|
||||
unsigned int i;
|
||||
static char buf[32];
|
||||
|
||||
for (i = 0 ; i < ARRAY_SIZE(ext4_encoding_map); i++)
|
||||
if (ext4_encoding_map[i].encoding_magic == encoding)
|
||||
return ext4_encoding_map[i].name;
|
||||
sprintf(buf, "UNKNOWN_ENCODING_%d", encoding);
|
||||
return buf;
|
||||
}
|
||||
|
||||
int e2p_get_encoding_flags(int encoding)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0 ; i < ARRAY_SIZE(ext4_encoding_map); i++)
|
||||
if (ext4_encoding_map[i].encoding_magic == encoding)
|
||||
return ext4_encoding_map[i].default_flags;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int e2p_str2encoding_flags(int encoding, char *param, __u16 *flags)
|
||||
{
|
||||
char *f = strtok(param, "-");
|
||||
const struct enc_flags *fl;
|
||||
unsigned int i, neg = 0;
|
||||
|
||||
if (encoding != EXT4_ENC_UTF8_12_1)
|
||||
return -EINVAL;
|
||||
while (f) {
|
||||
neg = 0;
|
||||
if (!strncmp("no", f, 2)) {
|
||||
neg = 1;
|
||||
f += 2;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(encoding_flags); i++) {
|
||||
fl = &encoding_flags[i];
|
||||
if (!strcmp(fl->param, f)) {
|
||||
if (neg)
|
||||
*flags &= ~fl->flag;
|
||||
else
|
||||
*flags |= fl->flag;
|
||||
|
||||
goto next_flag;
|
||||
}
|
||||
}
|
||||
return -EINVAL;
|
||||
next_flag:
|
||||
f = strtok(NULL, "-");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
48
e2fsprogs/lib/e2p/errcode.c
Normal file
48
e2fsprogs/lib/e2p/errcode.c
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* errcode.c - convert an error code to a string
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "e2p.h"
|
||||
|
||||
static const char *err_string[] = {
|
||||
"",
|
||||
"UNKNOWN", /* 1 */
|
||||
"EIO", /* 2 */
|
||||
"ENOMEM", /* 3 */
|
||||
"EFSBADCRC", /* 4 */
|
||||
"EFSCORRUPTED", /* 5 */
|
||||
"ENOSPC", /* 6 */
|
||||
"ENOKEY", /* 7 */
|
||||
"EROFS", /* 8 */
|
||||
"EFBIG", /* 9 */
|
||||
"EEXIST", /* 10 */
|
||||
"ERANGE", /* 11 */
|
||||
"EOVERFLOW", /* 12 */
|
||||
"EBUSY", /* 13 */
|
||||
"ENOTDIR", /* 14 */
|
||||
"ENOTEMPTY", /* 15 */
|
||||
"ESHUTDOWN", /* 16 */
|
||||
"EFAULT", /* 17 */
|
||||
};
|
||||
|
||||
#define ARRAY_SIZE(array) \
|
||||
(sizeof(array) / sizeof(array[0]))
|
||||
|
||||
/* Return the name of an encoding or NULL */
|
||||
const char *e2p_errcode2str(unsigned int err)
|
||||
{
|
||||
static char buf[32];
|
||||
|
||||
if (err < ARRAY_SIZE(err_string))
|
||||
return err_string[err];
|
||||
|
||||
sprintf(buf, "UNKNOWN_ERRCODE_%u", err);
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
445
e2fsprogs/lib/e2p/feature.c
Normal file
445
e2fsprogs/lib/e2p/feature.c
Normal file
@@ -0,0 +1,445 @@
|
||||
/*
|
||||
* feature.c --- convert between features and strings
|
||||
*
|
||||
* Copyright (C) 1999 Theodore Ts'o <tytso@mit.edu>
|
||||
*
|
||||
* %Begin-Header%
|
||||
* This file may be redistributed under the terms of the GNU Library
|
||||
* General Public License, version 2.
|
||||
* %End-Header%
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "e2p.h"
|
||||
#include <ext2fs/ext2fs.h>
|
||||
#include <ext2fs/kernel-jbd.h>
|
||||
|
||||
struct feature {
|
||||
int compat;
|
||||
unsigned int mask;
|
||||
const char *string;
|
||||
};
|
||||
|
||||
static struct feature feature_list[] = {
|
||||
{ E2P_FEATURE_COMPAT, EXT2_FEATURE_COMPAT_DIR_PREALLOC,
|
||||
"dir_prealloc" },
|
||||
{ E2P_FEATURE_COMPAT, EXT3_FEATURE_COMPAT_HAS_JOURNAL,
|
||||
"has_journal" },
|
||||
{ E2P_FEATURE_COMPAT, EXT2_FEATURE_COMPAT_IMAGIC_INODES,
|
||||
"imagic_inodes" },
|
||||
{ E2P_FEATURE_COMPAT, EXT2_FEATURE_COMPAT_EXT_ATTR,
|
||||
"ext_attr" },
|
||||
{ E2P_FEATURE_COMPAT, EXT2_FEATURE_COMPAT_DIR_INDEX,
|
||||
"dir_index" },
|
||||
{ E2P_FEATURE_COMPAT, EXT2_FEATURE_COMPAT_RESIZE_INODE,
|
||||
"resize_inode" },
|
||||
{ E2P_FEATURE_COMPAT, EXT2_FEATURE_COMPAT_LAZY_BG,
|
||||
"lazy_bg" },
|
||||
{ E2P_FEATURE_COMPAT, EXT2_FEATURE_COMPAT_EXCLUDE_BITMAP,
|
||||
"snapshot_bitmap" },
|
||||
{ E2P_FEATURE_COMPAT, EXT4_FEATURE_COMPAT_SPARSE_SUPER2,
|
||||
"sparse_super2" },
|
||||
{ E2P_FEATURE_COMPAT, EXT4_FEATURE_COMPAT_FAST_COMMIT,
|
||||
"fast_commit" },
|
||||
{ E2P_FEATURE_COMPAT, EXT4_FEATURE_COMPAT_STABLE_INODES,
|
||||
"stable_inodes" },
|
||||
|
||||
{ E2P_FEATURE_RO_INCOMPAT, EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER,
|
||||
"sparse_super" },
|
||||
{ E2P_FEATURE_RO_INCOMPAT, EXT2_FEATURE_RO_COMPAT_LARGE_FILE,
|
||||
"large_file" },
|
||||
{ E2P_FEATURE_RO_INCOMPAT, EXT4_FEATURE_RO_COMPAT_HUGE_FILE,
|
||||
"huge_file" },
|
||||
{ E2P_FEATURE_RO_INCOMPAT, EXT4_FEATURE_RO_COMPAT_GDT_CSUM,
|
||||
"uninit_bg" },
|
||||
{ E2P_FEATURE_RO_INCOMPAT, EXT4_FEATURE_RO_COMPAT_GDT_CSUM,
|
||||
"uninit_groups" },
|
||||
{ E2P_FEATURE_RO_INCOMPAT, EXT4_FEATURE_RO_COMPAT_DIR_NLINK,
|
||||
"dir_nlink" },
|
||||
{ E2P_FEATURE_RO_INCOMPAT, EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE,
|
||||
"extra_isize" },
|
||||
{ E2P_FEATURE_RO_INCOMPAT, EXT4_FEATURE_RO_COMPAT_QUOTA,
|
||||
"quota" },
|
||||
{ E2P_FEATURE_RO_INCOMPAT, EXT4_FEATURE_RO_COMPAT_BIGALLOC,
|
||||
"bigalloc"},
|
||||
{ E2P_FEATURE_RO_INCOMPAT, EXT4_FEATURE_RO_COMPAT_METADATA_CSUM,
|
||||
"metadata_csum"},
|
||||
{ E2P_FEATURE_RO_INCOMPAT, EXT4_FEATURE_RO_COMPAT_REPLICA,
|
||||
"replica" },
|
||||
{ E2P_FEATURE_RO_INCOMPAT, EXT4_FEATURE_RO_COMPAT_READONLY,
|
||||
"read-only" },
|
||||
{ E2P_FEATURE_RO_INCOMPAT, EXT4_FEATURE_RO_COMPAT_PROJECT,
|
||||
"project"},
|
||||
{ E2P_FEATURE_RO_INCOMPAT, EXT4_FEATURE_RO_COMPAT_SHARED_BLOCKS,
|
||||
"shared_blocks"},
|
||||
{ E2P_FEATURE_RO_INCOMPAT, EXT4_FEATURE_RO_COMPAT_VERITY,
|
||||
"verity"},
|
||||
|
||||
{ E2P_FEATURE_INCOMPAT, EXT2_FEATURE_INCOMPAT_COMPRESSION,
|
||||
"compression" },
|
||||
{ E2P_FEATURE_INCOMPAT, EXT2_FEATURE_INCOMPAT_FILETYPE,
|
||||
"filetype" },
|
||||
{ E2P_FEATURE_INCOMPAT, EXT3_FEATURE_INCOMPAT_RECOVER,
|
||||
"needs_recovery" },
|
||||
{ E2P_FEATURE_INCOMPAT, EXT3_FEATURE_INCOMPAT_JOURNAL_DEV,
|
||||
"journal_dev" },
|
||||
{ E2P_FEATURE_INCOMPAT, EXT3_FEATURE_INCOMPAT_EXTENTS,
|
||||
"extent" },
|
||||
{ E2P_FEATURE_INCOMPAT, EXT3_FEATURE_INCOMPAT_EXTENTS,
|
||||
"extents" },
|
||||
{ E2P_FEATURE_INCOMPAT, EXT2_FEATURE_INCOMPAT_META_BG,
|
||||
"meta_bg" },
|
||||
{ E2P_FEATURE_INCOMPAT, EXT4_FEATURE_INCOMPAT_64BIT,
|
||||
"64bit" },
|
||||
{ E2P_FEATURE_INCOMPAT, EXT4_FEATURE_INCOMPAT_MMP,
|
||||
"mmp" },
|
||||
{ E2P_FEATURE_INCOMPAT, EXT4_FEATURE_INCOMPAT_FLEX_BG,
|
||||
"flex_bg"},
|
||||
{ E2P_FEATURE_INCOMPAT, EXT4_FEATURE_INCOMPAT_EA_INODE,
|
||||
"ea_inode"},
|
||||
{ E2P_FEATURE_INCOMPAT, EXT4_FEATURE_INCOMPAT_DIRDATA,
|
||||
"dirdata"},
|
||||
{ E2P_FEATURE_INCOMPAT, EXT4_FEATURE_INCOMPAT_CSUM_SEED,
|
||||
"metadata_csum_seed"},
|
||||
{ E2P_FEATURE_INCOMPAT, EXT4_FEATURE_INCOMPAT_LARGEDIR,
|
||||
"large_dir"},
|
||||
{ E2P_FEATURE_INCOMPAT, EXT4_FEATURE_INCOMPAT_INLINE_DATA,
|
||||
"inline_data"},
|
||||
{ E2P_FEATURE_INCOMPAT, EXT4_FEATURE_INCOMPAT_ENCRYPT,
|
||||
"encrypt"},
|
||||
{ E2P_FEATURE_INCOMPAT, EXT4_FEATURE_INCOMPAT_CASEFOLD,
|
||||
"casefold"},
|
||||
{ E2P_FEATURE_INCOMPAT, EXT4_FEATURE_INCOMPAT_CASEFOLD,
|
||||
"fname_encoding"},
|
||||
{ 0, 0, 0 },
|
||||
};
|
||||
|
||||
static struct feature jrnl_feature_list[] = {
|
||||
{ E2P_FEATURE_COMPAT, JBD2_FEATURE_COMPAT_CHECKSUM,
|
||||
"journal_checksum" },
|
||||
|
||||
{ E2P_FEATURE_INCOMPAT, JBD2_FEATURE_INCOMPAT_REVOKE,
|
||||
"journal_incompat_revoke" },
|
||||
{ E2P_FEATURE_INCOMPAT, JBD2_FEATURE_INCOMPAT_64BIT,
|
||||
"journal_64bit" },
|
||||
{ E2P_FEATURE_INCOMPAT, JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT,
|
||||
"journal_async_commit" },
|
||||
{ E2P_FEATURE_INCOMPAT, JBD2_FEATURE_INCOMPAT_CSUM_V2,
|
||||
"journal_checksum_v2" },
|
||||
{ E2P_FEATURE_INCOMPAT, JBD2_FEATURE_INCOMPAT_CSUM_V3,
|
||||
"journal_checksum_v3" },
|
||||
{ 0, 0, 0 },
|
||||
};
|
||||
|
||||
void e2p_feature_to_string(int compat, unsigned int mask, char *buf,
|
||||
size_t buf_len)
|
||||
{
|
||||
struct feature *f;
|
||||
char fchar;
|
||||
int fnum;
|
||||
|
||||
for (f = feature_list; f->string; f++) {
|
||||
if ((compat == f->compat) &&
|
||||
(mask == f->mask)) {
|
||||
strncpy(buf, f->string, buf_len);
|
||||
buf[buf_len - 1] = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
switch (compat) {
|
||||
case E2P_FEATURE_COMPAT:
|
||||
fchar = 'C';
|
||||
break;
|
||||
case E2P_FEATURE_INCOMPAT:
|
||||
fchar = 'I';
|
||||
break;
|
||||
case E2P_FEATURE_RO_INCOMPAT:
|
||||
fchar = 'R';
|
||||
break;
|
||||
default:
|
||||
fchar = '?';
|
||||
break;
|
||||
}
|
||||
for (fnum = 0; mask >>= 1; fnum++);
|
||||
sprintf(buf, "FEATURE_%c%d", fchar, fnum);
|
||||
}
|
||||
|
||||
const char *e2p_feature2string(int compat, unsigned int mask)
|
||||
{
|
||||
static char buf[20];
|
||||
|
||||
e2p_feature_to_string(compat, mask, buf, sizeof(buf) / sizeof(buf[0]));
|
||||
return buf;
|
||||
}
|
||||
|
||||
int e2p_string2feature(char *string, int *compat_type, unsigned int *mask)
|
||||
{
|
||||
struct feature *f;
|
||||
char *eptr;
|
||||
int num;
|
||||
|
||||
for (f = feature_list; f->string; f++) {
|
||||
if (!strcasecmp(string, f->string)) {
|
||||
*compat_type = f->compat;
|
||||
*mask = f->mask;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (strncasecmp(string, "FEATURE_", 8))
|
||||
return 1;
|
||||
|
||||
switch (string[8]) {
|
||||
case 'c':
|
||||
case 'C':
|
||||
*compat_type = E2P_FEATURE_COMPAT;
|
||||
break;
|
||||
case 'i':
|
||||
case 'I':
|
||||
*compat_type = E2P_FEATURE_INCOMPAT;
|
||||
break;
|
||||
case 'r':
|
||||
case 'R':
|
||||
*compat_type = E2P_FEATURE_RO_INCOMPAT;
|
||||
break;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
if (string[9] == 0)
|
||||
return 1;
|
||||
num = strtol(string+9, &eptr, 10);
|
||||
if (num > 31 || num < 0)
|
||||
return 1;
|
||||
if (*eptr)
|
||||
return 1;
|
||||
*mask = 1 << num;
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *e2p_jrnl_feature2string(int compat, unsigned int mask)
|
||||
{
|
||||
struct feature *f;
|
||||
static char buf[20];
|
||||
char fchar;
|
||||
int fnum;
|
||||
|
||||
for (f = jrnl_feature_list; f->string; f++) {
|
||||
if ((compat == f->compat) &&
|
||||
(mask == f->mask))
|
||||
return f->string;
|
||||
}
|
||||
switch (compat) {
|
||||
case E2P_FEATURE_COMPAT:
|
||||
fchar = 'C';
|
||||
break;
|
||||
case E2P_FEATURE_INCOMPAT:
|
||||
fchar = 'I';
|
||||
break;
|
||||
case E2P_FEATURE_RO_INCOMPAT:
|
||||
fchar = 'R';
|
||||
break;
|
||||
default:
|
||||
fchar = '?';
|
||||
break;
|
||||
}
|
||||
for (fnum = 0; mask >>= 1; fnum++);
|
||||
sprintf(buf, "FEATURE_%c%d", fchar, fnum);
|
||||
return buf;
|
||||
}
|
||||
|
||||
int e2p_jrnl_string2feature(char *string, int *compat_type, unsigned int *mask)
|
||||
{
|
||||
struct feature *f;
|
||||
char *eptr;
|
||||
int num;
|
||||
|
||||
for (f = jrnl_feature_list; f->string; f++) {
|
||||
if (!strcasecmp(string, f->string)) {
|
||||
*compat_type = f->compat;
|
||||
*mask = f->mask;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (strncasecmp(string, "FEATURE_", 8))
|
||||
return 1;
|
||||
|
||||
switch (string[8]) {
|
||||
case 'c':
|
||||
case 'C':
|
||||
*compat_type = E2P_FEATURE_COMPAT;
|
||||
break;
|
||||
case 'i':
|
||||
case 'I':
|
||||
*compat_type = E2P_FEATURE_INCOMPAT;
|
||||
break;
|
||||
case 'r':
|
||||
case 'R':
|
||||
*compat_type = E2P_FEATURE_RO_INCOMPAT;
|
||||
break;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
if (string[9] == 0)
|
||||
return 1;
|
||||
num = strtol(string+9, &eptr, 10);
|
||||
if (num > 31 || num < 0)
|
||||
return 1;
|
||||
if (*eptr)
|
||||
return 1;
|
||||
*mask = 1 << num;
|
||||
return 0;
|
||||
}
|
||||
static char *skip_over_blanks(char *cp)
|
||||
{
|
||||
while (*cp && isspace(*cp))
|
||||
cp++;
|
||||
return cp;
|
||||
}
|
||||
|
||||
static char *skip_over_word(char *cp)
|
||||
{
|
||||
while (*cp && !isspace(*cp) && *cp != ',')
|
||||
cp++;
|
||||
return cp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Edit a feature set array as requested by the user. The ok_array,
|
||||
* if set, allows the application to limit what features the user is
|
||||
* allowed to set or clear using this function. If clear_ok_array is set,
|
||||
* then use it tell whether or not it is OK to clear a filesystem feature.
|
||||
*/
|
||||
int e2p_edit_feature2(const char *str, __u32 *compat_array, __u32 *ok_array,
|
||||
__u32 *clear_ok_array, int *type_err,
|
||||
unsigned int *mask_err)
|
||||
{
|
||||
char *cp, *buf, *next;
|
||||
int neg;
|
||||
unsigned int mask;
|
||||
int compat_type;
|
||||
int rc = 0;
|
||||
|
||||
if (!clear_ok_array)
|
||||
clear_ok_array = ok_array;
|
||||
|
||||
if (type_err)
|
||||
*type_err = 0;
|
||||
if (mask_err)
|
||||
*mask_err = 0;
|
||||
|
||||
buf = malloc(strlen(str)+1);
|
||||
if (!buf)
|
||||
return 1;
|
||||
strcpy(buf, str);
|
||||
for (cp = buf; cp && *cp; cp = next ? next+1 : 0) {
|
||||
neg = 0;
|
||||
cp = skip_over_blanks(cp);
|
||||
next = skip_over_word(cp);
|
||||
|
||||
if (*next == 0)
|
||||
next = 0;
|
||||
else
|
||||
*next = 0;
|
||||
|
||||
if ((strcasecmp(cp, "none") == 0) ||
|
||||
(strcasecmp(cp, "clear") == 0)) {
|
||||
compat_array[0] = 0;
|
||||
compat_array[1] = 0;
|
||||
compat_array[2] = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (*cp) {
|
||||
case '-':
|
||||
case '^':
|
||||
neg++;
|
||||
/* fallthrough */
|
||||
case '+':
|
||||
cp++;
|
||||
break;
|
||||
}
|
||||
if (e2p_string2feature(cp, &compat_type, &mask)) {
|
||||
rc = 1;
|
||||
break;
|
||||
}
|
||||
if (neg) {
|
||||
if (clear_ok_array &&
|
||||
!(clear_ok_array[compat_type] & mask)) {
|
||||
rc = 1;
|
||||
if (type_err)
|
||||
*type_err = (compat_type |
|
||||
E2P_FEATURE_NEGATE_FLAG);
|
||||
if (mask_err)
|
||||
*mask_err = mask;
|
||||
break;
|
||||
}
|
||||
compat_array[compat_type] &= ~mask;
|
||||
} else {
|
||||
if (ok_array && !(ok_array[compat_type] & mask)) {
|
||||
rc = 1;
|
||||
if (type_err)
|
||||
*type_err = compat_type;
|
||||
if (mask_err)
|
||||
*mask_err = mask;
|
||||
break;
|
||||
}
|
||||
compat_array[compat_type] |= mask;
|
||||
}
|
||||
}
|
||||
free(buf);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int e2p_edit_feature(const char *str, __u32 *compat_array, __u32 *ok_array)
|
||||
{
|
||||
return e2p_edit_feature2(str, compat_array, ok_array, 0, 0, 0);
|
||||
}
|
||||
|
||||
#ifdef TEST_PROGRAM
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int compat, compat2, i;
|
||||
unsigned int mask, mask2;
|
||||
const char *str;
|
||||
struct feature *f;
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
if (i == 0) {
|
||||
f = feature_list;
|
||||
printf("Feature list:\n");
|
||||
} else {
|
||||
printf("\nJournal feature list:\n");
|
||||
f = jrnl_feature_list;
|
||||
}
|
||||
for (; f->string; f++) {
|
||||
if (i == 0) {
|
||||
e2p_string2feature((char *)f->string, &compat,
|
||||
&mask);
|
||||
str = e2p_feature2string(compat, mask);
|
||||
} else {
|
||||
e2p_jrnl_string2feature((char *)f->string,
|
||||
&compat, &mask);
|
||||
str = e2p_jrnl_feature2string(compat, mask);
|
||||
}
|
||||
|
||||
printf("\tCompat = %d, Mask = %u, %s\n",
|
||||
compat, mask, f->string);
|
||||
if (strcmp(f->string, str)) {
|
||||
if (e2p_string2feature((char *) str, &compat2,
|
||||
&mask2) ||
|
||||
(compat2 != compat) ||
|
||||
(mask2 != mask)) {
|
||||
fprintf(stderr, "Failure!\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
#endif
|
||||
117
e2fsprogs/lib/e2p/fgetflags.c
Normal file
117
e2fsprogs/lib/e2p/fgetflags.c
Normal file
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* fgetflags.c - Get a file flags on an ext2 file system
|
||||
*
|
||||
* Copyright (C) 1993, 1994 Remy Card <card@masi.ibp.fr>
|
||||
* Laboratoire MASI, Institut Blaise Pascal
|
||||
* Universite Pierre et Marie Curie (Paris VI)
|
||||
*
|
||||
* %Begin-Header%
|
||||
* This file may be redistributed under the terms of the GNU Library
|
||||
* General Public License, version 2.
|
||||
* %End-Header%
|
||||
*/
|
||||
|
||||
/*
|
||||
* History:
|
||||
* 93/10/30 - Creation
|
||||
*/
|
||||
|
||||
#ifndef _LARGEFILE_SOURCE
|
||||
#define _LARGEFILE_SOURCE
|
||||
#endif
|
||||
#ifndef _LARGEFILE64_SOURCE
|
||||
#define _LARGEFILE64_SOURCE
|
||||
#endif
|
||||
|
||||
#include "config.h"
|
||||
#if HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
#if HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#if HAVE_EXT2_IOCTLS
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
|
||||
#include "e2p.h"
|
||||
|
||||
#ifndef O_LARGEFILE
|
||||
#define O_LARGEFILE 0
|
||||
#endif
|
||||
#ifndef O_NOFOLLOW
|
||||
#define O_NOFOLLOW 0
|
||||
#endif
|
||||
|
||||
#define OPEN_FLAGS (O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_NOFOLLOW)
|
||||
|
||||
int fgetflags (const char * name, unsigned long * flags)
|
||||
{
|
||||
#if HAVE_STAT_FLAGS && !(APPLE_DARWIN && HAVE_EXT2_IOCTLS)
|
||||
struct stat buf;
|
||||
|
||||
if (stat (name, &buf) == -1)
|
||||
return -1;
|
||||
|
||||
*flags = 0;
|
||||
#ifdef UF_IMMUTABLE
|
||||
if (buf.st_flags & UF_IMMUTABLE)
|
||||
*flags |= EXT2_IMMUTABLE_FL;
|
||||
#endif
|
||||
#ifdef UF_APPEND
|
||||
if (buf.st_flags & UF_APPEND)
|
||||
*flags |= EXT2_APPEND_FL;
|
||||
#endif
|
||||
#ifdef UF_NODUMP
|
||||
if (buf.st_flags & UF_NODUMP)
|
||||
*flags |= EXT2_NODUMP_FL;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
#elif APPLE_DARWIN && HAVE_EXT2_IOCTLS
|
||||
int f, save_errno = 0;
|
||||
|
||||
f = -1;
|
||||
save_errno = syscall(SYS_fsctl, name, EXT2_IOC_GETFLAGS, &f, 0);
|
||||
*flags = f;
|
||||
return (save_errno);
|
||||
#elif HAVE_EXT2_IOCTLS
|
||||
struct stat buf;
|
||||
int fd, r, f, save_errno = 0;
|
||||
|
||||
if (!stat(name, &buf) &&
|
||||
!S_ISREG(buf.st_mode) && !S_ISDIR(buf.st_mode)) {
|
||||
errno = EOPNOTSUPP;
|
||||
return -1;
|
||||
}
|
||||
fd = open(name, OPEN_FLAGS);
|
||||
if (fd == -1) {
|
||||
if (errno == ELOOP || errno == ENXIO)
|
||||
errno = EOPNOTSUPP;
|
||||
return -1;
|
||||
}
|
||||
if (!fstat(fd, &buf) &&
|
||||
!S_ISREG(buf.st_mode) && !S_ISDIR(buf.st_mode)) {
|
||||
close(fd);
|
||||
errno = EOPNOTSUPP;
|
||||
return -1;
|
||||
}
|
||||
r = ioctl(fd, EXT2_IOC_GETFLAGS, &f);
|
||||
if (r == -1) {
|
||||
if (errno == ENOTTY)
|
||||
errno = EOPNOTSUPP;
|
||||
save_errno = errno;
|
||||
}
|
||||
*flags = f;
|
||||
close(fd);
|
||||
if (save_errno)
|
||||
errno = save_errno;
|
||||
return r;
|
||||
#else
|
||||
errno = EOPNOTSUPP;
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
63
e2fsprogs/lib/e2p/fgetproject.c
Normal file
63
e2fsprogs/lib/e2p/fgetproject.c
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* fgetproject.c --- get project id
|
||||
*
|
||||
* Copyright (C) 1999 Theodore Ts'o <tytso@mit.edu>
|
||||
*
|
||||
* %Begin-Header%
|
||||
* This file may be redistributed under the terms of the GNU Library
|
||||
* General Public License, version 2.
|
||||
* %End-Header%
|
||||
*/
|
||||
|
||||
#ifndef _LARGEFILE_SOURCE
|
||||
#define _LARGEFILE_SOURCE
|
||||
#endif
|
||||
#ifndef _LARGEFILE64_SOURCE
|
||||
#define _LARGEFILE64_SOURCE
|
||||
#endif
|
||||
|
||||
#include "config.h"
|
||||
#if HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
#if HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#if HAVE_EXT2_IOCTLS
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include "project.h"
|
||||
#endif
|
||||
|
||||
#include "e2p.h"
|
||||
|
||||
#ifdef O_LARGEFILE
|
||||
#define OPEN_FLAGS (O_RDONLY|O_NONBLOCK|O_LARGEFILE)
|
||||
#else
|
||||
#define OPEN_FLAGS (O_RDONLY|O_NONBLOCK)
|
||||
#endif
|
||||
|
||||
int fgetproject(const char *name, unsigned long *project)
|
||||
{
|
||||
#ifndef FS_IOC_FSGETXATTR
|
||||
errno = EOPNOTSUPP;
|
||||
return -1;
|
||||
#else
|
||||
int fd, r, save_errno = 0;
|
||||
struct fsxattr fsx;
|
||||
|
||||
fd = open (name, OPEN_FLAGS);
|
||||
if (fd == -1)
|
||||
return -1;
|
||||
r = ioctl (fd, FS_IOC_FSGETXATTR, &fsx);
|
||||
if (r == 0)
|
||||
*project = fsx.fsx_projid;
|
||||
save_errno = errno;
|
||||
close (fd);
|
||||
if (save_errno)
|
||||
errno = save_errno;
|
||||
return r;
|
||||
#endif
|
||||
}
|
||||
74
e2fsprogs/lib/e2p/fgetversion.c
Normal file
74
e2fsprogs/lib/e2p/fgetversion.c
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* fgetversion.c - Get a file version on an ext2 file system
|
||||
*
|
||||
* Copyright (C) 1993, 1994 Remy Card <card@masi.ibp.fr>
|
||||
* Laboratoire MASI, Institut Blaise Pascal
|
||||
* Universite Pierre et Marie Curie (Paris VI)
|
||||
*
|
||||
* %Begin-Header%
|
||||
* This file may be redistributed under the terms of the GNU Library
|
||||
* General Public License, version 2.
|
||||
* %End-Header%
|
||||
*/
|
||||
|
||||
/*
|
||||
* History:
|
||||
* 93/10/30 - Creation
|
||||
*/
|
||||
|
||||
#ifndef _LARGEFILE_SOURCE
|
||||
#define _LARGEFILE_SOURCE
|
||||
#endif
|
||||
#ifndef _LARGEFILE64_SOURCE
|
||||
#define _LARGEFILE64_SOURCE
|
||||
#endif
|
||||
|
||||
#include "config.h"
|
||||
#if HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
#if HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
#if HAVE_SYS_IOCTL_H
|
||||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
|
||||
#include "e2p.h"
|
||||
|
||||
#ifdef O_LARGEFILE
|
||||
#define OPEN_FLAGS (O_RDONLY|O_NONBLOCK|O_LARGEFILE)
|
||||
#else
|
||||
#define OPEN_FLAGS (O_RDONLY|O_NONBLOCK)
|
||||
#endif
|
||||
|
||||
int fgetversion(const char *name, unsigned long *version)
|
||||
{
|
||||
unsigned int ver = -1;
|
||||
int rc = -1;
|
||||
#if HAVE_EXT2_IOCTLS
|
||||
# if !APPLE_DARWIN
|
||||
int fd, save_errno = 0;
|
||||
|
||||
fd = open(name, OPEN_FLAGS);
|
||||
if (fd == -1)
|
||||
return -1;
|
||||
|
||||
rc = ioctl(fd, EXT2_IOC_GETVERSION, &ver);
|
||||
if (rc == -1)
|
||||
save_errno = errno;
|
||||
close(fd);
|
||||
if (rc == -1)
|
||||
errno = save_errno;
|
||||
# else /* APPLE_DARWIN */
|
||||
rc = syscall(SYS_fsctl, name, EXT2_IOC_GETVERSION, &ver, 0);
|
||||
# endif /* !APPLE_DARWIN */
|
||||
#else /* ! HAVE_EXT2_IOCTLS */
|
||||
errno = EOPNOTSUPP;
|
||||
#endif /* ! HAVE_EXT2_IOCTLS */
|
||||
if (rc == 0)
|
||||
*version = ver;
|
||||
|
||||
return rc;
|
||||
}
|
||||
118
e2fsprogs/lib/e2p/fsetflags.c
Normal file
118
e2fsprogs/lib/e2p/fsetflags.c
Normal file
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* fsetflags.c - Set a file flags on an ext2 file system
|
||||
*
|
||||
* Copyright (C) 1993, 1994 Remy Card <card@masi.ibp.fr>
|
||||
* Laboratoire MASI, Institut Blaise Pascal
|
||||
* Universite Pierre et Marie Curie (Paris VI)
|
||||
*
|
||||
* %Begin-Header%
|
||||
* This file may be redistributed under the terms of the GNU Library
|
||||
* General Public License, version 2.
|
||||
* %End-Header%
|
||||
*/
|
||||
|
||||
/*
|
||||
* History:
|
||||
* 93/10/30 - Creation
|
||||
*/
|
||||
|
||||
#ifndef _LARGEFILE_SOURCE
|
||||
#define _LARGEFILE_SOURCE
|
||||
#endif
|
||||
#ifndef _LARGEFILE64_SOURCE
|
||||
#define _LARGEFILE64_SOURCE
|
||||
#endif
|
||||
|
||||
#include "config.h"
|
||||
#if HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
#if HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#if HAVE_EXT2_IOCTLS
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
|
||||
#include "e2p.h"
|
||||
|
||||
/*
|
||||
* Deal with lame glibc's that define this function without actually
|
||||
* implementing it. Can you say "attractive nuisance", boys and girls?
|
||||
* I knew you could!
|
||||
*/
|
||||
#ifdef __linux__
|
||||
#undef HAVE_CHFLAGS
|
||||
#endif
|
||||
|
||||
#ifndef O_LARGEFILE
|
||||
#define O_LARGEFILE 0
|
||||
#endif
|
||||
#ifndef O_NOFOLLOW
|
||||
#define O_NOFOLLOW 0
|
||||
#endif
|
||||
|
||||
#define OPEN_FLAGS (O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_NOFOLLOW)
|
||||
|
||||
int fsetflags (const char * name, unsigned long flags)
|
||||
{
|
||||
#if HAVE_CHFLAGS && !(APPLE_DARWIN && HAVE_EXT2_IOCTLS)
|
||||
unsigned long bsd_flags = 0;
|
||||
|
||||
#ifdef UF_IMMUTABLE
|
||||
if (flags & EXT2_IMMUTABLE_FL)
|
||||
bsd_flags |= UF_IMMUTABLE;
|
||||
#endif
|
||||
#ifdef UF_APPEND
|
||||
if (flags & EXT2_APPEND_FL)
|
||||
bsd_flags |= UF_APPEND;
|
||||
#endif
|
||||
#ifdef UF_NODUMP
|
||||
if (flags & EXT2_NODUMP_FL)
|
||||
bsd_flags |= UF_NODUMP;
|
||||
#endif
|
||||
|
||||
return chflags (name, bsd_flags);
|
||||
#elif APPLE_DARWIN && HAVE_EXT2_IOCTLS
|
||||
int f = (int) flags;
|
||||
return syscall(SYS_fsctl, name, EXT2_IOC_SETFLAGS, &f, 0);
|
||||
#elif HAVE_EXT2_IOCTLS
|
||||
struct stat buf;
|
||||
int fd, r, f, save_errno = 0;
|
||||
|
||||
if (!stat(name, &buf) &&
|
||||
!S_ISREG(buf.st_mode) && !S_ISDIR(buf.st_mode)) {
|
||||
errno = EOPNOTSUPP;
|
||||
return -1;
|
||||
}
|
||||
fd = open(name, OPEN_FLAGS);
|
||||
if (fd == -1) {
|
||||
if (errno == ELOOP || errno == ENXIO)
|
||||
errno = EOPNOTSUPP;
|
||||
return -1;
|
||||
}
|
||||
if (!fstat(fd, &buf) &&
|
||||
!S_ISREG(buf.st_mode) && !S_ISDIR(buf.st_mode)) {
|
||||
close(fd);
|
||||
errno = EOPNOTSUPP;
|
||||
return -1;
|
||||
}
|
||||
f = (int) flags;
|
||||
r = ioctl(fd, EXT2_IOC_SETFLAGS, &f);
|
||||
if (r == -1) {
|
||||
if (errno == ENOTTY)
|
||||
errno = EOPNOTSUPP;
|
||||
save_errno = errno;
|
||||
}
|
||||
close(fd);
|
||||
if (save_errno)
|
||||
errno = save_errno;
|
||||
return r;
|
||||
#else
|
||||
errno = EOPNOTSUPP;
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
69
e2fsprogs/lib/e2p/fsetproject.c
Normal file
69
e2fsprogs/lib/e2p/fsetproject.c
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* fgetproject.c --- get project id
|
||||
*
|
||||
* Copyright (C) 1999 Theodore Ts'o <tytso@mit.edu>
|
||||
*
|
||||
* %Begin-Header%
|
||||
* This file may be redistributed under the terms of the GNU Library
|
||||
* General Public License, version 2.
|
||||
* %End-Header%
|
||||
*/
|
||||
|
||||
#ifndef _LARGEFILE_SOURCE
|
||||
#define _LARGEFILE_SOURCE
|
||||
#endif
|
||||
#ifndef _LARGEFILE64_SOURCE
|
||||
#define _LARGEFILE64_SOURCE
|
||||
#endif
|
||||
|
||||
#include "config.h"
|
||||
#if HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
#if HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#if HAVE_EXT2_IOCTLS
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include "project.h"
|
||||
#endif
|
||||
|
||||
#include "e2p.h"
|
||||
|
||||
#ifdef O_LARGEFILE
|
||||
#define OPEN_FLAGS (O_RDONLY|O_NONBLOCK|O_LARGEFILE)
|
||||
#else
|
||||
#define OPEN_FLAGS (O_RDONLY|O_NONBLOCK)
|
||||
#endif
|
||||
|
||||
int fsetproject(const char *name, unsigned long project)
|
||||
{
|
||||
#ifndef FS_IOC_FSGETXATTR
|
||||
errno = EOPNOTSUPP;
|
||||
return -1;
|
||||
#else
|
||||
int fd, r, save_errno = 0;
|
||||
struct fsxattr fsx;
|
||||
|
||||
fd = open (name, OPEN_FLAGS);
|
||||
if (fd == -1)
|
||||
return -1;
|
||||
r = ioctl (fd, FS_IOC_FSGETXATTR, &fsx);
|
||||
if (r == -1) {
|
||||
save_errno = errno;
|
||||
goto errout;
|
||||
}
|
||||
fsx.fsx_projid = project;
|
||||
r = ioctl (fd, FS_IOC_FSSETXATTR, &fsx);
|
||||
if (r == -1)
|
||||
save_errno = errno;
|
||||
errout:
|
||||
close (fd);
|
||||
if (save_errno)
|
||||
errno = save_errno;
|
||||
return r;
|
||||
#endif
|
||||
}
|
||||
71
e2fsprogs/lib/e2p/fsetversion.c
Normal file
71
e2fsprogs/lib/e2p/fsetversion.c
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* fsetversion.c - Set a file version on an ext2 file system
|
||||
*
|
||||
* Copyright (C) 1993, 1994 Remy Card <card@masi.ibp.fr>
|
||||
* Laboratoire MASI, Institut Blaise Pascal
|
||||
* Universite Pierre et Marie Curie (Paris VI)
|
||||
*
|
||||
* %Begin-Header%
|
||||
* This file may be redistributed under the terms of the GNU Library
|
||||
* General Public License, version 2.
|
||||
* %End-Header%
|
||||
*/
|
||||
|
||||
/*
|
||||
* History:
|
||||
* 93/10/30 - Creation
|
||||
*/
|
||||
|
||||
#ifndef _LARGEFILE_SOURCE
|
||||
#define _LARGEFILE_SOURCE
|
||||
#endif
|
||||
#ifndef _LARGEFILE64_SOURCE
|
||||
#define _LARGEFILE64_SOURCE
|
||||
#endif
|
||||
|
||||
#include "config.h"
|
||||
#if HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
#if HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
#if HAVE_SYS_IOCTL_H
|
||||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
|
||||
#include "e2p.h"
|
||||
|
||||
#ifdef O_LARGEFILE
|
||||
#define OPEN_FLAGS (O_RDONLY|O_NONBLOCK|O_LARGEFILE)
|
||||
#else
|
||||
#define OPEN_FLAGS (O_RDONLY|O_NONBLOCK)
|
||||
#endif
|
||||
|
||||
int fsetversion (const char * name, unsigned long version)
|
||||
{
|
||||
#if HAVE_EXT2_IOCTLS
|
||||
#if !APPLE_DARWIN
|
||||
int fd, r, ver, save_errno = 0;
|
||||
|
||||
fd = open (name, OPEN_FLAGS);
|
||||
if (fd == -1)
|
||||
return -1;
|
||||
ver = (int) version;
|
||||
r = ioctl (fd, EXT2_IOC_SETVERSION, &ver);
|
||||
if (r == -1)
|
||||
save_errno = errno;
|
||||
close (fd);
|
||||
if (save_errno)
|
||||
errno = save_errno;
|
||||
return r;
|
||||
#else
|
||||
int ver = (int)version;
|
||||
return syscall(SYS_fsctl, name, EXT2_IOC_SETVERSION, &ver, 0);
|
||||
#endif
|
||||
#else /* ! HAVE_EXT2_IOCTLS */
|
||||
errno = EOPNOTSUPP;
|
||||
return -1;
|
||||
#endif /* ! HAVE_EXT2_IOCTLS */
|
||||
}
|
||||
71
e2fsprogs/lib/e2p/getflags.c
Normal file
71
e2fsprogs/lib/e2p/getflags.c
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* getflags.c - Get a file flags on an ext2 file system
|
||||
*
|
||||
* Copyright (C) 1993, 1994 Remy Card <card@masi.ibp.fr>
|
||||
* Laboratoire MASI, Institut Blaise Pascal
|
||||
* Universite Pierre et Marie Curie (Paris VI)
|
||||
*
|
||||
* %Begin-Header%
|
||||
* This file may be redistributed under the terms of the GNU Library
|
||||
* General Public License, version 2.
|
||||
* %End-Header%
|
||||
*/
|
||||
|
||||
/*
|
||||
* History:
|
||||
* 93/10/30 - Creation
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#if HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#if HAVE_EXT2_IOCTLS
|
||||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
|
||||
#include "e2p.h"
|
||||
|
||||
int getflags (int fd, unsigned long * flags)
|
||||
{
|
||||
#if HAVE_STAT_FLAGS
|
||||
struct stat buf;
|
||||
|
||||
if (fstat (fd, &buf) == -1)
|
||||
return -1;
|
||||
|
||||
*flags = 0;
|
||||
#ifdef UF_IMMUTABLE
|
||||
if (buf.st_flags & UF_IMMUTABLE)
|
||||
*flags |= EXT2_IMMUTABLE_FL;
|
||||
#endif
|
||||
#ifdef UF_APPEND
|
||||
if (buf.st_flags & UF_APPEND)
|
||||
*flags |= EXT2_APPEND_FL;
|
||||
#endif
|
||||
#ifdef UF_NODUMP
|
||||
if (buf.st_flags & UF_NODUMP)
|
||||
*flags |= EXT2_NODUMP_FL;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
#else
|
||||
#if HAVE_EXT2_IOCTLS
|
||||
struct stat buf;
|
||||
int r, f;
|
||||
|
||||
if (!fstat(fd, &buf) &&
|
||||
!S_ISREG(buf.st_mode) && !S_ISDIR(buf.st_mode))
|
||||
goto notsupp;
|
||||
r = ioctl(fd, EXT2_IOC_GETFLAGS, &f);
|
||||
*flags = f;
|
||||
|
||||
return r;
|
||||
notsupp:
|
||||
#endif /* HAVE_EXT2_IOCTLS */
|
||||
#endif
|
||||
errno = EOPNOTSUPP;
|
||||
return -1;
|
||||
}
|
||||
41
e2fsprogs/lib/e2p/getversion.c
Normal file
41
e2fsprogs/lib/e2p/getversion.c
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* getversion.c - Get a file version on an ext2 file system
|
||||
*
|
||||
* Copyright (C) 1993, 1994 Remy Card <card@masi.ibp.fr>
|
||||
* Laboratoire MASI, Institut Blaise Pascal
|
||||
* Universite Pierre et Marie Curie (Paris VI)
|
||||
*
|
||||
* %Begin-Header%
|
||||
* This file may be redistributed under the terms of the GNU Library
|
||||
* General Public License, version 2.
|
||||
* %End-Header%
|
||||
*/
|
||||
|
||||
/*
|
||||
* History:
|
||||
* 93/10/30 - Creation
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#if HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
#if HAVE_SYS_IOCTL_H
|
||||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
|
||||
#include "e2p.h"
|
||||
|
||||
int getversion (int fd, unsigned long * version)
|
||||
{
|
||||
#if HAVE_EXT2_IOCTLS
|
||||
int r, ver;
|
||||
|
||||
r = ioctl (fd, EXT2_IOC_GETVERSION, &ver);
|
||||
*version = ver;
|
||||
return r;
|
||||
#else /* ! HAVE_EXT2_IOCTLS */
|
||||
errno = EOPNOTSUPP;
|
||||
return -1;
|
||||
#endif /* ! HAVE_EXT2_IOCTLS */
|
||||
}
|
||||
72
e2fsprogs/lib/e2p/hashstr.c
Normal file
72
e2fsprogs/lib/e2p/hashstr.c
Normal file
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* feature.c --- convert between features and strings
|
||||
*
|
||||
* Copyright (C) 1999 Theodore Ts'o <tytso@mit.edu>
|
||||
*
|
||||
* %Begin-Header%
|
||||
* This file may be redistributed under the terms of the GNU Library
|
||||
* General Public License, version 2.
|
||||
* %End-Header%
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "e2p.h"
|
||||
|
||||
struct hash {
|
||||
int num;
|
||||
const char *string;
|
||||
};
|
||||
|
||||
static struct hash hash_list[] = {
|
||||
{ EXT2_HASH_LEGACY, "legacy" },
|
||||
{ EXT2_HASH_HALF_MD4, "half_md4" },
|
||||
{ EXT2_HASH_TEA, "tea" },
|
||||
{ 0, 0 },
|
||||
};
|
||||
|
||||
const char *e2p_hash2string(int num)
|
||||
{
|
||||
struct hash *p;
|
||||
static char buf[20];
|
||||
|
||||
for (p = hash_list; p->string; p++) {
|
||||
if (num == p->num)
|
||||
return p->string;
|
||||
}
|
||||
sprintf(buf, "HASHALG_%d", num);
|
||||
return buf;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the hash algorithm, or -1 on error
|
||||
*/
|
||||
int e2p_string2hash(char *string)
|
||||
{
|
||||
struct hash *p;
|
||||
char *eptr;
|
||||
int num;
|
||||
|
||||
for (p = hash_list; p->string; p++) {
|
||||
if (!strcasecmp(string, p->string)) {
|
||||
return p->num;
|
||||
}
|
||||
}
|
||||
if (strncasecmp(string, "HASHALG_", 8))
|
||||
return -1;
|
||||
|
||||
if (string[8] == 0)
|
||||
return -1;
|
||||
num = strtol(string+8, &eptr, 10);
|
||||
if (num > 255 || num < 0)
|
||||
return -1;
|
||||
if (*eptr)
|
||||
return -1;
|
||||
return num;
|
||||
}
|
||||
|
||||
76
e2fsprogs/lib/e2p/iod.c
Normal file
76
e2fsprogs/lib/e2p/iod.c
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* iod.c - Iterate a function on each entry of a directory
|
||||
*
|
||||
* Copyright (C) 1993, 1994 Remy Card <card@masi.ibp.fr>
|
||||
* Laboratoire MASI, Institut Blaise Pascal
|
||||
* Universite Pierre et Marie Curie (Paris VI)
|
||||
*
|
||||
* %Begin-Header%
|
||||
* This file may be redistributed under the terms of the GNU Library
|
||||
* General Public License, version 2.
|
||||
* %End-Header%
|
||||
*/
|
||||
|
||||
/*
|
||||
* History:
|
||||
* 93/10/30 - Creation
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "e2p.h"
|
||||
#if HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
int iterate_on_dir (const char * dir_name,
|
||||
int (*func) (const char *, struct dirent *, void *),
|
||||
void * private)
|
||||
{
|
||||
DIR * dir;
|
||||
struct dirent *de, *dep;
|
||||
int max_len = -1, len, ret = 0;
|
||||
|
||||
#if HAVE_PATHCONF && defined(_PC_NAME_MAX)
|
||||
max_len = pathconf(dir_name, _PC_NAME_MAX);
|
||||
#endif
|
||||
if (max_len == -1) {
|
||||
#ifdef _POSIX_NAME_MAX
|
||||
max_len = _POSIX_NAME_MAX;
|
||||
#else
|
||||
#ifdef NAME_MAX
|
||||
max_len = NAME_MAX;
|
||||
#else
|
||||
max_len = 256;
|
||||
#endif /* NAME_MAX */
|
||||
#endif /* _POSIX_NAME_MAX */
|
||||
}
|
||||
max_len += sizeof(struct dirent);
|
||||
|
||||
de = malloc(max_len+1);
|
||||
if (!de)
|
||||
return -1;
|
||||
memset(de, 0, max_len+1);
|
||||
|
||||
dir = opendir (dir_name);
|
||||
if (dir == NULL) {
|
||||
free(de);
|
||||
return -1;
|
||||
}
|
||||
while ((dep = readdir (dir))) {
|
||||
#ifdef HAVE_RECLEN_DIRENT
|
||||
len = dep->d_reclen;
|
||||
if (len > max_len)
|
||||
len = max_len;
|
||||
#else
|
||||
len = sizeof(struct dirent);
|
||||
#endif
|
||||
memcpy(de, dep, len);
|
||||
if ((*func)(dir_name, de, private))
|
||||
ret++;
|
||||
}
|
||||
free(de);
|
||||
closedir(dir);
|
||||
return ret;
|
||||
}
|
||||
134
e2fsprogs/lib/e2p/ljs.c
Normal file
134
e2fsprogs/lib/e2p/ljs.c
Normal file
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* ljs.c - List the contents of an journal superblock
|
||||
*
|
||||
* Copyright (C) 1995, 1996, 1997 Theodore Ts'o <tytso@mit.edu>
|
||||
*
|
||||
* %Begin-Header%
|
||||
* This file may be redistributed under the terms of the GNU Library
|
||||
* General Public License, version 2.
|
||||
* %End-Header%
|
||||
*/
|
||||
|
||||
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <string.h>
|
||||
#include <grp.h>
|
||||
#include <pwd.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "ext2fs/ext2_fs.h"
|
||||
#include "ext2fs/ext2fs.h"
|
||||
#include "e2p.h"
|
||||
#include "ext2fs/kernel-jbd.h"
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
#define e2p_be32(x) (x)
|
||||
#else
|
||||
static __u32 e2p_swab32(__u32 val)
|
||||
{
|
||||
return ((val>>24) | ((val>>8)&0xFF00) |
|
||||
((val<<8)&0xFF0000) | (val<<24));
|
||||
}
|
||||
|
||||
#define e2p_be32(x) e2p_swab32(x)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This function is copied from kernel-jbd.h's function
|
||||
* jbd2_journal_get_num_fc_blks() to avoid inter-library dependencies.
|
||||
*/
|
||||
static inline int get_num_fc_blks(journal_superblock_t *jsb)
|
||||
{
|
||||
int num_fc_blocks = e2p_be32(jsb->s_num_fc_blks);
|
||||
|
||||
return num_fc_blocks ? num_fc_blocks : JBD2_DEFAULT_FAST_COMMIT_BLOCKS;
|
||||
}
|
||||
|
||||
static const char *journal_checksum_type_str(__u8 type)
|
||||
{
|
||||
switch (type) {
|
||||
case JBD2_CRC32C_CHKSUM:
|
||||
return "crc32c";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
void e2p_list_journal_super(FILE *f, char *journal_sb_buf,
|
||||
int exp_block_size, int flags)
|
||||
{
|
||||
journal_superblock_t *jsb = (journal_superblock_t *) journal_sb_buf;
|
||||
__u32 *mask_ptr, mask, m;
|
||||
unsigned int size;
|
||||
int j, printed = 0;
|
||||
unsigned int i, nr_users;
|
||||
int num_fc_blks = 0;
|
||||
int journal_blks = 0;
|
||||
|
||||
if (flags & E2P_LIST_JOURNAL_FLAG_FC)
|
||||
num_fc_blks = get_num_fc_blks((journal_superblock_t *)journal_sb_buf);
|
||||
journal_blks = ntohl(jsb->s_maxlen) - num_fc_blks;
|
||||
fprintf(f, "%s", "Journal features: ");
|
||||
for (i=0, mask_ptr=&jsb->s_feature_compat; i <3; i++,mask_ptr++) {
|
||||
mask = e2p_be32(*mask_ptr);
|
||||
for (j=0,m=1; j < 32; j++, m<<=1) {
|
||||
if (mask & m) {
|
||||
fprintf(f, " %s", e2p_jrnl_feature2string(i, m));
|
||||
printed++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (printed == 0)
|
||||
fprintf(f, " (none)");
|
||||
fputc('\n', f);
|
||||
fputs("Total journal size: ", f);
|
||||
size = (ntohl(jsb->s_blocksize) / 1024) * ntohl(jsb->s_maxlen);
|
||||
if (size < 8192)
|
||||
fprintf(f, "%uk\n", size);
|
||||
else
|
||||
fprintf(f, "%uM\n", size >> 10);
|
||||
nr_users = (unsigned int) ntohl(jsb->s_nr_users);
|
||||
if (exp_block_size != (int) ntohl(jsb->s_blocksize))
|
||||
fprintf(f, "Journal block size: %u\n",
|
||||
(unsigned int)ntohl(jsb->s_blocksize));
|
||||
fprintf(f, "Total journal blocks: %u\n",
|
||||
(unsigned int)(journal_blks + num_fc_blks));
|
||||
fprintf(f, "Max transaction length: %u\n",
|
||||
(unsigned int)journal_blks);
|
||||
fprintf(f, "Fast commit length: %u\n",
|
||||
(unsigned int)num_fc_blks);
|
||||
|
||||
if (ntohl(jsb->s_first) != 1)
|
||||
fprintf(f, "Journal first block: %u\n",
|
||||
(unsigned int)ntohl(jsb->s_first));
|
||||
fprintf(f, "Journal sequence: 0x%08x\n"
|
||||
"Journal start: %u\n",
|
||||
(unsigned int)ntohl(jsb->s_sequence),
|
||||
(unsigned int)ntohl(jsb->s_start));
|
||||
if (nr_users != 1)
|
||||
fprintf(f, "Journal number of users: %u\n", nr_users);
|
||||
if (jsb->s_feature_compat & e2p_be32(JBD2_FEATURE_COMPAT_CHECKSUM))
|
||||
fprintf(f, "%s", "Journal checksum type: crc32\n");
|
||||
if ((jsb->s_feature_incompat &
|
||||
e2p_be32(JBD2_FEATURE_INCOMPAT_CSUM_V3)) ||
|
||||
(jsb->s_feature_incompat &
|
||||
e2p_be32(JBD2_FEATURE_INCOMPAT_CSUM_V2)))
|
||||
fprintf(f, "Journal checksum type: %s\n"
|
||||
"Journal checksum: 0x%08x\n",
|
||||
journal_checksum_type_str(jsb->s_checksum_type),
|
||||
e2p_be32(jsb->s_checksum));
|
||||
if ((nr_users > 1) ||
|
||||
!e2p_is_null_uuid(&jsb->s_users[0])) {
|
||||
for (i=0; i < nr_users && i < JBD2_USERS_MAX; i++) {
|
||||
printf(i ? " %s\n"
|
||||
: "Journal users: %s\n",
|
||||
e2p_uuid2str(&jsb->s_users[i * UUID_SIZE]));
|
||||
}
|
||||
}
|
||||
if (jsb->s_errno != 0)
|
||||
fprintf(f, "Journal errno: %d\n",
|
||||
(int) ntohl(jsb->s_errno));
|
||||
}
|
||||
491
e2fsprogs/lib/e2p/ls.c
Normal file
491
e2fsprogs/lib/e2p/ls.c
Normal file
@@ -0,0 +1,491 @@
|
||||
/*
|
||||
* ls.c - List the contents of an ext2fs superblock
|
||||
*
|
||||
* Copyright (C) 1992, 1993, 1994 Remy Card <card@masi.ibp.fr>
|
||||
* Laboratoire MASI, Institut Blaise Pascal
|
||||
* Universite Pierre et Marie Curie (Paris VI)
|
||||
*
|
||||
* Copyright (C) 1995, 1996, 1997 Theodore Ts'o <tytso@mit.edu>
|
||||
*
|
||||
* %Begin-Header%
|
||||
* This file may be redistributed under the terms of the GNU Library
|
||||
* General Public License, version 2.
|
||||
* %End-Header%
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <string.h>
|
||||
#include <grp.h>
|
||||
#include <pwd.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "e2p.h"
|
||||
#include "support/quotaio.h"
|
||||
|
||||
static void print_user (unsigned short uid, FILE *f)
|
||||
{
|
||||
struct passwd *pw;
|
||||
|
||||
fprintf(f, "%u ", uid);
|
||||
pw = getpwuid (uid);
|
||||
if (pw == NULL)
|
||||
fprintf(f, "(user unknown)\n");
|
||||
else
|
||||
fprintf(f, "(user %s)\n", pw->pw_name);
|
||||
}
|
||||
|
||||
static void print_group (unsigned short gid, FILE *f)
|
||||
{
|
||||
struct group *gr;
|
||||
|
||||
fprintf(f, "%u ", gid);
|
||||
gr = getgrgid (gid);
|
||||
if (gr == NULL)
|
||||
fprintf(f, "(group unknown)\n");
|
||||
else
|
||||
fprintf(f, "(group %s)\n", gr->gr_name);
|
||||
}
|
||||
|
||||
#define MONTH_INT (86400 * 30)
|
||||
#define WEEK_INT (86400 * 7)
|
||||
#define DAY_INT (86400)
|
||||
#define HOUR_INT (60 * 60)
|
||||
#define MINUTE_INT (60)
|
||||
|
||||
static const char *interval_string(unsigned int secs)
|
||||
{
|
||||
static char buf[256], tmp[80];
|
||||
int hr, min, num;
|
||||
|
||||
buf[0] = 0;
|
||||
|
||||
if (secs == 0)
|
||||
return "<none>";
|
||||
|
||||
if (secs >= MONTH_INT) {
|
||||
num = secs / MONTH_INT;
|
||||
secs -= num*MONTH_INT;
|
||||
sprintf(buf, "%d month%s", num, (num>1) ? "s" : "");
|
||||
}
|
||||
if (secs >= WEEK_INT) {
|
||||
num = secs / WEEK_INT;
|
||||
secs -= num*WEEK_INT;
|
||||
sprintf(tmp, "%s%d week%s", buf[0] ? ", " : "",
|
||||
num, (num>1) ? "s" : "");
|
||||
strcat(buf, tmp);
|
||||
}
|
||||
if (secs >= DAY_INT) {
|
||||
num = secs / DAY_INT;
|
||||
secs -= num*DAY_INT;
|
||||
sprintf(tmp, "%s%d day%s", buf[0] ? ", " : "",
|
||||
num, (num>1) ? "s" : "");
|
||||
strcat(buf, tmp);
|
||||
}
|
||||
if (secs > 0) {
|
||||
hr = secs / HOUR_INT;
|
||||
secs -= hr*HOUR_INT;
|
||||
min = secs / MINUTE_INT;
|
||||
secs -= min*MINUTE_INT;
|
||||
sprintf(tmp, "%s%d:%02d:%02d", buf[0] ? ", " : "",
|
||||
hr, min, secs);
|
||||
strcat(buf, tmp);
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
static void print_features(struct ext2_super_block * s, FILE *f)
|
||||
{
|
||||
#ifdef EXT2_DYNAMIC_REV
|
||||
int i, j, printed=0;
|
||||
__u32 *mask = &s->s_feature_compat, m;
|
||||
|
||||
fprintf(f, "Filesystem features: ");
|
||||
for (i=0; i <3; i++,mask++) {
|
||||
for (j=0,m=1; j < 32; j++, m<<=1) {
|
||||
if (*mask & m) {
|
||||
fprintf(f, " %s", e2p_feature2string(i, m));
|
||||
printed++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (printed == 0)
|
||||
fprintf(f, " (none)");
|
||||
fprintf(f, "\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
static void print_mntopts(struct ext2_super_block * s, FILE *f)
|
||||
{
|
||||
#ifdef EXT2_DYNAMIC_REV
|
||||
int i, printed=0;
|
||||
__u32 mask = s->s_default_mount_opts, m;
|
||||
|
||||
fprintf(f, "Default mount options: ");
|
||||
if (mask & EXT3_DEFM_JMODE) {
|
||||
fprintf(f, " %s", e2p_mntopt2string(mask & EXT3_DEFM_JMODE));
|
||||
printed++;
|
||||
}
|
||||
for (i=0,m=1; i < 32; i++, m<<=1) {
|
||||
if (m & EXT3_DEFM_JMODE)
|
||||
continue;
|
||||
if (mask & m) {
|
||||
fprintf(f, " %s", e2p_mntopt2string(m));
|
||||
printed++;
|
||||
}
|
||||
}
|
||||
if (printed == 0)
|
||||
fprintf(f, " (none)");
|
||||
fprintf(f, "\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
static void print_super_flags(struct ext2_super_block * s, FILE *f)
|
||||
{
|
||||
int flags_found = 0;
|
||||
|
||||
if (s->s_flags == 0)
|
||||
return;
|
||||
|
||||
fputs("Filesystem flags: ", f);
|
||||
if (s->s_flags & EXT2_FLAGS_SIGNED_HASH) {
|
||||
fputs("signed_directory_hash ", f);
|
||||
flags_found++;
|
||||
}
|
||||
if (s->s_flags & EXT2_FLAGS_UNSIGNED_HASH) {
|
||||
fputs("unsigned_directory_hash ", f);
|
||||
flags_found++;
|
||||
}
|
||||
if (s->s_flags & EXT2_FLAGS_TEST_FILESYS) {
|
||||
fputs("test_filesystem ", f);
|
||||
flags_found++;
|
||||
}
|
||||
if (flags_found)
|
||||
fputs("\n", f);
|
||||
else
|
||||
fputs("(none)\n", f);
|
||||
}
|
||||
|
||||
static __u64 e2p_blocks_count(struct ext2_super_block *super)
|
||||
{
|
||||
return super->s_blocks_count |
|
||||
(ext2fs_has_feature_64bit(super) ?
|
||||
(__u64) super->s_blocks_count_hi << 32 : 0);
|
||||
}
|
||||
|
||||
static __u64 e2p_r_blocks_count(struct ext2_super_block *super)
|
||||
{
|
||||
return super->s_r_blocks_count |
|
||||
(ext2fs_has_feature_64bit(super) ?
|
||||
(__u64) super->s_r_blocks_count_hi << 32 : 0);
|
||||
}
|
||||
|
||||
static __u64 e2p_free_blocks_count(struct ext2_super_block *super)
|
||||
{
|
||||
return super->s_free_blocks_count |
|
||||
(ext2fs_has_feature_64bit(super) ?
|
||||
(__u64) super->s_free_blocks_hi << 32 : 0);
|
||||
}
|
||||
|
||||
#ifndef EXT2_INODE_SIZE
|
||||
#define EXT2_INODE_SIZE(s) sizeof(struct ext2_inode)
|
||||
#endif
|
||||
|
||||
#ifndef EXT2_GOOD_OLD_REV
|
||||
#define EXT2_GOOD_OLD_REV 0
|
||||
#endif
|
||||
|
||||
static const char *checksum_type(__u8 type)
|
||||
{
|
||||
switch (type) {
|
||||
case EXT2_CRC32C_CHKSUM:
|
||||
return "crc32c";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
static const char *quota_prefix[MAXQUOTAS] = {
|
||||
[USRQUOTA] = "User quota inode:",
|
||||
[GRPQUOTA] = "Group quota inode:",
|
||||
[PRJQUOTA] = "Project quota inode:",
|
||||
};
|
||||
|
||||
/**
|
||||
* Convert type of quota to written representation
|
||||
*/
|
||||
static const char *quota_type2prefix(enum quota_type qtype)
|
||||
{
|
||||
return quota_prefix[qtype];
|
||||
}
|
||||
|
||||
void list_super2(struct ext2_super_block * sb, FILE *f)
|
||||
{
|
||||
int inode_blocks_per_group;
|
||||
char *str;
|
||||
time_t tm;
|
||||
enum quota_type qtype;
|
||||
|
||||
inode_blocks_per_group = (((sb->s_inodes_per_group *
|
||||
EXT2_INODE_SIZE(sb)) +
|
||||
EXT2_BLOCK_SIZE(sb) - 1) /
|
||||
EXT2_BLOCK_SIZE(sb));
|
||||
if (sb->s_volume_name[0])
|
||||
fprintf(f, "Filesystem volume name: %.*s\n",
|
||||
EXT2_LEN_STR(sb->s_volume_name));
|
||||
else
|
||||
fprintf(f, "Filesystem volume name: <none>\n");
|
||||
if (sb->s_last_mounted[0])
|
||||
fprintf(f, "Last mounted on: %.*s\n",
|
||||
EXT2_LEN_STR(sb->s_last_mounted));
|
||||
else
|
||||
fprintf(f, "Last mounted on: <not available>\n");
|
||||
fprintf(f, "Filesystem UUID: %s\n", e2p_uuid2str(sb->s_uuid));
|
||||
fprintf(f, "Filesystem magic number: 0x%04X\n", sb->s_magic);
|
||||
fprintf(f, "Filesystem revision #: %d", sb->s_rev_level);
|
||||
if (sb->s_rev_level == EXT2_GOOD_OLD_REV) {
|
||||
fprintf(f, " (original)\n");
|
||||
#ifdef EXT2_DYNAMIC_REV
|
||||
} else if (sb->s_rev_level == EXT2_DYNAMIC_REV) {
|
||||
fprintf(f, " (dynamic)\n");
|
||||
#endif
|
||||
} else
|
||||
fprintf(f, " (unknown)\n");
|
||||
print_features(sb, f);
|
||||
print_super_flags(sb, f);
|
||||
print_mntopts(sb, f);
|
||||
if (sb->s_mount_opts[0])
|
||||
fprintf(f, "Mount options: %.*s\n",
|
||||
EXT2_LEN_STR(sb->s_mount_opts));
|
||||
fprintf(f, "Filesystem state: ");
|
||||
print_fs_state (f, sb->s_state);
|
||||
fprintf(f, "\n");
|
||||
fprintf(f, "Errors behavior: ");
|
||||
print_fs_errors(f, sb->s_errors);
|
||||
fprintf(f, "\n");
|
||||
str = e2p_os2string(sb->s_creator_os);
|
||||
fprintf(f, "Filesystem OS type: %s\n", str);
|
||||
free(str);
|
||||
fprintf(f, "Inode count: %u\n", sb->s_inodes_count);
|
||||
fprintf(f, "Block count: %llu\n",
|
||||
(unsigned long long) e2p_blocks_count(sb));
|
||||
fprintf(f, "Reserved block count: %llu\n",
|
||||
(unsigned long long) e2p_r_blocks_count(sb));
|
||||
if (sb->s_overhead_clusters)
|
||||
fprintf(f, "Overhead clusters: %u\n",
|
||||
sb->s_overhead_clusters);
|
||||
fprintf(f, "Free blocks: %llu\n",
|
||||
(unsigned long long) e2p_free_blocks_count(sb));
|
||||
fprintf(f, "Free inodes: %u\n", sb->s_free_inodes_count);
|
||||
fprintf(f, "First block: %u\n", sb->s_first_data_block);
|
||||
fprintf(f, "Block size: %u\n", EXT2_BLOCK_SIZE(sb));
|
||||
if (ext2fs_has_feature_bigalloc(sb))
|
||||
fprintf(f, "Cluster size: %u\n",
|
||||
EXT2_CLUSTER_SIZE(sb));
|
||||
else
|
||||
fprintf(f, "Fragment size: %u\n",
|
||||
EXT2_CLUSTER_SIZE(sb));
|
||||
if (ext2fs_has_feature_64bit(sb))
|
||||
fprintf(f, "Group descriptor size: %u\n", sb->s_desc_size);
|
||||
if (sb->s_reserved_gdt_blocks)
|
||||
fprintf(f, "Reserved GDT blocks: %u\n",
|
||||
sb->s_reserved_gdt_blocks);
|
||||
fprintf(f, "Blocks per group: %u\n", sb->s_blocks_per_group);
|
||||
if (ext2fs_has_feature_bigalloc(sb))
|
||||
fprintf(f, "Clusters per group: %u\n",
|
||||
sb->s_clusters_per_group);
|
||||
else
|
||||
fprintf(f, "Fragments per group: %u\n",
|
||||
sb->s_clusters_per_group);
|
||||
fprintf(f, "Inodes per group: %u\n", sb->s_inodes_per_group);
|
||||
fprintf(f, "Inode blocks per group: %u\n", inode_blocks_per_group);
|
||||
if (sb->s_raid_stride)
|
||||
fprintf(f, "RAID stride: %u\n",
|
||||
sb->s_raid_stride);
|
||||
if (sb->s_raid_stripe_width)
|
||||
fprintf(f, "RAID stripe width: %u\n",
|
||||
sb->s_raid_stripe_width);
|
||||
if (sb->s_first_meta_bg)
|
||||
fprintf(f, "First meta block group: %u\n",
|
||||
sb->s_first_meta_bg);
|
||||
if (sb->s_log_groups_per_flex)
|
||||
fprintf(f, "Flex block group size: %u\n",
|
||||
1U << sb->s_log_groups_per_flex);
|
||||
if (sb->s_mkfs_time) {
|
||||
tm = sb->s_mkfs_time;
|
||||
fprintf(f, "Filesystem created: %s", ctime(&tm));
|
||||
}
|
||||
tm = sb->s_mtime;
|
||||
fprintf(f, "Last mount time: %s",
|
||||
sb->s_mtime ? ctime(&tm) : "n/a\n");
|
||||
tm = sb->s_wtime;
|
||||
fprintf(f, "Last write time: %s", ctime(&tm));
|
||||
fprintf(f, "Mount count: %u\n", sb->s_mnt_count);
|
||||
fprintf(f, "Maximum mount count: %d\n", sb->s_max_mnt_count);
|
||||
tm = sb->s_lastcheck;
|
||||
fprintf(f, "Last checked: %s", ctime(&tm));
|
||||
fprintf(f, "Check interval: %u (%s)\n", sb->s_checkinterval,
|
||||
interval_string(sb->s_checkinterval));
|
||||
if (sb->s_checkinterval)
|
||||
{
|
||||
time_t next;
|
||||
|
||||
next = sb->s_lastcheck + sb->s_checkinterval;
|
||||
fprintf(f, "Next check after: %s", ctime(&next));
|
||||
}
|
||||
#define POW2(x) ((__u64) 1 << (x))
|
||||
if (sb->s_kbytes_written) {
|
||||
fprintf(f, "Lifetime writes: ");
|
||||
if (sb->s_kbytes_written < POW2(13))
|
||||
fprintf(f, "%llu kB\n",
|
||||
(unsigned long long) sb->s_kbytes_written);
|
||||
else if (sb->s_kbytes_written < POW2(23))
|
||||
fprintf(f, "%llu MB\n", (unsigned long long)
|
||||
(sb->s_kbytes_written + POW2(9)) >> 10);
|
||||
else if (sb->s_kbytes_written < POW2(33))
|
||||
fprintf(f, "%llu GB\n", (unsigned long long)
|
||||
(sb->s_kbytes_written + POW2(19)) >> 20);
|
||||
else if (sb->s_kbytes_written < POW2(43))
|
||||
fprintf(f, "%llu TB\n", (unsigned long long)
|
||||
(sb->s_kbytes_written + POW2(29)) >> 30);
|
||||
else
|
||||
fprintf(f, "%llu PB\n", (unsigned long long)
|
||||
(sb->s_kbytes_written + POW2(39)) >> 40);
|
||||
}
|
||||
fprintf(f, "Reserved blocks uid: ");
|
||||
print_user(sb->s_def_resuid, f);
|
||||
fprintf(f, "Reserved blocks gid: ");
|
||||
print_group(sb->s_def_resgid, f);
|
||||
if (sb->s_rev_level >= EXT2_DYNAMIC_REV) {
|
||||
fprintf(f, "First inode: %d\n", sb->s_first_ino);
|
||||
fprintf(f, "Inode size: %d\n", sb->s_inode_size);
|
||||
if (sb->s_min_extra_isize)
|
||||
fprintf(f, "Required extra isize: %d\n",
|
||||
sb->s_min_extra_isize);
|
||||
if (sb->s_want_extra_isize)
|
||||
fprintf(f, "Desired extra isize: %d\n",
|
||||
sb->s_want_extra_isize);
|
||||
}
|
||||
if (!e2p_is_null_uuid(sb->s_journal_uuid))
|
||||
fprintf(f, "Journal UUID: %s\n",
|
||||
e2p_uuid2str(sb->s_journal_uuid));
|
||||
if (sb->s_journal_inum)
|
||||
fprintf(f, "Journal inode: %u\n",
|
||||
sb->s_journal_inum);
|
||||
if (sb->s_journal_dev)
|
||||
fprintf(f, "Journal device: 0x%04x\n",
|
||||
sb->s_journal_dev);
|
||||
if (sb->s_last_orphan)
|
||||
fprintf(f, "First orphan inode: %u\n",
|
||||
sb->s_last_orphan);
|
||||
if (ext2fs_has_feature_dir_index(sb) ||
|
||||
sb->s_def_hash_version)
|
||||
fprintf(f, "Default directory hash: %s\n",
|
||||
e2p_hash2string(sb->s_def_hash_version));
|
||||
if (!e2p_is_null_uuid(sb->s_hash_seed))
|
||||
fprintf(f, "Directory Hash Seed: %s\n",
|
||||
e2p_uuid2str(sb->s_hash_seed));
|
||||
if (sb->s_jnl_backup_type) {
|
||||
fprintf(f, "Journal backup: ");
|
||||
switch (sb->s_jnl_backup_type) {
|
||||
case 1:
|
||||
fprintf(f, "inode blocks\n");
|
||||
break;
|
||||
default:
|
||||
fprintf(f, "type %u\n", sb->s_jnl_backup_type);
|
||||
}
|
||||
}
|
||||
if (sb->s_backup_bgs[0] || sb->s_backup_bgs[1]) {
|
||||
fprintf(f, "Backup block groups: ");
|
||||
if (sb->s_backup_bgs[0])
|
||||
fprintf(f, "%u ", sb->s_backup_bgs[0]);
|
||||
if (sb->s_backup_bgs[1])
|
||||
fprintf(f, "%u ", sb->s_backup_bgs[1]);
|
||||
fputc('\n', f);
|
||||
}
|
||||
if (sb->s_snapshot_inum) {
|
||||
fprintf(f, "Snapshot inode: %u\n",
|
||||
sb->s_snapshot_inum);
|
||||
fprintf(f, "Snapshot ID: %u\n",
|
||||
sb->s_snapshot_id);
|
||||
fprintf(f, "Snapshot reserved blocks: %llu\n",
|
||||
(unsigned long long) sb->s_snapshot_r_blocks_count);
|
||||
}
|
||||
if (sb->s_snapshot_list)
|
||||
fprintf(f, "Snapshot list head: %u\n",
|
||||
sb->s_snapshot_list);
|
||||
if (sb->s_error_count)
|
||||
fprintf(f, "FS Error count: %u\n",
|
||||
sb->s_error_count);
|
||||
if (sb->s_first_error_time) {
|
||||
tm = sb->s_first_error_time;
|
||||
fprintf(f, "First error time: %s", ctime(&tm));
|
||||
fprintf(f, "First error function: %.*s\n",
|
||||
EXT2_LEN_STR(sb->s_first_error_func));
|
||||
fprintf(f, "First error line #: %u\n",
|
||||
sb->s_first_error_line);
|
||||
if (sb->s_first_error_ino)
|
||||
fprintf(f, "First error inode #: %u\n",
|
||||
sb->s_first_error_ino);
|
||||
if (sb->s_first_error_block)
|
||||
fprintf(f, "First error block #: %llu\n",
|
||||
(unsigned long long) sb->s_first_error_block);
|
||||
if (sb->s_first_error_errcode)
|
||||
fprintf(f, "First error err: %s\n",
|
||||
e2p_errcode2str(sb->s_first_error_errcode));
|
||||
}
|
||||
if (sb->s_last_error_time) {
|
||||
tm = sb->s_last_error_time;
|
||||
fprintf(f, "Last error time: %s", ctime(&tm));
|
||||
fprintf(f, "Last error function: %.*s\n",
|
||||
EXT2_LEN_STR(sb->s_last_error_func));
|
||||
fprintf(f, "Last error line #: %u\n",
|
||||
sb->s_last_error_line);
|
||||
if (sb->s_last_error_ino)
|
||||
fprintf(f, "Last error inode #: %u\n",
|
||||
sb->s_last_error_ino);
|
||||
if (sb->s_last_error_block)
|
||||
fprintf(f, "Last error block #: %llu\n",
|
||||
(unsigned long long) sb->s_last_error_block);
|
||||
if (sb->s_last_error_errcode)
|
||||
fprintf(f, "Last error err: %s\n",
|
||||
e2p_errcode2str(sb->s_last_error_errcode));
|
||||
}
|
||||
if (ext2fs_has_feature_mmp(sb)) {
|
||||
fprintf(f, "MMP block number: %llu\n",
|
||||
(unsigned long long) sb->s_mmp_block);
|
||||
fprintf(f, "MMP update interval: %u\n",
|
||||
sb->s_mmp_update_interval);
|
||||
}
|
||||
for (qtype = 0; qtype < MAXQUOTAS; qtype++) {
|
||||
if (*quota_sb_inump(sb, qtype) != 0)
|
||||
fprintf(f, "%-26s%u\n",
|
||||
quota_type2prefix(qtype),
|
||||
*quota_sb_inump(sb, qtype));
|
||||
}
|
||||
|
||||
if (ext2fs_has_feature_metadata_csum(sb)) {
|
||||
fprintf(f, "Checksum type: %s\n",
|
||||
checksum_type(sb->s_checksum_type));
|
||||
fprintf(f, "Checksum: 0x%08x\n",
|
||||
sb->s_checksum);
|
||||
}
|
||||
if (!e2p_is_null_uuid(sb->s_encrypt_pw_salt))
|
||||
fprintf(f, "Encryption PW Salt: %s\n",
|
||||
e2p_uuid2str(sb->s_encrypt_pw_salt));
|
||||
|
||||
if (ext2fs_has_feature_csum_seed(sb))
|
||||
fprintf(f, "Checksum seed: 0x%08x\n",
|
||||
sb->s_checksum_seed);
|
||||
if (ext2fs_has_feature_casefold(sb))
|
||||
fprintf(f, "Character encoding: %s\n",
|
||||
e2p_encoding2str(sb->s_encoding));
|
||||
}
|
||||
|
||||
void list_super (struct ext2_super_block * s)
|
||||
{
|
||||
list_super2(s, stdout);
|
||||
}
|
||||
|
||||
150
e2fsprogs/lib/e2p/mntopts.c
Normal file
150
e2fsprogs/lib/e2p/mntopts.c
Normal file
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
* mountopts.c --- convert between default mount options and strings
|
||||
*
|
||||
* Copyright (C) 2002 Theodore Ts'o <tytso@mit.edu>
|
||||
*
|
||||
* %Begin-Header%
|
||||
* This file may be redistributed under the terms of the GNU Library
|
||||
* General Public License, version 2.
|
||||
* %End-Header%
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "e2p.h"
|
||||
|
||||
struct mntopt {
|
||||
unsigned int mask;
|
||||
const char *string;
|
||||
};
|
||||
|
||||
static struct mntopt mntopt_list[] = {
|
||||
{ EXT2_DEFM_DEBUG, "debug" },
|
||||
{ EXT2_DEFM_BSDGROUPS, "bsdgroups" },
|
||||
{ EXT2_DEFM_XATTR_USER, "user_xattr" },
|
||||
{ EXT2_DEFM_ACL, "acl" },
|
||||
{ EXT2_DEFM_UID16, "uid16" },
|
||||
{ EXT3_DEFM_JMODE_DATA, "journal_data" },
|
||||
{ EXT3_DEFM_JMODE_ORDERED, "journal_data_ordered" },
|
||||
{ EXT3_DEFM_JMODE_WBACK, "journal_data_writeback" },
|
||||
{ EXT4_DEFM_NOBARRIER, "nobarrier" },
|
||||
{ EXT4_DEFM_BLOCK_VALIDITY, "block_validity" },
|
||||
{ EXT4_DEFM_DISCARD, "discard"},
|
||||
{ EXT4_DEFM_NODELALLOC, "nodelalloc"},
|
||||
{ 0, 0 },
|
||||
};
|
||||
|
||||
const char *e2p_mntopt2string(unsigned int mask)
|
||||
{
|
||||
struct mntopt *f;
|
||||
static char buf[20];
|
||||
int fnum;
|
||||
|
||||
for (f = mntopt_list; f->string; f++) {
|
||||
if (mask == f->mask)
|
||||
return f->string;
|
||||
}
|
||||
for (fnum = 0; mask >>= 1; fnum++);
|
||||
sprintf(buf, "MNTOPT_%d", fnum);
|
||||
return buf;
|
||||
}
|
||||
|
||||
int e2p_string2mntopt(char *string, unsigned int *mask)
|
||||
{
|
||||
struct mntopt *f;
|
||||
char *eptr;
|
||||
int num;
|
||||
|
||||
for (f = mntopt_list; f->string; f++) {
|
||||
if (!strcasecmp(string, f->string)) {
|
||||
*mask = f->mask;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (strncasecmp(string, "MNTOPT_", 7))
|
||||
return 1;
|
||||
|
||||
if (string[8] == 0)
|
||||
return 1;
|
||||
num = strtol(string+8, &eptr, 10);
|
||||
if (num > 31 || num < 0)
|
||||
return 1;
|
||||
if (*eptr)
|
||||
return 1;
|
||||
*mask = 1 << num;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *skip_over_blanks(char *cp)
|
||||
{
|
||||
while (*cp && isspace(*cp))
|
||||
cp++;
|
||||
return cp;
|
||||
}
|
||||
|
||||
static char *skip_over_word(char *cp)
|
||||
{
|
||||
while (*cp && !isspace(*cp) && *cp != ',')
|
||||
cp++;
|
||||
return cp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Edit a mntopt set array as requested by the user. The ok
|
||||
* parameter, if non-zero, allows the application to limit what
|
||||
* mntopts the user is allowed to set or clear using this function.
|
||||
*/
|
||||
int e2p_edit_mntopts(const char *str, __u32 *mntopts, __u32 ok)
|
||||
{
|
||||
char *cp, *buf, *next;
|
||||
int neg;
|
||||
unsigned int mask;
|
||||
int rc = 0;
|
||||
|
||||
buf = malloc(strlen(str)+1);
|
||||
if (!buf)
|
||||
return 1;
|
||||
strcpy(buf, str);
|
||||
cp = buf;
|
||||
while (cp && *cp) {
|
||||
neg = 0;
|
||||
cp = skip_over_blanks(cp);
|
||||
next = skip_over_word(cp);
|
||||
if (*next == 0)
|
||||
next = 0;
|
||||
else
|
||||
*next = 0;
|
||||
switch (*cp) {
|
||||
case '-':
|
||||
case '^':
|
||||
neg++;
|
||||
/* fallthrough */
|
||||
case '+':
|
||||
cp++;
|
||||
break;
|
||||
}
|
||||
if (e2p_string2mntopt(cp, &mask)) {
|
||||
rc = 1;
|
||||
break;
|
||||
}
|
||||
if (ok && !(ok & mask)) {
|
||||
rc = 1;
|
||||
break;
|
||||
}
|
||||
if (mask & EXT3_DEFM_JMODE)
|
||||
*mntopts &= ~EXT3_DEFM_JMODE;
|
||||
if (neg)
|
||||
*mntopts &= ~mask;
|
||||
else
|
||||
*mntopts |= mask;
|
||||
cp = next ? next+1 : 0;
|
||||
}
|
||||
free(buf);
|
||||
return rc;
|
||||
}
|
||||
79
e2fsprogs/lib/e2p/ostype.c
Normal file
79
e2fsprogs/lib/e2p/ostype.c
Normal file
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* getostype.c - Get the Filesystem OS type
|
||||
*
|
||||
* Copyright (C) 2004,2005 Theodore Ts'o <tytso@mit.edu>
|
||||
*
|
||||
* %Begin-Header%
|
||||
* This file may be redistributed under the terms of the GNU Library
|
||||
* General Public License, version 2.
|
||||
* %End-Header%
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "e2p.h"
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static const char *os_tab[] =
|
||||
{ "Linux",
|
||||
"Hurd",
|
||||
"Masix",
|
||||
"FreeBSD",
|
||||
"Lites",
|
||||
0 };
|
||||
|
||||
/*
|
||||
* Convert an os_type to a string
|
||||
*/
|
||||
char *e2p_os2string(int os_type)
|
||||
{
|
||||
const char *os;
|
||||
char *ret;
|
||||
|
||||
if (os_type >= 0 && os_type <= EXT2_OS_LITES)
|
||||
os = os_tab[os_type];
|
||||
else
|
||||
os = "(unknown os)";
|
||||
|
||||
ret = malloc(strlen(os)+1);
|
||||
if (ret)
|
||||
strcpy(ret, os);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert an os_type to a string
|
||||
*/
|
||||
int e2p_string2os(char *str)
|
||||
{
|
||||
const char **cpp;
|
||||
int i = 0;
|
||||
|
||||
for (cpp = os_tab; *cpp; cpp++, i++) {
|
||||
if (!strcasecmp(str, *cpp))
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef TEST_PROGRAM
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char *s;
|
||||
int i, os;
|
||||
|
||||
for (i=0; i <= EXT2_OS_LITES; i++) {
|
||||
s = e2p_os2string(i);
|
||||
os = e2p_string2os(s);
|
||||
printf("%d: %s (%d)\n", i, s, os);
|
||||
free(s);
|
||||
if (i != os) {
|
||||
fprintf(stderr, "Failure!\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
91
e2fsprogs/lib/e2p/parse_num.c
Normal file
91
e2fsprogs/lib/e2p/parse_num.c
Normal file
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* parse_num.c - Parse the number of blocks
|
||||
*
|
||||
* Copyright (C) 2004,2005 Theodore Ts'o <tytso@mit.edu>
|
||||
*
|
||||
* %Begin-Header%
|
||||
* This file may be redistributed under the terms of the GNU Library
|
||||
* General Public License, version 2.
|
||||
* %End-Header%
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "e2p.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
unsigned long long parse_num_blocks2(const char *arg, int log_block_size)
|
||||
{
|
||||
char *p;
|
||||
unsigned long long num;
|
||||
|
||||
num = strtoull(arg, &p, 0);
|
||||
|
||||
if (p[0] && p[1])
|
||||
return 0;
|
||||
|
||||
switch (*p) { /* Using fall-through logic */
|
||||
case 'T': case 't':
|
||||
num <<= 10;
|
||||
/* fallthrough */
|
||||
case 'G': case 'g':
|
||||
num <<= 10;
|
||||
/* fallthrough */
|
||||
case 'M': case 'm':
|
||||
num <<= 10;
|
||||
/* fallthrough */
|
||||
case 'K': case 'k':
|
||||
if (log_block_size < 0)
|
||||
num <<= 10;
|
||||
else
|
||||
num >>= log_block_size;
|
||||
break;
|
||||
case 's':
|
||||
if (log_block_size < 0)
|
||||
num <<= 9;
|
||||
else
|
||||
num >>= (1+log_block_size);
|
||||
break;
|
||||
case '\0':
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
unsigned long parse_num_blocks(const char *arg, int log_block_size)
|
||||
{
|
||||
return parse_num_blocks2(arg, log_block_size);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
unsigned long num;
|
||||
int log_block_size = 0;
|
||||
|
||||
if (argc != 2 && argc != 3) {
|
||||
fprintf(stderr, "Usage: %s arg [log_block_size]\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (argc == 3) {
|
||||
char *p;
|
||||
|
||||
log_block_size = strtol(argv[2], &p, 0);
|
||||
if (*p) {
|
||||
fprintf(stderr, "Bad log_block_size: %s\n", argv[2]);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
num = parse_num_blocks(argv[1], log_block_size);
|
||||
|
||||
printf("Parsed number: %lu\n", num);
|
||||
exit(0);
|
||||
}
|
||||
#endif
|
||||
40
e2fsprogs/lib/e2p/pe.c
Normal file
40
e2fsprogs/lib/e2p/pe.c
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* pe.c - Print a second extended filesystem errors behavior
|
||||
*
|
||||
* Copyright (C) 1992, 1993, 1994 Remy Card <card@masi.ibp.fr>
|
||||
* Laboratoire MASI, Institut Blaise Pascal
|
||||
* Universite Pierre et Marie Curie (Paris VI)
|
||||
*
|
||||
* %Begin-Header%
|
||||
* This file may be redistributed under the terms of the GNU Library
|
||||
* General Public License, version 2.
|
||||
* %End-Header%
|
||||
*/
|
||||
|
||||
/*
|
||||
* History:
|
||||
* 94/01/09 - Creation
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#include "e2p.h"
|
||||
|
||||
void print_fs_errors (FILE * f, unsigned short errors)
|
||||
{
|
||||
switch (errors)
|
||||
{
|
||||
case EXT2_ERRORS_CONTINUE:
|
||||
fprintf (f, "Continue");
|
||||
break;
|
||||
case EXT2_ERRORS_RO:
|
||||
fprintf (f, "Remount read-only");
|
||||
break;
|
||||
case EXT2_ERRORS_PANIC:
|
||||
fprintf (f, "Panic");
|
||||
break;
|
||||
default:
|
||||
fprintf (f, "Unknown (continue)");
|
||||
}
|
||||
}
|
||||
67
e2fsprogs/lib/e2p/percent.c
Normal file
67
e2fsprogs/lib/e2p/percent.c
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* percent.c - Take percentage of a number
|
||||
*
|
||||
* Copyright (C) 2006 Theodore Ts'o <tytso@mit.edu>
|
||||
*
|
||||
* %Begin-Header%
|
||||
* This file may be redistributed under the terms of the GNU Library
|
||||
* General Public License, version 2.
|
||||
* %End-Header%
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "e2p.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
/*
|
||||
* We work really hard to calculate this accurately, while avoiding
|
||||
* an overflow. "Is there a hyphen in anal-retentive?" :-)
|
||||
*/
|
||||
unsigned int e2p_percent(int percent, unsigned int base)
|
||||
{
|
||||
unsigned int mask = ~((1 << (sizeof(unsigned int) - 1) * 8) - 1);
|
||||
|
||||
if (!percent)
|
||||
return 0;
|
||||
if (100 % percent == 0)
|
||||
return base / (100 / percent);
|
||||
if (mask & base)
|
||||
return (base / 100) * percent;
|
||||
return base * percent / 100;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
unsigned int base;
|
||||
int percent;
|
||||
char *p;
|
||||
int log_block_size = 0;
|
||||
|
||||
if (argc != 3) {
|
||||
fprintf(stderr, "Usage: %s percent base\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
percent = strtoul(argv[1], &p, 0);
|
||||
if (p[0] && p[1]) {
|
||||
fprintf(stderr, "Bad percent: %s\n", argv[1]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
base = strtoul(argv[2], &p, 0);
|
||||
if (p[0] && p[1]) {
|
||||
fprintf(stderr, "Bad base: %s\n", argv[2]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf("%d percent of %u is %u.\n", percent, base,
|
||||
e2p_percent(percent, base));
|
||||
|
||||
exit(0);
|
||||
}
|
||||
#endif
|
||||
79
e2fsprogs/lib/e2p/pf.c
Normal file
79
e2fsprogs/lib/e2p/pf.c
Normal file
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* pf.c - Print file attributes on an ext2 file system
|
||||
*
|
||||
* Copyright (C) 1993, 1994 Remy Card <card@masi.ibp.fr>
|
||||
* Laboratoire MASI, Institut Blaise Pascal
|
||||
* Universite Pierre et Marie Curie (Paris VI)
|
||||
*
|
||||
* %Begin-Header%
|
||||
* This file may be redistributed under the terms of the GNU Library
|
||||
* General Public License, version 2.
|
||||
* %End-Header%
|
||||
*/
|
||||
|
||||
/*
|
||||
* History:
|
||||
* 93/10/30 - Creation
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#include "e2p.h"
|
||||
|
||||
struct flags_name {
|
||||
unsigned long flag;
|
||||
const char *short_name;
|
||||
const char *long_name;
|
||||
};
|
||||
|
||||
static struct flags_name flags_array[] = {
|
||||
{ EXT2_SECRM_FL, "s", "Secure_Deletion" },
|
||||
{ EXT2_UNRM_FL, "u" , "Undelete" },
|
||||
{ EXT2_SYNC_FL, "S", "Synchronous_Updates" },
|
||||
{ EXT2_DIRSYNC_FL, "D", "Synchronous_Directory_Updates" },
|
||||
{ EXT2_IMMUTABLE_FL, "i", "Immutable" },
|
||||
{ EXT2_APPEND_FL, "a", "Append_Only" },
|
||||
{ EXT2_NODUMP_FL, "d", "No_Dump" },
|
||||
{ EXT2_NOATIME_FL, "A", "No_Atime" },
|
||||
{ EXT2_COMPR_FL, "c", "Compression_Requested" },
|
||||
{ EXT4_ENCRYPT_FL, "E", "Encrypted" },
|
||||
{ EXT3_JOURNAL_DATA_FL, "j", "Journaled_Data" },
|
||||
{ EXT2_INDEX_FL, "I", "Indexed_directory" },
|
||||
{ EXT2_NOTAIL_FL, "t", "No_Tailmerging" },
|
||||
{ EXT2_TOPDIR_FL, "T", "Top_of_Directory_Hierarchies" },
|
||||
{ EXT4_EXTENTS_FL, "e", "Extents" },
|
||||
{ FS_NOCOW_FL, "C", "No_COW" },
|
||||
{ FS_DAX_FL, "x", "DAX" },
|
||||
{ EXT4_CASEFOLD_FL, "F", "Casefold" },
|
||||
{ EXT4_INLINE_DATA_FL, "N", "Inline_Data" },
|
||||
{ EXT4_PROJINHERIT_FL, "P", "Project_Hierarchy" },
|
||||
{ EXT4_VERITY_FL, "V", "Verity" },
|
||||
{ EXT2_NOCOMPR_FL, "m", "Dont_Compress" },
|
||||
{ 0, NULL, NULL }
|
||||
};
|
||||
|
||||
void print_flags (FILE * f, unsigned long flags, unsigned options)
|
||||
{
|
||||
int long_opt = (options & PFOPT_LONG);
|
||||
struct flags_name *fp;
|
||||
int first = 1;
|
||||
|
||||
for (fp = flags_array; fp->flag != 0; fp++) {
|
||||
if (flags & fp->flag) {
|
||||
if (long_opt) {
|
||||
if (first)
|
||||
first = 0;
|
||||
else
|
||||
fputs(", ", f);
|
||||
fputs(fp->long_name, f);
|
||||
} else
|
||||
fputs(fp->short_name, f);
|
||||
} else {
|
||||
if (!long_opt)
|
||||
fputs("-", f);
|
||||
}
|
||||
}
|
||||
if (long_opt && first)
|
||||
fputs("---", f);
|
||||
}
|
||||
32
e2fsprogs/lib/e2p/ps.c
Normal file
32
e2fsprogs/lib/e2p/ps.c
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* ps.c - Print filesystem state
|
||||
*
|
||||
* Copyright (C) 1993, 1994 Remy Card <card@masi.ibp.fr>
|
||||
* Laboratoire MASI, Institut Blaise Pascal
|
||||
* Universite Pierre et Marie Curie (Paris VI)
|
||||
*
|
||||
* %Begin-Header%
|
||||
* This file may be redistributed under the terms of the GNU Library
|
||||
* General Public License, version 2.
|
||||
* %End-Header%
|
||||
*/
|
||||
|
||||
/*
|
||||
* History:
|
||||
* 93/12/22 - Creation
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#include "e2p.h"
|
||||
|
||||
void print_fs_state (FILE * f, unsigned short state)
|
||||
{
|
||||
if (state & EXT2_VALID_FS)
|
||||
fprintf (f, " clean");
|
||||
else
|
||||
fprintf (f, " not clean");
|
||||
if (state & EXT2_ERROR_FS)
|
||||
fprintf (f, " with errors");
|
||||
}
|
||||
77
e2fsprogs/lib/e2p/setflags.c
Normal file
77
e2fsprogs/lib/e2p/setflags.c
Normal file
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* setflags.c - Set a file flags on an ext2 file system
|
||||
*
|
||||
* Copyright (C) 1993, 1994 Remy Card <card@masi.ibp.fr>
|
||||
* Laboratoire MASI, Institut Blaise Pascal
|
||||
* Universite Pierre et Marie Curie (Paris VI)
|
||||
*
|
||||
* %Begin-Header%
|
||||
* This file may be redistributed under the terms of the GNU Library
|
||||
* General Public License, version 2.
|
||||
* %End-Header%
|
||||
*/
|
||||
|
||||
/*
|
||||
* History:
|
||||
* 93/10/30 - Creation
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#if HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#if HAVE_EXT2_IOCTLS
|
||||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
|
||||
#include "e2p.h"
|
||||
|
||||
/*
|
||||
* Deal with lame glibc's that define this function without actually
|
||||
* implementing it. Can you say "attractive nuisance", boys and girls?
|
||||
* I knew you could!
|
||||
*/
|
||||
#ifdef __linux__
|
||||
#undef HAVE_CHFLAGS
|
||||
#endif
|
||||
|
||||
int setflags (int fd, unsigned long flags)
|
||||
{
|
||||
#if HAVE_CHFLAGS
|
||||
unsigned long bsd_flags = 0;
|
||||
|
||||
#ifdef UF_IMMUTABLE
|
||||
if (flags & EXT2_IMMUTABLE_FL)
|
||||
bsd_flags |= UF_IMMUTABLE;
|
||||
#endif
|
||||
#ifdef UF_APPEND
|
||||
if (flags & EXT2_APPEND_FL)
|
||||
bsd_flags |= UF_APPEND;
|
||||
#endif
|
||||
#ifdef UF_NODUMP
|
||||
if (flags & EXT2_NODUMP_FL)
|
||||
bsd_flags |= UF_NODUMP;
|
||||
#endif
|
||||
|
||||
return fchflags (fd, bsd_flags);
|
||||
#else /* ! HAVE_CHFLAGS */
|
||||
#if HAVE_EXT2_IOCTLS
|
||||
struct stat buf;
|
||||
int f;
|
||||
|
||||
if (!fstat(fd, &buf) &&
|
||||
!S_ISREG(buf.st_mode) && !S_ISDIR(buf.st_mode)) {
|
||||
errno = EOPNOTSUPP;
|
||||
return -1;
|
||||
}
|
||||
f = (int) flags;
|
||||
|
||||
return ioctl(fd, EXT2_IOC_SETFLAGS, &f);
|
||||
#else
|
||||
errno = EOPNOTSUPP;
|
||||
return -1;
|
||||
#endif /* HAVE_EXT2_IOCTLS */
|
||||
#endif /* HAVE_CHFLAGS */
|
||||
}
|
||||
40
e2fsprogs/lib/e2p/setversion.c
Normal file
40
e2fsprogs/lib/e2p/setversion.c
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* setversion.c - Set a file version on an ext2 file system
|
||||
*
|
||||
* Copyright (C) 1993, 1994 Remy Card <card@masi.ibp.fr>
|
||||
* Laboratoire MASI, Institut Blaise Pascal
|
||||
* Universite Pierre et Marie Curie (Paris VI)
|
||||
*
|
||||
* %Begin-Header%
|
||||
* This file may be redistributed under the terms of the GNU Library
|
||||
* General Public License, version 2.
|
||||
* %End-Header%
|
||||
*/
|
||||
|
||||
/*
|
||||
* History:
|
||||
* 93/10/30 - Creation
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#if HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
#if HAVE_SYS_IOCTL_H
|
||||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
|
||||
#include "e2p.h"
|
||||
|
||||
int setversion (int fd, unsigned long version)
|
||||
{
|
||||
#if HAVE_EXT2_IOCTLS
|
||||
int ver;
|
||||
|
||||
ver = (int) version;
|
||||
return ioctl (fd, EXT2_IOC_SETVERSION, &ver);
|
||||
#else /* ! HAVE_EXT2_IOCTLS */
|
||||
errno = EOPNOTSUPP;
|
||||
return -1;
|
||||
#endif /* ! HAVE_EXT2_IOCTLS */
|
||||
}
|
||||
85
e2fsprogs/lib/e2p/uuid.c
Normal file
85
e2fsprogs/lib/e2p/uuid.c
Normal file
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* uuid.c -- utility routines for manipulating UUID's.
|
||||
*
|
||||
* %Begin-Header%
|
||||
* This file may be redistributed under the terms of the GNU Library
|
||||
* General Public License, version 2.
|
||||
* %End-Header%
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ext2fs/ext2_types.h>
|
||||
|
||||
#include "e2p.h"
|
||||
|
||||
struct uuid {
|
||||
__u32 time_low;
|
||||
__u16 time_mid;
|
||||
__u16 time_hi_and_version;
|
||||
__u16 clock_seq;
|
||||
__u8 node[6];
|
||||
};
|
||||
|
||||
/* Returns 1 if the uuid is the NULL uuid */
|
||||
int e2p_is_null_uuid(void *uu)
|
||||
{
|
||||
__u8 *cp;
|
||||
int i;
|
||||
|
||||
for (i=0, cp = uu; i < 16; i++)
|
||||
if (*cp++)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void e2p_unpack_uuid(void *in, struct uuid *uu)
|
||||
{
|
||||
__u8 *ptr = in;
|
||||
__u32 tmp;
|
||||
|
||||
tmp = *ptr++;
|
||||
tmp = (tmp << 8) | *ptr++;
|
||||
tmp = (tmp << 8) | *ptr++;
|
||||
tmp = (tmp << 8) | *ptr++;
|
||||
uu->time_low = tmp;
|
||||
|
||||
tmp = *ptr++;
|
||||
tmp = (tmp << 8) | *ptr++;
|
||||
uu->time_mid = tmp;
|
||||
|
||||
tmp = *ptr++;
|
||||
tmp = (tmp << 8) | *ptr++;
|
||||
uu->time_hi_and_version = tmp;
|
||||
|
||||
tmp = *ptr++;
|
||||
tmp = (tmp << 8) | *ptr++;
|
||||
uu->clock_seq = tmp;
|
||||
|
||||
memcpy(uu->node, ptr, 6);
|
||||
}
|
||||
|
||||
void e2p_uuid_to_str(void *uu, char *out)
|
||||
{
|
||||
struct uuid uuid;
|
||||
|
||||
e2p_unpack_uuid(uu, &uuid);
|
||||
sprintf(out,
|
||||
"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
|
||||
uuid.time_low, uuid.time_mid, uuid.time_hi_and_version,
|
||||
uuid.clock_seq >> 8, uuid.clock_seq & 0xFF,
|
||||
uuid.node[0], uuid.node[1], uuid.node[2],
|
||||
uuid.node[3], uuid.node[4], uuid.node[5]);
|
||||
}
|
||||
|
||||
const char *e2p_uuid2str(void *uu)
|
||||
{
|
||||
static char buf[80];
|
||||
|
||||
if (e2p_is_null_uuid(uu))
|
||||
return "<none>";
|
||||
e2p_uuid_to_str(uu, buf);
|
||||
return buf;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user