Commit 0bc67824 authored by Lindsay Knupp's avatar Lindsay Knupp
Browse files

Lab 10.2 completed

parent e6a0d8f1
......@@ -24,7 +24,7 @@ CC = gcc
CFLAGS = -std=gnu99 -g -Wall
EXE = file_stat read_dir fdump
EXE = file_stat read_dir fdump traverse
all: $(EXE)
......@@ -46,5 +46,13 @@ hexdump.o: hexdump.h hexdump.c
fdump: fdump.c hexdump.o
$(CC) $(CFLAGS) fdump.c hexdump.o -o fdump
traverse: traverse.o
$(CC) -o traverse traverse.o
traverse.o: traverse.c
$(CC) -c $(CFLAGS) traverse.c
clean:
/bin/rm -f *~ *.o core $(EXE)
......@@ -33,6 +33,7 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <stdbool.h>
#include <time.h>
#define MAXLENGTH 255 // for file names
#define BYTE 8
......
/*
* CSCI 315 Operating Systems Design
* Original developed by CSCI 315 staff
* Modified by: L. Felipe Perrone
* Date: 2011-4-21
* Copyright (c) 2011 Bucknell University
*
* Permission is hereby granted, free of charge, to any individual or
* institution obtaining a copy of this software and associated
* documentation files (the "Software"), to use, copy, modify, and
* distribute without restriction, provided that this copyright and
* permission notice is maintained, intact, in all copies and supporting
* documentation.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL BUCKNELL UNIVERSITY BE LIABLE FOR ANY CLAIM, DAMAGES
* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "read_dir.h"
// function prototypes
void process(char *name);
void enqueue(char *name, que_t *q);
void dequeue(que_t *q);
void peek_front(char *name,que_t q);
bool queue_empty(que_t q);
void initq(que_t *q);
// main function
int main(int argc,char *argv[]) {
if (2 != argc) {
printf(" usage: %s dirpath\n", argv[0]);
exit(-1);
}
else {
// pass in the starting directory
process(argv[1]);
}
return 0;
}
// traverse a directory tree applying a function when a file is found
void process(char *root)
{
int numOfFiles = 0;
int numOfDir = 0;
int regFiles = 0;
int smallest = RAND_MAX;
int largest = 0;
int total = 0;
que_t nameq;
char dname[MAXLENGTH];
char cname[MAXLENGTH];
char prefix[MAXLENGTH];
unsigned int fd;
struct stat file_info;
struct tm timeinfo;
time_t leastrecent;
leastrecent = time(NULL);
time_t mostrecent;
mostrecent = 0;
char leastrecentf[MAXLENGTH];
char mostrecentf[MAXLENGTH];
char leastrecentstr[40];
char mostrecentstr[40];
struct stat buffer;
int status;
struct dirent *dp;
DIR *dirp;
char dirname[MAXLENGTH];
initq(&nameq);
enqueue(root,&nameq);
while (true != queue_empty(nameq)) {
peek_front(dname,nameq);
dequeue(&nameq);
dirp = opendir(dname);
if (dirp != NULL) { // it is a directory
strcpy(dirname,dname);
printf("directory : %s\n",dname);
strncpy(prefix, dname, MAXLENGTH);
strncat(prefix,"/", MAXLENGTH);
for (dp = readdir(dirp); NULL != dp; dp = readdir(dirp)) {
if ((strcmp(dp->d_name,"..") != 0) &&
(strcmp(dp->d_name,".") != 0)) {
// prevent from infinite loop
strncpy(cname, prefix, MAXLENGTH);
// concatenate the prefix
strncat(cname, dp->d_name, MAXLENGTH);
enqueue(cname,&nameq);
}
}
closedir (dirp);
numOfDir ++;
} else {
fd = open(dname, O_RDONLY);
if (-1 == fd){
perror("Failed to open read only file - ");
exit(-1);
}
// retrieve information on file size
if (fstat(fd, &file_info) == 0){
if((file_info.st_size) > largest){
largest = file_info.st_size;
}
if ((file_info.st_size) < smallest) {
smallest = file_info.st_size;
}
total = total + file_info.st_size;
}
// counts the number of regular files
if (S_ISREG(file_info.st_mode)){
regFiles++;
}
// finds the oldest file and newest file.
if (file_info.st_mtime < leastrecent){
leastrecent = file_info.st_mtime;
localtime_r(&(file_info.st_mtime), &timeinfo);
asctime_r(&timeinfo, leastrecentstr);
strcpy(leastrecentf,dname);
}
if (file_info.st_mtime > mostrecent) {
mostrecent = file_info.st_mtime;
localtime_r(&(file_info.st_mtime), &timeinfo);
asctime_r(&timeinfo, mostrecentstr);
strcpy(mostrecentf,dname);
}
// test if it is a regular file and not a device or link --
// if this is a regular file, then process it --
printf(" processing file: %s\n", dname);
numOfFiles++;
}
} // while
printf(" a total of %d files were counted\n",numOfFiles);
printf(" largest file size %lu\n", (unsigned long)largest);
printf( " smallest file size %lu\n", (unsigned long)smallest);
printf(" an average of %lu\n",(unsigned long) total / numOfFiles);
printf(" %d regular files were counted\n",regFiles);
printf( " %s is the least recently modified file: %s\n",
leastrecentf,leastrecentstr);
printf(" %s is the most recently modified file: %s\n",
mostrecentf, mostrecentstr);
printf(" a total of %d directories were counted\n",numOfDir);
}
// initialize queue data structure
void initq(que_t *q) {
q->head = q->tail = NULL;
}
// test whether queue data structure is empty
bool queue_empty(que_t q) {
if (NULL == q.head) {
return true;
} else {
return false;
}
}
// add an element to queue
void enqueue(char *name, que_t *q) {
item_t *temp;
temp = (item_t *)malloc(sizeof(item_t));
strncpy(temp->name,name,MAXLENGTH);
temp->next = NULL;
if (true == queue_empty(*q)) {
q->head = temp;
q->tail = temp;
} else {
q->tail->next = temp;
q->tail = q->tail->next;
}
}
// remove an element from the front of the queue
void dequeue(que_t *q) {
item_t *temp;
if (true == queue_empty(*q)) {
printf(" error in dequeue \n");
exit(-1);
} else {
temp = q->head;
q->head = q->head->next;
free(temp);
}
}
// find element at front of queue without removing
void peek_front(char *name, que_t q) {
if (true == queue_empty(q)) {
printf(" error in dequeue \n");
exit(-1);
} else {
strncpy(name, q.head->name, MAXLENGTH);
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment