Index: subversion/include/svn_client.h
===================================================================
--- subversion/include/svn_client.h	(revision 15448)
+++ subversion/include/svn_client.h	(working copy)
@@ -1799,7 +1799,7 @@
 
 
 /**
- * Set @a *dirents to a newly allocated hash of entries for @a
+ * Set @a *dirents and *locks to a newly allocated hash of entries for @a
  * path_or_url at @a revision.  The actual node revision selected is
  * determined by the path as it exists in @a peg_revision.  If @a
  * peg_revision is @c svn_opt_revision_unspecified, then it defaults
@@ -1810,18 +1810,36 @@
  * @a path_or_url is a file, return only the dirent for the file.  If @a
  * path_or_url is non-existent, return @c SVN_ERR_FS_NOT_FOUND.
  *
- * The hash maps entry names (<tt>const char *</tt>) to @c svn_dirent_t *'s.  
- * Do all allocation in @a pool.
+ * The dirents hash maps entry names (<tt>const char *</tt>) to
+ * @c svn_dirent_t *'s. Do all allocation in @a pool.
  *
+ * The locks hash maps entry names (<tt>const char *</tt>) to
+ * @c svn_lock_t *'s. Do all allocation in @a pool.
+ *
  * Use authentication baton cached in @a ctx to authenticate against the 
  * repository.
  *
  * If @a recurse is true (and @a path_or_url is a directory) this will
  * be a recursive operation.
  *
- * @since New in 1.2.
+ * @since New in 1.3.
  */
 svn_error_t *
+svn_client_ls3 (apr_hash_t **dirents,
+                apr_hash_t **locks,
+                const char *path_or_url,
+                const svn_opt_revision_t *peg_revision,
+                const svn_opt_revision_t *revision,
+                svn_boolean_t recurse,
+                svn_client_ctx_t *ctx,
+                apr_pool_t *pool);
+
+/**
+ * Similar to svn_client_ls3(),  return only dirent's in the form hash.
+ *
+ * @deprecated Provided for backward compatibility with the 1.2 API.
+ */
+svn_error_t *
 svn_client_ls2 (apr_hash_t **dirents,
                 const char *path_or_url,
                 const svn_opt_revision_t *peg_revision,
Index: subversion/libsvn_client/ls.c
===================================================================
--- subversion/libsvn_client/ls.c	(revision 15448)
+++ subversion/libsvn_client/ls.c	(working copy)
@@ -71,6 +71,79 @@
 }
 
 svn_error_t *
