Plasma GitLab Archive
Projects Blog Knowledge

(* $Id: index.ml,v 3.1 2002-02-12 21:18:21 stolpmann Exp $
 * ----------------------------------------------------------------------
 *
 *)

(* Note: This file must be parsed with camlp4, and the syntax
 * extensions from wdialog-p4.
 *)

open Wd_types

let read_directory path =
  (* Return the file names of the directory "path" as string list *)

  let d = Unix.opendir path in

  let rec readrec () =
    try
      let name = Unix.readdir d in
      name :: readrec()
    with
	End_of_file -> []
  in
  let names = readrec() in
  Unix.closedir d;
  names
;;


let permissions kind perm =
  (* Compute a textual representation of file 'kind' and
   * permission mode 'perm'
   *)
  let first_letter =
    match kind with
	Unix.S_REG -> "-"
      | Unix.S_DIR -> "d"
      | Unix.S_CHR -> "c"
      | Unix.S_BLK -> "b"
      | Unix.S_LNK -> "l"
      | Unix.S_FIFO -> "p"
      | Unix.S_SOCK -> "s"
  in

  let s = ref "" in
  let p = ref perm in

  List.iter
    (fun letter ->
       begin
	 if !p mod 2 = 1 then
	   s := letter ^ !s
	 else
	   s := "-" ^ !s
       end;
       p := !p / 2)
    [ "x"; "w"; "r"; "x"; "w"; "r"; "x"; "w"; "r" ];

  s := first_letter ^ !s;

  if (perm land 0o1000) > 0 then begin
    if !s.[9] = 'x' then
      !s.[9] <- 't'
    else
      !s.[9] <- 'T'
  end;

  if (perm land 0o2000) > 0 then begin
    if !s.[6] = 'x' then
      !s.[6] <- 's'
    else
      !s.[6] <- 'l'
  end;

  if (perm land 0o4000) > 0 then begin
    if !s.[6] = 'x' then
      !s.[6] <- 's'
    else
      !s.[6] <- 'S'
  end;

  !s
;;


let owner uid =
  (* Converts the numerical uid to a string *)
  try
    (Unix.getpwuid uid).Unix.pw_name
  with
      Not_found -> string_of_int uid
;;


let group gid =
  (* Converts the numerical gid to a string *)
  try
    (Unix.getgrgid gid).Unix.gr_name
  with
      Not_found -> string_of_int gid
;;


let timestring t =
  (* Converts the time value t to a string *)
  let tm = Unix.localtime t in
  Printf.sprintf
    "%04d-%02d-%02d %02d:%02d:%02d"
    (tm.Unix.tm_year + 1900)            (* Y2k-compliant *)
    (tm.Unix.tm_mon + 1)
    (tm.Unix.tm_mday)
    (tm.Unix.tm_hour)
    (tm.Unix.tm_min)
    (tm.Unix.tm_sec)
;;


class directory universe name env =
  interactive object (self)

    inherit Wd_dialog.dialog universe name env

    method private prepare_show_listing() =

      let path = _[path:string] in
      let names = Sort.list
		    (fun a b -> a >= b)       (* >=: sic! *)
		    (read_directory path) in             (* file names *)

      (* Get all necessary templates: *)
      let t_directory_row = self # t_get "directory-row" in
      let t_filename      = self # t_get "filename" in
      let t_filename_d    = self # t_get "filename_d" in

      let filename_alist = ref [] in
      let fileperms_alist = ref [] in
      let fileowner_alist = ref [] in
      let filegroup_alist = ref [] in
      let filesize_alist = ref [] in
      let filemtime_alist = ref [] in
      let filesymlink_alist = ref [] in

      List.iter
	(fun name ->
	   let path_name = Filename.concat path name in

	   let s  = Unix.stat path_name in
	   let ls = Unix.lstat path_name in

	   (* If the file is a directory, use t_filename_d instead of
	    * t_filename:
	    *)
	   let t_fname =
	     match s.Unix.st_kind with
		 Unix.S_DIR -> t_filename_d
	       | _          -> t_filename
	   in

	   filename_alist := (name,
			      String_value
				(self # t_to_string
				   (self # t_apply
		                      t_fname
				      [ "value", self # t_text name ])))
	                     :: !filename_alist;

	   fileperms_alist := (name,
			       String_value
				 (permissions
				    s.Unix.st_kind
				    s.Unix.st_perm)) :: !fileperms_alist;

	   fileowner_alist := (name,
			       String_value(owner s.Unix.st_uid))
                              :: !fileowner_alist;

	   filegroup_alist := (name,
			       String_value (group s.Unix.st_uid))
	                      :: !filegroup_alist;

	   filesize_alist := (name,
			      String_value (string_of_int s.Unix.st_size))
                             :: !filesize_alist;

	   filemtime_alist := (name,
			       String_value (timestring s.Unix.st_mtime))
                              :: !filemtime_alist;

	   filesymlink_alist := (name,
				 let t =
				   match ls.Unix.st_kind with
				       Unix.S_LNK ->
					 self # t_apply_byname "symlink"
					   [ "value",
					     self # t_text
					       (Unix.readlink path_name) ]
				     | _ -> self # t_empty
				 in
				 String_value (self # t_to_string t)
				)
	                        :: !filesymlink_alist;
	)
	names;

      _[filename:alist] <-    !filename_alist;
      _[fileperms:alist] <-   !fileperms_alist;
      _[fileowner:alist] <-   !fileowner_alist;
      _[filegroup:alist] <-   !filegroup_alist;
      _[filesize:alist] <-    !filesize_alist;
      _[filemtime:alist] <-   !filemtime_alist;
      _[filesymlink:alist] <- !filesymlink_alist;


    method private handle_show_listing() =
      match self # event with
	  Indexed_button ("goto_dir", dirname) ->
	    begin match dirname with
		"." -> ()
	      | ".." ->
		  let p = Filename.dirname _[path:string] in
		  _[path:string] <- p
	      | _ ->
		  _[path:string] <-
		    (Filename.concat
		       _[path:string]
		       dirname)
	    end
	| _ -> ()
  end
;;


Wd_run_cgi.run
  ~reg:(fun universe ->
          universe # register "directory" (new directory)
       )
  ()
;;


(* ======================================================================
 * History:
 *
 * $Log: index.ml,v $
 * Revision 3.1  2002-02-12 21:18:21  stolpmann
 * 	Initial revision at sourceforge
 *
 * Revision 1.2  2002/01/14 15:06:49  gerd
 * 	Updated to recent wd version.
 *
 * Revision 1.1  2000/04/13 17:43:05  gerd
 * 	Initial revision.
 *
 *
 *)

This web site is published by Informatikbüro Gerd Stolpmann
Powered by Caml