From 88331f301c557f3d6c8c16765d8f44058fddf952 Mon Sep 17 00:00:00 2001 From: Alexander Polakov Date: Fri, 5 Jun 2009 12:29:46 +0400 Subject: [PATCH] Stage 5/5: Change mount_msdos to use libkiconv mount_msdos should be linked shared now, that's unusual for /sbin. --- sbin/mount_msdos/Makefile | 7 +- sbin/mount_msdos/mount_msdos.8 | 33 +------- sbin/mount_msdos/mount_msdos.c | 142 +++++++++++++-------------------- 3 files changed, 62 insertions(+), 120 deletions(-) diff --git a/sbin/mount_msdos/Makefile b/sbin/mount_msdos/Makefile index 59dd979a5d..d9651ee41c 100644 --- a/sbin/mount_msdos/Makefile +++ b/sbin/mount_msdos/Makefile @@ -7,10 +7,11 @@ PROG= mount_msdos SRCS= mount_msdos.c getmntopts.c MAN= mount_msdos.8 DPADD= ${LIBUTIL} -LDADD= -lutil +LDADD= -lutil -lkiconv -MOUNT= ${.CURDIR}/../mount -CFLAGS+= -I${MOUNT} +MOUNT= ${.CURDIR}/../mount +CFLAGS= -I${MOUNT} +NOSHARED= no .PATH: ${MOUNT} TABDIR= ${DESTDIR}${LIBDATADIR}/msdosfs diff --git a/sbin/mount_msdos/mount_msdos.8 b/sbin/mount_msdos/mount_msdos.8 index b503dd5cb3..5942c7c467 100644 --- a/sbin/mount_msdos/mount_msdos.8 +++ b/sbin/mount_msdos/mount_msdos.8 @@ -147,36 +147,9 @@ This forces Specify locale name used for internal uppercase and lowercase conversions for DOS and Win'95 names. By default ISO 8859-1 assumed as local character set. -.It Fl W Ar table -Specify text file with 3 conversion tables: -.Bl -enum -.It -Local character set to Unicode conversion table (upper half) for Win'95 long -names, 128 Unicode codes separated by 8 per row. -If some code not present in Unicode, use -0x003F code ('?') as replacement. -.It -DOS to local character set conversion table (upper half) for DOS names, -128 character codes separated by 8 per row. -Code 0x3F ('?') used for impossible translations. -.It -Local character set to DOS conversion table (upper half) for DOS names, -128 character codes separated by 8 per row. -Some codes have special meaning: -.Bl -hang -.It 0x00 -character disallowed in DOS file name; -.It 0x01 -character should be replaced by '_' in DOS file name; -.It 0x02 -character should be skipped in DOS file name; -.El -.El -.Pp -By default ISO 8859-1 assumed as local character set. -If file path isn't absolute, -.Pa /usr/libdata/msdosfs/ -prefix prepended. +.It Fl D Ar DOS_codepage +Specify the MS-DOS code page (aka IBM/OEM code page) name used for +file name conversions for DOS names. .El .Sh FILES .Bl -tag -width /usr/libdata/msdosfs -compact diff --git a/sbin/mount_msdos/mount_msdos.c b/sbin/mount_msdos/mount_msdos.c index 9a0b4a3653..d4693019ae 100644 --- a/sbin/mount_msdos/mount_msdos.c +++ b/sbin/mount_msdos/mount_msdos.c @@ -36,8 +36,13 @@ #include #include #include - +#include +#include +#include +#ifdef notyet #include +#endif +#include "../msdosfs/msdosfsmount.h" #include #include @@ -56,7 +61,7 @@ /* * XXX - no way to specify "foo="-type options; that's what we'd - * want for "-u", "-g", "-m", "-L", and "-W". + * want for "-u", "-g", "-m", "-L", and "-D". */ static struct mntopt mopts[] = { MOPT_STDOPTS, @@ -76,8 +81,7 @@ static gid_t a_gid(char *); static uid_t a_uid(char *); static mode_t a_mask(char *); static void usage(void) __dead2; -static void load_u2wtable(struct msdosfs_args *, char *); -static void load_ultable(struct msdosfs_args *, char *); +int set_charset(struct msdosfs_args*, const char*, const char*); int main(int argc, char **argv) @@ -85,14 +89,16 @@ main(int argc, char **argv) struct msdosfs_args args; struct stat sb; int c, error, mntflags, set_gid, set_uid, set_mask; - char *dev, *dir, mntpath[MAXPATHLEN]; + char *dev, *dir, mntpath[MAXPATHLEN], *csp; + const char *quirk = NULL; + char *cs_local = NULL; + char *cs_dos = NULL; struct vfsconf vfc; - mntflags = set_gid = set_uid = set_mask = 0; memset(&args, '\0', sizeof(args)); args.magic = MSDOSFS_ARGSMAGIC; - while ((c = getopt(argc, argv, "sl9u:g:m:o:L:W:")) != -1) { + while ((c = getopt(argc, argv, "sl9u:g:m:o:L:D:")) != -1) { switch (c) { #ifdef MSDOSFSMNT_GEMDOSFS case 'G': @@ -121,12 +127,19 @@ main(int argc, char **argv) set_mask = 1; break; case 'L': - load_ultable(&args, optarg); - args.flags |= MSDOSFSMNT_ULTABLE; + if (setlocale(LC_CTYPE, optarg) == NULL) + err(EX_CONFIG, "%s", optarg); + csp = strchr(optarg,'.'); + if (!csp) + err(EX_CONFIG, "%s", optarg); + quirk = kiconv_quirkcs(csp + 1, KICONV_VENDOR_MICSFT); + cs_local = strdup(quirk); + args.flags |= MSDOSFSMNT_KICONV; break; - case 'W': - load_u2wtable(&args, optarg); - args.flags |= MSDOSFSMNT_U2WTABLE; + case 'D': + csp = optarg; + cs_dos = strdup(optarg); + args.flags |= MSDOSFSMNT_KICONV; break; case 'o': getmntopts(optarg, mopts, &mntflags, &args.flags); @@ -153,6 +166,15 @@ main(int argc, char **argv) args.fspec = dev; args.export.ex_root = -2; /* unchecked anyway on DOS fs */ + + if (cs_local != NULL) { + if (set_charset(&args, cs_local, cs_dos) == -1) + err(EX_OSERR, "msdos_iconv"); + } else if (cs_dos != NULL) { + if (set_charset(&args, "ISO8859-1", cs_dos) == -1) + err(EX_OSERR, "msdos_iconv"); + } + if (mntflags & MNT_RDONLY) args.export.ex_flags = MNT_EXRDONLY; else @@ -245,84 +267,30 @@ usage(void) { fprintf(stderr, "%s\n%s\n", "usage: mount_msdos [-o options] [-u user] [-g group] [-m mask]", - " [-s] [-l] [-9] [-L locale] [-W table] bdev dir"); + " [-s] [-l] [-9] [-L locale] [-D codepage] bdev dir"); exit(EX_USAGE); } -static void -load_u2wtable (struct msdosfs_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 %zu", 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 %zu", 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 %zu", 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 %zu", 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 %zu", 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 %zu", i, line); - for (j = 0; j < 8; j++) - pargs->u2d[i * 8 + j] = code[j]; - } - free(p); - fclose(f); -} - -static void -load_ultable (struct msdosfs_args *pargs, char *name) +int +set_charset(struct msdosfs_args *args, const char *cs_local, const char *cs_dos) { - int i; - - if (setlocale(LC_CTYPE, name) == NULL) - err(EX_CONFIG, "%s", name); - for (i = 0; i < 128; i++) { - pargs->ul[i] = tolower(i | 0x80); - pargs->lu[i] = toupper(i | 0x80); + int error; + if (modfind("msdos_iconv") < 0) { + if (kldload("msdos_iconv") < 0 || modfind("msdos_iconv") < 0) + { + warnx("cannot find or load \"msdos_iconv\" kernel module"); + return (-1); + } } + snprintf(args->cs_local, ICONV_CSNMAXLEN, "%s", cs_local); + error = kiconv_add_xlat16_cspairs(ENCODING_UNICODE, cs_local); + if (error) + return (-1); + if (!cs_dos) + cs_dos = strdup("CP437"); + snprintf(args->cs_dos, ICONV_CSNMAXLEN, "%s", cs_dos); + error = kiconv_add_xlat16_cspairs(cs_dos, cs_local); + if (error) + return (-1); + return (0); } -- 2.41.0