⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 g_update.c

📁 Non-Networked File System在几个非网络的(或慢网络的)Unix 计算机上提供了一个兼容的文件系统。
💻 C
字号:
/*    NNFS: Non-Networked File System. *    Copyright (C) 1995-2001  Thierry EXCOFFIER (exco@ligim.univ-lyon1.fr) * *    This program is free software; you can redistribute it and/or modify *    it under the terms of the GNU General Public License as published by *    the Free Software Foundation; either version 2 of the License, or *    (at your option) any later version. * *    This program is distributed in the hope that it will be useful, *    but WITHOUT ANY WARRANTY; without even the implied warranty of *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *    GNU General Public License for more details. * *    You should have received a copy of the GNU General Public License *    along with this program; if not, write to the Free Software *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */#include "g_const.h"#include "g_update.h"#include "g_debug.h"#include "g_malloc.h"#include "g_dspbar.h"#include "g_filter.h"#include "g_tree.h"/* * */char *g_Type_To_String(g_Type_Of_File t){  switch( t )    {    case g_Is_A_File       : return( "Reg. file" ) ;    case g_Is_A_Link       : return( "Sym. link" ) ;    case g_Is_A_Directory  : return( "Directory" ) ;    case g_Is_A_FIFO       : return( "FIFO     " ) ;    case g_Is_A_Deleted    : return( "Deleted  " ) ;    case g_Is_Any          : return( "Any      " ) ;    case g_Is_Not_Supported: return( "Unknown  " ) ;    }  return( "Bug in " __FILE__ ) ;}/* * */g_Type_Of_File g_String_To_Type(const char *s){  if ( strcmp("Reg. file",s) == 0 ) return(g_Is_A_File       ) ;  if ( strcmp("Sym. link",s) == 0 ) return(g_Is_A_Link       ) ;  if ( strcmp("FIFO     ",s) == 0 ) return(g_Is_A_FIFO       ) ;  if ( strcmp("Directory",s) == 0 ) return(g_Is_A_Directory  ) ;  if ( strcmp("Deleted  ",s) == 0 ) return(g_Is_A_Deleted    ) ;  if ( strcmp("Any      ",s) == 0 ) return(g_Is_Any          ) ;  if ( strcmp("Unknown  ",s) == 0 ) return(g_Is_Not_Supported) ; abort() ; return(g_Is_Any) ;}/* * Display debug information on NNFS file */void g_Display_Nnfs_File(const g_File_On_Host *f){  g_Printf("date=") ;  switch( f->date )    {    case G_DATE_DELETED_FILE: g_Printf("Del.file") ; break ;    case G_DATE_FILTRED_FILE: g_Printf("Fil.file") ; break ;    default                 : g_Printf("%8lx", f->date) ; break ;    }  g_Printf(" size=%8lx", f->size) ;#ifdef ROOTNNFS  g_Printf(" uid=%d gid=%d", f->uid, f->gid) ;#endif  g_Printf(" mode=%05o type=%s UpToDate=%d histo=%d\n",	   f->mode,	   g_Type_To_String((g_Type_Of_File)f->type),	   f->up_to_date,	   f->to_historize) ;}/* * */void g_Display_File_Info(g_NNFS *nnfs, g_File_Info *a){  int i ;  g_Printf("%s "             , nnfs->state.name) ;  if ( a->nnfs_to_local ) g_Printf("nnfs2local ") ;  if ( a->local_to_nnfs ) g_Printf("local2nnfs ") ;  if ( a->on_medium     ) g_Printf("onMedium ") ;  if ( a->local_change  ) g_Printf("localChange ") ;  if ( a->nnfs_change   ) g_Printf("nnfsChange ") ;  if ( a->to_delete     ) g_Printf("toDelete ") ;  if ( a->read_error    ) g_Printf("readErr=%d ", a->read_error) ;  if ( a->write_error   ) g_Printf("writeErr=%d ", a->write_error) ;  if ( a->need_time_stamp) g_Printf("needTimerStamp ") ;  if ( a->read_file_info) g_Printf("readFileInfo ") ;  if ( a->update_nnfs   ) g_Printf("updateNnfs ") ;  if ( a->conflict      ) g_Printf("conflict ") ;  if ( a->error         ) g_Printf("error=%d ", a->error) ;  if ( a->to_historize  ) g_Printf("toHistorize ") ;  if ( a->nb_children   ) g_Printf("nb_children=%d ", a->nb_children) ;  g_Printf("up_to_date=%d ", a->up_to_date) ;  g_Printf("up_to_date_on_medium=%d ", a->up_to_date_on_medium) ;  if ( a->filtered  ) g_Printf("filtered ") ;  if ( a->nnfs_filtered  ) g_Printf("nnfs_filtered ") ;  if ( a->nnfs_error  ) g_Printf("nnfs_error ") ;  if ( a->nnfs_to_local_child ) g_Printf("nnfs2localChild ") ;  g_Printf("\n") ;  for(i=0;i<=nnfs->header.nb_fs;i++)	{	g_Printf("%c%c%c%d ",		 i==nnfs->header.fs_id ? 'C' : ' ',		 i==a->up_to_date ? 'U' : ' ',		 i==a->up_to_date_on_medium ? 'M' : ' ',		 i) ;	g_Display_Nnfs_File(&a->hosts[i]) ;	}  g_Printf("\n") ;}/* * This function is only called * when we add an host. * Otherwise, local always lost conflicts */void G_FUNCTION(g_Local_Win_Conflict,		(g_NNFS *nnfs, g_File_Info *f))int i ;f->conflict = g_True ;f->hosts[nnfs->header.fs_id].up_to_date = g_True ;for(i=0;i<nnfs->header.nb_fs;i++)    if ( i != nnfs->header.fs_id )	{	f->hosts[i].up_to_date = g_False ;	f->hosts[i].to_historize = g_True ;	}f->up_to_date = nnfs->header.fs_id ; /* 05/08/97 *//* f->local_change = g_True ; */ /* 21/4/98 */G_RETURN(;) ;}/* * */void G_FUNCTION(g_Local_Lost_Conflict,		(g_NNFS *nnfs, g_File_Info *f))f->conflict = g_True ;f->hosts[nnfs->header.fs_id].to_historize = g_True ;f->local_change = g_False ;G_RETURN(;) ;}void G_FUNCTION(g_Mark_As_Deleted,		(g_NNFS *nnfs, g_File_Info *f))f->conflict = g_True ;f->to_delete = g_True ;f->to_historize = g_True ;f->local_to_nnfs = g_False ;f->local_change = g_False ;f->hosts[nnfs->header.fs_id].to_historize = g_True ;f->hosts[nnfs->header.fs_id].type = g_Is_A_Deleted ; f->hosts[nnfs->header.fs_id].date = G_DATE_DELETED_FILE ;f->hosts[nnfs->header.fs_id].size = 0 ;f->hosts[nnfs->header.fs_id].mode = 0 ;f->hosts[nnfs->header.fs_id].up_to_date = g_True ;G_RETURN(;) ;}/* * */g_Boolean g_Info_Different(g_File_On_Host *a, g_File_On_Host *b){return( (g_Boolean)( a->type != b->type     || a->mode != b->mode     || a->size != b->size     || a->date != b->date#ifdef ROOTNNFS     || a->uid  != b->uid     || a->gid  != b->gid#endif      ) ) ;}/* * */g_Boolean G_FUNCTION(g_Change_In_Child,(g_File_Info *f))int i ;for(i=0;i<f->nb_children;i++) if (f->children[i]->local_change) /* 22/4/98 was local_to_nnfs */	G_RETURN(g_True) ;G_RETURN(g_False) ;}/* * */void G_FUNCTION( g_Update, (g_NNFS *nnfs, g_File_Info *f) )g_File_On_Host *last,*local ;g_File_Info *tmp ;int i ;g_Boolean nnfs2local ;g_Display_Bar() ;G_PF("%s\n",nnfs->state.name);last    = &f->hosts[nnfs->header.fs_id] ;	   /* Last local mount */local   = &f->hosts[nnfs->header.nb_fs] ;/* * For test38 */for(i=0;i<f->nb_children;i++)     if (f->children[i]->nnfs_to_local_child)       {          f->nnfs_to_local_child = g_True ;          break ;       }/* * For test39 */for(i=0;i<f->nb_children;i++)     if (f->children[i]->local_to_nnfs_child)       {          f->local_to_nnfs_child = g_True ;          break ;       }/* * */if ( last->up_to_date ) f->nnfs_filtered = g_False ; /* COMPLEX *//*  * Compute "up_to_date" */for(i=0;i<nnfs->header.nb_fs;i++) if ( f->hosts[i].up_to_date ) break ;f->up_to_date_on_medium = i ;f->up_to_date = i ;/* * case of local file or -add */if ( i == nnfs->header.nb_fs )	{	G_PF("File is only local\n") ;	/* File is only local, and so it is up to date */	if ( local->date == G_DATE_DELETED_FILE )		{		G_PRINTF("%s\n", nnfs->state.name) ;		g_Display_File_Info(nnfs,f) ;		G_EXIT(1) ;		}        f->hosts[i].up_to_date = g_True ;	*last = *local ;	f->up_to_date = nnfs->header.fs_id ; /* 05/08/97 */	if ( !nnfs->options.add )		f->local_change = g_True ; /* 14/09/97 */	}else   {   if ( nnfs->options.add )	{	*last = *local ;	if ( last->type != g_Is_A_Deleted )            {	    if ( g_Info_Different(last, &f->hosts[f->up_to_date] ) )		{		if ( last->type == g_Is_A_Directory		     && f->hosts[f->up_to_date].type != g_Is_A_Directory )			g_Local_Win_Conflict(nnfs,f) ;		else		if ( last->type != g_Is_A_Directory		     && f->hosts[f->up_to_date].type == g_Is_A_Directory )			{			f->on_medium = g_True ;			g_Local_Lost_Conflict(nnfs,f) ;			}		else                   {		   if ( last->date >= f->hosts[f->up_to_date].date )			g_Local_Win_Conflict(nnfs,f) ;		   else			g_Local_Lost_Conflict(nnfs,f) ;		   if ( last->type == g_Is_A_Directory		     && f->hosts[f->up_to_date].type == g_Is_A_Directory )                        f->conflict = g_False ;                   }		}	      else		last->up_to_date = g_True ;           }	}   f->local_change = g_Info_Different(last, local )                       /* 21/4/1998 */ || g_Change_In_Child(f) ;   /*    * Solve test38 problems: Transform a file into a directory    * if this directory contains files that needs to be updated    * in the local host.    */   if ( f->local_change        && local->type != g_Is_A_Directory        && f->nnfs_to_local_child     )        {            G_PF("test38 bug correction\n") ;            f->nnfs_to_local = g_True ;            g_Local_Lost_Conflict(nnfs,f) ;        }   }/* * */f->nnfs_change  = !last->up_to_date ;if ( nnfs->header.nb_fs == 1 )	f->nnfs_change = g_False ;/* * In fact, nnfs_change is False only if filtered, not if errors */if ( f->nnfs_filtered )	f->nnfs_change = g_False ;/* * The file need to be copied on local host ? */if ( f->nnfs_change )   {   if ( f->local_change /* || g_Change_In_Child(f) */ ) /* 21/4/1998 Add ||CIC */	{	if ( local->type == last->type &&	     last->type == g_Is_A_Directory &&	     f->hosts[f->up_to_date].type == g_Is_A_Directory		)		{   		f->nnfs_to_local = g_True ;		f->local_change = g_False ;		}	else		{		  /* 02/11/2001 Added the "if" "else" so the local		   * can win the conflict		   */			 		  if ( f->on_medium )		    {			   g_Local_Lost_Conflict(nnfs,f) ;   			   f->nnfs_to_local = g_True ;		    }		  else		    {			   g_Local_Win_Conflict(nnfs,f) ;		    }		}	}   else   		f->nnfs_to_local = g_True ;   }/* * */if (    f->nnfs_to_local     && (    f->hosts[f->up_to_date].type == g_Is_A_Deleted          || (    f->hosts[f->up_to_date].type != g_Is_A_Directory               && local->type == g_Is_A_Directory             )        )   )   {	f->to_delete = g_True ;        /*	 * Solve test39 test40 problem: A remote file change conflict	 * with a local directory with the same name, but the local 	 * directory contains changed files.	 * Theses changed files must be not considered up to date.	 */        if ( f->local_to_nnfs_child )              {                  int size ;                  G_PF("Correct test39 behavior\n") ;                  tmp = g_Init_File_Info(nnfs->header.nb_fs) ;                  size = sizeof(*tmp) + nnfs->header.nb_fs * sizeof(g_File_On_Host) ;                  memcpy(tmp, f, size) ;                  g_Tree_Travel1(nnfs, f, NULL, g_Mark_As_Deleted) ;                  memcpy(f, tmp, size) ;                  g_Free(tmp) ;              }   }/* * Not very clean.... */nnfs2local = (g_Boolean)f->nnfs_to_local ;if ( f->nnfs_to_local && f->nnfs_error&& f->hosts[f->up_to_date].type != g_Is_A_Directory /* added 16/07/2001 */     )   {      f->read_error = g_Error_Because_Nnfs_Error ;      f->nnfs_to_local = g_False ;   }/* * Important */if (    f->hosts[f->up_to_date].type != g_Is_A_Directory      && !f->on_medium )	f->nnfs_to_local = g_False ;/* * Is the file needed elsewhere ? */   f->local_to_nnfs = f->local_change ;   if ( !f->local_to_nnfs )	for(i=0;i<nnfs->header.nb_fs;i++)	   {	   if ( i == nnfs->header.fs_id )		continue ;	   if ( !f->hosts[i].up_to_date )		{		f->local_to_nnfs = g_True ;		break ;		}	   }/* * Case raised by read error the previous nnfs run */   if ( last->up_to_date==g_False && f->nnfs_to_local==g_False &&	!f->local_change )	f->local_to_nnfs = g_False ;f->to_historize = last->to_historize ;if ( nnfs->config.historize )        f->to_historize |= f->nnfs_to_local ;/* * For test38 */if ( nnfs2local && f->hosts[f->up_to_date].type != g_Is_A_Deleted )     f->nnfs_to_local_child = g_True ;/* * For test39 */if ( f->local_to_nnfs &&  local->type != g_Is_A_Deleted )     f->local_to_nnfs_child = g_True ;G_RETURN(;) ;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -