]> gitweb.factorcode.org Git - factor.git/blob - basis/unix/groups/groups.factor
b009fe529fca0e4d1fd459da38fa54ac20a09c2c
[factor.git] / basis / unix / groups / groups.factor
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 unix ;
8 IN: unix.groups
9
10 QUALIFIED: unix.ffi
11
12 QUALIFIED: grouping
13
14 TUPLE: group id name passwd members ;
15
16 SYMBOL: group-cache
17
18 GENERIC: group-struct ( obj -- group/f )
19
20 <PRIVATE
21
22 : group-members ( group-struct -- seq )
23     gr_mem>> utf8 alien>strings ;
24
25 : (group-struct) ( id -- group-struct id group-struct byte-array length void* )
26     [ \ unix.ffi:group <struct> ] dip over 4096
27     [ <byte-array> ] keep f <void*> ;
28
29 : check-group-struct ( group-struct ptr -- group-struct/f )
30     *void* [ drop f ] unless ;
31
32 M: integer group-struct ( id -- group/f )
33     (group-struct)
34     [ [ unix.ffi:getgrgid_r ] unix-system-call drop ] keep
35     check-group-struct ;
36
37 M: string group-struct ( string -- group/f )
38     (group-struct)
39     [ [ unix.ffi:getgrnam_r ] unix-system-call drop ] keep
40     check-group-struct ;
41
42 : group-struct>group ( group-struct -- group )
43     [ \ group new ] dip
44     {
45         [ gr_name>> >>name ]
46         [ gr_passwd>> >>passwd ]
47         [ gr_gid>> >>id ]
48         [ group-members >>members ]
49     } cleave ;
50
51 PRIVATE>
52
53 : group-name ( id -- string )
54     dup group-cache get [
55         ?at [ name>> ] [ number>string ] if
56     ] [
57         group-struct [ gr_name>> ] [ f ] if*
58     ] if*
59     [ nip ] [ number>string ] if* ;
60
61 : group-id ( string -- id/f )
62     group-struct dup [ gr_gid>> ] when ;
63
64 <PRIVATE
65
66 : >groups ( byte-array n -- groups )
67     [ 4 grouping:group ] dip head-slice [ *uint group-name ] map ;
68
69 : (user-groups) ( string -- seq )
70     #! first group is -1337, legacy unix code
71     -1337 unix.ffi:NGROUPS_MAX [ 4 * <byte-array> ] keep
72     <int> [ [ unix.ffi:getgrouplist ] unix-system-call drop ] 2keep
73     [ 4 tail-slice ] [ *int 1 - ] bi* >groups ;
74
75 PRIVATE>
76     
77 GENERIC: user-groups ( string/id -- seq )
78
79 M: string user-groups ( string -- seq )
80     (user-groups) ; 
81
82 M: integer user-groups ( id -- seq )
83     user-name (user-groups) ;
84     
85 : all-groups ( -- seq )
86     [ unix.ffi:getgrent dup ] [ \ unix.ffi:group memory>struct group-struct>group ] produce nip ;
87
88 : <group-cache> ( -- assoc )
89     all-groups [ [ id>> ] keep ] H{ } map>assoc ;
90
91 : with-group-cache ( quot -- )
92     [ <group-cache> group-cache ] dip with-variable ; inline
93
94 : real-group-id ( -- id ) unix.ffi:getgid ; inline
95
96 : real-group-name ( -- string ) real-group-id group-name ; inline
97
98 : effective-group-id ( -- string ) unix.ffi:getegid ; inline
99
100 : effective-group-name ( -- string )
101     effective-group-id group-name ; inline
102
103 GENERIC: set-real-group ( obj -- )
104
105 GENERIC: set-effective-group ( obj -- )
106
107 : with-real-group ( string/id quot -- )
108     '[ _ set-real-group @ ]
109     real-group-id '[ _ set-real-group ] [ ] cleanup ; inline
110
111 : with-effective-group ( string/id quot -- )
112     '[ _ set-effective-group @ ]
113     effective-group-id '[ _ set-effective-group ] [ ] cleanup ; inline
114
115 <PRIVATE
116
117 : (set-real-group) ( id -- )
118     [ unix.ffi:setgid ] unix-system-call drop ; inline
119
120 : (set-effective-group) ( id -- )
121     [ unix.ffi:setegid ] unix-system-call drop ; inline
122
123 PRIVATE>
124     
125 M: string set-real-group ( string -- )
126     group-id (set-real-group) ;
127
128 M: integer set-real-group ( id -- )
129     (set-real-group) ;
130
131 M: integer set-effective-group ( id -- )    
132     (set-effective-group) ;
133
134 M: string set-effective-group ( string -- )
135     group-id (set-effective-group) ;