- Support for multibyte charsets in LIBICONV.
- CD9660_ICONV, NTFS_ICONV and MSDOSFS_ICONV kernel options (with corresponding modules). - kiconv(3) for loadable charset conversion tables support. Submitted by: Ryuichiro Imura <imura@ryu16.org>
This commit is contained in:
parent
0c8bfb6d00
commit
571ef024e3
@ -43,6 +43,7 @@
|
||||
.ds doc-str-Lb-libfetch File Transfer Library (libfetch, \-lfetch)
|
||||
.ds doc-str-Lb-libgeom Userland API Library for kernel GEOM subsystem (libgeom, \-lgeom)
|
||||
.ds doc-str-Lb-libipx IPX Address Conversion Support Library (libipx, \-lipx)
|
||||
.ds doc-str-Lb-libkiconv Kernel side iconv library (libkiconv, \-lkiconv)
|
||||
.ds doc-str-Lb-libmd Message Digest (MD4, MD5, etc.) Support Library (libmd, \-lmd)
|
||||
.ds doc-str-Lb-libnetgraph Netgraph User Library (libnetgraph, \-lnetgraph)
|
||||
.ds doc-str-Lb-libpam PAM Library (libpam, \-lpam)
|
||||
|
@ -26,7 +26,7 @@ SUBDIR= ${_csu} libcom_err libcrypt libkvm msun libmd \
|
||||
${_compat} libalias ${_libatm} ${_libbind} libbz2 libc ${_libc_r} \
|
||||
libcalendar libcam libcompat libdevinfo libdevstat ${_libdisk} \
|
||||
libedit libexpat libfetch libform libftpio libgeom ${_libio} libipsec \
|
||||
libipx libisc libmenu ${_libmilter} ${_libmp} ${_libncp} \
|
||||
libipx libisc libkiconv libmenu ${_libmilter} ${_libmp} ${_libncp} \
|
||||
libnetgraph libopie libpam libpanel libpcap ${_libpthread} \
|
||||
${_libsm} ${_libsmb} ${_libsmdb} ${_libsmutil} \
|
||||
libstand libtelnet ${_libthr} libufs libugidfw ${_libusbhid} \
|
||||
|
17
lib/libkiconv/Makefile
Normal file
17
lib/libkiconv/Makefile
Normal file
@ -0,0 +1,17 @@
|
||||
# $FreeBSD$
|
||||
|
||||
LIB= kiconv
|
||||
SHLIBDIR?= /lib
|
||||
SRCS= xlat16_iconv.c xlat16_sysctl.c
|
||||
SRCS+= quirks.c
|
||||
|
||||
SHLIB_MAJOR= 1
|
||||
|
||||
MAN= kiconv.3
|
||||
|
||||
MLINKS+= kiconv.3 kiconv_add_xlat16_cspair.3 \
|
||||
kiconv.3 kiconv_add_xlat16_table.3
|
||||
|
||||
CFLAGS+= -I${.CURDIR}/../../sys
|
||||
|
||||
.include <bsd.lib.mk>
|
106
lib/libkiconv/kiconv.3
Normal file
106
lib/libkiconv/kiconv.3
Normal file
@ -0,0 +1,106 @@
|
||||
.\"
|
||||
.\" Copyright (c) 2003 Ryuichiro Imura
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd July 17, 2003
|
||||
.Dt KICONV 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm kiconv_add_xlat16_cspair ,
|
||||
.Nm kiconv_add_xlat16_table
|
||||
.Nd Kernel side iconv library
|
||||
.Sh LIBRARY
|
||||
.Lb libkiconv
|
||||
.Sh SYNOPSIS
|
||||
.In sys/iconv.h
|
||||
.Ft int
|
||||
.Fo kiconv_add_xlat16_cspair
|
||||
.Fa "const char *tocode"
|
||||
.Fa "const char *fromcode"
|
||||
.Fa "int flag"
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fo kiconv_add_xlat16_table
|
||||
.Fa "const char *tocode"
|
||||
.Fa "const char *fromcode"
|
||||
.Fa "const void *data"
|
||||
.Fa "int datalen"
|
||||
.Fc
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Xr kiconv 3
|
||||
library provides multi-byte character conversion tables for kernel side
|
||||
iconv service.
|
||||
.Pp
|
||||
.Fn kiconv_add_xlat16_cspair
|
||||
defines a conversion table using
|
||||
.Xr iconv 3
|
||||
between
|
||||
.Ar fromcode
|
||||
charset and
|
||||
.Ar tocode
|
||||
charset. You can specify
|
||||
.Ar flag
|
||||
to determine if
|
||||
.Xr tolower 3
|
||||
/
|
||||
.Xr toupper 3
|
||||
conversion is included in the table.
|
||||
The
|
||||
.Ar flag
|
||||
has following values.
|
||||
.Pp
|
||||
.Bl -tag -width "KICONV_FROM_LOWER" -compact
|
||||
.It Fa KICONV_LOWER
|
||||
.It Fa KICONV_FROM_LOWER
|
||||
It generates a tolower table in addition to a character conversion table.
|
||||
The difference between two is tolower
|
||||
.Ar tocode
|
||||
or tolower
|
||||
.Ar fromcode .
|
||||
.It Fa KICONV_UPPER
|
||||
.It Fa KICONV_FROM_UPPER
|
||||
It generates a toupper table in addition to a character conversion table.
|
||||
The difference between two is toupper
|
||||
.Ar tocode
|
||||
or toupper
|
||||
.Ar fromcode .
|
||||
.El
|
||||
.Pp
|
||||
A tolower/toupper conversion is limited to single-byte characters.
|
||||
.Pp
|
||||
.Fn kiconv_add_xlat16_table
|
||||
defines a conversion table directly pointed by
|
||||
.Ar data
|
||||
whose length is
|
||||
.Ar datalen ,
|
||||
not using
|
||||
.Xr iconv 3 .
|
||||
.Sh SEE ALSO
|
||||
.Xr iconv 3
|
||||
.Xr tolower 3
|
||||
.Xr toupper 3
|
||||
.Xr iconv 9
|
192
lib/libkiconv/quirks.c
Normal file
192
lib/libkiconv/quirks.c
Normal file
@ -0,0 +1,192 @@
|
||||
/*-
|
||||
* Copyright (c) 2003 Ryuichiro Imura
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
* kiconv(3) requires shared linked, and reduce module size
|
||||
* when statically linked.
|
||||
*/
|
||||
|
||||
#ifdef PIC
|
||||
|
||||
/*
|
||||
* Why do we need quirks?
|
||||
* Since each vendors has their own Unicode mapping rules,
|
||||
* we need some quirks until iconv(3) supports them.
|
||||
* We can define Microsoft mappings here.
|
||||
*
|
||||
* For example, the eucJP and Unocode mapping rule is based on
|
||||
* the JIS standard. Since Microsoft uses cp932 for Unicode mapping
|
||||
* witch is not truly based on the JIS standard, reading a file
|
||||
* system created by Microsoft Windows family using eucJP/Unicode
|
||||
* mapping rule will cause a problem. That's why we define eucJP-ms here.
|
||||
* The eucJP-ms has been defined by The Open Group Japan Vendor Coucil.
|
||||
*
|
||||
* Well, Apple Mac OS also has their own Unicode mappings,
|
||||
* but we won't require these quirks here, because HFS doesn't have
|
||||
* Unicode and HFS+ has decomposed Unicode which can not be
|
||||
* handled by this xlat16 converter.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/iconv.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "quirks.h"
|
||||
|
||||
/*
|
||||
* All lists of quirk character set
|
||||
*/
|
||||
static struct {
|
||||
int vendor; /* reserved for non MS mapping */
|
||||
const char *base_codeset, *quirk_codeset;
|
||||
} quirk_list[] = {
|
||||
{ KICONV_VENDOR_MICSFT, "eucJP", "eucJP-ms" },
|
||||
{ KICONV_VENDOR_MICSFT, "EUC-JP", "eucJP-ms" },
|
||||
{ KICONV_VENDOR_MICSFT, "SJIS", "SJIS-ms" },
|
||||
{ KICONV_VENDOR_MICSFT, "Shift_JIS", "SJIS-ms" },
|
||||
{ KICONV_VENDOR_MICSFT, "Big5", "Big5-ms" }
|
||||
};
|
||||
|
||||
/*
|
||||
* The character list to replace for Japanese MS-Windows.
|
||||
*/
|
||||
static struct quirk_replace_list quirk_jis_cp932[] = {
|
||||
{ 0x00a2, 0xffe0 }, /* Cent Sign, Fullwidth Cent Sign */
|
||||
{ 0x00a3, 0xffe1 }, /* Pound Sign, Fullwidth Pound Sign */
|
||||
{ 0x00ac, 0xffe2 }, /* Not Sign, Fullwidth Not Sign */
|
||||
{ 0x2016, 0x2225 }, /* Double Vertical Line, Parallel To */
|
||||
{ 0x203e, 0x007e }, /* Overline, Tilde */
|
||||
{ 0x2212, 0xff0d }, /* Minus Sign, Fullwidth Hyphenminus */
|
||||
{ 0x301c, 0xff5e } /* Wave Dash, Fullwidth Tilde */
|
||||
};
|
||||
|
||||
/*
|
||||
* All entries of quirks
|
||||
*/
|
||||
#define NumOf(n) (sizeof((n)) / sizeof((n)[0]))
|
||||
static struct {
|
||||
const char *quirk_codeset, *iconv_codeset, *pair_codeset;
|
||||
struct quirk_replace_list (*replace_list)[];
|
||||
size_t num_of_replaces;
|
||||
} quirk_table[] = {
|
||||
{
|
||||
"eucJP-ms", "eucJP", ENCODING_UNICODE,
|
||||
(struct quirk_replace_list (*)[])&quirk_jis_cp932,
|
||||
NumOf(quirk_jis_cp932)
|
||||
},
|
||||
{
|
||||
"SJIS-ms", "CP932", ENCODING_UNICODE,
|
||||
/* XXX - quirk_replace_list should be NULL */
|
||||
(struct quirk_replace_list (*)[])&quirk_jis_cp932,
|
||||
NumOf(quirk_jis_cp932)
|
||||
},
|
||||
{
|
||||
"Big5-ms", "CP950", ENCODING_UNICODE,
|
||||
NULL, 0
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const char *
|
||||
kiconv_quirkcs(const char* base, int vendor)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
/*
|
||||
* We should compare codeset names ignoring case here,
|
||||
* so that quirk could be used for all of the user input
|
||||
* patterns.
|
||||
*/
|
||||
for (i = 0; i < NumOf(quirk_list); i++)
|
||||
if (quirk_list[i].vendor == vendor &&
|
||||
strcasecmp(quirk_list[i].base_codeset, base) == 0)
|
||||
return (quirk_list[i].quirk_codeset);
|
||||
|
||||
return (base);
|
||||
}
|
||||
|
||||
/*
|
||||
* Internal Functions
|
||||
*/
|
||||
const char *
|
||||
search_quirk(const char *given_codeset,
|
||||
const char *pair_codeset,
|
||||
struct quirk_replace_list **replace_list,
|
||||
size_t *num_of_replaces)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
*replace_list = NULL;
|
||||
*num_of_replaces = 0;
|
||||
for (i = 0; i < NumOf(quirk_table); i++)
|
||||
if (strcmp(quirk_table[i].quirk_codeset, given_codeset) == 0) {
|
||||
if (strcmp(quirk_table[i].pair_codeset, pair_codeset) == 0) {
|
||||
*replace_list = *quirk_table[i].replace_list;
|
||||
*num_of_replaces = quirk_table[i].num_of_replaces;
|
||||
}
|
||||
return (quirk_table[i].iconv_codeset);
|
||||
}
|
||||
|
||||
return (given_codeset);
|
||||
}
|
||||
|
||||
uint16_t
|
||||
quirk_vendor2unix(uint16_t c, struct quirk_replace_list *replace_list, size_t num)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < num; i++)
|
||||
if (replace_list[i].vendor_code == c)
|
||||
return (replace_list[i].standard_code);
|
||||
|
||||
return (c);
|
||||
}
|
||||
|
||||
uint16_t
|
||||
quirk_unix2vendor(uint16_t c, struct quirk_replace_list *replace_list, size_t num)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < num; i++)
|
||||
if (replace_list[i].standard_code == c)
|
||||
return (replace_list[i].vendor_code);
|
||||
|
||||
return (c);
|
||||
}
|
||||
|
||||
#else /* statically linked */
|
||||
|
||||
const char *
|
||||
kiconv_quirkcs(const char* base, int vendor)
|
||||
{
|
||||
return (base);
|
||||
}
|
||||
|
||||
#endif /* PIC */
|
45
lib/libkiconv/quirks.h
Normal file
45
lib/libkiconv/quirks.h
Normal file
@ -0,0 +1,45 @@
|
||||
/*-
|
||||
* Copyright (c) 2003 Ryuichiro Imura
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _KICONV_QUIRKS_H_
|
||||
#define _KICONV_QUIRKS_H_
|
||||
|
||||
struct quirk_replace_list {
|
||||
uint16_t standard_code, vendor_code;
|
||||
};
|
||||
|
||||
const char *search_quirk(const char *, const char *,
|
||||
struct quirk_replace_list **, size_t *);
|
||||
uint16_t quirk_vendor2unix(uint16_t,
|
||||
struct quirk_replace_list *,
|
||||
size_t);
|
||||
uint16_t quirk_unix2vendor(uint16_t,
|
||||
struct quirk_replace_list *,
|
||||
size_t);
|
||||
|
||||
#endif /* _KICONV_QUIRKS_H_ */
|
374
lib/libkiconv/xlat16_iconv.c
Normal file
374
lib/libkiconv/xlat16_iconv.c
Normal file
@ -0,0 +1,374 @@
|
||||
/*-
|
||||
* Copyright (c) 2003 Ryuichiro Imura
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
* kiconv(3) requires shared linked, and reduce module size
|
||||
* when statically linked.
|
||||
*/
|
||||
|
||||
#ifdef PIC
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/iconv.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <dlfcn.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "quirks.h"
|
||||
|
||||
typedef void *iconv_t;
|
||||
|
||||
struct xlat16_table {
|
||||
uint32_t * idx[0x200];
|
||||
void * data;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
static struct xlat16_table kiconv_xlat16_open(const char *, const char *, int);
|
||||
|
||||
static int my_iconv_init(void);
|
||||
static iconv_t (*my_iconv_open)(const char *, const char *);
|
||||
static size_t (*my_iconv)(iconv_t, const char **, size_t *, char **, size_t *);
|
||||
static int (*my_iconv_close)(iconv_t);
|
||||
static size_t my_iconv_char(iconv_t, const u_char **, size_t *, u_char **, size_t *);
|
||||
|
||||
int
|
||||
kiconv_add_xlat16_cspair(const char *tocode, const char *fromcode, int flag)
|
||||
{
|
||||
int error;
|
||||
size_t i, size, idxsize;
|
||||
struct iconv_cspair_info *csi;
|
||||
struct xlat16_table xt;
|
||||
void *data, *p;
|
||||
|
||||
if (sysctlbyname("kern.iconv.cslist", NULL, &size, NULL, 0) == -1)
|
||||
return (-1);
|
||||
if (size > 0) {
|
||||
csi = malloc(size);
|
||||
if (csi == NULL)
|
||||
return (-1);
|
||||
if (sysctlbyname("kern.iconv.cslist", csi, &size, NULL, 0) == -1) {
|
||||
free(csi);
|
||||
return (-1);
|
||||
}
|
||||
for (i = 0; i < (size/sizeof(*csi)); i++, csi++){
|
||||
if (strcmp(csi->cs_to, tocode) == 0 &&
|
||||
strcmp(csi->cs_from, fromcode) == 0)
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
xt = kiconv_xlat16_open(tocode, fromcode, flag);
|
||||
if (xt.size == 0)
|
||||
return (-1);
|
||||
|
||||
idxsize = sizeof(xt.idx);
|
||||
|
||||
if ((idxsize + xt.size) > ICONV_CSMAXDATALEN) {
|
||||
errno = E2BIG;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if ((data = malloc(idxsize + xt.size)) != NULL) {
|
||||
p = data;
|
||||
memcpy(p, xt.idx, idxsize);
|
||||
p += idxsize;
|
||||
memcpy(p, xt.data, xt.size);
|
||||
error = kiconv_add_xlat16_table(tocode, fromcode, data,
|
||||
(int)(idxsize + xt.size));
|
||||
return (error);
|
||||
}
|
||||
|
||||
return (-1);
|
||||
}
|
||||
|
||||
static struct xlat16_table
|
||||
kiconv_xlat16_open(const char *tocode, const char *fromcode, int lcase)
|
||||
{
|
||||
u_char src[3], dst[4], *srcp, *dstp, ud, ld;
|
||||
int us, ls, ret;
|
||||
uint16_t c;
|
||||
uint32_t table[0x80];
|
||||
size_t inbytesleft, outbytesleft, pre_q_size, post_q_size;
|
||||
struct xlat16_table xt;
|
||||
struct quirk_replace_list *pre_q_list, *post_q_list;
|
||||
iconv_t cd;
|
||||
void *p;
|
||||
|
||||
xt.data = NULL;
|
||||
xt.size = 0;
|
||||
|
||||
src[2] = NULL;
|
||||
dst[3] = NULL;
|
||||
|
||||
ret = my_iconv_init();
|
||||
if (ret)
|
||||
return (xt);
|
||||
|
||||
cd = my_iconv_open(search_quirk(tocode, fromcode, &pre_q_list, &pre_q_size),
|
||||
search_quirk(fromcode, tocode, &post_q_list, &post_q_size));
|
||||
if (cd == (iconv_t) (-1))
|
||||
return (xt);
|
||||
|
||||
if ((xt.data = malloc(0x200 * 0x80 * sizeof(uint32_t))) == NULL)
|
||||
return (xt);
|
||||
|
||||
p = xt.data;
|
||||
|
||||
for (ls = 0 ; ls < 0x200 ; ls++) {
|
||||
xt.idx[ls] = NULL;
|
||||
for (us = 0 ; us < 0x80 ; us++) {
|
||||
srcp = src;
|
||||
dstp = dst;
|
||||
|
||||
inbytesleft = 2;
|
||||
outbytesleft = 3;
|
||||
bzero(dst, outbytesleft);
|
||||
|
||||
c = ((ls & 0x100 ? us | 0x80 : us) << 8) | (u_char)ls;
|
||||
c = quirk_vendor2unix(c, pre_q_list, pre_q_size);
|
||||
src[0] = (u_char)(c >> 8);
|
||||
src[1] = (u_char)c;
|
||||
|
||||
ret = my_iconv_char(cd, (const u_char **)&srcp,
|
||||
&inbytesleft, &dstp, &outbytesleft);
|
||||
if (ret == -1) {
|
||||
table[us] = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
ud = (u_char)dst[0];
|
||||
ld = (u_char)dst[1];
|
||||
|
||||
switch(outbytesleft) {
|
||||
case 0:
|
||||
#ifdef XLAT16_ACCEPT_3BYTE_CHR
|
||||
table[us] = (ud << 8) | ld;
|
||||
table[us] |= (u_char)dst[2] << 16;
|
||||
table[us] |= XLAT16_IS_3BYTE_CHR;
|
||||
#else
|
||||
table[us] = 0;
|
||||
continue;
|
||||
#endif
|
||||
break;
|
||||
case 1:
|
||||
table[us] = quirk_unix2vendor((ud << 8) | ld,
|
||||
post_q_list, post_q_size);
|
||||
if ((table[us] >> 8) == 0)
|
||||
table[us] |= XLAT16_ACCEPT_NULL_OUT;
|
||||
break;
|
||||
case 2:
|
||||
table[us] = ud;
|
||||
if (lcase & KICONV_LOWER && ud != tolower(ud)) {
|
||||
table[us] |= (u_char)tolower(ud) << 16;
|
||||
table[us] |= XLAT16_HAS_LOWER_CASE;
|
||||
}
|
||||
if (lcase & KICONV_UPPER && ud != toupper(ud)) {
|
||||
table[us] |= (u_char)toupper(ud) << 16;
|
||||
table[us] |= XLAT16_HAS_UPPER_CASE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
switch(inbytesleft) {
|
||||
case 0:
|
||||
if ((ls & 0xff) == 0)
|
||||
table[us] |= XLAT16_ACCEPT_NULL_IN;
|
||||
break;
|
||||
case 1:
|
||||
c = ls > 0xff ? us | 0x80 : us;
|
||||
if (lcase & KICONV_FROM_LOWER && c != tolower(c)) {
|
||||
table[us] |= (u_char)tolower(c) << 16;
|
||||
table[us] |= XLAT16_HAS_FROM_LOWER_CASE;
|
||||
}
|
||||
if (lcase & KICONV_FROM_UPPER && c != toupper(c)) {
|
||||
table[us] |= (u_char)toupper(c) << 16;
|
||||
table[us] |= XLAT16_HAS_FROM_UPPER_CASE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (table[us] == 0)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* store not NULL
|
||||
*/
|
||||
xt.idx[ls] = table;
|
||||
}
|
||||
if (xt.idx[ls]) {
|
||||
memcpy(p, table, sizeof(table));
|
||||
p += sizeof(table);
|
||||
}
|
||||
}
|
||||
my_iconv_close(cd);
|
||||
|
||||
xt.size = p - xt.data;
|
||||
xt.data = realloc(xt.data, xt.size);
|
||||
return (xt);
|
||||
}
|
||||
|
||||
static int
|
||||
my_iconv_init(void)
|
||||
{
|
||||
void *iconv_lib;
|
||||
|
||||
iconv_lib = dlopen("libiconv.so", RTLD_LAZY | RTLD_GLOBAL);
|
||||
if (iconv_lib == NULL) {
|
||||
warn("Unable to load iconv library: %s\n", dlerror());
|
||||
errno = ENOENT;
|
||||
return (-1);
|
||||
}
|
||||
my_iconv_open = dlsym(iconv_lib, "iconv_open");
|
||||
my_iconv = dlsym(iconv_lib, "iconv");
|
||||
my_iconv_close = dlsym(iconv_lib, "iconv_close");
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static size_t
|
||||
my_iconv_char(iconv_t cd, const u_char **ibuf, size_t * ilen, u_char **obuf,
|
||||
size_t * olen)
|
||||
{
|
||||
const u_char *sp;
|
||||
u_char *dp, ilocal[3], olocal[3];
|
||||
u_char c1, c2;
|
||||
int ret;
|
||||
size_t ir, or;
|
||||
|
||||
sp = *ibuf;
|
||||
dp = *obuf;
|
||||
ir = *ilen;
|
||||
|
||||
bzero(*obuf, *olen);
|
||||
ret = my_iconv(cd, (const char **)&sp, ilen, (char **)&dp, olen);
|
||||
c1 = (*obuf)[0];
|
||||
c2 = (*obuf)[1];
|
||||
|
||||
if (ret == -1) {
|
||||
if (*ilen == ir - 1 && (*ibuf)[1] == '\0' && (c1 || c2))
|
||||
return (0);
|
||||
else
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* We must judge if inbuf is a single byte char or double byte char.
|
||||
* Here, to judge, try first byte(*sp) conversion and compare.
|
||||
*/
|
||||
ir = 1;
|
||||
or = 3;
|
||||
|
||||
bzero(olocal, or);
|
||||
memcpy(ilocal, *ibuf, sizeof(ilocal));
|
||||
sp = ilocal;
|
||||
dp = olocal;
|
||||
|
||||
if ((my_iconv(cd,(const char **)&sp, &ir, (char **)&dp, &or)) != -1) {
|
||||
if (olocal[0] != c1)
|
||||
return (ret);
|
||||
|
||||
if (olocal[1] == c2 && (*ibuf)[1] == '\0') {
|
||||
/*
|
||||
* inbuf is a single byte char
|
||||
*/
|
||||
*ilen = 1;
|
||||
*olen = or;
|
||||
return (ret);
|
||||
}
|
||||
|
||||
switch(or) {
|
||||
case 0:
|
||||
case 1:
|
||||
if (olocal[1] == c2) {
|
||||
/*
|
||||
* inbuf is a single byte char,
|
||||
* so return false here.
|
||||
*/
|
||||
return (-1);
|
||||
} else {
|
||||
/*
|
||||
* inbuf is a double byte char
|
||||
*/
|
||||
return (ret);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
/*
|
||||
* should compare second byte of inbuf
|
||||
*/
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* inbuf clould not be splitted, so inbuf is
|
||||
* a double byte char.
|
||||
*/
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* try second byte(*(sp+1)) conversion, and compare
|
||||
*/
|
||||
ir = 1;
|
||||
or = 3;
|
||||
|
||||
bzero(olocal, or);
|
||||
|
||||
sp = ilocal + 1;
|
||||
dp = olocal;
|
||||
|
||||
if ((my_iconv(cd,(const char **)&sp, &ir, (char **)&dp, &or)) != -1) {
|
||||
if (olocal[0] == c2)
|
||||
/*
|
||||
* inbuf is a single byte char
|
||||
*/
|
||||
return (-1);
|
||||
}
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
#else /* statically linked */
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
int
|
||||
kiconv_add_xlat16_cspair(const char *tocode, const char *fromcode, int flag)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
#endif /* PIC */
|
81
lib/libkiconv/xlat16_sysctl.c
Normal file
81
lib/libkiconv/xlat16_sysctl.c
Normal file
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (c) 2000-2001, Boris Popov
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Boris Popov.
|
||||
* 4. Neither the name of the author nor the names of any co-contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
* kiconv(3) requires shared linked, and reduce module size
|
||||
* when statically linked.
|
||||
*/
|
||||
|
||||
#ifdef PIC
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/iconv.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
int
|
||||
kiconv_add_xlat16_table(const char *to, const char *from, const void *data, int datalen)
|
||||
{
|
||||
struct iconv_add_in din;
|
||||
struct iconv_add_out dout;
|
||||
size_t olen;
|
||||
|
||||
if (strlen(from) > ICONV_CSNMAXLEN || strlen(to) > ICONV_CSNMAXLEN)
|
||||
return (EINVAL);
|
||||
din.ia_version = ICONV_ADD_VER;
|
||||
strcpy(din.ia_converter, "xlat16");
|
||||
strcpy(din.ia_from, from);
|
||||
strcpy(din.ia_to, to);
|
||||
din.ia_data = data;
|
||||
din.ia_datalen = datalen;
|
||||
olen = sizeof(dout);
|
||||
if (sysctlbyname("kern.iconv.add", &dout, &olen, &din, sizeof(din)) == -1)
|
||||
return (errno);
|
||||
return (0);
|
||||
}
|
||||
|
||||
#else /* statically linked */
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
int
|
||||
kiconv_add_xlat16_table(const char *to, const char *from, const void *data, int datalen)
|
||||
{
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
#endif /* PIC */
|
@ -22,4 +22,4 @@ srcdirs /usr/src/usr.sbin
|
||||
progs chown chroot
|
||||
ln chown chgrp
|
||||
|
||||
libs -ledit -lgeom -lkvm -lm -lncurses -lutil
|
||||
libs -ledit -lgeom -lkiconv -lkvm -lm -lncurses -lutil
|
||||
|
@ -26,4 +26,4 @@ progs arp ppp
|
||||
progs sysinstall
|
||||
|
||||
libs -ll -ledit -lutil -lkvm -lmd -lcrypt -lftpio -lz -lnetgraph
|
||||
libs -ldialog -lncurses -ldisk -lufs
|
||||
libs -ldialog -lncurses -ldisk -lufs -lkiconv
|
||||
|
@ -23,4 +23,4 @@ srcdirs /usr/src/usr.sbin
|
||||
progs chown chroot
|
||||
ln chown chgrp
|
||||
|
||||
libs -ledit -lgeom -lkvm -lm -lncurses -lutil
|
||||
libs -ledit -lgeom -lkiconv -lkvm -lm -lncurses -lutil
|
||||
|
@ -24,4 +24,4 @@ srcdirs /usr/src/usr.sbin
|
||||
progs chown chroot
|
||||
ln chown chgrp
|
||||
|
||||
libs -ledit -lgeom -lkvm -lm -lncurses -lutil
|
||||
libs -ledit -lgeom -lkiconv -lkvm -lm -lncurses -lutil
|
||||
|
@ -135,7 +135,7 @@ CRUNCH_PROGS_sbin+= ipf ipfs ipfstat ipmon ipnat
|
||||
# CRUNCH_PROGS+= devd
|
||||
|
||||
CRUNCH_LIBS+= -lalias -lbsdxml -lcam -lcurses -ldevstat -lipsec -lipx \
|
||||
-lgeom -lmd -lreadline -lsbuf -lufs -lz
|
||||
-lgeom -lkiconv -lmd -lreadline -lsbuf -lufs -lz
|
||||
|
||||
.if ${MACHINE_ARCH} == "i386"
|
||||
CRUNCH_PROGS_sbin+= cxconfig fdisk
|
||||
|
@ -4,11 +4,17 @@
|
||||
PROG= mount_cd9660
|
||||
SRCS= mount_cd9660.c getmntopts.c
|
||||
MAN= mount_cd9660.8
|
||||
DPADD= ${LIBKICONV}
|
||||
LDADD= -lkiconv
|
||||
|
||||
MOUNT= ${.CURDIR}/../mount
|
||||
CFLAGS+= -I${MOUNT}
|
||||
WARNS= 0
|
||||
|
||||
# Needs to be dynamically linked for optional dlopen() access to
|
||||
# userland libiconv
|
||||
NOSHARED?= NO
|
||||
|
||||
.PATH: ${MOUNT}
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
@ -47,6 +47,7 @@
|
||||
.Op Fl begjrv
|
||||
.Op Fl o Ar options
|
||||
.Op Fl s Ar startsector
|
||||
.Op Fl C Ar charset
|
||||
.Ar special | node
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
@ -123,6 +124,10 @@ It is possible to mount an arbitrary session of a multi-session CD by specifying
|
||||
the correct
|
||||
.Ar startsector
|
||||
here.
|
||||
.It Fl C Ar charset
|
||||
Specify local
|
||||
.Ar charset
|
||||
to convert Unicode file names when using Joliet extensions.
|
||||
.It Fl v
|
||||
Be verbose about the starting sector decisions made.
|
||||
.El
|
||||
@ -150,3 +155,7 @@ The
|
||||
.Nm
|
||||
utility first appeared in
|
||||
.Bx 4.4 .
|
||||
.Pp
|
||||
The unicode conversion routine was added by
|
||||
.An Ryuichiro Imura Aq imura@ryu16.org
|
||||
at 2003.
|
||||
|
@ -57,6 +57,8 @@ static const char rcsid[] =
|
||||
#include <sys/param.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/../isofs/cd9660/cd9660_mount.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/iconv.h>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
|
||||
@ -82,6 +84,7 @@ struct mntopt mopts[] = {
|
||||
};
|
||||
|
||||
int get_ssector(const char *dev);
|
||||
int set_charset(struct iso_args *, const char *);
|
||||
void usage(void);
|
||||
|
||||
int
|
||||
@ -95,7 +98,9 @@ main(int argc, char **argv)
|
||||
mntflags = opts = verbose = 0;
|
||||
memset(&args, 0, sizeof args);
|
||||
args.ssector = -1;
|
||||
while ((ch = getopt(argc, argv, "begjo:rs:v")) != -1)
|
||||
args.cs_disk = NULL;
|
||||
args.cs_local = NULL;
|
||||
while ((ch = getopt(argc, argv, "begjo:rs:vC:")) != -1)
|
||||
switch (ch) {
|
||||
case 'b':
|
||||
opts |= ISOFSMNT_BROKENJOLIET;
|
||||
@ -121,6 +126,11 @@ main(int argc, char **argv)
|
||||
case 'v':
|
||||
verbose++;
|
||||
break;
|
||||
case 'C':
|
||||
if (set_charset(&args, optarg) == -1)
|
||||
err(EX_OSERR, "cd9660_iconv");
|
||||
opts |= ISOFSMNT_KICONV;
|
||||
break;
|
||||
case '?':
|
||||
default:
|
||||
usage();
|
||||
@ -180,7 +190,7 @@ void
|
||||
usage(void)
|
||||
{
|
||||
(void)fprintf(stderr,
|
||||
"usage: mount_cd9660 [-egrv] [-o options] [-s startsector] special node\n");
|
||||
"usage: mount_cd9660 [-egrv] [-o options] [-s startsector] [-C charset ] special node\n");
|
||||
exit(EX_USAGE);
|
||||
}
|
||||
|
||||
@ -225,3 +235,31 @@ get_ssector(const char *dev)
|
||||
|
||||
return ntohl(toc_buffer[i].addr.lba);
|
||||
}
|
||||
|
||||
int
|
||||
set_charset(struct iso_args *args, const char *localcs)
|
||||
{
|
||||
int error;
|
||||
|
||||
if (modfind("cd9660_iconv") < 0)
|
||||
if (kldload("cd9660_iconv") < 0 || modfind("cd9660_iconv") < 0) {
|
||||
warnx( "cannot find or load \"cd9660_iconv\" kernel module");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if ((args->cs_disk = malloc(ICONV_CSNMAXLEN)) == NULL)
|
||||
return (-1);
|
||||
if ((args->cs_local = malloc(ICONV_CSNMAXLEN)) == NULL)
|
||||
return (-1);
|
||||
strncpy(args->cs_disk, ENCODING_UNICODE, ICONV_CSNMAXLEN);
|
||||
strncpy(args->cs_local, kiconv_quirkcs(localcs, KICONV_VENDOR_MICSFT),
|
||||
ICONV_CSNMAXLEN);
|
||||
error = kiconv_add_xlat16_cspair(args->cs_local, args->cs_disk, 0);
|
||||
if (error)
|
||||
return (-1);
|
||||
error = kiconv_add_xlat16_cspair(args->cs_disk, args->cs_local, 0);
|
||||
if (error)
|
||||
return (-1);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
@ -5,21 +5,17 @@
|
||||
PROG= mount_msdosfs
|
||||
SRCS= mount_msdosfs.c getmntopts.c
|
||||
MAN= mount_msdosfs.8
|
||||
DPADD= ${LIBUTIL}
|
||||
LDADD= -lutil
|
||||
DPADD= ${LIBKICONV}
|
||||
LDADD= -lkiconv
|
||||
|
||||
MOUNT= ${.CURDIR}/../mount
|
||||
CFLAGS+= -I${MOUNT}
|
||||
WARNS= 0
|
||||
|
||||
# Needs to be dynamically linked for optional dlopen() access to
|
||||
# userland libiconv
|
||||
NOSHARED?= NO
|
||||
|
||||
.PATH: ${MOUNT}
|
||||
|
||||
TABDIR= ${DESTDIR}${LIBDATADIR}/msdosfs
|
||||
TABLES= iso22dos iso72dos koi2dos koi8u2dos
|
||||
|
||||
afterinstall:
|
||||
cd ${.CURDIR} && \
|
||||
${INSTALL} -o ${BINOWN} -g ${BINGRP} -m ${SHAREMODE} \
|
||||
${TABLES} ${TABDIR}
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
@ -1,58 +0,0 @@
|
||||
# $FreeBSD$
|
||||
#
|
||||
# u2w: 16 rows of Latin2 -> Unicode conversion table (upper half)
|
||||
#
|
||||
0x0080 0x0081 0x0082 0x0083 0x0084 0x0085 0x0086 0x0087
|
||||
0x0088 0x0089 0x008a 0x008b 0x008c 0x008d 0x008e 0x008f
|
||||
0x0090 0x0091 0x0092 0x0093 0x0094 0x0095 0x0096 0x0097
|
||||
0x0098 0x0099 0x009a 0x009b 0x009c 0x009d 0x009e 0x009f
|
||||
0x00a0 0x0104 0x02d8 0x0141 0x00a4 0x013d 0x015a 0x00a7
|
||||
0x00a8 0x0160 0x015e 0x0164 0x0179 0x00ad 0x017d 0x017b
|
||||
0x00b0 0x0105 0x02db 0x0142 0x00b4 0x013e 0x015b 0x02c7
|
||||
0x00b8 0x0161 0x015f 0x0165 0x017a 0x02dd 0x017e 0x017c
|
||||
0x0154 0x00c1 0x00c2 0x0102 0x00c4 0x0139 0x0106 0x00c7
|
||||
0x010c 0x00c9 0x0118 0x00cb 0x011a 0x00cd 0x00ce 0x010e
|
||||
0x0110 0x0143 0x0147 0x00d3 0x00d4 0x0150 0x00d6 0x00d7
|
||||
0x0158 0x016e 0x00da 0x0170 0x00dc 0x00dd 0x0162 0x00df
|
||||
0x0155 0x00e1 0x00e2 0x0103 0x00e4 0x013a 0x0107 0x00e7
|
||||
0x010d 0x00e9 0x0119 0x00eb 0x011b 0x00ed 0x00ee 0x010f
|
||||
0x0111 0x0144 0x0148 0x00f3 0x00f4 0x0151 0x00f6 0x00f7
|
||||
0x0159 0x016f 0x00fa 0x0171 0x00fc 0x00fd 0x0163 0x02d9
|
||||
#
|
||||
# d2u: 16 rows of CP852 -> Latin2 conversion table (upper half)
|
||||
#
|
||||
0xc7 0xfc 0xe9 0xe2 0xe4 0xf9 0xe6 0xe7
|
||||
0xb3 0xeb 0xd5 0xf5 0xee 0xac 0xc4 0xc6
|
||||
0xc9 0xc5 0xe5 0xf4 0xf6 0xa5 0xb5 0xa6
|
||||
0xb6 0xd6 0xdc 0xab 0xbb 0xa3 0xd7 0xe8
|
||||
0xe1 0xed 0xf3 0xfa 0xa1 0xb1 0xae 0xbe
|
||||
0xca 0xea 0x3f 0xbc 0xc8 0xba 0x3f 0x3f
|
||||
0x3f 0x3f 0x3f 0x3f 0x3f 0xc1 0xc2 0xcc
|
||||
0xaa 0x3f 0x3f 0x3f 0x3f 0xaf 0xbf 0x3f
|
||||
0x3f 0x3f 0x3f 0x3f 0x3f 0x3f 0xc3 0xe3
|
||||
0x3f 0x3f 0x3f 0x3f 0x3f 0x3f 0x3f 0xa4
|
||||
0xf0 0xd0 0xcf 0xcb 0xef 0xd2 0xcd 0xce
|
||||
0xec 0x3f 0x3f 0x3f 0x3f 0xde 0xd9 0x3f
|
||||
0xd3 0xdf 0xd4 0xd1 0xf1 0xf2 0xa9 0xb9
|
||||
0xc0 0xda 0xe0 0xdb 0xfd 0xdd 0xfe 0xb4
|
||||
0xad 0xbd 0xb2 0xb7 0xa2 0xa7 0xf7 0xb8
|
||||
0xb0 0xa8 0xff 0xfb 0xd8 0xf8 0x3f 0xa0
|
||||
#
|
||||
# u2d: 16 rows of Latin2 -> CP852 conversion table (upper half)
|
||||
#
|
||||
0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0
|
||||
0xff 0xa4 0xf4 0x9d 0xcf 0x95 0x97 0xf5
|
||||
0xf9 0xe6 0xb8 0x9b 0x8d 0xf0 0xa6 0xbd
|
||||
0xf8 0xa5 0xf2 0x88 0xef 0x96 0x98 0xf3
|
||||
0xf7 0xe7 0xad 0x9c 0xab 0xf1 0xa7 0xbe
|
||||
0xe8 0xb5 0xb6 0xc6 0x8e 0x91 0x8f 0x80
|
||||
0xac 0x90 0xa8 0xd3 0xb7 0xd6 0xd7 0xd2
|
||||
0xd1 0xe3 0xd5 0xe0 0xe2 0x8a 0x99 0x9e
|
||||
0xfc 0xde 0xe9 0xeb 0x9a 0xed 0xdd 0xe1
|
||||
0xea 0xa0 0x83 0xc7 0x84 0x92 0x86 0x87
|
||||
0x9f 0x82 0xa9 0x89 0xd8 0xa1 0x8c 0xd4
|
||||
0xd0 0xe4 0xe5 0xa2 0x93 0x8b 0x94 0xf6
|
||||
0xfd 0x85 0xa3 0xfb 0x81 0xec 0xee 0xfa
|
@ -1,60 +0,0 @@
|
||||
# $FreeBSD$
|
||||
#
|
||||
# usr/libdata/msdosfs/iso72dos
|
||||
#
|
||||
# u2w: 16 rows of Latin7 -> Unicode conversion table (upper half)
|
||||
#
|
||||
0x0080 0x0081 0x0082 0x0083 0x0084 0x0085 0x0086 0x0087
|
||||
0x0088 0x0089 0x008a 0x008b 0x008c 0x008d 0x008e 0x008f
|
||||
0x0090 0x0091 0x0092 0x0093 0x0094 0x0095 0x0096 0x0097
|
||||
0x0098 0x0099 0x009a 0x009b 0x009c 0x009d 0x009e 0x009f
|
||||
0x00a0 0x201b 0x2019 0x00a3 0x003f 0x003f 0x00a6 0x00a7
|
||||
0x00a8 0x00a9 0x003f 0x00ab 0x00ac 0x00ad 0x003f 0x2015
|
||||
0x00b0 0x00b1 0x00b2 0x00b3 0x00b4 0x0385 0x0386 0x00b7
|
||||
0x0388 0x0389 0x038a 0x00bb 0x038c 0x00bd 0x038e 0x038f
|
||||
0x0390 0x0391 0x0392 0x0393 0x0394 0x0395 0x0396 0x0397
|
||||
0x0398 0x0399 0x039a 0x039b 0x039c 0x039d 0x039e 0x039f
|
||||
0x03a0 0x03a1 0x003f 0x03a3 0x03a4 0x03a5 0x03a6 0x03a7
|
||||
0x03a8 0x03a9 0x03aa 0x03ab 0x03ac 0x03ad 0x03ae 0x03af
|
||||
0x03b0 0x03b1 0x03b2 0x03b3 0x03b4 0x03b5 0x03b6 0x03b7
|
||||
0x03b8 0x03b9 0x03ba 0x03bb 0x03bc 0x03bd 0x03be 0x03bf
|
||||
0x03c0 0x03c1 0x03c2 0x03c3 0x03c4 0x03c5 0x03c6 0x03c7
|
||||
0x03c8 0x03c9 0x03ca 0x03cb 0x03cc 0x03cd 0x03ce 0x003f
|
||||
#
|
||||
# d2u: 16 rows of CP737 -> Latin7 conversion table (upper half)
|
||||
#
|
||||
0xc1 0xc2 0xc3 0xc4 0xc5 0xc6 0xc7 0xc8
|
||||
0xc9 0xca 0xcb 0xcc 0xcd 0xce 0xcf 0xd0
|
||||
0xd1 0xd3 0xd4 0xd5 0xd6 0xd7 0xd8 0xd9
|
||||
0xe1 0xe2 0xe3 0xe4 0xe5 0xe6 0xe7 0xe8
|
||||
0xe9 0xea 0xeb 0xec 0xed 0xee 0xef 0xf0
|
||||
0xf1 0xf3 0xf2 0xf4 0xf5 0xf6 0xf7 0xf8
|
||||
0x3f 0x3f 0x3f 0x3f 0x3f 0x3f 0x3f 0x3f
|
||||
0x3f 0x3f 0x3f 0x3f 0x3f 0x3f 0x3f 0x3f
|
||||
0x3f 0x3f 0x3f 0x3f 0x3f 0x3f 0x3f 0x3f
|
||||
0x3f 0x3f 0x3f 0x3f 0x3f 0x3f 0x3f 0x3f
|
||||
0x3f 0x3f 0x3f 0x3f 0x3f 0x3f 0x3f 0x3f
|
||||
0x3f 0x3f 0x3f 0x3f 0x3f 0x3f 0x3f 0x3f
|
||||
0xf9 0xdc 0xdd 0xde 0xfa 0xdf 0xfc 0xfd
|
||||
0xfb 0xfe 0xb6 0xb8 0xb9 0xba 0xbc 0xbe
|
||||
0xbf 0xb1 0x3f 0x3f 0xda 0xdb 0x3f 0x3f
|
||||
0xb0 0x3f 0xb7 0x3f 0x3f 0xb2 0x3f 0xa0
|
||||
#
|
||||
# u2d: 16 rows of Latin7 -> CP737 conversion table (upper half)
|
||||
#
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0xff 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0xf8 0xf1 0xfd 0x00 0x00 0x00 0xea 0xfa
|
||||
0xeb 0xec 0xed 0x00 0xee 0x00 0xef 0xf0
|
||||
0x00 0x80 0x81 0x82 0x83 0x84 0x85 0x86
|
||||
0x87 0x88 0x89 0x8a 0x8b 0x8c 0x8d 0x8e
|
||||
0x8f 0x90 0x00 0x91 0x92 0x93 0x94 0x95
|
||||
0x96 0x97 0xf4 0xf5 0xe1 0xe2 0xe3 0xe5
|
||||
0x00 0x98 0x99 0x9a 0x9b 0x9c 0x9d 0x9e
|
||||
0x9f 0xa0 0xa1 0xa2 0xa3 0xa4 0xa5 0xa6
|
||||
0xa7 0xa8 0xaa 0xa9 0xab 0xac 0xad 0xae
|
||||
0xaf 0xe0 0xe4 0xe8 0xe6 0xe7 0xe9 0x00
|
@ -1,58 +0,0 @@
|
||||
# $FreeBSD$
|
||||
#
|
||||
# u2w: 16 rows of KOI8-R -> Unicode conversion table (upper half)
|
||||
#
|
||||
0x2500 0x2502 0x250c 0x2510 0x2514 0x2518 0x251c 0x2524
|
||||
0x252c 0x2534 0x253c 0x2580 0x2584 0x2588 0x258c 0x2590
|
||||
0x2591 0x2592 0x2593 0x2320 0x25a0 0x2219 0x221a 0x2248
|
||||
0x2264 0x2265 0x00a0 0x2321 0x00b0 0x00b2 0x00b7 0x00f7
|
||||
0x2550 0x2551 0x2552 0x0451 0x2553 0x2554 0x2555 0x2556
|
||||
0x2557 0x2558 0x2559 0x255a 0x255b 0x255c 0x255d 0x255e
|
||||
0x255f 0x2560 0x2561 0x0401 0x2562 0x2563 0x2564 0x2565
|
||||
0x2566 0x2567 0x2568 0x2569 0x256a 0x256b 0x256c 0x00a9
|
||||
0x044e 0x0430 0x0431 0x0446 0x0434 0x0435 0x0444 0x0433
|
||||
0x0445 0x0438 0x0439 0x043a 0x043b 0x043c 0x043d 0x043e
|
||||
0x043f 0x044f 0x0440 0x0441 0x0442 0x0443 0x0436 0x0432
|
||||
0x044c 0x044b 0x0437 0x0448 0x044d 0x0449 0x0447 0x044a
|
||||
0x042e 0x0410 0x0411 0x0426 0x0414 0x0415 0x0424 0x0413
|
||||
0x0425 0x0418 0x0419 0x041a 0x041b 0x041c 0x041d 0x041e
|
||||
0x041f 0x042f 0x0420 0x0421 0x0422 0x0423 0x0416 0x0412
|
||||
0x042c 0x042b 0x0417 0x0428 0x042d 0x0429 0x0427 0x042a
|
||||
#
|
||||
# d2u: 16 rows of CP866 -> KOI8-R conversion table (upper half)
|
||||
#
|
||||
0xe1 0xe2 0xf7 0xe7 0xe4 0xe5 0xf6 0xfa
|
||||
0xe9 0xea 0xeb 0xec 0xed 0xee 0xef 0xf0
|
||||
0xf2 0xf3 0xf4 0xf5 0xe6 0xe8 0xe3 0xfe
|
||||
0xfb 0xfd 0xff 0xf9 0xf8 0xfc 0xe0 0xf1
|
||||
0xc1 0xc2 0xd7 0xc7 0xc4 0xc5 0xd6 0xda
|
||||
0xc9 0xca 0xcb 0xcc 0xcd 0xce 0xcf 0xd0
|
||||
0x90 0x91 0x92 0x81 0x87 0xb2 0xb4 0xa7
|
||||
0xa6 0xb5 0xa1 0xa8 0xae 0xad 0xac 0x83
|
||||
0x84 0x89 0x88 0x86 0x80 0x8a 0xaf 0xb0
|
||||
0xab 0xa5 0xbb 0xb8 0xb1 0xa0 0xbe 0xb9
|
||||
0xba 0xb6 0xb7 0xaa 0xa9 0xa2 0xa4 0xbd
|
||||
0xbc 0x85 0x82 0x8d 0x8c 0x8e 0x8f 0x8b
|
||||
0xd2 0xd3 0xd4 0xd5 0xc6 0xc8 0xc3 0xde
|
||||
0xdb 0xdd 0xdf 0xd9 0xd8 0xdc 0xc0 0xd1
|
||||
0xb3 0xa3 229 197 73 105 245 213
|
||||
0x9c 0x95 0x9e 0x96 78 210 0x94 0x9a
|
||||
#
|
||||
# u2d: 16 rows of KOI8-R -> CP866 conversion table (upper half)
|
||||
#
|
||||
0xc4 0xb3 0xda 0xbf 0xc0 0xd9 0xc3 0xb4
|
||||
0xc2 0xc1 0xc5 0xdf 0xdc 0xdb 0xdd 0xde
|
||||
0xb0 0xb1 0xb2 179 0xfe 0xf9 0xfb 61
|
||||
60 62 0xff 179 0xf8 50 0xfa 58
|
||||
0xcd 0xba 0xd5 0xf1 0xd6 0xc9 0xb8 0xb7
|
||||
0xbb 0xd4 0xd3 0xc8 0xbe 0xbd 0xbc 0xc6
|
||||
0xc7 0xcc 0xb5 0xf0 0xb6 0xb9 0xd1 0xd2
|
||||
0xcb 0xcf 0xd0 0xca 0xd8 0xd7 0xce 99
|
||||
0xee 0xa0 0xa1 0xe6 0xa4 0xa5 0xe4 0xa3
|
||||
0xe5 0xa8 0xa9 0xaa 0xab 0xac 0xad 0xae
|
||||
0xaf 0xef 0xe0 0xe1 0xe2 0xe3 0xa6 0xa2
|
||||
0xec 0xeb 0xa7 0xe8 0xed 0xe9 0xe7 0xea
|
||||
0x9e 0x80 0x81 0x96 0x84 0x85 0x94 0x83
|
||||
0x95 0x88 0x89 0x8a 0x8b 0x8c 0x8d 0x8e
|
||||
0x8f 0x9f 0x90 0x91 0x92 0x93 0x86 0x82
|
||||
0x9c 0x9b 0x87 0x98 0x9d 0x99 0x97 0x9a
|
@ -1,60 +0,0 @@
|
||||
# $FreeBSD$
|
||||
#
|
||||
# Translation table for ukrainian filenames support by <kunia@istc.kiev.ua>
|
||||
#
|
||||
# u2w: 16 rows of KOI8-U -> Unicode conversion table (upper half)
|
||||
#
|
||||
0x2500 0x2502 0x250c 0x2510 0x2514 0x2518 0x251c 0x2524
|
||||
0x252c 0x2534 0x253c 0x2580 0x2584 0x2588 0x258c 0x2590
|
||||
0x2591 0x2592 0x2593 0x2320 0x25a0 0x2219 0x221a 0x2248
|
||||
0x2264 0x2265 0x00a0 0x2321 0x00b0 0x00b2 0x00b7 0x00f7
|
||||
0x2550 0x2551 0x2552 0x0451 0x0454 0x2554 0x0456 0x0457
|
||||
0x2557 0x2558 0x2559 0x255a 0x255b 0x0491 0x255d 0x255e
|
||||
0x255f 0x2560 0x2561 0x0401 0x0404 0x2563 0x0406 0x0407
|
||||
0x2566 0x2567 0x2568 0x2569 0x256a 0x0490 0x256c 0x00a9
|
||||
0x044e 0x0430 0x0431 0x0446 0x0434 0x0435 0x0444 0x0433
|
||||
0x0445 0x0438 0x0439 0x043a 0x043b 0x043c 0x043d 0x043e
|
||||
0x043f 0x044f 0x0440 0x0441 0x0442 0x0443 0x0436 0x0432
|
||||
0x044c 0x044b 0x0437 0x0448 0x044d 0x0449 0x0447 0x044a
|
||||
0x042e 0x0410 0x0411 0x0426 0x0414 0x0415 0x0424 0x0413
|
||||
0x0425 0x0418 0x0419 0x041a 0x041b 0x041c 0x041d 0x041e
|
||||
0x041f 0x042f 0x0420 0x0421 0x0422 0x0423 0x0416 0x0412
|
||||
0x042c 0x042b 0x0417 0x0428 0x042d 0x0429 0x0427 0x042a
|
||||
#
|
||||
# d2u: 16 rows of CP866 -> KOI8-U conversion table (upper half)
|
||||
#
|
||||
0xe1 0xe2 0xf7 0xe7 0xe4 0xe5 0xf6 0xfa
|
||||
0xe9 0xea 0xeb 0xec 0xed 0xee 0xef 0xf0
|
||||
0xf2 0xf3 0xf4 0xf5 0xe6 0xe8 0xe3 0xfe
|
||||
0xfb 0xfd 0xff 0xf9 0xf8 0xfc 0xe0 0xf1
|
||||
0xc1 0xc2 0xd7 0xc7 0xc4 0xc5 0xd6 0xda
|
||||
0xc9 0xca 0xcb 0xcc 0xcd 0xce 0xcf 0xd0
|
||||
0x90 0x91 0x92 0x81 0x87 0xb2 0xb4 0xa7
|
||||
0xa6 0xb5 0xa1 0xa8 0xae 0xad 0xac 0x83
|
||||
0x84 0x89 0x88 0x86 0x80 0x8a 0xaf 0xb0
|
||||
0xab 0xa5 0xbb 0xb8 0xb1 0xa0 0xbe 0xb9
|
||||
0xba 0xb6 0xb7 0xaa 0xa9 0xa2 0xa4 0xbd
|
||||
0xbc 0x85 0x82 0x8d 0x8c 0x8e 0x8f 0x8b
|
||||
0xd2 0xd3 0xd4 0xd5 0xc6 0xc8 0xc3 0xde
|
||||
0xdb 0xdd 0xdf 0xd9 0xd8 0xdc 0xc0 0xd1
|
||||
0xb3 0xa3 0xb4 0xa4 0xb7 0xa7 245 213
|
||||
0x9c 0x95 0x9e 0x96 78 210 0x94 0x9a
|
||||
#
|
||||
# u2d: 16 rows of KOI8-U -> CP866 conversion table (upper half)
|
||||
#
|
||||
0xc4 0xb3 0xda 0xbf 0xc0 0xd9 0xc3 0xb4
|
||||
0xc2 0xc1 0xc5 0xdf 0xdc 0xdb 0xdd 0xde
|
||||
0xb0 0xb1 0xb2 179 0xfe 0xf9 0xfb 61
|
||||
60 62 0xff 179 0xf8 50 0xfa 58
|
||||
0xcd 0xba 0xd5 0xf1 0xf3 0xc9 0x01 0xf5
|
||||
0xbb 0xd4 0xd3 0xc8 0xbe 0x01 0xbc 0xc6
|
||||
0xc7 0xcc 0xb5 0xf0 0xf2 0xb9 0x01 0xf4
|
||||
0xcb 0xcf 0xd0 0xca 0xd8 0x01 0xce 99
|
||||
0xee 0xa0 0xa1 0xe6 0xa4 0xa5 0xe4 0xa3
|
||||
0xe5 0xa8 0xa9 0xaa 0xab 0xac 0xad 0xae
|
||||
0xaf 0xef 0xe0 0xe1 0xe2 0xe3 0xa6 0xa2
|
||||
0xec 0xeb 0xa7 0xe8 0xed 0xe9 0xe7 0xea
|
||||
0x9e 0x80 0x81 0x96 0x84 0x85 0x94 0x83
|
||||
0x95 0x88 0x89 0x8a 0x8b 0x8c 0x8d 0x8e
|
||||
0x8f 0x9f 0x90 0x91 0x92 0x93 0x86 0x82
|
||||
0x9c 0x9b 0x87 0x98 0x9d 0x99 0x97 0x9a
|
@ -48,6 +48,7 @@
|
||||
.Op Fl 9
|
||||
.\".Op Fl G
|
||||
.Op Fl L Ar locale
|
||||
.Op Fl D Ar dos-codepage
|
||||
.Op Fl W Ar table
|
||||
.Pa special
|
||||
.Pa node
|
||||
@ -160,50 +161,38 @@ This forces
|
||||
.\"limited to the boot block. This option enforces
|
||||
.\".Fl s .
|
||||
.It Fl L Ar locale
|
||||
Specify locale name used for internal uppercase and lowercase conversions
|
||||
Specify locale name used for file name conversions
|
||||
for DOS and Win'95 names.
|
||||
By default ISO 8859-1 assumed as local character set.
|
||||
.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.
|
||||
.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
|
||||
This option is remained for backward compatibility purpose, and will be
|
||||
removed in the future. Please do not use this option.
|
||||
.Pp
|
||||
By default ISO 8859-1 assumed as local character set.
|
||||
If file path isn't absolute,
|
||||
.Pa /usr/libdata/msdosfs/
|
||||
prefix prepended.
|
||||
Specify text file name with conversion table: iso22dos, iso72dos, koi2dos,
|
||||
koi8u2dos.
|
||||
.El
|
||||
.Sh FILES
|
||||
.Bl -tag -width /usr/libdata/msdosfs -compact
|
||||
.It Pa /usr/libdata/msdosfs
|
||||
default place for character sets conversion tables
|
||||
.Sh EXAMPLES
|
||||
To mount a Russian msdos file system located in /dev/ad1s1:
|
||||
.Bd -literal -offset indent
|
||||
# mount_msdosfs -L ru_RU.KOI8-R -D CP866 /dev/ad1s1 /mnt
|
||||
.Ed
|
||||
.Pp
|
||||
To mount a Japanese msdos file system located in /dev/ad1s1:
|
||||
.Bd -literal -offset indent
|
||||
# mount_msdosfs -L ja_JP.eucJP -D CP932 /dev/ad1s1 /mnt
|
||||
.Ed
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr mount 2 ,
|
||||
.Xr unmount 2 ,
|
||||
.Xr fstab 5 ,
|
||||
.Xr mount 8
|
||||
.Pp
|
||||
List of Localized MS Operating Systems:
|
||||
.Pa http://www.microsoft.com/globaldev/reference/oslocversion.mspx .
|
||||
.Sh CAVEATS
|
||||
The use of the
|
||||
.Fl 9
|
||||
@ -230,3 +219,7 @@ utility appeared in
|
||||
and was abandoned in favor
|
||||
of the more aptly-named
|
||||
.Nm .
|
||||
.Pp
|
||||
The character code conversion routine was added by
|
||||
.An Ryuichiro Imura Aq imura@ryu16.org
|
||||
at 2003.
|
||||
|
@ -38,6 +38,8 @@ static const char rcsid[] =
|
||||
#include <sys/param.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/iconv.h>
|
||||
|
||||
#include <fs/msdosfs/msdosfsmount.h>
|
||||
|
||||
@ -56,9 +58,11 @@ static const char rcsid[] =
|
||||
|
||||
#include "mntopts.h"
|
||||
|
||||
#define TRANSITION_PERIOD_HACK
|
||||
|
||||
/*
|
||||
* XXX - no way to specify "foo=<bar>"-type options; that's what we'd
|
||||
* want for "-u", "-g", "-m", "-L", and "-W".
|
||||
* want for "-u", "-g", "-m", "-L", "-D", and "-W".
|
||||
*/
|
||||
static struct mntopt mopts[] = {
|
||||
MOPT_STDOPTS,
|
||||
@ -78,8 +82,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 *);
|
||||
static int set_charset(struct msdosfs_args *);
|
||||
|
||||
int
|
||||
main(argc, argv)
|
||||
@ -89,13 +92,20 @@ main(argc, argv)
|
||||
struct msdosfs_args args;
|
||||
struct stat sb;
|
||||
int c, mntflags, set_gid, set_uid, set_mask, set_dirmask;
|
||||
char *dev, *dir, mntpath[MAXPATHLEN];
|
||||
char *dev, *dir, mntpath[MAXPATHLEN], *csp;
|
||||
|
||||
mntflags = set_gid = set_uid = set_mask = set_dirmask = 0;
|
||||
(void)memset(&args, '\0', sizeof(args));
|
||||
args.magic = MSDOSFS_ARGSMAGIC;
|
||||
|
||||
while ((c = getopt(argc, argv, "sl9u:g:m:M:o:L:W:")) != -1) {
|
||||
args.cs_win = NULL;
|
||||
args.cs_dos = NULL;
|
||||
args.cs_local = NULL;
|
||||
#ifdef TRANSITION_PERIOD_HACK
|
||||
while ((c = getopt(argc, argv, "sl9u:g:m:M:o:L:D:W:")) != -1) {
|
||||
#else
|
||||
while ((c = getopt(argc, argv, "sl9u:g:m:M:o:L:D:")) != -1) {
|
||||
#endif
|
||||
switch (c) {
|
||||
#ifdef MSDOSFSMNT_GEMDOSFS
|
||||
case 'G':
|
||||
@ -128,16 +138,52 @@ main(argc, argv)
|
||||
set_dirmask = 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);
|
||||
args.cs_local = malloc(ICONV_CSNMAXLEN);
|
||||
if (args.cs_local == NULL)
|
||||
err(EX_OSERR, "malloc()");
|
||||
strncpy(args.cs_local,
|
||||
kiconv_quirkcs(csp + 1, KICONV_VENDOR_MICSFT),
|
||||
ICONV_CSNMAXLEN);
|
||||
break;
|
||||
case 'W':
|
||||
load_u2wtable(&args, optarg);
|
||||
args.flags |= MSDOSFSMNT_U2WTABLE;
|
||||
case 'D':
|
||||
args.cs_dos = malloc(ICONV_CSNMAXLEN);
|
||||
if (args.cs_dos == NULL)
|
||||
err(EX_OSERR, "malloc()");
|
||||
strncpy(args.cs_dos, optarg, ICONV_CSNMAXLEN);
|
||||
break;
|
||||
case 'o':
|
||||
getmntopts(optarg, mopts, &mntflags, &args.flags);
|
||||
break;
|
||||
#ifdef TRANSITION_PERIOD_HACK
|
||||
case 'W':
|
||||
args.cs_local = malloc(ICONV_CSNMAXLEN);
|
||||
if (args.cs_local == NULL)
|
||||
err(EX_OSERR, "malloc()");
|
||||
args.cs_dos = malloc(ICONV_CSNMAXLEN);
|
||||
if (args.cs_dos == NULL)
|
||||
err(EX_OSERR, "malloc()");
|
||||
if (strcmp(optarg, "iso22dos") == 0) {
|
||||
strcpy(args.cs_local, "ISO8859-2");
|
||||
strcpy(args.cs_dos, "CP852");
|
||||
} else if (strcmp(optarg, "iso72dos") == 0) {
|
||||
strcpy(args.cs_local, "ISO8859-7");
|
||||
strcpy(args.cs_dos, "CP737");
|
||||
} else if (strcmp(optarg, "koi2dos") == 0) {
|
||||
strcpy(args.cs_local, "KOI8-R");
|
||||
strcpy(args.cs_dos, "CP866");
|
||||
} else if (strcmp(optarg, "koi8u2dos") == 0) {
|
||||
strcpy(args.cs_local, "KOI8-U");
|
||||
strcpy(args.cs_dos, "CP866");
|
||||
} else {
|
||||
err(EX_NOINPUT, "%s", optarg);
|
||||
}
|
||||
break;
|
||||
#endif /* TRANSITION_PERIOD_HACK */
|
||||
case '?':
|
||||
default:
|
||||
usage();
|
||||
@ -160,6 +206,19 @@ main(argc, argv)
|
||||
dev = argv[optind];
|
||||
dir = argv[optind + 1];
|
||||
|
||||
if (args.cs_local) {
|
||||
if (set_charset(&args) == -1)
|
||||
err(EX_OSERR, "msdosfs_iconv");
|
||||
args.flags |= MSDOSFSMNT_KICONV;
|
||||
} else if (args.cs_dos) {
|
||||
if ((args.cs_local = malloc(ICONV_CSNMAXLEN)) == NULL)
|
||||
err(EX_OSERR, "malloc()");
|
||||
strcpy(args.cs_local, "ISO8859-1");
|
||||
if (set_charset(&args) == -1)
|
||||
err(EX_OSERR, "msdosfs_iconv");
|
||||
args.flags |= MSDOSFSMNT_KICONV;
|
||||
}
|
||||
|
||||
/*
|
||||
* Resolve the mountpoint with realpath(3) and remove unnecessary
|
||||
* slashes from the devicename if there are any.
|
||||
@ -254,89 +313,52 @@ void
|
||||
usage()
|
||||
{
|
||||
fprintf(stderr, "%s\n%s\n",
|
||||
#ifdef TRANSITION_PERIOD_HACK
|
||||
"usage: mount_msdosfs [-o options] [-u user] [-g group] [-m mask] [-s] [-l]",
|
||||
" [-9] [-L locale] [-D dos-codepage] [-W table] bdev dir");
|
||||
#else
|
||||
"usage: mount_msdosfs [-o options] [-u user] [-g group] [-m mask]",
|
||||
" [-s] [-l] [-9] [-L locale] [-W table] bdev dir");
|
||||
" [-s] [-l] [-9] [-L locale] [-D dos-codepage] bdev dir");
|
||||
#endif
|
||||
exit(EX_USAGE);
|
||||
}
|
||||
|
||||
void
|
||||
load_u2wtable (pargs, name)
|
||||
struct msdosfs_args *pargs;
|
||||
char *name;
|
||||
int
|
||||
set_charset(struct msdosfs_args *args)
|
||||
{
|
||||
FILE *f;
|
||||
int i, j, code[8];
|
||||
size_t line = 0;
|
||||
char buf[128];
|
||||
char *fn, *s, *p;
|
||||
int error;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void
|
||||
load_ultable (pargs, name)
|
||||
struct msdosfs_args *pargs;
|
||||
char *name;
|
||||
{
|
||||
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);
|
||||
if (modfind("msdosfs_iconv") < 0)
|
||||
if (kldload("msdosfs_iconv") < 0 || modfind("msdosfs_iconv") < 0) {
|
||||
warnx( "cannot find or load \"msdosfs_iconv\" kernel module");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if ((args->cs_win = malloc(ICONV_CSNMAXLEN)) == NULL)
|
||||
return (-1);
|
||||
strncpy(args->cs_win, ENCODING_UNICODE, ICONV_CSNMAXLEN);
|
||||
error = kiconv_add_xlat16_cspair(args->cs_win, args->cs_local, 0);
|
||||
if (error)
|
||||
return (-1);
|
||||
error = kiconv_add_xlat16_cspair(args->cs_local, args->cs_win, 0);
|
||||
if (error)
|
||||
return (-1);
|
||||
if (args->cs_dos) {
|
||||
error = kiconv_add_xlat16_cspair(args->cs_dos, args->cs_local, KICONV_FROM_UPPER);
|
||||
if (error)
|
||||
return (-1);
|
||||
error = kiconv_add_xlat16_cspair(args->cs_local, args->cs_dos, KICONV_LOWER);
|
||||
if (error)
|
||||
return (-1);
|
||||
} else {
|
||||
if ((args->cs_dos = malloc(ICONV_CSNMAXLEN)) == NULL)
|
||||
return (-1);
|
||||
strcpy(args->cs_dos, args->cs_local);
|
||||
error = kiconv_add_xlat16_cspair(args->cs_local, args->cs_local,
|
||||
KICONV_FROM_UPPER | KICONV_LOWER);
|
||||
if (error)
|
||||
return (-1);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
@ -5,13 +5,17 @@
|
||||
PROG= mount_ntfs
|
||||
SRCS= mount_ntfs.c getmntopts.c
|
||||
MAN= mount_ntfs.8
|
||||
DPADD= ${LIBUTIL}
|
||||
LDADD= -lutil
|
||||
DPADD= ${LIBKICONV}
|
||||
LDADD= -lkiconv
|
||||
|
||||
MOUNT= ${.CURDIR}/../mount
|
||||
CFLAGS+=-I${MOUNT}
|
||||
WARNS= 0
|
||||
|
||||
# Needs to be dynamically linked for optional dlopen() access to
|
||||
# userland libiconv
|
||||
NOSHARED?= NO
|
||||
|
||||
.PATH: ${MOUNT}
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
@ -43,6 +43,7 @@
|
||||
.Op Fl u Ar uid
|
||||
.Op Fl g Ar gid
|
||||
.Op Fl m Ar mask
|
||||
.Op Fl C Ar charset
|
||||
.Op Fl W Ar u2wtable
|
||||
.Pa special
|
||||
.Pa node
|
||||
@ -81,6 +82,12 @@ 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 C Ar charset
|
||||
Specify local
|
||||
.Ar charset
|
||||
to convert Unicode file names.
|
||||
Currently only reading is supported, thus the file system is to be
|
||||
mounted read-only.
|
||||
.It Fl W Ar u2wtable
|
||||
Specify
|
||||
.Ux
|
||||
@ -90,6 +97,9 @@ translation table.
|
||||
See
|
||||
.Xr mount_msdosfs 8
|
||||
for the description of this option.
|
||||
This option is remained for backward compatibility purpose, so
|
||||
please do not use this option. This option will be removed in
|
||||
the future.
|
||||
.El
|
||||
.Sh FEATURES
|
||||
NTFS file attributes are accessed in following way:
|
||||
@ -120,11 +130,19 @@ To read directory raw data:
|
||||
.Bd -literal -offset indent
|
||||
# cat /mnt/foodir:\\$INDEX_ROOT:\\$I30
|
||||
.Ed
|
||||
.Pp
|
||||
To mount a
|
||||
.Pa Japanese
|
||||
ntfs volume located in /dev/ad0s1:
|
||||
.Bd -literal -offset indent
|
||||
# mount_ntfs -C eucJP /dev/ad0s1 /mnt
|
||||
.Ed
|
||||
.Sh WRITING
|
||||
There is limited writing ability.
|
||||
Limitations: file must be nonresident
|
||||
and must not contain any sparces (uninitialized areas); compressed
|
||||
files are also not supported.
|
||||
The file name must not contain multibyte characters.
|
||||
.Sh SEE ALSO
|
||||
.Xr mount 2 ,
|
||||
.Xr unmount 2 ,
|
||||
@ -141,6 +159,10 @@ The
|
||||
.Nm
|
||||
utility first appeared in
|
||||
.Fx 3.0 .
|
||||
.Pp
|
||||
The unicode conversion routine was added by
|
||||
.An Ryuichiro Imura Aq imura@ryu16.org
|
||||
at 2003.
|
||||
.Sh AUTHORS
|
||||
The NTFS kernel implementation,
|
||||
.Nm
|
||||
|
@ -37,6 +37,8 @@
|
||||
#define NTFS
|
||||
#include <sys/mount.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/iconv.h>
|
||||
#include <fs/ntfs/ntfsmount.h>
|
||||
#include <ctype.h>
|
||||
#include <err.h>
|
||||
@ -51,6 +53,8 @@
|
||||
|
||||
#include "mntopts.h"
|
||||
|
||||
#define TRANSITION_PERIOD_HACK
|
||||
|
||||
static struct mntopt mopts[] = {
|
||||
MOPT_STDOPTS,
|
||||
{ NULL }
|
||||
@ -61,7 +65,7 @@ static uid_t a_uid(char *);
|
||||
static mode_t a_mask(char *);
|
||||
static void usage(void) __dead2;
|
||||
|
||||
static void load_u2wtable(struct ntfs_args *, char *);
|
||||
static int set_charset(struct ntfs_args *);
|
||||
|
||||
int
|
||||
main(argc, argv)
|
||||
@ -75,8 +79,14 @@ main(argc, argv)
|
||||
|
||||
mntflags = set_gid = set_uid = set_mask = 0;
|
||||
(void)memset(&args, '\0', sizeof(args));
|
||||
args.cs_ntfs = NULL;
|
||||
args.cs_local = NULL;
|
||||
|
||||
while ((c = getopt(argc, argv, "aiu:g:m:o:W:")) != -1) {
|
||||
#ifdef TRANSITION_PERIOD_HACK
|
||||
while ((c = getopt(argc, argv, "aiu:g:m:o:C:W:")) != -1) {
|
||||
#else
|
||||
while ((c = getopt(argc, argv, "aiu:g:m:o:C:")) != -1) {
|
||||
#endif
|
||||
switch (c) {
|
||||
case 'u':
|
||||
args.uid = a_uid(optarg);
|
||||
@ -99,10 +109,32 @@ main(argc, argv)
|
||||
case 'o':
|
||||
getmntopts(optarg, mopts, &mntflags, 0);
|
||||
break;
|
||||
case 'W':
|
||||
load_u2wtable(&args, optarg);
|
||||
args.flag |= NTFSMNT_U2WTABLE;
|
||||
case 'C':
|
||||
args.cs_local = malloc(ICONV_CSNMAXLEN);
|
||||
if (args.cs_local == NULL)
|
||||
err(EX_OSERR, "malloc()");
|
||||
strncpy(args.cs_local,
|
||||
kiconv_quirkcs(optarg, KICONV_VENDOR_MICSFT),
|
||||
ICONV_CSNMAXLEN);
|
||||
break;
|
||||
#ifdef TRANSITION_PERIOD_HACK
|
||||
case 'W':
|
||||
args.cs_local = malloc(ICONV_CSNMAXLEN);
|
||||
if (args.cs_local == NULL)
|
||||
err(EX_OSERR, "malloc()");
|
||||
if (strcmp(optarg, "iso22dos") == 0) {
|
||||
strcpy(args.cs_local, "ISO8859-2");
|
||||
} else if (strcmp(optarg, "iso72dos") == 0) {
|
||||
strcpy(args.cs_local, "ISO8859-7");
|
||||
} else if (strcmp(optarg, "koi2dos") == 0) {
|
||||
strcpy(args.cs_local, "KOI8-R");
|
||||
} else if (strcmp(optarg, "koi8u2dos") == 0) {
|
||||
strcpy(args.cs_local, "KOI8-U");
|
||||
} else {
|
||||
err(EX_NOINPUT, "%s", optarg);
|
||||
}
|
||||
break;
|
||||
#endif /* TRANSITION_PERIOD_HACK */
|
||||
case '?':
|
||||
default:
|
||||
usage();
|
||||
@ -116,6 +148,18 @@ main(argc, argv)
|
||||
dev = argv[optind];
|
||||
dir = argv[optind + 1];
|
||||
|
||||
if (args.cs_local) {
|
||||
if (set_charset(&args) == -1)
|
||||
err(EX_OSERR, "ntfs_iconv");
|
||||
args.flag |= NTFS_MFLAG_KICONV;
|
||||
/*
|
||||
* XXX
|
||||
* Force to be MNT_RDONLY,
|
||||
* since only reading is supported right now,
|
||||
*/
|
||||
mntflags |= MNT_RDONLY;
|
||||
}
|
||||
|
||||
/*
|
||||
* Resolve the mountpoint with realpath(3) and remove unnecessary
|
||||
* slashes from the devicename if there are any.
|
||||
@ -207,74 +251,36 @@ a_mask(s)
|
||||
void
|
||||
usage()
|
||||
{
|
||||
fprintf(stderr, "usage: mount_ntfs [-a] [-i] [-u user] [-g group] [-m mask] [-W u2wtable] bdev dir\n");
|
||||
#ifdef TRANSITION_PERIOD_HACK
|
||||
fprintf(stderr, "%s\n%s\n",
|
||||
"usage: mount_ntfs [-a] [-i] [-u user] [-g group] [-m mask]",
|
||||
" [-C charset] [-W u2wtable] bdev dir");
|
||||
#else
|
||||
fprintf(stderr, "usage: mount_ntfs [-a] [-i] [-u user] [-g group] [-m mask] [-C charset] bdev dir\n");
|
||||
#endif
|
||||
exit(EX_USAGE);
|
||||
}
|
||||
|
||||
void
|
||||
load_u2wtable (pargs, name)
|
||||
struct ntfs_args *pargs;
|
||||
char *name;
|
||||
int
|
||||
set_charset(struct ntfs_args *pargs)
|
||||
{
|
||||
FILE *f;
|
||||
int i, j, code[8];
|
||||
size_t line = 0;
|
||||
char buf[128];
|
||||
char *fn, *s, *p;
|
||||
int error;
|
||||
|
||||
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);
|
||||
if (modfind("ntfs_iconv") < 0)
|
||||
if (kldload("ntfs_iconv") < 0 || modfind("ntfs_iconv") < 0) {
|
||||
warnx( "cannot find or load \"ntfs_iconv\" kernel module");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if ((pargs->cs_ntfs = malloc(ICONV_CSNMAXLEN)) == NULL)
|
||||
return (-1);
|
||||
strncpy(pargs->cs_ntfs, ENCODING_UNICODE, ICONV_CSNMAXLEN);
|
||||
error = kiconv_add_xlat16_cspair(pargs->cs_local, pargs->cs_ntfs, 0);
|
||||
if (error)
|
||||
return (-1);
|
||||
error = kiconv_add_xlat16_cspair(pargs->cs_ntfs, pargs->cs_local, 0);
|
||||
if (error)
|
||||
return (-1);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -49,6 +49,7 @@ LIBISC?= ${DESTDIR}${LIBDIR}/libisc.a
|
||||
LIBKADM5CLNT?= ${DESTDIR}${LIBDIR}/libkadm5clnt.a # XXX in secure dist, not base
|
||||
LIBKADM5SRV?= ${DESTDIR}${LIBDIR}/libkadm5srv.a # XXX in secure dist, not base
|
||||
LIBKEYCAP?= ${DESTDIR}${LIBDIR}/libkeycap.a
|
||||
LIBKICONV?= ${DESTDIR}${LIBDIR}/libkiconv.a
|
||||
LIBKRB5?= ${DESTDIR}${LIBDIR}/libkrb5.a # XXX in secure dist, not base
|
||||
LIBKVM?= ${DESTDIR}${LIBDIR}/libkvm.a
|
||||
LIBL?= ${DESTDIR}${LIBDIR}/libl.a
|
||||
|
@ -788,6 +788,12 @@ options VFS_AIO
|
||||
# Cryptographically secure random number generator; /dev/[u]random
|
||||
device random
|
||||
|
||||
# Optional character code conversion support with LIBICONV.
|
||||
# Each option requires their base file system and LIBICONV.
|
||||
options CD9660_ICONV
|
||||
options MSDOSFS_ICONV
|
||||
options NTFS_ICONV
|
||||
|
||||
|
||||
#####################################################################
|
||||
# POSIX P1003.1B
|
||||
|
@ -893,11 +893,13 @@ fs/msdosfs/msdosfs_fat.c optional msdosfs
|
||||
fs/msdosfs/msdosfs_lookup.c optional msdosfs
|
||||
fs/msdosfs/msdosfs_vfsops.c optional msdosfs
|
||||
fs/msdosfs/msdosfs_vnops.c optional msdosfs
|
||||
fs/msdosfs/msdosfs_iconv.c optional msdosfs_iconv
|
||||
fs/ntfs/ntfs_compr.c optional ntfs
|
||||
fs/ntfs/ntfs_ihash.c optional ntfs
|
||||
fs/ntfs/ntfs_subr.c optional ntfs
|
||||
fs/ntfs/ntfs_vfsops.c optional ntfs
|
||||
fs/ntfs/ntfs_vnops.c optional ntfs
|
||||
fs/ntfs/ntfs_iconv.c optional ntfs_iconv
|
||||
fs/nullfs/null_subr.c optional nullfs
|
||||
fs/nullfs/null_vfsops.c optional nullfs
|
||||
fs/nullfs/null_vnops.c optional nullfs
|
||||
@ -1056,6 +1058,7 @@ isofs/cd9660/cd9660_rrip.c optional cd9660
|
||||
isofs/cd9660/cd9660_util.c optional cd9660
|
||||
isofs/cd9660/cd9660_vfsops.c optional cd9660
|
||||
isofs/cd9660/cd9660_vnops.c optional cd9660
|
||||
isofs/cd9660/cd9660_iconv.c optional cd9660_iconv
|
||||
kern/imgact_elf.c standard
|
||||
kern/imgact_shell.c standard
|
||||
kern/inflate.c optional gzip
|
||||
@ -1198,6 +1201,7 @@ libkern/crc32.c standard
|
||||
libkern/iconv.c optional libiconv
|
||||
libkern/iconv_converter_if.m optional libiconv
|
||||
libkern/iconv_xlat.c optional libiconv
|
||||
libkern/iconv_xlat16.c optional libiconv
|
||||
libkern/index.c standard
|
||||
libkern/inet_ntoa.c standard
|
||||
libkern/mcount.c optional profiling-routine
|
||||
|
@ -198,6 +198,11 @@ FFS opt_ffs_broken_fixme.h
|
||||
NFSCLIENT opt_nfs.h
|
||||
NFSSERVER opt_nfs.h
|
||||
|
||||
# filesystems and libiconv bridge
|
||||
CD9660_ICONV opt_dontuse.h
|
||||
MSDOSFS_ICONV opt_dontuse.h
|
||||
NTFS_ICONV opt_dontuse.h
|
||||
|
||||
# If you are following the conditions in the copyright,
|
||||
# you can enable soft-updates which will speed up a lot of thigs
|
||||
# and make the system safer from crashes at the same time.
|
||||
|
36
sys/fs/cd9660/cd9660_iconv.c
Normal file
36
sys/fs/cd9660/cd9660_iconv.c
Normal file
@ -0,0 +1,36 @@
|
||||
/*-
|
||||
* Copyright (c) 2003 Ryuichiro Imura
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/iconv.h>
|
||||
|
||||
VFS_DECLARE_ICONV(cd9660);
|
@ -238,7 +238,12 @@ cd9660_lookup(ap)
|
||||
if (namelen != 1
|
||||
|| ep->name[0] != 0)
|
||||
goto notfound;
|
||||
} else if (!(res = isofncmp(name, len, ep->name, namelen, imp->joliet_level))) {
|
||||
} else if (!(res = isofncmp(name, len,
|
||||
ep->name, namelen,
|
||||
imp->joliet_level,
|
||||
imp->im_flags,
|
||||
imp->im_d2l,
|
||||
imp->im_l2d))) {
|
||||
if (isoflags & 2)
|
||||
ino = isodirino(ep, imp);
|
||||
else
|
||||
|
@ -47,9 +47,12 @@ struct iso_args {
|
||||
struct export_args export; /* network export info */
|
||||
int flags; /* mounting flags, see below */
|
||||
int ssector; /* starting sector, 0 for 1st session */
|
||||
char *cs_disk; /* disk charset for Joliet cs conversion */
|
||||
char *cs_local; /* local charset for Joliet cs conversion */
|
||||
};
|
||||
#define ISOFSMNT_NORRIP 0x00000001 /* disable Rock Ridge Ext.*/
|
||||
#define ISOFSMNT_GENS 0x00000002 /* enable generation numbers */
|
||||
#define ISOFSMNT_EXTATT 0x00000004 /* enable extended attributes */
|
||||
#define ISOFSMNT_NOJOLIET 0x00000008 /* disable Joliet Ext.*/
|
||||
#define ISOFSMNT_BROKENJOLIET 0x00000010/* allow broken Joliet disks */
|
||||
#define ISOFSMNT_KICONV 0x00000020 /* Use libiconv to convert chars */
|
||||
|
@ -293,7 +293,8 @@ cd9660_rrip_defname(isodir,ana)
|
||||
{
|
||||
isofntrans(isodir->name,isonum_711(isodir->name_len),
|
||||
ana->outbuf,ana->outlen,
|
||||
1,isonum_711(isodir->flags)&4, ana->imp->joliet_level);
|
||||
1,isonum_711(isodir->flags)&4, ana->imp->joliet_level,
|
||||
ana->imp->im_flags, ana->imp->im_d2l);
|
||||
switch (*ana->outbuf) {
|
||||
default:
|
||||
break;
|
||||
@ -491,7 +492,7 @@ cd9660_rrip_loop(isodir,ana,table)
|
||||
register ISO_SUSP_HEADER *pend;
|
||||
struct buf *bp = NULL;
|
||||
char *pwhead;
|
||||
u_char c;
|
||||
u_short c;
|
||||
int result;
|
||||
|
||||
/*
|
||||
@ -501,7 +502,8 @@ cd9660_rrip_loop(isodir,ana,table)
|
||||
pwhead = isodir->name + isonum_711(isodir->name_len);
|
||||
if (!(isonum_711(isodir->name_len)&1))
|
||||
pwhead++;
|
||||
isochar(isodir->name, pwhead, ana->imp->joliet_level, &c);
|
||||
isochar(isodir->name, pwhead, ana->imp->joliet_level, &c, NULL,
|
||||
ana->imp->im_flags, ana->imp->im_d2l);
|
||||
|
||||
/* If it's not the '.' entry of the root dir obey SP field */
|
||||
if (c != 0 || isonum_733(isodir->extent) != ana->imp->root_extent)
|
||||
@ -627,7 +629,7 @@ cd9660_rrip_getname(isodir,outbuf,outlen,inump,imp)
|
||||
{
|
||||
ISO_RRIP_ANALYZE analyze;
|
||||
RRIP_TABLE *tab;
|
||||
u_char c;
|
||||
u_short c;
|
||||
|
||||
analyze.outbuf = outbuf;
|
||||
analyze.outlen = outlen;
|
||||
@ -638,7 +640,7 @@ cd9660_rrip_getname(isodir,outbuf,outlen,inump,imp)
|
||||
*outlen = 0;
|
||||
|
||||
isochar(isodir->name, isodir->name + isonum_711(isodir->name_len),
|
||||
imp->joliet_level, &c);
|
||||
imp->joliet_level, &c, NULL, imp->im_flags, imp->im_d2l);
|
||||
tab = rrip_table_getname;
|
||||
if (c == 0 || c == 1) {
|
||||
cd9660_rrip_defname(isodir,&analyze);
|
||||
|
@ -46,16 +46,12 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/systm.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/vnode.h>
|
||||
#include <sys/iconv.h>
|
||||
|
||||
#include <isofs/cd9660/iso.h>
|
||||
#include <isofs/cd9660/cd9660_mount.h>
|
||||
|
||||
/*
|
||||
* XXX: limited support for loading of Unicode
|
||||
* conversion routine as a kld at a run-time.
|
||||
* Should be removed when native Unicode kernel
|
||||
* interfaces have been introduced.
|
||||
*/
|
||||
u_char (*cd9660_wchar2char)(u_int32_t wchar) = NULL;
|
||||
extern struct iconv_functions *cd9660_iconv;
|
||||
|
||||
/*
|
||||
* Get one character out of an iso filename
|
||||
@ -63,29 +59,47 @@ u_char (*cd9660_wchar2char)(u_int32_t wchar) = NULL;
|
||||
* Return number of bytes consumed
|
||||
*/
|
||||
int
|
||||
isochar(isofn, isoend, joliet_level, c)
|
||||
isochar(isofn, isoend, joliet_level, c, clen, flags, handle)
|
||||
u_char *isofn;
|
||||
u_char *isoend;
|
||||
int joliet_level;
|
||||
u_char *c;
|
||||
u_short *c;
|
||||
int *clen;
|
||||
int flags;
|
||||
void *handle;
|
||||
{
|
||||
size_t i, j, len;
|
||||
char inbuf[3], outbuf[3], *inp, *outp;
|
||||
|
||||
*c = *isofn++;
|
||||
if (clen) *clen = 1;
|
||||
if (joliet_level == 0 || isofn == isoend)
|
||||
/* (00) and (01) are one byte in Joliet, too */
|
||||
return 1;
|
||||
|
||||
/* No Unicode support yet :-( */
|
||||
switch (*c) {
|
||||
default:
|
||||
*c = '?';
|
||||
break;
|
||||
case '\0':
|
||||
*c = *isofn;
|
||||
break;
|
||||
if (flags & ISOFSMNT_KICONV && cd9660_iconv) {
|
||||
i = j = len = 2;
|
||||
inbuf[0]=(char)*(isofn - 1);
|
||||
inbuf[1]=(char)*isofn;
|
||||
inbuf[2]='\0';
|
||||
inp = inbuf;
|
||||
outp = outbuf;
|
||||
cd9660_iconv->convchr(handle, (const char **)&inp, &i, &outp, &j);
|
||||
len -= j;
|
||||
if (clen) *clen = len;
|
||||
*c = '\0';
|
||||
while(len--)
|
||||
*c |= (*(outp - len - 1) & 0xff) << (len << 3);
|
||||
} else {
|
||||
switch (*c) {
|
||||
default:
|
||||
*c = '?';
|
||||
break;
|
||||
case '\0':
|
||||
*c = *isofn;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* XXX: if Unicode conversion routine is loaded then use it */
|
||||
if (cd9660_wchar2char != NULL)
|
||||
*c = cd9660_wchar2char((*(isofn - 1) << 8) | *isofn);
|
||||
|
||||
return 2;
|
||||
}
|
||||
@ -96,53 +110,60 @@ isochar(isofn, isoend, joliet_level, c)
|
||||
* Note: Version number plus ';' may be omitted.
|
||||
*/
|
||||
int
|
||||
isofncmp(fn, fnlen, isofn, isolen, joliet_level)
|
||||
isofncmp(fn, fnlen, isofn, isolen, joliet_level, flags, handle, lhandle)
|
||||
u_char *fn;
|
||||
int fnlen;
|
||||
u_char *isofn;
|
||||
int isolen;
|
||||
int joliet_level;
|
||||
int flags;
|
||||
void *handle;
|
||||
void *lhandle;
|
||||
{
|
||||
int i, j;
|
||||
u_char c, *fnend = fn + fnlen, *isoend = isofn + isolen;
|
||||
u_short c, d;
|
||||
u_char *fnend = fn + fnlen, *isoend = isofn + isolen;
|
||||
|
||||
for (; fn != fnend; fn++) {
|
||||
for (; fn < fnend; ) {
|
||||
d = sgetrune(fn, fnend - fn, (char const **)&fn, flags, lhandle);
|
||||
if (isofn == isoend)
|
||||
return *fn;
|
||||
isofn += isochar(isofn, isoend, joliet_level, &c);
|
||||
return d;
|
||||
isofn += isochar(isofn, isoend, joliet_level, &c, NULL, flags, handle);
|
||||
if (c == ';') {
|
||||
if (*fn++ != ';')
|
||||
return fn[-1];
|
||||
for (i = 0; fn != fnend; i = i * 10 + *fn++ - '0') {
|
||||
if (d != ';')
|
||||
return d;
|
||||
for (i = 0; fn < fnend; i = i * 10 + *fn++ - '0') {
|
||||
if (*fn < '0' || *fn > '9') {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
for (j = 0; isofn != isoend; j = j * 10 + c - '0')
|
||||
isofn += isochar(isofn, isoend,
|
||||
joliet_level, &c);
|
||||
joliet_level, &c,
|
||||
NULL, flags, handle);
|
||||
return i - j;
|
||||
}
|
||||
if (c != *fn) {
|
||||
if (c != d) {
|
||||
if (c >= 'A' && c <= 'Z') {
|
||||
if (c + ('a' - 'A') != *fn) {
|
||||
if (*fn >= 'a' && *fn <= 'z')
|
||||
return *fn - ('a' - 'A') - c;
|
||||
if (c + ('a' - 'A') != d) {
|
||||
if (d >= 'a' && d <= 'z')
|
||||
return d - ('a' - 'A') - c;
|
||||
else
|
||||
return *fn - c;
|
||||
return d - c;
|
||||
}
|
||||
} else
|
||||
return *fn - c;
|
||||
return d - c;
|
||||
}
|
||||
}
|
||||
if (isofn != isoend) {
|
||||
isofn += isochar(isofn, isoend, joliet_level, &c);
|
||||
isofn += isochar(isofn, isoend, joliet_level, &c, NULL, flags, handle);
|
||||
switch (c) {
|
||||
default:
|
||||
return -c;
|
||||
case '.':
|
||||
if (isofn != isoend) {
|
||||
isochar(isofn, isoend, joliet_level, &c);
|
||||
isochar(isofn, isoend, joliet_level, &c,
|
||||
NULL, flags, handle);
|
||||
if (c == ';')
|
||||
return 0;
|
||||
}
|
||||
@ -158,7 +179,7 @@ isofncmp(fn, fnlen, isofn, isolen, joliet_level)
|
||||
* translate a filename of length > 0
|
||||
*/
|
||||
void
|
||||
isofntrans(infn, infnlen, outfn, outfnlen, original, assoc, joliet_level)
|
||||
isofntrans(infn, infnlen, outfn, outfnlen, original, assoc, joliet_level, flags, handle)
|
||||
u_char *infn;
|
||||
int infnlen;
|
||||
u_char *outfn;
|
||||
@ -166,25 +187,61 @@ isofntrans(infn, infnlen, outfn, outfnlen, original, assoc, joliet_level)
|
||||
int original;
|
||||
int assoc;
|
||||
int joliet_level;
|
||||
int flags;
|
||||
void *handle;
|
||||
{
|
||||
int fnidx = 0;
|
||||
u_char c, d = '\0', *infnend = infn + infnlen;
|
||||
u_short c, d = '\0';
|
||||
u_char *outp = outfn, *infnend = infn + infnlen;
|
||||
int clen;
|
||||
|
||||
if (assoc) {
|
||||
*outfn++ = ASSOCCHAR;
|
||||
fnidx++;
|
||||
*outp++ = ASSOCCHAR;
|
||||
}
|
||||
for (; infn != infnend; fnidx++) {
|
||||
infn += isochar(infn, infnend, joliet_level, &c);
|
||||
for (; infn != infnend; ) {
|
||||
infn += isochar(infn, infnend, joliet_level, &c, &clen, flags, handle);
|
||||
|
||||
if (!original && !joliet_level && c >= 'A' && c <= 'Z')
|
||||
*outfn++ = c + ('a' - 'A');
|
||||
c += ('a' - 'A');
|
||||
else if (!original && c == ';') {
|
||||
fnidx -= (d == '.');
|
||||
outp -= (d == '.');
|
||||
break;
|
||||
} else
|
||||
*outfn++ = c;
|
||||
}
|
||||
d = c;
|
||||
while(clen--)
|
||||
*outp++ = c >> (clen << 3);
|
||||
}
|
||||
*outfnlen = fnidx;
|
||||
*outfnlen = outp - outfn;
|
||||
}
|
||||
|
||||
/*
|
||||
* same as sgetrune(3)
|
||||
*/
|
||||
u_short
|
||||
sgetrune(string, n, result, flags, handle)
|
||||
const char *string;
|
||||
size_t n;
|
||||
char const **result;
|
||||
int flags;
|
||||
void *handle;
|
||||
{
|
||||
size_t i, j, len;
|
||||
char outbuf[3], *outp;
|
||||
u_short c = '\0';
|
||||
|
||||
len = i = (n < 2) ? n : 2;
|
||||
j = 2;
|
||||
outp = outbuf;
|
||||
|
||||
if (flags & ISOFSMNT_KICONV && cd9660_iconv) {
|
||||
cd9660_iconv->convchr(handle, (const char **)&string,
|
||||
&i, &outp, &j);
|
||||
len -= i;
|
||||
} else {
|
||||
len = 1;
|
||||
string++;
|
||||
}
|
||||
|
||||
if (result) *result = string;
|
||||
while(len--) c |= (*(string - len - 1) & 0xff) << (len << 3);
|
||||
return (c);
|
||||
}
|
||||
|
@ -56,6 +56,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/syslog.h>
|
||||
#include <sys/iconv.h>
|
||||
|
||||
|
||||
#include <isofs/cd9660/iso.h>
|
||||
@ -66,6 +67,8 @@ __FBSDID("$FreeBSD$");
|
||||
MALLOC_DEFINE(M_ISOFSMNT, "ISOFS mount", "ISOFS mount structure");
|
||||
MALLOC_DEFINE(M_ISOFSNODE, "ISOFS node", "ISOFS vnode private part");
|
||||
|
||||
struct iconv_functions *cd9660_iconv = NULL;
|
||||
|
||||
static vfs_mount_t cd9660_mount;
|
||||
static vfs_unmount_t cd9660_unmount;
|
||||
static vfs_root_t cd9660_root;
|
||||
@ -471,7 +474,16 @@ iso_mountfs(devvp, mp, td, argp)
|
||||
bp = NULL;
|
||||
}
|
||||
isomp->im_flags = argp->flags & (ISOFSMNT_NORRIP | ISOFSMNT_GENS |
|
||||
ISOFSMNT_EXTATT | ISOFSMNT_NOJOLIET);
|
||||
ISOFSMNT_EXTATT | ISOFSMNT_NOJOLIET |
|
||||
ISOFSMNT_KICONV);
|
||||
|
||||
if (isomp->im_flags & ISOFSMNT_KICONV && cd9660_iconv) {
|
||||
cd9660_iconv->open(argp->cs_local, argp->cs_disk, &isomp->im_d2l);
|
||||
cd9660_iconv->open(argp->cs_disk, argp->cs_local, &isomp->im_l2d);
|
||||
} else {
|
||||
isomp->im_d2l = NULL;
|
||||
isomp->im_l2d = NULL;
|
||||
}
|
||||
|
||||
if (high_sierra) {
|
||||
/* this effectively ignores all the mount flags */
|
||||
@ -551,6 +563,12 @@ cd9660_unmount(mp, mntflags, td)
|
||||
|
||||
isomp = VFSTOISOFS(mp);
|
||||
|
||||
if (isomp->im_flags & ISOFSMNT_KICONV && cd9660_iconv) {
|
||||
if (isomp->im_d2l)
|
||||
cd9660_iconv->close(isomp->im_d2l);
|
||||
if (isomp->im_l2d)
|
||||
cd9660_iconv->close(isomp->im_l2d);
|
||||
}
|
||||
isomp->im_devvp->v_rdev->si_mountpoint = NULL;
|
||||
error = VOP_CLOSE(isomp->im_devvp, FREAD, NOCRED, td);
|
||||
vrele(isomp->im_devvp);
|
||||
|
@ -562,7 +562,9 @@ cd9660_readdir(ap)
|
||||
idp->current.d_name, &namelen,
|
||||
imp->iso_ftype == ISO_FTYPE_9660,
|
||||
isonum_711(ep->flags)&4,
|
||||
imp->joliet_level);
|
||||
imp->joliet_level,
|
||||
imp->im_flags,
|
||||
imp->im_d2l);
|
||||
idp->current.d_namlen = (u_char)namelen;
|
||||
if (imp->iso_ftype == ISO_FTYPE_DEFAULT)
|
||||
error = iso_shipdir(idp);
|
||||
|
@ -245,6 +245,9 @@ struct iso_mnt {
|
||||
int rr_skip0;
|
||||
|
||||
int joliet_level;
|
||||
|
||||
void *im_d2l;
|
||||
void *im_l2d;
|
||||
};
|
||||
|
||||
#define VFSTOISOFS(mp) ((struct iso_mnt *)((mp)->mnt_data))
|
||||
@ -265,10 +268,11 @@ extern vop_t **cd9660_vnodeop_p;
|
||||
extern vop_t **cd9660_specop_p;
|
||||
extern vop_t **cd9660_fifoop_p;
|
||||
|
||||
int isochar(u_char *, u_char *, int, u_char *);
|
||||
int isofncmp(u_char *, int, u_char *, int, int);
|
||||
void isofntrans(u_char *, int, u_char *, u_short *, int, int, int);
|
||||
int isochar(u_char *, u_char *, int, u_short *, int *, int, void *);
|
||||
int isofncmp(u_char *, int, u_char *, int, int, int, void *, void *);
|
||||
void isofntrans(u_char *, int, u_char *, u_short *, int, int, int, int, void *);
|
||||
ino_t isodirino(struct iso_directory_record *, struct iso_mnt *);
|
||||
u_short sgetrune(const char *, size_t, char const **, int, void *);
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
|
@ -97,6 +97,11 @@ struct winentry {
|
||||
};
|
||||
#define WIN_CHARS 13 /* Number of chars per winentry */
|
||||
|
||||
/*
|
||||
* Maximum number of winentries for a filename
|
||||
*/
|
||||
#define WIN_MAXSUBENTRIES 20
|
||||
|
||||
/*
|
||||
* Maximum filename length in Win95
|
||||
* Note: Must be < sizeof(dirent.d_name)
|
||||
@ -132,12 +137,15 @@ struct dirent;
|
||||
void unix2dostime(struct timespec *tsp, u_int16_t *ddp,
|
||||
u_int16_t *dtp, u_int8_t *dhp);
|
||||
void dos2unixtime(u_int dd, u_int dt, u_int dh, struct timespec *tsp);
|
||||
int dos2unixfn(u_char dn[11], u_char *un, int lower, int d2u_loaded, u_int8_t *d2u, int ul_loaded, u_int8_t *ul);
|
||||
int unix2dosfn(const u_char *un, u_char dn[12], int unlen, u_int gen, int u2d_loaded, u_int8_t *u2d, int lu_loaded, u_int8_t *lu);
|
||||
int unix2winfn(const u_char *un, int unlen, struct winentry *wep, int cnt, int chksum, int table_loaded, u_int16_t *u2w);
|
||||
int winChkName(const u_char *un, int unlen, struct winentry *wep, int chksum, int u2w_loaded, u_int16_t *u2w, int ul_loaded, u_int8_t *ul);
|
||||
int win2unixfn(struct winentry *wep, struct dirent *dp, int chksum, int table_loaded, u_int16_t *u2w);
|
||||
int dos2unixfn(u_char dn[11], u_char *un, int lower, struct msdosfsmount *pmp);
|
||||
int unix2dosfn(const u_char *un, u_char dn[12], int unlen, u_int gen, struct msdosfsmount *pmp);
|
||||
int unix2winfn(const u_char *un, int unlen, struct winentry *wep, int cnt, int chksum, struct msdosfsmount *pmp);
|
||||
int winChkName(const u_char *un, int unlen, int chksum, struct msdosfsmount *pmp);
|
||||
int win2unixfn(struct winentry *wep, int chksum, struct msdosfsmount *pmp);
|
||||
u_int8_t winChksum(u_int8_t *name);
|
||||
int winSlotCnt(const u_char *un, int unlen);
|
||||
int winSlotCnt(const u_char *un, int unlen, struct msdosfsmount *);
|
||||
int winLenFixup(const u_char *un, int unlen);
|
||||
void mbnambuf_init(void);
|
||||
void mbnambuf_write(char *name, int id);
|
||||
char * mbnambuf_flush(struct dirent *dp);
|
||||
#endif /* _KERNEL */
|
||||
|
File diff suppressed because it is too large
Load Diff
36
sys/fs/msdosfs/msdosfs_iconv.c
Normal file
36
sys/fs/msdosfs/msdosfs_iconv.c
Normal file
@ -0,0 +1,36 @@
|
||||
/*-
|
||||
* Copyright (c) 2003 Ryuichiro Imura
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/iconv.h>
|
||||
|
||||
VFS_DECLARE_ICONV(msdosfs);
|
@ -57,9 +57,9 @@
|
||||
#include <sys/mount.h>
|
||||
|
||||
#include <fs/msdosfs/bpb.h>
|
||||
#include <fs/msdosfs/msdosfsmount.h>
|
||||
#include <fs/msdosfs/direntry.h>
|
||||
#include <fs/msdosfs/denode.h>
|
||||
#include <fs/msdosfs/msdosfsmount.h>
|
||||
#include <fs/msdosfs/fat.h>
|
||||
|
||||
/*
|
||||
@ -150,21 +150,19 @@ msdosfs_lookup(ap)
|
||||
}
|
||||
|
||||
switch (unix2dosfn((const u_char *)cnp->cn_nameptr, dosfilename,
|
||||
cnp->cn_namelen, 0,
|
||||
pmp->pm_flags & MSDOSFSMNT_U2WTABLE, pmp->pm_u2d,
|
||||
pmp->pm_flags & MSDOSFSMNT_ULTABLE, pmp->pm_lu)) {
|
||||
cnp->cn_namelen, 0, pmp)) {
|
||||
case 0:
|
||||
return (EINVAL);
|
||||
case 1:
|
||||
break;
|
||||
case 2:
|
||||
wincnt = winSlotCnt((const u_char *)cnp->cn_nameptr,
|
||||
cnp->cn_namelen) + 1;
|
||||
cnp->cn_namelen, pmp) + 1;
|
||||
break;
|
||||
case 3:
|
||||
olddos = 0;
|
||||
wincnt = winSlotCnt((const u_char *)cnp->cn_nameptr,
|
||||
cnp->cn_namelen) + 1;
|
||||
cnp->cn_namelen, pmp) + 1;
|
||||
break;
|
||||
}
|
||||
if (pmp->pm_flags & MSDOSFSMNT_SHORTNAME) {
|
||||
@ -193,6 +191,7 @@ msdosfs_lookup(ap)
|
||||
* by cnp->cn_nameptr.
|
||||
*/
|
||||
tdp = NULL;
|
||||
mbnambuf_init();
|
||||
/*
|
||||
* The outer loop ranges over the clusters that make up the
|
||||
* directory. Note that the root directory is different from all
|
||||
@ -232,6 +231,7 @@ msdosfs_lookup(ap)
|
||||
* Drop memory of previous long matches
|
||||
*/
|
||||
chksum = -1;
|
||||
mbnambuf_init();
|
||||
|
||||
if (slotcount < wincnt) {
|
||||
slotcount++;
|
||||
@ -256,14 +256,18 @@ msdosfs_lookup(ap)
|
||||
if (pmp->pm_flags & MSDOSFSMNT_SHORTNAME)
|
||||
continue;
|
||||
|
||||
chksum = winChkName((const u_char *)cnp->cn_nameptr,
|
||||
unlen,
|
||||
(struct winentry *)dep,
|
||||
chksum = win2unixfn((struct winentry *)dep,
|
||||
chksum,
|
||||
pmp->pm_flags & MSDOSFSMNT_U2WTABLE,
|
||||
pmp->pm_u2w,
|
||||
pmp->pm_flags & MSDOSFSMNT_ULTABLE,
|
||||
pmp->pm_ul);
|
||||
pmp);
|
||||
continue;
|
||||
}
|
||||
|
||||
chksum = winChkName((const u_char *)cnp->cn_nameptr,
|
||||
unlen,
|
||||
chksum,
|
||||
pmp);
|
||||
if (chksum == -2) {
|
||||
chksum = -1;
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -659,9 +663,7 @@ createde(dep, ddep, depp, cnp)
|
||||
ddep->de_fndoffset -= sizeof(struct direntry);
|
||||
}
|
||||
if (!unix2winfn(un, unlen, (struct winentry *)ndep,
|
||||
cnt++, chksum,
|
||||
pmp->pm_flags & MSDOSFSMNT_U2WTABLE,
|
||||
pmp->pm_u2w))
|
||||
cnt++, chksum, pmp))
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -992,19 +994,14 @@ uniqdosname(dep, cnp, cp)
|
||||
|
||||
if (pmp->pm_flags & MSDOSFSMNT_SHORTNAME)
|
||||
return (unix2dosfn((const u_char *)cnp->cn_nameptr, cp,
|
||||
cnp->cn_namelen, 0,
|
||||
pmp->pm_flags & MSDOSFSMNT_U2WTABLE, pmp->pm_u2d,
|
||||
pmp->pm_flags & MSDOSFSMNT_ULTABLE, pmp->pm_lu) ?
|
||||
0 : EINVAL);
|
||||
cnp->cn_namelen, 0, pmp) ? 0 : EINVAL);
|
||||
|
||||
for (gen = 1;; gen++) {
|
||||
/*
|
||||
* Generate DOS name with generation number
|
||||
*/
|
||||
if (!unix2dosfn((const u_char *)cnp->cn_nameptr, cp,
|
||||
cnp->cn_namelen, gen,
|
||||
pmp->pm_flags & MSDOSFSMNT_U2WTABLE, pmp->pm_u2d,
|
||||
pmp->pm_flags & MSDOSFSMNT_ULTABLE, pmp->pm_lu))
|
||||
cnp->cn_namelen, gen, pmp))
|
||||
return gen == 1 ? EINVAL : EEXIST;
|
||||
|
||||
/*
|
||||
|
@ -61,13 +61,14 @@
|
||||
#include <sys/fcntl.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/stat.h> /* defines ALLPERMS */
|
||||
#include <sys/iconv.h>
|
||||
#include <sys/mutex.h>
|
||||
|
||||
#include <fs/msdosfs/bpb.h>
|
||||
#include <fs/msdosfs/bootsect.h>
|
||||
#include <fs/msdosfs/msdosfsmount.h>
|
||||
#include <fs/msdosfs/direntry.h>
|
||||
#include <fs/msdosfs/denode.h>
|
||||
#include <fs/msdosfs/msdosfsmount.h>
|
||||
#include <fs/msdosfs/fat.h>
|
||||
|
||||
#define MSDOSFS_DFLTBSIZE 4096
|
||||
@ -86,6 +87,8 @@
|
||||
MALLOC_DEFINE(M_MSDOSFSMNT, "MSDOSFS mount", "MSDOSFS mount structure");
|
||||
static MALLOC_DEFINE(M_MSDOSFSFAT, "MSDOSFS FAT", "MSDOSFS file allocation table");
|
||||
|
||||
struct iconv_functions *msdosfs_iconv = NULL;
|
||||
|
||||
static int update_mp(struct mount *mp, struct msdosfs_args *argp);
|
||||
static int mountmsdosfs(struct vnode *devvp, struct mount *mp,
|
||||
struct thread *td, struct msdosfs_args *argp);
|
||||
@ -110,14 +113,16 @@ update_mp(mp, argp)
|
||||
pmp->pm_mask = argp->mask & ALLPERMS;
|
||||
pmp->pm_dirmask = argp->dirmask & ALLPERMS;
|
||||
pmp->pm_flags |= argp->flags & MSDOSFSMNT_MNTOPT;
|
||||
if (pmp->pm_flags & MSDOSFSMNT_U2WTABLE) {
|
||||
bcopy(argp->u2w, pmp->pm_u2w, sizeof(pmp->pm_u2w));
|
||||
bcopy(argp->d2u, pmp->pm_d2u, sizeof(pmp->pm_d2u));
|
||||
bcopy(argp->u2d, pmp->pm_u2d, sizeof(pmp->pm_u2d));
|
||||
}
|
||||
if (pmp->pm_flags & MSDOSFSMNT_ULTABLE) {
|
||||
bcopy(argp->ul, pmp->pm_ul, sizeof(pmp->pm_ul));
|
||||
bcopy(argp->lu, pmp->pm_lu, sizeof(pmp->pm_lu));
|
||||
if (pmp->pm_flags & MSDOSFSMNT_KICONV && msdosfs_iconv) {
|
||||
msdosfs_iconv->open(argp->cs_win, argp->cs_local , &pmp->pm_u2w);
|
||||
msdosfs_iconv->open(argp->cs_local, argp->cs_win , &pmp->pm_w2u);
|
||||
msdosfs_iconv->open(argp->cs_dos, argp->cs_local , &pmp->pm_u2d);
|
||||
msdosfs_iconv->open(argp->cs_local, argp->cs_dos , &pmp->pm_d2u);
|
||||
} else {
|
||||
pmp->pm_w2u = NULL;
|
||||
pmp->pm_u2w = NULL;
|
||||
pmp->pm_d2u = NULL;
|
||||
pmp->pm_u2d = NULL;
|
||||
}
|
||||
|
||||
if (pmp->pm_flags & MSDOSFSMNT_NOWIN95)
|
||||
@ -651,6 +656,16 @@ msdosfs_unmount(mp, mntflags, td)
|
||||
if (error)
|
||||
return error;
|
||||
pmp = VFSTOMSDOSFS(mp);
|
||||
if (pmp->pm_flags & MSDOSFSMNT_KICONV && msdosfs_iconv) {
|
||||
if (pmp->pm_w2u)
|
||||
msdosfs_iconv->close(pmp->pm_w2u);
|
||||
if (pmp->pm_u2w)
|
||||
msdosfs_iconv->close(pmp->pm_u2w);
|
||||
if (pmp->pm_d2u)
|
||||
msdosfs_iconv->close(pmp->pm_d2u);
|
||||
if (pmp->pm_u2d)
|
||||
msdosfs_iconv->close(pmp->pm_u2d);
|
||||
}
|
||||
pmp->pm_devvp->v_rdev->si_mountpoint = NULL;
|
||||
#ifdef MSDOSFS_DEBUG
|
||||
{
|
||||
@ -864,3 +879,4 @@ static struct vfsops msdosfs_vfsops = {
|
||||
};
|
||||
|
||||
VFS_SET(msdosfs_vfsops, msdosfs, 0);
|
||||
MODULE_VERSION(msdosfs, 1);
|
||||
|
@ -71,9 +71,9 @@
|
||||
#include <machine/mutex.h>
|
||||
|
||||
#include <fs/msdosfs/bpb.h>
|
||||
#include <fs/msdosfs/msdosfsmount.h>
|
||||
#include <fs/msdosfs/direntry.h>
|
||||
#include <fs/msdosfs/denode.h>
|
||||
#include <fs/msdosfs/msdosfsmount.h>
|
||||
#include <fs/msdosfs/fat.h>
|
||||
|
||||
#define DOS_FILESIZE_MAX 0xffffffff
|
||||
@ -1554,6 +1554,7 @@ msdosfs_readdir(ap)
|
||||
}
|
||||
}
|
||||
|
||||
mbnambuf_init();
|
||||
off = offset;
|
||||
while (uio->uio_resid > 0) {
|
||||
lbn = de_cluster(pmp, offset - bias);
|
||||
@ -1600,6 +1601,7 @@ msdosfs_readdir(ap)
|
||||
*/
|
||||
if (dentp->deName[0] == SLOT_DELETED) {
|
||||
chksum = -1;
|
||||
mbnambuf_init();
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -1610,9 +1612,7 @@ msdosfs_readdir(ap)
|
||||
if (pmp->pm_flags & MSDOSFSMNT_SHORTNAME)
|
||||
continue;
|
||||
chksum = win2unixfn((struct winentry *)dentp,
|
||||
&dirbuf, chksum,
|
||||
pmp->pm_flags & MSDOSFSMNT_U2WTABLE,
|
||||
pmp->pm_u2w);
|
||||
chksum, pmp);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -1621,6 +1621,7 @@ msdosfs_readdir(ap)
|
||||
*/
|
||||
if (dentp->deAttributes & ATTR_VOLUME) {
|
||||
chksum = -1;
|
||||
mbnambuf_init();
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
@ -1648,18 +1649,16 @@ msdosfs_readdir(ap)
|
||||
dirbuf.d_fileno = offset / sizeof(struct direntry);
|
||||
dirbuf.d_type = DT_REG;
|
||||
}
|
||||
if (chksum != winChksum(dentp->deName))
|
||||
if (chksum != winChksum(dentp->deName)) {
|
||||
dirbuf.d_namlen = dos2unixfn(dentp->deName,
|
||||
(u_char *)dirbuf.d_name,
|
||||
dentp->deLowerCase |
|
||||
((pmp->pm_flags & MSDOSFSMNT_SHORTNAME) ?
|
||||
(LCASE_BASE | LCASE_EXT) : 0),
|
||||
pmp->pm_flags & MSDOSFSMNT_U2WTABLE,
|
||||
pmp->pm_d2u,
|
||||
pmp->pm_flags & MSDOSFSMNT_ULTABLE,
|
||||
pmp->pm_ul);
|
||||
else
|
||||
dirbuf.d_name[dirbuf.d_namlen] = 0;
|
||||
pmp);
|
||||
mbnambuf_init();
|
||||
} else
|
||||
mbnambuf_flush(&dirbuf);
|
||||
chksum = -1;
|
||||
dirbuf.d_reclen = GENERIC_DIRSIZ(&dirbuf);
|
||||
if (uio->uio_resid < dirbuf.d_reclen) {
|
||||
|
@ -95,11 +95,10 @@ struct msdosfsmount {
|
||||
u_int pm_curfat; /* current fat for FAT32 (0 otherwise) */
|
||||
u_int *pm_inusemap; /* ptr to bitmap of in-use clusters */
|
||||
u_int pm_flags; /* see below */
|
||||
u_int16_t pm_u2w[128]; /* Local->Unicode table */
|
||||
u_int8_t pm_ul[128]; /* Local upper->lower table */
|
||||
u_int8_t pm_lu[128]; /* Local lower->upper table */
|
||||
u_int8_t pm_d2u[128]; /* DOS->local table */
|
||||
u_int8_t pm_u2d[128]; /* Local->DOS table */
|
||||
void *pm_u2w; /* Local->Unicode iconv handle */
|
||||
void *pm_w2u; /* Unicode->Local iconv handle */
|
||||
void *pm_u2d; /* Unicode->DOS iconv handle */
|
||||
void *pm_d2u; /* DOS->Local iconv handle */
|
||||
};
|
||||
/* Byte offset in FAT on filesystem pmp, cluster cn */
|
||||
#define FATOFS(pmp, cn) ((cn) * (pmp)->pm_fatmult / (pmp)->pm_fatdiv)
|
||||
@ -218,10 +217,9 @@ struct msdosfs_args {
|
||||
int flags; /* see below */
|
||||
int magic; /* version number */
|
||||
u_int16_t u2w[128]; /* Local->Unicode table */
|
||||
u_int8_t ul[128]; /* Local upper->lower table */
|
||||
u_int8_t lu[128]; /* Local lower->upper table */
|
||||
u_int8_t d2u[128]; /* DOS->local table */
|
||||
u_int8_t u2d[128]; /* Local->DOS table */
|
||||
char *cs_win; /* Windows(Unicode) Charset */
|
||||
char *cs_dos; /* DOS Charset */
|
||||
char *cs_local; /* Local Charset */
|
||||
};
|
||||
|
||||
/*
|
||||
@ -230,13 +228,11 @@ struct msdosfs_args {
|
||||
#define MSDOSFSMNT_SHORTNAME 1 /* Force old DOS short names only */
|
||||
#define MSDOSFSMNT_LONGNAME 2 /* Force Win'95 long names */
|
||||
#define MSDOSFSMNT_NOWIN95 4 /* Completely ignore Win95 entries */
|
||||
#define MSDOSFSMNT_U2WTABLE 0x10 /* Local->Unicode and local<->DOS */
|
||||
/* tables loaded */
|
||||
#define MSDOSFSMNT_ULTABLE 0x20 /* Local upper<->lower table loaded */
|
||||
#define MSDOSFSMNT_KICONV 0x10 /* Use libiconv to convert chars */
|
||||
/* All flags above: */
|
||||
#define MSDOSFSMNT_MNTOPT \
|
||||
(MSDOSFSMNT_SHORTNAME|MSDOSFSMNT_LONGNAME|MSDOSFSMNT_NOWIN95 \
|
||||
|MSDOSFSMNT_U2WTABLE|MSDOSFSMNT_ULTABLE)
|
||||
|MSDOSFSMNT_KICONV)
|
||||
#define MSDOSFSMNT_RONLY 0x80000000 /* mounted read-only */
|
||||
#define MSDOSFSMNT_WAITONFAT 0x40000000 /* mounted synchronous */
|
||||
#define MSDOSFS_FATMIRROR 0x20000000 /* FAT is mirrored */
|
||||
|
@ -254,6 +254,8 @@ struct ntfsmount {
|
||||
int ntm_adnum;
|
||||
wchar * ntm_82u; /* 8bit to Unicode */
|
||||
char ** ntm_u28; /* Unicode to 8 bit */
|
||||
void * ntm_ic_l2u; /* Local to Unicode (iconv) */
|
||||
void * ntm_ic_u2l; /* Unicode to Local (iconv) */
|
||||
};
|
||||
|
||||
#define ntm_mftcn ntm_bootfile.bf_mftcn
|
||||
|
36
sys/fs/ntfs/ntfs_iconv.c
Normal file
36
sys/fs/ntfs/ntfs_iconv.c
Normal file
@ -0,0 +1,36 @@
|
||||
/*-
|
||||
* Copyright (c) 2003 Ryuichiro Imura
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/iconv.h>
|
||||
|
||||
VFS_DECLARE_ICONV(ntfs);
|
@ -40,6 +40,7 @@
|
||||
#include <sys/file.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/iconv.h>
|
||||
|
||||
/* #define NTFS_DEBUG 1 */
|
||||
#include <fs/ntfs/ntfs.h>
|
||||
@ -67,6 +68,8 @@ static wchar *ntfs_toupper_tab;
|
||||
static struct lock ntfs_toupper_lock;
|
||||
static signed int ntfs_toupper_usecount;
|
||||
|
||||
struct iconv_functions *ntfs_iconv = NULL;
|
||||
|
||||
/* support macro for ntfs_ntvattrget() */
|
||||
#define NTFS_AALPCMP(aalp,type,name,namelen) ( \
|
||||
(aalp->al_type == type) && (aalp->al_namelen == namelen) && \
|
||||
@ -665,20 +668,41 @@ ntfs_uastricmp(ntmp, ustr, ustrlen, astr, astrlen)
|
||||
const char *astr;
|
||||
size_t astrlen;
|
||||
{
|
||||
size_t i;
|
||||
int res;
|
||||
int len;
|
||||
size_t i, j, mbstrlen = astrlen;
|
||||
int res;
|
||||
wchar wc;
|
||||
|
||||
/*
|
||||
* 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_82U(NTFS_U28(ustr[i])))) -
|
||||
((int)NTFS_TOUPPER(NTFS_82U(astr[i])));
|
||||
if (res)
|
||||
return res;
|
||||
if (ntmp->ntm_ic_l2u) {
|
||||
for (i = 0, j = 0; i < ustrlen && j < astrlen; i++, j++) {
|
||||
if (j < astrlen -1) {
|
||||
wc = (wchar)astr[j]<<8 | (astr[j+1]&0xFF);
|
||||
len = 2;
|
||||
} else {
|
||||
wc = (wchar)astr[j]<<8 & 0xFF00;
|
||||
len = 1;
|
||||
}
|
||||
res = ((int) NTFS_TOUPPER(ustr[i])) -
|
||||
((int)NTFS_TOUPPER(NTFS_82U(wc, &len)));
|
||||
j += len - 1;
|
||||
mbstrlen -= len - 1;
|
||||
|
||||
if (res)
|
||||
return res;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* 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_82U(NTFS_U28(ustr[i]), &len))) -
|
||||
((int)NTFS_TOUPPER(NTFS_82U((wchar)astr[i], &len)));
|
||||
if (res)
|
||||
return res;
|
||||
}
|
||||
}
|
||||
return (ustrlen - astrlen);
|
||||
return (ustrlen - mbstrlen);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -692,15 +716,25 @@ ntfs_uastrcmp(ntmp, ustr, ustrlen, astr, astrlen)
|
||||
const char *astr;
|
||||
size_t astrlen;
|
||||
{
|
||||
size_t i;
|
||||
int res;
|
||||
char u, l;
|
||||
size_t i, j, mbstrlen = astrlen;
|
||||
int res;
|
||||
wchar wc;
|
||||
|
||||
for (i = 0; (i < ustrlen) && (i < astrlen); i++) {
|
||||
res = (int) (((char)NTFS_U28(ustr[i])) - astr[i]);
|
||||
for (i = 0, j = 0; (i < ustrlen) && (j < astrlen); i++, j++) {
|
||||
res = 0;
|
||||
wc = NTFS_U28(ustr[i]);
|
||||
u = (char)(wc>>8);
|
||||
l = (char)wc;
|
||||
if (u != '\0' && j < astrlen -1) {
|
||||
res = (int) (u - astr[j++]);
|
||||
mbstrlen--;
|
||||
}
|
||||
res = (res<<8) + (int) (l - astr[j]);
|
||||
if (res)
|
||||
return res;
|
||||
}
|
||||
return (ustrlen - astrlen);
|
||||
return (ustrlen - mbstrlen);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2003,11 +2037,18 @@ ntfs_toupper_unuse()
|
||||
int
|
||||
ntfs_u28_init(
|
||||
struct ntfsmount *ntmp,
|
||||
wchar *u2w)
|
||||
wchar *u2w,
|
||||
char *cs_local,
|
||||
char *cs_ntfs)
|
||||
{
|
||||
char ** u28;
|
||||
int i, j, h, l;
|
||||
|
||||
if (ntfs_iconv && cs_local) {
|
||||
ntfs_iconv->open(cs_local, cs_ntfs, &ntmp->ntm_ic_u2l);
|
||||
return (0);
|
||||
}
|
||||
|
||||
MALLOC(u28, char **, 256 * sizeof(char*), M_TEMP, M_WAITOK | M_ZERO);
|
||||
|
||||
for (i=0; i<256; i++) {
|
||||
@ -2034,8 +2075,12 @@ ntfs_u28_uninit(struct ntfsmount *ntmp)
|
||||
char ** u28;
|
||||
int i;
|
||||
|
||||
if (ntmp->ntm_u28 == NULL)
|
||||
if (ntmp->ntm_u28 == NULL) {
|
||||
if (ntfs_iconv && ntmp->ntm_ic_u2l) {
|
||||
ntfs_iconv->close(ntmp->ntm_ic_u2l);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
u28 = ntmp->ntm_u28;
|
||||
|
||||
@ -2051,22 +2096,21 @@ ntfs_u28_uninit(struct ntfsmount *ntmp)
|
||||
int
|
||||
ntfs_82u_init(
|
||||
struct ntfsmount *ntmp,
|
||||
u_int16_t *u2w)
|
||||
char *cs_local,
|
||||
char *cs_ntfs)
|
||||
{
|
||||
wchar * _82u;
|
||||
int i;
|
||||
|
||||
if (ntfs_iconv && cs_local) {
|
||||
ntfs_iconv->open(cs_ntfs, cs_local, &ntmp->ntm_ic_l2u);
|
||||
return (0);
|
||||
}
|
||||
|
||||
MALLOC(_82u, wchar *, 256 * sizeof(wchar), M_TEMP, M_WAITOK);
|
||||
|
||||
if (u2w == NULL) {
|
||||
for (i=0; i<256; i++)
|
||||
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;
|
||||
|
||||
@ -2076,6 +2120,14 @@ ntfs_82u_init(
|
||||
int
|
||||
ntfs_82u_uninit(struct ntfsmount *ntmp)
|
||||
{
|
||||
|
||||
if (ntmp->ntm_82u == NULL) {
|
||||
if (ntfs_iconv && ntmp->ntm_ic_l2u) {
|
||||
ntfs_iconv->close(ntmp->ntm_ic_l2u);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
FREE(ntmp->ntm_82u, M_TEMP);
|
||||
return (0);
|
||||
}
|
||||
@ -2086,12 +2138,31 @@ ntfs_82u_uninit(struct ntfsmount *ntmp)
|
||||
* and substitutes a '_' for it if the result would be '\0';
|
||||
* something better has to be definitely though out
|
||||
*/
|
||||
char
|
||||
wchar
|
||||
ntfs_u28(
|
||||
struct ntfsmount *ntmp,
|
||||
wchar wc)
|
||||
{
|
||||
char * p;
|
||||
char *p, *outp, inbuf[3], outbuf[3];
|
||||
size_t ilen, olen;
|
||||
|
||||
if (ntfs_iconv && ntmp->ntm_ic_u2l) {
|
||||
ilen = olen = 2;
|
||||
|
||||
inbuf[0] = (char)(wc>>8);
|
||||
inbuf[1] = (char)wc;
|
||||
inbuf[2] = '\0';
|
||||
p = inbuf;
|
||||
outp = outbuf;
|
||||
ntfs_iconv->convchr(ntmp->ntm_ic_u2l, (const char **)&p, &ilen,
|
||||
&outp, &olen);
|
||||
if (olen == 1) {
|
||||
return ((wchar)(outbuf[0]));
|
||||
} else if (olen == 0) {
|
||||
return ((wchar)((outbuf[0]<<8) | (outbuf[1]&0xFF)));
|
||||
}
|
||||
return ('?');
|
||||
}
|
||||
|
||||
p = ntmp->ntm_u28[(wc>>8)&0xFF];
|
||||
if (p == NULL)
|
||||
@ -2099,3 +2170,36 @@ ntfs_u28(
|
||||
return (p[wc&0xFF]);
|
||||
}
|
||||
|
||||
wchar
|
||||
ntfs_82u(
|
||||
struct ntfsmount *ntmp,
|
||||
wchar wc,
|
||||
int *len)
|
||||
{
|
||||
char *p, *outp, inbuf[3], outbuf[3];
|
||||
wchar uc;
|
||||
size_t ilen, olen;
|
||||
|
||||
if (ntfs_iconv && ntmp->ntm_ic_l2u) {
|
||||
ilen = (size_t)*len;
|
||||
olen = 2;
|
||||
|
||||
inbuf[0] = (char)(wc>>8);
|
||||
inbuf[1] = (char)wc;
|
||||
inbuf[2] = '\0';
|
||||
p = inbuf;
|
||||
outp = outbuf;
|
||||
ntfs_iconv->convchr(ntmp->ntm_ic_l2u, (const char **)&p, &ilen,
|
||||
&outp, &olen);
|
||||
*len -= (int)ilen;
|
||||
uc = (wchar)((outbuf[0]<<8) | (outbuf[1]&0xFF));
|
||||
|
||||
return (uc);
|
||||
}
|
||||
|
||||
if (ntmp->ntm_82u != NULL)
|
||||
return (ntmp->ntm_82u[wc&0xFF]);
|
||||
|
||||
return ('?');
|
||||
}
|
||||
|
||||
|
@ -108,13 +108,14 @@ void ntfs_toupper_unuse(void);
|
||||
int ntfs_fget(struct ntfsmount *, struct ntnode *, int, char *, struct fnode **);
|
||||
void ntfs_frele(struct fnode *);
|
||||
|
||||
int ntfs_u28_init(struct ntfsmount *ntmp, wchar *u2w);
|
||||
int ntfs_u28_init(struct ntfsmount *ntmp, wchar *u2w, char *cs_local, char *cs_ntfs);
|
||||
int ntfs_u28_uninit(struct ntfsmount *ntmp);
|
||||
int ntfs_82u_init(struct ntfsmount *ntmp, u_int16_t *u2w);
|
||||
int ntfs_82u_init(struct ntfsmount *ntmp, char *cs_local, char *cs_ntfs);
|
||||
int ntfs_82u_uninit(struct ntfsmount *ntmp);
|
||||
char ntfs_u28(struct ntfsmount *ntmp, wchar wc);
|
||||
wchar ntfs_u28(struct ntfsmount *ntmp, wchar wc);
|
||||
wchar ntfs_82u(struct ntfsmount *ntmp, wchar wc, int *len);
|
||||
#define NTFS_U28(ch) ntfs_u28(ntmp, (ch))
|
||||
#define NTFS_82U(ch) (ntmp->ntm_82u[(ch)&0xFF])
|
||||
#define NTFS_82U(ch, len) ntfs_82u(ntmp, (ch), len)
|
||||
#define NTFS_UASTRCMP(ustr, ustrlen, astr, astrlen) \
|
||||
ntfs_uastrcmp(ntmp, (ustr), (ustrlen), (astr), (astrlen))
|
||||
#define NTFS_UASTRICMP(ustr, ustrlen, astr, astrlen) \
|
||||
|
@ -350,14 +350,14 @@ ntfs_mountfs(devvp, mp, argsp, td)
|
||||
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);
|
||||
if (argsp->flag & NTFS_MFLAG_KICONV) {
|
||||
ntfs_82u_init(ntmp, argsp->cs_local, argsp->cs_ntfs);
|
||||
ntfs_u28_init(ntmp, NULL, argsp->cs_local, argsp->cs_ntfs);
|
||||
} else {
|
||||
ntfs_82u_init(ntmp, NULL, NULL);
|
||||
ntfs_u28_init(ntmp, ntmp->ntm_82u, NULL, NULL);
|
||||
}
|
||||
|
||||
mp->mnt_data = (qaddr_t)ntmp;
|
||||
|
||||
@ -794,3 +794,4 @@ static struct vfsops ntfs_vfsops = {
|
||||
.vfs_vptofh = ntfs_vptofh,
|
||||
};
|
||||
VFS_SET(ntfs_vfsops, ntfs, 0);
|
||||
MODULE_VERSION(ntfs, 1);
|
||||
|
@ -495,7 +495,8 @@ ntfs_readdir(ap)
|
||||
register struct ntnode *ip = FTONT(fp);
|
||||
struct uio *uio = ap->a_uio;
|
||||
struct ntfsmount *ntmp = ip->i_mp;
|
||||
int i, error = 0;
|
||||
int i, j, error = 0;
|
||||
wchar c;
|
||||
u_int32_t faked = 0, num;
|
||||
int ncookies = 0;
|
||||
struct dirent cde;
|
||||
@ -552,14 +553,17 @@ ntfs_readdir(ap)
|
||||
if(!ntfs_isnamepermitted(ntmp,iep))
|
||||
continue;
|
||||
|
||||
for(i=0; i<iep->ie_fnamelen; i++) {
|
||||
cde.d_name[i] = NTFS_U28(iep->ie_fname[i]);
|
||||
for(i=0, j=0; i<iep->ie_fnamelen; i++, j++) {
|
||||
c = NTFS_U28(iep->ie_fname[i]);
|
||||
if (c&0xFF00)
|
||||
cde.d_name[j++] = (char)(c>>8);
|
||||
cde.d_name[j] = (char)c&0xFF;
|
||||
}
|
||||
cde.d_name[i] = '\0';
|
||||
cde.d_name[j] = '\0';
|
||||
dprintf(("ntfs_readdir: elem: %d, fname:[%s] type: %d, flag: %d, ",
|
||||
num, cde.d_name, iep->ie_fnametype,
|
||||
iep->ie_flag));
|
||||
cde.d_namlen = iep->ie_fnamelen;
|
||||
cde.d_namlen = j;
|
||||
cde.d_fileno = iep->ie_number;
|
||||
cde.d_type = (iep->ie_fflag & NTFS_FFLAG_DIR) ? DT_DIR : DT_REG;
|
||||
cde.d_reclen = sizeof(struct dirent);
|
||||
|
@ -30,7 +30,7 @@
|
||||
|
||||
#define NTFS_MFLAG_CASEINS 0x00000001
|
||||
#define NTFS_MFLAG_ALLNAMES 0x00000002
|
||||
#define NTFSMNT_U2WTABLE 0x00000004
|
||||
#define NTFS_MFLAG_KICONV 0x00000004
|
||||
|
||||
struct ntfs_args {
|
||||
char *fspec; /* block special device to mount */
|
||||
@ -39,5 +39,6 @@ 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 */
|
||||
char *cs_ntfs; /* NTFS Charset */
|
||||
char *cs_local; /* Local Charset */
|
||||
};
|
||||
|
@ -101,7 +101,7 @@ static struct vfsops smbfs_vfsops = {
|
||||
VFS_SET(smbfs_vfsops, smbfs, VFCF_NETWORK);
|
||||
|
||||
MODULE_DEPEND(smbfs, netsmb, NSMB_VERSION, NSMB_VERSION, NSMB_VERSION);
|
||||
MODULE_DEPEND(smbfs, libiconv, 1, 1, 1);
|
||||
MODULE_DEPEND(smbfs, libiconv, 1, 1, 2);
|
||||
MODULE_DEPEND(smbfs, libmchain, 1, 1, 1);
|
||||
|
||||
int smbfs_pbuf_freecnt = -1; /* start out unlimited */
|
||||
|
36
sys/isofs/cd9660/cd9660_iconv.c
Normal file
36
sys/isofs/cd9660/cd9660_iconv.c
Normal file
@ -0,0 +1,36 @@
|
||||
/*-
|
||||
* Copyright (c) 2003 Ryuichiro Imura
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/iconv.h>
|
||||
|
||||
VFS_DECLARE_ICONV(cd9660);
|
@ -238,7 +238,12 @@ cd9660_lookup(ap)
|
||||
if (namelen != 1
|
||||
|| ep->name[0] != 0)
|
||||
goto notfound;
|
||||
} else if (!(res = isofncmp(name, len, ep->name, namelen, imp->joliet_level))) {
|
||||
} else if (!(res = isofncmp(name, len,
|
||||
ep->name, namelen,
|
||||
imp->joliet_level,
|
||||
imp->im_flags,
|
||||
imp->im_d2l,
|
||||
imp->im_l2d))) {
|
||||
if (isoflags & 2)
|
||||
ino = isodirino(ep, imp);
|
||||
else
|
||||
|
@ -47,9 +47,12 @@ struct iso_args {
|
||||
struct export_args export; /* network export info */
|
||||
int flags; /* mounting flags, see below */
|
||||
int ssector; /* starting sector, 0 for 1st session */
|
||||
char *cs_disk; /* disk charset for Joliet cs conversion */
|
||||
char *cs_local; /* local charset for Joliet cs conversion */
|
||||
};
|
||||
#define ISOFSMNT_NORRIP 0x00000001 /* disable Rock Ridge Ext.*/
|
||||
#define ISOFSMNT_GENS 0x00000002 /* enable generation numbers */
|
||||
#define ISOFSMNT_EXTATT 0x00000004 /* enable extended attributes */
|
||||
#define ISOFSMNT_NOJOLIET 0x00000008 /* disable Joliet Ext.*/
|
||||
#define ISOFSMNT_BROKENJOLIET 0x00000010/* allow broken Joliet disks */
|
||||
#define ISOFSMNT_KICONV 0x00000020 /* Use libiconv to convert chars */
|
||||
|
@ -293,7 +293,8 @@ cd9660_rrip_defname(isodir,ana)
|
||||
{
|
||||
isofntrans(isodir->name,isonum_711(isodir->name_len),
|
||||
ana->outbuf,ana->outlen,
|
||||
1,isonum_711(isodir->flags)&4, ana->imp->joliet_level);
|
||||
1,isonum_711(isodir->flags)&4, ana->imp->joliet_level,
|
||||
ana->imp->im_flags, ana->imp->im_d2l);
|
||||
switch (*ana->outbuf) {
|
||||
default:
|
||||
break;
|
||||
@ -491,7 +492,7 @@ cd9660_rrip_loop(isodir,ana,table)
|
||||
register ISO_SUSP_HEADER *pend;
|
||||
struct buf *bp = NULL;
|
||||
char *pwhead;
|
||||
u_char c;
|
||||
u_short c;
|
||||
int result;
|
||||
|
||||
/*
|
||||
@ -501,7 +502,8 @@ cd9660_rrip_loop(isodir,ana,table)
|
||||
pwhead = isodir->name + isonum_711(isodir->name_len);
|
||||
if (!(isonum_711(isodir->name_len)&1))
|
||||
pwhead++;
|
||||
isochar(isodir->name, pwhead, ana->imp->joliet_level, &c);
|
||||
isochar(isodir->name, pwhead, ana->imp->joliet_level, &c, NULL,
|
||||
ana->imp->im_flags, ana->imp->im_d2l);
|
||||
|
||||
/* If it's not the '.' entry of the root dir obey SP field */
|
||||
if (c != 0 || isonum_733(isodir->extent) != ana->imp->root_extent)
|
||||
@ -627,7 +629,7 @@ cd9660_rrip_getname(isodir,outbuf,outlen,inump,imp)
|
||||
{
|
||||
ISO_RRIP_ANALYZE analyze;
|
||||
RRIP_TABLE *tab;
|
||||
u_char c;
|
||||
u_short c;
|
||||
|
||||
analyze.outbuf = outbuf;
|
||||
analyze.outlen = outlen;
|
||||
@ -638,7 +640,7 @@ cd9660_rrip_getname(isodir,outbuf,outlen,inump,imp)
|
||||
*outlen = 0;
|
||||
|
||||
isochar(isodir->name, isodir->name + isonum_711(isodir->name_len),
|
||||
imp->joliet_level, &c);
|
||||
imp->joliet_level, &c, NULL, imp->im_flags, imp->im_d2l);
|
||||
tab = rrip_table_getname;
|
||||
if (c == 0 || c == 1) {
|
||||
cd9660_rrip_defname(isodir,&analyze);
|
||||
|
@ -46,16 +46,12 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/systm.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/vnode.h>
|
||||
#include <sys/iconv.h>
|
||||
|
||||
#include <isofs/cd9660/iso.h>
|
||||
#include <isofs/cd9660/cd9660_mount.h>
|
||||
|
||||
/*
|
||||
* XXX: limited support for loading of Unicode
|
||||
* conversion routine as a kld at a run-time.
|
||||
* Should be removed when native Unicode kernel
|
||||
* interfaces have been introduced.
|
||||
*/
|
||||
u_char (*cd9660_wchar2char)(u_int32_t wchar) = NULL;
|
||||
extern struct iconv_functions *cd9660_iconv;
|
||||
|
||||
/*
|
||||
* Get one character out of an iso filename
|
||||
@ -63,29 +59,47 @@ u_char (*cd9660_wchar2char)(u_int32_t wchar) = NULL;
|
||||
* Return number of bytes consumed
|
||||
*/
|
||||
int
|
||||
isochar(isofn, isoend, joliet_level, c)
|
||||
isochar(isofn, isoend, joliet_level, c, clen, flags, handle)
|
||||
u_char *isofn;
|
||||
u_char *isoend;
|
||||
int joliet_level;
|
||||
u_char *c;
|
||||
u_short *c;
|
||||
int *clen;
|
||||
int flags;
|
||||
void *handle;
|
||||
{
|
||||
size_t i, j, len;
|
||||
char inbuf[3], outbuf[3], *inp, *outp;
|
||||
|
||||
*c = *isofn++;
|
||||
if (clen) *clen = 1;
|
||||
if (joliet_level == 0 || isofn == isoend)
|
||||
/* (00) and (01) are one byte in Joliet, too */
|
||||
return 1;
|
||||
|
||||
/* No Unicode support yet :-( */
|
||||
switch (*c) {
|
||||
default:
|
||||
*c = '?';
|
||||
break;
|
||||
case '\0':
|
||||
*c = *isofn;
|
||||
break;
|
||||
if (flags & ISOFSMNT_KICONV && cd9660_iconv) {
|
||||
i = j = len = 2;
|
||||
inbuf[0]=(char)*(isofn - 1);
|
||||
inbuf[1]=(char)*isofn;
|
||||
inbuf[2]='\0';
|
||||
inp = inbuf;
|
||||
outp = outbuf;
|
||||
cd9660_iconv->convchr(handle, (const char **)&inp, &i, &outp, &j);
|
||||
len -= j;
|
||||
if (clen) *clen = len;
|
||||
*c = '\0';
|
||||
while(len--)
|
||||
*c |= (*(outp - len - 1) & 0xff) << (len << 3);
|
||||
} else {
|
||||
switch (*c) {
|
||||
default:
|
||||
*c = '?';
|
||||
break;
|
||||
case '\0':
|
||||
*c = *isofn;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* XXX: if Unicode conversion routine is loaded then use it */
|
||||
if (cd9660_wchar2char != NULL)
|
||||
*c = cd9660_wchar2char((*(isofn - 1) << 8) | *isofn);
|
||||
|
||||
return 2;
|
||||
}
|
||||
@ -96,53 +110,60 @@ isochar(isofn, isoend, joliet_level, c)
|
||||
* Note: Version number plus ';' may be omitted.
|
||||
*/
|
||||
int
|
||||
isofncmp(fn, fnlen, isofn, isolen, joliet_level)
|
||||
isofncmp(fn, fnlen, isofn, isolen, joliet_level, flags, handle, lhandle)
|
||||
u_char *fn;
|
||||
int fnlen;
|
||||
u_char *isofn;
|
||||
int isolen;
|
||||
int joliet_level;
|
||||
int flags;
|
||||
void *handle;
|
||||
void *lhandle;
|
||||
{
|
||||
int i, j;
|
||||
u_char c, *fnend = fn + fnlen, *isoend = isofn + isolen;
|
||||
u_short c, d;
|
||||
u_char *fnend = fn + fnlen, *isoend = isofn + isolen;
|
||||
|
||||
for (; fn != fnend; fn++) {
|
||||
for (; fn < fnend; ) {
|
||||
d = sgetrune(fn, fnend - fn, (char const **)&fn, flags, lhandle);
|
||||
if (isofn == isoend)
|
||||
return *fn;
|
||||
isofn += isochar(isofn, isoend, joliet_level, &c);
|
||||
return d;
|
||||
isofn += isochar(isofn, isoend, joliet_level, &c, NULL, flags, handle);
|
||||
if (c == ';') {
|
||||
if (*fn++ != ';')
|
||||
return fn[-1];
|
||||
for (i = 0; fn != fnend; i = i * 10 + *fn++ - '0') {
|
||||
if (d != ';')
|
||||
return d;
|
||||
for (i = 0; fn < fnend; i = i * 10 + *fn++ - '0') {
|
||||
if (*fn < '0' || *fn > '9') {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
for (j = 0; isofn != isoend; j = j * 10 + c - '0')
|
||||
isofn += isochar(isofn, isoend,
|
||||
joliet_level, &c);
|
||||
joliet_level, &c,
|
||||
NULL, flags, handle);
|
||||
return i - j;
|
||||
}
|
||||
if (c != *fn) {
|
||||
if (c != d) {
|
||||
if (c >= 'A' && c <= 'Z') {
|
||||
if (c + ('a' - 'A') != *fn) {
|
||||
if (*fn >= 'a' && *fn <= 'z')
|
||||
return *fn - ('a' - 'A') - c;
|
||||
if (c + ('a' - 'A') != d) {
|
||||
if (d >= 'a' && d <= 'z')
|
||||
return d - ('a' - 'A') - c;
|
||||
else
|
||||
return *fn - c;
|
||||
return d - c;
|
||||
}
|
||||
} else
|
||||
return *fn - c;
|
||||
return d - c;
|
||||
}
|
||||
}
|
||||
if (isofn != isoend) {
|
||||
isofn += isochar(isofn, isoend, joliet_level, &c);
|
||||
isofn += isochar(isofn, isoend, joliet_level, &c, NULL, flags, handle);
|
||||
switch (c) {
|
||||
default:
|
||||
return -c;
|
||||
case '.':
|
||||
if (isofn != isoend) {
|
||||
isochar(isofn, isoend, joliet_level, &c);
|
||||
isochar(isofn, isoend, joliet_level, &c,
|
||||
NULL, flags, handle);
|
||||
if (c == ';')
|
||||
return 0;
|
||||
}
|
||||
@ -158,7 +179,7 @@ isofncmp(fn, fnlen, isofn, isolen, joliet_level)
|
||||
* translate a filename of length > 0
|
||||
*/
|
||||
void
|
||||
isofntrans(infn, infnlen, outfn, outfnlen, original, assoc, joliet_level)
|
||||
isofntrans(infn, infnlen, outfn, outfnlen, original, assoc, joliet_level, flags, handle)
|
||||
u_char *infn;
|
||||
int infnlen;
|
||||
u_char *outfn;
|
||||
@ -166,25 +187,61 @@ isofntrans(infn, infnlen, outfn, outfnlen, original, assoc, joliet_level)
|
||||
int original;
|
||||
int assoc;
|
||||
int joliet_level;
|
||||
int flags;
|
||||
void *handle;
|
||||
{
|
||||
int fnidx = 0;
|
||||
u_char c, d = '\0', *infnend = infn + infnlen;
|
||||
u_short c, d = '\0';
|
||||
u_char *outp = outfn, *infnend = infn + infnlen;
|
||||
int clen;
|
||||
|
||||
if (assoc) {
|
||||
*outfn++ = ASSOCCHAR;
|
||||
fnidx++;
|
||||
*outp++ = ASSOCCHAR;
|
||||
}
|
||||
for (; infn != infnend; fnidx++) {
|
||||
infn += isochar(infn, infnend, joliet_level, &c);
|
||||
for (; infn != infnend; ) {
|
||||
infn += isochar(infn, infnend, joliet_level, &c, &clen, flags, handle);
|
||||
|
||||
if (!original && !joliet_level && c >= 'A' && c <= 'Z')
|
||||
*outfn++ = c + ('a' - 'A');
|
||||
c += ('a' - 'A');
|
||||
else if (!original && c == ';') {
|
||||
fnidx -= (d == '.');
|
||||
outp -= (d == '.');
|
||||
break;
|
||||
} else
|
||||
*outfn++ = c;
|
||||
}
|
||||
d = c;
|
||||
while(clen--)
|
||||
*outp++ = c >> (clen << 3);
|
||||
}
|
||||
*outfnlen = fnidx;
|
||||
*outfnlen = outp - outfn;
|
||||
}
|
||||
|
||||
/*
|
||||
* same as sgetrune(3)
|
||||
*/
|
||||
u_short
|
||||
sgetrune(string, n, result, flags, handle)
|
||||
const char *string;
|
||||
size_t n;
|
||||
char const **result;
|
||||
int flags;
|
||||
void *handle;
|
||||
{
|
||||
size_t i, j, len;
|
||||
char outbuf[3], *outp;
|
||||
u_short c = '\0';
|
||||
|
||||
len = i = (n < 2) ? n : 2;
|
||||
j = 2;
|
||||
outp = outbuf;
|
||||
|
||||
if (flags & ISOFSMNT_KICONV && cd9660_iconv) {
|
||||
cd9660_iconv->convchr(handle, (const char **)&string,
|
||||
&i, &outp, &j);
|
||||
len -= i;
|
||||
} else {
|
||||
len = 1;
|
||||
string++;
|
||||
}
|
||||
|
||||
if (result) *result = string;
|
||||
while(len--) c |= (*(string - len - 1) & 0xff) << (len << 3);
|
||||
return (c);
|
||||
}
|
||||
|
@ -56,6 +56,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/syslog.h>
|
||||
#include <sys/iconv.h>
|
||||
|
||||
|
||||
#include <isofs/cd9660/iso.h>
|
||||
@ -66,6 +67,8 @@ __FBSDID("$FreeBSD$");
|
||||
MALLOC_DEFINE(M_ISOFSMNT, "ISOFS mount", "ISOFS mount structure");
|
||||
MALLOC_DEFINE(M_ISOFSNODE, "ISOFS node", "ISOFS vnode private part");
|
||||
|
||||
struct iconv_functions *cd9660_iconv = NULL;
|
||||
|
||||
static vfs_mount_t cd9660_mount;
|
||||
static vfs_unmount_t cd9660_unmount;
|
||||
static vfs_root_t cd9660_root;
|
||||
@ -471,7 +474,16 @@ iso_mountfs(devvp, mp, td, argp)
|
||||
bp = NULL;
|
||||
}
|
||||
isomp->im_flags = argp->flags & (ISOFSMNT_NORRIP | ISOFSMNT_GENS |
|
||||
ISOFSMNT_EXTATT | ISOFSMNT_NOJOLIET);
|
||||
ISOFSMNT_EXTATT | ISOFSMNT_NOJOLIET |
|
||||
ISOFSMNT_KICONV);
|
||||
|
||||
if (isomp->im_flags & ISOFSMNT_KICONV && cd9660_iconv) {
|
||||
cd9660_iconv->open(argp->cs_local, argp->cs_disk, &isomp->im_d2l);
|
||||
cd9660_iconv->open(argp->cs_disk, argp->cs_local, &isomp->im_l2d);
|
||||
} else {
|
||||
isomp->im_d2l = NULL;
|
||||
isomp->im_l2d = NULL;
|
||||
}
|
||||
|
||||
if (high_sierra) {
|
||||
/* this effectively ignores all the mount flags */
|
||||
@ -551,6 +563,12 @@ cd9660_unmount(mp, mntflags, td)
|
||||
|
||||
isomp = VFSTOISOFS(mp);
|
||||
|
||||
if (isomp->im_flags & ISOFSMNT_KICONV && cd9660_iconv) {
|
||||
if (isomp->im_d2l)
|
||||
cd9660_iconv->close(isomp->im_d2l);
|
||||
if (isomp->im_l2d)
|
||||
cd9660_iconv->close(isomp->im_l2d);
|
||||
}
|
||||
isomp->im_devvp->v_rdev->si_mountpoint = NULL;
|
||||
error = VOP_CLOSE(isomp->im_devvp, FREAD, NOCRED, td);
|
||||
vrele(isomp->im_devvp);
|
||||
|
@ -562,7 +562,9 @@ cd9660_readdir(ap)
|
||||
idp->current.d_name, &namelen,
|
||||
imp->iso_ftype == ISO_FTYPE_9660,
|
||||
isonum_711(ep->flags)&4,
|
||||
imp->joliet_level);
|
||||
imp->joliet_level,
|
||||
imp->im_flags,
|
||||
imp->im_d2l);
|
||||
idp->current.d_namlen = (u_char)namelen;
|
||||
if (imp->iso_ftype == ISO_FTYPE_DEFAULT)
|
||||
error = iso_shipdir(idp);
|
||||
|
@ -245,6 +245,9 @@ struct iso_mnt {
|
||||
int rr_skip0;
|
||||
|
||||
int joliet_level;
|
||||
|
||||
void *im_d2l;
|
||||
void *im_l2d;
|
||||
};
|
||||
|
||||
#define VFSTOISOFS(mp) ((struct iso_mnt *)((mp)->mnt_data))
|
||||
@ -265,10 +268,11 @@ extern vop_t **cd9660_vnodeop_p;
|
||||
extern vop_t **cd9660_specop_p;
|
||||
extern vop_t **cd9660_fifoop_p;
|
||||
|
||||
int isochar(u_char *, u_char *, int, u_char *);
|
||||
int isofncmp(u_char *, int, u_char *, int, int);
|
||||
void isofntrans(u_char *, int, u_char *, u_short *, int, int, int);
|
||||
int isochar(u_char *, u_char *, int, u_short *, int *, int, void *);
|
||||
int isofncmp(u_char *, int, u_char *, int, int, int, void *, void *);
|
||||
void isofntrans(u_char *, int, u_char *, u_short *, int, int, int, int, void *);
|
||||
ino_t isodirino(struct iso_directory_record *, struct iso_mnt *);
|
||||
u_short sgetrune(const char *, size_t, char const **, int, void *);
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
|
@ -38,6 +38,8 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/iconv.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/syslog.h>
|
||||
|
||||
#include "iconv_converter_if.h"
|
||||
|
||||
@ -48,7 +50,7 @@ SYSCTL_NODE(_kern, OID_AUTO, iconv, CTLFLAG_RW, NULL, "kernel iconv interface");
|
||||
MALLOC_DEFINE(M_ICONV, "ICONV", "ICONV structures");
|
||||
MALLOC_DEFINE(M_ICONVDATA, "ICONV data", "ICONV data");
|
||||
|
||||
MODULE_VERSION(libiconv, 1);
|
||||
MODULE_VERSION(libiconv, 2);
|
||||
|
||||
#ifdef notnow
|
||||
/*
|
||||
@ -272,7 +274,28 @@ int
|
||||
iconv_conv(void *handle, const char **inbuf,
|
||||
size_t *inbytesleft, char **outbuf, size_t *outbytesleft)
|
||||
{
|
||||
return ICONV_CONVERTER_CONV(handle, inbuf, inbytesleft, outbuf, outbytesleft);
|
||||
return ICONV_CONVERTER_CONV(handle, inbuf, inbytesleft, outbuf, outbytesleft, 0, 0);
|
||||
}
|
||||
|
||||
int
|
||||
iconv_conv_case(void *handle, const char **inbuf,
|
||||
size_t *inbytesleft, char **outbuf, size_t *outbytesleft, int casetype)
|
||||
{
|
||||
return ICONV_CONVERTER_CONV(handle, inbuf, inbytesleft, outbuf, outbytesleft, 0, casetype);
|
||||
}
|
||||
|
||||
int
|
||||
iconv_convchr(void *handle, const char **inbuf,
|
||||
size_t *inbytesleft, char **outbuf, size_t *outbytesleft)
|
||||
{
|
||||
return ICONV_CONVERTER_CONV(handle, inbuf, inbytesleft, outbuf, outbytesleft, 1, 0);
|
||||
}
|
||||
|
||||
int
|
||||
iconv_convchr_case(void *handle, const char **inbuf,
|
||||
size_t *inbytesleft, char **outbuf, size_t *outbytesleft, int casetype)
|
||||
{
|
||||
return ICONV_CONVERTER_CONV(handle, inbuf, inbytesleft, outbuf, outbytesleft, 1, casetype);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -371,6 +394,7 @@ iconv_sysctl_add(SYSCTL_HANDLER_ARGS)
|
||||
error = SYSCTL_OUT(req, &dout, sizeof(dout));
|
||||
if (error)
|
||||
goto bad;
|
||||
ICDEBUG("%s => %s, %d bytes\n",din.ia_from, din.ia_to, din.ia_datalen);
|
||||
return 0;
|
||||
bad:
|
||||
iconv_unregister_cspair(csp);
|
||||
@ -421,7 +445,7 @@ iconv_converter_handler(module_t mod, int type, void *data)
|
||||
}
|
||||
|
||||
/*
|
||||
* Common used functions
|
||||
* Common used functions (don't use with unicode)
|
||||
*/
|
||||
char *
|
||||
iconv_convstr(void *handle, char *dst, const char *src)
|
||||
@ -434,7 +458,8 @@ iconv_convstr(void *handle, char *dst, const char *src)
|
||||
strcpy(dst, src);
|
||||
return dst;
|
||||
}
|
||||
inlen = outlen = strlen(src);
|
||||
inlen = strlen(src);
|
||||
outlen = inlen * 3;
|
||||
error = iconv_conv(handle, NULL, NULL, &p, &outlen);
|
||||
if (error)
|
||||
return NULL;
|
||||
@ -459,7 +484,8 @@ iconv_convmem(void *handle, void *dst, const void *src, int size)
|
||||
memcpy(dst, src, size);
|
||||
return dst;
|
||||
}
|
||||
inlen = outlen = size;
|
||||
inlen = size;
|
||||
outlen = inlen * 3;
|
||||
error = iconv_conv(handle, NULL, NULL, &d, &outlen);
|
||||
if (error)
|
||||
return NULL;
|
||||
@ -483,3 +509,22 @@ iconv_lookupcp(char **cpp, const char *s)
|
||||
return 0;
|
||||
return ENOENT;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return if fsname is in use of not
|
||||
*/
|
||||
int
|
||||
iconv_vfs_refcount(const char *fsname)
|
||||
{
|
||||
struct vfsconf *vfsp;
|
||||
|
||||
for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next) {
|
||||
if (!strcmp(vfsp->vfc_name, fsname)) {
|
||||
if (vfsp->vfc_refcount > 0)
|
||||
return (EBUSY);
|
||||
else
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
@ -53,6 +53,8 @@ METHOD int conv {
|
||||
size_t *inbytesleft;
|
||||
char **outbuf;
|
||||
size_t *outbytesleft;
|
||||
int convchar;
|
||||
int casetype;
|
||||
};
|
||||
|
||||
STATICMETHOD int init {
|
||||
|
@ -46,7 +46,7 @@ __FBSDID("$FreeBSD$");
|
||||
*/
|
||||
|
||||
#ifdef MODULE_DEPEND
|
||||
MODULE_DEPEND(iconv_xlat, libiconv, 1, 1, 1);
|
||||
MODULE_DEPEND(iconv_xlat, libiconv, 2, 2, 2);
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -84,7 +84,8 @@ iconv_xlat_close(void *data)
|
||||
|
||||
static int
|
||||
iconv_xlat_conv(void *d2p, const char **inbuf,
|
||||
size_t *inbytesleft, char **outbuf, size_t *outbytesleft)
|
||||
size_t *inbytesleft, char **outbuf, size_t *outbytesleft,
|
||||
int convchar, int casetype)
|
||||
{
|
||||
struct iconv_xlat *dp = (struct iconv_xlat*)d2p;
|
||||
const char *src;
|
||||
@ -93,14 +94,19 @@ iconv_xlat_conv(void *d2p, const char **inbuf,
|
||||
|
||||
if (inbuf == NULL || *inbuf == NULL || outbuf == NULL || *outbuf == NULL)
|
||||
return 0;
|
||||
r = n = min(*inbytesleft, *outbytesleft);
|
||||
if (casetype != 0)
|
||||
return -1;
|
||||
if (convchar == 1)
|
||||
r = n = 1;
|
||||
else
|
||||
r = n = min(*inbytesleft, *outbytesleft);
|
||||
src = *inbuf;
|
||||
dst = *outbuf;
|
||||
while(r--)
|
||||
*dst++ = dp->d_table[(u_char)*src++];
|
||||
*inbuf += n;
|
||||
*outbuf += n;
|
||||
*inbytesleft += n;
|
||||
*inbytesleft -= n;
|
||||
*outbytesleft -= n;
|
||||
return 0;
|
||||
}
|
||||
|
242
sys/libkern/iconv_xlat16.c
Normal file
242
sys/libkern/iconv_xlat16.c
Normal file
@ -0,0 +1,242 @@
|
||||
/*-
|
||||
* Copyright (c) 2003, Ryuichiro Imura
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/iconv.h>
|
||||
|
||||
#include "iconv_converter_if.h"
|
||||
|
||||
/*
|
||||
* "XLAT16" converter
|
||||
*/
|
||||
|
||||
#ifdef MODULE_DEPEND
|
||||
MODULE_DEPEND(iconv_xlat16, libiconv, 2, 2, 2);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* XLAT16 converter instance
|
||||
*/
|
||||
struct iconv_xlat16 {
|
||||
KOBJ_FIELDS;
|
||||
uint32_t * d_table[0x200];
|
||||
struct iconv_cspair * d_csp;
|
||||
};
|
||||
|
||||
static int
|
||||
iconv_xlat16_open(struct iconv_converter_class *dcp,
|
||||
struct iconv_cspair *csp, struct iconv_cspair *cspf, void **dpp)
|
||||
{
|
||||
struct iconv_xlat16 *dp;
|
||||
uint32_t *headp, *idxp, dist = 0;
|
||||
int i;
|
||||
|
||||
dp = (struct iconv_xlat16 *)kobj_create((struct kobj_class*)dcp, M_ICONV, M_WAITOK);
|
||||
headp = idxp = (uint32_t *)csp->cp_data;
|
||||
dist = 0x200;
|
||||
for (i = 0 ; i < 0x200 ; i++) {
|
||||
if (*idxp) {
|
||||
dp->d_table[i] = headp + dist;
|
||||
dist += 0x80;
|
||||
} else {
|
||||
dp->d_table[i] = NULL;
|
||||
}
|
||||
idxp++;
|
||||
}
|
||||
dp->d_csp = csp;
|
||||
csp->cp_refcount++;
|
||||
*dpp = (void*)dp;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
iconv_xlat16_close(void *data)
|
||||
{
|
||||
struct iconv_xlat16 *dp = data;
|
||||
|
||||
dp->d_csp->cp_refcount--;
|
||||
kobj_delete((struct kobj*)data, M_ICONV);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
iconv_xlat16_conv(void *d2p, const char **inbuf,
|
||||
size_t *inbytesleft, char **outbuf, size_t *outbytesleft,
|
||||
int convchar, int casetype)
|
||||
{
|
||||
struct iconv_xlat16 *dp = (struct iconv_xlat16*)d2p;
|
||||
const char *src;
|
||||
char *dst;
|
||||
int ret = 0;
|
||||
size_t in, on, ir, or, inlen;
|
||||
uint32_t code;
|
||||
u_char u, l;
|
||||
u_int16_t c1, c2;
|
||||
|
||||
if (inbuf == NULL || *inbuf == NULL || outbuf == NULL || *outbuf == NULL)
|
||||
return (0);
|
||||
ir = in = *inbytesleft;
|
||||
or = on = *outbytesleft;
|
||||
src = *inbuf;
|
||||
dst = *outbuf;
|
||||
|
||||
while(ir > 0 && or > 0) {
|
||||
|
||||
inlen = 0;
|
||||
code = '\0';
|
||||
|
||||
c1 = ir > 1 ? *(src+1) & 0xff : 0;
|
||||
c2 = *src & 0xff;
|
||||
|
||||
c1 = c2 & 0x80 ? c1 | 0x100 : c1;
|
||||
c2 = c2 & 0x80 ? c2 & 0x7f : c2;
|
||||
|
||||
if (ir > 1 && dp->d_table[c1]) {
|
||||
/*
|
||||
* inbuf char is a double byte char
|
||||
*/
|
||||
code = dp->d_table[c1][c2];
|
||||
if (code)
|
||||
inlen = 2;
|
||||
}
|
||||
|
||||
if (inlen == 0) {
|
||||
c1 &= 0xff00;
|
||||
if (!dp->d_table[c1]) {
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* inbuf char is a single byte char
|
||||
*/
|
||||
inlen = 1;
|
||||
code = dp->d_table[c1][c2];
|
||||
if (!code) {
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ((inlen == 1) && (code & XLAT16_ACCEPT_NULL_IN)) {
|
||||
/*
|
||||
* XLAT16_ACCEPT_NULL_IN requires inbuf has 2byte
|
||||
*/
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* now start translation
|
||||
*/
|
||||
u = (u_char)(code >> 8);
|
||||
l = (u_char)code;
|
||||
|
||||
#ifdef XLAT16_ACCEPT_3BYTE_CHR
|
||||
if (code & XLAT16_IS_3BYTE_CHR) {
|
||||
if (or < 3) {
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
*dst++ = u;
|
||||
*dst++ = l;
|
||||
*dst++ = (u_char)(code >> 16);
|
||||
or -= 3;
|
||||
} else
|
||||
#endif
|
||||
if (u || code & XLAT16_ACCEPT_NULL_OUT) {
|
||||
if (or < 2) {
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
*dst++ = u;
|
||||
*dst++ = l;
|
||||
or -= 2;
|
||||
} else {
|
||||
if ((casetype == KICONV_LOWER && code & XLAT16_HAS_LOWER_CASE) ||
|
||||
(casetype == KICONV_UPPER && code & XLAT16_HAS_UPPER_CASE))
|
||||
*dst++ = (u_char)(code >> 16);
|
||||
else if ((casetype == KICONV_FROM_LOWER && code & XLAT16_HAS_FROM_LOWER_CASE) ||
|
||||
(casetype == KICONV_FROM_UPPER && code & XLAT16_HAS_FROM_UPPER_CASE))
|
||||
*dst++ = dp->d_table[0][(u_char)(code >> 16)];
|
||||
else
|
||||
*dst++ = l;
|
||||
or--;
|
||||
}
|
||||
|
||||
if (inlen == 2) {
|
||||
/*
|
||||
* there is a case that inbuf char is a single
|
||||
* byte char while inlen == 2
|
||||
*/
|
||||
if ((u_char)*(src+1) == 0 &&
|
||||
(code & XLAT16_ACCEPT_NULL_IN) == 0 ) {
|
||||
src++;
|
||||
ir--;
|
||||
} else {
|
||||
src += 2;
|
||||
ir -= 2;
|
||||
}
|
||||
} else {
|
||||
src++;
|
||||
ir--;
|
||||
}
|
||||
|
||||
if (convchar == 1)
|
||||
break;
|
||||
}
|
||||
|
||||
*inbuf += in - ir;
|
||||
*outbuf += on - or;
|
||||
*inbytesleft -= in - ir;
|
||||
*outbytesleft -= on - or;
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static const char *
|
||||
iconv_xlat16_name(struct iconv_converter_class *dcp)
|
||||
{
|
||||
return ("xlat16");
|
||||
}
|
||||
|
||||
static kobj_method_t iconv_xlat16_methods[] = {
|
||||
KOBJMETHOD(iconv_converter_open, iconv_xlat16_open),
|
||||
KOBJMETHOD(iconv_converter_close, iconv_xlat16_close),
|
||||
KOBJMETHOD(iconv_converter_conv, iconv_xlat16_conv),
|
||||
#if 0
|
||||
KOBJMETHOD(iconv_converter_init, iconv_xlat16_init),
|
||||
KOBJMETHOD(iconv_converter_done, iconv_xlat16_done),
|
||||
#endif
|
||||
KOBJMETHOD(iconv_converter_name, iconv_xlat16_name),
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
KICONV_CONVERTER(xlat16, sizeof(struct iconv_xlat16));
|
@ -25,6 +25,7 @@ SUBDIR= accf_data \
|
||||
bridge \
|
||||
cam \
|
||||
cd9660 \
|
||||
cd9660_iconv \
|
||||
coda \
|
||||
coda5 \
|
||||
${_crypto} \
|
||||
@ -85,12 +86,14 @@ SUBDIR= accf_data \
|
||||
mlx \
|
||||
mpt \
|
||||
msdosfs \
|
||||
msdosfs_iconv \
|
||||
my \
|
||||
nfsclient \
|
||||
nfsserver \
|
||||
nge \
|
||||
nmdm \
|
||||
ntfs \
|
||||
ntfs_iconv \
|
||||
nullfs \
|
||||
patm \
|
||||
pcn \
|
||||
|
@ -6,6 +6,6 @@ KMOD= cd9660
|
||||
SRCS= vnode_if.h \
|
||||
cd9660_bmap.c cd9660_lookup.c cd9660_node.c cd9660_rrip.c \
|
||||
cd9660_util.c cd9660_vfsops.c cd9660_vnops.c
|
||||
EXPORT_SYMS= cd9660_wchar2char
|
||||
EXPORT_SYMS= cd9660_iconv
|
||||
|
||||
.include <bsd.kmod.mk>
|
||||
|
7
sys/modules/cd9660_iconv/Makefile
Normal file
7
sys/modules/cd9660_iconv/Makefile
Normal file
@ -0,0 +1,7 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.PATH: ${.CURDIR}/../../isofs/cd9660
|
||||
KMOD= cd9660_iconv
|
||||
SRCS= cd9660_iconv.c
|
||||
|
||||
.include <bsd.kmod.mk>
|
@ -3,7 +3,7 @@
|
||||
.PATH: ${.CURDIR}/../../libkern ${.CURDIR}/../../sys
|
||||
|
||||
KMOD= libiconv
|
||||
SRCS= iconv.c iconv_xlat.c
|
||||
SRCS= iconv.c iconv_xlat.c iconv_xlat16.c
|
||||
SRCS+= iconv.h
|
||||
SRCS+= iconv_converter_if.c iconv_converter_if.h
|
||||
MFILES= libkern/iconv_converter_if.m
|
||||
@ -11,7 +11,11 @@ MFILES= libkern/iconv_converter_if.m
|
||||
EXPORT_SYMS= iconv_open \
|
||||
iconv_close \
|
||||
iconv_conv \
|
||||
iconv_conv_case \
|
||||
iconv_convchr \
|
||||
iconv_convchr_case \
|
||||
iconv_convstr \
|
||||
iconv_convmem
|
||||
iconv_convmem \
|
||||
iconv_vfs_refcount
|
||||
|
||||
.include <bsd.kmod.mk>
|
||||
|
@ -6,5 +6,6 @@ KMOD= msdosfs
|
||||
SRCS= vnode_if.h \
|
||||
msdosfs_conv.c msdosfs_denode.c msdosfs_fat.c msdosfs_lookup.c \
|
||||
msdosfs_vfsops.c msdosfs_vnops.c
|
||||
EXPORT_SYMS= msdosfs_iconv
|
||||
|
||||
.include <bsd.kmod.mk>
|
||||
|
7
sys/modules/msdosfs_iconv/Makefile
Normal file
7
sys/modules/msdosfs_iconv/Makefile
Normal file
@ -0,0 +1,7 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.PATH: ${.CURDIR}/../../fs/msdosfs
|
||||
KMOD= msdosfs_iconv
|
||||
SRCS= msdosfs_iconv.c
|
||||
|
||||
.include <bsd.kmod.mk>
|
@ -6,5 +6,6 @@ KMOD= ntfs
|
||||
SRCS= vnode_if.h \
|
||||
ntfs_vfsops.c ntfs_vnops.c ntfs_subr.c ntfs_ihash.c \
|
||||
ntfs_compr.c
|
||||
EXPORT_SYMS= ntfs_iconv
|
||||
|
||||
.include <bsd.kmod.mk>
|
||||
|
7
sys/modules/ntfs_iconv/Makefile
Normal file
7
sys/modules/ntfs_iconv/Makefile
Normal file
@ -0,0 +1,7 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.PATH: ${.CURDIR}/../../fs/ntfs
|
||||
KMOD= ntfs_iconv
|
||||
SRCS= ntfs_iconv.c
|
||||
|
||||
.include <bsd.kmod.mk>
|
@ -70,7 +70,7 @@ static d_open_t nsmb_dev_open;
|
||||
static d_close_t nsmb_dev_close;
|
||||
static d_ioctl_t nsmb_dev_ioctl;
|
||||
|
||||
MODULE_DEPEND(netsmb, libiconv, 1, 1, 1);
|
||||
MODULE_DEPEND(netsmb, libiconv, 1, 1, 2);
|
||||
MODULE_VERSION(netsmb, NSMB_VERSION);
|
||||
|
||||
static int smb_version = NSMB_VERSION;
|
||||
|
@ -36,7 +36,20 @@
|
||||
|
||||
#define ICONV_CSNMAXLEN 31 /* maximum length of charset name */
|
||||
#define ICONV_CNVNMAXLEN 31 /* maximum length of converter name */
|
||||
#define ICONV_CSMAXDATALEN 1024 /* maximum size of data associated with cs pair */
|
||||
#define ICONV_CSMAXDATALEN (2048+262144) /* maximum size of data associated with cs pair */
|
||||
|
||||
#define XLAT16_ACCEPT_NULL_OUT 0x01000000
|
||||
#define XLAT16_ACCEPT_NULL_IN 0x02000000
|
||||
#define XLAT16_HAS_LOWER_CASE 0x04000000
|
||||
#define XLAT16_HAS_UPPER_CASE 0x08000000
|
||||
#define XLAT16_HAS_FROM_LOWER_CASE 0x10000000
|
||||
#define XLAT16_HAS_FROM_UPPER_CASE 0x20000000
|
||||
#define XLAT16_IS_3BYTE_CHR 0x40000000
|
||||
|
||||
#define KICONV_LOWER 1 /* tolower converted character */
|
||||
#define KICONV_UPPER 2 /* toupper converted character */
|
||||
#define KICONV_FROM_LOWER 4 /* tolower source character, then convert */
|
||||
#define KICONV_FROM_UPPER 8 /* toupper source character, then convert */
|
||||
|
||||
/*
|
||||
* Entry for cslist sysctl
|
||||
@ -74,7 +87,13 @@ struct iconv_add_out {
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
#define ENCODING_UNICODE "ISO-10646-UCS-2"
|
||||
#define KICONV_VENDOR_MICSFT 1 /* Microsoft Vendor Code for quirk */
|
||||
|
||||
int kiconv_add_xlat_table(const char *, const char *, const u_char *);
|
||||
int kiconv_add_xlat16_cspair(const char *, const char *, int);
|
||||
int kiconv_add_xlat16_table(const char *, const char *, const void *, int);
|
||||
const char *kiconv_quirkcs(const char *, int);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
@ -133,8 +152,74 @@ int iconv_open(const char *to, const char *from, void **handle);
|
||||
int iconv_close(void *handle);
|
||||
int iconv_conv(void *handle, const char **inbuf,
|
||||
size_t *inbytesleft, char **outbuf, size_t *outbytesleft);
|
||||
int iconv_conv_case(void *handle, const char **inbuf,
|
||||
size_t *inbytesleft, char **outbuf, size_t *outbytesleft, int casetype);
|
||||
int iconv_convchr(void *handle, const char **inbuf,
|
||||
size_t *inbytesleft, char **outbuf, size_t *outbytesleft);
|
||||
int iconv_convchr_case(void *handle, const char **inbuf,
|
||||
size_t *inbytesleft, char **outbuf, size_t *outbytesleft, int casetype);
|
||||
char* iconv_convstr(void *handle, char *dst, const char *src);
|
||||
void* iconv_convmem(void *handle, void *dst, const void *src, int size);
|
||||
int iconv_vfs_refcount(const char *fsname);
|
||||
|
||||
/*
|
||||
* Bridge struct of iconv functions
|
||||
*/
|
||||
struct iconv_functions {
|
||||
int (*open)(const char *to, const char *from, void **handle);
|
||||
int (*close)(void *handle);
|
||||
int (*conv)(void *handle, const char **inbuf, size_t *inbytesleft,
|
||||
char **outbuf, size_t *outbytesleft);
|
||||
int (*conv_case)(void *handle, const char **inbuf, size_t *inbytesleft,
|
||||
char **outbuf, size_t *outbytesleft, int casetype);
|
||||
int (*convchr)(void *handle, const char **inbuf, size_t *inbytesleft,
|
||||
char **outbuf, size_t *outbytesleft);
|
||||
int (*convchr_case)(void *handle, const char **inbuf, size_t *inbytesleft,
|
||||
char **outbuf, size_t *outbytesleft, int casetype);
|
||||
};
|
||||
|
||||
#define VFS_DECLARE_ICONV(fsname) \
|
||||
static struct iconv_functions fsname ## _iconv_core = { \
|
||||
iconv_open, \
|
||||
iconv_close, \
|
||||
iconv_conv, \
|
||||
iconv_conv_case, \
|
||||
iconv_convchr, \
|
||||
iconv_convchr_case \
|
||||
}; \
|
||||
extern struct iconv_functions *fsname ## _iconv; \
|
||||
static int fsname ## _iconv_mod_handler(module_t mod, \
|
||||
int type, void *d); \
|
||||
static int \
|
||||
fsname ## _iconv_mod_handler(module_t mod, int type, void *d) \
|
||||
{ \
|
||||
int error = 0; \
|
||||
switch(type) { \
|
||||
case MOD_LOAD: \
|
||||
fsname ## _iconv = & fsname ## _iconv_core; \
|
||||
break; \
|
||||
case MOD_UNLOAD: \
|
||||
error = iconv_vfs_refcount(#fsname); \
|
||||
if (error) \
|
||||
return (EBUSY); \
|
||||
fsname ## _iconv = NULL; \
|
||||
break; \
|
||||
default: \
|
||||
error = EINVAL; \
|
||||
break; \
|
||||
} \
|
||||
return (error); \
|
||||
} \
|
||||
static moduledata_t fsname ## _iconv_mod = { \
|
||||
#fsname"_iconv", \
|
||||
fsname ## _iconv_mod_handler, \
|
||||
NULL \
|
||||
}; \
|
||||
DECLARE_MODULE(fsname ## _iconv, fsname ## _iconv_mod, \
|
||||
SI_SUB_DRIVERS, SI_ORDER_ANY); \
|
||||
MODULE_DEPEND(fsname ## _iconv, fsname, 1, 1, 1); \
|
||||
MODULE_DEPEND(fsname ## _iconv, libiconv, 2, 2, 2); \
|
||||
MODULE_VERSION(fsname ## _iconv, 1)
|
||||
|
||||
/*
|
||||
* Internal functions
|
||||
|
Loading…
Reference in New Issue
Block a user