Initial Commit.

This commit is contained in:
2013-05-24 00:49:29 +02:00
commit aeb408cfb1
14 changed files with 1286 additions and 0 deletions

4
.gitignore vendored Normal file
View File

@@ -0,0 +1,4 @@
*.o
*.exe
build
_tests

63
Makefile Normal file
View File

@@ -0,0 +1,63 @@
CC=gcc
RM=rm -f
ECHO=echo
MKDIR=mkdir
HEADS = util.h crc.h fileutil.h filenode.h
OBJS_BASE = \
$(BUILDDIR)/util.o \
$(BUILDDIR)/crc.o \
$(BUILDDIR)/fileutil.o \
$(BUILDDIR)/filenode.o
OBJS_APP = \
$(OBJS_BASE) \
$(BUILDDIR)/main.o
RES_APP=filesync
CFLAGS = -g
LIBS = -lm
BUILDDIR = build
DO_CC=@$(ECHO) "CC: $@" ;\
$(CC) $(CFLAGS) -o $@ -c $<
all: $(RES_APP)
clean:
$(RM) $(OBJS_BASE)
$(RM) $(OBJS_APP)
$(BUILDDIR):
@-$(MKDIR) $(BUILDDIR)
$(BUILDDIR)/util.o: util.c $(HEADS)
$(DO_CC)
$(BUILDDIR)/crc.o: crc.c $(HEADS)
$(DO_CC)
$(BUILDDIR)/fileutil.o: fileutil.c $(HEADS)
$(DO_CC)
$(BUILDDIR)/filenode.o: filenode.c $(HEADS)
$(DO_CC)
$(BUILDDIR)/main.o: main.c $(HEADS)
$(DO_CC)
$(RES_APP): $(BUILDDIR) $(OBJS_APP)
@$(ECHO) "LINK: $@"
@$(CC) $(OBJS_APP) \
-o $(RES_APP) $(LIBS)

19
NOTAS.txt Normal file
View File

@@ -0,0 +1,19 @@
POR HACER
=========
* Comparador de FileNodes que genere una lista de AccionFileCmp (filenodecmp.h)
* Realizar las acciones especificadas por la lista de AccionFileCmp
* Demonio
* GUI
HECHO
=====
* CRC de ficheros (CRC_File en crc.h)
* Lectura y Escritura de fechas de ficheros (FileTime end fileutil.h)
* Utilidades de ficheros (fileutil.h)
* Representacion de arboles de directorios que contienen informacion
de cada fichero; crc, fecha, estado (FileNode en filenode.h)
* Scaneo, construccion y reconstruccion de arboles FileNode, detectando cambios.

69
crc.c Normal file
View File

@@ -0,0 +1,69 @@
#include <stdio.h>
unsigned long CRCTable[256];
int CRCTable_initialized=0;
#define CRC32_POLYNOMIAL 0xEDB88320L
void CRCTable_Init(){
int i;
int j;
unsigned long crc;
if(CRCTable_initialized){
return;
}
CRCTable_initialized=1;
for (i=0;i<256;i++){
crc=i;
for (j=8;j>0;j--){
if (crc&1)
crc=(crc>>1)^CRC32_POLYNOMIAL;
else
crc>>=1;
}
CRCTable[i]=crc;
}
}
unsigned long CRC_Buffer(unsigned char *buffer,int len,unsigned long crc){
unsigned char *p;
unsigned long temp1;
unsigned long temp2;
// Calcular CRC del buffer
p=(unsigned char*)buffer;
while(len--!=0) {
temp1=(crc>>8)&0x00FFFFFFL;
temp2=CRCTable[((int)crc^*p++)&0xff];
crc=temp1^temp2;
}
return(crc);
}
unsigned long CRC_File(FILE *file){
unsigned long crc;
int count;
unsigned char buffer[512];
unsigned char *p;
unsigned long temp1;
unsigned long temp2;
CRCTable_Init();
crc=0xFFFFFFFFL;
for(;;){
// Llenar el buffer
count=fread(buffer,1,512,file);
if(count==0)
break;
// Calcular CRC del buffer
crc=CRC_Buffer(buffer,count,crc);
}
return(crc^=0xFFFFFFFFL);
}

9
crc.h Normal file
View File

