Export g_charset_converter_get_num_fallbacks in header
[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: Object used for authentication and user interaction
37  * @include: gio/gio.h
38  *
39  * #GMountOperation provides a mechanism for interacting with the user.
40  * It can be used for authenticating mountable operations, such as loop
41  * mounting files, hard drive partitions or server locations. It can
42  * also be used to ask the user questions or show a list of applications
43  * preventing unmount or eject operations from completing.
44  *
45  * Note that #GMountOperation is used for more than just #GMount
46  * objects – for example it is also used in g_drive_start() and
47  * g_drive_stop().
48  *
49  * Users should instantiate a subclass of this that implements all the
50  * various callbacks to show the required dialogs, such as
51  * #GtkMountOperation. If no user interaction is desired (for example
52  * when automounting filesystems at login time), usually %NULL can be
53  * passed, see each method taking a #GMountOperation for details.
54  */
55
56 G_DEFINE_TYPE (GMountOperation, g_mount_operation, G_TYPE_OBJECT);
57
58 enum {
59   ASK_PASSWORD,
60   ASK_QUESTION,
61   REPLY,
62   ABORTED,
63   SHOW_PROCESSES,
64   LAST_SIGNAL
65 };
66
67 static guint signals[LAST_SIGNAL] = { 0 };
68
69 struct _GMountOperationPrivate {
70   char *password;
71   char *user;
72   char *domain;
73   gboolean anonymous;
74   GPasswordSave password_save;
75   int choice;
76 };
77
78 enum {
79   PROP_0,
80   PROP_USERNAME,
81   PROP_PASSWORD,
82   PROP_ANONYMOUS,
83   PROP_DOMAIN,
84   PROP_PASSWORD_SAVE,
85   PROP_CHOICE
86 };
87
88 static void 
89 g_mount_operation_set_property (GObject      *object,
90                                 guint         prop_id,
91                                 const GValue *value,
92                                 GParamSpec   *pspec)
93 {
94   GMountOperation *operation;
95
96   operation = G_MOUNT_OPERATION (object);
97
98   switch (prop_id)
99     {
100     case PROP_USERNAME:
101       g_mount_operation_set_username (operation, 
102                                       g_value_get_string (value));
103       break;
104    
105     case PROP_PASSWORD:
106       g_mount_operation_set_password (operation, 
107                                       g_value_get_string (value));
108       break;
109
110     case PROP_ANONYMOUS:
111       g_mount_operation_set_anonymous (operation, 
112                                        g_value_get_boolean (value));
113       break;
114
115     case PROP_DOMAIN:
116       g_mount_operation_set_domain (operation, 
117                                     g_value_get_string (value));
118       break;
119
120     case PROP_PASSWORD_SAVE:
121       g_mount_operation_set_password_save (operation, 
122                                            g_value_get_enum (value));
123       break;
124
125     case PROP_CHOICE:
126       g_mount_operation_set_choice (operation, 
127                                     g_value_get_int (value));
128       break;
129
130     default:
131       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
132       break;
133     }
134 }
135
136
137 static void 
138 g_mount_operation_get_property (GObject    *object,
139                                 guint       prop_id,
140                                 GValue     *value,
141                                 GParamSpec *pspec)
142 {
143   GMountOperation *operation;
144   GMountOperationPrivate *priv;
145
146   operation = G_MOUNT_OPERATION (object);
147   priv = operation->priv;
148   
149   switch (prop_id)
150     {
151     case PROP_USERNAME:
152       g_value_set_string (value, priv->user);
153       break;
154
155     case PROP_PASSWORD:
156       g_value_set_string (value, priv->password);
157       break;
158
159     case PROP_ANONYMOUS:
160       g_value_set_boolean (value, priv->anonymous);
161       break;
162
163     case PROP_DOMAIN:
164       g_value_set_string (value, priv->domain);
165       break;
166
167     case PROP_PASSWORD_SAVE:
168       g_value_set_enum (value, priv->password_save);
169       break;
170
171     case PROP_CHOICE:
172       g_value_set_int (value, priv->choice);
173       break;
174
175     default:
176       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
177       break;
178     }
179 }
180
181
182 static void
183 g_mount_operation_finalize (GObject *object)
184 {
185   GMountOperation *operation;
186   GMountOperationPrivate *priv;
187
188   operation = G_MOUNT_OPERATION (object);
189
190   priv = operation->priv;
191   
192   g_free (priv->password);
193   g_free (priv->user);
194   g_free (priv->domain);
195
196   G_OBJECT_CLASS (g_mount_operation_parent_class)->finalize (object);
197 }
198
199 static gboolean
200 reply_non_handled_in_idle (gpointer data)
201 {
202   GMountOperation *op = data;
203
204   g_mount_operation_reply (op, G_MOUNT_OPERATION_UNHANDLED);
205   return FALSE;
206 }
207
208 static void
209 ask_password (GMountOperation *op,
210               const char      *message,
211               const char      *default_user,
212               const char      *default_domain,
213               GAskPasswordFlags flags)
214 {
215   g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
216                    reply_non_handled_in_idle,
217                    g_object_ref (op),
218                    g_object_unref);
219 }
220   
221 static void
222 ask_question (GMountOperation *op,
223               const char      *message,
224               const char      *choices[])
225 {
226   g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
227                    reply_non_handled_in_idle,
228                    g_object_ref (op),
229                    g_object_unref);
230 }
231
232 static void
233 show_processes (GMountOperation      *op,
234                 const gchar          *message,
235                 GArray               *processes,
236                 const gchar          *choices[])
237 {
238   g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
239                    reply_non_handled_in_idle,
240                    g_object_ref (op),
241                    g_object_unref);
242 }
243
244 static void
245 g_mount_operation_class_init (GMountOperationClass *klass)
246 {
247   GObjectClass *object_class;
248   
249   g_type_class_add_private (klass, sizeof (GMountOperationPrivate));
250  
251   object_class = G_OBJECT_CLASS (klass);
252   object_class->finalize = g_mount_operation_finalize;
253   object_class->get_property = g_mount_operation_get_property;
254   object_class->set_property = g_mount_operation_set_property;
255   
256   klass->ask_password = ask_password;
257   klass->ask_question = ask_question;
258   klass->show_processes = show_processes;
259   
260   /**
261    * GMountOperation::ask-password:
262    * @op: a #GMountOperation requesting a password.
263    * @message: string containing a message to display to the user.
264    * @default_user: string containing the default user name.
265    * @default_domain: string containing the default domain.
266    * @flags: a set of #GAskPasswordFlags.
267    *
268    * Emitted when a mount operation asks the user for a password.
269    *
270    * If the message contains a line break, the first line should be
271    * presented as a heading. For example, it may be used as the
272    * primary text in a #GtkMessageDialog.
273    */
274   signals[ASK_PASSWORD] =
275     g_signal_new (I_("ask-password"),
276                   G_TYPE_FROM_CLASS (object_class),
277                   G_SIGNAL_RUN_LAST,
278                   G_STRUCT_OFFSET (GMountOperationClass, ask_password),
279                   NULL, NULL,
280                   _gio_marshal_VOID__STRING_STRING_STRING_FLAGS,
281                   G_TYPE_NONE, 4,
282                   G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_ASK_PASSWORD_FLAGS);
283                   
284   /**
285    * GMountOperation::ask-question:
286    * @op: a #GMountOperation asking a question.
287    * @message: string containing a message to display to the user.
288    * @choices: an array of strings for each possible choice.
289    *
290    * Emitted when asking the user a question and gives a list of
291    * choices for the user to choose from.
292    *
293    * If the message contains a line break, the first line should be
294    * presented as a heading. For example, it may be used as the
295    * primary text in a #GtkMessageDialog.
296    */
297   signals[ASK_QUESTION] =
298     g_signal_new (I_("ask-question"),
299                   G_TYPE_FROM_CLASS (object_class),
300                   G_SIGNAL_RUN_LAST,
301                   G_STRUCT_OFFSET (GMountOperationClass, ask_question),
302                   NULL, NULL,
303                   _gio_marshal_VOID__STRING_BOXED,
304                   G_TYPE_NONE, 2,
305                   G_TYPE_STRING, G_TYPE_STRV);
306                   
307   /**
308    * GMountOperation::reply:
309    * @op: a #GMountOperation.
310    * @result: a #GMountOperationResult indicating how the request was handled
311    *
312    * Emitted when the user has replied to the mount operation.
313    */
314   signals[REPLY] =
315     g_signal_new (I_("reply"),
316                   G_TYPE_FROM_CLASS (object_class),
317                   G_SIGNAL_RUN_LAST,
318                   G_STRUCT_OFFSET (GMountOperationClass, reply),
319                   NULL, NULL,
320                   g_cclosure_marshal_VOID__ENUM,
321                   G_TYPE_NONE, 1,
322                   G_TYPE_MOUNT_OPERATION_RESULT);
323
324   /**
325    * GMountOperation::aborted:
326    *
327    * Emitted by the backend when e.g. a device becomes unavailable
328    * while a mount operation is in progress.
329    *
330    * Implementations of GMountOperation should handle this signal
331    * by dismissing open password dialogs.
332    *
333    * Since: 2.20
334    */
335   signals[ABORTED] =
336     g_signal_new (I_("aborted"),
337                   G_TYPE_FROM_CLASS (object_class),
338                   G_SIGNAL_RUN_LAST,
339                   G_STRUCT_OFFSET (GMountOperationClass, aborted),
340                   NULL, NULL,
341                   g_cclosure_marshal_VOID__VOID,
342                   G_TYPE_NONE, 0);
343
344   /**
345    * GMountOperation::show-processes:
346    * @op: a #GMountOperation.
347    * @message: string containing a message to display to the user.
348    * @processes: an array of #GPid for processes blocking the operation.
349    * @choices: an array of strings for each possible choice.
350    *
351    * Emitted when one or more processes are blocking an operation
352    * e.g. unmounting/ejecting a #GMount or stopping a #GDrive.
353    *
354    * Note that this signal may be emitted several times to update the
355    * list of blocking processes as processes close files. The
356    * application should only respond with g_mount_operation_reply() to
357    * the latest signal (setting #GMountOperation:choice to the choice
358    * the user made).
359    *
360    * If the message contains a line break, the first line should be
361    * presented as a heading. For example, it may be used as the
362    * primary text in a #GtkMessageDialog.
363    *
364    * Since: 2.22
365    */
366   signals[SHOW_PROCESSES] =
367     g_signal_new (I_("show-processes"),
368                   G_TYPE_FROM_CLASS (object_class),
369                   G_SIGNAL_RUN_LAST,
370                   G_STRUCT_OFFSET (GMountOperationClass, show_processes),
371                   NULL, NULL,
372                   _gio_marshal_VOID__STRING_BOXED_BOXED,
373                   G_TYPE_NONE, 3,
374                   G_TYPE_STRING, G_TYPE_ARRAY, G_TYPE_STRV);
375
376   /**
377    * GMountOperation:username:
378    *
379    * The user name that is used for authentication when carrying out
380    * the mount operation.
381    */ 
382   g_object_class_install_property (object_class,
383                                    PROP_USERNAME,
384                                    g_param_spec_string ("username",
385                                                         P_("Username"),
386                                                         P_("The user name"),
387                                                         NULL,
388                                                         G_PARAM_READWRITE|
389                                                         G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB));
390
391   /**
392    * GMountOperation:password:
393    *
394    * The password that is used for authentication when carrying out
395    * the mount operation.
396    */ 
397   g_object_class_install_property (object_class,
398                                    PROP_PASSWORD,
399                                    g_param_spec_string ("password",
400                                                         P_("Password"),
401                                                         P_("The password"),
402                                                         NULL,
403                                                         G_PARAM_READWRITE|
404                                                         G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB));
405
406   /**
407    * GMountOperation:anonymous:
408    * 
409    * Whether to use an anonymous user when authenticating.
410    */
411   g_object_class_install_property (object_class,
412                                    PROP_ANONYMOUS,
413                                    g_param_spec_boolean ("anonymous",
414                                                          P_("Anonymous"),
415                                                          P_("Whether to use an anonymous user"),
416                                                          FALSE,
417                                                          G_PARAM_READWRITE|
418                                                          G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB));
419
420   /**
421    * GMountOperation:domain:
422    *
423    * The domain to use for the mount operation.
424    */ 
425   g_object_class_install_property (object_class,
426                                    PROP_DOMAIN,
427                                    g_param_spec_string ("domain",
428                                                         P_("Domain"),
429                                                         P_("The domain of the mount operation"),
430                                                         NULL,
431                                                         G_PARAM_READWRITE|
432                                                         G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB));
433
434   /**
435    * GMountOperation:password-save:
436    *
437    * Determines if and how the password information should be saved. 
438    */ 
439   g_object_class_install_property (object_class,
440                                    PROP_PASSWORD_SAVE,
441                                    g_param_spec_enum ("password-save",
442                                                       P_("Password save"),
443                                                       P_("How passwords should be saved"),
444                                                       G_TYPE_PASSWORD_SAVE,
445                                                       G_PASSWORD_SAVE_NEVER,
446                                                       G_PARAM_READWRITE|
447                                                       G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB));
448
449   /**
450    * GMountOperation:choice:
451    *
452    * The index of the user's choice when a question is asked during the 
453    * mount operation. See the #GMountOperation::ask-question signal.
454    */ 
455   g_object_class_install_property (object_class,
456                                    PROP_CHOICE,
457                                    g_param_spec_int ("choice",
458                                                      P_("Choice"),
459                                                      P_("The users choice"),
460                                                      0, G_MAXINT, 0,
461                                                      G_PARAM_READWRITE|
462                                                      G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB));
463 }
464
465 static void
466 g_mount_operation_init (GMountOperation *operation)
467 {
468   operation->priv = G_TYPE_INSTANCE_GET_PRIVATE (operation,
469                                                  G_TYPE_MOUNT_OPERATION,
470                                                  GMountOperationPrivate);
471 }
472
473 /**
474  * g_mount_operation_new:
475  * 
476  * Creates a new mount operation.
477  * 
478  * Returns: a #GMountOperation.
479  **/
480 GMountOperation *
481 g_mount_operation_new (void)
482 {
483   return g_object_new (G_TYPE_MOUNT_OPERATION, NULL);
484 }
485
486 /**
487  * g_mount_operation_get_username
488  * @op: a #GMountOperation.
489  * 
490  * Get the user name from the mount operation.
491  *
492  * Returns: a string containing the user name.
493  **/
494 const char *
495 g_mount_operation_get_username (GMountOperation *op)
496 {
497   g_return_val_if_fail (G_IS_MOUNT_OPERATION (op), NULL);
498   return op->priv->user;
499 }
500
501 /**
502  * g_mount_operation_set_username:
503  * @op: a #GMountOperation.
504  * @username: input username.
505  *
506  * Sets the user name within @op to @username.
507  **/
508 void
509 g_mount_operation_set_username (GMountOperation *op,
510                                 const char      *username)
511 {
512   g_return_if_fail (G_IS_MOUNT_OPERATION (op));
513   g_free (op->priv->user);
514   op->priv->user = g_strdup (username);
515   g_object_notify (G_OBJECT (op), "username");
516 }
517
518 /**
519  * g_mount_operation_get_password:
520  * @op: a #GMountOperation.
521  *
522  * Gets a password from the mount operation. 
523  *
524  * Returns: a string containing the password within @op.
525  **/
526 const char *
527 g_mount_operation_get_password (GMountOperation *op)
528 {
529   g_return_val_if_fail (G_IS_MOUNT_OPERATION (op), NULL);
530   return op->priv->password;
531 }
532
533 /**
534  * g_mount_operation_set_password:
535  * @op: a #GMountOperation.
536  * @password: password to set.
537  * 
538  * Sets the mount operation's password to @password.  
539  *
540  **/
541 void
542 g_mount_operation_set_password (GMountOperation *op,
543                                 const char      *password)
544 {
545   g_return_if_fail (G_IS_MOUNT_OPERATION (op));
546   g_free (op->priv->password);
547   op->priv->password = g_strdup (password);
548   g_object_notify (G_OBJECT (op), "password");
549 }
550
551 /**
552  * g_mount_operation_get_anonymous:
553  * @op: a #GMountOperation.
554  * 
555  * Check to see whether the mount operation is being used 
556  * for an anonymous user.
557  * 
558  * Returns: %TRUE if mount operation is anonymous. 
559  **/
560 gboolean
561 g_mount_operation_get_anonymous (GMountOperation *op)
562 {
563   g_return_val_if_fail (G_IS_MOUNT_OPERATION (op), FALSE);
564   return op->priv->anonymous;
565 }
566
567 /**
568  * g_mount_operation_set_anonymous:
569  * @op: a #GMountOperation.
570  * @anonymous: boolean value.
571  * 
572  * Sets the mount operation to use an anonymous user if @anonymous is %TRUE.
573  **/  
574 void
575 g_mount_operation_set_anonymous (GMountOperation *op,
576                                  gboolean         anonymous)
577 {
578   GMountOperationPrivate *priv;
579   g_return_if_fail (G_IS_MOUNT_OPERATION (op));
580   priv = op->priv;
581
582   if (priv->anonymous != anonymous)
583     {
584       priv->anonymous = anonymous;
585       g_object_notify (G_OBJECT (op), "anonymous");
586     }
587 }
588
589 /**
590  * g_mount_operation_get_domain:
591  * @op: a #GMountOperation.
592  * 
593  * Gets the domain of the mount operation.
594  * 
595  * Returns: a string set to the domain. 
596  **/
597 const char *
598 g_mount_operation_get_domain (GMountOperation *op)
599 {
600   g_return_val_if_fail (G_IS_MOUNT_OPERATION (op), NULL);
601   return op->priv->domain;
602 }
603
604 /**
605  * g_mount_operation_set_domain:
606  * @op: a #GMountOperation.
607  * @domain: the domain to set.
608  * 
609  * Sets the mount operation's domain. 
610  **/  
611 void
612 g_mount_operation_set_domain (GMountOperation *op,
613                               const char      *domain)
614 {
615   g_return_if_fail (G_IS_MOUNT_OPERATION (op));
616   g_free (op->priv->domain);
617   op->priv->domain = g_strdup (domain);
618   g_object_notify (G_OBJECT (op), "domain");
619 }
620
621 /**
622  * g_mount_operation_get_password_save:
623  * @op: a #GMountOperation.
624  * 
625  * Gets the state of saving passwords for the mount operation.
626  *
627  * Returns: a #GPasswordSave flag. 
628  **/  
629
630 GPasswordSave
631 g_mount_operation_get_password_save (GMountOperation *op)
632 {
633   g_return_val_if_fail (G_IS_MOUNT_OPERATION (op), G_PASSWORD_SAVE_NEVER);
634   return op->priv->password_save;
635 }
636
637 /**
638  * g_mount_operation_set_password_save:
639  * @op: a #GMountOperation.
640  * @save: a set of #GPasswordSave flags.
641  * 
642  * Sets the state of saving passwords for the mount operation.
643  * 
644  **/   
645 void
646 g_mount_operation_set_password_save (GMountOperation *op,
647                                      GPasswordSave    save)
648 {
649   GMountOperationPrivate *priv;
650   g_return_if_fail (G_IS_MOUNT_OPERATION (op));
651   priv = op->priv;
652  
653   if (priv->password_save != save)
654     {
655       priv->password_save = save;
656       g_object_notify (G_OBJECT (op), "password-save");
657     }
658 }
659
660 /**
661  * g_mount_operation_get_choice:
662  * @op: a #GMountOperation.
663  * 
664  * Gets a choice from the mount operation.
665  *
666  * Returns: an integer containing an index of the user's choice from 
667  * the choice's list, or %0.
668  **/
669 int
670 g_mount_operation_get_choice (GMountOperation *op)
671 {
672   g_return_val_if_fail (G_IS_MOUNT_OPERATION (op), 0);
673   return op->priv->choice;
674 }
675
676 /**
677  * g_mount_operation_set_choice:
678  * @op: a #GMountOperation.
679  * @choice: an integer.
680  *
681  * Sets a default choice for the mount operation.
682  **/
683 void
684 g_mount_operation_set_choice (GMountOperation *op,
685                               int              choice)
686 {
687   GMountOperationPrivate *priv;
688   g_return_if_fail (G_IS_MOUNT_OPERATION (op));
689   priv = op->priv;
690   if (priv->choice != choice)
691     {
692       priv->choice = choice;
693       g_object_notify (G_OBJECT (op), "choice");
694     }
695 }
696
697 /**
698  * g_mount_operation_reply:
699  * @op: a #GMountOperation
700  * @result: a #GMountOperationResult
701  * 
702  * Emits the #GMountOperation::reply signal.
703  **/
704 void
705 g_mount_operation_reply (GMountOperation *op,
706                          GMountOperationResult result)
707 {
708   g_return_if_fail (G_IS_MOUNT_OPERATION (op));
709   g_signal_emit (op, signals[REPLY], 0, result);
710 }
711
712 #define __G_MOUNT_OPERATION_C__
713 #include "gioaliasdef.c"