~ubuntu-branches/ubuntu/wily/hal/wily

« back to all changes in this revision

Viewing changes to .pc/52-kfreebsd-libufs.patch/hald/freebsd/probing/probe-volume.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2010-10-12 16:50:48 UTC
  • mfrom: (1.1.20 sid)
  • Revision ID: james.westby@ubuntu.com-20101012165048-fm9vz0n87zpoovcm
Tags: 0.5.14-3ubuntu1
* Merge with Debian unstable; remaining Ubuntu changes:
 - Add support for smartdimmer backlight control for GeForce 7/8/9 based
   Sony laptops.
   + Add 04_nvidia_brightness.patch.
   + Add smartdimmer recommends.
 - debian/hal.postinst: Do not create plugdev and powerdev groups.
 - Change startup from init/upstart to D-Bus activation. This allows us
   having installed programs which still need hal without the need to start
   hal on boot:
   + Remove debian/hal.{init,default}.
   + Add D-Bus activation service file debian/org.freedesktop.Hal.service and
     install it in debian/hal.install.
   + debian/hal.postinst: When triggering an .fdi file update, just stop
     hald; it will be reactivated when needed.
 - Add 02_libhal_dont_check_running.patch, 00git_bigger_path_size.patch, see
   their patch headers.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***************************************************************************
 
2
 * CVSID: $Id$
 
3
 *
 
4
 * probe-volume.c : volume prober
 
5
 *
 
6
 * Copyright (C) 2006, 2007 Jean-Yves Lefort <jylefort@FreeBSD.org>
 
7
 *
 
8
 * This program is free software; you can redistribute it and/or modify
 
9
 * it under the terms of the GNU General Public License as published by
 
10
 * the Free Software Foundation; either version 2 of the License, or
 
11
 * (at your option) any later version.
 
12
 *
 
13
 * This program is distributed in the hope that it will be useful,
 
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
16
 * GNU General Public License for more details.
 
17
 *
 
18
 * You should have received a copy of the GNU General Public License
 
19
 * along with this program; if not, write to the Free Software
 
20
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
21
 *
 
22
 **************************************************************************/
 
23
 
 
24
#ifdef HAVE_CONFIG_H
 
25
#  include <config.h>
 
26
#endif
 
27
 
 
28
#include <stdio.h>
 
29
#include <string.h>
 
30
#include <stdlib.h>
 
31
#include <limits.h>
 
32
#include <inttypes.h>
 
33
#include <fcntl.h>
 
34
#include <unistd.h>
 
35
#include <sys/ioctl.h>
 
36
#include <sys/disk.h>
 
37
#include <sys/cdio.h>
 
38
#include <sys/param.h>
 
39
#include <sys/mount.h>
 
40
#include <sys/types.h>
 
41
#include <ufs/ufs/ufsmount.h>
 
42
#include <ufs/ufs/dinode.h>
 
43
#include <ufs/ffs/fs.h>
 
44
#include <libufs.h>
 
45
#include <isofs/cd9660/iso.h>
 
46
#include <glib.h>
 
47
#include <libvolume_id.h>
 
48
 
 
49
#include "libhal/libhal.h"
 
50
 
 
51
#include "../libprobe/hfp.h"
 
52
 
 
53
#include "freebsd_dvd_rw_utils.h"
 
54
 
 
55
#define ISO_VOLDESC_SEC        16
 
56
 
 
57
struct iso_path_table_entry
 
58
{
 
59
  char name_len               [ISODCL(1,1)];
 
60
  char ext_attr_len           [ISODCL(2,2)];
 
61
  char extent                 [ISODCL(3,6)];
 
62
  char parent_no              [ISODCL(7,8)];
 
63
  char name[1];
 
64
};
 
65
#define ISO_PATH_TABLE_ENTRY_SIZE         8
 
66
 
 
67
#if (__FreeBSD_version < 600101) && (__FreeBSD_kernel_version < 600101)
 
68
static uint32_t
 
69
isonum_731(unsigned char *p)
 
70
{
 
71
  return (p[0] | p[1] << 8 | p[2] << 16 | p[3] << 24);
 
72
}
 
73
 
 
74
static uint32_t
 
75
isonum_732(unsigned char *p)
 
