123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475(* This file is part of Luv, released under the MIT license. See LICENSE.md for
details, or visit https://github.com/aantron/luv/blob/master/LICENSE.md. *)typeuser={username:string;uid:Unsigned.ulong;gid:Unsigned.ulong;shell:stringoption;homedir:string;}typet=userletget_passwd?uid()=letc_passwd=Ctypes.makeC.Types.Passwd.tinletpointer=Ctypes.addrc_passwdinbeginmatchuidwith|None->C.Functions.Passwd.get_passwdpointer|Someuid->C.Functions.Passwd.get_passwd2pointeruidend|>Error.to_result_f@@fun()->letmodulePW=C.Types.Passwdinletpasswd={username=Ctypes.getfc_passwdPW.username;uid=Ctypes.getfc_passwdPW.uid;gid=Ctypes.getfc_passwdPW.gid;shell=Ctypes.getfc_passwdPW.shell;homedir=Ctypes.getfc_passwdPW.homedir;}inC.Functions.Passwd.free_passwdpointer;passwdtypegroup={groupname:string;gid:Unsigned.ulong;members:stringlist;}letstrlenc_string=letrecloopi=ifCtypes.(!@(c_string+@i))='\x00'thenielseloop(i+1)inloop0letstring_list_from_cc_strings=letrecloopiacc=letc_string=Ctypes.(!@(c_strings+@i))inifCtypes.is_nullc_stringthenList.revaccelseletlength=strlenc_stringinlets=Ctypes.string_from_ptrc_string~lengthinloop(i+1)(s::acc)inloop0[]letget_groupgid=letc_group=Ctypes.makeC.Types.Passwd.groupinC.Functions.Passwd.get_group(Ctypes.addrc_group)gid|>Error.to_result_f@@fun()->letmoduleG=C.Types.Passwdinletgroup={groupname=Ctypes.getfc_groupG.groupname;gid=Ctypes.getfc_groupG.group_gid;members=Ctypes.getfc_groupG.members|>string_list_from_c;}inC.Functions.Passwd.free_group(Ctypes.addrc_group);group