xref: /aosp_15_r20/external/e2fsprogs/lib/e2p/encoding.c (revision 6a54128f25917bfc36a8a6e9d722c04a0b4641b6)
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