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