Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/usr.sbin/fstyp fstyp: Use iconv(3) to convert NTFS vol label...



details:   https://anonhg.NetBSD.org/src/rev/6eeb0aeea719
branches:  trunk
changeset: 466629:6eeb0aeea719
user:      tkusumi <tkusumi%NetBSD.org@localhost>
date:      Sat Dec 28 08:22:30 2019 +0000

description:
fstyp: Use iconv(3) to convert NTFS vol labels correctly

taken-from: FreeBSD (freebsd/freebsd@23a4b310ffa90719eb9d11506bde1befab3c695f)

diffstat:

 usr.sbin/fstyp/fstyp.c |   6 ++--
 usr.sbin/fstyp/fstyp.h |   7 ++++-
 usr.sbin/fstyp/ntfs.c  |  75 ++++++++++++++++++++++++++++++++------------------
 3 files changed, 57 insertions(+), 31 deletions(-)

diffs (172 lines):

diff -r b99b31905569 -r 6eeb0aeea719 usr.sbin/fstyp/fstyp.c
--- a/usr.sbin/fstyp/fstyp.c    Sat Dec 28 08:00:08 2019 +0000
+++ b/usr.sbin/fstyp/fstyp.c    Sat Dec 28 08:22:30 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: fstyp.c,v 1.6 2019/12/28 08:00:08 tkusumi Exp $        */
+/*     $NetBSD: fstyp.c,v 1.7 2019/12/28 08:22:30 tkusumi Exp $        */
 
 /*-
  * Copyright (c) 2017 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
  *
  */
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: fstyp.c,v 1.6 2019/12/28 08:00:08 tkusumi Exp $");
+__RCSID("$NetBSD: fstyp.c,v 1.7 2019/12/28 08:22:30 tkusumi Exp $");
 
 #include <sys/disklabel.h>
 #include <sys/dkio.h>
@@ -74,7 +74,7 @@
        { "ext2fs", &fstyp_ext2fs, false, NULL },
        { "hfs+", &fstyp_hfsp, false, NULL },
        { "msdosfs", &fstyp_msdosfs, false, NULL },
-       { "ntfs", &fstyp_ntfs, false, NULL },
+       { "ntfs", &fstyp_ntfs, false, NTFS_ENC },
        { "ufs", &fstyp_ufs, false, NULL },
 #ifdef HAVE_ZFS
        { "zfs", &fstyp_zfs, true, NULL },
diff -r b99b31905569 -r 6eeb0aeea719 usr.sbin/fstyp/fstyp.h
--- a/usr.sbin/fstyp/fstyp.h    Sat Dec 28 08:00:08 2019 +0000
+++ b/usr.sbin/fstyp/fstyp.h    Sat Dec 28 08:22:30 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: fstyp.h,v 1.5 2019/12/28 08:00:08 tkusumi Exp $        */
+/*     $NetBSD: fstyp.h,v 1.6 2019/12/28 08:22:30 tkusumi Exp $        */
 
 /*-
  * Copyright (c) 2017 The NetBSD Foundation, Inc.
@@ -43,6 +43,11 @@
 
 /* The spec doesn't seem to permit UTF-16 surrogates; definitely LE. */
 #define        EXFAT_ENC       "UCS-2LE"
+/*
+ * NTFS itself is agnostic to encoding; it just stores 255 u16 wchars.  In
+ * practice, UTF-16 seems expected for NTFS.  (Maybe also for exFAT.)
+ */
+#define        NTFS_ENC        "UTF-16LE"
 
 extern bool    show_label;     /* -l flag */
 
