diff options
author | semenu <semenu@FreeBSD.org> | 2001-09-08 23:03:52 +0000 |
---|---|---|
committer | semenu <semenu@FreeBSD.org> | 2001-09-08 23:03:52 +0000 |
commit | 8c98d68610fb0ec072a45372df6fae9ec3afd215 (patch) | |
tree | 19a136464adf6bfe402fbab8c1d2c88463c6d7e7 | |
parent | 22c38894cbd19ca224d48e51045206a9406b5c0f (diff) | |
download | FreeBSD-src-8c98d68610fb0ec072a45372df6fae9ec3afd215.zip FreeBSD-src-8c98d68610fb0ec072a45372df6fae9ec3afd215.tar.gz |
Stole unicode translation table from mount_msdos. Add kernel code
to support this translation.
MFC after: 2 weeks
-rw-r--r-- | sbin/mount_ntfs/Makefile | 2 | ||||
-rw-r--r-- | sbin/mount_ntfs/mount_ntfs.8 | 6 | ||||
-rw-r--r-- | sbin/mount_ntfs/mount_ntfs.c | 79 | ||||
-rw-r--r-- | sys/fs/ntfs/ntfs.h | 2 | ||||
-rw-r--r-- | sys/fs/ntfs/ntfs_subr.c | 123 | ||||
-rw-r--r-- | sys/fs/ntfs/ntfs_subr.h | 13 | ||||
-rw-r--r-- | sys/fs/ntfs/ntfs_vfsops.c | 13 | ||||
-rw-r--r-- | sys/fs/ntfs/ntfs_vnops.c | 2 | ||||
-rw-r--r-- | sys/fs/ntfs/ntfsmount.h | 2 |
9 files changed, 222 insertions, 20 deletions
diff --git a/sbin/mount_ntfs/Makefile b/sbin/mount_ntfs/Makefile index 042c5e5..369d255 100644 --- a/sbin/mount_ntfs/Makefile +++ b/sbin/mount_ntfs/Makefile @@ -5,6 +5,8 @@ PROG= mount_ntfs SRCS= mount_ntfs.c getmntopts.c MAN= mount_ntfs.8 +DPADD= ${LIBUTIL} +LDADD= -lutil MOUNT= ${.CURDIR}/../mount CFLAGS+=-I${MOUNT} diff --git a/sbin/mount_ntfs/mount_ntfs.8 b/sbin/mount_ntfs/mount_ntfs.8 index 265e966..0ae53d2 100644 --- a/sbin/mount_ntfs/mount_ntfs.8 +++ b/sbin/mount_ntfs/mount_ntfs.8 @@ -43,6 +43,7 @@ .Op Fl u Ar uid .Op Fl g Ar gid .Op Fl m Ar mask +.Op Fl W Ar u2wtable .Pa special .Pa node .Sh DESCRIPTION @@ -80,6 +81,11 @@ on which the file system is being mounted. .It Fl m Ar mask Specify the maximum file permissions for files in the file system. +.It Fl W Ar u2wtable +Specify unix to unicode translation table. This option is +completly stolen from +.Xr mount_msdos 8 +so refer its manpage. .El .Sh FEATURES NTFS file attributes are accessed in following way: diff --git a/sbin/mount_ntfs/mount_ntfs.c b/sbin/mount_ntfs/mount_ntfs.c index b01e422..81e1376 100644 --- a/sbin/mount_ntfs/mount_ntfs.c +++ b/sbin/mount_ntfs/mount_ntfs.c @@ -47,6 +47,7 @@ #include <string.h> #include <sysexits.h> #include <unistd.h> +#include <libutil.h> #include "mntopts.h" @@ -60,6 +61,8 @@ static uid_t a_uid __P((char *)); static mode_t a_mask __P((char *)); static void usage __P((void)) __dead2; +static void load_u2wtable __P((struct ntfs_args *, char *)); + int main(argc, argv) int argc; @@ -78,7 +81,7 @@ main(argc, argv) mntflags = set_gid = set_uid = set_mask = 0; (void)memset(&args, '\0', sizeof(args)); - while ((c = getopt(argc, argv, "aiu:g:m:o:")) != -1) { + while ((c = getopt(argc, argv, "aiu:g:m:o:W:")) != -1) { switch (c) { case 'u': args.uid = a_uid(optarg); @@ -101,6 +104,10 @@ main(argc, argv) case 'o': getmntopts(optarg, mopts, &mntflags, 0); break; + case 'W': + load_u2wtable(&args, optarg); + args.flag |= NTFSMNT_U2WTABLE; + break; case '?': default: usage(); @@ -233,6 +240,74 @@ a_mask(s) void usage() { - fprintf(stderr, "usage: mount_ntfs [-a] [-i] [-u user] [-g group] [-m mask] bdev dir\n"); + fprintf(stderr, "usage: mount_ntfs [-a] [-i] [-u user] [-g group] [-m mask] [-W u2wtable] bdev dir\n"); exit(EX_USAGE); } + +void +load_u2wtable (pargs, name) + struct ntfs_args *pargs; + char *name; +{ + FILE *f; + int i, j, code[8]; + size_t line = 0; + char buf[128]; + char *fn, *s, *p; + + if (*name == '/') + fn = name; + else { + snprintf(buf, sizeof(buf), "/usr/libdata/msdosfs/%s", name); + buf[127] = '\0'; + fn = buf; + } + if ((f = fopen(fn, "r")) == NULL) + err(EX_NOINPUT, "%s", fn); + p = NULL; + for (i = 0; i < 16; i++) { + do { + if (p != NULL) free(p); + if ((p = s = fparseln(f, NULL, &line, NULL, 0)) == NULL) + errx(EX_DATAERR, "can't read u2w table row %d near line %d", i, line); + while (isspace((unsigned char)*s)) + s++; + } while (*s == '\0'); + if (sscanf(s, "%i%i%i%i%i%i%i%i", +code, code + 1, code + 2, code + 3, code + 4, code + 5, code + 6, code + 7) != 8) + errx(EX_DATAERR, "u2w table: missing item(s) in row %d, line %d", i, line); + for (j = 0; j < 8; j++) + pargs->u2w[i * 8 + j] = code[j]; + } + for (i = 0; i < 16; i++) { + do { + free(p); + if ((p = s = fparseln(f, NULL, &line, NULL, 0)) == NULL) + errx(EX_DATAERR, "can't read d2u table row %d near line %d", i, line); + while (isspace((unsigned char)*s)) + s++; + } while (*s == '\0'); + if (sscanf(s, "%i%i%i%i%i%i%i%i", +code, code + 1, code + 2, code + 3, code + 4, code + 5, code + 6, code + 7) != 8) + errx(EX_DATAERR, "d2u table: missing item(s) in row %d, line %d", i, line); + for (j = 0; j < 8; j++) + /* pargs->d2u[i * 8 + j] = code[j] */; + } + for (i = 0; i < 16; i++) { + do { + free(p); + if ((p = s = fparseln(f, NULL, &line, NULL, 0)) == NULL) + errx(EX_DATAERR, "can't read u2d table row %d near line %d", i, line); + while (isspace((unsigned char)*s)) + s++; + } while (*s == '\0'); + if (sscanf(s, "%i%i%i%i%i%i%i%i", +code, code + 1, code + 2, code + 3, code + 4, code + 5, code + 6, code + 7) != 8) + errx(EX_DATAERR, "u2d table: missing item(s) in row %d, line %d", i, line); + for (j = 0; j < 8; j++) + /* pargs->u2d[i * 8 + j] = code[j] */; + } + free(p); + fclose(f); +} + diff --git a/sys/fs/ntfs/ntfs.h b/sys/fs/ntfs/ntfs.h index d74fe6f..f5e9125 100644 --- a/sys/fs/ntfs/ntfs.h +++ b/sys/fs/ntfs/ntfs.h @@ -258,6 +258,8 @@ struct ntfsmount { #if !defined(__FreeBSD__) struct netexport ntm_export; /* export information */ #endif + wchar * ntm_82u; /* 8bit to Unicode */ + char ** ntm_u28; /* Unicode to 8 bit */ }; #define ntm_mftcn ntm_bootfile.bf_mftcn diff --git a/sys/fs/ntfs/ntfs_subr.c b/sys/fs/ntfs/ntfs_subr.c index 7b9ae76..e1e6006 100644 --- a/sys/fs/ntfs/ntfs_subr.c +++ b/sys/fs/ntfs/ntfs_subr.c @@ -63,21 +63,20 @@ MALLOC_DEFINE(M_NTFSDECOMP, "NTFS decomp", "NTFS decompression temporary"); static int ntfs_ntlookupattr __P((struct ntfsmount *, const char *, int, int *, char **)); static int ntfs_findvattr __P((struct ntfsmount *, struct ntnode *, struct ntvattr **, struct ntvattr **, u_int32_t, const char *, size_t, cn_t)); -static int ntfs_uastricmp __P((const wchar *, size_t, const char *, size_t)); -static int ntfs_uastrcmp __P((const wchar *, size_t, const char *, size_t)); +static int ntfs_uastricmp __P((struct ntfsmount *, const wchar *, size_t, const char *, size_t)); +static int ntfs_uastrcmp __P((struct ntfsmount *, const wchar *, size_t, const char *, size_t)); /* table for mapping Unicode chars into uppercase; it's filled upon first * ntfs mount, freed upon last ntfs umount */ static wchar *ntfs_toupper_tab; -#define NTFS_U28(ch) ((((ch) & 0xFF) == 0) ? '_' : (ch) & 0xFF) -#define NTFS_TOUPPER(ch) (ntfs_toupper_tab[(unsigned char)(ch)]) +#define NTFS_TOUPPER(ch) (ntfs_toupper_tab[(ch)]) static struct lock ntfs_toupper_lock; static signed int ntfs_toupper_usecount; /* support macro for ntfs_ntvattrget() */ #define NTFS_AALPCMP(aalp,type,name,namelen) ( \ (aalp->al_type == type) && (aalp->al_namelen == namelen) && \ - !ntfs_uastrcmp(aalp->al_name,aalp->al_namelen,name,namelen) ) + !NTFS_UASTRCMP(aalp->al_name,aalp->al_namelen,name,namelen) ) /* * @@ -662,7 +661,8 @@ ntfs_runtovrun( * Compare unicode and ascii string case insens. */ static int -ntfs_uastricmp(ustr, ustrlen, astr, astrlen) +ntfs_uastricmp(ntmp, ustr, ustrlen, astr, astrlen) + struct ntfsmount *ntmp; const wchar *ustr; size_t ustrlen; const char *astr; @@ -671,9 +671,13 @@ ntfs_uastricmp(ustr, ustrlen, astr, astrlen) size_t i; int res; + /* + * XXX We use NTFS_82U(NTFS_U28(c)) to get rid of unicode + * symbols not covered by translation table + */ for (i = 0; i < ustrlen && i < astrlen; i++) { - res = ((int) NTFS_TOUPPER(NTFS_U28(ustr[i]))) - - ((int)NTFS_TOUPPER(astr[i])); + res = ((int) NTFS_TOUPPER(NTFS_82U(NTFS_U28(ustr[i])))) - + ((int)NTFS_TOUPPER(NTFS_82U(astr[i]))); if (res) return res; } @@ -684,7 +688,8 @@ ntfs_uastricmp(ustr, ustrlen, astr, astrlen) * Compare unicode and ascii string case sens. */ static int -ntfs_uastrcmp(ustr, ustrlen, astr, astrlen) +ntfs_uastrcmp(ntmp, ustr, ustrlen, astr, astrlen) + struct ntfsmount *ntmp; const wchar *ustr; size_t ustrlen; const char *astr; @@ -918,7 +923,7 @@ ntfs_ntlookupfile( /* check the name - the case-insensitible check * has to come first, to break from this for loop * if needed, so we can dive correctly */ - res = ntfs_uastricmp(iep->ie_fname, iep->ie_fnamelen, + res = NTFS_UASTRICMP(iep->ie_fname, iep->ie_fnamelen, fname, fnamelen); if (res > 0) break; if (res < 0) continue; @@ -926,7 +931,7 @@ ntfs_ntlookupfile( if (iep->ie_fnametype == 0 || !(ntmp->ntm_flag & NTFS_MFLAG_CASEINS)) { - res = ntfs_uastrcmp(iep->ie_fname, + res = NTFS_UASTRCMP(iep->ie_fname, iep->ie_fnamelen, fname, fnamelen); if (res != 0) continue; } @@ -1956,13 +1961,13 @@ ntfs_toupper_use(mp, ntmp) * XXX for now, just the first 256 entries are used anyway, * so don't bother reading more */ - MALLOC(ntfs_toupper_tab, wchar *, 256 * sizeof(wchar), + MALLOC(ntfs_toupper_tab, wchar *, 65536 * sizeof(wchar), M_NTFSRDATA, M_WAITOK); if ((error = VFS_VGET(mp, NTFS_UPCASEINO, &vp))) goto out; error = ntfs_readattr(ntmp, VTONT(vp), NTFS_A_DATA, NULL, - 0, 256*sizeof(wchar), (char *) ntfs_toupper_tab, NULL); + 0, 65536*sizeof(wchar), (char *) ntfs_toupper_tab, NULL); vput(vp); out: @@ -1997,6 +2002,86 @@ ntfs_toupper_unuse() LOCKMGR(&ntfs_toupper_lock, LK_RELEASE, NULL); } +int +ntfs_u28_init( + struct ntfsmount *ntmp, + wchar *u2w) +{ + char ** u28; + int i, j, h, l; + + MALLOC(u28, char **, 256 * sizeof(char*), M_TEMP, M_WAITOK | M_ZERO); + + for (i=0; i<256; i++) { + h = (u2w[i] >> 8) & 0xFF; + l = (u2w[i]) &0xFF; + + if (u28[h] == NULL) { + MALLOC(u28[h], char *, 256 * sizeof(char), M_TEMP, M_WAITOK); + for (j=0; j<256; j++) + u28[h][j] = '_'; + } + + u28[h][l] = i & 0xFF; + } + + ntmp->ntm_u28 = u28; + + return (0); +} + +int +ntfs_u28_uninit(struct ntfsmount *ntmp) +{ + char ** u28; + int i; + + if (ntmp->ntm_u28 == NULL) + return (0); + + u28 = ntmp->ntm_u28; + + for (i=0; i<256; i++) + if (u28[i] != NULL) + FREE(u28[i], M_TEMP); + + FREE(u28, M_TEMP); + + return (0); +} + +int +ntfs_82u_init( + struct ntfsmount *ntmp, + u_int16_t *u2w) +{ + wchar * _82u; + int i; + + MALLOC(_82u, wchar *, 256 * sizeof(wchar), M_TEMP, M_WAITOK); + + if (u2w == NULL) { + for (i=0; i<256; i++) + _82u[i] = i; + } else { + for (i=0; i<128; i++) + _82u[i] = i; + for (i=0; i<128; i++) + _82u[i+128] = u2w[i]; + } + + ntmp->ntm_82u = _82u; + + return (0); +} + +int +ntfs_82u_uninit(struct ntfsmount *ntmp) +{ + FREE(ntmp->ntm_82u, M_TEMP); + return (0); +} + /* * maps the Unicode char to 8bit equivalent * XXX currently only gets lower 8bit from the Unicode char @@ -2004,9 +2089,15 @@ ntfs_toupper_unuse() * something better has to be definitely though out */ char -ntfs_u28(unichar) - wchar unichar; +ntfs_u28( + struct ntfsmount *ntmp, + wchar wc) { - return (char) NTFS_U28(unichar); + char * p; + + p = ntmp->ntm_u28[(wc>>8)&0xFF]; + if (p == NULL) + return ('_'); + return (p[wc&0xFF]); } diff --git a/sys/fs/ntfs/ntfs_subr.h b/sys/fs/ntfs/ntfs_subr.h index 8f1480a..41a2dc7 100644 --- a/sys/fs/ntfs/ntfs_subr.h +++ b/sys/fs/ntfs/ntfs_subr.h @@ -84,7 +84,6 @@ int ntfs_filesize __P(( struct ntfsmount *, struct fnode *, u_int64_t *, u_int64 int ntfs_times __P(( struct ntfsmount *, struct ntnode *, ntfs_times_t *)); struct timespec ntfs_nttimetounix __P(( u_int64_t )); int ntfs_ntreaddir __P(( struct ntfsmount *, struct fnode *, u_int32_t, struct attr_indexentry **)); -char ntfs_u28 __P((wchar)); int ntfs_runtovrun __P(( cn_t **, cn_t **, u_long *, u_int8_t *)); int ntfs_attrtontvattr __P(( struct ntfsmount *, struct ntvattr **, struct attr * )); void ntfs_freentvattr __P(( struct ntvattr * )); @@ -108,3 +107,15 @@ int ntfs_toupper_use __P((struct mount *, struct ntfsmount *)); void ntfs_toupper_unuse __P((void)); int ntfs_fget __P((struct ntfsmount *, struct ntnode *, int, char *, struct fnode **)); void ntfs_frele __P((struct fnode *)); + +int ntfs_u28_init(struct ntfsmount *ntmp, wchar *u2w); +int ntfs_u28_uninit(struct ntfsmount *ntmp); +int ntfs_82u_init(struct ntfsmount *ntmp, u_int16_t *u2w); +int ntfs_82u_uninit(struct ntfsmount *ntmp); +char ntfs_u28(struct ntfsmount *ntmp, wchar wc); +#define NTFS_U28(ch) ntfs_u28(ntmp, (ch)) +#define NTFS_82U(ch) (ntmp->ntm_82u[(ch)&0xFF]) +#define NTFS_UASTRCMP(ustr, ustrlen, astr, astrlen) \ + ntfs_uastrcmp(ntmp, (ustr), (ustrlen), (astr), (astrlen)) +#define NTFS_UASTRICMP(ustr, ustrlen, astr, astrlen) \ + ntfs_uastricmp(ntmp, (ustr), (ustrlen), (astr), (astrlen)) diff --git a/sys/fs/ntfs/ntfs_vfsops.c b/sys/fs/ntfs/ntfs_vfsops.c index 94af95b..26a09b8 100644 --- a/sys/fs/ntfs/ntfs_vfsops.c +++ b/sys/fs/ntfs/ntfs_vfsops.c @@ -501,6 +501,17 @@ ntfs_mountfs(devvp, mp, argsp, p) ntmp->ntm_gid = argsp->gid; ntmp->ntm_mode = argsp->mode; ntmp->ntm_flag = argsp->flag; + + /* Copy in the 8-bit to Unicode conversion table */ + if (argsp->flag & NTFSMNT_U2WTABLE) { + ntfs_82u_init(ntmp, argsp->u2w); + } else { + ntfs_82u_init(ntmp, NULL); + } + + /* Initialize Unicode to 8-bit table from 8toU table */ + ntfs_u28_init(ntmp, ntmp->ntm_82u); + mp->mnt_data = (qaddr_t)ntmp; dprintf(("ntfs_mountfs(): case-%s,%s uid: %d, gid: %d, mode: %o\n", @@ -697,6 +708,8 @@ ntfs_unmount( ntfs_toupper_unuse(); dprintf(("ntfs_umount: freeing memory...\n")); + ntfs_u28_uninit(ntmp); + ntfs_82u_uninit(ntmp); mp->mnt_data = (qaddr_t)0; mp->mnt_flag &= ~MNT_LOCAL; FREE(ntmp->ntm_ad, M_NTFSMNT); diff --git a/sys/fs/ntfs/ntfs_vnops.c b/sys/fs/ntfs/ntfs_vnops.c index be192a1..5c2297f 100644 --- a/sys/fs/ntfs/ntfs_vnops.c +++ b/sys/fs/ntfs/ntfs_vnops.c @@ -586,7 +586,7 @@ ntfs_readdir(ap) continue; for(i=0; i<iep->ie_fnamelen; i++) { - cde.d_name[i] = ntfs_u28(iep->ie_fname[i]); + cde.d_name[i] = NTFS_U28(iep->ie_fname[i]); } cde.d_name[i] = '\0'; dprintf(("ntfs_readdir: elem: %d, fname:[%s] type: %d, flag: %d, ", diff --git a/sys/fs/ntfs/ntfsmount.h b/sys/fs/ntfs/ntfsmount.h index f3a6d25..0c143ed 100644 --- a/sys/fs/ntfs/ntfsmount.h +++ b/sys/fs/ntfs/ntfsmount.h @@ -30,6 +30,7 @@ #define NTFS_MFLAG_CASEINS 0x00000001 #define NTFS_MFLAG_ALLNAMES 0x00000002 +#define NTFSMNT_U2WTABLE 0x00000004 struct ntfs_args { char *fspec; /* block special device to mount */ @@ -38,4 +39,5 @@ struct ntfs_args { gid_t gid; /* gid that owns ntfs files */ mode_t mode; /* mask to be applied for ntfs perms */ u_long flag; /* additional flags */ + u_int16_t u2w[256]; /* Unix to Wchar */ }; |