Exemplo n.º 1
0
static gboolean
hal_backend_set_version (ItdbBackend *itdb_backend, unsigned int version)
{
	HalBackend *backend = (HalBackend *)itdb_backend;
        libhal_device_set_property_int (backend->ctx, backend->udi, 
			                LIBGPOD_HAL_NS"version", 1, NULL);
	return TRUE;
}
Exemplo n.º 2
0
static gboolean
hal_backend_set_production_index (ItdbBackend *itdb_backend, guint index)
{
	HalBackend *backend = (HalBackend *)itdb_backend;
    	libhal_device_set_property_int (backend->ctx, backend->udi, 
					LIBGPOD_HAL_NS"ipod.production.number",
					index, NULL);
	return TRUE;
}
Exemplo n.º 3
0
static gboolean 
hal_backend_set_production_week (ItdbBackend *itdb_backend, guint week)
{
	HalBackend *backend = (HalBackend *)itdb_backend;
    	libhal_device_set_property_int (backend->ctx, backend->udi, 
					LIBGPOD_HAL_NS"ipod.production.week",
					week, NULL);
	return TRUE;
}
Exemplo n.º 4
0
int 
main (int argc, char *argv[])
{
	int fd, rfd;
	int ret;
	char *udi;
	char *device_file, *raw_device_file;
	char *devpath, *rdevpath;
	boolean_t is_dos;
	int dos_num;
	LibHalContext *ctx = NULL;
	DBusError error;
	DBusConnection *conn;
	char *parent_udi;
	char *storage_device;
	char *is_disc_str;
	int fdc;
	dbus_bool_t is_disc = FALSE;
	dbus_bool_t is_floppy = FALSE;
	unsigned int block_size;
	dbus_uint64_t vol_size;
	dbus_bool_t has_data = TRUE;	/* probe for fs by default */
	dbus_bool_t has_audio = FALSE;
	char *partition_scheme = NULL;
	dbus_uint64_t partition_start = 0;
	int partition_number = 0;
	struct vtoc vtoc;
	dk_gpt_t *gpt;
	struct dk_minfo mi;
	int i, dos_cnt;
	fstyp_handle_t fstyp_handle;
	int systid, relsect, numsect;
	off_t probe_offset = 0;
	int num_volumes;
	char **volumes;
	dbus_uint64_t v_start;
	const char *fstype;
	nvlist_t *fsattr;

	fd = rfd = -1;

	ret = 1;

	if ((udi = getenv ("UDI")) == NULL) {
		goto out;
	}
	if ((device_file = getenv ("HAL_PROP_BLOCK_DEVICE")) == NULL) {
		goto out;
	}
	if ((raw_device_file = getenv ("HAL_PROP_BLOCK_SOLARIS_RAW_DEVICE")) == NULL) {
		goto out;
	}
	if (!dos_to_dev(device_file, &rdevpath, &dos_num)) {
		rdevpath = raw_device_file;
	}
	if (!(is_dos = dos_to_dev(device_file, &devpath, &dos_num))) {
		devpath = device_file;
	}
	if ((parent_udi = getenv ("HAL_PROP_INFO_PARENT")) == NULL) {
		goto out;
	}
	if ((storage_device = getenv ("HAL_PROP_BLOCK_STORAGE_DEVICE")) == NULL) {
		goto out;
	}

	is_disc_str = getenv ("HAL_PROP_VOLUME_IS_DISC");
	if (is_disc_str != NULL && strcmp (is_disc_str, "true") == 0) {
		is_disc = TRUE;
	} else {
		is_disc = FALSE;
	}

	drop_privileges ();

	setup_logger ();

	dbus_error_init (&error);
	if ((ctx = libhal_ctx_init_direct (&error)) == NULL)
		goto out;

	HAL_DEBUG (("Doing probe-volume for %s\n", device_file));

	fd = open (devpath, O_RDONLY | O_NONBLOCK);
	if (fd < 0) {
		goto out;
	}
	rfd = open (rdevpath, O_RDONLY | O_NONBLOCK);
	if (rfd < 0) {
		goto out;
	}

	/* if it's a floppy with no media, bail out */
	if (ioctl(rfd, FDGETCHANGE, &fdc) == 0) {
		is_floppy = TRUE;
		if (fdc & FDGC_CURRENT) {
			goto out;
		}
	}

	/* block size and total size */
	if (ioctl(rfd, DKIOCGMEDIAINFO, &mi) != -1) {
		block_size = mi.dki_lbsize;
		vol_size = mi.dki_capacity * block_size;
	} else if (errno == ENXIO) {
		/* driver supports ioctl, but media is not available */
		goto out;
	} else {
		/* driver does not support ioctl, e.g. lofi */
		block_size = 512;
		vol_size = 0;
	}
	libhal_device_set_property_int (ctx, udi, "volume.block_size", block_size, &error);
	my_dbus_error_free (&error);
	libhal_device_set_property_uint64 (ctx, udi, "volume.size", vol_size, &error);
	my_dbus_error_free (&error);

	if (is_disc) {
		if (!probe_disc (rfd, ctx, udi, &has_data, &has_audio)) {
			HAL_DEBUG (("probe_disc failed, skipping fstyp"));
			goto out;
		}
		/* with audio present, create volume even if fs probing fails */
		if (has_audio) {
			ret = 0;
		}
	}

	if (!has_data) {
		goto skip_fs;
	}

	/* don't support partitioned floppy */
	if (is_floppy) {
		goto skip_part;
	}

	/*
	 * first get partitioning info
	 */
	if (is_dos) {
		/* for a dos drive find partition offset */
		if (!find_dos_drive(fd, dos_num, &relsect, &numsect, &systid)) {
			goto out;
		}
		partition_scheme = "mbr";
		partition_start = (dbus_uint64_t)relsect * 512;
		partition_number = dos_num;
		probe_offset = (off_t)relsect * 512;
	} else {
		if ((partition_number = read_vtoc(rfd, &vtoc)) >= 0) {
			if (!vtoc_one_slice_entire_disk(&vtoc)) {
				partition_scheme = "smi";
				if (partition_number < vtoc.v_nparts) {
					if (vtoc.v_part[partition_number].p_size == 0) {
						HAL_DEBUG (("zero size partition"));
					}
					partition_start = vtoc.v_part[partition_number].p_start * block_size;
				}
			}
		} else if ((partition_number = efi_alloc_and_read(rfd, &gpt)) >= 0) {
			partition_scheme = "gpt";
			if (partition_number < gpt->efi_nparts) {
				if (gpt->efi_parts[partition_number].p_size == 0) {
					HAL_DEBUG (("zero size partition"));
				}
				partition_start = gpt->efi_parts[partition_number].p_start * block_size;
			}
			efi_free(gpt);
		}
		probe_offset = 0;
	}

	if (partition_scheme != NULL) {
		libhal_device_set_property_string (ctx, udi, "volume.partition.scheme", partition_scheme, &error);
		my_dbus_error_free (&error);
		libhal_device_set_property_int (ctx, udi, "volume.partition.number", partition_number, &error);
		my_dbus_error_free (&error);
		libhal_device_set_property_uint64 (ctx, udi, "volume.partition.start", partition_start, &error);
		my_dbus_error_free (&error);
		libhal_device_set_property_bool (ctx, udi, "volume.is_partition", TRUE, &error);
		my_dbus_error_free (&error);
	} else {
		libhal_device_set_property_bool (ctx, udi, "volume.is_partition", FALSE, &error);
		my_dbus_error_free (&error);
	}

	/*
	 * ignore duplicate partitions
	 */
	if ((volumes = libhal_manager_find_device_string_match (
	    ctx, "block.storage_device", storage_device, &num_volumes, &error)) != NULL) {
		my_dbus_error_free (&error);
		for (i = 0; i < num_volumes; i++) {
			if (strcmp (udi, volumes[i]) == 0) {
				continue; /* skip self */
			}
			v_start = libhal_device_get_property_uint64 (ctx, volumes[i], "volume.partition.start", &error);
			if (dbus_error_is_set(&error)) {
				dbus_error_free(&error);
				continue;
			}
			if (v_start == partition_start) {
				HAL_DEBUG (("duplicate partition"));
				goto out;
			}
		}
		libhal_free_string_array (volumes);
	}

skip_part:

	/*
	 * now determine fs type
	 *
	 * XXX We could get better performance from block device,
	 * but for now we use raw device because:
	 *
	 * - fstyp_udfs has a bug that it only works on raw
	 *
	 * - sd has a bug that causes extremely slow reads
	 *   and incorrect probing of hybrid audio/data media
	 */
	if (fstyp_init(rfd, probe_offset, NULL, &fstyp_handle) != 0) {
		HAL_DEBUG (("fstyp_init failed"));
		goto out;
	}
	if ((fstyp_ident(fstyp_handle, NULL, &fstype) != 0) ||
	    (fstyp_get_attr(fstyp_handle, &fsattr) != 0)) {
		HAL_DEBUG (("fstyp ident or get_attr failed"));
		fstyp_fini(fstyp_handle);
		goto out;
	}
	set_fstyp_properties (ctx, udi, fstype, fsattr);

	if (strcmp (fstype, "hsfs") == 0) {
		hsfs_contents (fd, probe_offset, ctx, udi);
	}

	fstyp_fini(fstyp_handle);

skip_fs:

	ret = 0;

out:
	if (fd >= 0)
		close (fd);
	if (rfd >= 0)
		close (rfd);

	if (ctx != NULL) {
		my_dbus_error_free (&error);
		libhal_ctx_shutdown (ctx, &error);
		libhal_ctx_free (ctx);
	}

	return ret;

}
Exemplo n.º 5
0
int
main (int argc, char **argv)
{
  char *device_file;
  char *parent_udi;
  char *grandparent_udi;
  char *parent_drive_type;
  int fd = -1;
  struct volume_id *vid = NULL;
  int ret = 1;
  gboolean has_children;
  gboolean is_swap;
  gboolean is_cdrom;
  gboolean is_partition = FALSE;
  gboolean has_audio = FALSE;
  gboolean has_data = FALSE;
  gboolean is_blank = FALSE;
  const char *usage;
  char *label;
  unsigned int sector_size = 0;
  off_t media_size = 0;

  if (! hfp_init(argc, argv))
    goto end;

  device_file = getenv("HAL_PROP_BLOCK_DEVICE");
  if (! device_file)
    goto end;

  parent_udi = getenv("HAL_PROP_INFO_PARENT");
  if (! parent_udi)
    goto end;

  /* give a meaningful process title for ps(1) */
  setproctitle("%s", device_file);

  has_children = hfp_getenv_bool("HF_HAS_CHILDREN");
  is_swap = hfp_getenv_bool("HF_IS_SWAP");

  fd = open(device_file, O_RDONLY);
  if (fd < 0)
    goto end;

  parent_drive_type = libhal_device_get_property_string(hfp_ctx, parent_udi, "storage.drive_type", &hfp_error);
  dbus_error_free(&hfp_error);

  grandparent_udi = libhal_device_get_property_string(hfp_ctx, parent_udi, "info.parent", &hfp_error);
  dbus_error_free(&hfp_error);

  is_cdrom = parent_drive_type && ! strcmp(parent_drive_type, "cdrom");
  g_free(parent_drive_type);

  if (is_cdrom)
    {
      hf_probe_volume_get_disc_info(fd, &has_audio, &has_data);
      is_blank = (! has_audio && ! has_data);
    }

  ioctl(fd, DIOCGMEDIASIZE, &media_size);

  /*
   * We only check for filesystems if the volume has no children,
   * otherwise volume_id might find a filesystem in what is actually
   * the first child partition of the volume.
   *
   * If hald (which has looked at the partition type) reports that it
   * is a swap partition, we probe it nevertheless in case the
   * partition type is incorrect.
   */
  if (! has_children && ! (is_cdrom && ! has_data))
    {
      vid = volume_id_open_fd(fd);
      if (vid)
	{
	  if (volume_id_probe_all(vid, 0, media_size) == 0)
	    has_data = TRUE;
	  else
	    {
	      volume_id_close(vid);
	      vid = NULL;
	    }
	}
    }

  if (! has_children && ! is_swap && ! has_audio && ! has_data && ! is_blank)
    goto end;

  libhal_device_add_capability(hfp_ctx, hfp_udi, "volume", &hfp_error);
  if (is_cdrom)
    {
      HFPCDROM *cdrom;
      int type;
      guint64 capacity;

      libhal_device_set_property_string(hfp_ctx, hfp_udi, "info.category", "volume.disc", &hfp_error);
      libhal_device_add_capability(hfp_ctx, hfp_udi, "volume.disc", &hfp_error);

      libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.disc.has_audio", has_audio, &hfp_error);
      libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.disc.has_data", has_data, &hfp_error);
      libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.disc.is_vcd", FALSE, &hfp_error);
      libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.disc.is_svcd", FALSE, &hfp_error);
      libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.disc.is_videodvd", FALSE, &hfp_error);
      libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.disc.is_appendable", FALSE, &hfp_error);
      libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.disc.is_blank", is_blank, &hfp_error);
      libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.disc.is_rewritable", FALSE, &hfp_error);
      libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "unknown", &hfp_error);

      /* the following code was adapted from linux's probe-volume.c */

      cdrom = hfp_cdrom_new_from_fd(fd, device_file, grandparent_udi);
      if (cdrom)
	{
	  type = get_disc_type(cdrom);
	  if (type != -1)
	    switch (type)
	      {
	      case 0x08: /* CD-ROM */
		libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "cd_rom", &hfp_error);
		break;
	      case 0x09: /* CD-R */
		libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "cd_r", &hfp_error);
		break;
	      case 0x0a: /* CD-RW */
		libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "cd_rw", &hfp_error);
		libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.disc.is_rewritable", TRUE, &hfp_error);
		break;
	      case 0x10: /* DVD-ROM */
		libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "dvd_rom", &hfp_error);
		break;
	      case 0x11: /* DVD-R Sequential */
		libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "dvd_r", &hfp_error);
		break;
	      case 0x12: /* DVD-RAM */
		libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "dvd_ram", &hfp_error);
		libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.disc.is_rewritable", TRUE, &hfp_error);
		break;
	      case 0x13: /* DVD-RW Restricted Overwrite */
		libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "dvd_rw", &hfp_error);
		libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.disc.is_rewritable", TRUE, &hfp_error);
		break;
	      case 0x14: /* DVD-RW Sequential */
		libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "dvd_rw", &hfp_error);
		libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.disc.is_rewritable", TRUE, &hfp_error);
		break;
	      case 0x1A: /* DVD+RW */
		libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "dvd_plus_rw", &hfp_error);
		libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.disc.is_rewritable", TRUE, &hfp_error);
		break;
	      case 0x1B: /* DVD+R */
		libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "dvd_plus_r", &hfp_error);
		break;
	      case 0x2B: /* DVD+R Double Layer */
		libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "dvd_plus_r_dl", &hfp_error);
		break;
	      case 0x40: /* BD-ROM  */
		libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "bd_rom", &hfp_error);
		break;
	      case 0x41: /* BD-R Sequential */
		libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "bd_r", &hfp_error);
		break;
	      case 0x42: /* BD-R Random */
		libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "bd_r", &hfp_error);
		break;
	      case 0x43: /* BD-RE */
		libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "bd_re", &hfp_error);
		libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.disc.is_rewritable", TRUE, &hfp_error);
		break;
	      case 0x50: /* HD DVD-ROM */
		libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "hddvd_rom", &hfp_error);
		break;
	      case 0x51: /* HD DVD-R */
		libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "hddvd_r", &hfp_error);
		break;
	      case 0x52: /* HD DVD-Rewritable */
		libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "hddvd_rw", &hfp_error);
		libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.disc.is_rewritable", TRUE, &hfp_error);
		break;
	      }

	  if (get_disc_capacity_for_type(cdrom, type, &capacity) == 0)
	    libhal_device_set_property_uint64(hfp_ctx, hfp_udi, "volume.disc.capacity", capacity, &hfp_error);

	  /*
	   * linux's probe-volume.c: "on some hardware the get_disc_type
	   * call fails, so we use this as a backup".
	   */
	  if (disc_is_rewritable(cdrom))
	    libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.disc.is_rewritable", TRUE, &hfp_error);
	  if (disc_is_appendable(cdrom))
	    libhal_device_set_property_bool (hfp_ctx, hfp_udi, "volume.disc.is_appendable", TRUE, &hfp_error);

	  hfp_cdrom_free(cdrom);
	}

      if (has_data && vid && (! strcmp(vid->type, "iso9660") ||
          ! strcmp(vid->type, "udf")))
        hf_probe_volume_advanced_disc_detect(fd);
    }
  else
    {
      libhal_device_set_property_string(hfp_ctx, hfp_udi, "info.category", "volume", &hfp_error);

      if (libhal_device_query_capability(hfp_ctx, parent_udi, "storage", &hfp_error))
	{
	  char *geom_class;
	  char *type;
	  char *scheme;
	  int number;
	  guint64 mediasize;
	  guint64 offset;

	  geom_class = getenv("HF_VOLUME_GEOM_CLASS");

	  if (geom_class)
            {
              if (hf_probe_volume_get_partition_info(geom_class, device_file, &number, &type, &scheme, &mediasize, &offset))
                {
                  is_partition = TRUE;

		  libhal_device_set_property_int(hfp_ctx, hfp_udi, "volume.partition.number", number, &hfp_error);
		  libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.partition.scheme", scheme, &hfp_error);
		  libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.partition.type", type, &hfp_error);

		  /* FIXME We need to fill in the supported partition flags. */

		  libhal_device_set_property_uint64(hfp_ctx, hfp_udi, "volume.partition.media_size", mediasize, &hfp_error);
		  libhal_device_set_property_uint64(hfp_ctx, hfp_udi, "volume.partition.start", offset, &hfp_error);

		  if (! strcmp(scheme, "gpt"))
                    libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.partition.uuid", type, &hfp_error);

		  if (! strcmp(scheme, "gpt") || ! strcmp(scheme, "apm"))
                    libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.partition.label", "", &hfp_error);

		  g_free(type);
		  g_free(scheme);
		}
	    }
	}
      else
	dbus_error_free(&hfp_error);
    }

  libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.is_disc", is_cdrom, &hfp_error);
  libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.is_partition", is_partition, &hfp_error);

  libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.ignore", has_children || is_swap, &hfp_error);

