diff --git a/.gitignore b/.gitignore index 7df3361..8726e09 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ *.o *.exe build -_tests + diff --git a/NOTAS.txt b/NOTAS.txt index ac382b5..e78a8a9 100644 --- a/NOTAS.txt +++ b/NOTAS.txt @@ -1,7 +1,6 @@ POR HACER ========= -* Realizar las acciones especificadas por la lista de AccionFileCmp * Demonio * GUI @@ -15,4 +14,5 @@ HECHO de cada fichero; crc, fecha, estado (FileNode en filenode.h) * Scaneo, construccion y reconstruccion de arboles FileNode, detectando cambios. * Comparador de FileNodes que genere una lista de AccionFileCmp (filenodecmp.h) +* Realizar las acciones especificadas por la lista de AccionFileCmp diff --git a/filenode.c b/filenode.c index 1249fc2..62d1a4e 100644 --- a/filenode.c +++ b/filenode.c @@ -81,9 +81,9 @@ void FileNode_GetPath_Rec(FileNode *fn,char **pathnode){ pathnode[0]=NULL; } } -char temppath[1024]; +char temppath[MaxPath]; char *FileNode_GetPath(FileNode *fn,char *path){ - char *pathnodes[100]; + char *pathnodes[128]; int levels,i; char *pathptr=temppath; if(path)pathptr=path; @@ -98,6 +98,23 @@ char *FileNode_GetPath(FileNode *fn,char *path){ strcat(pathptr,fn->name); return temppath; } +char *FileNode_GetFullPath(FileNode *fn,char *basePath,char *path){ + char *pathnodes[128]; + int levels,i; + char *pathptr=temppath; + if(path)pathptr=path; + + FileNode_GetPath_Rec(fn,pathnodes); + levels=0;while(pathnodes[levels]){levels++;} + strcpy(pathptr,basePath); + strcat(pathptr,"/"); + for(i=levels-2;i>=0;i--){ + strcat(pathptr,pathnodes[i]); + strcat(pathptr,"/"); + } + strcat(pathptr,fn->name); + return temppath; +} @@ -320,7 +337,9 @@ void FileNode_Print(FileNode *fn){ while(fnAux!=NULL && !end){ - FileNode_PrintNode(fnAux); + if(fnAux->padre!=NULL){ + FileNode_PrintNode(fnAux); + } if(fnAux->child){ fnAux=fnAux->child; @@ -414,10 +433,8 @@ int FileNode_Build_Iterate(char *path,char *name,void *d){ 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 + // El fichero/directorio ha sido borrado if(!fn){ fn=FileNode_New(); File_GetName(path,fn->name); @@ -468,7 +485,7 @@ FileNode *FileNode_Refresh(FileNode *fn,char *path){ fn_child=fn->child;while(fn_child){ if(fn_child->flags&FileFlag_MarcaRevision){ fn_child->flags&=~FileFlag_MarcaRevision; - fn_child->estado=EstadoFichero_Borrado; + FileNode_SetEstadoRec(fn_child,EstadoFichero_Borrado); } fn_child=fn_child->sig; } diff --git a/filenode.h b/filenode.h index f4eb555..7a37064 100644 --- a/filenode.h +++ b/filenode.h @@ -21,7 +21,7 @@ typedef enum { } EstadoFichero; typedef struct FileNode_Tag{ - char name[512]; + char name[MaxFilename]; int flags; @@ -44,6 +44,8 @@ FileNode *FileNode_New(); void FileNode_Delete(FileNode *fn); void FileNode_AddChild(FileNode *file,FileNode *file2); +char *FileNode_GetFullPath(FileNode *fn,char *basePath,char *path); + void FileNode_GetTamanho(FileNode *fn,char *file); void FileNode_GetFecha(FileNode *fn,char *file); void FileNode_GetCRC(FileNode *fn,char *file); diff --git a/filenodecmp.c b/filenodecmp.c index 60aa7ac..99f38df 100644 --- a/filenodecmp.c +++ b/filenodecmp.c @@ -36,6 +36,7 @@ AccionFileNode *AccionFileNode_Crear(){ afn->izquierda=NULL; afn->derecha=NULL; afn->sig=NULL; + afn->motivo[0]=0; return(afn); } @@ -47,168 +48,409 @@ void AccionFileNode_Destruir(AccionFileNode *afn){ _n_accionfilenode--; } - -void AccionFileNode_CompareChilds( - AccionFileNode *afnRaiz, - AccionFileNode **afnCola); - - -void AccionFileNode_CheckPair( - FileNode *fnIzq,FileNode *fnDer,AccionFileNode **afnCola) +AccionFileNode *AccionFileNode_CrearNormal(FileNode *fnIzq,FileNode *fnDer) { AccionFileNode *afnNew; afnNew=AccionFileNode_Crear(); + afnNew->accion=AccionFileCmp_Nada; afnNew->izquierda=fnIzq; afnNew->derecha=fnDer; - int doChilds=0; + return afnNew; +} + +void AccionFileNode_CompareChilds( + AccionFileNode *afnRaiz, + AccionFileNode **afnCola, + void (*CheckPair)(FileNode *fnIzq,FileNode *fnDer,AccionFileNode **afnCola)) +{ + FileNode *fnIzq,*fnDer; + AccionFileNode *afnColaStart=(*afnCola); + + // Comprobar si hay algo que comparar + if(!afnRaiz->izquierda && !afnRaiz->derecha){ + // Nada que hacer + return; + } + + // Iterar todos los nodos de la izquierda + if(afnRaiz->izquierda){ + fnIzq=afnRaiz->izquierda->child; + while(fnIzq){ + if(afnRaiz->derecha){ + fnDer=afnRaiz->derecha->child; + while(fnDer){ + if(!strcmp(fnIzq->name,fnDer->name)){ + break; + }else{ + fnDer=fnDer->sig; + } + } + }else{ + fnDer=NULL; + } + + CheckPair(fnIzq,fnDer,afnCola); + + fnIzq=fnIzq->sig; + } + } + + + // Iterar todos los nodos de la derecha, + // ignorando las comparaciones ya realizadas + if(afnRaiz->derecha){ + fnDer=afnRaiz->derecha->child; + while(fnDer){ + int doCheck=1; + if(afnRaiz->izquierda){ + fnIzq=afnRaiz->izquierda->child; + while(fnIzq){ + AccionFileNode *afnCheck=afnColaStart; + while(afnCheck){ + if(afnCheck->izquierda==fnIzq && afnCheck->derecha==fnDer){ + break; + }else{ + afnCheck=afnCheck->sig; + } + } + if(afnCheck){ + doCheck=0; + break; + } + + if(!strcmp(fnIzq->name,fnDer->name)){ + break; + }else{ + fnIzq=fnIzq->sig; + } + } + }else{ + fnIzq=NULL; + } + + if(doCheck){ + CheckPair(fnIzq,fnDer,afnCola); + } + + fnDer=fnDer->sig; + } + } + +} + + + +void AccionFileNode_DeletePair( + FileNode *fnIzq,FileNode *fnDer,AccionFileNode **afnCola) +{ + AccionFileNode *afnNew=AccionFileNode_CrearNormal(fnIzq,fnDer); if(!fnIzq && !fnDer){ AccionFileNode_Destruir(afnNew); return; } if(!fnIzq && fnDer){ - afnNew->accion=AccionFileCmp_DerechaAIzquierda; - if(fnDer->child && fnDer->estado!=EstadoFichero_Borrado){ - doChilds=1; + if(fnDer->flags&FileFlag_Directorio){ + // Iterar hijos para borrarlos + AccionFileNode_CompareChilds(afnNew,afnCola, + AccionFileNode_DeletePair); } - // Anular en caso de se operacion nula - if(fnDer->estado==EstadoFichero_Borrado){ - afnNew->accion=AccionFileCmp_Nada; + if(fnDer->estado!=EstadoFichero_Borrado){ + // Accion de borrado para el nodo + afnNew->accion=AccionFileCmp_BorrarDerecha; + strcpy(afnNew->motivo,"DEL: solo existe Der"); + (*afnCola)->sig=afnNew; + (*afnCola)=afnNew; + }else{ + AccionFileNode_Destruir(afnNew); } } if(fnIzq && !fnDer){ - afnNew->accion=AccionFileCmp_IzquierdaADerecha; - if(fnIzq->child && fnIzq->estado!=EstadoFichero_Borrado){ - doChilds=1; + if(fnIzq->flags&FileFlag_Directorio){ + // Iterar hijos para borrarlos + AccionFileNode_CompareChilds(afnNew,afnCola, + AccionFileNode_DeletePair); } - // Anular en caso de se operacion nula - if(fnIzq->estado==EstadoFichero_Borrado){ - afnNew->accion=AccionFileCmp_Nada; + if(fnIzq->estado!=EstadoFichero_Borrado){ + // Accion de borrado para el nodo + afnNew->accion=AccionFileCmp_BorrarIzquierda; + strcpy(afnNew->motivo,"DEL: solo existe Izq"); + (*afnCola)->sig=afnNew; + (*afnCola)=afnNew; + }else{ + AccionFileNode_Destruir(afnNew); } } if(fnIzq && fnDer){ - // Realizar comparacion completa - if(fnIzq->child && fnIzq->estado!=EstadoFichero_Borrado){ - doChilds=1; - } - if(fnIzq->child && fnDer->estado!=EstadoFichero_Borrado){ - doChilds=1; - } - - // Comparacion mediante fechas - if(fnIzq->ft==fnDer->ft){ - afnNew->accion=AccionFileCmp_Nada; - }else - if(fnIzq->ftft){ - afnNew->accion=AccionFileCmp_DerechaAIzquierda; - if(fnDer->estado==EstadoFichero_Borrado){ - afnNew->accion=AccionFileCmp_BorrarIzquierda; - } - }else - if(fnIzq->ft>fnDer->ft){ - afnNew->accion=AccionFileCmp_IzquierdaADerecha; - if(fnIzq->estado==EstadoFichero_Borrado){ - afnNew->accion=AccionFileCmp_BorrarDerecha; - } - } - - // Anular en caso de se operacion nula - if(fnDer->estado==EstadoFichero_Borrado && - fnIzq->estado==EstadoFichero_Borrado) + if(fnIzq->flags&FileFlag_Directorio || + fnDer->flags&FileFlag_Directorio) { - afnNew->accion=AccionFileCmp_Nada; + // Alguno es directorio + + // Iterar hijos para borrarlos + AccionFileNode_CompareChilds(afnNew,afnCola, + AccionFileNode_DeletePair); } - } - // Anhadir a la lista de acciones - (*afnCola)->sig=afnNew; - (*afnCola)=afnNew; - - if(doChilds){ - AccionFileNode_CompareChilds(afnNew,afnCola); + if(fnIzq->estado!=EstadoFichero_Borrado){ + // Accion de borrado para el nodo izquierdo + afnNew->accion=AccionFileCmp_BorrarIzquierda; + strcpy(afnNew->motivo,"DEL: existe Izq"); + (*afnCola)->sig=afnNew; + (*afnCola)=afnNew; + afnNew=NULL; + } + if(fnDer->estado!=EstadoFichero_Borrado){ + if(!afnNew){ afnNew=AccionFileNode_CrearNormal(fnIzq,fnDer); } + // Accion de borrado para el nodo derecho + afnNew->accion=AccionFileCmp_BorrarDerecha; + strcpy(afnNew->motivo,"DEL: existe Der"); + (*afnCola)->sig=afnNew; + (*afnCola)=afnNew; + afnNew=NULL; + } + if(afnNew){ + AccionFileNode_Destruir(afnNew); + } } } - -void AccionFileNode_CompareChilds( - AccionFileNode *afnRaiz, - AccionFileNode **afnCola) +void AccionFileNode_CheckPair( + FileNode *fnIzq,FileNode *fnDer,AccionFileNode **afnCola) { - FileNode *fnIzq,*fnDer; - AccionFileNode *afnColaStart=(*afnCola); + AccionFileNode *afnNew=AccionFileNode_CrearNormal(fnIzq,fnDer); - // Comprobar si hay algo que comparar - if(!afnRaiz->izquierda || !afnRaiz->derecha){ - // Nada que hacer + if(!fnIzq && !fnDer){ + AccionFileNode_Destruir(afnNew); return; } + if(!fnIzq && fnDer){ + if(fnDer->flags&FileFlag_Directorio){ + // Directory + if(fnDer->estado==EstadoFichero_Borrado){ + afnNew->accion=AccionFileCmp_Nada; + + // Anhadir a la lista de acciones + strcpy(afnNew->motivo,"CMP: nada, solo der borrada"); + (*afnCola)->sig=afnNew; + (*afnCola)=afnNew; - // Iterar todos los nodos de la izquierda - fnIzq=afnRaiz->izquierda->child; - while(fnIzq){ - fnDer=afnRaiz->derecha->child; - while(fnDer){ - if(!strcmp(fnIzq->name,fnDer->name)){ - break; }else{ - fnDer=fnDer->sig; + afnNew->accion=AccionFileCmp_CrearDirIzquierda; + + // Anhadir a la lista de acciones + strcpy(afnNew->motivo,"CMP: dir izquierdo no existe"); + (*afnCola)->sig=afnNew; + (*afnCola)=afnNew; + + // Iterar hijos + AccionFileNode_CompareChilds(afnNew,afnCola, + AccionFileNode_CheckPair); + + // Crear nueva accion para copiar la fecha + afnNew=AccionFileNode_CrearNormal(fnIzq,fnDer); + afnNew->accion=AccionFileCmp_FechaDerechaAIzquierda; + strcpy(afnNew->motivo,"CMP: dir izquierdo no existe"); + (*afnCola)->sig=afnNew; + (*afnCola)=afnNew; } + }else{ + // File + if(fnDer->estado==EstadoFichero_Borrado){ + afnNew->accion=AccionFileCmp_Nada; + strcpy(afnNew->motivo,"CMP: nada, solo der borrada"); + }else{ + afnNew->accion=AccionFileCmp_DerechaAIzquierda; + strcpy(afnNew->motivo,"CMP: solo existe der"); + } + (*afnCola)->sig=afnNew; + (*afnCola)=afnNew; } - - AccionFileNode_CheckPair(fnIzq,fnDer,afnCola); - - fnIzq=fnIzq->sig; } + if(fnIzq && !fnDer){ + if(fnIzq->flags&FileFlag_Directorio){ + // Directory + if(fnIzq->estado==EstadoFichero_Borrado){ + afnNew->accion=AccionFileCmp_Nada; + // Anhadir a la lista de acciones + strcpy(afnNew->motivo,"CMP: nada, solo izq borrada"); + (*afnCola)->sig=afnNew; + (*afnCola)=afnNew; - // Iterar todos los nodos de la derecha, - // ignorando las comparaciones ya realizadas - fnDer=afnRaiz->derecha->child; - while(fnDer){ - int doCheck=1; - fnIzq=afnRaiz->izquierda->child; - while(fnIzq){ - AccionFileNode *afnCheck=afnColaStart; - while(afnCheck){ - if(afnCheck->izquierda==fnIzq && afnCheck->derecha==fnDer){ - break; + }else{ + afnNew->accion=AccionFileCmp_CrearDirDerecha; + + // Anhadir a la lista de acciones + strcpy(afnNew->motivo,"CMP: dir der no existe"); + (*afnCola)->sig=afnNew; + (*afnCola)=afnNew; + + // Iterar hijos + AccionFileNode_CompareChilds(afnNew,afnCola, + AccionFileNode_CheckPair); + + // Crear nueva accion para copiar la fecha + afnNew=AccionFileNode_CrearNormal(fnIzq,fnDer); + afnNew->accion=AccionFileCmp_FechaIzquierdaADerecha; + strcpy(afnNew->motivo,"CMP: dir der no existe"); + (*afnCola)->sig=afnNew; + (*afnCola)=afnNew; + } + }else{ + // File + if(fnIzq->estado==EstadoFichero_Borrado){ + afnNew->accion=AccionFileCmp_Nada; + strcpy(afnNew->motivo,"CMP: nada, solo izq borrada"); + }else{ + afnNew->accion=AccionFileCmp_IzquierdaADerecha; + strcpy(afnNew->motivo,"CMP: solo existe der"); + } + (*afnCola)->sig=afnNew; + (*afnCola)=afnNew; + } + } + if(fnIzq && fnDer){ + if(fnIzq->flags&FileFlag_Directorio && + fnDer->flags&FileFlag_Directorio) + { + // Directorios + + // Preparar accion para el par de directorios + if(fnIzq->ft==fnDer->ft){ + if(fnDer->estado==EstadoFichero_Borrado && + fnIzq->estado==EstadoFichero_Borrado) + { + afnNew->accion=AccionFileCmp_Nada; + }else + if(fnDer->estado==EstadoFichero_Borrado){ + afnNew->accion=AccionFileCmp_BorrarIzquierda; + if(fnIzq->estado==EstadoFichero_Borrado){ + afnNew->accion=AccionFileCmp_Nada; + } + }else + if(fnIzq->estado==EstadoFichero_Borrado){ + afnNew->accion=AccionFileCmp_BorrarDerecha; + if(fnDer->estado==EstadoFichero_Borrado){ + afnNew->accion=AccionFileCmp_Nada; + } }else{ - afnCheck=afnCheck->sig; + afnNew->accion=AccionFileCmp_Nada; + } + }else + if(fnIzq->ftft){ + afnNew->accion=AccionFileCmp_FechaDerechaAIzquierda; + if(fnDer->estado==EstadoFichero_Borrado){ + afnNew->accion=AccionFileCmp_BorrarIzquierda; + if(fnIzq->estado==EstadoFichero_Borrado){ + afnNew->accion=AccionFileCmp_Nada; + } + } + }else + if(fnIzq->ft>fnDer->ft){ + afnNew->accion=AccionFileCmp_FechaIzquierdaADerecha; + if(fnIzq->estado==EstadoFichero_Borrado){ + afnNew->accion=AccionFileCmp_BorrarDerecha; + if(fnDer->estado==EstadoFichero_Borrado){ + afnNew->accion=AccionFileCmp_Nada; + } } } - if(afnCheck){ - doCheck=0; - break; - } - if(!strcmp(fnIzq->name,fnDer->name)){ - break; + // Procesar nodos hijos + if(afnNew->accion==AccionFileCmp_BorrarDerecha || + afnNew->accion==AccionFileCmp_BorrarIzquierda || + (fnIzq->estado==EstadoFichero_Borrado && + fnDer->estado==EstadoFichero_Borrado)) + { + // Iterar nodos hijos para borrarlos + AccionFileNode_CompareChilds(afnNew,afnCola, + AccionFileNode_DeletePair); }else{ - fnIzq=fnIzq->sig; + AccionFileNode_CompareChilds(afnNew,afnCola, + AccionFileNode_CheckPair); } - } - if(doCheck){ - AccionFileNode_CheckPair(fnIzq,fnDer,afnCola); - } + // Encolar accion para el directorio padre + strcpy(afnNew->motivo,"CMP: dir cmp"); + (*afnCola)->sig=afnNew; + (*afnCola)=afnNew; - fnDer=fnDer->sig; + }else + if(fnIzq->flags&FileFlag_Normal && + fnDer->flags&FileFlag_Normal) + { + // Ficheros + + + // Preparar accion para el par de ficheros + if(abs(fnIzq->ft-fnDer->ft)<=1){ // appoximadamente iguales + if(fnDer->estado==EstadoFichero_Borrado && + fnIzq->estado==EstadoFichero_Borrado) + { + afnNew->accion=AccionFileCmp_Nada; + }else + if(fnDer->estado==EstadoFichero_Borrado){ + afnNew->accion=AccionFileCmp_BorrarIzquierda; + if(fnIzq->estado==EstadoFichero_Borrado){ + afnNew->accion=AccionFileCmp_Nada; + } + }else + if(fnIzq->estado==EstadoFichero_Borrado){ + afnNew->accion=AccionFileCmp_BorrarDerecha; + if(fnDer->estado==EstadoFichero_Borrado){ + afnNew->accion=AccionFileCmp_Nada; + } + }else{ + afnNew->accion=AccionFileCmp_Nada; + } + }else + if(fnIzq->ftft){ + //strcpy(afnNew->motivo,"CMP: izqmotivo,"i:%lld < d:%lld",fnIzq->ft,fnDer->ft); + afnNew->accion=AccionFileCmp_DerechaAIzquierda; + if(fnDer->estado==EstadoFichero_Borrado){ + afnNew->accion=AccionFileCmp_BorrarIzquierda; + if(fnIzq->estado==EstadoFichero_Borrado){ + afnNew->accion=AccionFileCmp_Nada; + } + } + }else + if(fnIzq->ft>fnDer->ft){ + //strcpy(afnNew->motivo,"CMP: dermotivo,"d:%lld < i:%lld",fnDer->ft,fnIzq->ft); + afnNew->accion=AccionFileCmp_IzquierdaADerecha; + if(fnIzq->estado==EstadoFichero_Borrado){ + afnNew->accion=AccionFileCmp_BorrarDerecha; + if(fnDer->estado==EstadoFichero_Borrado){ + afnNew->accion=AccionFileCmp_Nada; + } + } + } + + // Encolar accion para el fichero + (*afnCola)->sig=afnNew; + (*afnCola)=afnNew; + + }else{ + // FIXME: !!!!! + // Directory vs File + + } } - } + AccionFileNode *AccionFileNode_Build( FileNode *izquierda,FileNode *derecha) { - AccionFileNode *afnRaiz=AccionFileNode_Crear(); + AccionFileNode *afnRaiz=AccionFileNode_CrearNormal(izquierda,derecha); AccionFileNode *afnCola=afnRaiz; - afnRaiz->izquierda=izquierda; - afnRaiz->derecha=derecha; - - AccionFileNode_CompareChilds(afnRaiz,&afnCola); + AccionFileNode_CompareChilds(afnRaiz,&afnCola, + AccionFileNode_CheckPair); return afnRaiz; } @@ -216,7 +458,7 @@ AccionFileNode *AccionFileNode_Build( void AccionFileNode_Print(AccionFileNode *afn){ - char pathIzq[4096],pathDer[4096]; + char pathIzq[MaxPath],pathDer[MaxPath]; while(afn!=NULL){ if(afn->izquierda){ FileNode_GetPath(afn->izquierda,pathIzq); @@ -234,19 +476,106 @@ void AccionFileNode_Print(AccionFileNode *afn){ //printf("%s == %s\n",pathIzq,pathDer); break; case AccionFileCmp_IzquierdaADerecha: - printf("%s => %s\n",pathIzq,pathDer);break; + printf("%s => %s %s\n",pathIzq,pathDer,afn->motivo);break; case AccionFileCmp_DerechaAIzquierda: - printf("%s <= %s\n",pathIzq,pathDer);break; + printf("%s <= %s %s\n",pathIzq,pathDer,afn->motivo);break; case AccionFileCmp_BorrarIzquierda: - printf("%s *- %s\n",pathIzq,pathDer);break; + printf("%s *- %s %s\n",pathIzq,pathDer,afn->motivo);break; case AccionFileCmp_BorrarDerecha: - printf("%s -* %s\n",pathIzq,pathDer);break; + printf("%s -* %s %s\n",pathIzq,pathDer,afn->motivo);break; case AccionFileCmp_FechaIzquierdaADerecha: - printf("%s -> %s\n",pathIzq,pathDer);break; + printf("%s -> %s %s\n",pathIzq,pathDer,afn->motivo);break; case AccionFileCmp_FechaDerechaAIzquierda: - printf("%s <- %s\n",pathIzq,pathDer);break; + printf("%s <- %s %s\n",pathIzq,pathDer,afn->motivo);break; + case AccionFileCmp_CrearDirDerecha: + printf("%s -D %s %s\n",pathIzq,pathDer,afn->motivo);break; + case AccionFileCmp_CrearDirIzquierda: + printf("%s D- %s %s\n",pathIzq,pathDer,afn->motivo);break; } afn=afn->sig; } + printf("End\n"); +} + + + + + +void AccionFileNodeAux_CopyDate(char *pathOrig,char *pathDest){ + FileTime ft=FileTime_Get(pathOrig); + FileTime_Set(pathDest,ft); +} + +void AccionFileNodeAux_Copy(char *pathOrig,char *pathDest){ + if(File_Copiar(pathOrig,pathDest)){ + AccionFileNodeAux_CopyDate(pathOrig,pathDest); + } +} +void AccionFileNodeAux_Delete(char *pathOrig,char *pathDest){ + if(File_EsDirectorio(pathDest)){ + File_BorrarDirectorio(pathDest); + }else{ + File_Borrar(pathDest); + } +} +void AccionFileNodeAux_MakeDir(char *pathOrig,char *pathDest){ + File_CrearDir(pathDest); +} + +void AccionFileNode_RunList(AccionFileNode *afn,char *pathIzquierda,char *pathDerecha){ + char pathIzq[MaxPath],pathDer[MaxPath]; + while(afn!=NULL){ + if(afn->izquierda){ + FileNode_GetFullPath(afn->izquierda,pathIzquierda,pathIzq); + }else{ + FileNode_GetFullPath(afn->derecha,pathIzquierda,pathIzq); + } + if(afn->derecha){ + FileNode_GetFullPath(afn->derecha,pathDerecha,pathDer); + }else{ + FileNode_GetFullPath(afn->izquierda,pathDerecha,pathDer); + } + + switch(afn->accion){ + case AccionFileCmp_Nada: + //printf("%s == %s\n",pathIzq,pathDer); + break; + case AccionFileCmp_IzquierdaADerecha: + printf("%s => %s\n",pathIzq,pathDer); + AccionFileNodeAux_Copy(pathIzq,pathDer); + break; + case AccionFileCmp_DerechaAIzquierda: + printf("%s <= %s\n",pathIzq,pathDer); + AccionFileNodeAux_Copy(pathDer,pathIzq); + break; + case AccionFileCmp_BorrarIzquierda: + printf("%s *- %s\n",pathIzq,pathDer); + AccionFileNodeAux_Delete(pathDer,pathIzq); + break; + case AccionFileCmp_BorrarDerecha: + printf("%s -* %s\n",pathIzq,pathDer); + AccionFileNodeAux_Delete(pathIzq,pathDer); + break; + case AccionFileCmp_FechaIzquierdaADerecha: + printf("%s -> %s\n",pathIzq,pathDer); + AccionFileNodeAux_CopyDate(pathIzq,pathDer); + break; + case AccionFileCmp_FechaDerechaAIzquierda: + printf("%s <- %s\n",pathIzq,pathDer); + AccionFileNodeAux_CopyDate(pathDer,pathIzq); + break; + case AccionFileCmp_CrearDirDerecha: + printf("%s -D %s\n",pathIzq,pathDer); + AccionFileNodeAux_MakeDir(pathIzq,pathDer); + break; + case AccionFileCmp_CrearDirIzquierda: + printf("%s D- %s\n",pathIzq,pathDer); + AccionFileNodeAux_MakeDir(pathDer,pathIzq); + break; + } + + afn=afn->sig; + } + printf("End\n"); } diff --git a/filenodecmp.h b/filenodecmp.h index 1affb2e..1e5fb1c 100644 --- a/filenodecmp.h +++ b/filenodecmp.h @@ -11,7 +11,9 @@ typedef enum { AccionFileCmp_BorrarIzquierda, AccionFileCmp_BorrarDerecha, AccionFileCmp_FechaIzquierdaADerecha, - AccionFileCmp_FechaDerechaAIzquierda + AccionFileCmp_FechaDerechaAIzquierda, + AccionFileCmp_CrearDirDerecha, + AccionFileCmp_CrearDirIzquierda } AccionFileCmp; @@ -20,14 +22,20 @@ typedef struct Tag_AccionFileNode { FileNode *izquierda; FileNode *derecha; struct Tag_AccionFileNode *sig; + char motivo[128]; } AccionFileNode; AccionFileNode *AccionFileNode_Crear(); void AccionFileNode_Destruir(AccionFileNode *afn); +AccionFileNode *AccionFileNode_CrearNormal(FileNode *fnIzq,FileNode *fnDer); AccionFileNode *AccionFileNode_Build(FileNode *izquierda,FileNode *derecha); + void AccionFileNode_Print(AccionFileNode *afn); +void AccionFileNode_RunList(AccionFileNode *afn, + char *pathIzquierda,char *pathDerecha); + #endif diff --git a/fileutil.c b/fileutil.c index 7257569..b581c46 100644 --- a/fileutil.c +++ b/fileutil.c @@ -243,13 +243,13 @@ void File_IterateDir(char *path, { int handle; struct _finddata_t fileinfo; - char f_path[512]; + char f_path[MaxPath]; int fin=0; int findnext_rc; - char path_aux[512]; + char path_aux[MaxPath]; char *ptr; - snprintf(path_aux,512, + snprintf(path_aux,MaxPath, "%s/*",path); handle=_findfirst(path_aux,&fileinfo); if(handle==-1) @@ -278,7 +278,7 @@ void File_IterateDir(char *path, { DIR *directorio; struct dirent *entidad_dir; - char f_path[512]; + char f_path[MaxPath]; int fin=0; char *ptr; @@ -295,7 +295,7 @@ void File_IterateDir(char *path, { // A partir de aqui hay un fichero // (o directorio) - snprintf(f_path,512, + snprintf(f_path,MaxPath, "%s/%s",path,entidad_dir->d_name); fin=func(f_path, entidad_dir->d_name, @@ -309,4 +309,48 @@ void File_IterateDir(char *path, +void File_Borrar(char *path){ + unlink(path); +} +void File_BorrarDirectorio(char *path){ + rmdir(path); +} + + +#define MaxBuffer 16384 +int File_Copiar( const char *pathOrig,const char *pathDest){ + FILE *fOrig,*fDest; + char buffer[MaxBuffer]; + int readLen=0; + int writeLen=0; + int ok=0; + + if((fOrig=fopen(pathOrig,"rb"))==NULL){ + return 0; + } + if((fDest=fopen(pathDest,"wb"))==NULL){ + return 0; + } + + do{ + readLen=fread(&buffer,1,MaxBuffer,fOrig); + if(readLen>0){ + writeLen=fwrite(&buffer,1,readLen,fDest); + if(writeLen!=readLen){ + // Error + fclose(fOrig); + fclose(fDest); + return 0; + } + } + }while(readLen==MaxBuffer); + + if(feof(fOrig)){ + ok=1; + } + + fclose(fOrig); + fclose(fDest); + return ok; +} \ No newline at end of file diff --git a/fileutil.h b/fileutil.h index 8437a8c..dce30b3 100644 --- a/fileutil.h +++ b/fileutil.h @@ -15,6 +15,9 @@ void FileTime_Print(FileTime t); /////////////////////////////////////////////// // File +#define MaxPath 4096 +#define MaxFilename 512 + void File_GetName(char *path,char *name); int File_ExistePath(char *path); @@ -30,7 +33,8 @@ int File_CrearDir(char *path); void File_IterateDir(char *path, int (*func)(char *path,char *name,void *data),void *data); - +void File_Borrar(char *path); +void File_BorrarDirectorio(char *path); #endif diff --git a/main.c b/main.c index d21900b..65bb94e 100644 --- a/main.c +++ b/main.c @@ -9,7 +9,7 @@ #include "filenodecmp.h" void help(char *exe){ - char exeFilename[1024]; + char exeFilename[MaxPath]; File_GetName(exe,exeFilename); printf("Modo de uso:\n"); printf("\t%s info [file] {[file] {..}}\n",exeFilename); @@ -20,6 +20,10 @@ void help(char *exe){ printf("\t%s sync [dirIzquierda] [dirDerecha]\n",exeFilename); } + +int sync(char *pathIzquierda,char *pathDerecha,int dryrun); + + int main(int argc,char *argv[]){ FILE *f; unsigned long crc=0; @@ -68,13 +72,13 @@ int main(int argc,char *argv[]){ if(!strcmp(argv[1],"dir") && argc==3){ // Leer informacion de dir char *path=argv[2]; - char dirNodesFile[4092]; + char dirNodesFile[MaxPath]; FileNode *fn; printf("Checking Directory.. %s\n",path); if(File_ExistePath(path) && File_EsDirectorio(path)){ // Get the FileNode from the dir - snprintf(dirNodesFile,4092,"%s/"FileNode_Filename,path); + snprintf(dirNodesFile,MaxPath,"%s/"FileNode_Filename,path); fn=FileNode_Load(dirNodesFile); if(fn){ fn=FileNode_Refresh(fn,path); @@ -88,109 +92,77 @@ int main(int argc,char *argv[]){ } }else if(!strcmp(argv[1],"sync") && argc==4){ - // Leer informacion de dir + // Sincronizar dos directorios char *pathIzquierda=argv[2]; char *pathDerecha=argv[3]; - char dirNodesFileIzq[4092]; - char dirNodesFileDer[4092]; - FileNode *fnIzquierda,*fnDerecha; - - if(!File_ExistePath(pathIzquierda) || !File_EsDirectorio(pathIzquierda)) - { - printf("Error, directory does not exist: %s\n",pathIzquierda); - return 0; - } - if(!File_ExistePath(pathDerecha) || !File_EsDirectorio(pathDerecha)) - { - printf("Error, directory does not exist: %s\n",pathDerecha); - return 0; - } - - // Comprobar directorio izquierdo - printf("Checking Directory.. %s\n",pathIzquierda); - snprintf(dirNodesFileIzq,4092,"%s/"FileNode_Filename,pathIzquierda); - fnIzquierda=FileNode_Load(dirNodesFileIzq); - if(fnIzquierda){ - fnIzquierda=FileNode_Refresh(fnIzquierda,pathIzquierda); - }else{ - fnIzquierda=FileNode_Build(pathIzquierda); - } - - // Comprobar directorui derecho - printf("Checking Directory.. %s\n",pathDerecha); - snprintf(dirNodesFileDer,4092,"%s/"FileNode_Filename,pathDerecha); - fnDerecha=FileNode_Load(dirNodesFileDer); - if(fnDerecha){ - fnDerecha=FileNode_Refresh(fnDerecha,pathDerecha); - }else{ - fnDerecha=FileNode_Build(pathIzquierda); - } - - // Construir acciones - printf("Building action list.. \n"); - AccionFileNode *afn=NULL; - afn=AccionFileNode_Build(fnIzquierda,fnDerecha); - AccionFileNode_Print(afn); + sync(pathIzquierda,pathDerecha,0); + }else + if(!strcmp(argv[1],"synctest") && argc==4){ + // Sincronizar dos directorios + char *pathIzquierda=argv[2]; + char *pathDerecha=argv[3]; + sync(pathIzquierda,pathDerecha,1); }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); -} \ No newline at end of file +} + + +int sync(char *pathIzquierda,char *pathDerecha,int dryrun){ + char dirNodesFileIzq[MaxPath]; + char dirNodesFileDer[MaxPath]; + FileNode *fnIzquierda,*fnDerecha; + + if(!File_ExistePath(pathIzquierda) || !File_EsDirectorio(pathIzquierda)){ + printf("Error, directory does not exist: %s\n",pathIzquierda); + return 0; + } + if(!File_ExistePath(pathDerecha) || !File_EsDirectorio(pathDerecha)){ + printf("Error, directory does not exist: %s\n",pathDerecha); + return 0; + } + + // Comprobar directorio izquierdo + printf("Checking Directory.. %s\n",pathIzquierda); + snprintf(dirNodesFileIzq,MaxPath,"%s/"FileNode_Filename, + pathIzquierda); + fnIzquierda=FileNode_Load(dirNodesFileIzq); + if(fnIzquierda){ + fnIzquierda=FileNode_Refresh(fnIzquierda,pathIzquierda); + }else{ + fnIzquierda=FileNode_Build(pathIzquierda); + } + FileNode_Save(fnIzquierda,dirNodesFileIzq); + + // Comprobar directorui derecho + printf("Checking Directory.. %s\n",pathDerecha); + snprintf(dirNodesFileDer,MaxPath,"%s/"FileNode_Filename, + pathDerecha); + fnDerecha=FileNode_Load(dirNodesFileDer); + if(fnDerecha){ + fnDerecha=FileNode_Refresh(fnDerecha,pathDerecha); + }else{ + fnDerecha=FileNode_Build(pathDerecha); + } + FileNode_Save(fnDerecha,dirNodesFileDer); + + // Construir acciones + printf("Building action list.. \n"); + AccionFileNode *afn=NULL; + afn=AccionFileNode_Build(fnIzquierda,fnDerecha); + + if(dryrun){ + // Mostrar lista de acciones + AccionFileNode_Print(afn); + }else{ + // Ejecutar lista de acciones + AccionFileNode_RunList(afn,pathIzquierda,pathDerecha); + } + + return(1); +} +