msdosfs_conv.c (203827) | msdosfs_conv.c (227650) |
---|---|
1/* $FreeBSD: head/sys/fs/msdosfs/msdosfs_conv.c 203827 2010-02-13 12:41:07Z kib $ */ | 1/* $FreeBSD: head/sys/fs/msdosfs/msdosfs_conv.c 227650 2011-11-18 03:05:20Z kevlo $ */ |
2/* $NetBSD: msdosfs_conv.c,v 1.25 1997/11/17 15:36:40 ws Exp $ */ 3 4/*- 5 * Copyright (C) 1995, 1997 Wolfgang Solfrank. 6 * Copyright (C) 1995, 1997 TooLs GmbH. 7 * All rights reserved. 8 * Original code by Paul Popelka (paulp@uts.amdahl.com) (see below). 9 * --- 46 unchanged lines hidden (view full) --- 56 57#include <fs/msdosfs/bpb.h> 58#include <fs/msdosfs/direntry.h> 59#include <fs/msdosfs/msdosfsmount.h> 60 61extern struct iconv_functions *msdosfs_iconv; 62 63static int mbsadjpos(const char **, size_t, size_t, int, int, void *handle); | 2/* $NetBSD: msdosfs_conv.c,v 1.25 1997/11/17 15:36:40 ws Exp $ */ 3 4/*- 5 * Copyright (C) 1995, 1997 Wolfgang Solfrank. 6 * Copyright (C) 1995, 1997 TooLs GmbH. 7 * All rights reserved. 8 * Original code by Paul Popelka (paulp@uts.amdahl.com) (see below). 9 * --- 46 unchanged lines hidden (view full) --- 56 57#include <fs/msdosfs/bpb.h> 58#include <fs/msdosfs/direntry.h> 59#include <fs/msdosfs/msdosfsmount.h> 60 61extern struct iconv_functions *msdosfs_iconv; 62 63static int mbsadjpos(const char **, size_t, size_t, int, int, void *handle); |
64static u_int16_t dos2unixchr(const u_char **, size_t *, int, struct msdosfsmount *); | 64static u_char * dos2unixchr(const u_char **, size_t *, int, struct msdosfsmount *); |
65static u_int16_t unix2doschr(const u_char **, size_t *, struct msdosfsmount *); | 65static u_int16_t unix2doschr(const u_char **, size_t *, struct msdosfsmount *); |
66static u_int16_t win2unixchr(u_int16_t, struct msdosfsmount *); | 66static u_char * win2unixchr(u_int16_t, struct msdosfsmount *); |
67static u_int16_t unix2winchr(const u_char **, size_t *, int, struct msdosfsmount *); 68 69/* 70 * 0 - character disallowed in long file name. 71 * 1 - character should be replaced by '_' in DOS file name, 72 * and generation number inserted. 73 * 2 - character ('.' and ' ') should be skipped in DOS file name, 74 * and generation number inserted. --- 162 unchanged lines hidden (view full) --- 237dos2unixfn(dn, un, lower, pmp) 238 u_char dn[11]; 239 u_char *un; 240 int lower; 241 struct msdosfsmount *pmp; 242{ 243 size_t i; 244 int thislong = 0; | 67static u_int16_t unix2winchr(const u_char **, size_t *, int, struct msdosfsmount *); 68 69/* 70 * 0 - character disallowed in long file name. 71 * 1 - character should be replaced by '_' in DOS file name, 72 * and generation number inserted. 73 * 2 - character ('.' and ' ') should be skipped in DOS file name, 74 * and generation number inserted. --- 162 unchanged lines hidden (view full) --- 237dos2unixfn(dn, un, lower, pmp) 238 u_char dn[11]; 239 u_char *un; 240 int lower; 241 struct msdosfsmount *pmp; 242{ 243 size_t i; 244 int thislong = 0; |
245 u_int16_t c; | 245 u_char *c; |
246 247 /* 248 * If first char of the filename is SLOT_E5 (0x05), then the real 249 * first char of the filename should be 0xe5. But, they couldn't 250 * just have a 0xe5 mean 0xe5 because that is used to mean a freed 251 * directory slot. Another dos quirk. 252 */ 253 if (*dn == SLOT_E5) 254 *dn = 0xe5; 255 256 /* 257 * Copy the name portion into the unix filename string. 258 */ 259 for (i = 8; i > 0 && *dn != ' ';) { 260 c = dos2unixchr((const u_char **)&dn, &i, lower & LCASE_BASE, 261 pmp); | 246 247 /* 248 * If first char of the filename is SLOT_E5 (0x05), then the real 249 * first char of the filename should be 0xe5. But, they couldn't 250 * just have a 0xe5 mean 0xe5 because that is used to mean a freed 251 * directory slot. Another dos quirk. 252 */ 253 if (*dn == SLOT_E5) 254 *dn = 0xe5; 255 256 /* 257 * Copy the name portion into the unix filename string. 258 */ 259 for (i = 8; i > 0 && *dn != ' ';) { 260 c = dos2unixchr((const u_char **)&dn, &i, lower & LCASE_BASE, 261 pmp); |
262 if (c & 0xff00) { 263 *un++ = c >> 8; | 262 while (*c != '\0') { 263 *un++ = *c++; |
264 thislong++; 265 } | 264 thislong++; 265 } |
266 *un++ = c; 267 thislong++; | |
268 } 269 dn += i; 270 271 /* 272 * Now, if there is an extension then put in a period and copy in 273 * the extension. 274 */ 275 if (*dn != ' ') { 276 *un++ = '.'; 277 thislong++; 278 for (i = 3; i > 0 && *dn != ' ';) { 279 c = dos2unixchr((const u_char **)&dn, &i, 280 lower & LCASE_EXT, pmp); | 266 } 267 dn += i; 268 269 /* 270 * Now, if there is an extension then put in a period and copy in 271 * the extension. 272 */ 273 if (*dn != ' ') { 274 *un++ = '.'; 275 thislong++; 276 for (i = 3; i > 0 && *dn != ' ';) { 277 c = dos2unixchr((const u_char **)&dn, &i, 278 lower & LCASE_EXT, pmp); |
281 if (c & 0xff00) { 282 *un++ = c >> 8; | 279 while (*c != '\0') { 280 *un++ = *c++; |
283 thislong++; 284 } | 281 thislong++; 282 } |
285 *un++ = c; 286 thislong++; | |
287 } 288 } 289 *un++ = 0; 290 291 return (thislong); 292} 293 294/* --- 352 unchanged lines hidden (view full) --- 647 */ 648int 649win2unixfn(nbp, wep, chksum, pmp) 650 struct mbnambuf *nbp; 651 struct winentry *wep; 652 int chksum; 653 struct msdosfsmount *pmp; 654{ | 283 } 284 } 285 *un++ = 0; 286 287 return (thislong); 288} 289 290/* --- 352 unchanged lines hidden (view full) --- 643 */ 644int 645win2unixfn(nbp, wep, chksum, pmp) 646 struct mbnambuf *nbp; 647 struct winentry *wep; 648 int chksum; 649 struct msdosfsmount *pmp; 650{ |
651 u_char *c; |
|
655 u_int8_t *cp; | 652 u_int8_t *cp; |
656 u_int8_t *np, name[WIN_CHARS * 2 + 1]; | 653 u_int8_t *np, name[WIN_CHARS * 3 + 1]; |
657 u_int16_t code; 658 int i; 659 660 if ((wep->weCnt&WIN_CNT) > howmany(WIN_MAXLEN, WIN_CHARS) 661 || !(wep->weCnt&WIN_CNT)) 662 return -1; 663 664 /* --- 16 unchanged lines hidden (view full) --- 681 case 0: 682 *np = '\0'; 683 mbnambuf_write(nbp, name, (wep->weCnt & WIN_CNT) - 1); 684 return chksum; 685 case '/': 686 *np = '\0'; 687 return -1; 688 default: | 654 u_int16_t code; 655 int i; 656 657 if ((wep->weCnt&WIN_CNT) > howmany(WIN_MAXLEN, WIN_CHARS) 658 || !(wep->weCnt&WIN_CNT)) 659 return -1; 660 661 /* --- 16 unchanged lines hidden (view full) --- 678 case 0: 679 *np = '\0'; 680 mbnambuf_write(nbp, name, (wep->weCnt & WIN_CNT) - 1); 681 return chksum; 682 case '/': 683 *np = '\0'; 684 return -1; 685 default: |
689 code = win2unixchr(code, pmp); 690 if (code & 0xff00) 691 *np++ = code >> 8; 692 *np++ = code; | 686 c = win2unixchr(code, pmp); 687 while (*c != '\0') 688 *np++ = *c++; |
693 break; 694 } 695 cp += 2; 696 } 697 for (cp = wep->wePart2, i = sizeof(wep->wePart2)/2; --i >= 0;) { 698 code = (cp[1] << 8) | cp[0]; 699 switch (code) { 700 case 0: 701 *np = '\0'; 702 mbnambuf_write(nbp, name, (wep->weCnt & WIN_CNT) - 1); 703 return chksum; 704 case '/': 705 *np = '\0'; 706 return -1; 707 default: | 689 break; 690 } 691 cp += 2; 692 } 693 for (cp = wep->wePart2, i = sizeof(wep->wePart2)/2; --i >= 0;) { 694 code = (cp[1] << 8) | cp[0]; 695 switch (code) { 696 case 0: 697 *np = '\0'; 698 mbnambuf_write(nbp, name, (wep->weCnt & WIN_CNT) - 1); 699 return chksum; 700 case '/': 701 *np = '\0'; 702 return -1; 703 default: |
708 code = win2unixchr(code, pmp); 709 if (code & 0xff00) 710 *np++ = code >> 8; 711 *np++ = code; | 704 c = win2unixchr(code, pmp); 705 while (*c != '\0') 706 *np++ = *c++; |
712 break; 713 } 714 cp += 2; 715 } 716 for (cp = wep->wePart3, i = sizeof(wep->wePart3)/2; --i >= 0;) { 717 code = (cp[1] << 8) | cp[0]; 718 switch (code) { 719 case 0: 720 *np = '\0'; 721 mbnambuf_write(nbp, name, (wep->weCnt & WIN_CNT) - 1); 722 return chksum; 723 case '/': 724 *np = '\0'; 725 return -1; 726 default: | 707 break; 708 } 709 cp += 2; 710 } 711 for (cp = wep->wePart3, i = sizeof(wep->wePart3)/2; --i >= 0;) { 712 code = (cp[1] << 8) | cp[0]; 713 switch (code) { 714 case 0: 715 *np = '\0'; 716 mbnambuf_write(nbp, name, (wep->weCnt & WIN_CNT) - 1); 717 return chksum; 718 case '/': 719 *np = '\0'; 720 return -1; 721 default: |
727 code = win2unixchr(code, pmp); 728 if (code & 0xff00) 729 *np++ = code >> 8; 730 *np++ = code; | 722 c = win2unixchr(code, pmp); 723 while (*c != '\0') 724 *np++ = *c++; |
731 break; 732 } 733 cp += 2; 734 } 735 *np = '\0'; 736 mbnambuf_write(nbp, name, (wep->weCnt & WIN_CNT) - 1); 737 return chksum; 738} --- 73 unchanged lines hidden (view full) --- 812 813 (*instr) += min(inlen, outlen); 814 return (inlen - min(inlen, outlen)); 815} 816 817/* 818 * Convert DOS char to Local char 819 */ | 725 break; 726 } 727 cp += 2; 728 } 729 *np = '\0'; 730 mbnambuf_write(nbp, name, (wep->weCnt & WIN_CNT) - 1); 731 return chksum; 732} --- 73 unchanged lines hidden (view full) --- 806 807 (*instr) += min(inlen, outlen); 808 return (inlen - min(inlen, outlen)); 809} 810 811/* 812 * Convert DOS char to Local char 813 */ |
820static u_int16_t | 814static u_char * |
821dos2unixchr(const u_char **instr, size_t *ilen, int lower, struct msdosfsmount *pmp) 822{ | 815dos2unixchr(const u_char **instr, size_t *ilen, int lower, struct msdosfsmount *pmp) 816{ |
823 u_char c; 824 char *outp, outbuf[3]; 825 u_int16_t wc; | 817 u_char c, *outp, outbuf[5]; |
826 size_t len, olen; 827 | 818 size_t len, olen; 819 |
820 outp = outbuf; |
|
828 if (pmp->pm_flags & MSDOSFSMNT_KICONV && msdosfs_iconv) { | 821 if (pmp->pm_flags & MSDOSFSMNT_KICONV && msdosfs_iconv) { |
829 olen = len = 2; 830 outp = outbuf; | 822 olen = len = 4; |
831 832 if (lower & (LCASE_BASE | LCASE_EXT)) 833 msdosfs_iconv->convchr_case(pmp->pm_d2u, (const char **)instr, | 823 824 if (lower & (LCASE_BASE | LCASE_EXT)) 825 msdosfs_iconv->convchr_case(pmp->pm_d2u, (const char **)instr, |
834 ilen, &outp, &olen, KICONV_LOWER); | 826 ilen, (char **)&outp, &olen, KICONV_LOWER); |
835 else 836 msdosfs_iconv->convchr(pmp->pm_d2u, (const char **)instr, | 827 else 828 msdosfs_iconv->convchr(pmp->pm_d2u, (const char **)instr, |
837 ilen, &outp, &olen); | 829 ilen, (char **)&outp, &olen); |
838 len -= olen; 839 840 /* 841 * return '?' if failed to convert 842 */ 843 if (len == 0) { 844 (*ilen)--; 845 (*instr)++; | 830 len -= olen; 831 832 /* 833 * return '?' if failed to convert 834 */ 835 if (len == 0) { 836 (*ilen)--; 837 (*instr)++; |
846 return ('?'); | 838 *outp++ = '?'; |
847 } | 839 } |
848 849 wc = 0; 850 while(len--) 851 wc |= (*(outp - len - 1) & 0xff) << (len << 3); 852 return (wc); | 840 } else { 841 (*ilen)--; 842 c = *(*instr)++; 843 c = dos2unix[c]; 844 if (lower & (LCASE_BASE | LCASE_EXT)) 845 c = u2l[c]; 846 *outp++ = c; 847 outbuf[1] = '\0'; |
853 } 854 | 848 } 849 |
855 (*ilen)--; 856 c = *(*instr)++; 857 c = dos2unix[c]; 858 if (lower & (LCASE_BASE | LCASE_EXT)) 859 c = u2l[c]; 860 return ((u_int16_t)c); | 850 *outp = '\0'; 851 outp = outbuf; 852 return (outp); |
861} 862 863/* 864 * Convert Local char to DOS char 865 */ 866static u_int16_t 867unix2doschr(const u_char **instr, size_t *ilen, struct msdosfsmount *pmp) 868{ --- 66 unchanged lines hidden (view full) --- 935 c = l2u[c]; 936 c = unix2dos[c]; 937 return ((u_int16_t)c); 938} 939 940/* 941 * Convert Windows char to Local char 942 */ | 853} 854 855/* 856 * Convert Local char to DOS char 857 */ 858static u_int16_t 859unix2doschr(const u_char **instr, size_t *ilen, struct msdosfsmount *pmp) 860{ --- 66 unchanged lines hidden (view full) --- 927 c = l2u[c]; 928 c = unix2dos[c]; 929 return ((u_int16_t)c); 930} 931 932/* 933 * Convert Windows char to Local char 934 */ |
943static u_int16_t | 935static u_char * |
944win2unixchr(u_int16_t wc, struct msdosfsmount *pmp) 945{ | 936win2unixchr(u_int16_t wc, struct msdosfsmount *pmp) 937{ |
946 u_char *inp, *outp, inbuf[3], outbuf[3]; | 938 u_char *inp, *outp, inbuf[3], outbuf[5]; |
947 size_t ilen, olen, len; 948 | 939 size_t ilen, olen, len; 940 |
949 if (wc == 0) 950 return (0); 951 | 941 outp = outbuf; |
952 if (pmp->pm_flags & MSDOSFSMNT_KICONV && msdosfs_iconv) { 953 inbuf[0] = (u_char)(wc>>8); 954 inbuf[1] = (u_char)wc; 955 inbuf[2] = '\0'; 956 | 942 if (pmp->pm_flags & MSDOSFSMNT_KICONV && msdosfs_iconv) { 943 inbuf[0] = (u_char)(wc>>8); 944 inbuf[1] = (u_char)wc; 945 inbuf[2] = '\0'; 946 |
957 ilen = olen = len = 2; | 947 ilen = 2; 948 olen = len = 4; |
958 inp = inbuf; | 949 inp = inbuf; |
959 outp = outbuf; | |
960 msdosfs_iconv->convchr(pmp->pm_w2u, (const char **)&inp, &ilen, 961 (char **)&outp, &olen); 962 len -= olen; 963 964 /* 965 * return '?' if failed to convert 966 */ | 950 msdosfs_iconv->convchr(pmp->pm_w2u, (const char **)&inp, &ilen, 951 (char **)&outp, &olen); 952 len -= olen; 953 954 /* 955 * return '?' if failed to convert 956 */ |
967 if (len == 0) { 968 wc = '?'; 969 return (wc); 970 } 971 972 wc = 0; 973 while(len--) 974 wc |= (*(outp - len - 1) & 0xff) << (len << 3); 975 return (wc); | 957 if (len == 0) 958 *outp++ = '?'; 959 } else { 960 *outp++ = (wc & 0xff00) ? '?' : (u_char)(wc & 0xff); |
976 } 977 | 961 } 962 |
978 if (wc & 0xff00) 979 wc = '?'; 980 981 return (wc); | 963 *outp = '\0'; 964 outp = outbuf; 965 return (outp); |
982} 983 984/* 985 * Convert Local char to Windows char 986 */ 987static u_int16_t 988unix2winchr(const u_char **instr, size_t *ilen, int lower, struct msdosfsmount *pmp) 989{ --- 111 unchanged lines hidden --- | 966} 967 968/* 969 * Convert Local char to Windows char 970 */ 971static u_int16_t 972unix2winchr(const u_char **instr, size_t *ilen, int lower, struct msdosfsmount *pmp) 973{ --- 111 unchanged lines hidden --- |