Source file pwd.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
[@@@warning "@A"]

type struct_passwd = {
  pw_name: string;
  pw_passwd: string;
  pw_uid: int;
  pw_gid: int;
  pw_gcos: string;
  pw_dir: string;
  pw_shell: string;
}

let getpwuid (uid: int) : struct_passwd =
  let i = Stdcompat.open_in "/etc/passwd" in
  let rec aux () =
    match Stdcompat.input_line i with
    | exception End_of_file -> Stdcompat.close_in i; raise (Exn.KeyError (Format.asprintf "getpwuid(): uid not found: %d" uid))
    | s ->
      match Stdcompat.String.split_on_char ':' s with
      | name :: passwd :: uid_ :: gid ::gcos :: dir :: shell :: [] ->
        if uid = int_of_string uid_ then
          {
            pw_name = name;
            pw_passwd = passwd;
            pw_uid = uid;
            pw_gid = int_of_string gid;
            pw_gcos = gcos;
            pw_dir = dir;
            pw_shell = shell;
          }
        else
          aux ()
      | _ -> failwith "todo"
  in
  aux ()

let getpwname (name: string) : struct_passwd =
  let i = Stdcompat.open_in "/etc/passwd" in
  let rec aux () =
    match Stdcompat.input_line i with
    | exception End_of_file -> Stdcompat.close_in i; raise (Exn.KeyError (Format.asprintf "getpwname(): name not found: \"%s\"" name))
    | s ->
      match Stdcompat.String.split_on_char ':' s with
      | name_ :: passwd :: uid :: gid ::gcos :: dir :: shell :: [] ->
        if name = name_ then
          {
            pw_name = name;
            pw_passwd = passwd;
            pw_uid = int_of_string uid;
            pw_gid = int_of_string gid;
            pw_gcos = gcos;
            pw_dir = dir;
            pw_shell = shell;
          }
        else
          aux ()
      | _ -> failwith "todo"
  in
  aux ()

let getpwall () : struct_passwd list =
  let i = Stdcompat.open_in "/etc/passwd" in
  let rec aux acc =
    match Stdcompat.input_line i with
    | exception End_of_file -> Stdcompat.close_in i; acc
    | s ->
      match Stdcompat.String.split_on_char ':' s with
      | name :: passwd :: uid :: gid ::gcos :: dir :: shell :: [] ->
        aux ({
            pw_name = name;
            pw_passwd = passwd;
            pw_uid = int_of_string uid;
            pw_gid = int_of_string gid;
            pw_gcos = gcos;
            pw_dir = dir;
            pw_shell = shell;
          }::acc)
      | _ -> failwith "todo"
  in
  aux []