#ifdef HAVE_LIBUFS
  if (vid && ! strcmp (vid->type, "ufs"))
    {
      struct uufsd ufsdisk;

      if (ufs_disk_fillout(&ufsdisk, device_file) == 0)
        {
	  char ufsid[64];
	  char **ufs_devs = NULL;
	  int num_udis;
	  int i;

	  snprintf(ufsid, sizeof(ufsid), "%08x%08x", ufsdisk.d_fs.fs_id[0], ufsdisk.d_fs.fs_id[1]);
	  libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.freebsd.ufsid", ufsid, &hfp_error);
	  dbus_error_free(&hfp_error);
	  ufs_devs = libhal_manager_find_device_string_match(hfp_ctx,
			  				     "volume.freebsd.ufsid",
							     ufsid,
							     &num_udis,
							     &hfp_error);
	  dbus_error_free(&hfp_error);
	  for (i = 0; i < num_udis; i++)
            {
              if (ufs_devs[i] != NULL && strcmp(ufs_devs[i], hfp_udi))
                {
                  gboolean mounted;

		  mounted = libhal_device_get_property_bool(hfp_ctx, ufs_devs[i], "volume.is_mounted", &hfp_error);
	          dbus_error_free(&hfp_error);
		  if (mounted)
	            {
                      libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.ignore", TRUE, &hfp_error);
		      dbus_error_free(&hfp_error);
		      break;
		    }
		}
	    }
	  if (ufs_devs)
	    libhal_free_string_array(ufs_devs);
	  ufs_disk_close(&ufsdisk);
	}
    }
