LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   The event->name (inotify) prints all the sub-directories - not the main directory (https://www.linuxquestions.org/questions/programming-9/the-event-name-inotify-prints-all-the-sub-directories-not-the-main-directory-4175501538/)

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;
}


MichaelStein 04-13-2014 05:43 PM

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.

berndbausch 04-14-2014 08:19 PM

Quote:

Originally Posted by MichaelStein (Post 5151740)
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.

rigor 04-15-2014 08:20 PM

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.

colucix 06-22-2014 05:37 AM

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.

dwhitney67 06-22-2014 06:04 AM

Quote:

Originally Posted by MichaelStein (Post 5151952)
... 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'.


All times are GMT -5. The time now is 08:01 PM.