chain up unconditionally in finalize() and dispose(). Also don't
[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    * @abort: a boolean indicating %TRUE if the operation was aborted.
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  **/
432 void
433 g_mount_operation_set_username (GMountOperation *op,
434                                 const char      *username)
435 {
436   g_return_if_fail (G_IS_MOUNT_OPERATION (op));
437   g_free (op->priv->user);
438   op->priv->user = g_strdup (username);
439   g_object_notify (G_OBJECT (op), "username");
440 }
441
442 /**
443  * g_mount_operation_get_password:
444  * @op: a #GMountOperation.
445  *
446  * Gets a password from the mount operation. 
447  *
448  * Returns: a string containing the password within @op.
449  **/
450 const char *
451 g_mount_operation_get_password (GMountOperation *op)
452 {
453   g_return_val_if_fail (G_IS_MOUNT_OPERATION (op), NULL);
454   return op->priv->password;
455 }
456
457 /**
458  * g_mount_operation_set_password:
459  * @op: a #GMountOperation.
460  * @password: password to set.
461  * 
462  * Sets the mount operation's password to @password.  
463  *
464  **/
465 void
466 g_mount_operation_set_password (GMountOperation *op,
467                                 const char      *password)
468 {
469   g_return_if_fail (G_IS_MOUNT_OPERATION (op));
470   g_free (op->priv->password);
471   op->priv->password = g_strdup (password);
472   g_object_notify (G_OBJECT (op), "password");
473 }
474
475 /**
476  * g_mount_operation_get_anonymous:
477  * @op: a #GMountOperation.
478  * 
479  * Check to see whether the mount operation is being used 
480  * for an anonymous user.
481  * 
482  * Returns: %TRUE if mount operation is anonymous. 
483  **/
484 gboolean
485 g_mount_operation_get_anonymous (GMountOperation *op)
486 {
487   g_return_val_if_fail (G_IS_MOUNT_OPERATION (op), FALSE);
488   return op->priv->anonymous;
489 }
490
491 /**
492  * g_mount_operation_set_anonymous:
493  * @op: a #GMountOperation.
494  * @anonymous: boolean value.
495  * 
496  * Sets the mount operation to use an anonymous user if @anonymous is %TRUE.
497  **/  
498 void
499 g_mount_operation_set_anonymous (GMountOperation *op,
500                                  gboolean         anonymous)
501 {
502   GMountOperationPrivate *priv;
503   g_return_if_fail (G_IS_MOUNT_OPERATION (op));
504   priv = op->priv;
505
506   if (priv->anonymous != anonymous)
507     {
508       priv->anonymous = anonymous;
509       g_object_notify (G_OBJECT (op), "anonymous");
510     }
511 }
512
513 /**
514  * g_mount_operation_get_domain:
515  * @op: a #GMountOperation.
516  * 
517  * Gets the domain of the mount operation.
518  * 
519  * Returns: a string set to the domain. 
520  **/
521 const char *
522 g_mount_operation_get_domain (GMountOperation *op)
523 {
524   g_return_val_if_fail (G_IS_MOUNT_OPERATION (op), NULL);
525   return op->priv->domain;
526 }
527
528 /**
529  * g_mount_operation_set_domain:
530  * @op: a #GMountOperation.
531  * @domain: the domain to set.
532  * 
533  * Sets the mount operation's domain. 
534  **/  
535 void
536 g_mount_operation_set_domain (GMountOperation *op,
537                               const char      *domain)
538 {
539   g_return_if_fail (G_IS_MOUNT_OPERATION (op));
540   g_free (op->priv->domain);
541   op->priv->domain = g_strdup (domain);
542   g_object_notify (G_OBJECT (op), "domain");
543 }
544
545 /**
546  * g_mount_operation_get_password_save:
547  * @op: a #GMountOperation.
548  * 
549  * Gets the state of saving passwords for the mount operation.
550  *
551  * Returns: a #GPasswordSave flag. 
552  **/  
553
554 GPasswordSave
555 g_mount_operation_get_password_save (GMountOperation *op)
556 {
557   g_return_val_if_fail (G_IS_MOUNT_OPERATION (op), G_PASSWORD_SAVE_NEVER);
558   return op->priv->password_save;
559 }
560
561 /**
562  * g_mount_operation_set_password_save:
563  * @op: a #GMountOperation.
564  * @save: a set of #GPasswordSave flags.
565  * 
566  * Sets the state of saving passwords for the mount operation.
567  * 
568  **/   
569 void
570 g_mount_operation_set_password_save (GMountOperation *op,
571                                      GPasswordSave    save)
572 {
573   GMountOperationPrivate *priv;
574   g_return_if_fail (G_IS_MOUNT_OPERATION (op));
575   priv = op->priv;
576  
577   if (priv->password_save != save)
578     {
579       priv->password_save = save;
580       g_object_notify (G_OBJECT (op), "password-save");
581     }
582 }
583
584 /**
585  * g_mount_operation_get_choice:
586  * @op: a #GMountOperation.
587  * 
588  * Gets a choice from the mount operation.
589  *
590  * Returns: an integer containing an index of the user's choice from 
591  * the choice's list, or %0.
592  **/
593 int
594 g_mount_operation_get_choice (GMountOperation *op)
595 {
596   g_return_val_if_fail (G_IS_MOUNT_OPERATION (op), 0);
597   return op->priv->choice;
598 }
599
600 /**
601  * g_mount_operation_set_choice:
602  * @op: a #GMountOperation.
603  * @choice: an integer.
604  *
605  * Sets a default choice for the mount operation.
606  **/
607 void
608 g_mount_operation_set_choice (GMountOperation *op,
609                               int              choice)
610 {
611   GMountOperationPrivate *priv;
612   g_return_if_fail (G_IS_MOUNT_OPERATION (op));
613   priv = op->priv;
614   if (priv->choice != choice)
615     {
616       priv->choice = choice;
617       g_object_notify (G_OBJECT (op), "choice");
618     }
619 }
620
621 /**
622  * g_mount_operation_reply:
623  * @op: a #GMountOperation
624  * @result: a #GMountOperationResult
625  * 
626  * Emits the #GMountOperation::reply signal.
627  **/
628 void
629 g_mount_operation_reply (GMountOperation *op,
630                          GMountOperationResult result)
631 {
632   g_return_if_fail (G_IS_MOUNT_OPERATION (op));
633   g_signal_emit (op, signals[REPLY], 0, result);
634 }
635
636 #define __G_MOUNT_OPERATION_C__
637 #include "gioaliasdef.c"