@@ -0,0 +1,9 @@
#ifndef _CRC_
#define _CRC_
#include <stdio.h>
unsigned long CRC_Buffer(unsigned char *buffer,int len,unsigned long crc);
unsigned long CRC_File(FILE *file);
#endif

515
filenode.c Normal file
View File

@@ -0,0 +1,515 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "util.h"
#include "crc.h"
#include "fileutil.h"
#include "filenode.h"
FileNode *_free_filenode=NULL;
int _n_filenode=0;
#define FileNode_Tocho 1024
FileNode *FileNode_New(){
FileNode *fn;
if(_free_filenode==NULL){
FileNode *nodos;
int i;
// Reservar un tocho
nodos=malloc(sizeof(FileNode)*FileNode_Tocho);
for(i=0;i<FileNode_Tocho-1;i++){
nodos[i].sig=&nodos[i+1];
}
nodos[FileNode_Tocho-1].sig=NULL;
_free_filenode=&nodos[0];
}
// Obtener el primero libre
fn=_free_filenode;
_free_filenode=fn->sig;
_n_filenode++;
// Iniciar
fn->name[0]=0;
fn->flags=0;
fn->estado=EstadoFichero_Nada;
fn->size=0;
fn->crc=0;
fn->ft=0;
fn->child=NULL;
fn->n_childs=0;
fn->sig=NULL;
fn->padre=NULL;
return(fn);
}
void FileNode_Delete(FileNode *fn){
fn->sig=_free_filenode;
_free_filenode=fn;
_n_filenode--;
}
void FileNode_AddChild(FileNode *file,FileNode *file2){
if(!file2 || !file)
return;
file2->sig=file->child;
file->child=file2;
file->n_childs++;
file2->padre=file;
}
void FileNode_SetEstadoRec(FileNode *file,EstadoFichero estado){
FileNode *fn_child;
file->estado=estado;
fn_child=file->child;
while(fn_child!=NULL){
FileNode_SetEstadoRec(fn_child,estado);
fn_child=fn_child->sig;
}
}
void FileNode_GetPath_Rec(FileNode *fn,char **pathnode){
if(fn->padre){
pathnode[0]=fn->padre->name;
FileNode_GetPath_Rec(fn->padre,pathnode+1);
}else{
pathnode[0]=NULL;
}
}
char temppath[1024];
char *FileNode_GetPath(FileNode *fn,char *path){
char *pathnodes[100];
int levels,i;
char *pathptr=temppath;
if(path)pathptr=path;
FileNode_GetPath_Rec(fn,pathnodes);
levels=0;while(pathnodes[levels]){levels++;}
strcpy(pathptr,"");
for(i=levels-1;i>=0;i--){
strcat(pathptr,pathnodes[i]);
strcat(pathptr,"/");
}
strcat(pathptr,fn->name);
}
void FileNode_GetTamanho(FileNode *fn,char *file){
fn->flags|=FileFlag_TieneTamanho;
fn->size=File_TamanhoFichero(file);
}
void FileNode_GetFecha(FileNode *fn,char *file){
fn->flags|=FileFlag_TieneFecha;
fn->ft=FileTime_Get(file);
}
void FileNode_GetCRC(FileNode *fn,char *file){
FILE *f;
f=fopen(file,"rb");
if(!f){ return; }
fn->flags|=FileFlag_TieneCRC;
fn->crc=CRC_File(f);
fclose(f);
}
void FileNode_SaveNode(FileNode *fn,FILE *file){
short name_len;
// Escribir nombre
name_len=strlen(fn->name);
fwrite((void *)&name_len,sizeof(name_len),1,file);
fputs(fn->name,file);
// Escribir flags
fwrite((void *)&fn->flags,sizeof(fn->flags),1,file);
// Escribir estado
fputc((char)fn->estado,file);
// Escribir tamanho
if(fn->flags&FileFlag_TieneTamanho){
fwrite((void *)&fn->size,sizeof(fn->size),1,file);
}
// Escribir fecha
if(fn->flags&FileFlag_TieneFecha){
fwrite((void *)&fn->ft,sizeof(fn->ft),1,file);
}
// Escribir CRC
if(fn->flags&FileFlag_TieneCRC){
fwrite((void *)&fn->crc,sizeof(fn->crc),1,file);
}
// Escribir ficheros del directorio
if(fn->flags&FileFlag_Directorio){
FileNode *fnc;
fwrite((void *)&fn->n_childs,sizeof(fn->n_childs),1,file);
fnc=fn->child;
while(fnc){
FileNode_SaveNode(fnc,file);
fnc=fnc->sig;
}
}
}
void FileNode_Save(FileNode *fn,char *fichero){
FILE *file;
char marca[5];
int version;
if(!fn)
return;
file=fopen(fichero,"wb+");
if(!file)
return;
// Escribir marca y version
strcpy(marca,"sYnC");
fwrite((void *)marca,sizeof(char),4,file);
version=FileNode_Version;
fwrite((void *)&version,sizeof(int),1,file);
FileNode_SaveNode(fn,file);
fclose(file);
}
FileNode *FileNode_LoadNode(FILE *file){
short name_len;
FileNode *fn;
int i;
fn=FileNode_New();
// Leer el nombre
fread((void *)&name_len,sizeof(name_len),1,file);
fread((void *)fn->name,sizeof(char),name_len,file);
fn->name[name_len]=0;
// Leer vanderas
fread((void *)&fn->flags,sizeof(fn->flags),1,file);
// Leer estado
fn->estado=fgetc(file);
// Leer tamanho
if(fn->flags&FileFlag_TieneTamanho){
fread((void *)&fn->size,sizeof(fn->size),1,file);
}
// Leer fecha
if(fn->flags&FileFlag_TieneFecha){
fread((void *)&fn->ft,sizeof(fn->ft),1,file);
}
// Leer CRC
if(fn->flags&FileFlag_TieneCRC){
fread((void *)&fn->crc,sizeof(fn->crc),1,file);
}
// Leer ficheros del directorio
if(fn->flags&FileFlag_Directorio){
FileNode *fnca=NULL,*fnc;
fread((void *)&fn->n_childs,sizeof(fn->n_childs),1,file);
for(i=0;i<fn->n_childs;i++){
fnc=FileNode_LoadNode(file);
fnc->padre=fn;
if(!fnca){
fn->child=fnc;
}else{
fnca->sig=fnc;
}
fnca=fnc;
}
}
return(fn);
}
FileNode *FileNode_Load(char *fichero){
FILE *file;
FileNode *fn;
char marca[5];
int version;
file=fopen(fichero,"rb");
if(!file)
return(NULL);
// Leer marca y version
fread((void *)marca,sizeof(char),4,file);
marca[4]=0;
if(strcmp(marca,"sYnC")){
// Marca incorrecta
fclose(file);
return(NULL);
}
fread((void *)&version,sizeof(int),1,file);
if(version!=FileNode_Version){
// Version incorrecta
fclose(file);
return(NULL);
}
fn=FileNode_LoadNode(file);
fclose(file);
return(fn);
}
void FileNode_Print(FileNode *fn){
FileNode *padre;
// Nombre
printf(FileNode_GetPath(fn,NULL));
if(fn->flags&FileFlag_Normal){
printf(" File");
}else{
printf(" Dir");
}
printf(" %d",fn->estado);
if(fn->estado==EstadoFichero_Nuevo){
printf(" Nuevo");
}
if(fn->estado==EstadoFichero_Modificado){
printf(" Modificado");
}
if(fn->estado==EstadoFichero_Borrado){
printf(" Borrado!!!");
}
printf("\n");
/*
// Tamanho
if(fn->flags&FileFlag_TieneTamanho){
printf("\\-Tamanho: %lld\n",fn->size);
}
// Fecha
if(fn->flags&FileFlag_TieneFecha){
printf("\\-Fecha : ");FileTime_Print(fn->ft);printf("\n");
}
// CRC
if(fn->flags&FileFlag_TieneCRC){
printf("\\-CRC : [%08X]\n",fn->crc);
}
*/
// Hijos
if(fn->flags&FileFlag_Directorio){
FileNode *fn2;
fn2=fn->child;
while(fn2){
FileNode_Print(fn2);
fn2=fn2->sig;
}
}
}
int FileNode_Build_Iterate(char *path,char *name,void *d);
FileNode *FileNode_Build(char *path){
FileNode *file;
if(!File_ExistePath(path))
return(NULL);
// Crear el nodo
file=FileNode_New();
File_GetName(path,file->name);
// Determinar si es un fichero o directorio
if(File_EsDirectorio(path)){
// Obtener datos para los directorios
file->flags|=FileFlag_Directorio;
FileNode_GetFecha(file,path);
File_IterateDir(path,FileNode_Build_Iterate,file);
}else{
// Obtener datos para los ficheros
file->flags|=FileFlag_Normal;
FileNode_GetTamanho(file,path);
FileNode_GetFecha(file,path);
}
return(file);
}
int FileNode_Build_Iterate(char *path,char *name,void *d){
FileNode *file,*fn_padre=d;;
file=FileNode_Build(path);
FileNode_AddChild(fn_padre,file);
return(0);
}
int FileNode_Refresh_Iterate(char *path,char *name,void *d);
FileNode *FileNode_Refresh(FileNode *fn,char *path){
if(!File_ExistePath(path)){
// El fichero ha sido borrado
if(!fn){
fn=FileNode_New();
File_GetName(path,fn->name);
}
FileNode_SetEstadoRec(fn,EstadoFichero_Borrado);
return(fn);
}
if(!fn){
// El fichero ha sido creado
fn=FileNode_Build(path);
FileNode_SetEstadoRec(fn,EstadoFichero_Nuevo);
}else{
// Comprobar si ha sido modificado
FileTime ft;
long long size;
int crc;
// Marcar normal
fn->estado=EstadoFichero_Nada;
fn->flags&=~FileFlag_MarcaRevision;
// Determinar si es un fichero o directorio
if(File_EsDirectorio(path)){
FileNode *fn_child;
// Comparar datos de los directorios
if(!(fn->flags&FileFlag_Directorio)){
fn->estado=EstadoFichero_Modificado;
fn->flags|=FileFlag_Directorio;
fn->flags&=~FileFlag_Normal;
}
ft=FileTime_Get(path);
if(ft!=fn->ft){
fn->estado=EstadoFichero_Modificado;
fn->ft=ft;
}
// Marcar hijos para determinar cual es actualizado
fn_child=fn->child;while(fn_child){
fn_child->flags|=FileFlag_MarcaRevision;
fn_child=fn_child->sig;
}
// Escanear subdirectorios
File_IterateDir(path,FileNode_Refresh_Iterate,fn);
// Buscar que sigan marcados (borrados)
fn_child=fn->child;while(fn_child){
if(fn_child->flags&FileFlag_MarcaRevision){
fn_child->flags&=~FileFlag_MarcaRevision;
fn_child->estado=EstadoFichero_Borrado;
}
fn_child=fn_child->sig;
}
}else{
// Comprar datos de los ficheros
if(!(fn->flags&FileFlag_Normal)){
fn->estado=EstadoFichero_Modificado;
fn->flags|=FileFlag_Normal;
fn->flags&=~FileFlag_Directorio;
}
size=File_TamanhoFichero(path);
if(size!=fn->size){
fn->estado=EstadoFichero_Modificado;
fn->size=size;
}
ft=FileTime_Get(path);
if(ft!=fn->ft){
fn->estado=EstadoFichero_Modificado;
fn->ft=ft;
}
if(fn->estado==EstadoFichero_Modificado){
fn->flags&=~FileFlag_TieneCRC;
}
}
}
return(fn);
}
int FileNode_Refresh_Iterate(char *path,char *name,void *d){
FileNode *fn=d;
FileNode *fn_child;
// Buscar el fichero entre los del arbol
fn_child=fn->child;
while(fn_child){
if(!strcmp(fn_child->name,name)){
break;
}
fn_child=fn_child->sig;
}
if(fn_child){
// Existe, refrescar
FileNode_Refresh(fn_child,path);
}else{
// Nuevo, construir
fn_child=FileNode_Refresh(NULL,path);
FileNode_AddChild(fn,fn_child);
}
return(0);
}