#endif /* HAVE_LIBUFS */

  if (has_children)
    usage = "partitiontable";
  else if (is_swap)
    usage = "other";
  else
    switch (vid ? vid->usage_id : (enum volume_id_usage) -1)
      {
      case VOLUME_ID_FILESYSTEM:	usage = "filesystem"; break;
      case VOLUME_ID_DISKLABEL:		usage = "disklabel"; break;
      case VOLUME_ID_OTHER:		usage = "other"; break;
      case VOLUME_ID_RAID:		usage = "raid"; break;
      case VOLUME_ID_CRYPTO:		usage = "crypto"; break;
      case VOLUME_ID_UNUSED:		usage = "unused"; break;
      default:				usage = "unknown"; break;
      }

  libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.fsusage", usage, &hfp_error);
  libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.fstype", vid ? vid->type: "", &hfp_error);
  if (vid && *vid->type_version)
    libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.fsversion", vid->type_version, &hfp_error);

  label = hf_probe_volume_get_label(vid);
  libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.label", label ? label : "", &hfp_error);
  g_free(label);

  libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.uuid", vid ? vid->uuid : "", &hfp_error);

  ioctl(fd, DIOCGSECTORSIZE, &sector_size);

  if (sector_size != 0)
    libhal_device_set_property_uint64(hfp_ctx, hfp_udi, "volume.block_size", sector_size, &hfp_error);
  if (media_size != 0)
    libhal_device_set_property_uint64(hfp_ctx, hfp_udi, "volume.size", media_size, &hfp_error);
  if (sector_size != 0 && media_size != 0)
    libhal_device_set_property_uint64(hfp_ctx, hfp_udi, "volume.num_blocks", media_size / sector_size, &hfp_error);

  ret = 0;			/* is a volume */

 end:
  return ret;
}
Exemplo n.º 6
0
/** 
 *  main:
 *  @argc:                Number of arguments given to program
 *  @argv:                Arguments given to program
 *
 *  Returns:              Return code
 *
 *  Main entry point 
 */
