Low level Linux Directory command
Low Level I/O
You will use the C low level I/O functions to create our own xdir command in C. This program must not use bash, ls, sed, awk, and/or Perl. It must not use any of the exec functions.
Syntax of xdir:
xdirdirectory
xdirdirectory switches
Your source code must be namedxdir.c
In each of the cases, we show the directory. The directory entries are then indented four spaces.
Without any switches
- xdir will first print the directory name followed by a colon.
- xdir will not print any files that begin with “.”
- xdir will print the filenames (unqualified) in the order they are provided by the readdir function.
>xdir Data
Data :
file5
file6
Program4
Program5
Program2
Program3
file4
With just the -l switch
- xdir will first print the directory name followed by a colon.
- xdir will not print any files that begin with “.”
- For each file, xdir will print (on one line):
- file name (unqualified)
- file type (F – regular file, D – directory, L – link, P – Pipe)
- number of 512 byte blocks
- size in bytes
- xdir will print the files in the order they are provided by the readdir function.
>xdir Data -l
Data :
file5 F 8 blks 167 bytes
file6 F 8 blks 121 bytes
Program4 D 8 blks 4096 bytes
Program5 D 8 blks 4096 bytes
Program2 D 8 blks 4096 bytes
Program3 D 8 blks 4096 bytes
file4 F 8 blks 87 bytes
With just the -a switch
- xdir will first print the directory name followed by a colon.
- xdir will print any files in the directory including ones that begin with a “.”
- xdir will print the filenames (unqualified) in the order they are provided by the readdir function.
>xdir Data -a
Data :
.
..
file5
file6
.mydot
Program4
Program5
Program2
Program3
file4
With both the -l and -a switches
- xdir will first print the directory name followed by a colon.
- xdir will print any files in the directory including ones that begin with a “.”
- For each file, xdir will print (on one line):
- file name (unqualified)
- file type (F – regular file, D – directory, L – link, P – Pipe)
- number of 512 byte blocks
- size in bytes
- xdir will print the files in the order they are provided by the readdir function.
>xdir Data -l -a
Data :
. D 8 blks 4096 bytes
.. D 8 blks 4096 bytes
file5 F 8 blks 167 bytes
file6 F 8 blks 121 bytes
.mydot F 8 blks 25 bytes
Program4 D 8 blks 4096 bytes
Program5 D 8 blks 4096 bytes
Program2 D 8 blks 4096 bytes
Program3 D 8 blks 4096 bytes
file4 F 8 blks 87 bytes
Solution
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
#define OFFSET 4
charfile_type(struct stat path_stat)
{
if ( S_ISDIR(path_stat.st_mode) )
return ‘D’;
else if ( S_ISFIFO(path_stat.st_mode) )
return ‘P’;
else if ( S_ISLNK(path_stat.st_mode) )
return ‘L’;
else
return ‘F’;
}
intprocess_dir(char *dirname, intaflag, intlflag, intrflag, int level) {
DIR *dir;
structdirent *dp;
struct stat path_stat;
char path[1024];
charftype;
dir = opendir(dirname);
while( (dp = readdir(dir)) != NULL ) {
/* skip hidden files */
if (dp->d_name[0] == ‘.’ &&aflag == 0)
continue;
/* complete path to the file */
snprintf(path, 1024, “%s/%s”, dirname, dp->d_name);
stat(path, &path_stat);
ftype = file_type(path_stat);
printf(“%*c”, (level + 1) * OFFSET, ‘ ‘);
printf(“%s”, dp->d_name);
if (ftype == ‘D’ &&rflag&&strcmp(dp->d_name, “.”) != 0 &&strcmp(dp->d_name, “..”) != 0 )
{
printf(“:\n”);
/* recursive call */
process_dir(path, aflag, lflag, rflag, level + 1);
}
else
{
if (lflag) /* print file stats */
printf(” %c %d blks %d bytes”, ftype, path_stat.st_blocks, path_stat.st_size);
printf(“\n”);
}
}
closedir(dir);
}
int main(intargc, char **argv) {
char *dirname;
intaflag = 0, lflag = 0, rflag = 0;
int index, c;
/* parse command-line arguments */
while ((c = getopt (argc, argv, “alr”)) != -1) {
switch (c) {
case ‘a’:
aflag = 1;
break;
case ‘l’:
lflag = 1;
break;
case ‘r’:
rflag = 1;
break;
case ‘?’:
return 1;
default:
break;
}
}
if (optind<argc) { /* get the remaining argument: directory name */
dirname = argv[optind];
}
else {
printf(“usage: directory [-alr]\n”, argv[0]);
return 1;
}
printf(“%s:\n”, dirname);
process_dir(dirname, aflag, lflag, rflag, 0);
return 0;
}