Subject: bug#7900: [PATCH]

From: Dmitry Antipov <[email-masked]>
Date: Thu, 22 Sep 2011 07:57:29 +0400

=== modified file 'configure.in'
--- configure.in	2011-09-15 03:01:25 +0000
+++ configure.in	2011-09-21 03:36:38 +0000
@@ -1206,7 +1206,7 @@
   linux/version.h sys/systeminfo.h \
   stdio_ext.h fcntl.h coff.h pty.h sys/mman.h \
   sys/vlimit.h sys/resource.h locale.h sys/_mbstate_t.h \
-  sys/utsname.h pwd.h utmp.h dirent.h util.h)
+  sys/utsname.h pwd.h grp.h utmp.h dirent.h util.h)
 
 AC_MSG_CHECKING(if personality LINUX32 can be set)
 AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/personality.h>]], [[personality (PER_LINUX32)]])],
@@ -2730,6 +2730,7 @@
 sendto recvfrom getsockopt setsockopt getsockname getpeername \
 gai_strerror mkstemp getline getdelim mremap fsync sync \
 difftime mempcpy mblen mbrlen posix_memalign \
+getpwent endpwent getgrent endgrent \
 cfmakeraw cfsetspeed copysign __executable_start)
 
 dnl Cannot use AC_CHECK_FUNCS

=== modified file 'lisp/dired-aux.el'
--- lisp/dired-aux.el	2011-09-14 15:06:28 +0000
+++ lisp/dired-aux.el	2011-09-21 07:12:38 +0000
@@ -244,8 +244,12 @@
 			 (if (eq op-symbol 'touch)
 			     " (default now): "
 			   ": ")))
-	 (new-attribute (dired-mark-read-string prompt nil op-symbol
-						arg files default))
+	 (new-attribute (dired-mark-read-string
+			 prompt
+			 (cond ((eq op-symbol 'chown) (system-users))
+			       ((eq op-symbol 'chgrp) (system-groups)))
+			 nil op-symbol
+			 arg files default))
 	 (operation (concat program " " new-attribute))
 	 failures)
     (setq failures
@@ -284,7 +288,7 @@
 			 (match-string 2 modestr)
 			 (match-string 3 modestr)))))
 	 (modes (dired-mark-read-string
-		 "Change mode of %s to: "
+		 "Change mode of %s to: " nil
 		 nil 'chmod arg files default))
 	 num-modes)
     (cond ((equal modes "")
@@ -374,7 +378,7 @@
   (interactive "P")
   (let* ((file-list (dired-get-marked-files t arg))
 	 (command (dired-mark-read-string
-		   "Print %s with: "
+		   "Print %s with: " nil
  		   (mapconcat 'identity
 			      (cons lpr-command
 				    (if (stringp lpr-switches)
@@ -384,8 +388,8 @@
 		   'print arg file-list)))
     (dired-run-shell-command (dired-shell-stuff-it command file-list nil))))
 
-(defun dired-mark-read-string (prompt initial op-symbol arg files
-			       &optional default-value)
+(defun dired-mark-read-string (prompt collection initial op-symbol
+			       arg files &optional default-value)
   "Read args for a Dired marked-files command, prompting with PROMPT.
 Return the user input (a string).
 
@@ -399,9 +403,9 @@
 user enters empty input, this function returns the empty string,
 not DEFAULT-VALUE."
   (dired-mark-pop-up nil op-symbol files
-		     'read-from-minibuffer
+		     'completing-read
 		     (format prompt (dired-mark-prompt arg files))
-		     initial nil nil nil default-value))
+		     collection nil nil initial nil default-value nil))
 
 ;;; Cleaning a directory: flagging some backups for deletion.

=== modified file 'src/dired.c'
--- src/dired.c	2011-09-09 01:06:52 +0000
+++ src/dired.c	2011-09-21 15:41:25 +0000
@@ -27,7 +27,9 @@
 #ifdef HAVE_PWD_H
 #include <pwd.h>
 #endif
+#ifdef HAVE_GRP_H
 #include <grp.h>
+#endif
 
 #include <errno.h>
 #include <unistd.h>
@@ -1014,6 +1016,45 @@
   return Fstring_lessp (Fcar (f1), Fcar (f2));
 }
 
+
+DEFUN ("system-users", Fsystem_users, Ssystem_users, 0, 0, 0,
+       doc: /* Return a list of user names currently registered in the system.
+The value may be nil if not supported on this platform.  */)
+     (void)
+{
+  Lisp_Object users = Qnil;
+#if defined(HAVE_GETPWENT) && defined(HAVE_ENDPWENT)
+  struct passwd *pw;
+
+  while ((pw = getpwent ()))
+    users = Fcons (DECODE_SYSTEM (build_string (pw->pw_name)), users);
+
+  endpwent ();
+#endif
+  if (EQ (users, Qnil))
+    /* At least current user is always known. */
+    users = Fcons (Vuser_real_login_name, Qnil);
+  return users;
+}
+
+DEFUN ("system-groups", Fsystem_groups, Ssystem_groups, 0, 0, 0,
+       doc: /* Return a list of user group names currently registered in the system.
+The value may be nil if not supported on this platform.  */)
+     (void)
+{
+  Lisp_Object groups = Qnil;
+#if defined(HAVE_GETGRENT) && defined(HAVE_ENDGRENT)
+  struct group *gr;
+  int length;
+
+  while ((gr = getgrent ()))
+    groups = Fcons (DECODE_SYSTEM (build_string (gr->gr_name)), groups);
+
+  endgrent ();
+#endif
+  return groups;
+}
+
 void
 syms_of_dired (void)
 {
@@ -1031,6 +1072,8 @@
   defsubr (&Sfile_name_all_completions);
   defsubr (&Sfile_attributes);
   defsubr (&Sfile_attributes_lessp);
+  defsubr (&Ssystem_users);
+  defsubr (&Ssystem_groups);
 
   DEFVAR_LISP ("completion-ignored-extensions", Vcompletion_ignored_extensions,
 	       doc: /* Completion ignores file names ending in any string in this list.