[gnome-control-center] printers: Add functions for searching for LPD printers
- From: Marek Kašík <mkasik src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-control-center] printers: Add functions for searching for LPD printers
- Date: Thu, 31 Jul 2014 09:46:32 +0000 (UTC)
commit 7eded1afa54d818f362c8692cd66dfb64269b0ff
Author: Marek Kasik <mkasik redhat com>
Date: Wed Jul 30 15:37:46 2014 +0200
printers: Add functions for searching for LPD printers
Add pp_host_get_lpd_devices_async() and
pp_host_get_lpd_devices_finish() functions to PpHost class.
pp_host_get_lpd_devices_async() starts searching for LPD printer
on given address.
The test consist in connection to the default port 515 (or the one
given by creator of PpHost) of the address and sending a print job
to it, which in turn returns a status (we test several standard
queue names).
We suppose that there is a LPD printer on the address if a buffer
with zero length is returned (rfc 1179 5.2).
https://bugzilla.gnome.org/show_bug.cgi?id=695564
panels/printers/pp-host.c | 222 ++++++++++++++++++++++++++++++++++++++++++++
panels/printers/pp-host.h | 10 ++
panels/printers/pp-utils.h | 3 +-
3 files changed, 234 insertions(+), 1 deletions(-)
---
diff --git a/panels/printers/pp-host.c b/panels/printers/pp-host.c
index 4ce6652..081a3d2 100644
--- a/panels/printers/pp-host.c
+++ b/panels/printers/pp-host.c
@@ -22,6 +22,8 @@
#include <glib/gi18n.h>
+#define BUFFER_LENGTH 1024
+
struct _PpHostPrivate
{
gchar *hostname;
@@ -577,3 +579,223 @@ pp_host_get_jetdirect_devices_finish (PpHost *host,
return g_task_propagate_pointer (G_TASK (res), error);
}
+
+static gboolean
+test_lpd_queue (GSocketClient *client,
+ gchar *address,
+ gint port,
+ GCancellable *cancellable,
+ gchar *queue_name)
+{
+ GSocketConnection *connection;
+ gboolean result = FALSE;
+ GError *error = NULL;
+
+ connection = g_socket_client_connect_to_host (client,
+ address,
+ port,
+ cancellable,
+ &error);
+
+ if (connection != NULL)
+ {
+ if (G_IS_TCP_CONNECTION (connection))
+ {
+ GOutputStream *output;
+ GInputStream *input;
+ gssize bytes_read, bytes_written;
+ gchar buffer[BUFFER_LENGTH];
+ gint length;
+
+ output = g_io_stream_get_output_stream (G_IO_STREAM (connection));
+ input = g_io_stream_get_input_stream (G_IO_STREAM (connection));
+
+ /* This LPD command is explained in RFC 1179, section 5.2 */
+ length = g_snprintf (buffer, BUFFER_LENGTH, "\2%s\n", queue_name);
+
+ bytes_written = g_output_stream_write (output,
+ buffer,
+ length,
+ NULL,
+ &error);
+
+ if (bytes_written != -1)
+ {
+ bytes_read = g_input_stream_read (input,
+ buffer,
+ BUFFER_LENGTH,
+ NULL,
+ &error);
+
+ if (bytes_read != -1)
+ {
+ if (bytes_read > 0 && buffer[0] == 0)
+ {
+ /* This LPD command is explained in RFC 1179, section 6.1 */
+ length = g_snprintf (buffer, BUFFER_LENGTH, "\1\n");
+
+ bytes_written = g_output_stream_write (output,
+ buffer,
+ length,
+ NULL,
+ &error);
+
+ result = TRUE;
+ }
+ }
+ else
+ {
+ g_clear_error (&error);
+ }
+ }
+ else
+ {
+ g_clear_error (&error);
+ }
+ }
+
+ g_io_stream_close (G_IO_STREAM (connection), NULL, NULL);
+ g_object_unref (connection);
+ }
+
+ return result;
+}
+
+static void
+_pp_host_get_lpd_devices_thread (GTask *task,
+ gpointer source_object,
+ gpointer task_data,
+ GCancellable *cancellable)
+{
+ GSocketConnection *connection;
+ PpPrintDevice *device;
+ PpHost *host = (PpHost *) source_object;
+ PpHostPrivate *priv = host->priv;
+ GSocketClient *client;
+ PpDevicesList *result;
+ GSDData *data = (GSDData *) task_data;
+ GError *error = NULL;
+ GList *candidates = NULL;
+ GList *iter;
+ gchar *found_queue = NULL;
+ gchar *candidate;
+ gchar *address;
+ gint port;
+ gint i;
+
+ if (priv->port == PP_HOST_UNSET_PORT)
+ port = PP_HOST_DEFAULT_LPD_PORT;
+ else
+ port = priv->port;
+
+ address = g_strdup_printf ("%s:%d", priv->hostname, port);
+ if (address == NULL || address[0] == '/')
+ goto out;
+
+ result = data->devices;
+ data->devices = NULL;
+
+ client = g_socket_client_new ();
+
+ connection = g_socket_client_connect_to_host (client,
+ address,
+ port,
+ cancellable,
+ &error);
+
+ if (connection != NULL)
+ {
+ g_io_stream_close (G_IO_STREAM (connection), NULL, NULL);
+ g_object_unref (connection);
+
+ /* Most of this list is taken from system-config-printer */
+ candidates = g_list_append (candidates, g_strdup ("PASSTHRU"));
+ candidates = g_list_append (candidates, g_strdup ("AUTO"));
+ candidates = g_list_append (candidates, g_strdup ("BINPS"));
+ candidates = g_list_append (candidates, g_strdup ("RAW"));
+ candidates = g_list_append (candidates, g_strdup ("TEXT"));
+ candidates = g_list_append (candidates, g_strdup ("ps"));
+ candidates = g_list_append (candidates, g_strdup ("lp"));
+ candidates = g_list_append (candidates, g_strdup ("PORT1"));
+
+ for (i = 0; i < 8; i++)
+ {
+ candidates = g_list_append (candidates, g_strdup_printf ("LPT%d", i));
+ candidates = g_list_append (candidates, g_strdup_printf ("LPT%d_PASSTHRU", i));
+ candidates = g_list_append (candidates, g_strdup_printf ("COM%d", i));
+ candidates = g_list_append (candidates, g_strdup_printf ("COM%d_PASSTHRU", i));
+ }
+
+ for (i = 0; i < 50; i++)
+ candidates = g_list_append (candidates, g_strdup_printf ("pr%d", i));
+
+ for (iter = candidates; iter != NULL; iter = iter->next)
+ {
+ candidate = (gchar *) iter->data;
+
+ if (test_lpd_queue (client,
+ address,
+ port,
+ cancellable,
+ candidate))
+ {
+ found_queue = g_strdup (candidate);
+ break;
+ }
+ }
+
+ if (found_queue != NULL)
+ {
+ device = g_new0 (PpPrintDevice, 1);
+ device->device_class = g_strdup ("network");
+ device->device_uri = g_strdup_printf ("lpd://%s:%d/%s",
+ priv->hostname,
+ port,
+ found_queue);
+ /* Translators: The found device is a Line Printer Daemon printer */
+ device->device_name = g_strdup (_("LPD Printer"));
+ device->host_name = g_strdup (priv->hostname);
+ device->host_port = port;
+ device->acquisition_method = ACQUISITION_METHOD_LPD;
+
+ result->devices = g_list_append (result->devices, device);
+ }
+
+ g_list_free_full (candidates, g_free);
+ }
+
+ g_object_unref (client);
+
+out:
+ g_task_return_pointer (task, result, (GDestroyNotify) pp_devices_list_free);
+ g_object_unref (task);
+
+ g_free (address);
+}
+
+void
+pp_host_get_lpd_devices_async (PpHost *host,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSDData *data;
+ GTask *task;
+
+ data = g_new0 (GSDData, 1);
+ data->devices = g_new0 (PpDevicesList, 1);
+
+ task = g_task_new (G_OBJECT (host), cancellable, callback, user_data);
+ g_task_set_task_data (task, data, (GDestroyNotify) gsd_data_free);
+ g_task_run_in_thread (task, _pp_host_get_lpd_devices_thread);
+}
+
+PpDevicesList *
+pp_host_get_lpd_devices_finish (PpHost *host,
+ GAsyncResult *res,
+ GError **error)
+{
+ g_return_val_if_fail (g_task_is_valid (res, host), NULL);
+
+ return g_task_propagate_pointer (G_TASK (res), error);
+}
diff --git a/panels/printers/pp-host.h b/panels/printers/pp-host.h
index b5347a5..5483d85 100644
--- a/panels/printers/pp-host.h
+++ b/panels/printers/pp-host.h
@@ -37,6 +37,7 @@ G_BEGIN_DECLS
#define PP_HOST_UNSET_PORT -1
#define PP_HOST_DEFAULT_IPP_PORT 631
#define PP_HOST_DEFAULT_JETDIRECT_PORT 9100
+#define PP_HOST_DEFAULT_LPD_PORT 515
typedef struct _PpHost PpHost;
typedef struct _PpHostClass PpHostClass;
@@ -84,6 +85,15 @@ PpDevicesList *pp_host_get_jetdirect_devices_finish (PpHost *hos
GAsyncResult *result,
GError **error);
+void pp_host_get_lpd_devices_async (PpHost *host,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+PpDevicesList *pp_host_get_lpd_devices_finish (PpHost *host,
+ GAsyncResult *result,
+ GError **error);
+
G_END_DECLS
#endif /* __PP_HOST_H__ */
diff --git a/panels/printers/pp-utils.h b/panels/printers/pp-utils.h
index cd7a515..3850976 100644
--- a/panels/printers/pp-utils.h
+++ b/panels/printers/pp-utils.h
@@ -54,7 +54,8 @@ enum
ACQUISITION_METHOD_SNMP,
ACQUISITION_METHOD_SAMBA,
ACQUISITION_METHOD_SAMBA_HOST,
- ACQUISITION_METHOD_JETDIRECT
+ ACQUISITION_METHOD_JETDIRECT,
+ ACQUISITION_METHOD_LPD
};
typedef struct
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]