From aeb408cfb1c029dd1b32c8c39fdc91cad3c87adc Mon Sep 17 00:00:00 2001 From: "Valeriano A.R" Date: Fri, 24 May 2013 00:49:29 +0200 Subject: [PATCH] Initial Commit. --- .gitignore | 4 + Makefile | 63 ++++++ NOTAS.txt | 19 ++ crc.c | 69 +++++++ crc.h | 9 + filenode.c | 515 ++++++++++++++++++++++++++++++++++++++++++++++++++ filenode.h | 61 ++++++ filenodecmp.c | 25 +++ filenodecmp.h | 30 +++ fileutil.c | 312 ++++++++++++++++++++++++++++++ fileutil.h | 36 ++++ main.c | 122 ++++++++++++ util.c | 15 ++ util.h | 6 + 14 files changed, 1286 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 NOTAS.txt create mode 100644 crc.c create mode 100644 crc.h create mode 100644 filenode.c create mode 100644 filenode.h create mode 100644 filenodecmp.c create mode 100644 filenodecmp.h create mode 100644 fileutil.c create mode 100644 fileutil.h create mode 100644 main.c create mode 100644 util.c create mode 100644 util.h 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