61
filenode.h Normal file
View File

@@ -0,0 +1,61 @@
#ifndef _FILENODE_H_
#define _FILENODE_H_
#define FileNode_Version 4
#define FileFlag_Raiz 1
#define FileFlag_Normal 2
#define FileFlag_Directorio 4
#define FileFlag_TieneTamanho 8
#define FileFlag_TieneFecha 16
#define FileFlag_TieneCRC 32
#define FileFlag_MarcaRevision 1024
typedef enum {
EstadoFichero_Nada,
EstadoFichero_Nuevo,
EstadoFichero_Modificado,
EstadoFichero_Borrado
} EstadoFichero;
typedef struct FileNode_Tag{
char name[512];
int flags;
EstadoFichero estado;
long long size;
unsigned long crc;
FileTime ft;
struct FileNode_Tag *child;
int n_childs;
struct FileNode_Tag *sig;
struct FileNode_Tag *padre;
} FileNode;
FileNode *FileNode_New();
void FileNode_Delete(FileNode *fn);
void FileNode_AddChild(FileNode *file,FileNode *file2);
void FileNode_GetTamanho(FileNode *fn,char *file);
void FileNode_GetFecha(FileNode *fn,char *file);
void FileNode_GetCRC(FileNode *fn,char *file);
void FileNode_Save(FileNode *fn,char *fichero);
FileNode *FileNode_Load(char *fichero);
void FileNode_Print(FileNode *fn);
FileNode *FileNode_Build(char *path);
FileNode *FileNode_Refresh(FileNode *file,char *path);
#endif

