96f360c67a6eea2caace948c8fd85026530b2f07
[platform/upstream/glib.git] / gio / gmountoperation.c
1 /* GIO - GLib Input, Output and Streaming Library
2  * 
3  * Copyright (C) 2006-2007 Red Hat, Inc.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library 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 GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General
16  * Public License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18  * Boston, MA 02111-1307, USA.
19  *
20  * Author: Alexander Larsson <alexl@redhat.com>
21  */
22
23 #include "config.h"
24
25 #include <string.h>
26
27 #include "gmountoperation.h"
28 #include "gioenumtypes.h"
29 #include "gio-marshal.h"
30 #include "glibintl.h"
31
32 #include "gioalias.h"
33
34 /** 
35  * SECTION:gmountoperation
36  * @short_description: Authentication methods for mountable locations
37  * @include: gio/gio.h
38  *
39  * #GMountOperation provides a mechanism for authenticating mountable 
40  * operations, such as loop mounting files, hard drive partitions or 
41  * server locations. 
42  *
43  * Mounting operations are handed a #GMountOperation that then can use 
44  * if they require any privileges or authentication for their volumes 
45  * to be mounted (e.g. a hard disk partition or an encrypted filesystem), 
46  * or if they are implementing a remote server protocol which requires 
47  * user credentials such as FTP or WebDAV.
48  *
49  * Users should instantiate a subclass of this that implements all
50  * the various callbacks to show the required dialogs, such as 
51  * #GtkMountOperation.
52  **/
53
54 G_DEFINE_TYPE (GMountOperation, g_mount_operation, G_TYPE_OBJECT);
55
56 enum {
57   ASK_PASSWORD,
58   ASK_QUESTION,
59   REPLY,
60   LAST_SIGNAL
61 };
62
63 static guint signals[LAST_SIGNAL] = { 0 };
64
65 struct _GMountOperationPrivate {
66   char *password;
67   char *user;
68   char *domain;
69   gboolean anonymous;
70   GPasswordSave password_save;
71   int choice;
72 };
73
74 enum {
75   PROP_0,
76   PROP_USERNAME,
77   PROP_PASSWORD,
78   PROP_ANONYMOUS,
79   PROP_DOMAIN,
80   PROP_PASSWORD_SAVE,
81   PROP_CHOICE
82 };
83
84 static void 
85 g_mount_operation_set_property (GObject      *object,
86                                 guint         prop_id,
87                                 const GValue *value,
88                                 GParamSpec   *pspec)
89 {
90   GMountOperation *operation;
91
92   operation = G_MOUNT_OPERATION (object);
93
94   switch (prop_id)
95     {
96     case PROP_USERNAME:
97       g_mount_operation_set_username (operation, 
98                                       g_value_get_string (value));
99       break;
100    
101     case PROP_PASSWORD:
102       g_mount_operation_set_password (operation, 
103                                       g_value_get_string (value));
104       break;
105
106     case PROP_ANONYMOUS:
107       g_mount_operation_set_anonymous (operation, 
108                                        g_value_get_boolean (value));
109       break;
110
111     case PROP_DOMAIN:
112       g_mount_operation_set_domain (operation, 
113                                     g_value_get_string (value));
114       break;
115
116     case PROP_PASSWORD_SAVE:
117       g_mount_operation_set_password_save (operation, 
118                                            g_value_get_enum (value));
119       break;
120
121     case PROP_CHOICE:
122       g_mount_operation_set_choice (operation, 
123                                     g_value_get_int (value));
124       break;
125
126     default:
127       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
128       break;
129     }
130 }
131
132
133 static void 
134 g_mount_operation_get_property (GObject    *object,
135                                 guint       prop_id,
136                                 GValue     *value,
137                                 GParamSpec *pspec)
138 {
139   GMountOperation *operation;
140   GMountOperationPrivate *priv;
141
142   operation = G_MOUNT_OPERATION (object);
143   priv = operation->priv;
144   
145   switch (prop_id)
146     {
147     case PROP_USERNAME:
148       g_value_set_string (value, priv->user);
149       break;
150
151     case PROP_PASSWORD:
152       g_value_set_string (value, priv->password);
153       break;
154
155     case PROP_ANONYMOUS:
156       g_value_set_boolean (value, priv->anonymous);
157       break;
158
159     case PROP_DOMAIN:
160       g_value_set_string (value, priv->domain);
161       break;
162
163     case PROP_PASSWORD_SAVE:
164       g_value_set_enum (value, priv->password_save);
165       break;
166
167     case PROP_CHOICE:
168       g_value_set_int (value, priv->choice);
169       break;
170
171     default:
172       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
173       break;
174     }
175 }
176
177
178 static void
179 g_mount_operation_finalize (GObject *object)
180 {
181   GMountOperation *operation;
182   GMountOperationPrivate *priv;
183
184   operation = G_MOUNT_OPERATION (object);
185
186   priv = operation->priv;
187   
188   g_free (priv->password);
189   g_free (priv->user);
190   g_free (priv->domain);
191
192   G_OBJECT_CLASS (g_mount_operation_parent_class)->finalize (object);
193 }
194
195 static gboolean
196 reply_non_handled_in_idle (gpointer data)
197 {
198   GMountOperation *op = data;
199
200   g_mount_operation_reply (op, G_MOUNT_OPERATION_UNHANDLED);
201   return FALSE;
202 }
203
204 static void
205 ask_password (GMountOperation *op,
206               const char      *message,
207               const char      *default_user,
208               const char      *default_domain,
209               GAskPasswordFlags flags)
210 {
211   g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
212                    reply_non_handled_in_idle,
213                    g_object_ref (op),
214                    g_object_unref);
215 }
216   
217 static void
218 ask_question (GMountOperation *op,
219               const char      *message,
220               const char      *choices[])
221 {
222   g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
223                    reply_non_handled_in_idle,
224                    g_object_ref (op),
225                    g_object_unref);
226 }
227
228 static void
229 g_mount_operation_class_init (GMountOperationClass *klass)
230 {
231   GObjectClass *object_class;
232   
233   g_type_class_add_private (klass, sizeof (GMountOperationPrivate));
234  
235   object_class = G_OBJECT_CLASS (klass);
236   object_class->finalize = g_mount_operation_finalize;
237   object_class->get_property = g_mount_operation_get_property;
238   object_class->set_property = g_mount_operation_set_property;
239   
240   klass->ask_password = ask_password;
241   klass->ask_question = ask_question;
242   
243   /**
244    * GMountOperation::ask-password:
245    * @op: a #GMountOperation requesting a password.
246    * @message: string containing a message to display to the user.
247    * @default_user: string containing the default user name.
248    * @default_domain: string containing the default domain.
249    * @flags: a set of #GAskPasswordFlags.
250    * 
251    * Emitted when a mount operation asks the user for a password.
252    */
253   signals[ASK_PASSWORD] =
254     g_signal_new (I_("ask_password"),
255                   G_TYPE_FROM_CLASS (object_class),
256                   G_SIGNAL_RUN_LAST,
257                   G_STRUCT_OFFSET (GMountOperationClass, ask_password),
258                   NULL, NULL,
259                   _gio_marshal_VOID__STRING_STRING_STRING_FLAGS,
260                   G_TYPE_NONE, 4,
261                   G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_ASK_PASSWORD_FLAGS);
262                   
263   /**
264    * GMountOperation::ask-question:
265    * @op: a #GMountOperation asking a question.
266    * @message: string containing a message to display to the user.
267    * @choices: an array of strings for each possible choice.
268    * 
269    * Emitted when asking the user a question and gives a list of 
270    * choices for the user to choose from. 
271    */
272   signals[ASK_QUESTION] =
273     g_signal_new (I_("ask_question"),
274                   G_TYPE_FROM_CLASS (object_class),
275                   G_SIGNAL_RUN_LAST,
276                   G_STRUCT_OFFSET (GMountOperationClass, ask_question),
277                   NULL, NULL,
278                   _gio_marshal_VOID__STRING_BOXED,
279                   G_TYPE_NONE, 2,
280                   G_TYPE_STRING, G_TYPE_STRV);
281                   
282   /**
283    * GMountOperation::reply:
284    * @op: a #GMountOperation.
285    * @result: a #GMountOperationResult indicating how the request was handled
286    * 
287    * Emitted when the user has replied to the mount operation.
288    */
289   signals[REPLY] =
290     g_signal_new (I_("reply"),
291                   G_TYPE_FROM_CLASS (object_class),
292                   G_SIGNAL_RUN_LAST,
293                   G_STRUCT_OFFSET (GMountOperationClass, reply),
294                   NULL, NULL,
295                   g_cclosure_marshal_VOID__ENUM,
296                   G_TYPE_NONE, 1,
297                   G_TYPE_MOUNT_OPERATION_RESULT);
298
299   /**
300    * GMountOperation:username:
301    *
302    * The user name that is used for authentication when carrying out
303    * the mount operation.
304    */ 
305   g_object_class_install_property (object_class,
306                                    PROP_USERNAME,
307                                    g_param_spec_string ("username",
308                                                         P_("Username"),
309                                                         P_("The user name"),
310                                                         NULL,
311                                                         G_PARAM_READWRITE|
312                                                         G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB));
313
314   /**
315    * GMountOperation:password:
316    *
317    * The password that is used for authentication when carrying out
318    * the mount operation.
319    */ 
320   g_object_class_install_property (object_class,
321                                    PROP_PASSWORD,
322                                    g_param_spec_string ("password",
323                                                         P_("Password"),
324                                                         P_("The password"),
325                                                         NULL,
326                                                         G_PARAM_READWRITE|
327                                                         G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB));
328
329   /**
330    * GMountOperation:anonymous:
331    * 
332    * Whether to use an anonymous user when authenticating.
333    */
334   g_object_class_install_property (object_class,
335                                    PROP_ANONYMOUS,
336                                    g_param_spec_boolean ("anonymous",
337                                                          P_("Anonymous"),
338                                                          P_("Whether to use an anonymous user"),
339                                                          FALSE,
340                                                          G_PARAM_READWRITE|
341                                                          G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB));
342
343   /**
344    * GMountOperation:domain:
345    *
346    * The domain to use for the mount operation.
347    */ 
348   g_object_class_install_property (object_class,
349                                    PROP_DOMAIN,
350                                    g_param_spec_string ("domain",
351                                                         P_("Domain"),
352                                                         P_("The domain of the mount operation"),
353                                                         NULL,
354                                                         G_PARAM_READWRITE|
355                                                         G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB));
356
357   /**
358    * GMountOperation:password-save:
359    *
360    * Determines if and how the password information should be saved. 
361    */ 
362   g_object_class_install_property (object_class,
363                                    PROP_PASSWORD_SAVE,
364                                    g_param_spec_enum ("password-save",
365                                                       P_("Password save"),
366                                                       P_("How passwords should be saved"),
367                                                       G_TYPE_PASSWORD_SAVE,
368                                                       G_PASSWORD_SAVE_NEVER,
369                                                       G_PARAM_READWRITE|
370                                                       G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB));
371
372   /**
373    * GMountOperation:choice:
374    *
375    * The index of the user's choice when a question is asked during the 
376    * mount operation. See the #GMountOperation::ask-question signal.
377    */ 
378   g_object_class_install_property (object_class,
379                                    PROP_CHOICE,
380                                    g_param_spec_int ("choice",
381                                                      P_("Choice"),
382                                                      P_("The users choice"),
383                                                      0, G_MAXINT, 0,
384                                                      G_PARAM_READWRITE|
385                                                      G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB));
386 }
387
388 static void
389 g_mount_operation_init (GMountOperation *operation)
390 {
391   operation->priv = G_TYPE_INSTANCE_GET_PRIVATE (operation,
392                                                  G_TYPE_MOUNT_OPERATION,
393                                                  GMountOperationPrivate);
394 }
395
396 /**
397  * g_mount_operation_new:
398  * 
399  * Creates a new mount operation.
400  * 
401  * Returns: a #GMountOperation.
402  **/
403 GMountOperation *
404 g_mount_operation_new (void)
405 {
406   return g_object_new (G_TYPE_MOUNT_OPERATION, NULL);
407 }
408
409 /**
410  * g_mount_operation_get_username
411  * @op: a #GMountOperation.
412  * 
413  * Get the user name from the mount operation.
414  *
415  * Returns: a string containing the user name.
416  **/
417 const char *
418 g_mount_operation_get_username (GMountOperation *op)
419 {
420   g_return_val_if_fail (G_IS_MOUNT_OPERATION (op), NULL);
421   return op->priv->user;
422 }
423
424 /**
425  * g_mount_operation_set_username:
426  * @op: a #GMountOperation.
427  * @username: input username.
428  *
429  * Sets the user name within @op to @username.
430  **/
431 void
432 g_mount_operation_set_username (GMountOperation *op,
433                                 const char      *username)
434 {
435   g_return_if_fail (G_IS_MOUNT_OPERATION (op));
436   g_free (op->priv->user);
437   op->priv->user = g_strdup (username);
438   g_object_notify (G_OBJECT (op), "username");
439 }
440
441 /**
442  * g_mount_operation_get_password:
443  * @op: a #GMountOperation.
444  *
445  * Gets a password from the mount operation. 
446  *
447  * Returns: a string containing the password within @op.
448  **/
449 const char *
450 g_mount_operation_get_password (GMountOperation *op)
451 {
452   g_return_val_if_fail (G_IS_MOUNT_OPERATION (op), NULL);
453   return op->priv->password;
454 }
455
456 /**
457  * g_mount_operation_set_password:
458  * @op: a #GMountOperation.
459  * @password: password to set.
460  * 
461  * Sets the mount operation's password to @password.  
462  *
463  **/
464 void
465 g_mount_operation_set_password (GMountOperation *op,
466                                 const char      *password)
467 {
468   g_return_if_fail (G_IS_MOUNT_OPERATION (op));
469   g_free (op->priv->password);
470   op->priv->password = g_strdup (password);
471   g_object_notify (G_OBJECT (op), "password");
472 }
473
474 /**
475  * g_mount_operation_get_anonymous:
476  * @op: a #GMountOperation.
477  * 
478  * Check to see whether the mount operation is being used 
479  * for an anonymous user.
480  * 
481  * Returns: %TRUE if mount operation is anonymous. 
482  **/
483 gboolean
484 g_mount_operation_get_anonymous (GMountOperation *op)
485 {
486   g_return_val_if_fail (G_IS_MOUNT_OPERATION (op), FALSE);
487   return op->priv->anonymous;
488 }
489
490 /**
491  * g_mount_operation_set_anonymous:
492  * @op: a #GMountOperation.
493  * @anonymous: boolean value.
494  * 
495  * Sets the mount operation to use an anonymous user if @anonymous is %TRUE.
496  **/  
497 void
498 g_mount_operation_set_anonymous (GMountOperation *op,
499                                  gboolean         anonymous)
500 {
501   GMountOperationPrivate *priv;
502   g_return_if_fail (G_IS_MOUNT_OPERATION (op));
503   priv = op->priv;
504
505   if (priv->anonymous != anonymous)
506     {
507       priv->anonymous = anonymous;
508       g_object_notify (G_OBJECT (op), "anonymous");
509     }
510 }
511
512 /**
513  * g_mount_operation_get_domain:
514  * @op: a #GMountOperation.
515  * 
516  * Gets the domain of the mount operation.
517  * 
518  * Returns: a string set to the domain. 
519  **/
520 const char *
521 g_mount_operation_get_domain (GMountOperation *op)
522 {
523   g_return_val_if_fail (G_IS_MOUNT_OPERATION (op), NULL);
524   return op->priv->domain;
525 }
526
527 /**
528  * g_mount_operation_set_domain:
529  * @op: a #GMountOperation.
530  * @domain: the domain to set.
531  * 
532  * Sets the mount operation's domain. 
533  **/  
534 void
535 g_mount_operation_set_domain (GMountOperation *op,
536                               const char      *domain)
537 {
538   g_return_if_fail (G_IS_MOUNT_OPERATION (op));
539   g_free (op->priv->domain);
540   op->priv->domain = g_strdup (domain);
541   g_object_notify (G_OBJECT (op), "domain");
542 }
543
544 /**
545  * g_mount_operation_get_password_save:
546  * @op: a #GMountOperation.
547  * 
548  * Gets the state of saving passwords for the mount operation.
549  *
550  * Returns: a #GPasswordSave flag. 
551  **/  
552
553 GPasswordSave
554 g_mount_operation_get_password_save (GMountOperation *op)
555 {
556   g_return_val_if_fail (G_IS_MOUNT_OPERATION (op), G_PASSWORD_SAVE_NEVER);
557   return op->priv->password_save;
558 }
559
560 /**
561  * g_mount_operation_set_password_save:
562  * @op: a #GMountOperation.
563  * @save: a set of #GPasswordSave flags.
564  * 
565  * Sets the state of saving passwords for the mount operation.
566  * 
567  **/   
568 void
569 g_mount_operation_set_password_save (GMountOperation *op,
570                                      GPasswordSave    save)
571 {
572   GMountOperationPrivate *priv;
573   g_return_if_fail (G_IS_MOUNT_OPERATION (op));
574   priv = op->priv;
575  
576   if (priv->password_save != save)
577     {
578       priv->password_save = save;
579       g_object_notify (G_OBJECT (op), "password-save");
580     }
581 }
582
583 /**
584  * g_mount_operation_get_choice:
585  * @op: a #GMountOperation.
586  * 
587  * Gets a choice from the mount operation.
588  *
589  * Returns: an integer containing an index of the user's choice from 
590  * the choice's list, or %0.
591  **/
592 int
593 g_mount_operation_get_choice (GMountOperation *op)
594 {
595   g_return_val_if_fail (G_IS_MOUNT_OPERATION (op), 0);
596   return op->priv->choice;
597 }
598
599 /**
600  * g_mount_operation_set_choice:
601  * @op: a #GMountOperation.
602  * @choice: an integer.
603  *
604  * Sets a default choice for the mount operation.
605  **/
606 void
607 g_mount_operation_set_choice (GMountOperation *op,
608                               int              choice)
609 {
610   GMountOperationPrivate *priv;
611   g_return_if_fail (G_IS_MOUNT_OPERATION (op));
612   priv = op->priv;
613   if (priv->choice != choice)
614     {
615       priv->choice = choice;
616       g_object_notify (G_OBJECT (op), "choice");
617     }
618 }
619
620 /**
621  * g_mount_operation_reply:
622  * @op: a #GMountOperation
623  * @result: a #GMountOperationResult
624  * 
625  * Emits the #GMountOperation::reply signal.
626  **/
627 void
628 g_mount_operation_reply (GMountOperation *op,
629                          GMountOperationResult result)
630 {
631   g_return_if_fail (G_IS_MOUNT_OPERATION (op));
632   g_signal_emit (op, signals[REPLY], 0, result);
633 }
634
635 #define __G_MOUNT_OPERATION_C__
636 #include "gioaliasdef.c"