In the long term, this will be more stable than the previous strategy.
IN the short term (for the next 1-2 days) vsys is broken... don't use it
+backend.cmo: inotify.cmi globals.cmo frontend.cmo fifowatcher.cmo \
+ dirwatcher.cmo
+backend.cmx: inotify.cmi globals.cmx frontend.cmx fifowatcher.cmx \
+ dirwatcher.cmx
+conffile.cmo: globals.cmo
+conffile.cmx: globals.cmx
+directfifowatcher.cmo: splice.cmo inotify.cmi globals.cmo dirwatcher.cmo
+directfifowatcher.cmx: splice.cmx inotify.cmi globals.cmx dirwatcher.cmx
dirwatcher.cmo: inotify.cmi globals.cmo fdwatcher.cmo
dirwatcher.cmx: inotify.cmi globals.cmx fdwatcher.cmx
fdwatcher.cmo: globals.cmo
fdwatcher.cmx: globals.cmx
-fifowatcher.cmo: inotify.cmi globals.cmo fdwatcher.cmo dirwatcher.cmo
-fifowatcher.cmx: inotify.cmi globals.cmx fdwatcher.cmx dirwatcher.cmx
-frontend.cmo: globals.cmo fifowatcher.cmo
-frontend.cmx: globals.cmx fifowatcher.cmx
+fifowatcher.cmo: splice.cmo inotify.cmi globals.cmo fdwatcher.cmo \
+ dirwatcher.cmo
+fifowatcher.cmx: splice.cmx inotify.cmi globals.cmx fdwatcher.cmx \
+ dirwatcher.cmx
+frontend.cmo: globals.cmo directfifowatcher.cmo
+frontend.cmx: globals.cmx directfifowatcher.cmx
main.cmo: inotify.cmi globals.cmo frontend.cmo fifowatcher.cmo fdwatcher.cmo \
- dirwatcher.cmo backend.cmo
+ dirwatcher.cmo conffile.cmo backend.cmo
main.cmx: inotify.cmi globals.cmx frontend.cmx fifowatcher.cmx fdwatcher.cmx \
- dirwatcher.cmx backend.cmx
+ dirwatcher.cmx conffile.cmx backend.cmx
$(MAKE) -C ocaml_inotify-0.4 && cp -f ocaml_inotify-0.4/inotify_stubs.o ./
vsys: ocaml_inotify-0.4/inotify.cmxa globals.cmx fdwatcher.cmx conffile.cmx splice_stub.o splice.cmx dirwatcher.cmx fifowatcher.cmx frontend.cmx backend.cmx main.cmx docs
- ocamlopt -I ocaml_inotify-0.4 str.cmxa unix.cmxa inotify.cmxa globals.cmx fdwatcher.cmx dirwatcher.cmx splice.cmx splice_stub.o fifowatcher.cmx frontend.cmx backend.cmx str.cmxa conffile.cmx main.cmx -o vsys
+ ocamlopt -I ocaml_inotify-0.4 str.cmxa unix.cmxa inotify.cmxa globals.cmx fdwatcher.cmx dirwatcher.cmx splice.cmx splice_stub.o directfifowatcher.cmx frontend.cmx backend.cmx str.cmxa conffile.cmx main.cmx -o vsys
-vsys.b: ocaml_inotify-0.4/inotify.cma inotify.cmi globals.ml fdwatcher.ml dirwatcher.ml fifowatcher.ml frontend.ml backend.ml main.ml
- ocamlc -g str.cma unix.cma ocaml_inotify-0.4/inotify.cma globals.cmo fdwatcher.cmo dirwatcher.cmo fifowatcher.cmo frontend.cmo backend.cmo str.cma conffile.cmo main.cmo -o vsys.b
+vsys.b: ocaml_inotify-0.4/inotify.cma inotify.cmi globals.ml fdwatcher.ml dirwatcher.ml directfifowatcher.ml frontend.ml backend.ml main.ml
+ ocamlc -g str.cma unix.cma ocaml_inotify-0.4/inotify.cma globals.cmo fdwatcher.cmo dirwatcher.cmo directfifowatcher.cmo frontend.cmo backend.cmo str.cma conffile.cmo main.cmo -o vsys.b
install: vsys
cp vsys $(INSTALL_DIR)/usr/bin
--- /dev/null
+(** fifowatcher.ml: Routines to handle non-persistent scripts *)
+
+open Inotify
+open Unix
+open Globals
+open Dirwatcher
+open Printf
+open Splice
+
+let backend_prefix = ref ""
+let direct_fifo_table: (string,(string*string) option) Hashtbl.t = Hashtbl.create 1024
+
+let rec list_check lst elt =
+ match lst with
+ | [] -> false
+ | car::cdr -> if (car==elt) then true else list_check cdr elt
+
+
+
+
+(* vsys is activated when a client opens an in file *)
+let connect_file fqp_in =
+ (* Do we care about this file? *)
+ let entry_info = try
+ Hashtbl.find direct_fifo_table fqp_in with _ -> fprintf logfd "[Alert] Access via unauthorized vsys entry: %s\n" fqp_in;flush logfd;None in
+ match entry_info with
+ | Some(execpath,slice_name) ->
+ fprintf logfd "Executing %s for slice %s\n" execpath slice_name;flush logfd;
+ begin
+ let len = String.length fqp_in in
+ let fqp = String.sub fqp_in 0 (len-3) in
+ let fqp_out = String.concat "." [fqp;"out"] in
+ let fifo_fdin =
+ try openfile fqp_in [O_RDONLY;O_NONBLOCK] 0o777 with
+ e->fprintf logfd "Error opening and connecting FIFO: %s\n" fqp_in;flush logfd;raise e
+ in
+ let fifo_fdout =
+ try openfile fqp_out [O_WRONLY;O_NONBLOCK] 0o777 with
+ _->fprintf logfd "%s Output pipe not open, using stdout in place of %s\n" slice_name fqp_out;flush logfd;stdout
+ in
+ try ignore(create_process execpath [|execpath;slice_name|] fifo_fdin fifo_fdout fifo_fdout) with e -> fprintf logfd "Error executing service: %s\n" execpath;flush logfd
+ end
+ | None -> ()
+
+
+(** Make a pair of fifo entries *)
+let mkentry fqp abspath perm uname =
+ fprintf logfd "Making entry %s->%s\n" fqp abspath;flush logfd;
+ let fifoin=sprintf "%s.in" fqp in
+ let fifoout=sprintf "%s.out" fqp in
+ (try Unix.unlink fifoin with _ -> ());
+ (try Unix.unlink fifoout with _ -> ());
+ (try
+ let infname =(sprintf "%s.in" fqp) in
+ let outfname =(sprintf "%s.out" fqp) in
+ Unix.mkfifo infname 0o666;
+ Unix.mkfifo outfname 0o666;
+ ( (* Make the user the owner of the pipes in a non-chroot environment *)
+ if (!Globals.nochroot) then
+ let pwentry = Unix.getpwnam uname in
+ Unix.chown infname pwentry.pw_uid pwentry.pw_gid;
+ Unix.chown outfname pwentry.pw_uid pwentry.pw_gid
+ );
+ Success
+ with
+ e->fprintf logfd "Error creating FIFO: %s->%s. May be something wrong at the frontend.\n" fqp fifoout;flush logfd;Failed)
+
+(** Open fifos for a session. SHOULD NOt shutdown vsys if the fifos don't exist *)
+let openentry fqp backend_spec =
+ let fqp_in = String.concat "." [fqp;"in"] in
+ Hashtbl.replace direct_fifo_table fqp_in (Some(backend_spec))
+
+(** Close fifos that just got removed *)
+let closeentry fqp =
+ let fqp_in = String.concat "." [fqp;"in"] in
+ Hashtbl.remove direct_fifo_table fqp_in
+
+let direct_fifo_handler dirname evlist fname =
+ printf "Received event %s %s\n" dirname fname;flush Pervasives.stdout;
+ let is_event = list_check evlist in
+ if (is_event Open) then
+ let fqp_in = String.concat "/" [dirname;fname] in
+ connect_file fqp_in
+
+let add_dir_watch fqp =
+ Dirwatcher.add_watch fqp [S_Open] (Some(direct_fifo_handler))
+
+let del_dir_watch fqp =
+ (* XXX Dirwatcher.del_watch fqp *)
+ ()
flush logfd
let add_watch dir events handler =
- fprintf logfd "Adding watch for %s\n" dir;flush logfd;
+ printf "Adding watch for %s\n" dir;flush Pervasives.stdout;
let wd = Inotify.add_watch fd dir events in
Hashtbl.add wdmap wd (dir,handler)
+ (* XXX
+let del_watch dir =
+ fprintf logfd "Removing watch for %s\n" dir;flush logfd;
+ let wd = Inotify.rm_watch fd dir in
+ Hashtbl.remove wdmap wd
+ *)
+
let asciiz s =
let rec findfirstnul str idx len =
if ((idx==len) ||
open Printf
open Unix
open Globals
-open Fifowatcher
+open Directfifowatcher
(** frontendhandler class: Methods to create and unlink pipes and directories
@param root_dir vsys directory inside a slice
@param abspath Absolute path of the entry
@param perm Permissions of the entry at the frontend *)
method mkentry (rp:relpath) abspath perm =
- let realperm = perm land (lnot 0o111) in
- match rp with Relpath(rel) ->
- let fqp = String.concat "/" [root_dir;rel] in
- let res = Fifowatcher.mkentry fqp abspath realperm slice_name in
- match res with
- | Success ->
- Fifowatcher.openentry fqp (abspath,slice_name) realperm
- | _ -> ()
+ let realperm = perm land (lnot 0o111) in
+ match rp with Relpath(rel) ->
+ let fqp = String.concat "/" [root_dir;rel] in
+ let res = Directfifowatcher.mkentry fqp abspath realperm slice_name in
+ match res with
+ | Success ->
+ Directfifowatcher.openentry fqp (abspath,slice_name)
+ | _ -> ()
(** A new directory was created at the backend, make a corresponding directory
at the frontend. Refer to mkentry for parameters *)
method mkdir rp perm =
match rp with Relpath(rel) ->
- let fqp = String.concat "/" [root_dir;rel] in
- try
- let s = Unix.stat fqp in
- if (s.st_kind<>S_DIR) then
- begin
- Unix.unlink fqp;
- Unix.mkdir fqp perm
- end
- else if (s.st_perm <> perm) then
- begin
- fprintf logfd "Removing directory %s\n" fqp;
- flush logfd;
- Unix.rmdir fqp;
- Unix.mkdir fqp perm
- end
- with Unix.Unix_error(_,_,_) ->
- Unix.mkdir fqp perm
+ let fqp = String.concat "/" [root_dir;rel] in
+ try
+ let s = Unix.stat fqp in
+ if (s.st_kind<>S_DIR) then
+ begin
+ Unix.unlink fqp;
+ Unix.mkdir fqp perm
+ end
+ else if (s.st_perm <> perm) then
+ begin
+ Unix.rmdir fqp;
+ Unix.mkdir fqp perm
+ end;
+ with Unix.Unix_error(_,_,_) ->
+ Unix.mkdir fqp perm;
+ Directfifowatcher.add_dir_watch fqp
+
+
+
+
(** Functions corresponding to file deletion/directory removal *)
(** *)
method unlink rp =
match rp with Relpath(rel) ->
- let fqp1 = String.concat "/" [root_dir;rel] in
- let fqp_in = String.concat "." [fqp1;"in"] in
- let fqp2 = String.concat "/" [root_dir;rel] in
- let fqp_out = String.concat "." [fqp2;"out"] in
- try
- Unix.unlink fqp_in;
- Unix.unlink fqp_out
- with _ ->
- fprintf logfd "Hm. %s disappeared. Looks like slice %s shot itself in the foot\n" fqp1 (this#get_slice_name ());flush logfd
+ let fqp = String.concat "/" [root_dir;rel] in
+ let fqp_in = String.concat "." [fqp;"in"] in
+ let fqp_out = String.concat "." [fqp;"out"] in
+ Directfifowatcher.closeentry fqp;
+ try
+ Unix.unlink fqp_in;
+ Unix.unlink fqp_out
+ with _ ->
+ fprintf logfd "Hm. %s disappeared. Looks like slice %s shot itself in the foot\n" fqp (this#get_slice_name ());flush logfd
method rmdir rp =
match rp with Relpath(rel) ->
- let fqp = String.concat "/" [root_dir;rel] in
- try
- Unix.rmdir fqp
- with _ ->
- fprintf logfd "Hm. %s disappeared. Looks like slice %s shot itself in the foot\n" fqp (this#get_slice_name ());flush logfd
+ let fqp = String.concat "/" [root_dir;rel] in
+ Directfifowatcher.del_dir_watch fqp;
+ try
+ Unix.rmdir fqp
+ with _ ->
+ fprintf logfd "Hm. %s disappeared or not empty. Looks like slice %s shot itself in the foot\n" fqp (this#get_slice_name ());flush logfd
+
+ initializer
+ Directfifowatcher.add_dir_watch root_dir
end
open Inotify
open Backend
open Frontend
-open Fifowatcher
open Conffile
let input_file_list = ref []
end;
Dirwatcher.initialize ();
- Fifowatcher.initialize ();
if (!Globals.conffile <> "") then
begin
let frontends = Conffile.read_frontends !Globals.conffile in