76
{
 
77
  return (p[3] | p[2] << 8 | p[1] << 16 | p[0] << 24);
 
78
}
 
79
#endif
 
80
 
 
81
static uintmax_t
 
82
hf_probe_volume_getenv_uintmax (const char *name)
 
83
{
 
84
  char *str;
 
85
 
 
86
  g_return_val_if_fail(name != NULL, 0);
 
87
 
 
88
  str = getenv(name);
 
89
 
 
90
  return str ? strtoumax(str, NULL, 10) : 0;
 
91
}
 
92
 
 
93
static int
 
94
hf_probe_volume_getenv_int (const char *name)
 
95
{
 
96
  char *str;
 
97
 
 
98
  g_return_val_if_fail(name != NULL, 0);
 
99
 
 
100
  str = getenv(name);
 
101
 
 
102
  return str ? atoi(str) : 0;
 
103
}
 
104
 
 
105
static char *
 
106
hf_probe_volume_get_label (const struct volume_id *vid)
 
107
{
 
108
  char *label = NULL;
 
109
 
 
110
  if (vid && *vid->label)
 
111
    {
 
112
      if (g_utf8_validate(vid->label, -1, NULL))
 
113
        label = g_strdup(vid->label);
 
114
      else                              /* assume ISO8859-1 */
 
115
        label = g_convert(vid->label, -1, "UTF-8", "ISO8859-1", NULL, NULL, NULL);
 
116
    }
 
117
 
 
118
  return label;
 
119
}
 
120
 
 
121
static void
 
122
hf_probe_volume_get_disc_info (int fd,
 
123
                               gboolean *has_audio,
 
124
                               gboolean *has_data)
 
125
{
 
126
  struct ioc_toc_header toc_header;
 
127
  int n_tracks;
 
128
  struct cd_toc_entry *buffer = NULL;
 
129
  struct ioc_read_toc_entry read_toc_entry;
 
130
  int i;
 
131
 
 
132
  g_return_if_fail(has_audio != NULL);
 
133
  g_return_if_fail(has_data != NULL);
 
134
 
 
135
  *has_audio = FALSE;
 
136
  *has_data = FALSE;
 
137
 
 
138
  if (ioctl(fd, CDIOREADTOCHEADER, &toc_header) < 0)
 
139
    return;
 
140
 
 
141
  n_tracks = toc_header.ending_track - toc_header.starting_track + 1;
 
142
 
 
143
  buffer = g_new(struct cd_toc_entry, n_tracks + 1);
 
144
 
 
145
  read_toc_entry.address_format = CD_MSF_FORMAT;
 
146
  read_toc_entry.starting_track = 0;
 
147
  read_toc_entry.data_len = (n_tracks + 1) * sizeof(struct cd_toc_entry);
 
148
  read_toc_entry.data = buffer;
 
149
 
 
150
  if (ioctl(fd, CDIOREADTOCENTRYS, &read_toc_entry) < 0)
 
151
    goto end;
 
152
 
 
153
  for (i = 0; i < n_tracks; i++)
 
154
    {
 
155
      if ((buffer[i].control & 4) != 0)
 
156
        *has_data = TRUE;
 
157
      else
 
158
        *has_audio = TRUE;
 
159
    }
 
160
 
 
161
 end:
 
162
  g_free(buffer);
 
163
}
 
164
 
 
165
static void
 
166
hf_probe_volume_advanced_disc_detect (int fd)
 
