1 /*
2  * Copyright (C) 2014 Edscott Wilson Garcia
3  * EMail: edscott.wilson.garcia@gmail.com
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program;
17  */
18 
19 #ifdef HAVE_CONFIG_H
20 #include <config.h>
21 #endif
22 
23 #include "rodent.h"
24 
25 
26 /* this should be first 2 lines after headers: */
27 G_MODULE_EXPORT
28 LIBRFM_MODULE
29 
30 
31 #define MODULE_NAME "pkg"
32 #define SUBMODULE_NAME "pkg"
33 #define MODULE_LABEL _("Package Manager")
34 #define PKG_MODULE_ICON_ID "xffm/emblem_package/compositeSW/emblem_bsd"
35 #define ZYPPER_MODULE_ICON_ID "xffm/emblem_package/compositeSW/emblem_opensuse"
36 #define YUM_MODULE_ICON_ID "xffm/emblem_package/compositeSW/emblem_centos"
37 #define APT_MODULE_ICON_ID "xffm/emblem_package/compositeSW/emblem_debian"
38 #define EMERGE_MODULE_ICON_ID "xffm/emblem_package/compositeSW/emblem_gentoo"
39 #define PACMAN_MODULE_ICON_ID "xffm/emblem_package/compositeSW/emblem_archlinux"
40 #define FALLBACK_MODULE_ICON_ID "xffm/emblem_package/compositeSW/emblem_star"
41 #define MODULE_ENTRY_TIP _("A package manager")
42 
43 #include "module-skeleton.h"
44 // Skeleton definitions
45 //G_MODULE_EXPORT RFM_G_MODULE_CHECK_INIT
46 
47 G_MODULE_EXPORT RFM_MODULE_NAME
48 G_MODULE_EXPORT RFM_SUBMODULE_NAME
49 G_MODULE_EXPORT RFM_MODULE_LABEL
50 //G_MODULE_EXPORT RFM_MODULE_ICON_ID
51 G_MODULE_EXPORT RFM_MODULE_ENTRY_TIP
52 G_MODULE_EXPORT RFM_BLOCKING_LOAD(TRUE)
53 
54 G_MODULE_EXPORT RFM_MODULE_PREFERENCES_KEY("RODENT-PKG");
55 G_MODULE_EXPORT RFM_IS_ROOT_MODULE(TRUE)
56 G_MODULE_EXPORT RFM_PLUGIN_INFO(_("Configure external packages"))
57 G_MODULE_EXPORT RFM_MODULE_ACTIVE(TRUE)
58 G_MODULE_EXPORT RFM_MODULE_MONITOR(FALSE)
59 G_MODULE_EXPORT RFM_IS_SELECTABLE(TRUE)
60 
61 ////////////// Specific module initialization function
62 static gchar *pkg_command=NULL;
63 #include "pkg-module.i"
64 void *
g_module_check_init(GModule * module)65 g_module_check_init(GModule *module){
66     NOOP(stderr, "g_module_check_init pkg\n");
67     pkg_command=get_defaults();
68 #ifdef ENABLE_NLS
69     /* this binds rodent domain: */
70     bindtextdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);
71     DBG("rodent-pkgmain(): textdomain=%s (%s) locale_dir=%s (%s)\n",
72 	    textdomain(NULL), GETTEXT_PACKAGE,
73 	    bindtextdomain(textdomain(NULL), NULL), PACKAGE_LOCALE_DIR);
74 # ifdef HAVE_BIND_TEXTDOMAIN_CODESET
75     bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
76 # endif
77 #endif
78     gchar *xmlfile = g_strdup_printf("%s/rfm/plugins/xml/pkg_%s.xml",LIBDIR, pkg_command);
79 
80     if (!parse_xml(xmlfile, pkg_command)) {
81         g_free(xmlfile);
82         return NULL;
83     }
84     g_free(xmlfile);
85     rfm_view_thread_create(NULL, thread_popup, NULL, "thread_popup:pkg");
86     return NULL;
87 }
88 
89 void *
module_icon_id(void)90 module_icon_id(void){
91     if (emerge)return EMERGE_MODULE_ICON_ID;
92     else if (pkg) return PKG_MODULE_ICON_ID;
93     else if (zypper) return ZYPPER_MODULE_ICON_ID;
94     else if (yum) return YUM_MODULE_ICON_ID;
95     else if (apt) return APT_MODULE_ICON_ID;
96     else if (pacman) return PACMAN_MODULE_ICON_ID;
97     else return FALLBACK_MODULE_ICON_ID;
98 }
99 
100 
101 // gboolean
102 // This function is to generate a module specific popup menu, either on
103 // icon click or on void space click .
104 // If this function will generate a popup menu, return value should be TRUE,
105 // otherwise return FALSE so Rodent will generate the default popup menu.
106 // Parameter p is the view's widgets_p pointer.
107 // Parameter q is the icon's record entry.
108 G_MODULE_EXPORT
109 void *
private_popup(void * p,void * q)110 private_popup(void *p, void *q){
111     TRACE( "private_popup:pkg\n");
112     return pkg_popup(p, q);
113 }
114 
115 //////////////  Generalized Root Module functions ///////////////////
116 
117 // Plugin functions. Plugin functions may be specified as one of the
118 // following types.
119 //
120 // void:     These functions all return a void pointer
121 //   	     and take no argument
122 // natural:  These functions all return a void pointer
123 // 	     and take a single void pointer argument.
124 // 	     The space of natural functions is isomorphic
125 // 	     to the set of natural numbers.
126 // rational: These functions all return a void pointer
127 // 	     and take a two void pointer arguments.
128 // 	     The space of rational functions is isomorphic
129 // 	     to the set of rational numbers.
130 // complex:  These functions all return a void pointer
131 // 	     and take a three void pointer arguments.
132 // 	     The space of rational functions is isomorphic
133 // 	     to the set of complex numbers with integer
134 // 	     imaginary component.
135 
136 
137 //////////////////////////////////////////////////////////////////////
138 //                          void functions                          //
139 //////////////////////////////////////////////////////////////////////
140 
141 void *
module_argv(void * p,void * q)142 module_argv(void *p, void *q){
143     record_entry_t *en=p;
144     if (!en) {
145 	DBG("ps-module: en == NULL\n");
146 	return NULL;
147     }
148     gchar **argv=q;
149     if (!argv) {
150 	DBG("ps-module: argv == NULL\n");
151 	return NULL;
152     }
153     gchar *cmd = NULL;
154     gchar **a = q;
155     // Start with argument 2 (arg 0 would be rodent-plug, 1 pkg)
156     a++; if (a) a++;
157     for (;a && *a; a++){
158         if (!cmd) cmd = g_strdup("search ");
159         else {
160             gchar *f = g_strconcat(cmd, " ", NULL);
161             g_free(cmd);
162             cmd = f;
163         }
164         gchar *g = g_strconcat(cmd, *a, NULL);
165         g_free(cmd);
166         cmd=g;
167     }
168     if (!cmd || !strlen(cmd)) {
169         g_free(cmd);
170         return NULL;
171     }
172     g_free(en->path);
173     en->path = cmd;
174 
175     return GINT_TO_POINTER(1);
176 }
177 
178 
179 //////////////////////////////////////////////////////////////////////
180 //                        natural functions                         //
181 // gboolean
182 // This function fills in previously allocated xfdir_p
183 // with glob records and entries of the module population.
184 // Records which are filled in are:
185 // xfdir_p->pathc: Number of icons for Rodent to display
186 // xfdir_p->gl[0 ... pathc-1].pathv: Labels to display with each icon
187 // xfdir_p->gl[0 ... pathc-1].en: Record_entry_t of each icon
188 // 				  (NULL entries will point to Rodent root)
189 G_MODULE_EXPORT
190 void *
module_xfdir_get(void * p)191 module_xfdir_get (void *p) {
192     NOOP(stderr, "get module xfdir...\n");
193     xfdir_t *xfdir_p = p;
194     widgets_t *widgets_p = &(xfdir_p->view_p->widgets);
195 
196     static gboolean warned = FALSE;
197     if (!warned) {
198         if (pkg) {
199             gchar *cmd = g_strdup_printf("%s -v", pkg);
200 
201             FILE *pp = popen(cmd, "r");
202             if (!pp){
203                 rfm_threaded_diagnostics(widgets_p, "xffm/stock_dialog-warning", NULL);
204                 rfm_threaded_diagnostics(widgets_p, "xffm_tag/stderr", g_strdup_printf("%s: %s\n",cmd, _("unknown error")));
205                 g_free(cmd);
206                 return NULL;
207 
208             }
209             g_free(cmd);
210             gchar line[256];
211             memset(line,0,256);
212             if(fgets(line, 255, pp)){
213                 rfm_threaded_show_text(widgets_p);
214                 rfm_threaded_diagnostics(widgets_p,
215                         "xffm/emblem_package", NULL);
216                 rfm_threaded_diagnostics(widgets_p,
217                         "xffm_tag/blue", g_strdup_printf("pkg-%s", line));
218             }
219             pclose(pp);
220         }
221         if (geteuid() != 0){
222             gchar *t="If you are behind a proxy wall, make sure sudo is configured to keep your http_proxy and ftp_proxy environment variables.\n";
223             gchar *s="This is done with visudo, add \"http_proxy\" and \"ftp_proxy\" to Defaults\n";
224 	    rfm_threaded_show_text(widgets_p);
225             rfm_threaded_diagnostics(widgets_p, "xffm/stock_dialog-info", NULL);
226             rfm_threaded_diagnostics(widgets_p, "xffm_tag/red", g_strdup(t));
227             rfm_threaded_diagnostics(widgets_p, "xffm/stock_dialog-info", NULL);
228             rfm_threaded_diagnostics(widgets_p, "xffm_tag/red", g_strdup(s));
229         } else {
230             gchar *argv[] = {"pkg", "stats", NULL};
231             rfm_thread_run_argv (widgets_p, argv, FALSE);
232         }
233         warned = TRUE;
234     }
235 
236     GtkWidget *hold_your_horses = rfm_context_function(hold_your_horses_f, NULL);
237     gint retval=pkg_xfdir_get(p);
238     rfm_context_function(loose_your_horses_f, hold_your_horses);
239 
240     return GINT_TO_POINTER(retval);
241 }
242 
243 G_MODULE_EXPORT
double_click(void * p,void * q)244 void *double_click(void *p, void *q){
245     //DBG("void *double_click\n");
246     widgets_t *widgets_p = p;
247     record_entry_t *en = q;
248     if (!en) return NULL;
249     if (IS_ROOT_TYPE(en->type)) return NULL;
250     if (g_path_is_absolute(en->path) && g_file_test(en->path, G_FILE_TEST_IS_DIR)) return NULL;
251 
252     if (strcmp(en->path, _("Search"))==0){
253         pkg_command_t *c = xml_cmds;
254         for (;c && c->pkg; c++){
255             if (!c->cmd) continue;
256             const gchar *search="search";
257             if (emerge) search="--search";
258             else if (pacman) search="-Ss";
259             if (strcmp(c->cmd, search)==0){
260                 fprintf(stderr, "process command: %s\n", c->cmd);
261                 process_cmd(NULL, c);
262                 return GINT_TO_POINTER(1);
263             }
264         }
265         //return GINT_TO_POINTER(1);
266     }
267     //rfm_threaded_diagnostics(widgets_p, "rodent", g_strdup("And here we could open a dialog to act upon the selected item or items (wishlist)\n"));
268     pkg_popup(p, q);
269     return GINT_TO_POINTER(1);
270 }
271 
272 
273 // const gchar *
274 // This function returns a const pointer to the entry's icon
275 // identifier.
276 // Parameter p is the item's entry pointer.
277 // Identifier may be returned as a mimetype or an absolute path.
278 G_MODULE_EXPORT
279 void *
item_icon_id(void * p)280 item_icon_id (void *p) {
281     record_entry_t *en = p;
282     if (strcmp(en->path, _("Search"))==0) return "xffm/emblem_find";
283     if (g_path_is_absolute(en->path)) {
284 	if (pkg)
285 	    return "xffm/emblem_bsd/compositeSE/stock_directory";
286         else if (emerge)
287             return "xffm/emblem_gentoo/compositeSE/stock_directory";
288         else if (zypper)
289 	    return "xffm/emblem_opensuse/compositeSE/stock_directory";
290         else if (yum)
291 	    return "xffm/emblem_centos/compositeSE/stock_directory";
292         else if (apt)
293 	    return "xffm/emblem_debian/compositeSE/stock_directory";
294         else if (pacman)
295 	    return "xffm/emblem_archlinux/compositeSE/stock_directory";
296         else
297 	    return "xffm/emblem_gentoo/compositeSE/stock_directory";
298     }
299 
300     if (IS_LOCAL_TYPE(en->type)) return "xffm/emblem_package/compositeNE/emblem_greenball";
301     if (!en || strcmp(en->path,MODULE_LABEL)==0) {
302         if (pkg) return PKG_MODULE_ICON_ID;
303         else if (emerge) return EMERGE_MODULE_ICON_ID;
304         else if (zypper) return ZYPPER_MODULE_ICON_ID;
305         else if (yum) return YUM_MODULE_ICON_ID;
306         else if (apt) return APT_MODULE_ICON_ID;
307         else if (pacman) return PACMAN_MODULE_ICON_ID;
308         else return FALLBACK_MODULE_ICON_ID;
309     }
310     if (pkg){
311         if (IS_PLUGIN_TYPE1(en->type)) // older version installed.
312             return "xffm/emblem_bsd/compositeNE/emblem_star";
313         else
314             return "xffm/emblem_bsd/compositeNE/emblem_package";
315     }
316     else if (emerge)
317 	return "xffm/emblem_gentoo/compositeNE/emblem_package";
318     else if (yum)
319 	return "xffm/emblem_centos/compositeNE/emblem_package";
320     else if (zypper)
321 	return "xffm/emblem_opensuse/compositeNE/emblem_package";
322     else if (apt)
323 	return "xffm/emblem_debian/compositeNE/emblem_package";
324     else if (pacman)
325         return "xffm/emblem_archlinux/compositeNE/emblem_package";
326     else
327 	return "xffm/emblem_star/compositeNE/emblem_package";
328 }
329 //this should be the label tip. entry tip should cook up a preview with package info:../src/pkg-module.c: En la función ‘item_icon_id’:
330 //pkg query "%n %v %o %p %m %c %e %w %l %sh %a %q %k %M %t" en->path
331 G_MODULE_EXPORT
332 void *
item_entry_tip(void * p)333 item_entry_tip(void *p){
334     if (pthread_mutex_trylock(&db_mutex)!=0){
335 	DBG("get_tooltip_text(): cannot lock mutex.\n");
336 	//return g_strdup(_("Work in progress..."));
337 	return NULL;
338     }
339     gchar *ret = get_tooltip_text((record_entry_t *)p);
340     pthread_mutex_unlock(&db_mutex);
341     return ret;
342 }
343 
344 
345