int
main (int argc, char *argv[])
{
	dbus_bool_t rc = 0;
	char *udi = NULL;
	char *key = NULL;
	char *str_value = NULL;
	dbus_int32_t int_value = 0;
	dbus_uint64_t uint64_value = 0;
	double double_value = 0.0f;
	dbus_bool_t bool_value = TRUE;
	dbus_bool_t remove = FALSE;
	dbus_bool_t is_version = FALSE;
	int type = PROP_INVALID;
	DBusError error;
	dbus_bool_t direct = FALSE;

	if (argc <= 1) {
		usage (argc, argv);
		return 1;
	}

	while (1) {
		int c;
		int option_index = 0;
		const char *opt;
		static struct option long_options[] = {
			{"udi", 1, NULL, 0},
			{"key", 1, NULL, 0},
			{"int", 1, NULL, 0},
			{"uint64", 1, NULL, 0},
			{"string", 1, NULL, 0},
			{"double", 1, NULL, 0},
			{"bool", 1, NULL, 0},
			{"strlist-pre", 1, NULL, 0},
			{"strlist-post", 1, NULL, 0},
			{"strlist-rem", 1, NULL, 0},
			{"direct", 0, NULL, 0},
			{"remove", 0, NULL, 0},
			{"version", 0, NULL, 0},
			{"help", 0, NULL, 0},
			{NULL, 0, NULL, 0}
		};
		
		c = getopt_long (argc, argv, "",
				 long_options, &option_index);
		if (c == -1)
			break;

		switch (c) {
		case 0:
			opt = long_options[option_index].name;

			if (strcmp (opt, "help") == 0) {
				usage (argc, argv);
				return 0;
			} else if (strcmp (opt, "key") == 0) {
				key = strdup (optarg);
			} else if (strcmp (opt, "string") == 0) {
				str_value = strdup (optarg);
				type = PROP_STRING;
			} else if (strcmp (opt, "int") == 0) {
				int_value = strtol (optarg, NULL, 0);
				type = PROP_INT;
			} else if (strcmp (opt, "uint64") == 0) {
				uint64_value = strtoull (optarg, NULL, 0);
				type = PROP_UINT64;
			} else if (strcmp (opt, "double") == 0) {
				double_value = (double) atof (optarg);
				type = PROP_DOUBLE;
			} else if (strcmp (opt, "bool") == 0) {
				if (strcmp (optarg, "true") == 0)
					bool_value = TRUE;
				else if (strcmp (optarg, "false") == 0)
					bool_value = FALSE;
				else {
					usage (argc, argv);
					return 1;
				}
				type = PROP_BOOL;
			} else if (strcmp (opt, "strlist-pre") == 0) {
				str_value = strdup (optarg);
				type = PROP_STRLIST_PRE;
			} else if (strcmp (opt, "strlist-post") == 0) {
				str_value = strdup (optarg);
				type = PROP_STRLIST_POST;
			} else if (strcmp (opt, "strlist-rem") == 0) {
				str_value = strdup (optarg);
				type = PROP_STRLIST_REM;
			} else if (strcmp (opt, "remove") == 0) {
				remove = TRUE;
			} else if (strcmp (opt, "direct") == 0) {
				direct = TRUE;
			} else if (strcmp (opt, "udi") == 0) {
				udi = strdup (optarg);
			} else if (strcmp (opt, "version") == 0) {
				is_version = TRUE;
			}
			break;

		default:
			usage (argc, argv);
			return 1;
			break;
		}
	}

	if (is_version) {
		printf ("hal-set-property " PACKAGE_VERSION "\n");
		return 0;
	}

	/* must have at least one, but not neither or both */
	if ((remove && type != PROP_INVALID) || ((!remove) && type == PROP_INVALID)) {
		usage (argc, argv);
		return 1;
	}
	
	fprintf (stderr, "\n");
	
	dbus_error_init (&error);
	if (direct) {
		if ((hal_ctx = libhal_ctx_init_direct (&error)) == NULL) {
			fprintf (stderr, "error: libhal_ctx_init_direct\n");
			LIBHAL_FREE_DBUS_ERROR (&error);
			return 1;
		}
	} else {
		if ((hal_ctx = libhal_ctx_new ()) == NULL) {
			fprintf (stderr, "error: libhal_ctx_new\n");
			return 1;
		}
		if (!libhal_ctx_set_dbus_connection (hal_ctx, dbus_bus_get (DBUS_BUS_SYSTEM, &error))) {
			fprintf (stderr, "error: libhal_ctx_set_dbus_connection: %s: %s\n", error.name, error.message);
			LIBHAL_FREE_DBUS_ERROR (&error);
			return 1;
		}
		if (!libhal_ctx_init (hal_ctx, &error)) {
			if (dbus_error_is_set(&error)) {
				fprintf (stderr, "error: libhal_ctx_init: %s: %s\n", error.name, error.message);
				dbus_error_free (&error);
			}
			fprintf (stderr, "Could not initialise connection to hald.\n"
					"Normally this means the HAL daemon (hald) is not running or not ready.\n");
			return 1;
		}
	}

	if (remove) {
		rc = libhal_device_remove_property (hal_ctx, udi, key, &error);
		if (!rc) {
			fprintf (stderr, "error: libhal_device_remove_property: %s: %s\n", error.name, error.message);
			LIBHAL_FREE_DBUS_ERROR (&error);
			return 1;
		}
	} else {
		switch (type) {
		case PROP_STRING:
			rc = libhal_device_set_property_string (hal_ctx, udi, key, str_value, &error);
			break;
		case PROP_INT:
			rc = libhal_device_set_property_int (hal_ctx, udi, key, int_value, &error);
			break;
		case PROP_UINT64:
			rc = libhal_device_set_property_uint64 (hal_ctx, udi, key, uint64_value, &error);
			break;
		case PROP_DOUBLE:
			rc = libhal_device_set_property_double (hal_ctx, udi, key, double_value, &error);
			break;
		case PROP_BOOL:
			rc = libhal_device_set_property_bool (hal_ctx, udi, key, bool_value, &error);
			break;
		case PROP_STRLIST_PRE:
			rc = libhal_device_property_strlist_prepend (hal_ctx, udi, key, str_value, &error);
			break;
		case PROP_STRLIST_POST:
			rc = libhal_device_property_strlist_append (hal_ctx, udi, key, str_value, &error);
			break;
		case PROP_STRLIST_REM:
			rc = libhal_device_property_strlist_remove (hal_ctx, udi, key, str_value, &error);
			break;
		}
		if (!rc) {
			fprintf (stderr, "error: libhal_device_set_property: %s: %s\n", error.name, error.message);
			dbus_error_free (&error);
			return 1;
		}
	}
	    
	return rc ? 0 : 1;
}
int
main (int argc, char *argv[])
{
	DBusError err;
	int retval = 0;

	hal_set_proc_title_init (argc, argv);

	setup_logger ();	

	device_udi = getenv ("UDI");

	HAL_DEBUG (("device:[%s]", device_udi));
	if (device_udi == NULL) {
		HAL_ERROR (("No device specified"));
		return -2;
	}

	dbus_error_init (&err);
	if ((halctx = libhal_ctx_init_direct (&err)) == NULL) {
		HAL_ERROR (("Cannot connect to hald"));
		retval = -3;
		goto out;
	}


	/* update_properties */
	libhal_device_set_property_bool (halctx, device_udi, 
			"battery.present", TRUE, &err);

	LIBHAL_FREE_DBUS_ERROR (&err);
	if (!libhal_device_property_exists (halctx, device_udi, 
			"battery.is_rechargeable", &err)) {
		LIBHAL_FREE_DBUS_ERROR (&err);
		libhal_device_set_property_bool (halctx, device_udi, 
			"battery.is_rechargeable", FALSE, &err);
	}

	LIBHAL_FREE_DBUS_ERROR (&err);
	libhal_device_set_property_int (halctx, device_udi, 
			"battery.charge_level.design", 7, &err);
	LIBHAL_FREE_DBUS_ERROR (&err);
	libhal_device_set_property_int (halctx, device_udi, 
			"battery.charge_level.last_full", 7, &err);
	LIBHAL_FREE_DBUS_ERROR (&err);
	libhal_device_set_property_string (halctx, device_udi, 
			"info.category", "battery", &err);
	LIBHAL_FREE_DBUS_ERROR (&err);
	libhal_device_set_property_string (halctx, device_udi, 
			"battery.command_interface", "csr", &err);

	/* monitor change */
	libhal_ctx_set_device_property_modified (halctx, property_modified);

	/* Initial fillup */
	dev_props = property_cache_item_get (device_udi);
	HAL_ERROR (("** Initial fillup done"));

	/* init usb */
	usb_init ();
	
	/* do coldplug */
	check_all_batteries (NULL);

	/* only add capability when initial charge_level key has been set */
	LIBHAL_FREE_DBUS_ERROR (&err);
	libhal_device_add_capability (halctx, device_udi, "battery", &err);

	LIBHAL_FREE_DBUS_ERROR (&err);
	if (!libhal_device_addon_is_ready (halctx, device_udi, &err)) {
		retval = -4;
		goto out;
	}

	hal_set_proc_title ("hald-addon-usb-csr: listening on '%s'", 
			    libhal_device_get_property_string(halctx, device_udi,
							      "info.product", &err));

	main_loop = g_main_loop_new (NULL, FALSE);
#ifdef HAVE_GLIB_2_14
	g_timeout_add_seconds (TIMEOUT, check_all_batteries, NULL);
#else
	g_timeout_add (1000L * TIMEOUT, check_all_batteries, NULL);
#endif
	g_main_loop_run (main_loop);
	return 0;

out:
        HAL_DEBUG (("An error occured, exiting cleanly"));

        LIBHAL_FREE_DBUS_ERROR (&err);

        if (halctx != NULL) {
                libhal_ctx_shutdown (halctx, &err);
                LIBHAL_FREE_DBUS_ERROR (&err);
                libhal_ctx_free (halctx);
        }

        return retval;
}
/* Thanks to lmctl code. I'd LOVE, REALLY LOVE to see some docs though... */
static void 
check_battery (const char *hal_device_udi, PropertyCacheItem *pci)
{
	struct usb_device *curr_device;
	usb_dev_handle *handle;
	char buf[80];
	DBusError err;
	unsigned int addr;
	int is_dual = 0;
	int percentage = 0;

	if (pci == NULL)
		return;

	HAL_DEBUG (("CSR device: [%s]", hal_device_udi));
	is_dual = pci->csr_is_dual;

	/* Which of subdevices to address */
	HAL_DEBUG (("Is dual: %d", is_dual));
	addr = is_dual? 1<<8 : 0;

	curr_device = find_device (pci);
	if (curr_device == NULL)	{
		HAL_ERROR (("Device %s not found", hal_device_udi));
		return;
	}

	handle = usb_open (curr_device);
	if (handle == NULL) {
		HAL_ERROR (("Could not open usb device"));
		return;
	}

	if (!usb_control_msg (handle, 0xc0, 0x09, 0x03|addr, 0x00|addr,
			 buf, 8, TIMEOUT) != 8)	{
		if ((P0 == 0x3b) && (P4 == 0)) {
			HAL_DEBUG (("Receiver busy, trying again later"));
		} else {
			int current_charge = P5 & 0x07;

			HAL_DEBUG (("Charge level: %d->%d", pci->current_charge, current_charge));
			if (current_charge != pci->current_charge) { 
				pci->current_charge = current_charge; 
				dbus_error_init (&err);

		 		libhal_device_set_property_int (halctx, hal_device_udi, 
		 			"battery.charge_level.current", current_charge, &err);
				LIBHAL_FREE_DBUS_ERROR (&err);

		 		if (current_charge != 0) {
		 			percentage = (100.0 / 7.0) * current_charge;
		 			libhal_device_set_property_int (halctx, hal_device_udi, 
		 				"battery.charge_level.percentage", percentage, &err);
				} else {
					libhal_device_remove_property(halctx, hal_device_udi,
								      "battery.charge_level.percentage", &err);	
				}

				LIBHAL_FREE_DBUS_ERROR (&err);
			}
		}
	} else {
		perror ("Writing to USB device");
	}

	usb_close (handle);
}
Exemplo n.º 9
0
static void
battery_dynamic_update(LibHalContext *ctx, const char *udi, int fd)
{
	int reporting_rate;
	int reporting_current;
	int reporting_lastfull;
	int design_voltage;
	int present_voltage;
	char *reporting_unit;
	int remaining_time;
	int remaining_percentage;
	gboolean charging;
	gboolean discharging;
	acpi_bst_t bst;
	LibHalChangeSet *cs;
	DBusError error;
	static int counter = 0;

	HAL_DEBUG(("battery_dynamic_update() enter"));
	bzero(&bst, sizeof (bst));
	if (ioctl(fd, BATT_IOC_STATUS, &bst) < 0) {
		return;
	}

	charging = bst.bst_state & BATT_BST_CHARGING ? TRUE : FALSE;
	discharging = bst.bst_state & BATT_BST_DISCHARGING ? TRUE : FALSE;
	/* No need to continue if battery is essentially idle. */
	if (counter && !charging && !discharging) {
		return;
	}
	dbus_error_init(&error);
	libhal_device_set_property_bool(ctx, udi, "battery.is_rechargeable",
	    TRUE, &error);
	my_dbus_error_free(&error);
	if (libhal_device_property_exists(ctx, udi,
	    "battery.charge_level.percentage", &error)) {
		remaining_percentage = libhal_device_get_property_int(ctx, udi,
		    "battery.charge_level.percentage", &error);
		if ((remaining_percentage == 100) && charging) {
			charging = FALSE;
		}
	}
	libhal_device_set_property_bool(ctx, udi,
	    "battery.rechargeable.is_charging", charging, &error);
	my_dbus_error_free(&error);
	libhal_device_set_property_bool(ctx, udi,
	    "battery.rechargeable.is_discharging", discharging, &error);
	my_dbus_error_free(&error);
	reporting_current = bst.bst_rem_cap;
	libhal_device_set_property_int(ctx, udi, "battery.reporting.current",
	    bst.bst_rem_cap, &error);
	my_dbus_error_free(&error);
	reporting_rate = bst.bst_rate;
	libhal_device_set_property_int(ctx, udi, "battery.reporting.rate",
	    bst.bst_rate, &error);
	my_dbus_error_free(&error);
	present_voltage = bst.bst_voltage;
	libhal_device_set_property_int(ctx, udi, "battery.voltage.present",
	    bst.bst_voltage, &error);
	/* get all the data we know */
	my_dbus_error_free(&error);
	reporting_unit = libhal_device_get_property_string(ctx, udi,
	    "battery.reporting.unit", &error);
	my_dbus_error_free(&error);
	reporting_lastfull = libhal_device_get_property_int(ctx, udi,
	    "battery.reporting.last_full", &error);

	/*
	 * Convert mAh to mWh since util_compute_time_remaining() works
	 * for mWh.
	 */
	if (reporting_unit && strcmp(reporting_unit, "mAh") == 0) {
		my_dbus_error_free(&error);
		design_voltage = libhal_device_get_property_int(ctx, udi,
		    "battery.voltage.design", &error);
		/*
		 * If the present_voltage is inaccurate, set it to the
		 * design_voltage.
		 */
		if (((present_voltage * 10) < design_voltage) ||
		    (present_voltage <= 0) ||
		    (present_voltage > design_voltage)) {
			present_voltage = design_voltage;
		}
		reporting_rate = (reporting_rate * present_voltage) / 1000;
		reporting_lastfull = (reporting_lastfull * present_voltage) /
		    1000;
		reporting_current = (reporting_current * present_voltage) /
		    1000;
	}

	/* Make sure the current charge does not exceed the full charge */
	if (reporting_current > reporting_lastfull) {
		reporting_current = reporting_lastfull;
	}
	if (!charging && !discharging) {
		counter++;
		reporting_rate = 0;
	}

	if ((cs = libhal_device_new_changeset(udi)) == NULL) {
		HAL_DEBUG(("Cannot allocate changeset"));
		libhal_free_string(reporting_unit);
		my_dbus_error_free(&error);
		return;
	}

	libhal_changeset_set_property_int(cs, "battery.charge_level.rate",
	    reporting_rate);
	libhal_changeset_set_property_int(cs,
	    "battery.charge_level.last_full", reporting_lastfull);
	libhal_changeset_set_property_int(cs,
	    "battery.charge_level.current", reporting_current);

	remaining_percentage = util_compute_percentage_charge(udi,
	    reporting_current, reporting_lastfull);
	remaining_time = util_compute_time_remaining(udi, reporting_rate,
	    reporting_current, reporting_lastfull, discharging, charging, 0);
	/*
	 * Some batteries give bad remaining_time estimates relative to
	 * the charge level.
	 */
	if (charging && ((remaining_time < 30) || ((remaining_time < 300) &&
	    (remaining_percentage < 95)) || (remaining_percentage > 97))) {
		remaining_time = util_compute_time_remaining(udi,
		    reporting_rate, reporting_current, reporting_lastfull,
		    discharging, charging, 1);
	}

	if (remaining_percentage > 0) {
		libhal_changeset_set_property_int(cs,
		    "battery.charge_level.percentage", remaining_percentage);
	} else {
		my_dbus_error_free(&error);
		libhal_device_remove_property(ctx, udi,
		    "battery.charge_level.percentage", &error);
	}
	if ((remaining_percentage == 100) && charging) {
		battery_last_full(cs, fd);
	}
	/*
	 * remaining_percentage is more accurate so we handle cases
	 * where the remaining_time cannot be correct.
	 */
	if ((!charging && !discharging) || ((remaining_percentage == 100) &&
	    !discharging)) {
		remaining_time = 0;
	}
	if (remaining_time < 0) {
		my_dbus_error_free(&error);
		libhal_device_remove_property(ctx, udi,
		    "battery.remaining_time", &error);
	} else if (remaining_time >= 0) {
		libhal_changeset_set_property_int(cs,
		    "battery.remaining_time", remaining_time);
	}

	my_dbus_error_free(&error);
	libhal_device_commit_changeset(ctx, cs, &error);
	libhal_device_free_changeset(cs);
	libhal_free_string(reporting_unit);
	my_dbus_error_free(&error);
	HAL_DEBUG(("battery_dynamic_update() exit"));
}
Exemplo n.º 10
0
int add_properties(LibHalContext *hal_ctx, new_dev_t *nd, lh_prop_t *prop)
{
	DBusError error;
	lh_prop_t *p;
	char *udi2 = NULL, *udi3 = NULL, **s;
	LibHalPropertyType old_type;

	dbus_error_init(&error);

	for(p = prop; p; p = p->next) {
		if (!strcmp(p->key, "udi") && p->type == LIBHAL_PROPERTY_TYPE_STRING) {
			udi2 = p->v.str_value;
			continue;
		}

		old_type = libhal_device_get_property_type(hal_ctx, nd->real_udi, p->key, &error);
		dbus_error_init(&error);

		if (old_type != LIBHAL_PROPERTY_TYPE_INVALID &&
		    ( p->type != old_type || p->type == LIBHAL_PROPERTY_TYPE_STRLIST)) {
			if (!libhal_device_remove_property(hal_ctx, nd->real_udi, p->key, &error)) {
				fprintf(stderr, "%s: %s\n", error.name, error.message);
				LIBHAL_FREE_DBUS_ERROR (&error);
				return 41;
			}
		}

		switch (p->type) {
			case LIBHAL_PROPERTY_TYPE_INVALID:
				break;
			case LIBHAL_PROPERTY_TYPE_BOOLEAN:
				if (!libhal_device_set_property_bool(hal_ctx, nd->real_udi, p->key, p->v.bool_value, &error)) {
					fprintf(stderr, "%s: %s\n", error.name, error.message);
					LIBHAL_FREE_DBUS_ERROR (&error);
					return 42;
				}
				break;
			case LIBHAL_PROPERTY_TYPE_INT32:
				if (!libhal_device_set_property_int(hal_ctx, nd->real_udi, p->key, p->v.int_value, &error)) {
					fprintf(stderr, "%s: %s\n", error.name, error.message);
					LIBHAL_FREE_DBUS_ERROR (&error);
					return 42;
				}
				break;
			case LIBHAL_PROPERTY_TYPE_UINT64:
				if (!libhal_device_set_property_uint64(hal_ctx, nd->real_udi, p->key, p->v.uint64_value, &error)) {
					fprintf(stderr, "%s: %s\n", error.name, error.message);
					LIBHAL_FREE_DBUS_ERROR (&error);
					return 42;
				}
				break;
			case LIBHAL_PROPERTY_TYPE_DOUBLE:
				if (!libhal_device_set_property_double(hal_ctx, nd->real_udi, p->key, p->v.double_value, &error)) {
					fprintf(stderr, "%s: %s\n", error.name, error.message);
					LIBHAL_FREE_DBUS_ERROR (&error);
					return 42;
				}
				break;
			case LIBHAL_PROPERTY_TYPE_STRING:
				if (!strcmp(p->key, "info.udi")) udi3 = p->v.str_value;
				if (!libhal_device_set_property_string(hal_ctx, nd->real_udi, p->key, p->v.str_value, &error)) {
					fprintf(stderr, "%s: %s\n", error.name, error.message);
					LIBHAL_FREE_DBUS_ERROR (&error);
					return 42;
				}
				break;
			case LIBHAL_PROPERTY_TYPE_STRLIST:
				for(s = p->v.strlist_value; *s; s++) {
					if (!libhal_device_property_strlist_append(hal_ctx, nd->real_udi, p->key, *s, &error)) {
						fprintf(stderr, "%s: %s\n", error.name, error.message);
						LIBHAL_FREE_DBUS_ERROR (&error);
						return 42;
					}
				}
				break;
		}
	}

	if (udi2) udi3 = NULL;
	if (udi3) udi2 = udi3;

	if (udi2 && !nd->udi)
		nd->udi = strdup(udi2);

	return 0;
}