25
filenodecmp.c Normal file
View File

@@ -0,0 +1,25 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "util.h"
#include "crc.h"
#include "fileutil.h"
#include "filenode.h"
#include "filenodecmp.h"
AccionFileNode *_free_accionfilenode=NULL;
int _n_accionfilenode=0;
#define AccionFileNode_Tocho 1024
AccionFileNode *AccionFileNode_Crear(){
}
void AccionFileNode_Destruir(AccionFileNode *afn){
}
AccionFileNode *AccionFileNode_Build(FileNode *izquierda,FileNode *derecha){
}

30
filenodecmp.h Normal file
View File

@@ -0,0 +1,30 @@
#ifndef _FILENODE_H_
#define _FILENODE_H_
#include "filenode.h"
typedef enum {
AccionFileCmp_Nada,
AccionFileCmp_IzquierdaADerecha,
AccionFileCmp_DerechaAIzquierda,
AccionFileCmp_BorrarIzquierda,
AccionFileCmp_BorrarDerecha
} AccionFileCmp;
typedef struct Tag_AccionFileNode {
AccionFileCmp accion;
FileNode *izquierda;
FileNode *derecha;
struct Tag_AccionFileNode *sig;
} AccionFileNode;
AccionFileNode *AccionFileNode_Crear();
void AccionFileNode_Destruir(AccionFileNode *afn);
AccionFileNode *AccionFileNode_Build(FileNode *izquierda,FileNode *derecha);
#endif

