1 ! Copyright (C) 2008 Doug Coleman.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: alien alien.c-types alien.strings io.encodings.utf8
4 io.backend.unix kernel math sequences splitting unix strings
5 combinators.short-circuit byte-arrays combinators
6 accessors math.parser fry assocs namespaces continuations
7 unix.users unix.utilities ;
12 TUPLE: group id name passwd members ;
16 GENERIC: group-struct ( obj -- group/f )
20 : group-members ( group-struct -- seq )
21 group-gr_mem utf8 alien>strings ;
23 : (group-struct) ( id -- group-struct id group-struct byte-array length void* )
24 "group" <c-object> tuck 4096
25 [ <byte-array> ] keep f <void*> ;
27 : check-group-struct ( group-struct ptr -- group-struct/f )
28 *void* [ drop f ] unless ;
30 M: integer group-struct ( id -- group/f )
31 (group-struct) [ getgrgid_r io-error ] keep check-group-struct ;
33 M: string group-struct ( string -- group/f )
34 (group-struct) [ getgrnam_r io-error ] keep check-group-struct ;
36 : group-struct>group ( group-struct -- group )
39 [ group-gr_name >>name ]
40 [ group-gr_passwd >>passwd ]
42 [ group-members >>members ]
47 : group-name ( id -- string )
50 dupd at* [ name>> nip ] [ drop number>string ] if
52 group-struct [ group-gr_name ] [ f ] if*
54 [ nip ] [ number>string ] if* ;
56 : group-id ( string -- id/f )
57 group-struct [ group-gr_gid ] [ f ] if* ;
61 : >groups ( byte-array n -- groups )
62 [ 4 grouping:group ] dip head-slice [ *uint group-name ] map ;
64 : (user-groups) ( string -- seq )
65 #! first group is -1337, legacy unix code
66 -1337 NGROUPS_MAX [ 4 * <byte-array> ] keep
67 <int> [ getgrouplist io-error ] 2keep
68 [ 4 tail-slice ] [ *int 1- ] bi* >groups ;
72 GENERIC: user-groups ( string/id -- seq )
74 M: string user-groups ( string -- seq )
77 M: integer user-groups ( id -- seq )
78 user-name (user-groups) ;
80 : all-groups ( -- seq )
81 [ getgrent dup ] [ group-struct>group ] [ drop ] produce ;
83 : <group-cache> ( -- assoc )
84 all-groups [ [ id>> ] keep ] H{ } map>assoc ;
86 : with-group-cache ( quot -- )
87 [ <group-cache> group-cache ] dip with-variable ; inline
89 : real-group-id ( -- id )
92 : real-group-name ( -- string )
93 real-group-id group-name ; inline
95 : effective-group-id ( -- string )
98 : effective-group-name ( -- string )
99 effective-group-id group-name ; inline
101 GENERIC: set-real-group ( obj -- )
103 GENERIC: set-effective-group ( obj -- )
105 : with-real-group ( string/id quot -- )
106 '[ _ set-real-group @ ]
107 real-group-id '[ _ set-real-group ] [ ] cleanup ; inline
109 : with-effective-group ( string/id quot -- )
110 '[ _ set-effective-group @ ]
111 effective-group-id '[ _ set-effective-group ] [ ] cleanup ; inline
115 : (set-real-group) ( id -- )
116 setgid io-error ; inline
118 : (set-effective-group) ( id -- )
119 setegid io-error ; inline
123 M: string set-real-group ( string -- )
124 group-id (set-real-group) ;
126 M: integer set-real-group ( id -- )
129 M: integer set-effective-group ( id -- )
130 (set-effective-group) ;
132 M: string set-effective-group ( string -- )
133 group-id (set-effective-group) ;