(main)
1. Network File System
2. Client
3. Server
4. Defrag Utility
5. Conclusion
6. Appendix A: File System Commands (Command Classes)
7. Appendix B: Screen Shots

 

Network File System (FSERV)

Copyright 1997

Ted Bonkenburg

tjb13@cornell.edu

 

Introduction: The CS415 network file system can be split into three main parts, the client, the server, and the Volume defragmenting utility (Defrag). The client mainly acts as a shell application that provides a command line user interface that supports about 25 or so commands. The server acts as a remote file system that handles low level file access and the handling of some of the higher level client commands. The defrag program takes a virtual file system (created by the server), and defragments all off it’s files in a graphical and somewhat user interactive interface. As such, this project can be broken down into these three elements:

 

The Client

 

The client is a simple command interpreter with some built in features. It reads in a user’s command string and splits it into two pieces, the command and the args. It then hashes into a table that contains Command objects, and does Command.execute(args). The client uses the server as a remote file system to fulfill almost all file system needs. It is allowed a small local directory which is required to use the "get" and "put" commands which retrieve files from the server and send them to the server respectively.

The client was built so that it would not crash if communications with the server go wrong. It will merely disconnect from the server and wait for a new connection request.

The client has three main classes and about 26 classes of type Command:

1. class Client: The Client class serves as the entry point of the client. It creates a new Shell and Server object and waits for user input. It continuously passes the user input to the Shell for processing. In this fashion, if the user wanted some other form of Shell, a different Shell object could be substituted. This could easily turn the client from a Unix-like command interface into a DOS style interface or whatever was desired. The client class also reads in and parses the client config file, although that feature is currently disabled.
2. class Server: The Server class is basically an interface between the Shell and a remote server. All requests for input from the server or messages sent to the server make use of the utilities in the Server class. In this fasion, it would be possible to get rid of a remote server. By replacing the Server class with one that provided the same interface functions, it would be possible to make this into a standalone, local file system rather easily. Currently, if any network errors occur, the server is responsible for attempting to shut down the connection and recover.
3. class Shell: The Shell class acts as a simple shell, in a fashion similar to UNIX bash shell. It consists of only two functions, processInput and initCommandTable. The initCommandTable initializes the hashtable with all of the Command objects. The processInput method simply extracts the command and arguments from the input string and runs Command.execute(sArgs) on the corresponding Command. In this way, it is extremely easy to extend the Client shell with new commands. All that has to be done is to create a new object derived from Command that has a function called execute() which takes in a string. The object is added to the shell by simply inserting a line in the initCommandTable function. For example, to add a command "date" which prints the current date and takes no arguments:
1. Create a new object, CommandDate which is a subclass of Command
2. Create a function, execute, which takes in a String (although in this case it will ignore it), and prints the current date to the console in a nice fashion.
3. Add the line: commandTable.put("date", new CommandDate()); to the initCommandTable() function of class Shell.
4. Note: To follow my standard, you would want to create help for this command in the standard format.
4. class Timer: The timer class is a small utility class. It is needed to support the shell command "timer". The main reason that this is included is so the user can time how long it takes to process events. For example, the recommended method for timing is to create a batch file with the events to be timed inside a "timer on" and "timer off" block. For example:
timer on;
get bigFile.txt;
timer off;
5. class xCatFrame: The xCatFrame class is the class that implements the "xcat" command’s text editor. It pops up a frame and allows saving, editing, and exiting. It also has a scrollBar that acts as a status bar when a save is initiated, but usually it saves so fast that it is impossible to notice.
6. class Holder: This is actually from the first project. It is used sort of as a semaphore, so that the client can be put to sleep and later woken up when necessary.
7. Command classes: The Client supports 26 different commands. Almost every command prints out default help where applicable if it is used incorrectly. Also, every command prints out error messages if something goes wrong, such as a server miscommunication, file not found, etc. and attempts to recover. Some commands are actually created using other client commands, where applicable. A summary of each command and how it is processed will be presented later (in Appendix A) to allow more familiarity with the server.

 

The Server

 

The server is also, in a sense, a simple command interpreter. On startup it mounts a Volume (passed as a command line arg). Once it finishes initializing the directory and FAT data structures, the cache, etc, it basically sits and waits for a connection. On a new connection, the server spawns a thread that handles the client. The server can handle multiple clients at once with mutual exlcusion based on an OpenFileTable and an OpenDirectoryTable.

Before a Volume is used, it must be formatted using the command:

jview Server format <name.vol> <iBlockSize> <iNumBlocks>

This is necessary because the volumes contain internal structure that cannot easily be created by hand. The server maintains a file system that must always maintain the following properties:

 1. The smallest file size is one block. That is, files are read and written in units of one block at a time. Directory files may be modified on a smaller scale by the server’s directory functions, but they are still files and must therefore be at minimum one block large. Therefore, the block size must be bigger than the size of two directory entries (for "." and ".."). Because of this, the format command currently limits block size to being greater than 255 bytes.
 2. Mutual exclusion will be upheld through the open file table. That is, the readers/writer’s probem is solved by forcing each read and write to occur to a file that has been "opened" through the open file table. This guarantees mutual exclusion because each open file serves as a monitor that allows simultaneous reads but only a single writer. Opening a non-existent file for write creates a new empty file. Each file must be closed immediately after use. It would seem that there would be a possibility of deadlock in the system. While this cannot be completely ruled out, it should be noted that the request scheme for opening files is such that the containing directory is always opened before the actual file (if necessary), so there is an ordering to resource requests that should prevent deadlocks.
3. All file descriptors (directory entries) will be of the same type. That is, directories and files both have the same filedescriptor (a class TFile). A directory is just a file that contains filedescriptors.
 4. All directories will contain the "." and ".." entries at all times. The "." and ".." entries can’t be deleted. Nonempty directories cannot be deleted.
 5. Once formatted, the Volume maintains a constant size. That is, the volume is like a fixed size hard drive.
 6. All entire blocks to be read from the drive will first attempt a read from the cache. If it is not in the cache, it will be placed in the cache after being read. All entire blocks to be written will be updated or placed in the cache and written to disk. The only process that doesn’t write to the cache is the creation or removal of new files or directories, and these processes must invalidate any blocks written from the cache. Moreover, any blocks that are freed (given back to the free block pool) will be invalidated and therefore removed from the cache.
 7. The volume shall have the final block maintained as a swap block at all times. This is needed for the defrag utility. Basically, upon formatting the final block is marked as used, and since there is no link to it, it will never be unmarked.
 8. Directory hazards will be avoided through an openDirectoryTable. That is, each client shall have the current working directory as "opened for read" at all times. Because of this, it is impossible to delete a client’s working directory. It is also impossible to delete a directory previous in the path, since only empty directories can be deleted.

 

The server has 12 main classes:

class Block: The Block class contains an array for the block data and in int for the number of bytes stored in this block. It is basically used to create new blocks that are read from or to the file system.
class Cache: The server has a read/writethrough cache. The cache blocks currently default to the same size as the file system blocks (usually 4K, but that depends on how the Volume was formatted). Whenever a block is read, it gets cached. Whenever a block is written, it either gets cached or updated in the Cache. Whenever a block is discarded, it gets invalidated and tossed from the cache. Some low level directory operations such as mkdir, rmdir, mkfile, rnfile, and rmfile write directly to blocks and thus need to invalidate them. The cache has a global disable so that better testing can be done. It is still updated when the cache is disabled, but it will always return a Cache Miss. The cache is more of a passive entity. It does not do any sending or receiving from the client itself, but as mentioned above blocks are always placed in the cache. This keeps the cache simple and allows focus on the caching algorithms when relating to the cache. Due to the enormous size of this project, the caching algorithms are fairly weak, but still effective.
 class Connection: A connection thread is created whenever a new client connects. These threads allow multiple users to be on the system simultaneously. Each connection has it’s own connectionFileTable that indexes into the global system file table. That way clients can each have their own file table which includes a file pointer associated with each file. Clients also maintain their current working directory in the Server’s OpenDirectoryTable at all times.
