Ervin Pangilinan
Spring 2023
CSC 310 - File Structures & Advanced Algorithms
C++
Write a version of the Linux systems utility tar that will create a tar file, unpack a tar file, and list the files packed into a tar file.
A tar file is a file that holds enough information to recreate each file on the command line. If the file is a directory, then it holds enough information to recreate all files reachable from that directory.
c++ jtar.cpp
The jtar software uses a custom File class for storing metadata on each file and directory. Every File object has the following attributes:
- name (A char array of length 81 for storing the file name)
- pmode (A char array of length 5 for storing the numerical shorthand of RWX accesses)
- size (A char array of length 7 for storing the number of bytes in the file)
- stamp (A char array of length 16 for storing the canonical time of the file's modification time)
Additionally, its constructor can be called in 3 ways: An empty constructor with everything set to null, a constructor with attributes passed into it as parameters, and a reference to another File object to create a deep copy.
The jtar software has 4 different command line flags that can be called upon execution.
jtar -cf tarfile file1 dir1...
This specifies jtar to make a tar file named tarfile based on the files or directories following the name of the tarfile.
jtar -tf tarfile
This specifies jtar to list the names of all files that have packed into a tar file.
jtar -xf tarfile
This specifies jtar to read a tar file, and recreate all the files saved in that tar file.
jtar --help
If the help option is present on the command line, the program should print a description of the three options above, and exit.
This is done in 4 steps. First, jtar verifies that valid files and directories were passed onto the command line upon calling the "-cf" command. This is done by checking if the filename names a regular file or a directory and seeing if its respective file pointer is good. For invalid file names and directories, jtar will quit execution.
Secondly, jtar obtains all files and directories to be placed into the tar file. This is once again done by parsing through the passed arguments of file and directory names. Similar to step 1, jtar will check if the argument is a regular file or directory. If it's a regular file, jtar will count that as a file to place into the tar file. If it's a directory, jtar will call an "ls" command on that directory and feed the output to a text file, and parse through the text file and add the relative path name of the file as a file to place in the tar file. Knowing which file to place in the tar file is done by adding it to a vector of file names.
Next, jtar creates a vector of File objects by iterating through the vector of file names. On each iteration, jtar will call the parameterized constructor of the File class and fetch the metadata on each file that matches the parameters of the constructor.
Finally, jtar creates a binary file that writes out the File objects from the vector. If the File object is a directory, jtar will iterate to the next object in the vector. For regular files, the File object is followed by writing out the contents in the actual file itself into the binary file.
Recreating the tarred files is done in the following manner. First, jtar reads in a File object and determines if the File object is a regular file or directory. For directories, jtar then determines if the directory is already present in the current directory. If present, jtar calls a "cd" command into that directory. If not present, then jtar calls a "mkdir" command to create a new directory. For files, jtar opens a filestream for output and writes out the next bytes, corresponding to the file size. This is done until the every byte in the tar file has been read.