diff options
author | 53hornet <53hornet@gmail.com> | 2019-02-02 22:59:54 -0500 |
---|---|---|
committer | 53hornet <53hornet@gmail.com> | 2019-02-02 22:59:54 -0500 |
commit | 379c2c17e68d5d471a6a9673b7e9cd1fb9d99bbb (patch) | |
tree | eed499da8211a5eece757639331a2d82bce4fa4c /pgm3/accessed.c | |
download | csci415-master.tar.xz csci415-master.zip |
Diffstat (limited to 'pgm3/accessed.c')
-rw-r--r-- | pgm3/accessed.c | 122 |
1 files changed, 122 insertions, 0 deletions
diff --git a/pgm3/accessed.c b/pgm3/accessed.c new file mode 100644 index 0000000..b1007a9 --- /dev/null +++ b/pgm3/accessed.c @@ -0,0 +1,122 @@ +#include <errno.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/sysmacros.h> +#include <time.h> +#include <unistd.h> + +#define FALSE 0 +#define FILE_BUFF 4096 +#define TRUE 1 + +struct NODE { + char filename[FILE_BUFF]; + int inode; + long atime; + struct NODE *next; +}; + +int makeList(struct NODE **head) { + /* + * makeList builds a linked list of nodes representing the filenames + * given on stdin and their access time. + */ + char filename[FILE_BUFF]; + int inList = FALSE; + struct NODE *currentNode = NULL; + struct NODE *newNode = NULL; + struct stat statData; + + while (scanf(" %s", filename) == 1) { + + if (stat(filename, &statData) == 0 && S_ISREG(statData.st_mode)) { + inList = FALSE; + + for (currentNode = *head; currentNode != NULL; currentNode = currentNode->next) { + + if (currentNode->inode == statData.st_ino) { + inList = TRUE; + } + + } + + if (!inList) { + newNode = (struct NODE *) malloc(sizeof(struct NODE)); + newNode->inode = statData.st_ino; + strcpy(newNode->filename, filename); + newNode->atime = (time(NULL) - statData.st_atime) / 86400; + newNode->next = *head; + *head = newNode; + } + + } + + } + + return 0; +} + +int main(int argc, char *argv[]) { + /* + * accessed takes in filenames from stdin and one command line argument, + * "num". It then builds a linked list of the unique, regular files and + * prints out those files not accessed in "num" days (if num is positive) + * or prints out those files accesssed within "num" days (if num is + * negative). + */ + int accessedNum = 0; + struct NODE *currentNode = NULL; + struct NODE *list = NULL; + + // Go through args + if (argc != 2) { + fprintf(stderr, "accessed: usage: ./accessed [num days]\n"); + exit(1); + } + + accessedNum = strtol(argv[1], NULL, 10); + + if (errno == EINVAL) { + fprintf(stderr, "accessed: error: num must be integer type.\n"); + exit(1); + } + else if (errno == ERANGE) { + fprintf(stderr, "accessed: error: num must be of integer size.\n"); + exit(1); + } + else if (accessedNum == 0) { + fprintf(stderr, "accessed: error: num must be nonzero integer.\n"); + exit(1); + } + + if (makeList(&list) != 0) { + fprintf(stderr, "accessed: error: could not build linked list.\n"); + exit(1); + } + + // print out filenames that match requested access time + for (currentNode = list; currentNode != NULL; currentNode = currentNode->next) { + + if (accessedNum > 0 && currentNode->atime > accessedNum) { // not within num days + printf("%s\n", currentNode->filename); + } + + if (accessedNum < 0 && currentNode->atime <= (accessedNum * -1)) { // within num days + printf("%s\n", currentNode->filename); + } + + } + + // free list + while (currentNode != NULL) { + currentNode = list; + list = list->next; + free(currentNode); + } + + exit(0); +} |