167
{
 
168
  size_t secsz = ISO_DEFAULT_BLOCK_SIZE;
 
169
  int readoff;
 
170
  struct iso_primary_descriptor desc;
 
171
  u_char *ptbl;
 
172
  int ptbl_size, ptbl_bsize;
 
173
  int ptbl_lbn;
 
174
  struct iso_path_table_entry *pte;
 
175
  int pte_len;
 
176
  int name_len;
 
177
  int off;
 
178
 
 
179
  readoff = ISO_VOLDESC_SEC * secsz;
 
180
  do
 
181
    {
 
182
      if (pread(fd, &desc, sizeof desc, readoff) != sizeof desc)
 
183
        {
 
184
          hfp_warning("volume descriptor read error");
 
185
          return;
 
186
        }
 
187
      if (isonum_711(desc.type) == ISO_VD_END)
 
188
        return;
 
189
      readoff += secsz;
 
190
    }
 
191
  while (isonum_711(desc.type) != ISO_VD_PRIMARY);
 
192
 
 
193
  ptbl_size = isonum_733(desc.path_table_size);
 
194
#if BYTE_ORDER == LITTLE_ENDIAN
 
195
  ptbl_lbn = isonum_731(desc.type_l_path_table);
 
196
#else
 
197
  ptbl_lbn = isonum_732(desc.type_m_path_table);
 
198
#endif
 
199
  ptbl_bsize = (ptbl_size + secsz - 1) / secsz * secsz;
 
200
  ptbl = g_malloc(ptbl_bsize);
 
201
  if (ptbl == NULL)
 
202
    {
 
203
      hfp_warning("path table allocation failure");
 
204
      return;
 
205
    }
 
206
  readoff = ptbl_lbn * secsz;
 
207
  if (pread(fd, ptbl, ptbl_bsize, readoff) != ptbl_bsize)
 
208
    {
 
209
      g_free(ptbl);
 
210
      hfp_warning("path table read error");
 
211
    }
 
212
  for (off = 0; off < ptbl_size; off += pte_len)
 
213
    {
 
214
      pte = (struct iso_path_table_entry *)(ptbl + off);
 
215
      name_len = *pte->name_len;
 
216
      pte_len = ISO_PATH_TABLE_ENTRY_SIZE + name_len + (name_len % 2);
 
217
      if (*(short *)pte->parent_no != 1)
 
218
        continue;
 
219
      if (name_len == 8 && strncmp(pte->name, "VIDEO_TS", 8) == 0)
 
220
        {
 
221
          libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.disc.is_videodvd", TRUE, &hfp_error);
 
222
          break;
 
223
        }
 
224
      else if (name_len == 3 && strncmp(pte->name, "VCD", 8) == 0)
 
225
        {
 
226
          libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.disc.is_vcd", TRUE, &hfp_error);
 
227
          break;
 
228
        }
 
229
      else if (name_len == 4 && strncmp(pte->name, "SVCD", 4) == 0)
 
230
        {
 
231
          libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.disc.is_svcd", TRUE, &hfp_error);
 
232
          break;
 
233
        }
 
234
    }
 
235
  g_free(ptbl);
 
236
}
 
237
 
 
238
static gboolean
 
239
hf_probe_volume_get_partition_info (const char *geom_class,
 
240
                                    const char *devfile,
 
241
                                    int *number,
 
242
                                    char **type,
 
243
                                    char **scheme,
 
244
                                    guint64 *mediasize,
 
245
                                    guint64 *offset)
 
246
{
 
247
  g_return_val_if_fail(geom_class != NULL, FALSE);
 
248
  g_return_val_if_fail(devfile != NULL, FALSE);
 
249
  g_return_val_if_fail(number != NULL, FALSE);
 
250
  g_return_val_if_fail(type != NULL, FALSE);
 
251
  g_return_val_if_fail(scheme != NULL, FALSE);
 
252
  g_return_val_if_fail(mediasize != NULL, FALSE);
 
253
  g_return_val_if_fail(offset != NULL, FALSE);
 
254
 
 
255
  if (strcmp(geom_class, "MBR") &&
 
256
      strcmp(geom_class, "MBREXT") &&
 
257
      strcmp(geom_class, "GPT") &&
 
258
      strcmp(geom_class, "SUN") &&
 
259
      strcmp(geom_class, "APPLE"))
 
260
    return FALSE;
 
261
 
 
262
  *mediasize = hf_probe_volume_getenv_uintmax("HF_VOLUME_SIZE");
 
263
  if (*mediasize == 0)
 
264
    return FALSE;
 
265
 
 
266
  *offset = hf_probe_volume_getenv_uintmax("HF_VOLUME_OFFSET");
 
267
 
 
268
  *number = hf_probe_volume_getenv_int("HF_VOLUME_PART_INDEX");
 
269
  if (*number == 0)
 
270
    {
 
271
      size_t len;
 
272
      char *partno;
 
273
 
 
274
      partno = strrchr(devfile, 's');
 
275
      if (! partno)
 
276
        return FALSE;
 
277
 
 
278
      len = strlen(partno) - 1;
 
279
      if (len > 0 && strspn(partno + 1, "0123456789") == len)
 
280
        *number = atoi(partno);
 
281
      else
 
282
        return FALSE;
 
283
    }
 
284
 
 
285
  *scheme = g_ascii_strdown(geom_class, -1);
 
286
  if (! strcmp(*scheme, "apple"))
 
287
    {
 
288
      g_free(*scheme);
 
289
      *scheme = g_strdup("apm");
 
290
    }
 
291
 
 
292
  if (! strcmp(*scheme, "mbrext"))
 
293
    {
 
294
      g_free(*scheme);
 
295
      *scheme = g_strdup("embr");
 
296
    }
 
297
 
 
298
  if (! strcmp(*scheme, "mbr") || ! strcmp(*scheme, "embr"))
 
299
    *type = g_strdup_printf("0x%x",
 
300
                            hf_probe_volume_getenv_int("HF_VOLUME_PART_TYPE"));
 
301
  else
 
302
    {
 
303
      char *parttype;
 
304
 
 
305
      parttype = getenv("HF_VOLUME_PART_TYPE");
 
306
 
 
307
      if (parttype)
 
308
        *type = g_strdup(parttype);
 
309
      else
 
310
        *type = g_strdup("");
 
311
    }
 
312
 
 
313
  return TRUE;
 
314
}
 
