diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-02-04 07:40:19 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-02-04 07:40:19 +0000 |
commit | 33263fc5f9ac8e8cb2b22d06af3ce5ac1dd815e4 (patch) | |
tree | 2d1b86a40bef0958a68cf1a2eafbeb0667a70543 /fs/ncpfs/ncplib_kernel.c | |
parent | 216f5f51aa02f8b113aa620ebc14a9631a217a00 (diff) |
Merge with Linux 2.3.32.
Diffstat (limited to 'fs/ncpfs/ncplib_kernel.c')
-rw-r--r-- | fs/ncpfs/ncplib_kernel.c | 222 |
1 files changed, 222 insertions, 0 deletions
diff --git a/fs/ncpfs/ncplib_kernel.c b/fs/ncpfs/ncplib_kernel.c index 5dbd0c55a..7220e4852 100644 --- a/fs/ncpfs/ncplib_kernel.c +++ b/fs/ncpfs/ncplib_kernel.c @@ -4,6 +4,7 @@ * Copyright (C) 1995, 1996 by Volker Lendecke * Modified for big endian by J.F. Chadima and David S. Miller * Modified 1997 Peter Waltenberg, Bill Hawes, David Woodhouse for 2.1 dcache + * Modified 1999 Wolfram Pienkoss for NLS * */ @@ -886,4 +887,225 @@ ncp_ClearPhysicalRecord(struct ncp_server *server, const char *file_id, } #endif /* CONFIG_NCPFS_IOCTL_LOCKING */ +#ifdef CONFIG_NCPFS_NLS +/* This are the NLS conversion routines with inspirations and code parts + * from the vfat file system and hints from Petr Vandrovec. + */ + +inline unsigned char +ncp__tolower(struct nls_table *t, unsigned char c) +{ + unsigned char nc = t->charset2lower[c]; + + return nc ? nc : c; +} + +inline unsigned char +ncp__toupper(struct nls_table *t, unsigned char c) +{ + unsigned char nc = t->charset2upper[c]; + + return nc ? nc : c; +} + +int +ncp__io2vol(struct ncp_server *server, unsigned char *vname, unsigned int *vlen, + const unsigned char *iname, unsigned int ilen, int cc) +{ + struct nls_table *in = server->nls_io; + struct nls_table *out = server->nls_vol; + struct nls_unicode uc; + unsigned char nc, *up; + int i, k, maxlen = *vlen - 1; + __u16 ec; + + *vlen = 0; + + for (i = 0; i < ilen;) { + if (*vlen == maxlen) + return -ENAMETOOLONG; + + if (NCP_IS_FLAG(server, NCP_FLAG_UTF8)) { + k = utf8_mbtowc(&ec, iname, ilen - i); + if (k == -1) + return -EINVAL; + uc.uni1 = ec & 0xFF; + uc.uni2 = ec >> 8; + iname += k; + i += k; + } else { + if (*iname == NCP_ESC) { + if (i > ilen - 5) + return -EINVAL; + + ec = 0; + for (k = 1; k < 5; k++) { + nc = iname[k]; + ec <<= 4; + if (nc >= '0' && nc <= '9') { + ec |= nc - '0'; + continue; + } + if (nc >= 'a' && nc <= 'f') { + ec |= nc - ('a' - 10); + continue; + } + if (nc >= 'A' && nc <= 'F') { + ec |= nc - ('A' - 10); + continue; + } + return -EINVAL; + } + uc.uni1 = ec & 0xFF; + uc.uni2 = ec >> 8; + iname += 5; + i += 5; + } else { + uc = in->charset2uni[*iname]; + iname++; + i++; + } + } + + up = out->page_uni2charset[uc.uni2]; + if (!up) + return -EINVAL; + + nc = up[uc.uni1]; + if (!nc) + return -EINVAL; + + *vname = cc ? ncp_toupper(out, nc) : nc; + vname++; + *vlen += 1; + } + + *vname = 0; + return 0; +} + +int +ncp__vol2io(struct ncp_server *server, unsigned char *iname, unsigned int *ilen, + const unsigned char *vname, unsigned int vlen, int cc) +{ + struct nls_table *in = server->nls_vol; + struct nls_table *out = server->nls_io; + struct nls_unicode uc; + unsigned char nc, *up; + int i, k, maxlen = *ilen - 1; + __u16 ec; + + *ilen = 0; + + for (i = 0; i < vlen; i++) { + if (*ilen == maxlen) + return -ENAMETOOLONG; + + uc = in->charset2uni[cc ? ncp_tolower(in, *vname) : *vname]; + + if (NCP_IS_FLAG(server, NCP_FLAG_UTF8)) { + k = utf8_wctomb(iname, (uc.uni2 << 8) + uc.uni1, + maxlen - *ilen); + if (k == -1) + return -ENAMETOOLONG; + iname += k; + *ilen += k; + } else { + up = out->page_uni2charset[uc.uni2]; + if (up) + nc = up[uc.uni1]; + else + nc = 0; + + if (nc) { + *iname = nc; + iname++; + *ilen += 1; + } else { + if (*ilen > maxlen - 5) + return -ENAMETOOLONG; + ec = (uc.uni2 << 8) + uc.uni1; + *iname = NCP_ESC; + for (k = 4; k > 0; k--) { + nc = ec & 0xF; + iname[k] = nc > 9 ? nc + ('a' - 10) + : nc + '0'; + ec >>= 4; + } + iname += 5; + *ilen += 5; + } + } + vname++; + } + + *iname = 0; + return 0; +} +#else + +int +ncp__io2vol(unsigned char *vname, unsigned int *vlen, + const unsigned char *iname, unsigned int ilen, int cc) +{ + int i; + + if (*vlen <= ilen) + return -ENAMETOOLONG; + + if (cc) + for (i = 0; i < ilen; i++) { + *vname = toupper(*iname); + vname++; + iname++; + } + else { + memmove(vname, iname, ilen); + vname += ilen; + } + + *vlen = ilen; + *vname = 0; + return 0; +} + +int +ncp__vol2io(unsigned char *iname, unsigned int *ilen, + const unsigned char *vname, unsigned int vlen, int cc) +{ + int i; + + if (*ilen <= vlen) + return -ENAMETOOLONG; + + if (cc) + for (i = 0; i < vlen; i++) { + *iname = tolower(*vname); + iname++; + vname++; + } + else { + memmove(iname, vname, vlen); + iname += vlen; + } + + *ilen = vlen; + *iname = 0; + return 0; +} + +#endif + +inline int +ncp_strnicmp(struct nls_table *t, const unsigned char *s1, + const unsigned char *s2, int n) +{ + int i; + + for (i=0; i<n; i++) + if (ncp_tolower(t, s1[i]) != ncp_tolower(t, s2[i])) + return 1; + + return 0; +} |