요즘 윈도우 파티션에 들어있는 mp3들을 우찌 잘 들어볼 방법이 없을까. 이런 저런 고민을 하다가, msdosfs.ko를 libiconv.ko를 쓰게 하는 게 아무래도 구조상 무리라서 (현재 libiconv.ko는 CES가 제대로 지원될 수 없는 구조..) msdosfs.ko에 직접 UTF-8패치를 해보려고 시도를 해 봤습니다.
그래서, 이런 저런 닭짓끝에, 기본적인 인코딩/디코딩은 성공했는데.. 두둥.. 웬걸~ 글자가 앞쪽만 잘려서 나오는 겁니다. 으흐.. 이게 무슨 일이냐 해서 보니.. UTF-8 시퀀스가 유니코드 글자 개수만큼 바이트로 잘려서 나오는… 그러니까.. ‘한글’이라는 파일 이름은 ‘\xed\x95\x9c\xea\xb8\x80’ 인데, 이게 앞에 2바이트만 잘려서 ‘\xed\x95’가 되는 것.. 왜 그런지 여러모로 뒤져보니.. 이런! msdosfs.ko가 글자 길이를 그냥 원래 유니코드 시퀀스 길이로 계산해버리는.. 그러니, 사실상 256:256 컨버트가 가능한 ISO-8859 쓰는 녀석들만 msdosfs를 정상적으로 쓸 수 있다는.. 그런 구조로 되어있던 것이었습니다.
그래서, 제대로 계산하게 좀 패치를 했는데(좀 미심쩍은 부분이 있긴 했지만..), 또 웬걸~ 좀 파일 이름만 길어지면 또 뒤가 잘리는.. 그 문제는 이번에는 또 윈도우의 파일 시스템 구조 특성상 13글자 단위로 뒤에서부터 엔트리가 시작돼서.. 긴 파일 이름이 여러 슬롯으로 나뉜다는 것입니다. 그러니.. 결국 파일 이름이 좀 길어지면 13글자 단위로 쪼개서 뒷 블럭부터 변환이 일어나서.. 가변폭 인코딩인 UTF-8로서는 도저히 길이 계산을 할 방법이 없어진다는… 도식적으로 그려보자면 “1234567890123에헤라디여바람분다창문닫아라” 라는 파일이 있다면
-
ATTR_WIN95 엔트리: ‘라’를 들고 있고 WIN_CNT가 2
-
ATTR_WIN95 엔트리: ‘에헤라디여바람분다창문닫아’를 이름으로 들고 있고 WIN_CNT가 1
-
ATTR_WIN95 엔트리: ‘1234567890123’을 이름으로 들고 있고 WIN_CNT가 0
-
일반 파일 엔트리: ‘123456~1 123’을 이름으로 들고 있음. (짧은 이름이 123456~1.123이 됨)
이렇게 돼서.. 순서대로 파싱하려면 맨 끝에있는 ‘라’가 먼저 나와버리기 때문에, 현재 msdosfs.ko처럼 ATTR_WIN95 엔트리를 처리하면서 변환까지 같이 하는 구조에서는 가변폭 인코딩을 처리할 방법이 전혀 없습니다. 그래서 궁리를 좀 해보니, WIN95 길이의 최대길이인 256글자를 스택에 들고 있으면서 거기에 버퍼링을 해 뒀다가 그걸 한꺼번에 전체를 인코딩하는 방법 밖에는 없겠다 싶었습니다. 그래서 좀 찾아보니.. 으허허 역시 Apple Darwin에서는 벌써 그런 방법으로 고쳐놓았더군요. 그래서 결국은 FreeBSD의 win2unixfn 함수가 없어지고 getunicodefn이 msdosfs_conv에 들어가서, msdosfs_vnops에서는 win2unixfn으로 일일이 엔트리마다 변환해서 dp->d_name에 직접 쓰는 것이 아니라, getunicodefn으로 각 엔트리별 유니코드 스트링을 스택에 버퍼한 다음에 그걸 사용하는 것으로 되어있었습니다. 그런데, Darwin은 원래 파일시스템이 유니코드 기반이라 변환이 필요없지만, FreeBSD는 8bit byte sequence형태이므로 변환할 필요가 있기 때문에 Darwin것 그대로 수용은 불가능했지만, 그래도 뭔가 좀 빌려 쓰면 될 것 같네요.
음.. 그래서.. 결론은? 에.. 며칠 삽질 더 해야겠다는.. 크크;;
이렇게 하고 나면 뭐 거의 libiconv.ko에도 바로 붙을 수 있는 수준 –;;;;;