Version 0.1.1 - Added very simple support for plugins.
[mx3r.git] / util.c
blobea55d2684b6f8bc33c268cd28760803ed8116e59
1 #include <gcrypt.h>
2 #include <ctype.h>
3 #include <string.h>
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <dlfcn.h>
9 #include "util.h"
11 int loadsplitplugin(void) {
12 void *handle;
14 int (*split)(int);
15 const char *error;
16 handle = dlopen ("./plugin-split-lines.so", RTLD_LAZY);
17 if (!handle) {
18 fputs (dlerror(), stderr);
19 return 0;
22 split = dlsym(handle, "split");
23 if ((error = dlerror()) != NULL) {
24 fputs(error, stderr);
25 return 0;
28 printf ("%d\n", (*split)(1));
29 printf ("%d\n", (*split)(2));
30 printf ("%d\n", (*split)(3));
31 dlclose(handle);
33 return 1;
36 unsigned int *hash_loadfile(char *filename, int *size) {
37 char *nombre=filename, linea[MAX_LINE];
38 FILE *fichero;
39 fichero = fopen( nombre, "r" );
41 if( !fichero ) {
42 printf( "Error (NO ABIERTO)\n" );
43 return NULL;
45 char *txt;
47 int lines;
48 for (lines=0;fgets(linea, MAX_LINE, fichero); lines++);
49 rewind(fichero);
50 *size=lines;
51 unsigned int *data=malloc(lines*sizeof(unsigned int*));
52 int line=0;
53 while (txt=fgets(linea, MAX_LINE, fichero)) {
54 reducetext(txt);
55 data[line++]=ihash(txt);
58 if( fclose(fichero)!=0 ) {
59 printf( "\nError: fichero NO CERRADO\n" );
60 return NULL;
63 return data;
67 // ihash calcula un hash de 32 bits para un texto.
68 unsigned int ihash(char *txt) {
69 // Longitud del mensaje a cifrar
70 int msg_len = strlen( txt );
72 // Longitud del hash resultante - gcry_md_get_algo_dlen
73 // devuelve la longitud del resumen hash para un algoritmo
74 int hash_len = gcry_md_get_algo_dlen( HASH_TYPE );
76 // Salida del hash SHA1 - esto serán datos binarios
77 unsigned char hash[ hash_len ];
79 // Calcular el resumen SHA1. Esto es una especie de función-atajo,
80 // ya que la mayoría de funciones gcrypt requieren
81 // la creación de un handle, etc.
82 gcry_md_hash_buffer( HASH_TYPE, hash, txt, msg_len );
84 // unsigned int ihash=*((unsigned int *)hash);
85 return *((unsigned int *)hash);
89 void reducetext(char * txt) {
91 int n=0, nn=0;
92 char newline[256];
93 char lastc=0;
94 char c=txt[n];
95 char type=0; // Tipos de palabras o grupos:
96 // a -> texto, variable.
97 // 1 -> números, con, sin decimales.
98 // % -> símbolos unarios, binarios.
99 // 0 -> huecos y espacios
101 for (n=0;n<MAX_LINE;n++) {
102 c=tolower(txt[n]); // Captura del carácter en minúscula.
104 // Traducción del carácter.
105 switch(c)
107 // Retonos de carro y fin de fichero: salir de la función.
108 case 10:
109 case 13:
110 case 0:
111 n=MAX_LINE; continue;
112 // Tabuladores y espacios: cuentan como espacio.
113 case ' ':
114 case '\t':
115 c=' '; break;
116 // Acentos.
118 case 'á': c='a'; break;
119 case 'é': c='e'; break;
120 case 'í': c='i'; break;
121 case 'ó': c='o'; break;
122 case 'ú': c='u'; break;
126 switch(type) // Cambios de tipos según algunos datos.
128 case 0: // Segun si estábamos en un espacio.
129 if (c>='0' && c<='9') {
130 type='1';
131 } else if (isalpha(c)) {
132 type='a';
133 } else type='%';
134 break;
135 case '1': // Segun si estábamos en un espacio.
136 if (c>='0' && c<='9') {
137 type='1';
138 } else if (c=='.') {
139 type='1';
140 } else if (isalpha(c)) {
141 type='a';
142 } else type='%';
143 break;
144 case 'a': // Segun si estábamos en un espacio.
145 if (c>='0' && c<='9') {
146 type='a';
147 } else if (isalpha(c)) {
148 type='a';
149 } else type='%';
150 break;
151 default:
152 case '%':
153 if (c==' ') {
154 continue;
155 } else
156 if (c>='0' && c<='9') {
157 type='1';
158 } else if (isalpha(c)) {
159 type='a';
160 } else type='%';
161 break;
163 if (c==' ') type=0;
164 if (!nn && c==' ') continue; // Si está tabulando al inicio, tampoco tiene efecto.
165 if (c==lastc && (type=='a' || type==0)) continue; // Desperdiciar letras repetidas.
167 if (type=='%' && newline[nn-1]==' ') nn--;
168 newline[nn]=c;
170 nn++;
171 lastc=c;
173 newline[nn]=0;
174 strcpy(txt,newline);
179 int compare2hashvectors(int *Bvector, int Bsize, int *Mvector, int Msize,
180 int MaxPassSize, hashblock *blocks, int blocksize)
182 // Bvector: vector of hashes of Base, original or unmodified file.
183 // Mvector: vector of hashes of modified file.
184 // Bsize and Msize: Stores the size of their arrays.
185 // MaxPassSize: (default: 256) Which is the maximum block-size of algorithm
187 int line_base,line_local,size;
188 int maxsize=1,total=0;
189 int i,k,m;
190 hashblock *bloque=blocks;
191 int nbloques=0;
192 int lbb=0;
193 int conf_pasada[]={256,128,64,32,16,8,4,2,1,0};
194 int p;
195 int min_bloque=0;
196 for (p=0;min_bloque=conf_pasada[p];p++)
198 if (conf_pasada[p]>MaxPassSize) continue;
200 for (i=0;i<Bsize;i+=maxsize) {
201 maxsize=1;
202 int j;
203 for (j=0;j<nbloques;j++)
205 if (i>=bloque[j].line1 && i<=bloque[j].line1+bloque[j].size) break;
207 if (j<nbloques)
209 i=bloque[j].line1+bloque[j].size; continue;
213 for (k=0;k<Msize;k++)
215 int j;
216 for (j=0;j<nbloques;j++)
218 if (k>=bloque[j].line2 && k<=bloque[j].line2+bloque[j].size) break;
220 if (j<nbloques)
222 k=bloque[j].line2+bloque[j].size; continue;
225 if (Bvector[i]==Mvector[k])
227 int nz=0,nzbl=0;
229 for(m=0;k+m<Msize && i+m<Bsize;m++)
231 for (j=0;j<nbloques;j++)
233 if (k+m>=bloque[j].line2 && k+m<=bloque[j].line2+bloque[j].size) break;
234 if (i+m>=bloque[j].line1 && i+m<=bloque[j].line1+bloque[j].size) break;
236 if (j<nbloques) break;
237 if (Bvector[i+m]!=Mvector[k+m])
239 nz++;
240 if (nz>size/4) break;
241 continue;
243 if (nz==0) size=m;
244 else
246 nzbl++;
247 if (nzbl>2)
249 nzbl=0;
250 nz--;
256 if (size>maxsize)
258 maxsize=size;
259 line_base=i;
260 line_local=k;
265 if (maxsize>min_bloque)
267 if (nbloques<blocksize)
269 bloque[nbloques].line1=line_base;
270 bloque[nbloques].line2=line_local;
271 bloque[nbloques].size=maxsize;
272 nbloques++;
273 } else printf( "Error: OUT OF BLOCKS. \n");
276 lbb=line_base+maxsize;
277 total+=maxsize;
284 int j;
286 hashblock auxbloque[blocksize];
287 int minline=0, min_j=0;
288 for (p=0;p<nbloques;p++)
290 minline=Bsize;
291 for (j=0;j<64 && j<nbloques;j++)
293 if (bloque[j].line1<minline)
295 minline=bloque[j].line1;
296 min_j=j;
299 auxbloque[p]=bloque[min_j];
300 bloque[min_j].line1=Bsize;
302 memcpy(bloque,auxbloque,blocksize*sizeof(hashblock));
304 return nbloques;