git: 02de2f3b499a - releng/15.0 - id: Add -d and -s options

From: Colin Percival <cperciva_at_FreeBSD.org>
Date: Thu, 30 Oct 2025 23:52:25 UTC
The branch releng/15.0 has been updated by cperciva:

URL: https://cgit.FreeBSD.org/src/commit/?id=02de2f3b499a571dd1d4123d2524e6a373ab7e59

commit 02de2f3b499a571dd1d4123d2524e6a373ab7e59
Author:     Dag-Erling Smørgrav <des@FreeBSD.org>
AuthorDate: 2025-10-28 16:51:56 +0000
Commit:     Colin Percival <cperciva@FreeBSD.org>
CommitDate: 2025-10-30 23:48:15 +0000

    id: Add -d and -s options
    
    These options may not be combined with any other options and print the
    current or specified user's home directory and shell respectively.
    
    Approved by:    re (cperciva)
    Reviewed by:    imp, bcr
    Differential Revision:  https://reviews.freebsd.org/D53301
    
    (cherry picked from commit f41b1eb637f576634be0df9d657f46aa57afea59)
    (cherry picked from commit eff786f23611582e518f038e4086a1306c019d23)
---
 usr.bin/id/id.1 | 28 +++++++++++++++++++++++++---
 usr.bin/id/id.c | 48 +++++++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 70 insertions(+), 6 deletions(-)

diff --git a/usr.bin/id/id.1 b/usr.bin/id/id.1
index b8dafb6650b0..62c941f84798 100644
--- a/usr.bin/id/id.1
+++ b/usr.bin/id/id.1
@@ -28,7 +28,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd March 5, 2011
+.Dd October 23, 2025
 .Dt ID 1
 .Os
 .Sh NAME
@@ -50,12 +50,18 @@
 .Nm
 .Fl c
 .Nm
+.Fl d
+.Op Ar user
+.Nm
 .Fl g Op Fl nr
 .Op Ar user
 .Nm
 .Fl p
 .Op Ar user
 .Nm
+.Fl s
+.Op Ar user
+.Nm
 .Fl u Op Fl nr
 .Op Ar user
 .Sh DESCRIPTION
@@ -90,6 +96,8 @@ Ignored for compatibility with other
 implementations.
 .It Fl c
 Display current login class.
+.It Fl d
+Display the home directory of the current or specified user.
 .It Fl g
 Display the effective group ID as a number.
 .It Fl n
@@ -128,6 +136,8 @@ Display the real ID for the
 and
 .Fl u
 options instead of the effective ID.
+.It Fl s
+Display the shell of the current or specified user.
 .It Fl u
 Display the effective user ID as a number.
 .El
@@ -174,8 +184,20 @@ bob          pts/5        Dec  4 19:51
 .Sh STANDARDS
 The
 .Nm
-function is expected to conform to
-.St -p1003.2 .
+utility is expected to conform to
+.St -p1003.1-2024 .
+The
+.Fl A ,
+.Fl M ,
+.Fl P ,
+.Fl c ,
+.Fl d ,
+.Fl p ,
+and
+.Fl s
+options are
+.Fx
+extensions.
 .Sh HISTORY
 The
 historic
diff --git a/usr.bin/id/id.c b/usr.bin/id/id.c
index a326aa14c7c7..5f9d2670caa3 100644
--- a/usr.bin/id/id.c
+++ b/usr.bin/id/id.c
@@ -55,6 +55,8 @@ static void	auditid(void);
 #endif
 static void	group(struct passwd *, bool);
 static void	maclabel(void);
+static void	dir(struct passwd *);
+static void	shell(struct passwd *);
 static void	usage(void);
 static struct passwd *who(char *);
 
@@ -69,7 +71,7 @@ main(int argc, char *argv[])
 	bool Aflag;
 #endif
 	bool Gflag, Mflag, Pflag;
-	bool cflag, gflag, nflag, pflag, rflag, uflag;
+	bool cflag, dflag, gflag, nflag, pflag, rflag, sflag, uflag;
 	int ch, combo, error, id;
 	const char *myname, *optstr;
 	char loginclass[MAXLOGNAME];
@@ -78,10 +80,10 @@ main(int argc, char *argv[])
 	Aflag = false;
 #endif
 	Gflag = Mflag = Pflag = false;
-	cflag = gflag = nflag = pflag = rflag = uflag = false;
+	cflag = dflag = gflag = nflag = pflag = rflag = sflag = uflag = false;
 
 	myname = getprogname();
-	optstr = "AGMPacgnpru";
+	optstr = "AGMPacdgnprsu";
 	if (strcmp(myname, "groups") == 0) {
 		isgroups = true;
 		optstr = "";
@@ -114,6 +116,9 @@ main(int argc, char *argv[])
 		case 'c':
 			cflag = true;
 			break;
+		case 'd':
+			dflag = true;
+			break;
 		case 'g':
 			gflag = true;
 			break;
@@ -126,6 +131,9 @@ main(int argc, char *argv[])
 		case 'r':
 			rflag = true;
 			break;
+		case 's':
+			sflag = true;
+			break;
 		case 'u':
 			uflag = true;
 			break;
@@ -142,6 +150,8 @@ main(int argc, char *argv[])
 		usage();
 
 	combo = Aflag + Gflag + Mflag + Pflag + gflag + pflag + uflag;
+	if (combo + dflag + sflag > 1)
+		usage();
 	if (combo > 1)
 		usage();
 	if (combo == 0 && (nflag || rflag))
@@ -185,6 +195,11 @@ main(int argc, char *argv[])
 		exit(0);
 	}
 
+	if (dflag) {
+		dir(pw);
+		exit(0);
+	}
+
 	if (Gflag) {
 		group(pw, nflag);
 		exit(0);
@@ -205,6 +220,11 @@ main(int argc, char *argv[])
 		exit(0);
 	}
 
+	if (sflag) {
+		shell(pw);
+		exit(0);
+	}
+
 	id_print(pw);
 	exit(0);
 }
@@ -464,6 +484,26 @@ pline(struct passwd *pw)
 	    pw->pw_dir, pw->pw_shell);
 }
 
+static void
+dir(struct passwd *pw)
+{
+	if (pw == NULL) {
+		if ((pw = getpwuid(getuid())) == NULL)
+			err(1, "getpwuid");
+	}
+	printf("%s\n", pw->pw_dir);
+}
+
+static void
+shell(struct passwd *pw)
+{
+	if (pw == NULL) {
+		if ((pw = getpwuid(getuid())) == NULL)
+			err(1, "getpwuid");
+	}
+	printf("%s\n", pw->pw_shell);
+}
+
 static void
 usage(void)
 {
@@ -481,8 +521,10 @@ usage(void)
 		    "       id -M\n"
 		    "       id -P [user]\n"
 		    "       id -c\n"
+		    "       id -d [user]\n"
 		    "       id -g [-nr] [user]\n"
 		    "       id -p [user]\n"
+		    "       id -s [user]\n"
 		    "       id -u [-nr] [user]\n");
 	exit(1);
 }