The connection thread takes care of parsing any network input from the client. Currently it runs a rather poor setup of a giant if-else statement. A much neater and more efficient solution would be one similar to how the client processes commands using a hashtable. There was not time to set this up, however. Currently the connection thread has functions that correspond to each of the possible 20 or so requests by the client. Most of these functions simply parse the input string into a directory file and the file name. They take care of maintaining the OpenFileTable (opening and closing files as necessary). They then call the associated low-level functions in the directory class to do the "dirty work". The functions always follow the rule of opening and closing files for reading or writing before use by way of the connectionFileTable. These function consist of one for each of the 20 client requests, such as openFile, moveFiles, etc.
The Connection class also has some helper functions such as parseDirString which parses the given string into a directory file and a name. Other functions such as reportSuccess() and reportError() send common messages to the client.
class ConnectionFileTable: The ConnectionFileTable class defines the local file table that is native to a connection thread. This is used to index into the global file table, and also keeps a RandomAccessFile pointer for each file.
class Directory: This is a giant utility class that does all the low level file work. It assumes that the necessary files have already been opened by the calling function (except in a few cases) and performs the low level duties of file management, being sure to maintain the properties of the file system given above. Some of the functions in this class such as mkdir are allowed lower than block level access to the drive. Most of the functions take in a TFile object that is the directory on which the action is to be performed. The sName parameter is usually the file on which the action is to be performed, such as making a new file in a directory, or deleting a file found in a directory. This technique works out rather nicely. The Directory functions include:
findFile: this is a general purpose utility that returns the TFile (file descriptor) of the file in the given directory with the name sName, or null if it doesn’t exist. This is often called by other functions, or the parseDirString of Connection.
findFiles: this utility breaks down arguments that can contain a wildCard, ‘*’, and calls listDirectory with the appropriate filter. It then returns a Vector of all of the files.
freeBlocks: this takes in a TFile and frees all of it’s blocks, invalidating them from the cache. It is usually called when a file is deleted.
listBlocks: this returns a vector of all of the blocks (in order) that a file has.
listDirectory: this returns a Vector of all of the TFile’s of a directory. It can be used for both ls and l, as well as for parsing *’s in command strings. It can take in a filter, and return only those files that match the filter.
mkdir: creates a new directory with name sName in the given directory.
mkfile: creates a new zero length file in the given directory with name sName.
lnfile: creates a symbolic link to a file.
mvfile: moves a file (only one at a time).
cpfile: copies a file (only one at a time).
resolveLink: returns the path that a link refers to.
readBlock: reads the given block from the drive. it uses the cache if possible and updates it.
rmdir: removes the directory with name sName in the given directory.
rmfile: removes the file with name sName in the given directory
rnfile: renames a file.
updateEntry: updates the TFile entry for the given TFile. Useful when size/time/startBlock/etc. changes.
removeEntry: removes an unwanted TFile entry in a directory.
writeBlock: writes the given block to the drive and updates the cache.
 
class FAT: this class implements the File Allocation Table as a giant array of size iNumBlocks in the Volume. It has functions for getting a free block, marking a block EOF, freeing a block, and getting the entry[index]. It is a simple implementation of a FAT.
class FileTable: This class is for the global file table. It maintains an array of FileTableEntry’s. It removes entries when there are no more pointers to that entry, and has functions for opening and closing files for reading/writing. It is also used for the OpenDirectoryTable.
class FileTableEntry: A class for an entry in the file table. It holds the TFile object corresponding to this entry, and implements a monitor solution to the readers/writers problem, forcing users to wait and notifying them when a successful open has completed.
class ParseResult: This class is simply a wrapper used to return the result of parsing a directory string. It allows the return of more than one argument, and will be more useful in the future.
class Server: this is the entry class for the Server. it initializes all of the objects and sits waiting for connections to occur. Currently, the only way to exit from the server is to hit CTRL-C. This will be fixed for the final version.
class TFile: This is the FileDescriptor common to all files. It is like a giant struct, but has the ability to write itself to disk and has useful constructors. It contains many fields, such as time, date, size, etc. It also contains a byte of boolean flags. Currently, the most useful flag is "isDir", so that files can be differentiated with directories. It also has a flag "isLn" that will be used to denote if this file contains a string path which is the location of another file. This will be useful when symbolic linking is added.
class Volume: This manages the virtual hard drive. The constructor initializes the FAT and sets up the root directory. This class also contains the functions to format a new volume as well as functions to get new file pointers and seek to the beginning of a block. This class contains the definitions of EOF as well as other Volume attributes.

 

