/*** Copyright (c), The Regents of the University of California *** *** For more information please refer to files in the COPYRIGHT directory ***/ /* rcMisc.c - misc client routines */ #ifndef windows_platform #include #include #else #include "Unix2Nt.h" #endif #include "rcMisc.h" #include "apiHeaderAll.h" #include "modDataObjMeta.h" #include "rcGlobalExtern.h" #include "rodsGenQueryNames.h" #include "rodsType.h" #ifdef EXTENDED_ICAT #define EXTENDED_ICAT_TABLES_1 1 /* have extendedICAT.h set up the set 1 tables */ #include "extendedICAT.h" #endif #include "bulkDataObjPut.h" #include "putUtil.h" #ifdef USE_BOOST #include #include #endif /* check with the input path is a valid path - * 1 - valid * 0 - not valid */ #ifdef USE_BOOST_FS int isPath (char *myPath) { path p (myPath); if (exists(p)) { return (1); } else { return (0); } } #else /* USE_BOOST_FS */ int isPath (char *path) { #ifndef windows_platform struct stat statbuf; if (stat (path, &statbuf) == 0) { return (1); } else { return (0); } #else struct irodsntstat statbuf; if(iRODSNt_stat(path, &statbuf) == 0) { return 1; } return 0; #endif } #endif /* USE_BOOST_FS */ #ifdef USE_BOOST_FS rodsLong_t getFileSize (char *myPath) { path p (myPath); if (exists(p) && is_regular_file (p)) { return (file_size(p)); } else { return (-1); } } #else rodsLong_t getFileSize (char *path) { #ifndef windows_platform struct stat statbuf; if (stat (path, &statbuf) == 0) { return (statbuf.st_size); } else { return (-1); } #else struct irodsntstat statbuf; if(iRODSNt_stat(path, &statbuf) == 0) { return statbuf.st_size; } return -1; #endif } #endif /* USE_BOOST_FS */ int freeBBuf (bytesBuf_t *myBBuf) { if (myBBuf == NULL) { return (0); } if (myBBuf->buf != NULL) { free (myBBuf->buf); } free (myBBuf); return (0); } int clearBBuf (bytesBuf_t *myBBuf) { if (myBBuf == NULL) { return (0); } if (myBBuf->buf != NULL) { free (myBBuf->buf); } memset (myBBuf, 0, sizeof (bytesBuf_t)); return (0); } /* addRErrorMsg - Add an error msg to the rError_t struct. * rError_t *myError - the rError_t struct for the error msg. * int status - the input error status. * char *msg - the error msg string. This string will be copied to myError. */ int addRErrorMsg (rError_t *myError, int status, char *msg) { rErrMsg_t **newErrMsg; int newLen; int i; if (myError == NULL) { return (SYS_INTERNAL_NULL_INPUT_ERR); } if ((myError->len % PTR_ARRAY_MALLOC_LEN) == 0) { newLen = myError->len + PTR_ARRAY_MALLOC_LEN; newErrMsg = (rErrMsg_t **) malloc (newLen * sizeof (newErrMsg)); memset (newErrMsg, 0, newLen * sizeof (newErrMsg)); for (i = 0; i < myError->len; i++) { newErrMsg[i] = myError->errMsg[i]; } if (myError->errMsg != NULL) free (myError->errMsg); myError->errMsg = newErrMsg; } myError->errMsg[myError->len] = (rErrMsg_t*)malloc (sizeof (rErrMsg_t)); strncpy (myError->errMsg[myError->len]->msg, msg, ERR_MSG_LEN-1); myError->errMsg[myError->len]->status = status; myError->len++; return (0); } int replErrorStack (rError_t *srcRError, rError_t *destRError) { int i, len; rErrMsg_t *errMsg; if (srcRError == NULL || destRError == NULL) { return USER__NULL_INPUT_ERR; } len = srcRError->len; for (i = 0;i < len; i++) { errMsg = srcRError->errMsg[i]; addRErrorMsg (destRError, errMsg->status, errMsg->msg); } return 0; } int freeRError (rError_t *myError) { if (myError == NULL) { return (0); } freeRErrorContent (myError); free (myError); return (0); } int freeRErrorContent (rError_t *myError) { int i; if (myError == NULL) { return (0); } if (myError->len > 0) { for (i = 0; i < myError->len; i++) { free (myError->errMsg[i]); } free (myError->errMsg); } memset (myError, 0, sizeof (rError_t)); return (0); } /* Parse the input fullUserNameIn into an output userName and userZone and check that the username is a valid format, meaning at most one '@' and at most one '#'. Full userNames are of the form user@department[#zone]. It is assumed the output strings are at least NAME_LEN characters long and the input string is at most that long. */ int parseUserName(char *fullUserNameIn, char *userName, char *userZone) { char *cp; int ix; cp = strstr(fullUserNameIn, "#"); ix = cp - fullUserNameIn; if (cp != NULL && ix > 0 && ix < NAME_LEN-1) { strncpy(userName, fullUserNameIn, ix); *(userName+ix)='\0'; strncpy(userZone, fullUserNameIn+ix+1, NAME_LEN); if (strstr(userZone, "#")) return(USER_INVALID_USERNAME_FORMAT); } else { strncpy(userName, fullUserNameIn, NAME_LEN); strncpy(userZone, "", NAME_LEN); } cp = strstr(userName, "@"); if (cp) { char *cp2; cp2 = strstr(cp+1, "@"); if (cp2) return(USER_INVALID_USERNAME_FORMAT); } return(0); } int apiTableLookup (int apiNumber) { int i; for (i = 0; i < NumOfApi; i++) { if (RcApiTable[i].apiNumber == apiNumber) return (i); } return (SYS_UNMATCHED_API_NUM); } int myHtonll (rodsLong_t inlonglong, rodsLong_t *outlonglong) { int *inPtr, *outPtr; if (outlonglong == NULL) { return (SYS_INTERNAL_NULL_INPUT_ERR); } if (ntohl(1) == 1) { *outlonglong = inlonglong; return 0; } inPtr = (int *) &inlonglong; outPtr = (int *) outlonglong; *outPtr = htonl (*(inPtr + 1)); outPtr++; *outPtr = htonl (*inPtr); return (0); } int myNtohll (rodsULong_t inlonglong, rodsLong_t *outlonglong) { int *inPtr, *outPtr; if (outlonglong == NULL) { return (SYS_INTERNAL_NULL_INPUT_ERR); } if (ntohl(1) == 1) { *outlonglong = inlonglong; return 0; } inPtr = (int *) &inlonglong; outPtr = (int *) outlonglong; *outPtr = ntohl (*(inPtr + 1)); outPtr ++; *outPtr = ntohl (*inPtr); return (0); } int statToRodsStat (rodsStat_t *rodsStat, struct stat *myFileStat) { if (rodsStat == NULL || myFileStat == NULL) return (SYS_INTERNAL_NULL_INPUT_ERR); rodsStat->st_size = myFileStat->st_size; rodsStat->st_dev = myFileStat->st_dev; rodsStat->st_ino = myFileStat->st_ino; rodsStat->st_mode = myFileStat->st_mode; rodsStat->st_nlink = myFileStat->st_nlink; rodsStat->st_uid = myFileStat->st_uid; rodsStat->st_gid = myFileStat->st_gid; rodsStat->st_rdev = myFileStat->st_rdev; rodsStat->st_atim = myFileStat->st_atime; rodsStat->st_mtim = myFileStat->st_mtime; rodsStat->st_ctim = myFileStat->st_ctime; #ifndef _WIN32 rodsStat->st_blksize = myFileStat->st_blksize; rodsStat->st_blocks = myFileStat->st_blocks; #endif return (0); } /* YYYY - rodsStatToStat - this routine is currently not used */ int rodsStatToStat (struct stat *myFileStat, rodsStat_t *rodsStat) { if (myFileStat == NULL || rodsStat == NULL) return (SYS_INTERNAL_NULL_INPUT_ERR); myFileStat->st_size = rodsStat->st_size; myFileStat->st_dev = rodsStat->st_dev; myFileStat->st_ino = rodsStat->st_ino; myFileStat->st_mode = rodsStat->st_mode; myFileStat->st_nlink = rodsStat->st_nlink; myFileStat->st_uid = rodsStat->st_uid; myFileStat->st_gid = rodsStat->st_gid; myFileStat->st_rdev = rodsStat->st_rdev; myFileStat->st_atime = rodsStat->st_atim; myFileStat->st_mtime = rodsStat->st_mtim; myFileStat->st_ctime = rodsStat->st_ctim; #ifndef _WIN32 myFileStat->st_blksize = rodsStat->st_blksize; myFileStat->st_blocks = rodsStat->st_blocks; #endif return (0); } int direntToRodsDirent (struct rodsDirent *dirent, struct dirent *fileDirent) { if (dirent == NULL || fileDirent == NULL) return (SYS_INTERNAL_NULL_INPUT_ERR); strcpy (dirent->d_name, fileDirent->d_name); #if defined(linux_platform) dirent->d_ino = fileDirent->d_ino; dirent->d_offset = 0; dirent->d_reclen = fileDirent->d_reclen; dirent->d_namlen = _D_EXACT_NAMLEN(fileDirent); #elif defined(solaris_platform) dirent->d_ino = fileDirent->d_ino; dirent->d_offset = fileDirent->d_off; dirent->d_reclen = fileDirent->d_reclen; dirent->d_namlen = 0; #elif defined(aix_platform) dirent->d_ino = fileDirent->d_ino; dirent->d_offset = fileDirent->d_offset; dirent->d_reclen = fileDirent->d_reclen; dirent->d_namlen = fileDirent->d_namlen; #elif defined(sgi_platform) dirent->d_ino = fileDirent->d_ino; dirent->d_offset = fileDirent->d_off; dirent->d_reclen = fileDirent->d_reclen; dirent->d_namlen = 0; #elif defined(sunos_platform) dirent->d_ino = fileDirent->d_fileno; dirent->d_offset = fileDirent->d_off; dirent->d_reclen = fileDirent->d_reclen; dirent->d_namlen = fileDirent->d_namlen; #elif defined(alpha_platform) dirent->d_ino = fileDirent->d_ino; dirent->d_offset = 0; dirent->d_reclen = fileDirent->d_reclen; dirent->d_namlen = fileDirent->d_namlen; #elif defined(osx_platform) dirent->d_ino = fileDirent->d_ino; dirent->d_offset = 0; dirent->d_reclen = fileDirent->d_reclen; dirent->d_namlen = fileDirent->d_namlen; #elif defined(windows_platform) dirent->d_ino = fileDirent->d_ino; dirent->d_offset = 0; dirent->d_reclen = 0; dirent->d_namlen = 0; #else /* unknown. use linux */ dirent->d_ino = fileDirent->d_ino; dirent->d_offset = 0; dirent->d_reclen = fileDirent->d_reclen; dirent->d_namlen = _D_EXACT_NAMLEN(fileDirent); #endif return (0); } /* getStrInBuf get the next str in buf. * treat # as comment. ignore any leading white space. * Return the length of str copied, not including NULL. * bufSize is the remaining len in inbuf to be processed */ int getStrInBuf (char **inbuf, char *outbuf, int *inbufLen, int outbufLen) { char *inPtr, *outPtr; int bytesCopied = 0; int c; inPtr = *inbuf; outPtr = outbuf; while ((c = *inPtr) != '\0' && *inbufLen > 0) { (*inbufLen)--; inPtr ++; if (isspace (c)) { if (bytesCopied > 0) { break; } else { continue; } } else if (c == '#') { break; } else { if (bytesCopied >= outbufLen - 1) { rodsLog (LOG_ERROR, "getStrInBuf: outbuf overflow buf len %d", bytesCopied); break; } *outPtr = c; bytesCopied ++; outPtr++; } } *outPtr = '\0'; *inbuf = inPtr; return (bytesCopied); } /* getNextEleInStr - same as getStrInBuf except it did not check for # */ int getNextEleInStr (char **inbuf, char *outbuf, int *inbufLen, int maxOutLen) { char *inPtr, *outPtr; int bytesCopied = 0; int c; int hasQuote; inPtr = *inbuf; outPtr = outbuf; hasQuote = 0; while ((c = *inPtr) != '\0' && *inbufLen > 0) { (*inbufLen)--; inPtr ++; if (isspace (c) && hasQuote == False) { if (bytesCopied > 0) { break; } else { continue; } } else if (c == '\'') { if (hasQuote == True) { inPtr ++; break; } else { hasQuote = True; } } else { if (bytesCopied >= maxOutLen - 1) { rodsLog (LOG_ERROR, "getNextEleInStr: outbuf overflow buf len %d", bytesCopied); break; } *outPtr = c; bytesCopied ++; outPtr++; } } *outPtr = '\0'; *inbuf = inPtr; return (bytesCopied); } /* getLine - Read the next line. Add a NULL char at the end. * return the length of the line including the terminating NULL. */ int getLine (FILE *fp, char *buf, int bufSize) { int c; int len = 0; char *cptr = buf; while ((c = getc(fp)) != EOF) { if (c == '\n') break; *cptr ++ = c; len ++; /* overflow buf ? */ if (len >= bufSize - 1) { rodsLog (LOG_ERROR, "getLine: buffer overflow bufSize %d", bufSize); break; } } if (c == EOF && len == 0) return EOF; else { *cptr ++ = '\0'; len ++; return len; } } int getZoneNameFromHint (char *rcatZoneHint, char *zoneName, int len) { int bytesCopied = 0; char *hintPtr, *outPtr; if (rcatZoneHint == NULL) { zoneName[0] = '\0'; return (0); } if (rcatZoneHint[0] == '/') { /* a path */ hintPtr = rcatZoneHint + 1; outPtr = zoneName; while (*hintPtr != '\0' && *hintPtr != '/' && bytesCopied < len - 1) { *outPtr = *hintPtr; bytesCopied ++; outPtr ++; hintPtr ++; } /* take out the last ' */ if (*(outPtr - 1) == '\'') { *(outPtr - 1) = '\0'; } else { *outPtr = '\0'; } } else { /* just a zoneName. use strncpy instead of rstrcpy to avoid error * msg */ #if 0 rstrcpy (zoneName, rcatZoneHint, len); #endif strncpy (zoneName, rcatZoneHint, len); zoneName[len - 1] = '\0'; } return (0); } int freeDataObjInfo (dataObjInfo_t *dataObjInfo) { if (dataObjInfo == NULL) return (0); /* separate specColl */ if (dataObjInfo->specColl != NULL) free (dataObjInfo->specColl); free (dataObjInfo); return (0); } int freeAllDataObjInfo (dataObjInfo_t *dataObjInfoHead) { dataObjInfo_t *tmpDataObjInfo, *nextDataObjInfo; tmpDataObjInfo = dataObjInfoHead; while (tmpDataObjInfo != NULL) { nextDataObjInfo = tmpDataObjInfo->next; /* don't free rescInfo because it came from global if (tmpDataObjInfo->rescInfo != NULL) { free (tmpDataObjInfo->rescInfo); } */ freeDataObjInfo (tmpDataObjInfo); tmpDataObjInfo = nextDataObjInfo; } return (0); } /* queDataObjInfo - queue the input dataObjInfo in dataObjInfoHead queue. * Input * int singleInfoFlag - 1 - the input dataObjInfo is a single dataObjInfo. * 0 - the input dataObjInfo is a link list * int topFlag - 1 - queue the input dataObjInfo at the head of the queue * 0 - queue the input dataObjInfo at the bottom of the * queue. */ int queDataObjInfo (dataObjInfo_t **dataObjInfoHead, dataObjInfo_t *dataObjInfo, int singleInfoFlag, int topFlag) { dataObjInfo_t *tmpDataObjInfo; if (dataObjInfo == NULL) return (-1); if (*dataObjInfoHead == NULL) { *dataObjInfoHead = dataObjInfo; if (singleInfoFlag > 0) { dataObjInfo->next = NULL; } } else { if (topFlag > 0) { dataObjInfo_t *savedDataObjInfo; savedDataObjInfo = *dataObjInfoHead; *dataObjInfoHead = dataObjInfo; if (singleInfoFlag > 0) { (*dataObjInfoHead)->next = savedDataObjInfo; } else { /* have to drill down to find the last DataObjInfo */ tmpDataObjInfo = *dataObjInfoHead; while (tmpDataObjInfo->next != NULL) { tmpDataObjInfo = tmpDataObjInfo->next; } tmpDataObjInfo->next = savedDataObjInfo; } } else { tmpDataObjInfo = *dataObjInfoHead; while (tmpDataObjInfo->next != NULL) { tmpDataObjInfo = tmpDataObjInfo->next; } tmpDataObjInfo->next = dataObjInfo; if (singleInfoFlag > 0) { dataObjInfo->next = NULL; } } } return (0); } int dequeDataObjInfo (dataObjInfo_t **dataObjInfoHead, dataObjInfo_t *dataObjInfo) { dataObjInfo_t *tmpDataObjInfo; dataObjInfo_t *prevDataObjInfo = NULL; if (dataObjInfo == NULL || dataObjInfoHead == NULL) return (-1); tmpDataObjInfo = *dataObjInfoHead; while (tmpDataObjInfo != NULL) { if (tmpDataObjInfo == dataObjInfo) { if (prevDataObjInfo == NULL) { *dataObjInfoHead = tmpDataObjInfo->next; } else { prevDataObjInfo->next = tmpDataObjInfo->next; } return 0; } prevDataObjInfo = tmpDataObjInfo; tmpDataObjInfo = tmpDataObjInfo->next; } return -1; } int getDataObjInfoCnt (dataObjInfo_t *dataObjInfoHead) { dataObjInfo_t *tmpDataObjInfo; int cnt = 0; tmpDataObjInfo = dataObjInfoHead; while (tmpDataObjInfo != NULL) { cnt++; tmpDataObjInfo = tmpDataObjInfo->next; } return (cnt); } char * getValByKey (keyValPair_t *condInput, char *keyWord) { int i; if (condInput == NULL) { return (NULL); } for (i = 0; i < condInput->len; i++) { if (strcmp (condInput->keyWord[i], keyWord) == 0) { return (condInput->value[i]); } } return (NULL); } /* YYYY - getValByInx - this routine is currently not used */ char * getValByInx (inxValPair_t *inxValPair, int inx) { int i; if (inxValPair == NULL) { return (NULL); } for (i = 0; i < inxValPair->len; i++) { if (inxValPair->inx[i] == inx) { return (inxValPair->value[i]); } } return (NULL); } int getIvalByInx (inxIvalPair_t *inxIvalPair, int inx, int *outValue) { int i; if (inxIvalPair == NULL) { return (UNMATCHED_KEY_OR_INDEX); } for (i = 0; i < inxIvalPair->len; i++) { if (inxIvalPair->inx[i] == inx) { *outValue = inxIvalPair->value[i]; return (0); } } return (UNMATCHED_KEY_OR_INDEX); } int rmKeyVal (keyValPair_t *condInput, char *keyWord) { int i, j; if (condInput == NULL) { return (0); } for (i = 0; i < condInput->len; i++) { if (condInput->keyWord[i] != NULL && strcmp (condInput->keyWord[i], keyWord) == 0) { free (condInput->keyWord[i]); free (condInput->value[i]); condInput->len--; for (j = i; j < condInput->len; j++) { condInput->keyWord[j] = condInput->keyWord[j + 1]; condInput->value[j] = condInput->value[j + 1]; } if (condInput->len <= 0) { free (condInput->keyWord); free (condInput->value); condInput->value = condInput->keyWord = NULL; } break; } } return (0); } int replKeyVal (keyValPair_t *srcCondInput, keyValPair_t *destCondInput) { int i; memset (destCondInput, 0, sizeof (keyValPair_t)); for (i = 0; i < srcCondInput->len; i++) { addKeyVal (destCondInput, srcCondInput->keyWord[i], srcCondInput->value[i]); } return (0); } int replDataObjInp (dataObjInp_t *srcDataObjInp, dataObjInp_t *destDataObjInp) { *destDataObjInp = *srcDataObjInp; replKeyVal (&srcDataObjInp->condInput, &destDataObjInp->condInput); replSpecColl (srcDataObjInp->specColl, &destDataObjInp->specColl); return (0); } int replSpecColl (specColl_t *inSpecColl, specColl_t **outSpecColl) { if (inSpecColl == NULL || outSpecColl == NULL) return USER__NULL_INPUT_ERR; *outSpecColl = (specColl_t *)malloc (sizeof (specColl_t)); *(*outSpecColl) = *inSpecColl; return 0; } int addKeyVal (keyValPair_t *condInput, char *keyWord, char *value) { char **newKeyWord; char **newValue; int newLen; int i; int emptyInx = -1; if (condInput == NULL) { return (SYS_INTERNAL_NULL_INPUT_ERR); } /* check if the keyword exists */ for (i = 0; i < condInput->len; i++) { if (strcmp (keyWord, condInput->keyWord[i]) == 0) { free ( condInput->value[i]); condInput->value[i] = strdup (value); return (0); } else if (strlen (condInput->keyWord[i]) == 0) { emptyInx = i; } } if (emptyInx >= 0) { free (condInput->keyWord[emptyInx]); free (condInput->value[emptyInx]); condInput->keyWord[emptyInx] = strdup (keyWord); condInput->value[emptyInx] = strdup (value); return (0); } if ((condInput->len % PTR_ARRAY_MALLOC_LEN) == 0) { newLen = condInput->len + PTR_ARRAY_MALLOC_LEN; newKeyWord = (char **) malloc (newLen * sizeof (newKeyWord)); newValue = (char **) malloc (newLen * sizeof (newValue)); memset (newKeyWord, 0, newLen * sizeof (newKeyWord)); memset (newValue, 0, newLen * sizeof (newValue)); for (i = 0; i < condInput->len; i++) { newKeyWord[i] = condInput->keyWord[i]; newValue[i] = condInput->value[i]; } if (condInput->keyWord != NULL) free (condInput->keyWord); if (condInput->value != NULL) free (condInput->value); condInput->keyWord = newKeyWord; condInput->value = newValue; } condInput->keyWord[condInput->len] = strdup (keyWord); condInput->value[condInput->len] = strdup (value); condInput->len++; return (0); } int addTagStruct (tagStruct_t *condInput, char *preTag, char *postTag, char *keyWord) { char **newKeyWord; char **newPreTag; char **newPostTag; int newLen; int i; if (condInput == NULL) { return (SYS_INTERNAL_NULL_INPUT_ERR); } if ((condInput->len % PTR_ARRAY_MALLOC_LEN) == 0) { newLen = condInput->len + PTR_ARRAY_MALLOC_LEN; newKeyWord = (char **) malloc (newLen * sizeof (newKeyWord)); newPreTag = (char **) malloc (newLen * sizeof (newPreTag)); newPostTag = (char **) malloc (newLen * sizeof (newPostTag)); memset (newKeyWord, 0, newLen * sizeof (newKeyWord)); memset (newPreTag, 0, newLen * sizeof (newPreTag)); memset (newPostTag, 0, newLen * sizeof (newPostTag)); for (i = 0; i < condInput->len; i++) { newKeyWord[i] = condInput->keyWord[i]; newPreTag[i] = condInput->preTag[i]; newPostTag[i] = condInput->postTag[i]; } if (condInput->keyWord != NULL) free (condInput->keyWord); if (condInput->preTag != NULL) free (condInput->preTag); if (condInput->postTag != NULL) free (condInput->postTag); condInput->keyWord = newKeyWord; condInput->preTag = newPreTag; condInput->postTag = newPostTag; } condInput->keyWord[condInput->len] = strdup (keyWord); condInput->preTag[condInput->len] = strdup (preTag); condInput->postTag[condInput->len] = strdup (postTag); condInput->len++; return (0); } int addInxIval (inxIvalPair_t *inxIvalPair, int inx, int value) { int *newInx; int *newValue; int newLen; int i; if (inxIvalPair == NULL) { return (SYS_INTERNAL_NULL_INPUT_ERR); } if ((inxIvalPair->len % PTR_ARRAY_MALLOC_LEN) == 0) { newLen = inxIvalPair->len + PTR_ARRAY_MALLOC_LEN; newInx = (int *) malloc (newLen * sizeof (int)); newValue = (int *) malloc (newLen * sizeof (int)); memset (newInx, 0, newLen * sizeof (int)); memset (newValue, 0, newLen * sizeof (int)); for (i = 0; i < inxIvalPair->len; i++) { newInx[i] = inxIvalPair->inx[i]; newValue[i] = inxIvalPair->value[i]; } if (inxIvalPair->inx != NULL) free (inxIvalPair->inx); if (inxIvalPair->value != NULL) free (inxIvalPair->value); inxIvalPair->inx = newInx; inxIvalPair->value = newValue; } inxIvalPair->inx[inxIvalPair->len] = inx; inxIvalPair->value[inxIvalPair->len] = value; inxIvalPair->len++; return (0); } int addInxVal (inxValPair_t *inxValPair, int inx, char *value) { int *newInx; char **newValue; int newLen; int i; if (inxValPair == NULL) { return (SYS_INTERNAL_NULL_INPUT_ERR); } if ((inxValPair->len % PTR_ARRAY_MALLOC_LEN) == 0) { newLen = inxValPair->len + PTR_ARRAY_MALLOC_LEN; newInx = (int *) malloc (newLen * sizeof (int)); newValue = (char **) malloc (newLen * sizeof (newValue)); memset (newInx, 0, newLen * sizeof (int)); memset (newValue, 0, newLen * sizeof (newValue)); for (i = 0; i < inxValPair->len; i++) { newInx[i] = inxValPair->inx[i]; newValue[i] = inxValPair->value[i]; } if (inxValPair->inx != NULL) free (inxValPair->inx); if (inxValPair->value != NULL) free (inxValPair->value); inxValPair->inx = newInx; inxValPair->value = newValue; } inxValPair->inx[inxValPair->len] = inx; inxValPair->value[inxValPair->len] = strdup (value); inxValPair->len++; return (0); } int addStrArray (strArray_t *strArray, char *value) { char *newValue; int newLen; int i; int size; int myLen; if (strArray == NULL) { return (SYS_INTERNAL_NULL_INPUT_ERR); } if (strArray->size <= 0) { if (strArray->len == 0) { /* dafault to NAME_LEN */ strArray->size = NAME_LEN; } else { rodsLog (LOG_ERROR, "addStrArray: invalid size %d, len %d", strArray->size, strArray->len); return (SYS_INTERNAL_NULL_INPUT_ERR); } } myLen = strlen (value); size = strArray->size; while (size < myLen + 1) { size = size * 2; } /* XXXXXXX should be replaced by resizeStrArray after 2.3 release */ if (size != strArray->size || (strArray->len % PTR_ARRAY_MALLOC_LEN) == 0) { int oldSize = strArray->size; /* have to redo it */ strArray->size = size; newLen = strArray->len + PTR_ARRAY_MALLOC_LEN; newValue = (char *) malloc (newLen * size); memset (newValue, 0, newLen * size); for (i = 0; i < strArray->len; i++) { rstrcpy (&newValue[i * size], &strArray->value[i * oldSize], size); } if (strArray->value != NULL) free (strArray->value); strArray->value = newValue; } rstrcpy (&strArray->value[strArray->len * size], value, size); strArray->len++; return (0); } int resizeStrArray (strArray_t *strArray, int newSize) { int i, newLen; char *newValue; if (newSize > strArray->size || (strArray->len % PTR_ARRAY_MALLOC_LEN) == 0) { int oldSize = strArray->size; /* have to redo it */ if (strArray->size > newSize) newSize = strArray->size; else strArray->size = newSize; newLen = strArray->len + PTR_ARRAY_MALLOC_LEN; newValue = (char *) malloc (newLen * newSize); memset (newValue, 0, newLen * newSize); for (i = 0; i < strArray->len; i++) { rstrcpy (&newValue[i * newSize], &strArray->value[i * oldSize], newSize); } if (strArray->value != NULL) free (strArray->value); strArray->value = newValue; } return 0; } /* YYYY - addIntArray - this routine is currently not used */ int addIntArray (intArray_t *intArray, int value) { int newLen; int *newValue; int i; if (intArray == NULL) { return (SYS_INTERNAL_NULL_INPUT_ERR); } if ((intArray->len % PTR_ARRAY_MALLOC_LEN) == 0) { newLen = intArray->len + PTR_ARRAY_MALLOC_LEN; newValue = (int *) malloc (newLen * sizeof (int)); memset (newValue, 0, newLen * sizeof (int)); for (i = 0; i < intArray->len; i++) { newValue[i] = intArray->value[i]; } if (intArray->value != NULL) free (intArray->value); intArray->value = newValue; } intArray->value[intArray->len] = value; intArray->len++; return (0); } int clearKeyVal (keyValPair_t *condInput) { int i; if (condInput == NULL || condInput->len <= 0) return (0); for (i = 0; i < condInput->len; i++) { free (condInput->keyWord[i]); free (condInput->value[i]); } free (condInput->keyWord); free (condInput->value); memset (condInput, 0, sizeof (keyValPair_t)); return(0); } /* YYYY - clearTagStruct - this routine is currently not used */ int clearTagStruct (tagStruct_t *condInput) { int i; if (condInput == NULL || condInput->len <= 0) return (0); for (i = 0; i < condInput->len; i++) { free (condInput->keyWord[i]); free (condInput->preTag[i]); free (condInput->postTag[i]); } free (condInput->keyWord); free (condInput->preTag); free (condInput->postTag); memset (condInput, 0, sizeof (tagStruct_t)); return(0); } int clearInxIval (inxIvalPair_t *inxIvalPair) { if (inxIvalPair == NULL || inxIvalPair->len <= 0) return (0); free (inxIvalPair->inx); free (inxIvalPair->value); memset (inxIvalPair, 0, sizeof (inxIvalPair_t)); return (0); } int clearInxVal (inxValPair_t *inxValPair) { int i; if (inxValPair == NULL || inxValPair->len <= 0) return (0); for (i = 0; i < inxValPair->len; i++) { free (inxValPair->value[i]); } free (inxValPair->inx); free (inxValPair->value); memset (inxValPair, 0, sizeof (inxValPair_t)); return(0); } int clearGenQueryInp (genQueryInp_t *genQueryInp) { if (genQueryInp == NULL) { return (0); } clearInxIval (&genQueryInp->selectInp); clearInxVal (&genQueryInp->sqlCondInp); clearKeyVal (&genQueryInp->condInput); return (0); } int freeGenQueryOut (genQueryOut_t **genQueryOut) { if (genQueryOut == NULL) return 0; if (*genQueryOut == NULL) return 0; clearGenQueryOut (*genQueryOut); free (*genQueryOut); *genQueryOut = NULL; return (0); } int clearGenQueryOut (genQueryOut_t *genQueryOut) { int i; if (genQueryOut == NULL) return 0; for (i = 0; i < genQueryOut->attriCnt; i++) { if (genQueryOut->sqlResult[i].value != NULL) free (genQueryOut->sqlResult[i].value); } return (0); } /* catGenQueryOut - Concatenate genQueryOut to targGenQueryOut up to maxRowCnt. * It is assumed that the two genQueryOut have the same attriInx and * len for each attri. * */ int catGenQueryOut (genQueryOut_t *targGenQueryOut, genQueryOut_t *genQueryOut, int maxRowCnt) { int i; int totalRowCnt; /* do some sanity checks */ if (targGenQueryOut == NULL || genQueryOut == NULL) return USER__NULL_INPUT_ERR; if (genQueryOut->rowCnt == 0) return 0; if ((totalRowCnt = targGenQueryOut->rowCnt + genQueryOut->rowCnt) > maxRowCnt) { rodsLog (LOG_ERROR, "catGenQueryOut: total rowCnt %d > %d", targGenQueryOut->rowCnt + genQueryOut->rowCnt, maxRowCnt); return SYS_STRUCT_ELEMENT_MISMATCH; } if (targGenQueryOut->attriCnt != genQueryOut->attriCnt) { rodsLog (LOG_ERROR, "catGenQueryOut: attriCnt mismatch %d != %d", targGenQueryOut->attriCnt, genQueryOut->attriCnt); return SYS_STRUCT_ELEMENT_MISMATCH; } for (i = 0; i < genQueryOut->attriCnt; i++) { if (targGenQueryOut->sqlResult[i].attriInx != genQueryOut->sqlResult[i].attriInx) { rodsLog (LOG_ERROR, "catGenQueryOut: attriInx mismatch %d != %d", targGenQueryOut->sqlResult[i].attriInx, genQueryOut->sqlResult[i].attriInx); return SYS_STRUCT_ELEMENT_MISMATCH; } if (targGenQueryOut->sqlResult[i].len != genQueryOut->sqlResult[i].len) { rodsLog (LOG_ERROR, "catGenQueryOut: len mismatch %d != %d", targGenQueryOut->sqlResult[i].len, genQueryOut->sqlResult[i].len); return SYS_STRUCT_ELEMENT_MISMATCH; } } for (i = 0; i < genQueryOut->attriCnt; i++) { char *tmpValue; int len; if ((len = genQueryOut->sqlResult[i].len) <= 0) continue; if ((tmpValue = (char *)malloc (totalRowCnt * len)) == 0) return (SYS_MALLOC_ERR - errno); if (targGenQueryOut->sqlResult[i].value != NULL) { memcpy (tmpValue, targGenQueryOut->sqlResult[i].value, len * targGenQueryOut->rowCnt); free (targGenQueryOut->sqlResult[i].value); } targGenQueryOut->sqlResult[i].value = tmpValue; tmpValue += len * targGenQueryOut->rowCnt; memcpy (tmpValue, genQueryOut->sqlResult[i].value, len * genQueryOut->rowCnt); } targGenQueryOut->rowCnt = totalRowCnt; return (0); } int clearBulkOprInp (bulkOprInp_t *bulkOprInp) { if (bulkOprInp == NULL) return 0; clearGenQueryOut (&bulkOprInp->attriArray); clearKeyVal (&bulkOprInp->condInput); return 0; } int moveKeyVal (keyValPair_t *destKeyVal, keyValPair_t *srcKeyVal) { if (destKeyVal == NULL || srcKeyVal == NULL) return (0); *destKeyVal = *srcKeyVal; memset (srcKeyVal, 0, sizeof (keyValPair_t)); return (0); } int getUnixUid (char *userName) { #ifndef _WIN32 struct passwd *pw; int myuid; char *splitPos; if ((splitPos = strchr (userName, '@')) != NULL) { *splitPos = '\0'; /* skip @ */ } if (!(pw = getpwnam(userName))) { myuid = -1; } else { myuid = (int) pw->pw_uid; } if (splitPos != NULL) *splitPos = '@'; return (myuid); #else return (-1); #endif } int getUnixUsername (int uid, char *username, int username_len) { #ifndef _WIN32 struct passwd *pwent; if (uid < 0 || username == NULL) { return USER__NULL_INPUT_ERR; } /* if getpwuid returns NULL and errno is zero, it means the user doesn't exist in the user db */ errno = 0; pwent = getpwuid(uid); if (pwent == NULL) { if (errno) { rodsLog(LOG_ERROR, "getUnixUsername: error calling getpwuid for uid %d. errno = %d", uid, errno); } else { rodsLog(LOG_ERROR, "getUnixUsername: no user with uid %d", uid); } return SYS_USER_RETRIEVE_ERR - errno; } if ((unsigned int)username_len <= strlen(pwent->pw_name)) { rodsLog(LOG_ERROR, "getUnixUsername: username input buffer too small (%d <= %d)", username_len, strlen(pwent->pw_name)); return USER_STRLEN_TOOLONG; } strcpy(username, pwent->pw_name); return 0; #else return -1; #endif } int getUnixGroupname(int gid, char *groupname, int groupname_len) { #ifndef _WIN32 struct group *grent; if (gid < 0 || groupname == NULL) { return USER__NULL_INPUT_ERR; } errno = 0; grent = getgrgid(gid); if (grent == NULL) { if (errno) { rodsLog(LOG_ERROR, "getUnixGroupname: error calling getgrgid for gid %d. errno = %d", gid, errno); } else { rodsLog(LOG_ERROR, "getUnixGroupname: no group with gid %d", gid); } return SYS_GROUP_RETRIEVE_ERR - errno; } if ((unsigned int)groupname_len <= strlen(grent->gr_name)) { rodsLog(LOG_ERROR, "getUnixGroupname: groupname input buffer too small (%d <= %d)", groupname_len, strlen(grent->gr_name)); return USER_STRLEN_TOOLONG; } strcpy(groupname, grent->gr_name); return 0; #else return -1; #endif } /* Return 64 semi-random bytes terminated by a null. This is designed to be very quick and sufficiently pseudo-random for the context in which it is used (a challenge in the challenge - response protocol). If /dev/urandom is available (as is usually the case on Linux/Unix hosts) we now use that, as it will be normally be sufficiently fast and has much entropy (very pseudo-random). Otherwise, this algorithm creates sufficient pseudo-randomness as described below. There are about 20 bits of entropy from the microsecond clock, plus a few more via the pid, and more from the seconds value. By using the PID and a static counter as part of this, we're guaranteed that one or the other of those will vary each time, even if called repeatedly (the microsecond time value will vary too). The use of the epoch seconds value (a large number that increments each second), also helps prevent returning the same set of pseudo-random bytes over time. MD5 is a quick and handy way to fill out the 64 bytes using the input values, in a manner that is very unlikely to repeat. The entropy of the seeds, in combination with these other features, makes the probability of repeating a particular pattern on the order of one out of many billions. If /dev/urandom is available, the odds are even smaller. */ int get64RandomBytes(char *buf) { MD5_CTX context; char buffer[65]; /* each digest is 16 bytes, 4 of them */ int ints[30]; int pid; #ifdef windows_platform SYSTEMTIME tv; #else struct timeval tv; #endif static int count=12348; int i; #ifndef windows_platform /* Use /dev/urandom instead, if available */ int uran_fd, rval; uran_fd = open("/dev/urandom", O_RDONLY); if (uran_fd > 0) { rval = read(uran_fd, buffer, 64); close(uran_fd); if (rval==64) { for (i=0;i<64;i++) { if (buffer[i]=='\0') { buffer[i]++; /* make sure no nulls before end of 'string'*/ } } buffer[64]='\0'; strncpy(buf,buffer,65); return(0); } } #endif #ifdef windows_platform GetSystemTime(&tv); #else gettimeofday(&tv, 0); #endif pid = getpid(); count++; ints[0]=12349994; ints[1]=count; #ifdef windows_platform ints[2]= (int)tv.wSecond; ints[5]= (int)tv.wSecond; #else ints[2]=tv.tv_usec; ints[5]=tv.tv_sec; #endif MD5Init (&context); MD5Update (&context, (unsigned char*)&ints[0], 100); MD5Final ((unsigned char*)buffer, &context); ints[0]=pid; ints[4]=(int)buffer[10]; MD5Init (&context); MD5Update (&context, (unsigned char *)&ints[0], 100); MD5Final ((unsigned char*)(buffer+16), &context); MD5Init (&context); MD5Update (&context, (unsigned char*)&ints[0], 100); MD5Final ((unsigned char*)(buffer+32), &context); MD5Init (&context); MD5Update (&context, (unsigned char*)buffer, 40); MD5Final ((unsigned char*)(buffer+48), &context); for (i=0;i<64;i++) { if (buffer[i]=='\0') { buffer[i]++; /* make sure no nulls before end of 'string'*/ } } buffer[64]='\0'; strncpy(buf,buffer,65); return(0); } sqlResult_t * getSqlResultByInx (genQueryOut_t *genQueryOut, int attriInx) { int i; if (genQueryOut == NULL) return NULL; for (i = 0; i < genQueryOut->attriCnt; i++) { if (genQueryOut->sqlResult[i].attriInx == attriInx) return (&genQueryOut->sqlResult[i]); } return (NULL); } int clearModDataObjMetaInp (modDataObjMeta_t *modDataObjMetaInp) { if (modDataObjMetaInp == NULL) { return 0; } if (modDataObjMetaInp->regParam != NULL) { clearKeyVal (modDataObjMetaInp->regParam); free (modDataObjMetaInp->regParam); } if (modDataObjMetaInp->dataObjInfo != NULL) { freeDataObjInfo (modDataObjMetaInp->dataObjInfo); } return (0); } int clearUnregDataObj (unregDataObj_t *unregDataObjInp) { if (unregDataObjInp == NULL) { return 0; } if (unregDataObjInp->condInput != NULL) { clearKeyVal (unregDataObjInp->condInput); free (unregDataObjInp->condInput); } if (unregDataObjInp->dataObjInfo != NULL) { freeDataObjInfo (unregDataObjInp->dataObjInfo); } return (0); } int clearRegReplicaInp (regReplica_t *regReplicaInp) { if (regReplicaInp == NULL) { return 0; } clearKeyVal (®ReplicaInp->condInput); if (regReplicaInp->srcDataObjInfo != NULL) { freeDataObjInfo (regReplicaInp->srcDataObjInfo); } if (regReplicaInp->destDataObjInfo != NULL) { freeDataObjInfo (regReplicaInp->destDataObjInfo); } memset (regReplicaInp, 0, sizeof (regReplica_t)); return (0); } int clearDataObjInp (dataObjInp_t *dataObjInp) { if (dataObjInp == NULL) { return 0; } clearKeyVal (&dataObjInp->condInput); if (dataObjInp->specColl != NULL) free (dataObjInp->specColl); memset (dataObjInp, 0, sizeof (dataObjInp_t)); return (0); } int clearCollInp (collInp_t *collInp) { if (collInp == NULL) { return 0; } clearKeyVal (&collInp->condInput); memset (collInp, 0, sizeof (collInp_t)); return (0); } int clearDataObjCopyInp (dataObjCopyInp_t *dataObjCopyInp) { if (dataObjCopyInp == NULL) { return 0; } clearKeyVal (&dataObjCopyInp->destDataObjInp.condInput); clearKeyVal (&dataObjCopyInp->srcDataObjInp.condInput); if (dataObjCopyInp->srcDataObjInp.specColl != NULL) free (dataObjCopyInp->srcDataObjInp.specColl); memset (dataObjCopyInp, 0, sizeof (dataObjCopyInp_t)); return (0); } int freeAllRescGrpInfo (rescGrpInfo_t *rescGrpInfoHead) { rescGrpInfo_t *tmpRescGrpInfo, *nextRescGrpInfo; rescGrpInfo_t *cacheRescGrpInfo, *nextCacheRescGrpInfo; cacheRescGrpInfo = rescGrpInfoHead; while (cacheRescGrpInfo != NULL) { tmpRescGrpInfo = cacheRescGrpInfo; nextCacheRescGrpInfo = cacheRescGrpInfo->cacheNext; while (tmpRescGrpInfo != NULL) { nextRescGrpInfo = tmpRescGrpInfo->next; free (tmpRescGrpInfo); tmpRescGrpInfo = nextRescGrpInfo; } cacheRescGrpInfo = nextCacheRescGrpInfo; } return (0); } int freeAllRescQuota (rescQuota_t *rescQuotaHead) { rescQuota_t *tmpRescQuota, *nextRescQuota; tmpRescQuota = rescQuotaHead; while (tmpRescQuota != NULL) { nextRescQuota = tmpRescQuota->next; free (tmpRescQuota); tmpRescQuota = nextRescQuota; } return (0); } int parseMultiStr (char *strInput, strArray_t *strArray) { char *startPtr, *endPtr; int endReached = 0; if (strInput == NULL || strArray == NULL) { return (SYS_INTERNAL_NULL_INPUT_ERR); } startPtr = endPtr = strInput; while (1) { /* RAJA changed JUl 11, 2007 so that two %% will be taken as an input % instead of as a delimiter */ while (*endPtr != '%' && *endPtr != '\0') { endPtr ++; } if (*endPtr == '%') { if (*(endPtr+1) == '%') { endPtr ++;endPtr ++; continue; } *endPtr = '\0'; } else { endReached = 1; } addStrArray (strArray, startPtr); if (endReached == 1) { break; } endPtr++; startPtr = endPtr; } return (strArray->len); } /* Get the current time, in the form: 2006-10-25-10.52.43 */ /* 0123456789012345678 */ extern char *tzname[2]; /* Return an integer string of the current time in the Unix Time format (integer seconds since 1970). This is the same in all timezones (sort of CUT) and is converted to local time for display. */ void getNowStr(char *timeStr) { time_t myTime; myTime = time(NULL); snprintf(timeStr, 15, "%011d", (uint) myTime); } /* Convert a Unix time value (as from getNowStr) to a local time format. */ int getLocalTimeFromRodsTime(char *timeStrIn, char *timeStr) { time_t myTime; struct tm *mytm; if (sizeof(time_t)==4) { myTime = atol(timeStrIn); } else { #ifdef _WIN32 myTime = _atoi64(timeStrIn); #else myTime = atoll(timeStrIn); #endif } mytm = localtime (&myTime); getLocalTimeStr (mytm, timeStr); return 0; } int getLocalTimeStr (struct tm *mytm, char *timeStr) { snprintf (timeStr, TIME_LEN, "%4d-%2d-%2d.%2d:%2d:%2d", mytm->tm_year + 1900, mytm->tm_mon + 1, mytm->tm_mday, mytm->tm_hour, mytm->tm_min, mytm->tm_sec); if (timeStr[5] == ' ') { timeStr[5] = '0'; } if (timeStr[8] == ' ') { timeStr[8] = '0'; } if (timeStr[11] == ' ') { timeStr[11] = '0'; } if (timeStr[14] == ' ') { timeStr[14] = '0'; } if (timeStr[17] == ' ') { timeStr[17] = '0'; } return(0); } /* Get the current time + offset , in the form: 2006-10-25-10.52.43 */ /* offset is a string of the same form */ /* 0123456789012345678 */ void getOffsetTimeStr(char *timeStr, char *offSet) { time_t myTime; myTime = time(NULL); myTime += atoi (offSet); snprintf (timeStr, NAME_LEN, "%d", (uint) myTime); } /* Update the input time string to be offset minutes ahead of the input value. timeStr is input and ouput, in the form: 2006-10-25-10.52.43 0123456789012345678 Offset the number of minutes to add. This is based on getOffsetTimeStr. YYYY - updateOffsetTimeStr - this routine is currently not used */ void updateOffsetTimeStr(char *timeStr, int offset) { time_t myTime; struct tm *mytm; time_t newTime; char s[50]; myTime = time(NULL); mytm = localtime (&myTime); rstrcpy(s,timeStr,49); s[19] = '\0'; mytm->tm_sec = atoi(&s[17]); s[16] = '\0'; mytm->tm_min = atoi(&s[14]); s[13] = '\0'; mytm->tm_hour = atoi(&s[11]); s[10] = '\0'; mytm->tm_mday = atoi(&s[8]); s[7] = '\0'; mytm->tm_mon = atoi(&s[5]) - 1; s[4] = '\0'; mytm->tm_year = atoi(&s[0]) - 1900; mytm->tm_min += offset; /* offset by the input minutes */ newTime = mktime(mytm); mytm = localtime (&newTime); snprintf (timeStr, TIME_LEN, "%4d-%2d-%2d-%2d.%2d.%2d", mytm->tm_year + 1900, mytm->tm_mon + 1, mytm->tm_mday, mytm->tm_hour, mytm->tm_min, mytm->tm_sec); if (timeStr[5] == ' ') { timeStr[5] = '0'; } if (timeStr[8] == ' ') { timeStr[8] = '0'; } if (timeStr[11] == ' ') { timeStr[11] = '0'; } if (timeStr[14] == ' ') { timeStr[14] = '0'; } if (timeStr[17] == ' ') { timeStr[17] = '0'; } } /* getNextRepeatTime - analyze the string given in delayStr to output the time * in sec of unix time in string nextTime for the next repetition based on * the current time given in string currTime. * Strings currTime and nextTime will be in sec of unix time. * The delayStr is of the format: * nnnnU where * nnnn is a number, and * U is the unit of the number (s-sec,m-min,h-hour,d-day,y-year), * The can be for the form: * - equal to REPEAT FOR EVER * REPEAT FOR EVER * REPEAT UNTIL SUCCESS * REPEAT nnnn TIMES - where nnnn is an integer * REPEAT UNTIL