Protegendo um Banco de Bados Padrão xBase

Autor: Mário Leite  

Apesar das atuais interfaces gráficas e de vários formatos de armazenamento de dados, o padrão xBase ainda continua sendo uma realidade em termos de banco de dados desktop no Brasil; e por isso merece atenção especial por parte dos programadores. Por outro lado, devido aos laços históricos que os uniram durante um bom tempo, ou talvez por pura falta de esclarecimento, alguns programadores Clipper ainda o descrevem como um compilador do dBase; mas, na realidade, ele é muito mais do que simplesmente isto. No geral o Clipper fornece um superconjunto para a linguagem de acesso a banco de dados não disponível no dBase; existem, além disso, diferenças significativas entre os dois produtos, acentuadas a partir das versões 5.x do Clipper. Mas, tendo o dBase um ambiente interativo para criação e manutenção de arquivo de dados (padrão .DBF) é até natural que alguns programadores o utilizem para criar os arquivos de dados das suas aplicações em Clipper. Contudo, a despeito dessa facilidade, a empresa proprietária do Clipper adverte que pode haver problemas sérios com esta atitude aparentemente inofensiva, já que em termos de estrutura interna de arquivos de dados e de índices existem diferenças acentuadas. Por isso, o produto vem com seu próprio utilitário para criação e manutenção de estrutura de dados; é o DBU (Data Base Utilities) que permite a criação de arquivos de dados, edição de dados e criação de índices.

 

O padrão xBase de arquivo de dados (formato .DBF) é muito frágil, podendo se desestruturar com muita facilidade, e isso pode acontecer mais facilmente se for usado um produto estranho para criar a base de dados que será gerenciada pelo Clipper. Podemos, entretanto, criar uma rotina para proteger um arquivo de dados padrão .DBF contra edições "estranhas" de maneira simples; apenas trocando o byte que o identifica como tal. Esse byte é o primeiro do arquivo, chamado de assinatura, e pode assumir um dos dois valores: 3 (03H) ou 131 (83H). O valor 131 indica que o arquivo possui um campo Memo, e 3 indica que não possui campo Memo; desse modo se alterarmos esse byte o arquivo não poderá mais ser reconhecido como um arquivo de dados padrão .DBF. Usando funções de baixo nível podemos ter acesso a qualquer parte de um arquivo de qualquer tipo; assim, a rotina da figura 1 tem o seguinte comportamento:

 

  • caso o primeiro byte seja igual ao valor 3 alteramos o valor para 4 (e vice-versa);
  •  

 

  • caso o primeiro byte seja igual a 131 alteramos esse valor para 132 (e vice-versa).
  •  

 

Portanto, após a alteração do byte de 3 para 4 (por exemplo) se for tentado um acesso a ele, usando, por exemplo, o dBase, seria emitida a mensagem: Not a DBASE database; e se usarmos o DBU para tentar acessá-lo a mensagem de erro será: Error DBFNTX/1012 Corruption detected: nome_do_arquivo

 

A função Protect() protege e desprotege o arquivo de dados; caso ele esteja desprotegido (situação normal) ela o protegerá com a troca do primeiro byte de 131 para 132 (caso possua campo Memo) ou de 3 para 4 caso não possua campo Memo. Entretanto, se ele já estiver protegido ela o desprotegerá trocando o primeiro byte de 132 para 131 ou de 4 para 3 (voltando à situação normal). A figura 1 mostra o código da função Protect() e a figura 2 um programa que usa essa função para proteger o arquivo Cadastro.dbf.

Figura 1 - Código da função Protect()

Figura 2 - Testando a função Protect()