315
 
 
316
int
 
317
main (int argc, char **argv)
 
318
{
 
319
  char *device_file;
 
320
  char *parent_udi;
 
321
  char *grandparent_udi;
 
322
  char *parent_drive_type;
 
323
  int fd = -1;
 
324
  struct volume_id *vid = NULL;
 
325
  int ret = 1;
 
326
  gboolean has_children;
 
327
  gboolean is_swap;
 
328
  gboolean is_cdrom;
 
329
  gboolean is_partition = FALSE;
 
330
  gboolean has_audio = FALSE;
 
331
  gboolean has_data = FALSE;
 
332
  gboolean is_blank = FALSE;
 
333
  const char *usage;
 
334
  char *label;
 
335
  unsigned int sector_size = 0;
 
336
  off_t media_size = 0;
 
337
 
 
338
  if (! hfp_init(argc, argv))
 
339
    goto end;
 
340
 
 
341
  device_file = getenv("HAL_PROP_BLOCK_DEVICE");
 
342
  if (! device_file)
 
343
    goto end;
 
344
 
 
345
  parent_udi = getenv("HAL_PROP_INFO_PARENT");
 
346
  if (! parent_udi)
 
347
    goto end;
 
348
 
 
349
  /* give a meaningful process title for ps(1) */
 
350
#ifndef __GLIBC__
 
351
  setproctitle("%s", device_file);
 
352
#endif
 
353
 
 
354
  has_children = hfp_getenv_bool("HF_HAS_CHILDREN");
 
355
  is_swap = hfp_getenv_bool("HF_IS_SWAP");
 
356
 
 
357
  fd = open(device_file, O_RDONLY);
 
358
  if (fd < 0)
 
359
    goto end;
 
360
 
 
361
  parent_drive_type = libhal_device_get_property_string(hfp_ctx, parent_udi, "storage.drive_type", &hfp_error);
 
362
  dbus_error_free(&hfp_error);
 
363
 
 
364
  grandparent_udi = libhal_device_get_property_string(hfp_ctx, parent_udi, "info.parent", &hfp_error);
 
365
  dbus_error_free(&hfp_error);
 
366
 
 
367
  is_cdrom = parent_drive_type && ! strcmp(parent_drive_type, "cdrom");
 
368
  g_free(parent_drive_type);
 
369
 
 
370
  if (is_cdrom)
 
371
    {
 
372
      hf_probe_volume_get_disc_info(fd, &has_audio, &has_data);
 
373
      is_blank = (! has_audio && ! has_data);
 
374
    }
 
375
 
 
376
  ioctl(fd, DIOCGMEDIASIZE, &media_size);
 
377
 
 
378
  /*
 
379
   * We only check for filesystems if the volume has no children,
 
380
   * otherwise volume_id might find a filesystem in what is actually
 
381
   * the first child partition of the volume.
 
382
   *
 
383
   * If hald (which has looked at the partition type) reports that it
 
384
   * is a swap partition, we probe it nevertheless in case the
 
385
   * partition type is incorrect.
 
386
   */
 
387
  if (! has_children && ! (is_cdrom && ! has_data))
 
388
    {
 
389
      vid = volume_id_open_fd(fd);
 
390
      if (vid)
 
391
        {
 
392
          if (volume_id_probe_all(vid, 0, media_size) == 0)
 
393
            has_data = TRUE;
 
394
          else
 
395
            {
 
396
              volume_id_close(vid);
 
397
              vid = NULL;
 
398
            }
 
399
        }
 
400
    }
 
401
 
 
402
  if (! has_children && ! is_swap && ! has_audio && ! has_data && ! is_blank)
 
403
    goto end;
 
404
 
 
405
  libhal_device_add_capability(hfp_ctx, hfp_udi, "volume", &hfp_error);
 
406
  if (is_cdrom)
 
407
    {
 
408
      HFPCDROM *cdrom;
 
409
      int type;
 
410
      guint64 capacity;
 
411
 
 
412
      libhal_device_set_property_string(hfp_ctx, hfp_udi, "info.category", "volume.disc", &hfp_error);
 
413
      libhal_device_add_capability(hfp_ctx, hfp_udi, "volume.disc", &hfp_error);
 
414
 
 
415
      libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.disc.has_audio", has_audio, &hfp_error);
 
416
      libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.disc.has_data", has_data, &hfp_error);
 
417
      libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.disc.is_vcd", FALSE, &hfp_error);
 
418
      libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.disc.is_svcd", FALSE, &hfp_error);
 
419
      libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.disc.is_videodvd", FALSE, &hfp_error);
 
420
      libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.disc.is_appendable", FALSE, &hfp_error);
 
421
      libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.disc.is_blank", is_blank, &hfp_error);
 
422
      libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.disc.is_rewritable", FALSE, &hfp_error);
 
423
      libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "unknown", &hfp_error);
 
424
 
 
425
      /* the following code was adapted from linux's probe-volume.c */
 
426
 
 
427
      cdrom = hfp_cdrom_new_from_fd(fd, device_file, grandparent_udi);
 
428
      if (cdrom)
 
429
        {
 
430
          type = get_disc_type(cdrom);
 
431
          if (type != -1)
 
432
            switch (type)
 
433
              {
 
434
              case 0x08: /* CD-ROM */
 
435
                libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "cd_rom", &hfp_error);
 
436
                break;
 
437
              case 0x09: /* CD-R */
 
438
                libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "cd_r", &hfp_error);
 
439
                break;
 
440
              case 0x0a: /* CD-RW */
 
441
                libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "cd_rw", &hfp_error);
 
