Blame src/FileUtilREADLINK.ml

Packit 9ff65e
(******************************************************************************)
Packit 9ff65e
(*  ocaml-fileutils: files and filenames common operations                    *)
Packit 9ff65e
(*                                                                            *)
Packit 9ff65e
(*  Copyright (C) 2003-2014, Sylvain Le Gall                                  *)
Packit 9ff65e
(*                                                                            *)
Packit 9ff65e
(*  This library is free software; you can redistribute it and/or modify it   *)
Packit 9ff65e
(*  under the terms of the GNU Lesser General Public License as published by  *)
Packit 9ff65e
(*  the Free Software Foundation; either version 2.1 of the License, or (at   *)
Packit 9ff65e
(*  your option) any later version, with the OCaml static compilation         *)
Packit 9ff65e
(*  exception.                                                                *)
Packit 9ff65e
(*                                                                            *)
Packit 9ff65e
(*  This library is distributed in the hope that it will be useful, but       *)
Packit 9ff65e
(*  WITHOUT ANY WARRANTY; without even the implied warranty of                *)
Packit 9ff65e
(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the file         *)
Packit 9ff65e
(*  COPYING for more details.                                                 *)
Packit 9ff65e
(*                                                                            *)
Packit 9ff65e
(*  You should have received a copy of the GNU Lesser General Public License  *)
Packit 9ff65e
(*  along with this library; if not, write to the Free Software Foundation,   *)
Packit 9ff65e
(*  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA             *)
Packit 9ff65e
(******************************************************************************)
Packit 9ff65e
Packit 9ff65e
open FileUtilTypes
Packit 9ff65e
open FilePath
Packit 9ff65e
open FileUtilMisc
Packit 9ff65e
open FileUtilPWD
Packit 9ff65e
open FileUtilTEST
Packit 9ff65e
Packit 9ff65e
Packit 9ff65e
let readlink fln =
Packit 9ff65e
  let all_upper_dir fln =
Packit 9ff65e
    let rec all_upper_dir_aux lst fln =
Packit 9ff65e
      let dir = dirname fln in
Packit 9ff65e
        match lst with
Packit 9ff65e
        | prev_dir :: _ when prev_dir = dir -> lst
Packit 9ff65e
        | _ -> all_upper_dir_aux (dir :: lst) dir
Packit 9ff65e
    in
Packit 9ff65e
    all_upper_dir_aux [fln] fln
Packit 9ff65e
  in
Packit 9ff65e
  let ctst =
Packit 9ff65e
    let st_opt, stL_opt = None, None in
Packit 9ff65e
    compile_filter ?st_opt ?stL_opt Is_link
Packit 9ff65e
  in
Packit 9ff65e
  let rec readlink_aux already_read fln =
Packit 9ff65e
    let newly_read = prevent_recursion already_read fln in
Packit 9ff65e
    let dirs = all_upper_dir fln in
Packit 9ff65e
    try
Packit 9ff65e
        let src_link = List.find ctst (List.rev dirs) in
Packit 9ff65e
        let dst_link = Unix.readlink src_link in
Packit 9ff65e
        let real_link =
Packit 9ff65e
          if is_relative dst_link then
Packit 9ff65e
            reduce (concat (dirname src_link) dst_link)
Packit 9ff65e
          else
Packit 9ff65e
            reduce dst_link
Packit 9ff65e
        in
Packit 9ff65e
        readlink_aux newly_read (reparent src_link real_link fln)
Packit 9ff65e
      with Not_found ->
Packit 9ff65e
        fln
Packit 9ff65e
  in
Packit 9ff65e
  readlink_aux SetFilename.empty (make_absolute (pwd ()) fln)
Packit 9ff65e
Packit 9ff65e