--- jakarta-slide\src\webdav\client\src\org\apache\webdav\cmd\Slide.java	Thu May 17 02:34:01 2001
+++ jakarta-slide\src\webdav\client\src\org\apache\webdav\cmd\Slide.java	Fri Jun 08 16:07:34 2001
@@ -86,6 +86,9 @@
 
 import org.apache.webdav.lib.WebdavResource;
 import org.apache.webdav.lib.methods.*;
+import org.apache.webdav.lib.properties.AclProperty;
+import org.apache.webdav.lib.Ace;
+import org.apache.webdav.lib.Privilege;
 
 /**
  * The Slide client, the command line version for WebDAV client.
@@ -93,6 +96,7 @@
  * @author <a href="mailto:jericho@thinkree.com">Park, Sung-Gu</a>
  * @author <a href="mailto:remm@apache.org">Remy Maucherat</a>
  * @author <a href="mailto:daveb@miceda-data.com">Dave Bryson</a>
+ * @author Dirk Verbeeck
  */
 public class Slide {
 
@@ -382,10 +386,12 @@
                 } else
                 if (todo.equalsIgnoreCase("exit") ||
                     todo.equalsIgnoreCase("quit") ||
+                    todo.equalsIgnoreCase("q") ||
                     todo.equalsIgnoreCase("bye")) {
                     break;
                 } else
                 if (todo.equalsIgnoreCase("help") ||
+                    todo.equalsIgnoreCase("h") ||
                     todo.equalsIgnoreCase("?")) {
                     printSlideClientUsage();
                 } else
@@ -813,12 +819,89 @@
                         } // end of switch
                     }
                 } else
-                if (todo.equalsIgnoreCase("propget") ||
+                if (todo.equalsIgnoreCase("grant")) {
+				    int count = params.size();
+					String principal=null;
+					String to=null;
+					String path=null;
+					String on=null;
+					String permission=null;
+					String namespace=null;
+					if (count==3) { // grant <permission> to <principal>
+						principal=(String)params.pop();
+						to=(String)params.pop();
+						path=checkUri(webdavResource.getPath());
+						on="on";
+						permission=(String)params.pop();
+						namespace=null;
+					} else if (count==4) { // grant <namespace> <permission> to <principal>
+						principal=(String)params.pop();
+						to=(String)params.pop();
+						path=checkUri(webdavResource.getPath());
+						on="on";
+						permission=(String)params.pop();
+						namespace=(String)params.pop();
+					} else if (count==5) { // grant <permission> on <path> to <principal>
+						principal=(String)params.pop();
+						to=(String)params.pop();
+						path=checkUri((String)params.pop());
+						on=(String)params.pop();
+						permission=(String)params.pop();
+						namespace=null;
+					} else if (count==6) { // grant <namespace> <permission> on <path> to <principal>
+						principal=(String)params.pop();
+	 					to=(String)params.pop();
+	 					path=checkUri((String)params.pop());
+	 					on=(String)params.pop();
+	 					permission=(String)params.pop();
+	 					namespace=(String)params.pop();
+ 					} 
+					if (!"to".equalsIgnoreCase(to) || !"on".equalsIgnoreCase(on)) {
+						System.out.println("Syntax: grant <namespace> <permission> on <path> to <principal>");
+						continue;
+					}
+					if (namespace==null) {
+						namespace=resolveNamespace(permission);
+						if (namespace==null) {
+							System.out.println("Could not resolve namespace for permission " + permission);
+							continue;
+						}
+					}
+					grant(webdavResource, namespace, permission, path, principal);
+
+                } else
+                if (todo.equalsIgnoreCase("acl")) {
+				    String path=null;
+					AclProperty acl=null;
+                    int count = params.size();
+                    if (count>1) {
+                        System.out.print("acl has a maximum of 1 argument");
+                        continue;
+                    }
+					if (count==1) {
+						path=checkUri((String)params.pop());
+					}
+					else {
+						path=webdavResource.getPath();
+					}
+					acl = webdavResource.aclfindMethod(path);
+
+					if (acl==null)
+					{
+					    System.out.print("Error: PropFind didn't return an AclProperty!");
+                        continue;
+					}
+					System.out.println();
+					showAces(path, acl.getAces());
+                } else
+	                if (todo.equalsIgnoreCase("propget") ||
                     todo.equalsIgnoreCase("propfind")) {
                     // FIXME: some work is still needed.
                     int count = params.size();
-                    if (count <= 1)
+                    if (count <= 1) {
+                        System.out.print("Propget/propfind requires at least 2 arguments");
                         continue;
+                    }
 
                     Vector properties = new Vector();
                     for (int i = 0; i < count-1; i++) {
@@ -874,6 +957,8 @@
                             System.err.println("Error: Check! " +
                                 e.getMessage());
                         }
+                    } else {
+                        System.out.print("Propput/proppatch requires 3 arguments");
                     }
                 } else
                 // TODO: more than 2, the mput command is easy to use.
