source: branches/3.2/mindi-busybox/e2fsprogs/old_e2fsprogs/e2p/feature.c @ 3232

Last change on this file since 3232 was 3232, checked in by bruno, 5 years ago
  • Update mindi-busybox to 1.21.1
  • Property svn:eol-style set to native
File size: 3.9 KB
Line 
1/* vi: set sw=4 ts=4: */
2/*
3 * feature.c --- convert between features and strings
4 *
5 * Copyright (C) 1999  Theodore Ts'o <tytso@mit.edu>
6 *
7 * This file can be redistributed under the terms of the GNU Library General
8 * Public License
9 *
10 */
11
12#include <stdio.h>
13#include <stdlib.h>
14#include <string.h>
15#include <ctype.h>
16#include <errno.h>
17
18#include "e2p.h"
19
20struct feature {
21    int     compat;
22    unsigned int    mask;
23    const char  *string;
24};
25
26static const struct feature feature_list[] = {
27    {   E2P_FEATURE_COMPAT, EXT2_FEATURE_COMPAT_DIR_PREALLOC,
28            "dir_prealloc" },
29    {   E2P_FEATURE_COMPAT, EXT3_FEATURE_COMPAT_HAS_JOURNAL,
30            "has_journal" },
31    {   E2P_FEATURE_COMPAT, EXT2_FEATURE_COMPAT_IMAGIC_INODES,
32            "imagic_inodes" },
33    {   E2P_FEATURE_COMPAT, EXT2_FEATURE_COMPAT_EXT_ATTR,
34            "ext_attr" },
35    {   E2P_FEATURE_COMPAT, EXT2_FEATURE_COMPAT_DIR_INDEX,
36            "dir_index" },
37    {   E2P_FEATURE_COMPAT, EXT2_FEATURE_COMPAT_RESIZE_INO,
38            "resize_inode" },
39    {   E2P_FEATURE_RO_INCOMPAT, EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER,
40            "sparse_super" },
41    {   E2P_FEATURE_RO_INCOMPAT, EXT2_FEATURE_RO_COMPAT_LARGE_FILE,
42            "large_file" },
43    {   E2P_FEATURE_INCOMPAT, EXT2_FEATURE_INCOMPAT_COMPRESSION,
44            "compression" },
45    {   E2P_FEATURE_INCOMPAT, EXT2_FEATURE_INCOMPAT_FILETYPE,
46            "filetype" },
47    {   E2P_FEATURE_INCOMPAT, EXT3_FEATURE_INCOMPAT_RECOVER,
48            "needs_recovery" },
49    {   E2P_FEATURE_INCOMPAT, EXT3_FEATURE_INCOMPAT_JOURNAL_DEV,
50            "journal_dev" },
51    {   E2P_FEATURE_INCOMPAT, EXT3_FEATURE_INCOMPAT_EXTENTS,
52            "extents" },
53    {   E2P_FEATURE_INCOMPAT, EXT2_FEATURE_INCOMPAT_META_BG,
54            "meta_bg" },
55    {   0, 0, 0 },
56};
57
58const char *e2p_feature2string(int compat, unsigned int mask)
59{
60    const struct feature *f;
61    static char buf[20];
62    char fchar;
63    int fnum;
64
65    for (f = feature_list; f->string; f++) {
66        if ((compat == f->compat) &&
67            (mask == f->mask))
68            return f->string;
69    }
70    switch (compat) {
71    case E2P_FEATURE_COMPAT:
72        fchar = 'C';
73        break;
74    case E2P_FEATURE_INCOMPAT:
75        fchar = 'I';
76        break;
77    case E2P_FEATURE_RO_INCOMPAT:
78        fchar = 'R';
79        break;
80    default:
81        fchar = '?';
82        break;
83    }
84    for (fnum = 0; mask >>= 1; fnum++);
85        sprintf(buf, "FEATURE_%c%d", fchar, fnum);
86    return buf;
87}
88
89int e2p_string2feature(char *string, int *compat_type, unsigned int *mask)
90{
91    const struct feature *f;
92    char *eptr;
93    int num;
94
95    for (f = feature_list; f->string; f++) {
96        if (!strcasecmp(string, f->string)) {
97            *compat_type = f->compat;
98            *mask = f->mask;
99            return 0;
100        }
101    }
102    if (strncasecmp(string, "FEATURE_", 8))
103        return 1;
104
105    switch (string[8]) {
106    case 'c':
107    case 'C':
108        *compat_type = E2P_FEATURE_COMPAT;
109        break;
110    case 'i':
111    case 'I':
112        *compat_type = E2P_FEATURE_INCOMPAT;
113        break;
114    case 'r':
115    case 'R':
116        *compat_type = E2P_FEATURE_RO_INCOMPAT;
117        break;
118    default:
119        return 1;
120    }
121    if (string[9] == 0)
122        return 1;
123    num = strtol(string+9, &eptr, 10);
124    if (num > 32 || num < 0)
125        return 1;
126    if (*eptr)
127        return 1;
128    *mask = 1 << num;
129    return 0;
130}
131
132static inline char *skip_over_blanks(char *cp)
133{
134    while (*cp && isspace(*cp))
135        cp++;
136    return cp;
137}
138
139static inline char *skip_over_word(char *cp)
140{
141    while (*cp && !isspace(*cp) && *cp != ',')
142        cp++;
143    return cp;
144}
145
146/*
147 * Edit a feature set array as requested by the user.  The ok_array,
148 * if set, allows the application to limit what features the user is
149 * allowed to set or clear using this function.
150 */
151int e2p_edit_feature(const char *str, __u32 *compat_array, __u32 *ok_array)
152{
153    char    *cp, *buf, *next;
154    int neg;
155    unsigned int    mask;
156    int     compat_type;
157
158    buf = xstrdup(str);
159    cp = buf;
160    while (cp && *cp) {
161        neg = 0;
162        cp = skip_over_blanks(cp);
163        next = skip_over_word(cp);
164        if (*next == 0)
165            next = 0;
166        else
167            *next = 0;
168        switch (*cp) {
169        case '-':
170        case '^':
171            neg++;
172        case '+':
173            cp++;
174            break;
175        }
176        if (e2p_string2feature(cp, &compat_type, &mask))
177            return 1;
178        if (ok_array && !(ok_array[compat_type] & mask))
179            return 1;
180        if (neg)
181            compat_array[compat_type] &= ~mask;
182        else
183            compat_array[compat_type] |= mask;
184        cp = next ? next+1 : 0;
185    }
186    return 0;
187}
Note: See TracBrowser for help on using the repository browser.