app-manager/localmedia.c
author J. Ali Harlow <ali@juiblex.co.uk>
Sat Jul 16 11:07:18 2016 +0100 (2016-07-16)
changeset 61 31fb35727621
parent 12 1d18b9c34d26
permissions -rw-r--r--
Support parallel installations. The idea is that for CAD screener, we want
to be able to install this on the same machine as a standard AVOT setup
(most notably for John's laptop). To allow for the possibility of a second
application that might have the same requirements, we add the concept of
vendor-specific distributions. Thus we can have one distribution for CAD
screener and one for The Next Big Thing. It doesn't seem trivial to have
both CAD screener and AVOT under the same vendor tag so we'll have to have
AVOT under "City Occupational" and CAD screener under "City Occupational Ltd"
or some such kludge.

Most of this is done although we are very short of test cases (in particular
we don't test that it's actually possible to install CAD screener in parallel
with AVOT or to update either of them once installed, which is fundamental).

We also have a lot of baggage left over, including an intercept of razor_set.
The problem that this was introduced to debug has been fixed but it looks
like there are a number of memory leaks which it might be useful to help
track down so it has been left in place for now.

There is still a lot of confusion in plover between path-based and URI-based
API. We should review the API, decide what we want and have a general clear up.

There is also confusion as to the purpose of RAZOR_ROOT (and meaning; path or
URI). This is not used at all in librazor (although it is used in razor.exe).
Ideally we shouldn't use it in plover or plover-gtk either although again, we
might want to support it or an equivalent in (some of) the various executables.

Work that would still to nice to do for CAD screener:

- uninstall (ideally as an installed program that hooks into Add/Remove programs
but even re-running the installer would be acceptable).
- xz support (smaller packages).
- repomd.xml and xml:base (would be needed for an Internet installer).
- graphical installer.
ali@9
     1
/*
ali@9
     2
 * Copyright (C) 2010  J. Ali Harlow <ali@juiblex.co.uk>
ali@9
     3
 *
ali@9
     4
 * This program is free software; you can redistribute it and/or modify
ali@9
     5
 * it under the terms of the GNU General Public License as published by
ali@9
     6
 * the Free Software Foundation; either version 2 of the License, or
ali@9
     7
 * (at your option) any later version.
ali@9
     8
 *
ali@9
     9
 * This program is distributed in the hope that it will be useful,
ali@9
    10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
ali@9
    11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
ali@9
    12
 * GNU General Public License for more details.
ali@9
    13
 *
ali@9
    14
 * You should have received a copy of the GNU General Public License along
ali@9
    15
 * with this program; if not, write to the Free Software Foundation, Inc.,
ali@9
    16
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
ali@9
    17
 */
ali@9
    18
ali@9
    19
#include "config.h"
ali@9
    20
#include <stdlib.h>
ali@9
    21
#include <string.h>
ali@10
    22
#ifdef WIN32
ali@10
    23
#include <windows.h>
ali@10
    24
#endif
ali@9
    25
#include <glib.h>
ali@9
    26
#include <gio/gio.h>
ali@9
    27
#include <gtk/gtk.h>
ali@9
    28
#include <plover-gtk/packagestore.h>
ali@10
    29
#include "app-manager.h"
ali@9
    30
#include "localmedia.h"
ali@9
    31
ali@9
    32
G_DEFINE_TYPE(PloverLocalMediaStore,plover_local_media_store,
ali@9
    33
  PLOVER_TYPE_PACKAGE_STORE);
ali@9
    34
ali@9
    35
static void plover_local_media_store_dispose(GObject *obj)
ali@9
    36
{
ali@9
    37
    PloverLocalMediaStore *store=PLOVER_LOCAL_MEDIA_STORE(obj);
ali@9
    38
    if (store->monitor)
ali@9
    39
    {
ali@9
    40
	g_object_unref(store->monitor);
ali@9
    41
	store->monitor=NULL;
ali@9
    42
    }
ali@9
    43
    if (G_OBJECT_CLASS(plover_local_media_store_parent_class)->dispose)
ali@9
    44
	G_OBJECT_CLASS(plover_local_media_store_parent_class)->dispose(obj);
ali@9
    45
}
ali@9
    46
ali@9
    47
static void
ali@9
    48
  plover_local_media_store_class_init(PloverLocalMediaStoreClass *klass)
ali@9
    49
{
ali@9
    50
    GObjectClass *oclass=G_OBJECT_CLASS(klass);
ali@9
    51
    oclass->dispose=plover_local_media_store_dispose;
ali@9
    52
}
ali@9
    53
ali@9
    54
GtkTreeModel *plover_local_media_store_new(void)
ali@9
    55
{
ali@9
    56
    return g_object_new(PLOVER_TYPE_LOCAL_MEDIA_STORE,NULL);
ali@9
    57
}
ali@9
    58
ali@9
    59
static void local_media_scan_mount(PloverLocalMediaStore *store,GMount *mount)
ali@9
    60
{
ali@9
    61
    GFile *root;
ali@9
    62
    gchar *path;
ali@10
    63
#ifdef WIN32
ali@10
    64
    gunichar2 *path2;
ali@10
    65
    UINT type;
ali@10
    66
#endif
ali@9
    67
    PloverPackageSet *set;
ali@9
    68
    root=g_mount_get_root(mount);
ali@9
    69
    path=g_file_get_path(root);
ali@10
    70
#ifdef WIN32
ali@9
    71
    if (path)
ali@9
    72
    {
ali@10
    73
	path2=g_utf8_to_utf16(path,-1,NULL,NULL,NULL);
ali@10
    74
	if (path2)
ali@10
    75
	{
ali@10
    76
	    type=GetDriveTypeW(path2);
ali@10
    77
	    g_free(path2);
ali@10
    78
	}
ali@10
    79
	else
ali@10
    80
	    type=DRIVE_UNKNOWN;
ali@10
    81
	if (type!=DRIVE_REMOVABLE && type!=DRIVE_CDROM)
ali@10
    82
	{
ali@10
    83
	    gchar *name=g_mount_get_name(mount);
ali@10
    84
	    g_debug("Skipping non-local mount \"%s\"",name);
ali@10
    85
	    g_free(name);
ali@10
    86
	    g_free(path);
ali@10
    87
	    path=NULL;
ali@10
    88
	}
ali@10
    89
    }
ali@10
    90
#endif
ali@10
    91
    if (path)
ali@10
    92
    {
ali@24
    93
	set=plover_package_set_new_from_yum(path,relocations,NULL);
ali@9
    94
	if (set)
ali@9
    95
	{
ali@9
    96
	    g_object_set_data(G_OBJECT(mount),"plover-local-media-set",set);
ali@9
    97
	    plover_package_store_add_set(PLOVER_PACKAGE_STORE(store),set);
ali@9
    98
	    g_object_ref(mount);
ali@9
    99
	}
ali@9
   100
	g_free(path);
ali@9
   101
    }
ali@9
   102
    g_object_unref(root);
ali@9
   103
}
ali@9
   104
ali@9
   105
static void local_media_mounted(GObject *source,GAsyncResult *res,gpointer data)
ali@9
   106
{
ali@9
   107
    GVolume *volume=G_VOLUME(source);
ali@9
   108
    GMount *mount;
ali@9
   109
    PloverLocalMediaStore *store=PLOVER_LOCAL_MEDIA_STORE(data);
ali@9
   110
    if (g_volume_mount_finish(volume,res,NULL))
ali@9
   111
    {
ali@9
   112
	mount=g_volume_get_mount(volume);
ali@9
   113
	if (mount)
ali@9
   114
	{
ali@9
   115
	    local_media_scan_mount(store,mount);
ali@9
   116
	    g_object_unref(mount);
ali@9
   117
	}
ali@9
   118
    }
ali@9
   119
    g_object_unref(volume);
ali@9
   120
}
ali@9
   121
ali@9
   122
static void local_media_scan_drive(PloverLocalMediaStore *store,GDrive *drive)
ali@9
   123
{
ali@9
   124
    GVolume *volume;
ali@9
   125
    GMount *mount;
ali@10
   126
    GList *volumes,*mounts,*link;
ali@10
   127
    if (!drive)
ali@10
   128
	volumes=g_volume_monitor_get_volumes(store->monitor);
ali@10
   129
    else if (g_drive_has_media(drive))
ali@10
   130
	volumes=g_drive_get_volumes(drive);
ali@10
   131
    else
ali@10
   132
	volumes=NULL;
ali@10
   133
    for(link=volumes;link;link=link->next)
ali@9
   134
    {
ali@10
   135
	volume=G_VOLUME(link->data);
ali@10
   136
	mount=g_volume_get_mount(volume);
ali@10
   137
	if (mount)
ali@9
   138
	{
ali@10
   139
	    local_media_scan_mount(store,mount);
ali@10
   140
	    g_object_unref(mount);
ali@9
   141
	}
ali@10
   142
	else if (!store->implicit_scan && g_volume_can_mount(volume))
ali@10
   143
	    g_volume_mount(volume,G_MOUNT_MOUNT_NONE,NULL,NULL,
ali@10
   144
	      local_media_mounted,store);
ali@10
   145
	g_object_unref(volume);
ali@10
   146
    }
ali@10
   147
    g_list_free(volumes);
ali@10
   148
    if (!drive)
ali@10
   149
    {
ali@10
   150
	mounts=g_volume_monitor_get_mounts(store->monitor);
ali@10
   151
	for(link=mounts;link;link=link->next)
ali@10
   152
	{
ali@10
   153
	    mount=G_MOUNT(link->data);
ali@10
   154
	    local_media_scan_mount(store,mount);
ali@10
   155
	    g_object_unref(mount);
ali@10
   156
	}
ali@10
   157
	g_list_free(mounts);
ali@9
   158
    }
ali@9
   159
}
ali@9
   160
ali@9
   161
static void local_media_polled(GObject *source,GAsyncResult *res,gpointer data)
ali@9
   162
{
ali@9
   163
    GDrive *drive=G_DRIVE(source);
ali@9
   164
    PloverLocalMediaStore *store=PLOVER_LOCAL_MEDIA_STORE(data);
ali@9
   165
    if (g_drive_poll_for_media_finish(drive,res,NULL))
ali@9
   166
	local_media_scan_drive(store,drive);
ali@9
   167
    g_object_unref(drive);
ali@9
   168
}
ali@9
   169
ali@9
   170
void plover_local_media_store_scan(PloverLocalMediaStore *store)
ali@9
   171
{
ali@12
   172
    GSList *sets,*slink;
ali@12
   173
    GList *drives,*link;
ali@9
   174
    GDrive *drive;
ali@9
   175
    g_return_if_fail(PLOVER_IS_LOCAL_MEDIA_STORE(store));
ali@10
   176
    sets=
ali@10
   177
      g_slist_copy(plover_package_store_get_sets(PLOVER_PACKAGE_STORE(store)));
ali@12
   178
    for(slink=sets;slink;slink=slink->next)
ali@10
   179
	plover_package_store_remove_set(PLOVER_PACKAGE_STORE(store),
ali@12
   180
	  PLOVER_PACKAGE_SET(slink->data));
ali@10
   181
    g_slist_free(sets);
ali@9
   182
    drives=g_volume_monitor_get_connected_drives(store->monitor);
ali@9
   183
    for(link=drives;link;link=link->next)
ali@9
   184
    {
ali@9
   185
	drive=G_DRIVE(link->data);
ali@9
   186
	if (g_drive_is_media_removable(drive))
ali@9
   187
	{
ali@9
   188
	    if (!g_drive_is_media_check_automatic(drive) &&
ali@9
   189
	      g_drive_can_poll_for_media(drive) ||
ali@9
   190
	      !g_drive_has_media(drive) && !store->implicit_scan)
ali@9
   191
	    {
ali@9
   192
		g_object_ref(drive);
ali@9
   193
		g_drive_poll_for_media(drive,NULL,local_media_polled,store);
ali@9
   194
	    }
ali@9
   195
	    else
ali@9
   196
		local_media_scan_drive(store,drive);
ali@9
   197
	}
ali@9
   198
	g_object_unref(drive);
ali@9
   199
    }
ali@9
   200
    g_list_free(drives);
ali@10
   201
    local_media_scan_drive(store,NULL);
ali@9
   202
}
ali@9
   203
ali@9
   204
static void local_media_mount_added(GVolumeMonitor *volume_monitor,
ali@9
   205
  GMount *mount,PloverLocalMediaStore *store)
ali@9
   206
{
ali@9
   207
    local_media_scan_mount(store,mount);
ali@9
   208
}
ali@9
   209
ali@9
   210
static void local_media_mount_removed(GVolumeMonitor *volume_monitor,
ali@9
   211
  GMount *mount,PloverLocalMediaStore *store)
ali@9
   212
{
ali@9
   213
    PloverPackageSet *set=
ali@9
   214
      g_object_get_data(G_OBJECT(mount),"plover-local-media-set");
ali@9
   215
    if (set)
ali@9
   216
    {
ali@9
   217
	plover_package_store_remove_set(PLOVER_PACKAGE_STORE(store),set);
ali@9
   218
	g_object_set_data(G_OBJECT(mount),"plover-local-media-set",NULL);
ali@9
   219
	g_object_unref(set);
ali@9
   220
	g_object_unref(mount);
ali@9
   221
    }
ali@9
   222
}
ali@9
   223
ali@9
   224
static void local_media_mount_changed(GVolumeMonitor *volume_monitor,
ali@9
   225
  GMount *mount,PloverLocalMediaStore *store)
ali@9
   226
{
ali@9
   227
    local_media_mount_removed(volume_monitor,mount,store);
ali@9
   228
    local_media_mount_added(volume_monitor,mount,store);
ali@9
   229
}
ali@9
   230
ali@9
   231
static void plover_local_media_store_init(PloverLocalMediaStore *store)
ali@9
   232
{
ali@9
   233
    store->monitor=g_volume_monitor_get();
ali@9
   234
    store->implicit_scan=TRUE;
ali@9
   235
    plover_local_media_store_scan(store);
ali@9
   236
    store->implicit_scan=FALSE;
ali@9
   237
    g_signal_connect(store->monitor,"mount-added",
ali@9
   238
      G_CALLBACK(local_media_mount_added),store);
ali@9
   239
    g_signal_connect(store->monitor,"mount-changed",
ali@9
   240
      G_CALLBACK(local_media_mount_changed),store);
ali@9
   241
    g_signal_connect(store->monitor,"mount-removed",
ali@9
   242
      G_CALLBACK(local_media_mount_removed),store);
ali@9
   243
}