@@ -1121,7 +1206,7 @@
                                 debugLevel = Integer.MAX_VALUE;
                                 webdavResource.setDebug(debugLevel);
                                 System.out.println
-                                    ("The debug flag is on(level=all).");
+                                    ("The debug flag is on (level=all).");
                             } else if (value.equalsIgnoreCase("off") ||
                                        (value.equalsIgnoreCase("0"))) {
                                 webdavResource.setDebug(debugLevel = 0);
@@ -1131,7 +1216,7 @@
                                     debugLevel = Integer.parseInt(value);
                                     webdavResource.setDebug(debugLevel);
                                     System.out.println
-                                        ("The debug flag is on(level=" +
+                                        ("The debug flag is on (level=" +
                                          debugLevel + ").");
                                 } catch (NumberFormatException nfe) {
                                     System.err.println
@@ -1143,7 +1228,7 @@
                             System.err.println("Invalid option.");
                         }
                     } else {
-                        System.err.println("Error: 'set' needs 2 parameters");
+                        System.err.println("Error: 'set' needs at least 2 parameters");
                     }
                 } else {
                     System.err.println("Invalid Command.");
@@ -1366,6 +1451,9 @@
             "Set URL encoding flag, default: on");
         System.out.println("  set debug {on|off|<level>}    " +
             "Set debug level, default: off");
+        System.out.println("  acl [path]                    " +
+            "Displays the ACL of path");
+        System.out.println("  grant [<namespace>] <permission> [on <path>] to <principal>");
         System.out.println
             ("Aliases: help=?, open=connect, ls=dir, pwc=pwd, cc=cd, " +
              "lls=ldir, copy=cp,\n move=mv, delete=del=rm, mkcol=mkdir, " +
@@ -1386,4 +1474,126 @@
         } catch( InterruptedException ex ) {
         }
     }