The Defrag Utility

The defrag utility is used to defragment a Volume. It has a graphical display (see Appendix B) which allows the user to browse the volume’s blocks both before and after defragmentation (to tell the difference). The display works independent of Volume size because it scales the size of the blocks displayed up or down accordingly. Directory blocks are colored in cyan, and file blocks are colored in blue. If the user clicks on a block, it will display the associated file’s name and highlight all of the blocks of that file in green. When the user presses the "Defrag" button, he or she will be able to watch while the Volume is quickly defragmented. The program will wait until the user hits the exit button before quitting. If at any point the Defrag program fails, the Volume will remain intact and without errors, unless the failure occurs in a small "critical" code section (the moveBlock function).

The algorithm for defragmenting the volume is a very basic approach. Basically, it first uses depth-first search to fill a table which I call the "reverse file table" (fileFAT). That is, for each block, i, that is occupied by a file, fileFAT[i] is a pointer to that file. This is how each of the blocks on-screen is set up, and how when a user clicks on an occupied block the appropriate file is found. The program then defragments by using again a depth first search (starting with the root directory). It keeps a current block pointer, and for each directory and file in the system, it goes through one by one and places the blocks in order, swapping and moving blocks if necessary. Swapping is done by making use of the Volume’s built in swap block, which is defined as the last block in a volume. When it is finished, all of the files are moved to the front of the Volume, and each file has its blocks in complete and un-interrupted order. This is sort of a brute force algorithm, but it works fine and there wasn’t enough time to come up with a much better approach. It was also extremely hard to debug, but has been tested many times and appears to be working perfectly.

The defrag project contains 9 classes, the most important of which is the Defrag class:

class Defrag: This is the entry class for defrag. It contains the functions to set up the DefragFrame, and initialize everything, as well as the main defrag function. The defrag process consists of calls to "initFileFAT", "defragDir", and moveBlock:
initFileFAT: This function does a depth first search, starting at the root, to fill the fileFAT table and set up the display for each of the blocks. It is a recursive function.
defragDir: This recursive function does a depth first search, starting at the root, and defrags every file. For each block of the current file (iBlock), it checks the block pointer (where the next block is supposed to go, iPtr). If it is the same, it does nothing. If the block pointer is empty, it calls moveBlock(iBlock, iPtr). If the destination block is occupied by another file, it swaps the blocks by calling:
moveBlock(iPtr, iSwapLoc);
moveBlock(iBlock, iPtr);
moveBlock(iSwapLoc, iBlock);
 moveBlock: This is perhaps the most important function, as it must move a block while maintaining the file system afterwards. That is:
1. Before a moveBlock, the Volume must be a legal volume, V.
2. When the moveBlock function returns, the Volume must be a legal Volume V’, where [V’] == [V]. That is, after the move, everything must be updated so that if the defrag were to fail at this point, the Volume would appear to an end user to be the same Volume as before (w/blocks shuffled around) and have the same exact content, with no errors.
class DefragFrame: This class is the frame for the Defrag program, and thus the GUI. It uses a number of tricks (mainly because I haven’t used Java that much) to accomplish it’s task. The blocks that are created are sized to fit a constant area, so if the Volume size is different, the blocks automatically shrink or expand accordingly. Since Java has no progress bar (which I find important), I created my own using a simple scroll bar. I keep the scroll bar value at 0, and expand the size of the scrolling element as progress proceeds. Personally, I think it looks kind of neat. In order to create the window exactly as I wanted it, I set the LayoutManager to null. In this way, I could take total control of the controls, although I had to do all of the work of resizing, etc. The displayed blocks are made up of class gBlock.
class gBlock: This class is the graphical representation of a block. It basically draws itself to the screen, and is created with the proper width and x,y location. The blocks can be of any arbitrary color, and can be drawn as either raised or sunken in. Normally all blocks start raised, but as each has been defragmented, they are sunken in and redrawn (so in the end, all blocks are sunken in). The sinking effect is rather poor, but the color change (due to lighting) is noticeable, and it provides a nice effect.
other classes: The other classes are "stolen" right from the server project, so they need not be explained here. They include Block, Directory, FAT, Volume, Holder, and TFile.

 