312
fileutil.c Normal file
View File

@@ -0,0 +1,312 @@
#include <stdio.h>
#include <dirent.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <utime.h>
#include <time.h>
#ifdef WIN32
#define _WIN32_WINNT 0x0501
#include <signal.h>
#include <windows.h>
#include <fcntl.h>
#include <io.h>
#else
#include <unistd.h>
#endif
#include "fileutil.h"
#ifdef WIN32
long long FileTime_to_POSIX(FILETIME ft){
LARGE_INTEGER date, adjust;
// takes the last modified date
date.HighPart = ft.dwHighDateTime;
date.LowPart = ft.dwLowDateTime;
// 100-nanoseconds = milliseconds * 10000
adjust.QuadPart = 11644473600000ll * 10000;
// removes the diff between 1970 and 1601
date.QuadPart -= adjust.QuadPart;
// converts back from 100-nanoseconds to seconds
return date.QuadPart / 10000000ll;
}
FILETIME POSIX_to_FileTime(FileTime ft){
LARGE_INTEGER date, adjust;
FILETIME filetime;
// converts to 100-nanoseconds from seconds
date.QuadPart=ft*10000000ll;
// 100-nanoseconds = milliseconds * 10000
adjust.QuadPart = 11644473600000ll * 10000ll;
// removes the diff between 1970 and 1601
date.QuadPart += adjust.QuadPart;
// asigns to filetime
filetime.dwHighDateTime=date.HighPart;
filetime.dwLowDateTime=date.LowPart;
return filetime;
}
FileTime FileTime_Get(char *filename){
HANDLE hFile;
FILETIME ftCreate, ftAccess, ftWrite;
hFile = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
GetFileTime(hFile, &ftCreate, &ftAccess, &ftWrite);
CloseHandle(hFile);
return(FileTime_to_POSIX(ftWrite));
}
void FileTime_Set(char *filename,FileTime t){
HANDLE hFile;
FILETIME ftWrite;
hFile = CreateFile(filename, GENERIC_WRITE, FILE_SHARE_READ,
NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
ftWrite=POSIX_to_FileTime(t);
SetFileTime(hFile, NULL, NULL, &ftWrite);
CloseHandle(hFile);
}
#else
FileTime FileTime_Get(char *filename){
struct stat fs;
lstat(filename,&fs);
return(fs.st_mtime);
}
void FileTime_Set(char *filename,FileTime t){
struct utimbuf utb;
utb.actime=t;
utb.modtime=t;
utime(filename,&utb);
}
#endif
void FileTime_Print(FileTime t){
struct tm *tms;
tms=localtime((time_t *)&t);
printf("%d/%d/%d %02d:%02d:%02d",
tms->tm_year+1900,
tms->tm_mon+1,
tms->tm_mday,
tms->tm_hour,
tms->tm_min,
tms->tm_sec);
}
void File_GetName(char *path,char *name){
int i,j;
i=strlen(path)-1;
while(i>=0 ){
if(path[i]=='/' || path[i]=='\\'){
i++;
break;
}else{
i--;
}
}
if(i<0)
i++;
j=0;
while(path[i]){
name[j]=path[i];
i++;j++;
}
name[j]=0;
}
#ifdef WIN32
int File_ExistePath(char *path){
unsigned rc;
rc=GetFileAttributes(path);
if(rc==INVALID_FILE_ATTRIBUTES){
return(0);
}
return(1);
}
int File_EsDirectorio(char *dir){
unsigned rc;
rc=GetFileAttributes(dir);
if(rc==INVALID_FILE_ATTRIBUTES){
return(0);
}
if(rc&FILE_ATTRIBUTE_DIRECTORY){
return(1);
}
return(0);
}
int File_EsFichero(char *fichero){
unsigned rc;
rc=GetFileAttributes(fichero);
if(rc==INVALID_FILE_ATTRIBUTES){
return(0);
}
if(rc&FILE_ATTRIBUTE_DIRECTORY){
return(0);
}
return(1);
}
#else
int File_ExistePath(char *path){
struct stat info;
if(lstat(path,&info)==-1){
return(0);
}
return(1);
}
int File_EsDirectorio(char *dir){
struct stat info;
if(lstat(dir,&info)==-1){
return(0);
}
if(S_ISDIR(info.st_mode)){
return(1);
}
return(0);
}
int File_EsFichero(char *fichero){
struct stat info;
if(lstat(fichero,&info)==-1){
return(0);
}
if(S_ISDIR(info.st_mode)){
return(0);
}
return(1);
}
#endif
long long File_TamanhoFichero(char *fichero){
FILE *f;
long long tamanho;
f=fopen(fichero,"rb");
if(!f)
return(-1);
fseek(f,0,SEEK_END);
tamanho=ftell(f);
fclose(f);
return(tamanho);
}
#ifdef WIN32
int File_CrearDir(char *path){
return(_mkdir(path));
}
#else
int File_CrearDir(char *path){
return(mkdir(path,0777));
}
#endif
#ifdef WIN32
void File_IterateDir(char *path,
int (*func)(char *path,char *name,void *data),void *data)
{
int handle;
struct _finddata_t fileinfo;
char f_path[512];
int fin=0;
int findnext_rc;
char path_aux[512];
char *ptr;
snprintf(path_aux,512,
"%s/*",path);
handle=_findfirst(path_aux,&fileinfo);
if(handle==-1)
return;
// Recorrer el directorio
do{
if(strcmp(fileinfo.name,".") &&
strcmp(fileinfo.name,".."))
{
// Apartir de aqui hay un fichero
// (o directorio)
snprintf(f_path,512,
"%s/%s",path,fileinfo.name);
fin=func(f_path,fileinfo.name,data);
}
findnext_rc=_findnext(handle,&fileinfo);
}while(findnext_rc!=-1 && !fin);
_findclose(handle);
}
#else
void File_IterateDir(char *path,
int (*func)(char *path,char *name,void *data),void *data)
{
DIR *directorio;
struct dirent *entidad_dir;
char f_path[512];
int fin=0;
char *ptr;
directorio=opendir(path);
if(directorio==NULL)
return;
// Recorrer el directorio
do{
entidad_dir=readdir(directorio);
if(entidad_dir!=NULL){
if(strcmp(entidad_dir->d_name,".") &&
strcmp(entidad_dir->d_name,".."))
{
// A partir de aqui hay un fichero
// (o directorio)
snprintf(f_path,512,
"%s/%s",path,entidad_dir->d_name);
fin=func(f_path,
entidad_dir->d_name,
data);
}
}
}while(entidad_dir!=NULL && !fin);
closedir(directorio);
}
#endif

36
fileutil.h Normal file
View File

@@ -0,0 +1,36 @@
#ifndef _FILEUTIL_
#define _FILEUTIL_
////////////////////////////////////////////////
// FileTime
typedef long long FileTime;
FileTime FileTime_Get(char *filename);
void FileTime_Set(char *filename,FileTime t);
void FileTime_Print(FileTime t);
///////////////////////////////////////////////
// File
void File_GetName(char *path,char *name);
int File_ExistePath(char *path);
int File_EsDirectorio(char *path);
int File_EsFichero(char *path);
long long File_TamanhoFichero(char *ficheros);
int File_CrearDir(char *path);
void File_IterateDir(char *path,
int (*func)(char *path,char *name,void *data),void *data);
#endif

122
main.c Normal file
View File

@@ -0,0 +1,122 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "util.h"
#include "crc.h"
#include "fileutil.h"
#include "filenode.h"
void help(char *exe){
printf("%s info [file] {[file] {..}}\n",exe);
printf("%s scan [dir] [tree] \n",exe);
printf("%s rescan [dir] [tree] \n",exe);
printf("%s read [file] [tree]\n",exe);
}
int main(int argc,char *argv[]){
FILE *f;
unsigned long crc;
FileTime ft;
int i;
if(argc<2){
help(argv[0]);
}else
if(!strcmp(argv[1],"info") && argc>=3){
// Informacion de ficheros
for(i=2;i<argc;i++){
f=fopen(argv[i],"rb");
if(f){
crc=CRC_File(f);
fclose(f);
ft=FileTime_Get(argv[i]);
printf("%s:\t[%08X]\t",argv[i],crc);
FileTime_Print(ft);printf("\n");
}
}
}else
if(!strcmp(argv[1],"scan") && argc==4){
// Scanear informacion de directorio y guardar arbol
FileNode *fn;
printf("Building FileNode..\n");
fn=FileNode_Build(argv[2]);
FileNode_Save(fn,argv[3]);
}else
if(!strcmp(argv[1],"rescan") && argc==4){
// Scanear informacion de directorio y guardar arbol
FileNode *fn;
printf("Loading FileNode..\n");
fn=FileNode_Load(argv[3]);
if(fn){
printf("Rebuilding FileNode..\n");
fn=FileNode_Refresh(fn,argv[2]);
FileNode_Save(fn,argv[3]);
}
}else
if(!strcmp(argv[1],"read") && argc==3){
// Leer informacion de arbol
FileNode *fn;
fn=FileNode_Load(argv[2]);
if(fn)FileNode_Print(fn);
}else{
help(argv[0]);
}
/*
if(argc<2){
return(1);
}
f=fopen(argv[1],"rb");
if(f){
crc=CRC_File(f);
fclose(f);
printf("%s:\t%08X\n",argv[1],crc);
}
*/
/*
if(argc<2){
return(1);
}
//printf("%d\n",FileTime_Get(argv[1]));
FileTime ft;
ft=FileTime_Get(argv[1]);
FileTime_Print(ft);printf("\n");
FileTime_Set(argv[1],ft+120);
ft=FileTime_Get(argv[1]);
FileTime_Print(ft);printf("\n");
*/
/*
if(argc<2){
return(1);
}
FileNode *fn;
printf("Building FileNode..\n");
fn=FileNode_Build(argv[1]);
//printf("FileNode Contents:\n");
//FileNode_Print(fn);
extern int _n_filenode;
printf("%d\n",_n_filenode);
printf("END\n");
FileNode_Save(fn,"test2.fs");
*/
/*
FileNode *fn;
fn=FileNode_Load("test2.fs");
FileNode_Print(fn);
*/
return(0);
}

15
util.c Normal file
View File

@@ -0,0 +1,15 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "util.h"
char *String_Copy(char *str){
char *strnew;
int len;
len=strlen(str);
strnew=malloc(len+1);
strcpy(strnew,str);
return(strnew);
}

6
util.h Normal file
View File

@@ -0,0 +1,6 @@
#ifndef _UTIL_
#define _UTIL_
char *String_Copy(char *str);
#endif