From 82562ae5ddd7e50428aaedb5eb1edeec57c3f54f Mon Sep 17 00:00:00 2001 From: Marek Kasik Date: Wed, 16 Sep 2009 14:54:05 +0200 Subject: [PATCH] Add support for 'auth-info' attribute to the CUPS backend Check for 'auth-info-required' attribute from printer attributes to find out whether an authentization of user is needed. Change password dialog of print backend to be able to require informations requested thru 'auth-info-required' (#566522). --- gtk/gtkmarshalers.list | 1 + gtk/gtkprintbackend.c | 164 +++++++------- gtk/gtkprintbackend.h | 16 +- modules/printbackends/cups/gtkcupsutils.c | 5 + modules/printbackends/cups/gtkcupsutils.h | 3 + modules/printbackends/cups/gtkprintbackendcups.c | 255 ++++++++++++++++++++-- modules/printbackends/cups/gtkprintercups.c | 2 + modules/printbackends/cups/gtkprintercups.h | 1 + 8 files changed, 339 insertions(+), 108 deletions(-) diff --git a/gtk/gtkmarshalers.list b/gtk/gtkmarshalers.list index 533a266..77873cb 100644 --- a/gtk/gtkmarshalers.list +++ b/gtk/gtkmarshalers.list @@ -111,3 +111,4 @@ VOID:UINT,STRING,UINT VOID:UINT,UINT VOID:VOID OBJECT:OBJECT,INT,INT +VOID:POINTER,POINTER,POINTER,POINTER,STRING diff --git a/gtk/gtkprintbackend.c b/gtk/gtkprintbackend.c index 567273b..3c64823 100644 --- a/gtk/gtkprintbackend.c +++ b/gtk/gtkprintbackend.c @@ -50,9 +50,8 @@ struct _GtkPrintBackendPrivate guint printer_list_requested : 1; guint printer_list_done : 1; GtkPrintBackendStatus status; - char *hostname; - char *username; - char *password; + char **auth_info_required; + char **auth_info; }; enum { @@ -359,8 +358,10 @@ static GList * fallback_printer_list_papers (GtkPrinter static GtkPageSetup * fallback_printer_get_default_page_size (GtkPrinter *printer); static GtkPrintCapabilities fallback_printer_get_capabilities (GtkPrinter *printer); static void request_password (GtkPrintBackend *backend, - const gchar *hostname, - const gchar *username, + gpointer auth_info_required, + gpointer auth_info_default, + gpointer auth_info_display, + gpointer auth_info_visible, const gchar *prompt); static void @@ -441,8 +442,8 @@ gtk_print_backend_class_init (GtkPrintBackendClass *class) G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GtkPrintBackendClass, request_password), NULL, NULL, - _gtk_marshal_VOID__STRING_STRING_STRING, - G_TYPE_NONE, 3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING); + _gtk_marshal_VOID__POINTER_POINTER_POINTER_POINTER_STRING, + G_TYPE_NONE, 5, G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_STRING); } static void @@ -455,9 +456,8 @@ gtk_print_backend_init (GtkPrintBackend *backend) priv->printers = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) g_free, (GDestroyNotify) g_object_unref); - priv->hostname = NULL; - priv->username = NULL; - priv->password = NULL; + priv->auth_info_required = NULL; + priv->auth_info = NULL; } static void @@ -662,40 +662,29 @@ gtk_print_backend_print_stream (GtkPrintBackend *backend, } void -gtk_print_backend_set_password (GtkPrintBackend *backend, - const gchar *hostname, - const gchar *username, - const gchar *password) +gtk_print_backend_set_password (GtkPrintBackend *backend, + gchar **auth_info_required, + gchar **auth_info) { g_return_if_fail (GTK_IS_PRINT_BACKEND (backend)); if (GTK_PRINT_BACKEND_GET_CLASS (backend)->set_password) - GTK_PRINT_BACKEND_GET_CLASS (backend)->set_password (backend, hostname, username, password); + GTK_PRINT_BACKEND_GET_CLASS (backend)->set_password (backend, auth_info_required, auth_info); } static void -store_password (GtkEntry *entry, - GtkPrintBackend *backend) +store_entry (GtkEntry *entry, + gpointer user_data) { - GtkPrintBackendPrivate *priv = backend->priv; + gchar **data = (gchar **) user_data; - if (priv->password != NULL) + if (*data != NULL) { - memset (priv->password, 0, strlen (priv->password)); - g_free (priv->password); + memset (*data, 0, strlen (*data)); + g_free (*data); } - priv->password = g_strdup (gtk_entry_get_text (entry)); -} - -static void -store_username (GtkEntry *entry, - GtkPrintBackend *backend) -{ - GtkPrintBackendPrivate *priv = backend->priv; - - g_free (priv->username); - priv->username = g_strdup (gtk_entry_get_text (entry)); + *data = g_strdup (gtk_entry_get_text (entry)); } static void @@ -704,21 +693,24 @@ password_dialog_response (GtkWidget *dialog, GtkPrintBackend *backend) { GtkPrintBackendPrivate *priv = backend->priv; + gint i; if (response_id == GTK_RESPONSE_OK) - gtk_print_backend_set_password (backend, priv->hostname, priv->username, priv->password); + gtk_print_backend_set_password (backend, priv->auth_info_required, priv->auth_info); else - gtk_print_backend_set_password (backend, priv->hostname, priv->username, NULL); + gtk_print_backend_set_password (backend, priv->auth_info_required, NULL); - if (priv->password != NULL) - { - memset (priv->password, 0, strlen (priv->password)); - g_free (priv->password); - priv->password = NULL; - } + for (i = 0; i < g_strv_length (priv->auth_info_required); i++) + if (priv->auth_info[i] != NULL) + { + memset (priv->auth_info[i], 0, strlen (priv->auth_info[i])); + g_free (priv->auth_info[i]); + priv->auth_info[i] = NULL; + } + g_free (priv->auth_info); + priv->auth_info = NULL; - g_free (priv->username); - priv->username = NULL; + g_strfreev (priv->auth_info_required); gtk_widget_destroy (dialog); @@ -726,16 +718,27 @@ password_dialog_response (GtkWidget *dialog, } static void -request_password (GtkPrintBackend *backend, - const gchar *hostname, - const gchar *username, - const gchar *prompt) +request_password (GtkPrintBackend *backend, + gpointer auth_info_required, + gpointer auth_info_default, + gpointer auth_info_display, + gpointer auth_info_visible, + const gchar *prompt) { GtkPrintBackendPrivate *priv = backend->priv; - GtkWidget *dialog, *username_box, *password_box, *main_box, *label, *icon, *vbox, - *password_prompt, *username_prompt, - *password_entry, *username_entry; + GtkWidget *dialog, *box, *main_box, *label, *icon, *vbox, *entry; + GtkWidget *focus = NULL; gchar *markup; + gint length; + gint i; + gchar **ai_required = (gchar **) auth_info_required; + gchar **ai_default = (gchar **) auth_info_default; + gchar **ai_display = (gchar **) auth_info_display; + gboolean *ai_visible = (gboolean *) auth_info_visible; + + priv->auth_info_required = g_strdupv (ai_required); + length = g_strv_length (ai_required); + priv->auth_info = g_new0 (gchar *, length); dialog = gtk_dialog_new_with_buttons ( _("Authentication"), NULL, GTK_DIALOG_MODAL, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, @@ -766,27 +769,6 @@ request_password (GtkPrintBackend *backend, g_free (markup); - /* Right - 2. */ - username_box = gtk_hbox_new (TRUE, 0); - - username_prompt = gtk_label_new (_("Username:")); - gtk_misc_set_alignment (GTK_MISC (username_prompt), 0.0, 0.5); - - username_entry = gtk_entry_new (); - gtk_entry_set_text (GTK_ENTRY (username_entry), username); - - - /* Right - 3. */ - password_box = gtk_hbox_new (TRUE, 0); - - password_prompt = gtk_label_new (_("Password:")); - gtk_misc_set_alignment (GTK_MISC (password_prompt), 0.0, 0.5); - - password_entry = gtk_entry_new (); - gtk_entry_set_visibility (GTK_ENTRY (password_entry), FALSE); - gtk_entry_set_activates_default (GTK_ENTRY (password_entry), TRUE); - - /* Packing */ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), main_box, TRUE, FALSE, 0); @@ -794,26 +776,42 @@ request_password (GtkPrintBackend *backend, gtk_box_pack_start (GTK_BOX (main_box), vbox, FALSE, FALSE, 6); gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, TRUE, 6); - gtk_box_pack_start (GTK_BOX (vbox), username_box, FALSE, TRUE, 6); - gtk_box_pack_start (GTK_BOX (vbox), password_box, FALSE, TRUE, 6); + + /* Right - 2. */ + for (i = 0; i < length; i++) + { + priv->auth_info[i] = g_strdup (ai_default[i]); + if (ai_display[i] != NULL) + { + box = gtk_hbox_new (TRUE, 0); + + label = gtk_label_new (ai_display[i]); + gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); - gtk_box_pack_start (GTK_BOX (username_box), username_prompt, TRUE, TRUE, 0); - gtk_box_pack_start (GTK_BOX (username_box), username_entry, TRUE, TRUE, 0); + entry = gtk_entry_new (); + focus = entry; - gtk_box_pack_start (GTK_BOX (password_box), password_prompt, TRUE, TRUE, 0); - gtk_box_pack_start (GTK_BOX (password_box), password_entry, TRUE, TRUE, 0); + if (ai_default[i] != NULL) + gtk_entry_set_text (GTK_ENTRY (entry), ai_default[i]); + gtk_entry_set_visibility (GTK_ENTRY (entry), ai_visible[i]); + gtk_entry_set_activates_default (GTK_ENTRY (entry), TRUE); - gtk_widget_grab_focus (password_entry); + gtk_box_pack_start (GTK_BOX (vbox), box, FALSE, TRUE, 6); - priv->hostname = g_strdup (hostname); - priv->username = g_strdup (username); + gtk_box_pack_start (GTK_BOX (box), label, TRUE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (box), entry, TRUE, TRUE, 0); - g_signal_connect (password_entry, "changed", - G_CALLBACK (store_password), backend); + g_signal_connect (entry, "changed", + G_CALLBACK (store_entry), &(priv->auth_info[i])); + } + } - g_signal_connect (username_entry, "changed", - G_CALLBACK (store_username), backend); + if (focus != NULL) + { + gtk_widget_grab_focus (focus); + focus = NULL; + } g_object_ref (backend); g_signal_connect (G_OBJECT (dialog), "response", diff --git a/gtk/gtkprintbackend.h b/gtk/gtkprintbackend.h index 7d75f8e..c4b43b1 100644 --- a/gtk/gtkprintbackend.h +++ b/gtk/gtkprintbackend.h @@ -121,15 +121,16 @@ struct _GtkPrintBackendClass void (*printer_status_changed) (GtkPrintBackend *backend, GtkPrinter *printer); void (*request_password) (GtkPrintBackend *backend, - const gchar *hostname, - const gchar *username, + gpointer auth_info_required, + gpointer auth_info_default, + gpointer auth_info_display, + gpointer auth_info_visible, const gchar *prompt); /* not a signal */ void (*set_password) (GtkPrintBackend *backend, - const gchar *hostname, - const gchar *username, - const gchar *password); + gchar **auth_info_required, + gchar **auth_info); /* Padding for future expansion */ void (*_gtk_reserved1) (void); @@ -153,9 +154,8 @@ void gtk_print_backend_print_stream (GtkPrintBackend *pri GList * gtk_print_backend_load_modules (void); void gtk_print_backend_destroy (GtkPrintBackend *print_backend); void gtk_print_backend_set_password (GtkPrintBackend *backend, - const gchar *hostname, - const gchar *username, - const gchar *password); + gchar **auth_info_required, + gchar **auth_info); /* Backend-only functions for GtkPrintBackend */ diff --git a/modules/printbackends/cups/gtkcupsutils.c b/modules/printbackends/cups/gtkcupsutils.c index bcd03dc..cd97f10 100644 --- a/modules/printbackends/cups/gtkcupsutils.c +++ b/modules/printbackends/cups/gtkcupsutils.c @@ -187,6 +187,10 @@ gtk_cups_request_new_with_username (http_t *connection, "requesting-user-name", NULL, cupsUser ()); + request->auth_info_required = NULL; + request->auth_info = NULL; + request->need_auth_info = FALSE; + cupsLangFree (language); return request; @@ -241,6 +245,7 @@ gtk_cups_request_free (GtkCupsRequest *request) } g_free (request->username); + g_strfreev (request->auth_info_required); gtk_cups_result_free (request->result); diff --git a/modules/printbackends/cups/gtkcupsutils.h b/modules/printbackends/cups/gtkcupsutils.h index 47fd106..ba43f87 100644 --- a/modules/printbackends/cups/gtkcupsutils.h +++ b/modules/printbackends/cups/gtkcupsutils.h @@ -99,6 +99,9 @@ struct _GtkCupsRequest gint own_http : 1; gint need_password : 1; + gint need_auth_info : 1; + gchar **auth_info_required; + gchar **auth_info; GtkCupsPasswordState password_state; }; diff --git a/modules/printbackends/cups/gtkprintbackendcups.c b/modules/printbackends/cups/gtkprintbackendcups.c index 92d4b9b..b715817 100644 --- a/modules/printbackends/cups/gtkprintbackendcups.c +++ b/modules/printbackends/cups/gtkprintbackendcups.c @@ -94,6 +94,8 @@ typedef struct GtkCupsRequest *request; GPollFD *data_poll; GtkPrintBackendCups *backend; + GtkPrintCupsResponseCallbackFunc callback; + gpointer callback_data; } GtkPrintCupsDispatchWatch; @@ -179,13 +181,13 @@ static cairo_surface_t * cups_printer_create_cairo_surface (GtkPrinter gdouble height, GIOChannel *cache_io); -static void gtk_print_backend_cups_set_password (GtkPrintBackend *backend, - const gchar *hostname, - const gchar *username, - const gchar *password); +static void gtk_print_backend_cups_set_password (GtkPrintBackend *backend, + gchar **auth_info_required, + gchar **auth_info); -void overwrite_and_free (gpointer data); -static gboolean is_address_local (const gchar *address); +void overwrite_and_free (gpointer data); +static gboolean is_address_local (const gchar *address); +static gboolean request_auth_info (gpointer data); static void gtk_print_backend_cups_register_type (GTypeModule *module) @@ -557,6 +559,9 @@ gtk_print_backend_cups_print_stream (GtkPrintBackend *print_backend, ps->dnotify = dnotify; ps->job = g_object_ref (job); + request->need_auth_info = cups_printer->auth_info_required != NULL; + request->auth_info_required = g_strdupv (cups_printer->auth_info_required); + cups_request_execute (GTK_PRINT_BACKEND_CUPS (print_backend), request, (GtkPrintCupsResponseCallbackFunc) cups_print_cb, @@ -656,18 +661,38 @@ is_address_local (const gchar *address) } static void -gtk_print_backend_cups_set_password (GtkPrintBackend *backend, - const gchar *hostname, - const gchar *username, - const gchar *password) +gtk_print_backend_cups_set_password (GtkPrintBackend *backend, + gchar **auth_info_required, + gchar **auth_info) { GtkPrintBackendCups *cups_backend = GTK_PRINT_BACKEND_CUPS (backend); GList *l; char dispatch_hostname[HTTP_MAX_URI]; gchar *key; + gchar *username = NULL; + gchar *hostname = NULL; + gchar *password = NULL; + gint length; + gint i; - key = g_strconcat (username, "@", hostname, NULL); - g_hash_table_insert (cups_backend->auth, key, g_strdup (password)); + length = g_strv_length (auth_info_required); + + if (auth_info != NULL) + for (i = 0; i < length; i++) + { + if (g_strcmp0 (auth_info_required[i], "username") == 0) + username = g_strdup (auth_info[i]); + else if (g_strcmp0 (auth_info_required[i], "hostname") == 0) + hostname = g_strdup (auth_info[i]); + else if (g_strcmp0 (auth_info_required[i], "password") == 0) + password = g_strdup (auth_info[i]); + } + + if (hostname != NULL && username != NULL && password != NULL) + { + key = g_strconcat (username, "@", hostname, NULL); + g_hash_table_insert (cups_backend->auth, key, g_strdup (password)); + } g_free (cups_backend->username); cups_backend->username = g_strdup (username); @@ -683,7 +708,18 @@ gtk_print_backend_cups_set_password (GtkPrintBackend *backend, if (is_address_local (dispatch_hostname)) strcpy (dispatch_hostname, "localhost"); - if (strcmp (hostname, dispatch_hostname) == 0) + if (dispatch->request->need_auth_info) + { + if (auth_info != NULL) + { + dispatch->request->auth_info = g_new0 (gchar *, length + 1); + for (i = 0; i < length; i++) + dispatch->request->auth_info[i] = g_strdup (auth_info[i]); + } + dispatch->backend->authentication_lock = FALSE; + dispatch->request->need_auth_info = FALSE; + } + else if (dispatch->request->password_state == GTK_CUPS_PASSWORD_REQUESTED || auth_info == NULL) { overwrite_and_free (dispatch->request->password); dispatch->request->password = g_strdup (password); @@ -704,6 +740,12 @@ request_password (gpointer data) gchar *prompt = NULL; gchar *key = NULL; char hostname[HTTP_MAX_URI]; + gchar **auth_info_required; + gchar **auth_info_default; + gchar **auth_info_display; + gboolean *auth_info_visible; + gint length = 3; + gint i; if (dispatch->backend->authentication_lock) return FALSE; @@ -717,6 +759,22 @@ request_password (gpointer data) else username = cupsUser (); + auth_info_required = g_new0 (gchar*, length + 1); + auth_info_required[0] = g_strdup ("hostname"); + auth_info_required[1] = g_strdup ("username"); + auth_info_required[2] = g_strdup ("password"); + + auth_info_default = g_new0 (gchar*, length + 1); + auth_info_default[0] = g_strdup (hostname); + auth_info_default[1] = g_strdup (username); + + auth_info_display = g_new0 (gchar*, length + 1); + auth_info_display[1] = g_strdup (_("Username:")); + auth_info_display[2] = g_strdup (_("Password:")); + + auth_info_visible = g_new0 (gboolean, length + 1); + auth_info_visible[1] = TRUE; + key = g_strconcat (username, "@", hostname, NULL); password = g_hash_table_lookup (dispatch->backend->auth, key); @@ -784,11 +842,22 @@ request_password (gpointer data) g_free (printer_name); g_signal_emit_by_name (dispatch->backend, "request-password", - hostname, username, prompt); + auth_info_required, auth_info_default, auth_info_display, auth_info_visible, prompt); g_free (prompt); } + for (i = 0; i < length; i++) + { + g_free (auth_info_required[i]); + g_free (auth_info_default[i]); + g_free (auth_info_display[i]); + } + + g_free (auth_info_required); + g_free (auth_info_default); + g_free (auth_info_display); + g_free (auth_info_visible); g_free (key); return FALSE; @@ -828,6 +897,133 @@ cups_dispatch_add_poll (GSource *source) } static gboolean +check_auth_info (gpointer user_data) +{ + GtkPrintCupsDispatchWatch *dispatch; + dispatch = (GtkPrintCupsDispatchWatch *) user_data; + + if (!dispatch->request->need_auth_info) + { + if (dispatch->request->auth_info == NULL) + { + dispatch->callback (GTK_PRINT_BACKEND (dispatch->backend), + gtk_cups_request_get_result (dispatch->request), + dispatch->callback_data); + g_source_destroy ((GSource *) dispatch); + } + else + { + gint length; + gint i; + + length = g_strv_length (dispatch->request->auth_info_required); + + gtk_cups_request_ipp_add_strings (dispatch->request, + IPP_TAG_JOB, + IPP_TAG_TEXT, + "auth-info", + length, + NULL, + dispatch->request->auth_info); + + g_source_attach ((GSource *) dispatch, NULL); + g_source_unref ((GSource *) dispatch); + + for (i = 0; i < length; i++) + overwrite_and_free (dispatch->request->auth_info[i]); + g_free (dispatch->request->auth_info); + dispatch->request->auth_info = NULL; + } + + return FALSE; + } + + return TRUE; +} + +static gboolean +request_auth_info (gpointer user_data) +{ + GtkPrintCupsDispatchWatch *dispatch; + const char *job_title; + const char *printer_uri; + gchar *prompt = NULL; + char *printer_name = NULL; + gint length; + gint i; + gboolean *auth_info_visible = NULL; + gchar **auth_info_default = NULL; + gchar **auth_info_display = NULL; + + dispatch = (GtkPrintCupsDispatchWatch *) user_data; + + if (dispatch->backend->authentication_lock) + return FALSE; + + job_title = gtk_cups_request_ipp_get_string (dispatch->request, IPP_TAG_NAME, "job-name"); + printer_uri = gtk_cups_request_ipp_get_string (dispatch->request, IPP_TAG_URI, "printer-uri"); + length = g_strv_length (dispatch->request->auth_info_required); + + auth_info_visible = g_new0 (gboolean, length); + auth_info_default = g_new0 (gchar *, length + 1); + auth_info_display = g_new0 (gchar *, length + 1); + + for (i = 0; i < length; i++) + { + if (g_strcmp0 (dispatch->request->auth_info_required[i], "domain") == 0) + { + auth_info_display[i] = g_strdup (_("Domain:")); + auth_info_default[i] = g_strdup ("WORKGROUP"); + auth_info_visible[i] = TRUE; + } + else if (g_strcmp0 (dispatch->request->auth_info_required[i], "username") == 0) + { + auth_info_display[i] = g_strdup (_("Username:")); + if (dispatch->backend->username != NULL) + auth_info_default[i] = g_strdup (dispatch->backend->username); + else + auth_info_default[i] = g_strdup (cupsUser ()); + auth_info_visible[i] = TRUE; + } + else if (g_strcmp0 (dispatch->request->auth_info_required[i], "password") == 0) + { + auth_info_display[i] = g_strdup (_("Password:")); + auth_info_visible[i] = FALSE; + } + } + + if (printer_uri != NULL && strrchr (printer_uri, '/') != NULL) + printer_name = g_strdup (strrchr (printer_uri, '/') + 1); + + dispatch->backend->authentication_lock = TRUE; + + if (job_title != NULL && printer_name != NULL) + prompt = g_strdup_printf ( _("Authentication informations are required to print document '%s' on printer %s"), job_title, printer_name); + + g_signal_emit_by_name (dispatch->backend, "request-password", + dispatch->request->auth_info_required, + auth_info_default, + auth_info_display, + auth_info_visible, + prompt); + + for (i = 0; i < length; i++) + { + g_free (auth_info_default[i]); + g_free (auth_info_display[i]); + } + + g_free (auth_info_default); + g_free (auth_info_display); + g_free (printer_name); + g_free (prompt); + + g_idle_add (check_auth_info, user_data); + + return FALSE; +} + +static gboolean cups_dispatch_watch_check (GSource *source) { GtkPrintCupsDispatchWatch *dispatch; @@ -1008,13 +1204,24 @@ cups_request_execute (GtkPrintBackendCups *print_backend, dispatch->request = request; dispatch->backend = g_object_ref (print_backend); dispatch->data_poll = NULL; + dispatch->callback = NULL; + dispatch->callback_data = NULL; print_backend->requests = g_list_prepend (print_backend->requests, dispatch); g_source_set_callback ((GSource *) dispatch, (GSourceFunc) callback, user_data, notify); - g_source_attach ((GSource *) dispatch, NULL); - g_source_unref ((GSource *) dispatch); + if (request->need_auth_info) + { + dispatch->callback = callback; + dispatch->callback_data = user_data; + request_auth_info (dispatch); + } + else + { + g_source_attach ((GSource *) dispatch, NULL); + g_source_unref ((GSource *) dispatch); + } } #if 0 @@ -1435,6 +1642,7 @@ cups_request_printer_list_cb (GtkPrintBackendCups *cups_backend, gchar *default_cover_before = NULL; gchar *default_cover_after = NULL; gboolean remote_printer = FALSE; + gchar **auth_info_required = NULL; /* Skip leading attributes until we hit a printer... */ @@ -1553,6 +1761,15 @@ cups_request_printer_list_cb (GtkPrintBackendCups *cups_backend, else remote_printer = FALSE; } + else if (strcmp (attr->name, "auth-info-required") == 0) + { + if (strcmp (attr->values[0].string.text, "none") != 0) + { + auth_info_required = g_new0 (gchar *, attr->num_values + 1); + for (i = 0; i < attr->num_values; i++) + auth_info_required[i] = g_strdup (attr->values[i].string.text); + } + } else { GTK_NOTE (PRINTING, @@ -1674,6 +1891,9 @@ cups_request_printer_list_cb (GtkPrintBackendCups *cups_backend, cups_printer->hostname = g_strdup (hostname); cups_printer->port = port; + cups_printer->auth_info_required = g_strdupv (auth_info_required); + g_strfreev (auth_info_required); + printer = GTK_PRINTER (cups_printer); if (cups_backend->default_printer != NULL && @@ -1866,7 +2086,8 @@ cups_request_printer_list (GtkPrintBackendCups *cups_backend) "printer-is-accepting-jobs", "job-sheets-supported", "job-sheets-default", - "printer-type" + "printer-type", + "auth-info-required" }; if (cups_backend->list_printers_pending) diff --git a/modules/printbackends/cups/gtkprintercups.c b/modules/printbackends/cups/gtkprintercups.c index cd27b17..efdb0e5 100644 --- a/modules/printbackends/cups/gtkprintercups.c +++ b/modules/printbackends/cups/gtkprintercups.c @@ -77,6 +77,7 @@ gtk_printer_cups_init (GtkPrinterCups *printer) printer->ppd_file = NULL; printer->default_cover_before = NULL; printer->default_cover_after = NULL; + printer->auth_info_required = NULL; } static void @@ -94,6 +95,7 @@ gtk_printer_cups_finalize (GObject *object) g_free (printer->ppd_name); g_free (printer->default_cover_before); g_free (printer->default_cover_after); + g_strfreev (printer->auth_info_required); if (printer->ppd_file) ppdClose (printer->ppd_file); diff --git a/modules/printbackends/cups/gtkprintercups.h b/modules/printbackends/cups/gtkprintercups.h index cd2b318..7a869a0 100644 --- a/modules/printbackends/cups/gtkprintercups.h +++ b/modules/printbackends/cups/gtkprintercups.h @@ -47,6 +47,7 @@ struct _GtkPrinterCups gchar *printer_uri; gchar *hostname; gint port; + gchar **auth_info_required; ipp_pstate_t state; gboolean reading_ppd; -- 1.6.2.5