aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2012-08-07 22:18:23 -0700
committerH. Peter Anvin <hpa@zytor.com>2012-08-07 22:18:23 -0700
commit4e38eb13133ba2eaf35ff9421dac5251bdbb01e7 (patch)
treec09920fbb56f0115e998fb780e41a5ddccfbbe17
parent783cd9743376bb7b277175ce08cdf2f31d8f298a (diff)
downloadabc80-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.c80
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;
}