Register forum user name Search FAQ

Gammon Forum

Notice: Any messages purporting to come from this site telling you that your password has expired, or that you need to verify your details, confirm your email, resolve issues, making threats, or asking for money, are spam. We do not email users with any such messages. If you have lost your password you can obtain a new one by using the password reset link.
 Entire forum ➜ MUSHclient ➜ Lua ➜ Scanning directories

Scanning directories

It is now over 60 days since the last post. This thread is closed.     Refresh page


Posted by Nick Gammon   Australia  (23,120 posts)  Bio   Forum Administrator
Date Sun 13 Nov 2005 01:11 AM (UTC)

Amended on Mon 14 Nov 2005 07:45 PM (UTC) by Nick Gammon

Message
Version 3.69 of MUSHclient adds a new function to the "utils" table, which reads an entire directory on your PC into a Lua table, based on the wildcard you supply.

For example:



t, e = utils.readdir ("c:/mushclient/plugins/*.xml")

assert (t, e) -- raises error on failure

for k, v in pairs (t) do
  Tell (k)
  if (v.directory) then
    Tell (" (dir) ")
  end -- if directory
  Tell (" size ", v.size, " bytes, ")
  Note (os.date ("%c", v.write_time))
end -- for



Example output:



ShowActivity.xml size 1429 bytes, 03/23/04 11:06:54
Slow_speedwalk.xml size 9655 bytes, 10/24/05 08:58:07
Automap.xml size 19944 bytes, 03/26/04 14:20:11


If the directory specification is matched, the result from the call is a table of directory items, keyed by the filename. If the directory specification cannot be matched, or is invalid, it returns nil followed by an error message. You can simply test for non-nil, or call "assert" to report the error.

For each file in the directory (that matches the wildcard) the following is returned:



  • size - file size in bytes

  • create_time - creation time (except for FAT filesystems, where it is omitted)

  • access_time - last access time (except for FAT filesystems, where it is omitted)

  • write_time - time written

  • archive - true if archive. Set whenever the file is changed, and cleared by the BACKUP command.

  • hidden - hidden file. Not normally seen with the DIR command

  • normal - normal file. File can be read or written to without restriction.

  • readonly - read-only. File cannot be opened for
    writing, and a file with the same name cannot be created.

  • directory - Subdirectory.

  • system - system file. Not normally seen with the DIR command.


By detecting suddirectories you could conceivably recurse and find the contents of subdirectories as well.


- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Nick Gammon   Australia  (23,120 posts)  Bio   Forum Administrator
Date Reply #1 on Mon 14 Nov 2005 07:24 PM (UTC)

Amended on Mon 14 Nov 2005 07:44 PM (UTC) by Nick Gammon

Message
In case anyone wants to incorporate the code I used into their own projects, here it is ...


#include "../lua/lua.h"
#include "../lua/lauxlib.h"
#include <io.h>
#include <errno.h>

// make number table item
static void MakeNumberTableItem (lua_State *L, const char * name, const double n)
  {
  lua_pushstring (L, name);
  lua_pushnumber (L, n);
  lua_rawset(L, -3);
  }

// make boolean table item
static void MakeBoolTableItem (lua_State *L, const char * name, const int b)
  {
  if (b)
    {
    lua_pushstring (L, name);
    lua_pushboolean (L, b != 0);
    lua_rawset(L, -3);
    }
  }

static int getdirectory (lua_State *L)
  {
  // get directory name (eg. C:\mushclient\*.doc)
  size_t dirLength;
  const char * dirname = luaL_checklstring (L, 1, &dirLength);

  struct _finddatai64_t fdata;

  int h = _findfirsti64 (dirname, &fdata); // get handle

  if (h == -1L)    // no good?
    {
    lua_pushnil (L);

    switch (errno)
      {
      case EINVAL: lua_pushstring (L, "Invalid filename specification"); break;
      default:     lua_pushstring (L, "File specification could not be matched"); break;
      }
    return 2;   // return nil, error message
    }

  lua_newtable(L);    // table of entries
  
  do
    {

    lua_pushstring (L, fdata.name); // file name (will be key)
    lua_newtable(L);                // table of attributes

    // inside this new table put the file attributes

    MakeNumberTableItem (L, "size", (double) fdata.size);
    if (fdata.time_create != -1)    // except FAT
     MakeNumberTableItem (L, "create_time", fdata.time_create);
    if (fdata.time_access != -1)    // except FAT
      MakeNumberTableItem (L, "access_time", fdata.time_access);
    MakeNumberTableItem (L, "write_time",  fdata.time_write);
    MakeBoolTableItem   (L, "archive", fdata.attrib & _A_ARCH);
    MakeBoolTableItem   (L, "hidden", fdata.attrib & _A_HIDDEN);
    MakeBoolTableItem   (L, "normal", fdata.attrib & _A_NORMAL);
    MakeBoolTableItem   (L, "readonly", fdata.attrib & _A_RDONLY);
    MakeBoolTableItem   (L, "directory", fdata.attrib & _A_SUBDIR);
    MakeBoolTableItem   (L, "system", fdata.attrib & _A_SYSTEM);

    lua_rawset(L, -3);              // set key of table item (ie. file name)

    } while (_findnexti64 ( h, &fdata ) == 0);

  _findclose  (h);

  return 1;  // one table of entries
  } // end of getdirectory

// table of operations
static const struct luaL_reg utilslib [] = 
  {

  {"readdir", getdirectory},
 
  {NULL, NULL}
  };

// register library

LUALIB_API int luaopen_compress(lua_State *L)
  {
  luaL_openlib(L, "utils", utilslib, 0);
  return 1;
  }



- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).

To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.


7,191 views.

It is now over 60 days since the last post. This thread is closed.     Refresh page

Go to topic:           Search the forum


[Go to top] top

Information and images on this site are licensed under the Creative Commons Attribution 3.0 Australia License unless stated otherwise.