1 #ifdef COPYRIGHT_INFORMATION
2 #include "gplv3.h"
3 #endif
4 /*
5 * Edscott Wilson Garcia Copyright 2012
6 *
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program;
20 */
21 #include "samba-common.h"
22
23
24 #define POPUP_ID "smb_module_menu"
25 #define POPUP_MENU_ID "smb_module_menu_menu"
26 #define SMB_MENU_STUFF \
27 {MENUITEM_TYPE,POPUP_MENU_ID,"smb_reset_user_credentials",\
28 {0x3001, N_("Browsing Settings"),"xffm/emblem_network/compositeSE/emblem_blueball", \
29 (gpointer) reset_user_credentials, NULL}},\
30 {NULL_TYPE}
31 #if 0
32 // not yet implemented...
33 {MENUITEM_TYPE,POPUP_MENU_ID,"smb_properties",\
34 {N_("Properties"),"xffm/stock_properties", \
35 (gpointer) do_prop, NULL}},\
36 {MENUITEM_TYPE,POPUP_MENU_ID,"smb_mount",\
37 {N_("Mount"),"xffm/stock_yes", \
38 (gpointer) , NULL}},\
39 {MENUITEM_TYPE,POPUP_MENU_ID,"smb_unmount",\
40 {N_("Unmount"),"xffm/stock_no", \
41 (gpointer) , NULL}},
42 #endif
43
44 #ifdef SAMBA_MODULE_C
45 static void
set_up_item(xfdir_t * xfdir_p)46 set_up_item(xfdir_t *xfdir_p){
47 // Up icon
48 xfdir_p->gl[0].en = NULL;
49 xfdir_p->gl[0].pathv = g_strdup (g_get_host_name ());
50 #if 0
51 // up item: cifs module.
52 xfdir_p->gl[0].en=rfm_mk_entry(0);
53 xfdir_p->gl[0].en->st = NULL;
54 xfdir_p->gl[0].en->parent_module = MODULE_NAME;
55 xfdir_p->gl[0].en->module = PARENT_MODULE_NAME;
56 // Get the up item text directly from the cifs module.
57 gchar *g = rfm_void(PLUGIN_DIR, PARENT_MODULE_NAME, "module_label");
58 if (!g) g=g_strdup_printf("FIXME: %s module_label failed", PARENT_MODULE_NAME);
59 xfdir_p->gl[0].en->path=g;
60 xfdir_p->gl[0].pathv = g_strdup(g);
61 SET_DUMMY_TYPE (xfdir_p->gl[0].en->type);
62 SET_UP_TYPE (xfdir_p->gl[0].en->type);
63 #endif
64 }
65 #else
66
67
68 #ifdef SHARES_MODULE_C
69 static void
set_up_item(xfdir_t * xfdir_p)70 set_up_item(xfdir_t *xfdir_p){
71 rfm_global_t *rfm_global_p = rfm_global();
72 widgets_t *widgets_p = &(xfdir_p->view_p->widgets);
73
74 const gchar *smb_server = g_object_get_data(G_OBJECT(widgets_p->paper), "smb_server");
75 const gchar *wg = g_object_get_data(G_OBJECT(widgets_p->paper), "smb_workgroup");
76 const gchar *tag = g_object_get_data(G_OBJECT(widgets_p->paper), "tag");
77
78 if (!smb_server) {
79 smb_server = g_object_get_data(G_OBJECT(rfm_global_p->window), "smb_server");
80 if (smb_server) g_object_set_data(G_OBJECT(widgets_p->paper), "smb_server", g_strdup(smb_server));
81 }
82 if (!wg) {
83 wg = g_object_get_data(G_OBJECT(rfm_global_p->window), "smb_workgroup");
84 if (wg) g_object_set_data(G_OBJECT(widgets_p->paper), "smb_workgroup", g_strdup(wg));
85 }
86 if (!tag) {
87 tag = g_object_get_data(G_OBJECT(rfm_global_p->window), "tag");
88 if (tag) g_object_set_data(G_OBJECT(widgets_p->paper), "tag", g_strdup(tag));
89 }
90 // up item: wg module.
91 xfdir_p->gl[0].en=rfm_mk_entry(0);
92 xfdir_p->gl[0].en->st = NULL;
93 xfdir_p->gl[0].en->parent_module = MODULE_NAME;
94 xfdir_p->gl[0].en->module = "workgroup";
95 SET_ROOT_TYPE(xfdir_p->gl[0].en->type);
96 if (tag) xfdir_p->gl[0].en->tag=g_strdup(tag);
97 xfdir_p->gl[0].en->path=g_strdup(smb_server);
98 if (wg) xfdir_p->gl[0].en->pseudo_path=g_strdup(wg);
99 xfdir_p->gl[0].pathv = g_strdup(wg);
100 SET_DUMMY_TYPE (xfdir_p->gl[0].en->type);
101 SET_UP_TYPE (xfdir_p->gl[0].en->type);
102 NOOP(stderr, "+++++++ tag is %s\n", wg);
103 return;
104 }
105 #endif
106
107 #ifdef WORKGROUP_MODULE_C
108 static void
set_up_item(xfdir_t * xfdir_p)109 set_up_item(xfdir_t *xfdir_p){
110 widgets_t *widgets_p = &(xfdir_p->view_p->widgets);
111 rfm_global_t *rfm_global_p = rfm_global();
112
113 const gchar *smb_server = g_object_get_data(G_OBJECT(widgets_p->paper), "smb_server");
114 const gchar *wg = g_object_get_data(G_OBJECT(widgets_p->paper), "smb_workgroup");
115 const gchar *tag = g_object_get_data(G_OBJECT(widgets_p->paper), "tag");
116
117 if (!smb_server) {
118 smb_server = g_object_get_data(G_OBJECT(rfm_global_p->window), "smb_server");
119 if (smb_server) g_object_set_data(G_OBJECT(widgets_p->paper), "smb_server", g_strdup(smb_server));
120 }
121 if (!wg) {
122 wg = g_object_get_data(G_OBJECT(rfm_global_p->window), "smb_workgroup");
123 if (wg) g_object_set_data(G_OBJECT(widgets_p->paper), "smb_workgroup", g_strdup(wg));
124 }
125 if (!tag) {
126 tag = g_object_get_data(G_OBJECT(rfm_global_p->window), "tag");
127 if (tag) g_object_set_data(G_OBJECT(widgets_p->paper), "tag", g_strdup(tag));
128 }
129 // up item: wg module.
130 xfdir_p->gl[0].en=rfm_mk_entry(0);
131 xfdir_p->gl[0].en->st = NULL;
132 xfdir_p->gl[0].en->parent_module = MODULE_NAME;
133 xfdir_p->gl[0].en->module = "smb";
134 SET_ROOT_TYPE(xfdir_p->gl[0].en->type);
135 if (tag) xfdir_p->gl[0].en->tag=g_strdup(tag);
136 xfdir_p->gl[0].en->path=g_strdup(smb_server);
137 if (wg) xfdir_p->gl[0].en->pseudo_path=g_strdup(wg);
138 xfdir_p->gl[0].pathv = g_strdup(_("SMB Browser"));
139 SET_DUMMY_TYPE (xfdir_p->gl[0].en->type);
140 SET_UP_TYPE (xfdir_p->gl[0].en->type);
141 NOOP(stderr, "+++++++ tag is %s\n", wg);
142 return;
143 }
144 #endif
145 #endif
146
147
148 /////////////////////////////////////////////////////////////////////
149 // gint
150 // This function returns the count of elements in the module's
151 // view. This value is compared with current value to determine
152 // whether a reload is necessary.
153 // Parameter p is the view's widgets_p.
154
155 G_MODULE_EXPORT
156 void *
module_count(void * p)157 module_count (void *p) {
158 static gint count=0;
159 widgets_t *widgets_p = p;
160 view_t *view_p = widgets_p->view_p;
161 smb_data_t *smb_data_p =
162 g_object_get_data(G_OBJECT(view_p->widgets.paper), MODULE_DATA_ID);
163 if (!smb_data_p) {
164 xfdir_exit_monitor(view_p);
165 NOOP("samba-module, module_count(): !smb_data_p\n");
166 return GINT_TO_POINTER (NO_RELOAD_COUNT);
167 }
168 if (smb_data_p->condition & DELAY_MONITOR){
169 return GINT_TO_POINTER (NO_RELOAD_COUNT);
170 }
171
172
173 if (!(smb_data_p->condition & RELOAD)){
174 NOOP( "THREAD 0x%x: condition = 0x%x --> waiting for signal...\n", GPOINTER_TO_INT(g_thread_self()), smb_data_p->condition);
175 g_mutex_lock(smb_data_p->mutex);
176
177 g_cond_wait(smb_data_p->signal, smb_data_p->mutex);
178 g_mutex_unlock(smb_data_p->mutex);
179 NOOP( "THREAD 0x%x: condition signal %s... do we need to loop again? Condition is 0x%x & 0x%x --> 0x%x --> 0x%x\n",
180 GPOINTER_TO_INT(g_thread_self()),
181 "obtained",
182 smb_data_p->condition, RELOAD,
183 (smb_data_p->condition) & RELOAD,
184 smb_data_p->condition & RELOAD);
185 return GINT_TO_POINTER (READ_ERROR);
186 }
187
188
189 NOOP( "THREAD 0x%x: reload condition = 0x%x & 0x%x\n", GPOINTER_TO_INT(g_thread_self()), smb_data_p->condition, RELOAD);
190
191 return GINT_TO_POINTER (count++);
192 }
193
194 G_MODULE_EXPORT
195 void *
monitor_skipwait(void * p)196 monitor_skipwait (void *p) {
197 view_t *view_p = p;
198 smb_data_t *smb_data_p =
199 g_object_get_data(G_OBJECT(view_p->widgets.paper), MODULE_DATA_ID);
200 if (!smb_data_p) return GINT_TO_POINTER(TRUE);
201 if (smb_data_p->condition & DELAY_MONITOR) {
202 return NULL;
203 }
204 return GINT_TO_POINTER(TRUE);
205 }
206
207 static gboolean
smb_check_program(widgets_t * widgets_p,const gchar * program_to_check)208 smb_check_program(widgets_t *widgets_p, const gchar *program_to_check){
209 if (!program_to_check) {
210 DBG("check_program(): program_to_check==NULL!\n");
211 }
212 gchar *p = g_find_program_in_path(program_to_check);
213 if (!p){
214 rfm_show_text(widgets_p);
215 gchar *text=g_strdup_printf (_("The \"%s\" utility is not installed.\nPlease install it."), program_to_check);
216 rfm_diagnostics(widgets_p, "xffm/stock_dialog-warning", text, "\n", NULL);
217
218 #ifdef BROKEN_SHARED_SEMAPHORES
219 // Not Linux...
220 rfm_diagnostics(widgets_p, "xffm_tag/red", "FreeBSD: ", NULL);
221 rfm_diagnostics(widgets_p, "xffm_tag/blue", "cd /usr/ports/net/samba-nmblookup && sudo make install", "\n", NULL);
222 #endif
223
224 // crashes:
225 // rfm_confirm(NULL, GTK_MESSAGE_WARNING, text, NULL, _("Accept"));
226 g_free(text);
227 return FALSE;
228 }
229 g_free(p);
230 return TRUE;
231 }
232
233 #if 0
234 static
235 void do_prop(GtkMenuItem *m, gpointer data){
236 record_entry_t *en = data;
237 widgets_t *widgets_p = g_object_get_data(G_OBJECT(m), "widgets_p");
238 if (!widgets_p || !data){
239 DBG("shares do_prop(): this should never happen, !widgets_p || ! data\n");
240 }
241 rfm_rational(PLUGIN_DIR, "cifs", widgets_p, en, "double_click");
242 }
243 #endif
244 G_MODULE_EXPORT
245 void *
private_popup(void * p,void * q)246 private_popup(void *p, void *q){
247 widgets_t *widgets_p = rfm_get_widget("widgets_p");
248 view_t *view_p = widgets_p->view_p;
249 if (!(g_slist_length(view_p->selection_list)==1)) return NULL;
250 record_entry_t *en=(record_entry_t *)view_p->selection_list->data;
251 if (!en) {
252 NOOP("ps_popup en==NULL\n");
253 return NULL;
254 }
255 GtkWidget *popup_widget = rfm_get_widget(POPUP_MENU_ID);
256 if (!popup_widget) g_error("popup_widget is initialized on module load...\n");
257
258 #if 0
259 GtkWidget *w;
260 const gchar *id = POPUP_ID;
261 record_entry_t *en=(record_entry_t *)q;
262 const gchar *label=MODULE_LABEL;
263 #ifdef SHARES_MODULE_C
264 if(en && en->pseudo_path) label = en->pseudo_path;
265 #endif
266 view_t *view_p=widgets_p->view_p;
267
268 // if (en->st==NULL){return NULL;}
269
270 GtkWidget *popup_widget=g_object_get_data(G_OBJECT(widgets_p->paper), id);
271 GtkWidget *old_popup_widget=popup_widget;
272
273 #ifdef DEBUG
274 const gchar *url = en->pseudo_path;
275 NOOP( "private_popup(): url is %s\n", url);
276 #endif
277
278 // rodent_mk_menu autoprotects with GDK mutex when called from non main thread
279 popup_widget=rodent_mk_menu(
280 widgets_p, /* window */
281 label, /* label */
282 POPUP_MENU_ID, /* name */
283 NULL, /* parent */
284 NULL, /* callback (or NULL)*/
285 NULL); /* icon id*/
286 g_object_set_data(G_OBJECT(widgets_p->paper), id, popup_widget);
287 // register popumenu with xfdir monitor
288 xfdir_register_popup(view_p, popup_widget);
289
290
291 w = gtk_image_menu_item_new_with_mnemonic (_("Browsing Settings"));
292 g_object_set_data(G_OBJECT(w),"widgets_p",widgets_p);
293 gtk_widget_show (w);
294 gtk_container_add (GTK_CONTAINER (popup_widget), w);
295 rodent_mk_pixmap_menu("xffm/places_network-workgroup/compositeC/actions_insert-object", w, MENU_PIXMAP);
296 g_signal_connect ((gpointer) w, "activate", G_CALLBACK (reset_user_credentials), widgets_p);
297
298 #ifdef SHARES_MODULE_C
299 w = gtk_image_menu_item_new_with_mnemonic (_("Properties"));
300 g_object_set_data(G_OBJECT(w),"widgets_p",widgets_p);
301 gtk_widget_show (w);
302 gtk_container_add (GTK_CONTAINER (popup_widget), w);
303 rodent_mk_pixmap_menu("xffm/stock_properties", w, MENU_PIXMAP);
304 g_object_set_data(G_OBJECT(w), "widgets_p", widgets_p);
305 g_signal_connect ((gpointer) w, "activate", G_CALLBACK (do_prop), en);
306
307
308 w = gtk_image_menu_item_new_with_mnemonic (_("Mount"));
309 g_object_set_data(G_OBJECT(w),"widgets_p",widgets_p);
310 gtk_widget_show (w);
311 gtk_container_add (GTK_CONTAINER (popup_widget), w);
312 rodent_mk_pixmap_menu("xffm/stock_yes", w, MENU_PIXMAP);
313 //g_signal_connect ((gpointer) w, "activate", G_CALLBACK (reset_user_credentials), NULL);
314
315 w = gtk_image_menu_item_new_with_mnemonic (_("Unmount"));
316 g_object_set_data(G_OBJECT(w),"widgets_p",widgets_p);
317 gtk_widget_show (w);
318 gtk_container_add (GTK_CONTAINER (popup_widget), w);
319 rodent_mk_pixmap_menu("xffm/stock_no", w, MENU_PIXMAP);
320 //g_signal_connect ((gpointer) w, "activate", G_CALLBACK (reset_user_credentials), NULL);
321 #endif
322 #endif
323
324 gtk_menu_popup(GTK_MENU(popup_widget), NULL, NULL, NULL, NULL, 3, view_p->mouse_event.eventtime);
325 #if 0
326 if (old_popup_widget) {
327 gtk_widget_destroy(old_popup_widget);
328 }
329 #endif
330
331 return GINT_TO_POINTER(1);
332 }
333
334
335 // gchar *
336 // This function returns a newly allocated string with the general information
337 // of the entry (parameter p). Rodent uses this to construct the popup tip.
338 // Returned value should be freed when no longer used.
339 G_MODULE_EXPORT
340 void *
item_entry_tip(void * p)341 item_entry_tip(void *p){
342 if (!p) return NULL;
343 record_entry_t *en = p;
344 #ifdef SHARES_MODULE_C
345 return g_strdup_printf("%s\n%s\n %s \n %s %s\n\n%s lib%s \n%s: lib%s\n",
346 en->pseudo_path,
347 MODULE_ENTRY_TIP, (en->tag)?en->tag:"", _("Mount point:"),en->path,
348 _("Plugin: "),en->module,
349 _("Parent"), MODULE_NAME);
350 #else
351 return g_strdup_printf("%s\n %s\n\n%slib%s (%s: lib%s)",
352 MODULE_ENTRY_TIP, (en->tag)?en->tag:en->path,
353 _("Plugin: "),en->module,
354 _("Parent"), MODULE_NAME);
355 #endif
356 }
357
358
359 static void *
thread_popup(void * data)360 thread_popup(void *data){
361 if (rfm_get_gtk_thread() == g_thread_self()){
362 g_warning("thread_mk_popup_menu: only to be called from non main thread\n");
363 return NULL;
364 }
365
366 GtkWidget *popup_widget=NULL;
367 GMutex *popup_mutex = rfm_get_widget("smb_popup_mutex");
368 g_mutex_lock(popup_mutex);
369 popup_widget = rfm_get_widget(POPUP_MENU_ID);
370 if (!popup_widget) {
371 popup_widget=rodent_thread_add_submenu (NULL, "rodent-smb", POPUP_ID, NULL);
372 TRACE( "smb_thread_popup creation...\n");
373 RodentMenuDefinition menu_definitions_p[] = {SMB_MENU_STUFF};
374 rodent_thread_multimenu_make(NULL, menu_definitions_p);
375 widgets_t *widgets_p = rfm_get_widget ("widgets_p");
376 view_t *view_p = widgets_p->view_p;
377 xfdir_register_popup(view_p, popup_widget);
378 } else {
379 TRACE( "smb_thread_popup retrieval...\n");
380 }
381 g_mutex_unlock(popup_mutex);
382 return popup_widget;
383 }
384
385 static void *
common_init(GModule * module)386 common_init(GModule *module){
387 NOOP("domain=(no gettext support)");
388 GMutex *mutex = rfm_get_widget("smb_popup_mutex");
389 if (!mutex){
390 rfm_mutex_init(mutex);
391 rfm_set_widget(mutex, "smb_popup_mutex");
392 }
393 rfm_view_thread_create(NULL, thread_popup, NULL, "thread_popup:samba-common");
394 return NULL;
395 }
396
397