Beispiel #1
0
int
isioFlush( int fileIndex ) {
    int i;
    int status;
    openedDataObjInp_t dataObjWriteInp;
    bytesBuf_t dataObjWriteOutBBuf;

    i = fileIndex;
    if ( debug ) {
        printf( "isioFlush: %d\n", i );
    }
    if ( cacheInfo[i].written > 0 ) {

        dataObjWriteOutBBuf.buf = cacheInfo[i].base;
        dataObjWriteOutBBuf.len = cacheInfo[i].written;

        memset( &dataObjWriteInp, 0, sizeof( dataObjWriteInp ) );

        dataObjWriteInp.l1descInx = openFiles[fileIndex];
        dataObjWriteInp.len = cacheInfo[i].written;

        if ( debug ) printf( "isioFlush: writing %d\n",
                                 cacheInfo[i].written );
        status = rcDataObjWrite( Comm, &dataObjWriteInp,
                                 &dataObjWriteOutBBuf );
        if ( status >= 0 ) {
            cacheInfo[i].ptr = cacheInfo[i].base;
            cacheInfo[i].written = 0;
        }
        return status;

    }
    return 0;
}
Beispiel #2
0
int
irods_file_write_( int *fd, void *buffer, int *size ) {
    openedDataObjInp_t dataObjWriteInp;
    bytesBuf_t dataObjWriteOutBBuf;
    int status;
    char *cp1;

    if ( debug ) {
        printf( "irods_file_write_\n" );
    }

    dataObjWriteOutBBuf.buf = buffer;
    dataObjWriteOutBBuf.len = *size;

    memset( &dataObjWriteInp, 0, sizeof( dataObjWriteInp ) );

    dataObjWriteInp.l1descInx = *fd;
    dataObjWriteInp.len = *size;

    status = rcDataObjWrite( Comm, &dataObjWriteInp,
                             &dataObjWriteOutBBuf );

    if ( debug ) {
        printf( "irods_file_write_ rcDataObjWrite stat: %d\n", status );
    }

    return status;
}
Beispiel #3
0
int irods_reli_pwrite    ( struct irods_file *file, const char *data, int length, INT64_T offset )
{
	int result;
	openedDataObjInp_t request;
	bytesBuf_t        response;

	struct irods_server *server = connect_to_host(file->host);
	if(!server) return -1;

	if(!connect_to_file(server,file)) return -1;

	if(irods_reli_lseek_if_needed(file,offset)<0) return -1;

	memset(&request,0,sizeof(request));
	request.l1descInx = file->fd;
	request.len = length;

	response.buf = (char*)data;
	response.len = length;

	debug(D_IRODS,"rcDataObjWrite %s %d %d",file->host,file->fd,length);
	result = rcDataObjWrite(server->conn,&request,&response);
	debug(D_IRODS,"= %d",result);

	if(result<0) {
		errno = irods_reli_errno(result);
		return -1;
	}

	file->offset += result;

	return result;
}
Beispiel #4
0
static ssize_t irods_write(hFILE *fpv, const void *buffer, size_t nbytes)
{
    hFILE_irods *fp = (hFILE_irods *) fpv;
    openedDataObjInp_t args;
    bytesBuf_t buf;
    int ret;

    memset(&args, 0, sizeof args);
    args.l1descInx = fp->descriptor;
    args.len = nbytes;

    buf.buf = (void *) buffer; // ...the iRODS API is not const-correct here
    buf.len = nbytes;

    ret = rcDataObjWrite(irods.conn, &args, &buf);
    if (ret < 0) set_errno(ret);
    return ret;
}
Beispiel #5
0
int
isioFileWrite( int fileIndex, void *buffer, int countToWrite ) {
    int status;
    int spaceInBuffer;
    int newBufSize;

    openedDataObjInp_t dataObjWriteInp;
    bytesBuf_t dataObjWriteOutBBuf;

    if ( debug ) {
        printf( "isioFileWrite: %d\n", fileIndex );
    }

    if ( cacheInfo[fileIndex].count > 0 ) {
        /* buffer has read data in it, so seek to where the
           the app thinks the pointer is and disgard the buffered
           read data */
        long offset;
        offset = - cacheInfo[fileIndex].count;
        status = isioFileSeek( fileIndex, offset, SEEK_CUR );
        if ( status ) {
            return status;
        }
        cacheInfo[fileIndex].ptr = cacheInfo[fileIndex].base;
        cacheInfo[fileIndex].count = 0;
    }

    spaceInBuffer = cacheInfo[fileIndex].bufferSize -
                    cacheInfo[fileIndex].written;

    if ( debug ) {
        printf( "isioFileWrite: spaceInBuffer %d\n", spaceInBuffer );
    }
    if ( countToWrite < spaceInBuffer ) {
        /* Fits in the buffer, just cache it */
        if ( debug ) printf( "isioFileWrite: caching 1 %x %d\n",
                                 ( int ) cacheInfo[fileIndex].ptr, countToWrite );
        memcpy( cacheInfo[fileIndex].ptr, buffer, countToWrite );
        cacheInfo[fileIndex].ptr += countToWrite;
        cacheInfo[fileIndex].written += countToWrite;
        return countToWrite;
    }

    status = isioFlush( fileIndex ); /* if anything is buffered, flush it */
    if ( status < 0 ) {
        return status;
    }

    if ( countToWrite > ISIO_MAX_BUF_SIZE ) {
        /* Too big to cache, just send it */
        dataObjWriteOutBBuf.buf = buffer;
        dataObjWriteOutBBuf.len = countToWrite;

        memset( &dataObjWriteInp, 0, sizeof( dataObjWriteInp ) );

        dataObjWriteInp.l1descInx = openFiles[fileIndex];
        dataObjWriteInp.len = countToWrite;

        status = rcDataObjWrite( Comm, &dataObjWriteInp,
                                 &dataObjWriteOutBBuf );
        if ( debug ) {
            printf( "isioFileWrite: rcDataWrite 2 %d\n", status );
        }
        if ( status < 0 ) {
            return status;
        }

        return ( status ); /* total bytes written */
    }

    newBufSize = ( 2 * countToWrite ) + 8; /* Possible next size */
    if ( newBufSize > ISIO_MAX_BUF_SIZE ) {
        newBufSize = ISIO_MAX_BUF_SIZE;
    }

    if ( newBufSize > cacheInfo[fileIndex].bufferSize ) {
        /* free old and make new larger buffer */
        int i = fileIndex;
        if ( cacheInfo[i].usingUsersBuffer == 'n' ) {
            if ( debug ) {
                printf( "isioFilewrite calling free\n" );
            }
            free( cacheInfo[i].base );
        }
        if ( debug ) printf( "isioFilewrite calling malloc %d\n",
                                 newBufSize );
        cacheInfo[i].base = ( char * )malloc( newBufSize );
        if ( cacheInfo[i].base == NULL ) {
            fprintf( stderr, "Memory Allocation error\n" );
            return 0;
        }
        cacheInfo[i].bufferSize = newBufSize;
        cacheInfo[i].usingUsersBuffer = 'n';
        cacheInfo[i].ptr = cacheInfo[i].base;
    }

    /* Now it fits in the buffer, so cache it */
    if ( debug ) printf( "isioFileWrite: caching 2 %x %d\n",
                             ( int ) cacheInfo[fileIndex].ptr, countToWrite );
    memcpy( cacheInfo[fileIndex].ptr, buffer, countToWrite );
    cacheInfo[fileIndex].ptr += countToWrite;
    cacheInfo[fileIndex].count -= countToWrite; //??
    cacheInfo[fileIndex].written += countToWrite;
    return countToWrite;

}
Beispiel #6
0
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;
}
Beispiel #7
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);
}
Beispiel #8
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);
}