You are viewing a plain text version of this content. The canonical link for it is here.
Posted to common-commits@hadoop.apache.org by su...@apache.org on 2012/11/19 00:18:17 UTC

svn commit: r1411017 - in /hadoop/common/branches/branch-1-win: ./ src/core/org/apache/hadoop/fs/ src/core/org/apache/hadoop/security/ src/core/org/apache/hadoop/util/ src/test/org/apache/hadoop/security/ src/winutils/

Author: suresh
Date: Sun Nov 18 23:18:13 2012
New Revision: 1411017

URL: http://svn.apache.org/viewvc?rev=1411017&view=rev
Log:
HADOOP-8456. Support spaces in user names and group names in results returned via winutils. Contributed by Ivan Mitic.

Modified:
    hadoop/common/branches/branch-1-win/CHANGES.branch-1-win.txt
    hadoop/common/branches/branch-1-win/src/core/org/apache/hadoop/fs/RawLocalFileSystem.java
    hadoop/common/branches/branch-1-win/src/core/org/apache/hadoop/security/ShellBasedUnixGroupsMapping.java
    hadoop/common/branches/branch-1-win/src/core/org/apache/hadoop/util/Shell.java
    hadoop/common/branches/branch-1-win/src/test/org/apache/hadoop/security/TestUserGroupInformation.java
    hadoop/common/branches/branch-1-win/src/winutils/groups.c

Modified: hadoop/common/branches/branch-1-win/CHANGES.branch-1-win.txt
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-1-win/CHANGES.branch-1-win.txt?rev=1411017&r1=1411016&r2=1411017&view=diff
==============================================================================
--- hadoop/common/branches/branch-1-win/CHANGES.branch-1-win.txt (original)
+++ hadoop/common/branches/branch-1-win/CHANGES.branch-1-win.txt Sun Nov 18 23:18:13 2012
@@ -220,3 +220,6 @@ Branch-hadoop-1-win - unreleased
 
     HADOOP-8847. Change untar to use Java API on Windows instead of spawning
     tar process. (Bikas Saha via suresh)
+
+    HADOOP-8456. Support spaces in user names and group names in results 
+    returned via winutils. (Ivan Mitic via suresh)