Conclusion

 

This file system meets all of the specified requirements fully. A significant attempt has been made to go well beyond these requirements, such as adding support for batch files, linking to directories, timer commands, date and time stamps, added directory commands, a graphical text editor, and many other commands and options. Both the client and server have been designed to be robust applications (to a point) and have been beta tested extremely thoroughly. Through the use of open file tables and other mutual exclusion techniques, multiple clients can process commands simultaneously, and it is a thrilling effect (for me at least) to watch two clients read a large file simultaneously. In addition to the above, a fully graphical defrag program has been created that will successfully defragment the given Volume.

This project was an attempt to create an almost bug-free and completely useable network file system. It has been an immense learning experience, and most likely will be continued to be worked on even after the project is demo’d. Although there is always room for improvement, it would seem that this is a most complete system.

 

 

 

Appendix A

 

The following is a summary of each command (from the client perspective). The "Problems" section is for coverage of known problems (or slight lacking in feature), and the "Future" section is for expected future changes (if the project were to be worked on after the demo). The "Impl" section stands for implementation, and gives a brief summary of how this command is implemented on the client and server ends.

 CommandBlocks

 Description: This command prints a string ("b1à b2 à b3 àà bx") of all of the blocks used by a program to the client. It is useful in order to tell when a file is fragmented, and if it has been unfragmented correctly (by the defragging utility).

 Usage: blocks <filename>

 Impl: client sends a request to the server to "listBlocks". The server then creates a list of all the blocks a file occupies, and sends it back to the client.

 Problems: There are no known problems with this command.

 Future: The output could be made a bit prettier.

 

CommandCd

 Description: This command is used to change directories on the server file system. It accepts paths that are relative to the client’s current directory or paths that are relative to the root. It also supports direct change of directory to the root by "cd /" as well as the standard ".." and "." notations.

Usage: cd <path> ;path is the pathname to change directory to.

Impl: client sends a request to the server for cd. The server parses the path, and if successful it closes the current entry in the OpenDirectoryTable. It then opens the new directory, and sends the entire path back to the client.

Problems: There are no known problems with this command. It appears to work perfectly in this version.

Future: There will most likely be no changes to this command in the future.

 

CommandClose

 Description: This command is implemented for debugging purposes only. It closes the file associated in the connectionFileTable associated with the given index. It was implemented only for testing mutual exclusion (which works).

 Usage: close <index> ;closes the file associated with this (int) index

 Impl: client sends a request to the server to close, passing index. The server closes the file.

 Problems: Since this isn’t a user command, there is no checking for a valid index. That is, if an invalid index is closed, a null pointer exception may occur.

 Future: This command will be stripped from the release version (but will be in the demo). It will, however, remain a reserved keyword.

 

CommandConnect

 Description: Used to connect to a remote file server. It will disconnect if you are currently connected.

 Usage: connect <dns || ip> ;connects to the associated server

 Impl: client attempts to create new TCP socket connecting to server. It then requests for the file system block size for later use. The server creates a new user connection sets it up as a thread.

 Problems: There don’t seem to be any problems with connect at this time.

 Future: No changes are expected.

 

CommandCp

 Description: Copies the source file to the destination directory, overwriting any existing file.

 Usage: cp <source> <dest> ;This command accepts the * character.

 Impl: client sends cp command to the server with the arguments. The server copies each block to the destination. It then returns success/fail.

 Problems: There are no known problems with this command.

 Future: A possible addition would be the ability to change the name of the file while copying (like DOS).

 

CommandDisconnect

 Description: Disconnects from the server. Leaves user in shell with the opportunity to connect to another server.

 Usage: disconnect

 Impl: client sends disconnect message to the server. Server shuts down connect, closing any open files.

 Problems: There are no problems with this command. If a client side cache is added, possible cleanup will be needed (writing dirty blocks).

 Future: No changes are expected for this command.

 

