int redirectConnToRescSvr( rcComm_t **conn, dataObjInp_t *dataObjInp, rodsEnv *myEnv, int reconnFlag ) { int status; char *outHost = NULL; if ( dataObjInp->oprType == PUT_OPR ) { status = rcGetHostForPut( *conn, dataObjInp, &outHost ); } else if ( dataObjInp->oprType == GET_OPR ) { status = rcGetHostForGet( *conn, dataObjInp, &outHost ); } else { rodsLog( LOG_NOTICE, "redirectConnToRescSvr: Unknown oprType %d\n", dataObjInp->oprType ); return 0; } if ( status < 0 || outHost == NULL || strcmp( outHost, THIS_ADDRESS ) == 0 ) { return status; } status = rcReconnect( conn, outHost, myEnv, reconnFlag ); return status; }
int main (int argc, char **argv) { rcComm_t *conn = NULL; rodsEnv irods_env; rErrMsg_t err_msg; dataObjInp_t data_obj; openedDataObjInp_t open_obj; int open_fd; char *new_host = NULL; int status; char *obj_name = NULL; char *buffer; char prog_name[255]; size_t buf_size = DEFAULT_BUFFER_SIZE; int verbose = 0; int opt; unsigned long total_written = 0; int write_to_irods = 1; int server_set = 0; while ((opt = getopt(argc, argv, "b:vhrdw")) != -1) { switch (opt) { case 'b': buf_size = atoi(optarg); if (buf_size <= 0) { error_and_exit(conn, "Error: buffer size must be greater than 0.\n"); } break; case 'v': verbose = 1; break; case 'r': write_to_irods = 0; break; case 'w': // dummy write option to be enforced later break; case 'd': server_set = 1; break; case 'h': usage_and_exit(argv[0], EXIT_SUCCESS); break; default: usage_and_exit(argv[0], EXIT_FAILURE); break; } } if (optind >= argc) { fprintf(stderr, "Error: Missing iRODS file.\n"); usage_and_exit(argv[0], EXIT_FAILURE); } obj_name = argv[optind]; if ((buffer = malloc(buf_size)) == NULL) { error_and_exit(conn, "Error: unable to set buffer to size %ld\n", buf_size); } // set the client name so iRODS knows what program is connecting to it sprintf(prog_name, "%s:%s", PACKAGE_NAME, PACKAGE_VERSION); if (verbose) { fprintf(stderr, "Setting client name to: %s\n", prog_name); } setenv(SP_OPTION, prog_name, 1); // lets get the irods environment if ((status = getRodsEnv(&irods_env)) < 0) { error_and_exit(conn, "Error: getRodsEnv failed with status %d:%s\n", status, get_irods_error_name(status, verbose)); } if ((status = irods_uri_check(obj_name, &irods_env, verbose)) < 0) { error_and_exit(conn, "Error: invalid uri: %s\n", obj_name); } else if (status > 0) { server_set = 1; } if (verbose) { fprintf(stderr, "host %s\nzone %s\nuser %s\nport %d\n", irods_env.rodsHost, irods_env.rodsZone, irods_env.rodsUserName, irods_env.rodsPort); } #if IRODS_VERSION_INTEGER && IRODS_VERSION_INTEGER >= 4001008 init_client_api_table(); #endif // make the irods connections conn = rcConnect(irods_env.rodsHost, irods_env.rodsPort, irods_env.rodsUserName, irods_env.rodsZone, 0, &err_msg); if (!conn) { print_irods_error("Error: rcConnect failed:", &err_msg); exit(EXIT_FAILURE); } #if IRODS_VERSION_INTEGER && IRODS_VERSION_INTEGER >= 4001008 status = clientLogin(conn, "", ""); #else status = clientLogin(conn); #endif if (status < 0) { error_and_exit(conn, "Error: clientLogin failed with status %d:%s\n", status, get_irods_error_name(status, verbose)); } // set up the data object memset(&data_obj, 0, sizeof(data_obj)); strncpy(data_obj.objPath, obj_name, MAX_NAME_LEN); if (write_to_irods) { data_obj.openFlags = O_WRONLY; } else { data_obj.openFlags = O_RDONLY; } data_obj.dataSize = 0; // talk to server if (write_to_irods) { if (!server_set) { if ((status = rcGetHostForPut(conn, &data_obj, &new_host)) < 0) { error_and_exit(conn, "Error: rcGetHostForPut failed with status %d:%s\n", status, get_irods_error_name(status, verbose)); } choose_server(&conn, new_host, &irods_env, verbose); free(new_host); } if ((open_fd = rcDataObjCreate(conn, &data_obj)) < 0) { error_and_exit(conn, "Error: rcDataObjCreate failed with status %d:%s\n", open_fd, get_irods_error_name(open_fd, verbose)); } } else { if (!server_set) { if ((status = rcGetHostForGet(conn, &data_obj, &new_host)) < 0) { error_and_exit(conn, "Error: rcGetHostForGet failed with status %d:%s\n", status, get_irods_error_name(status, verbose)); } choose_server(&conn, new_host, &irods_env, verbose); free(new_host); } if ((open_fd = rcDataObjOpen(conn, &data_obj)) < 0) { error_and_exit(conn, "Error: rcDataObjOpen failed with status %d:%s\n", open_fd, get_irods_error_name(open_fd, verbose)); } } // the read/write loop while (1) { bytesBuf_t data_buffer; long read_in; long written_out; // set up common data elements memset(&open_obj, 0, sizeof(open_obj)); open_obj.l1descInx = open_fd; data_buffer.buf = buffer; // time to read something if (write_to_irods) { read_in = fread(buffer, 1, buf_size, stdin); open_obj.len = read_in; data_buffer.len = open_obj.len; } else { open_obj.len = buf_size; data_buffer.len = open_obj.len; if ((read_in = rcDataObjRead(conn, &open_obj, &data_buffer)) < 0) { error_and_exit(conn, "Error: rcDataObjRead failed with status %ld:%s\n", read_in, get_irods_error_name(read_in, verbose)); } } if (verbose) { fprintf(stderr, "%ld bytes read\n", read_in); } if (!read_in) break; // now try and write something if (write_to_irods) { open_obj.len = read_in; data_buffer.len = open_obj.len; if ((written_out = rcDataObjWrite(conn, &open_obj, &data_buffer)) < 0) { error_and_exit(conn, "Error: rcDataObjWrite failed with status %ld\n", written_out, get_irods_error_name(written_out, verbose)); } } else { written_out = fwrite(buffer, 1, read_in, stdout); } if (verbose) { fprintf(stderr, "%ld bytes written\n", written_out); } total_written += written_out; if (read_in != written_out) { error_and_exit(conn, "Error: write fail %ld written, should be %ld.\n", written_out, read_in); } }; if (verbose) { fprintf(stderr, "Total bytes written %ld\n", total_written); } if ((status = rcDataObjClose(conn, &open_obj)) < 0) { error_and_exit(conn, "Error: rcDataObjClose failed with status %d:%s\n", status, get_irods_error_name(status, verbose)); } rcDisconnect(conn); free(buffer); exit(EXIT_SUCCESS); }
int rsGetHostForPut (rsComm_t *rsComm, dataObjInp_t *dataObjInp, char **outHost) { int status; rescGrpInfo_t *myRescGrpInfo; rescInfo_t *myRescInfo; rodsServerHost_t *rodsServerHost; rodsHostAddr_t addr; specCollCache_t *specCollCache = NULL; char *myHost; int remoteFlag; *outHost = NULL; #if 0 if (isLocalZone (dataObjInp->objPath) == 0) { /* it is a remote zone. better connect to this host */ *outHost = strdup (THIS_ADDRESS); return 0; } #endif if (getValByKey (&dataObjInp->condInput, ALL_KW) != NULL || getValByKey (&dataObjInp->condInput, FORCE_FLAG_KW) != NULL) { /* going to ALL copies or overwriting files. not sure which is the * best */ *outHost = strdup (THIS_ADDRESS); return 0; } resolveLinkedPath (rsComm, dataObjInp->objPath, &specCollCache, NULL); if (isLocalZone (dataObjInp->objPath) == 0) { #if 0 /* it is a remote zone. better connect to this host */ *outHost = strdup (THIS_ADDRESS); return 0; #else resolveLinkedPath (rsComm, dataObjInp->objPath, &specCollCache, &dataObjInp->condInput); remoteFlag = getAndConnRcatHost (rsComm, SLAVE_RCAT, dataObjInp->objPath, &rodsServerHost); if (remoteFlag < 0) { return (remoteFlag); } else if (remoteFlag == LOCAL_HOST) { *outHost = strdup (THIS_ADDRESS); return 0; } else { status = rcGetHostForPut (rodsServerHost->conn, dataObjInp, outHost); if (status >= 0 && *outHost != NULL && strcmp (*outHost, THIS_ADDRESS) == 0) { free (*outHost); *outHost = strdup (rodsServerHost->hostName->name); } return (status); } #endif } status = getSpecCollCache (rsComm, dataObjInp->objPath, 0, &specCollCache); if (status >= 0) { if (specCollCache->specColl.collClass == MOUNTED_COLL) { status = resolveResc (specCollCache->specColl.resource, &myRescInfo); if (status < 0) { rodsLog (LOG_ERROR, "rsGetHostForPut: resolveResc error for %s, status = %d", specCollCache->specColl.resource, status); return status; } /* mounted coll will fall through */ } else { *outHost = strdup (THIS_ADDRESS); return 0; } } else { /* normal type */ status = getRescGrpForCreate (rsComm, dataObjInp, &myRescGrpInfo); if (status < 0) return status; myRescInfo = myRescGrpInfo->rescInfo; freeAllRescGrpInfo (myRescGrpInfo); /* status == 1 means random sorting scheme */ if ((status == 1 && getRescCnt (myRescGrpInfo) > 1) || getRescClass (myRescInfo) == COMPOUND_CL) { *outHost = strdup (THIS_ADDRESS); return 0; } } /* get down here when we got a valid myRescInfo */ bzero (&addr, sizeof (addr)); rstrcpy (addr.hostAddr, myRescInfo->rescLoc, NAME_LEN); status = resolveHost (&addr, &rodsServerHost); if (status < 0) return status; if (rodsServerHost->localFlag == LOCAL_HOST) { *outHost = strdup (THIS_ADDRESS); return 0; } myHost = getSvrAddr (rodsServerHost); if (myHost != NULL) { *outHost = strdup (myHost); return 0; } else { *outHost = NULL; return SYS_INVALID_SERVER_HOST; } }