1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef HAVE_GUDEV
#include <sys/wait.h>
#include <ctype.h>
#define G_UDEV_API_IS_SUBJECT_TO_CHANGE
#include <gudev/gudev.h>
#include <sys/utsname.h>
gchar *hplip_helper[] = { "/usr/bin/hp-plugin-ubuntu", NULL };
static inline void
g_debug_uevent(const char *msg, ...)
{
va_list va;
va_start(va, msg);
g_logv("uevent",G_LOG_LEVEL_DEBUG, msg, va);
va_end(va);
}
static gboolean scp_checked = FALSE;
static gboolean
deal_with_scp(GUdevDevice *device)
{
GError *error = NULL;
/* only do this once */
if (scp_checked)
return FALSE;
/* check if we just added a printer */
if ((g_strcmp0(g_udev_device_get_sysfs_attr(device, "bInterfaceClass"), "07") != 0 ||
g_strcmp0(g_udev_device_get_sysfs_attr(device, "bInterfaceSubClass"), "01") != 0) &&
!g_str_has_prefix(g_udev_device_get_name (device), "lp")) {
g_debug_uevent ("deal_with_scp: devpath=%s: not a printer", g_udev_device_get_sysfs_path(device));
return FALSE;
}
g_debug_uevent ("deal_with_scp: devpath=%s: printer identified", g_udev_device_get_sysfs_path(device));
scp_checked = TRUE;
gchar* ps_argv[] = {"ps", "h", "-ocommand", "-Cpython", NULL};
gchar* ps_out;
if (!g_spawn_sync (NULL, ps_argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL,
&ps_out, NULL, NULL, &error)) {
g_warning ("deal_with_scp: error calling ps: %s", error->message);
g_error_free (error);
return TRUE;
}
g_debug_uevent ("deal_with_scp: running python processes:%s", ps_out);
if (strstr (ps_out, "system-config-printer") != NULL) {
g_debug_uevent ("deal_with_scp: system-config-printer already running");
return TRUE;
}
g_debug_uevent ("deal_with_scp: launching system-config-printer");
gchar* scp_argv[] = {"system-config-printer-applet", NULL};
error = NULL;
if (!g_spawn_async(NULL, scp_argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, &error)) {
g_warning("%s could not be called: %s", scp_argv[0], error->message);
g_error_free (error);
}
return TRUE;
}
static void
on_uevent (GUdevClient *client,
gchar *action,
GUdevDevice *device,
gpointer user_data)
{
g_debug_uevent ("uevent.c on_uevent: action=%s, devpath=%s", action, g_udev_device_get_sysfs_path(device));
if (g_strcmp0 (action, "add") != 0 && g_strcmp0 (action, "change") != 0)
return;
if (deal_with_scp(device))
return;
}
void
uevent_init(void)
{
const gchar* subsystems[] = {"firmware", "usb", NULL};
struct utsname u;
if (uname (&u) != 0) {
g_warning("uname() failed, not monitoring devices");
return;
}
GUdevClient* gudev = g_udev_client_new (subsystems);
g_signal_connect (gudev, "uevent", G_CALLBACK (on_uevent), NULL);
/* cold plug HPLIP devices */
GList *usb_devices, *elem;
usb_devices = g_udev_client_query_by_subsystem (gudev, "usb");
for (elem = usb_devices; elem != NULL; elem = g_list_next(elem)) {
deal_with_scp(elem->data);
g_object_unref(elem->data);
}
g_list_free(usb_devices);
}
#else
#include <glib.h>
void
uevent_init(void)
{
g_warning("Printer monitoring disabled.");
}
#endif // HAVE_GUDEV
|