HTTPS (almost) everywhere.
[metze/wireshark/wip.git] / epan / wslua / wslua_file_common.c
1 /*
2  * wslua_file_common.c
3  *
4  * Wireshark's interface to the Lua Programming Language
5  * for file handling related source file internal functions.
6  *
7  * (c) 2014, Hadriel Kaplan <hadrielk@yahoo.com>
8  *
9  * Wireshark - Network traffic analyzer
10  * By Gerald Combs <gerald@wireshark.org>
11  * Copyright 1998 Gerald Combs
12  *
13  * SPDX-License-Identifier: GPL-2.0-or-later
14  */
15
16 /************
17  * The following is for handling private data for the duration of the file
18  * read_open/read/close cycle, or write_open/write/write_close cycle.
19  * In other words it handles the "priv" member of wtap and wtap_dumper,
20  * but for the Lua script's use. A Lua script can set a Lua table
21  * to CaptureInfo/CaptureInfoConst and have it saved and retrievable this way.
22  * We need to offer that, because there needs to be a way for Lua scripts
23  * to save state for a given file's operations cycle. Since there can be
24  * two files opened at the same time for the same Lua script (due to reload
25  * and other such events), the script can't just have one file state.
26  */
27
28 #include "wslua_file_common.h"
29
30
31 /* create and set the wtap->priv private data for the file instance */
32 void create_wth_priv(lua_State* L, wtap *wth) {
33     file_priv_t *priv = (file_priv_t*)g_malloc(sizeof(file_priv_t));
34
35     if (wth->priv != NULL) {
36         g_free(priv);
37         luaL_error(L, "Cannot create wtap private data because there already is private data");
38         return;
39     }
40     priv->table_ref = LUA_NOREF;
41     wth->priv = (void*) priv;
42 }
43
44 /* gets the private data table from wtap */
45 int get_wth_priv_table_ref(lua_State* L, wtap *wth) {
46     file_priv_t *priv = (file_priv_t*) wth->priv;
47
48     if (!priv) {
49         /* shouldn't be possible */
50         luaL_error(L, "Cannot get wtap private data: it is null");
51         return LUA_NOREF;
52     }
53
54     /* the following might push a nil, but that's ok */
55     lua_rawgeti(L, LUA_REGISTRYINDEX, priv->table_ref);
56
57     return 1;
58 }
59
60 /* sets the private data to wtap - the table is presumed on top of stack */
61 int set_wth_priv_table_ref(lua_State* L, wtap *wth) {
62     file_priv_t *priv = (file_priv_t*) wth->priv;
63
64     if (!priv) {
65         /* shouldn't be possible */
66         luaL_error(L, "Cannot get wtap private data: it is null");
67         return 0;
68     }
69
70     if (lua_isnil(L, -1)){
71         /* user is setting it nil - ok, de-ref any previous one */
72         luaL_unref(L, LUA_REGISTRYINDEX, priv->table_ref);
73         priv->table_ref = LUA_NOREF;
74         return 0;
75     }
76
77     if (!lua_istable(L, -1)) {
78         luaL_error(L, "The private_table member can only be set to a table or nil");
79         return 0;
80     }
81
82     /* if we had a table already referenced, de-ref it first */
83     if (priv->table_ref != LUA_NOREF) {
84         luaL_unref(L, LUA_REGISTRYINDEX, priv->table_ref);
85     }
86
87     priv->table_ref = luaL_ref(L, LUA_REGISTRYINDEX);
88
89     return 0;
90 }
91
92 /* remove, deref, and free the wtap->priv data */
93 void remove_wth_priv(lua_State* L, wtap *wth) {
94     file_priv_t *priv = (file_priv_t*) wth->priv;
95
96     if (!priv) {
97         /* shouldn't be possible */
98         luaL_error(L, "Cannot remove wtap private data: it is null");
99         return;
100     }
101
102     luaL_unref(L, LUA_REGISTRYINDEX, priv->table_ref);
103
104     g_free(wth->priv);
105     wth->priv = NULL;
106 }
107
108 /* create and set the wtap_dumper->priv private data for the file instance */
109 void create_wdh_priv(lua_State* L, wtap_dumper *wdh) {
110     file_priv_t *priv = (file_priv_t*)g_malloc(sizeof(file_priv_t));
111
112     if (wdh->priv != NULL) {
113         g_free(priv);
114         luaL_error(L, "Cannot create wtap_dumper private data because there already is private data");
115         return;
116     }
117     priv->table_ref = LUA_NOREF;
118     wdh->priv = (void*) priv;
119 }
120
121 /* get the private data from wtap_dumper */
122 int get_wdh_priv_table_ref(lua_State* L, wtap_dumper *wdh) {
123     file_priv_t *priv = (file_priv_t*) wdh->priv;
124
125     if (!priv) {
126         /* shouldn't be possible */
127         luaL_error(L, "Cannot get wtap_dumper private data: it is null");
128         return LUA_NOREF;
129     }
130
131     /* the following might push a nil, but that's ok */
132     lua_rawgeti(L, LUA_REGISTRYINDEX, priv->table_ref);
133
134     return 1;
135 }
136
137 /* sets the private data to wtap - the table is presumed on top of stack */
138 int set_wdh_priv_table_ref(lua_State* L, wtap_dumper *wdh) {
139     file_priv_t *priv = (file_priv_t*) wdh->priv;
140
141     if (!priv) {
142         /* shouldn't be possible */
143         luaL_error(L, "Cannot get wtap private data: it is null");
144         return 0;
145     }
146
147     if (lua_isnil(L, -1)){
148         /* user is setting it nil - ok, de-ref any previous one */
149         luaL_unref(L, LUA_REGISTRYINDEX, priv->table_ref);
150         priv->table_ref = LUA_NOREF;
151         return 0;
152     }
153
154     if (!lua_istable(L, -1)) {
155         luaL_error(L, "The private_table member can only be set to a table or nil");
156         return 0;
157     }
158
159     /* if we had a table already referenced, de-ref it first */
160     if (priv->table_ref != LUA_NOREF) {
161         luaL_unref(L, LUA_REGISTRYINDEX, priv->table_ref);
162     }
163
164     priv->table_ref = luaL_ref(L, LUA_REGISTRYINDEX);
165
166     return 0;
167 }
168
169 /* remove and deref the wtap_dumper->priv data */
170 void remove_wdh_priv(lua_State* L, wtap_dumper *wdh) {
171     file_priv_t *priv = (file_priv_t*) wdh->priv;
172
173     if (!priv) {
174         /* shouldn't be possible */
175         luaL_error(L, "Cannot remove wtap_dumper private data: it is null");
176         return;
177     }
178
179     luaL_unref(L, LUA_REGISTRYINDEX, priv->table_ref);
180     /* we do NOT free wtap_dumper's priv member - wtap_dump_close() free's it */
181 }
182
183
184 /*
185  * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
186  *
187  * Local variables:
188  * c-basic-offset: 4
189  * tab-width: 8
190  * indent-tabs-mode: nil
191  * End:
192  *
193  * vi: set shiftwidth=4 tabstop=8 expandtab:
194  * :indentSize=4:tabSize=8:noTabs=true:
195  */