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