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 strings
5 combinators.short-circuit byte-arrays combinators
6 accessors math.parser fry assocs namespaces continuations
7 unix.users unix.utilities classes.struct ;
14 TUPLE: group id name passwd members ;
18 GENERIC: group-struct ( obj -- group/f )
22 : group-members ( group-struct -- seq )
23 gr_mem>> utf8 alien>strings ;
25 : (group-struct) ( id -- group-struct id group-struct byte-array length void* )
26 [ \ unix:group <struct> ] dip over 4096
27 [ <byte-array> ] keep f <void*> ;
29 : check-group-struct ( group-struct ptr -- group-struct/f )
30 *void* [ drop f ] unless ;
32 M: integer group-struct ( id -- group/f )
33 (group-struct) [ unix:getgrgid_r unix:io-error ] keep check-group-struct ;
35 M: string group-struct ( string -- group/f )
36 (group-struct) [ unix:getgrnam_r unix:io-error ] keep check-group-struct ;
38 : group-struct>group ( group-struct -- group )
42 [ gr_passwd>> >>passwd ]
44 [ group-members >>members ]
49 : group-name ( id -- string )
51 ?at [ name>> ] [ number>string ] if
53 group-struct [ gr_name>> ] [ f ] if*
55 [ nip ] [ number>string ] if* ;
57 : group-id ( string -- id/f )
58 group-struct [ gr_gid>> ] [ f ] if* ;
62 : >groups ( byte-array n -- groups )
63 [ 4 grouping:group ] dip head-slice [ *uint group-name ] map ;
65 : (user-groups) ( string -- seq )
66 #! first group is -1337, legacy unix code
67 -1337 unix:NGROUPS_MAX [ 4 * <byte-array> ] keep
68 <int> [ unix:getgrouplist unix:io-error ] 2keep
69 [ 4 tail-slice ] [ *int 1 - ] bi* >groups ;
73 GENERIC: user-groups ( string/id -- seq )
75 M: string user-groups ( string -- seq )
78 M: integer user-groups ( id -- seq )
79 user-name (user-groups) ;
81 : all-groups ( -- seq )
82 [ unix:getgrent dup ] [ \ unix:group memory>struct group-struct>group ] produce nip ;
84 : <group-cache> ( -- assoc )
85 all-groups [ [ id>> ] keep ] H{ } map>assoc ;
87 : with-group-cache ( quot -- )
88 [ <group-cache> group-cache ] dip with-variable ; inline
90 : real-group-id ( -- id ) unix:getgid ; inline
92 : real-group-name ( -- string ) real-group-id group-name ; inline
94 : effective-group-id ( -- string ) unix:getegid ; inline
96 : effective-group-name ( -- string )
97 effective-group-id group-name ; inline
99 GENERIC: set-real-group ( obj -- )
101 GENERIC: set-effective-group ( obj -- )
103 : with-real-group ( string/id quot -- )
104 '[ _ set-real-group @ ]
105 real-group-id '[ _ set-real-group ] [ ] cleanup ; inline
107 : with-effective-group ( string/id quot -- )
108 '[ _ set-effective-group @ ]
109 effective-group-id '[ _ set-effective-group ] [ ] cleanup ; inline
113 : (set-real-group) ( id -- )
114 unix:setgid unix:io-error ; inline
116 : (set-effective-group) ( id -- )
117 unix:setegid unix:io-error ; inline
121 M: string set-real-group ( string -- )
122 group-id (set-real-group) ;
124 M: integer set-real-group ( id -- )
127 M: integer set-effective-group ( id -- )
128 (set-effective-group) ;
130 M: string set-effective-group ( string -- )
131 group-id (set-effective-group) ;