1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
3
* Copyright 2012 Red Hat, Inc,
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 2 of the License, or
8
* (at your option) any later version.
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.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19
* Author: Marek Kasik <mkasik@redhat.com>
30
G_DEFINE_TYPE (PpHost, pp_host, G_TYPE_OBJECT);
39
pp_host_finalize (GObject *object)
43
priv = PP_HOST (object)->priv;
45
g_clear_pointer (&priv->hostname, g_free);
47
G_OBJECT_CLASS (pp_host_parent_class)->finalize (object);
51
pp_host_get_property (GObject *object,
54
GParamSpec *param_spec)
58
self = PP_HOST (object);
63
g_value_set_string (value, self->priv->hostname);
66
g_value_set_int (value, self->priv->port);
69
G_OBJECT_WARN_INVALID_PROPERTY_ID (object,
77
pp_host_set_property (GObject *object,
80
GParamSpec *param_spec)
82
PpHost *self = PP_HOST (object);
87
g_free (self->priv->hostname);
88
self->priv->hostname = g_value_dup_string (value);
91
self->priv->port = g_value_get_int (value);
94
G_OBJECT_WARN_INVALID_PROPERTY_ID (object,
102
pp_host_class_init (PpHostClass *klass)
104
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
106
g_type_class_add_private (klass, sizeof (PpHostPrivate));
108
gobject_class->set_property = pp_host_set_property;
109
gobject_class->get_property = pp_host_get_property;
110
gobject_class->finalize = pp_host_finalize;
112
g_object_class_install_property (gobject_class, PROP_HOSTNAME,
113
g_param_spec_string ("hostname",
119
g_object_class_install_property (gobject_class, PROP_PORT,
120
g_param_spec_int ("port",
128
pp_host_init (PpHost *host)
130
host->priv = G_TYPE_INSTANCE_GET_PRIVATE (host,
136
pp_host_new (const gchar *hostname,
139
return g_object_new (PP_TYPE_HOST,
140
"hostname", hostname,
147
PpDevicesList *devices;
151
line_split (gchar *line)
153
gboolean escaped = FALSE;
154
gboolean quoted = FALSE;
155
gboolean in_word = FALSE;
156
gchar **words = NULL;
157
gchar **result = NULL;
158
gchar *buffer = NULL;
161
gint i, j = 0, k = 0;
166
words = g_new0 (gchar *, n + 1);
167
buffer = g_new0 (gchar, n + 1);
169
for (i = 0; i < n; i++)
196
else if (g_ascii_isspace (ch))
198
words[j++] = g_strdup (buffer);
199
memset (buffer, 0, n + 1);
215
else if (!g_ascii_isspace (ch))
224
if (buffer && buffer[0] != '\0')
225
words[j++] = g_strdup (buffer);
227
result = g_strdupv (words);
235
_pp_host_get_snmp_devices_thread (GSimpleAsyncResult *res,
237
GCancellable *cancellable)
239
PpHost *host = (PpHost *) object;
240
PpHostPrivate *priv = host->priv;
241
PpPrintDevice *device;
245
gchar *stdout_string = NULL;
246
gchar *stderr_string = NULL;
249
data = g_simple_async_result_get_op_res_gpointer (res);
250
data->devices = g_new0 (PpDevicesList, 1);
251
data->devices->devices = NULL;
253
argv = g_new0 (gchar *, 3);
254
argv[0] = g_strdup ("/usr/lib/cups/backend/snmp");
255
argv[1] = g_strdup (priv->hostname);
257
/* Use SNMP to get printer's informations */
273
if (exit_status == 0 && stdout_string)
275
gchar **printer_informations = NULL;
278
printer_informations = line_split (stdout_string);
279
length = g_strv_length (printer_informations);
283
device = g_new0 (PpPrintDevice, 1);
285
device->device_class = g_strdup (printer_informations[0]);
286
device->device_uri = g_strdup (printer_informations[1]);
287
device->device_make_and_model = g_strdup (printer_informations[2]);
288
device->device_info = g_strdup (printer_informations[3]);
289
device->device_name = g_strdup (printer_informations[3]);
290
device->device_name =
291
g_strcanon (device->device_name, ALLOWED_CHARACTERS, '-');
292
device->acquisition_method = ACQUISITION_METHOD_SNMP;
294
if (length >= 5 && printer_informations[4][0] != '\0')
295
device->device_id = g_strdup (printer_informations[4]);
297
if (length >= 6 && printer_informations[5][0] != '\0')
298
device->device_location = g_strdup (printer_informations[5]);
300
data->devices->devices = g_list_append (data->devices->devices, device);
303
g_strfreev (printer_informations);
304
g_free (stdout_string);
309
gsd_data_free (GSDData *data)
317
if (data->devices->devices)
319
for (iter = data->devices->devices; iter; iter = iter->next)
320
pp_print_device_free ((PpPrintDevice *) iter->data);
321
g_list_free (data->devices->devices);
324
g_free (data->devices);
332
pp_host_get_snmp_devices_async (PpHost *host,
333
GCancellable *cancellable,
334
GAsyncReadyCallback callback,
337
GSimpleAsyncResult *res;
340
res = g_simple_async_result_new (G_OBJECT (host), callback, user_data, pp_host_get_snmp_devices_async);
341
data = g_new0 (GSDData, 1);
342
data->devices = NULL;
344
g_simple_async_result_set_check_cancellable (res, cancellable);
345
g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify) gsd_data_free);
346
g_simple_async_result_run_in_thread (res, _pp_host_get_snmp_devices_thread, 0, cancellable);
348
g_object_unref (res);
352
pp_host_get_snmp_devices_finish (PpHost *host,
356
GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
358
PpDevicesList *result;
360
g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == pp_host_get_snmp_devices_async);
362
if (g_simple_async_result_propagate_error (simple, error))
365
data = g_simple_async_result_get_op_res_gpointer (simple);
366
result = data->devices;
367
data->devices = NULL;
373
_pp_host_get_remote_cups_devices_thread (GSimpleAsyncResult *res,
375
GCancellable *cancellable)
377
cups_dest_t *dests = NULL;
379
PpHost *host = (PpHost *) object;
380
PpHostPrivate *priv = host->priv;
381
PpPrintDevice *device;
383
gint num_of_devices = 0;
386
data = g_simple_async_result_get_op_res_gpointer (res);
387
data->devices = g_new0 (PpDevicesList, 1);
388
data->devices->devices = NULL;
390
/* Connect to remote CUPS server and get its devices */
391
http = httpConnect (priv->hostname, priv->port);
394
num_of_devices = cupsGetDests2 (http, &dests);
395
if (num_of_devices > 0)
397
for (i = 0; i < num_of_devices; i++)
399
device = g_new0 (PpPrintDevice, 1);
400
device->device_class = g_strdup ("network");
401
device->device_uri = g_strdup_printf ("ipp://%s:%d/printers/%s",
405
device->device_name = g_strdup (dests[i].name);
406
device->device_location = g_strdup (cupsGetOption ("printer-location",
407
dests[i].num_options,
409
device->host_name = g_strdup (priv->hostname);
410
device->host_port = priv->port;
411
device->acquisition_method = ACQUISITION_METHOD_REMOTE_CUPS_SERVER;
412
data->devices->devices = g_list_append (data->devices->devices, device);
421
pp_host_get_remote_cups_devices_async (PpHost *host,
422
GCancellable *cancellable,
423
GAsyncReadyCallback callback,
426
GSimpleAsyncResult *res;
429
res = g_simple_async_result_new (G_OBJECT (host), callback, user_data, pp_host_get_remote_cups_devices_async);
430
data = g_new0 (GSDData, 1);
431
data->devices = NULL;
433
g_simple_async_result_set_check_cancellable (res, cancellable);
434
g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify) gsd_data_free);
435
g_simple_async_result_run_in_thread (res, _pp_host_get_remote_cups_devices_thread, 0, cancellable);
437
g_object_unref (res);
441
pp_host_get_remote_cups_devices_finish (PpHost *host,
445
GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
447
PpDevicesList *result;
449
g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == pp_host_get_remote_cups_devices_async);
451
if (g_simple_async_result_propagate_error (simple, error))
454
data = g_simple_async_result_get_op_res_gpointer (simple);
455
result = data->devices;
456
data->devices = NULL;