4 * (c) 2014, Hadriel Kaplan <hadrielk at yahoo dot com>
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * SPDX-License-Identifier: GPL-2.0-or-later
15 /* WSLUA_MODULE Dir Directory handling functions */
18 #include <wsutil/file_util.h>
20 WSLUA_CLASS_DEFINE(Dir,FAIL_ON_NULL("Dir")); /* A Directory object, as well as associated functions. */
22 WSLUA_CONSTRUCTOR Dir_make(lua_State* L) {
23 /* Creates a directory.
25 The created directory is set for permission mode 0755 (octal), meaning it is
26 read+write+execute by owner, but only read+execute by group and others.
28 IF the directory was created successfully, a boolean `true` is returned.
29 If the directory cannot be made because it already exists, `false` is returned.
30 If the directory cannot be made because an error occurred, `nil` is returned.
34 #define WSLUA_ARG_Dir_make_NAME 1 /* The name of the directory, possibly including path. */
36 const char *dir_path = luaL_checkstring(L, WSLUA_ARG_Dir_make_NAME);
40 if (ws_stat64(dir_path, &s_buf) != 0 && errno == ENOENT) {
41 ret = ws_mkdir(dir_path, 0755);
45 lua_pushboolean(L, 1);
48 lua_pushboolean(L, 0);
51 WSLUA_RETURN(1); /* Boolean `true` on success, `false` if already exists, `nil` on error. */
54 WSLUA_CONSTRUCTOR Dir_exists(lua_State* L) {
55 /* Returns true if the given directory name exists.
57 If the directory exists, a boolean `true` is returned.
58 If the path is a file instead, `false` is returned.
59 If the path does not exist or an error occurred, `nil` is returned.
63 #define WSLUA_ARG_Dir_exists_NAME 1 /* The name of the directory, possibly including path. */
65 const char *dir_path = luaL_checkstring(L, WSLUA_ARG_Dir_exists_NAME);
68 if ((ret = test_for_directory (dir_path)) == EISDIR) {
69 lua_pushboolean(L, 1);
72 lua_pushboolean(L, 0);
78 WSLUA_RETURN(1); /* Boolean `true` if the directory exists, `false` if it's a file, `nil` on error/not-exist. */
81 WSLUA_CONSTRUCTOR Dir_remove(lua_State* L) {
82 /* Removes an empty directory.
84 If the directory was removed successfully, a boolean `true` is returned.
85 If the directory cannot be removed because it does not exist, `false` is returned.
86 If the directory cannot be removed because an error occurred, `nil` is returned.
88 This function only removes empty directories. To remove a directory regardless,
89 use `Dir.remove_all()`.
93 #define WSLUA_ARG_Dir_remove_NAME 1 /* The name of the directory, possibly including path. */
95 const char *dir_path = luaL_checkstring(L, WSLUA_ARG_Dir_remove_NAME);
98 if (test_for_directory (dir_path) == EISDIR) {
99 ret = ws_remove(dir_path);
103 lua_pushboolean(L, 1);
106 lua_pushboolean(L, 0);
109 WSLUA_RETURN(1); /* Boolean `true` on success, `false` if does not exist, `nil` on error. */
112 static int delete_directory(const char *directory) {
118 /* delete all contents of directory */
119 if ((dir = ws_dir_open(directory, 0, NULL)) != NULL) {
120 while ((file = ws_dir_read_name(dir)) != NULL) {
121 filename = g_build_filename(directory, ws_dir_get_name(file), NULL);
122 if (test_for_directory(filename) != EISDIR) {
123 ret = ws_remove(filename);
126 ret = delete_directory (filename);
137 ret = ws_remove(directory);
144 WSLUA_CONSTRUCTOR Dir_remove_all(lua_State* L) {
145 /* Removes an empty or non-empty directory.
147 If the directory was removed successfully, a boolean `true` is returned.
148 If the directory cannot be removed because it does not exist, `false` is returned.
149 If the directory cannot be removed because an error occurred, `nil` is returned.
153 #define WSLUA_ARG_Dir_remove_all_NAME 1 /* The name of the directory, possibly including path. */
155 const char *dir_path = luaL_checkstring(L, WSLUA_ARG_Dir_remove_all_NAME);
158 if (test_for_directory (dir_path) == EISDIR) {
159 ret = delete_directory(dir_path);
163 lua_pushboolean(L, 1);
166 lua_pushboolean(L, 0);
169 WSLUA_RETURN(1); /* Boolean `true` on success, `false` if does not exist, `nil` on error. */
172 WSLUA_CONSTRUCTOR Dir_open(lua_State* L) {
173 /* Opens a directory and returns a `Dir` object representing the files in the directory.
177 for filename in Dir.open(path) do ... end
180 #define WSLUA_ARG_Dir_open_PATHNAME 1 /* The pathname of the directory. */
181 #define WSLUA_OPTARG_Dir_open_EXTENSION 2 /* If given, only files with this extension will be returned. */
183 const char* dirname = luaL_checkstring(L,WSLUA_ARG_Dir_open_PATHNAME);
184 const char* extension = luaL_optstring(L,WSLUA_OPTARG_Dir_open_EXTENSION,NULL);
188 dirname_clean = wslua_get_actual_filename(dirname);
189 if (!dirname_clean) {
190 WSLUA_ARG_ERROR(Dir_open,PATHNAME,"directory does not exist");
194 if (!test_for_directory(dirname_clean)) {
195 g_free(dirname_clean);
196 WSLUA_ARG_ERROR(Dir_open,PATHNAME, "must be a directory");
200 dir = (Dir)g_malloc(sizeof(struct _wslua_dir));
201 dir->dir = g_dir_open(dirname_clean, 0, NULL);
202 g_free(dirname_clean);
204 if (dir->dir == NULL) {
207 WSLUA_ARG_ERROR(Dir_open,PATHNAME,"could not open directory");
211 dir->ext = g_strdup(extension);
214 WSLUA_RETURN(1); /* the `Dir` object. */
217 WSLUA_METAMETHOD Dir__call(lua_State* L) {
218 /* At every invocation will return one file (nil when done). */
220 Dir dir = checkDir(L,1);
222 const gchar* filename;
229 if ( ! ( file = g_dir_read_name(dir->dir ) )) {
230 g_dir_close(dir->dir);
237 lua_pushstring(L,file);
244 /* XXX strstr returns ptr to first match,
245 this fails ext=".xxx" filename="aaa.xxxz.xxx" */
246 if ( ( ext = strstr(filename,dir->ext)) && g_str_equal(ext,dir->ext) ) {
247 lua_pushstring(L,filename);
250 } while(( file = g_dir_read_name(dir->dir) ));
252 g_dir_close(dir->dir);
257 WSLUA_METHOD Dir_close(lua_State* L) {
258 /* Closes the directory. */
259 Dir dir = checkDir(L,1);
262 g_dir_close(dir->dir);
269 WSLUA_CONSTRUCTOR Dir_personal_config_path(lua_State* L) {
270 /* Gets the personal configuration directory path, with filename if supplied.
274 #define WSLUA_OPTARG_personal_config_path_FILENAME 1 /* A filename. */
275 const char *fname = luaL_optstring(L, WSLUA_OPTARG_personal_config_path_FILENAME,"");
276 char* filename = get_persconffile_path(fname,FALSE);
278 lua_pushstring(L,filename);
280 WSLUA_RETURN(1); /* The full pathname for a file in the personal configuration directory. */
283 WSLUA_CONSTRUCTOR Dir_global_config_path(lua_State* L) {
284 /* Gets the global configuration directory path, with filename if supplied.
288 #define WSLUA_OPTARG_global_config_path_FILENAME 1 /* A filename */
289 const char *fname = luaL_optstring(L, WSLUA_OPTARG_global_config_path_FILENAME,"");
292 filename = get_datafile_path(fname);
293 lua_pushstring(L,filename);
295 WSLUA_RETURN(1); /* The full pathname for a file in wireshark's configuration directory. */
298 WSLUA_CONSTRUCTOR Dir_personal_plugins_path(lua_State* L) {
299 /* Gets the personal plugins directory path.
303 lua_pushstring(L, get_plugins_pers_dir());
304 WSLUA_RETURN(1); /* The pathname for the personal plugins directory. */
307 WSLUA_CONSTRUCTOR Dir_global_plugins_path(lua_State* L) {
308 /* Gets the global plugins directory path.
312 lua_pushstring(L, get_plugins_dir());
313 WSLUA_RETURN(1); /* The pathname for the global plugins directory. */
316 /* Gets registered as metamethod automatically by WSLUA_REGISTER_CLASS/META */
317 static int Dir__gc(lua_State* L) {
318 Dir dir = toDir(L,1);
323 g_dir_close(dir->dir);
332 WSLUA_METHODS Dir_methods[] = {
333 WSLUA_CLASS_FNREG(Dir,make),
334 WSLUA_CLASS_FNREG(Dir,exists),
335 WSLUA_CLASS_FNREG(Dir,remove),
336 WSLUA_CLASS_FNREG(Dir,remove_all),
337 WSLUA_CLASS_FNREG(Dir,open),
338 WSLUA_CLASS_FNREG(Dir,close),
339 WSLUA_CLASS_FNREG(Dir,personal_config_path),
340 WSLUA_CLASS_FNREG(Dir,global_config_path),
341 WSLUA_CLASS_FNREG(Dir,personal_plugins_path),
342 WSLUA_CLASS_FNREG(Dir,global_plugins_path),
346 WSLUA_META Dir_meta[] = {
347 WSLUA_CLASS_MTREG(Dir,call),
351 int Dir_register(lua_State* L) {
352 WSLUA_REGISTER_CLASS(Dir);
357 * Editor modelines - https://www.wireshark.org/tools/modelines.html
362 * indent-tabs-mode: nil
365 * vi: set shiftwidth=4 tabstop=8 expandtab:
366 * :indentSize=4:tabSize=8:noTabs=true: