--- /dev/null
+open Unix
+open Globals
+open Dirwatcher
+open Inotify
+open Fifowatcher
+open Frontend
+open Printf
+
+let delete_prefix prefix str =
+ let len = String.length str in
+ let plen = String.length prefix in
+ if (String.sub str 0 plen <> prefix)
+ then
+ raise Bad_path
+ else
+ Relpath(String.sub str (plen+1) (len-plen-1))
+
+let rec list_check lst elt =
+ match lst with
+ | [] -> false
+ | car::cdr -> if (car==elt) then true else list_check cdr elt
+
+
+ (*
+ * One backendHandler class for each
+ * backend. Builds the initial
+ * tree for the frontend and
+ * watches for directory
+ * events.
+ *)
+
+class backendHandler dir_root (frontend_lst: frontendHandler list) =
+ let mk_rel_path = delete_prefix dir_root in object(this)
+
+ val file_regexp = ref (Str.regexp "[a-zA-Z][a-zA-Z0-9_-'.']*")
+
+ method new_dir fqp func =
+ let s = Unix.stat fqp in
+ List.iter
+ (fun frontend->
+ frontend#mkdir (mk_rel_path fqp) (s.st_perm);
+ Dirwatcher.add_watch fqp [S_Create;S_Delete] (Some(func)))
+ frontend_lst;
+
+ method new_script fqp =
+ let s = Unix.stat fqp in
+ List.iter (fun frontend->
+ frontend#mkentry (mk_rel_path fqp) fqp (s.st_perm)) frontend_lst
+
+ val dir_regexp = Str.regexp "^dir_";
+
+ method handle_dir_event dirname evlist fname =
+ let fqp = String.concat "/" [dirname;fname] in
+ if (Str.string_match !file_regexp fname 0) then
+ begin
+ let is_event = list_check evlist in
+ if (is_event Create) then
+ begin
+ if (is_event Isdir) then
+ begin
+ this#new_dir fqp this#handle_dir_event
+ end
+ else
+ (* It's a new script *)
+ begin
+ (*
+ if (Str.string_match dir_regexp fname 0) then
+ let fqp = String.concat "/" [dirname;String.sub fname 4 ((String.length fname)-4+1)] in
+ let real_fqp = String.concat "/" [dirname;fname] in
+ this#new_dir fqp this#handle_spool_event;
+ Hashtbl.add spools fqp real_fqp
+ else*)
+ this#new_script fqp
+ end
+ end
+ else if (is_event Delete) then
+ begin
+ if (is_event Isdir) then
+ begin
+ (*this#rm_watch fqp;*)
+ List.iter (fun frontend->
+ frontend#rmdir (mk_rel_path fqp)) frontend_lst
+ end
+ else List.iter (fun frontend ->
+ frontend#unlink (mk_rel_path fqp)) frontend_lst
+ end
+ end
+ else (* regex not matched *)
+ ()
+
+ initializer
+ let rec build_initial_tree dir =
+ let dir_handle = opendir dir in
+ let cont = ref true in
+ while (!cont) do
+ try
+ let curfile = readdir dir_handle in
+ let fqp = String.concat "/" [dir;curfile] in
+ if (Str.string_match !file_regexp curfile 0) then
+ let s = Unix.stat fqp in
+ begin
+ match s.st_kind with
+ | S_DIR ->
+ this#new_dir fqp this#handle_dir_event;
+ build_initial_tree fqp;
+ | S_REG ->
+ this#new_script fqp
+ | _ ->
+ printf "Don't know what to do with %s\n" curfile;flush Pervasives.stdout
+ end
+ with
+ _->cont:=false;()
+ done
+ in
+ begin
+ build_initial_tree dir_root;
+ Dirwatcher.add_watch dir_root [S_Create;S_Delete] (Some(this#handle_dir_event));
+ end
+end