/* Duplicity.c generated by valac, the Vala compiler
 * generated from Duplicity.vala, do not modify */

/* -*- Mode: Vala; indent-tabs-mode: nil; tab-width: 2 -*- */
/*
    This file is part of Déjà Dup.
    © 2008,2009 Michael Terry <mike@mterry.name>,
    © 2009 Andrew Fister <temposs@gmail.com>

    Déjà Dup is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Déjà Dup is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Déjà Dup.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <glib.h>
#include <glib-object.h>
#include <stdlib.h>
#include <string.h>
#include <gio/gio.h>
#include <float.h>
#include <math.h>
#include <gconf/gconf-client.h>
#include <glib/gi18n-lib.h>


#define DEJA_DUP_TYPE_DUPLICITY (deja_dup_duplicity_get_type ())
#define DEJA_DUP_DUPLICITY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DEJA_DUP_TYPE_DUPLICITY, DejaDupDuplicity))
#define DEJA_DUP_DUPLICITY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DEJA_DUP_TYPE_DUPLICITY, DejaDupDuplicityClass))
#define DEJA_DUP_IS_DUPLICITY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DEJA_DUP_TYPE_DUPLICITY))
#define DEJA_DUP_IS_DUPLICITY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DEJA_DUP_TYPE_DUPLICITY))
#define DEJA_DUP_DUPLICITY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DEJA_DUP_TYPE_DUPLICITY, DejaDupDuplicityClass))

typedef struct _DejaDupDuplicity DejaDupDuplicity;
typedef struct _DejaDupDuplicityClass DejaDupDuplicityClass;
typedef struct _DejaDupDuplicityPrivate DejaDupDuplicityPrivate;

#define DEJA_DUP_TYPE_BACKEND (deja_dup_backend_get_type ())
#define DEJA_DUP_BACKEND(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DEJA_DUP_TYPE_BACKEND, DejaDupBackend))
#define DEJA_DUP_BACKEND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DEJA_DUP_TYPE_BACKEND, DejaDupBackendClass))
#define DEJA_DUP_IS_BACKEND(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DEJA_DUP_TYPE_BACKEND))
#define DEJA_DUP_IS_BACKEND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DEJA_DUP_TYPE_BACKEND))
#define DEJA_DUP_BACKEND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DEJA_DUP_TYPE_BACKEND, DejaDupBackendClass))

typedef struct _DejaDupBackend DejaDupBackend;
typedef struct _DejaDupBackendClass DejaDupBackendClass;

#define DEJA_DUP_OPERATION_TYPE_MODE (deja_dup_operation_mode_get_type ())

#define DEJA_DUP_DUPLICITY_TYPE_STATE (deja_dup_duplicity_state_get_type ())

#define DEJA_DUP_TYPE_DUPLICITY_INSTANCE (deja_dup_duplicity_instance_get_type ())
#define DEJA_DUP_DUPLICITY_INSTANCE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DEJA_DUP_TYPE_DUPLICITY_INSTANCE, DejaDupDuplicityInstance))
#define DEJA_DUP_DUPLICITY_INSTANCE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DEJA_DUP_TYPE_DUPLICITY_INSTANCE, DejaDupDuplicityInstanceClass))
#define DEJA_DUP_IS_DUPLICITY_INSTANCE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DEJA_DUP_TYPE_DUPLICITY_INSTANCE))
#define DEJA_DUP_IS_DUPLICITY_INSTANCE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DEJA_DUP_TYPE_DUPLICITY_INSTANCE))
#define DEJA_DUP_DUPLICITY_INSTANCE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DEJA_DUP_TYPE_DUPLICITY_INSTANCE, DejaDupDuplicityInstanceClass))

typedef struct _DejaDupDuplicityInstance DejaDupDuplicityInstance;
typedef struct _DejaDupDuplicityInstanceClass DejaDupDuplicityInstanceClass;

#define DEJA_DUP_DUPLICITY_TYPE_DATE_INFO (deja_dup_duplicity_date_info_get_type ())
typedef struct _DejaDupDuplicityDateInfo DejaDupDuplicityDateInfo;
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
#define __g_list_free_g_object_unref0(var) ((var == NULL) ? NULL : (var = (_g_list_free_g_object_unref (var), NULL)))
#define _g_free0(var) (var = (g_free (var), NULL))
#define __g_list_free_g_free0(var) ((var == NULL) ? NULL : (var = (_g_list_free_g_free (var), NULL)))
#define __g_list_free_deja_dup_duplicity_date_info_free0(var) ((var == NULL) ? NULL : (var = (_g_list_free_deja_dup_duplicity_date_info_free (var), NULL)))

#define DEJA_DUP_TYPE_NETWORK_MANAGER (deja_dup_network_manager_get_type ())
#define DEJA_DUP_NETWORK_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DEJA_DUP_TYPE_NETWORK_MANAGER, DejaDupNetworkManager))
#define DEJA_DUP_NETWORK_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DEJA_DUP_TYPE_NETWORK_MANAGER, DejaDupNetworkManagerClass))
#define DEJA_DUP_IS_NETWORK_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DEJA_DUP_TYPE_NETWORK_MANAGER))
#define DEJA_DUP_IS_NETWORK_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DEJA_DUP_TYPE_NETWORK_MANAGER))
#define DEJA_DUP_NETWORK_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DEJA_DUP_TYPE_NETWORK_MANAGER, DejaDupNetworkManagerClass))

typedef struct _DejaDupNetworkManager DejaDupNetworkManager;
typedef struct _DejaDupNetworkManagerClass DejaDupNetworkManagerClass;
#define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var), NULL)))
#define _g_list_free0(var) ((var == NULL) ? NULL : (var = (g_list_free (var), NULL)))

#define DEJA_DUP_TYPE_DUPLICITY_INFO (deja_dup_duplicity_info_get_type ())
#define DEJA_DUP_DUPLICITY_INFO(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DEJA_DUP_TYPE_DUPLICITY_INFO, DejaDupDuplicityInfo))
#define DEJA_DUP_DUPLICITY_INFO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DEJA_DUP_TYPE_DUPLICITY_INFO, DejaDupDuplicityInfoClass))
#define DEJA_DUP_IS_DUPLICITY_INFO(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DEJA_DUP_TYPE_DUPLICITY_INFO))
#define DEJA_DUP_IS_DUPLICITY_INFO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DEJA_DUP_TYPE_DUPLICITY_INFO))
#define DEJA_DUP_DUPLICITY_INFO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DEJA_DUP_TYPE_DUPLICITY_INFO, DejaDupDuplicityInfoClass))

typedef struct _DejaDupDuplicityInfo DejaDupDuplicityInfo;
typedef struct _DejaDupDuplicityInfoClass DejaDupDuplicityInfoClass;

#define DEJA_DUP_TYPE_BACKEND_S3 (deja_dup_backend_s3_get_type ())
#define DEJA_DUP_BACKEND_S3(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DEJA_DUP_TYPE_BACKEND_S3, DejaDupBackendS3))
#define DEJA_DUP_BACKEND_S3_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DEJA_DUP_TYPE_BACKEND_S3, DejaDupBackendS3Class))
#define DEJA_DUP_IS_BACKEND_S3(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DEJA_DUP_TYPE_BACKEND_S3))
#define DEJA_DUP_IS_BACKEND_S3_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DEJA_DUP_TYPE_BACKEND_S3))
#define DEJA_DUP_BACKEND_S3_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DEJA_DUP_TYPE_BACKEND_S3, DejaDupBackendS3Class))

typedef struct _DejaDupBackendS3 DejaDupBackendS3;
typedef struct _DejaDupBackendS3Class DejaDupBackendS3Class;

struct _DejaDupDuplicity {
	GObject parent_instance;
	DejaDupDuplicityPrivate * priv;
	GList* includes;
	GList* excludes;
};

struct _DejaDupDuplicityClass {
	GObjectClass parent_class;
	void (*start) (DejaDupDuplicity* self, DejaDupBackend* backend, gboolean encrypted, GList* argv, GList* envp);
	void (*process_error) (DejaDupDuplicity* self, char** firstline, int firstline_length1, GList* data, const char* text_in);
	void (*process_info) (DejaDupDuplicity* self, char** firstline, int firstline_length1, GList* data, const char* text);
	void (*process_warning) (DejaDupDuplicity* self, char** firstline, int firstline_length1, GList* data, const char* text);
};

typedef enum  {
	DEJA_DUP_OPERATION_MODE_INVALID,
	DEJA_DUP_OPERATION_MODE_BACKUP,
	DEJA_DUP_OPERATION_MODE_RESTORE,
	DEJA_DUP_OPERATION_MODE_STATUS,
	DEJA_DUP_OPERATION_MODE_LIST
} DejaDupOperationMode;

typedef enum  {
	DEJA_DUP_DUPLICITY_STATE_NORMAL,
	DEJA_DUP_DUPLICITY_STATE_DRY_RUN,
	DEJA_DUP_DUPLICITY_STATE_STATUS,
	DEJA_DUP_DUPLICITY_STATE_CHECK_CONTENTS,
	DEJA_DUP_DUPLICITY_STATE_CLEANUP,
	DEJA_DUP_DUPLICITY_STATE_DELETE
} DejaDupDuplicityState;

struct _DejaDupDuplicityDateInfo {
	gboolean full;
	GTimeVal time;
};

struct _DejaDupDuplicityPrivate {
	DejaDupOperationMode _original_mode;
	DejaDupOperationMode _mode;
	gboolean _error_issued;
	gboolean _was_stopped;
	GFile* _local;
	DejaDupBackend* _backend;
	GList* _restore_files;
	DejaDupDuplicityState _state;
	DejaDupDuplicityInstance* inst;
	char* remote;
	GList* backend_argv;
	GList* saved_argv;
	GList* saved_envp;
	gboolean cleaned_up_once;
	gboolean is_full_backup;
	gboolean needs_root;
	gboolean has_progress_total;
	double progress_total;
	double progress_count;
	gboolean has_checked_contents;
	gboolean has_non_home_contents;
	GList* homes;
	gboolean checked_collection_info;
	gboolean got_collection_info;
	GList* collection_info;
	gboolean deleted_files;
	gint delete_age;
	GFile* last_touched_file;
	char* saved_status;
	GFile* saved_status_file;
	gboolean saved_status_file_action;
};


static GFile* deja_dup_duplicity_slash;
static GFile* deja_dup_duplicity_slash = NULL;
static GFile* deja_dup_duplicity_slash_root;
static GFile* deja_dup_duplicity_slash_root = NULL;
static GFile* deja_dup_duplicity_slash_home;
static GFile* deja_dup_duplicity_slash_home = NULL;
static GFile* deja_dup_duplicity_slash_home_me;
static GFile* deja_dup_duplicity_slash_home_me = NULL;
extern GConfClient* deja_dup_client;
static gpointer deja_dup_duplicity_parent_class = NULL;

GType deja_dup_duplicity_get_type (void);
GType deja_dup_backend_get_type (void);
GType deja_dup_operation_mode_get_type (void);
GType deja_dup_duplicity_state_get_type (void);
GType deja_dup_duplicity_instance_get_type (void);
static GType deja_dup_duplicity_date_info_get_type (void) G_GNUC_UNUSED;
static DejaDupDuplicityDateInfo* deja_dup_duplicity_date_info_dup (const DejaDupDuplicityDateInfo* self);
static void deja_dup_duplicity_date_info_free (DejaDupDuplicityDateInfo* self);
#define DEJA_DUP_DUPLICITY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), DEJA_DUP_TYPE_DUPLICITY, DejaDupDuplicityPrivate))
enum  {
	DEJA_DUP_DUPLICITY_DUMMY_PROPERTY,
	DEJA_DUP_DUPLICITY_ORIGINAL_MODE,
	DEJA_DUP_DUPLICITY_MODE,
	DEJA_DUP_DUPLICITY_ERROR_ISSUED,
	DEJA_DUP_DUPLICITY_WAS_STOPPED,
	DEJA_DUP_DUPLICITY_LOCAL,
	DEJA_DUP_DUPLICITY_BACKEND,
	DEJA_DUP_DUPLICITY_RESTORE_FILES,
	DEJA_DUP_DUPLICITY_STATE
};
static void _g_list_free_g_object_unref (GList* self);
static void _g_list_free_g_free (GList* self);
static void _g_list_free_deja_dup_duplicity_date_info_free (GList* self);
#define DEJA_DUP_DUPLICITY_MINIMUM_FULL 2
#define DEJA_DUP_DUPLICITY_ERROR_HOSTNAME_CHANGED 3
#define DEJA_DUP_DUPLICITY_ERROR_RESTORE_DIR_NOT_FOUND 19
#define DEJA_DUP_DUPLICITY_ERROR_EXCEPTION 30
#define DEJA_DUP_DUPLICITY_ERROR_GPG 31
#define DEJA_DUP_DUPLICITY_INFO_PROGRESS 2
#define DEJA_DUP_DUPLICITY_INFO_COLLECTION_STATUS 3
#define DEJA_DUP_DUPLICITY_INFO_DIFF_FILE_NEW 4
#define DEJA_DUP_DUPLICITY_INFO_DIFF_FILE_CHANGED 5
#define DEJA_DUP_DUPLICITY_INFO_DIFF_FILE_DELETED 6
#define DEJA_DUP_DUPLICITY_INFO_PATCH_FILE_WRITING 7
#define DEJA_DUP_DUPLICITY_INFO_PATCH_FILE_PATCHING 8
#define DEJA_DUP_DUPLICITY_INFO_FILE_STAT 10
#define DEJA_DUP_DUPLICITY_INFO_SYNCHRONOUS_UPLOAD_BEGIN 11
#define DEJA_DUP_DUPLICITY_INFO_ASYNCHRONOUS_UPLOAD_BEGIN 12
#define DEJA_DUP_DUPLICITY_INFO_SYNCHRONOUS_UPLOAD_DONE 13
#define DEJA_DUP_DUPLICITY_INFO_ASYNCHRONOUS_UPLOAD_DONE 14
#define DEJA_DUP_DUPLICITY_WARNING_ORPHANED_SIG 2
#define DEJA_DUP_DUPLICITY_WARNING_UNNECESSARY_SIG 3
#define DEJA_DUP_DUPLICITY_WARNING_UNMATCHED_SIG 4
#define DEJA_DUP_DUPLICITY_WARNING_INCOMPLETE_BACKUP 5
#define DEJA_DUP_DUPLICITY_WARNING_ORPHANED_BACKUP 6
void deja_dup_duplicity_resume (DejaDupDuplicity* self);
void deja_dup_duplicity_pause (DejaDupDuplicity* self);
GType deja_dup_network_manager_get_type (void);
static void deja_dup_duplicity_network_changed (DejaDupDuplicity* self, DejaDupNetworkManager* nm, gboolean connected);
DejaDupDuplicity* deja_dup_duplicity_new (DejaDupOperationMode mode);
DejaDupDuplicity* deja_dup_duplicity_construct (GType object_type, DejaDupOperationMode mode);
DejaDupOperationMode deja_dup_duplicity_get_original_mode (DejaDupDuplicity* self);
static void deja_dup_duplicity_set_mode (DejaDupDuplicity* self, DejaDupOperationMode value);
char* deja_dup_backend_get_location (DejaDupBackend* self, GError** error);
void deja_dup_duplicity_set_backend (DejaDupDuplicity* self, DejaDupBackend* value);
void deja_dup_backend_add_argv (DejaDupBackend* self, DejaDupOperationMode mode, GList** argv);
DejaDupOperationMode deja_dup_duplicity_get_mode (DejaDupDuplicity* self);
static void deja_dup_duplicity_process_include_excludes (DejaDupDuplicity* self);
#define DEJA_DUP_DELETE_AFTER_KEY "/apps/deja-dup/delete-after"
static gboolean deja_dup_duplicity_restart (DejaDupDuplicity* self);
gboolean deja_dup_backend_is_native (DejaDupBackend* self);
DejaDupNetworkManager* deja_dup_network_manager_get (void);
static void _deja_dup_duplicity_network_changed_deja_dup_network_manager_changed (DejaDupNetworkManager* _sender, gboolean connected, gpointer self);
gboolean deja_dup_network_manager_get_connected (DejaDupNetworkManager* self);
void deja_dup_duplicity_start (DejaDupDuplicity* self, DejaDupBackend* backend, gboolean encrypted, GList* argv, GList* envp);
static void deja_dup_duplicity_real_start (DejaDupDuplicity* self, DejaDupBackend* backend, gboolean encrypted, GList* argv, GList* envp);
static gint deja_dup_duplicity_cmp_prefix (DejaDupDuplicity* self, GFile* a, GFile* b);
DejaDupDuplicityState deja_dup_duplicity_get_state (DejaDupDuplicity* self);
static gboolean deja_dup_duplicity_cleanup (DejaDupDuplicity* self);
static void deja_dup_duplicity_cancel_inst (DejaDupDuplicity* self);
void deja_dup_duplicity_cancel (DejaDupDuplicity* self);
static void deja_dup_duplicity_set_was_stopped (DejaDupDuplicity* self, gboolean value);
GType deja_dup_duplicity_info_get_type (void);
DejaDupDuplicityInfo* deja_dup_duplicity_info_get_default (void);
gboolean deja_dup_duplicity_info_get_can_resume (DejaDupDuplicityInfo* self);
void deja_dup_duplicity_stop (DejaDupDuplicity* self);
void deja_dup_duplicity_instance_pause (DejaDupDuplicityInstance* self);
static void deja_dup_duplicity_set_status (DejaDupDuplicity* self, const char* msg, gboolean save);
void deja_dup_duplicity_instance_resume (DejaDupDuplicityInstance* self);
static void deja_dup_duplicity_set_saved_status (DejaDupDuplicity* self);
static void deja_dup_duplicity_handle_done (DejaDupDuplicity* self, DejaDupDuplicityInstance* inst, gboolean success, gboolean cancelled);
void deja_dup_duplicity_instance_cancel (DejaDupDuplicityInstance* self);
void deja_dup_duplicity_set_state (DejaDupDuplicity* self, DejaDupDuplicityState value);
gboolean deja_dup_duplicity_info_get_has_collection_status (DejaDupDuplicityInfo* self);
gboolean deja_dup_duplicity_info_get_has_backup_progress (DejaDupDuplicityInfo* self);
void deja_dup_get_full_backup_threshold_date (GDate* result);
gboolean deja_dup_duplicity_info_get_has_rename_arg (DejaDupDuplicityInfo* self);
GList* deja_dup_duplicity_get_restore_files (DejaDupDuplicity* self);
static GFile* deja_dup_duplicity_make_local_rel_path (DejaDupDuplicity* self, GFile* file);
static void deja_dup_duplicity_show_error (DejaDupDuplicity* self, const char* errorstr, const char* detail);
GFile* deja_dup_duplicity_get_local (DejaDupDuplicity* self);
gboolean deja_dup_duplicity_info_get_has_restore_progress (DejaDupDuplicityInfo* self);
char* deja_dup_operation_mode_to_string (DejaDupOperationMode mode);
static void deja_dup_duplicity_connect_and_start (DejaDupDuplicity* self, GList* argv_extra, GList* envp_extra, GList* argv_entire, GFile* custom_local);
gboolean deja_dup_duplicity_info_get_has_broken_cleanup (DejaDupDuplicityInfo* self);
static gboolean deja_dup_duplicity_delete_excess (DejaDupDuplicity* self, gint cutoff);
static gboolean deja_dup_duplicity_delete_files_if_needed (DejaDupDuplicity* self);
gboolean deja_dup_duplicity_get_was_stopped (DejaDupDuplicity* self);
gboolean deja_dup_duplicity_get_error_issued (DejaDupDuplicity* self);
static void deja_dup_duplicity_set_status_file (DejaDupDuplicity* self, GFile* file, gboolean action, gboolean save);
gboolean deja_dup_duplicity_info_get_can_read_short_filenames (DejaDupDuplicityInfo* self);
static gboolean deja_dup_duplicity_restart_with_short_filenames_if_needed (DejaDupDuplicity* self);
void deja_dup_duplicity_process_error (DejaDupDuplicity* self, char** firstline, int firstline_length1, GList* data, const char* text_in);
void deja_dup_duplicity_process_info (DejaDupDuplicity* self, char** firstline, int firstline_length1, GList* data, const char* text);
void deja_dup_duplicity_process_warning (DejaDupDuplicity* self, char** firstline, int firstline_length1, GList* data, const char* text);
static void deja_dup_duplicity_handle_message (DejaDupDuplicity* self, DejaDupDuplicityInstance* inst, char** control_line, int control_line_length1, GList* data_lines, const char* user_text);
static void deja_dup_duplicity_disconnect_inst (DejaDupDuplicity* self);
static gboolean deja_dup_duplicity_ask_question (DejaDupDuplicity* self, const char* t, const char* m);
static void deja_dup_duplicity_process_exception (DejaDupDuplicity* self, const char* exception, const char* text);
static void deja_dup_duplicity_real_process_error (DejaDupDuplicity* self, char** firstline, int firstline_length1, GList* data, const char* text_in);
DejaDupBackend* deja_dup_duplicity_get_backend (DejaDupDuplicity* self);
GType deja_dup_backend_s3_get_type (void);
gboolean deja_dup_backend_s3_bump_bucket (DejaDupBackendS3* self);
char* deja_dup_backend_get_location_pretty (DejaDupBackend* self, GError** error);
gboolean deja_dup_duplicity_info_get_new_time_format (DejaDupDuplicityInfo* self);
static void deja_dup_duplicity_process_diff_file (DejaDupDuplicity* self, const char* file);
static void deja_dup_duplicity_process_patch_file (DejaDupDuplicity* self, const char* file);
static void deja_dup_duplicity_process_progress (DejaDupDuplicity* self, char** firstline, int firstline_length1);
static void deja_dup_duplicity_process_collection_status (DejaDupDuplicity* self, GList* lines);
static void deja_dup_duplicity_process_file_stat (DejaDupDuplicity* self, const char* date, const char* file);
static void deja_dup_duplicity_real_process_info (DejaDupDuplicity* self, char** firstline, int firstline_length1, GList* data, const char* text);
static GFile* deja_dup_duplicity_make_file_obj (DejaDupDuplicity* self, const char* file);
static void deja_dup_duplicity_real_process_warning (DejaDupDuplicity* self, char** firstline, int firstline_length1, GList* data, const char* text);
static void deja_dup_duplicity_set_error_issued (DejaDupDuplicity* self, gboolean value);
static gint deja_dup_duplicity_get_volsize (DejaDupDuplicity* self);
static void _deja_dup_duplicity_handle_done_deja_dup_duplicity_instance_done (DejaDupDuplicityInstance* _sender, gboolean success, gboolean cancelled, gpointer self);
static void _deja_dup_duplicity_handle_message_deja_dup_duplicity_instance_message (DejaDupDuplicityInstance* _sender, char** control_line, int control_line_length1, GList* data_lines, const char* user_text, gpointer self);
DejaDupDuplicityInstance* deja_dup_duplicity_instance_new (void);
DejaDupDuplicityInstance* deja_dup_duplicity_instance_construct (GType object_type);
void deja_dup_duplicity_instance_start (DejaDupDuplicityInstance* self, GList* argv_in, GList* envp_in, gboolean as_root, GError** error);
static void deja_dup_duplicity_set_original_mode (DejaDupDuplicity* self, DejaDupOperationMode value);
void deja_dup_duplicity_set_local (DejaDupDuplicity* self, GFile* value);
void deja_dup_duplicity_set_restore_files (DejaDupDuplicity* self, GList* value);
static GObject * deja_dup_duplicity_constructor (GType type, guint n_construct_properties, GObjectConstructParam * construct_properties);
static void deja_dup_duplicity_finalize (GObject* obj);
static void deja_dup_duplicity_get_property (GObject * object, guint property_id, GValue * value, GParamSpec * pspec);
static void deja_dup_duplicity_set_property (GObject * object, guint property_id, const GValue * value, GParamSpec * pspec);
static void _vala_array_destroy (gpointer array, gint array_length, GDestroyNotify destroy_func);
static void _vala_array_free (gpointer array, gint array_length, GDestroyNotify destroy_func);
static gint _vala_array_length (gpointer array);
static int _vala_strcmp0 (const char * str1, const char * str2);


static void g_cclosure_user_marshal_VOID__BOOLEAN_BOOLEAN (GClosure * closure, GValue * return_value, guint n_param_values, const GValue * param_values, gpointer invocation_hint, gpointer marshal_data);
static void g_cclosure_user_marshal_VOID__STRING_STRING (GClosure * closure, GValue * return_value, guint n_param_values, const GValue * param_values, gpointer invocation_hint, gpointer marshal_data);
static void g_cclosure_user_marshal_VOID__OBJECT_BOOLEAN (GClosure * closure, GValue * return_value, guint n_param_values, const GValue * param_values, gpointer invocation_hint, gpointer marshal_data);

GType deja_dup_duplicity_state_get_type (void) {
	static volatile gsize deja_dup_duplicity_state_type_id__volatile = 0;
	if (g_once_init_enter (&deja_dup_duplicity_state_type_id__volatile)) {
		static const GEnumValue values[] = {{DEJA_DUP_DUPLICITY_STATE_NORMAL, "DEJA_DUP_DUPLICITY_STATE_NORMAL", "normal"}, {DEJA_DUP_DUPLICITY_STATE_DRY_RUN, "DEJA_DUP_DUPLICITY_STATE_DRY_RUN", "dry-run"}, {DEJA_DUP_DUPLICITY_STATE_STATUS, "DEJA_DUP_DUPLICITY_STATE_STATUS", "status"}, {DEJA_DUP_DUPLICITY_STATE_CHECK_CONTENTS, "DEJA_DUP_DUPLICITY_STATE_CHECK_CONTENTS", "check-contents"}, {DEJA_DUP_DUPLICITY_STATE_CLEANUP, "DEJA_DUP_DUPLICITY_STATE_CLEANUP", "cleanup"}, {DEJA_DUP_DUPLICITY_STATE_DELETE, "DEJA_DUP_DUPLICITY_STATE_DELETE", "delete"}, {0, NULL, NULL}};
		GType deja_dup_duplicity_state_type_id;
		deja_dup_duplicity_state_type_id = g_enum_register_static ("DejaDupDuplicityState", values);
		g_once_init_leave (&deja_dup_duplicity_state_type_id__volatile, deja_dup_duplicity_state_type_id);
	}
	return deja_dup_duplicity_state_type_id__volatile;
}


static void _g_list_free_g_object_unref (GList* self) {
	g_list_foreach (self, (GFunc) g_object_unref, NULL);
	g_list_free (self);
}


static void _g_list_free_g_free (GList* self) {
	g_list_foreach (self, (GFunc) g_free, NULL);
	g_list_free (self);
}


static void _g_list_free_deja_dup_duplicity_date_info_free (GList* self) {
	g_list_foreach (self, (GFunc) deja_dup_duplicity_date_info_free, NULL);
	g_list_free (self);
}


static void deja_dup_duplicity_network_changed (DejaDupDuplicity* self, DejaDupNetworkManager* nm, gboolean connected) {
	g_return_if_fail (self != NULL);
	g_return_if_fail (nm != NULL);
	if (connected) {
		deja_dup_duplicity_resume (self);
	} else {
		deja_dup_duplicity_pause (self);
	}
}


DejaDupDuplicity* deja_dup_duplicity_construct (GType object_type, DejaDupOperationMode mode) {
	DejaDupDuplicity * self;
	self = (DejaDupDuplicity*) g_object_new (object_type, "original-mode", mode, NULL);
	return self;
}


DejaDupDuplicity* deja_dup_duplicity_new (DejaDupOperationMode mode) {
	return deja_dup_duplicity_construct (DEJA_DUP_TYPE_DUPLICITY, mode);
}


static void _deja_dup_duplicity_network_changed_deja_dup_network_manager_changed (DejaDupNetworkManager* _sender, gboolean connected, gpointer self) {
	deja_dup_duplicity_network_changed (self, _sender, connected);
}


static void deja_dup_duplicity_real_start (DejaDupDuplicity* self, DejaDupBackend* backend, gboolean encrypted, GList* argv, GList* envp) {
	GError * _inner_error_;
	GList* _tmp2_;
	GList* _tmp3_;
	GList* _tmp4_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (backend != NULL);
	_inner_error_ = NULL;
	deja_dup_duplicity_set_mode (self, self->priv->_original_mode);
	{
		char* _tmp0_;
		char* _tmp1_;
		_tmp0_ = deja_dup_backend_get_location (backend, &_inner_error_);
		if (_inner_error_ != NULL) {
			goto __catch17_g_error;
		}
		self->priv->remote = (_tmp1_ = _tmp0_, _g_free0 (self->priv->remote), _tmp1_);
	}
	goto __finally17;
	__catch17_g_error:
	{
		GError * e;
		e = _inner_error_;
		_inner_error_ = NULL;
		{
			g_signal_emit_by_name (self, "raise-error", e->message, NULL);
			g_signal_emit_by_name (self, "done", FALSE, FALSE);
			_g_error_free0 (e);
			return;
		}
	}
	__finally17:
	if (_inner_error_ != NULL) {
		g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code);
		g_clear_error (&_inner_error_);
		return;
	}
	deja_dup_duplicity_set_backend (self, backend);
	self->priv->saved_argv = (_tmp2_ = NULL, __g_list_free_g_free0 (self->priv->saved_argv), _tmp2_);
	self->priv->saved_envp = (_tmp3_ = NULL, __g_list_free_g_free0 (self->priv->saved_envp), _tmp3_);
	self->priv->backend_argv = (_tmp4_ = NULL, __g_list_free_g_free0 (self->priv->backend_argv), _tmp4_);
	{
		GList* s_collection;
		GList* s_it;
		s_collection = argv;
		for (s_it = s_collection; s_it != NULL; s_it = s_it->next) {
			char* s;
			s = g_strdup ((const char*) s_it->data);
			{
				self->priv->saved_argv = g_list_append (self->priv->saved_argv, g_strdup (s));
				_g_free0 (s);
			}
		}
	}
	{
		GList* s_collection;
		GList* s_it;
		s_collection = envp;
		for (s_it = s_collection; s_it != NULL; s_it = s_it->next) {
			char* s;
			s = g_strdup ((const char*) s_it->data);
			{
				self->priv->saved_envp = g_list_append (self->priv->saved_envp, g_strdup (s));
				_g_free0 (s);
			}
		}
	}
	deja_dup_backend_add_argv (backend, DEJA_DUP_OPERATION_MODE_INVALID, &self->priv->backend_argv);
	if (!encrypted) {
		self->priv->backend_argv = g_list_append (self->priv->backend_argv, g_strdup ("--no-encryption"));
	}
	if (self->priv->_mode == DEJA_DUP_OPERATION_MODE_BACKUP) {
		deja_dup_duplicity_process_include_excludes (self);
	}
	{
		gint _tmp5_;
		_tmp5_ = gconf_client_get_int (deja_dup_client, DEJA_DUP_DELETE_AFTER_KEY, &_inner_error_);
		if (_inner_error_ != NULL) {
			goto __catch18_g_error;
		}
		self->priv->delete_age = _tmp5_;
	}
	goto __finally18;
	__catch18_g_error:
	{
		GError * e;
		e = _inner_error_;
		_inner_error_ = NULL;
		{
			g_warning ("Duplicity.vala:157: %s\n", e->message);
			_g_error_free0 (e);
		}
	}
	__finally18:
	if (_inner_error_ != NULL) {
		g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code);
		g_clear_error (&_inner_error_);
		return;
	}
	if (!deja_dup_duplicity_restart (self)) {
		g_signal_emit_by_name (self, "done", FALSE, FALSE);
	}
	if (!deja_dup_backend_is_native (backend)) {
		DejaDupNetworkManager* _tmp6_;
		DejaDupNetworkManager* _tmp7_;
		gboolean _tmp8_;
		g_signal_connect_object (_tmp6_ = deja_dup_network_manager_get (), "changed", (GCallback) _deja_dup_duplicity_network_changed_deja_dup_network_manager_changed, self, 0);
		_g_object_unref0 (_tmp6_);
		if ((_tmp8_ = !deja_dup_network_manager_get_connected (_tmp7_ = deja_dup_network_manager_get ()), _g_object_unref0 (_tmp7_), _tmp8_)) {
			g_debug ("Duplicity.vala:165: No connection found. Postponing the backup.");
			deja_dup_duplicity_pause (self);
		}
	}
}


void deja_dup_duplicity_start (DejaDupDuplicity* self, DejaDupBackend* backend, gboolean encrypted, GList* argv, GList* envp) {
	DEJA_DUP_DUPLICITY_GET_CLASS (self)->start (self, backend, encrypted, argv, envp);
}


static gint deja_dup_duplicity_cmp_prefix (DejaDupDuplicity* self, GFile* a, GFile* b) {
	gint result = 0;
	g_return_val_if_fail (self != NULL, 0);
	g_return_val_if_fail (a != NULL, 0);
	g_return_val_if_fail (b != NULL, 0);
	if (g_file_has_prefix (a, b)) {
		result = -1;
		return result;
	} else {
		if (g_file_has_prefix (b, a)) {
			result = 1;
			return result;
		} else {
			result = 0;
			return result;
		}
	}
}


static gpointer _g_object_ref0 (gpointer self) {
	return self ? g_object_ref (self) : NULL;
}


static void deja_dup_duplicity_process_include_excludes (DejaDupDuplicity* self) {
	g_return_if_fail (self != NULL);
	self->includes = g_list_sort (self->includes, (GCompareFunc) deja_dup_duplicity_cmp_prefix);
	self->excludes = g_list_sort (self->excludes, (GCompareFunc) deja_dup_duplicity_cmp_prefix);
	{
		GList* i_collection;
		GList* i_it;
		i_collection = self->includes;
		for (i_it = i_collection; i_it != NULL; i_it = i_it->next) {
			GFile* i;
			i = _g_object_ref0 ((GFile*) i_it->data);
			{
				GList* excludes2;
				char* _tmp1_;
				excludes2 = g_list_copy (self->excludes);
				{
					GList* e_collection;
					GList* e_it;
					e_collection = excludes2;
					for (e_it = e_collection; e_it != NULL; e_it = e_it->next) {
						GFile* e;
						e = _g_object_ref0 ((GFile*) e_it->data);
						{
							if (g_file_has_prefix (e, i)) {
								char* _tmp0_;
								self->priv->saved_argv = g_list_append (self->priv->saved_argv, g_strconcat ("--exclude=", _tmp0_ = g_file_get_path (e), NULL));
								_g_free0 (_tmp0_);
								self->excludes = g_list_remove (self->excludes, e);
							}
							_g_object_unref0 (e);
						}
					}
				}
				self->priv->saved_argv = g_list_append (self->priv->saved_argv, g_strconcat ("--include=", _tmp1_ = g_file_get_path (i), NULL));
				_g_free0 (_tmp1_);
				_g_object_unref0 (i);
				_g_list_free0 (excludes2);
			}
		}
	}
	{
		GList* e_collection;
		GList* e_it;
		e_collection = self->excludes;
		for (e_it = e_collection; e_it != NULL; e_it = e_it->next) {
			GFile* e;
			e = _g_object_ref0 ((GFile*) e_it->data);
			{
				char* _tmp2_;
				self->priv->saved_argv = g_list_append (self->priv->saved_argv, g_strconcat ("--exclude=", _tmp2_ = g_file_get_path (e), NULL));
				_g_free0 (_tmp2_);
				_g_object_unref0 (e);
			}
		}
	}
	self->priv->saved_argv = g_list_append (self->priv->saved_argv, g_strdup ("--exclude=**"));
}


void deja_dup_duplicity_cancel (DejaDupDuplicity* self) {
	DejaDupOperationMode prev_mode;
	gboolean _tmp0_ = FALSE;
	g_return_if_fail (self != NULL);
	prev_mode = self->priv->_mode;
	deja_dup_duplicity_set_mode (self, DEJA_DUP_OPERATION_MODE_INVALID);
	if (prev_mode == DEJA_DUP_OPERATION_MODE_BACKUP) {
		_tmp0_ = self->priv->_state == DEJA_DUP_DUPLICITY_STATE_NORMAL;
	} else {
		_tmp0_ = FALSE;
	}
	if (_tmp0_) {
		if (deja_dup_duplicity_cleanup (self)) {
			return;
		}
	}
	deja_dup_duplicity_cancel_inst (self);
}


void deja_dup_duplicity_stop (DejaDupDuplicity* self) {
	DejaDupDuplicityInfo* _tmp0_;
	gboolean _tmp1_;
	g_return_if_fail (self != NULL);
	deja_dup_duplicity_set_was_stopped (self, TRUE);
	if ((_tmp1_ = !deja_dup_duplicity_info_get_can_resume (_tmp0_ = deja_dup_duplicity_info_get_default ()), _g_object_unref0 (_tmp0_), _tmp1_)) {
		deja_dup_duplicity_cancel (self);
	} else {
		deja_dup_duplicity_set_mode (self, DEJA_DUP_OPERATION_MODE_INVALID);
		deja_dup_duplicity_cancel_inst (self);
	}
}


void deja_dup_duplicity_pause (DejaDupDuplicity* self) {
	g_return_if_fail (self != NULL);
	if (self->priv->inst != NULL) {
		deja_dup_duplicity_instance_pause (self->priv->inst);
		deja_dup_duplicity_set_status (self, _ ("Paused (no network)"), FALSE);
	}
}


void deja_dup_duplicity_resume (DejaDupDuplicity* self) {
	g_return_if_fail (self != NULL);
	if (self->priv->inst != NULL) {
		deja_dup_duplicity_instance_resume (self->priv->inst);
		deja_dup_duplicity_set_saved_status (self);
	}
}


static void deja_dup_duplicity_cancel_inst (DejaDupDuplicity* self) {
	g_return_if_fail (self != NULL);
	if (self->priv->inst == NULL) {
		deja_dup_duplicity_handle_done (self, NULL, FALSE, TRUE);
	} else {
		deja_dup_duplicity_instance_cancel (self->priv->inst);
	}
}


static gboolean deja_dup_duplicity_restart (DejaDupDuplicity* self) {
	gboolean result = FALSE;
	GError * _inner_error_;
	GList* extra_argv;
	char* action_desc;
	GFile* custom_local;
	g_return_val_if_fail (self != NULL, FALSE);
	_inner_error_ = NULL;
	deja_dup_duplicity_set_state (self, DEJA_DUP_DUPLICITY_STATE_NORMAL);
	if (self->priv->_mode == DEJA_DUP_OPERATION_MODE_INVALID) {
		result = FALSE;
		return result;
	}
	extra_argv = NULL;
	action_desc = NULL;
	custom_local = NULL;
	switch (self->priv->_original_mode) {
		case DEJA_DUP_OPERATION_MODE_BACKUP:
		{
			gboolean _tmp0_ = FALSE;
			if (!self->priv->checked_collection_info) {
				DejaDupDuplicityInfo* _tmp1_;
				_tmp0_ = deja_dup_duplicity_info_get_has_collection_status (_tmp1_ = deja_dup_duplicity_info_get_default ());
				_g_object_unref0 (_tmp1_);
			} else {
				_tmp0_ = FALSE;
			}
			if (_tmp0_) {
				char* _tmp2_;
				deja_dup_duplicity_set_mode (self, DEJA_DUP_OPERATION_MODE_STATUS);
				deja_dup_duplicity_set_state (self, DEJA_DUP_DUPLICITY_STATE_STATUS);
				action_desc = (_tmp2_ = g_strdup (_ ("Preparing…")), _g_free0 (action_desc), _tmp2_);
			} else {
				gboolean _tmp3_ = FALSE;
				if (!self->priv->has_progress_total) {
					DejaDupDuplicityInfo* _tmp4_;
					_tmp3_ = deja_dup_duplicity_info_get_has_backup_progress (_tmp4_ = deja_dup_duplicity_info_get_default ());
					_g_object_unref0 (_tmp4_);
				} else {
					_tmp3_ = FALSE;
				}
				if (_tmp3_) {
					char* _tmp5_;
					deja_dup_duplicity_set_state (self, DEJA_DUP_DUPLICITY_STATE_DRY_RUN);
					action_desc = (_tmp5_ = g_strdup (_ ("Preparing…")), _g_free0 (action_desc), _tmp5_);
					extra_argv = g_list_append (extra_argv, g_strdup ("--dry-run"));
				} else {
					DejaDupDuplicityInfo* _tmp6_;
					gboolean _tmp7_;
					if ((_tmp7_ = deja_dup_duplicity_info_get_has_backup_progress (_tmp6_ = deja_dup_duplicity_info_get_default ()), _g_object_unref0 (_tmp6_), _tmp7_)) {
						g_signal_emit_by_name (self, "progress", (double) 0.f);
					}
					if (self->priv->got_collection_info) {
						GDate _tmp8_ = {0};
						GDate threshold;
						GDate full_backup = {0};
						gboolean _tmp9_ = FALSE;
						threshold = (deja_dup_get_full_backup_threshold_date (&_tmp8_), _tmp8_);
						memset (&full_backup, 0, sizeof (GDate));
						{
							GList* info_collection;
							GList* info_it;
							info_collection = self->priv->collection_info;
							for (info_it = info_collection; info_it != NULL; info_it = info_it->next) {
								DejaDupDuplicityDateInfo info;
								info = *((DejaDupDuplicityDateInfo*) info_it->data);
								{
									if (info.full) {
										g_date_set_time_val (&full_backup, &info.time);
									}
								}
							}
						}
						if (!g_date_valid (&full_backup)) {
							_tmp9_ = TRUE;
						} else {
							_tmp9_ = g_date_compare (&threshold, &full_backup) > 0;
						}
						if (_tmp9_) {
							self->priv->is_full_backup = TRUE;
							if (!g_date_valid (&full_backup)) {
								g_signal_emit_by_name (self, "secondary-desc-changed", _ ("Creating the first backup.  This may take a while."));
							} else {
								g_signal_emit_by_name (self, "secondary-desc-changed", _ ("Creating a fresh backup to protect against backup corruption.  This wi" \
"ll take longer than normal."));
							}
						}
					}
				}
			}
			break;
		}
		case DEJA_DUP_OPERATION_MODE_RESTORE:
		{
			if (!self->priv->has_checked_contents) {
				char* _tmp10_;
				deja_dup_duplicity_set_mode (self, DEJA_DUP_OPERATION_MODE_LIST);
				deja_dup_duplicity_set_state (self, DEJA_DUP_DUPLICITY_STATE_CHECK_CONTENTS);
				action_desc = (_tmp10_ = g_strdup (_ ("Preparing…")), _g_free0 (action_desc), _tmp10_);
			} else {
				DejaDupDuplicityInfo* _tmp15_;
				gboolean _tmp16_;
				if (g_list_length (self->priv->homes) > 1) {
					self->priv->has_non_home_contents = TRUE;
				} else {
					if (g_list_length (self->priv->homes) == 1) {
						DejaDupDuplicityInfo* _tmp11_;
						gboolean _tmp12_;
						if ((_tmp12_ = deja_dup_duplicity_info_get_has_rename_arg (_tmp11_ = deja_dup_duplicity_info_get_default ()), _g_object_unref0 (_tmp11_), _tmp12_)) {
							GFile* old_home;
							GFile* new_home;
							old_home = _g_object_ref0 ((GFile*) self->priv->homes->data);
							new_home = _g_object_ref0 (deja_dup_duplicity_slash_home_me);
							extra_argv = g_list_append (extra_argv, g_strdup ("--rename"));
							extra_argv = g_list_append (extra_argv, g_file_get_relative_path (deja_dup_duplicity_slash, old_home));
							extra_argv = g_list_append (extra_argv, g_file_get_relative_path (deja_dup_duplicity_slash, new_home));
							_g_object_unref0 (old_home);
							_g_object_unref0 (new_home);
						} else {
							if (!g_file_has_prefix ((GFile*) self->priv->homes->data, deja_dup_duplicity_slash_home_me)) {
								self->priv->has_non_home_contents = TRUE;
							}
						}
					}
				}
				if (deja_dup_duplicity_get_restore_files (self) != NULL) {
					GFile* local_file;
					GFile* _tmp13_;
					char* rel_file_path;
					local_file = deja_dup_duplicity_make_local_rel_path (self, (GFile*) deja_dup_duplicity_get_restore_files (self)->data);
					if (!g_file_has_prefix (local_file, deja_dup_duplicity_slash_home_me)) {
						self->priv->needs_root = TRUE;
					}
					{
						g_file_make_directory_with_parents (local_file, NULL, &_inner_error_);
						if (_inner_error_ != NULL) {
							if (g_error_matches (_inner_error_, G_IO_ERROR, G_IO_ERROR_EXISTS)) {
								goto __catch19_g_io_error_exists;
							}
							goto __catch19_g_error;
						}
					}
					goto __finally19;
					__catch19_g_io_error_exists:
					{
						GError * e;
						e = _inner_error_;
						_inner_error_ = NULL;
						{
							_g_error_free0 (e);
						}
					}
					goto __finally19;
					__catch19_g_error:
					{
						GError * e;
						e = _inner_error_;
						_inner_error_ = NULL;
						{
							deja_dup_duplicity_show_error (self, e->message, NULL);
							result = FALSE;
							_g_error_free0 (e);
							_g_object_unref0 (local_file);
							__g_list_free_g_free0 (extra_argv);
							_g_free0 (action_desc);
							_g_object_unref0 (custom_local);
							return result;
						}
					}
					__finally19:
					if (_inner_error_ != NULL) {
						_g_object_unref0 (local_file);
						__g_list_free_g_free0 (extra_argv);
						_g_free0 (action_desc);
						_g_object_unref0 (custom_local);
						g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code);
						g_clear_error (&_inner_error_);
						return FALSE;
					}
					custom_local = (_tmp13_ = _g_object_ref0 (local_file), _g_object_unref0 (custom_local), _tmp13_);
					rel_file_path = g_file_get_relative_path (deja_dup_duplicity_slash, (GFile*) deja_dup_duplicity_get_restore_files (self)->data);
					extra_argv = g_list_append (extra_argv, g_strdup_printf ("--file-to-restore=%s", rel_file_path));
					_g_object_unref0 (local_file);
					_g_free0 (rel_file_path);
				} else {
					gboolean _tmp14_ = FALSE;
					if (self->priv->has_non_home_contents) {
						_tmp14_ = !g_file_has_prefix (self->priv->_local, deja_dup_duplicity_slash_home_me);
					} else {
						_tmp14_ = FALSE;
					}
					if (_tmp14_) {
						self->priv->needs_root = TRUE;
					}
				}
				if ((_tmp16_ = deja_dup_duplicity_info_get_has_restore_progress (_tmp15_ = deja_dup_duplicity_info_get_default ()), _g_object_unref0 (_tmp15_), _tmp16_)) {
					g_signal_emit_by_name (self, "progress", (double) 0.f);
				}
			}
			break;
		}
	}
	if (action_desc == NULL) {
		char* _tmp17_;
		action_desc = (_tmp17_ = deja_dup_operation_mode_to_string (self->priv->_mode), _g_free0 (action_desc), _tmp17_);
	}
	deja_dup_duplicity_set_status (self, action_desc, TRUE);
	deja_dup_duplicity_connect_and_start (self, extra_argv, NULL, NULL, custom_local);
	result = TRUE;
	__g_list_free_g_free0 (extra_argv);
	_g_free0 (action_desc);
	_g_object_unref0 (custom_local);
	return result;
}


static GFile* deja_dup_duplicity_make_local_rel_path (DejaDupDuplicity* self, GFile* file) {
	GFile* result = NULL;
	char* rel_file_path;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (file != NULL, NULL);
	rel_file_path = g_file_get_relative_path (deja_dup_duplicity_slash, file);
	result = g_file_resolve_relative_path (self->priv->_local, rel_file_path);
	_g_free0 (rel_file_path);
	return result;
}


static gboolean deja_dup_duplicity_cleanup (DejaDupDuplicity* self) {
	gboolean result = FALSE;
	gboolean _tmp0_ = FALSE;
	DejaDupDuplicityInfo* _tmp1_;
	gboolean _tmp2_;
	GList* cleanup_argv;
	g_return_val_if_fail (self != NULL, FALSE);
	if ((_tmp2_ = deja_dup_duplicity_info_get_has_broken_cleanup (_tmp1_ = deja_dup_duplicity_info_get_default ()), _g_object_unref0 (_tmp1_), _tmp2_)) {
		_tmp0_ = TRUE;
	} else {
		_tmp0_ = self->priv->_state == DEJA_DUP_DUPLICITY_STATE_CLEANUP;
	}
	if (_tmp0_) {
		result = FALSE;
		return result;
	}
	deja_dup_duplicity_set_state (self, DEJA_DUP_DUPLICITY_STATE_CLEANUP);
	cleanup_argv = NULL;
	cleanup_argv = g_list_append (cleanup_argv, g_strdup ("cleanup"));
	cleanup_argv = g_list_append (cleanup_argv, g_strdup ("--force"));
	cleanup_argv = g_list_append (cleanup_argv, g_strdup (self->priv->remote));
	deja_dup_duplicity_set_status (self, _ ("Cleaning up…"), TRUE);
	deja_dup_duplicity_connect_and_start (self, NULL, NULL, cleanup_argv, NULL);
	result = TRUE;
	__g_list_free_g_free0 (cleanup_argv);
	return result;
}


static gboolean deja_dup_duplicity_delete_excess (DejaDupDuplicity* self, gint cutoff) {
	gboolean result = FALSE;
	GList* argv;
	g_return_val_if_fail (self != NULL, FALSE);
	if (cutoff < DEJA_DUP_DUPLICITY_MINIMUM_FULL) {
		result = FALSE;
		return result;
	}
	deja_dup_duplicity_set_state (self, DEJA_DUP_DUPLICITY_STATE_DELETE);
	argv = NULL;
	argv = g_list_append (argv, g_strdup ("remove-all-but-n-full"));
	argv = g_list_append (argv, g_strdup_printf ("%d", cutoff));
	argv = g_list_append (argv, g_strdup ("--force"));
	argv = g_list_append (argv, g_strdup (self->priv->remote));
	deja_dup_duplicity_set_status (self, _ ("Cleaning up…"), TRUE);
	deja_dup_duplicity_connect_and_start (self, NULL, NULL, argv, NULL);
	result = TRUE;
	__g_list_free_g_free0 (argv);
	return result;
}


static void deja_dup_duplicity_handle_done (DejaDupDuplicity* self, DejaDupDuplicityInstance* inst, gboolean success, gboolean cancelled) {
	gboolean _tmp4_ = FALSE;
	gboolean _tmp5_ = FALSE;
	g_return_if_fail (self != NULL);
	if (!cancelled) {
		switch (self->priv->_state) {
			case DEJA_DUP_DUPLICITY_STATE_DRY_RUN:
			{
				if (success) {
					self->priv->has_progress_total = TRUE;
					self->priv->progress_total = self->priv->progress_count;
					if (deja_dup_duplicity_restart (self)) {
						return;
					}
				}
				break;
			}
			case DEJA_DUP_DUPLICITY_STATE_CLEANUP:
			{
				self->priv->cleaned_up_once = TRUE;
				if (deja_dup_duplicity_restart (self)) {
					return;
				}
				success = FALSE;
				cancelled = TRUE;
				break;
			}
			case DEJA_DUP_DUPLICITY_STATE_STATUS:
			{
				if (success) {
					gboolean _tmp0_ = FALSE;
					self->priv->checked_collection_info = TRUE;
					deja_dup_duplicity_set_mode (self, DEJA_DUP_OPERATION_MODE_BACKUP);
					if (!self->priv->got_collection_info) {
						_tmp0_ = TRUE;
					} else {
						_tmp0_ = self->priv->collection_info == NULL;
					}
					if (_tmp0_) {
						{
							GList* s_collection;
							GList* s_it;
							s_collection = self->priv->backend_argv;
							for (s_it = s_collection; s_it != NULL; s_it = s_it->next) {
								const char* s;
								s = (const char*) s_it->data;
								{
									if (_vala_strcmp0 (s, "--short-filenames") == 0) {
										self->priv->backend_argv = g_list_remove (self->priv->backend_argv, s);
									}
								}
							}
						}
					}
					if (deja_dup_duplicity_restart (self)) {
						return;
					} else {
						success = FALSE;
					}
				}
				break;
			}
			case DEJA_DUP_DUPLICITY_STATE_CHECK_CONTENTS:
			{
				if (success) {
					self->priv->has_checked_contents = TRUE;
					deja_dup_duplicity_set_mode (self, DEJA_DUP_OPERATION_MODE_RESTORE);
					if (deja_dup_duplicity_restart (self)) {
						return;
					} else {
						success = FALSE;
					}
				}
				break;
			}
			case DEJA_DUP_DUPLICITY_STATE_NORMAL:
			{
				gboolean _tmp1_ = FALSE;
				gboolean _tmp2_ = FALSE;
				if (success) {
					_tmp2_ = self->priv->_mode == DEJA_DUP_OPERATION_MODE_RESTORE;
				} else {
					_tmp2_ = FALSE;
				}
				if (_tmp2_) {
					_tmp1_ = deja_dup_duplicity_get_restore_files (self) != NULL;
				} else {
					_tmp1_ = FALSE;
				}
				if (_tmp1_) {
					self->priv->_restore_files = g_list_delete_link (self->priv->_restore_files, self->priv->_restore_files);
					if (deja_dup_duplicity_get_restore_files (self) != NULL) {
						if (deja_dup_duplicity_restart (self)) {
							return;
						}
					}
				} else {
					gboolean _tmp3_ = FALSE;
					if (success) {
						_tmp3_ = self->priv->_mode == DEJA_DUP_OPERATION_MODE_BACKUP;
					} else {
						_tmp3_ = FALSE;
					}
					if (_tmp3_) {
						if (deja_dup_duplicity_delete_files_if_needed (self)) {
							return;
						}
					}
				}
				break;
			}
		}
	} else {
		if (self->priv->_was_stopped) {
			success = TRUE;
		}
	}
	if (self->priv->_error_issued) {
		success = FALSE;
	}
	if (!success) {
		_tmp5_ = !cancelled;
	} else {
		_tmp5_ = FALSE;
	}
	if (_tmp5_) {
		_tmp4_ = !self->priv->_error_issued;
	} else {
		_tmp4_ = FALSE;
	}
	if (_tmp4_) {
		deja_dup_duplicity_show_error (self, _ ("Failed with an unknown error."), NULL);
	}
	inst = NULL;
	g_signal_emit_by_name (self, "done", success, cancelled);
}


static void deja_dup_duplicity_set_status (DejaDupDuplicity* self, const char* msg, gboolean save) {
	g_return_if_fail (self != NULL);
	g_return_if_fail (msg != NULL);
	if (save) {
		char* _tmp0_;
		GFile* _tmp1_;
		self->priv->saved_status = (_tmp0_ = g_strdup (msg), _g_free0 (self->priv->saved_status), _tmp0_);
		self->priv->saved_status_file = (_tmp1_ = NULL, _g_object_unref0 (self->priv->saved_status_file), _tmp1_);
	}
	g_signal_emit_by_name (self, "action-desc-changed", msg);
}


static void deja_dup_duplicity_set_status_file (DejaDupDuplicity* self, GFile* file, gboolean action, gboolean save) {
	g_return_if_fail (self != NULL);
	g_return_if_fail (file != NULL);
	if (save) {
		char* _tmp0_;
		GFile* _tmp1_;
		self->priv->saved_status = (_tmp0_ = NULL, _g_free0 (self->priv->saved_status), _tmp0_);
		self->priv->saved_status_file = (_tmp1_ = _g_object_ref0 (file), _g_object_unref0 (self->priv->saved_status_file), _tmp1_);
		self->priv->saved_status_file_action = action;
	}
	g_signal_emit_by_name (self, "action-file-changed", file, action);
}


static void deja_dup_duplicity_set_saved_status (DejaDupDuplicity* self) {
	g_return_if_fail (self != NULL);
	if (self->priv->saved_status != NULL) {
		deja_dup_duplicity_set_status (self, self->priv->saved_status, FALSE);
	} else {
		deja_dup_duplicity_set_status_file (self, self->priv->saved_status_file, self->priv->saved_status_file_action, FALSE);
	}
}


static gboolean deja_dup_duplicity_restart_with_short_filenames_if_needed (DejaDupDuplicity* self) {
	gboolean result = FALSE;
	DejaDupDuplicityInfo* _tmp0_;
	gboolean _tmp1_;
	g_return_val_if_fail (self != NULL, FALSE);
	if ((_tmp1_ = deja_dup_duplicity_info_get_can_read_short_filenames (_tmp0_ = deja_dup_duplicity_info_get_default ()), _g_object_unref0 (_tmp0_), _tmp1_)) {
		result = FALSE;
		return result;
	}
	{
		GList* s_collection;
		GList* s_it;
		s_collection = self->priv->backend_argv;
		for (s_it = s_collection; s_it != NULL; s_it = s_it->next) {
			char* s;
			s = g_strdup ((const char*) s_it->data);
			{
				if (_vala_strcmp0 (s, "--short-filenames") == 0) {
					result = FALSE;
					_g_free0 (s);
					return result;
				}
				_g_free0 (s);
			}
		}
	}
	self->priv->backend_argv = g_list_append (self->priv->backend_argv, g_strdup ("--short-filenames"));
	if (!deja_dup_duplicity_restart (self)) {
		g_signal_emit_by_name (self, "done", FALSE, FALSE);
		result = FALSE;
		return result;
	}
	result = TRUE;
	return result;
}


static gboolean deja_dup_duplicity_delete_files_if_needed (DejaDupDuplicity* self) {
	gboolean result = FALSE;
	gboolean _tmp0_ = FALSE;
	g_return_val_if_fail (self != NULL, FALSE);
	if (self->priv->got_collection_info) {
		_tmp0_ = !self->priv->deleted_files;
	} else {
		_tmp0_ = FALSE;
	}
	if (_tmp0_) {
		gint full_dates;
		GTimeVal prev_time = {0};
		GDate prev_date = {0};
		gint too_old;
		GTimeVal now = {0};
		GDate today = {0};
		gboolean _tmp1_ = FALSE;
		full_dates = 0;
		g_get_current_time (&prev_time);
		memset (&prev_date, 0, sizeof (GDate));
		too_old = 0;
		g_get_current_time (&now);
		g_get_current_time (&now);
		memset (&today, 0, sizeof (GDate));
		g_date_set_time_val (&today, &now);
		{
			GList* info_collection;
			GList* info_it;
			info_collection = self->priv->collection_info;
			for (info_it = info_collection; info_it != NULL; info_it = info_it->next) {
				DejaDupDuplicityDateInfo info;
				info = *((DejaDupDuplicityDateInfo*) info_it->data);
				{
					if (info.full) {
						if (full_dates > 0) {
							g_date_set_time_val (&prev_date, &prev_time);
							if (g_date_days_between (&prev_date, &today) > self->priv->delete_age) {
								too_old = too_old + 1;
							}
						}
						full_dates = full_dates + 1;
					}
					prev_time = info.time;
				}
			}
		}
		g_date_set_time_val (&prev_date, &prev_time);
		if (g_date_days_between (&prev_date, &today) > self->priv->delete_age) {
			too_old = too_old + 1;
		}
		if (self->priv->is_full_backup) {
			full_dates = full_dates + 1;
		}
		if (too_old > 0) {
			_tmp1_ = full_dates > DEJA_DUP_DUPLICITY_MINIMUM_FULL;
		} else {
			_tmp1_ = FALSE;
		}
		if (_tmp1_) {
			gint cutoff;
			cutoff = MAX (DEJA_DUP_DUPLICITY_MINIMUM_FULL, full_dates - too_old);
			result = deja_dup_duplicity_delete_excess (self, cutoff);
			return result;
		}
		self->priv->deleted_files = TRUE;
		result = FALSE;
		return result;
	} else {
		result = FALSE;
		return result;
	}
}


static void deja_dup_duplicity_handle_message (DejaDupDuplicity* self, DejaDupDuplicityInstance* inst, char** control_line, int control_line_length1, GList* data_lines, const char* user_text) {
	char* keyword;
	GQuark _tmp1_;
	const char* _tmp0_;
	static GQuark _tmp1__label0 = 0;
	static GQuark _tmp1__label1 = 0;
	static GQuark _tmp1__label2 = 0;
	g_return_if_fail (self != NULL);
	g_return_if_fail (inst != NULL);
	g_return_if_fail (user_text != NULL);
	if (control_line_length1 == 0) {
		return;
	}
	keyword = g_strdup (control_line[0]);
	_tmp0_ = keyword;
	_tmp1_ = (NULL == _tmp0_) ? 0 : g_quark_from_string (_tmp0_);
	if (_tmp1_ == ((0 != _tmp1__label0) ? _tmp1__label0 : (_tmp1__label0 = g_quark_from_static_string ("ERROR"))))
	switch (0) {
		default:
		{
			deja_dup_duplicity_process_error (self, control_line, control_line_length1, data_lines, user_text);
			break;
		}
	} else if (_tmp1_ == ((0 != _tmp1__label1) ? _tmp1__label1 : (_tmp1__label1 = g_quark_from_static_string ("INFO"))))
	switch (0) {
		default:
		{
			deja_dup_duplicity_process_info (self, control_line, control_line_length1, data_lines, user_text);
			break;
		}
	} else if (_tmp1_ == ((0 != _tmp1__label2) ? _tmp1__label2 : (_tmp1__label2 = g_quark_from_static_string ("WARNING"))))
	switch (0) {
		default:
		{
			deja_dup_duplicity_process_warning (self, control_line, control_line_length1, data_lines, user_text);
			break;
		}
	}
	_g_free0 (keyword);
}


static gboolean deja_dup_duplicity_ask_question (DejaDupDuplicity* self, const char* t, const char* m) {
	gboolean result = FALSE;
	gboolean rv;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (t != NULL, FALSE);
	g_return_val_if_fail (m != NULL, FALSE);
	deja_dup_duplicity_disconnect_inst (self);
	g_signal_emit_by_name (self, "question", t, m);
	rv = self->priv->_mode != DEJA_DUP_OPERATION_MODE_INVALID;
	if (!rv) {
		deja_dup_duplicity_handle_done (self, NULL, FALSE, TRUE);
	}
	result = rv;
	return result;
}


static void deja_dup_duplicity_real_process_error (DejaDupDuplicity* self, char** firstline, int firstline_length1, GList* data, const char* text_in) {
	char* text;
	g_return_if_fail (self != NULL);
	g_return_if_fail (text_in != NULL);
	text = g_strdup (text_in);
	if (self->priv->_state == DEJA_DUP_DUPLICITY_STATE_CLEANUP) {
		_g_free0 (text);
		return;
	}
	if (firstline_length1 > 1) {
		switch (atoi (firstline[1])) {
			case DEJA_DUP_DUPLICITY_ERROR_EXCEPTION:
			{
				const char* _tmp0_;
				_tmp0_ = NULL;
				if (firstline_length1 > 2) {
					_tmp0_ = firstline[2];
				} else {
					_tmp0_ = "";
				}
				deja_dup_duplicity_process_exception (self, _tmp0_, text);
				_g_free0 (text);
				return;
			}
			case DEJA_DUP_DUPLICITY_ERROR_RESTORE_DIR_NOT_FOUND:
			{
				if (deja_dup_duplicity_get_restore_files (self) != NULL) {
					char* _tmp2_;
					char* _tmp1_;
					text = (_tmp2_ = g_strdup_printf (_ ("Could not restore ‘%s’: File not found in backup"), _tmp1_ = g_file_get_parse_name ((GFile*) deja_dup_duplicity_get_restore_files (self)->data)), _g_free0 (text), _tmp2_);
					_g_free0 (_tmp1_);
				}
				break;
			}
			case DEJA_DUP_DUPLICITY_ERROR_GPG:
			{
				char* _tmp3_;
				text = (_tmp3_ = g_strdup (_ ("Bad encryption password.")), _g_free0 (text), _tmp3_);
				break;
			}
			case DEJA_DUP_DUPLICITY_ERROR_HOSTNAME_CHANGED:
			{
				if (firstline_length1 >= 4) {
					char* _tmp4_;
					gboolean _tmp5_;
					if ((_tmp5_ = !deja_dup_duplicity_ask_question (self, _ ("Computer name changed"), _tmp4_ = g_strdup_printf (_ ("The existing backup is of a computer named %s, but the current compute" \
"r’s name is %s.  If this is unexpected, you should backup to a differe" \
"nt location."), firstline[2], firstline[3])), _g_free0 (_tmp4_), _tmp5_)) {
						_g_free0 (text);
						return;
					}
				}
				self->priv->saved_argv = g_list_append (self->priv->saved_argv, g_strdup ("--allow-source-mismatch"));
				if (deja_dup_duplicity_restart (self)) {
					_g_free0 (text);
					return;
				}
				break;
			}
		}
	}
	deja_dup_duplicity_show_error (self, text, NULL);
	_g_free0 (text);
}


void deja_dup_duplicity_process_error (DejaDupDuplicity* self, char** firstline, int firstline_length1, GList* data, const char* text_in) {
	DEJA_DUP_DUPLICITY_GET_CLASS (self)->process_error (self, firstline, firstline_length1, data, text_in);
}


static void deja_dup_duplicity_process_exception (DejaDupDuplicity* self, const char* exception, const char* text) {
	GError * _inner_error_;
	GQuark _tmp14_;
	const char* _tmp13_;
	static GQuark _tmp14__label0 = 0;
	static GQuark _tmp14__label1 = 0;
	static GQuark _tmp14__label2 = 0;
	static GQuark _tmp14__label3 = 0;
	g_return_if_fail (self != NULL);
	g_return_if_fail (exception != NULL);
	g_return_if_fail (text != NULL);
	_inner_error_ = NULL;
	_tmp13_ = exception;
	_tmp14_ = (NULL == _tmp13_) ? 0 : g_quark_from_string (_tmp13_);
	if (_tmp14_ == ((0 != _tmp14__label0) ? _tmp14__label0 : (_tmp14__label0 = g_quark_from_static_string ("S3ResponseError"))))
	switch (0) {
		default:
		{
			if (strstr (text, "<Code>InvalidAccessKeyId</Code>") != NULL) {
				deja_dup_duplicity_show_error (self, _ ("Invalid ID."), NULL);
			} else {
				if (strstr (text, "<Code>SignatureDoesNotMatch</Code>") != NULL) {
					deja_dup_duplicity_show_error (self, _ ("Invalid secret key."), NULL);
				} else {
					if (strstr (text, "<Code>NotSignedUp</Code>") != NULL) {
						deja_dup_duplicity_show_error (self, _ ("Your Amazon Web Services account is not signed up for the S3 service."), NULL);
					}
				}
			}
			break;
		}
	} else if (_tmp14_ == ((0 != _tmp14__label1) ? _tmp14__label1 : (_tmp14__label1 = g_quark_from_static_string ("S3CreateError"))))
	switch (0) {
		default:
		{
			if (strstr (text, "<Code>BucketAlreadyExists</Code>") != NULL) {
				if (deja_dup_backend_s3_bump_bucket (DEJA_DUP_BACKEND_S3 (self->priv->_backend))) {
					{
						char* _tmp0_;
						char* _tmp1_;
						_tmp0_ = deja_dup_backend_get_location (self->priv->_backend, &_inner_error_);
						if (_inner_error_ != NULL) {
							goto __catch20_g_error;
						}
						self->priv->remote = (_tmp1_ = _tmp0_, _g_free0 (self->priv->remote), _tmp1_);
						if (deja_dup_duplicity_restart (self)) {
							return;
						}
					}
					goto __finally20;
					__catch20_g_error:
					{
						GError * e;
						e = _inner_error_;
						_inner_error_ = NULL;
						{
							g_warning ("Duplicity.vala:725: %s\n", e->message);
							_g_error_free0 (e);
						}
					}
					__finally20:
					if (_inner_error_ != NULL) {
						g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code);
						g_clear_error (&_inner_error_);
						return;
					}
				}
				deja_dup_duplicity_show_error (self, _ ("S3 bucket name is not available."), NULL);
			}
			break;
		}
	} else if (_tmp14_ == ((0 != _tmp14__label2) ? _tmp14__label2 : (_tmp14__label2 = g_quark_from_static_string ("IOError"))))
	switch (0) {
		default:
		{
			if (strstr (text, "GnuPG") != NULL) {
				deja_dup_duplicity_show_error (self, _ ("Bad encryption password."), NULL);
			} else {
				gboolean _tmp2_ = FALSE;
				if (strstr (text, "[Errno 5]") != NULL) {
					_tmp2_ = self->priv->last_touched_file != NULL;
				} else {
					_tmp2_ = FALSE;
				}
				if (_tmp2_) {
					if (self->priv->_mode == DEJA_DUP_OPERATION_MODE_BACKUP) {
						char* _tmp4_;
						char* _tmp3_;
						deja_dup_duplicity_show_error (self, _tmp4_ = g_strdup_printf (_ ("Error reading file ‘%s’."), _tmp3_ = g_file_get_parse_name (self->priv->last_touched_file)), NULL);
						_g_free0 (_tmp4_);
						_g_free0 (_tmp3_);
					} else {
						char* _tmp6_;
						char* _tmp5_;
						deja_dup_duplicity_show_error (self, _tmp6_ = g_strdup_printf (_ ("Error writing file ‘%s’."), _tmp5_ = g_file_get_parse_name (self->priv->last_touched_file)), NULL);
						_g_free0 (_tmp6_);
						_g_free0 (_tmp5_);
					}
				} else {
					if (strstr (text, "[Errno 28]") != NULL) {
						char* where;
						where = NULL;
						if (self->priv->_mode == DEJA_DUP_OPERATION_MODE_BACKUP) {
							{
								char* _tmp7_;
								char* _tmp8_;
								_tmp7_ = deja_dup_backend_get_location_pretty (self->priv->_backend, &_inner_error_);
								if (_inner_error_ != NULL) {
									goto __catch21_g_error;
								}
								where = (_tmp8_ = _tmp7_, _g_free0 (where), _tmp8_);
							}
							goto __finally21;
							__catch21_g_error:
							{
								GError * e;
								e = _inner_error_;
								_inner_error_ = NULL;
								{
									g_warning ("Duplicity.vala:747: %s\n", e->message);
									_g_error_free0 (e);
								}
							}
							__finally21:
							if (_inner_error_ != NULL) {
								_g_free0 (where);
								g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code);
								g_clear_error (&_inner_error_);
								return;
							}
						} else {
							char* _tmp9_;
							where = (_tmp9_ = g_file_get_path (self->priv->_local), _g_free0 (where), _tmp9_);
						}
						if (where == NULL) {
							deja_dup_duplicity_show_error (self, _ ("No space left"), NULL);
						} else {
							char* _tmp10_;
							deja_dup_duplicity_show_error (self, _tmp10_ = g_strdup_printf (_ ("No space left in %s"), where), NULL);
							_g_free0 (_tmp10_);
						}
						_g_free0 (where);
					} else {
						DejaDupDuplicityInfo* _tmp11_;
						gboolean _tmp12_;
						if ((_tmp12_ = !deja_dup_duplicity_info_get_new_time_format (_tmp11_ = deja_dup_duplicity_info_get_default ()), _g_object_unref0 (_tmp11_), _tmp12_)) {
							deja_dup_duplicity_restart_with_short_filenames_if_needed (self);
						}
					}
				}
			}
			break;
		}
	} else if (_tmp14_ == ((0 != _tmp14__label3) ? _tmp14__label3 : (_tmp14__label3 = g_quark_from_static_string ("CollectionsError"))))
	switch (0) {
		default:
		{
			if (deja_dup_duplicity_restart_with_short_filenames_if_needed (self)) {
				deja_dup_duplicity_show_error (self, _ ("No backup files found"), NULL);
			}
			break;
		}
	}
	if (!self->priv->_error_issued) {
		deja_dup_duplicity_show_error (self, _ ("Failed with an unknown error."), text);
	}
}


static void deja_dup_duplicity_real_process_info (DejaDupDuplicity* self, char** firstline, int firstline_length1, GList* data, const char* text) {
	g_return_if_fail (self != NULL);
	g_return_if_fail (text != NULL);
	if (firstline_length1 > 1) {
		switch (atoi (firstline[1])) {
			case DEJA_DUP_DUPLICITY_INFO_DIFF_FILE_NEW:
			case DEJA_DUP_DUPLICITY_INFO_DIFF_FILE_CHANGED:
			case DEJA_DUP_DUPLICITY_INFO_DIFF_FILE_DELETED:
			{
				if (firstline_length1 > 2) {
					deja_dup_duplicity_process_diff_file (self, firstline[2]);
				}
				break;
			}
			case DEJA_DUP_DUPLICITY_INFO_PATCH_FILE_WRITING:
			case DEJA_DUP_DUPLICITY_INFO_PATCH_FILE_PATCHING:
			{
				if (firstline_length1 > 2) {
					deja_dup_duplicity_process_patch_file (self, firstline[2]);
				}
				break;
			}
			case DEJA_DUP_DUPLICITY_INFO_PROGRESS:
			{
				deja_dup_duplicity_process_progress (self, firstline, firstline_length1);
				break;
			}
			case DEJA_DUP_DUPLICITY_INFO_COLLECTION_STATUS:
			{
				deja_dup_duplicity_process_collection_status (self, data);
				break;
			}
			case DEJA_DUP_DUPLICITY_INFO_SYNCHRONOUS_UPLOAD_BEGIN:
			case DEJA_DUP_DUPLICITY_INFO_ASYNCHRONOUS_UPLOAD_BEGIN:
			{
				if (!deja_dup_backend_is_native (self->priv->_backend)) {
					deja_dup_duplicity_set_status (self, _ ("Uploading…"), TRUE);
				}
				break;
			}
			case DEJA_DUP_DUPLICITY_INFO_FILE_STAT:
			{
				deja_dup_duplicity_process_file_stat (self, firstline[2], firstline[3]);
				break;
			}
		}
	}
}


void deja_dup_duplicity_process_info (DejaDupDuplicity* self, char** firstline, int firstline_length1, GList* data, const char* text) {
	DEJA_DUP_DUPLICITY_GET_CLASS (self)->process_info (self, firstline, firstline_length1, data, text);
}


static void deja_dup_duplicity_process_file_stat (DejaDupDuplicity* self, const char* date, const char* file) {
	g_return_if_fail (self != NULL);
	g_return_if_fail (date != NULL);
	g_return_if_fail (file != NULL);
	if (self->priv->_mode != DEJA_DUP_OPERATION_MODE_LIST) {
		return;
	}
	if (self->priv->_state == DEJA_DUP_DUPLICITY_STATE_CHECK_CONTENTS) {
		GFile* gfile;
		gboolean _tmp0_ = FALSE;
		gboolean _tmp5_ = FALSE;
		gboolean _tmp6_ = FALSE;
		gfile = deja_dup_duplicity_make_file_obj (self, file);
		if (g_file_equal (gfile, deja_dup_duplicity_slash_root)) {
			_tmp0_ = TRUE;
		} else {
			gboolean _tmp1_ = FALSE;
			GFile* _tmp2_;
			gboolean _tmp3_;
			if ((_tmp3_ = (_tmp2_ = g_file_get_parent (gfile)) != NULL, _g_object_unref0 (_tmp2_), _tmp3_)) {
				GFile* _tmp4_;
				_tmp1_ = g_file_equal (_tmp4_ = g_file_get_parent (gfile), deja_dup_duplicity_slash_home);
				_g_object_unref0 (_tmp4_);
			} else {
				_tmp1_ = FALSE;
			}
			_tmp0_ = _tmp1_;
		}
		if (_tmp0_) {
			self->priv->homes = g_list_append (self->priv->homes, _g_object_ref0 (gfile));
		}
		if (!self->priv->has_non_home_contents) {
			_tmp6_ = !g_file_equal (gfile, deja_dup_duplicity_slash);
		} else {
			_tmp6_ = FALSE;
		}
		if (_tmp6_) {
			_tmp5_ = !g_file_has_prefix (gfile, deja_dup_duplicity_slash_home);
		} else {
			_tmp5_ = FALSE;
		}
		if (_tmp5_) {
			self->priv->has_non_home_contents = TRUE;
		}
		_g_object_unref0 (gfile);
	}
}


static void deja_dup_duplicity_process_diff_file (DejaDupDuplicity* self, const char* file) {
	GFile* gfile;
	GFile* _tmp0_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (file != NULL);
	gfile = deja_dup_duplicity_make_file_obj (self, file);
	self->priv->last_touched_file = (_tmp0_ = _g_object_ref0 (gfile), _g_object_unref0 (self->priv->last_touched_file), _tmp0_);
	if (g_file_query_file_type (gfile, G_FILE_QUERY_INFO_NONE, NULL) != G_FILE_TYPE_DIRECTORY) {
		deja_dup_duplicity_set_status_file (self, gfile, self->priv->_state != DEJA_DUP_DUPLICITY_STATE_DRY_RUN, TRUE);
	}
	_g_object_unref0 (gfile);
}


static void deja_dup_duplicity_process_patch_file (DejaDupDuplicity* self, const char* file) {
	GFile* gfile;
	GFile* _tmp0_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (file != NULL);
	gfile = deja_dup_duplicity_make_file_obj (self, file);
	self->priv->last_touched_file = (_tmp0_ = _g_object_ref0 (gfile), _g_object_unref0 (self->priv->last_touched_file), _tmp0_);
	if (g_file_query_file_type (gfile, G_FILE_QUERY_INFO_NONE, NULL) != G_FILE_TYPE_DIRECTORY) {
		deja_dup_duplicity_set_status_file (self, gfile, self->priv->_state != DEJA_DUP_DUPLICITY_STATE_DRY_RUN, TRUE);
	}
	_g_object_unref0 (gfile);
}


static void deja_dup_duplicity_process_progress (DejaDupDuplicity* self, char** firstline, int firstline_length1) {
	gboolean _tmp0_ = FALSE;
	DejaDupDuplicityInfo* _tmp1_;
	gboolean _tmp2_;
	double total = 0.0;
	double percent;
	g_return_if_fail (self != NULL);
	if ((_tmp2_ = !deja_dup_duplicity_info_get_has_restore_progress (_tmp1_ = deja_dup_duplicity_info_get_default ()), _g_object_unref0 (_tmp1_), _tmp2_)) {
		_tmp0_ = self->priv->_mode == DEJA_DUP_OPERATION_MODE_RESTORE;
	} else {
		_tmp0_ = FALSE;
	}
	if (_tmp0_) {
		return;
	}
	if (firstline_length1 > 2) {
		self->priv->progress_count = g_ascii_strtod (firstline[2], NULL);
	} else {
		return;
	}
	if (firstline_length1 > 3) {
		total = g_ascii_strtod (firstline[3], NULL);
	} else {
		if (self->priv->progress_total > 0) {
			total = self->priv->progress_total;
		} else {
			return;
		}
	}
	percent = self->priv->progress_count / ((double) total);
	if (percent > 1) {
		percent = (double) 1;
	}
	if (percent < 0) {
		percent = (double) 0;
	}
	g_signal_emit_by_name (self, "progress", percent);
}


static GFile* deja_dup_duplicity_make_file_obj (DejaDupDuplicity* self, const char* file) {
	GFile* result = NULL;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (file != NULL, NULL);
	result = g_file_resolve_relative_path (deja_dup_duplicity_slash, file);
	return result;
}


static glong string_get_length (const char* self) {
	glong result;
	g_return_val_if_fail (self != NULL, 0L);
	result = g_utf8_strlen (self, -1);
	return result;
}


static gpointer _deja_dup_duplicity_date_info_dup0 (gpointer self) {
	return self ? deja_dup_duplicity_date_info_dup (self) : NULL;
}


static void deja_dup_duplicity_process_collection_status (DejaDupDuplicity* self, GList* lines) {
	GTimeVal timeval = {0};
	GList* dates;
	GList* infos;
	gboolean in_chain;
	gboolean _tmp6_ = FALSE;
	GList* _tmp7_;
	g_return_if_fail (self != NULL);
	g_get_current_time (&timeval);
	dates = NULL;
	infos = NULL;
	in_chain = FALSE;
	{
		GList* line_collection;
		GList* line_it;
		line_collection = lines;
		for (line_it = line_collection; line_it != NULL; line_it = line_it->next) {
			char* line;
			line = g_strdup ((const char*) line_it->data);
			{
				gboolean _tmp0_ = FALSE;
				if (_vala_strcmp0 (line, "chain-complete") == 0) {
					_tmp0_ = TRUE;
				} else {
					_tmp0_ = _vala_strcmp0 (strstr (line, "chain-no-sig"), line) == 0;
				}
				if (_tmp0_) {
					in_chain = TRUE;
				} else {
					gboolean _tmp1_ = FALSE;
					gboolean _tmp2_ = FALSE;
					if (in_chain) {
						_tmp2_ = string_get_length (line) > 0;
					} else {
						_tmp2_ = FALSE;
					}
					if (_tmp2_) {
						_tmp1_ = g_utf8_get_char (g_utf8_offset_to_pointer (line, 0)) == ' ';
					} else {
						_tmp1_ = FALSE;
					}
					if (_tmp1_) {
						char** _tmp4_;
						gint _tokens_size_;
						gint tokens_length1;
						char** _tmp3_;
						char** tokens;
						gboolean _tmp5_ = FALSE;
						tokens = (_tmp4_ = _tmp3_ = g_strsplit (line, " ", 0), tokens_length1 = _vala_array_length (_tmp3_), _tokens_size_ = tokens_length1, _tmp4_);
						if (tokens_length1 > 2) {
							_tmp5_ = g_time_val_from_iso8601 (tokens[2], &timeval);
						} else {
							_tmp5_ = FALSE;
						}
						if (_tmp5_) {
							DejaDupDuplicityDateInfo info = {0};
							dates = g_list_append (dates, g_strdup (tokens[2]));
							memset (&info, 0, sizeof (DejaDupDuplicityDateInfo));
							info.time = timeval;
							info.full = _vala_strcmp0 (tokens[1], "full") == 0;
							infos = g_list_append (infos, _deja_dup_duplicity_date_info_dup0 (&info));
						}
						tokens = (_vala_array_free (tokens, tokens_length1, (GDestroyNotify) g_free), NULL);
					} else {
						if (in_chain) {
							in_chain = FALSE;
						}
					}
				}
				_g_free0 (line);
			}
		}
	}
	if (self->priv->_mode == DEJA_DUP_OPERATION_MODE_STATUS) {
		_tmp6_ = g_list_length (dates) == 0;
	} else {
		_tmp6_ = FALSE;
	}
	if (_tmp6_) {
		if (deja_dup_duplicity_restart_with_short_filenames_if_needed (self)) {
			__g_list_free_g_free0 (dates);
			__g_list_free_deja_dup_duplicity_date_info_free0 (infos);
			return;
		}
	}
	self->priv->got_collection_info = TRUE;
	self->priv->collection_info = (_tmp7_ = NULL, __g_list_free_deja_dup_duplicity_date_info_free0 (self->priv->collection_info), _tmp7_);
	{
		GList* s_collection;
		GList* s_it;
		s_collection = infos;
		for (s_it = s_collection; s_it != NULL; s_it = s_it->next) {
			DejaDupDuplicityDateInfo s;
			s = *((DejaDupDuplicityDateInfo*) s_it->data);
			{
				self->priv->collection_info = g_list_append (self->priv->collection_info, _deja_dup_duplicity_date_info_dup0 (&s));
			}
		}
	}
	g_signal_emit_by_name (self, "collection-dates", dates);
	__g_list_free_g_free0 (dates);
	__g_list_free_deja_dup_duplicity_date_info_free0 (infos);
}


static void deja_dup_duplicity_real_process_warning (DejaDupDuplicity* self, char** firstline, int firstline_length1, GList* data, const char* text) {
	g_return_if_fail (self != NULL);
	g_return_if_fail (text != NULL);
	if (firstline_length1 > 1) {
		switch (atoi (firstline[1])) {
			case DEJA_DUP_DUPLICITY_WARNING_ORPHANED_SIG:
			case DEJA_DUP_DUPLICITY_WARNING_UNNECESSARY_SIG:
			case DEJA_DUP_DUPLICITY_WARNING_UNMATCHED_SIG:
			case DEJA_DUP_DUPLICITY_WARNING_INCOMPLETE_BACKUP:
			case DEJA_DUP_DUPLICITY_WARNING_ORPHANED_BACKUP:
			{
				if (!self->priv->cleaned_up_once) {
					deja_dup_duplicity_cleanup (self);
				}
				break;
			}
		}
	}
}


void deja_dup_duplicity_process_warning (DejaDupDuplicity* self, char** firstline, int firstline_length1, GList* data, const char* text) {
	DEJA_DUP_DUPLICITY_GET_CLASS (self)->process_warning (self, firstline, firstline_length1, data, text);
}


static void deja_dup_duplicity_show_error (DejaDupDuplicity* self, const char* errorstr, const char* detail) {
	g_return_if_fail (self != NULL);
	g_return_if_fail (errorstr != NULL);
	if (self->priv->_error_issued == FALSE) {
		deja_dup_duplicity_set_error_issued (self, TRUE);
		g_signal_emit_by_name (self, "raise-error", errorstr, detail);
	}
}


static gint deja_dup_duplicity_get_volsize (DejaDupDuplicity* self) {
	gint result = 0;
	g_return_val_if_fail (self != NULL, 0);
	if (deja_dup_backend_is_native (self->priv->_backend)) {
		result = 30;
		return result;
	} else {
		result = 10;
		return result;
	}
}


static void _deja_dup_duplicity_handle_done_deja_dup_duplicity_instance_done (DejaDupDuplicityInstance* _sender, gboolean success, gboolean cancelled, gpointer self) {
	deja_dup_duplicity_handle_done (self, _sender, success, cancelled);
}


static void _deja_dup_duplicity_handle_message_deja_dup_duplicity_instance_message (DejaDupDuplicityInstance* _sender, char** control_line, int control_line_length1, GList* data_lines, const char* user_text, gpointer self) {
	deja_dup_duplicity_handle_message (self, _sender, control_line, control_line_length1, data_lines, user_text);
}


static void deja_dup_duplicity_disconnect_inst (DejaDupDuplicity* self) {
	g_return_if_fail (self != NULL);
	if (self->priv->inst != NULL) {
		guint _tmp0_;
		guint _tmp1_;
		DejaDupDuplicityInstance* _tmp2_;
		g_signal_parse_name ("done", DEJA_DUP_TYPE_DUPLICITY_INSTANCE, &_tmp0_, NULL, FALSE);
		g_signal_handlers_disconnect_matched (self->priv->inst, G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, _tmp0_, 0, NULL, (GCallback) _deja_dup_duplicity_handle_done_deja_dup_duplicity_instance_done, self);
		g_signal_parse_name ("message", DEJA_DUP_TYPE_DUPLICITY_INSTANCE, &_tmp1_, NULL, FALSE);
		g_signal_handlers_disconnect_matched (self->priv->inst, G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, _tmp1_, 0, NULL, (GCallback) _deja_dup_duplicity_handle_message_deja_dup_duplicity_instance_message, self);
		deja_dup_duplicity_instance_cancel (self->priv->inst);
		self->priv->inst = (_tmp2_ = NULL, _g_object_unref0 (self->priv->inst), _tmp2_);
	}
}


static void deja_dup_duplicity_connect_and_start (DejaDupDuplicity* self, GList* argv_extra, GList* envp_extra, GList* argv_entire, GFile* custom_local) {
	GError * _inner_error_;
	DejaDupDuplicityInstance* _tmp0_;
	GList* _tmp1_;
	GList* master_argv;
	GFile* _tmp2_;
	GFile* local_arg;
	GList* argv;
	GList* envp;
	g_return_if_fail (self != NULL);
	_inner_error_ = NULL;
	deja_dup_duplicity_disconnect_inst (self);
	self->priv->inst = (_tmp0_ = deja_dup_duplicity_instance_new (), _g_object_unref0 (self->priv->inst), _tmp0_);
	g_signal_connect_object (self->priv->inst, "done", (GCallback) _deja_dup_duplicity_handle_done_deja_dup_duplicity_instance_done, self, 0);
	g_signal_connect_object (self->priv->inst, "message", (GCallback) _deja_dup_duplicity_handle_message_deja_dup_duplicity_instance_message, self, 0);
	_tmp1_ = NULL;
	if (argv_entire == NULL) {
		_tmp1_ = self->priv->saved_argv;
	} else {
		_tmp1_ = argv_entire;
	}
	master_argv = _tmp1_;
	_tmp2_ = NULL;
	if (custom_local == NULL) {
		_tmp2_ = self->priv->_local;
	} else {
		_tmp2_ = custom_local;
	}
	local_arg = _tmp2_;
	argv = NULL;
	{
		GList* s_collection;
		GList* s_it;
		s_collection = master_argv;
		for (s_it = s_collection; s_it != NULL; s_it = s_it->next) {
			char* s;
			s = g_strdup ((const char*) s_it->data);
			{
				argv = g_list_append (argv, g_strdup (s));
				_g_free0 (s);
			}
		}
	}
	{
		GList* s_collection;
		GList* s_it;
		s_collection = argv_extra;
		for (s_it = s_collection; s_it != NULL; s_it = s_it->next) {
			char* s;
			s = g_strdup ((const char*) s_it->data);
			{
				argv = g_list_append (argv, g_strdup (s));
				_g_free0 (s);
			}
		}
	}
	{
		GList* s_collection;
		GList* s_it;
		s_collection = self->priv->backend_argv;
		for (s_it = s_collection; s_it != NULL; s_it = s_it->next) {
			char* s;
			s = g_strdup ((const char*) s_it->data);
			{
				argv = g_list_append (argv, g_strdup (s));
				_g_free0 (s);
			}
		}
	}
	if (argv_entire == NULL) {
		switch (self->priv->_mode) {
			case DEJA_DUP_OPERATION_MODE_BACKUP:
			{
				if (self->priv->is_full_backup) {
					argv = g_list_prepend (argv, g_strdup ("full"));
				}
				argv = g_list_append (argv, g_strdup_printf ("--volsize=%d", deja_dup_duplicity_get_volsize (self)));
				argv = g_list_append (argv, g_file_get_path (local_arg));
				argv = g_list_append (argv, g_strdup (self->priv->remote));
				break;
			}
			case DEJA_DUP_OPERATION_MODE_RESTORE:
			{
				argv = g_list_prepend (argv, g_strdup ("restore"));
				argv = g_list_append (argv, g_strdup ("--force"));
				argv = g_list_append (argv, g_strdup (self->priv->remote));
				argv = g_list_append (argv, g_file_get_path (local_arg));
				break;
			}
			case DEJA_DUP_OPERATION_MODE_STATUS:
			{
				argv = g_list_prepend (argv, g_strdup ("collection-status"));
				argv = g_list_append (argv, g_strdup (self->priv->remote));
				break;
			}
			case DEJA_DUP_OPERATION_MODE_LIST:
			{
				argv = g_list_prepend (argv, g_strdup ("list-current-files"));
				argv = g_list_append (argv, g_strdup (self->priv->remote));
				break;
			}
		}
	}
	envp = NULL;
	{
		GList* s_collection;
		GList* s_it;
		s_collection = self->priv->saved_envp;
		for (s_it = s_collection; s_it != NULL; s_it = s_it->next) {
			char* s;
			s = g_strdup ((const char*) s_it->data);
			{
				envp = g_list_append (envp, g_strdup (s));
				_g_free0 (s);
			}
		}
	}
	{
		GList* s_collection;
		GList* s_it;
		s_collection = envp_extra;
		for (s_it = s_collection; s_it != NULL; s_it = s_it->next) {
			char* s;
			s = g_strdup ((const char*) s_it->data);
			{
				envp = g_list_append (envp, g_strdup (s));
				_g_free0 (s);
			}
		}
	}
	{
		deja_dup_duplicity_instance_start (self->priv->inst, argv, envp, self->priv->needs_root, &_inner_error_);
		if (_inner_error_ != NULL) {
			goto __catch22_g_error;
		}
	}
	goto __finally22;
	__catch22_g_error:
	{
		GError * e;
		e = _inner_error_;
		_inner_error_ = NULL;
		{
			deja_dup_duplicity_show_error (self, e->message, NULL);
			g_signal_emit_by_name (self, "done", FALSE, FALSE);
			_g_error_free0 (e);
		}
	}
	__finally22:
	if (_inner_error_ != NULL) {
		__g_list_free_g_free0 (argv);
		__g_list_free_g_free0 (envp);
		g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code);
		g_clear_error (&_inner_error_);
		return;
	}
	__g_list_free_g_free0 (argv);
	__g_list_free_g_free0 (envp);
}


DejaDupOperationMode deja_dup_duplicity_get_original_mode (DejaDupDuplicity* self) {
	DejaDupOperationMode result;
	g_return_val_if_fail (self != NULL, 0);
	result = self->priv->_original_mode;
	return result;
}


static void deja_dup_duplicity_set_original_mode (DejaDupDuplicity* self, DejaDupOperationMode value) {
	g_return_if_fail (self != NULL);
	self->priv->_original_mode = value;
	g_object_notify ((GObject *) self, "original-mode");
}


DejaDupOperationMode deja_dup_duplicity_get_mode (DejaDupDuplicity* self) {
	DejaDupOperationMode result;
	g_return_val_if_fail (self != NULL, 0);
	result = self->priv->_mode;
	return result;
}


static void deja_dup_duplicity_set_mode (DejaDupDuplicity* self, DejaDupOperationMode value) {
	g_return_if_fail (self != NULL);
	self->priv->_mode = value;
	g_object_notify ((GObject *) self, "mode");
}


gboolean deja_dup_duplicity_get_error_issued (DejaDupDuplicity* self) {
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	result = self->priv->_error_issued;
	return result;
}


static void deja_dup_duplicity_set_error_issued (DejaDupDuplicity* self, gboolean value) {
	g_return_if_fail (self != NULL);
	self->priv->_error_issued = value;
	g_object_notify ((GObject *) self, "error-issued");
}


gboolean deja_dup_duplicity_get_was_stopped (DejaDupDuplicity* self) {
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	result = self->priv->_was_stopped;
	return result;
}


static void deja_dup_duplicity_set_was_stopped (DejaDupDuplicity* self, gboolean value) {
	g_return_if_fail (self != NULL);
	self->priv->_was_stopped = value;
	g_object_notify ((GObject *) self, "was-stopped");
}


GFile* deja_dup_duplicity_get_local (DejaDupDuplicity* self) {
	GFile* result;
	g_return_val_if_fail (self != NULL, NULL);
	result = self->priv->_local;
	return result;
}


void deja_dup_duplicity_set_local (DejaDupDuplicity* self, GFile* value) {
	GFile* _tmp0_;
	g_return_if_fail (self != NULL);
	self->priv->_local = (_tmp0_ = _g_object_ref0 (value), _g_object_unref0 (self->priv->_local), _tmp0_);
	g_object_notify ((GObject *) self, "local");
}


DejaDupBackend* deja_dup_duplicity_get_backend (DejaDupDuplicity* self) {
	DejaDupBackend* result;
	g_return_val_if_fail (self != NULL, NULL);
	result = self->priv->_backend;
	return result;
}


void deja_dup_duplicity_set_backend (DejaDupDuplicity* self, DejaDupBackend* value) {
	DejaDupBackend* _tmp0_;
	g_return_if_fail (self != NULL);
	self->priv->_backend = (_tmp0_ = _g_object_ref0 (value), _g_object_unref0 (self->priv->_backend), _tmp0_);
	g_object_notify ((GObject *) self, "backend");
}


GList* deja_dup_duplicity_get_restore_files (DejaDupDuplicity* self) {
	GList* result;
	g_return_val_if_fail (self != NULL, NULL);
	result = self->priv->_restore_files;
	return result;
}


void deja_dup_duplicity_set_restore_files (DejaDupDuplicity* self, GList* value) {
	GList* _tmp0_;
	g_return_if_fail (self != NULL);
	{
		GList* f_collection;
		GList* f_it;
		f_collection = self->priv->_restore_files;
		for (f_it = f_collection; f_it != NULL; f_it = f_it->next) {
			GFile* f;
			f = _g_object_ref0 ((GFile*) f_it->data);
			{
				g_object_unref ((GObject*) f);
				_g_object_unref0 (f);
			}
		}
	}
	self->priv->_restore_files = (_tmp0_ = g_list_copy (value), __g_list_free_g_object_unref0 (self->priv->_restore_files), _tmp0_);
	{
		GList* f_collection;
		GList* f_it;
		f_collection = self->priv->_restore_files;
		for (f_it = f_collection; f_it != NULL; f_it = f_it->next) {
			GFile* f;
			f = _g_object_ref0 ((GFile*) f_it->data);
			{
				g_object_ref ((GObject*) f);
				_g_object_unref0 (f);
			}
		}
	}
	g_object_notify ((GObject *) self, "restore-files");
}


DejaDupDuplicityState deja_dup_duplicity_get_state (DejaDupDuplicity* self) {
	DejaDupDuplicityState result;
	g_return_val_if_fail (self != NULL, 0);
	result = self->priv->_state;
	return result;
}


void deja_dup_duplicity_set_state (DejaDupDuplicity* self, DejaDupDuplicityState value) {
	g_return_if_fail (self != NULL);
	self->priv->_state = value;
	g_object_notify ((GObject *) self, "state");
}


static GObject * deja_dup_duplicity_constructor (GType type, guint n_construct_properties, GObjectConstructParam * construct_properties) {
	GObject * obj;
	GObjectClass * parent_class;
	DejaDupDuplicity * self;
	parent_class = G_OBJECT_CLASS (deja_dup_duplicity_parent_class);
	obj = parent_class->constructor (type, n_construct_properties, construct_properties);
	self = DEJA_DUP_DUPLICITY (obj);
	{
		if (deja_dup_duplicity_slash == NULL) {
			GFile* _tmp0_;
			GFile* _tmp1_;
			GFile* _tmp2_;
			GFile* _tmp3_;
			deja_dup_duplicity_slash = (_tmp0_ = g_file_new_for_path ("/"), _g_object_unref0 (deja_dup_duplicity_slash), _tmp0_);
			deja_dup_duplicity_slash_root = (_tmp1_ = g_file_new_for_path ("/root"), _g_object_unref0 (deja_dup_duplicity_slash_root), _tmp1_);
			deja_dup_duplicity_slash_home = (_tmp2_ = g_file_new_for_path ("/home"), _g_object_unref0 (deja_dup_duplicity_slash_home), _tmp2_);
			deja_dup_duplicity_slash_home_me = (_tmp3_ = g_file_new_for_path (g_get_home_dir ()), _g_object_unref0 (deja_dup_duplicity_slash_home_me), _tmp3_);
		}
	}
	return obj;
}


static DejaDupDuplicityDateInfo* deja_dup_duplicity_date_info_dup (const DejaDupDuplicityDateInfo* self) {
	DejaDupDuplicityDateInfo* dup;
	dup = g_new0 (DejaDupDuplicityDateInfo, 1);
	memcpy (dup, self, sizeof (DejaDupDuplicityDateInfo));
	return dup;
}


static void deja_dup_duplicity_date_info_free (DejaDupDuplicityDateInfo* self) {
	g_free (self);
}


static GType deja_dup_duplicity_date_info_get_type (void) {
	static volatile gsize deja_dup_duplicity_date_info_type_id__volatile = 0;
	if (g_once_init_enter (&deja_dup_duplicity_date_info_type_id__volatile)) {
		GType deja_dup_duplicity_date_info_type_id;
		deja_dup_duplicity_date_info_type_id = g_boxed_type_register_static ("DejaDupDuplicityDateInfo", (GBoxedCopyFunc) deja_dup_duplicity_date_info_dup, (GBoxedFreeFunc) deja_dup_duplicity_date_info_free);
		g_once_init_leave (&deja_dup_duplicity_date_info_type_id__volatile, deja_dup_duplicity_date_info_type_id);
	}
	return deja_dup_duplicity_date_info_type_id__volatile;
}


static void deja_dup_duplicity_class_init (DejaDupDuplicityClass * klass) {
	deja_dup_duplicity_parent_class = g_type_class_peek_parent (klass);
	g_type_class_add_private (klass, sizeof (DejaDupDuplicityPrivate));
	DEJA_DUP_DUPLICITY_CLASS (klass)->start = deja_dup_duplicity_real_start;
	DEJA_DUP_DUPLICITY_CLASS (klass)->process_error = deja_dup_duplicity_real_process_error;
	DEJA_DUP_DUPLICITY_CLASS (klass)->process_info = deja_dup_duplicity_real_process_info;
	DEJA_DUP_DUPLICITY_CLASS (klass)->process_warning = deja_dup_duplicity_real_process_warning;
	G_OBJECT_CLASS (klass)->get_property = deja_dup_duplicity_get_property;
	G_OBJECT_CLASS (klass)->set_property = deja_dup_duplicity_set_property;
	G_OBJECT_CLASS (klass)->constructor = deja_dup_duplicity_constructor;
	G_OBJECT_CLASS (klass)->finalize = deja_dup_duplicity_finalize;
	g_object_class_install_property (G_OBJECT_CLASS (klass), DEJA_DUP_DUPLICITY_ORIGINAL_MODE, g_param_spec_enum ("original-mode", "original-mode", "original-mode", DEJA_DUP_OPERATION_TYPE_MODE, 0, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
	g_object_class_install_property (G_OBJECT_CLASS (klass), DEJA_DUP_DUPLICITY_MODE, g_param_spec_enum ("mode", "mode", "mode", DEJA_DUP_OPERATION_TYPE_MODE, DEJA_DUP_OPERATION_MODE_INVALID, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), DEJA_DUP_DUPLICITY_ERROR_ISSUED, g_param_spec_boolean ("error-issued", "error-issued", "error-issued", FALSE, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), DEJA_DUP_DUPLICITY_WAS_STOPPED, g_param_spec_boolean ("was-stopped", "was-stopped", "was-stopped", FALSE, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), DEJA_DUP_DUPLICITY_LOCAL, g_param_spec_object ("local", "local", "local", G_TYPE_FILE, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE | G_PARAM_WRITABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), DEJA_DUP_DUPLICITY_BACKEND, g_param_spec_object ("backend", "backend", "backend", DEJA_DUP_TYPE_BACKEND, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE | G_PARAM_WRITABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), DEJA_DUP_DUPLICITY_RESTORE_FILES, g_param_spec_pointer ("restore-files", "restore-files", "restore-files", G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE | G_PARAM_WRITABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), DEJA_DUP_DUPLICITY_STATE, g_param_spec_enum ("state", "state", "state", DEJA_DUP_DUPLICITY_TYPE_STATE, 0, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE | G_PARAM_WRITABLE));
	g_signal_new ("done", DEJA_DUP_TYPE_DUPLICITY, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_user_marshal_VOID__BOOLEAN_BOOLEAN, G_TYPE_NONE, 2, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN);
	g_signal_new ("raise_error", DEJA_DUP_TYPE_DUPLICITY, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_user_marshal_VOID__STRING_STRING, G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_STRING);
	g_signal_new ("action_desc_changed", DEJA_DUP_TYPE_DUPLICITY, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__STRING, G_TYPE_NONE, 1, G_TYPE_STRING);
	g_signal_new ("action_file_changed", DEJA_DUP_TYPE_DUPLICITY, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_user_marshal_VOID__OBJECT_BOOLEAN, G_TYPE_NONE, 2, G_TYPE_FILE, G_TYPE_BOOLEAN);
	g_signal_new ("progress", DEJA_DUP_TYPE_DUPLICITY, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__DOUBLE, G_TYPE_NONE, 1, G_TYPE_DOUBLE);
	g_signal_new ("collection_dates", DEJA_DUP_TYPE_DUPLICITY, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER);
	g_signal_new ("question", DEJA_DUP_TYPE_DUPLICITY, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_user_marshal_VOID__STRING_STRING, G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_STRING);
	g_signal_new ("secondary_desc_changed", DEJA_DUP_TYPE_DUPLICITY, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__STRING, G_TYPE_NONE, 1, G_TYPE_STRING);
}


static void deja_dup_duplicity_instance_init (DejaDupDuplicity * self) {
	self->priv = DEJA_DUP_DUPLICITY_GET_PRIVATE (self);
	self->priv->_mode = DEJA_DUP_OPERATION_MODE_INVALID;
	self->priv->_error_issued = FALSE;
	self->priv->_was_stopped = FALSE;
	self->priv->cleaned_up_once = FALSE;
	self->priv->is_full_backup = FALSE;
	self->priv->needs_root = FALSE;
	self->priv->has_progress_total = FALSE;
	self->priv->has_checked_contents = FALSE;
	self->priv->has_non_home_contents = FALSE;
	self->priv->homes = NULL;
	self->priv->checked_collection_info = FALSE;
	self->priv->got_collection_info = FALSE;
	self->priv->collection_info = NULL;
	self->priv->deleted_files = FALSE;
	self->priv->delete_age = 0;
	self->priv->last_touched_file = NULL;
}


static void deja_dup_duplicity_finalize (GObject* obj) {
	DejaDupDuplicity * self;
	self = DEJA_DUP_DUPLICITY (obj);
	_g_object_unref0 (self->priv->_local);
	_g_object_unref0 (self->priv->_backend);
	__g_list_free_g_object_unref0 (self->includes);
	__g_list_free_g_object_unref0 (self->excludes);
	__g_list_free_g_object_unref0 (self->priv->_restore_files);
	_g_object_unref0 (self->priv->inst);
	_g_free0 (self->priv->remote);
	__g_list_free_g_free0 (self->priv->backend_argv);
	__g_list_free_g_free0 (self->priv->saved_argv);
	__g_list_free_g_free0 (self->priv->saved_envp);
	__g_list_free_g_object_unref0 (self->priv->homes);
	__g_list_free_deja_dup_duplicity_date_info_free0 (self->priv->collection_info);
	_g_object_unref0 (self->priv->last_touched_file);
	_g_free0 (self->priv->saved_status);
	_g_object_unref0 (self->priv->saved_status_file);
	G_OBJECT_CLASS (deja_dup_duplicity_parent_class)->finalize (obj);
}


GType deja_dup_duplicity_get_type (void) {
	static volatile gsize deja_dup_duplicity_type_id__volatile = 0;
	if (g_once_init_enter (&deja_dup_duplicity_type_id__volatile)) {
		static const GTypeInfo g_define_type_info = { sizeof (DejaDupDuplicityClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) deja_dup_duplicity_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (DejaDupDuplicity), 0, (GInstanceInitFunc) deja_dup_duplicity_instance_init, NULL };
		GType deja_dup_duplicity_type_id;
		deja_dup_duplicity_type_id = g_type_register_static (G_TYPE_OBJECT, "DejaDupDuplicity", &g_define_type_info, 0);
		g_once_init_leave (&deja_dup_duplicity_type_id__volatile, deja_dup_duplicity_type_id);
	}
	return deja_dup_duplicity_type_id__volatile;
}


static void deja_dup_duplicity_get_property (GObject * object, guint property_id, GValue * value, GParamSpec * pspec) {
	DejaDupDuplicity * self;
	self = DEJA_DUP_DUPLICITY (object);
	switch (property_id) {
		case DEJA_DUP_DUPLICITY_ORIGINAL_MODE:
		g_value_set_enum (value, deja_dup_duplicity_get_original_mode (self));
		break;
		case DEJA_DUP_DUPLICITY_MODE:
		g_value_set_enum (value, deja_dup_duplicity_get_mode (self));
		break;
		case DEJA_DUP_DUPLICITY_ERROR_ISSUED:
		g_value_set_boolean (value, deja_dup_duplicity_get_error_issued (self));
		break;
		case DEJA_DUP_DUPLICITY_WAS_STOPPED:
		g_value_set_boolean (value, deja_dup_duplicity_get_was_stopped (self));
		break;
		case DEJA_DUP_DUPLICITY_LOCAL:
		g_value_set_object (value, deja_dup_duplicity_get_local (self));
		break;
		case DEJA_DUP_DUPLICITY_BACKEND:
		g_value_set_object (value, deja_dup_duplicity_get_backend (self));
		break;
		case DEJA_DUP_DUPLICITY_RESTORE_FILES:
		g_value_set_pointer (value, deja_dup_duplicity_get_restore_files (self));
		break;
		case DEJA_DUP_DUPLICITY_STATE:
		g_value_set_enum (value, deja_dup_duplicity_get_state (self));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}


static void deja_dup_duplicity_set_property (GObject * object, guint property_id, const GValue * value, GParamSpec * pspec) {
	DejaDupDuplicity * self;
	self = DEJA_DUP_DUPLICITY (object);
	switch (property_id) {
		case DEJA_DUP_DUPLICITY_ORIGINAL_MODE:
		deja_dup_duplicity_set_original_mode (self, g_value_get_enum (value));
		break;
		case DEJA_DUP_DUPLICITY_MODE:
		deja_dup_duplicity_set_mode (self, g_value_get_enum (value));
		break;
		case DEJA_DUP_DUPLICITY_ERROR_ISSUED:
		deja_dup_duplicity_set_error_issued (self, g_value_get_boolean (value));
		break;
		case DEJA_DUP_DUPLICITY_WAS_STOPPED:
		deja_dup_duplicity_set_was_stopped (self, g_value_get_boolean (value));
		break;
		case DEJA_DUP_DUPLICITY_LOCAL:
		deja_dup_duplicity_set_local (self, g_value_get_object (value));
		break;
		case DEJA_DUP_DUPLICITY_BACKEND:
		deja_dup_duplicity_set_backend (self, g_value_get_object (value));
		break;
		case DEJA_DUP_DUPLICITY_RESTORE_FILES:
		deja_dup_duplicity_set_restore_files (self, g_value_get_pointer (value));
		break;
		case DEJA_DUP_DUPLICITY_STATE:
		deja_dup_duplicity_set_state (self, g_value_get_enum (value));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}


static void _vala_array_destroy (gpointer array, gint array_length, GDestroyNotify destroy_func) {
	if ((array != NULL) && (destroy_func != NULL)) {
		int i;
		for (i = 0; i < array_length; i = i + 1) {
			if (((gpointer*) array)[i] != NULL) {
				destroy_func (((gpointer*) array)[i]);
			}
		}
	}
}


static void _vala_array_free (gpointer array, gint array_length, GDestroyNotify destroy_func) {
	_vala_array_destroy (array, array_length, destroy_func);
	g_free (array);
}


static gint _vala_array_length (gpointer array) {
	int length;
	length = 0;
	if (array) {
		while (((gpointer*) array)[length]) {
			length++;
		}
	}
	return length;
}


static int _vala_strcmp0 (const char * str1, const char * str2) {
	if (str1 == NULL) {
		return -(str1 != str2);
	}
	if (str2 == NULL) {
		return str1 != str2;
	}
	return strcmp (str1, str2);
}



static void g_cclosure_user_marshal_VOID__BOOLEAN_BOOLEAN (GClosure * closure, GValue * return_value, guint n_param_values, const GValue * param_values, gpointer invocation_hint, gpointer marshal_data) {
	typedef void (*GMarshalFunc_VOID__BOOLEAN_BOOLEAN) (gpointer data1, gboolean arg_1, gboolean arg_2, gpointer data2);
	register GMarshalFunc_VOID__BOOLEAN_BOOLEAN callback;
	register GCClosure * cc;
	register gpointer data1, data2;
	cc = (GCClosure *) closure;
	g_return_if_fail (n_param_values == 3);
	if (G_CCLOSURE_SWAP_DATA (closure)) {
		data1 = closure->data;
		data2 = param_values->data[0].v_pointer;
	} else {
		data1 = param_values->data[0].v_pointer;
		data2 = closure->data;
	}
	callback = (GMarshalFunc_VOID__BOOLEAN_BOOLEAN) (marshal_data ? marshal_data : cc->callback);
	callback (data1, g_value_get_boolean (param_values + 1), g_value_get_boolean (param_values + 2), data2);
}


static void g_cclosure_user_marshal_VOID__STRING_STRING (GClosure * closure, GValue * return_value, guint n_param_values, const GValue * param_values, gpointer invocation_hint, gpointer marshal_data) {
	typedef void (*GMarshalFunc_VOID__STRING_STRING) (gpointer data1, const char* arg_1, const char* arg_2, gpointer data2);
	register GMarshalFunc_VOID__STRING_STRING callback;
	register GCClosure * cc;
	register gpointer data1, data2;
	cc = (GCClosure *) closure;
	g_return_if_fail (n_param_values == 3);
	if (G_CCLOSURE_SWAP_DATA (closure)) {
		data1 = closure->data;
		data2 = param_values->data[0].v_pointer;
	} else {
		data1 = param_values->data[0].v_pointer;
		data2 = closure->data;
	}
	callback = (GMarshalFunc_VOID__STRING_STRING) (marshal_data ? marshal_data : cc->callback);
	callback (data1, g_value_get_string (param_values + 1), g_value_get_string (param_values + 2), data2);
}


static void g_cclosure_user_marshal_VOID__OBJECT_BOOLEAN (GClosure * closure, GValue * return_value, guint n_param_values, const GValue * param_values, gpointer invocation_hint, gpointer marshal_data) {
	typedef void (*GMarshalFunc_VOID__OBJECT_BOOLEAN) (gpointer data1, gpointer arg_1, gboolean arg_2, gpointer data2);
	register GMarshalFunc_VOID__OBJECT_BOOLEAN callback;
	register GCClosure * cc;
	register gpointer data1, data2;
	cc = (GCClosure *) closure;
	g_return_if_fail (n_param_values == 3);
	if (G_CCLOSURE_SWAP_DATA (closure)) {
		data1 = closure->data;
		data2 = param_values->data[0].v_pointer;
	} else {
		data1 = param_values->data[0].v_pointer;
		data2 = closure->data;
	}
	callback = (GMarshalFunc_VOID__OBJECT_BOOLEAN) (marshal_data ? marshal_data : cc->callback);
	callback (data1, g_value_get_object (param_values + 1), g_value_get_boolean (param_values + 2), data2);
}



