sync.c

来自「ftam等标准协议服务器和客户端的源代码。」· C语言 代码 · 共 653 行 · 第 1/2 页

C
653
字号
	    if (rfa == NULL) {		fprintf(err, "found new MASTER sub-directory '%s' at remote\n", 			    rrfa->ri_filename);		if ((rfa = mallocRfaInfo(strdup(rrfa->ri_filename))) == NULL) {		    fprintf(err,"%scant't create local SLAVE for %s ***\n", 				incstr, rrfa->ri_filename);		    return NOTOK_LOCAL_ERROR;		}		if (mkdir(makeFN(fn), rrfa->ri_mode & 07777) == -1) {		    fprintf(err,"*** can't create subdir %s ***\n", 				rrfa->ri_filename);		    return NOTOK_FILEACCESS;		}		SET_STATUS(rfa->ri_status, RI_SLAVE);		SET_LOCKINFO(rfa->ri_status, RI_UNLOCKED);		SET_TRANSFER(rfa->ri_status, RI_TRANSFER(rrfa->ri_status));		time(&(rfa->ri_lastChange));		rfa->ri_modTime = 0L;		rfa->ri_mode = rrfa->ri_mode;		rfa->ri_next = *localRfaListPtr;		*localRfaListPtr = rfa;		changeFileOwner(fn, rrfa);		if (putRfaInfoList(dir, *localRfaListPtr) != OK) {		    fprintf(err,"%scan't set SLAVE status of %s ***\n", incstr, 			    rrfa->ri_filename);		    return NOTOK_FILEACCESS;		}	    } else {  /*--- local rfa found ---*/		if((rfa->ri_mode & S_IFDIR & S_IFMT) == 0) {		    fprintf(err,"%slocal file '%s' conflicts with",incstr,			    rrfa->ri_filename);		    fprintf(err," remote directory ***\n");		    return NOTOK_INCONSISTENCY;		}		if (checkState(rfa, rrfa, dir, wrp) == NOTOK)		    return NOTOK_INCONSISTENCY;	    	    } /* if local rfa exists */    } /* switch rrfa->ri_status */    /*--- now we have a local version of the dir ---*/    if(rec && IS_TR_AUTO(rfa->ri_status))  	if ((rc = syncDir(fn, rec)) != OK)  {	    fprintf(err,"\t*** syncdir for %s failed ***\n", rrfa->ri_filename);	    return rc;	}        return OK;} /*--------------------------------------------------------------*//*  syncDir							*//*--------------------------------------------------------------*/int syncDir (dir, rec)char *dir;    int rec;{    struct RfaInfo *rfa, *localRfaList, *rrfa, *remoteRfaList;    char buf[BUFSIZ];    int writeList, rc;    char *l, *lp;    struct stat st;    int rmode;    char fn[BUFSIZ];    char syncfiles[BUFSIZ*10];    /*--- get file Info ---*/    if ((rc = getRfaInfoList(dir, &localRfaList, (char *)NULL, 1)) != OK)  {	fprintf(err,"\t*** can't get rfainfo : %s ***\n", errMsg(rc));	return(rc);    }    /*--- get remote rfa list ---*/    if ((rc = getRemoteRfaInfoList(dir, &remoteRfaList)) != OK) {	releaseRfaInfoList(dir, localRfaList);	return rc;    }    fprintf(err, "syncing directory %s\n", dir);    *syncfiles = '\0';    /*-- check remote list agaist local one --*/    for(rrfa = remoteRfaList; rrfa; rrfa = rrfa->ri_next) {	writeList = 0;	switch(rrfa->ri_mode & S_IFMT) {	    case S_IFIFO:	    case S_IFCHR:	    case S_IFBLK:	    case S_IFSOCK:		continue;	    case S_IFLNK:		if (rrfa->ri_lnkName == NULL)		    continue;		    		strcpy(buf, makeFN2(dir, rrfa->ri_filename));		if (*(rrfa->ri_lnkName) == '/') 		    lp = l = makeFN(rrfa->ri_lnkName);		else {		    l = rrfa->ri_lnkName;		    lp = makeFN2(dir, rrfa->ri_lnkName);		}		if (stat(lp, &st) == -1)		    continue;		if ((rfa = findRfaInfo(rrfa->ri_filename,localRfaList)) == NULL)		{		    fprintf(err, "\tcreating link %s to %s\n", 			    rrfa->ri_filename, l);		    if(symlink(l, buf) == -1) {			fprintf(err,"\t*** can't create link %s ***\n",buf);			continue;		    }		    continue;		}		if ((rfa->ri_mode & S_IFMT) == S_IFLNK) {		    if(strcmp(rfa->ri_lnkName, l) == 0)			continue;		    unlink(makeFN2(dir, rfa->ri_filename));		    fprintf(err, "\tcreating link %s to %s\n", 			    rrfa->ri_filename, l);		    if(symlink(l, buf) == -1) {			fprintf(err,"\t*** can't create link %s ***\n",buf);			continue;		    }		    continue;		}		fprintf(err,"%slocal file %s conflicts with remote link ***\n",			incstr, buf);		continue;					    case S_IFDIR:		if (handleDir(dir, &localRfaList, rrfa,rec,&writeList) != OK) {		    continue;		}		continue;	    case S_IFREG:		break;	    default:		continue;	}	/*--- rrfa->ri_filename is regular file ---*/	rfa = findRfaInfo(rrfa->ri_filename, localRfaList);	switch (RI_STATUS(rrfa->ri_status)) {	    case RI_UNREGISTERED:		checkState(rfa, rrfa, dir, &writeList);		break;	    case RI_SLAVE:		if (checkState(rfa, rrfa, dir, &writeList) == NOTOK)		    continue;		checkMasterSlave(rfa, rrfa, "local", "remote");		break;	    case RI_MASTER:		if (rfa == NULL) {		    /*--- check if not a .rfaexec file ---*/		    if (strcmp(rrfa->ri_filename, ".rfaexec") == 0) {			fprintf(err,			    "%sremote file '%s' is MASTER, not transfered ***\n"			    ,rfa->ri_filename);			continue;		    }		    fprintf(err, "\tfound new MASTER file '%s' at remote\n", 			    rrfa->ri_filename);		    if ((rfa=mallocRfaInfo(strdup(rrfa->ri_filename)))==NULL) {			fprintf(err,"%scant't create local SLAVE for %s ***\n",				incstr, rrfa->ri_filename);			continue;		    }		    SET_STATUS(rfa->ri_status, RI_SLAVE);		    SET_LOCKINFO(rfa->ri_status, RI_UNLOCKED);		    SET_TRANSFER(rfa->ri_status, RI_TRANSFER(rrfa->ri_status));		    (void)time(&(rfa->ri_lastChange));		    rfa->ri_modTime = 0L;		    rfa->ri_mode = rrfa->ri_mode;		    rfa->ri_next = localRfaList;		    localRfaList = rfa;		    writeList++;		} else {		    if (checkState(rfa, rrfa, dir, &writeList) == NOTOK)			break;;		    checkMasterSlave(rrfa, rfa, "remote", "local");		} /* if local rfa exists */		/*--- now we are ready to get the remote file ---*/		if (writeList && IS_TR_REQ(rfa->ri_status)) {		    if (createEmptyFile(dir, rrfa) == NOTOK) 			continue;		} else 		    if( IS_TR_AUTO(rfa->ri_status) && 			    (rfa->ri_modTime < rrfa->ri_modTime)) 		    {			sprintf(fn, "%s%s%s", dir, 				*(dir+strlen(dir)-1) == '/' ? "" : "/",				rfa->ri_filename);			fprintf(err, "\t%s - ", rrfa->ri_filename);			if ((rc = getfile_aux(fn, rfa, &rmode)) != OK)  			    continue;			strcat(syncfiles, rfa->ri_filename);			strcat(syncfiles, " ");		    } 		break;	    default:		fprintf(err, "%sinvalid state for remote '%s' ***\n",			    incstr, rrfa->ri_filename);		continue;		} /* switch rrfa->ri_status */	/*--- now we have a local slave version of the file ---*/	if (writeList)	    if ((rc = putRfaInfoList(dir, localRfaList)) != OK) {		fprintf(err,"%scan't set SLAVE status of %s ***\n", incstr, 			rfa->ri_filename);		continue;	    }	    } /* for rrfa */    /*-- now check local list against remote list --*/    for(rfa = localRfaList; rfa; rfa = rfa->ri_next) 	if (findRfaInfo(rfa->ri_filename, remoteRfaList) == NULL) {	    checkState(rfa, (struct RfaInfo *)NULL, dir, &writeList);	}    if (writeList)	if ((rc = putRfaInfoList(dir, localRfaList)) != OK) {	    fprintf(err,"%scan't set SLAVE status of %s ***\n", incstr, 		    rfa->ri_filename);	}    (void)releaseRfaInfoList(dir, localRfaList);    freeRfaInfoList(remoteRfaList);    /*-- look for .rfaexec script --*/    return rfaMake(dir, syncfiles);}/*--------------------------------------------------------------*//*  rfaMake							*//*--------------------------------------------------------------*/int rfaMake(dir, fns)    char *dir, *fns;{    struct RfaInfo *rfa, *rrfa, *localRfaList, *remoteRfaList;    char execfn[BUFSIZ];    char buf[BUFSIZ];    struct stat st;    int rc;    /*-- check if files sync'ed --*/    if (*fns == '\0' || doRfaExec == 0)	return OK;    /*-- check if .rfaexec exists --*/    sprintf(execfn, "%s/.rfaexec", dir);    if (lstat(makeFN(execfn),&st) == -1) {        if (errno == ENOENT) 	    return OK;	fprintf(err, "\t*** can't stat %s - %s", execfn,sys_errname(errno));	return NOTOK_LOCAL_ERROR;    }    if (access(makeFN(execfn), X_OK) == -1)  {	fprintf(err,"\t*** can't exec '%s' (%s) ***\n", execfn, 		sys_errname(errno));	return NOTOK_LOCAL_ERROR;    }    /*-- check if dir is locked --*/    if ((rc=getRfaInfoList(dirname(dir),&localRfaList,(char *)NULL,0)) != OK) {	return rc;    }    if (rfa = findRfaInfo(basename(dir),localRfaList)) {	if (IS_MASTER(rfa->ri_status) && IS_LOCKED(rfa->ri_status)) {	    freeRfaInfoList(localRfaList);	    return OK;	}    }    if ((rfa == NULL) || (rfa && !IS_MASTER(rfa->ri_status))) {	freeRfaInfoList(localRfaList);	/*--- get remote rfa list ---*/	if ((rc = getRemoteRfaInfoList(dirname(dir), &remoteRfaList)) != OK) {	    return rc;	}	if ((rrfa = findRfaInfo(basename(dir),remoteRfaList)) == NULL) {	    fprintf(err,"\t*** can't determine status of '%s' ***\n", dir);	    freeRfaInfoList(remoteRfaList);	    return NOTOK_REMOTE_ERROR;	}	if (!IS_MASTER(rrfa->ri_status)) {	    fprintf(err,"\t*** can't find MASTER version of '%s' ***\n", dir);	    freeRfaInfoList(remoteRfaList);	    return NOTOK_REMOTE_ERROR;	}	if (IS_LOCKED(rrfa->ri_status))  {	    freeRfaInfoList(remoteRfaList);	    return OK;	}	freeRfaInfoList(remoteRfaList);    }    /*-- change cwd to sync'ed dir --*/    if (chdir(makeFN(dir)) == -1) {	fprintf(err,"\t*** can't change dir to '%s' (%s) ***\n", dir,		sys_errname(errno));	return NOTOK_LOCAL_ERROR;    }    /*-- so we are able to exec .rfaexec --*/    fprintf(err,"\texecuting '%s'...\n", execfn);    sprintf(buf, "%s %s", makeFN(execfn), fns);    if (system(buf) == -1)	return NOTOK_LOCAL_ERROR;    return OK;}		    

⌨️ 快捷键说明

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