Due:
Fri. Feb 16, 2001 (at noon)
Your employer just bought a broken Unix system off the street, and much to
your dismay you discover that the ls command is missing. You decide to
write a replacement called mydir which will do some of what ls
does. You design the program as follows:
- The program reads a single directory, and prints information about all
files in that directory.
- The program sorts its output alphabetically by file name, unless a switch
(described below) is given.
- If no file argument is given, the program looks at the current working
directory '.'. Otherwise it examines the directory named on the
command line.
- The switch -t makes the program sort the files from most recently
modified to least recently modified.
- The switch -r reverses the sense of the default sort, or the time
sort indicated by the -t switch.
- The switch -a makes mydir print files whose names start
with '.', which are ordinarily suppressed.
- The program prints out the following information in tabular form (i.e. in
fixed-width fields): the ``mode'' of the file showing the permission bits and
whether the file is actually a directory (exactly as ls would show
it); the login-name and group of the file owner, the file size in bytes, the
date of last modification, and the file name.
A partial example output is shown below:
drwx------ harper users 512 Oct 27 2000 HOWTO
-rw------- harper users 4426 Sep 21 2000 HelloWorld.class
-rwx------ harper other 1113 Sep 21 2000 HelloWorld.java
drwx------ harper users 2048 Jan 31 11:15 Mail
drwxr-x--- harper other 512 Jan 5 14:59 NEW
drwx------ harper users 512 Nov 26 1999 News
-rw------- harper users 13354 Oct 23 2000 PW.C
drwx------ harper users 1024 Dec 22 11:01 System
Observe the changing date format: for files more than about 90 days old, only
the day and year are shown, for newer files, the year is suppressed and the time
is shown. In either case the date occupies the same amount of space in the
output. You will have to extract the required pieces from the ctime()
output.
This is a program about command-line processing and system calls. You will
have to read the man-pages on a number of library functions as noted below and
determine how to use them. Pay particular attention to the include files listed,
since these provide the function prototypes and structure definitions that you
require.
Here are some of the library functions and man pages that will be of use in
writing this program:
getopt(),
chdir(),
stat(),
opendir(),
readdir(),
rewinddir(),
qsort(),
getpwuid(),
getgrgid().
ctime(),
strcmp(),
time(),
mknod.
Submit the code and the output of your program when run on the /etc
directory on fissure using the -a, -t, and -r flags
together.
As always, start NOW.
This program is easily built-up in stages, each of which is largely
independent of the others. Thus, testing and development are straightforward.
The final program, if well written, shouldn't be more than about 200 lines, in
one file (not including comments).
- Since you must sort the data by various criteria, you need to have it all
in hand before you sort or print. The easiest way to do this is to simply make
two passes through the directory with readdir(), the first counts how
many files there are, then you can allocate appropriate storage and load it
with the second pass.
- The file name is obtained from the directory entry, but all other
information comes from the inode as returned by the stat() call. Your
storage needs to be able to store both sets of info (nested structures is an
obvious way to do this) 1.
- Once you've designed your storage, allocate an entire array of it, not
just an array of pointers.
- qsort() takes the address of an array, the number of elements,
and the size of each, and a function that provides the ordering information.
This function gets two address (of two elements in the array), and can compare
these elements (or parts thereof) any way it pleases. It returns 1 if the
first element is considered ``greater'' than the second, -1 if less, and 0 if
they are equal. You can have more than one sort function.
- Reversing the sort is trivial. If you seem to need lots of code to do it,
rethink.
- You can deal with the permissions using bit-operations and the masks
provided in the stat include file.
- Unix times are actually stored as a long int representing the number of
seconds elapsed from Jan. 1 1970 GMT. The ordering of such time stamps is
obvious, and the ctime() routine can be used to convert to a string
representation of the time. Observe that each file has three times associated
with it: the last access time, the last modify time, and the last change time.
You are only interested in one of these.
- Watch this space on-line
for any further notes or hints.
Footnotes
- ... this)1
- Just because you're not using all the info now doesn't mean the program
might not need it in the future. Plan ahead and keep most of the data.
John Harper
2001-01-31