Commit fd795689 authored by Son Pham's avatar Son Pham

Pre-lab 11.1 Completed

parent e47ab545
#
# CSCI 315 Operating Systems Design
# Author: L. Felipe Perrone
# Date: 2011-04-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.
# compiler
CC = gcc
CFLAGS = -g -Wall
EXE = file_stat read_dir fdump
all: $(EXE)
fdump: fdump.c hexdump.o
$(CC) $(CFLAGS) fdump.c hexdump.o -o fdump
hexdump.o: hexdump.c
$(CC) $(CFLAGS) -c hexdump.c -o hexdump.o
file_stat: file_stat.o
$(CC) $(CFLAGS) -o file_stat file_stat.o
file_stat.o: file_stat.c
$(CC) -c $(CFLAGS) file_stat.c
read_dir: read_dir.o
$(CC) -o read_dir read_dir.o
read_dir.o: read_dir.c
$(CC) -c $(CFLAGS) read_dir.c
clean:
/bin/rm -f *~ *.o core $(EXE)
#
# CSCI 315 Operating Systems Design
# Author: L. Felipe Perrone
# Date: 2011-04-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.
# compiler
CC = gcc
CFLAGS = -g -Wall
EXE = file_stat read_dir
all: $(EXE)
fdump: fdump.c hexdump.o
$(CC) $(CFLAGS) fdump.c hexdump.o -o fdump
hexdump.o: hexdump.c
$(CC) $(CFLAGS) -c hexdump.c -o hexdump.o
file_stat: file_stat.o
$(CC) $(CFLAGS) -o file_stat file_stat.o
file_stat.o: file_stat.c
$(CC) -c $(CFLAGS) file_stat.c
read_dir: read_dir.o
$(CC) -o read_dir read_dir.o
read_dir.o: read_dir.c
$(CC) -c $(CFLAGS) read_dir.c
clean:
/bin/rm -f *~ *.o core $(EXE)
/**
* Name: Son Pham
* Class: CSCI 315
* Prof: Luiz Felipe Perrone
* fdump.c
*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include "hexdump.h"
int main(int argc, char* argv[]) {
// Check if there are enough arguments
if (argc != 4) {
printf("Command: fdump [filename] [offset] [size]\n");
exit(-1);
}
// Read arguments into filename
char* filename = argv[1];
unsigned long int offset = atoi(argv[2]);
unsigned long int size = atoi(argv[3]);
// Open the file and move to designated position
FILE* file = fopen(filename, "r");
fseek(file, offset, SEEK_SET);
// Read the number of bytes determine by size
char buf[size+1];
fread((void*) buf, size, 1, file);
hexdump(buf, size);
printf("\n"); // For the sake of clarity, include space
// Return 0 if everything is successful
return 0;
}
/**
* Name: Son Pham
* Class: CSCI 315
* Prof: Luiz Felipe Perrone
* fdump.c
*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include "hexdump.h"
int main(int argc, char* argv[]) {
// Check if there are enough arguments
if (argc != 4) {
printf("Command: fdump [filename] [offset] [size]\n");
exit(-1);
}
// Read arguments into filename
char* filename = argv[1];
unsigned long int offset = atoi(argv[2]);
unsigned long int size = atoi(argv[3]);
// Open the file and move to designated position
FILE* file = fopen(filename, "r");
fseek(file, offset, SEEK_SET);
// Read the number of bytes determine by size
char buf[size+1];
fread((void*) buf, size, 1, file);
hexdump(buf, size);
// Return 0 if everything is successful
return 0;
}
/*
* 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 <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <grp.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/statvfs.h>
#include <pwd.h>
#include <time.h>
#include <unistd.h>
int main(int argc, char *argv[]) {
// pointer to file name string
char *name;
// allocate tm structure to store retrieved time
struct tm time;
// allocate space to hold a string with retrieved time (ASCII text)
char asctime_str[35];
// container for complete set of file permission bits (binary)
unsigned int mode;
// container for the three bits of user permissions
unsigned int umode;
// container for the three bits of group permissions
unsigned int gmode;
// container for the three bits of owner permission
unsigned int omode;
// human readable file permissions (ASCII text)
char perm_bits_str[] = "---------";
// file descriptor
unsigned int fd;
// structure to contain the result of the fstat call (info on this file)
struct stat file_info;
// structure to contain the result of the vfstat call (info on file system)
struct statvfs fs_info;
// used to save the return value of realpath
char resolved_path[PATH_MAX];
char* ret_path;
// check number of arguments for appropriate usage
if (2 != argc) {
printf(" usage: %s [file_name]\n", argv[0]);
exit(-11);
}
// post-condition: argv[1] contains name of file to use
// try to open file
fd = open(argv[1], O_RDONLY);
if (-1 == fd) {
perror("Failed to open read only file - ");
exit(-1);
}
// use fstatvfs to learn details about the file system
if (fstatvfs(fd, &fs_info) == 0) {
printf("== FILE SYSTEM INFO ============================\n");
printf(" file system fstatvfs() call successful\n");
printf(" file system block size: %d\n", 0); // TO-DO
printf(" max. file name length: %d\n", 0); // TO-DO
} else {
printf("%s: File system fstatvfs call failed\n", argv[0]);
exit(-1);
}
// post-condition: maximum length of file name string is known
// use calloc to allocate space for file name string
name = calloc(fs_info.f_namemax, 1);
if (NULL == name) {
perror("Problem in calloc - ");
exit(-1);
}
// copy file name into name variable using secure version of string copy
strncpy(name, argv[1], 500);
// use fstat to get information on specific file
if (fstat(fd, &file_info) == 0) {
printf("\n== FILE INFO ============================\n");
printf(" file fstat() call successful\n");
// mode comes from the lower 9 bits in file_info.st_mode
mode = file_info.st_mode & 0x1FF;
printf(" file protection bits = 0%o\n", mode);
// umode comes from the high 3 bits in mode
umode = 0; // TO-DO
// gmode comes from the middle 3 bits in mode
gmode = 0; // TO-DO
// omode comes from the low 3 bits in mode
omode = 0; // TO-DO
// once you have set umode, gmode, and omode, the code below
// will construct the right string for you and display it
// construct string with file protection information
if (umode & 0x4) perm_bits_str[0] = 'r';
if (umode & 0x2) perm_bits_str[1] = 'w';
if (umode & 0x1) perm_bits_str[2] = 'x';
if (gmode & 0x4) perm_bits_str[3] = 'r';
if (gmode & 0x2) perm_bits_str[4] = 'w';
if (gmode & 0x1) perm_bits_str[5] = 'x';
if (omode & 0x4) perm_bits_str[6] = 'r';
if (omode & 0x2) perm_bits_str[7] = 'w';
if (omode & 0x1) perm_bits_str[8] = 'x';
printf(" file protection string = %s\n", perm_bits_str);
printf(" file protection mode (u:g:o) = %o:%o:%o\n",
umode, gmode, omode);
printf(" owner user name = %s\n",""); // TO-DO: man getpwuid
printf(" owner group name = %s\n", ""); // TO-DO: man getgrgid
// TO-DO: print "mode = x", where x may be:
// "regular file"
// "directory"
// "character device"
// "block device"
// "symbolic link"
// "socket"
// "fifo"
// "unknown"
if (S_ISREG(file_info.st_mode)) {
printf(" mode = regular file\n");
} else { // see TO-DO above
}
ret_path = realpath(name, resolved_path);
if (NULL != ret_path)
printf(" absolute path = %s\n", ret_path);
else {
perror(" couldn't resolve path");
exit(-1);
}
// fill in the time the last write was made to file
localtime_r(&(file_info.st_mtime), &time);
asctime_r(&time, asctime_str);
printf(" time of last modification: %s\n", asctime_str);
fflush(stdout);
close(fd);
exit(0);
}
else
printf(" fstat call failed\n");
return 0;
}
/*
* Copyright (c) 2012 Bucknell University
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: L. Felipe Perrone (perrone@bucknell.edu)
*/
#include <stdio.h>
char is_printable(unsigned char c) {
if ((c >= 0x20) && (c < 0x7F))
return c;
else
return '.';
}
void hexdump(char* buffer, unsigned int length) {
int b=0, c=0;
int s, rem;
// b is a counter for the number of bytes (half the number of hex digits)
printf("\n PAYLOAD HEXDUMP:\n");
while (b < length) {
printf("\n %07x:", b);
for (; (b%16<15) && (b<length); b++) {
if (0 == b % 2)
printf(" ");
printf("%02hhx", buffer[b]);
}
if (b < length)
printf("%02hhx ", buffer[b++]);
else { // print a number of spaces to align the remaining text
rem = b % 16;
for (s=0; s < 44 - ((rem*2) + (rem/2) + 1); s++)
printf(" ");
}
for (;(c%16<15) && (c<length); c++) {
printf("%c", is_printable(buffer[c]));
}
if (c<length)
printf("%c", is_printable(buffer[c++]));
}
}
/*
* Copyright (c) 2012 Bucknell University
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: L. Felipe Perrone (perrone@bucknell.edu)
*/
#include <stdio.h>
char is_printable(unsigned char c) {
if ((c >= 0x20) && (c < 0x7F))
return c;
else
return '.';
}
void hexdump(unsigned char* buffer, unsigned int length) {
int b=0, c=0;
int s, rem;
// b is a counter for the number of bytes (half the number of hex digits)
printf("\n PAYLOAD HEXDUMP:\n");
while (b < length) {
printf("\n %07x:", b);
for (; (b%16<15) && (b<length); b++) {
if (0 == b % 2)
printf(" ");
printf("%02hhx", buffer[b]);
}
if (b < length)
printf("%02hhx ", buffer[b++]);
else { // print a number of spaces to align the remaining text
rem = b % 16;
for (s=0; s < 44 - ((rem*2) + (rem/2) + 1); s++)
printf(" ");
}
for (;(c%16<15) && (c<length); c++) {
printf("%c", is_printable(buffer[c]));
}
if (c<length)
printf("%c", is_printable(buffer[c++]));
}
}
/*
* Copyright (c) 2012 Bucknell University
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: L. Felipe Perrone (perrone@bucknell.edu)
*/
#ifndef __HEXDUMP_H__
#define __HEXDUMP_H__
/**
* This function prints to stdout the contents of a buffer in hexadecimal
* and in its ASCII representation. The output is similar to what you would
* get by running the Linux utility xxd on a file.
*
* @param buffer pointer to a memory buffer
* @param length number of bytes in the buffer
*/
extern void hexdump(char* buffer, unsigned int length);
#endif /* __HEXDUMP_H__ */
/*
* Copyright (c) 2012 Bucknell University
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: L. Felipe Perrone (perrone@bucknell.edu)
*/
#ifndef __HEXDUMP_H__
#define __HEXDUMP_H__
/**
* This function prints to stdout the contents of a buffer in hexadecimal
* and in its ASCII representation. The output is similar to what you would
* get by running the Linux utility xxd on a file.
*
* @param buffer pointer to a memory buffer
* @param length number of bytes in the buffer
*/
extern void hexdump(unsigned char* buffer, unsigned int length);
#endif /* __HEXDUMP_H__ */
/*
* 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;
que_t nameq;
char dname[MAXLENGTH];
char cname[MAXLENGTH];
char prefix[MAXLENGTH];
struct dirent *dp;
DIR *dirp;
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
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);
} else {
// test if it is a regular file and not a device or link -- TO-DO
// if this is a regular file, then process it -- TO-DO
printf(" processing file: %s\n", dname);
numOfFiles++;
}
} // while
printf(" a total of %d files were counted\n",numOfFiles);
}
// 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);
}
}
/*
* 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 <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <fcntl.h>
#include <ctype.h>
#include <sys/time.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdbool.h>