linux-bk/fs/isofs/joliet.c
<<
>>
Prefs
   1/*
   2 *  linux/fs/isofs/joliet.c
   3 *
   4 *  (C) 1996 Gordon Chaffee
   5 *
   6 *  Joliet: Microsoft's Unicode extensions to iso9660
   7 */
   8
   9#include <linux/string.h>
  10#include <linux/nls.h>
  11#include <linux/mm.h>
  12#include <linux/iso_fs.h>
  13#include <asm/unaligned.h>
  14
  15/*
  16 * Convert Unicode 16 to UTF8 or ASCII.
  17 */
  18static int
  19uni16_to_x8(unsigned char *ascii, u16 *uni, int len, struct nls_table *nls)
  20{
  21        wchar_t *ip, ch;
  22        unsigned char *op;
  23
  24        ip = uni;
  25        op = ascii;
  26
  27        while ((ch = get_unaligned(ip)) && len) {
  28                int llen;
  29                ch = be16_to_cpu(ch);
  30                if ((llen = nls->uni2char(ch, op, NLS_MAX_CHARSET_SIZE)) > 0)
  31                        op += llen;
  32                else
  33                        *op++ = '?';
  34                ip++;
  35
  36                len--;
  37        }
  38        *op = 0;
  39        return (op - ascii);
  40}
  41
  42/* Convert big endian wide character string to utf8 */
  43static int
  44wcsntombs_be(__u8 *s, const __u8 *pwcs, int inlen, int maxlen)
  45{
  46        const __u8 *ip;
  47        __u8 *op;
  48        int size;
  49        __u16 c;
  50
  51        op = s;
  52        ip = pwcs;
  53        while ((*ip || ip[1]) && (maxlen > 0) && (inlen > 0)) {
  54                c = (*ip << 8) | ip[1];
  55                if (c > 0x7f) {
  56                        size = utf8_wctomb(op, c, maxlen);
  57                        if (size == -1) {
  58                                /* Ignore character and move on */
  59                                maxlen--;
  60                        } else {
  61                                op += size;
  62                                maxlen -= size;
  63                        }
  64                } else {
  65                        *op++ = (__u8) c;
  66                }
  67                ip += 2;
  68                inlen--;
  69        }
  70        return (op - s);
  71}
  72
  73int
  74get_joliet_filename(struct iso_directory_record * de, unsigned char *outname, struct inode * inode)
  75{
  76        unsigned char utf8;
  77        struct nls_table *nls;
  78        unsigned char len = 0;
  79
  80        utf8 = ISOFS_SB(inode->i_sb)->s_utf8;
  81        nls = ISOFS_SB(inode->i_sb)->s_nls_iocharset;
  82
  83        if (utf8) {
  84                len = wcsntombs_be(outname, de->name,
  85                                   de->name_len[0] >> 1, PAGE_SIZE);
  86        } else {
  87                len = uni16_to_x8(outname, (u16 *) de->name,
  88                                  de->name_len[0] >> 1, nls);
  89        }
  90        if ((len > 2) && (outname[len-2] == ';') && (outname[len-1] == '1')) {
  91                len -= 2;
  92        }
  93
  94        /*
  95         * Windows doesn't like periods at the end of a name,
  96         * so neither do we
  97         */
  98        while (len >= 2 && (outname[len-1] == '.')) {
  99                len--;
 100        }
 101
 102        return len;
 103}
 104
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.