head	1.2;
access;
symbols
	pkgsrc-2026Q1:1.2.0.70
	pkgsrc-2026Q1-base:1.2
	pkgsrc-2025Q4:1.2.0.68
	pkgsrc-2025Q4-base:1.2
	pkgsrc-2025Q3:1.2.0.66
	pkgsrc-2025Q3-base:1.2
	pkgsrc-2025Q2:1.2.0.64
	pkgsrc-2025Q2-base:1.2
	pkgsrc-2025Q1:1.2.0.62
	pkgsrc-2025Q1-base:1.2
	pkgsrc-2024Q4:1.2.0.60
	pkgsrc-2024Q4-base:1.2
	pkgsrc-2024Q3:1.2.0.58
	pkgsrc-2024Q3-base:1.2
	pkgsrc-2024Q2:1.2.0.56
	pkgsrc-2024Q2-base:1.2
	pkgsrc-2024Q1:1.2.0.54
	pkgsrc-2024Q1-base:1.2
	pkgsrc-2023Q4:1.2.0.52
	pkgsrc-2023Q4-base:1.2
	pkgsrc-2023Q3:1.2.0.50
	pkgsrc-2023Q3-base:1.2
	pkgsrc-2023Q2:1.2.0.48
	pkgsrc-2023Q2-base:1.2
	pkgsrc-2023Q1:1.2.0.46
	pkgsrc-2023Q1-base:1.2
	pkgsrc-2022Q4:1.2.0.44
	pkgsrc-2022Q4-base:1.2
	pkgsrc-2022Q3:1.2.0.42
	pkgsrc-2022Q3-base:1.2
	pkgsrc-2022Q2:1.2.0.40
	pkgsrc-2022Q2-base:1.2
	pkgsrc-2022Q1:1.2.0.38
	pkgsrc-2022Q1-base:1.2
	pkgsrc-2021Q4:1.2.0.36
	pkgsrc-2021Q4-base:1.2
	pkgsrc-2021Q3:1.2.0.34
	pkgsrc-2021Q3-base:1.2
	pkgsrc-2021Q2:1.2.0.32
	pkgsrc-2021Q2-base:1.2
	pkgsrc-2021Q1:1.2.0.30
	pkgsrc-2021Q1-base:1.2
	pkgsrc-2020Q4:1.2.0.28
	pkgsrc-2020Q4-base:1.2
	pkgsrc-2020Q3:1.2.0.26
	pkgsrc-2020Q3-base:1.2
	pkgsrc-2020Q2:1.2.0.22
	pkgsrc-2020Q2-base:1.2
	pkgsrc-2020Q1:1.2.0.2
	pkgsrc-2020Q1-base:1.2
	pkgsrc-2019Q4:1.2.0.24
	pkgsrc-2019Q4-base:1.2
	pkgsrc-2019Q3:1.2.0.20
	pkgsrc-2019Q3-base:1.2
	pkgsrc-2019Q2:1.2.0.18
	pkgsrc-2019Q2-base:1.2
	pkgsrc-2019Q1:1.2.0.16
	pkgsrc-2019Q1-base:1.2
	pkgsrc-2018Q4:1.2.0.14
	pkgsrc-2018Q4-base:1.2
	pkgsrc-2018Q3:1.2.0.12
	pkgsrc-2018Q3-base:1.2
	pkgsrc-2018Q2:1.2.0.10
	pkgsrc-2018Q2-base:1.2
	pkgsrc-2018Q1:1.2.0.8
	pkgsrc-2018Q1-base:1.2
	pkgsrc-2017Q4:1.2.0.6
	pkgsrc-2017Q4-base:1.2
	pkgsrc-2017Q3:1.2.0.4
	pkgsrc-2017Q3-base:1.2
	pkgsrc-2017Q2:1.1.0.2
	pkgsrc-2017Q2-base:1.1;
locks; strict;
comment	@# @;


1.2
date	2017.08.10.05.38.30;	author jlam;	state Exp;
branches;
next	1.1;
commitid	6hrsYCaUal0AXC2A;

