package timere

  1. Overview
  2. Docs

Source file timere_tzlocal.ml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
let local () : string list =
  (* Approached copied from Python package tzlocal:
     https://github.com/regebro/tzlocal
  *)
  match Sys.getenv_opt "TZ" with
  | Some name -> [name]
  | None ->
    if CCIO.File.exists "/system/bin/getprop" then
      (* if we are under Termux on Android *)
      let ic = Unix.open_process_in "getprop" in
      let name =
          (CCIO.read_all ic) in
      close_in ic;
      [name]
    else
      (* Look for distribution specific configs *)
      let try1 =
        List.fold_left (fun tz file ->
            match tz with
            | Some tz -> Some tz
            | None ->
              try
              CCIO.with_in ~flags:[ Open_rdonly; ] file (fun ic ->
                  let lines =
                    CCIO.read_lines_l ic in
                  match lines with
                  | [] -> None
                  | x :: _ ->
                    if CCString.sub x 0 5 = "TZif2" then
                      None
                    else
                      List.fold_left (fun tz line ->
                          match tz with
                          | Some tz -> Some tz
                          | None ->
                            let name =
                              line
                              |> String.split_on_char ' '
                              |> List.hd
                              |> String.split_on_char '#'
                              |> List.hd
                            in
                            Some name
                        )
                        None
                        lines
                )
              with
              | _ -> None
          )
          None
          [ "/etc/timezone"; "/var/db/zoneinfo"]
      in
      match try1 with
      | Some name -> [name]
      | None ->
        (* CentOS has a ZONE setting in /etc/sysconfig/clock,
           OpenSUSE has a TIMEZONE setting in /etc/sysconfig/clock and
           Gentoo has a TIMEZONE setting in /etc/conf.d/clock
           We look through these files for a timezone
        *)
        let try2 =
        List.fold_left (fun tz file ->
            match tz with
            | Some tz -> Some tz
            | None ->
              try
              CCIO.with_in ~flags:[Open_rdonly; ] file (fun ic ->
                  let lines =
                    CCIO.read_lines_l ic in
                  List.fold_left (fun tz line ->
                      match tz with
                      | Some tz -> Some tz
                      | None ->
                        let name =
                          try
                            Some (
                              Scanf.sscanf line {| ZONE = "%[^"]"|} CCFun.id
                            )
                          with
                          | _ ->
                            try
                              Some (
                                Scanf.sscanf line {| TIMEZONE = "%[^"]"|} CCFun.id
                              )
                            with
                            | _ -> None
                        in
                        match name with
                        | None -> None
                        | Some s ->
                          Some (CCString.replace ~sub:" " ~by:"_" s)
                    )
                    None
                    lines
                  )
              with
              | _ -> None
          )
        None
        ["/etc/sysconfig/clock"; "/etc/conf.d/clock"]
        in
        match try2 with
        | Some name -> [name]
        | None ->
          (* systemd distributions use symlinks that include the zone name *)
          let try3 =
            let file = "/etc/localtime" in
            if FileUtil.(test Is_link file) then
              let real_path = FileUtil.readlink file in
              let parts = String.split_on_char '/' real_path in
              let combinations, _ =
                List.fold_left (fun (acc, parts) _ ->
                    (parts :: acc, List.tl parts)
                  )
                  ([], parts)
                  parts
              in
              List.map (String.concat "/") combinations
            else
              []
          in
          try3
OCaml

Innovation. Community. Security.