/** Forces any buffered output bytes to be written. */ void flush() // @B2A - code relocated from IFSFileOutputStreamImplRemote,etc. throws IOException, AS400SecurityException { // Request that changes be committed to disk. IFSCommitReq req = new IFSCommitReq(fileHandle_); ClientAccessDataStream ds = null; try { ds = (ClientAccessDataStream) server_.sendAndReceive(req); } catch (ConnectionDroppedException e) { Trace.log(Trace.ERROR, "Byte stream server connection lost"); connectionDropped(e); } catch (InterruptedException e) { Trace.log(Trace.ERROR, "Interrupted", e); throw new InterruptedIOException(e.getMessage()); } // Verify that the request was successful. if (ds instanceof IFSReturnCodeRep) { int rc = ((IFSReturnCodeRep) ds).getReturnCode(); if (rc != IFSReturnCodeRep.SUCCESS) { throwSecurityExceptionIfAccessDenied(path_, rc); // check for "access denied" Trace.log(Trace.ERROR, "IFSReturnCodeRep return code", descriptionForReturnCode(rc)); throw new ExtendedIOException(path_, rc); } } else { // Unknown data stream. Trace.log(Trace.ERROR, "Unknown reply data stream", ds.data_); throw new InternalErrorException( Integer.toHexString(ds.getReqRepID()), InternalErrorException.DATA_STREAM_UNKNOWN); } }
/** Copies a file or directory to another file or directory. */ boolean copyTo(String destinationPath, boolean replace) throws AS400SecurityException, IOException { ClientAccessDataStream ds = null; IFSCopyReq req = new IFSCopyReq(path_, destinationPath, replace); try { ds = (ClientAccessDataStream) server_.sendAndReceive(req); } catch (ConnectionDroppedException e) { Trace.log(Trace.ERROR, "Byte stream connection lost during copy", e); connectionDropped(e); } catch (InterruptedException e) { Trace.log(Trace.ERROR, "Interrupted", e); throw new InterruptedIOException(e.getMessage()); } if (ds instanceof IFSReturnCodeRep) { int rc = ((IFSReturnCodeRep) ds).getReturnCode(); if (rc != IFSReturnCodeRep.SUCCESS) { String path = (rc == IFSReturnCodeRep.DUPLICATE_DIR_ENTRY_NAME ? destinationPath : path_); throwSecurityExceptionIfAccessDenied(path, rc); // check for "access denied" Trace.log(Trace.ERROR, "IFSReturnCodeRep return code", descriptionForReturnCode(rc)); throw new ExtendedIOException(path, rc); } return true; } else { Trace.log(Trace.ERROR, "Unknown reply data stream", ds.data_); throw new InternalErrorException( Integer.toHexString(ds.getReqRepID()), InternalErrorException.DATA_STREAM_UNKNOWN); } }
void close(int fileHandle) throws IOException { if (fileHandle == UNINITIALIZED) return; // @B8c // Close the file. Send a close request to the server. ClientAccessDataStream ds = null; IFSCloseReq req = new IFSCloseReq(fileHandle); try { ds = (ClientAccessDataStream) server_.sendAndReceive(req); } catch (ConnectionDroppedException e) { Trace.log(Trace.ERROR, "Byte stream connection lost during close", e); connectionDropped(e); } catch (InterruptedException e) { Trace.log(Trace.ERROR, "Interrupted", e); throw new InterruptedIOException(e.getMessage()); } // Validate the reply. if (ds instanceof IFSCloseRep) { int rc = ((IFSCloseRep) ds).getReturnCode(); if (rc != 0) { Trace.log(Trace.ERROR, "IFSCloseRep return code", rc); throw new ExtendedIOException(path_, rc); } } else if (ds instanceof IFSReturnCodeRep) { int rc = ((IFSReturnCodeRep) ds).getReturnCode(); if (rc != IFSReturnCodeRep.SUCCESS) { Trace.log(Trace.ERROR, "IFSReturnCodeRep return code", descriptionForReturnCode(rc)); throw new ExtendedIOException(path_, rc); } } else { Trace.log(Trace.ERROR, "Unknown reply data stream", ds.data_); throw new InternalErrorException( Integer.toHexString(ds.getReqRepID()), InternalErrorException.DATA_STREAM_UNKNOWN); } }
// @B8a boolean setLength(long length) throws IOException, AS400SecurityException { // Assume that we are connected to the server. // Prepare to issue a 'change attributes' request. ClientAccessDataStream ds = null; int fileHandle = UNINITIALIZED; try { // Open the file for read/write, get a file handle, and call 'change attributes'. fileHandle = createFileHandle(IFSOpenReq.WRITE_ACCESS, IFSOpenReq.OPEN_OPTION_FAIL_OPEN); if (fileHandle == UNINITIALIZED) { if (Trace.traceOn_) Trace.log( Trace.ERROR, "Unable to create handle to file " + path_ + ". IFSReturnCodeRep return code", errorRC_); return false; } IFSChangeAttrsReq req = new IFSChangeAttrsReq(fileHandle, length, serverDatastreamLevel_); ds = (ClientAccessDataStream) server_.sendAndReceive(req); } catch (ConnectionDroppedException e) { Trace.log(Trace.ERROR, "Byte stream server connection lost."); connectionDropped(e); } catch (InterruptedException e) { Trace.log(Trace.ERROR, "Interrupted"); throw new InterruptedIOException(e.getMessage()); } finally { close(fileHandle); // we don't need this handle anymore } // Verify the reply. boolean success = false; if (ds instanceof IFSReturnCodeRep) { int rc = ((IFSReturnCodeRep) ds).getReturnCode(); if (rc == IFSReturnCodeRep.SUCCESS) success = true; else { throwSecurityExceptionIfAccessDenied(path_, rc); // check for "access denied" Trace.log( Trace.ERROR, path_ + ": IFSReturnCodeRep return code", descriptionForReturnCode(rc)); } } else { // Unknown data stream. Trace.log(Trace.ERROR, "Unknown reply data stream", ds.data_); throw new InternalErrorException( Integer.toHexString(ds.getReqRepID()), InternalErrorException.DATA_STREAM_UNKNOWN); } // Back off the file pointer if needed. if (fileOffset_ > length) { fileOffset_ = length; } return success; }
// Opens the file with specified access and option, and returns a file handle. // If failure, sets errorRC_ and returns UNINITIALIZED. int createFileHandle(int access, int openOption) // @D1C @B8c throws IOException, AS400SecurityException { int returnCode = IFSReturnCodeRep.FILE_NOT_FOUND; int fileHandle = UNINITIALIZED; errorRC_ = 0; // Try to open the file for the specified type of access. try { // Process an open file request. // For 3rd parm (file data CCSID), specify 0 since we don't care about CCSID. IFSOpenReq req = new IFSOpenReq( getPathnameAsBytes(), preferredServerCCSID_, 0, access, IFSOpenReq.DENY_NONE, IFSOpenReq.NO_CONVERSION, openOption, serverDatastreamLevel_); // @D1C ClientAccessDataStream ds = (ClientAccessDataStream) server_.sendAndReceive(req); if (ds instanceof IFSOpenRep) { // The open was successful. Close the file if appropriate. returnCode = IFSReturnCodeRep.SUCCESS; fileHandle = ((IFSOpenRep) ds).getFileHandle(); // @B8a } else if (ds instanceof IFSReturnCodeRep) { returnCode = ((IFSReturnCodeRep) ds).getReturnCode(); throwSecurityExceptionIfAccessDenied(path_, returnCode); // check for "access denied" } else { // Unknown data stream. Trace.log(Trace.ERROR, "Unknown reply data stream", ds.data_); throw new InternalErrorException( Integer.toHexString(ds.getReqRepID()), InternalErrorException.DATA_STREAM_UNKNOWN); } } catch (ConnectionDroppedException e) { Trace.log(Trace.ERROR, "Byte stream server connection lost", e); connectionDropped(e); } catch (InterruptedException e) { Trace.log(Trace.ERROR, "Interrupted", e); throw new InterruptedIOException(e.getMessage()); } if (returnCode != IFSReturnCodeRep.SUCCESS) { if (Trace.isTraceOn() && Trace.isTraceDiagnosticOn()) { Trace.log( Trace.DIAGNOSTIC, "Unable to open file " + path_ + ": " + "IFSReturnCodeRep return code", descriptionForReturnCode(returnCode)); } errorRC_ = returnCode; return UNINITIALIZED; } return fileHandle; }
IFSKey lock( long offset, // @B2A - code relocated from IFSFileOutputStreamImplRemote,etc. long length) throws IOException, AS400SecurityException { // Assume the arguments have been validated by the caller. // Attempt to lock the file. ClientAccessDataStream ds = null; try { // Issue a mandatory, exclusive lock bytes request. Mandatory // means that the file system enforces the lock by causing any // operation which conflicts with the lock to fail. Exclusive // means that only the owner of the lock can read or write the // locked area. IFSLockBytesReq req = new IFSLockBytesReq(fileHandle_, true, false, offset, length, serverDatastreamLevel_); ds = (ClientAccessDataStream) server_.sendAndReceive(req); } catch (ConnectionDroppedException e) { Trace.log(Trace.ERROR, "Byte stream server connection lost"); connectionDropped(e); } catch (InterruptedException e) { Trace.log(Trace.ERROR, "Interrupted", e); throw new InterruptedIOException(e.getMessage()); } // Verify the reply. if (ds instanceof IFSLockBytesRep) { int rc = ((IFSLockBytesRep) ds).getReturnCode(); if (rc != 0) { Trace.log(Trace.ERROR, "IFSLockBytesRep return code", rc); throw new ExtendedIOException(path_, rc); } } else if (ds instanceof IFSReturnCodeRep) { int rc = ((IFSReturnCodeRep) ds).getReturnCode(); if (rc != IFSReturnCodeRep.SUCCESS) { throwSecurityExceptionIfAccessDenied(path_, rc); // check for "access denied" Trace.log(Trace.ERROR, "IFSReturnCodeRep return code", descriptionForReturnCode(rc)); throw new ExtendedIOException(path_, rc); } } else { // Unknown data stream. Trace.log(Trace.ERROR, "Unknown reply data stream", ds.data_); throw new InternalErrorException( Integer.toHexString(ds.getReqRepID()), InternalErrorException.DATA_STREAM_UNKNOWN); } // Generate the key for this lock. IFSKey key = new IFSKey(fileHandle_, offset, length, true); return key; }
/** * Undoes a lock on this file. * * @param key The key for the lock. * @exception IOException If an error occurs while communicating with the server. * @see IFSKey * @see #lock */ void unlock(IFSKey key) // @B2A - code relocated from IFSFileOutputStreamImplRemote,etc. throws IOException, AS400SecurityException { // Assume the argument has been validated by the caller. // Verify that this key is compatible with this file. if (key.fileHandle_ != fileHandle_) { Trace.log(Trace.ERROR, "Attempt to use IFSKey on different file stream."); throw new ExtendedIllegalArgumentException( "key", ExtendedIllegalArgumentException.PARAMETER_VALUE_NOT_VALID); } // Attempt to unlock the file. ClientAccessDataStream ds = null; // Issue an unlock bytes request. IFSUnlockBytesReq req = new IFSUnlockBytesReq( key.fileHandle_, key.offset_, key.length_, key.isMandatory_, serverDatastreamLevel_); try { ds = (ClientAccessDataStream) server_.sendAndReceive(req); } catch (ConnectionDroppedException e) { Trace.log(Trace.ERROR, "Byte stream server connection lost"); connectionDropped(e); } catch (InterruptedException e) { Trace.log(Trace.ERROR, "Interrupted", e); throw new InterruptedIOException(e.getMessage()); } // Verify the reply. if (ds instanceof IFSReturnCodeRep) { int rc = ((IFSReturnCodeRep) ds).getReturnCode(); if (rc != IFSReturnCodeRep.SUCCESS) { throwSecurityExceptionIfAccessDenied(path_, rc); // check for "access denied" Trace.log(Trace.ERROR, "IFSReturnCodeRep return code", descriptionForReturnCode(rc)); throw new ExtendedIOException(path_, rc); } } else { // Unknown data stream. Trace.log(Trace.ERROR, "Unknown reply data stream", ds.data_); throw new InternalErrorException( Integer.toHexString(ds.getReqRepID()), InternalErrorException.DATA_STREAM_UNKNOWN); } }
/** * Reads up to <i>length</i> bytes of data from this input stream into <i>data</i>, starting at * the array offset <i>dataOffset</i>. * * @param data The buffer into which the data is read. * @param offset The start offset of the data in the buffer. * @param length The maximum number of bytes to read * @return The total number of bytes read into the buffer, or -1 if there is no more data because * the end of file has been reached. * @exception ConnectionDroppedException If the connection is dropped unexpectedly. * @exception ExtendedIOException If an error occurs while communicating with the server. * @exception InterruptedIOException If this thread is interrupted. * @exception ServerStartupException If the server cannot be started. * @exception UnknownHostException If the system cannot be located. */ int read( byte[] data, // @B2A - code relocated from IFSFileInputStreamImplRemote,etc. int dataOffset, int length) throws IOException, AS400SecurityException { // Assume the arguments have been validated by the public class. // If length is zero then return zero. if (length == 0) { return 0; } int totalBytesRead = 0; int bytesRemainingToRead = length; boolean endOfFile = false; while (totalBytesRead < length && !endOfFile) { // If the number of bytes being requested is greater than 16 million, then submit multiple // requests for smaller chunks. The File Server has a limit that is somewhat below 16 // megabytes (allowing for headers, etc), so 16 _million_ bytes is a safe limit. // Issue the read data request. int bytesToReadThisTime = Math.min(bytesRemainingToRead, MAX_BYTES_PER_READ); IFSReadReq req = new IFSReadReq( fileHandle_, fileOffset_, bytesToReadThisTime, serverDatastreamLevel_); ClientAccessDataStream ds = null; try { ds = (ClientAccessDataStream) server_.sendAndReceive(req); } catch (ConnectionDroppedException e) { Trace.log(Trace.ERROR, "Byte stream server connection lost"); connectionDropped(e); } catch (InterruptedException e) { Trace.log(Trace.ERROR, "Interrupted", e); throw new InterruptedIOException(e.getMessage()); } // Receive replies until the end of chain. boolean endOfChain = false; int bytesReadByThisRequest = 0; do { if (ds instanceof IFSReadRep) { // Copy the data from the reply to the data parameter. byte[] buffer = ((IFSReadRep) ds).getData(); if (buffer.length > 0) { System.arraycopy(buffer, 0, data, dataOffset, buffer.length); bytesReadByThisRequest += buffer.length; dataOffset += buffer.length; } else // no data returned. This implies end-of-file (e.g. if file is empty). { bytesReadByThisRequest = -1; endOfFile = true; } } else if (ds instanceof IFSReturnCodeRep) { // Check for failure. int rc = ((IFSReturnCodeRep) ds).getReturnCode(); if (rc == IFSReturnCodeRep.SUCCESS) { // It worked, so nothing special to do here. } else if (rc == IFSReturnCodeRep.NO_MORE_DATA) { // End of file. bytesReadByThisRequest = -1; endOfFile = true; } else // none of the above { throwSecurityExceptionIfAccessDenied(path_, rc); // check for "access denied" Trace.log(Trace.ERROR, "IFSReturnCodeRep return code", descriptionForReturnCode(rc)); throw new ExtendedIOException(path_, rc); } } else // neither IFSReadRep nor IFSReturnCodeRep { // Unknown data stream. Trace.log(Trace.ERROR, "Unknown reply data stream", ds.data_); throw new InternalErrorException( Integer.toHexString(ds.getReqRepID()), InternalErrorException.DATA_STREAM_UNKNOWN); } // Get the next reply if not end of chain. endOfChain = ((IFSDataStream) ds).isEndOfChain(); if (!endOfChain) { try { ds = (ClientAccessDataStream) server_.receive(req.getCorrelation()); } catch (ConnectionDroppedException e) { Trace.log(Trace.ERROR, "Byte stream server connection lost"); connectionDropped(e); } catch (InterruptedException e) { Trace.log(Trace.ERROR, "Interrupted", e); throw new InterruptedIOException(e.getMessage()); } } } while (!endOfChain); // Advance the file pointer. if (bytesReadByThisRequest > 0) { incrementFileOffset(bytesReadByThisRequest); totalBytesRead += bytesReadByThisRequest; bytesRemainingToRead -= bytesReadByThisRequest; } } // If we have read zero bytes and hit end-of-file, indicate that by returning -1. // Otherwise return total number of bytes read. return (endOfFile && totalBytesRead == 0 ? -1 : totalBytesRead); }
// Submit the specified request, and fetch list attributes reply(s). // The returned Vector contains IFSListAttrsRep objects. Vector listAttributes(IFSListAttrsReq req) throws IOException, AS400SecurityException { // Assume connect() has already been done. errorRC_ = 0; Vector replys = new Vector(256); ClientAccessDataStream ds = null; try { ds = (ClientAccessDataStream) server_.sendAndReceive(req); } catch (ConnectionDroppedException e) { Trace.log(Trace.ERROR, "Byte stream server connection lost."); connectionDropped(e); } catch (InterruptedException e) { Trace.log(Trace.ERROR, "Interrupted"); throw new InterruptedIOException(e.getMessage()); } // @A1A int rc = -1; // @A1A boolean done = false; do { if (ds instanceof IFSListAttrsRep) { replys.addElement(ds); } else if (ds instanceof IFSReturnCodeRep) { // If the return code is NO_MORE_FILES then all files // that match the specification have been returned. rc = ((IFSReturnCodeRep) ds).getReturnCode(); if (rc != IFSReturnCodeRep.SUCCESS && // @D4A rc != IFSReturnCodeRep.NO_MORE_FILES && rc != IFSReturnCodeRep.FILE_NOT_FOUND && rc != IFSReturnCodeRep.PATH_NOT_FOUND) { throwSecurityExceptionIfAccessDenied(path_, rc); // check for "access denied" Trace.log( Trace.ERROR, "Error getting file attributes for file " + path_ + ": " + "IFSReturnCodeRep return code", descriptionForReturnCode(rc)); throw new ExtendedIOException(path_, rc); } } else { // Unknown data stream. Trace.log(Trace.ERROR, "Unknown reply data stream", ds.data_); // @A9C throw new InternalErrorException( Integer.toHexString(ds.getReqRepID()), InternalErrorException.DATA_STREAM_UNKNOWN); } // Fetch the next reply if not already done. done = ((IFSDataStream) ds).isEndOfChain(); if (!done) { try { ds = (ClientAccessDataStream) server_.receive(req.getCorrelation()); } catch (ConnectionDroppedException e) { Trace.log(Trace.ERROR, "Byte stream server connection lost."); connectionDropped(e); } catch (InterruptedException e) { Trace.log(Trace.ERROR, "Interrupted"); throw new InterruptedIOException(e.getMessage()); } } } while (!done); // @A1A if (rc == IFSReturnCodeRep.PATH_NOT_FOUND) { // @A1A // If the directory or file does not exist, then return NULL. errorRC_ = rc; replys = null; // @A1A } // @A1A else { // @A1A // Set the vector capacity to the current size. replys.trimToSize(); } // @A1A return replys; }
void writeBytes( byte[] data, // @B2A - code relocated from IFSFileOutputStreamImplRemote,etc. int dataOffset, int length, boolean forceToStorage) throws IOException, AS400SecurityException { // Assume the arguments have been validated by the caller. // Send write requests until all data has been written. while (length > 0) { // Determine how much data can be written on this request. int writeLength = (length > maxDataBlockSize_ ? maxDataBlockSize_ : length); // Build the write request. Set the chain bit if there is // more data to write. IFSWriteReq req = new IFSWriteReq( fileHandle_, fileOffset_, data, dataOffset, writeLength, 0xffff, forceToStorage, serverDatastreamLevel_); if (length - writeLength > 0) { // Indicate that there is more to write. req.setChainIndicator(1); } // Send the request. ClientAccessDataStream ds = null; try { // Send the request and receive the response. ds = (ClientAccessDataStream) server_.sendAndReceive(req); } catch (ConnectionDroppedException e) { Trace.log(Trace.ERROR, "Byte stream server connection lost"); connectionDropped(e); } catch (InterruptedException e) { Trace.log(Trace.ERROR, "Interrupted", e); throw new InterruptedIOException(e.getMessage()); } // Check the reply. if (ds instanceof IFSWriteRep) { IFSWriteRep rep = (IFSWriteRep) ds; int rc = rep.getReturnCode(); if (rc != 0) { Trace.log(Trace.ERROR, "IFSWriteRep return code", rc); throw new ExtendedIOException(path_, rc); } // Advance the file pointer the length of the data // written. int lengthWritten = writeLength - rep.getLengthNotWritten(); incrementFileOffset(lengthWritten); dataOffset += lengthWritten; length -= lengthWritten; // Ensure that all data requested was written. if (lengthWritten != writeLength) { Trace.log( Trace.ERROR, "Incomplete write. Only " + Integer.toString(lengthWritten) + " bytes of a requested " + Integer.toString(writeLength) + " were written."); throw new ExtendedIOException(path_, ExtendedIOException.UNKNOWN_ERROR); } } else if (ds instanceof IFSReturnCodeRep) { int rc = ((IFSReturnCodeRep) ds).getReturnCode(); if (rc != IFSReturnCodeRep.SUCCESS) { throwSecurityExceptionIfAccessDenied(path_, rc); // check for "access denied" Trace.log(Trace.ERROR, "IFSReturnCodeRep return code", descriptionForReturnCode(rc)); throw new ExtendedIOException(path_, rc); } } else { // Unknown data stream. Trace.log(Trace.ERROR, "Unknown reply data stream", ds.data_); throw new InternalErrorException( Integer.toHexString(ds.getReqRepID()), InternalErrorException.DATA_STREAM_UNKNOWN); } } }