• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 577
  • Last Modified:

Directory and SubDirectory watcher

HI
I am linux Admin, and i last touched  C when i was 3rd year Computer science student!! after that from last good couple of year did not touch C

anyway ..
i am looking for some solution which i explained to this questions :
http://www.experts-exchange.com/OS/Linux/Q_25026679.html?cid=1576

while looking in google, i found this C code which works as directory watcher
http://www.ibm.com/developerworks/linux/library/l-ubuntu-inotify/index.html

Now,i tryed this code, its only works the directory, it does not go inside another directory
Example, if i set :

wd = inotify_add_watch( fd, "/htdocs",
it will just keep watch first 1st level of this directory, any directory bellow this will not watch
is there any way to add this facilities on this code ???


also : how can i run this code always?? if i run this code
./watcher  &

it will just fire onece, but after that it will exit, so how can i run this code always???

thanks
 
0
fosiul01
Asked:
fosiul01
  • 5
  • 4
  • 3
4 Solutions
 
nuke3ddCommented:
This does not directly answer your question, but maybe it will help you to avoid having to reinvent something:
http://iwatch.sourceforge.net/index.html
0
 
jkrCommented:
>>it will just keep watch first 1st level of this directory, any directory bellow this
>>will not watch

According to the manpages for that API (http://linux.die.net/man/7/inotify and http://linux.die.net/man/2/inotify_add_watch), it seems that watching a subtree is not implemented, you'd have to set a watch for each subdirectory individually. Maybe 'fileschanged (http://fileschanged.sourceforge.net/) could serve you better here - similar to the one suggested by nuke3dd.

>>also : how can i run this code always??

That'd be the simpler part, e.g.
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/inotify.h>

#define EVENT_SIZE  ( sizeof (struct inotify_event) )
#define BUF_LEN     ( 1024 * ( EVENT_SIZE + 16 ) )

int main( int argc, char **argv ) 
{
  int length, i = 0;
  int fd;
  int wd;
  char buffer[BUF_LEN];

  fd = inotify_init();

  if ( fd < 0 ) {
    perror( "inotify_init" );
  }

  wd = inotify_add_watch( fd, "/home/strike", 
                         IN_MODIFY | IN_CREATE | IN_DELETE );
  length = read( fd, buffer, BUF_LEN );  

  if ( length < 0 ) {
    perror( "read" );
  }  

  while (1) { // <-------------- START loop to continuously monitor files

  while ( i < length ) {
    struct inotify_event *event = ( struct inotify_event * ) &buffer[ i ];
    if ( event->len ) {
      if ( event->mask & IN_CREATE ) {
        if ( event->mask & IN_ISDIR ) {
          printf( "The directory %s was created.\n", event->name );       
        }
        else {
          printf( "The file %s was created.\n", event->name );
        }
      }
      else if ( event->mask & IN_DELETE ) {
        if ( event->mask & IN_ISDIR ) {
          printf( "The directory %s was deleted.\n", event->name );       
        }
        else {
          printf( "The file %s was deleted.\n", event->name );
        }
      }
      else if ( event->mask & IN_MODIFY ) {
        if ( event->mask & IN_ISDIR ) {
          printf( "The directory %s was modified.\n", event->name );
        }
        else {
          printf( "The file %s was modified.\n", event->name );
        }
      }
    }
    i += EVENT_SIZE + event->len;
  }

  } // <-------------- END loop to continuously monitor files

  ( void ) inotify_rm_watch( fd, wd );
  ( void ) close( fd );

  exit( 0 );
}

Open in new window

0
 
fosiul01Author Commented:
HI
thanks @jkr and @nuke3dd

@jkr :
i compiled as your code, then run it , but still it does not continue .. after first file watch, it does not do anything

@nuke3dd..
my purpose was to monitor a directory, if programm see, there is any changes of that directory it will fire rsync programm to copy data from that directory to anotehr server...

so i am not thinking of security measure.. its mainly file transfer  .... ( near to real time)
0
Cloud Class® Course: MCSA MCSE Windows Server 2012

This course teaches how to install and configure Windows Server 2012 R2.  It is the first step on your path to becoming a Microsoft Certified Solutions Expert (MCSE).

 
jkrCommented:
>>i compiled as your code, then run it , but still it does not continue ..

Sorry, overhurried change on my side, the loop should be different and enclose the 'read()' call:


#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/inotify.h>

#define EVENT_SIZE  ( sizeof (struct inotify_event) )
#define BUF_LEN     ( 1024 * ( EVENT_SIZE + 16 ) )

int main( int argc, char **argv ) 
{
  int length, i = 0;
  int fd;
  int wd;
  char buffer[BUF_LEN];

  fd = inotify_init();

  if ( fd < 0 ) {
    perror( "inotify_init" );
  }

  wd = inotify_add_watch( fd, "/home/strike", 
                         IN_MODIFY | IN_CREATE | IN_DELETE );


  while (1) { // <-------------- START loop to continuously monitor files

  length = read( fd, buffer, BUF_LEN );  

  if ( length < 0 ) {
    perror( "read" );
  }  

  while ( i < length ) {
    struct inotify_event *event = ( struct inotify_event * ) &buffer[ i ];
    if ( event->len ) {
      if ( event->mask & IN_CREATE ) {
        if ( event->mask & IN_ISDIR ) {
          printf( "The directory %s was created.\n", event->name );       
        }
        else {
          printf( "The file %s was created.\n", event->name );
        }
      }
      else if ( event->mask & IN_DELETE ) {
        if ( event->mask & IN_ISDIR ) {
          printf( "The directory %s was deleted.\n", event->name );       
        }
        else {
          printf( "The file %s was deleted.\n", event->name );
        }
      }
      else if ( event->mask & IN_MODIFY ) {
        if ( event->mask & IN_ISDIR ) {
          printf( "The directory %s was modified.\n", event->name );
        }
        else {
          printf( "The file %s was modified.\n", event->name );
        }
      }
    }
    i += EVENT_SIZE + event->len;
  }

  } // <-------------- END loop to continuously monitor files

  ( void ) inotify_rm_watch( fd, wd );
  ( void ) close( fd );

  exit( 0 );
}

Open in new window

0
 
nuke3ddCommented:
Yes, iWatch can execute a command if an event occures. If it's not flexible enough there's always the possibility to modify it, since it's opensource.
0
 
fosiul01Author Commented:
Sorry , nop, still its,just taking the first modification,

like if create or delete anything from directory first time, it will work, but after that, it does not do anything
0
 
fosiul01Author Commented:
@nuke3dd, iwatch is comming as file binary...

its saying its perl module, but author is not providing any perl code to modify it
0
 
jkrCommented:
OK, let's take that to the extreme then ;o)
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/inotify.h>

#define EVENT_SIZE  ( sizeof (struct inotify_event) )
#define BUF_LEN     ( 1024 * ( EVENT_SIZE + 16 ) )

int main( int argc, char **argv ) 
{
  int length, i = 0;
  int fd;
  int wd;
  char buffer[BUF_LEN];

  while (1) { // <-------------- START loop to continuously monitor files

  fd = inotify_init();

  if ( fd < 0 ) {
    perror( "inotify_init" );
  }

  wd = inotify_add_watch( fd, "/home/strike", 
                         IN_MODIFY | IN_CREATE | IN_DELETE );


  length = read( fd, buffer, BUF_LEN );  

  if ( length < 0 ) {
    perror( "read" );
  }  

  while ( i < length ) {
    struct inotify_event *event = ( struct inotify_event * ) &buffer[ i ];
    if ( event->len ) {
      if ( event->mask & IN_CREATE ) {
        if ( event->mask & IN_ISDIR ) {
          printf( "The directory %s was created.\n", event->name );       
        }
        else {
          printf( "The file %s was created.\n", event->name );
        }
      }
      else if ( event->mask & IN_DELETE ) {
        if ( event->mask & IN_ISDIR ) {
          printf( "The directory %s was deleted.\n", event->name );       
        }
        else {
          printf( "The file %s was deleted.\n", event->name );
        }
      }
      else if ( event->mask & IN_MODIFY ) {
        if ( event->mask & IN_ISDIR ) {
          printf( "The directory %s was modified.\n", event->name );
        }
        else {
          printf( "The file %s was modified.\n", event->name );
        }
      }
    }
    i += EVENT_SIZE + event->len;
  }

  ( void ) inotify_rm_watch( fd, wd );
  ( void ) close( fd );

  } // <-------------- END loop to continuously monitor files

  exit( 0 );
}

Open in new window

0
 
fosiul01Author Commented:
hahaa, sorry,... still no luck....

i am running the programme by ./iwatch



0
 
nuke3ddCommented:
It's hosted at sourceforge, so it has to be opensource. The file included in the archive is pure perl, not a binary.
0
 
fosiul01Author Commented:
@nuke3dd, Sorry i cant find it, can you please give me the right link to download the source code??
0
 
nuke3ddCommented:
Ok, here's the direct link to the archive containing the iwatch perl source (which also the executable):
http://downloads.sourceforge.net/project/iwatch/iwatch/0.2.2/iwatch-0.2.2.tgz?use_mirror=heanet
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Cloud Class® Course: Microsoft Azure 2017

Azure has a changed a lot since it was originally introduce by adding new services and features. Do you know everything you need to about Azure? This course will teach you about the Azure App Service, monitoring and application insights, DevOps, and Team Services.

  • 5
  • 4
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now