#include #include #include #include #include #include #include #include "projet.h" #include "projetx.m" /* Ouvre un fichier pour remplacer temporairement un handle d‚j… ouvert (g‚n‚ralement 0,1, ou 2 pour stdin, stdout ou stderr) Retourne une copie du handle … remplacer. */ int rcs_opendup ( const char *fname, // Si == NULL, fait rien et retourne -1 int mode, // Mode d'ouverture du fichier int remplace, // Handle … remplacer // La fonction retourner une duplication de ce handle const char *msgerr) // Message d'erreur { int ret = -1; if (fname != NULL){ int handle = open (fname,mode,S_IREAD|S_IWRITE); if (handle == -1){ xconf_error (msgerr,fname); }else{ int curhandle = dup(remplace); if (curhandle == -1){ xconf_error (MSG_U(E_CANTDUP ,"Ne peut pas duplicater le handle %d") ,remplace); }else{ if (dup2(handle,remplace) == -1){ xconf_error (MSG_U(E_CANTDUP2 ,"Ne peut pas duplicater le handle %d -> %d") ,handle,remplace); }else{ ret = curhandle; } close (handle); } } } return ret; } /* Ferme le fichier ouvert par rcs_opendup() et replace les handle comme avant. Si opendup_ret == -1, fait rien. */ int rcs_closedup (int opendup_ret, int remplace) { int ret = 0; if (opendup_ret != -1){ close (remplace); ret = dup2 (opendup_ret,remplace); close (opendup_ret); } return ret; } /* D‚coupe une commande en mot et ex‚cute via spawn. Retourne -1 si code de retour != 0. */ int rcs_system (const char *buf) { int ret = 0; #ifdef MSDOS // On utilise system() au lieu de spawnvp pour des raisons // mysterieuse. Dans l'environnement DV/X, spawn faisait // perdre la communicaton avec le serveur X. // C'etait d'autant plus myst‚rieux que ca se produisait // lors de l'op‚ration diff du dialogue de fusion (rcs_vdiff()). // Par contre MAKEFILE::unzip fonctionnait tres bien. if (system (buf) != 0) ret = -1; #elif 0 char lbuf[500]; strcpy (lbuf,buf); char *ptbuf = lbuf; const char *arg[50]; int noarg = 0; while (1){ while (isspace(*ptbuf)) ptbuf++; if (*ptbuf == '\0') break; arg[noarg++] = ptbuf; while (!isspace(*ptbuf) && *ptbuf != '\0') ptbuf++; if (isspace(*ptbuf)) *ptbuf++ = '\0'; } arg[noarg] = NULL; if (spawnvp(P_WAIT,arg[0],arg)!= 0){ ret = -1; xconf_error (MSG_U(E_SPAWN ,"Ne peut exécuter correctement la commande\n" "%s\n(%s:%s)") ,buf,strerror(errno),arg[0]); } #else system (buf); #endif return ret; } /* Ex‚cution d'un commande avec red‚finition optionnelle des trois fichiers standard. Chacun des std_xxx peut ˆtre soit un fichier ou NULL. */ int rcs_system ( const char *std_in, const char *std_out, // Fichier qui contiendra stdout ou NULL const char *std_err, // Fichier qui contiendra stderr ou NULL // std_err peut ˆtre le mˆme que std_out const char *buf) // Commande … ex‚cuter { //if (is_os2()) return os2_system(std_in, std_out, std_err, buf); int oldstdin = rcs_opendup (std_in,O_RDONLY,0 ,MSG_U(E_RCSINPUT,"Ne peut rediriger input <- %s")); int oldstdout = rcs_opendup (std_out,O_CREAT|O_RDWR|O_TRUNC,1 ,MSG_U(E_RCSOUTPUT,"Ne peut rediriger output -> %s")); int oldstderr; if (std_out != NULL && std_err != NULL && strcmp(std_out,std_err)==0){ oldstderr = dup(2); dup2(1,2); }else{ oldstderr = rcs_opendup (std_err,O_CREAT|O_RDWR|O_TRUNC,2 ,MSG_U(E_RCSERR ,"Ne peut pas ouvrir le fichier\n" "de redirection d'erreur.")); } int ret = rcs_system (buf); rcs_closedup (oldstdin,0); rcs_closedup (oldstdout,1); rcs_closedup (oldstderr,2); return ret; } /* Commande l'extraction d'un fichier du pack.zip. */ int rcs_unzip ( const USERINFO *user, const char *wpath, // Path du projet dans /kit/ombre const char *sdir, // Sous-r‚pertoire r‚vision (_1_1_2_1.s) const char *fichier) { int ret = -1; SAVEPATH save; if (path_pushdir(user,wpath,&save)!=-1){ if (file_exist("pack.zip")){ char cmd[MAXSIZ_PATH]; sprintf (cmd,"unzip pack %s/%s",sdir,fichier); char tmpf[MAXSIZ_PATH]; path_tmpname (NULL,"$ex",tmpf,MAXSIZ_PATH); ret = rcs_system(NULL,tmpf,tmpf,cmd); if (ret == -1){ /* #Sp‚cification: archivage / extraction / unzip Si un erreur survient durant l'op‚ration unzip d'un fichier, les messages produits par unzip sont ajout‚s au fichier error.log */ FILE *fout = log_fopen("error.log",1); if (fout != NULL){ FILE *fin = fopen_err (tmpf,"r",0); if (fin != NULL){ char buf[300]; while (fgets(buf,sizeof(buf)-1,fin)!=NULL){ fputs (buf,fout); } fclose (fin); } fclose (fout); } } file_unlink (tmpf); }else{ user->logerr ("Pas de pack.zip %s pour %s/%s\n",wpath ,sdir,fichier); xconf_error (MSG_U(E_NOPACKZIP ,"Fichier pack.zip manquant dans le répertoire\n" "%s\n" "Ne peut extraire %s/%s") ,wpath,sdir,fichier); } path_popdir(&save); } return ret; }