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 */
19 #include <wsutil/file_util.h>
21 WSLUA_CLASS_DEFINE(Dir
,FAIL_ON_NULL("Dir")); /* A Directory object, as well as associated functions. */
23 WSLUA_CONSTRUCTOR
Dir_make(lua_State
* L
) {
24 /* Creates a directory.
26 The created directory is set for permission mode 0755 (octal), meaning it is
27 read+write+execute by owner, but only read+execute by group members and others.
29 If the directory was created successfully, a boolean `true` is returned.
30 If the directory cannot be made because it already exists, `false` is returned.
31 If the directory cannot be made because an error occurred, `nil` is returned.
33 #define WSLUA_ARG_Dir_make_NAME 1 /* The name of the directory, possibly including path. */
35 const char *dir_path
= luaL_checkstring(L
, WSLUA_ARG_Dir_make_NAME
);
39 if (ws_stat64(dir_path
, &s_buf
) != 0 && errno
== ENOENT
) {
40 ret
= ws_mkdir(dir_path
, 0755);
44 lua_pushboolean(L
, 1);
47 lua_pushboolean(L
, 0);
50 WSLUA_RETURN(1); /* Boolean `true` on success, `false` if the directory already exists, `nil` on error. */
53 WSLUA_CONSTRUCTOR
Dir_exists(lua_State
* L
) {
54 /* Returns true if the given directory name exists.
56 If the directory exists, a boolean `true` is returned.
57 If the path is a file instead, `false` is returned.
58 If the path does not exist or an error occurred, `nil` is returned.
60 #define WSLUA_ARG_Dir_exists_NAME 1 /* The name of the directory, possibly including path. */
62 const char *dir_path
= luaL_checkstring(L
, WSLUA_ARG_Dir_exists_NAME
);
65 if ((ret
= test_for_directory (dir_path
)) == EISDIR
) {
66 lua_pushboolean(L
, 1);
69 lua_pushboolean(L
, 0);
75 WSLUA_RETURN(1); /* Boolean `true` if the directory exists, `false` if it's a file, `nil` on error or not-exist. */
78 WSLUA_CONSTRUCTOR
Dir_remove(lua_State
* L
) {
79 /* Removes an empty directory.
81 If the directory was removed successfully, a boolean `true` is returned.
82 If the directory cannot be removed because it does not exist, `false` is returned.
83 If the directory cannot be removed because an error occurred, `nil` is returned.
85 This function only removes empty directories. To remove a directory regardless,
86 use `Dir.remove_all()`.
88 #define WSLUA_ARG_Dir_remove_NAME 1 /* The name of the directory, possibly including path. */
90 const char *dir_path
= luaL_checkstring(L
, WSLUA_ARG_Dir_remove_NAME
);
93 if (test_for_directory (dir_path
) == EISDIR
) {
94 ret
= ws_remove(dir_path
);
98 lua_pushboolean(L
, 1);
101 lua_pushboolean(L
, 0);
104 WSLUA_RETURN(1); /* Boolean `true` on success, `false` if does not exist, `nil` on error. */
107 static int delete_directory(const char *directory
) {
113 /* delete all contents of directory */
114 if ((dir
= ws_dir_open(directory
, 0, NULL
)) != NULL
) {
115 while ((file
= ws_dir_read_name(dir
)) != NULL
) {
116 filename
= g_build_filename(directory
, ws_dir_get_name(file
), NULL
);
117 if (test_for_directory(filename
) != EISDIR
) {
118 ret
= ws_remove(filename
);
121 ret
= delete_directory (filename
);
132 ret
= ws_remove(directory
);
139 WSLUA_CONSTRUCTOR
Dir_remove_all(lua_State
* L
) {
140 /* Removes an empty or non-empty directory.
142 If the directory was removed successfully, a boolean `true` is returned.
143 If the directory cannot be removed because it does not exist, `false` is returned.
144 If the directory cannot be removed because an error occurred, `nil` is returned.
146 #define WSLUA_ARG_Dir_remove_all_NAME 1 /* The name of the directory, possibly including path. */
148 const char *dir_path
= luaL_checkstring(L
, WSLUA_ARG_Dir_remove_all_NAME
);
151 if (test_for_directory (dir_path
) == EISDIR
) {
152 ret
= delete_directory(dir_path
);
156 lua_pushboolean(L
, 1);
159 lua_pushboolean(L
, 0);
162 WSLUA_RETURN(1); /* Boolean `true` on success, `false` if does not exist, `nil` on error. */
165 WSLUA_CONSTRUCTOR
Dir_open(lua_State
* L
) {
166 /* Opens a directory and returns a <<lua_class_Dir,`Dir`>> object representing the files in the directory.
172 -- Print the contents of a directory
173 for filename in Dir.open('/path/to/dir') do
178 #define WSLUA_ARG_Dir_open_PATHNAME 1 /* The pathname of the directory. */
179 #define WSLUA_OPTARG_Dir_open_EXTENSION 2 /* If given, only files with this extension will be returned. */
181 const char* dirname
= luaL_checkstring(L
,WSLUA_ARG_Dir_open_PATHNAME
);
182 const char* extension
= luaL_optstring(L
,WSLUA_OPTARG_Dir_open_EXTENSION
,NULL
);
186 dirname_clean
= wslua_get_actual_filename(dirname
);
187 if (!dirname_clean
) {
188 WSLUA_ARG_ERROR(Dir_open
,PATHNAME
,"directory does not exist");
192 if (!test_for_directory(dirname_clean
)) {
193 g_free(dirname_clean
);
194 WSLUA_ARG_ERROR(Dir_open
,PATHNAME
, "must be a directory");
198 dir
= (Dir
)g_malloc(sizeof(struct _wslua_dir
));
199 dir
->dir
= g_dir_open(dirname_clean
, 0, NULL
);
200 g_free(dirname_clean
);
202 if (dir
->dir
== NULL
) {
205 WSLUA_ARG_ERROR(Dir_open
,PATHNAME
,"could not open directory");
209 dir
->ext
= g_strdup(extension
);
212 WSLUA_RETURN(1); /* The <<lua_class_Dir,`Dir`>> object. */
215 WSLUA_METAMETHOD
Dir__call(lua_State
* L
) {
217 Gets the next file or subdirectory within the directory, or `nil` when done.
223 -- Open a directory and print the name of the first file or subdirectory
224 local dir = Dir.open('/path/to/dir')
226 print(tostring(file))
230 Dir dir
= checkDir(L
,1);
232 const char* filename
;
239 if ( ! ( file
= g_dir_read_name(dir
->dir
) )) {
240 g_dir_close(dir
->dir
);
247 lua_pushstring(L
,file
);
254 /* XXX strstr returns ptr to first match,
255 this fails ext=".xxx" filename="aaa.xxxz.xxx" */
256 if ( ( ext
= strstr(filename
,dir
->ext
)) && g_str_equal(ext
,dir
->ext
) ) {
257 lua_pushstring(L
,filename
);
260 } while(( file
= g_dir_read_name(dir
->dir
) ));
262 g_dir_close(dir
->dir
);
267 WSLUA_METHOD
Dir_close(lua_State
* L
) {
268 /* Closes the directory. Called automatically during garbage collection of a <<lua_class_Dir,`Dir`>> object. */
269 Dir dir
= checkDir(L
,1);
272 g_dir_close(dir
->dir
);
279 WSLUA_CONSTRUCTOR
Dir_personal_config_path(lua_State
* L
) {
280 /* Gets the https://www.wireshark.org/docs/wsug_html_chunked/ChAppFilesConfigurationSection.html[personal configuration] directory path, with filename if supplied. */
281 #define WSLUA_OPTARG_Dir_personal_config_path_FILENAME 1 /* A filename. */
282 const char *fname
= luaL_optstring(L
, WSLUA_OPTARG_Dir_personal_config_path_FILENAME
,"");
283 char* filename
= get_persconffile_path(fname
,false);
285 lua_pushstring(L
,filename
);
287 WSLUA_RETURN(1); /* The full pathname for a file in the personal configuration directory. */
290 WSLUA_CONSTRUCTOR
Dir_global_config_path(lua_State
* L
) {
291 /* Gets the https://www.wireshark.org/docs/wsug_html_chunked/ChAppFilesConfigurationSection.html[global configuration] directory path, with filename if supplied. */
292 #define WSLUA_OPTARG_Dir_global_config_path_FILENAME 1 /* A filename */
293 const char *fname
= luaL_optstring(L
, WSLUA_OPTARG_Dir_global_config_path_FILENAME
,"");
296 filename
= get_datafile_path(fname
);
297 lua_pushstring(L
,filename
);
299 WSLUA_RETURN(1); /* The full pathname for a file in Wireshark's configuration directory. */
302 WSLUA_CONSTRUCTOR
Dir_personal_plugins_path(lua_State
* L
) {
303 /* Gets the personal plugins directory path. */
304 lua_pushstring(L
, get_plugins_pers_dir());
305 WSLUA_RETURN(1); /* The pathname of the https://www.wireshark.org/docs/wsug_html_chunked/ChPluginFolders.html[personal plugins] directory. */
308 WSLUA_CONSTRUCTOR
Dir_global_plugins_path(lua_State
* L
) {
309 /* Gets the global plugins directory path. */
310 lua_pushstring(L
, get_plugins_dir());
311 WSLUA_RETURN(1); /* The pathname of the https://www.wireshark.org/docs/wsug_html_chunked/ChPluginFolders.html[global plugins] directory. */
314 /* Gets registered as metamethod automatically by WSLUA_REGISTER_CLASS/META */
315 static int Dir__gc(lua_State
* L
) {
316 Dir dir
= toDir(L
,1);
321 g_dir_close(dir
->dir
);
330 WSLUA_METHODS Dir_methods
[] = {
331 WSLUA_CLASS_FNREG(Dir
,make
),
332 WSLUA_CLASS_FNREG(Dir
,exists
),
333 WSLUA_CLASS_FNREG(Dir
,remove
),
334 WSLUA_CLASS_FNREG(Dir
,remove_all
),
335 WSLUA_CLASS_FNREG(Dir
,open
),
336 WSLUA_CLASS_FNREG(Dir
,close
),
337 WSLUA_CLASS_FNREG(Dir
,personal_config_path
),
338 WSLUA_CLASS_FNREG(Dir
,global_config_path
),
339 WSLUA_CLASS_FNREG(Dir
,personal_plugins_path
),
340 WSLUA_CLASS_FNREG(Dir
,global_plugins_path
),
344 WSLUA_META Dir_meta
[] = {
345 WSLUA_CLASS_MTREG(Dir
,call
),
349 int Dir_register(lua_State
* L
) {
350 WSLUA_REGISTER_CLASS(Dir
);
355 * Editor modelines - https://www.wireshark.org/tools/modelines.html
360 * indent-tabs-mode: nil
363 * vi: set shiftwidth=4 tabstop=8 expandtab:
364 * :indentSize=4:tabSize=8:noTabs=true: