bin/189057: [PATCH] Adding an option to /bin/ls to display file permissions in octal

A.J. van Werven freebsd at skysmurf.nl
Sun Apr 27 17:50:00 UTC 2014


>Number:         189057
>Category:       bin
>Synopsis:       [PATCH] Adding an option to /bin/ls to display file permissions in octal
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Sun Apr 27 17:50:00 UTC 2014
>Closed-Date:
>Last-Modified:
>Originator:     A.J. van Werven
>Release:        9.2-RELEASE-p3
>Organization:
>Environment:
>Description:
A user of the FreeBSD Forums requested that an option be added to /bin/ls that makes the long format (-l option) display the file permissions in octal rather than symbolically, e.g. instead of "-rwxr-xr-x" it would say "-0755". The attached patch does just that and has been proposed on freebsd-hackers@, where it was suggested that a PR be submitted to prevent it from "getting lost".

If the proposed addition has already been incorporated or rejected, this PR can be closed.
>How-To-Repeat:
N/A: this is a feature request, not a bug report.
>Fix:
Apply the attached patch. It includes an update to the usage message and to the man page, although the STANDARDS part probably needs some reviewing.

Patch attached with submission follows:

diff -ruN ls.orig/ls.1 ls/ls.1
--- ls.orig/ls.1	2014-04-08 18:22:46.000000000 +0200
+++ ls/ls.1	2014-04-08 19:04:01.000000000 +0200
@@ -40,7 +40,7 @@
 .Nd list directory contents
 .Sh SYNOPSIS
 .Nm
-.Op Fl ABCFGHILPRSTUWZabcdfghiklmnopqrstuwxy1,
+.Op Fl ABCFGHILOPRSTUWZabcdfghiklmnopqrstuwxy1,
 .Op Fl D Ar format
 .Op Ar
 .Sh DESCRIPTION
@@ -150,6 +150,11 @@
 This option cancels the
 .Fl P
 option.
+.It Fl O
+When used with the
+.Fl l
+option, display the file permissions in octal notation. Note that the file type
+is still displayed symbolically.
 .It Fl P
 If argument is a symbolic link, list the link itself rather than the
 object the link references.
@@ -526,6 +531,15 @@
 use
 .Xr getfacl 1
 to do this.
+.Pp
+When the
+.Fl O
+option is used, the entry type is displayed as described above, but the
+permissions are displayed in
+.Dq raw 
+octal mode, consisting of four octal digits. The first digit indicates whether
+any of the set-user-ID, set-group-ID or sticky bits have been set. The other
+three digits represent the owner, group and other permissions respectively.
 .Sh ENVIRONMENT
 The following environment variables affect the execution of
 .Nm :
@@ -739,9 +753,9 @@
 .Xr getfmac 8
 .Sh STANDARDS
 With the exception of options
-.Fl I , g , n
-and
-.Fl o ,
+.Fl I , g , n, o
+and possibly
+.Fl O ,
 the
 .Nm
 utility conforms to
diff -ruN ls.orig/ls.c ls/ls.c
--- ls.orig/ls.c	2014-04-08 18:22:46.000000000 +0200
+++ ls/ls.c	2014-04-08 19:03:27.000000000 +0200
@@ -120,6 +120,7 @@
        int f_notabs;		/* don't use tab-separated multi-col output */
 static int f_numericonly;	/* don't convert uid/gid to name */
        int f_octal;		/* show unprintables as \xxx */
+       int f_octalperms;        /* print permissions and modes in octal */
        int f_octal_escape;	/* like f_octal but use C escapes if possible */
 static int f_recursive;		/* ls subdirectories also */
 static int f_reversesort;	/* reverse whatever sort is used */
@@ -186,7 +187,7 @@
 	if (getenv("LS_SAMESORT"))
 		f_samesort = 1;
 	while ((ch = getopt(argc, argv,
-	    "1ABCD:FGHILPRSTUWXZabcdfghiklmnopqrstuwxy,")) != -1) {
+	    "1ABCD:FGHILOPRSTUWXZabcdfghiklmnopqrstuwxy,")) != -1) {
 		switch (ch) {
 		/*
 		 * The -1, -C, -x and -l options all override each other so
@@ -272,6 +273,9 @@
 			fts_options |= FTS_LOGICAL;
 			f_nofollow = 0;
 			break;
+		case 'O':
+			f_octalperms=1;
+			break;
 		case 'P':
 			fts_options &= ~FTS_COMFOLLOW;
 			fts_options &= ~FTS_LOGICAL;
diff -ruN ls.orig/ls.h ls/ls.h
--- ls.orig/ls.h	2014-04-08 18:22:46.000000000 +0200
+++ ls/ls.h	2014-04-08 16:18:33.000000000 +0200
@@ -47,6 +47,7 @@
 extern int f_inode;		/* print inode */
 extern int f_longform;		/* long listing format */
 extern int f_octal;		/* print unprintables in octal */
+extern int f_octalperms;        /* print permissions and modes in octal */
 extern int f_octal_escape;	/* like f_octal but use C escapes if possible */
 extern int f_nonprint;		/* show unprintables as ? */
 extern int f_samesort;		/* sort time and name in same direction */
diff -ruN ls.orig/print.c ls/print.c
--- ls.orig/print.c	2014-04-08 18:22:46.000000000 +0200
+++ ls/print.c	2014-04-08 22:32:54.000000000 +0200
@@ -73,6 +73,7 @@
 static int	colortype(mode_t);
 #endif
 static void	aclmode(char *, const FTSENT *);
+static void     octalmode(int, char *);
 
 #define	IS_NOPRINT(p)	((p)->fts_number == NO_PRINT)
 
@@ -141,12 +142,15 @@
 #ifdef COLORLS
 	int color_printed = 0;
 #endif
+	void (*strmodefcn)(int, char *);
 
 	if ((dp->list == NULL || dp->list->fts_level != FTS_ROOTLEVEL) &&
 	    (f_longform || f_size)) {
 		(void)printf("total %lu\n", howmany(dp->btotal, blocksize));
 	}
 
+	strmodefcn = (f_octalperms > 0) ? octalmode : strmode;
+
 	for (p = dp->list; p; p = p->fts_link) {
 		if (IS_NOPRINT(p))
 			continue;
@@ -157,7 +161,7 @@
 		if (f_size)
 			(void)printf("%*jd ",
 			    dp->s_block, howmany(sp->st_blocks, blocksize));
-		strmode(sp->st_mode, buf);
+		strmodefcn(sp->st_mode, buf);
 		aclmode(buf, p);
 		np = p->fts_pointer;
 		(void)printf("%s %*u %-*s  %-*s  ", buf, dp->s_nlink,
@@ -684,3 +688,44 @@
 		buf[10] = '+';
 	acl_free(facl);
 }
+
+/*
+ * Print file mode and permissions in octal mode. Like the regular strmode(),
+ * add a space at the end for (potential) use by aclmode().
+ */
+static void
+octalmode(int mode, char *bp)
+{
+        /* Print the file type symbolically, this makes no sense in octal. */
+	switch (mode & S_IFMT) {
+	case S_IFDIR:
+		*bp++ = 'd';
+		break;
+	case S_IFCHR:
+		*bp++ = 'c';
+		break;
+	case S_IFBLK:
+		*bp++ = 'b';
+		break;
+	case S_IFREG:
+		*bp++ = '-';
+		break;
+	case S_IFLNK:
+		*bp++ = 'l';
+		break;
+	case S_IFSOCK:
+		*bp++ = 's';
+		break;
+	case S_IFIFO:
+		*bp++ = 'p';
+		break;
+	case S_IFWHT:
+		*bp++ = 'w';
+		break;
+	default:
+		*bp++ = '?';
+		break;
+	}
+	(void)snprintf(bp, 6, "%o%o%o%o ", (mode & 0007000) >> 9,
+	    (mode & S_IRWXU) >> 6, (mode & S_IRWXG) >> 3, mode & S_IRWXO);
+}
diff -ruN ls.orig/util.c ls/util.c
--- ls.orig/util.c	2014-04-08 18:22:46.000000000 +0200
+++ ls/util.c	2014-04-08 17:17:01.000000000 +0200
@@ -222,9 +222,9 @@
 {
 	(void)fprintf(stderr,
 #ifdef COLORLS
-	"usage: ls [-ABCFGHILPRSTUWZabcdfghiklmnopqrstuwxy1,] [-D format]"
+	"usage: ls [-ABCFGHILOPRSTUWZabcdfghiklmnopqrstuwxy1,] [-D format]"
 #else
-	"usage: ls [-ABCFHILPRSTUWZabcdfghiklmnopqrstuwxy1,] [-D format]"
+	"usage: ls [-ABCFHILOPRSTUWZabcdfghiklmnopqrstuwxy1,] [-D format]"
 #endif
 		      " [file ...]\n");
 	exit(1);


>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list