示例#1
0
文件: isio.cpp 项目: 0x414A/irods
int
isioFileClose( int fileIndex ) {
    openedDataObjInp_t dataObjCloseInp;
    int i, status;

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

    /* If the buffer had been used for writing, flush it */
    status = isioFlush( fileIndex );
    if ( status < 0 ) {
        return status;
    }


    memset( &dataObjCloseInp, 0, sizeof( dataObjCloseInp ) );
    dataObjCloseInp.l1descInx = openFiles[fileIndex];

    openFiles[fileIndex] = 0;

    i = fileIndex;
    if ( cacheInfo[i].usingUsersBuffer == 'n' ) {
        if ( debug ) {
            printf( "isioFileClose calling free\n" );
        }
        free( cacheInfo[i].base );
    }

    cacheInfo[i].usingUsersBuffer = ' ';

    return rcDataObjClose( Comm, &dataObjCloseInp );
}
示例#2
0
int
closeIrodsFd( rcComm_t *conn, int fd ) {
    int status;

    openedDataObjInp_t dataObjCloseInp;

    bzero( &dataObjCloseInp, sizeof( dataObjCloseInp ) );
    dataObjCloseInp.l1descInx = fd;
    status = rcDataObjClose( conn, &dataObjCloseInp );
    return ( status );
}
示例#3
0
static int irods_close(hFILE *fpv)
{
    hFILE_irods *fp = (hFILE_irods *) fpv;
    openedDataObjInp_t args;
    int ret;

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

    ret = rcDataObjClose(irods.conn, &args);
    if (ret < 0) set_errno(ret);
    return ret;
}
示例#4
0
int irods_file_close_( int *fd ) {
    int status;
    openedDataObjInp_t dataObjCloseInp;

    if ( debug ) {
        printf( "irods_file_close fd: %d\n", *fd );
    }

    memset( &dataObjCloseInp, 0, sizeof( dataObjCloseInp ) );
    dataObjCloseInp.l1descInx = *fd;

    status = rcDataObjClose( Comm, &dataObjCloseInp );

    return status;
}
示例#5
0
int irods_reli_close    ( struct irods_file *file )
{
	int result;
	openedDataObjInp_t request;

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

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

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

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

	free(file->host);
	free(file->path);
	free(file);

	return 0;
}
示例#6
0
    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;

    }
示例#7
0
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);
} 
示例#8
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);
}
示例#9
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);
}
示例#10
0
文件: tears.c 项目: whitwham/tears
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);
}