opendir e readdir codificando strings nas minhas costas?

6

(Você pode pular os detalhes para o último par de linhas, se você é capaz de responder à pergunta :))

Estou em um Ubuntu 12.04. Eu estou tentando resolver um problema antigo que eu postei no passado (se você está curioso: link ). Há um problema de compatibilidade conhecido entre arquivos Linux, Mac, HFS + e coreano, e passei o dia todo tentando encontrar algum tipo de solução alternativa.

Basicamente, montei minha unidade HFS + no linux. Ls e cd normais têm problemas para acessar os arquivos, porque eles estão em coreano. Então eu escrevi um programa em C para tentar acessar esses arquivos no nível mais baixo, para ter mais certeza de que nada estaria acontecendo nas minhas costas:

DIR* dp; 
struct dirent *ep;
char* parent = "/media/external/Movies";
dp = opendir( parent );
if( dp != NULL )
{   
    while( ep = readdir(dp) )
    {   
        printf( "%d %s %X\t", ep->d_ino, ep->d_name, ep->d_type );

    // now print out the filenames in hex
        for( int i = 0; i != strlen( ep->d_name ) ; i++)
        {   
            printf( "0x%X " , ep->d_name[i] & 0xff );
        }   
        printf("\n");
    }   
    closedir(dp);
}
else
{   
     perror("Couldn't open the directory! ");
}   

Aqui está uma amostra da saída que recebo para isso:

433949 밀양 4 0xEB 0xB0 0x80 0xEC 0x96 0x91

413680 박쥐 4 0xEB 0xB0 0x95 0xEC 0xA5 0x90

434033 사탕 사탕 4 0xEB 0xB0 0x95 0xED 0x95 0x98 0xEC 0x82 0xAC 0xED 0x83 0x95

Portanto, na aparência, parece que o openddir não tem problemas para visualizar as entradas do diretório. Os números de inode estão lá, eles estão marcados corretamente como diretórios (4 significa diretório) e parece que os nomes dos arquivos são armazenados como codificados em UTF-8, uma vez que esses hexadecimais são os códigos UTF-8 corretos para os nomes de arquivos coreanos. Mas agora, se eu fosse fazer um readdir de um desses diretórios (e eu vou estar usando o nome do arquivo em hexadecimal para ter cuidado extra que nada está acontecendo nas minhas costas):

unsigned char new_dirname[] = {'/',0xEB,0xB0,0x80,0xEC,0x96,0x91,'
DIR* dp; 
struct dirent *ep;
char* parent = "/media/external/Movies";
dp = opendir( parent );
if( dp != NULL )
{   
    while( ep = readdir(dp) )
    {   
        printf( "%d %s %X\t", ep->d_ino, ep->d_name, ep->d_type );

    // now print out the filenames in hex
        for( int i = 0; i != strlen( ep->d_name ) ; i++)
        {   
            printf( "0x%X " , ep->d_name[i] & 0xff );
        }   
        printf("\n");
    }   
    closedir(dp);
}
else
{   
     perror("Couldn't open the directory! ");
}   
'}; unsigned char final[ strlen(parent) + strlen(new_dirname) + 1 ]; memcpy(final, parent, strlen( parent )); strcpy(final + strlen(parent), dirname ); dp = opendir( final ); // dp == NULL here!!!

Não é possível abrir o diretório. Isso me confunde, porque se o opendir estivesse apenas reportando os bits brutos do nome do arquivo na entrada de diretório, e readdir estivesse apenas pegando meu nome de arquivo e combinando com a entrada de diretório correta, então eu pensei que não deveria haver nenhum problema encontrando o inode e abrindo o diretório. Isso parece sugerir que opendir não está sendo completamente honesto sobre os nomes de arquivos.

Os nomes dos arquivos nas entradas do diretório relatados pelo opendir não são o que está realmente no disco (isto é, eles estão sendo codificados)? Se assim for existe alguma maneira que eu possa controlar como opendir e readdir estão codificando nomes, ou talvez usar algumas outras chamadas de sistema que funcionam com bytes brutos em vez de codificar as coisas pelas minhas costas? Em geral, acho muito confuso em que nível de codificação está acontecendo e agradeço qualquer explicação ou, melhor ainda, uma referência para entender isso! Obrigado!

    
por bhh1988 16.07.2012 / 01:49

1 resposta

1

opendir e readdir trabalham em bytes. Eles não realizam e reencodificam.

Alguns drivers do sistema de arquivos podem impor restrições nas seqüências de bytes. Por exemplo, o HFS + normaliza os nomes de arquivos usando um esquema de normalização Unicode proprietário. Eu esperaria que o formulário retornado por readdir funcionasse quando passado para opendir , no entanto, assim como o OP no Ubuntu tópico do fórum que jw013 mencionado , suspeito de um bug no driver HFS +. É o não o único programa que é ativado pelo Hangul no HFS +. Mesmo o OSX parece ter problemas com Unicode normalização.

    
por 20.07.2012 / 00:34