static int connect_to_file( struct irods_server *server, struct irods_file *file ) { dataObjInp_t request; int result; if(server->serial == file->serial) return 1; memset(&request,0,sizeof(request)); strcpy(request.objPath,file->path); request.openFlags = file->flags & ~(O_CREAT|O_TRUNC|O_EXCL); debug(D_IRODS,"rcDataObjOpen %s %s",file->host,file->path); result = rcDataObjOpen(server->conn,&request); debug(D_IRODS,"= %d",result); if(result<0) { errno = irods_reli_errno(result); return 0; } file->fd = result; file->offset = 0; file->serial = server->serial; return 1; }
int irods_file_open_( char *filename, char *mode ) { int i; int status; dataObjInp_t dataObjInp; char **outPath; char *cp1, *cp2; int nameLen; if ( debug ) { printf( "irods_file_open filename input:%s:\n", filename ); } /* Remove trailing blanks from the filename */ cp1 = filename; cp2 = cp1 + strlen( filename ) - 1; for ( ; *cp2 == ' ' && cp2 > cp1; cp2-- ) { } cp2++; if ( cp2 > cp1 ) { *cp2 = '\0'; } if ( debug ) printf( "irods_file_open filename w/o trailing blanks:%s:\n", filename ); if ( setupFlag == 0 ) { status = irods_connect_(); if ( status ) { return -1; } } memset( &dataObjInp, 0, sizeof( dataObjInp ) ); status = parseRodsPathStr( filename , &myRodsEnv, dataObjInp.objPath ); if ( status < 0 ) { rodsLogError( LOG_ERROR, status, "irods_file_open" ); return -1; } /* Set the openFlags based on the input mode (incomplete * currently) // */ dataObjInp.openFlags = O_RDONLY; if ( strstr( mode, "WRITE" ) != NULL ) { dataObjInp.openFlags = O_RDWR; } /* may want a O_WRONLY mode too sometime */ status = rcDataObjOpen( Comm, &dataObjInp ); if ( status == CAT_NO_ROWS_FOUND && dataObjInp.openFlags == O_WRONLY ) { status = rcDataObjCreate( Comm, &dataObjInp ); } if ( status < 0 ) { rodsLogError( LOG_ERROR, status, "irods_file_open" ); return -1; } return status; }
hFILE *hopen_irods(const char *filename, const char *mode) { hFILE_irods *fp; rodsPath_t path; dataObjInp_t args; int ret; // Initialise the iRODS connection if this is the first use. if (irods.conn == NULL) { if (irods_init() < 0) return NULL; } if (strncmp(filename, "irods:", 6) == 0) filename += 6; else { errno = EINVAL; return NULL; } fp = (hFILE_irods *) hfile_init(sizeof (hFILE_irods), mode, 0); if (fp == NULL) return NULL; strncpy(path.inPath, filename, MAX_NAME_LEN-1); path.inPath[MAX_NAME_LEN-1] = '\0'; ret = parseRodsPath(&path, &irods.env); if (ret < 0) goto error; memset(&args, 0, sizeof args); strcpy(args.objPath, path.outPath); args.openFlags = hfile_oflags(mode); if (args.openFlags & O_CREAT) { args.createMode = 0666; addKeyVal(&args.condInput, DEST_RESC_NAME_KW,irods.env.rodsDefResource); } ret = rcDataObjOpen(irods.conn, &args); if (ret < 0) goto error; fp->descriptor = ret; fp->base.backend = &irods_backend; return &fp->base; error: hfile_destroy((hFILE *) fp); set_errno(ret); return NULL; }
FILE *isioFileOpen( char *filename, char *modes ) { int i; int status; dataObjInp_t dataObjInp; char **outPath; if ( debug ) { printf( "isioFileOpen: %s\n", filename ); } if ( setupFlag == 0 ) { status = isioSetup(); if ( status ) { return NULL; } } for ( i = ISIO_MIN_OPEN_FD; i < ISIO_MAX_OPEN_FILES; i++ ) { if ( openFiles[i] == 0 ) { break; } } if ( i >= ISIO_MAX_OPEN_FILES ) { fprintf( stderr, "Too many open files in isioFileOpen\n" ); return NULL; } memset( &dataObjInp, 0, sizeof( dataObjInp ) ); status = parseRodsPathStr( filename , &myRodsEnv, dataObjInp.objPath ); if ( status < 0 ) { rodsLogError( LOG_ERROR, status, "isioFileOpen" ); return NULL; } /* Set the openFlags based on the input mode (incomplete * currently) // */ dataObjInp.openFlags = O_RDONLY; if ( strncmp( modes, "w", 1 ) == 0 ) { dataObjInp.openFlags = O_WRONLY; /* Need to handle other cases sometime */ } if ( strncmp( modes, "r+", 2 ) == 0 ) { dataObjInp.openFlags = O_RDWR; } status = rcDataObjOpen( Comm, &dataObjInp ); if ( status == CAT_NO_ROWS_FOUND && dataObjInp.openFlags == O_WRONLY ) { status = rcDataObjCreate( Comm, &dataObjInp ); } if ( status < 0 ) { rodsLogError( LOG_ERROR, status, "isioFileOpen" ); return NULL; } openFiles[i] = status; cacheInfo[i].base = ( char * )malloc( sizeof( char ) * ISIO_INITIAL_BUF_SIZE ); if ( cacheInfo[i].base == NULL ) { fprintf( stderr, "Memory Allocation error\n" ); return NULL; } cacheInfo[i].bufferSize = sizeof( char ) * ISIO_INITIAL_BUF_SIZE; cacheInfo[i].ptr = cacheInfo[i].base; cacheInfo[i].count = 0; cacheInfo[i].usingUsersBuffer = 'n'; cacheInfo[i].written = 0; return ( FILE * )i; }
int _ifuseFileCacheWrite( fileCache_t *fileCache, char *buf, size_t size, off_t offset ) { int status, myError; openedDataObjInp_t dataObjWriteInp; bytesBuf_t dataObjWriteInpBBuf; iFuseConn_t *conn; bzero( &dataObjWriteInp, sizeof( dataObjWriteInp ) ); /* lseek to the right offset in case this cache is share by multiple descs */ status = _iFuseFileCacheLseek( fileCache, offset ); if ( status < 0 ) { if ( ( myError = getErrno( status ) ) > 0 ) { return -myError; } else { return -ENOENT; } } if ( fileCache->state == NO_FILE_CACHE ) { /* no file cache */ dataObjWriteInpBBuf.buf = ( void * ) buf; dataObjWriteInpBBuf.len = size; dataObjWriteInp.l1descInx = fileCache->iFd; dataObjWriteInp.len = size; conn = getAndUseConnByPath( fileCache->localPath, &status ); status = rcDataObjWrite( conn->conn, &dataObjWriteInp, &dataObjWriteInpBBuf ); unuseIFuseConn( conn ); if ( status < 0 ) { if ( ( myError = getErrno( status ) ) > 0 ) { return -myError; } else { return -ENOENT; } } else if ( status != ( int ) size ) { rodsLog( LOG_ERROR, "ifuseWrite: IFuseDesc[descInx].conn for %s is NULL", fileCache->localPath ); return -ENOENT; } fileCache->offset += status; if ( fileCache->offset > fileCache->fileSize ) { fileCache->fileSize = fileCache->offset; } } else { status = write( fileCache->iFd, buf, size ); if ( status < 0 ) { return errno ? ( -1 * errno ) : -1; } fileCache->offset += status; if ( fileCache->offset > fileCache->fileSize ) { fileCache->fileSize = fileCache->offset; } if ( fileCache->offset >= MAX_NEWLY_CREATED_CACHE_SIZE ) { _iFuseFileCacheFlush( fileCache ); fileCache->iFd = 0; /* reopen file */ dataObjInp_t dataObjOpenInp; memset( &dataObjOpenInp, 0, sizeof( dataObjOpenInp ) ); rstrcpy( dataObjOpenInp.objPath, fileCache->objPath, MAX_NAME_LEN ); dataObjOpenInp.openFlags = O_RDWR; int status; conn = getAndUseConnByPath( fileCache->localPath, &status ); status = rcDataObjOpen( conn->conn, &dataObjOpenInp ); unuseIFuseConn( conn ); if ( status < 0 ) { rodsLog( LOG_ERROR, "iFuseWrite: rcDataObjOpen of %s error. status = %d", fileCache->objPath, status ); return -ENOENT; } fileCache->iFd = status; } } return status; }
int msiobjget_irods( msParam_t* inRequestPath, msParam_t* inFileMode, msParam_t* inFileFlags, msParam_t* inCacheFilename, ruleExecInfo_t* rei ) { char *locStr; int mode; char *cacheFilename; char *str, *t; int status, bytesRead, bytesWritten; int destFd, i; rcComm_t *rcComm = NULL; dataObjInp_t dataObjInp; int objFD; openedDataObjInp_t dataObjReadInp; openedDataObjInp_t dataObjCloseInp; bytesBuf_t readBuf; RE_TEST_MACRO( " Calling msiobjget_irods" ); /* check for input parameters */ if ( inRequestPath == NULL || strcmp( inRequestPath->type , STR_MS_T ) != 0 || inRequestPath->inOutStruct == NULL ) { return USER_PARAM_TYPE_ERR; } if ( inFileMode == NULL || strcmp( inFileMode->type , STR_MS_T ) != 0 || inFileMode->inOutStruct == NULL ) { return USER_PARAM_TYPE_ERR; } if ( inFileFlags == NULL || strcmp( inFileFlags->type , STR_MS_T ) != 0 || inFileFlags->inOutStruct == NULL ) { return USER_PARAM_TYPE_ERR; } if ( inCacheFilename == NULL || strcmp( inCacheFilename->type , STR_MS_T ) != 0 || inCacheFilename->inOutStruct == NULL ) { return USER_PARAM_TYPE_ERR; } /* coerce input to local variables */ str = strdup( ( char * ) inRequestPath->inOutStruct ); if ( ( t = strstr( str, ":" ) ) != NULL ) { locStr = t + 1; if ( ( t = strstr( locStr, "/" ) ) != NULL ) { locStr = t; } else { free( str ); return USER_INPUT_FORMAT_ERR; } } else { free( str ); return USER_INPUT_FORMAT_ERR; } cacheFilename = ( char * ) inCacheFilename->inOutStruct; mode = atoi( ( char * ) inFileMode->inOutStruct ); /* Do the processing */ i = connectToRemoteiRODS( ( char * ) inRequestPath->inOutStruct, &rcComm ); if ( i < 0 ) { printf( "msiputobj_irods: error connecting to remote iRODS: %s:%i\n", ( char * ) inRequestPath->inOutStruct, i ); free( str ); return i; } bzero( &dataObjInp, sizeof( dataObjInp ) ); bzero( &dataObjReadInp, sizeof( dataObjReadInp ) ); bzero( &dataObjCloseInp, sizeof( dataObjCloseInp ) ); bzero( &readBuf, sizeof( readBuf ) ); dataObjInp.openFlags = O_RDONLY; rstrcpy( dataObjInp.objPath, locStr, MAX_NAME_LEN ); free( str ); objFD = rcDataObjOpen( rcComm, &dataObjInp ); if ( objFD < 0 ) { printf( "msigetobj_irods: Unable to open file %s:%i\n", dataObjInp.objPath, objFD ); rcDisconnect( rcComm ); return objFD; } destFd = open( cacheFilename, O_WRONLY | O_CREAT | O_TRUNC, mode ); if ( destFd < 0 ) { status = UNIX_FILE_OPEN_ERR - errno; printf( "msigetobj_irods: open error for cacheFilename %s, status = %d", cacheFilename, status ); rcDisconnect( rcComm ); return status; } dataObjReadInp.l1descInx = objFD; dataObjCloseInp.l1descInx = objFD; readBuf.len = MAX_SZ_FOR_SINGLE_BUF; readBuf.buf = ( char * )malloc( readBuf.len ); dataObjReadInp.len = readBuf.len; while ( ( bytesRead = rcDataObjRead( rcComm, &dataObjReadInp, &readBuf ) ) > 0 ) { bytesWritten = write( destFd, readBuf.buf, bytesRead ); if ( bytesWritten != bytesRead ) { free( readBuf.buf ); close( destFd ); rcDataObjClose( rcComm, &dataObjCloseInp ); rcDisconnect( rcComm ); printf( "msigetobj_irods: In Cache File %s bytesWritten %d != returned objLen %i\n", cacheFilename, bytesWritten, bytesRead ); return SYS_COPY_LEN_ERR; } } free( readBuf.buf ); close( destFd ); i = rcDataObjClose( rcComm, &dataObjCloseInp ); rcDisconnect( rcComm ); return i; }
struct irods_file * irods_reli_open ( const char *host, const char *path, int flags, int mode ) { struct irods_file *file; struct irods_server *server; dataObjInp_t request; int result; server = connect_to_host(host); if(!server) return 0; memset(&request,0,sizeof(request)); strcpy(request.objPath,path); request.openFlags = flags; debug(D_IRODS,"rcDataObjOpen %s %s",host,path); result = rcDataObjOpen (server->conn,&request); debug(D_IRODS,"= %d",result); if(result<0 && flags&O_CREAT) { memset(&request,0,sizeof(request)); strcpy(request.objPath,path); request.createMode = mode; request.openFlags = flags; request.dataSize = -1; addKeyVal (&request.condInput, DATA_TYPE_KW, "generic"); if(irods_env.rodsDefResource[0]) { addKeyVal (&request.condInput, RESC_NAME_KW,irods_env.rodsDefResource); } debug(D_IRODS,"rcDataObjCreate %s %s",host,path); result = rcDataObjCreate (server->conn,&request); debug(D_IRODS,"= %d",result); } /* An attempt to open a directory returns CAT_NO_ROWS_FOUND. For Unix compatibility, we must check for a directory by that name, and return EISDIR if it exists. */ if(result==CAT_NO_ROWS_FOUND) { struct pfs_stat info; if(irods_reli_stat(host,path,&info)>=0) { if(S_ISDIR(info.st_mode)) { errno = EISDIR; return 0; } } } if(result<0) { errno = irods_reli_errno(result); return 0; } if(flags&O_TRUNC) { irods_reli_truncate(host,path,0); } file = malloc(sizeof(*file)); file->host = strdup(host); file->path = strdup(path); file->fd = result; file->offset = 0; file->serial = server->serial; file->flags = flags; return file; }
int main(int argc, char **argv) { rcComm_t *conn; rodsEnv myRodsEnv; int status; rErrMsg_t errMsg; int l1descInx1; dataObjInp_t dataObjOpenInp; openedDataObjInp_t dataObjCloseInp; #if 0 dataObjInp_t dataObjCreateInp; openedDataObjInp_t dataObjWriteInp; bytesBuf_t dataObjWriteInpBBuf; openedDataObjInp_t dataObjReadInp; bytesBuf_t dataObjReadOutBBuf; dataObjInp_t dataObjOprInp; bytesBuf_t dataObjInpBBuf; struct stat statbuf; int bytesWritten, bytesRead, total; int in_fd, out_fd; openedDataObjInp_t dataObjLseekInp; fileLseekOut_t *dataObjLseekOut = NULL; dataObjCopyInp_t dataObjCopyInp; collInp_t collCreateInp; execCmd_t execCmd; execCmdOut_t *execCmdOut = NULL; char *chksumStr; char myPath[MAX_NAME_LEN], myCwd[MAX_NAME_LEN]; #endif if (argc != 2) { fprintf(stderr, "Usage: %s rods_dataObj\n",argv[0]); exit(1); } status = getRodsEnv (&myRodsEnv); if (status < 0) { fprintf (stderr, "getRodsEnv error, status = %d\n", status); exit (1); } conn = rcConnect (myRodsEnv.rodsHost, myRodsEnv.rodsPort, myRodsEnv.rodsUserName, myRodsEnv.rodsZone, 0, &errMsg); if (conn == NULL) { fprintf (stderr, "rcConnect error\n"); exit (1); } status = clientLogin(conn); if (status != 0) { fprintf (stderr, "clientLogin error\n"); rcDisconnect(conn); exit (7); } printf("--------------open file for read -----------\n"); memset (&dataObjOpenInp, 0, sizeof (dataObjOpenInp)); snprintf (dataObjOpenInp.objPath, MAX_NAME_LEN, "%s/%s", MY_HOME, argv[1]); dataObjOpenInp.openFlags = O_RDONLY; l1descInx1 = rcDataObjOpen (conn, &dataObjOpenInp); if (l1descInx1 < 0) { fprintf (stderr, "rcDataObjOpen error. status = %d\n", l1descInx1); rcDisconnect (conn); exit (1); } else { printf ("rcDataObjOpen: l1descInx1 = %d\n", l1descInx1); } printf("--------------end of open file Read -----------\n"); /* close the files */ memset (&dataObjCloseInp, 0, sizeof (dataObjCloseInp)); dataObjCloseInp.l1descInx = l1descInx1; status = rcDataObjClose (conn, &dataObjCloseInp); if (status < 0 ) { fprintf (stderr, "rcDataObjClose of %d error, status = %d\n", l1descInx1, status); exit (1); } else { printf ("rcDataObjClose: status = %d\n", status); } printf("--------------open file for write ----------\n"); memset (&dataObjOpenInp, 0, sizeof (dataObjOpenInp)); snprintf (dataObjOpenInp.objPath, MAX_NAME_LEN, "%s/%s", MY_HOME, argv[1]); dataObjOpenInp.openFlags = O_WRONLY; l1descInx1 = rcDataObjOpen (conn, &dataObjOpenInp); if (l1descInx1 < 0) { fprintf (stderr, "rcDataObjOpen error. status = %d\n", l1descInx1); rcDisconnect (conn); exit (1); } else { printf ("rcDataObjOpen: l1descInx1 = %d\n", l1descInx1); } printf("--------------end of open file for write ---------\n"); status = rcDataObjClose (conn, &dataObjCloseInp); if (status < 0 ) { fprintf (stderr, "rcDataObjClose of %d error, status = %d\n", l1descInx1, status); exit (1); } else { printf ("rcDataObjClose: status = %d\n", status); } rcDisconnect (conn); exit (0); }
int irodsOpen (const char *path, struct fuse_file_info *fi) { dataObjInp_t dataObjInp; int status; int fd; iFuseConn_t *iFuseConn = NULL; iFuseDesc_t *desc = NULL; pathCache_t *tmpPathCache = NULL; struct stat stbuf; char cachePath[MAX_NAME_LEN]; char objPath[MAX_NAME_LEN]; int flags = fi->flags; rodsLog (LOG_DEBUG, "irodsOpen: %s, flags = %d", path, fi->flags); matchAndLockPathCache((char *) path, &tmpPathCache); if(tmpPathCache!= NULL) { if(tmpPathCache->fileCache != NULL) { LOCK_STRUCT(*(tmpPathCache->fileCache)); if (tmpPathCache->fileCache->state != NO_FILE_CACHE) { rodsLog (LOG_DEBUG, "irodsOpen: a match for %s", path); desc = newIFuseDesc(tmpPathCache->fileCache->objPath, (char *) path, tmpPathCache->fileCache, &status); if (status < 0) { UNLOCK_STRUCT(*(tmpPathCache->fileCache)); UNLOCK_STRUCT(*tmpPathCache); rodsLogError (LOG_ERROR, status, "irodsOpen: create descriptor of %s error", dataObjInp.objPath); return status; } fi->fh = desc->index; if(tmpPathCache->fileCache->iFd == 0) { tmpPathCache->fileCache->iFd = open(tmpPathCache->fileCache->fileCachePath, O_RDWR); } UNLOCK_STRUCT(*(tmpPathCache->fileCache)); UNLOCK_STRUCT(*tmpPathCache); return (0); } UNLOCK_STRUCT(*(tmpPathCache->fileCache)); } UNLOCK_STRUCT(*tmpPathCache); } memset (&dataObjInp, 0, sizeof (dataObjInp)); dataObjInp.openFlags = flags; status = parseRodsPathStr ((char *) (path + 1) , &MyRodsEnv, objPath); rstrcpy(dataObjInp.objPath, objPath, MAX_NAME_LEN); if (status < 0) { rodsLogError (LOG_ERROR, status, "irodsOpen: parseRodsPathStr of %s error", path); /* use ENOTDIR for this type of error */ return -ENOTDIR; } iFuseConn = getAndUseConnByPath((char *) path, &MyRodsEnv, &status); /* status = getAndUseIFuseConn(&iFuseConn, &MyRodsEnv); */ if(status < 0) { rodsLogError (LOG_ERROR, status, "irodsOpen: cannot get connection for %s error", path); /* use ENOTDIR for this type of error */ return -ENOTDIR; } /* do only O_RDONLY (0) */ status = _irodsGetattr (iFuseConn, path, &stbuf); if ((flags & (O_WRONLY | O_RDWR)) != 0 || status < 0 || stbuf.st_size > MAX_READ_CACHE_SIZE) { fd = rcDataObjOpen (iFuseConn->conn, &dataObjInp); unuseIFuseConn (iFuseConn); if (fd < 0) { rodsLogError (LOG_ERROR, status, "irodsOpen: rcDataObjOpen of %s error, status = %d", path, fd); return -ENOENT; } fileCache_t *fileCache = addFileCache(fd, objPath, (char *) path, NULL, stbuf.st_mode, stbuf.st_size, NO_FILE_CACHE); matchAndLockPathCache((char *) path, &tmpPathCache); if(tmpPathCache == NULL) { pathExist((char *) path, fileCache, &stbuf, NULL); } else { _addFileCacheForPath(tmpPathCache, fileCache); UNLOCK_STRUCT(*tmpPathCache); } desc = newIFuseDesc (objPath, (char *) path, fileCache, &status); if (desc == NULL) { rodsLogError (LOG_ERROR, status, "irodsOpen: allocIFuseDesc of %s error", path); return -ENOENT; } } else { rodsLog (LOG_DEBUG, "irodsOpenWithReadCache: caching %s", path); if ((status = getFileCachePath (path, cachePath)) < 0) { unuseIFuseConn(iFuseConn); return status; } /* get the file to local cache */ dataObjInp.dataSize = stbuf.st_size; status = rcDataObjGet (iFuseConn->conn, &dataObjInp, cachePath); unuseIFuseConn(iFuseConn); if (status < 0) { rodsLogError (LOG_ERROR, status, "irodsOpenWithReadCache: rcDataObjGet of %s error", dataObjInp.objPath); return status; } int fd = open(cachePath, O_RDWR); fileCache_t *fileCache = addFileCache(fd, objPath, (char *) path, cachePath, stbuf.st_mode, stbuf.st_size, HAVE_READ_CACHE); matchAndLockPathCache((char *) path, &tmpPathCache); if(tmpPathCache == NULL) { pathExist((char *) path, fileCache, &stbuf, NULL); } else { _addFileCacheForPath(tmpPathCache, fileCache); UNLOCK_STRUCT(*tmpPathCache); } desc = newIFuseDesc(objPath, (char *) path,fileCache, &status); if (status < 0) { rodsLogError (LOG_ERROR, status, "irodsOpen: create descriptor of %s error", dataObjInp.objPath); return status; } } fi->fh = desc->index; return (0); }
int irodsSymlink (const char *to, const char *from) { int status; iFuseConn_t *iFuseConn = NULL; int l1descInx; dataObjInp_t dataObjOpenInp; openedDataObjInp_t dataObjWriteInp; bytesBuf_t dataObjWriteOutBBuf; char collPath[MAX_NAME_LEN]; struct stat stbuf; rodsLog (LOG_DEBUG, "irodsSymlink: %s to %s", from, to); status = parseRodsPathStr ((char *) (from + 1), &MyRodsEnv, collPath); if (status < 0) { rodsLogError (LOG_ERROR, status, "irodsReaddir: parseRodsPathStr of %s error", from); /* use ENOTDIR for this type of error */ return -ENOTDIR; } iFuseConn = getAndUseConnByPath ((char *) from, &MyRodsEnv, &status); status = _irodsGetattr(iFuseConn, (char *) from, &stbuf); memset (&dataObjOpenInp, 0, sizeof (dataObjOpenInp)); rstrcpy (dataObjOpenInp.objPath, collPath, MAX_NAME_LEN); if(status != -ENOENT) { if (status < 0) { return status; } dataObjOpenInp.dataSize = 0; status = rcDataObjTruncate(iFuseConn->conn, &dataObjOpenInp); if (status < 0) { rodsLog (LOG_ERROR, "irodsReadlink: rcDataObjTruncate of %s error. status = %d", collPath, status); unuseIFuseConn (iFuseConn); return -ENOENT; } } memset (&dataObjOpenInp, 0, sizeof (dataObjOpenInp)); rstrcpy (dataObjOpenInp.objPath, collPath, MAX_NAME_LEN); dataObjOpenInp.openFlags = O_WRONLY | O_CREAT; dataObjOpenInp.createMode = S_IFLNK; status = rcDataObjOpen (iFuseConn->conn, &dataObjOpenInp); if (status < 0) { rodsLog (LOG_ERROR, "irodsSymlink: rcDataObjOpen of %s error. status = %d", collPath, status); unuseIFuseConn (iFuseConn); return -ENOENT; } l1descInx = status; memset(&dataObjWriteInp, 0, sizeof (dataObjWriteInp)); memset(&dataObjWriteOutBBuf, 0, sizeof (bytesBuf_t)); dataObjWriteInp.l1descInx = l1descInx; dataObjWriteInp.len = strlen(to); dataObjWriteOutBBuf.len = strlen(to); dataObjWriteOutBBuf.buf = strdup(to); status = rcDataObjWrite (iFuseConn->conn, &dataObjWriteInp, &dataObjWriteOutBBuf); free(dataObjWriteOutBBuf.buf); if (status < 0) { rodsLog (LOG_ERROR, "irodsSymlink: rcDataObjWrite of %s error. status = %d", collPath, status); unuseIFuseConn (iFuseConn); return -ENOENT; } rcDataObjClose(iFuseConn->conn, &dataObjWriteInp); unuseIFuseConn (iFuseConn); return (0); }
int irodsReadlink (const char *path, char *buf, size_t size) { int status; iFuseConn_t *iFuseConn = NULL; int l1descInx; dataObjInp_t dataObjOpenInp; openedDataObjInp_t dataObjReadInp; bytesBuf_t dataObjReadOutBBuf; char collPath[MAX_NAME_LEN]; rodsLog (LOG_DEBUG, "irodsReadlink: %s", path); status = parseRodsPathStr ((char *) (path + 1), &MyRodsEnv, collPath); if (status < 0) { rodsLogError (LOG_ERROR, status, "irodsReaddir: parseRodsPathStr of %s error", path); /* use ENOTDIR for this type of error */ return -ENOTDIR; } iFuseConn = getAndUseConnByPath ((char *) path, &MyRodsEnv, &status); memset (&dataObjOpenInp, 0, sizeof (dataObjOpenInp)); rstrcpy (dataObjOpenInp.objPath, collPath, MAX_NAME_LEN); dataObjOpenInp.openFlags = O_RDONLY; status = rcDataObjOpen (iFuseConn->conn, &dataObjOpenInp); if (status < 0) { if (isReadMsgError (status)) { ifuseReconnect (iFuseConn); status = rcDataObjOpen (iFuseConn->conn, &dataObjOpenInp); } if (status < 0) { rodsLog (LOG_ERROR, "irodsReadlink: rcDataObjOpen of %s error. status = %d", collPath, status); unuseIFuseConn (iFuseConn); return -ENOENT; } } l1descInx = status; memset(&dataObjReadInp, 0, sizeof (dataObjReadInp)); memset(&dataObjReadOutBBuf, 0, sizeof (bytesBuf_t)); dataObjReadInp.l1descInx = l1descInx; dataObjReadInp.len = size - 1; status = rcDataObjRead(iFuseConn->conn, &dataObjReadInp, &dataObjReadOutBBuf); if (status < 0) { rodsLog (LOG_ERROR, "irodsReadlink: rcDataObjRead of %s error. status = %d", collPath, status); unuseIFuseConn (iFuseConn); return -ENOENT; } memcpy(buf, dataObjReadOutBBuf.buf, status); buf[status] = '\0'; rcDataObjClose(iFuseConn->conn, &dataObjReadInp); unuseIFuseConn (iFuseConn); return (0); }
/************************************************************************** * private functions **************************************************************************/ static int _commitLocalBuffer(const char *iRODSPath, struct fuse_file_info *fi, lazyUploadFileInfo_t *lazyUploadFileInfo) { int status; int desc; char bufferPath[MAX_NAME_LEN]; int descInx; status = _getBufferPath(iRODSPath, bufferPath); if(status < 0) { rodsLog (LOG_DEBUG, "_upload: failed to get Buffered lazy upload file path - %s", iRODSPath); return status; } // close local buffer file handle if(lazyUploadFileInfo->localHandle < 0) { rodsLog (LOG_DEBUG, "_commitLocalBuffer: wrong file descriptor - %s, %d", iRODSPath, lazyUploadFileInfo->localHandle); return -EBADF; } // no write but requested flush if(lazyUploadFileInfo->curOffset == 0) { return 0; } fsync(lazyUploadFileInfo->localHandle); close(lazyUploadFileInfo->localHandle); lazyUploadFileInfo->localHandle = -1; rodsLog (LOG_DEBUG, "_commitLocalBuffer: upload - %s", iRODSPath); if(lazyUploadFileInfo->commitCount == 0) { // put and reopen iRODS file dataObjInp_t dataObjInp; int fd; pathCache_t *tmpPathCache = NULL; iFuseConn_t *iFuseConn = NULL; iFuseDesc_t *desc = NULL; struct stat stbuf; char objPath[MAX_NAME_LEN]; descInx = GET_IFUSE_DESC_INDEX(fi); rodsLog (LOG_DEBUG, "_commitLocalBuffer: closing existing iRODS file handle - %s - %d", iRODSPath, descInx); status = ifuseClose (&IFuseDesc[descInx]); if (status < 0) { int myError; if ((myError = getErrno (status)) > 0) { return (-myError); } else { return -ENOENT; } } // put rodsLog (LOG_DEBUG, "_commitLocalBuffer: uploading buffered file - %s", iRODSPath); status = _upload(iRODSPath); if(status != 0) { rodsLog (LOG_DEBUG, "_commitLocalBuffer: upload error - %s, %d", iRODSPath, status); return status; } // reopen file rodsLog (LOG_DEBUG, "_commitLocalBuffer: reopening iRODS file handle - %s", iRODSPath); memset (&dataObjInp, 0, sizeof (dataObjInp)); //dataObjInp.openFlags = lazyUploadFileInfo->accmode; dataObjInp.openFlags = O_RDWR | O_APPEND; status = parseRodsPathStr ((char *) iRODSPath, LazyUploadRodsEnv, objPath); rstrcpy(dataObjInp.objPath, objPath, MAX_NAME_LEN); if (status < 0) { rodsLogError (LOG_ERROR, status, "_commitLocalBuffer: parseRodsPathStr of %s error", iRODSPath); /* use ENOTDIR for this type of error */ return -ENOTDIR; } iFuseConn = getAndUseConnByPath((char *) iRODSPath, &status); /* status = getAndUseIFuseConn(&iFuseConn); */ if(status < 0) { rodsLogError (LOG_ERROR, status, "_commitLocalBuffer: cannot get connection for %s error", iRODSPath); /* use ENOTDIR for this type of error */ return -ENOTDIR; } status = _irodsGetattr (iFuseConn, iRODSPath, &stbuf); fd = rcDataObjOpen (iFuseConn->conn, &dataObjInp); unuseIFuseConn (iFuseConn); if (fd < 0) { rodsLogError (LOG_ERROR, status, "_commitLocalBuffer: rcDataObjOpen of %s error, status = %d", iRODSPath, fd); return -ENOENT; } fileCache_t *fileCache = addFileCache(fd, objPath, (char *) iRODSPath, NULL, stbuf.st_mode, stbuf.st_size, NO_FILE_CACHE); matchAndLockPathCache(pctable, (char *) iRODSPath, &tmpPathCache); if(tmpPathCache == NULL) { pathExist(pctable, (char *) iRODSPath, fileCache, &stbuf, NULL); } else { _addFileCacheForPath(tmpPathCache, fileCache); UNLOCK_STRUCT(*tmpPathCache); } desc = newIFuseDesc (objPath, (char *) iRODSPath, fileCache, &status); if (desc == NULL) { rodsLogError (LOG_ERROR, status, "_commitLocalBuffer: allocIFuseDesc of %s error", iRODSPath); return -ENOENT; } SET_IFUSE_DESC_INDEX(fi, desc->index); rodsLog (LOG_DEBUG, "_commitLocalBuffer: created new file handle - %s - %d", iRODSPath, desc->index); } else { // append int localDesc = open (bufferPath, O_RDONLY, 0755); char *buffer = (char*)malloc(FUSE_LAZY_UPLOAD_MEM_BUFFER_SIZE); int grandTotalReadLen = 0; if(localDesc < 0) { rodsLog (LOG_DEBUG, "_commitLocalBuffer: file descriptor error - %s, %d", iRODSPath, localDesc); return -ENOENT; } descInx = GET_IFUSE_DESC_INDEX(fi); if (checkFuseDesc (descInx) < 0) { return -EBADF; } status = 0; while(grandTotalReadLen < lazyUploadFileInfo->curOffset) { int totalReadLen = 0; int totalWriteLen = 0; while(totalReadLen < FUSE_LAZY_UPLOAD_MEM_BUFFER_SIZE) { int readLen = read(localDesc, buffer + totalReadLen, FUSE_LAZY_UPLOAD_MEM_BUFFER_SIZE - totalReadLen); if(readLen > 0) { totalReadLen += readLen; } else if(readLen == 0) { // EOF break; } else if(readLen < 0) { rodsLog (LOG_DEBUG, "_commitLocalBuffer: buffered file read error - %s, %d", iRODSPath, localDesc); status = getErrno (readLen); break; } } if(status >= 0) { while(totalWriteLen < totalReadLen) { int writeLen = _ifuseWrite (&IFuseDesc[descInx], buffer + totalWriteLen, totalReadLen - totalWriteLen, lazyUploadFileInfo->curLocalOffsetStart + totalWriteLen); if(writeLen > 0) { totalWriteLen += writeLen; } else if(writeLen == 0) { // EOF break; } else if(writeLen < 0) { rodsLog (LOG_DEBUG, "_commitLocalBuffer: iRODS file write error - %s", iRODSPath); status = getErrno (writeLen); break; } } } grandTotalReadLen += totalReadLen; } unlockDesc (descInx); free(buffer); close(localDesc); } rodsLog (LOG_DEBUG, "_commitLocalBuffer: reset local buffered file - %s", iRODSPath); // reset local buffer file desc = open (bufferPath, O_RDWR|O_CREAT|O_TRUNC, 0755); lazyUploadFileInfo->localHandle = desc; lazyUploadFileInfo->commitCount++; lazyUploadFileInfo->curLocalOffsetStart += lazyUploadFileInfo->curOffset; lazyUploadFileInfo->curOffset = 0; return (0); }
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); }