Index: src/apps/admin/pvfs2-ls.c
===================================================================
--- src/apps/admin/pvfs2-ls.c	(revision 12643)
+++ src/apps/admin/pvfs2-ls.c	(working copy)
@@ -32,6 +32,12 @@
 #define MAX_NUM_DIRENTS    113
 
 /*
+  Define the maximum length of a single line of output. This is about the 
+  size of 256 maximum path segments, a file name, and attributes.
+ */
+#define ENTRY_MAX          66560
+
+/*
   arbitrarily restrict the number of paths
   that this ls version can take as arguments
 */
@@ -51,6 +57,7 @@
     int list_all;
     int list_no_owner;
     int list_inode;
+    int list_all_times;
     int list_use_si_units;
     char *start[MAX_NUM_PATHS];
     int num_starts;
@@ -76,19 +83,22 @@
     PVFS_fs_id fs_id,
     PVFS_sys_attr *attr,
     int attr_error,
-    struct options *opts);
+    struct options *opts,
+    char* entry_buffer);
 
 static int do_list(
     char *full_path,
     char *start,
     int fs_id,
-    struct options *opts);
+    struct options *opts,
+    char *entry_buffer);
 
 static void print_entry_attr(
     PVFS_handle handle,
     char *entry_name,
     PVFS_sys_attr *attr,
-    struct options *opts);
+    struct options *opts,
+    char *entry_buffer);
 
 #define print_dot_and_dot_dot_info_if_required(refn)        \
 do {                                                        \
@@ -106,9 +116,11 @@
         }                                                   \
         else if (opts->list_long) {                         \
             print_entry(".", refn.handle,                   \
-                        refn.fs_id, NULL, 0, opts);         \
+                        refn.fs_id, NULL, 0, opts,          \
+                        entry_buffer);                      \
             print_entry(".. (faked)", refn.handle,          \
-                        refn.fs_id, NULL, 0, opts);         \
+                        refn.fs_id, NULL, 0, opts,          \
+                        entry_buffer);                      \
         }                                                   \
         else {                                              \
             printf(".\n");                                  \
@@ -188,19 +200,20 @@
     PVFS_handle handle,
     char *entry_name,
     PVFS_sys_attr *attr,
-    struct options *opts)
+    struct options *opts,
+    char *entry_buffer)
 {
-    char buf[128] = {0}, *formatted_size = NULL;
-    char *formatted_owner = NULL, *formatted_group = NULL;
+    char *formatted_size = NULL;
+    char *formatted_owner = NULL, *formatted_group = NULL, *formatted_time = NULL;
     struct group *grp = NULL;
     struct passwd *pwd = NULL;
     char *empty_str = "";
     char *owner = empty_str, *group = empty_str;
     char *inode = empty_str;
-    time_t mtime;
+    time_t mtime, atime, ctime;
     struct tm *time;    
     PVFS_size size = 0;
-    char scratch_owner[16] = {0}, scratch_group[16] = {0};
+    char scratch_owner[16] = {0}, scratch_group[16] = {0}, scratch_time[27] = {0}, scratch_big_time[78] = {0};
     char scratch_size[16] = {0}, scratch_inode[16] = {0};
     char f_type = '-';
     char group_x_char = '-';
@@ -213,9 +226,37 @@
     {
         return;
     }
+
     mtime = (time_t)attr->mtime;
     time = localtime(&mtime);
+    if(opts->list_all_times)
+    {
+        atime = (time_t)attr->atime;
+        ctime = (time_t)attr->ctime;
 
+        strftime( scratch_time,26,"%F %H:%M:%S %z",time );
+        strncat(scratch_big_time," ",2);
+        strncat(scratch_big_time,scratch_time,26);
+
+        time = localtime(&atime);
+        strftime( scratch_time,26,"%F %H:%M:%S %z",time );
+        strncat(scratch_big_time,"  ",2);
+        strncat(scratch_big_time,scratch_time,26);
+
+        time = localtime(&ctime);
+        strftime( scratch_time,26,"%F %H:%M:%S %z",time );
+        strncat(scratch_big_time,"  ",2);
+        strncat(scratch_big_time,scratch_time,26);
+        strncat(scratch_big_time," ",2);
+
+        format_size_string(scratch_big_time,78,&formatted_time,0,1);
+    }
+    else
+    {
+        strftime( scratch_time,26,"%F %H:%M:%S %z",time );
+        format_size_string(scratch_time,26,&formatted_time,0,1);
+    }
+
     snprintf(scratch_owner,16,"%d",(int)attr->owner);
     snprintf(scratch_group,16,"%d",(int)attr->group);
 
@@ -301,8 +342,8 @@
         group_x_char = ((attr->perms & PVFS_G_EXECUTE) ? 'x' : '-');
     }
 