Modified: hadoop/common/branches/branch-1-win/src/core/org/apache/hadoop/fs/RawLocalFileSystem.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-1-win/src/core/org/apache/hadoop/fs/RawLocalFileSystem.java?rev=1411017&r1=1411016&r2=1411017&view=diff
==============================================================================
--- hadoop/common/branches/branch-1-win/src/core/org/apache/hadoop/fs/RawLocalFileSystem.java (original)
+++ hadoop/common/branches/branch-1-win/src/core/org/apache/hadoop/fs/RawLocalFileSystem.java Sun Nov 18 23:18:13 2012
@@ -502,9 +502,10 @@ public class RawLocalFileSystem extends 
     private void loadPermissionInfo() {
       IOException e = null;
       try {
-        StringTokenizer t = new StringTokenizer(
-            FileUtil.execCommand(new File(getPath().toUri()), 
-                                          Shell.getGetPermissionCommand()));
+        String output = FileUtil.execCommand(new File(getPath().toUri()), 
+            Shell.getGetPermissionCommand());
+        StringTokenizer t =
+            new StringTokenizer(output, Shell.TOKEN_SEPARATOR_REGEX);
         //expected format
         //-rw-------    1 username groupname ...
         String permission = t.nextToken();
@@ -524,7 +525,6 @@ public class RawLocalFileSystem extends 
         }
         setOwner(owner);
 
-        // FIXME: Group names could have spaces on Windows
         setGroup(t.nextToken());
       } catch (Shell.ExitCodeException ioe) {
         if (ioe.getExitCode() != 1) {

Modified: hadoop/common/branches/branch-1-win/src/core/org/apache/hadoop/security/ShellBasedUnixGroupsMapping.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-1-win/src/core/org/apache/hadoop/security/ShellBasedUnixGroupsMapping.java?rev=1411017&r1=1411016&r2=1411017&view=diff
==============================================================================
--- hadoop/common/branches/branch-1-win/src/core/org/apache/hadoop/security/ShellBasedUnixGroupsMapping.java (original)
+++ hadoop/common/branches/branch-1-win/src/core/org/apache/hadoop/security/ShellBasedUnixGroupsMapping.java Sun Nov 18 23:18:13 2012
@@ -67,7 +67,8 @@ public class ShellBasedUnixGroupsMapping
         // if we didn't get the group - just return empty list;
         LOG.warn("got exception trying to get groups for user " + user, e);
       }
-      StringTokenizer tokenizer = new StringTokenizer(result);
+      StringTokenizer tokenizer =
+          new StringTokenizer(result, Shell.TOKEN_SEPARATOR_REGEX);
       
       while (tokenizer.hasMoreTokens()) {
         groups.add(tokenizer.nextToken());

Modified: hadoop/common/branches/branch-1-win/src/core/org/apache/hadoop/util/Shell.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-1-win/src/core/org/apache/hadoop/util/Shell.java?rev=1411017&r1=1411016&r2=1411017&view=diff
==============================================================================
--- hadoop/common/branches/branch-1-win/src/core/org/apache/hadoop/util/Shell.java (original)
+++ hadoop/common/branches/branch-1-win/src/core/org/apache/hadoop/util/Shell.java Sun Nov 18 23:18:13 2012
@@ -63,7 +63,7 @@ abstract public class Shell {
   /** Return a command to get a given user's groups list */
   public static String[] getGroupsForUserCommand(final String user) {
     //'groups username' command return is non-consistent across different unixes
-    return (WINDOWS)? new String[] { WINUTILS, "groups", user}
+    return (WINDOWS)? new String[] { WINUTILS, "groups", "-F", "\"" + user + "\""}
                     : new String [] {"bash", "-c", "id -Gn " + user};
   }
 
@@ -76,7 +76,7 @@ abstract public class Shell {
 
   /** Return a command to get permission information. */
   public static String[] getGetPermissionCommand() {
-    return (WINDOWS) ? new String[] { WINUTILS, "ls" }
+    return (WINDOWS) ? new String[] { WINUTILS, "ls", "-F" }
                      : new String[] { "/bin/ls", "-ld" };
   }
 
@@ -99,10 +99,10 @@ abstract public class Shell {
 
   /** Return a command to set owner */
   public static String[] getSetOwnerCommand(String owner) {
-    return (WINDOWS) ? new String[] { WINUTILS, "chown", owner }
+    return (WINDOWS) ? new String[] { WINUTILS, "chown", "\"" + owner + "\"" }
                      : new String[] { "chown", owner };
   }
-
+  
   /** Return a command to create symbolic links */
   public static String[] getSymlinkCommand(String target, String link) {
     return WINDOWS ? new String[] { WINUTILS, "symlink", link, target }
@@ -209,6 +209,10 @@ abstract public class Shell {
   public static final boolean LINUX
                 = System.getProperty("os.name").startsWith("Linux");
 
+  /** Token separator regex used to parse Shell tool outputs */
+  public static final String TOKEN_SEPARATOR_REGEX
+                = WINDOWS ? "[|\n\r]" : "[ \t\n\r\f]";
+
   /* Set flag for aiding Windows porting temporarily for branch-1-win*/
   // TODO - this needs to be fixed
   public static final boolean DISABLEWINDOWS_TEMPORARILY = WINDOWS; 

Modified: hadoop/common/branches/branch-1-win/src/test/org/apache/hadoop/security/TestUserGroupInformation.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-1-win/src/test/org/apache/hadoop/security/TestUserGroupInformation.java?rev=1411017&r1=1411016&r2=1411017&view=diff
==============================================================================
--- hadoop/common/branches/branch-1-win/src/test/org/apache/hadoop/security/TestUserGroupInformation.java (original)
+++ hadoop/common/branches/branch-1-win/src/test/org/apache/hadoop/security/TestUserGroupInformation.java Sun Nov 18 23:18:13 2012
@@ -124,14 +124,15 @@ public class TestUserGroupInformation {
     }
     // get the groups
     pp = Runtime.getRuntime().exec(Shell.WINDOWS ?
-      Shell.WINUTILS + " groups" : "id -Gn");
+      Shell.WINUTILS + " groups -F" : "id -Gn");
     br = new BufferedReader(new InputStreamReader(pp.getInputStream()));
     String line = br.readLine();
 
     System.out.println(userName + ":" + line);
    
-    List<String> groups = new ArrayList<String> ();    
-    for(String s: line.split("[\\s]")) {
+    List<String> groups = new ArrayList<String> ();
+    String[] tokens = line.split(Shell.TOKEN_SEPARATOR_REGEX);
+    for(String s: tokens) {
       groups.add(s);
     }
     

Modified: hadoop/common/branches/branch-1-win/src/winutils/groups.c
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-1-win/src/winutils/groups.c?rev=1411017&r1=1411016&r2=1411017&view=diff
==============================================================================
--- hadoop/common/branches/branch-1-win/src/winutils/groups.c (original)
+++ hadoop/common/branches/branch-1-win/src/winutils/groups.c Sun Nov 18 23:18:13 2012
@@ -28,8 +28,13 @@
 // Notes:
 //   This function could fail on first pass when we fail to find groups for
 //   domain account; so we do not report Windows API errors in this function.
+//   If formatOutput is true, pipe character is used as separator for groups
+//   otherwise, space.
 //
-static BOOL PrintGroups(LPLOCALGROUP_USERS_INFO_0 groups, DWORD entries)
+static BOOL PrintGroups(
+  LPLOCALGROUP_USERS_INFO_0 groups,
+  DWORD entries,
+  BOOL formatOutput)
 {
   BOOL ret = TRUE;
   LPLOCALGROUP_USERS_INFO_0 pTmpBuf = groups;
@@ -45,7 +50,14 @@ static BOOL PrintGroups(LPLOCALGROUP_USE
 
     if (i != 0)
     {
-      wprintf(L" ");
+      if (formatOutput)
+      {
+        wprintf(L"|");
+      }
+      else
+      {
+        wprintf(L" ");
+      }
     }
     wprintf(L"%s", pTmpBuf->lgrui0_name);
 
@@ -59,6 +71,56 @@ static BOOL PrintGroups(LPLOCALGROUP_USE
 }
 
 //----------------------------------------------------------------------------
+// Function: ParseCommandLine
+//
+// Description:
+//   Parses the command line
+//
+// Returns:
+//   TRUE on the valid command line, FALSE otherwise
+//
+static BOOL ParseCommandLine(
+  int argc, wchar_t *argv[], wchar_t **user, BOOL *formatOutput)
+{
+  *formatOutput = FALSE;
+
+  assert(argv != NULL);
+  assert(user != NULL);
+
+  if (argc == 1)
+  {
+    // implicitly use the current user
+    *user = NULL;
+    return TRUE;
+  }
+  else if (argc == 2)
+  {
+    // check if the second argument is formating
+    if (wcscmp(argv[1], L"-F") == 0)
+    {
+      *user = NULL;
+      *formatOutput = TRUE;
+      return TRUE;
+    }
+    else
+    {
+      *user = argv[1];
+      return TRUE;
+    }
+  }
+  else if (argc == 3 && wcscmp(argv[1], L"-F") == 0)
+  {
+    // if 3 args, the second argument must be "-F"
+
+    *user = argv[2];
+    *formatOutput = TRUE;
+    return TRUE;
+  }
+
+  return FALSE;
+}
+
+//----------------------------------------------------------------------------
 // Function: Groups
 //
 // Description:
@@ -83,15 +145,18 @@ int Groups(int argc, wchar_t *argv[])
   DWORD dwRtnCode = ERROR_SUCCESS;
 
   int ret = EXIT_SUCCESS;
+  BOOL formatOutput = FALSE;
 
-  if (argc != 2 && argc != 1)
+  if (!ParseCommandLine(argc, argv, &input, &formatOutput))
   {
     fwprintf(stderr, L"Incorrect command line arguments.\n\n");
     GroupsUsage(argv[0]);
     return EXIT_FAILURE;
   }
 
-  if (argc == 1)
+  // if username was not specified on the command line, fallback to the
+  // current user
+  if (input == NULL)
   {
     GetUserNameW(currentUser, &cchCurrentUser);
     if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
@@ -120,10 +185,6 @@ int Groups(int argc, wchar_t *argv[])
       goto GroupsEnd;
     }
   }
-  else
-  {
-    input = argv[1];
-  }
 
   if ((dwRtnCode = GetLocalGroupsForUser(input, &groups, &entries))
     != ERROR_SUCCESS)
@@ -133,7 +194,7 @@ int Groups(int argc, wchar_t *argv[])
     goto GroupsEnd;
   }
 
-  if (!PrintGroups(groups, entries))
+  if (!PrintGroups(groups, entries, formatOutput))
   {
     ret = EXIT_FAILURE;
   }
@@ -147,8 +208,10 @@ GroupsEnd:
 void GroupsUsage(LPCWSTR program)
 {
   fwprintf(stdout, L"\
-Usage: %s [USERNAME]\n\
-Print group information of the specified USERNAME\
-(the current user by default).\n",
+Usage: %s [OPTIONS] [USERNAME]\n\
+Print group information of the specified USERNAME \
+(the current user by default).\n\
+\n\
+OPTIONS: -F format the output by separating tokens with a pipe\n",
 program);
 }