commit aeb408cfb1c029dd1b32c8c39fdc91cad3c87adc Author: Valeriano A.R Date: Fri May 24 00:49:29 2013 +0200 Initial Commit. diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7df3361 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +*.o +*.exe +build +_tests diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..6e0e52d --- /dev/null +++ b/Makefile @@ -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) + + diff --git a/NOTAS.txt b/NOTAS.txt new file mode 100644 index 0000000..95db6c7 --- /dev/null +++ b/NOTAS.txt @@ -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. diff --git a/crc.c b/crc.c new file mode 100644 index 0000000..250bf09 --- /dev/null +++ b/crc.c @@ -0,0 +1,69 @@ +#include + +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); +} diff --git a/crc.h b/crc.h new file mode 100644 index 0000000..b897705 --- /dev/null +++ b/crc.h @@ -0,0 +1,9 @@ +#ifndef _CRC_ +#define _CRC_ + +#include + +unsigned long CRC_Buffer(unsigned char *buffer,int len,unsigned long crc); +unsigned long CRC_File(FILE *file); + +#endif diff --git a/filenode.c b/filenode.c new file mode 100644 index 0000000..68eeb3e --- /dev/null +++ b/filenode.c @@ -0,0 +1,515 @@ +#include +#include +#include + +#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;isig; + _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;in_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); +} + + + + + + + + + + diff --git a/filenode.h b/filenode.h new file mode 100644 index 0000000..8230840 --- /dev/null +++ b/filenode.h @@ -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 diff --git a/filenodecmp.c b/filenodecmp.c new file mode 100644 index 0000000..461a4f2 --- /dev/null +++ b/filenodecmp.c @@ -0,0 +1,25 @@ +#include +#include +#include + +#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){ + +} diff --git a/filenodecmp.h b/filenodecmp.h new file mode 100644 index 0000000..cd2a4df --- /dev/null +++ b/filenodecmp.h @@ -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 diff --git a/fileutil.c b/fileutil.c new file mode 100644 index 0000000..f89d7e7 --- /dev/null +++ b/fileutil.c @@ -0,0 +1,312 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef WIN32 + #define _WIN32_WINNT 0x0501 + #include + #include + #include + #include +#else + #include +#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 + + + + diff --git a/fileutil.h b/fileutil.h new file mode 100644 index 0000000..8437a8c --- /dev/null +++ b/fileutil.h @@ -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 diff --git a/main.c b/main.c new file mode 100644 index 0000000..6fa6250 --- /dev/null +++ b/main.c @@ -0,0 +1,122 @@ +#include +#include +#include + +#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 +#include +#include + +#include "util.h" + +char *String_Copy(char *str){ + char *strnew; + int len; + len=strlen(str); + strnew=malloc(len+1); + strcpy(strnew,str); + return(strnew); +} + diff --git a/util.h b/util.h new file mode 100644 index 0000000..594cb3a --- /dev/null +++ b/util.h @@ -0,0 +1,6 @@ +#ifndef _UTIL_ +#define _UTIL_ + +char *String_Copy(char *str); + +#endif