1*6a54128fSAndroid Build Coastguard Worker /*
2*6a54128fSAndroid Build Coastguard Worker * encoding.c --- convert between encoding magic numbers and strings
3*6a54128fSAndroid Build Coastguard Worker *
4*6a54128fSAndroid Build Coastguard Worker * Copyright (C) 2018 Collabora Ltd.
5*6a54128fSAndroid Build Coastguard Worker *
6*6a54128fSAndroid Build Coastguard Worker * %Begin-Header%
7*6a54128fSAndroid Build Coastguard Worker * This file may be redistributed under the terms of the GNU Library
8*6a54128fSAndroid Build Coastguard Worker * General Public License, version 2.
9*6a54128fSAndroid Build Coastguard Worker * %End-Header%
10*6a54128fSAndroid Build Coastguard Worker */
11*6a54128fSAndroid Build Coastguard Worker
12*6a54128fSAndroid Build Coastguard Worker #include "config.h"
13*6a54128fSAndroid Build Coastguard Worker #include <stdio.h>
14*6a54128fSAndroid Build Coastguard Worker #include <stdlib.h>
15*6a54128fSAndroid Build Coastguard Worker #include <string.h>
16*6a54128fSAndroid Build Coastguard Worker #include <ctype.h>
17*6a54128fSAndroid Build Coastguard Worker #include <errno.h>
18*6a54128fSAndroid Build Coastguard Worker #include <stdio.h>
19*6a54128fSAndroid Build Coastguard Worker
20*6a54128fSAndroid Build Coastguard Worker #include "e2p.h"
21*6a54128fSAndroid Build Coastguard Worker
22*6a54128fSAndroid Build Coastguard Worker #define ARRAY_SIZE(array) \
23*6a54128fSAndroid Build Coastguard Worker (sizeof(array) / sizeof(array[0]))
24*6a54128fSAndroid Build Coastguard Worker
25*6a54128fSAndroid Build Coastguard Worker static const struct {
26*6a54128fSAndroid Build Coastguard Worker const char *name;
27*6a54128fSAndroid Build Coastguard Worker __u16 encoding_magic;
28*6a54128fSAndroid Build Coastguard Worker __u16 default_flags;
29*6a54128fSAndroid Build Coastguard Worker
30*6a54128fSAndroid Build Coastguard Worker } ext4_encoding_map[] = {
31*6a54128fSAndroid Build Coastguard Worker {
32*6a54128fSAndroid Build Coastguard Worker .encoding_magic = EXT4_ENC_UTF8_12_1,
33*6a54128fSAndroid Build Coastguard Worker .name = "utf8-12.1",
34*6a54128fSAndroid Build Coastguard Worker .default_flags = 0,
35*6a54128fSAndroid Build Coastguard Worker },
36*6a54128fSAndroid Build Coastguard Worker {
37*6a54128fSAndroid Build Coastguard Worker .encoding_magic = EXT4_ENC_UTF8_12_1,
38*6a54128fSAndroid Build Coastguard Worker .name = "utf8",
39*6a54128fSAndroid Build Coastguard Worker .default_flags = 0,
40*6a54128fSAndroid Build Coastguard Worker },
41*6a54128fSAndroid Build Coastguard Worker };
42*6a54128fSAndroid Build Coastguard Worker
43*6a54128fSAndroid Build Coastguard Worker static const struct enc_flags {
44*6a54128fSAndroid Build Coastguard Worker __u16 flag;
45*6a54128fSAndroid Build Coastguard Worker const char *param;
46*6a54128fSAndroid Build Coastguard Worker } encoding_flags[] = {
47*6a54128fSAndroid Build Coastguard Worker { EXT4_ENC_STRICT_MODE_FL, "strict" },
48*6a54128fSAndroid Build Coastguard Worker };
49*6a54128fSAndroid Build Coastguard Worker
50*6a54128fSAndroid Build Coastguard Worker /* Return a positive number < 0xff indicating the encoding magic number
51*6a54128fSAndroid Build Coastguard Worker * or a negative value indicating error. */
e2p_str2encoding(const char * string)52*6a54128fSAndroid Build Coastguard Worker int e2p_str2encoding(const char *string)
53*6a54128fSAndroid Build Coastguard Worker {
54*6a54128fSAndroid Build Coastguard Worker unsigned int i;
55*6a54128fSAndroid Build Coastguard Worker
56*6a54128fSAndroid Build Coastguard Worker for (i = 0 ; i < ARRAY_SIZE(ext4_encoding_map); i++)
57*6a54128fSAndroid Build Coastguard Worker if (!strcmp(string, ext4_encoding_map[i].name))
58*6a54128fSAndroid Build Coastguard Worker return ext4_encoding_map[i].encoding_magic;
59*6a54128fSAndroid Build Coastguard Worker
60*6a54128fSAndroid Build Coastguard Worker return -EINVAL;
61*6a54128fSAndroid Build Coastguard Worker }
62*6a54128fSAndroid Build Coastguard Worker
63*6a54128fSAndroid Build Coastguard Worker /* Return the name of an encoding or NULL */
e2p_encoding2str(int encoding)64*6a54128fSAndroid Build Coastguard Worker const char *e2p_encoding2str(int encoding)
65*6a54128fSAndroid Build Coastguard Worker {
66*6a54128fSAndroid Build Coastguard Worker unsigned int i;
67*6a54128fSAndroid Build Coastguard Worker static char buf[32];
68*6a54128fSAndroid Build Coastguard Worker
69*6a54128fSAndroid Build Coastguard Worker for (i = 0 ; i < ARRAY_SIZE(ext4_encoding_map); i++)
70*6a54128fSAndroid Build Coastguard Worker if (ext4_encoding_map[i].encoding_magic == encoding)
71*6a54128fSAndroid Build Coastguard Worker return ext4_encoding_map[i].name;
72*6a54128fSAndroid Build Coastguard Worker sprintf(buf, "UNKNOWN_ENCODING_%d", encoding);
73*6a54128fSAndroid Build Coastguard Worker return buf;
74*6a54128fSAndroid Build Coastguard Worker }
75*6a54128fSAndroid Build Coastguard Worker
e2p_get_encoding_flags(int encoding)76*6a54128fSAndroid Build Coastguard Worker int e2p_get_encoding_flags(int encoding)
77*6a54128fSAndroid Build Coastguard Worker {
78*6a54128fSAndroid Build Coastguard Worker unsigned int i;
79*6a54128fSAndroid Build Coastguard Worker
80*6a54128fSAndroid Build Coastguard Worker for (i = 0 ; i < ARRAY_SIZE(ext4_encoding_map); i++)
81*6a54128fSAndroid Build Coastguard Worker if (ext4_encoding_map[i].encoding_magic == encoding)
82*6a54128fSAndroid Build Coastguard Worker return ext4_encoding_map[i].default_flags;
83*6a54128fSAndroid Build Coastguard Worker
84*6a54128fSAndroid Build Coastguard Worker return 0;
85*6a54128fSAndroid Build Coastguard Worker }
86*6a54128fSAndroid Build Coastguard Worker
e2p_str2encoding_flags(int encoding,char * param,__u16 * flags)87*6a54128fSAndroid Build Coastguard Worker int e2p_str2encoding_flags(int encoding, char *param, __u16 *flags)
88*6a54128fSAndroid Build Coastguard Worker {
89*6a54128fSAndroid Build Coastguard Worker char *f = strtok(param, "-");
90*6a54128fSAndroid Build Coastguard Worker const struct enc_flags *fl;
91*6a54128fSAndroid Build Coastguard Worker unsigned int i, neg = 0;
92*6a54128fSAndroid Build Coastguard Worker
93*6a54128fSAndroid Build Coastguard Worker if (encoding != EXT4_ENC_UTF8_12_1)
94*6a54128fSAndroid Build Coastguard Worker return -EINVAL;
95*6a54128fSAndroid Build Coastguard Worker while (f) {
96*6a54128fSAndroid Build Coastguard Worker neg = 0;
97*6a54128fSAndroid Build Coastguard Worker if (!strncmp("no", f, 2)) {
98*6a54128fSAndroid Build Coastguard Worker neg = 1;
99*6a54128fSAndroid Build Coastguard Worker f += 2;
100*6a54128fSAndroid Build Coastguard Worker }
101*6a54128fSAndroid Build Coastguard Worker
102*6a54128fSAndroid Build Coastguard Worker for (i = 0; i < ARRAY_SIZE(encoding_flags); i++) {
103*6a54128fSAndroid Build Coastguard Worker fl = &encoding_flags[i];
104*6a54128fSAndroid Build Coastguard Worker if (!strcmp(fl->param, f)) {
105*6a54128fSAndroid Build Coastguard Worker if (neg)
106*6a54128fSAndroid Build Coastguard Worker *flags &= ~fl->flag;
107*6a54128fSAndroid Build Coastguard Worker else
108*6a54128fSAndroid Build Coastguard Worker *flags |= fl->flag;
109*6a54128fSAndroid Build Coastguard Worker
110*6a54128fSAndroid Build Coastguard Worker goto next_flag;
111*6a54128fSAndroid Build Coastguard Worker }
112*6a54128fSAndroid Build Coastguard Worker }
113*6a54128fSAndroid Build Coastguard Worker return -EINVAL;
114*6a54128fSAndroid Build Coastguard Worker next_flag:
115*6a54128fSAndroid Build Coastguard Worker f = strtok(NULL, "-");
116*6a54128fSAndroid Build Coastguard Worker }
117*6a54128fSAndroid Build Coastguard Worker return 0;
118*6a54128fSAndroid Build Coastguard Worker }
119