1.1
date	2017.06.01.01.58.34;	author jlam;	state Exp;
branches;
next	;
commitid	ZKq8jUL9nZlDZBTz;


desc
@@


1.2
log
@Update pkgtools/pkgtasks to version 1.13.

* Add a "icon_themes" task to cache GTK+ icon theme directories.
* Change the way that install-info(1) is invoked.
* Clarify the output from the "groups" and "users" tasks.
* Bug fixes.
@
text
@# Copyright (c) 2017 The NetBSD Foundation, Inc.
# All rights reserved.
#
# This code is derived from software contributed to The NetBSD Foundation
# by Johnny C. Lam.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
# NAME
#	users.subr -- user management for packages
#
# SYNOPSIS
#	task_users [-s] add | remove
#	task_users check-add | check-remove
#
# DESCRIPTION
#	The task_users function supports four actions: "add", "remove",
#	"check-add", and "check-remove".
#
#	The available options are as follows:
#
#	-s	Silent; don't write to standard output.
#
#	The function reads standard input line by line and looks for
#	lines of the form:
#
#	    # USER: <name>:<group>[:<userid>[:<descr>[:<home>[:<shell>]]]]
#
#	Only the user name and group are required; the remaining fields
#	are optional.
#
#	The "add" action creates the user with the given name if it is
#	missing, with the given user ID, if ${PKG_CREATE_USERGROUP} is
#	"yes".  A reference count for the user will be added for the
#	package.
#
#	The "remove" action removes a reference count for the user by
#	the package.  This function shall not remove any user on the
#	system.
#
#	The "check-add" action will check whether the users exist with
#	the optional user IDs if they are given, or otherwise writes a
#	message to standard output noting the missing users.
#
#	The "check-remove" action will check whether the users have been
#	removed, or otherwise writes a message to standard output noting
#	the users still exists.
#
# RETURN VALUES
#	The "add" and "remove" actions return 0 if they are successful
#	for all users, and >0 if an error occurs.
#
#	The "check-add" and "check-remove" actions return >0 if they
#	write informative messages, and return 0 otherwise.
#
# ENVIRONMENT
#	The following variables are used if they are set:
#
#	PKGNAME
#		The name of the package.
#
#	PKG_CREATE_USERGROUP
#		If ${PKG_CREATE_USERGROUP} is a "truthy" value, then the
#		"add" and "remove" actions are allowed to create and
#		remove users from the system.
#
#	TASK_MSG
#		String prepended to all normal message written to
#		standard output.
#

__task_users__="yes"
__task_users_init__="_task_users_init"

task_load cleanup
task_load echo
task_load quote
task_load refcount
task_load truthy
task_load usergroup
task_load usergroup_exists

task_users()
{
	: ${PKGNAME:=${0##*/}}
	: ${PKG_CREATE_USERGROUP:=yes}
	: ${TASK_MSG:=""}

	local arg
	local echo="task_echo"
	local OPTIND=1
	while getopts ":s" arg "$@@"; do
		case $arg in
		s)	echo=":" ;;
		*)	return 127 ;;
		esac
	done
	shift $(( ${OPTIND} - 1 ))
	[ $# -gt 0 ] || return 127

	local action="$1"; shift
	case $action in
	add|remove|check-add|check-remove)
		: "valid action" ;;
	*)	return 0 ;;
	esac

	local create="yes"
	task_is_truthy "${PKG_CREATE_USERGROUP}" || create=

	local result line_result
	local save_IFS user group uid descr home shell msg submsg

	result=0
	local hash tag entry
	while read hash tag entry; do
		# Filter for "# USER:".
		case $hash/$tag in
		"#/USER:")
			: "use this line" ;;
		*)	continue ;;
		esac

		save_IFS=$IFS; IFS=:
		set -o noglob; set -- $entry; set +o noglob
		user=$1; group=$2	# required
		uid=$3; descr=$4; home=$5; shell=$6
		IFS=$save_IFS
		[ -n "$user" -a -n "$group" ] || continue

		submsg=
		[ -z "$uid" ] || submsg="$submsg, uid = $uid"
		[ -z "$group" ] || submsg="$submsg, group = $group"
		[ -z "$home" ] || submsg="$submsg, home = $home"
		[ -z "$shell" ] || submsg="$submsg, shell = $shell"
		submsg="(${submsg#, })"
		if [ "$submsg" = "()" ]; then
			msg="$user"
		else
			msg="$user $submsg"
		fi

		line_result=0
		case $action in
		add)	if task_refcount add users "$user"; then
				task_user_exists "$user" "$uid"
				case $? in
				0)	# $user exists and has uid $uid
					$echo "${TASK_MSG}! user already exists: $user" ;;
				1)	# neither $user nor $uid exist
					if [ -z "$create" ]; then
						$echo "${TASK_MSG}! user creation skipped: $msg"
					elif task_adduser "$user" "$group" "$uid" "$descr" "$home" "$shell"; then
						$echo "${TASK_MSG}> user created: $msg"
						task_quote "$user"
						__task_users_error__="$__task_users_error__ $_quoted"
					else
						$echo "${TASK_MSG}! user not created: $msg"
						line_result=1
					fi ;;
				2)	$echo "${TASK_MSG}! user conflict: $msg"
					result=1
					break ;;
				*)	$echo "${TASK_MSG}! user not created: $msg"
					line_result=1 ;;
				esac
			else
				# add refcount failed; skip to next line
				$echo "${TASK_MSG}! refcount add failure: users $user"
				result=1
				continue
			fi ;;
		remove)	if task_refcount remove users "$user"; then
				if task_refcount exists users "$user"; then
					: "refcount is not zero"
				else
					# delete the reference count
					task_refcount delete users "$user"
				fi
			else
				# remove refcount failed
				$echo "${TASK_MSG}! refcount remove failure: users $user"
				line_result=1
			fi ;;
		check-add)
			if task_user_exists "$user" "$uid"; then
				: "user already exists"
			else
				task_echo "!!! INFO: ${PKGNAME}: Create user: $msg"
				line_result=1
			fi ;;
		check-remove)
			if task_user_exists "$user" "$uid"; then
				task_echo "!!! INFO: ${PKGNAME}: Remove user if unused: $user"
				line_result=1
			fi ;;
		esac
		[ $line_result -eq 0 ] || result=1
	done

	# Clear users to remove in case of error if all users added
	# successfully.
	#
	[ $result -gt 0 ] || __task_users_error__=

	return $result
}

_task_users_cleanup()
{
	eval set -- $__task_users_error__
	local user
	for user; do
		if task_user_exists "$user"; then
			task_echo "!!! ERROR: ${PKGNAME}: User created before error: $user"
		fi
	done
	__task_users_error__=
}

_task_users_init()
{
	task_cleanup_add_hook _task_users_cleanup
}

# Static variable for users that should be removed if an error occurs.
__task_users_error__=
@


1.1
log
@Import pkgtasks-1-1.9 as pkgsrc/pkgtools/pkgtasks.

pkgtasks is a shell script library to ease writing POSIX-compliant
shell scripts to handle common tasks during installation or removal
of a package, e.g.,

  * creating groups and users needed by the package

  * creating and removing directories with special permissions and
    ownership,

  * copying example config files to their final locations during
    package installation, and removing them during package removal
    if they don't differ from the example ones,

  * reminding the user of files that may be customized after
    package installation.
@
text
@d131 1
a131 1
	local save_IFS user group uid descr home shell msg
d150 8
a157 2
		if [ -n "$uid" ]; then
			msg="$user (uid = $uid)"
d159 1
a159 1
			msg="$user"
a160 3
		msg="$msg: $group"
		[ -z "$home" ] || msg="$msg, $home"
		[ -z "$shell" ] || msg="$msg, $shell"
d168 1
a168 1
					$echo "${TASK_MSG}! user already exists: $msg" ;;
d188 1
a188 1
				$echo "${TASK_MSG}! refcount add failure: users $msg"
d201 1
a201 1
				$echo "${TASK_MSG}! refcount remove failure: users $msg"
@

