Lines 63-69
extern struct iconv_functions *msdosfs_i
Link Here
|
63 |
static int mbsadjpos(const char **, size_t, size_t, int, int, void *handle); |
63 |
static int mbsadjpos(const char **, size_t, size_t, int, int, void *handle); |
64 |
static u_int16_t dos2unixchr(const u_char **, size_t *, int, struct msdosfsmount *); |
64 |
static u_int16_t dos2unixchr(const u_char **, size_t *, int, struct msdosfsmount *); |
65 |
static u_int16_t unix2doschr(const u_char **, size_t *, struct msdosfsmount *); |
65 |
static u_int16_t unix2doschr(const u_char **, size_t *, struct msdosfsmount *); |
66 |
static u_int16_t win2unixchr(u_int16_t, struct msdosfsmount *); |
66 |
static u_int32_t win2unixchr(u_int16_t, struct msdosfsmount *); |
67 |
static u_int16_t unix2winchr(const u_char **, size_t *, int, struct msdosfsmount *); |
67 |
static u_int16_t unix2winchr(const u_char **, size_t *, int, struct msdosfsmount *); |
68 |
|
68 |
|
69 |
/* |
69 |
/* |
Lines 221-226
l2u[256] = {
Link Here
|
221 |
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* f8-ff */ |
221 |
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* f8-ff */ |
222 |
}; |
222 |
}; |
223 |
|
223 |
|
|
|
224 |
static int iconv_u2w(const char **inbuf, size_t *inbytes, |
225 |
char **outbuf, size_t *outbytes) |
226 |
{ |
227 |
u_int8_t mark; |
228 |
u_int16_t uc = 0; |
229 |
char * obuf = NULL; |
230 |
const char *ibuf, *ibuf_end, *obuf_end; |
231 |
if ((inbuf && inbytes && outbuf && outbytes) |
232 |
&& (*inbuf && *inbytes && *outbuf && *outbytes)) { |
233 |
ibuf = *inbuf; |
234 |
ibuf_end = *inbuf + *inbytes; |
235 |
obuf = *outbuf; |
236 |
obuf_end = *outbuf + *outbytes; |
237 |
int follow = 0; |
238 |
while (ibuf < ibuf_end && &obuf[1] < obuf_end) { |
239 |
mark = (u_int8_t)*ibuf++; |
240 |
if (mark < 0xF0 && mark > 0xE0) { |
241 |
/* 1110XXXX */ |
242 |
uc = mark & 0x0F; |
243 |
follow = 2; |
244 |
} else if (mark < 0xE0 && mark > 0xC0) { |
245 |
/* 110XXXXX */ |
246 |
uc = mark & 0x1F; |
247 |
follow = 1; |
248 |
} else if (mark < 0x80) { |
249 |
/* 0XXXXXXX */ |
250 |
uc = mark; |
251 |
follow = 0; |
252 |
} else { |
253 |
/* convert fail: 0xF0 0xE0 should NOT be in UTF-8 seq */ |
254 |
printf("convert fail 0xF0 0xE0\n"); |
255 |
break; |
256 |
} |
257 |
if (&ibuf[follow] > ibuf_end) { |
258 |
/* unexpected end of input */ |
259 |
break; |
260 |
} |
261 |
for (; follow > 0; follow--) { |
262 |
/* 10XX.XXXX 0x80-0xBF */ |
263 |
if ((*ibuf&0xC0) != 0x80) { |
264 |
*outbytes = obuf_end - *outbuf; |
265 |
*inbytes = ibuf_end - *inbuf; |
266 |
printf("convert fail SEQ\n"); |
267 |
return (0); |
268 |
} |
269 |
uc = (uc << 6) | (*ibuf++ & 0x3F); |
270 |
} |
271 |
*obuf++ = (uc >> 8); |
272 |
*obuf++ = uc; |
273 |
*outbuf = obuf; |
274 |
*inbuf = ibuf; |
275 |
} |
276 |
*outbytes = obuf_end - *outbuf; |
277 |
*inbytes = ibuf_end - *inbuf; |
278 |
} |
279 |
return (0); |
280 |
} |
281 |
|
282 |
static int iconv_w2u(const char **inbuf, size_t *inbytes, |
283 |
char **outbuf, size_t *outbytes) |
284 |
{ |
285 |
u_int16_t uc = 0; |
286 |
char *obuf = NULL; |
287 |
const char *ibuf, *ibuf_end, *obuf_end; |
288 |
if ((inbuf && inbytes && outbuf && outbytes) |
289 |
&& (*inbuf && *inbytes && *outbuf && *outbytes)) { |
290 |
ibuf = *inbuf; |
291 |
ibuf_end = *inbuf+*inbytes; |
292 |
obuf = *outbuf; |
293 |
obuf_end = *outbuf+*outbytes; |
294 |
int follow = 0; |
295 |
while (&ibuf[1] < ibuf_end && obuf < obuf_end) { |
296 |
uc = (0xFF & *ibuf++); |
297 |
uc = (0xFF & *ibuf++) | (uc << 8); |
298 |
if (uc < 0x80) { |
299 |
*obuf++ = (uc); |
300 |
follow = 0; |
301 |
} else if (uc < 0x800) { |
302 |
*obuf++ = (uc >> 6) | 0xC0; |
303 |
follow = 1; |
304 |
} else { |
305 |
/* assert(uc <= 0xFFFF); */ |
306 |
*obuf++ = (uc >> 12) | 0xE0; |
307 |
follow = 2; |
308 |
} |
309 |
if (&obuf[follow] > obuf_end) { |
310 |
/* no output buffer */ |
311 |
break; |
312 |
} |
313 |
for (follow--; follow >= 0; follow--) { |
314 |
int shift = follow * 6; |
315 |
u_int8_t ch = uc >> shift; |
316 |
*obuf++ = (ch & 0x3F) | 0x80; |
317 |
} |
318 |
*outbuf = obuf; |
319 |
*inbuf = ibuf; |
320 |
} |
321 |
*outbytes = obuf_end - *outbuf; |
322 |
*inbytes = ibuf_end - *inbuf; |
323 |
} |
324 |
return (0); |
325 |
} |
326 |
|
224 |
/* |
327 |
/* |
225 |
* DOS filenames are made of 2 parts, the name part and the extension part. |
328 |
* DOS filenames are made of 2 parts, the name part and the extension part. |
226 |
* The name part is 8 characters long and the extension part is 3 |
329 |
* The name part is 8 characters long and the extension part is 3 |
Lines 653-660
win2unixfn(nbp, wep, chksum, pmp)
Link Here
|
653 |
struct msdosfsmount *pmp; |
756 |
struct msdosfsmount *pmp; |
654 |
{ |
757 |
{ |
655 |
u_int8_t *cp; |
758 |
u_int8_t *cp; |
656 |
u_int8_t *np, name[WIN_CHARS * 2 + 1]; |
759 |
u_int8_t *np, name[WIN_CHARS * 3 + 1]; |
657 |
u_int16_t code; |
760 |
u_int32_t code; |
658 |
int i; |
761 |
int i; |
659 |
|
762 |
|
660 |
if ((wep->weCnt & WIN_CNT) > howmany(WIN_MAXLEN, WIN_CHARS) |
763 |
if ((wep->weCnt & WIN_CNT) > howmany(WIN_MAXLEN, WIN_CHARS) |
Lines 687-692
win2unixfn(nbp, wep, chksum, pmp)
Link Here
|
687 |
return -1; |
790 |
return -1; |
688 |
default: |
791 |
default: |
689 |
code = win2unixchr(code, pmp); |
792 |
code = win2unixchr(code, pmp); |
|
|
793 |
if (code & 0xff0000) |
794 |
*np++ = code >> 16; |
690 |
if (code & 0xff00) |
795 |
if (code & 0xff00) |
691 |
*np++ = code >> 8; |
796 |
*np++ = code >> 8; |
692 |
*np++ = code; |
797 |
*np++ = code; |
Lines 706-711
win2unixfn(nbp, wep, chksum, pmp)
Link Here
|
706 |
return -1; |
811 |
return -1; |
707 |
default: |
812 |
default: |
708 |
code = win2unixchr(code, pmp); |
813 |
code = win2unixchr(code, pmp); |
|
|
814 |
if (code & 0xff0000) |
815 |
*np++ = code >> 16; |
709 |
if (code & 0xff00) |
816 |
if (code & 0xff00) |
710 |
*np++ = code >> 8; |
817 |
*np++ = code >> 8; |
711 |
*np++ = code; |
818 |
*np++ = code; |
Lines 725-730
win2unixfn(nbp, wep, chksum, pmp)
Link Here
|
725 |
return -1; |
832 |
return -1; |
726 |
default: |
833 |
default: |
727 |
code = win2unixchr(code, pmp); |
834 |
code = win2unixchr(code, pmp); |
|
|
835 |
if (code & 0xff0000) |
836 |
*np++ = code >> 16; |
728 |
if (code & 0xff00) |
837 |
if (code & 0xff00) |
729 |
*np++ = code >> 8; |
838 |
*np++ = code >> 8; |
730 |
*np++ = code; |
839 |
*np++ = code; |
Lines 777-783
winSlotCnt(un, unlen, pmp)
Link Here
|
777 |
if (pmp->pm_flags & MSDOSFSMNT_KICONV && msdosfs_iconv) { |
886 |
if (pmp->pm_flags & MSDOSFSMNT_KICONV && msdosfs_iconv) { |
778 |
wlen = WIN_MAXLEN * 2; |
887 |
wlen = WIN_MAXLEN * 2; |
779 |
wnp = wn; |
888 |
wnp = wn; |
780 |
msdosfs_iconv->conv(pmp->pm_u2w, (const char **)&un, &unlen, &wnp, &wlen); |
889 |
if (pmp->pm_u2w != NULL) |
|
|
890 |
msdosfs_iconv->conv(pmp->pm_u2w, (const char **)&un, &unlen, &wnp, &wlen); |
891 |
else |
892 |
iconv_u2w((const char**)&un, &unlen, &wnp, &wlen); |
781 |
if (unlen > 0) |
893 |
if (unlen > 0) |
782 |
return 0; |
894 |
return 0; |
783 |
return howmany(WIN_MAXLEN - wlen/2, WIN_CHARS); |
895 |
return howmany(WIN_MAXLEN - wlen/2, WIN_CHARS); |
Lines 815-821
mbsadjpos(const char **instr, size_t inl
Link Here
|
815 |
if (flag & MSDOSFSMNT_KICONV && msdosfs_iconv) { |
927 |
if (flag & MSDOSFSMNT_KICONV && msdosfs_iconv) { |
816 |
outp = outstr; |
928 |
outp = outstr; |
817 |
outlen *= weight; |
929 |
outlen *= weight; |
818 |
msdosfs_iconv->conv(handle, instr, &inlen, &outp, &outlen); |
930 |
if (handle != NULL) |
|
|
931 |
msdosfs_iconv->conv(handle, instr, &inlen, &outp, &outlen); |
932 |
else |
933 |
iconv_u2w(instr, &inlen, &outp, &outlen); |
819 |
return (inlen); |
934 |
return (inlen); |
820 |
} |
935 |
} |
821 |
|
936 |
|
Lines 887-894
unix2doschr(const u_char **instr, size_t
Link Here
|
887 |
ucslen = 2; |
1002 |
ucslen = 2; |
888 |
len = *ilen; |
1003 |
len = *ilen; |
889 |
up = unicode; |
1004 |
up = unicode; |
890 |
msdosfs_iconv->convchr(pmp->pm_u2w, (const char **)instr, |
1005 |
if (pmp->pm_u2w != NULL) |
891 |
ilen, &up, &ucslen); |
1006 |
msdosfs_iconv->convchr(pmp->pm_u2w, (const char **)instr, |
|
|
1007 |
ilen, &up, &ucslen); |
1008 |
else |
1009 |
iconv_u2w((const char**)instr, ilen, &up, &ucslen); |
892 |
unixlen = len - *ilen; |
1010 |
unixlen = len - *ilen; |
893 |
|
1011 |
|
894 |
/* |
1012 |
/* |
Lines 949-958
unix2doschr(const u_char **instr, size_t
Link Here
|
949 |
/* |
1067 |
/* |
950 |
* Convert Windows char to Local char |
1068 |
* Convert Windows char to Local char |
951 |
*/ |
1069 |
*/ |
952 |
static u_int16_t |
1070 |
static u_int32_t |
953 |
win2unixchr(u_int16_t wc, struct msdosfsmount *pmp) |
1071 |
win2unixchr(u_int16_t wc, struct msdosfsmount *pmp) |
954 |
{ |
1072 |
{ |
955 |
u_char *inp, *outp, inbuf[3], outbuf[3]; |
1073 |
u_char *inp, *outp, inbuf[3], outbuf[4]; |
956 |
size_t ilen, olen, len; |
1074 |
size_t ilen, olen, len; |
957 |
|
1075 |
|
958 |
if (wc == 0) |
1076 |
if (wc == 0) |
Lines 964-973
win2unixchr(u_int16_t wc, struct msdosfs
Link Here
|
964 |
inbuf[2] = '\0'; |
1082 |
inbuf[2] = '\0'; |
965 |
|
1083 |
|
966 |
ilen = olen = len = 2; |
1084 |
ilen = olen = len = 2; |
|
|
1085 |
len = olen = 4; |
967 |
inp = inbuf; |
1086 |
inp = inbuf; |
968 |
outp = outbuf; |
1087 |
outp = outbuf; |
969 |
msdosfs_iconv->convchr(pmp->pm_w2u, (const char **)&inp, &ilen, |
1088 |
if (pmp->pm_w2u != NULL) |
970 |
(char **)&outp, &olen); |
1089 |
msdosfs_iconv->convchr(pmp->pm_w2u, (const char **)&inp, &ilen, |
|
|
1090 |
(char **)&outp, &olen); |
1091 |
else |
1092 |
iconv_w2u((const char**)&inp, &ilen, (char**)&outp, &olen); |
971 |
len -= olen; |
1093 |
len -= olen; |
972 |
|
1094 |
|
973 |
/* |
1095 |
/* |
Lines 978-987
win2unixchr(u_int16_t wc, struct msdosfs
Link Here
|
978 |
return (wc); |
1100 |
return (wc); |
979 |
} |
1101 |
} |
980 |
|
1102 |
|
981 |
wc = 0; |
1103 |
u_int32_t wc32 = 0; |
982 |
while (len--) |
1104 |
while (len--) |
983 |
wc |= (*(outp - len - 1) & 0xff) << (len << 3); |
1105 |
wc32 |= (*(outp - len - 1) & 0xff) << (len << 3); |
984 |
return (wc); |
1106 |
return (wc32); |
985 |
} |
1107 |
} |
986 |
|
1108 |
|
987 |
if (wc & 0xff00) |
1109 |
if (wc & 0xff00) |
Lines 1006-1012
unix2winchr(const u_char **instr, size_t
Link Here
|
1006 |
if (pmp->pm_flags & MSDOSFSMNT_KICONV && msdosfs_iconv) { |
1128 |
if (pmp->pm_flags & MSDOSFSMNT_KICONV && msdosfs_iconv) { |
1007 |
outp = outbuf; |
1129 |
outp = outbuf; |
1008 |
olen = 2; |
1130 |
olen = 2; |
1009 |
if (lower & (LCASE_BASE | LCASE_EXT)) |
1131 |
if (pmp->pm_u2w == NULL) |
|
|
1132 |
iconv_u2w((const char**)instr, ilen, (char **)&outp, &olen); |
1133 |
else if (lower & (LCASE_BASE | LCASE_EXT)) |
1010 |
msdosfs_iconv->convchr_case(pmp->pm_u2w, (const char **)instr, |
1134 |
msdosfs_iconv->convchr_case(pmp->pm_u2w, (const char **)instr, |
1011 |
ilen, (char **)&outp, &olen, |
1135 |
ilen, (char **)&outp, &olen, |
1012 |
KICONV_FROM_LOWER); |
1136 |
KICONV_FROM_LOWER); |
Lines 1020-1026
unix2winchr(const u_char **instr, size_t
Link Here
|
1020 |
if (olen == 2) |
1144 |
if (olen == 2) |
1021 |
return (0); |
1145 |
return (0); |
1022 |
|
1146 |
|
1023 |
wc = (outbuf[0]<<8) | outbuf[1]; |
1147 |
wc = (outbuf[0] << 8) | outbuf[1]; |
1024 |
|
1148 |
|
1025 |
return (wc); |
1149 |
return (wc); |
1026 |
} |
1150 |
} |