-    snprintf(buf,128,"%s%c%c%c%c%c%c%c%c%c%c    1 %s %s %s "
-             "%.4d-%.2d-%.2d %.2d:%.2d %s",
+    snprintf(entry_buffer,ENTRY_MAX,"%s%c%c%c%c%c%c%c%c%c%c    1 %s %s %s "
+             "%s %s",
              inode,
              f_type,
              ((attr->perms & PVFS_U_READ) ? 'r' : '-'),
@@ -317,11 +358,7 @@
              formatted_owner,
              formatted_group,
              formatted_size,
-             (time->tm_year + 1900),
-             (time->tm_mon + 1),
-             time->tm_mday,
-             (time->tm_hour),
-             (time->tm_min),
+             formatted_time,
              entry_name);
 
     if (formatted_size)
@@ -336,6 +373,10 @@
     {
         free(formatted_group);
     }
+    if (formatted_time)
+    {
+        free(formatted_time);
+    }
 
     if (attr->objtype == PVFS_TYPE_SYMLINK)
     {
@@ -343,16 +384,16 @@
 
         if (opts->list_long)
         {
-            printf("%s -> %s\n", buf, attr->link_target);
+            printf("%s -> %s\n", entry_buffer, attr->link_target);
         }
         else
         {
-            printf("%s\n",buf);
+            printf("%s\n",entry_buffer);
         }
     }
     else
     {
-        printf("%s\n",buf);
+        printf("%s\n",entry_buffer);
     }
 }
 
@@ -362,7 +403,8 @@
     PVFS_fs_id fs_id,
     PVFS_sys_attr *attr,
     int attr_error,
-    struct options *opts)
+    struct options *opts,
+    char *entry_buffer)
 {
     int ret = -1;
     PVFS_object_ref ref;
@@ -404,11 +446,11 @@
                 PVFS_perror("Getattr failure", ret);
                 return;
             }
-            print_entry_attr(handle, entry_name,  &getattr_response.attr, opts);
+            print_entry_attr(handle, entry_name,  &getattr_response.attr, opts, entry_buffer);
         }
         else
         {
-            print_entry_attr(handle, entry_name, attr, opts);
+            print_entry_attr(handle, entry_name, attr, opts, entry_buffer);
         }
     }
 }
@@ -424,7 +466,8 @@
     char *full_path,
     char *start,
     int fs_id,
-    struct options *opts)
+    struct options *opts,
+    char *entry_buffer)
 {
     int i = 0, printed_dot_info = 0;
     int ret = -1;
@@ -493,14 +536,14 @@
             if (opts->list_long)
             {
                 print_entry_attr(ref.handle, segment,
-                                 &getattr_response.attr, opts);
+                                 &getattr_response.attr, opts, entry_buffer);
             }
             else
             {
                 print_entry(segment, ref.handle, ref.fs_id, 
                         NULL,
                         0,
-                        opts);
+                        opts, entry_buffer);
             }
             return 0;
         }
@@ -557,7 +600,7 @@
             print_entry(cur_file, cur_handle, fs_id,
                     &rdplus_response.attr_array[i],
                     rdplus_response.stat_err_array[i],
-                    opts);
+                    opts, entry_buffer);
 
             PVFS_sys_attr *attr = &rdplus_response.attr_array[i];
             if(attr->objtype == PVFS_TYPE_DIRECTORY && opts->list_recursive)
@@ -638,7 +681,7 @@
         while(current)
         {
             printf("\n");
-            do_list(full_path,current->path,fs_id,opts);
+            do_list(full_path,current->path,fs_id,opts,entry_buffer);
             current = current->next;
             free(head->path);
             free(head);
@@ -674,6 +717,7 @@
         {"all",0,0,0},
         {"inode",0,0,0},
         {"size",0,0,0},
+        {"all-times",0,0,0},
         {0,0,0,0}
     };
 
@@ -743,6 +787,10 @@
                 {
                     goto list_inode;
                 }
+                else if (strcmp("all-times", cur_option) == 0)
+                {
+                    goto list_all_times;
+                }
                 else
                 {
                     usage(argc, argv);
@@ -794,6 +842,9 @@
           list_inode:
                 tmp_opts->list_inode = 1;
                 break;
+          list_all_times:
+                tmp_opts->list_all_times = 1;
+                break;
             case 't':
                 do_timing = 1;
                 break;
@@ -843,6 +894,8 @@
             "format\n");
     fprintf(stderr,"  -n, --numeric-uid-gid      like -l, but list "
             "numeric UIDs and GIDs\n");
+    fprintf(stderr,"      --all-times            display mtime atime "
+            " and ctime information\n");
     fprintf(stderr,"  -o                         like -l, but do not "
             "list group information\n");
     fprintf(stderr,"      --help                 display this help "
@@ -865,9 +918,9 @@
     struct options* user_opts = NULL;
     char current_dir[PVFS_NAME_MAX] = {0};
     int found_one = 0;
+    char *entry_buffer = malloc(ENTRY_MAX);
 
     process_name = argv[0];
-
     user_opts = parse_args(argc, argv);
     if (!user_opts)
     {
@@ -958,7 +1011,7 @@
         }
         else /* Root directory case has nothing to match */
         {
-            substr = &user_opts->start[i][strlen(user_opts->start[i])-1];
+            substr = &user_opts->start[i][strlen(user_opts->start[i])];
         }
 
         while (index != substr)
@@ -968,7 +1021,7 @@
         }
         user_opts->start[i][j] = '\0';
 
-        do_list(user_opts->start[i], pvfs_path[i], fs_id_array[i], user_opts);
+        do_list(user_opts->start[i], pvfs_path[i], fs_id_array[i], user_opts, entry_buffer);
 
         if (user_opts->num_starts > 1)
         {
@@ -978,6 +1031,7 @@
 
     PVFS_sys_finalize();
     free(user_opts);
+    free(entry_buffer);
 
     return(ret);
 }
