/*** Copyright (c), The Regents of the University of California *** *** For more information please refer to files in the COPYRIGHT directory ***/ #ifndef windows_platform #include #endif #include "rodsPath.h" #include "rodsErrorTable.h" #include "rodsLog.h" #include "miscUtil.h" #include "cpUtil.h" int cpUtil (rcComm_t *conn, rodsEnv *myRodsEnv, rodsArguments_t *myRodsArgs, rodsPathInp_t *rodsPathInp) { int i; int status; int savedStatus = 0; rodsPath_t *targPath; dataObjCopyInp_t dataObjCopyInp; rodsRestart_t rodsRestart; if (rodsPathInp == NULL) { return (USER__NULL_INPUT_ERR); } status = resolveRodsTarget (conn, myRodsEnv, rodsPathInp, 1); if (status < 0) { rodsLogError (LOG_ERROR, status, "cpUtil: resolveRodsTarget error, status = %d", status); return (status); } initCondForCp (myRodsEnv, myRodsArgs, &dataObjCopyInp, &rodsRestart); /* initialize the progress struct */ if (gGuiProgressCB != NULL) { bzero (&conn->operProgress, sizeof (conn->operProgress)); for (i = 0; i < rodsPathInp->numSrc; i++) { targPath = &rodsPathInp->targPath[i]; if (targPath->objType == DATA_OBJ_T) { conn->operProgress.totalNumFiles++; if (rodsPathInp->srcPath[i].size > 0) { conn->operProgress.totalFileSize += rodsPathInp->srcPath[i].size; } } else { getCollSizeForProgStat (conn, rodsPathInp->srcPath[i].outPath, &conn->operProgress); } } } for (i = 0; i < rodsPathInp->numSrc; i++) { targPath = &rodsPathInp->targPath[i]; if (rodsPathInp->srcPath[i].rodsObjStat != NULL && rodsPathInp->srcPath[i].rodsObjStat->specColl != NULL) { dataObjCopyInp.srcDataObjInp.specColl = rodsPathInp->srcPath[i].rodsObjStat->specColl; } if (targPath->objType == DATA_OBJ_T) { rmKeyVal (&dataObjCopyInp.srcDataObjInp.condInput, TRANSLATED_PATH_KW); status = cpFileUtil (conn, rodsPathInp->srcPath[i].outPath, targPath->outPath, rodsPathInp->srcPath[i].size, myRodsEnv, myRodsArgs, &dataObjCopyInp); } else if (targPath->objType == COLL_OBJ_T) { setStateForRestart (conn, &rodsRestart, targPath, myRodsArgs); /* The path given by collEnt.collName from rclReadCollection * has already been translated */ addKeyVal (&dataObjCopyInp.srcDataObjInp.condInput, TRANSLATED_PATH_KW, ""); status = cpCollUtil (conn, rodsPathInp->srcPath[i].outPath, targPath->outPath, myRodsEnv, myRodsArgs, &dataObjCopyInp, &rodsRestart); if (rodsRestart.fd > 0 && status < 0) { close (rodsRestart.fd); return (status); } if (dataObjCopyInp.srcDataObjInp.specColl != NULL && dataObjCopyInp.srcDataObjInp.specColl->collClass == STRUCT_FILE_COLL) { dataObjCopyInp.srcDataObjInp.specColl = NULL; status = cpCollUtil (conn, rodsPathInp->srcPath[i].outPath, targPath->outPath, myRodsEnv, myRodsArgs, &dataObjCopyInp, &rodsRestart); } } else { /* should not be here */ rodsLog (LOG_ERROR, "cpUtil: invalid cp dest objType %d for %s", targPath->objType, targPath->outPath); return (USER_INPUT_PATH_ERR); } /* XXXX may need to return a global status */ if (status < 0) { rodsLogError (LOG_ERROR, status, "cpUtil: cp error for %s, status = %d", targPath->outPath, status); savedStatus = status; } } if (rodsRestart.fd > 0) { close (rodsRestart.fd); } if (savedStatus < 0) { return (savedStatus); } else if (status == CAT_NO_ROWS_FOUND || status == SYS_SPEC_COLL_OBJ_NOT_EXIST) { return (0); } else { return (status); } } int cpFileUtil (rcComm_t *conn, char *srcPath, char *targPath, rodsLong_t srcSize, rodsEnv *myRodsEnv, rodsArguments_t *rodsArgs, dataObjCopyInp_t *dataObjCopyInp) { int status; struct timeval startTime, endTime; if (srcPath == NULL || targPath == NULL) { rodsLog (LOG_ERROR, "cpFileUtil: NULL srcPath or targPath incp"); return (USER__NULL_INPUT_ERR); } if (rodsArgs->verbose == True) { (void) gettimeofday(&startTime, (struct timezone *)0); } if (gGuiProgressCB != NULL) { rstrcpy (conn->operProgress.curFileName, srcPath, MAX_NAME_LEN); conn->operProgress.curFileSize = srcSize; conn->operProgress.curFileSizeDone = 0; conn->operProgress.flag = 0; gGuiProgressCB (&conn->operProgress); } rstrcpy (dataObjCopyInp->destDataObjInp.objPath, targPath, MAX_NAME_LEN); rstrcpy (dataObjCopyInp->srcDataObjInp.objPath, srcPath, MAX_NAME_LEN); #if 0 dataObjCopyInp->srcDataObjInp.dataSize = srcSize; #endif dataObjCopyInp->srcDataObjInp.dataSize = -1; status = rcDataObjCopy (conn, dataObjCopyInp); if (status >= 0) { if (rodsArgs->verbose == True) { (void) gettimeofday(&endTime, (struct timezone *)0); printTiming (conn, dataObjCopyInp->destDataObjInp.objPath, conn->transStat.bytesWritten, NULL, &startTime, &endTime); } if (gGuiProgressCB != NULL) { conn->operProgress.totalNumFilesDone++; conn->operProgress.totalFileSizeDone += srcSize; } } return (status); } int initCondForCp (rodsEnv *myRodsEnv, rodsArguments_t *rodsArgs, dataObjCopyInp_t *dataObjCopyInp, rodsRestart_t *rodsRestart) { #ifdef RBUDP_TRANSFER char *tmpStr; #endif /* RBUDP_TRANSFER */ if (dataObjCopyInp == NULL) { rodsLog (LOG_ERROR, "initCondForCp: NULL dataObjCopyInp incp"); return (USER__NULL_INPUT_ERR); } memset (dataObjCopyInp, 0, sizeof (dataObjCopyInp_t)); if (rodsArgs == NULL) { return (0); } if (rodsArgs->dataType == True) { if (rodsArgs->dataTypeString != NULL) { addKeyVal (&dataObjCopyInp->destDataObjInp.condInput, DATA_TYPE_KW, rodsArgs->dataTypeString); } } if (rodsArgs->force == True) { addKeyVal (&dataObjCopyInp->destDataObjInp.condInput, FORCE_FLAG_KW, ""); } if (rodsArgs->checksum == True) { addKeyVal (&dataObjCopyInp->destDataObjInp.condInput, REG_CHKSUM_KW, ""); } if (rodsArgs->verifyChecksum == True) { addKeyVal (&dataObjCopyInp->destDataObjInp.condInput, VERIFY_CHKSUM_KW, ""); } if (rodsArgs->number == True) { if (rodsArgs->numberValue == 0) { dataObjCopyInp->destDataObjInp.numThreads = NO_THREADING; } else { dataObjCopyInp->destDataObjInp.numThreads = rodsArgs->numberValue; } } if (rodsArgs->physicalPath == True) { if (rodsArgs->physicalPathString == NULL) { rodsLog (LOG_ERROR, "initCondForCp: NULL physicalPathString error"); return (USER__NULL_INPUT_ERR); } else { addKeyVal (&dataObjCopyInp->destDataObjInp.condInput, FILE_PATH_KW, rodsArgs->physicalPathString); } } if (rodsArgs->resource == True) { if (rodsArgs->resourceString == NULL) { rodsLog (LOG_ERROR, "initCondForCp: NULL resourceString error"); return (USER__NULL_INPUT_ERR); } else { addKeyVal (&dataObjCopyInp->destDataObjInp.condInput, DEST_RESC_NAME_KW, rodsArgs->resourceString); } } else if (myRodsEnv != NULL && strlen (myRodsEnv->rodsDefResource) > 0) { addKeyVal (&dataObjCopyInp->destDataObjInp.condInput, DEST_RESC_NAME_KW, myRodsEnv->rodsDefResource); } #ifdef RBUDP_TRANSFER if (rodsArgs->rbudp == True) { /* use -Q for rbudp transfer */ addKeyVal (&dataObjCopyInp->destDataObjInp.condInput, RBUDP_TRANSFER_KW, ""); addKeyVal (&dataObjCopyInp->srcDataObjInp.condInput, RBUDP_TRANSFER_KW, ""); } if (rodsArgs->veryVerbose == True) { addKeyVal (&dataObjCopyInp->destDataObjInp.condInput, VERY_VERBOSE_KW, ""); addKeyVal (&dataObjCopyInp->srcDataObjInp.condInput, VERY_VERBOSE_KW, ""); } if ((tmpStr = getenv (RBUDP_SEND_RATE_KW)) != NULL) { addKeyVal (&dataObjCopyInp->destDataObjInp.condInput, RBUDP_SEND_RATE_KW, tmpStr); addKeyVal (&dataObjCopyInp->srcDataObjInp.condInput, RBUDP_SEND_RATE_KW, tmpStr); } if ((tmpStr = getenv (RBUDP_PACK_SIZE_KW)) != NULL) { addKeyVal (&dataObjCopyInp->destDataObjInp.condInput, RBUDP_PACK_SIZE_KW, tmpStr); addKeyVal (&dataObjCopyInp->srcDataObjInp.condInput, RBUDP_PACK_SIZE_KW, tmpStr); } #else /* RBUDP_TRANSFER */ if (rodsArgs->rbudp == True) { rodsLog (LOG_NOTICE, "initCondForCp: RBUDP_TRANSFER (-d) not supported"); } #endif /* RBUDP_TRANSFER */ memset (rodsRestart, 0, sizeof (rodsRestart_t)); if (rodsArgs->restart == True) { int status; status = openRestartFile (rodsArgs->restartFileString, rodsRestart, rodsArgs); if (status < 0) { rodsLogError (LOG_ERROR, status, "initCondForCp: openRestartFile of %s errno", rodsArgs->restartFileString); return (status); } } dataObjCopyInp->destDataObjInp.createMode = 0700; dataObjCopyInp->destDataObjInp.openFlags = O_WRONLY; return (0); } int cpCollUtil (rcComm_t *conn, char *srcColl, char *targColl, rodsEnv *myRodsEnv, rodsArguments_t *rodsArgs, dataObjCopyInp_t *dataObjCopyInp, rodsRestart_t *rodsRestart) { int status = 0; int savedStatus = 0; #if 0 int collLen; #else char parPath[MAX_NAME_LEN], childPath[MAX_NAME_LEN]; #endif collHandle_t collHandle; collEnt_t collEnt; char srcChildPath[MAX_NAME_LEN], targChildPath[MAX_NAME_LEN]; dataObjCopyInp_t childDataObjCopyInp; if (srcColl == NULL || targColl == NULL) { rodsLog (LOG_ERROR, "cpCollUtil: NULL srcColl or targColl incp"); return (USER__NULL_INPUT_ERR); } if (rodsArgs->recursive != True) { rodsLog (LOG_ERROR, "cpCollUtil: -r option must be used for cpting %s directory", srcColl); return (USER_INPUT_OPTION_ERR); } #if 0 status = rclOpenCollection (conn, srcColl, RECUR_QUERY_FG, &collHandle); #else status = rclOpenCollection (conn, srcColl, 0, &collHandle); #endif if (status < 0) { rodsLog (LOG_ERROR, "cpCollUtil: rclOpenCollection of %s error. status = %d", srcColl, status); return status; } #if 0 collLen = strlen (srcColl); collLen = getOpenedCollLen (&collHandle); #endif while ((status = rclReadCollection (conn, &collHandle, &collEnt)) >= 0) { if (collEnt.objType == DATA_OBJ_T) { snprintf (srcChildPath, MAX_NAME_LEN, "%s/%s", collEnt.collName, collEnt.dataName); #if 0 snprintf (targChildPath, MAX_NAME_LEN, "%s%s/%s", targColl, collEnt.collName + collLen, collEnt.dataName); #else snprintf (targChildPath, MAX_NAME_LEN, "%s/%s", targColl, collEnt.dataName); #endif status = chkStateForResume (conn, rodsRestart, targChildPath, rodsArgs, DATA_OBJ_T, &dataObjCopyInp->destDataObjInp.condInput, 1); if (status < 0) { /* restart failed */ break; } else if (status == 0) { continue; } status = cpFileUtil (conn, srcChildPath, targChildPath, collEnt.dataSize, myRodsEnv, rodsArgs, dataObjCopyInp); #if 0 -1, myRodsEnv, rodsArgs, dataObjCopyInp); #endif if (status < 0) { rodsLogError (LOG_ERROR, status, "getCollUtil: getDataObjUtil failed for %s. status = %d", srcChildPath, status); if (rodsRestart->fd > 0) { break; } else { savedStatus = status; } } else { status = procAndWrriteRestartFile (rodsRestart, targChildPath); } } else if (collEnt.objType == COLL_OBJ_T) { #if 0 if (strlen (collEnt.collName) <= collLen) continue; snprintf (targChildPath, MAX_NAME_LEN, "%s%s", targColl, collEnt.collName + collLen); #else if ((status = splitPathByKey ( collEnt.collName, parPath, childPath, '/')) < 0) { rodsLogError (LOG_ERROR, status, "cpCollUtil:: splitPathByKey for %s error, status = %d", collEnt.collName, status); return (status); } snprintf (targChildPath, MAX_NAME_LEN, "%s/%s", targColl, childPath); #endif #ifdef FILESYSTEM_META mkCollRWithSrcCollMeta (conn, targColl, targChildPath, collEnt.collName); #else mkCollR (conn, targColl, targChildPath); #endif if (rodsArgs->verbose == True) { fprintf (stdout, "C- %s:\n", targChildPath); } #if 0 if (collEnt.specColl.collClass != NO_SPEC_COLL) { #endif /* the child is a spec coll. need to drill down */ childDataObjCopyInp = *dataObjCopyInp; if (collEnt.specColl.collClass != NO_SPEC_COLL) childDataObjCopyInp.srcDataObjInp.specColl = &collEnt.specColl; status = cpCollUtil (conn, collEnt.collName, targChildPath, myRodsEnv, rodsArgs, &childDataObjCopyInp, rodsRestart); if (status < 0 && status != CAT_NO_ROWS_FOUND && status != SYS_SPEC_COLL_OBJ_NOT_EXIST) { savedStatus = status; } #if 0 } #endif } } rclCloseCollection (&collHandle); if (savedStatus < 0) { return (savedStatus); } else if (status == CAT_NO_ROWS_FOUND || status == SYS_SPEC_COLL_OBJ_NOT_EXIST) { return (0); } else { return (status); } }