LinuxQuestions.org
Review your favorite Linux distribution.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 04-13-2014, 11:52 AM   #1
MichaelStein
LQ Newbie
 
Registered: Apr 2014
Posts: 14

Rep: Reputation: Disabled
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;
}
 
Old 04-13-2014, 06:43 PM   #2
MichaelStein
LQ Newbie
 
Registered: Apr 2014
Posts: 14

Original Poster
Rep: Reputation: Disabled
Inotify finding a directory name instead of event->name

Hey everyone,
I am writing a program to write a the time a directory was accessed to LogFile.txt.

Now when I put in:

Code:
struct inotify_event* event = (struct inotify_event * ) &buffer[i];
		if(event->mask & IN_ACCESS)
		{	
			log.WriteFile(event->name);
		}
the program writes the names of all the files in the directory itself to the log. I want it to write the directory (ie. pathname) itself to the log. How do I get the pathname of the file being accessed?

Any help would be greatly appreciated.

Last edited by MichaelStein; 04-13-2014 at 09:43 PM. Reason: Clarification
 
Old 04-14-2014, 09:19 PM   #3
berndbausch
Senior Member
 
Registered: Nov 2013
Location: Tokyo
Distribution: A few
Posts: 3,623

Rep: Reputation: 979Reputation: 979Reputation: 979Reputation: 979Reputation: 979Reputation: 979Reputation: 979Reputation: 979
Quote:
Originally Posted by MichaelStein View Post
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.
I may be missing something, but the inotify(7) man page says:

Quote:
When a directory is monitored, inotify will return events for the directory itself, and for files inside the directory.
Not being an expert with this API, I can't say if this behaviour is configurable, and why the directory itself is left out in your case.
 
Old 04-15-2014, 09:20 PM   #4
rigor
Member
 
Registered: Sep 2011
Posts: 289

Rep: Reputation: Disabled
The inotify(7) man page also says:

Quote:
The name field is present only when an event is returned for a file inside a watched directory; it identifies the file pathname relative to the watched directory.
 
Old 06-22-2014, 06:37 AM   #5
colucix
LQ Guru
 
Registered: Sep 2003
Location: Bologna
Distribution: CentOS 6.5 OpenSuSE 12.3
Posts: 10,509

Rep: Reputation: 1981Reputation: 1981Reputation: 1981Reputation: 1981Reputation: 1981Reputation: 1981Reputation: 1981Reputation: 1981Reputation: 1981Reputation: 1981Reputation: 1981
Moved: This thread is more suitable in Programming and has been moved accordingly to help your thread/question get the exposure it deserves. Furthermore two very similar threads of yours have been merged here.
 
Old 06-22-2014, 07:04 AM   #6
dwhitney67
Senior Member
 
Registered: Jun 2006
Location: Maryland
Distribution: Kubuntu, Fedora, RHEL
Posts: 1,539

Rep: Reputation: 335Reputation: 335Reputation: 335Reputation: 335
Quote:
Originally Posted by MichaelStein View Post
... I want it to write the directory (ie. pathname) itself to the log. How do I get the pathname of the file being accessed?

Any help would be greatly appreciated.
Is this a trick question? Have you considered using the contents of the variable 'filename' for the path?

Perhaps you should consider renaming the variable to something more appropriate, such as 'pathname'.
 
  


Reply

Tags
c++, inotify


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
A script that prints an event for a given date. springjer10 Linux - Newbie 2 11-10-2012 02:32 PM
[SOLVED] Inotify miss event for directories under /sys/firmware Haidong839 Linux - Kernel 4 09-27-2012 04:58 AM
inotify to watch a directory then print and move algreig Linux - Newbie 4 05-25-2012 11:14 AM
inotify and filename / directory name change events euroquisling Programming 3 05-20-2009 04:26 AM
inotify for recursive directory monitoring venkat_k Programming 4 12-24-2008 04:45 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 04:25 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration