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