CommandExec

 Description: This command executes the named batch file on the server. It basically executes each line of the given batch file in order. This will be useful for timing the length of running commands. It has already been used to show that when the server cache is enabled, file transfers can increase for files requested more than once. The syntax for batch files is the same as normal commands, but each command should be followed by the ‘;’ character.

Usage: exec <batchfilename>

 Impl: This command uses the code from the get command (modified) to read the batch file intoa string. It then uses a StringTokenizer to extract the individual commands, and uses Shell.processInput(..) to process them in order. It opens the batch file for "reading" before executing it, and closes it afterwards.

Problems: There are no known problems with this command.

Future: It would be rather easy to get rid of the ‘;’ requirement. This could be done if so desired.

 

CommandFree

Description: This command returns info on the total remote file system space, and free and used drive space.

Usage: free

Impl: client sends request to server for "free" info. The server calculates the free and used space, and sends it to the client. The client then formats this info and displays for the user.

Problems:The sizes reported are in bytes, however they are based on used and free blocks. A probably more realistic use would be to report the used and free blocks, but this would not make the user happy.

Future: The number of free and used blocks might be added in addition to the current information.

 

CommandGet

Description: This retrieves the named file off of the server and saves it to the client’s local directory. It will overwrite any existing file.

Usage: get <filename>

Impl: client opens the file for reading. The server returns an ID for that file. It then requests all of the blocks for the file by sending the "get" command (referencing the file using the ID). The server sends each block. The client writes the blocks as it receives them to a file in the local directory. It then closes the file by sending the "close" command to the server and the ID to close.

Problems: Get uses RandomAccessFile, which doesn’t always create a new file form scratch. This may cause some files to be written incorrectly if a same filename already exists and that file is bigger. This has not been tested, though, and the problem may not exist. No other problems.

Future: Get rid of possible RandomAccessFile problem.

 

CommandHelp

Description:This command prints a small help screen that lists all of the available commands for the current shell.

Usage: help

Impl: The client enumerates the "keys" of the Shell’s command hashTable. These keys match the list of all of the commands in the system. Even if another command is added at a later date, the help command is automatically updated.

Problems:There are no known problems with this command.

Future: It would be nice to have help <command> run the command’s showHelp() function.

 

CommandL

Description:This command displays the client’s working directory in long format. That is, it displays date and time created, whether the file is a directory, and file size if it is not a directory as well as the directory names.

Usage: l <pathname>; <pathname> is optional. this command supports the * char.

Impl:client sends request for l info. The server does a listDirectory. If no args were provided, it does a listDirectory of the current directory with * as the arg. The client formats the info and presents to the user in a nice readable fashion.

Problems:There are no known problems with this command.

Future: Perhaps "link" files could be noted as such. Currently, they are not.

 

CommandLcl

Description: This command displays the local client directory.

Usage: lcl

Impl: client creates a File object for ".". This is the current directory. client does File.list() to list all of the files and displays them to the user.

Problems: The files "." and ".." do not appear in the output.

Future: No changes will be made in the future.

 

CommandLn

 Description: creates a symbloic link to the target file. Links to directories are also possible, and a number of Commands are able to follow a link to it’s target in usage. Some commands, however, such as cp, rm, etc. act on the link itself.

 Usage: ln <linkname> <target> ;Note: link also supports full linking to directories.

Impl: client sends ln request to the server. Server creates a link, and returns success/fail.

Problems: There are no known problems with this command.

Future: No changes will be made.

 

 

CommandLogout

Description: Exits from client.

Usage: logout

Impl: client disconnects from server if necessary and quits.

Problems: None

Future: No changes will be made.

 

CommandLs

Description: Prints the short directory.

Usage: ls <pathname> ;<pathname> is optional. This command supports the * char

Impl: client sends message to server for ls. Server returns a listDirectory (on . and * if no path provided). The client formats output for user.

Problems: ls takes no arguments. It only displays the current path.

Future: There will be no changes to this command.

 

CommandMkDir

Description: Creates a new directory in the given path. It will not make a new directory if one already exists.

Usage: mkdir <dirname>

Impl: client sends mkdir message to server with args. The server creates the requested directory, and returns success/fail.

