source: MondoRescue/branches/stable/mindi-busybox/e2fsprogs/e2p/feature.c @ 821

Last change on this file since 821 was 821, checked in by Bruno Cornec, 14 years ago

Addition of busybox 1.2.1 as a mindi-busybox new package
This should avoid delivering binary files in mindi not built there (Fedora and Debian are quite serious about that)

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