+svn_client_ls3 (apr_hash_t **dirents,
+                apr_hash_t **locks,
+                const char *path_or_url,
+                const svn_opt_revision_t *peg_revision,
+                const svn_opt_revision_t *revision,
+                svn_boolean_t recurse,
+                svn_client_ctx_t *ctx,
+                apr_pool_t *pool)
+{
+  svn_ra_session_t *ra_session;
+  const char *url;
+  const char *repos_root;
+  svn_revnum_t rev;
+  apr_hash_index_t *hi;
+  const char *rel_path;
+  svn_node_kind_t kind;
+  apr_hash_t *new_locks;
+  apr_pool_t *subpool;
+
+  SVN_ERR (svn_client_ls2 (dirents, path_or_url, peg_revision,
+                           revision, recurse, ctx, pool));
+
+  if (locks == NULL)
+    return SVN_NO_ERROR;
+
+  /* Getting repository root. */
+  SVN_ERR (svn_client_url_from_path (&repos_root, "", pool));
+
+  /* Get an RA plugin for this filesystem object. */
+  SVN_ERR (svn_client__ra_session_from_path (&ra_session, &rev,
+                                             &url, path_or_url, peg_revision,
+                                             revision, ctx, pool));
+
+  rel_path = svn_path_is_child (repos_root, url, pool);
+  if (rel_path == NULL)
+    rel_path = "/";
+  else
+    {
+      svn_ra_check_path (ra_session, "", rev, &kind, pool);
+      if (kind == svn_node_file)
+          svn_path_split (rel_path, &rel_path, NULL, pool);
+
+      rel_path = apr_psprintf (pool, "/%s/", rel_path);
+    }
+
+  /* Get lock. */
+  apr_pool_create (&subpool, pool);
+  SVN_ERR (svn_ra_get_locks (ra_session, locks, "",
+                             subpool));
+
+  new_locks = apr_hash_make (pool);
+  for (hi = apr_hash_first (subpool, *locks);
+       hi;
+       hi = apr_hash_next (hi))
+    {
+      const void *key;
+      void *val;
+
+      apr_hash_this (hi, &key, NULL, &val);
+      apr_hash_set (new_locks, svn_path_is_child (
+                                svn_path_canonicalize (rel_path, pool), 
+                                svn_path_canonicalize (key, pool), pool),
+                    APR_HASH_KEY_STRING, val);
+    }
+  apr_pool_destroy (subpool);
+
+  *locks = new_locks;
+
+  return SVN_NO_ERROR;
+}
+
+
+svn_error_t *
 svn_client_ls2 (apr_hash_t **dirents,
                 const char *path_or_url,
                 const svn_opt_revision_t *peg_revision,
Index: subversion/clients/cmdline/ls-cmd.c
===================================================================
--- subversion/clients/cmdline/ls-cmd.c	(revision 15448)
+++ subversion/clients/cmdline/ls-cmd.c	(working copy)
@@ -37,6 +37,7 @@
 
 static svn_error_t *
 print_dirents (apr_hash_t *dirents,
+               apr_hash_t *locks,
                svn_boolean_t verbose,
                svn_client_ctx_t *ctx,
                apr_pool_t *pool)
@@ -51,6 +52,7 @@
     {
       const char *utf8_entryname;
       svn_dirent_t *dirent;
+      svn_lock_t *lock;
       svn_sort__item_t *item;
 
       svn_pool_clear (subpool);
@@ -63,6 +65,7 @@
       utf8_entryname = item->key;
 
       dirent = apr_hash_get (dirents, utf8_entryname, item->klen);
+      lock = apr_hash_get (locks, utf8_entryname, APR_HASH_KEY_STRING);
 
       if (verbose)
         {
@@ -70,8 +73,8 @@
           apr_time_exp_t exp_time;
           apr_status_t apr_err;
           apr_size_t size;
-          char timestr[20];
-          const char *sizestr, *utf8_timestr;
+          char timestr[20], lock_timestr[20];
+          const char *sizestr, *utf8_timestr, *utf8_lock_timestr;
           
           /* svn_time_to_human_cstring gives us something *way* too long
              to use for this, so we have to roll our own.  We include
@@ -98,13 +101,42 @@
 
           sizestr = apr_psprintf (subpool, "%" SVN_FILESIZE_T_FMT,
                                   dirent->size);
+          if (lock)
+            {
+               apr_time_exp_lt (&exp_time, lock->creation_date);
+               if (apr_time_sec
+                    (now - lock->creation_date) < (365 * 86400 / 2)
+                   && apr_time_sec
+                    (lock->creation_date - now) < (365 * 86400 / 2))
+                 {
+                   apr_err = apr_strftime (lock_timestr, &size,
+                                           sizeof (lock_timestr),
+                                           "%b %d %H:%M", &exp_time);
+                 }
+               else
+                 {
+                   apr_err = apr_strftime (lock_timestr, &size,
+                                           sizeof (timestr),
+                                           "%b %d  %Y", &exp_time);
+                 }
 
+               /* if that failed, just zero out the string and print nothing */
+               if (apr_err)
+                 lock_timestr[0] = '\0';
+
+              /* we need it in UTF-8. */
+              SVN_ERR (svn_utf_cstring_to_utf8
+                         (&utf8_lock_timestr, lock_timestr, subpool));
+            }
+
           SVN_ERR (svn_cmdline_printf
-                   (subpool, "%7ld %-8.8s %10s %12s %s%s\n",
+                   (subpool, "%7ld %-12s %10s %12s %-12s %12s %s%s\n",
                     dirent->created_rev,
                     dirent->last_author ? dirent->last_author : " ? ",
                     (dirent->kind == svn_node_file) ? sizestr : "",
                     utf8_timestr,
+                    lock ? lock->owner : "",
+                    lock ? utf8_lock_timestr : "",
                     utf8_entryname,
                     (dirent->kind == svn_node_dir) ? "/" : ""));
         }
@@ -154,6 +186,7 @@
 
 static svn_error_t *
 print_dirents_xml (apr_hash_t *dirents,
+                   apr_hash_t *locks,
                    const char *path,
                    svn_client_ctx_t *ctx,
                    apr_pool_t *pool)
@@ -179,6 +212,7 @@
       const char *utf8_entryname;
       svn_dirent_t *dirent;
       svn_sort__item_t *item;
+      svn_lock_t *lock;
 
       svn_pool_clear (subpool);
 
@@ -190,6 +224,7 @@
       utf8_entryname = item->key;
 
       dirent = apr_hash_get (dirents, utf8_entryname, item->klen);
+      lock = apr_hash_get (locks, utf8_entryname, APR_HASH_KEY_STRING);
 
       sb = svn_stringbuf_create ("", subpool);
 
@@ -238,6 +273,49 @@
       /* "</commit>" */
       svn_xml_make_close_tag (&sb, subpool, "commit");
 
+      /* "<lock>" */
+      if (lock)
+        {
+          svn_xml_make_open_tag (&sb, pool, svn_xml_normal, "lock", NULL);
+
+          svn_xml_make_open_tag (&sb, pool, svn_xml_protect_pcdata,
+                                 "token", NULL);
+          svn_xml_escape_cdata_cstring (&sb, lock->token, pool);
+          svn_xml_make_close_tag (&sb, pool, "token");
+
+          svn_xml_make_open_tag (&sb, pool, svn_xml_protect_pcdata,
+                                 "owner", NULL);
+          svn_xml_escape_cdata_cstring (&sb, lock->owner, pool);
+          svn_xml_make_close_tag (&sb, pool, "owner");
+
+          if (lock->comment)
+            {
+              svn_xml_make_open_tag (&sb, pool, svn_xml_normal,
+                                     "comment", NULL);
+              svn_xml_escape_cdata_cstring (&sb, lock->comment, pool);
+              svn_xml_make_close_tag (&sb, pool, "comment");
+            }
+
+          svn_xml_make_open_tag (&sb, pool, svn_xml_protect_pcdata,
+                                 "created", NULL);
+          svn_xml_escape_cdata_cstring (&sb, svn_time_to_cstring
+                                        (lock->creation_date, pool),
+                                        pool);
+          svn_xml_make_close_tag (&sb, pool, "created");
+
+          if (lock->expiration_date != 0)
+            {
+              svn_xml_make_open_tag (&sb, pool, svn_xml_protect_pcdata,
+                                     "expires", NULL);
+              svn_xml_escape_cdata_cstring (&sb, svn_time_to_cstring
+                                            (lock->expiration_date, pool),
+                                            pool);
+              svn_xml_make_close_tag (&sb, pool, "expires");
+            }
+
+          /* "<lock>" */
+          svn_xml_make_close_tag (&sb, subpool, "lock");
+        }
       /* "</entry>" */
       svn_xml_make_close_tag (&sb, subpool, "entry");
 
@@ -311,6 +389,7 @@
   for (i = 0; i < targets->nelts; i++)
     {
       apr_hash_t *dirents;
+      apr_hash_t *locks;
       const char *target = ((const char **) (targets->elts))[i];
       const char *truepath;
       svn_opt_revision_t peg_revision;
@@ -322,14 +401,15 @@
       /* Get peg revisions. */
       SVN_ERR (svn_opt_parse_path (&peg_revision, &truepath, target,
                                    subpool));
-      SVN_ERR (svn_client_ls2 (&dirents, truepath, &peg_revision,
+
+      SVN_ERR (svn_client_ls3 (&dirents, &locks, truepath, &peg_revision,
                                &(opt_state->start_revision),
                                opt_state->recursive, ctx, subpool));
 
       if (opt_state->xml)
-        SVN_ERR (print_dirents_xml (dirents, truepath, ctx, subpool));
+        SVN_ERR (print_dirents_xml (dirents, locks, truepath, ctx, subpool));
       else
-        SVN_ERR (print_dirents (dirents, opt_state->verbose, ctx, subpool));
+        SVN_ERR (print_dirents (dirents, locks, opt_state->verbose, ctx, subpool));
     }
 
   svn_pool_destroy (subpool);
Index: subversion/clients/cmdline/main.c
===================================================================
--- subversion/clients/cmdline/main.c	(revision 15448)
+++ subversion/clients/cmdline/main.c	(working copy)
@@ -389,12 +389,14 @@
        "current\n"
        "  working directory.\n"
        "\n"
-       "  With --verbose, the following fields show the status of the item:\n"
+       "  With --verbose, the following fields will be shown for each item:\n"
        "\n"
        "    Revision number of the last commit\n"
        "    Author of the last commit\n"
        "    Size (in bytes)\n"
-       "    Date and time of the last commit\n"),
+       "    Date and time of the last commit\n"
+       "    Date and time of the lock creation\n"
+       "    Owner of the lock\n"),
     {'r', 'v', 'R', svn_cl__incremental_opt, svn_cl__xml_opt,
      SVN_CL__AUTH_OPTIONS, svn_cl__config_dir_opt} },
   
Index: subversion/clients/cmdline/dtd/list.dtd
===================================================================
--- subversion/clients/cmdline/dtd/list.dtd	(revision 15448)
+++ subversion/clients/cmdline/dtd/list.dtd	(working copy)
@@ -8,9 +8,16 @@
 <!ELEMENT lists (list+)>
 <!ELEMENT list (entry*)>
 <!ATTLIST list path CDATA #REQUIRED>  <!-- local path or URL -->
-<!ELEMENT entry (name, size?, commit)>
+<!ELEMENT entry (name, size?, commit, lock?)>
 <!ATTLIST entry kind (dir | file) #REQUIRED>
 <!ELEMENT name (#PCDATA)>  <!-- name of file or directory -->
 <!ELEMENT size (#PCDATA)>  <!-- file size in bytes: integer -->
 <!ELEMENT commit (author, date)>
 <!ATTLIST commit revision CDATA #REQUIRED>  <!-- revision number: integer -->
+<!-- Lock info stored repos. -->
+<!ELEMENT lock (token, owner, comment?, created, expires?)>
+<!ELEMENT token (#PCDATA)>    <!-- lock token URI -->
+<!ELEMENT owner (#PCDATA)>    <!-- lock owner -->
+<!ELEMENT comment (#PCDATA)>  <!-- lock comment -->
+<!ELEMENT created (#PCDATA)>  <!-- creation date in ISO format -->
+<!ELEMENT expires (#PCDATA)>  <!-- expiration date in ISO format -->