diff -r b99b31905569 -r 6eeb0aeea719 usr.sbin/fstyp/ntfs.c
--- a/usr.sbin/fstyp/ntfs.c     Sat Dec 28 08:00:08 2019 +0000
+++ b/usr.sbin/fstyp/ntfs.c     Sat Dec 28 08:22:30 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ntfs.c,v 1.1 2018/01/09 03:31:15 christos Exp $        */
+/*     $NetBSD: ntfs.c,v 1.2 2019/12/28 08:22:30 tkusumi Exp $ */
 
 /*-
  * Copyright (c) 2017 The NetBSD Foundation, Inc.
@@ -35,8 +35,10 @@
  * SUCH DAMAGE.
  */
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: ntfs.c,v 1.1 2018/01/09 03:31:15 christos Exp $");
+__RCSID("$NetBSD: ntfs.c,v 1.2 2019/12/28 08:22:30 tkusumi Exp $");
 
+#include <err.h>
+#include <iconv.h>
 #include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -98,6 +100,38 @@
        uint32_t        bf_volsn;
 } __packed;
 
+static void
+convert_label(const void *label /* LE */, size_t labellen, char *label_out,
+    size_t label_sz)
+{
+       char *label_out_orig;
+       iconv_t cd;
+       size_t rc;
+
+       /* dstname="" means convert to the current locale. */
+       cd = iconv_open("", NTFS_ENC);
+       if (cd == (iconv_t)-1) {
+               warn("ntfs: Could not open iconv");
+               return;
+       }
+
+       label_out_orig = label_out;
+
+       rc = iconv(cd, __UNCONST(&label), &labellen, &label_out,
+           &label_sz);
+       if (rc == (size_t)-1) {
+               warn("ntfs: iconv()");
+               *label_out_orig = '\0';
+       } else {
+               /* NUL-terminate result (iconv advances label_out). */
+               if (label_sz == 0)
+                       label_out--;
+               *label_out = '\0';
+       }
+
+       iconv_close(cd);
+}
+
 int
 fstyp_ntfs(FILE *fp, char *label, size_t size)
 {
@@ -107,21 +141,22 @@
        off_t voloff;
        char *filerecp, *ap;
        int8_t mftrecsz;
-       char vnchar;
-       size_t recsize, j;
+       size_t recsize;
 
        filerecp = NULL;
 
        bf = read_buf(fp, 0, 512);
        if (bf == NULL || strncmp((char*)bf->bf_sysid, "NTFS    ", 8) != 0)
                goto fail;
+       if (!show_label)
+               goto ok;
 
        mftrecsz = bf->bf_mftrecsz;
        recsize = mftrecsz > 0 ? (size_t)(mftrecsz * bf->bf_bps * bf->bf_spc)
            : (size_t)(1 << -mftrecsz);
 
-       voloff = (off_t)(bf->bf_mftcn * bf->bf_spc * bf->bf_bps +
-           recsize * NTFS_VOLUMEINO);
+       voloff = (off_t)((off_t)bf->bf_mftcn * bf->bf_spc * bf->bf_bps +
+           (off_t)recsize * NTFS_VOLUMEINO);
 
        filerecp = read_buf(fp, voloff, recsize);
        if (filerecp == NULL)
@@ -134,29 +169,15 @@
        for (ap = filerecp + fr->fr_attroff;
            atr = (struct ntfs_attr *)ap, (int)atr->a_type != -1;
            ap += atr->reclen) {
-               if (atr->a_type == NTFS_A_VOLUMENAME) {
-                       if(atr->a_datalen >= size *2){
-                               goto fail;
-                       }
-                       /*
-                        * UNICODE to ASCII.
-                        * Should we need to use iconv(9)?
-                        */
-                       for (j = 0; j < atr->a_datalen; j++) {
-                               vnchar = *(ap + atr->a_dataoff + j);
-                               if (j & 1) {
-                                       if (vnchar) {
-                                               goto fail;
-                                       }
-                               } else {
-                                       label[j / 2] = vnchar;
-                               }
-                       }
-                       label[j / 2] = 0;
-                       break;
-               }
+               if (atr->a_type != NTFS_A_VOLUMENAME)
+                       continue;
+
+               convert_label(ap + atr->a_dataoff,
+                   atr->a_datalen, label, size);
+               break;
        }
 
+ok:
        free(bf);
        free(filerecp);
 



Home | Main Index | Thread Index | Old Index