Problems: There are no known problems with mkdir.

Future: There are no expected changes to mkdir.

 

CommandMore

Description: Prints the requested file to the screen. Similar to DOS "type" command. This is part of an equivalent "cat" command capability.

Usage: more <filename>

Impl: client uses the code from the "get" command and pipes the blocks received to the screen.

Problems: There are no known problems with this command.

Future: There are no expected changes to this command.

 

CommandMv

Description: Moves the given file to a new directory. Move overwrites any existing file with the same name.

Usage: mv <source> <destDir> ;this command accepts the * char

Impl: client sends mv request to server and awaits response. Server mv’s the file(s) simply by moving it’s directory entry. It returns success/fail.

Problems: There are no known problems with this command.

Future: No expected changes.

 

CommandOpen

Description: This command is implemented for debugging purposes only. It opens the given file for writing, and returns the index into the connectionFileTable. It has been used to check for errors in the readers/writers problem in the Open File Table system that the server employs.

Usage: open

Impl: client sends request for open (writing) and args. receives either failure or an integer index.

Problems: There are no known problems with this command.

Future: This command will be removed from the final version (after the demo). However, open will remain a reserved word.

 

CommandPut

Description: :Stores a file from the client’s local directory on the current working directory of the server.

Usage: put <filename>

Impl: client sends request to put to the server. client sends size to server and sends blocks. Server creates a new file, and stores the blocks in that file.

Problems: There are no known problems with this command.

Future: No changes are expected.

 

CommandRm

Description: Removes/deletes the given file.

Usage: rm <filename> ;this command accepts the ‘*’ character.

Impl: client sends rm request to server and command line args (path). Server removes the file(s), and frees all of it’s blocks. It then returns the result (success/fail).

Problems: There are no known problems with rm.

Future: This command will not be changed in the future.

 

CommandRmDir

Description: Removes the given directory on the condition that it is empty.

Usage: rmdir <dirname> ;this command accepts the ‘*’ character.

Impl: client sends rmdir request to the server. Server removes the directory if empty. It then sends result (success/fail).

Problems: There are no known problems with this command.

Future: There are no expected changes for this command.

 

CommandRn

Description: Renames a file.

Usage: rn <file> newName ;Note: Currently does not rename directories.

Impl: Client sends an "rn" request to the server. Server renames the file, and returns result.

Problems: There are no known problems with this command.

Future: It would be fairly trivial to add support for renaming directories. However, this would make it very easy for a user to screw up his "link" files.

 

CommandTime

Description: Prints current time to the screen. Useful so that I know when to eat.

Usage: time

Impl: a simple call to a java function to obtain the current time in 24hr format.

Problems: None.

Future: None.

 

CommandTimer

Description: Either turns on or turns off the timer. If the timer is turned off, it will print the elapsed time.

Usage: timer <on || off>

Impl: implemented using calls to the timer class.

Problems: If timer off is called w/out a previous timer on, the results are invalid.

Future: No changes are expected for this command.

 

CommandXCat

Description: Brings up a simple text editor. This is actually a java frame window, and allows one to edit and save small files.

Usage: xcat <fileName>

Impl: client opens file for write. Client sends a "get" request to the server to get the contents of the file. Client then creates a new xCatFrame and sends it the string containing the file. When the file is saved, the client sends a "put" command to the server, and sends the file over. It then closes the file for writing.

Problems: xcat can only be used to edit small files. For some reason, the file to be edited gets fully placed in the string, and when printed to the screen the string is fine. However, when the string is placed in the textArea, it is concatenated (the end gets cut off, and somehow strangely garbled). This might actually be an error with the microsoft java implementation, as what is being done is rather trivial.

Future: The bug in xcat will (hopefully) be fixed, and large files will be able to be edited in xcat.

 

Possible Future Commands:

 

CommandW – This would show a list of what directories people are in.

CommandDate – As mentioned earlier, the date.

 

Appendix B

 

The defrag display. This is an already defragmented volume. The blocks in light blue are directories, and the blocks in the darker blue belong to files. The green blocks are an entire selected file (in this case called "temp"). The red block is the defrag utility's swap block, and is defined inaccessible in the Volume definition itself.