--- octave-3.8.2-orig/libinterp/corefcn/dirfns.cc	2014-08-06 21:54:14.000000000 +0400
+++ octave-3.8.2/libinterp/corefcn/dirfns.cc	2014-10-02 18:07:29.256491360 +0400
@@ -800,3 +800,196 @@
 {
   return SET_INTERNAL_VARIABLE (confirm_recursive_rmdir);
 }
+
+
+DEFUN (dir2, args, nargout,
+"-*- texinfo -*-\n\
+@deftypefn  {Function File} {} dir2\n\
+@deftypefnx {Function File} {} dir2 (@var{directory})\n\
+@deftypefnx {Function File} {[@var{list}] =} dir2 (@var{directory})\n\
+Display file listing for directory @var{directory}.\n\
+\n\
+If @var{directory} is not specified then list the present working directory.\n\
+\n\
+If a return value is requested, return a structure array with the fields\n\
+\n\
+@table @asis\n\
+@item name\n\
+File or directory name.\n\
+\n\
+@item date\n\
+Timestamp of file modification (string value).\n\
+\n\
+@item bytes\n\
+File size in bytes.\n\
+\n\
+@item isdir\n\
+True if name is a directory.\n\
+\n\
+@item datenum\n\
+Timestamp of file modification as serial date number (double).\n\
+\n\
+@item statinfo\n\
+Information structure returned from @code{stat}.\n\
+@end table\n\
+\n\
+If @var{directory} is a filename, rather than a directory, then return\n\
+information about the named file.  @var{directory} may also be a list rather\n\
+than a single directory or file.\n\
+\n\
+@var{directory} is subject to shell expansion if it contains any wildcard\n\
+characters @samp{*}, @samp{?}, @samp{[]}.  If you want to find a\n\
+literal example of a wildcard character you must escape it using the\n\
+backslash operator @samp{\}.\n\
+\n\
+Note that for symbolic links, @code{dir} returns information about\n\
+the file that the symbolic link points to rather than the link itself.\n\
+However, if the link points to a nonexistent file, @code{dir} returns\n\
+information about the link.\n\
+@seealso{ls, readdir, glob, what, stat}\n\
+@end deftypefn")
+/*
+       "-*- texinfo -*-\n\
+@deftypefn  {Built-in Function} {@var{files} =} dir2 (@var{dir})\n\
+@deftypefnx {Built-in Function} {[@var{files}, @var{err}, @var{msg}] =} dir2 (@var{dir})\n\
+Return the names of files in the directory @var{dir} as a cell array of\n\
+strings.\n\
+\n\
+If an error occurs, return an empty cell array in @var{files}.\n\
+If successful, @var{err} is 0 and @var{msg} is an empty string.\n\
+Otherwise, @var{err} is nonzero and @var{msg} contains a\n\
+system-dependent error message.\n\
+@seealso{ls, dir, glob, what}\n\
+@end deftypefn") */
+{
+  octave_value_list retval;
+  octave_value_list Fstat(const octave_value_list &args, int);
+  
+  const char* date_fmt = "%d-%b-%Y %T";
+
+  string_vector header (6);
+  header(0) = "name";
+  header(1) = "date";
+  header(2) = "bytes";
+  header(3) = "isdir";
+  header(4) = "datenum";
+  header(5) = "statinfo";
+
+  retval(2) = std::string ();
+  retval(1) = -1.0;
+  retval(0) = octave_map(dim_vector(0,1), header);
+  
+  string_vector dir_list;
+  octave_idx_type dir_len;
+  file_stat stat;
+
+  if (args.length() <= 1)
+    {
+      std::string dirname = (args.length() == 0) ? "." : args(0).string_value();
+
+      // dir2('*') == dir2('.')
+      if (strcmp(dirname.c_str(), "*") == 0) {
+        dirname = ".";
+      }
+
+      // Get dir length
+      if (strcmp(dirname.c_str(), ".") == 0) {
+        dir_len = 1;
+      } else {
+        glob_match pattern (file_ops::tilde_expand (dirname));
+        dir_list = pattern.glob();
+        dir_len = dir_list.length();
+      }
+      
+      // If glob returned only 1 result - check if it's a dir
+      if (dir_len == 1) {
+        stat.get_stats(dirname);
+        // If it is - get its file list
+        if (stat.is_dir()) {
+          dir_list = dir_entry(dirname).read().sort();
+          dir_len = dir_list.length();
+        }
+      }
+      
+      // Create a dim vector and a map based on it
+      dim_vector map_dim = dim_vector(dir_len, 1);
+      octave_map map = octave_map(map_dim, header);
+      // Assign cell ref to each field
+      Cell& m_name = map.contents(header.elem(0));
+      Cell& m_date = map.contents(header.elem(1));
+      Cell& m_bytes = map.contents(header.elem(2));
+      Cell& m_isdir = map.contents(header.elem(3));
+      Cell& m_datenum = map.contents(header.elem(4));
+      Cell& m_statinfo = map.contents(header.elem(5));
+      // File stat and time vars
+      octave_localtime lt;
+
+      // Time variables
+      double y, m, d;
+      
+      // Populate value lists
+      for (int i = 0; i < dir_len; i++) {
+        // Get file info
+        stat.get_stats(dirname + "/" + dir_list.elem(i));
+        lt = octave_localtime(stat.mtime().double_value());
+        // Populate each list
+        m_name(i) = dir_list.elem(i);
+        m_date(i) = lt.strftime(date_fmt);
+        m_bytes(i) = stat.size();
+        m_isdir(i) = stat.is_dir() ? 1 : 0;
+        // Next is the Rata Die algorithm 
+        // (http://mysite.verizon.net/aesir_research/date/rata.htm)
+        // But here i should add 366 days, 
+        // because it counts from 01-01-0001, while MatLAB uses 00-00-0000 (srsly, that's not even a day O_o)
+        if (lt.mon() < 3) {
+          y = lt.year() + 1899;
+          m = lt.mon() + 12;
+        } else {
+          y = lt.year() + 1900;
+          m = lt.mon();
+        }
+        d = lt.mday();
+        // And the main formula
+        m_datenum(i) = gnulib::round(
+          365*y + y/4 - y/100 + y/400 + // Year
+          (153*m - 457)/5 + // Month
+          d - 306 + 366); // Day
+        
+        // For statinfo i'm using the Fstat function result's (0) member, just like for the internal stat.
+        m_statinfo(i) = Fstat(octave_value (dirname + "/" + dir_list.elem(i)), 0) (0);
+      }
+
+      // Return the map
+      retval(1) = 0.0;
+      retval(0) = map;
+        // Check if we need to return smth or just to show the dir_names
+      if (nargout < 1)
+      {
+        // Check if our result is empty
+        if (map.is_empty()) 
+        {
+          #ifndef PATH_MAX
+            char buff[4096];
+          #else
+            char buff[PATH_MAX];
+          #endif
+          sprintf(buff, "\ndir2: non-existent directory %s\n", dirname.c_str());
+          retval(0) = buff;
+        } 
+        else 
+        {
+          // Create a nice-looking list
+          std::ostringstream buf;
+          buf.put('\n');
+          string_vector s = string_vector(map.contents(0).cellstr_value());
+          s.list_in_columns(buf);
+          
+          retval(0) = buf.str();
+        }
+      }
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