442
                libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.disc.is_rewritable", TRUE, &hfp_error);
 
443
                break;
 
444
              case 0x10: /* DVD-ROM */
 
445
                libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "dvd_rom", &hfp_error);
 
446
                break;
 
447
              case 0x11: /* DVD-R Sequential */
 
448
                libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "dvd_r", &hfp_error);
 
449
                break;
 
450
              case 0x12: /* DVD-RAM */
 
451
                libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "dvd_ram", &hfp_error);
 
452
                libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.disc.is_rewritable", TRUE, &hfp_error);
 
453
                break;
 
454
              case 0x13: /* DVD-RW Restricted Overwrite */
 
455
                libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "dvd_rw", &hfp_error);
 
456
                libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.disc.is_rewritable", TRUE, &hfp_error);
 
457
                break;
 
458
              case 0x14: /* DVD-RW Sequential */
 
459
                libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "dvd_rw", &hfp_error);
 
460
                libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.disc.is_rewritable", TRUE, &hfp_error);
 
461
                break;
 
462
              case 0x1A: /* DVD+RW */
 
463
                libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "dvd_plus_rw", &hfp_error);
 
464
                libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.disc.is_rewritable", TRUE, &hfp_error);
 
465
                break;
 
466
              case 0x1B: /* DVD+R */
 
467
                libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "dvd_plus_r", &hfp_error);
 
468
                break;
 
469
              case 0x2B: /* DVD+R Double Layer */
 
470
                libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "dvd_plus_r_dl", &hfp_error);
 
471
                break;
 
472
              case 0x40: /* BD-ROM  */
 
