119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/*
219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * feature.c --- convert between features and strings
33984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt *
419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Copyright (C) 1999  Theodore Ts'o <tytso@mit.edu>
53984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt *
68558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall * %Begin-Header%
78558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall * This file may be redistributed under the terms of the GNU Library
88558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall * General Public License, version 2.
98558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall * %End-Header%
1019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */
1119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
1219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <stdio.h>
1319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <stdlib.h>
1419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <string.h>
1519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <ctype.h>
1619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <errno.h>
1719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
1819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include "e2p.h"
193984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#include <ext2fs/ext2fs.h>
203984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#include <ext2fs/jfs_user.h>
2119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
2219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstruct feature {
2319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	int		compat;
2419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	unsigned int	mask;
2519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	const char	*string;
2619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project};
2719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
2819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic struct feature feature_list[] = {
2919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	{	E2P_FEATURE_COMPAT, EXT2_FEATURE_COMPAT_DIR_PREALLOC,
3019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			"dir_prealloc" },
3119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	{	E2P_FEATURE_COMPAT, EXT3_FEATURE_COMPAT_HAS_JOURNAL,
3219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			"has_journal" },
3319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	{	E2P_FEATURE_COMPAT, EXT2_FEATURE_COMPAT_IMAGIC_INODES,
3419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			"imagic_inodes" },
3519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	{	E2P_FEATURE_COMPAT, EXT2_FEATURE_COMPAT_EXT_ATTR,
3619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			"ext_attr" },
3719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	{	E2P_FEATURE_COMPAT, EXT2_FEATURE_COMPAT_DIR_INDEX,
3819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			"dir_index" },
3919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	{	E2P_FEATURE_COMPAT, EXT2_FEATURE_COMPAT_RESIZE_INODE,
4019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			"resize_inode" },
4119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	{	E2P_FEATURE_COMPAT, EXT2_FEATURE_COMPAT_LAZY_BG,
4219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			"lazy_bg" },
4319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
4419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	{	E2P_FEATURE_RO_INCOMPAT, EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER,
4519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			"sparse_super" },
4619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	{	E2P_FEATURE_RO_INCOMPAT, EXT2_FEATURE_RO_COMPAT_LARGE_FILE,
4719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			"large_file" },
4819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	{	E2P_FEATURE_RO_INCOMPAT, EXT4_FEATURE_RO_COMPAT_HUGE_FILE,
4919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			"huge_file" },
5019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	{	E2P_FEATURE_RO_INCOMPAT, EXT4_FEATURE_RO_COMPAT_GDT_CSUM,
513984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			"uninit_bg" },
523984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	{	E2P_FEATURE_RO_INCOMPAT, EXT4_FEATURE_RO_COMPAT_GDT_CSUM,
533984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			"uninit_groups" },
5419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	{	E2P_FEATURE_RO_INCOMPAT, EXT4_FEATURE_RO_COMPAT_DIR_NLINK,
5519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			"dir_nlink" },
5619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	{	E2P_FEATURE_RO_INCOMPAT, EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE,
5719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			"extra_isize" },
5819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
5919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	{	E2P_FEATURE_INCOMPAT, EXT2_FEATURE_INCOMPAT_COMPRESSION,
6019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			"compression" },
6119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	{	E2P_FEATURE_INCOMPAT, EXT2_FEATURE_INCOMPAT_FILETYPE,
6219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			"filetype" },
6319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	{	E2P_FEATURE_INCOMPAT, EXT3_FEATURE_INCOMPAT_RECOVER,
6419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			"needs_recovery" },
6519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	{	E2P_FEATURE_INCOMPAT, EXT3_FEATURE_INCOMPAT_JOURNAL_DEV,
6619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			"journal_dev" },
6719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	{	E2P_FEATURE_INCOMPAT, EXT3_FEATURE_INCOMPAT_EXTENTS,
683984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			"extent" },
693984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	{	E2P_FEATURE_INCOMPAT, EXT3_FEATURE_INCOMPAT_EXTENTS,
7019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			"extents" },
7119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	{	E2P_FEATURE_INCOMPAT, EXT2_FEATURE_INCOMPAT_META_BG,
7219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			"meta_bg" },
7319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	{	E2P_FEATURE_INCOMPAT, EXT4_FEATURE_INCOMPAT_64BIT,
7419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			"64bit" },
753984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	{       E2P_FEATURE_INCOMPAT, EXT4_FEATURE_INCOMPAT_FLEX_BG,
763984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt                        "flex_bg"},
7719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	{	0, 0, 0 },
7819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project};
7919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
803984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtstatic struct feature jrnl_feature_list[] = {
813984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt       {       E2P_FEATURE_COMPAT, JFS_FEATURE_COMPAT_CHECKSUM,
823984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt                       "journal_checksum" },
833984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
843984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt       {       E2P_FEATURE_INCOMPAT, JFS_FEATURE_INCOMPAT_REVOKE,
853984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt                       "journal_incompat_revoke" },
863984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt       {       E2P_FEATURE_INCOMPAT, JFS_FEATURE_INCOMPAT_ASYNC_COMMIT,
873984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt                       "journal_async_commit" },
883984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt       {       0, 0, 0 },
893984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt};
903984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
9119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectconst char *e2p_feature2string(int compat, unsigned int mask)
9219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
9319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	struct feature  *f;
9419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	static char buf[20];
9519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	char	fchar;
9619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	int	fnum;
9719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
9819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	for (f = feature_list; f->string; f++) {
9919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if ((compat == f->compat) &&
10019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		    (mask == f->mask))
10119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			return f->string;
10219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
10319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	switch (compat) {
10419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	case  E2P_FEATURE_COMPAT:
10519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		fchar = 'C';
10619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		break;
10719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	case E2P_FEATURE_INCOMPAT:
10819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		fchar = 'I';
10919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		break;
11019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	case E2P_FEATURE_RO_INCOMPAT:
11119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		fchar = 'R';
11219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		break;
11319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	default:
11419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		fchar = '?';
11519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		break;
11619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
11719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	for (fnum = 0; mask >>= 1; fnum++);
11819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	sprintf(buf, "FEATURE_%c%d", fchar, fnum);
11919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	return buf;
12019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
12119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
12219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectint e2p_string2feature(char *string, int *compat_type, unsigned int *mask)
12319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
12419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	struct feature  *f;
12519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	char		*eptr;
12619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	int		num;
12719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
12819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	for (f = feature_list; f->string; f++) {
12919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (!strcasecmp(string, f->string)) {
13019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			*compat_type = f->compat;
13119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			*mask = f->mask;
13219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			return 0;
13319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		}
13419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
13519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (strncasecmp(string, "FEATURE_", 8))
13619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return 1;
13719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
13819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	switch (string[8]) {
13919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	case 'c':
14019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	case 'C':
14119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		*compat_type = E2P_FEATURE_COMPAT;
14219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		break;
14319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	case 'i':
14419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	case 'I':
14519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		*compat_type = E2P_FEATURE_INCOMPAT;
14619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		break;
14719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	case 'r':
14819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	case 'R':
14919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		*compat_type = E2P_FEATURE_RO_INCOMPAT;
15019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		break;
15119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	default:
15219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return 1;
15319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
15419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (string[9] == 0)
15519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return 1;
15619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	num = strtol(string+9, &eptr, 10);
15719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (num > 32 || num < 0)
15819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return 1;
15919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (*eptr)
16019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return 1;
16119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	*mask = 1 << num;
16219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	return 0;
16319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
16419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
1653984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtconst char *e2p_jrnl_feature2string(int compat, unsigned int mask)
1663984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt{
1673984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	struct feature  *f;
1683984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	static char buf[20];
1693984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	char	fchar;
1703984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	int	fnum;
1713984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
1723984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	for (f = jrnl_feature_list; f->string; f++) {
1733984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		if ((compat == f->compat) &&
1743984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		    (mask == f->mask))
1753984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			return f->string;
1763984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	}
1773984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	switch (compat) {
1783984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	case  E2P_FEATURE_COMPAT:
1793984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		fchar = 'C';
1803984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		break;
1813984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	case E2P_FEATURE_INCOMPAT:
1823984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		fchar = 'I';
1833984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		break;
1843984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	case E2P_FEATURE_RO_INCOMPAT:
1853984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		fchar = 'R';
1863984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		break;
1873984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	default:
1883984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		fchar = '?';
1893984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		break;
1903984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	}
1913984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	for (fnum = 0; mask >>= 1; fnum++);
1923984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	sprintf(buf, "FEATURE_%c%d", fchar, fnum);
1933984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	return buf;
1943984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt}
1953984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
1963984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtint e2p_jrnl_string2feature(char *string, int *compat_type, unsigned int *mask)
1973984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt{
1983984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	struct feature  *f;
1993984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	char		*eptr;
2003984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	int		num;
2013984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
2023984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	for (f = jrnl_feature_list; f->string; f++) {
2033984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		if (!strcasecmp(string, f->string)) {
2043984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			*compat_type = f->compat;
2053984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			*mask = f->mask;
2063984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			return 0;
2073984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		}
2083984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	}
2093984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if (strncasecmp(string, "FEATURE_", 8))
2103984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		return 1;
2113984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
2123984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	switch (string[8]) {
2133984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	case 'c':
2143984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	case 'C':
2153984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		*compat_type = E2P_FEATURE_COMPAT;
2163984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		break;
2173984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	case 'i':
2183984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	case 'I':
2193984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		*compat_type = E2P_FEATURE_INCOMPAT;
2203984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		break;
2213984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	case 'r':
2223984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	case 'R':
2233984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		*compat_type = E2P_FEATURE_RO_INCOMPAT;
2243984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		break;
2253984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	default:
2263984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		return 1;
2273984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	}
2283984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if (string[9] == 0)
2293984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		return 1;
2303984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	num = strtol(string+9, &eptr, 10);
2313984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if (num > 32 || num < 0)
2323984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		return 1;
2333984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if (*eptr)
2343984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		return 1;
2353984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	*mask = 1 << num;
2363984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	return 0;
2373984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt}
23819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic char *skip_over_blanks(char *cp)
23919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
24019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	while (*cp && isspace(*cp))
24119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		cp++;
24219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	return cp;
24319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
24419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
24519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic char *skip_over_word(char *cp)
24619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
24719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	while (*cp && !isspace(*cp) && *cp != ',')
24819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		cp++;
24919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	return cp;
25019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
25119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
25219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/*
25319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Edit a feature set array as requested by the user.  The ok_array,
25419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * if set, allows the application to limit what features the user is
2553984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * allowed to set or clear using this function.  If clear_ok_array is set,
25619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * then use it tell whether or not it is OK to clear a filesystem feature.
25719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */
25819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectint e2p_edit_feature2(const char *str, __u32 *compat_array, __u32 *ok_array,
2593984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		      __u32 *clear_ok_array, int *type_err,
26019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		      unsigned int *mask_err)
26119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
26219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	char		*cp, *buf, *next;
26319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	int		neg;
26419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	unsigned int	mask;
26519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	int		compat_type;
26619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	int		rc = 0;
26719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
26819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (!clear_ok_array)
26919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		clear_ok_array = ok_array;
27019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
27119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (type_err)
27219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		*type_err = 0;
27319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (mask_err)
27419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		*mask_err = 0;
27519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
27619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	buf = malloc(strlen(str)+1);
27719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (!buf)
27819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return 1;
27919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	strcpy(buf, str);
28019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	for (cp = buf; cp && *cp; cp = next ? next+1 : 0) {
28119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		neg = 0;
28219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		cp = skip_over_blanks(cp);
28319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		next = skip_over_word(cp);
2843984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
28519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (*next == 0)
28619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			next = 0;
28719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		else
28819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			*next = 0;
28919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
29019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if ((strcasecmp(cp, "none") == 0) ||
29119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		    (strcasecmp(cp, "clear") == 0)) {
29219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			compat_array[0] = 0;
29319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			compat_array[1] = 0;
29419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			compat_array[2] = 0;
29519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			continue;
29619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		}
29719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
29819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		switch (*cp) {
29919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		case '-':
30019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		case '^':
30119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			neg++;
30219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		case '+':
30319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			cp++;
30419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			break;
30519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		}
30619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (e2p_string2feature(cp, &compat_type, &mask)) {
30719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			rc = 1;
30819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			break;
30919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		}
31019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (neg) {
3113984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			if (clear_ok_array &&
31219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			    !(clear_ok_array[compat_type] & mask)) {
31319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				rc = 1;
31419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				if (type_err)
3153984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt					*type_err = (compat_type |
31619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project						     E2P_FEATURE_NEGATE_FLAG);
31719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				if (mask_err)
31819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project					*mask_err = mask;
31919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				break;
32019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			}
32119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			compat_array[compat_type] &= ~mask;
32219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		} else {
32319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			if (ok_array && !(ok_array[compat_type] & mask)) {
32419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				rc = 1;
32519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				if (type_err)
32619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project					*type_err = compat_type;
32719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				if (mask_err)
32819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project					*mask_err = mask;
32919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				break;
33019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			}
33119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			compat_array[compat_type] |= mask;
33219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		}
33319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
33419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	free(buf);
33519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	return rc;
33619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
33719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
33819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectint e2p_edit_feature(const char *str, __u32 *compat_array, __u32 *ok_array)
33919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
34019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	return e2p_edit_feature2(str, compat_array, ok_array, 0, 0, 0);
34119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
3423984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
3433984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#ifdef TEST_PROGRAM
3443984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtint main(int argc, char **argv)
3453984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt{
3463984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	int compat, compat2, i;
3473984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	unsigned int mask, mask2;
3483984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	const char *str;
3493984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	struct feature *f;
3503984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
3513984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	for (i = 0; i < 2; i++) {
3523984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		if (i == 0) {
3533984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			f = feature_list;
3543984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			printf("Feature list:\n");
3553984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		} else {
3563984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			printf("\nJournal feature list:\n");
3573984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			f = jrnl_feature_list;
3583984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		}
3593984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		for (; f->string; f++) {
3603984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			if (i == 0) {
3613984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt				e2p_string2feature((char *)f->string, &compat,
3623984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt						   &mask);
3633984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt				str = e2p_feature2string(compat, mask);
3643984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			} else {
3653984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt				e2p_jrnl_string2feature((char *)f->string,
3663984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt							&compat, &mask);
3673984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt				str = e2p_jrnl_feature2string(compat, mask);
3683984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			}
3693984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
3703984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			printf("\tCompat = %d, Mask = %u, %s\n",
3713984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			       compat, mask, f->string);
3723984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			if (strcmp(f->string, str)) {
3733984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt				if (e2p_string2feature((char *) str, &compat2,
3743984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt						       &mask2) ||
3753984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt				    (compat2 != compat) ||
3763984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt				    (mask2 != mask)) {
3773984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt					fprintf(stderr, "Failure!\n");
3783984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt					exit(1);
3793984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt				}
3803984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			}
3813984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		}
3823984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	}
3833984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	exit(0);
3843984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt}
3853984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#endif
386