| 
									
										
										
										
											2008-10-07 20:25:05 -04:00
										 |  |  | ! Copyright (C) 2008 Doug Coleman. | 
					
						
							|  |  |  | ! See http://factorcode.org/license.txt for BSD license. | 
					
						
							| 
									
										
										
										
											2010-06-21 13:07:56 -04:00
										 |  |  | USING: accessors alien alien.c-types alien.strings assocs | 
					
						
							|  |  |  | byte-arrays classes.struct combinators | 
					
						
							|  |  |  | combinators.short-circuit continuations fry io.backend.unix | 
					
						
							|  |  |  | io.encodings.utf8 kernel math math.parser namespaces sequences | 
					
						
							|  |  |  | splitting strings unix unix.ffi unix.users unix.utilities ;
 | 
					
						
							| 
									
										
										
										
											2010-01-20 23:42:07 -05:00
										 |  |  | QUALIFIED: unix.ffi | 
					
						
							| 
									
										
										
										
											2008-10-07 20:25:05 -04:00
										 |  |  | QUALIFIED: grouping | 
					
						
							| 
									
										
										
										
											2010-06-21 13:07:56 -04:00
										 |  |  | IN: unix.groups | 
					
						
							| 
									
										
										
										
											2008-10-07 20:25:05 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | TUPLE: group id name passwd members ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | SYMBOL: group-cache | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-09 16:28:10 -05:00
										 |  |  | GENERIC: group-struct ( obj -- group/f )
 | 
					
						
							| 
									
										
										
										
											2008-10-07 20:25:05 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | <PRIVATE
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : group-members ( group-struct -- seq )
 | 
					
						
							| 
									
										
										
										
											2009-08-31 00:07:46 -04:00
										 |  |  |     gr_mem>> utf8 alien>strings ;
 | 
					
						
							| 
									
										
										
										
											2008-10-07 20:25:05 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : (group-struct) ( id -- group-struct id group-struct byte-array length void* )
 | 
					
						
							| 
									
										
										
										
											2010-01-20 23:42:07 -05:00
										 |  |  |     [ \ unix.ffi:group <struct> ] dip over 4096
 | 
					
						
							| 
									
										
										
										
											2008-10-07 20:25:05 -04:00
										 |  |  |     [ <byte-array> ] keep f <void*> ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-09 16:28:10 -05:00
										 |  |  | : check-group-struct ( group-struct ptr -- group-struct/f )
 | 
					
						
							|  |  |  |     *void* [ drop f ] unless ;
 | 
					
						
							| 
									
										
										
										
											2008-10-07 20:25:05 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-09 16:28:10 -05:00
										 |  |  | M: integer group-struct ( id -- group/f )
 | 
					
						
							| 
									
										
										
										
											2010-01-20 23:42:07 -05:00
										 |  |  |     (group-struct) | 
					
						
							| 
									
										
										
										
											2010-01-23 10:07:35 -05:00
										 |  |  |     [ [ unix.ffi:getgrgid_r ] unix-system-call drop ] keep
 | 
					
						
							| 
									
										
										
										
											2010-01-20 23:42:07 -05:00
										 |  |  |     check-group-struct ;
 | 
					
						
							| 
									
										
										
										
											2009-01-09 16:28:10 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | M: string group-struct ( string -- group/f )
 | 
					
						
							| 
									
										
										
										
											2010-01-20 23:42:07 -05:00
										 |  |  |     (group-struct) | 
					
						
							| 
									
										
										
										
											2010-01-23 10:07:35 -05:00
										 |  |  |     [ [ unix.ffi:getgrnam_r ] unix-system-call drop ] keep
 | 
					
						
							| 
									
										
										
										
											2010-01-20 23:42:07 -05:00
										 |  |  |     check-group-struct ;
 | 
					
						
							| 
									
										
										
										
											2008-10-07 20:25:05 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : group-struct>group ( group-struct -- group )
 | 
					
						
							|  |  |  |     [ \ group new ] dip
 | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2009-08-31 00:07:46 -04:00
										 |  |  |         [ gr_name>> >>name ] | 
					
						
							|  |  |  |         [ gr_passwd>> >>passwd ] | 
					
						
							|  |  |  |         [ gr_gid>> >>id ] | 
					
						
							| 
									
										
										
										
											2008-10-07 20:25:05 -04:00
										 |  |  |         [ group-members >>members ] | 
					
						
							|  |  |  |     } cleave ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PRIVATE>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : group-name ( id -- string )
 | 
					
						
							|  |  |  |     dup group-cache get [ | 
					
						
							| 
									
										
										
										
											2009-02-22 18:52:59 -05:00
										 |  |  |         ?at [ name>> ] [ number>string ] if
 | 
					
						
							| 
									
										
										
										
											2008-10-07 20:25:05 -04:00
										 |  |  |     ] [ | 
					
						
							| 
									
										
										
										
											2009-08-31 00:07:46 -04:00
										 |  |  |         group-struct [ gr_name>> ] [ f ] if*
 | 
					
						
							| 
									
										
										
										
											2008-10-07 20:25:05 -04:00
										 |  |  |     ] if*
 | 
					
						
							|  |  |  |     [ nip ] [ number>string ] if* ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-09 16:28:10 -05:00
										 |  |  | : group-id ( string -- id/f )
 | 
					
						
							| 
									
										
										
										
											2010-02-04 22:50:33 -05:00
										 |  |  |     group-struct dup [ gr_gid>> ] when ;
 | 
					
						
							| 
									
										
										
										
											2008-10-07 20:25:05 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-17 13:59:19 -04:00
										 |  |  | ERROR: no-group string ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : ?group-id ( string -- id )
 | 
					
						
							|  |  |  |     dup group-struct [ nip gr_gid>> ] [ no-group ] if* ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-10-07 20:25:05 -04:00
										 |  |  | <PRIVATE
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : >groups ( byte-array n -- groups )
 | 
					
						
							|  |  |  |     [ 4 grouping:group ] dip head-slice [ *uint group-name ] map ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-10-08 14:05:16 -04:00
										 |  |  | : (user-groups) ( string -- seq )
 | 
					
						
							| 
									
										
										
										
											2008-10-07 20:25:05 -04:00
										 |  |  |     #! first group is -1337, legacy unix code | 
					
						
							| 
									
										
										
										
											2010-01-20 23:42:07 -05:00
										 |  |  |     -1337 unix.ffi:NGROUPS_MAX [ 4 * <byte-array> ] keep
 | 
					
						
							| 
									
										
										
										
											2010-01-23 10:07:35 -05:00
										 |  |  |     <int> [ [ unix.ffi:getgrouplist ] unix-system-call drop ] 2keep
 | 
					
						
							| 
									
										
										
										
											2009-08-13 20:21:44 -04:00
										 |  |  |     [ 4 tail-slice ] [ *int 1 - ] bi* >groups ;
 | 
					
						
							| 
									
										
										
										
											2008-10-07 20:25:05 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-10-08 14:05:16 -04:00
										 |  |  | PRIVATE>
 | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  | GENERIC: user-groups ( string/id -- seq )
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | M: string user-groups ( string -- seq )
 | 
					
						
							|  |  |  |     (user-groups) ;  | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | M: integer user-groups ( id -- seq )
 | 
					
						
							| 
									
										
										
										
											2009-01-08 18:07:33 -05:00
										 |  |  |     user-name (user-groups) ;
 | 
					
						
							| 
									
										
										
										
											2008-10-08 14:05:16 -04:00
										 |  |  |      | 
					
						
							| 
									
										
										
										
											2008-10-07 20:25:05 -04:00
										 |  |  | : all-groups ( -- seq )
 | 
					
						
							| 
									
										
										
										
											2010-06-21 13:07:56 -04:00
										 |  |  |     [ unix.ffi:getgrent dup ] [ group-struct>group ] produce nip
 | 
					
						
							|  |  |  |     endgrent ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : all-group-names ( -- seq )
 | 
					
						
							|  |  |  |     all-groups [ name>> ] map ;
 | 
					
						
							| 
									
										
										
										
											2008-10-07 20:25:05 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-11-18 12:45:55 -05:00
										 |  |  | : <group-cache> ( -- assoc )
 | 
					
						
							|  |  |  |     all-groups [ [ id>> ] keep ] H{ } map>assoc ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-10-07 20:25:05 -04:00
										 |  |  | : with-group-cache ( quot -- )
 | 
					
						
							| 
									
										
										
										
											2008-11-18 12:45:55 -05:00
										 |  |  |     [ <group-cache> group-cache ] dip with-variable ; inline
 | 
					
						
							| 
									
										
										
										
											2008-10-07 20:25:05 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-20 23:42:07 -05:00
										 |  |  | : real-group-id ( -- id ) unix.ffi:getgid ; inline
 | 
					
						
							| 
									
										
										
										
											2008-10-07 20:25:05 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-31 00:07:46 -04:00
										 |  |  | : real-group-name ( -- string ) real-group-id group-name ; inline
 | 
					
						
							| 
									
										
										
										
											2008-10-07 20:25:05 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-20 23:42:07 -05:00
										 |  |  | : effective-group-id ( -- string ) unix.ffi:getegid ; inline
 | 
					
						
							| 
									
										
										
										
											2008-10-07 20:25:05 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : effective-group-name ( -- string )
 | 
					
						
							|  |  |  |     effective-group-id group-name ; inline
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-21 13:07:56 -04:00
										 |  |  | : group-exists? ( name/id -- ? ) group-id >boolean ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-10-07 20:25:05 -04:00
										 |  |  | GENERIC: set-real-group ( obj -- )
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | GENERIC: set-effective-group ( obj -- )
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-17 14:20:51 -04:00
										 |  |  | : (with-real-group) ( string/id quot -- )
 | 
					
						
							| 
									
										
										
										
											2008-10-07 20:25:05 -04:00
										 |  |  |     '[ _ set-real-group @ ] | 
					
						
							|  |  |  |     real-group-id '[ _ set-real-group ] [ ] cleanup ; inline
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-17 14:20:51 -04:00
										 |  |  | : with-real-group ( string/id/f quot -- )
 | 
					
						
							|  |  |  |     over [ (with-real-group) ] [ nip call ] if ; inline
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : (with-effective-group) ( string/id quot -- )
 | 
					
						
							| 
									
										
										
										
											2008-10-07 20:25:05 -04:00
										 |  |  |     '[ _ set-effective-group @ ] | 
					
						
							|  |  |  |     effective-group-id '[ _ set-effective-group ] [ ] cleanup ; inline
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-17 14:20:51 -04:00
										 |  |  | : with-effective-group ( string/id/f quot -- )
 | 
					
						
							|  |  |  |     over [ (with-effective-group) ] [ nip call ] if ; inline
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-10-07 20:25:05 -04:00
										 |  |  | <PRIVATE
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : (set-real-group) ( id -- )
 | 
					
						
							| 
									
										
										
										
											2010-01-23 10:07:35 -05:00
										 |  |  |     [ unix.ffi:setgid ] unix-system-call drop ; inline
 | 
					
						
							| 
									
										
										
										
											2008-10-07 20:25:05 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : (set-effective-group) ( id -- )
 | 
					
						
							| 
									
										
										
										
											2010-01-23 10:07:35 -05:00
										 |  |  |     [ unix.ffi:setegid ] unix-system-call drop ; inline
 | 
					
						
							| 
									
										
										
										
											2008-10-07 20:25:05 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | PRIVATE>
 | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  | M: integer set-real-group ( id -- )
 | 
					
						
							|  |  |  |     (set-real-group) ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-17 13:59:19 -04:00
										 |  |  | M: string set-real-group ( string -- )
 | 
					
						
							|  |  |  |     ?group-id (set-real-group) ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-10-07 20:25:05 -04:00
										 |  |  | M: integer set-effective-group ( id -- )     | 
					
						
							|  |  |  |     (set-effective-group) ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | M: string set-effective-group ( string -- )
 | 
					
						
							| 
									
										
										
										
											2010-06-17 13:59:19 -04:00
										 |  |  |     ?group-id (set-effective-group) ;
 |