Introduced direct-connected services, which offer pipe semantics.
[vsys.git] / dirwatcher.ml
1 (** Watches directories for events. Agnostic to vsys semantics of backends and
2 frontends *)
3 open Inotify
4 open Fdwatcher
5 open Printf
6 open Globals
7
8 (* I don't know if a wd corresponding to a deleted directory is evicted or just
9  * leaks - fix implementation of rmdir accordingly
10  *)
11
12 let wdmap = Hashtbl.create 1024
13
14 let fd = Inotify.init ()
15
16 let handle_dir_event dirname evlist str = 
17     let fname = String.concat "/" [dirname;str] in
18         fprintf logfd "File: %s. " fname;List.iter 
19                   (fun e -> 
20                      fprintf logfd "Event: %s\n" (string_of_event e)) 
21                   evlist;
22         flush logfd
23
24 let add_watch dir events handler =
25   printf "Adding watch for %s\n" dir;flush Pervasives.stdout;
26   let wd = Inotify.add_watch fd dir events in
27       Hashtbl.add wdmap wd (dir,handler)
28
29         (* XXX
30 let del_watch dir =
31   fprintf logfd "Removing watch for %s\n" dir;flush logfd;
32   let wd = Inotify.rm_watch fd dir in
33       Hashtbl.remove wdmap wd 
34          *)
35
36 let asciiz s =
37   let rec findfirstnul str idx len =
38     if ((idx==len) || 
39       (str.[idx]==(char_of_int 0))) then idx
40       else
41         findfirstnul str (idx+1) len
42   in
43   let nulterm = findfirstnul s 0 (String.length s) in
44     String.sub s 0 nulterm
45
46 let receive_event (eventdescriptor:fname_and_fd) (bla:fname_and_fd) =
47   let (_,fd) = eventdescriptor in
48       let evs = Inotify.read fd in
49         List.iter (fun x->
50                 match x with
51                   | (wd,evlist,_,Some(str)) ->
52                       let purestr = asciiz(str) in
53                       let (dirname,handler) = 
54                         try Hashtbl.find wdmap wd with Not_found->fprintf logfd "Unknown watch descriptor\n";raise Not_found
55                       in
56                         (
57                         match handler with
58                           | None->handle_dir_event dirname evlist purestr
59                           | Some(handler)->handler dirname evlist purestr
60                         )
61                   | _ -> ()) 
62           evs
63
64 let initialize () =
65   Fdwatcher.add_fd (None,fd) (None,fd) receive_event