#!/bin/bash

## Copyright (C) 2012 - 2025 ENCRYPTED SUPPORT LLC <adrelanos@whonix.org>
## See the file COPYING for copying conditions.

set -o errexit
set -o nounset
set -o errtrace
set -o pipefail
shopt -s inherit_errexit
shopt -s shift_verbose
export LC_ALL=C

# shellcheck source=./strings.bsh
source "${HELPER_SCRIPTS_PATH:-}"/usr/libexec/helper-scripts/strings.bsh

adduser_conf_path="${GET_USER_LIST_ADDUSER_CONF:-/etc/adduser.conf}"
passwd_path="${GET_USER_LIST_PASSWD:-/etc/passwd}"

## Read one key's value from adduser.conf. In case of multiple matches, the
## last match wins.
read_adduser_conf_field() {
  local key line value found

  key="$1"
  value=""
  found="false"

  while IFS= read -r line; do
    if [[ "${line}" =~ ^[[:space:]]*${key}[[:space:]]*= ]]; then
      value="${line#*=}"
      found="true"
    fi
  done < "${adduser_conf_path}"

  if [ "${found}" = "false" ]; then
    printf '%s' ""
    return 0
  fi

  ## Strip whitespace.
  value="${value#"${value%%[![:space:]]*}"}"
  value="${value%"${value##*[![:space:]]}"}"

  printf '%s' "${value}"
}

if test -r "${adduser_conf_path}"; then
  first_uid="$(read_adduser_conf_field FIRST_UID)"
  if ! is_whole_number "${first_uid}"; then
    printf '%s\n' "$0: ERROR: FIRST_UID in file '${adduser_conf_path}' is not a whole number!" >&2
    exit 1
  fi

  last_uid="$(read_adduser_conf_field LAST_UID)"
  if ! is_whole_number "${last_uid}"; then
    printf '%s\n' "$0: ERROR: LAST_UID in file '${adduser_conf_path}' is not a whole number!" >&2
    exit 1
  fi
fi

if [ -z "${first_uid:-}" ]; then
  first_uid=1000
fi
if [ -z "${last_uid:-}" ]; then
  last_uid=59999
fi

if ! test -r "${passwd_path}"; then
  printf '%s\n' "$0: ERROR: file '${passwd_path}' is not readable!" >&2
  exit 1
fi

while read -r user_entry; do
   current_uid="$(cut -d':' -f3 <<< "${user_entry}")"
   if [ "${current_uid}" -ge "${first_uid}" ] \
      && [ "${current_uid}" -le "${last_uid}" ]; then
      cut -d':' -f1 <<< "${user_entry}"
   elif [ "${current_uid}" = '0' ]; then
      ## Include the root user in the list.
      cut -d':' -f1 <<< "${user_entry}"
   fi
done < "${passwd_path}"
