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