diff options
author | H. Peter Anvin <hpa@zytor.com> | 2012-08-07 22:18:23 -0700 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2012-08-07 22:18:23 -0700 |
commit | 4e38eb13133ba2eaf35ff9421dac5251bdbb01e7 (patch) | |
tree | c09920fbb56f0115e998fb780e41a5ddccfbbe17 | |
parent | 783cd9743376bb7b277175ce08cdf2f31d8f298a (diff) | |
download | abc80-4e38eb13133ba2eaf35ff9421dac5251bdbb01e7.tar.gz abc80-4e38eb13133ba2eaf35ff9421dac5251bdbb01e7.tar.xz abc80-4e38eb13133ba2eaf35ff9421dac5251bdbb01e7.zip |
fileop: handle multibyte host filenames, e.g. UTF-8
Handle host filenames with multibyte encoding, like UTF-8.
-rw-r--r-- | tools/fileop.c | 80 |
1 files changed, 45 insertions, 35 deletions
diff --git a/tools/fileop.c b/tools/fileop.c index 2417423..e597f4a 100644 --- a/tools/fileop.c +++ b/tools/fileop.c @@ -6,6 +6,7 @@ #include <unistd.h> #include <inttypes.h> #include <stdbool.h> +#include <wchar.h> #ifndef O_TEXT # define O_TEXT 0 @@ -95,32 +96,50 @@ static void do_closeall(int fd) send_reply(fd, 0); } -/* XXX: This assumes Latin-1; Unicode requires more sophistication */ -static const char my_tolower[256] = - "\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017" - "\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" - " !\"#$%&'()*+,-./0123456789:;<=>?" - "\351abcdefghijklmnopqrstuvwxyz\344\366\345\374_" - "\351abcdefghijklmnopqrstuvwxyz\344\366\345\374\377" - "\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217" - "\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237" - "\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257" - "\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277" - "\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317" - "\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337" - "\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357" - "\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377"; +static void unmangle_filename(char *out, const unsigned char *in) +{ + static const wchar_t my_tolower[256] = + L"\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017" + L"\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" + L" !\"#¤%&'()*+,-./0123456789:;<=>?" + L"éabcdefghijklmnopqrstuvwxyzäöåü_" + L"éabcdefghijklmnopqrstuvwxyzäöåü\377" + L"\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217" + L"\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237" + L"\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257" + L"\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277" + L"\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317" + L"\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337" + L"\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357" + L"\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377"; + int i; + + wctomb(NULL, 0); + + for (i = 0; i < 8; i++) { + if (*in != ' ') + out += wctomb(out, my_tolower[*in]); + in++; + } + + if (memcmp(in, " ", 3) && memcmp(in, "Ufd", 3)) { + out += wctomb(out, L'.'); + for (i = 0; i < 3; i++) { + if (*in != ' ') + out += wctomb(out, my_tolower[*in]); + in++; + } + } + + *out = '\0'; +} static void do_open(int fd, uint16_t ix, char *name) { - int i; - bool nodot; - struct file_data *fm; int err; + struct file_data *fm; static const char *modes[6] = {"r+t", "r+b", "w+t", "w+b", "rt", "rb" }; - char path[16], *p; - - name[11] = '\0'; + char path[64]; if (!fileops) { send_reply(fd, 128+42); /* Skivan ej klar */ @@ -129,24 +148,13 @@ static void do_open(int fd, uint16_t ix, char *name) do_close(-1, ix); - nodot = true; - p = path; - for (i = 0; i < 11; i++) { - if (name[i] != ' ') { - if (i >= 8 && nodot) { - *p++ = '.'; - nodot = false; - } - *p++ = my_tolower[(unsigned char)name[i]]; - } - } + unmangle_filename(path, (const unsigned char *)name); - if (p == path) { + if (!path[0]) { /* Empty filename */ send_reply(fd, 128+21); /* File not found */ return; } - *p = '\0'; fm = calloc(1, sizeof(struct file_info *)); if (!fm) { @@ -161,6 +169,7 @@ static void do_open(int fd, uint16_t ix, char *name) if (!fm->f) { free(fm); switch (errno) { +#if 0 /* Enable this? */ case EACCES: err = 128+39; break; @@ -171,11 +180,12 @@ static void do_open(int fd, uint16_t ix, char *name) case ENOTDIR: err = 128+48; break; +#endif default: err = 128+21; break; } - send_reply(fd, 128+21); + send_reply(fd, err); return; } |