summaryrefslogtreecommitdiffstats
path: root/fs/ncpfs/ncplib_kernel.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-07-21 22:00:56 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-07-21 22:00:56 +0000
commit168660f24dfc46c2702acbe4701a446f42a59578 (patch)
treef431368afbf6b1b71809cf3fd904d800ea126f4d /fs/ncpfs/ncplib_kernel.c
parent6420f767924fa73b0ea267864d96820815f4ba5a (diff)
Merge with Linux 2.4.0-test5-pre3.
Diffstat (limited to 'fs/ncpfs/ncplib_kernel.c')
-rw-r--r--fs/ncpfs/ncplib_kernel.c179
1 files changed, 102 insertions, 77 deletions
diff --git a/fs/ncpfs/ncplib_kernel.c b/fs/ncpfs/ncplib_kernel.c
index 29e92ea12..9272822a4 100644
--- a/fs/ncpfs/ncplib_kernel.c
+++ b/fs/ncpfs/ncplib_kernel.c
@@ -916,73 +916,73 @@ ncp__io2vol(struct ncp_server *server, unsigned char *vname, unsigned int *vlen,
{
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;
+ unsigned char *vname_start;
+ unsigned char *vname_end;
+ const unsigned char *iname_end;
- *vlen = 0;
+ iname_end = iname + ilen;
+ vname_start = vname;
+ vname_end = vname + *vlen - 1;
- for (i = 0; i < ilen;) {
- if (*vlen == maxlen)
- return -ENAMETOOLONG;
+ while (iname < iname_end) {
+ int chl;
+ wchar_t ec;
if (NCP_IS_FLAG(server, NCP_FLAG_UTF8)) {
- k = utf8_mbtowc(&ec, iname, ilen - i);
- if (k == -1)
+ int k;
+
+ k = utf8_mbtowc(&ec, iname, iname_end - iname);
+ if (k < 0)
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;
+ int k;
+
+ if (iname_end - iname < 5)
+ goto nospec;
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;
+ unsigned char nc;
+
+ nc = iname[k] - '0';
+ if (nc >= 10) {
+ nc -= 'A' - '0' - 10;
+ if ((nc < 10) || (nc > 15)) {
+ goto nospec;
+ }
}
- if (nc >= 'A' && nc <= 'F') {
- ec |= nc - ('A' - 10);
- continue;
- }
- return -EINVAL;
+ ec = (ec << 4) | nc;
}
- uc.uni1 = ec & 0xFF;
- uc.uni2 = ec >> 8;
iname += 5;
- i += 5;
} else {
- uc = in->charset2uni[*iname];
- iname++;
- i++;
+nospec:;
+ if ( (chl = in->char2uni(iname, iname_end - iname, &ec)) < 0)
+ return chl;
+ iname += chl;
}
}
- up = out->page_uni2charset[uc.uni2];
- if (!up)
- return -EINVAL;
+ /* unitoupper should be here! */
+
+ chl = out->uni2char(ec, vname, vname_end - vname);
+ if (chl < 0)
+ return chl;
- nc = up[uc.uni1];
- if (!nc)
- return -EINVAL;
+ /* this is wrong... */
+ if (cc) {
+ int chi;
- *vname = cc ? ncp_toupper(out, nc) : nc;
- vname++;
- *vlen += 1;
+ for (chi = 0; chi < chl; chi++){
+ vname[chi] = ncp_toupper(out, vname[chi]);
+ }
+ }
+ vname += chl;
}
*vname = 0;
+ *vlen = vname - vname_start;
return 0;
}
@@ -992,57 +992,82 @@ ncp__vol2io(struct ncp_server *server, unsigned char *iname, unsigned int *ilen,
{
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;
+ const unsigned char *vname_end;
+ unsigned char *iname_start;
+ unsigned char *iname_end;
+ unsigned char *vname_cc;
+ int err;
+
+ vname_cc = NULL;
- *ilen = 0;
+ if (cc) {
+ int i;
- for (i = 0; i < vlen; i++) {
- if (*ilen == maxlen)
- return -ENAMETOOLONG;
+ /* this is wrong! */
+ vname_cc = kmalloc(vlen, GFP_KERNEL);
+ for (i = 0; i < vlen; i++)
+ vname_cc[i] = ncp_tolower(in, vname[i]);
+ vname = vname_cc;
+ }
+
+ iname_start = iname;
+ iname_end = iname + *ilen - 1;
+ vname_end = vname + vlen;
- uc = in->charset2uni[cc ? ncp_tolower(in, *vname) : *vname];
+ while (vname < vname_end) {
+ wchar_t ec;
+ int chl;
+
+ if ( (chl = in->char2uni(vname, vname_end - vname, &ec)) < 0) {
+ err = chl;
+ goto quit;
+ }
+ vname += chl;
+
+ /* unitolower should be here! */
if (NCP_IS_FLAG(server, NCP_FLAG_UTF8)) {
- k = utf8_wctomb(iname, (uc.uni2 << 8) + uc.uni1,
- maxlen - *ilen);
- if (k == -1)
- return -ENAMETOOLONG;
+ int k;
+
+ k = utf8_wctomb(iname, ec, iname_end - iname);
+ if (k < 0) {
+ err = -ENAMETOOLONG;
+ goto quit;
+ }
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;
+ if ( (chl = out->uni2char(ec, iname, iname_end - iname)) >= 0) {
+ iname += chl;
} else {
- if (*ilen > maxlen - 5)
- return -ENAMETOOLONG;
- ec = (uc.uni2 << 8) + uc.uni1;
+ int k;
+
+ if (iname_end - iname < 5) {
+ err = -ENAMETOOLONG;
+ goto quit;
+ }
*iname = NCP_ESC;
for (k = 4; k > 0; k--) {
- nc = ec & 0xF;
- iname[k] = nc > 9 ? nc + ('a' - 10)
- : nc + '0';
+ unsigned char v;
+
+ v = (ec & 0xF) + '0';
+ if (v > '9') {
+ v += 'A' - '9' - 1;
+ }
+ iname[k] = v;
ec >>= 4;
}
iname += 5;
- *ilen += 5;
}
}
- vname++;
}
*iname = 0;
- return 0;
+ *ilen = iname - iname_start;
+ err = 0;
+quit:;
+ if (cc)
+ kfree(vname_cc);
+ return err;
}
#else