+
+	private String resolveNamespace(String permission)
+	{
+		String DEFAULT_NAMESPACE = "DAV:";
+		String SLIDE_NAMESPACE = "http://jakarta.apache.org/slide/";
+		String namespace=null;
+
+		if (permission==null)
+			return null;
+		
+		if ((permission.equalsIgnoreCase("all")) ||
+		    (permission.equalsIgnoreCase("read")) ||
+		    (permission.equalsIgnoreCase("write")) ||
+		    (permission.equalsIgnoreCase("read-acl")) ||
+		    (permission.equalsIgnoreCase("write-acl")))
+	    {
+		    namespace=DEFAULT_NAMESPACE;
+		}
+		
+		if ((permission.equalsIgnoreCase("read-object")) ||
+		    (permission.equalsIgnoreCase("read-revision-metadata")) ||
+		    (permission.equalsIgnoreCase("read-revision-content")) ||
+		    (permission.equalsIgnoreCase("create-object")) ||
+		    (permission.equalsIgnoreCase("remove-object")) ||
+		    (permission.equalsIgnoreCase("lock-object")) ||
+		    (permission.equalsIgnoreCase("read-locks")) ||
+		    (permission.equalsIgnoreCase("create-revision-metadata")) ||
+		    (permission.equalsIgnoreCase("modify-revision-metadata")) ||
+		    (permission.equalsIgnoreCase("remove-revision-metadata")) ||
+		    (permission.equalsIgnoreCase("create-revision-content")) ||
+		    (permission.equalsIgnoreCase("modify-revision-content")) ||
+		    (permission.equalsIgnoreCase("remove-revision-content")) ||
+		    (permission.equalsIgnoreCase("grant-permission")) ||
+		    (permission.equalsIgnoreCase("revoke-permission")))
+		{
+			namespace=SLIDE_NAMESPACE;
+		}
+		
+		return namespace;
+	}
+
+	private boolean grant(WebdavResource webdavResource, String namespace, String permission, String path, String principal) throws HttpException, IOException
+	{
+		System.out.println("grant " + namespace + permission + " on " + path + " to " + principal);
+
+		AclProperty acl = webdavResource.aclfindMethod(path);
+		if (acl==null)
+		{
+			System.out.print("Error: PropFind didn't return an AclProperty!");
+			return false;
+		}
+		Ace[] aces=acl.getAces();
+
+		if (debugLevel>5) {
+            System.out.println();
+			System.out.println("ACL from server");
+		    showAces(path, aces);
+		}
+		
+		Ace ace=null;
+		for (int i=0; i<aces.length && (ace==null); i++)
+		{
+			if (!aces[i].isNegative() && !aces[i].isProtected() 
+			    && !aces[i].isInherited() && aces[i].getPrincipal().equals(principal))
+			{
+				System.out.println("found ace");
+				ace=aces[i];
+			}
+		}
+		if (ace==null)
+		{
+			Ace[] oldAces=aces;
+			aces=new Ace[oldAces.length+1];
+			System.arraycopy(oldAces,0,aces,0,oldAces.length);
+			ace=new Ace(principal, false, false, false,null);
+			aces[oldAces.length]=ace;
+		}
+		
+		Privilege privilege=new Privilege(namespace, permission, null);
+		ace.addPrivilege(privilege);
+		
+		if (debugLevel>5) {
+			System.out.println();
+			System.out.println("ACL with updated privileges");
+		    showAces(path, aces);
+		}
+
+		boolean success = webdavResource.aclMethod(path,aces);
+	
+		if (!success)
+            System.err.println(webdavResource.getStatusMessage());	
+
+        if (debugLevel>5) {
+          	System.out.println();
+          	System.out.println("ACL from server after update");
+            showAces(path, aces);
+        }
+			
+		return success;
+	}
+	
+	private void showAces(String path, Ace[] aces)
+	{
+		System.out.println("ACL for " + path + ":");
+		System.out.println("------------------------------------------------------------");
+		for (int i=0; i<aces.length ; i++) 
+		{
+			Ace ace=aces[i];
+			System.out.println((!ace.isNegative()?"granted":"denied") + 
+				" to " + ace.getPrincipal() + " " + 
+				"   (" + (ace.isProtected()?"protected":"not protected") + ")" +
+				"   (" + (ace.isInherited()? ("inherited from '" + ace.getInheritedFrom() + "'"): "not inherited") +")");
+		
+			Enumeration privileges=ace.enumeratePrivileges();
+			while (privileges.hasMoreElements())
+			{
+				Privilege priv=(Privilege)privileges.nextElement();
+				System.out.println("   " + priv.getNamespace() + priv.getName() + "   " + (priv.getParameter()==null?"":("("+priv.getParameter()+")")));
+			}
+		}
+		System.out.println("------------------------------------------------------------");
+	}
 }