473
                libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "bd_rom", &hfp_error);
 
474
                break;
 
475
              case 0x41: /* BD-R Sequential */
 
476
                libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "bd_r", &hfp_error);
 
477
                break;
 
478
              case 0x42: /* BD-R Random */
 
479
                libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "bd_r", &hfp_error);
 
480
                break;
 
481
              case 0x43: /* BD-RE */
 
482
                libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "bd_re", &hfp_error);
 
483
                libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.disc.is_rewritable", TRUE, &hfp_error);
 
484
                break;
 
485
              case 0x50: /* HD DVD-ROM */
 
486
                libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "hddvd_rom", &hfp_error);
 
487
                break;
 
488
              case 0x51: /* HD DVD-R */
 
489
                libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "hddvd_r", &hfp_error);
 
490
                break;
 
491
              case 0x52: /* HD DVD-Rewritable */
 
492
                libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "hddvd_rw", &hfp_error);
 
493
                libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.disc.is_rewritable", TRUE, &hfp_error);
 
494
                break;
 
495
              }
 
496
 
 
497
          if (get_disc_capacity_for_type(cdrom, type, &capacity) == 0)
 
498
            libhal_device_set_property_uint64(hfp_ctx, hfp_udi, "volume.disc.capacity", capacity, &hfp_error);
 
499
 
 
500
          /*
 
501
           * linux's probe-volume.c: "on some hardware the get_disc_type
 
502
           * call fails, so we use this as a backup".
 
503
           */
 
504
          if (disc_is_rewritable(cdrom))
 
505
            libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.disc.is_rewritable", TRUE, &hfp_error);
 
506
          if (disc_is_appendable(cdrom))
 
507
            libhal_device_set_property_bool (hfp_ctx, hfp_udi, "volume.disc.is_appendable", TRUE, &hfp_error);
 
508
 
 
509
          hfp_cdrom_free(cdrom);
 
510
        }
 
511
 
 
512
      if (has_data && vid && (! strcmp(vid->type, "iso9660") ||
 
513
          ! strcmp(vid->type, "udf")))
 
514
        hf_probe_volume_advanced_disc_detect(fd);
 
515
    }
 
516
  else
 
517
    {
 
518
      libhal_device_set_property_string(hfp_ctx, hfp_udi, "info.category", "volume", &hfp_error);
 
519
 
 
520
      if (libhal_device_query_capability(hfp_ctx, parent_udi, "storage", &hfp_error))
 
521
        {
 
522
          char *geom_class;
 
523
          char *type;
 
524
          char *scheme;
 
525
          int number;
 
526
          guint64 mediasize;
 
527
          guint64 offset;
 
528
 
 
529
          geom_class = getenv("HF_VOLUME_GEOM_CLASS");
 
530
 
 
531
          if (geom_class)
 
532
            {
 
533
              if (hf_probe_volume_get_partition_info(geom_class, device_file, &number, &type, &scheme, &mediasize, &offset))
 
534
                {
 
535
                  is_partition = TRUE;
 
536
 
 
537
                  libhal_device_set_property_int(hfp_ctx, hfp_udi, "volume.partition.number", number, &hfp_error);
 
538
                  libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.partition.scheme", scheme, &hfp_error);
 
539
                  libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.partition.type", type, &hfp_error);
 
540
 
 
541
                  /* FIXME We need to fill in the supported partition flags. */
 
542
 
 
543
                  libhal_device_set_property_uint64(hfp_ctx, hfp_udi, "volume.partition.media_size", mediasize, &hfp_error);
 
544
                  libhal_device_set_property_uint64(hfp_ctx, hfp_udi, "volume.partition.start", offset, &hfp_error);
 
545
 
 
546
                  if (! strcmp(scheme, "gpt"))
 
547
                    libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.partition.uuid", type, &hfp_error);
 
548
 
 
549
                  if (! strcmp(scheme, "gpt") || ! strcmp(scheme, "apm"))
 
550
                    libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.partition.label", "", &hfp_error);
 
551
 
 
552
                  g_free(type);
 
553
                  g_free(scheme);
 
554
                }
 
555
            }
 
556
        }
 
557
      else
 
558
        dbus_error_free(&hfp_error);
 
559
    }
 
