00001
00002
00003
00004
00005
00006
00007
00008 #include "fileChksum.h"
00009 #include "miscServerFunct.h"
00010
00011
00012
00013 #include "eirods_log.h"
00014 #include "eirods_file_object.h"
00015 #include "eirods_stacktrace.h"
00016 #include "eirods_resource_backport.h"
00017
00018 #define SVR_MD5_BUF_SZ (1024*1024)
00019
00020 int
00021 rsFileChksum (rsComm_t *rsComm, fileChksumInp_t *fileChksumInp,
00022 char **chksumStr)
00023 {
00024 rodsServerHost_t *rodsServerHost;
00025 int remoteFlag;
00026 int status;
00027
00028
00029 eirods::error ret = eirods::get_host_for_hier_string( fileChksumInp->rescHier, remoteFlag, rodsServerHost );
00030 if( !ret.ok() ) {
00031 eirods::log( PASSMSG( "failed in call to eirods::get_host_for_hier_string", ret ) );
00032 return -1;
00033 }
00034
00035
00036 if (remoteFlag == LOCAL_HOST) {
00037 status = _rsFileChksum (rsComm, fileChksumInp, chksumStr);
00038 } else if (remoteFlag == REMOTE_HOST) {
00039 status = remoteFileChksum (rsComm, fileChksumInp, chksumStr,
00040 rodsServerHost);
00041 } else {
00042 if (remoteFlag < 0) {
00043 return (remoteFlag);
00044 } else {
00045 rodsLog (LOG_NOTICE,
00046 "rsFileChksum: resolveHost returned unrecognized value %d",
00047 remoteFlag);
00048 return (SYS_UNRECOGNIZED_REMOTE_FLAG);
00049 }
00050 }
00051
00052 return (status);
00053 }
00054
00055 int
00056 remoteFileChksum (rsComm_t *rsComm, fileChksumInp_t *fileChksumInp,
00057 char **chksumStr, rodsServerHost_t *rodsServerHost)
00058 {
00059 int status;
00060
00061 if (rodsServerHost == NULL) {
00062 rodsLog (LOG_NOTICE,
00063 "remoteFileChksum: Invalid rodsServerHost");
00064 return SYS_INVALID_SERVER_HOST;
00065 }
00066
00067 if ((status = svrToSvrConnect (rsComm, rodsServerHost)) < 0) {
00068 return status;
00069 }
00070
00071
00072 status = rcFileChksum (rodsServerHost->conn, fileChksumInp, chksumStr);
00073
00074 if (status < 0) {
00075 rodsLog (LOG_NOTICE,
00076 "remoteFileChksum: rcFileChksum failed for %s",
00077 fileChksumInp->fileName);
00078 }
00079
00080 return status;
00081 }
00082
00083 int
00084 _rsFileChksum (rsComm_t *rsComm, fileChksumInp_t *fileChksumInp,
00085 char **chksumStr)
00086 {
00087 int status;
00088
00089 *chksumStr = (char*)malloc (NAME_LEN);
00090
00091 status = fileChksum (fileChksumInp->fileType, rsComm, fileChksumInp->objPath,
00092 fileChksumInp->fileName, fileChksumInp->rescHier, *chksumStr);
00093
00094 if (status < 0) {
00095 rodsLog (LOG_NOTICE,
00096 "_rsFileChksum: fileChksum for %s, status = %d",
00097 fileChksumInp->fileName, status);
00098 free (*chksumStr);
00099 *chksumStr = NULL;
00100 return (status);
00101 }
00102
00103 return (status);
00104 }
00105
00106 int
00107 fileChksum (
00108 int fileType,
00109 rsComm_t *rsComm,
00110 char* objPath,
00111 char *fileName,
00112 char* rescHier,
00113 char *chksumStr)
00114 {
00115 MD5_CTX context;
00116 int bytes_read;
00117 unsigned char buffer[SVR_MD5_BUF_SZ], digest[16];
00118 int status;
00119
00120 #ifdef MD5_DEBUG
00121 rodsLong_t total_bytes_read = 0;
00122 #endif
00123
00124 if(objPath == NULL || objPath[0] == '\0') {
00125 std::stringstream msg;
00126 msg << __FUNCTION__;
00127 msg << " - Empty logical path.";
00128 eirods::log(LOG_ERROR, msg.str());
00129 return -1;
00130 }
00131
00132
00133
00134 eirods::file_object file_obj( rsComm, objPath, fileName, rescHier, -1, 0, O_RDONLY );
00135 eirods::error ret = fileOpen( rsComm, file_obj );
00136 if( !ret.ok() ) {
00137 status = UNIX_FILE_OPEN_ERR - errno;
00138 std::stringstream msg;
00139 msg << "fileOpen failed for [";
00140 msg << fileName;
00141 msg << "]";
00142 eirods::log( PASSMSG( msg.str(), ret ) );
00143 return (status);
00144 }
00145
00146 MD5Init (&context);
00147
00148 eirods::error read_err = fileRead( rsComm, file_obj, buffer, SVR_MD5_BUF_SZ );
00149 bytes_read = read_err.code();
00150
00151 while( read_err.ok() && bytes_read > 0 ) {
00152 #ifdef MD5_DEBUG
00153 total_bytes_read += bytes_read;
00154 #endif
00155 MD5Update (&context, buffer, bytes_read);
00156
00157 read_err = fileRead( rsComm, file_obj, buffer, SVR_MD5_BUF_SZ );
00158 bytes_read = read_err.code();
00159
00160 }
00161
00162 MD5Final (digest, &context);
00163
00164 ret = fileClose( rsComm, file_obj );
00165 if( !ret.ok() ) {
00166 eirods::error err = PASSMSG( "error on close", ret );
00167 eirods::log( err );
00168 }
00169
00170 md5ToStr (digest, chksumStr);
00171
00172 #ifdef MD5_DEBUG
00173 rodsLog (LOG_NOTICE,
00174 "fileChksum: chksum = %s, total_bytes_read = %lld", chksumStr, total_bytes_read);
00175 #endif
00176
00177 return (0);
00178
00179 }
00180