summaryrefslogtreecommitdiff
path: root/sys/isofs/udf
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2006-01-14 19:04:18 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2006-01-14 19:04:18 +0000
commitdc020d5edad184ce0746299844a3d25b9cbc3264 (patch)
treee64027739f95c18c4954f6216ef24dd76f1075af /sys/isofs/udf
parentf83a64de348c2d1013a09e1230f2b64cb75c2f77 (diff)
Better UDF name extraction code, which will not forget to report errors in
some cases; also silence a few udf messages unless option DIAGNOSTIC. Tests and tweaks and ok pedro@
Diffstat (limited to 'sys/isofs/udf')
-rw-r--r--sys/isofs/udf/osta.c508
-rw-r--r--sys/isofs/udf/osta.h30
-rw-r--r--sys/isofs/udf/udf.h4
-rw-r--r--sys/isofs/udf/udf_extern.h7
-rw-r--r--sys/isofs/udf/udf_subr.c79
-rw-r--r--sys/isofs/udf/udf_vfsops.c3
-rw-r--r--sys/isofs/udf/udf_vnops.c22
7 files changed, 102 insertions, 551 deletions
diff --git a/sys/isofs/udf/osta.c b/sys/isofs/udf/osta.c
deleted file mode 100644
index 30ff2114f42..00000000000
--- a/sys/isofs/udf/osta.c
+++ /dev/null
@@ -1,508 +0,0 @@
-/* $OpenBSD: osta.c,v 1.2 2005/03/30 01:06:49 pedro Exp $ */
-
-/*
- * Various routines from the OSTA 2.01 specs. Copyrights are included with
- * each code segment. Slight whitespace modifications have been made for
- * formatting purposes. Typos/bugs have been fixed.
- *
- * $FreeBSD: src/sys/fs/udf/osta.c,v 1.4 2005/01/06 18:10:41 imp Exp $
- */
-
-#include <isofs/udf/osta.h>
-
-/*****************************************************************************/
-/*-
- **********************************************************************
- * OSTA compliant Unicode compression, uncompression routines.
- * Copyright 1995 Micro Design International, Inc.
- * Written by Jason M. Rinn.
- * Micro Design International gives permission for the free use of the
- * following source code.
- */
-
-/***********************************************************************
- * Takes an OSTA CS0 compressed unicode name, and converts
- * it to Unicode.
- * The Unicode output will be in the byte order
- * that the local compiler uses for 16-bit values.
- * NOTE: This routine only performs error checking on the compID.
- * It is up to the user to ensure that the unicode buffer is large
- * enough, and that the compressed unicode name is correct.
- *
- * RETURN VALUE
- *
- * The number of unicode characters which were uncompressed.
- * A -1 is returned if the compression ID is invalid.
- */
-int
-udf_UncompressUnicode(
- int numberOfBytes, /* (Input) number of bytes read from media. */
- byte *UDFCompressed, /* (Input) bytes read from media. */
- unicode_t *unicode) /* (Output) uncompressed unicode characters. */
-{
- unsigned int compID;
- int unicodeIndex, byteIndex;
-
- /* Use UDFCompressed to store current byte being read. */
- compID = UDFCompressed[0];
-
- /* First check for valid compID. */
- if (compID != 8 && compID != 16)
- return (-1);
-
- unicodeIndex = 0;
- byteIndex = 1;
-
- /* Loop through all the bytes. */
- while (byteIndex < numberOfBytes) {
- if (compID == 16) {
- /*
- * Move the first byte to the high
- * bits of the unicode char.
- */
- unicode[unicodeIndex] = UDFCompressed[byteIndex++] << 8;
- } else {
- unicode[unicodeIndex] = 0;
- }
- if (byteIndex < numberOfBytes) {
- /* Then the next byte to the low bits. */
- unicode[unicodeIndex] |= UDFCompressed[byteIndex++];
- }
- unicodeIndex++;
- }
- return (unicodeIndex);
-}
-
-/*
- * Almost same as udf_UncompressUnicode(). The difference is that
- * it keeps byte order of unicode string.
- */
-int
-udf_UncompressUnicodeByte(
- int numberOfBytes, /* (Input) number of bytes read from media. */
- byte *UDFCompressed, /* (Input) bytes read from media. */
- byte *unicode) /* (Output) uncompressed unicode characters. */
-{
- unsigned int compID;
- int unicodeIndex, byteIndex;
-
- /* Use UDFCompressed to store current byte being read. */
- compID = UDFCompressed[0];
-
- /* First check for valid compID. */
- if (compID != 8 && compID != 16)
- return (-1);
-
- unicodeIndex = 0;
- byteIndex = 1;
-
- /* Loop through all the bytes. */
- while (byteIndex < numberOfBytes) {
- if (compID == 16) {
- /*
- * Move the first byte to the high
- * bits of the unicode char.
- */
- unicode[unicodeIndex++] = UDFCompressed[byteIndex++];
- } else {
- unicode[unicodeIndex++] = 0;
- }
- if (byteIndex < numberOfBytes) {
- /* Then the next byte to the low bits. */
- unicode[unicodeIndex++] = UDFCompressed[byteIndex++];
- }
- }
- return (unicodeIndex);
-}
-
-/***********************************************************************
- * DESCRIPTION:
- * Takes a string of unicode wide characters and returns an OSTA CS0
- * compressed unicode string. The unicode MUST be in the byte order of
- * the compiler in order to obtain correct results. Returns an error
- * if the compression ID is invalid.
- *
- * NOTE: This routine assumes the implementation already knows, by
- * the local environment, how many bits are appropriate and
- * therefore does no checking to test if the input characters fit
- * into that number of bits or not.
- *
- * RETURN VALUE
- *
- * The total number of bytes in the compressed OSTA CS0 string,
- * including the compression ID.
- * A -1 is returned if the compression ID is invalid.
- */
-int
-udf_CompressUnicode(
- int numberOfChars, /* (Input) number of unicode characters. */
- int compID, /* (Input) compression ID to be used. */
- unicode_t *unicode, /* (Input) unicode characters to compress. */
- byte *UDFCompressed) /* (Output) compressed string, as bytes. */
-{
- int byteIndex, unicodeIndex;
-
- if (compID != 8 && compID != 16)
- return (-1); /* Unsupported compression ID ! */
-
- /* Place compression code in first byte. */
- UDFCompressed[0] = compID;
-
- byteIndex = 1;
- unicodeIndex = 0;
-
- while (unicodeIndex < numberOfChars) {
- if (compID == 16) {
- /*
- * First, place the high bits of
- * the char into the byte stream.
- */
- UDFCompressed[byteIndex++] =
- (unicode[unicodeIndex] & 0xFF00) >> 8;
- }
- /* Then place the low bits into the stream. */
- UDFCompressed[byteIndex++] = unicode[unicodeIndex] & 0x00FF;
- unicodeIndex++;
- }
- return(byteIndex);
-}
-
-/*****************************************************************************/
-/*
- * CRC 010041
- */
-static unsigned short crc_table[256] = {
- 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
- 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
- 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
- 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
- 0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
- 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
- 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
- 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
- 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
- 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
- 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
- 0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
- 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
- 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
- 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
- 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
- 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
- 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
- 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
- 0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
- 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
- 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
- 0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
- 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
- 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
- 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
- 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
- 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
- 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
- 0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
- 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
- 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
-};
-
-unsigned short
-udf_cksum(s, n)
- unsigned char *s;
- int n;
-{
- unsigned short crc=0;
-
- while (n-- > 0)
- crc = crc_table[(crc>>8 ^ *s++) & 0xff] ^ (crc<<8);
- return crc;
-}
-
-/* UNICODE Checksum */
-unsigned short
-udf_unicode_cksum(s, n)
- unsigned short *s;
- int n;
-{
- unsigned short crc=0;
-
- while (n-- > 0) {
- /* Take high order byte first--corresponds to a big endian
- * byte stream.
- */
- crc = crc_table[(crc>>8 ^ (*s>>8)) & 0xff] ^ (crc<<8);
- crc = crc_table[(crc>>8 ^ (*s++ & 0xff)) & 0xff] ^ (crc<<8);
- }
- return crc;
-}
-
-#ifdef MAIN
-unsigned char bytes[] = { 0x70, 0x6A, 0x77 };
-
-main()
-{
- unsigned short x;
- x = cksum(bytes, sizeof bytes);
- printf("checksum: calculated=%4.4x, correct=%4.4x\en", x, 0x3299);
- exit(0);
-}
-#endif
-
-/*****************************************************************************/
-#ifdef NEEDS_ISPRINT
-/*-
- **********************************************************************
- * OSTA UDF compliant file name translation routine for OS/2,
- * Windows 95, Windows NT, Macintosh and UNIX.
- * Copyright 1995 Micro Design International, Inc.
- * Written by Jason M. Rinn.
- * Micro Design International gives permission for the free use of the
- * following source code.
- */
-
-/***********************************************************************
- * To use these routines with different operating systems.
- *
- * OS/2
- * Define OS2
- * Define MAXLEN = 254
- *
- * Windows 95
- * Define WIN_95
- * Define MAXLEN = 255
- *
- * Windows NT
- * Define WIN_NT
- * Define MAXLEN = 255
- *
- * Macintosh:
- * Define MAC.
- * Define MAXLEN = 31.
- *
- * UNIX
- * Define UNIX.
- * Define MAXLEN as specified by unix version.
- */
-
-#define ILLEGAL_CHAR_MARK 0x005F
-#define CRC_MARK 0x0023
-#define EXT_SIZE 5
-#define TRUE 1
-#define FALSE 0
-#define PERIOD 0x002E
-#define SPACE 0x0020
-
-/*** PROTOTYPES ***/
-int IsIllegal(unicode_t ch);
-
-/* Define a function or macro which determines if a Unicode character is
- * printable under your implementation.
- */
-int UnicodeIsPrint(unicode_t);
-
-/***********************************************************************
- * Translates a long file name to one using a MAXLEN and an illegal
- * char set in accord with the OSTA requirements. Assumes the name has
- * already been translated to Unicode.
- *
- * RETURN VALUE
- *
- * Number of unicode characters in translated name.
- */
-int UDFTransName(
- unicode_t *newName, /* (Output)Translated name. Must be of length
- * MAXLEN */
- unicode_t *udfName, /* (Input) Name from UDF volume.*/
- int udfLen) /* (Input) Length of UDF Name. */
-{
- int index, newIndex = 0, needsCRC = FALSE;
- int extIndex = 0, newExtIndex = 0, hasExt = FALSE;
-#if defined OS2 || defined WIN_95 || defined WIN_NT
- int trailIndex = 0;
-#endif
- unsigned short valueCRC;
- unicode_t current;
- const char hexChar[] = "0123456789ABCDEF";
-
- for (index = 0; index < udfLen; index++) {
- current = udfName[index];
-
- if (IsIllegal(current) || !UnicodeIsPrint(current)) {
- needsCRC = TRUE;
- /* Replace Illegal and non-displayable chars with
- * underscore.
- */
- current = ILLEGAL_CHAR_MARK;
- /* Skip any other illegal or non-displayable
- * characters.
- */
- while(index+1 < udfLen && (IsIllegal(udfName[index+1])
- || !UnicodeIsPrint(udfName[index+1]))) {
- index++;
- }
- }
-
- /* Record position of extension, if one is found. */
- if (current == PERIOD && (udfLen - index -1) <= EXT_SIZE) {
- if (udfLen == index + 1) {
- /* A trailing period is NOT an extension. */
- hasExt = FALSE;
- } else {
- hasExt = TRUE;
- extIndex = index;
- newExtIndex = newIndex;
- }
- }
-
-#if defined OS2 || defined WIN_95 || defined WIN_NT
- /* Record position of last char which is NOT period or space. */
- else if (current != PERIOD && current != SPACE) {
- trailIndex = newIndex;
- }
-#endif
-
- if (newIndex < MAXLEN) {
- newName[newIndex++] = current;
- } else {
- needsCRC = TRUE;
- }
- }
-
-#if defined OS2 || defined WIN_95 || defined WIN_NT
- /* For OS2, 95 & NT, truncate any trailing periods and\or spaces. */
- if (trailIndex != newIndex - 1) {
- newIndex = trailIndex + 1;
- needsCRC = TRUE;
- hasExt = FALSE; /* Trailing period does not make an
- * extension. */
- }
-#endif
-
- if (needsCRC) {
- unicode_t ext[EXT_SIZE];
- int localExtIndex = 0;
- if (hasExt) {
- int maxFilenameLen;
- /* Translate extension, and store it in ext. */
- for(index = 0; index<EXT_SIZE &&
- extIndex + index +1 < udfLen; index++ ) {
- current = udfName[extIndex + index + 1];
- if (IsIllegal(current) ||
- !UnicodeIsPrint(current)) {
- needsCRC = 1;
- /* Replace Illegal and non-displayable
- * chars with underscore.
- */
- current = ILLEGAL_CHAR_MARK;
- /* Skip any other illegal or
- * non-displayable characters.
- */
- while(index + 1 < EXT_SIZE
- && (IsIllegal(udfName[extIndex +
- index + 2]) ||
- !isprint(udfName[extIndex +
- index + 2]))) {
- index++;
- }
- }
- ext[localExtIndex++] = current;
- }
-
- /* Truncate filename to leave room for extension and
- * CRC.
- */
- maxFilenameLen = ((MAXLEN - 5) - localExtIndex - 1);
- if (newIndex > maxFilenameLen) {
- newIndex = maxFilenameLen;
- } else {
- newIndex = newExtIndex;
- }
- } else if (newIndex > MAXLEN - 5) {
- /*If no extension, make sure to leave room for CRC. */
- newIndex = MAXLEN - 5;
- }
- newName[newIndex++] = CRC_MARK; /* Add mark for CRC. */
-
- /*Calculate CRC from original filename from FileIdentifier. */
- valueCRC = udf_unicode_cksum(udfName, udfLen);
- /* Convert 16-bits of CRC to hex characters. */
- newName[newIndex++] = hexChar[(valueCRC & 0xf000) >> 12];
- newName[newIndex++] = hexChar[(valueCRC & 0x0f00) >> 8];
- newName[newIndex++] = hexChar[(valueCRC & 0x00f0) >> 4];
- newName[newIndex++] = hexChar[(valueCRC & 0x000f)];
-
- /* Place a translated extension at end, if found. */
- if (hasExt) {
- newName[newIndex++] = PERIOD;
- for (index = 0;index < localExtIndex ;index++ ) {
- newName[newIndex++] = ext[index];
- }
- }
- }
- return(newIndex);
-}
-
-#if defined OS2 || defined WIN_95 || defined WIN_NT
-/***********************************************************************
- * Decides if a Unicode character matches one of a list
- * of ASCII characters.
- * Used by OS2 version of IsIllegal for readability, since all of the
- * illegal characters above 0x0020 are in the ASCII subset of Unicode.
- * Works very similarly to the standard C function strchr().
- *
- * RETURN VALUE
- *
- * Non-zero if the Unicode character is in the given ASCII string.
- */
-int UnicodeInString(
- unsigned char *string, /* (Input) String to search through. */
- unicode_t ch) /* (Input) Unicode char to search for. */
-{
- int found = FALSE;
- while (*string != '\0' && found == FALSE) {
- /* These types should compare, since both are unsigned
- * numbers. */
- if (*string == ch) {
- found = TRUE;
- }
- string++;
- }
- return(found);
-}
-#endif /* OS2 */
-
-/***********************************************************************
- * Decides whether the given character is illegal for a given OS.
- *
- * RETURN VALUE
- *
- * Non-zero if char is illegal.
- */
-int IsIllegal(unicode_t ch)
-{
-#ifdef MAC
- /* Only illegal character on the MAC is the colon. */
- if (ch == 0x003A) {
- return(1);
- } else {
- return(0);
- }
-
-#elif defined UNIX
- /* Illegal UNIX characters are NULL and slash. */
- if (ch == 0x0000 || ch == 0x002F) {
- return(1);
- } else {
- return(0);
- }
-
-#elif defined OS2 || defined WIN_95 || defined WIN_NT
- /* Illegal char's for OS/2 according to WARP toolkit. */
- if (ch < 0x0020 || UnicodeInString("\\/:*?\"<>|", ch)) {
- return(1);
- } else {
- return(0);
- }
-#endif
-}
-#endif
diff --git a/sys/isofs/udf/osta.h b/sys/isofs/udf/osta.h
deleted file mode 100644
index fdc9c46db30..00000000000
--- a/sys/isofs/udf/osta.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/* $OpenBSD: osta.h,v 1.1 2005/03/29 17:24:52 pedro Exp $ */
-
-/*
- * Prototypes for the OSTA functions
- *
- * $FreeBSD: src/sys/fs/udf/osta.h,v 1.2 2003/11/05 06:55:23 scottl Exp $
- */
-
-#ifndef UNIX
-#define UNIX
-#endif
-
-#ifndef MAXLEN
-#define MAXLEN 255
-#endif
-
-/***********************************************************************
- * The following two typedef's are to remove compiler dependancies.
- * byte needs to be unsigned 8-bit, and unicode_t needs to be
- * unsigned 16-bit.
- */
-typedef unsigned short unicode_t;
-typedef unsigned char byte;
-
-int udf_UncompressUnicode(int, byte *, unicode_t *);
-int udf_UncompressUnicodeByte(int, byte *, byte *);
-int udf_CompressUnicode(int, int, unicode_t *, byte *);
-unsigned short udf_cksum(unsigned char *, int);
-unsigned short udf_unicode_cksum(unsigned short *, int);
-int UDFTransName(unicode_t *, unicode_t *, int);
diff --git a/sys/isofs/udf/udf.h b/sys/isofs/udf/udf.h
index b9aba264183..071fd7a37ff 100644
--- a/sys/isofs/udf/udf.h
+++ b/sys/isofs/udf/udf.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: udf.h,v 1.1 2005/03/29 17:24:52 pedro Exp $ */
+/* $OpenBSD: udf.h,v 1.2 2006/01/14 19:04:17 miod Exp $ */
/*
* Copyright (c) 2001, 2002 Scott Long <scottl@freebsd.org>
@@ -134,3 +134,5 @@ int udf_hashlookup(struct udf_mnt *, ino_t, int, struct vnode **);
int udf_hashins(struct udf_node *);
int udf_hashrem(struct udf_node *);
int udf_checktag(struct desc_tag *, uint16_t);
+
+typedef uint16_t unicode_t;
diff --git a/sys/isofs/udf/udf_extern.h b/sys/isofs/udf/udf_extern.h
index 6c5dcdb3f45..6d314c533e7 100644
--- a/sys/isofs/udf/udf_extern.h
+++ b/sys/isofs/udf/udf_extern.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: udf_extern.h,v 1.2 2005/03/30 00:37:13 pedro Exp $ */
+/* $OpenBSD: udf_extern.h,v 1.3 2006/01/14 19:04:17 miod Exp $ */
/*
* Written by Pedro Martelletto <pedro@openbsd.org> in February 2005.
@@ -6,6 +6,11 @@
*/
/*
+ * udf_subr.c
+ */
+int udf_rawnametounicode(u_int len, char *, unicode_t *);
+
+/*
* udf_vfsops.c
*/
int udf_init(struct vfsconf *);
diff --git a/sys/isofs/udf/udf_subr.c b/sys/isofs/udf/udf_subr.c
new file mode 100644
index 00000000000..c0060e2d074
--- /dev/null
+++ b/sys/isofs/udf/udf_subr.c
@@ -0,0 +1,79 @@
+/* $OpenBSD: udf_subr.c,v 1.1 2006/01/14 19:04:17 miod Exp $ */
+
+/*
+ * Copyright (c) 2006, Miodrag Vallat
+ *
+ * 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 ``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 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/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/mutex.h>
+#include <sys/stat.h>
+#include <sys/mount.h>
+#include <sys/vnode.h>
+#include <sys/dirent.h>
+#include <sys/unistd.h>
+
+#include <isofs/udf/ecma167-udf.h>
+#include <isofs/udf/udf.h>
+#include <isofs/udf/udf_extern.h>
+
+/*
+ * Convert a CS0 dstring to a 16-bit Unicode string.
+ * Returns the length of the Unicode string, in unicode characters (not
+ * bytes!), or -1 if an error arises.
+ * Note that the transname destination buffer is expected to be large
+ * enough to hold the result, and will not be terminated in any way.
+ */
+int
+udf_rawnametounicode(u_int len, char *cs0string, unicode_t *transname)
+{
+ unicode_t *origname = transname;
+
+ if (len-- == 0)
+ return (-1);
+
+ switch (*cs0string++) {
+ case 8: /* bytes string */
+ while (len-- != 0)
+ *transname++ = (unicode_t)*cs0string++;
+ break;
+ case 16: /* 16 bit unicode string */
+ if (len & 1)
+ return (-1);
+ len >>= 1;
+ while (len-- != 0) {
+ unicode_t tmpchar;
+
+ tmpchar = (unicode_t)*cs0string++;
+ tmpchar = (tmpchar << 8) | (unicode_t)*cs0string++;
+ *transname++ = tmpchar;
+ }
+ break;
+ default:
+ return (-1);
+ }
+
+ return (transname - origname);
+}
diff --git a/sys/isofs/udf/udf_vfsops.c b/sys/isofs/udf/udf_vfsops.c
index 63dc5eae75d..7b91e887700 100644
--- a/sys/isofs/udf/udf_vfsops.c
+++ b/sys/isofs/udf/udf_vfsops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: udf_vfsops.c,v 1.3 2005/05/15 21:26:19 pedro Exp $ */
+/* $OpenBSD: udf_vfsops.c,v 1.4 2006/01/14 19:04:17 miod Exp $ */
/*
* Copyright (c) 2001, 2002 Scott Long <scottl@freebsd.org>
@@ -98,7 +98,6 @@
#include <miscfs/specfs/specdev.h>
#include <isofs/udf/ecma167-udf.h>
-#include <isofs/udf/osta.h>
#include <isofs/udf/udf.h>
#include <isofs/udf/udf_extern.h>
diff --git a/sys/isofs/udf/udf_vnops.c b/sys/isofs/udf/udf_vnops.c
index cf197034885..c5cc2c73ce3 100644
--- a/sys/isofs/udf/udf_vnops.c
+++ b/sys/isofs/udf/udf_vnops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: udf_vnops.c,v 1.9 2005/11/19 02:18:01 pedro Exp $ */
+/* $OpenBSD: udf_vnops.c,v 1.10 2006/01/14 19:04:17 miod Exp $ */
/*
* Copyright (c) 2001, 2002 Scott Long <scottl@freebsd.org>
@@ -52,7 +52,6 @@
#include <miscfs/specfs/specdev.h>
#include <isofs/udf/ecma167-udf.h>
-#include <isofs/udf/osta.h>
#include <isofs/udf/udf.h>
#include <isofs/udf/udf_extern.h>
@@ -470,10 +469,9 @@ udf_read(void *v)
}
/*
- * Call the OSTA routines to translate the name from a CS0 dstring to a
- * 16-bit Unicode String. Hooks need to be placed in here to translate from
- * Unicode to the encoding that the kernel/user expects. Return the length
- * of the translated string.
+ * Translate the name from a CS0 dstring to a 16-bit Unicode String.
+ * Hooks need to be placed in here to translate from Unicode to the encoding
+ * that the kernel/user expects. Return the length of the translated string.
*/
int
udf_transname(char *cs0string, char *destname, int len, struct udf_mnt *udfmp)
@@ -482,15 +480,19 @@ udf_transname(char *cs0string, char *destname, int len, struct udf_mnt *udfmp)
int i, unilen = 0, destlen;
if (len > MAXNAMLEN) {
+#ifdef DIAGNOSTIC
printf("udf_transname(): name too long\n");
+#endif
return (0);
}
/* allocate a buffer big enough to hold an 8->16 bit expansion */
transname = pool_get(&udf_trans_pool, PR_WAITOK);
- if ((unilen = udf_UncompressUnicode(len, cs0string, transname)) == -1) {
- printf("udf: Unicode translation failed\n");
+ if ((unilen = udf_rawnametounicode(len, cs0string, transname)) == -1) {
+#ifdef DIAGNOSTIC
+ printf("udf_transname(): Unicode translation failed\n");
+#endif
pool_put(&udf_trans_pool, transname);
return (0);
}
@@ -498,11 +500,13 @@ udf_transname(char *cs0string, char *destname, int len, struct udf_mnt *udfmp)
/* Pack it back to 8-bit Unicode. */
for (i = 0; i < unilen ; i++)
if (transname[i] & 0xff00)
- destname[i] = '.'; /* Fudge the 16bit chars */
+ destname[i] = '?'; /* Fudge the 16bit chars */
else
destname[i] = transname[i] & 0xff;
pool_put(&udf_trans_pool, transname);
+
+ /* Don't forget to terminate the string. */
destname[unilen] = 0;
destlen = unilen;