diff -u -r1.50 SymlinkProgram
--- bin/SymlinkProgram	25 Nov 2007 02:08:56 -0000	1.50
+++ bin/SymlinkProgram	7 Jan 2008 09:57:02 -0000
@@ -22,6 +22,7 @@
 Add_Option_Entry "t" "tasks" "Link tasks into ${goboExecutables}: 'yes', 'no' or 'safe'." "yes"
 Add_Option_Entry "u" "unmanaged" "Defines what to do with unmanaged files in package: 'ask', 'install' or 'skip'." "ask"
 Add_Option_Boolean "E" "no-environment" "Do not link entries from ${goboEnvironment}."
+Add_Option_Boolean "R" "no-requirements" "Do not process Resources/Requirements."
 Add_Option_Boolean "A" "no-variable" "Do not move variable files into ${goboVariable}."
 Add_Option_Boolean "M" "no-doc" "Do not link manuals and info files."
 Add_Option_Boolean "C" "cleanup" "Clean up after installation."
@@ -369,6 +370,104 @@
 
 ################################################################################
 
+if ! Boolean "no-requirements"
+then
+   # We only allow hardcoded uid/gid's in the range [1..99]. These are reserved for
+   # GoboLinux usage, as in scripts or daemons. All other uid/gid's should be generated
+   # dynamically through get_next_system_id().
+   function check_id_range() {
+      id="$1"
+      idtype="$2"
+      name="$3"
+      [ "$idtype" = "uid" ] && idtarget="user account" || idtarget="group"
+      if [ $id -lt 1 -o $id -gt 99 ]
+      then
+         Log_Error "$idtype $id is out of range [1..99], will not create $idtarget '$name'"
+         return 1
+      fi
+      return 0
+   }
+   # Ensures that only uid/gid's in the range [100..999] are created. Numbers below
+   # that are reserved for GoboLinux usage, and the ones above are attributed to user
+   # accounts only (user accounts should not be created using Resources/Requirements).
+   function get_next_system_id() {
+      unset next
+      # search sequentially
+      for num in `cat "$1" | cut -d: -f3 | sort -n`
+      do
+         [ $num -ge 100 -a $num -lt 999 ] && next=$num
+      done
+      if [ "$next" ] && ! cat "$1" | cut -d: -f3 | grep "^$next$"
+      then
+         let next=next+1
+         echo "$next"
+         return
+      fi
+      # get the first available slot
+      for num in `seq 100 999`
+      do
+         if ! cat "$1" | cut -d: -f3 | grep -q "^$num$"
+         then
+            echo "$num"
+            return
+         fi
+      done
+   }
+   if [ -f $current/Resources/Requirements ]
+   then
+      Log_Normal "Asserting that requirements are met..."
+      source $current/Resources/Requirements
+    
+      for entry in "${required_groups[@]}"
+      do
+         group=`echo "$entry" | cut -d" " -f1`
+         grep -q "^$group:" $goboSettings/group && continue
+         
+         if echo "$entry" | grep -q "gid="
+         then 
+            gid="`echo $entry | sed 's,.*gid=\([^ ]*\).*,\1,g'`"
+            check_id_range $gid "gid" "$group" || continue
+         else
+            gid="`get_next_system_id $goboSettings/group`"
+            [ ! "$gid" ] && { Log_Error "Could not add group $group: no free slots"; continue; }
+         fi
+         Log_Normal "Adding group $group..."
+         $sudo_exec groupadd $group --gid $gid
+         grep -q "^$group:" $goboSettings/group || Log_Error "Error adding group $group."
+      done
+
+      for entry in "${required_users[@]}"
+      do
+         user=`echo "$entry" | cut -d" " -f1`
+         grep -q "^$user:" $goboSettings/passwd && continue
+         
+         if echo "$entry" | grep -q "home="
+         then homedir="`echo $entry | sed 's,.*home=\([^ ]*\).*,\1,g'`"
+         else homedir="$goboVariable/empty"
+         fi
+         if echo "$entry" | grep -q "groups="
+         then groups="`echo $entry | sed 's,.*groups=\([^ ]*\).*,\1,g'`"
+         else unset groups
+         fi
+         if echo "$entry" | grep -q "uid="
+         then 
+            uid="`echo $entry | sed 's,.*uid=\([^ ]*\).*,\1,g'`"
+            check_id_range $uid "uid" "$user" || continue
+         else
+            uid="`get_next_system_id $goboSettings/passwd`"
+            [ ! "$uid" ] && { Log_Error "Could not add user $user: no free slots"; continue; }
+         fi
+         Log_Normal "Adding user $user..."
+         [ -d "$homedir" ] && createhomedir= || createhomedir="-m"
+         $sudo_exec useradd $user --uid $uid -c "Added by Scripts" $createhomedir -d "$homedir" -s "$goboExecutables/nologin"
+         [ "$groups" ] && $sudo_exec usermod -a -G "$groups" "$user"
+         grep -q "^$user:" $goboSettings/passwd || Log_Error "Error adding user $group."
+      done
+   fi
+fi
+
+################################################################################
+
 Log_Normal "Removing unused directories..."
 PrepareProgram --tree-cleanup "$package" "$version"
 
