MichaelStein |
04-13-2014 10:52 AM |
The event->name (inotify) prints all the sub-directories - not the main directory
Hi all,
I have been writing a program to monitor when a certain file has been accessed and record the result in a Logfile.txt. However, whenever I enter the file to be monitored, instead of printing when that file was accessed, it does that to all its sub-directories.
For example in the command line I enter:
michaelstein@ubuntu:~/Desktop/codes/File_Monitor_Project$ ./Monitor_File_Access
Please enter the file path name: /home/michaelstein/Desktop/codes
it should print in the LogFile.txt:
User ID: michaelstein. File name: /home/michaelstein/Desktop/codes. Access time: Sun Apr 13 11:23:47 2014
but instead it prints:
User ID: michaelstein. File name: FileWriter.cxx. Access time: Sun Apr 13 11:25:06 2014
User ID: michaelstein. File name: Helloworld.cxx. Access time: Sun Apr 13 11:25:06 2014
User ID: michaelstein. File name: main.cxx. Access time: Sun Apr 13 11:25:06 2014
which is all the sub-directories. I have a feeling that it has to do with the event->name called in the main function. But I don't know how to fix it.
Here is the code:
Log.h:
Code:
#ifndef LOG_H
#define LOG_H
#include <iostream>
#include <ios>
#include <fstream>
#include <string>
#include <cstring>
#include <ctime>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
using namespace std;
class LogFiles
{
public:
LogFiles(char* filename);
~LogFiles();
void WriteFile(string filename);
private:
ofstream outf;
};
#endif
Log.cxx:
Code:
#include "Log.h"
LogFiles::LogFiles(char* filename)
{
/*Opens the file to append text to it*/
outf.open(filename, std::ios_base::app | std::ios_base::out);
/*Error handling*/
if(!outf.is_open())
{
cerr << "Error opening Logfile" << endl;
}
}
/*Print the time the file was accessed*/
void LogFiles::WriteFile(string filename)
{
/*Get the current time and date using the ctime library*/
time_t now = time(0);
/*Convert to char*/
char* dt = ctime(&now);
/*Output*/
outf << "User ID: " << getenv("USER") << ". File name: " << filename << ". Access time: " << dt << endl;
}
/*Destructor*/
LogFiles::~LogFiles()
{
outf.close();
}
Monitor-File_Access.cxx
Code:
/* This program will take as arguments one or more directory
or file names, and monitor them, printing time, date of access
and user id. Use ctrl-C or kill to terminate otherwise.
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/inotify.h>
#include <sys/stat.h>
#include <signal.h>
#include <list>
#include "Log.h"
#define EVENT_SIZE ( sizeof (struct inotify_event) )
#define BUF_LEN ( 1024 * ( EVENT_SIZE + 16 ) )
char buffer[BUF_LEN];
bool exitProgram = false;
/*Function to exit the program.*/
void SignalHandler(int signum)
{
printf("\nProgram interrupted. Exiting.\n");
exit(signum);
exitProgram = true;
}
/*Function to check if the file exists.*/
bool FileExists(string filename) {
struct stat fileInfo;
return stat(filename.c_str(), &fileInfo) == 0;
}
using namespace std;
int main (int argc, char **argv)
{
/*Program terminates when ctrl+c is pressed.*/
signal(SIGINT, SignalHandler);
int length, i = 0;
/*Initialise a file descriptor.*/
int fd;
/*Initialise a watch descriptor.*/
int wd;
/*The file descriptor is set to the new inotify instance created*/
fd = inotify_init();
/*Initialise log file name and call log() function to open and print access times to log file*/
char logFileName[] = "Log file.txt";
LogFiles log(logFileName);
/*Obtain the filename to be monitored from user input.*/
string filename;
printf("Please enter the file path name: ");
getline(cin, filename);
/*Check whether files exists. Prompt user to re-enter filename*/
while(FileExists(filename) == false )
{
printf("File %s does not exist. Try again.\n", filename.c_str());
printf("Please enter the file path name: ");
getline(cin, filename);
}
int index;
wd = 0;
/* Watches IN_ACCESS for the directories and
files passed in as arguments.*/
while(exitProgram != true)
{
/*Adds a watch*/
wd = inotify_add_watch(fd, filename.c_str(), IN_ACCESS);
/*Calls read() to wait for alert*/
length = read(fd, buffer, BUF_LEN);
if(length < 0)
{
perror("read");
}
struct inotify_event* event = (struct inotify_event * ) &buffer[0];
if(event->mask & IN_ACCESS)
{
log.WriteFile(event->name);
}
}
printf ("\nTerminating\n");
/* Finish up by closing the fd
and returning a proper code
*/
(void) inotify_rm_watch(fd, wd);
(void) close(fd);
return 0;
}
|