diff -u task-1.60/src/fstools/ffind.c task-1.60-2/src/fstools/ffind.c --- task-1.60/src/fstools/ffind.c Tue Jan 7 01:08:55 2003 +++ task-1.60-2/src/fstools/ffind.c Fri Feb 21 16:10:48 2003 @@ -46,6 +46,7 @@ */ #include "fs_tools.h" #include "error.h" +#include "ntfs.h" /* NTFS has an optimized version of this function */ extern void ntfs_find_file (FS_INFO *, INUM_T, int, FS_DENT_WALK_FN, char *); @@ -54,6 +55,7 @@ usage(char *myProg) { printf("usage: %s [-aduvV] [-f fstype] image inode\n", myProg); + printf("\t-8: Use UTF-8 for display\n"); printf("\t-a: Find all occurrences\n"); printf("\t-d: Find deleted entries ONLY\n"); printf("\t-u: Find undeleted entries ONLY\n"); @@ -103,10 +105,15 @@ char ch; FS_INFO *fs; extern int optind; + extern void (*uni2dos)(char *, int, char *, int); progname= argv[0]; + uni2dos = uni2ascii; - while ((ch = getopt(argc, argv, "adf:uvV")) > 0) { + while ((ch = getopt(argc, argv, "8adf:uvV")) > 0) { switch (ch) { + case '8': + uni2dos = uni2utf8; + break; case 'a': localflags |= FIND_ALL; break; diff -u task-1.60/src/fstools/fls.c task-1.60-2/src/fstools/fls.c --- task-1.60/src/fstools/fls.c Mon Jan 13 07:03:21 2003 +++ task-1.60-2/src/fstools/fls.c Fri Feb 21 16:10:12 2003 @@ -56,9 +56,10 @@ void usage(char *myProg) { - printf("usage: %s [-adDFlpruvV] [-f fstype] [-m dir/] [-z ZONE] [-s seconds] image [inode]\n", + printf("usage: %s [-8adDFlpruvV] [-f fstype] [-m dir/] [-z ZONE] [-s seconds] image [inode]\n", myProg); printf("\tIf [inode] is not given, the root directory is used\n"); + printf("\t-8: Use UTF-8 for display\n"); printf("\t-a: Display \".\" and \"..\" entries\n"); printf("\t-d: Display deleted entries only\n"); printf("\t-D: Display directory entries only\n"); @@ -267,15 +268,21 @@ char ch; FS_INFO *fs; extern int optind; + extern void (*uni2dos)(char *, int, char *, int); progname = argv[0]; localFlags = LCL_DIR | LCL_FILE; + uni2dos = uni2ascii; - while ((ch = getopt(argc, argv, "adDf:Fm:lprs:uvVz:")) > 0) { + while ((ch = getopt(argc, argv, "8adDf:Fm:lprs:uvVz:")) > 0) { switch (ch) { case '?': default: usage(argv[0]); + break; + case '8': + uni2dos = uni2utf8; + break; case 'a': localFlags |= LCL_DOT; break; diff -u task-1.60/src/fstools/ntfs.c task-1.60-2/src/fstools/ntfs.c --- task-1.60/src/fstools/ntfs.c Mon Jan 13 06:58:16 2003 +++ task-1.60-2/src/fstools/ntfs.c Fri Feb 21 16:08:59 2003 @@ -130,6 +130,57 @@ return; } +/* + * Convert a UNICODE string to an UTF-8 string + * + * both uni and asc must be defined + */ +void +uni2utf8(char *ucs2, int ucs2len, char *utf8, int utf8len) +{ + int utf8pos, ucs2pos, maxlen; + + /* find the maximum that we can go + * we will break when we hit NULLs, but this is the + * absolute max + */ + if (((utf8len - 1) / 3 ) < ucs2len) + maxlen = (utf8len - 1) / 3; + else + maxlen = ucs2len; + + utf8pos = 0; ucs2pos = 0; + + while (ucs2pos < maxlen) { + unsigned short *ucs2p = (unsigned short *)ucs2; + /* If this value is NULL, then stop */ + if (ucs2p[ucs2pos] == 0) + break; + /* If this value is NULL, then stop */ + + if (ucs2p[ucs2pos] <= 0x7f) { + utf8[utf8pos] = ucs2p[ucs2pos] & 0x007f; + utf8pos++; + } + else if (ucs2p[ucs2pos] <= 0x7ff) { + utf8[utf8pos] = 0xc0 | ((ucs2p[ucs2pos] & 0x7c0) >> 6); + utf8[utf8pos+1] = 0x80 | (ucs2p[ucs2pos] & 0x003f); + utf8pos = utf8pos + 2; + } + else if (ucs2p[ucs2pos] > 0x800) { + utf8[utf8pos] = 0xe0 | ((ucs2p[ucs2pos] & 0xf000) >> 12); + utf8[utf8pos+1] = 0x80 | (ucs2p[ucs2pos] & 0xfc0) >> 6; + utf8[utf8pos+2] = 0x80 | (ucs2p[ucs2pos] & 0x003f); + utf8pos = utf8pos + 3; + } + ucs2pos++; + } + /* NULL Terminate */ + utf8[utf8pos] = '\0'; + utf8pos++; + return; +} + /********************************************************************** * @@ -693,7 +744,7 @@ /* Copy the name into ASCII */ if (attr->nlen) - uni2ascii(&attr->c.r.name, attr->nlen, name, sizeof(name)); + uni2dos(&attr->c.r.name, attr->nlen, name, sizeof(name)); /* Call the unnamed $Data attribute, $Data */ else if (type == NTFS_ATYPE_DATA) strncpy(name, "$Data", NTFS_MAXNAMLEN+1); @@ -722,7 +773,7 @@ /* Copy the name */ if (attr->nlen) - uni2ascii(&attr->c.nr.name, attr->nlen, name, sizeof(name)); + uni2dos(&attr->c.nr.name, attr->nlen, name, sizeof(name)); else if (type == NTFS_ATYPE_DATA) strncpy(name, "$Data", NTFS_MAXNAMLEN+1); else @@ -806,7 +857,7 @@ fs_name->next = NULL; } - uni2ascii(&fname->name, fname->nlen, fs_name->name, 256); + uni2dos(&fname->name, fname->nlen, fs_name->name, 256); fs_name->par_inode = getu48(fs, fname->par_ref); fs_name->par_seq = getu16(fs, fname->par_seq); @@ -1248,7 +1299,7 @@ while (getu32(fs, attrdef->type)) { if (getu32(fs, attrdef->type) == type) { - uni2ascii(attrdef->label, 128, name, len); + uni2dos(attrdef->label, 128, name, len); return; } attrdef++; @@ -1560,7 +1611,7 @@ error ("Volume Name attribute not found in $Volume"); if ((fs_data->flags & FS_DATA_RES) && (fs_data->size)) { - uni2ascii(fs_data->buf, fs_data->size, asc, 128); + uni2dos(fs_data->buf, fs_data->size, asc, 128); fprintf(hFile, "Volume Name: %s\n", asc); } @@ -1606,7 +1657,7 @@ attrdeftmp = ntfs->attrdef; while (getu32(fs, attrdeftmp->type)) { - uni2ascii(attrdeftmp->label, 128, asc, 128); + uni2dos(attrdeftmp->label, 128, asc, 128); printf("%s: %d\n", asc, getu32(fs, attrdeftmp->type)); attrdeftmp++; diff -u task-1.60/src/fstools/ntfs.h task-1.60-2/src/fstools/ntfs.h --- task-1.60/src/fstools/ntfs.h Tue Jan 7 01:08:56 2003 +++ task-1.60-2/src/fstools/ntfs.h Fri Feb 21 16:08:59 2003 @@ -7,6 +7,10 @@ extern void uni2ascii(char *, int, char *, int); +extern void +uni2utf8(char *, int, char *, int); +void +(*uni2dos)(char *, int, char *, int); extern u_int32_t nt2unixtime(u_int64_t ntdate); diff -u task-1.60/src/fstools/ntfs_dent.c task-1.60-2/src/fstools/ntfs_dent.c --- task-1.60/src/fstools/ntfs_dent.c Tue Jan 7 01:08:55 2003 +++ task-1.60-2/src/fstools/ntfs_dent.c Fri Feb 21 16:08:59 2003 @@ -40,7 +40,7 @@ /* Copy the name */ fs_dent->namlen = fname->nlen; - uni2ascii((char *)&fname->name, fname->nlen, + uni2dos((char *)&fname->name, fname->nlen, fs_dent->name, fs_dent->maxnamlen); /* copy the path data */