#include #include #include #include #include #include "projet.h" #include "projetx.m" static PROJET_LOG *foper_log = NULL; // Collecte ou affiche ou les deux // les op‚rations de copie. /* Enregistre objet pour g‚n‚rer message … l'‚cran. */ void foper_setlog( PROJET_LOG *log) // Enregistre les commandes dans un log // Peut ˆtre NULL. { foper_log = log; } /* Ajoute un message au log */ void foper_logprintf (const char *ctl, ...) { if (foper_log != NULL){ va_list list; va_start (list,ctl); foper_log->vprintf (ctl,list); va_end (list); } } /* Ex‚cute une copie de fichier avec gestion du log. Retourne -1 si erreur. */ static int near foper_copyp ( const char *src, const char *dst) // Path destination (r‚pertoire) { char cwd[MAXSIZ_PATH]; path_getcwd(cwd,sizeof(cwd)); if (foper_log != NULL){ foper_log->printf ("%s # copy %s %s\n",cwd,src,dst); } int ret = -1; // S'assure que le r‚pertoire destination existe, sinon cr‚ation. if (file_type(dst) == 1 || file_mkdiranc(dst) != -1){ char path[MAXSIZ_PATH]; path_make (dst,src,path); if (file_type (src)==3){ // Lien symbolique char tmp[PATH_MAX]; int len = readlink(src,tmp,sizeof(tmp)-1); if (len!=-1){ tmp[len] = '\0'; char filedst[PATH_MAX]; path_make (dst,src,filedst); ret = symlink (tmp,filedst); } }else{ ret = file_copyp (src,path); } if (ret == -1){ if (foper_log != NULL){ foper_log->printf (" **** Erreur copy errno=%s\n" ,strerror(errno)); } xconf_error (MSG_U(E_COPY ,"Copie incomplète\n%s/%s -> %s\n") ,cwd,src,path); } }else{ if (foper_log != NULL){ foper_log->printf (" **** Erreur cr‚ation %s errno=%d\n" ,dst,strerror(errno)); } xconf_error (MSG_U(E_DIRCREATE ,"Ne peut pas créer le répertoire\n%s") ,dst); } return ret; } /* Enregistre une r‚vision d'un fichier dans l'archive (/kit/ombre). Le fichier est dans le r‚pertoire courant. Retourne -1 si erreur. */ int foper_archive ( const char *nom, const char *projet, const REVISION *rev, const USERINFO *user) { char path[MAXSIZ_PATH]; user->makombpath(projet,path); char revstr[MAXSIZ_PATH]; rev->formatpath (revstr); strcat (revstr,".s"); path_make (path,revstr,path); return foper_copyp (nom,path); } /* Enregistre une r‚vision d'un fichier dans le backup de livraison (/kit/livre). Le fichier est dans le r‚pertoire courant. Retourne -1 si erreur. */ int foper_backup ( const char *nom, const char *projet, REVISION *rev, const USERINFO *user) { char path[MAXSIZ_PATH]; char revstr[MAXSIZ_REVISION+1]; rev->formatpath (revstr); user->maklivpath(revstr,path); path_make (path,projet,path); return foper_copyp (nom,path); } int foper_compare (const char *f1, const char *f2) { int ret = -1; char path1[PATH_MAX],path2[PATH_MAX]; int len1 = readlink (f1,path1,sizeof(path1)-1); int len2 = readlink (f2,path2,sizeof(path2)-1); if (len1 != -1 || len2 != -1){ // Un des deux est un lien symbolique, comparons if (len2 == len1){ ret = memcmp(path1,path2,len1); } }else{ struct stat st1,st2; if (stat(f1,&st1)!=-1 && stat(f2,&st2)!=-1 && st1.st_size == st2.st_size){ // Même grandeur, ca vaut la peine de comparer FILE *fin1 = fopen (f1,"r"); if (fin1 != NULL){ FILE *fin2 = fopen (f2,"r"); if (fin2 != NULL){ ret = 0; while (1){ char buf1[4096],buf2[4096]; int n1 = fread (buf1,1,sizeof(buf1),fin1); int n2 = fread (buf2,1,sizeof(buf1),fin2); if (n1 != n2){ ret = -1; break; }else if (n1 <= 0){ break; }else if (memcmp(buf1,buf2,n1)!=0){ ret = -1; break; } } fclose (fin2); } fclose (fin1); } } } return ret; }