560
 
 
561
  libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.is_disc", is_cdrom, &hfp_error);
 
562
  libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.is_partition", is_partition, &hfp_error);
 
563
 
 
564
  libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.ignore", has_children || is_swap, &hfp_error);
 
565
 
 
566
  if (vid && ! strcmp (vid->type, "ufs"))
 
567
    {
 
568
      struct uufsd ufsdisk;
 
569
 
 
570
      if (ufs_disk_fillout(&ufsdisk, device_file) == 0)
 
571
        {
 
572
          char ufsid[64];
 
573
          char **ufs_devs = NULL;
 
574
          int num_udis;
 
575
          int i;
 
576
 
 
577
          snprintf(ufsid, sizeof(ufsid), "%08x%08x", ufsdisk.d_fs.fs_id[0], ufsdisk.d_fs.fs_id[1]);
 
578
          libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.freebsd.ufsid", ufsid, &hfp_error);
 
579
          ufs_devs = libhal_manager_find_device_string_match(hfp_ctx,
 
580
                                                             "volume.freebsd.ufsid",
 
581
                                                             ufsid,
 
582
                                                             &num_udis,
 
583
                                                             &hfp_error);
 
584
          dbus_error_free(&hfp_error);
 
585
          for (i = 0; i < num_udis; i++)
 
586
            {
 
587
              if (ufs_devs[i] != NULL)
 
588
                {
 
589
                  gboolean mounted;
 
590
 
 
591
                  mounted = libhal_device_get_property_bool(hfp_ctx, ufs_devs[i], "volume.is_mounted", &hfp_error);
 
592
                  dbus_error_free(&hfp_error);
 
593
                  if (mounted)
 
594
                    {
 
595
                      libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.ignore", TRUE, &hfp_error);
 
596
                      dbus_error_free(&hfp_error);
 
597
                    }
 
598
                }
 
599
            }
 
600
          if (ufs_devs)
 
601
            libhal_free_string_array(ufs_devs);
 
602
          ufs_disk_close(&ufsdisk);
 
603
        }
 
604
    }
 
605
 
 
606
  if (has_children)
 
607
    usage = "partitiontable";
 
608
  else if (is_swap)
 
609
    usage = "other";
 
610
  else
 
611
    switch (vid ? vid->usage_id : (enum volume_id_usage) -1)
 
612
      {
 
613
      case VOLUME_ID_FILESYSTEM:        usage = "filesystem"; break;
 
614
      case VOLUME_ID_DISKLABEL:         usage = "disklabel"; break;
 
615
      case VOLUME_ID_OTHER:             usage = "other"; break;
 
616
      case VOLUME_ID_RAID:              usage = "raid"; break;
 
617
      case VOLUME_ID_CRYPTO:            usage = "crypto"; break;
 
618
      case VOLUME_ID_UNUSED:            usage = "unused"; break;
 
619
      default:                          usage = "unknown"; break;
 
620
      }
 
621
 
 
622
  libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.fsusage", usage, &hfp_error);
 
623
  libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.fstype", vid ? vid->type: "", &hfp_error);
 
624
  if (vid && *vid->type_version)
 
625
    libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.fsversion", vid->type_version, &hfp_error);
 
626
 
 
627
  label = hf_probe_volume_get_label(vid);
 
628
  libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.label", label ? label : "", &hfp_error);
 
629
  g_free(label);
 
630
 
 
631
  libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.uuid", vid ? vid->uuid : "", &hfp_error);
 
632
 
 
633
  ioctl(fd, DIOCGSECTORSIZE, &sector_size);
 
634
 
 
635
  if (sector_size != 0)
 
636
    libhal_device_set_property_uint64(hfp_ctx, hfp_udi, "volume.block_size", sector_size, &hfp_error);
 
637
  if (media_size != 0)
 
638
    libhal_device_set_property_uint64(hfp_ctx, hfp_udi, "volume.size", media_size, &hfp_error);
 
639
  if (sector_size != 0 && media_size != 0)
 
640
    libhal_device_set_property_uint64(hfp_ctx, hfp_udi, "volume.num_blocks", media_size / sector_size, &hfp_error);
 
641
 
 
642
  ret = 0;                      /* is a volume */
 
643
 
 
644
 end:
 
645
  return ret;
 
646
}