diff options
| author | artem <none@none> | 2006-10-12 22:44:10 -0700 |
|---|---|---|
| committer | artem <none@none> | 2006-10-12 22:44:10 -0700 |
| commit | 18c2aff776a775d34a4c9893a4c72e0434d68e36 (patch) | |
| tree | 2ce07e824c6b4db04bfedb4dea79bc5f255851ed /usr/src/lib | |
| parent | 38787b9f841232f52e2f48dd8a9e475d09954391 (diff) | |
| download | illumos-joyent-18c2aff776a775d34a4c9893a4c72e0434d68e36.tar.gz | |
PSARC 2005/399 Tamarack: Removable Media Enhancements in Solaris
6460497 Tamarack (ON)
6460498 vold EOF removal
--HG--
rename : usr/src/cmd/fs.d/hsfs/ident/Makefile => deleted_files/usr/src/cmd/fs.d/hsfs/ident/Makefile
rename : usr/src/cmd/fs.d/hsfs/ident/ident_hsfs.c => deleted_files/usr/src/cmd/fs.d/hsfs/ident/ident_hsfs.c
rename : usr/src/cmd/fs.d/pcfs/ident/Makefile => deleted_files/usr/src/cmd/fs.d/pcfs/ident/Makefile
rename : usr/src/cmd/fs.d/pcfs/ident/ident_pcfs.c => deleted_files/usr/src/cmd/fs.d/pcfs/ident/ident_pcfs.c
rename : usr/src/cmd/fs.d/udfs/ident/Makefile => deleted_files/usr/src/cmd/fs.d/udfs/ident/Makefile
rename : usr/src/cmd/fs.d/udfs/ident/ident_udfs.c => deleted_files/usr/src/cmd/fs.d/udfs/ident/ident_udfs.c
rename : usr/src/cmd/fs.d/ufs/ident/Makefile => deleted_files/usr/src/cmd/fs.d/ufs/ident/Makefile
rename : usr/src/cmd/fs.d/ufs/ident/ident_ufs.c => deleted_files/usr/src/cmd/fs.d/ufs/ident/ident_ufs.c
rename : usr/src/cmd/initpkg/init.d/volmgt => deleted_files/usr/src/cmd/initpkg/init.d/volmgt
rename : usr/src/cmd/volmgt/Makefile => deleted_files/usr/src/cmd/volmgt/Makefile
rename : usr/src/cmd/volmgt/Makefile.volmgt => deleted_files/usr/src/cmd/volmgt/Makefile.volmgt
rename : usr/src/cmd/volmgt/etc/Makefile => deleted_files/usr/src/cmd/volmgt/etc/Makefile
rename : usr/src/cmd/volmgt/etc/rmmount.conf => deleted_files/usr/src/cmd/volmgt/etc/rmmount.conf
rename : usr/src/cmd/volmgt/etc/svc-volfs => deleted_files/usr/src/cmd/volmgt/etc/svc-volfs
rename : usr/src/cmd/volmgt/etc/vold.conf => deleted_files/usr/src/cmd/volmgt/etc/vold.conf
rename : usr/src/cmd/volmgt/etc/volfs.xml => deleted_files/usr/src/cmd/volmgt/etc/volfs.xml
rename : usr/src/cmd/volmgt/req.flg => deleted_files/usr/src/cmd/volmgt/req.flg
rename : usr/src/cmd/volmgt/rmm/Makefile => deleted_files/usr/src/cmd/volmgt/rmm/Makefile
rename : usr/src/cmd/volmgt/rmm/action_dvdvideo.c => deleted_files/usr/src/cmd/volmgt/rmm/action_dvdvideo.c
rename : usr/src/cmd/volmgt/rmm/action_filemgr.c => deleted_files/usr/src/cmd/volmgt/rmm/action_filemgr.c
rename : usr/src/cmd/volmgt/rmm/action_test.c => deleted_files/usr/src/cmd/volmgt/rmm/action_test.c
rename : usr/src/cmd/volmgt/rmm/action_wabi.c => deleted_files/usr/src/cmd/volmgt/rmm/action_wabi.c
rename : usr/src/cmd/volmgt/rmm/action_workman.c => deleted_files/usr/src/cmd/volmgt/rmm/action_workman.c
rename : usr/src/cmd/volmgt/rmm/action_xmcd.c => deleted_files/usr/src/cmd/volmgt/rmm/action_xmcd.c
rename : usr/src/cmd/volmgt/rmm/req.flg => deleted_files/usr/src/cmd/volmgt/rmm/req.flg
rename : usr/src/cmd/volmgt/rmm/rmm.c => deleted_files/usr/src/cmd/volmgt/rmm/rmm.c
rename : usr/src/cmd/volmgt/rmm/rmm_config.c => deleted_files/usr/src/cmd/volmgt/rmm/rmm_config.c
rename : usr/src/cmd/volmgt/rmm/rmm_int.h => deleted_files/usr/src/cmd/volmgt/rmm/rmm_int.h
rename : usr/src/cmd/volmgt/rmm/rmm_util.c => deleted_files/usr/src/cmd/volmgt/rmm/rmm_util.c
rename : usr/src/cmd/volmgt/test/Makefile => deleted_files/usr/src/cmd/volmgt/test/Makefile
rename : usr/src/cmd/volmgt/test/README => deleted_files/usr/src/cmd/volmgt/test/README
rename : usr/src/cmd/volmgt/test/devlink.vt => deleted_files/usr/src/cmd/volmgt/test/devlink.vt
rename : usr/src/cmd/volmgt/test/stress => deleted_files/usr/src/cmd/volmgt/test/stress
rename : usr/src/cmd/volmgt/test/test_class_list => deleted_files/usr/src/cmd/volmgt/test/test_class_list
rename : usr/src/cmd/volmgt/test/test_suite_list => deleted_files/usr/src/cmd/volmgt/test/test_suite_list
rename : usr/src/cmd/volmgt/test/test_utilities_list => deleted_files/usr/src/cmd/volmgt/test/test_utilities_list
rename : usr/src/cmd/volmgt/test/voltestdrv.c => deleted_files/usr/src/cmd/volmgt/test/voltestdrv.c
rename : usr/src/cmd/volmgt/test/voltestdrv.conf => deleted_files/usr/src/cmd/volmgt/test/voltestdrv.conf
rename : usr/src/cmd/volmgt/test/voltestdrv.h => deleted_files/usr/src/cmd/volmgt/test/voltestdrv.h
rename : usr/src/cmd/volmgt/test/vttest.c => deleted_files/usr/src/cmd/volmgt/test/vttest.c
rename : usr/src/cmd/volmgt/util/Makefile => deleted_files/usr/src/cmd/volmgt/util/Makefile
rename : usr/src/cmd/volmgt/util/volcancel.c => deleted_files/usr/src/cmd/volmgt/util/volcancel.c
rename : usr/src/cmd/volmgt/util/volck.c => deleted_files/usr/src/cmd/volmgt/util/volck.c
rename : usr/src/cmd/volmgt/util/volmissing.c => deleted_files/usr/src/cmd/volmgt/util/volmissing.c
rename : usr/src/cmd/volmgt/util/volrmmount.c => deleted_files/usr/src/cmd/volmgt/util/volrmmount.c
rename : usr/src/cmd/volmgt/util/volsetup => deleted_files/usr/src/cmd/volmgt/util/volsetup
rename : usr/src/cmd/volmgt/util/volstat.c => deleted_files/usr/src/cmd/volmgt/util/volstat.c
rename : usr/src/cmd/volmgt/util/volutil.h => deleted_files/usr/src/cmd/volmgt/util/volutil.h
rename : usr/src/cmd/volmgt/vold/Makefile => deleted_files/usr/src/cmd/volmgt/vold/Makefile
rename : usr/src/cmd/volmgt/vold/action.h => deleted_files/usr/src/cmd/volmgt/vold/action.h
rename : usr/src/cmd/volmgt/vold/blank_partition.c => deleted_files/usr/src/cmd/volmgt/vold/blank_partition.c
rename : usr/src/cmd/volmgt/vold/db.h => deleted_files/usr/src/cmd/volmgt/vold/db.h
rename : usr/src/cmd/volmgt/vold/db_mem.c => deleted_files/usr/src/cmd/volmgt/vold/db_mem.c
rename : usr/src/cmd/volmgt/vold/db_nis.c => deleted_files/usr/src/cmd/volmgt/vold/db_nis.c
rename : usr/src/cmd/volmgt/vold/db_nis.h => deleted_files/usr/src/cmd/volmgt/vold/db_nis.h
rename : usr/src/cmd/volmgt/vold/dev.h => deleted_files/usr/src/cmd/volmgt/vold/dev.h
rename : usr/src/cmd/volmgt/vold/dev_cdrom.c => deleted_files/usr/src/cmd/volmgt/vold/dev_cdrom.c
rename : usr/src/cmd/volmgt/vold/dev_cdtest.c => deleted_files/usr/src/cmd/volmgt/vold/dev_cdtest.c
rename : usr/src/cmd/volmgt/vold/dev_floppy.c => deleted_files/usr/src/cmd/volmgt/vold/dev_floppy.c
rename : usr/src/cmd/volmgt/vold/dev_pcmem.c => deleted_files/usr/src/cmd/volmgt/vold/dev_pcmem.c
rename : usr/src/cmd/volmgt/vold/dev_rmdisk.c => deleted_files/usr/src/cmd/volmgt/vold/dev_rmdisk.c
rename : usr/src/cmd/volmgt/vold/dev_rmscsi.c => deleted_files/usr/src/cmd/volmgt/vold/dev_rmscsi.c
rename : usr/src/cmd/volmgt/vold/dev_test.c => deleted_files/usr/src/cmd/volmgt/vold/dev_test.c
rename : usr/src/cmd/volmgt/vold/fdisk_partition.c => deleted_files/usr/src/cmd/volmgt/vold/fdisk_partition.c
rename : usr/src/cmd/volmgt/vold/hsfs_partition.c => deleted_files/usr/src/cmd/volmgt/vold/hsfs_partition.c
rename : usr/src/cmd/volmgt/vold/label.h => deleted_files/usr/src/cmd/volmgt/vold/label.h
rename : usr/src/cmd/volmgt/vold/label_cdrom.c => deleted_files/usr/src/cmd/volmgt/vold/label_cdrom.c
rename : usr/src/cmd/volmgt/vold/label_dos.c => deleted_files/usr/src/cmd/volmgt/vold/label_dos.c
rename : usr/src/cmd/volmgt/vold/label_sun.c => deleted_files/usr/src/cmd/volmgt/vold/label_sun.c
rename : usr/src/cmd/volmgt/vold/label_test.c => deleted_files/usr/src/cmd/volmgt/vold/label_test.c
rename : usr/src/cmd/volmgt/vold/medium.c => deleted_files/usr/src/cmd/volmgt/vold/medium.c
rename : usr/src/cmd/volmgt/vold/medium.h => deleted_files/usr/src/cmd/volmgt/vold/medium.h
rename : usr/src/cmd/volmgt/vold/medium_private.h => deleted_files/usr/src/cmd/volmgt/vold/medium_private.h
rename : usr/src/cmd/volmgt/vold/name_factory.c => deleted_files/usr/src/cmd/volmgt/vold/name_factory.c
rename : usr/src/cmd/volmgt/vold/name_factory.h => deleted_files/usr/src/cmd/volmgt/vold/name_factory.h
rename : usr/src/cmd/volmgt/vold/nfs_server.c => deleted_files/usr/src/cmd/volmgt/vold/nfs_server.c
rename : usr/src/cmd/volmgt/vold/nfs_trace.c => deleted_files/usr/src/cmd/volmgt/vold/nfs_trace.c
rename : usr/src/cmd/volmgt/vold/node.h => deleted_files/usr/src/cmd/volmgt/vold/node.h
rename : usr/src/cmd/volmgt/vold/obj.h => deleted_files/usr/src/cmd/volmgt/vold/obj.h
rename : usr/src/cmd/volmgt/vold/partition.c => deleted_files/usr/src/cmd/volmgt/vold/partition.c
rename : usr/src/cmd/volmgt/vold/partition.h => deleted_files/usr/src/cmd/volmgt/vold/partition.h
rename : usr/src/cmd/volmgt/vold/partition_private.h => deleted_files/usr/src/cmd/volmgt/vold/partition_private.h
rename : usr/src/cmd/volmgt/vold/pcfs_partition.c => deleted_files/usr/src/cmd/volmgt/vold/pcfs_partition.c
rename : usr/src/cmd/volmgt/vold/solaris_partition.c => deleted_files/usr/src/cmd/volmgt/vold/solaris_partition.c
rename : usr/src/cmd/volmgt/vold/udfs_partition.c => deleted_files/usr/src/cmd/volmgt/vold/udfs_partition.c
rename : usr/src/cmd/volmgt/vold/ufs_partition.c => deleted_files/usr/src/cmd/volmgt/vold/ufs_partition.c
rename : usr/src/cmd/volmgt/vold/util.h => deleted_files/usr/src/cmd/volmgt/vold/util.h
rename : usr/src/cmd/volmgt/vold/vold.h => deleted_files/usr/src/cmd/volmgt/vold/vold.h
rename : usr/src/cmd/volmgt/vold/vold_action.c => deleted_files/usr/src/cmd/volmgt/vold/vold_action.c
rename : usr/src/cmd/volmgt/vold/vold_config.c => deleted_files/usr/src/cmd/volmgt/vold/vold_config.c
rename : usr/src/cmd/volmgt/vold/vold_db.c => deleted_files/usr/src/cmd/volmgt/vold/vold_db.c
rename : usr/src/cmd/volmgt/vold/vold_dev.c => deleted_files/usr/src/cmd/volmgt/vold/vold_dev.c
rename : usr/src/cmd/volmgt/vold/vold_err.c => deleted_files/usr/src/cmd/volmgt/vold/vold_err.c
rename : usr/src/cmd/volmgt/vold/vold_label.c => deleted_files/usr/src/cmd/volmgt/vold/vold_label.c
rename : usr/src/cmd/volmgt/vold/vold_main.c => deleted_files/usr/src/cmd/volmgt/vold/vold_main.c
rename : usr/src/cmd/volmgt/vold/vold_mnt.c => deleted_files/usr/src/cmd/volmgt/vold/vold_mnt.c
rename : usr/src/cmd/volmgt/vold/vold_node.c => deleted_files/usr/src/cmd/volmgt/vold/vold_node.c
rename : usr/src/cmd/volmgt/vold/vold_obj.c => deleted_files/usr/src/cmd/volmgt/vold/vold_obj.c
rename : usr/src/cmd/volmgt/vold/vold_path.c => deleted_files/usr/src/cmd/volmgt/vold/vold_path.c
rename : usr/src/cmd/volmgt/vold/vold_proc.c => deleted_files/usr/src/cmd/volmgt/vold/vold_proc.c
rename : usr/src/cmd/volmgt/vold/vold_props.c => deleted_files/usr/src/cmd/volmgt/vold/vold_props.c
rename : usr/src/cmd/volmgt/vold/vold_sysevent.c => deleted_files/usr/src/cmd/volmgt/vold/vold_sysevent.c
rename : usr/src/cmd/volmgt/vold/vold_util.c => deleted_files/usr/src/cmd/volmgt/vold/vold_util.c
rename : usr/src/cmd/volmgt/vold/vold_vol.c => deleted_files/usr/src/cmd/volmgt/vold/vold_vol.c
rename : usr/src/cmd/volmgt/vold/vtoc.c => deleted_files/usr/src/cmd/volmgt/vold/vtoc.c
rename : usr/src/cmd/volmgt/vold/vtoc.h => deleted_files/usr/src/cmd/volmgt/vold/vtoc.h
rename : usr/src/head/rmmount.h => deleted_files/usr/src/head/rmmount.h
rename : usr/src/lib/libvolmgt/common/volattr.c => deleted_files/usr/src/lib/libvolmgt/common/volattr.c
rename : usr/src/lib/libvolmgt/common/volmgt_fsi.c => deleted_files/usr/src/lib/libvolmgt/common/volmgt_fsi.c
rename : usr/src/lib/libvolmgt/common/volmgt_fsi_private.h => deleted_files/usr/src/lib/libvolmgt/common/volmgt_fsi_private.h
rename : usr/src/lib/libvolmgt/common/volmgt_fsidbi.c => deleted_files/usr/src/lib/libvolmgt/common/volmgt_fsidbi.c
rename : usr/src/lib/libvolmgt/common/volname.c => deleted_files/usr/src/lib/libvolmgt/common/volname.c
rename : usr/src/lib/libvolmgt/common/volutil.c => deleted_files/usr/src/lib/libvolmgt/common/volutil.c
rename : usr/src/pkgdefs/SUNWpcmem/preinstall => deleted_files/usr/src/pkgdefs/SUNWpcmem/preinstall
rename : usr/src/pkgdefs/SUNWvolr/Makefile => deleted_files/usr/src/pkgdefs/SUNWvolr/Makefile
rename : usr/src/pkgdefs/SUNWvolr/pkginfo.tmpl => deleted_files/usr/src/pkgdefs/SUNWvolr/pkginfo.tmpl
rename : usr/src/pkgdefs/SUNWvolr/postinstall => deleted_files/usr/src/pkgdefs/SUNWvolr/postinstall
rename : usr/src/pkgdefs/SUNWvolr/preinstall => deleted_files/usr/src/pkgdefs/SUNWvolr/preinstall
rename : usr/src/pkgdefs/SUNWvolr/prototype_com => deleted_files/usr/src/pkgdefs/SUNWvolr/prototype_com
rename : usr/src/pkgdefs/SUNWvolr/prototype_i386 => deleted_files/usr/src/pkgdefs/SUNWvolr/prototype_i386
rename : usr/src/pkgdefs/SUNWvolr/prototype_sparc => deleted_files/usr/src/pkgdefs/SUNWvolr/prototype_sparc
rename : usr/src/pkgdefs/SUNWvolu/Makefile => deleted_files/usr/src/pkgdefs/SUNWvolu/Makefile
rename : usr/src/pkgdefs/SUNWvolu/depend => deleted_files/usr/src/pkgdefs/SUNWvolu/depend
rename : usr/src/pkgdefs/SUNWvolu/pkginfo.tmpl => deleted_files/usr/src/pkgdefs/SUNWvolu/pkginfo.tmpl
rename : usr/src/pkgdefs/SUNWvolu/postremove => deleted_files/usr/src/pkgdefs/SUNWvolu/postremove
rename : usr/src/pkgdefs/SUNWvolu/prototype_com => deleted_files/usr/src/pkgdefs/SUNWvolu/prototype_com
rename : usr/src/pkgdefs/SUNWvolu/prototype_i386 => deleted_files/usr/src/pkgdefs/SUNWvolu/prototype_i386
rename : usr/src/pkgdefs/SUNWvolu/prototype_sparc => deleted_files/usr/src/pkgdefs/SUNWvolu/prototype_sparc
rename : usr/src/pkgdefs/common_files/i.rmmconf => deleted_files/usr/src/pkgdefs/common_files/i.rmmconf
rename : usr/src/pkgdefs/common_files/i.voldconf => deleted_files/usr/src/pkgdefs/common_files/i.voldconf
rename : usr/src/uts/common/io/vol.c => deleted_files/usr/src/uts/common/io/vol.c
rename : usr/src/uts/common/io/vol.conf => deleted_files/usr/src/uts/common/io/vol.conf
rename : usr/src/uts/common/sys/vol.h => deleted_files/usr/src/uts/common/sys/vol.h
rename : usr/src/uts/intel/vol/Makefile => deleted_files/usr/src/uts/intel/vol/Makefile
rename : usr/src/uts/sparc/vol/Makefile => deleted_files/usr/src/uts/sparc/vol/Makefile
rename : usr/src/cmd/volmgt/util/eject.c => usr/src/cmd/eject/eject.c
rename : usr/src/cmd/volmgt/util/volcheck.c => usr/src/cmd/volcheck/volcheck.c
Diffstat (limited to 'usr/src/lib')
59 files changed, 9453 insertions, 4105 deletions
diff --git a/usr/src/lib/Makefile b/usr/src/lib/Makefile index a18075620b..14b189482c 100644 --- a/usr/src/lib/Makefile +++ b/usr/src/lib/Makefile @@ -221,6 +221,8 @@ SUBDIRS += \ libzfs_jni \ libmapid \ brand \ + policykit \ + hal \ $($(MACH)_SUBDIRS) sparc_SUBDIRS= .WAIT \ @@ -372,6 +374,8 @@ HDRSUBDIRS= \ libzfs \ libzfs_jni \ libzoneinfo \ + hal \ + policykit \ lvm \ openssl \ pkcs11 \ diff --git a/usr/src/lib/hal/Makefile b/usr/src/lib/hal/Makefile new file mode 100644 index 0000000000..b98e17dc17 --- /dev/null +++ b/usr/src/lib/hal/Makefile @@ -0,0 +1,56 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +include ../Makefile.lib +include $(SRC)/cmd/hal/Makefile.hal + +SUBDIRS = libhal libhal-storage +HDRSUBDIRS = libhal libhal-storage + +all := TARGET= all +clean := TARGET= clean +clobber := TARGET= clobber +install := TARGET= install +install_h := TARGET= install_h + +.KEEP_STATE: + +all clean clobber install: $(SUBDIRS) + +install_h: $(ROOTHDRDIR) $(ROOTHDRS) $(SUBDIRS) + +# +# Don't check 3rd party code +# +check: + +$(SUBDIRS): FRC + @cd $@; pwd; $(MAKE) $(TARGET) + +FRC: + +include ../Makefile.targ diff --git a/usr/src/lib/hal/Makefile.com b/usr/src/lib/hal/Makefile.com new file mode 100644 index 0000000000..426528f6e1 --- /dev/null +++ b/usr/src/lib/hal/Makefile.com @@ -0,0 +1,55 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +include $(SRC)/lib/Makefile.lib +include $(SRC)/cmd/hal/Makefile.hal + +CPPFLAGS = $(HAL_DBUS_CPPFLAGS) $(HAL_GLIB_CPPFLAGS) $(CPPFLAGS.master) + +ROOTLIBPCDIR = $(ROOT)/usr/lib/pkgconfig +ROOTLIBPC = $(LIBPCSRC:%=$(ROOTLIBPCDIR)/%) + +CLOBBERFILES += $(LIBPCSRC) + +# +# Ensure `all' is the default target. +# +all: + +# no lint for 3rd party code +lint: + +$(ROOTLIBPCDIR): + $(INS.dir) + +$(ROOTLIBPC): $(ROOTLIBPCDIR) $(LIBPCSRC) + $(INS.file) $(LIBPCSRC) + +$(LIBPCSRC): ../common/$(LIBPCSRC).in + $(SED) -e "s@__VERSION__@$(HAL_VERSION)@" \ + < ../common/$(LIBPCSRC).in > $(LIBPCSRC) + diff --git a/usr/src/lib/hal/libhal-storage/Makefile b/usr/src/lib/hal/libhal-storage/Makefile new file mode 100644 index 0000000000..b7bffe3fac --- /dev/null +++ b/usr/src/lib/hal/libhal-storage/Makefile @@ -0,0 +1,52 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" + +include ../../Makefile.lib +include ../Makefile.com + +HDRS = libhal-storage.h +HDRDIR = common +ROOTHDRDIR = $(ROOT)/usr/include/hal + +SUBDIRS= $(MACH) + +all := TARGET= all +clean := TARGET= clean +clobber := TARGET= clobber +install := TARGET= install + +.KEEP_STATE: + +all clean clobber install: $(SUBDIRS) + +install_h: $(ROOTHDRS) + +$(SUBDIRS): FRC + @cd $@; pwd; $(MAKE) $(TARGET) + +FRC: + +include $(SRC)/lib/Makefile.targ diff --git a/usr/src/lib/hal/libhal-storage/Makefile.com b/usr/src/lib/hal/libhal-storage/Makefile.com new file mode 100644 index 0000000000..27faf43cc0 --- /dev/null +++ b/usr/src/lib/hal/libhal-storage/Makefile.com @@ -0,0 +1,61 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# +# usr/src/lib/hal/libhal-storage/Makefile.com +# + +LIBRARY = libhal-storage.a +VERS = .1.0.0 +VERS_MAJ = .1 +OBJECTS = libhal-storage.o +LIBPCSRC = hal-storage.pc + +include ../../Makefile.com + +LIBS = $(DYNLIB) $(LINTLIB) +LDLIBS += -lc -ldbus-1 -lhal +$(LINTLIB) := SRCS = $(SRCDIR)/$(LINTSRC) + +SRCDIR = ../common + +CFLAGS += $(CCVERBOSE) +CFLAGS += -_gcc=-Wno-deprecated-declarations +CPPFLAGS += -DGETTEXT_PACKAGE=\"$(HAL_GETTEXT_PACKAGE)\" -DENABLE_NLS +CPPFLAGS += -DPACKAGE_LOCALE_DIR=\"/usr/lib/locale\" +CPPFLAGS += -I$(ROOT)/usr/include/hal + +ROOTMAJLINK = $(ROOTLIBDIR)/$(LIBRARY:.a=.so)$(VERS_MAJ) + +.KEEP_STATE: + +all: $(LIBS) + +lint: lintcheck + +$(ROOTMAJLINK): + -$(RM) $@; $(SYMLINK) $(DYNLIB) $@ + +include $(SRC)/lib/Makefile.targ diff --git a/usr/src/lib/hal/libhal-storage/common/hal-storage.pc.in b/usr/src/lib/hal/libhal-storage/common/hal-storage.pc.in new file mode 100644 index 0000000000..8915793c62 --- /dev/null +++ b/usr/src/lib/hal/libhal-storage/common/hal-storage.pc.in @@ -0,0 +1,19 @@ +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# Licensed under the Academic Free License version 2.1 +# +# ident "%Z%%M% %I% %E% SMI" + +prefix=/usr +exec_prefix=${prefix} +libdir=${exec_prefix}/lib +includedir=${prefix}/include + +Name: hal-storage +Description: hal library for storage devices and volumes +Version: __VERSION__ +Requires: dbus-1 hal +Libs: -L${libdir} -lhal-storage +Cflags: -DDBUS_API_SUBJECT_TO_CHANGE -I${includedir}/hal diff --git a/usr/src/lib/hal/libhal-storage/common/libhal-storage.c b/usr/src/lib/hal/libhal-storage/common/libhal-storage.c new file mode 100644 index 0000000000..39bdc53735 --- /dev/null +++ b/usr/src/lib/hal/libhal-storage/common/libhal-storage.c @@ -0,0 +1,2037 @@ +/*************************************************************************** + * CVSID: $Id$ + * + * libhal-storage.c : HAL convenience library for storage devices and volumes + * + * Copyright (C) 2004 Red Hat, Inc. + * + * Author: David Zeuthen <davidz@redhat.com> + * + * Licensed under the Academic Free License version 2.1 + * + * This program 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 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + **************************************************************************/ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <dbus/dbus.h> + +#include <libhal.h> +#include "libhal-storage.h" + + +#ifdef ENABLE_NLS +# include <libintl.h> +# define _(String) dgettext (GETTEXT_PACKAGE, String) +# ifdef gettext_noop +# define N_(String) gettext_noop (String) +# else +# define N_(String) (String) +# endif +#else +/* Stubs that do something close enough. */ +# define textdomain(String) (String) +# define gettext(String) (String) +# define dgettext(Domain,Message) (Message) +# define dcgettext(Domain,Message,Type) (Message) +# define bindtextdomain(Domain,Directory) (Domain) +# define _(String) (String) +# define N_(String) (String) +#endif + +typedef struct IconMappingEntry_s { + LibHalStoragePolicyIcon icon; + char *path; + struct IconMappingEntry_s *next; +} IconMappingEntry; + +struct LibHalStoragePolicy_s { + IconMappingEntry *icon_mappings; +}; + +LibHalStoragePolicy * +libhal_storage_policy_new () +{ + LibHalStoragePolicy *p; + + p = malloc (sizeof (LibHalStoragePolicy)); + if (p == NULL) + goto out; + + p->icon_mappings = NULL; +out: + return p; +} + +void +libhal_storage_policy_free (LibHalStoragePolicy *policy) +{ + IconMappingEntry *i; + IconMappingEntry *j; + + /* free all icon mappings */ + for (i = policy->icon_mappings; i != NULL; i = j) { + j = i->next; + free (i->path); + free (i); + } + + free (policy); +} + +void +libhal_storage_policy_set_icon_path (LibHalStoragePolicy *policy, LibHalStoragePolicyIcon icon, const char *path) +{ + IconMappingEntry *i; + + /* see if it already exist */ + for (i = policy->icon_mappings; i != NULL; i = i->next) { + if (i->icon == icon) { + free (i->path); + i->path = strdup (path); + goto out; + } + } + + i = malloc (sizeof (IconMappingEntry)); + if (i == NULL) + goto out; + i->icon = icon; + i->path = strdup (path); + i->next = policy->icon_mappings; + policy->icon_mappings = i; + +out: + return; +} + +void +libhal_storage_policy_set_icon_mapping (LibHalStoragePolicy *policy, LibHalStoragePolicyIconPair *pairs) +{ + LibHalStoragePolicyIconPair *i; + + for (i = pairs; i->icon != 0x00; i++) { + libhal_storage_policy_set_icon_path (policy, i->icon, i->icon_path); + } +} + +const char * +libhal_storage_policy_lookup_icon (LibHalStoragePolicy *policy, LibHalStoragePolicyIcon icon) +{ + IconMappingEntry *i; + const char *path; + + path = NULL; + for (i = policy->icon_mappings; i != NULL; i = i->next) { + if (i->icon == icon) { + path = i->path; + goto out; + } + } +out: + return path; +} + + +#define MAX_STRING_SZ 256 + +char * +libhal_volume_policy_compute_size_as_string (LibHalVolume *volume) +{ + dbus_uint64_t size; + char *result; + char* sizes_str[] = {"K", "M", "G", "T", NULL}; + dbus_uint64_t cur = 1000L; + dbus_uint64_t base = 10L; + dbus_uint64_t step = 10L*10L*10L; + int cur_str = 0; + char buf[MAX_STRING_SZ]; + + result = NULL; + + size = libhal_volume_get_size (volume); + + do { + if (sizes_str[cur_str+1] == NULL || size < cur*step) { + /* found the unit, display a comma number if result is a single digit */ + if (size < cur*base) { + snprintf (buf, MAX_STRING_SZ, "%.01f%s", + ((double)size)/((double)cur), sizes_str[cur_str]); + result = strdup (buf); + } else { + snprintf (buf, MAX_STRING_SZ, "%llu%s", (long long unsigned int) size / cur, sizes_str[cur_str]); + result = strdup (buf); + } + goto out; + } + + cur *= step; + cur_str++; + } while (1); + +out: + return result; +} + +static void +fixup_string (char *s) +{ + /* TODO: first strip leading and trailing whitespace */ + /*g_strstrip (s);*/ + + /* TODO: could do nice things on all-upper case strings */ +} + +/* volume may be NULL (e.g. if drive supports removable media) */ +char * +libhal_drive_policy_compute_display_name (LibHalDrive *drive, LibHalVolume *volume, LibHalStoragePolicy *policy) +{ + char *name; + char *size_str; + char *vendormodel_str; + const char *model; + const char *vendor; + LibHalDriveType drive_type; + dbus_bool_t drive_is_hotpluggable; + dbus_bool_t drive_is_removable; + LibHalDriveCdromCaps drive_cdrom_caps; + char buf[MAX_STRING_SZ]; + + model = libhal_drive_get_model (drive); + vendor = libhal_drive_get_vendor (drive); + drive_type = libhal_drive_get_type (drive); + drive_is_hotpluggable = libhal_drive_is_hotpluggable (drive); + drive_is_removable = libhal_drive_uses_removable_media (drive); + drive_cdrom_caps = libhal_drive_get_cdrom_caps (drive); + + if (volume != NULL) + size_str = libhal_volume_policy_compute_size_as_string (volume); + else + size_str = NULL; + + if (vendor == NULL || strlen (vendor) == 0) { + if (model == NULL || strlen (model) == 0) + vendormodel_str = strdup (""); + else + vendormodel_str = strdup (model); + } else { + if (model == NULL || strlen (model) == 0) + vendormodel_str = strdup (vendor); + else { + snprintf (buf, MAX_STRING_SZ, "%s %s", vendor, model); + vendormodel_str = strdup (buf); + } + } + + fixup_string (vendormodel_str); + + if (drive_type==LIBHAL_DRIVE_TYPE_CDROM) { + + /* Optical drive handling */ + char *first; + char *second; + + + first = "CD-ROM"; + if (drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_CDR) + first = "CD-R"; + if (drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_CDRW) + first = "CD-RW"; + + second = ""; + if (drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_DVDROM) + second = "/DVD-ROM"; + if (drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSR) + second = "/DVD+R"; + if (drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSRW) + second = "/DVD+RW"; + if (drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_DVDR) + second = "/DVD-R"; + if (drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_DVDRW) + second = "/DVD-RW"; + if (drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_DVDRAM) + second = "/DVD-RAM"; + if ((drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_DVDR) && + (drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSR)) { + if(drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSRDL) + second = "/DVD±R DL"; + else + second = "/DVD±R"; + } + if ((drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_DVDRW) && + (drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSRW)) { + if(drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSRDL || + drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSRWDL) + second = "/DVD±RW DL"; + else + second = "/DVD±RW"; + } + if (drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_BDROM) + second = "/BD-ROM"; + if (drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_BDR) + second = "/BD-R"; + if (drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_BDRE) + second = "/BD-RE"; + if (drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_HDDVDROM) + second = "/HD DVD-ROM"; + if (drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_HDDVDR) + second = "/HD DVD-R"; + if (drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_HDDVDRW) + second = "/HD DVD-RW"; + + if (drive_is_hotpluggable) { + snprintf (buf, MAX_STRING_SZ, _("External %s%s Drive"), first, second); + name = strdup (buf); + } else { + snprintf (buf, MAX_STRING_SZ, _("%s%s Drive"), first, second); + name = strdup (buf); + } + + } else if (drive_type==LIBHAL_DRIVE_TYPE_FLOPPY) { + + /* Floppy Drive handling */ + + if (drive_is_hotpluggable) + name = strdup (_("External Floppy Drive")); + else + name = strdup (_("Floppy Drive")); + } else if (drive_type==LIBHAL_DRIVE_TYPE_DISK && !drive_is_removable) { + + /* Harddisks */ + + if (size_str != NULL) { + if (drive_is_hotpluggable) { + snprintf (buf, MAX_STRING_SZ, _("%s External Hard Drive"), size_str); + name = strdup (buf); + } else { + snprintf (buf, MAX_STRING_SZ, _("%s Hard Drive"), size_str); + name = strdup (buf); + } + } else { + if (drive_is_hotpluggable) + name = strdup (_("External Hard Drive")); + else + name = strdup (_("Hard Drive")); + } + } else { + + /* The rest - includes drives with removable Media */ + + if (strlen (vendormodel_str) > 0) + name = strdup (vendormodel_str); + else + name = strdup (_("Drive")); + } + + free (vendormodel_str); + free (size_str); + + return name; +} + +char * +libhal_volume_policy_compute_display_name (LibHalDrive *drive, LibHalVolume *volume, LibHalStoragePolicy *policy) +{ + char *name; + char *size_str; + const char *volume_label; + const char *model; + const char *vendor; + LibHalDriveType drive_type; + dbus_bool_t drive_is_hotpluggable; + dbus_bool_t drive_is_removable; + LibHalDriveCdromCaps drive_cdrom_caps; + char buf[MAX_STRING_SZ]; + + volume_label = libhal_volume_get_label (volume); + model = libhal_drive_get_model (drive); + vendor = libhal_drive_get_vendor (drive); + drive_type = libhal_drive_get_type (drive); + drive_is_hotpluggable = libhal_drive_is_hotpluggable (drive); + drive_is_removable = libhal_drive_uses_removable_media (drive); + drive_cdrom_caps = libhal_drive_get_cdrom_caps (drive); + + size_str = libhal_volume_policy_compute_size_as_string (volume); + + /* If the volume label is available use that + * + * TODO: If label is a fully-qualified UNIX path don't use that + */ + if (volume_label != NULL) { + name = strdup (volume_label); + goto out; + } + + /* Handle media in optical drives */ + if (drive_type==LIBHAL_DRIVE_TYPE_CDROM) { + switch (libhal_volume_get_disc_type (volume)) { + + default: + /* explict fallthrough */ + case LIBHAL_VOLUME_DISC_TYPE_CDROM: + name = strdup (_("CD-ROM ")); + break; + + case LIBHAL_VOLUME_DISC_TYPE_CDR: + if (libhal_volume_disc_is_blank (volume)) + name = strdup (_("Blank CD-R")); + else + name = strdup (_("CD-R")); + break; + + case LIBHAL_VOLUME_DISC_TYPE_CDRW: + if (libhal_volume_disc_is_blank (volume)) + name = strdup (_("Blank CD-RW")); + else + name = strdup (_("CD-RW")); + break; + + case LIBHAL_VOLUME_DISC_TYPE_DVDROM: + name = strdup (_("DVD-ROM")); + break; + + case LIBHAL_VOLUME_DISC_TYPE_DVDRAM: + if (libhal_volume_disc_is_blank (volume)) + name = strdup (_("Blank DVD-RAM")); + else + name = strdup (_("DVD-RAM")); + break; + + case LIBHAL_VOLUME_DISC_TYPE_DVDR: + if (libhal_volume_disc_is_blank (volume)) + name = strdup (_("Blank DVD-R")); + else + name = strdup (_("DVD-R")); + break; + + case LIBHAL_VOLUME_DISC_TYPE_DVDRW: + if (libhal_volume_disc_is_blank (volume)) + name = strdup (_("Blank DVD-RW")); + else + name = strdup (_("DVD-RW")); + break; + + case LIBHAL_VOLUME_DISC_TYPE_DVDPLUSR: + if (libhal_volume_disc_is_blank (volume)) + name = strdup (_("Blank DVD+R")); + else + name = strdup (_("DVD+R")); + break; + + case LIBHAL_VOLUME_DISC_TYPE_DVDPLUSRW: + if (libhal_volume_disc_is_blank (volume)) + name = strdup (_("Blank DVD+RW")); + else + name = strdup (_("DVD+RW")); + break; + + case LIBHAL_VOLUME_DISC_TYPE_DVDPLUSR_DL: + if (libhal_volume_disc_is_blank (volume)) + name = strdup (_("Blank DVD+R Dual-Layer")); + else + name = strdup (_("DVD+R Dual-Layer")); + break; + + case LIBHAL_VOLUME_DISC_TYPE_BDROM: + name = strdup (_("BD-ROM")); + break; + + case LIBHAL_VOLUME_DISC_TYPE_BDR: + if (libhal_volume_disc_is_blank (volume)) + name = strdup (_("Blank BD-R")); + else + name = strdup (_("BD-R")); + break; + + case LIBHAL_VOLUME_DISC_TYPE_BDRE: + if (libhal_volume_disc_is_blank (volume)) + name = strdup (_("Blank BD-RE")); + else + name = strdup (_("BD-RE")); + break; + + case LIBHAL_VOLUME_DISC_TYPE_HDDVDROM: + name = strdup (_("HD DVD-ROM")); + break; + + case LIBHAL_VOLUME_DISC_TYPE_HDDVDR: + if (libhal_volume_disc_is_blank (volume)) + name = strdup (_("Blank HD DVD-R")); + else + name = strdup (_("HD DVD-R")); + break; + + case LIBHAL_VOLUME_DISC_TYPE_HDDVDRW: + if (libhal_volume_disc_is_blank (volume)) + name = strdup (_("Blank HD DVD-RW")); + else + name = strdup (_("HD DVD-RW")); + break; + + } + + /* Special case for pure audio disc */ + if (libhal_volume_disc_has_audio (volume) && !libhal_volume_disc_has_data (volume)) { + free (name); + name = strdup (_("Audio CD")); + } + + goto out; + } + + /* Fallback: size of media */ + if (drive_is_removable) { + snprintf (buf, MAX_STRING_SZ, _("%s Removable Media"), size_str); + name = strdup (buf); + } else { + snprintf (buf, MAX_STRING_SZ, _("%s Media"), size_str); + name = strdup (buf); + } + + /* Fallback: Use drive name */ + /*name = libhal_drive_policy_compute_display_name (drive, volume);*/ + +out: + free (size_str); + return name; +} + +char * +libhal_drive_policy_compute_icon_name (LibHalDrive *drive, LibHalVolume *volume, LibHalStoragePolicy *policy) +{ + const char *name; + LibHalDriveBus bus; + LibHalDriveType drive_type; + + bus = libhal_drive_get_bus (drive); + drive_type = libhal_drive_get_type (drive); + + /* by design, the enums are laid out so we can do easy computations */ + + switch (drive_type) { + case LIBHAL_DRIVE_TYPE_REMOVABLE_DISK: + case LIBHAL_DRIVE_TYPE_DISK: + case LIBHAL_DRIVE_TYPE_CDROM: + case LIBHAL_DRIVE_TYPE_FLOPPY: + name = libhal_storage_policy_lookup_icon (policy, 0x10000 + drive_type*0x100 + bus); + break; + + default: + name = libhal_storage_policy_lookup_icon (policy, 0x10000 + drive_type*0x100); + } + + if (name != NULL) + return strdup (name); + else + return NULL; +} + +char * +libhal_volume_policy_compute_icon_name (LibHalDrive *drive, LibHalVolume *volume, LibHalStoragePolicy *policy) +{ + const char *name; + LibHalDriveBus bus; + LibHalDriveType drive_type; + LibHalVolumeDiscType disc_type; + + /* by design, the enums are laid out so we can do easy computations */ + + if (libhal_volume_is_disc (volume)) { + disc_type = libhal_volume_get_disc_type (volume); + name = libhal_storage_policy_lookup_icon (policy, 0x30000 + disc_type); + goto out; + } + + if (drive == NULL) { + name = libhal_storage_policy_lookup_icon (policy, LIBHAL_STORAGE_ICON_VOLUME_REMOVABLE_DISK); + goto out; + } + + bus = libhal_drive_get_bus (drive); + drive_type = libhal_drive_get_type (drive); + + switch (drive_type) { + case LIBHAL_DRIVE_TYPE_REMOVABLE_DISK: + case LIBHAL_DRIVE_TYPE_DISK: + case LIBHAL_DRIVE_TYPE_CDROM: + case LIBHAL_DRIVE_TYPE_FLOPPY: + name = libhal_storage_policy_lookup_icon (policy, 0x20000 + drive_type*0x100 + bus); + break; + + default: + name = libhal_storage_policy_lookup_icon (policy, 0x20000 + drive_type*0x100); + } +out: + if (name != NULL) + return strdup (name); + else + return NULL; +} + +/** Policy function to determine if a volume should be visible in a desktop + * environment. This is useful to hide certain system volumes as bootstrap + * partitions, the /usr partition, swap partitions and other volumes that + * a unprivileged desktop user shouldn't know even exists. + * + * @param drive Drive that the volume is stemming from + * @param volume Volume + * @param policy Policy object + * @param target_mount_point The mount point that the volume is expected to + * be mounted at if not already mounted. This may + * e.g. stem from /etc/fstab. If this is NULL the + * then mount point isn't taking into account when + * evaluating whether the volume should be visible + * @return Whether the volume should be shown in a desktop + * environment. + */ +dbus_bool_t +libhal_volume_policy_should_be_visible (LibHalDrive *drive, LibHalVolume *volume, LibHalStoragePolicy *policy, + const char *target_mount_point) +{ + unsigned int i; + dbus_bool_t is_visible; + const char *label; + const char *mount_point; + const char *fstype; + const char *fhs23_toplevel_mount_points[] = { + "/", + "/bin", + "/boot", + "/dev", + "/etc", + "/home", + "/lib", + "/lib64", + "/media", + "/mnt", + "/opt", + "/root", + "/sbin", + "/srv", + "/tmp", + "/usr", + "/var", + "/proc", + "/sbin", + NULL + }; + + is_visible = FALSE; + + /* skip if hal says it's not used as a filesystem */ + if (libhal_volume_get_fsusage (volume) != LIBHAL_VOLUME_USAGE_MOUNTABLE_FILESYSTEM) + goto out; + + label = libhal_volume_get_label (volume); + mount_point = libhal_volume_get_mount_point (volume); + fstype = libhal_volume_get_fstype (volume); + + /* use target mount point if we're not mounted yet */ + if (mount_point == NULL) + mount_point = target_mount_point; + + /* bail out if we don't know the filesystem */ + if (fstype == NULL) + goto out; + + /* blacklist fhs2.3 top level mount points */ + if (mount_point != NULL) { + for (i = 0; fhs23_toplevel_mount_points[i] != NULL; i++) { + if (strcmp (mount_point, fhs23_toplevel_mount_points[i]) == 0) + goto out; + } + } + + /* blacklist partitions with name 'bootstrap' of type HFS (Apple uses that) */ + if (label != NULL && strcmp (label, "bootstrap") == 0 && strcmp (fstype, "hfs") == 0) + goto out; + + /* only the real lucky mount points will make it this far :-) */ + is_visible = TRUE; + +out: + return is_visible; +} + +/*************************************************************************/ + +#define MOUNT_OPTIONS_SIZE 256 + +struct LibHalDrive_s { + char *udi; + + int device_major; + int device_minor; + char *device_file; + + LibHalDriveBus bus; + char *vendor; /* may be "", is never NULL */ + char *model; /* may be "", is never NULL */ + dbus_bool_t is_hotpluggable; + dbus_bool_t is_removable; + dbus_bool_t is_media_detected; + dbus_bool_t requires_eject; + + LibHalDriveType type; + char *type_textual; + + char *physical_device; /* UDI of physical device, e.g. the + * IDE, USB, IEEE1394 device */ + + char *dedicated_icon_drive; + char *dedicated_icon_volume; + + char *serial; + char *firmware_version; + LibHalDriveCdromCaps cdrom_caps; + + char *desired_mount_point; + char *mount_filesystem; + dbus_bool_t should_mount; + + dbus_bool_t no_partitions_hint; + + dbus_uint64_t drive_size; + dbus_uint64_t drive_media_size; + char *partition_scheme; + + LibHalContext *hal_ctx; + + char **capabilities; + + char mount_options[MOUNT_OPTIONS_SIZE]; +}; + +struct LibHalVolume_s { + char *udi; + + int device_major; + int device_minor; + char *device_file; + char *volume_label; /* may be NULL, is never "" */ + dbus_bool_t is_mounted; + dbus_bool_t is_mounted_read_only; /* TRUE iff is_mounted and r/o fs */ + char *mount_point; /* NULL iff !is_mounted */ + char *fstype; /* NULL iff !is_mounted or unknown */ + char *fsversion; + char *uuid; + char *storage_device; + + LibHalVolumeUsage fsusage; + + dbus_bool_t is_partition; + unsigned int partition_number; + char *partition_scheme; + char *partition_type; + char *partition_label; + char *partition_uuid; + char **partition_flags; + + int msdos_part_table_type; + dbus_uint64_t msdos_part_table_start; + dbus_uint64_t msdos_part_table_size; + + dbus_bool_t is_disc; + LibHalVolumeDiscType disc_type; + dbus_bool_t disc_has_audio; + dbus_bool_t disc_has_data; + dbus_bool_t disc_is_appendable; + dbus_bool_t disc_is_blank; + dbus_bool_t disc_is_rewritable; + + unsigned int block_size; + unsigned int num_blocks; + + char *desired_mount_point; + char *mount_filesystem; + dbus_bool_t should_mount; + + dbus_bool_t ignore_volume; + + char *crypto_backing_volume; + + char mount_options[MOUNT_OPTIONS_SIZE]; + + dbus_uint64_t volume_size; + dbus_uint64_t disc_capacity; + + dbus_uint64_t partition_start_offset; + dbus_uint64_t partition_media_size; +}; + +const char * +libhal_drive_get_dedicated_icon_drive (LibHalDrive *drive) +{ + return drive->dedicated_icon_drive; +} + +const char * +libhal_drive_get_dedicated_icon_volume (LibHalDrive *drive) +{ + return drive->dedicated_icon_volume; +} + +/** Free all resources used by a LibHalDrive object. + * + * @param drive Object to free + */ +void +libhal_drive_free (LibHalDrive *drive) +{ + if (drive == NULL ) + return; + + free (drive->udi); + libhal_free_string (drive->device_file); + libhal_free_string (drive->vendor); + libhal_free_string (drive->model); + libhal_free_string (drive->type_textual); + libhal_free_string (drive->physical_device); + libhal_free_string (drive->dedicated_icon_drive); + libhal_free_string (drive->dedicated_icon_volume); + libhal_free_string (drive->serial); + libhal_free_string (drive->firmware_version); + libhal_free_string (drive->desired_mount_point); + libhal_free_string (drive->mount_filesystem); + libhal_free_string_array (drive->capabilities); + libhal_free_string (drive->partition_scheme); + + free (drive); +} + + +/** Free all resources used by a LibHalVolume object. + * + * @param vol Object to free + */ +void +libhal_volume_free (LibHalVolume *vol) +{ + if (vol == NULL ) + return; + + free (vol->udi); + libhal_free_string (vol->device_file); + libhal_free_string (vol->volume_label); + libhal_free_string (vol->fstype); + libhal_free_string (vol->mount_point); + libhal_free_string (vol->fsversion); + libhal_free_string (vol->uuid); + libhal_free_string (vol->desired_mount_point); + libhal_free_string (vol->mount_filesystem); + libhal_free_string (vol->crypto_backing_volume); + libhal_free_string (vol->storage_device); + + libhal_free_string (vol->partition_scheme); + libhal_free_string (vol->partition_type); + libhal_free_string (vol->partition_label); + libhal_free_string (vol->partition_uuid); + libhal_free_string_array (vol->partition_flags); + + free (vol); +} + + +static char ** +my_strvdup (char **strv) +{ + unsigned int num_elems; + unsigned int i; + char **res; + + for (num_elems = 0; strv[num_elems] != NULL; num_elems++) + ; + + res = calloc (num_elems + 1, sizeof (char*)); + if (res == NULL) + goto out; + + for (i = 0; i < num_elems; i++) + res[i] = strdup (strv[i]); + res[i] = NULL; + +out: + return res; +} + +/* ok, hey, so this is a bit ugly */ + +#define LIBHAL_PROP_EXTRACT_BEGIN if (FALSE) +#define LIBHAL_PROP_EXTRACT_END ; +#define LIBHAL_PROP_EXTRACT_INT(_property_, _where_) else if (strcmp (key, _property_) == 0 && type == LIBHAL_PROPERTY_TYPE_INT32) _where_ = libhal_psi_get_int (&it) +#define LIBHAL_PROP_EXTRACT_UINT64(_property_, _where_) else if (strcmp (key, _property_) == 0 && type == LIBHAL_PROPERTY_TYPE_UINT64) _where_ = libhal_psi_get_uint64 (&it) +#define LIBHAL_PROP_EXTRACT_STRING(_property_, _where_) else if (strcmp (key, _property_) == 0 && type == LIBHAL_PROPERTY_TYPE_STRING) _where_ = (libhal_psi_get_string (&it) != NULL && strlen (libhal_psi_get_string (&it)) > 0) ? strdup (libhal_psi_get_string (&it)) : NULL +#define LIBHAL_PROP_EXTRACT_BOOL(_property_, _where_) else if (strcmp (key, _property_) == 0 && type == LIBHAL_PROPERTY_TYPE_BOOLEAN) _where_ = libhal_psi_get_bool (&it) +#define LIBHAL_PROP_EXTRACT_BOOL_BITFIELD(_property_, _where_, _field_) else if (strcmp (key, _property_) == 0 && type == LIBHAL_PROPERTY_TYPE_BOOLEAN) _where_ |= libhal_psi_get_bool (&it) ? _field_ : 0 +#define LIBHAL_PROP_EXTRACT_STRLIST(_property_, _where_) else if (strcmp (key, _property_) == 0 && type == LIBHAL_PROPERTY_TYPE_STRLIST) _where_ = my_strvdup (libhal_psi_get_strlist (&it)) + +/** Given a UDI for a HAL device of capability 'storage', this + * function retrieves all the relevant properties into convenient + * in-process data structures. + * + * @param hal_ctx libhal context + * @param udi HAL UDI + * @return LibHalDrive object or NULL if UDI is invalid + */ +LibHalDrive * +libhal_drive_from_udi (LibHalContext *hal_ctx, const char *udi) +{ + char *bus_textual; + LibHalDrive *drive; + LibHalPropertySet *properties; + LibHalPropertySetIterator it; + DBusError error; + unsigned int i; + + LIBHAL_CHECK_LIBHALCONTEXT(hal_ctx, NULL); + + drive = NULL; + properties = NULL; + bus_textual = NULL; + + dbus_error_init (&error); + if (!libhal_device_query_capability (hal_ctx, udi, "storage", &error)) + goto error; + + drive = malloc (sizeof (LibHalDrive)); + if (drive == NULL) + goto error; + memset (drive, 0x00, sizeof (LibHalDrive)); + + drive->hal_ctx = hal_ctx; + + drive->udi = strdup (udi); + if (drive->udi == NULL) + goto error; + + properties = libhal_device_get_all_properties (hal_ctx, udi, &error); + if (properties == NULL) + goto error; + + /* we can count on hal to give us all these properties */ + for (libhal_psi_init (&it, properties); libhal_psi_has_more (&it); libhal_psi_next (&it)) { + int type; + char *key; + + type = libhal_psi_get_type (&it); + key = libhal_psi_get_key (&it); + + LIBHAL_PROP_EXTRACT_BEGIN; + + LIBHAL_PROP_EXTRACT_INT ("block.minor", drive->device_minor); + LIBHAL_PROP_EXTRACT_INT ("block.major", drive->device_major); + LIBHAL_PROP_EXTRACT_STRING ("block.device", drive->device_file); + LIBHAL_PROP_EXTRACT_STRING ("storage.bus", bus_textual); + LIBHAL_PROP_EXTRACT_STRING ("storage.vendor", drive->vendor); + LIBHAL_PROP_EXTRACT_STRING ("storage.model", drive->model); + LIBHAL_PROP_EXTRACT_STRING ("storage.drive_type", drive->type_textual); + LIBHAL_PROP_EXTRACT_UINT64 ("storage.size", drive->drive_size); + + LIBHAL_PROP_EXTRACT_STRING ("storage.icon.drive", drive->dedicated_icon_drive); + LIBHAL_PROP_EXTRACT_STRING ("storage.icon.volume", drive->dedicated_icon_volume); + + LIBHAL_PROP_EXTRACT_BOOL ("storage.hotpluggable", drive->is_hotpluggable); + LIBHAL_PROP_EXTRACT_BOOL ("storage.removable", drive->is_removable); + LIBHAL_PROP_EXTRACT_BOOL ("storage.removable.media_available", drive->is_media_detected); + LIBHAL_PROP_EXTRACT_UINT64 ("storage.removable.media_size", drive->drive_media_size); + LIBHAL_PROP_EXTRACT_BOOL ("storage.requires_eject", drive->requires_eject); + + LIBHAL_PROP_EXTRACT_STRING ("storage.partitioning_scheme", drive->partition_scheme); + + LIBHAL_PROP_EXTRACT_STRING ("storage.physical_device", drive->physical_device); + LIBHAL_PROP_EXTRACT_STRING ("storage.firmware_version", drive->firmware_version); + LIBHAL_PROP_EXTRACT_STRING ("storage.serial", drive->serial); + + LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.cdr", drive->cdrom_caps, LIBHAL_DRIVE_CDROM_CAPS_CDR); + LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.cdrw", drive->cdrom_caps, LIBHAL_DRIVE_CDROM_CAPS_CDRW); + LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.dvd", drive->cdrom_caps, LIBHAL_DRIVE_CDROM_CAPS_DVDROM); + LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.dvdplusr", drive->cdrom_caps, LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSR); + LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.dvdplusrw", drive->cdrom_caps, LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSRW); + LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.dvdplusrwdl", drive->cdrom_caps, LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSRWDL); + LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.dvdplusrdl", drive->cdrom_caps, LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSRDL); + LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.dvdr", drive->cdrom_caps, LIBHAL_DRIVE_CDROM_CAPS_DVDR); + LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.dvdrw", drive->cdrom_caps, LIBHAL_DRIVE_CDROM_CAPS_DVDRW); + LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.dvdram", drive->cdrom_caps, LIBHAL_DRIVE_CDROM_CAPS_DVDRAM); + LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.bd", drive->cdrom_caps, LIBHAL_DRIVE_CDROM_CAPS_BDROM); + LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.bdr", drive->cdrom_caps, LIBHAL_DRIVE_CDROM_CAPS_BDR); + LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.bdre", drive->cdrom_caps, LIBHAL_DRIVE_CDROM_CAPS_BDRE); + LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.hddvd", drive->cdrom_caps, LIBHAL_DRIVE_CDROM_CAPS_HDDVDROM); + LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.hddvdr", drive->cdrom_caps, LIBHAL_DRIVE_CDROM_CAPS_HDDVDR); + LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.hddvdrw", drive->cdrom_caps, LIBHAL_DRIVE_CDROM_CAPS_HDDVDRW); + + LIBHAL_PROP_EXTRACT_BOOL ("storage.policy.should_mount", drive->should_mount); + LIBHAL_PROP_EXTRACT_STRING ("storage.policy.desired_mount_point", drive->desired_mount_point); + LIBHAL_PROP_EXTRACT_STRING ("storage.policy.mount_filesystem", drive->mount_filesystem); + + LIBHAL_PROP_EXTRACT_BOOL ("storage.no_partitions_hint", drive->no_partitions_hint); + + LIBHAL_PROP_EXTRACT_STRLIST ("info.capabilities", drive->capabilities); + + LIBHAL_PROP_EXTRACT_END; + } + + if (drive->type_textual != NULL) { + if (strcmp (drive->type_textual, "cdrom") == 0) { + drive->cdrom_caps |= LIBHAL_DRIVE_CDROM_CAPS_CDROM; + drive->type = LIBHAL_DRIVE_TYPE_CDROM; + } else if (strcmp (drive->type_textual, "floppy") == 0) { + drive->type = LIBHAL_DRIVE_TYPE_FLOPPY; + } else if (strcmp (drive->type_textual, "disk") == 0) { + if (drive->is_removable) + drive->type = LIBHAL_DRIVE_TYPE_REMOVABLE_DISK; + else + drive->type = LIBHAL_DRIVE_TYPE_DISK; + } else if (strcmp (drive->type_textual, "tape") == 0) { + drive->type = LIBHAL_DRIVE_TYPE_TAPE; + } else if (strcmp (drive->type_textual, "compact_flash") == 0) { + drive->type = LIBHAL_DRIVE_TYPE_COMPACT_FLASH; + } else if (strcmp (drive->type_textual, "memory_stick") == 0) { + drive->type = LIBHAL_DRIVE_TYPE_MEMORY_STICK; + } else if (strcmp (drive->type_textual, "smart_media") == 0) { + drive->type = LIBHAL_DRIVE_TYPE_SMART_MEDIA; + } else if (strcmp (drive->type_textual, "sd_mmc") == 0) { + drive->type = LIBHAL_DRIVE_TYPE_SD_MMC; + } else if (strcmp (drive->type_textual, "zip") == 0) { + drive->type = LIBHAL_DRIVE_TYPE_ZIP; + } else if (strcmp (drive->type_textual, "jaz") == 0) { + drive->type = LIBHAL_DRIVE_TYPE_JAZ; + } else if (strcmp (drive->type_textual, "flashkey") == 0) { + drive->type = LIBHAL_DRIVE_TYPE_FLASHKEY; + } else { + drive->type = LIBHAL_DRIVE_TYPE_DISK; + } + + } + + if (drive->capabilities != NULL) { + for (i = 0; drive->capabilities[i] != NULL; i++) { + if (strcmp (drive->capabilities[i], "portable_audio_player") == 0) { + drive->type = LIBHAL_DRIVE_TYPE_PORTABLE_AUDIO_PLAYER; + break; + } else if (strcmp (drive->capabilities[i], "camera") == 0) { + drive->type = LIBHAL_DRIVE_TYPE_CAMERA; + break; + } + } + } + + if (bus_textual != NULL) { + if (strcmp (bus_textual, "usb") == 0) { + drive->bus = LIBHAL_DRIVE_BUS_USB; + } else if (strcmp (bus_textual, "ieee1394") == 0) { + drive->bus = LIBHAL_DRIVE_BUS_IEEE1394; + } else if (strcmp (bus_textual, "ide") == 0) { + drive->bus = LIBHAL_DRIVE_BUS_IDE; + } else if (strcmp (bus_textual, "scsi") == 0) { + drive->bus = LIBHAL_DRIVE_BUS_SCSI; + } else if (strcmp (bus_textual, "ccw") == 0) { + drive->bus = LIBHAL_DRIVE_BUS_CCW; + } + } + + libhal_free_string (bus_textual); + libhal_free_property_set (properties); + + return drive; + +error: + LIBHAL_FREE_DBUS_ERROR(&error); + libhal_free_string (bus_textual); + libhal_free_property_set (properties); + libhal_drive_free (drive); + return NULL; +} + +const char * +libhal_volume_get_storage_device_udi (LibHalVolume *volume) +{ + return volume->storage_device; +} + +const char *libhal_drive_get_physical_device_udi (LibHalDrive *drive) +{ + return drive->physical_device; +} + +dbus_bool_t +libhal_drive_requires_eject (LibHalDrive *drive) +{ + return drive->requires_eject; +} + +/** Given a UDI for a LIBHAL device of capability 'volume', this + * function retrieves all the relevant properties into convenient + * in-process data structures. + * + * @param hal_ctx libhal context + * @param udi HAL UDI + * @return LibHalVolume object or NULL if UDI is invalid + */ +LibHalVolume * +libhal_volume_from_udi (LibHalContext *hal_ctx, const char *udi) +{ + char *disc_type_textual; + char *vol_fsusage_textual; + LibHalVolume *vol; + LibHalPropertySet *properties; + LibHalPropertySetIterator it; + DBusError error; + + LIBHAL_CHECK_LIBHALCONTEXT(hal_ctx, NULL); + + vol = NULL; + properties = NULL; + disc_type_textual = NULL; + vol_fsusage_textual = NULL; + + dbus_error_init (&error); + if (!libhal_device_query_capability (hal_ctx, udi, "volume", &error)) + goto error; + + vol = malloc (sizeof (LibHalVolume)); + if (vol == NULL) + goto error; + memset (vol, 0x00, sizeof (LibHalVolume)); + + vol->udi = strdup (udi); + + properties = libhal_device_get_all_properties (hal_ctx, udi, &error); + if (properties == NULL) + goto error; + + /* we can count on hal to give us all these properties */ + for (libhal_psi_init (&it, properties); libhal_psi_has_more (&it); libhal_psi_next (&it)) { + int type; + char *key; + + type = libhal_psi_get_type (&it); + key = libhal_psi_get_key (&it); + + LIBHAL_PROP_EXTRACT_BEGIN; + + LIBHAL_PROP_EXTRACT_BOOL ("volume.is_partition", vol->is_partition); + LIBHAL_PROP_EXTRACT_INT ("volume.partition.number", vol->partition_number); + LIBHAL_PROP_EXTRACT_STRING ("volume.partition.scheme", vol->partition_scheme); + LIBHAL_PROP_EXTRACT_STRING ("volume.partition.type", vol->partition_type); + LIBHAL_PROP_EXTRACT_STRING ("volume.partition.label", vol->partition_label); + LIBHAL_PROP_EXTRACT_STRING ("volume.partition.uuid", vol->partition_uuid); + LIBHAL_PROP_EXTRACT_STRLIST ("volume.partition.flags", vol->partition_flags); + + LIBHAL_PROP_EXTRACT_UINT64 ("volume.partition.start", vol->partition_start_offset); + LIBHAL_PROP_EXTRACT_UINT64 ("volume.partition.media_size", vol->partition_media_size); + LIBHAL_PROP_EXTRACT_INT ("volume.partition.msdos_part_table_type", vol->msdos_part_table_type); + LIBHAL_PROP_EXTRACT_UINT64 ("volume.partition.msdos_part_table_start", vol->msdos_part_table_start); + LIBHAL_PROP_EXTRACT_UINT64 ("volume.partition.msdos_part_table_size", vol->msdos_part_table_size); + + LIBHAL_PROP_EXTRACT_INT ("block.minor", vol->device_minor); + LIBHAL_PROP_EXTRACT_INT ("block.major", vol->device_major); + LIBHAL_PROP_EXTRACT_STRING ("block.device", vol->device_file); + + LIBHAL_PROP_EXTRACT_STRING ("block.storage_device", vol->storage_device); + + LIBHAL_PROP_EXTRACT_STRING ("volume.crypto_luks.clear.backing_volume", vol->crypto_backing_volume); + + LIBHAL_PROP_EXTRACT_INT ("volume.block_size", vol->block_size); + LIBHAL_PROP_EXTRACT_INT ("volume.num_blocks", vol->num_blocks); + LIBHAL_PROP_EXTRACT_UINT64 ("volume.size", vol->volume_size); + LIBHAL_PROP_EXTRACT_STRING ("volume.label", vol->volume_label); + LIBHAL_PROP_EXTRACT_STRING ("volume.mount_point", vol->mount_point); + LIBHAL_PROP_EXTRACT_STRING ("volume.fstype", vol->fstype); + LIBHAL_PROP_EXTRACT_STRING ("volume.fsversion", vol->fsversion); + LIBHAL_PROP_EXTRACT_BOOL ("volume.is_mounted", vol->is_mounted); + LIBHAL_PROP_EXTRACT_BOOL ("volume.is_mounted_read_only", vol->is_mounted_read_only); + LIBHAL_PROP_EXTRACT_STRING ("volume.fsusage", vol_fsusage_textual); + LIBHAL_PROP_EXTRACT_STRING ("volume.uuid", vol->uuid); + + LIBHAL_PROP_EXTRACT_BOOL ("volume.ignore", vol->ignore_volume); + + LIBHAL_PROP_EXTRACT_BOOL ("volume.is_disc", vol->is_disc); + LIBHAL_PROP_EXTRACT_STRING ("volume.disc.type", disc_type_textual); + LIBHAL_PROP_EXTRACT_BOOL ("volume.disc.has_audio", vol->disc_has_audio); + LIBHAL_PROP_EXTRACT_BOOL ("volume.disc.has_data", vol->disc_has_data); + LIBHAL_PROP_EXTRACT_BOOL ("volume.disc.is_appendable", vol->disc_is_appendable); + LIBHAL_PROP_EXTRACT_BOOL ("volume.disc.is_blank", vol->disc_is_blank); + LIBHAL_PROP_EXTRACT_BOOL ("volume.disc.is_rewritable", vol->disc_is_rewritable); + LIBHAL_PROP_EXTRACT_UINT64 ("volume.disc.capacity", vol->disc_capacity); + + LIBHAL_PROP_EXTRACT_BOOL ("volume.policy.should_mount", vol->should_mount); + LIBHAL_PROP_EXTRACT_STRING ("volume.policy.desired_mount_point", vol->desired_mount_point); + LIBHAL_PROP_EXTRACT_STRING ("volume.policy.mount_filesystem", vol->mount_filesystem); + + LIBHAL_PROP_EXTRACT_END; + } + + if (disc_type_textual != NULL) { + if (strcmp (disc_type_textual, "cd_rom") == 0) { + vol->disc_type = LIBHAL_VOLUME_DISC_TYPE_CDROM; + } else if (strcmp (disc_type_textual, "cd_r") == 0) { + vol->disc_type = LIBHAL_VOLUME_DISC_TYPE_CDR; + } else if (strcmp (disc_type_textual, "cd_rw") == 0) { + vol->disc_type = LIBHAL_VOLUME_DISC_TYPE_CDRW; + } else if (strcmp (disc_type_textual, "dvd_rom") == 0) { + vol->disc_type = LIBHAL_VOLUME_DISC_TYPE_DVDROM; + } else if (strcmp (disc_type_textual, "dvd_ram") == 0) { + vol->disc_type = LIBHAL_VOLUME_DISC_TYPE_DVDRAM; + } else if (strcmp (disc_type_textual, "dvd_r") == 0) { + vol->disc_type = LIBHAL_VOLUME_DISC_TYPE_DVDR; + } else if (strcmp (disc_type_textual, "dvd_rw") == 0) { + vol->disc_type = LIBHAL_VOLUME_DISC_TYPE_DVDRW; + } else if (strcmp (disc_type_textual, "dvd_plus_r") == 0) { + vol->disc_type = LIBHAL_VOLUME_DISC_TYPE_DVDPLUSR; + } else if (strcmp (disc_type_textual, "dvd_plus_rw") == 0) { + vol->disc_type = LIBHAL_VOLUME_DISC_TYPE_DVDPLUSRW; + } else if (strcmp (disc_type_textual, "dvd_plus_r_dl") == 0) { + vol->disc_type = LIBHAL_VOLUME_DISC_TYPE_DVDPLUSR_DL; + } else if (strcmp (disc_type_textual, "bd_rom") == 0) { + vol->disc_type = LIBHAL_VOLUME_DISC_TYPE_BDROM; + } else if (strcmp (disc_type_textual, "bd_r") == 0) { + vol->disc_type = LIBHAL_VOLUME_DISC_TYPE_BDR; + } else if (strcmp (disc_type_textual, "bd_re") == 0) { + vol->disc_type = LIBHAL_VOLUME_DISC_TYPE_BDRE; + } else if (strcmp (disc_type_textual, "hddvd_rom") == 0) { + vol->disc_type = LIBHAL_VOLUME_DISC_TYPE_HDDVDROM; + } else if (strcmp (disc_type_textual, "hddvd_r") == 0) { + vol->disc_type = LIBHAL_VOLUME_DISC_TYPE_HDDVDR; + } else if (strcmp (disc_type_textual, "hddvd_rw") == 0) { + vol->disc_type = LIBHAL_VOLUME_DISC_TYPE_HDDVDRW; + } + } + + vol->fsusage = LIBHAL_VOLUME_USAGE_UNKNOWN; + if (vol_fsusage_textual != NULL) { + if (strcmp (vol_fsusage_textual, "filesystem") == 0) { + vol->fsusage = LIBHAL_VOLUME_USAGE_MOUNTABLE_FILESYSTEM; + } else if (strcmp (vol_fsusage_textual, "partitiontable") == 0) { + vol->fsusage = LIBHAL_VOLUME_USAGE_PARTITION_TABLE; + } else if (strcmp (vol_fsusage_textual, "raid") == 0) { + vol->fsusage = LIBHAL_VOLUME_USAGE_RAID_MEMBER; + } else if (strcmp (vol_fsusage_textual, "crypto") == 0) { + vol->fsusage = LIBHAL_VOLUME_USAGE_CRYPTO; + } else if (strcmp (vol_fsusage_textual, "other") == 0) { + vol->fsusage = LIBHAL_VOLUME_USAGE_OTHER; + } else { + vol->fsusage = LIBHAL_VOLUME_USAGE_UNKNOWN; + } + } + + libhal_free_string (vol_fsusage_textual); + libhal_free_string (disc_type_textual); + libhal_free_property_set (properties); + return vol; +error: + if (dbus_error_is_set (&error)) { + dbus_error_free (&error); + } + libhal_free_string (vol_fsusage_textual); + libhal_free_string (disc_type_textual); + libhal_free_property_set (properties); + libhal_volume_free (vol); + return NULL; +} + + +/** If the volume is on a drive with a MSDOS style partition table, return + * the partition table id. + * + * @param volume Volume object + * @return The partition type or -1 if volume is not + * a partition or the media the volume stems from + * isn't partition with a MS DOS style table + */ +int +libhal_volume_get_msdos_part_table_type (LibHalVolume *volume) +{ + return volume->msdos_part_table_type; +} + +/** If the volume is on a drive with a MSDOS style partition table, return + * the partition start offset according to the partition table. + * + * @param volume Volume object + * @return The partition start offset or -1 if volume isnt + * a partition or the media the volume stems from + * isn't partition with a MS DOS style table + */ +dbus_uint64_t +libhal_volume_get_msdos_part_table_start (LibHalVolume *volume) +{ + return volume->msdos_part_table_start; +} + +/** If the volume is on a drive with a MSDOS style partition table, return + * the partition size according to the partition table. + * + * @param volume Volume object + * @return The partition size or -1 if volume is not + * a partition or the media the volume stems from + * isn't partition with a MS DOS style table + */ +dbus_uint64_t +libhal_volume_get_msdos_part_table_size (LibHalVolume *volume) +{ + return volume->msdos_part_table_size; +} + +/***********************************************************************/ + +/** Get the drive object that either is (when given e.g. /dev/sdb) or contains + * (when given e.g. /dev/sdb1) the given device file. + * + * @param hal_ctx libhal context to use + * @param device_file Name of special device file, e.g. '/dev/hdc' + * @return LibHalDrive object or NULL if it doesn't exist + */ +LibHalDrive * +libhal_drive_from_device_file (LibHalContext *hal_ctx, const char *device_file) +{ + int i; + char **hal_udis; + int num_hal_udis; + LibHalDrive *result; + char *found_udi; + DBusError error; + + LIBHAL_CHECK_LIBHALCONTEXT(hal_ctx, NULL); + + result = NULL; + found_udi = NULL; + + dbus_error_init (&error); + if ((hal_udis = libhal_manager_find_device_string_match (hal_ctx, "block.device", + device_file, &num_hal_udis, &error)) == NULL) { + LIBHAL_FREE_DBUS_ERROR(&error); + goto out; + } + + for (i = 0; i < num_hal_udis; i++) { + char *udi; + char *storage_udi; + DBusError err1; + DBusError err2; + udi = hal_udis[i]; + + dbus_error_init (&err1); + dbus_error_init (&err2); + if (libhal_device_query_capability (hal_ctx, udi, "volume", &err1)) { + + storage_udi = libhal_device_get_property_string (hal_ctx, udi, "block.storage_device", &err1); + if (storage_udi == NULL) + continue; + found_udi = strdup (storage_udi); + libhal_free_string (storage_udi); + break; + } else if (libhal_device_query_capability (hal_ctx, udi, "storage", &err2)) { + found_udi = strdup (udi); + } + LIBHAL_FREE_DBUS_ERROR(&err1); + LIBHAL_FREE_DBUS_ERROR(&err2); + } + + libhal_free_string_array (hal_udis); + + if (found_udi != NULL) + result = libhal_drive_from_udi (hal_ctx, found_udi); + + free (found_udi); +out: + return result; +} + + +/** Get the volume object for a given device file. + * + * @param hal_ctx libhal context to use + * @param device_file Name of special device file, e.g. '/dev/hda5' + * @return LibHalVolume object or NULL if it doesn't exist + */ +LibHalVolume * +libhal_volume_from_device_file (LibHalContext *hal_ctx, const char *device_file) +{ + int i; + char **hal_udis; + int num_hal_udis; + LibHalVolume *result; + char *found_udi; + DBusError error; + + LIBHAL_CHECK_LIBHALCONTEXT(hal_ctx, NULL); + + result = NULL; + found_udi = NULL; + + dbus_error_init (&error); + if ((hal_udis = libhal_manager_find_device_string_match (hal_ctx, "block.device", + device_file, &num_hal_udis, &error)) == NULL) + goto out; + + for (i = 0; i < num_hal_udis; i++) { + char *udi; + udi = hal_udis[i]; + if (libhal_device_query_capability (hal_ctx, udi, "volume", &error)) { + found_udi = strdup (udi); + break; + } + } + + libhal_free_string_array (hal_udis); + + if (found_udi != NULL) + result = libhal_volume_from_udi (hal_ctx, found_udi); + + free (found_udi); +out: + LIBHAL_FREE_DBUS_ERROR(&error); + return result; +} + +dbus_uint64_t +libhal_volume_get_size (LibHalVolume *volume) +{ + if (volume->volume_size > 0) + return volume->volume_size; + else + return ((dbus_uint64_t)volume->block_size) * ((dbus_uint64_t)volume->num_blocks); +} + +dbus_uint64_t +libhal_volume_get_disc_capacity (LibHalVolume *volume) +{ + return volume->disc_capacity; +} + + +dbus_bool_t +libhal_drive_is_hotpluggable (LibHalDrive *drive) +{ + return drive->is_hotpluggable; +} + +dbus_bool_t +libhal_drive_uses_removable_media (LibHalDrive *drive) +{ + return drive->is_removable; +} + +dbus_bool_t +libhal_drive_is_media_detected (LibHalDrive *drive) +{ + return drive->is_media_detected; +} + +dbus_uint64_t +libhal_drive_get_size (LibHalDrive *drive) +{ + return drive->drive_size; +} + +dbus_uint64_t +libhal_drive_get_media_size (LibHalDrive *drive) +{ + return drive->drive_media_size; +} + +const char * +libhal_drive_get_partition_scheme (LibHalDrive *drive) +{ + return drive->partition_scheme; +} + + +LibHalDriveType +libhal_drive_get_type (LibHalDrive *drive) +{ + return drive->type; +} + +LibHalDriveBus +libhal_drive_get_bus (LibHalDrive *drive) +{ + return drive->bus; +} + +LibHalDriveCdromCaps +libhal_drive_get_cdrom_caps (LibHalDrive *drive) +{ + return drive->cdrom_caps; +} + +unsigned int +libhal_drive_get_device_major (LibHalDrive *drive) +{ + return drive->device_major; +} + +unsigned int +libhal_drive_get_device_minor (LibHalDrive *drive) +{ + return drive->device_minor; +} + +const char * +libhal_drive_get_type_textual (LibHalDrive *drive) +{ + return drive->type_textual; +} + +const char * +libhal_drive_get_device_file (LibHalDrive *drive) +{ + return drive->device_file; +} + +const char * +libhal_drive_get_udi (LibHalDrive *drive) +{ + return drive->udi; +} + +const char * +libhal_drive_get_serial (LibHalDrive *drive) +{ + return drive->serial; +} + +const char * +libhal_drive_get_firmware_version (LibHalDrive *drive) +{ + return drive->firmware_version; +} + +const char * +libhal_drive_get_model (LibHalDrive *drive) +{ + return drive->model; +} + +const char * +libhal_drive_get_vendor (LibHalDrive *drive) +{ + return drive->vendor; +} + +/*****************************************************************************/ + +const char * +libhal_volume_get_udi (LibHalVolume *volume) +{ + return volume->udi; +} + +const char * +libhal_volume_get_device_file (LibHalVolume *volume) +{ + return volume->device_file; +} + +unsigned int libhal_volume_get_device_major (LibHalVolume *volume) +{ + return volume->device_major; +} + +unsigned int libhal_volume_get_device_minor (LibHalVolume *volume) +{ + return volume->device_minor; +} + +const char * +libhal_volume_get_fstype (LibHalVolume *volume) +{ + return volume->fstype; +} + +const char * +libhal_volume_get_fsversion (LibHalVolume *volume) +{ + return volume->fsversion; +} + +LibHalVolumeUsage +libhal_volume_get_fsusage (LibHalVolume *volume) +{ + return volume->fsusage; +} + +dbus_bool_t +libhal_volume_is_mounted (LibHalVolume *volume) +{ + return volume->is_mounted; +} + +dbus_bool_t +libhal_volume_is_mounted_read_only (LibHalVolume *volume) +{ + return volume->is_mounted_read_only; +} + +dbus_bool_t +libhal_volume_is_partition (LibHalVolume *volume) +{ + return volume->is_partition; +} + +dbus_bool_t +libhal_volume_is_disc (LibHalVolume *volume) +{ + return volume->is_disc; +} + +unsigned int +libhal_volume_get_partition_number (LibHalVolume *volume) +{ + return volume->partition_number; +} + +const char * +libhal_volume_get_partition_scheme (LibHalVolume *volume) +{ + return volume->partition_scheme; +} + +const char * +libhal_volume_get_partition_type (LibHalVolume *volume) +{ + return volume->partition_type; +} + +const char * +libhal_volume_get_partition_label (LibHalVolume *volume) +{ + return volume->partition_label; +} + +const char * +libhal_volume_get_partition_uuid (LibHalVolume *volume) +{ + return volume->partition_uuid; +} + +const char ** +libhal_volume_get_partition_flags (LibHalVolume *volume) +{ + return (const char **) volume->partition_flags; +} + + +dbus_uint64_t +libhal_volume_get_partition_start_offset (LibHalVolume *volume) +{ + return volume->partition_start_offset; +} + +dbus_uint64_t +libhal_volume_get_partition_media_size (LibHalVolume *volume) +{ + return volume->partition_media_size; +} + +const char * +libhal_volume_get_label (LibHalVolume *volume) +{ + return volume->volume_label; +} + +const char * +libhal_volume_get_mount_point (LibHalVolume *volume) +{ + return volume->mount_point; +} + +const char * +libhal_volume_get_uuid (LibHalVolume *volume) +{ + return volume->uuid; +} + +dbus_bool_t +libhal_volume_disc_has_audio (LibHalVolume *volume) +{ + return volume->disc_has_audio; +} + +dbus_bool_t +libhal_volume_disc_has_data (LibHalVolume *volume) +{ + return volume->disc_has_data; +} + +dbus_bool_t +libhal_volume_disc_is_blank (LibHalVolume *volume) +{ + return volume->disc_is_blank; +} + +dbus_bool_t +libhal_volume_disc_is_rewritable (LibHalVolume *volume) +{ + return volume->disc_is_rewritable; +} + +dbus_bool_t +libhal_volume_disc_is_appendable (LibHalVolume *volume) +{ + return volume->disc_is_appendable; +} + +LibHalVolumeDiscType +libhal_volume_get_disc_type (LibHalVolume *volume) +{ + return volume->disc_type; +} + +dbus_bool_t +libhal_volume_should_ignore (LibHalVolume *volume) +{ + return volume->ignore_volume; +} + +char ** +libhal_drive_find_all_volumes (LibHalContext *hal_ctx, LibHalDrive *drive, int *num_volumes) +{ + int i; + char **udis; + int num_udis; + const char *drive_udi; + char **result; + DBusError error; + + LIBHAL_CHECK_LIBHALCONTEXT(hal_ctx, NULL); + + udis = NULL; + result = NULL; + *num_volumes = 0; + + drive_udi = libhal_drive_get_udi (drive); + if (drive_udi == NULL) + goto out; + + /* get initial list... */ + dbus_error_init (&error); + if ((udis = libhal_manager_find_device_string_match (hal_ctx, "block.storage_device", + drive_udi, &num_udis, &error)) == NULL) { + LIBHAL_FREE_DBUS_ERROR(&error); + goto out; + } + + result = malloc (sizeof (char *) * num_udis); + if (result == NULL) + goto out; + + /* ...and filter out the single UDI that is the drive itself */ + for (i = 0; i < num_udis; i++) { + if (strcmp (udis[i], drive_udi) == 0) + continue; + result[*num_volumes] = strdup (udis[i]); + *num_volumes = (*num_volumes) + 1; + } + /* set last element (above removed UDI) to NULL for libhal_free_string_array()*/ + result[*num_volumes] = NULL; + +out: + libhal_free_string_array (udis); + return result; +} + +const char * +libhal_volume_crypto_get_backing_volume_udi (LibHalVolume *volume) +{ + return volume->crypto_backing_volume; +} + +char * +libhal_volume_crypto_get_clear_volume_udi (LibHalContext *hal_ctx, LibHalVolume *volume) +{ + DBusError error; + char **clear_devices; + int num_clear_devices; + char *result; + + result = NULL; + + LIBHAL_CHECK_LIBHALCONTEXT (hal_ctx, NULL); + + dbus_error_init (&error); + clear_devices = libhal_manager_find_device_string_match (hal_ctx, + "volume.crypto_luks.clear.backing_volume", + volume->udi, + &num_clear_devices, + &error); + if (clear_devices != NULL) { + + if (num_clear_devices >= 1) { + result = strdup (clear_devices[0]); + } + libhal_free_string_array (clear_devices); + } + + return result; +} + + +/*************************************************************************/ + +char * +libhal_drive_policy_default_get_mount_root (LibHalContext *hal_ctx) +{ + char *result; + DBusError error; + + LIBHAL_CHECK_LIBHALCONTEXT(hal_ctx, NULL); + + dbus_error_init (&error); + if ((result = libhal_device_get_property_string (hal_ctx, "/org/freedesktop/Hal/devices/computer", + "storage.policy.default.mount_root", &error)) == NULL) + LIBHAL_FREE_DBUS_ERROR(&error); + + return result; +} + +dbus_bool_t +libhal_drive_policy_default_use_managed_keyword (LibHalContext *hal_ctx) +{ + dbus_bool_t result; + DBusError error; + + LIBHAL_CHECK_LIBHALCONTEXT(hal_ctx, FALSE); + + dbus_error_init (&error); + if ((result = libhal_device_get_property_bool (hal_ctx, "/org/freedesktop/Hal/devices/computer", + "storage.policy.default.use_managed_keyword", &error)) == FALSE) + LIBHAL_FREE_DBUS_ERROR(&error); + + return result; +} + +char * +libhal_drive_policy_default_get_managed_keyword_primary (LibHalContext *hal_ctx) +{ + char *result; + DBusError error; + + LIBHAL_CHECK_LIBHALCONTEXT(hal_ctx, NULL); + + dbus_error_init (&error); + if ((result = libhal_device_get_property_string (hal_ctx, "/org/freedesktop/Hal/devices/computer", + "storage.policy.default.managed_keyword.primary", &error)) == NULL) + LIBHAL_FREE_DBUS_ERROR(&error); + + return result; +} + +char * +libhal_drive_policy_default_get_managed_keyword_secondary (LibHalContext *hal_ctx) +{ + char *result; + DBusError error; + + LIBHAL_CHECK_LIBHALCONTEXT(hal_ctx, NULL); + + dbus_error_init (&error); + if ((result = libhal_device_get_property_string (hal_ctx, "/org/freedesktop/Hal/devices/computer", + "storage.policy.default.managed_keyword.secondary", &error)) == NULL) + LIBHAL_FREE_DBUS_ERROR(&error); + + return result; +} + +/*************************************************************************/ + +dbus_bool_t +libhal_drive_policy_is_mountable (LibHalDrive *drive, LibHalStoragePolicy *policy) +{ + printf ("should_mount=%d, no_partitions_hint=%d\n", drive->should_mount, drive->no_partitions_hint); + + return drive->should_mount && drive->no_partitions_hint; +} + +const char * +libhal_drive_policy_get_desired_mount_point (LibHalDrive *drive, LibHalStoragePolicy *policy) +{ + return drive->desired_mount_point; +} + +/* safely strcat() at most the remaining space in 'dst' */ +#define strcat_len(dst, src, dstmaxlen) do { \ + dst[dstmaxlen - 1] = '\0'; \ + strncat (dst, src, dstmaxlen - strlen (dst) - 1); \ +} while(0) + + +static void +mopts_collect (LibHalContext *hal_ctx, const char *namespace, int namespace_len, + const char *udi, char *options_string, size_t options_max_len, dbus_bool_t only_collect_imply_opts) +{ + LibHalPropertySet *properties; + LibHalPropertySetIterator it; + DBusError error; + + if(hal_ctx == 0) { + fprintf (stderr,"%s %d : LibHalContext *ctx is NULL\n",__FILE__, __LINE__); + return; + } + + dbus_error_init (&error); + + /* first collect from root computer device */ + properties = libhal_device_get_all_properties (hal_ctx, udi, &error); + if (properties == NULL ) { + LIBHAL_FREE_DBUS_ERROR(&error); + return; + } + + for (libhal_psi_init (&it, properties); libhal_psi_has_more (&it); libhal_psi_next (&it)) { + int type; + char *key; + + type = libhal_psi_get_type (&it); + key = libhal_psi_get_key (&it); + if (libhal_psi_get_type (&it) == LIBHAL_PROPERTY_TYPE_BOOLEAN && + strncmp (key, namespace, namespace_len - 1) == 0) { + const char *option = key + namespace_len - 1; + char *location; + dbus_bool_t is_imply_opt; + + is_imply_opt = FALSE; + if (strcmp (option, "user") == 0 || + strcmp (option, "users") == 0 || + strcmp (option, "defaults") == 0 || + strcmp (option, "pamconsole") == 0) + is_imply_opt = TRUE; + + + if (only_collect_imply_opts) { + if (!is_imply_opt) + continue; + } else { + if (is_imply_opt) + continue; + } + + if (libhal_psi_get_bool (&it)) { + /* see if option is already there */ + location = strstr (options_string, option); + if (location == NULL) { + if (strlen (options_string) > 0) + strcat_len (options_string, ",", options_max_len); + strcat_len (options_string, option, options_max_len); + } + } else { + /* remove option if already there */ + location = strstr (options_string, option); + if (location != NULL) { + char *end; + + end = strchr (location, ','); + if (end == NULL) { + location[0] = '\0'; + } else { + strcpy (location, end + 1); /* skip the extra comma */ + } + } + + } + } + } + + libhal_free_property_set (properties); +} + + +const char * +libhal_drive_policy_get_mount_options (LibHalDrive *drive, LibHalStoragePolicy *policy) +{ + const char *result; + char stor_mount_option_default_begin[] = "storage.policy.default.mount_option."; + char stor_mount_option_begin[] = "storage.policy.mount_option."; + + result = NULL; + drive->mount_options[0] = '\0'; + + /* collect options != ('pamconsole', 'user', 'users', 'defaults' options that imply other options) */ + mopts_collect (drive->hal_ctx, stor_mount_option_default_begin, sizeof (stor_mount_option_default_begin), + "/org/freedesktop/Hal/devices/computer", drive->mount_options, MOUNT_OPTIONS_SIZE, TRUE); + mopts_collect (drive->hal_ctx, stor_mount_option_begin, sizeof (stor_mount_option_begin), + drive->udi, drive->mount_options, MOUNT_OPTIONS_SIZE, TRUE); + /* ensure ('pamconsole', 'user', 'users', 'defaults' options that imply other options), are first */ + mopts_collect (drive->hal_ctx, stor_mount_option_default_begin, sizeof (stor_mount_option_default_begin), + "/org/freedesktop/Hal/devices/computer", drive->mount_options, MOUNT_OPTIONS_SIZE, FALSE); + mopts_collect (drive->hal_ctx, stor_mount_option_begin, sizeof (stor_mount_option_begin), + drive->udi, drive->mount_options, MOUNT_OPTIONS_SIZE, FALSE); + + result = drive->mount_options; + + return result; +} + +const char * +libhal_drive_policy_get_mount_fs (LibHalDrive *drive, LibHalStoragePolicy *policy) +{ + return drive->mount_filesystem; +} + + +dbus_bool_t +libhal_volume_policy_is_mountable (LibHalDrive *drive, LibHalVolume *volume, LibHalStoragePolicy *policy) +{ + return drive->should_mount && volume->should_mount; +} + +const char *libhal_volume_policy_get_desired_mount_point (LibHalDrive *drive, LibHalVolume *volume, LibHalStoragePolicy *policy) +{ + return volume->desired_mount_point; +} + +const char *libhal_volume_policy_get_mount_options (LibHalDrive *drive, LibHalVolume *volume, LibHalStoragePolicy *policy) +{ + const char *result; + char stor_mount_option_default_begin[] = "storage.policy.default.mount_option."; + char vol_mount_option_begin[] = "volume.policy.mount_option."; + + result = NULL; + volume->mount_options[0] = '\0'; + + /* ensure ('pamconsole', 'user', 'users', 'defaults' options that imply other options), are first */ + mopts_collect (drive->hal_ctx, stor_mount_option_default_begin, sizeof (stor_mount_option_default_begin), + "/org/freedesktop/Hal/devices/computer", volume->mount_options, MOUNT_OPTIONS_SIZE, TRUE); + mopts_collect (drive->hal_ctx, vol_mount_option_begin, sizeof (vol_mount_option_begin), + volume->udi, volume->mount_options, MOUNT_OPTIONS_SIZE, TRUE); + /* collect options != ('pamconsole', 'user', 'users', 'defaults' options that imply other options) */ + mopts_collect (drive->hal_ctx, stor_mount_option_default_begin, sizeof (stor_mount_option_default_begin), + "/org/freedesktop/Hal/devices/computer", volume->mount_options, MOUNT_OPTIONS_SIZE, FALSE); + mopts_collect (drive->hal_ctx, vol_mount_option_begin, sizeof (vol_mount_option_begin), + volume->udi, volume->mount_options, MOUNT_OPTIONS_SIZE, FALSE); + + result = volume->mount_options; + + return result; +} + +const char *libhal_volume_policy_get_mount_fs (LibHalDrive *drive, LibHalVolume *volume, LibHalStoragePolicy *policy) +{ + return volume->mount_filesystem; +} + +dbus_bool_t +libhal_drive_no_partitions_hint (LibHalDrive *drive) +{ + return drive->no_partitions_hint; +} + +/** @} */ diff --git a/usr/src/lib/hal/libhal-storage/common/libhal-storage.h b/usr/src/lib/hal/libhal-storage/common/libhal-storage.h new file mode 100644 index 0000000000..c88a389feb --- /dev/null +++ b/usr/src/lib/hal/libhal-storage/common/libhal-storage.h @@ -0,0 +1,362 @@ +/*************************************************************************** + * CVSID: $Id$ + * + * libhal-storage.h : HAL convenience library for storage devices and volumes + * + * Copyright (C) 2004 Red Hat, Inc. + * + * Author: David Zeuthen <davidz@redhat.com> + * + * Licensed under the Academic Free License version 2.1 + * + * This program 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 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + **************************************************************************/ + +#ifndef LIBHAL_STORAGE_H +#define LIBHAL_STORAGE_H + +#include <libhal.h> + +#if defined(__cplusplus) +extern "C" { +#if 0 +} /* shut up emacs indenting */ +#endif +#endif + +struct LibHalDrive_s; +typedef struct LibHalDrive_s LibHalDrive; +struct LibHalVolume_s; +typedef struct LibHalVolume_s LibHalVolume; +struct LibHalStoragePolicy_s; +typedef struct LibHalStoragePolicy_s LibHalStoragePolicy; + + +typedef enum { + LIBHAL_STORAGE_ICON_DRIVE_REMOVABLE_DISK = 0x10000, + LIBHAL_STORAGE_ICON_DRIVE_REMOVABLE_DISK_IDE = 0x10001, + LIBHAL_STORAGE_ICON_DRIVE_REMOVABLE_DISK_SCSI = 0x10002, + LIBHAL_STORAGE_ICON_DRIVE_REMOVABLE_DISK_USB = 0x10003, + LIBHAL_STORAGE_ICON_DRIVE_REMOVABLE_DISK_IEEE1394 = 0x10004, + LIBHAL_STORAGE_ICON_DRIVE_DISK = 0x10100, + LIBHAL_STORAGE_ICON_DRIVE_DISK_IDE = 0x10101, + LIBHAL_STORAGE_ICON_DRIVE_DISK_SCSI = 0x10102, + LIBHAL_STORAGE_ICON_DRIVE_DISK_USB = 0x10103, + LIBHAL_STORAGE_ICON_DRIVE_DISK_IEEE1394 = 0x10104, + LIBHAL_STORAGE_ICON_DRIVE_CDROM = 0x10200, + LIBHAL_STORAGE_ICON_DRIVE_CDROM_IDE = 0x10201, + LIBHAL_STORAGE_ICON_DRIVE_CDROM_SCSI = 0x10202, + LIBHAL_STORAGE_ICON_DRIVE_CDROM_USB = 0x10203, + LIBHAL_STORAGE_ICON_DRIVE_CDROM_IEEE1394 = 0x10204, + LIBHAL_STORAGE_ICON_DRIVE_FLOPPY = 0x10300, + LIBHAL_STORAGE_ICON_DRIVE_FLOPPY_IDE = 0x10301, + LIBHAL_STORAGE_ICON_DRIVE_FLOPPY_SCSI = 0x10302, + LIBHAL_STORAGE_ICON_DRIVE_FLOPPY_USB = 0x10303, + LIBHAL_STORAGE_ICON_DRIVE_FLOPPY_IEEE1394 = 0x10304, + LIBHAL_STORAGE_ICON_DRIVE_TAPE = 0x10400, + LIBHAL_STORAGE_ICON_DRIVE_COMPACT_FLASH = 0x10500, + LIBHAL_STORAGE_ICON_DRIVE_MEMORY_STICK = 0x10600, + LIBHAL_STORAGE_ICON_DRIVE_SMART_MEDIA = 0x10700, + LIBHAL_STORAGE_ICON_DRIVE_SD_MMC = 0x10800, + LIBHAL_STORAGE_ICON_DRIVE_CAMERA = 0x10900, + LIBHAL_STORAGE_ICON_DRIVE_PORTABLE_AUDIO_PLAYER = 0x10a00, + LIBHAL_STORAGE_ICON_DRIVE_ZIP = 0x10b00, + LIBHAL_STORAGE_ICON_DRIVE_JAZ = 0x10c00, + LIBHAL_STORAGE_ICON_DRIVE_FLASH_KEY = 0x10d00, + + LIBHAL_STORAGE_ICON_VOLUME_REMOVABLE_DISK = 0x20000, + LIBHAL_STORAGE_ICON_VOLUME_REMOVABLE_DISK_IDE = 0x20001, + LIBHAL_STORAGE_ICON_VOLUME_REMOVABLE_DISK_SCSI = 0x20002, + LIBHAL_STORAGE_ICON_VOLUME_REMOVABLE_DISK_USB = 0x20003, + LIBHAL_STORAGE_ICON_VOLUME_REMOVABLE_DISK_IEEE1394 = 0x20004, + LIBHAL_STORAGE_ICON_VOLUME_DISK = 0x20100, + LIBHAL_STORAGE_ICON_VOLUME_DISK_IDE = 0x20101, + LIBHAL_STORAGE_ICON_VOLUME_DISK_SCSI = 0x20102, + LIBHAL_STORAGE_ICON_VOLUME_DISK_USB = 0x20103, + LIBHAL_STORAGE_ICON_VOLUME_DISK_IEEE1394 = 0x20104, + LIBHAL_STORAGE_ICON_VOLUME_CDROM = 0x20200, + LIBHAL_STORAGE_ICON_VOLUME_CDROM_IDE = 0x20201, + LIBHAL_STORAGE_ICON_VOLUME_CDROM_SCSI = 0x20202, + LIBHAL_STORAGE_ICON_VOLUME_CDROM_USB = 0x20203, + LIBHAL_STORAGE_ICON_VOLUME_CDROM_IEEE1394 = 0x20204, + LIBHAL_STORAGE_ICON_VOLUME_FLOPPY = 0x20300, + LIBHAL_STORAGE_ICON_VOLUME_FLOPPY_IDE = 0x20301, + LIBHAL_STORAGE_ICON_VOLUME_FLOPPY_SCSI = 0x20302, + LIBHAL_STORAGE_ICON_VOLUME_FLOPPY_USB = 0x20303, + LIBHAL_STORAGE_ICON_VOLUME_FLOPPY_IEEE1394 = 0x20304, + LIBHAL_STORAGE_ICON_VOLUME_TAPE = 0x20400, + LIBHAL_STORAGE_ICON_VOLUME_COMPACT_FLASH = 0x20500, + LIBHAL_STORAGE_ICON_VOLUME_MEMORY_STICK = 0x20600, + LIBHAL_STORAGE_ICON_VOLUME_SMART_MEDIA = 0x20700, + LIBHAL_STORAGE_ICON_VOLUME_SD_MMC = 0x20800, + LIBHAL_STORAGE_ICON_VOLUME_CAMERA = 0x20900, + LIBHAL_STORAGE_ICON_VOLUME_PORTABLE_AUDIO_PLAYER = 0x20a00, + LIBHAL_STORAGE_ICON_VOLUME_ZIP = 0x20b00, + LIBHAL_STORAGE_ICON_VOLUME_JAZ = 0x20c00, + LIBHAL_STORAGE_ICON_VOLUME_FLASH_KEY = 0x20d00, + + LIBHAL_STORAGE_ICON_DISC_CDROM = 0x30000, + LIBHAL_STORAGE_ICON_DISC_CDR = 0x30001, + LIBHAL_STORAGE_ICON_DISC_CDRW = 0x30002, + LIBHAL_STORAGE_ICON_DISC_DVDROM = 0x30003, + LIBHAL_STORAGE_ICON_DISC_DVDRAM = 0x30004, + LIBHAL_STORAGE_ICON_DISC_DVDR = 0x30005, + LIBHAL_STORAGE_ICON_DISC_DVDRW = 0x30006, + LIBHAL_STORAGE_ICON_DISC_DVDPLUSR = 0x30007, + LIBHAL_STORAGE_ICON_DISC_DVDPLUSRW = 0x30008, + LIBHAL_STORAGE_ICON_DISC_DVDPLUSRWDL = 0x30009, + LIBHAL_STORAGE_ICON_DISC_BDROM = 0x3000a, + LIBHAL_STORAGE_ICON_DISC_BDR = 0x3000b, + LIBHAL_STORAGE_ICON_DISC_BDRE = 0x3000c, + LIBHAL_STORAGE_ICON_DISC_HDDVDROM = 0x3000d, + LIBHAL_STORAGE_ICON_DISC_HDDVDR = 0x3000e, + LIBHAL_STORAGE_ICON_DISC_HDDVDRW = 0x3000f +} LibHalStoragePolicyIcon; + +typedef struct { + LibHalStoragePolicyIcon icon; + const char *icon_path; +} LibHalStoragePolicyIconPair; + +LibHalStoragePolicy *libhal_storage_policy_new (void) LIBHAL_DEPRECATED; +void libhal_storage_policy_free (LibHalStoragePolicy *policy) LIBHAL_DEPRECATED; + +void libhal_storage_policy_set_icon_path (LibHalStoragePolicy *policy, + LibHalStoragePolicyIcon icon, + const char *path) LIBHAL_DEPRECATED; + +void libhal_storage_policy_set_icon_mapping (LibHalStoragePolicy *policy, + LibHalStoragePolicyIconPair *pairs) LIBHAL_DEPRECATED; +const char *libhal_storage_policy_lookup_icon (LibHalStoragePolicy *policy, + LibHalStoragePolicyIcon icon) LIBHAL_DEPRECATED; + +typedef enum { + LIBHAL_DRIVE_BUS_UNKNOWN = 0x00, + LIBHAL_DRIVE_BUS_IDE = 0x01, + LIBHAL_DRIVE_BUS_SCSI = 0x02, + LIBHAL_DRIVE_BUS_USB = 0x03, + LIBHAL_DRIVE_BUS_IEEE1394 = 0x04, + LIBHAL_DRIVE_BUS_CCW = 0x05 +} LibHalDriveBus; + +typedef enum { + LIBHAL_DRIVE_TYPE_REMOVABLE_DISK = 0x00, + LIBHAL_DRIVE_TYPE_DISK = 0x01, + LIBHAL_DRIVE_TYPE_CDROM = 0x02, + LIBHAL_DRIVE_TYPE_FLOPPY = 0x03, + LIBHAL_DRIVE_TYPE_TAPE = 0x04, + LIBHAL_DRIVE_TYPE_COMPACT_FLASH = 0x05, + LIBHAL_DRIVE_TYPE_MEMORY_STICK = 0x06, + LIBHAL_DRIVE_TYPE_SMART_MEDIA = 0x07, + LIBHAL_DRIVE_TYPE_SD_MMC = 0x08, + LIBHAL_DRIVE_TYPE_CAMERA = 0x09, + LIBHAL_DRIVE_TYPE_PORTABLE_AUDIO_PLAYER = 0x0a, + LIBHAL_DRIVE_TYPE_ZIP = 0x0b, + LIBHAL_DRIVE_TYPE_JAZ = 0x0c, + LIBHAL_DRIVE_TYPE_FLASHKEY = 0x0d +} LibHalDriveType; + +typedef enum { + LIBHAL_DRIVE_CDROM_CAPS_CDROM = 0x00001, + LIBHAL_DRIVE_CDROM_CAPS_CDR = 0x00002, + LIBHAL_DRIVE_CDROM_CAPS_CDRW = 0x00004, + LIBHAL_DRIVE_CDROM_CAPS_DVDRAM = 0x00008, + LIBHAL_DRIVE_CDROM_CAPS_DVDROM = 0x00010, + LIBHAL_DRIVE_CDROM_CAPS_DVDR = 0x00020, + LIBHAL_DRIVE_CDROM_CAPS_DVDRW = 0x00040, + LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSR = 0x00080, + LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSRW = 0x00100, + LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSRDL = 0x00200, + LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSRWDL = 0x00400, + LIBHAL_DRIVE_CDROM_CAPS_BDROM = 0x00800, + LIBHAL_DRIVE_CDROM_CAPS_BDR = 0x01000, + LIBHAL_DRIVE_CDROM_CAPS_BDRE = 0x02000, + LIBHAL_DRIVE_CDROM_CAPS_HDDVDROM = 0x04000, + LIBHAL_DRIVE_CDROM_CAPS_HDDVDR = 0x08000, + LIBHAL_DRIVE_CDROM_CAPS_HDDVDRW = 0x10000 +} LibHalDriveCdromCaps; + +LibHalDrive *libhal_drive_from_udi (LibHalContext *hal_ctx, + const char *udi); +LibHalDrive *libhal_drive_from_device_file (LibHalContext *hal_ctx, + const char *device_file); +void libhal_drive_free (LibHalDrive *drive); + +dbus_bool_t libhal_drive_is_hotpluggable (LibHalDrive *drive); +dbus_bool_t libhal_drive_uses_removable_media (LibHalDrive *drive); +dbus_bool_t libhal_drive_is_media_detected (LibHalDrive *drive); +dbus_uint64_t libhal_drive_get_size (LibHalDrive *drive); +dbus_uint64_t libhal_drive_get_media_size (LibHalDrive *drive); +const char *libhal_drive_get_partition_scheme (LibHalDrive *drive); +dbus_bool_t libhal_drive_no_partitions_hint (LibHalDrive *drive); +dbus_bool_t libhal_drive_requires_eject (LibHalDrive *drive); +LibHalDriveType libhal_drive_get_type (LibHalDrive *drive); +LibHalDriveBus libhal_drive_get_bus (LibHalDrive *drive); +LibHalDriveCdromCaps libhal_drive_get_cdrom_caps (LibHalDrive *drive); +unsigned int libhal_drive_get_device_major (LibHalDrive *drive); +unsigned int libhal_drive_get_device_minor (LibHalDrive *drive); +const char *libhal_drive_get_type_textual (LibHalDrive *drive); +const char *libhal_drive_get_device_file (LibHalDrive *drive); +const char *libhal_drive_get_udi (LibHalDrive *drive); +const char *libhal_drive_get_serial (LibHalDrive *drive); +const char *libhal_drive_get_firmware_version (LibHalDrive *drive); +const char *libhal_drive_get_model (LibHalDrive *drive); +const char *libhal_drive_get_vendor (LibHalDrive *drive); +const char *libhal_drive_get_physical_device_udi (LibHalDrive *drive); + +const char *libhal_drive_get_dedicated_icon_drive (LibHalDrive *drive); +const char *libhal_drive_get_dedicated_icon_volume (LibHalDrive *drive); + +char *libhal_drive_policy_compute_display_name (LibHalDrive *drive, + LibHalVolume *volume, + LibHalStoragePolicy *policy) LIBHAL_DEPRECATED; +char *libhal_drive_policy_compute_icon_name (LibHalDrive *drive, + LibHalVolume *volume, + LibHalStoragePolicy *policy) LIBHAL_DEPRECATED; + +dbus_bool_t libhal_drive_policy_is_mountable (LibHalDrive *drive, + LibHalStoragePolicy *policy) LIBHAL_DEPRECATED; +const char *libhal_drive_policy_get_desired_mount_point (LibHalDrive *drive, + LibHalStoragePolicy *policy) LIBHAL_DEPRECATED; +const char *libhal_drive_policy_get_mount_options (LibHalDrive *drive, + LibHalStoragePolicy *policy) LIBHAL_DEPRECATED; +const char *libhal_drive_policy_get_mount_fs (LibHalDrive *drive, + LibHalStoragePolicy *policy) LIBHAL_DEPRECATED; + +char **libhal_drive_find_all_volumes (LibHalContext *hal_ctx, + LibHalDrive *drive, + int *num_volumes); + + +char *libhal_drive_policy_default_get_mount_root (LibHalContext *hal_ctx) LIBHAL_DEPRECATED; +dbus_bool_t libhal_drive_policy_default_use_managed_keyword (LibHalContext *hal_ctx) LIBHAL_DEPRECATED; +char *libhal_drive_policy_default_get_managed_keyword_primary (LibHalContext *hal_ctx) LIBHAL_DEPRECATED; +char *libhal_drive_policy_default_get_managed_keyword_secondary (LibHalContext *hal_ctx) LIBHAL_DEPRECATED; + + +typedef enum { + LIBHAL_VOLUME_USAGE_MOUNTABLE_FILESYSTEM, + LIBHAL_VOLUME_USAGE_PARTITION_TABLE, + LIBHAL_VOLUME_USAGE_RAID_MEMBER, + LIBHAL_VOLUME_USAGE_CRYPTO, + LIBHAL_VOLUME_USAGE_UNKNOWN, + LIBHAL_VOLUME_USAGE_OTHER +} LibHalVolumeUsage; + +typedef enum { + LIBHAL_VOLUME_DISC_TYPE_CDROM = 0x00, + LIBHAL_VOLUME_DISC_TYPE_CDR = 0x01, + LIBHAL_VOLUME_DISC_TYPE_CDRW = 0x02, + LIBHAL_VOLUME_DISC_TYPE_DVDROM = 0x03, + LIBHAL_VOLUME_DISC_TYPE_DVDRAM = 0x04, + LIBHAL_VOLUME_DISC_TYPE_DVDR = 0x05, + LIBHAL_VOLUME_DISC_TYPE_DVDRW = 0x06, + LIBHAL_VOLUME_DISC_TYPE_DVDPLUSR = 0x07, + LIBHAL_VOLUME_DISC_TYPE_DVDPLUSRW = 0x08, + LIBHAL_VOLUME_DISC_TYPE_DVDPLUSR_DL = 0x09, + LIBHAL_VOLUME_DISC_TYPE_BDROM = 0x0a, + LIBHAL_VOLUME_DISC_TYPE_BDR = 0x0b, + LIBHAL_VOLUME_DISC_TYPE_BDRE = 0x0c, + LIBHAL_VOLUME_DISC_TYPE_HDDVDROM = 0x0d, + LIBHAL_VOLUME_DISC_TYPE_HDDVDR = 0x0e, + LIBHAL_VOLUME_DISC_TYPE_HDDVDRW = 0x0f +} LibHalVolumeDiscType; + +LibHalVolume *libhal_volume_from_udi (LibHalContext *hal_ctx, + const char *udi); +LibHalVolume *libhal_volume_from_device_file (LibHalContext *hal_ctx, + const char *device_file); +void libhal_volume_free (LibHalVolume *volume); +dbus_uint64_t libhal_volume_get_size (LibHalVolume *volume); +dbus_uint64_t libhal_volume_get_disc_capacity (LibHalVolume *volume); + +const char *libhal_volume_get_udi (LibHalVolume *volume); +const char *libhal_volume_get_device_file (LibHalVolume *volume); +unsigned int libhal_volume_get_device_major (LibHalVolume *volume); +unsigned int libhal_volume_get_device_minor (LibHalVolume *volume); +const char *libhal_volume_get_fstype (LibHalVolume *volume); +const char *libhal_volume_get_fsversion (LibHalVolume *volume); +LibHalVolumeUsage libhal_volume_get_fsusage (LibHalVolume *volume); +dbus_bool_t libhal_volume_is_mounted (LibHalVolume *volume); +dbus_bool_t libhal_volume_is_mounted_read_only (LibHalVolume *volume); +dbus_bool_t libhal_volume_is_partition (LibHalVolume *volume); +dbus_bool_t libhal_volume_is_disc (LibHalVolume *volume); + +const char *libhal_volume_get_partition_scheme (LibHalVolume *volume); +const char *libhal_volume_get_partition_type (LibHalVolume *volume); +const char *libhal_volume_get_partition_label (LibHalVolume *volume); +const char *libhal_volume_get_partition_uuid (LibHalVolume *volume); +const char **libhal_volume_get_partition_flags (LibHalVolume *volume); +unsigned int libhal_volume_get_partition_number (LibHalVolume *volume); +dbus_uint64_t libhal_volume_get_partition_start_offset (LibHalVolume *volume); +dbus_uint64_t libhal_volume_get_partition_media_size (LibHalVolume *volume); + +const char *libhal_volume_get_label (LibHalVolume *volume); +const char *libhal_volume_get_mount_point (LibHalVolume *volume); +const char *libhal_volume_get_uuid (LibHalVolume *volume); +const char *libhal_volume_get_storage_device_udi (LibHalVolume *volume); + +const char *libhal_volume_crypto_get_backing_volume_udi (LibHalVolume *volume); +char *libhal_volume_crypto_get_clear_volume_udi (LibHalContext *hal_ctx, LibHalVolume *volume); + + +dbus_bool_t libhal_volume_disc_has_audio (LibHalVolume *volume); +dbus_bool_t libhal_volume_disc_has_data (LibHalVolume *volume); +dbus_bool_t libhal_volume_disc_is_blank (LibHalVolume *volume); +dbus_bool_t libhal_volume_disc_is_rewritable (LibHalVolume *volume); +dbus_bool_t libhal_volume_disc_is_appendable (LibHalVolume *volume); +LibHalVolumeDiscType libhal_volume_get_disc_type (LibHalVolume *volume); + +int libhal_volume_get_msdos_part_table_type (LibHalVolume *volume) LIBHAL_DEPRECATED; +dbus_uint64_t libhal_volume_get_msdos_part_table_start (LibHalVolume *volume) LIBHAL_DEPRECATED; +dbus_uint64_t libhal_volume_get_msdos_part_table_size (LibHalVolume *volume) LIBHAL_DEPRECATED; + + +dbus_bool_t libhal_volume_should_ignore (LibHalVolume *volume); + +char *libhal_volume_policy_compute_size_as_string (LibHalVolume *volume) LIBHAL_DEPRECATED; + +char *libhal_volume_policy_compute_display_name (LibHalDrive *drive, + LibHalVolume *volume, + LibHalStoragePolicy *policy) LIBHAL_DEPRECATED; +char *libhal_volume_policy_compute_icon_name (LibHalDrive *drive, + LibHalVolume *volume, + LibHalStoragePolicy *policy) LIBHAL_DEPRECATED; + +dbus_bool_t libhal_volume_policy_should_be_visible (LibHalDrive *drive, + LibHalVolume *volume, + LibHalStoragePolicy *policy, + const char *target_mount_point) LIBHAL_DEPRECATED; + +dbus_bool_t libhal_volume_policy_is_mountable (LibHalDrive *drive, + LibHalVolume *volume, + LibHalStoragePolicy *policy) LIBHAL_DEPRECATED; +const char *libhal_volume_policy_get_desired_mount_point (LibHalDrive *drive, + LibHalVolume *volume, + LibHalStoragePolicy *policy) LIBHAL_DEPRECATED; +const char *libhal_volume_policy_get_mount_options (LibHalDrive *drive, + LibHalVolume *volume, + LibHalStoragePolicy *policy) LIBHAL_DEPRECATED; +const char *libhal_volume_policy_get_mount_fs (LibHalDrive *drive, + LibHalVolume *volume, + LibHalStoragePolicy *policy) LIBHAL_DEPRECATED; + + +#if defined(__cplusplus) +} +#endif + +#endif /* LIBHAL_STORAGE_H */ diff --git a/usr/src/lib/hal/libhal-storage/common/llib-lhal-storage b/usr/src/lib/hal/libhal-storage/common/llib-lhal-storage new file mode 100644 index 0000000000..93af701653 --- /dev/null +++ b/usr/src/lib/hal/libhal-storage/common/llib-lhal-storage @@ -0,0 +1,30 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ +#pragma ident "%Z%%M% %I% %E% SMI" + +/* LINTLIBRARY */ +/* PROTOLIB1 */ + +#include <hal/libhal-storage.h> diff --git a/usr/src/lib/hal/libhal-storage/common/mapfile-vers b/usr/src/lib/hal/libhal-storage/common/mapfile-vers new file mode 100644 index 0000000000..329b75b641 --- /dev/null +++ b/usr/src/lib/hal/libhal-storage/common/mapfile-vers @@ -0,0 +1,120 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +SUNW_1.1 { + global: + libhal_storage_policy_new; + libhal_storage_policy_free; + libhal_storage_policy_set_icon_path; + libhal_storage_policy_set_icon_mapping; + libhal_storage_policy_lookup_icon; + libhal_drive_from_udi; + libhal_drive_from_device_file; + libhal_drive_free; + libhal_drive_is_hotpluggable; + libhal_drive_uses_removable_media; + libhal_drive_no_partitions_hint; + libhal_drive_requires_eject; + libhal_drive_get_type; + libhal_drive_get_bus; + libhal_drive_get_cdrom_caps; + libhal_drive_get_device_major; + libhal_drive_get_device_minor; + libhal_drive_get_type_textual; + libhal_drive_get_device_file; + libhal_drive_get_udi; + libhal_drive_get_serial; + libhal_drive_get_firmware_version; + libhal_drive_get_model; + libhal_drive_get_vendor; + libhal_drive_get_physical_device_udi; + libhal_drive_get_dedicated_icon_drive; + libhal_drive_get_dedicated_icon_volume; + libhal_drive_get_partition_scheme; + libhal_drive_policy_compute_display_name; + libhal_drive_policy_compute_icon_name; + libhal_drive_policy_is_mountable; + libhal_drive_policy_get_desired_mount_point; + libhal_drive_policy_get_mount_options; + libhal_drive_policy_get_mount_fs; + libhal_drive_find_all_volumes; + libhal_drive_policy_default_get_mount_root; + libhal_drive_policy_default_use_managed_keyword; + libhal_drive_policy_default_get_managed_keyword_primary; + libhal_drive_policy_default_get_managed_keyword_secondary; + libhal_volume_from_udi; + libhal_volume_from_device_file; + libhal_volume_free; + libhal_volume_get_size; + libhal_volume_get_disc_capacity; + libhal_volume_get_udi; + libhal_volume_get_device_file; + libhal_volume_get_device_major; + libhal_volume_get_device_minor; + libhal_volume_get_fstype; + libhal_volume_get_fsversion; + libhal_volume_get_fsusage; + libhal_volume_is_mounted; + libhal_volume_is_mounted_read_only; + libhal_volume_is_partition; + libhal_volume_is_disc; + libhal_volume_get_partition_number; + libhal_volume_get_label; + libhal_volume_get_mount_point; + libhal_volume_get_uuid; + libhal_volume_get_storage_device_udi; + libhal_volume_crypto_get_backing_volume_udi; + libhal_volume_crypto_get_clear_volume_udi; + libhal_volume_disc_has_audio; + libhal_volume_disc_has_data; + libhal_volume_disc_is_blank; + libhal_volume_disc_is_rewritable; + libhal_volume_disc_is_appendable; + libhal_volume_get_disc_type; + libhal_volume_get_msdos_part_table_type; + libhal_volume_get_partition_scheme; + libhal_volume_get_partition_type; + libhal_volume_get_partition_label; + libhal_volume_get_partition_uuid; + libhal_volume_get_partition_flags; + libhal_volume_should_ignore; + libhal_volume_policy_compute_size_as_string; + libhal_volume_policy_compute_display_name; + libhal_volume_policy_compute_icon_name; + libhal_volume_policy_should_be_visible; + libhal_volume_policy_is_mountable; + libhal_volume_policy_get_desired_mount_point; + libhal_volume_policy_get_mount_options; + libhal_volume_policy_get_mount_fs; +}; + +SUNWprivate_1.1 { + global: + SUNWprivate_1.1; + local: + *; +}; diff --git a/usr/src/lib/hal/libhal-storage/i386/Makefile b/usr/src/lib/hal/libhal-storage/i386/Makefile new file mode 100644 index 0000000000..8643a8305f --- /dev/null +++ b/usr/src/lib/hal/libhal-storage/i386/Makefile @@ -0,0 +1,30 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#ident "%Z%%M% %I% %E% SMI" +# + +include ../Makefile.com + +install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTLINT) $(ROOTLIBPC) $(ROOTMAJLINK) diff --git a/usr/src/lib/hal/libhal-storage/sparc/Makefile b/usr/src/lib/hal/libhal-storage/sparc/Makefile new file mode 100644 index 0000000000..8643a8305f --- /dev/null +++ b/usr/src/lib/hal/libhal-storage/sparc/Makefile @@ -0,0 +1,30 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#ident "%Z%%M% %I% %E% SMI" +# + +include ../Makefile.com + +install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTLINT) $(ROOTLIBPC) $(ROOTMAJLINK) diff --git a/usr/src/lib/hal/libhal/Makefile b/usr/src/lib/hal/libhal/Makefile new file mode 100644 index 0000000000..b90c784c0d --- /dev/null +++ b/usr/src/lib/hal/libhal/Makefile @@ -0,0 +1,52 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" + +include ../../Makefile.lib +include ../Makefile.com + +HDRS = libhal.h +HDRDIR = common +ROOTHDRDIR = $(ROOT)/usr/include/hal + +SUBDIRS= $(MACH) + +all := TARGET= all +clean := TARGET= clean +clobber := TARGET= clobber +install := TARGET= install + +.KEEP_STATE: + +all clean clobber install: $(SUBDIRS) + +install_h: $(ROOTHDRS) + +$(SUBDIRS): FRC + @cd $@; pwd; $(MAKE) $(TARGET) + +FRC: + +include $(SRC)/lib/Makefile.targ diff --git a/usr/src/lib/hal/libhal/Makefile.com b/usr/src/lib/hal/libhal/Makefile.com new file mode 100644 index 0000000000..9741f9de72 --- /dev/null +++ b/usr/src/lib/hal/libhal/Makefile.com @@ -0,0 +1,57 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# +# usr/src/lib/hal/libhal/Makefile.com +# + +LIBRARY = libhal.a +VERS = .1.0.0 +VERS_MAJ = .1 +OBJECTS = libhal.o +LIBPCSRC = hal.pc + +include ../../Makefile.com + +LIBS = $(DYNLIB) $(LINTLIB) +LDLIBS += -lc -ldbus-1 +$(LINTLIB) := SRCS = $(SRCDIR)/$(LINTSRC) + +SRCDIR = ../common + +CFLAGS += $(CCVERBOSE) +CPPFLAGS += $(HAL_CONFIG_CPPFLAGS) +CPPFLAGS += -DGETTEXT_PACKAGE=\"$(HAL_GETTEXT_PACKAGE)\" -DENABLE_NLS + +ROOTMAJLINK = $(ROOTLIBDIR)/$(LIBRARY:.a=.so)$(VERS_MAJ) + +.KEEP_STATE: + +all: $(LIBS) + +$(ROOTMAJLINK): + -$(RM) $@; $(SYMLINK) $(DYNLIB) $@ + +include $(SRC)/lib/Makefile.targ diff --git a/usr/src/lib/hal/libhal/common/hal.pc.in b/usr/src/lib/hal/libhal/common/hal.pc.in new file mode 100644 index 0000000000..e814f914e1 --- /dev/null +++ b/usr/src/lib/hal/libhal/common/hal.pc.in @@ -0,0 +1,19 @@ +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# Licensed under the Academic Free License version 2.1 +# +# ident "%Z%%M% %I% %E% SMI" + +prefix=/usr +exec_prefix=${prefix} +libdir=${exec_prefix}/lib +includedir=${prefix}/include + +Name: hal +Description: Free desktop hardware abstraction layer +Version: __VERSION__ +Requires: dbus-1 +Libs: -L${libdir} -lhal +Cflags: -DDBUS_API_SUBJECT_TO_CHANGE -I${includedir}/hal diff --git a/usr/src/lib/hal/libhal/common/libhal.c b/usr/src/lib/hal/libhal/common/libhal.c new file mode 100644 index 0000000000..e88ca3d869 --- /dev/null +++ b/usr/src/lib/hal/libhal/common/libhal.c @@ -0,0 +1,3992 @@ +/*************************************************************************** + * CVSID: $Id$ + * + * libhal.c : HAL daemon C convenience library + * + * Copyright (C) 2003 David Zeuthen, <david@fubar.dk> + * + * Licensed under the Academic Free License version 2.1 + * + * This program 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 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + **************************************************************************/ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <dbus/dbus.h> + +#include "libhal.h" + +#ifdef ENABLE_NLS +# include <libintl.h> +# define _(String) dgettext (GETTEXT_PACKAGE, String) +# ifdef gettext_noop +# define N_(String) gettext_noop (String) +# else +# define N_(String) (String) +# endif +#else +/* Stubs that do something close enough. */ +# define textdomain(String) (String) +# define gettext(String) (String) +# define dgettext(Domain,Message) (Message) +# define dcgettext(Domain,Message,Type) (Message) +# define bindtextdomain(Domain,Directory) (Domain) +# define _(String) +# define N_(String) (String) +#endif + +static char **libhal_get_string_array_from_iter (DBusMessageIter *iter, int *num_elements); + +static dbus_bool_t libhal_property_fill_value_from_variant (LibHalProperty *p, DBusMessageIter *var_iter); + + + +/** + * libhal_free_string_array: + * @str_array: the array to be freed + * + * Frees a NULL-terminated array of strings. If passed NULL, does nothing. + */ +void +libhal_free_string_array (char **str_array) +{ + if (str_array != NULL) { + int i; + + for (i = 0; str_array[i] != NULL; i++) { + free (str_array[i]); + str_array[i] = NULL; + } + free (str_array); + str_array = NULL; + } +} + + +/** + * libhal_get_string_array_from_iter: + * @iter: the message iterator to extract the strings from + * @num_elements: pointer to an integer where to store number of elements (can be NULL) + * + * Creates a NULL terminated array of strings from a dbus message iterator. + * + * Returns: pointer to the string array + */ +static char ** +libhal_get_string_array_from_iter (DBusMessageIter *iter, int *num_elements) +{ + int count; + char **buffer; + + count = 0; + buffer = (char **)malloc (sizeof (char *) * 8); + + if (buffer == NULL) + goto oom; + + buffer[0] = NULL; + while (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_STRING) { + const char *value; + char *str; + + if ((count % 8) == 0 && count != 0) { + buffer = realloc (buffer, sizeof (char *) * (count + 8)); + if (buffer == NULL) + goto oom; + } + + dbus_message_iter_get_basic (iter, &value); + str = strdup (value); + if (str == NULL) + goto oom; + + buffer[count] = str; + + dbus_message_iter_next(iter); + count++; + } + + if ((count % 8) == 0) { + buffer = realloc (buffer, sizeof (char *) * (count + 1)); + if (buffer == NULL) + goto oom; + } + + buffer[count] = NULL; + if (num_elements != NULL) + *num_elements = count; + return buffer; + +oom: + fprintf (stderr, "%s %d : error allocating memory\n", __FILE__, __LINE__); + return NULL; + +} + +/** + * libhal_free_string: + * @str: the nul-terminated sting to free + * + * Used to free strings returned by libhal. + */ +void +libhal_free_string (char *str) +{ + if (str != NULL) { + free (str); + str = NULL; + } +} + + +/** + * LibHalPropertySet: + * + * Represents a set of properties. Opaque; use the + * libhal_property_set_*() family of functions to access it. + */ +struct LibHalPropertySet_s { + unsigned int num_properties; /**< Number of properties in set */ + LibHalProperty *properties_head; + /**< Pointer to first property or NULL + * if there are no properties */ +}; + +/** + * LibHalProperty: + * + * Represents a property. Opaque. + */ +struct LibHalProperty_s { + int type; /**< Type of property */ + char *key; /**< ASCII string */ + + /** Possible values of the property */ + union { + char *str_value; /**< UTF-8 zero-terminated string */ + dbus_int32_t int_value; + /**< 32-bit signed integer */ + dbus_uint64_t uint64_value; + /**< 64-bit unsigned integer */ + double double_value; /**< IEEE754 double precision float */ + dbus_bool_t bool_value; + /**< Truth value */ + + char **strlist_value; /**< List of UTF-8 zero-terminated strings */ + } v; + + LibHalProperty *next; /**< Next property or NULL if this is + * the last */ +}; + +/** + * LibHalContext: + * + * Context for connection to the HAL daemon. Opaque, use the + * libhal_ctx_*() family of functions to access it. + */ +struct LibHalContext_s { + DBusConnection *connection; /**< D-BUS connection */ + dbus_bool_t is_initialized; /**< Are we initialised */ + dbus_bool_t is_shutdown; /**< Have we been shutdown */ + dbus_bool_t cache_enabled; /**< Is the cache enabled */ + dbus_bool_t is_direct; /**< Whether the connection to hald is direct */ + + /** Device added */ + LibHalDeviceAdded device_added; + + /** Device removed */ + LibHalDeviceRemoved device_removed; + + /** Device got a new capability */ + LibHalDeviceNewCapability device_new_capability; + + /** Device got a new capability */ + LibHalDeviceLostCapability device_lost_capability; + + /** A property of a device changed */ + LibHalDevicePropertyModified device_property_modified; + + /** A non-continous event on the device occured */ + LibHalDeviceCondition device_condition; + + void *user_data; /**< User data */ +}; + +/** + * libhal_ctx_set_user_data: + * @ctx: the context for the connection to hald + * @user_data: user data + * + * Set user data for the context. + * + * Returns: TRUE if user data was successfully set, FALSE if otherwise + */ +dbus_bool_t +libhal_ctx_set_user_data(LibHalContext *ctx, void *user_data) +{ + LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); + ctx->user_data = user_data; + return TRUE; +} + +/** + * libhal_ctx_get_user_data: + * @ctx: the context for the connection to hald + * + * Get user data for the context. + * + * Returns: opaque pointer stored through libhal_ctx_set_user_data() or NULL if not set. + */ +void* +libhal_ctx_get_user_data(LibHalContext *ctx) +{ + LIBHAL_CHECK_LIBHALCONTEXT(ctx, NULL); + return ctx->user_data; +} + + +/** + * libhal_property_fill_value_from_variant: + * @p: the property to fill in + * @var_iter: variant iterator to extract the value from + * + * Fills in the value for the LibHalProperty given a variant iterator. + * + * Returns: Whether the value was put in. + */ +static dbus_bool_t +libhal_property_fill_value_from_variant (LibHalProperty *p, DBusMessageIter *var_iter) +{ + DBusMessageIter iter_array; + switch (p->type) { + case DBUS_TYPE_ARRAY: + if (dbus_message_iter_get_element_type (var_iter) != DBUS_TYPE_STRING) + return FALSE; + + dbus_message_iter_recurse (var_iter, &iter_array); + p->v.strlist_value = libhal_get_string_array_from_iter (&iter_array, NULL); + + p->type = LIBHAL_PROPERTY_TYPE_STRLIST; + + break; + case DBUS_TYPE_STRING: + { + const char *v; + + dbus_message_iter_get_basic (var_iter, &v); + + p->v.str_value = strdup (v); + if (p->v.str_value == NULL) + return FALSE; + p->type = LIBHAL_PROPERTY_TYPE_STRING; + + break; + } + case DBUS_TYPE_INT32: + { + dbus_int32_t v; + + dbus_message_iter_get_basic (var_iter, &v); + + p->v.int_value = v; + p->type = LIBHAL_PROPERTY_TYPE_INT32; + + break; + } + case DBUS_TYPE_UINT64: + { + dbus_uint64_t v; + + dbus_message_iter_get_basic (var_iter, &v); + + p->v.uint64_value = v; + p->type = LIBHAL_PROPERTY_TYPE_UINT64; + + break; + } + case DBUS_TYPE_DOUBLE: + { + double v; + + dbus_message_iter_get_basic (var_iter, &v); + + p->v.double_value = v; + p->type = LIBHAL_PROPERTY_TYPE_DOUBLE; + + break; + } + case DBUS_TYPE_BOOLEAN: + { + double v; + + dbus_message_iter_get_basic (var_iter, &v); + + p->v.double_value = v; + p->type = LIBHAL_PROPERTY_TYPE_BOOLEAN; + + break; + } + default: + /** @todo report error */ + break; + } + + return TRUE; +} + +/** + * libhal_device_get_all_properties: + * @ctx: the context for the connection to hald + * @udi: the Unique id of device + * @error: pointer to an initialized dbus error object for returning errors or NULL + * + * Retrieve all the properties on a device. + * + * Returns: An object represent all properties. Must be freed with libhal_free_property_set(). + */ +LibHalPropertySet * +libhal_device_get_all_properties (LibHalContext *ctx, const char *udi, DBusError *error) +{ + DBusMessage *message; + DBusMessage *reply; + DBusMessageIter reply_iter; + DBusMessageIter dict_iter; + LibHalPropertySet *result; + LibHalProperty *p_last; + DBusError _error; + + LIBHAL_CHECK_LIBHALCONTEXT(ctx, NULL); + + message = dbus_message_new_method_call ("org.freedesktop.Hal", udi, + "org.freedesktop.Hal.Device", + "GetAllProperties"); + + if (message == NULL) { + fprintf (stderr, + "%s %d : Couldn't allocate D-BUS message\n", + __FILE__, __LINE__); + return NULL; + } + + dbus_error_init (&_error); + reply = dbus_connection_send_with_reply_and_block (ctx->connection, + message, -1, + &_error); + + dbus_move_error (&_error, error); + if (error != NULL && dbus_error_is_set (error)) { + fprintf (stderr, + "%s %d : %s\n", + __FILE__, __LINE__, error->message); + + dbus_message_unref (message); + return NULL; + } + + if (reply == NULL) { + dbus_message_unref (message); + return NULL; + } + + dbus_message_iter_init (reply, &reply_iter); + + result = malloc (sizeof (LibHalPropertySet)); + if (result == NULL) + goto oom; +/* + result->properties = malloc(sizeof(LibHalProperty)*result->num_properties); + if( result->properties==NULL ) + { + /// @todo cleanup + return NULL; + } +*/ + + result->properties_head = NULL; + result->num_properties = 0; + + if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_ARRAY && + dbus_message_iter_get_element_type (&reply_iter) != DBUS_TYPE_DICT_ENTRY) { + fprintf (stderr, "%s %d : error, expecting an array of dict entries\n", + __FILE__, __LINE__); + dbus_message_unref (message); + dbus_message_unref (reply); + return NULL; + } + + dbus_message_iter_recurse (&reply_iter, &dict_iter); + + p_last = NULL; + + while (dbus_message_iter_get_arg_type (&dict_iter) == DBUS_TYPE_DICT_ENTRY) + { + DBusMessageIter dict_entry_iter, var_iter; + const char *key; + LibHalProperty *p; + + dbus_message_iter_recurse (&dict_iter, &dict_entry_iter); + + dbus_message_iter_get_basic (&dict_entry_iter, &key); + + p = malloc (sizeof (LibHalProperty)); + if (p == NULL) + goto oom; + + p->next = NULL; + + if (result->num_properties == 0) + result->properties_head = p; + + if (p_last != NULL) + p_last->next = p; + + p_last = p; + + p->key = strdup (key); + if (p->key == NULL) + goto oom; + + dbus_message_iter_next (&dict_entry_iter); + + dbus_message_iter_recurse (&dict_entry_iter, &var_iter); + + + p->type = dbus_message_iter_get_arg_type (&var_iter); + + result->num_properties++; + + if(!libhal_property_fill_value_from_variant (p, &var_iter)) + goto oom; + + dbus_message_iter_next (&dict_iter); + } + + dbus_message_unref (message); + dbus_message_unref (reply); + + return result; + +oom: + fprintf (stderr, + "%s %d : error allocating memory\n", + __FILE__, __LINE__); + /** @todo FIXME cleanup */ + return NULL; +} + +/** + * libhal_free_property_set: + * @set: property-set to free + * + * Free a property set earlier obtained with libhal_device_get_all_properties(). + */ +void +libhal_free_property_set (LibHalPropertySet * set) +{ + LibHalProperty *p; + LibHalProperty *q; + + if (set == NULL) + return; + + for (p = set->properties_head; p != NULL; p = q) { + free (p->key); + if (p->type == DBUS_TYPE_STRING) + free (p->v.str_value); + if (p->type == LIBHAL_PROPERTY_TYPE_STRLIST) + libhal_free_string_array (p->v.strlist_value); + q = p->next; + free (p); + } + free (set); +} + +/** + * libhal_property_set_get_num_elems: + * @set: property set to consider + * + * Get the number of properties in a property set. + * + * Returns: number of properties in given property set + */ +unsigned int +libhal_property_set_get_num_elems (LibHalPropertySet *set) +{ + unsigned int num_elems; + LibHalProperty *p; + + if (set == NULL) + return 0; + + num_elems = 0; + for (p = set->properties_head; p != NULL; p = p->next) + num_elems++; + + return num_elems; +} + + +/** + * libhal_psi_init: + * @iter: iterator object + * @set: property set to iterate over + * + * Initialize a property set iterator. + * + */ +void +libhal_psi_init (LibHalPropertySetIterator * iter, LibHalPropertySet * set) +{ + if (set == NULL) + return; + + iter->set = set; + iter->idx = 0; + iter->cur_prop = set->properties_head; +} + + +/** + * libhal_psi_has_more: + * @iter: iterator object + * + * Determine whether there are more properties to iterate over. + * + * Returns: TRUE if there are more properties, FALSE otherwise. + */ +dbus_bool_t +libhal_psi_has_more (LibHalPropertySetIterator * iter) +{ + return iter->idx < iter->set->num_properties; +} + +/** + * libhal_psi_next: + * @iter: iterator object + * + * Advance iterator to next property. + */ +void +libhal_psi_next (LibHalPropertySetIterator * iter) +{ + iter->idx++; + iter->cur_prop = iter->cur_prop->next; +} + +/** + * libhal_psi_get_type: + * @iter: iterator object + * + * Get type of property. + * + * Returns: the property type at the iterator's position + */ +LibHalPropertyType +libhal_psi_get_type (LibHalPropertySetIterator * iter) +{ + return iter->cur_prop->type; +} + +/** + * libhal_psi_get_key: + * @iter: iterator object + * + * Get the key of a property. + * + * Returns: ASCII nul-terminated string. This pointer is only valid + * until libhal_free_property_set() is invoked on the property set + * this property belongs to. + */ +char * +libhal_psi_get_key (LibHalPropertySetIterator * iter) +{ + return iter->cur_prop->key; +} + +/** + * libhal_psi_get_string: + * @iter: iterator object + * + * Get the value of a property of type string. + * + * Returns: UTF8 nul-terminated string. This pointer is only valid + * until libhal_free_property_set() is invoked on the property set + * this property belongs to. + */ +char * +libhal_psi_get_string (LibHalPropertySetIterator * iter) +{ + return iter->cur_prop->v.str_value; +} + +/** + * libhal_psi_get_int: + * @iter: iterator object + * + * Get the value of a property of type signed integer. + * + * Returns: property value (32-bit signed integer) + */ +dbus_int32_t +libhal_psi_get_int (LibHalPropertySetIterator * iter) +{ + return iter->cur_prop->v.int_value; +} + +/** + * libhal_psi_get_uint64: + * @iter: iterator object + * + * Get the value of a property of type unsigned integer. + * + * Returns: property value (64-bit unsigned integer) + */ +dbus_uint64_t +libhal_psi_get_uint64 (LibHalPropertySetIterator * iter) +{ + return iter->cur_prop->v.uint64_value; +} + +/** + * libhal_psi_get_double: + * @iter: iterator object + * + * Get the value of a property of type double. + * + * Returns: property value (IEEE754 double precision float) + */ +double +libhal_psi_get_double (LibHalPropertySetIterator * iter) +{ + return iter->cur_prop->v.double_value; +} + +/** + * libhal_psi_get_bool: + * @iter: iterator object + * + * Get the value of a property of type bool. + * + * Returns: property value (bool) + */ +dbus_bool_t +libhal_psi_get_bool (LibHalPropertySetIterator * iter) +{ + return iter->cur_prop->v.bool_value; +} + +/** + * libhal_psi_get_strlist: + * @iter: iterator object + * + * Get the value of a property of type string list. + * + * Returns: pointer to array of strings + */ +char ** +libhal_psi_get_strlist (LibHalPropertySetIterator * iter) +{ + return iter->cur_prop->v.strlist_value; +} + + +static DBusHandlerResult +filter_func (DBusConnection * connection, + DBusMessage * message, void *user_data) +{ + const char *object_path; + DBusError error; + LibHalContext *ctx = (LibHalContext *) user_data; + + if (ctx->is_shutdown) + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + + dbus_error_init (&error); + + object_path = dbus_message_get_path (message); + + /*printf("*** in filter_func, object_path=%s\n", object_path);*/ + + if (dbus_message_is_signal (message, "org.freedesktop.Hal.Manager", + "DeviceAdded")) { + char *udi; + if (dbus_message_get_args (message, &error, + DBUS_TYPE_STRING, &udi, + DBUS_TYPE_INVALID)) { + if (ctx->device_added != NULL) { + ctx->device_added (ctx, udi); + } + } else { + LIBHAL_FREE_DBUS_ERROR(&error); + } + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } else if (dbus_message_is_signal (message, "org.freedesktop.Hal.Manager", "DeviceRemoved")) { + char *udi; + if (dbus_message_get_args (message, &error, + DBUS_TYPE_STRING, &udi, + DBUS_TYPE_INVALID)) { + if (ctx->device_removed != NULL) { + ctx->device_removed (ctx, udi); + } + } else { + LIBHAL_FREE_DBUS_ERROR(&error); + } + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } else if (dbus_message_is_signal (message, "org.freedesktop.Hal.Manager","NewCapability")) { + char *udi; + char *capability; + if (dbus_message_get_args (message, &error, + DBUS_TYPE_STRING, &udi, + DBUS_TYPE_STRING, &capability, + DBUS_TYPE_INVALID)) { + if (ctx->device_new_capability != NULL) { + ctx->device_new_capability (ctx, udi, capability); + } + } else { + LIBHAL_FREE_DBUS_ERROR(&error); + } + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } else if (dbus_message_is_signal (message, "org.freedesktop.Hal.Device", "Condition")) { + char *condition_name; + char *condition_detail; + if (dbus_message_get_args (message, &error, + DBUS_TYPE_STRING, &condition_name, + DBUS_TYPE_STRING, &condition_detail, + DBUS_TYPE_INVALID)) { + if (ctx->device_condition != NULL) { + ctx->device_condition (ctx, object_path, condition_name, condition_detail); + } + } else { + LIBHAL_FREE_DBUS_ERROR(&error); + } + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } else if (dbus_message_is_signal (message, "org.freedesktop.Hal.Device", "PropertyModified")) { + if (ctx->device_property_modified != NULL) { + int i; + char *key; + dbus_bool_t removed; + dbus_bool_t added; + int num_modifications; + DBusMessageIter iter; + DBusMessageIter iter_array; + + dbus_message_iter_init (message, &iter); + dbus_message_iter_get_basic (&iter, &num_modifications); + dbus_message_iter_next (&iter); + + dbus_message_iter_recurse (&iter, &iter_array); + + for (i = 0; i < num_modifications; i++) { + DBusMessageIter iter_struct; + + dbus_message_iter_recurse (&iter_array, &iter_struct); + + dbus_message_iter_get_basic (&iter_struct, &key); + dbus_message_iter_next (&iter_struct); + dbus_message_iter_get_basic (&iter_struct, &removed); + dbus_message_iter_next (&iter_struct); + dbus_message_iter_get_basic (&iter_struct, &added); + + ctx->device_property_modified (ctx, + object_path, + key, removed, + added); + + dbus_message_iter_next (&iter_array); + } + + } + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +/* for i18n purposes */ +static dbus_bool_t libhal_already_initialized_once = FALSE; + + +/** + * libhal_get_all_devices: + * @ctx: the context for the connection to hald + * @num_devices: the number of devices will be stored here + * @error: pointer to an initialized dbus error object for returning errors or NULL + * + * Get all devices in the Global Device List (GDL). + * + * Returns: An array of device identifiers terminated with NULL. It is + * the responsibility of the caller to free with + * libhal_free_string_array(). If an error occurs NULL is returned. + */ +char ** +libhal_get_all_devices (LibHalContext *ctx, int *num_devices, DBusError *error) +{ + DBusMessage *message; + DBusMessage *reply; + DBusMessageIter iter_array, reply_iter; + char **hal_device_names; + DBusError _error; + + LIBHAL_CHECK_LIBHALCONTEXT(ctx, NULL); + + *num_devices = 0; + + message = dbus_message_new_method_call ("org.freedesktop.Hal", + "/org/freedesktop/Hal/Manager", + "org.freedesktop.Hal.Manager", + "GetAllDevices"); + if (message == NULL) { + fprintf (stderr, "%s %d : Could not allocate D-BUS message\n", __FILE__, __LINE__); + return NULL; + } + + dbus_error_init (&_error); + reply = dbus_connection_send_with_reply_and_block (ctx->connection, message, -1, &_error); + + dbus_move_error (&_error, error); + if (error != NULL && dbus_error_is_set (error)) { + dbus_message_unref (message); + return NULL; + } + if (reply == NULL) { + dbus_message_unref (message); + return NULL; + } + + /* now analyze reply */ + dbus_message_iter_init (reply, &reply_iter); + + if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_ARRAY) { + fprintf (stderr, "%s %d : wrong reply from hald. Expecting an array.\n", __FILE__, __LINE__); + return NULL; + } + + dbus_message_iter_recurse (&reply_iter, &iter_array); + + hal_device_names = libhal_get_string_array_from_iter (&iter_array, num_devices); + + dbus_message_unref (reply); + dbus_message_unref (message); + + return hal_device_names; +} + +/** + * libhal_device_get_property_type: + * @ctx: the context for the connection to hald + * @udi: the Unique Device Id + * @key: name of the property + * @error: pointer to an initialized dbus error object for returning errors or NULL + * + * Query a property type of a device. + * + * Returns: A LibHalPropertyType. LIBHAL_PROPERTY_TYPE_INVALID is + * return if the property doesn't exist. + */ +LibHalPropertyType +libhal_device_get_property_type (LibHalContext *ctx, const char *udi, const char *key, DBusError *error) +{ + DBusMessage *message; + DBusMessage *reply; + DBusMessageIter iter, reply_iter; + int type; + DBusError _error; + + LIBHAL_CHECK_LIBHALCONTEXT(ctx, LIBHAL_PROPERTY_TYPE_INVALID); /* or return NULL? */ + + message = dbus_message_new_method_call ("org.freedesktop.Hal", udi, + "org.freedesktop.Hal.Device", + "GetPropertyType"); + if (message == NULL) { + fprintf (stderr, "%s %d : Couldn't allocate D-BUS message\n", __FILE__, __LINE__); + return LIBHAL_PROPERTY_TYPE_INVALID; + } + + dbus_message_iter_init_append (message, &iter); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key); + + dbus_error_init (&_error); + reply = dbus_connection_send_with_reply_and_block (ctx->connection, + message, -1, + &_error); + + dbus_move_error (&_error, error); + if (error != NULL && dbus_error_is_set (error)) { + dbus_message_unref (message); + return LIBHAL_PROPERTY_TYPE_INVALID; + } + if (reply == NULL) { + dbus_message_unref (message); + return LIBHAL_PROPERTY_TYPE_INVALID; + } + + dbus_message_iter_init (reply, &reply_iter); + dbus_message_iter_get_basic (&reply_iter, &type); + + dbus_message_unref (message); + dbus_message_unref (reply); + + return type; +} + +/** + * libhal_device_get_property_strlist: + * @ctx: the context for the connection to hald + * @udi: unique Device Id + * @key: name of the property + * @error: pointer to an initialized dbus error object for returning errors or NULL + * + * Get the value of a property of type string list. + * + * Returns: Array of pointers to UTF8 nul-terminated strings + * terminated by NULL. The caller is responsible for freeing this + * string array with the function libhal_free_string_array(). Returns + * NULL if the property didn't exist or we are OOM + */ +char ** +libhal_device_get_property_strlist (LibHalContext *ctx, const char *udi, const char *key, DBusError *error) +{ + DBusMessage *message; + DBusMessage *reply; + DBusMessageIter iter, iter_array, reply_iter; + char **our_strings; + DBusError _error; + + LIBHAL_CHECK_LIBHALCONTEXT(ctx, NULL); + + message = dbus_message_new_method_call ("org.freedesktop.Hal", udi, + "org.freedesktop.Hal.Device", + "GetPropertyStringList"); + if (message == NULL) { + fprintf (stderr, + "%s %d : Couldn't allocate D-BUS message\n", + __FILE__, __LINE__); + return NULL; + } + + dbus_message_iter_init_append (message, &iter); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key); + + dbus_error_init (&_error); + reply = dbus_connection_send_with_reply_and_block (ctx->connection, + message, -1, + &_error); + + dbus_move_error (&_error, error); + if (error != NULL && dbus_error_is_set (error)) { + dbus_message_unref (message); + return NULL; + } + if (reply == NULL) { + dbus_message_unref (message); + return NULL; + } + /* now analyse reply */ + dbus_message_iter_init (reply, &reply_iter); + + if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_ARRAY) { + fprintf (stderr, "%s %d : wrong reply from hald. Expecting an array.\n", __FILE__, __LINE__); + return NULL; + } + + dbus_message_iter_recurse (&reply_iter, &iter_array); + + our_strings = libhal_get_string_array_from_iter (&iter_array, NULL); + + dbus_message_unref (reply); + dbus_message_unref (message); + + return our_strings; +} + +/** + * libhal_device_get_property_string: + * @ctx: the context for the connection to hald + * @udi: the Unique Device Id + * @key: the name of the property + * @error: pointer to an initialized dbus error object for returning errors or NULL + * + * Get the value of a property of type string. + * + * Returns: UTF8 nul-terminated string. The caller is responsible for + * freeing this string with the function libhal_free_string(). Returns + * NULL if the property didn't exist or we are OOM. + */ +char * +libhal_device_get_property_string (LibHalContext *ctx, + const char *udi, const char *key, DBusError *error) +{ + DBusMessage *message; + DBusMessage *reply; + DBusMessageIter iter, reply_iter; + char *value; + char *dbus_str; + DBusError _error; + + LIBHAL_CHECK_LIBHALCONTEXT(ctx, NULL); + + message = dbus_message_new_method_call ("org.freedesktop.Hal", udi, + "org.freedesktop.Hal.Device", + "GetPropertyString"); + + if (message == NULL) { + fprintf (stderr, + "%s %d : Couldn't allocate D-BUS message\n", + __FILE__, __LINE__); + return NULL; + } + + dbus_message_iter_init_append (message, &iter); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key); + + dbus_error_init (&_error); + reply = dbus_connection_send_with_reply_and_block (ctx->connection, + message, -1, + &_error); + + dbus_move_error (&_error, error); + if (error != NULL && dbus_error_is_set (error)) { + dbus_message_unref (message); + return NULL; + } + if (reply == NULL) { + dbus_message_unref (message); + return NULL; + } + + dbus_message_iter_init (reply, &reply_iter); + + /* now analyze reply */ + if (dbus_message_iter_get_arg_type (&reply_iter) != + DBUS_TYPE_STRING) { + dbus_message_unref (message); + dbus_message_unref (reply); + return NULL; + } + + dbus_message_iter_get_basic (&reply_iter, &dbus_str); + value = (char *) ((dbus_str != NULL) ? strdup (dbus_str) : NULL); + if (value == NULL) { + fprintf (stderr, "%s %d : error allocating memory\n", + __FILE__, __LINE__); + /** @todo FIXME cleanup */ + return NULL; + } + + dbus_message_unref (message); + dbus_message_unref (reply); + return value; +} + +/** + * libhal_device_get_property_int: + * @ctx: the context for the connection to hald + * @udi: the Unique Device Id + * @key: name of the property + * @error: pointer to an initialized dbus error object for returning errors or NULL + * + * Get the value of a property of type integer. + * + * Returns: Property value (32-bit signed integer) + */ +dbus_int32_t +libhal_device_get_property_int (LibHalContext *ctx, + const char *udi, const char *key, DBusError *error) +{ + DBusMessage *message; + DBusMessage *reply; + DBusMessageIter iter, reply_iter; + dbus_int32_t value; + DBusError _error; + + LIBHAL_CHECK_LIBHALCONTEXT(ctx, -1); + + message = dbus_message_new_method_call ("org.freedesktop.Hal", udi, + "org.freedesktop.Hal.Device", + "GetPropertyInteger"); + if (message == NULL) { + fprintf (stderr, + "%s %d : Couldn't allocate D-BUS message\n", + __FILE__, __LINE__); + return -1; + } + + dbus_message_iter_init_append (message, &iter); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key); + + dbus_error_init (&_error); + reply = dbus_connection_send_with_reply_and_block (ctx->connection, + message, -1, + &_error); + + dbus_move_error (&_error, error); + if (error != NULL && dbus_error_is_set (error)) { + dbus_message_unref (message); + return -1; + } + if (reply == NULL) { + dbus_message_unref (message); + return -1; + } + + dbus_message_iter_init (reply, &reply_iter); + + /* now analyze reply */ + if (dbus_message_iter_get_arg_type (&reply_iter) != + DBUS_TYPE_INT32) { + fprintf (stderr, + "%s %d : property '%s' for device '%s' is not " + "of type integer\n", __FILE__, __LINE__, key, + udi); + dbus_message_unref (message); + dbus_message_unref (reply); + return -1; + } + dbus_message_iter_get_basic (&reply_iter, &value); + + dbus_message_unref (message); + dbus_message_unref (reply); + return value; +} + +/** + * libhal_device_get_property_uint64: + * @ctx: the context for the connection to hald + * @udi: the Unique Device Id + * @key: name of the property + * @error: pointer to an initialized dbus error object for returning errors or NULL + * + * Get the value of a property of type signed integer. + * + * Returns: Property value (64-bit unsigned integer) + */ +dbus_uint64_t +libhal_device_get_property_uint64 (LibHalContext *ctx, + const char *udi, const char *key, DBusError *error) +{ + DBusMessage *message; + DBusMessage *reply; + DBusMessageIter iter, reply_iter; + dbus_uint64_t value; + DBusError _error; + + LIBHAL_CHECK_LIBHALCONTEXT(ctx, -1); + + message = dbus_message_new_method_call ("org.freedesktop.Hal", udi, + "org.freedesktop.Hal.Device", + "GetPropertyInteger"); + if (message == NULL) { + fprintf (stderr, + "%s %d : Couldn't allocate D-BUS message\n", + __FILE__, __LINE__); + return -1; + } + + dbus_message_iter_init_append (message, &iter); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key); + + dbus_error_init (&_error); + reply = dbus_connection_send_with_reply_and_block (ctx->connection, + message, -1, + &_error); + + dbus_move_error (&_error, error); + if (error != NULL && dbus_error_is_set (error)) { + dbus_message_unref (message); + return -1; + } + if (reply == NULL) { + dbus_message_unref (message); + return -1; + } + + dbus_message_iter_init (reply, &reply_iter); + /* now analyze reply */ + if (dbus_message_iter_get_arg_type (&reply_iter) != + DBUS_TYPE_UINT64) { + fprintf (stderr, + "%s %d : property '%s' for device '%s' is not " + "of type integer\n", __FILE__, __LINE__, key, + udi); + dbus_message_unref (message); + dbus_message_unref (reply); + return -1; + } + dbus_message_iter_get_basic (&reply_iter, &value); + + dbus_message_unref (message); + dbus_message_unref (reply); + return value; +} + +/** + * libhal_device_get_property_double: + * @ctx: the context for the connection to hald + * @udi: the Unique Device Id + * @key: name of the property + * @error: pointer to an initialized dbus error object for returning errors or NULL + * + * Get the value of a property of type double. + * + * Returns: Property value (IEEE754 double precision float) + */ +double +libhal_device_get_property_double (LibHalContext *ctx, + const char *udi, const char *key, DBusError *error) +{ + DBusMessage *message; + DBusMessage *reply; + DBusMessageIter iter, reply_iter; + double value; + DBusError _error; + + LIBHAL_CHECK_LIBHALCONTEXT(ctx, -1.0); + + message = dbus_message_new_method_call ("org.freedesktop.Hal", udi, + "org.freedesktop.Hal.Device", + "GetPropertyDouble"); + if (message == NULL) { + fprintf (stderr, + "%s %d : Couldn't allocate D-BUS message\n", + __FILE__, __LINE__); + return -1.0f; + } + + dbus_message_iter_init_append (message, &iter); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key); + + dbus_error_init (&_error); + reply = dbus_connection_send_with_reply_and_block (ctx->connection, + message, -1, + &_error); + + dbus_move_error (&_error, error); + if (error != NULL && dbus_error_is_set (error)) { + dbus_message_unref (message); + return -1.0f; + } + if (reply == NULL) { + dbus_message_unref (message); + return -1.0f; + } + + dbus_message_iter_init (reply, &reply_iter); + + /* now analyze reply */ + if (dbus_message_iter_get_arg_type (&reply_iter) != + DBUS_TYPE_DOUBLE) { + fprintf (stderr, + "%s %d : property '%s' for device '%s' is not " + "of type double\n", __FILE__, __LINE__, key, udi); + dbus_message_unref (message); + dbus_message_unref (reply); + return -1.0f; + } + dbus_message_iter_get_basic (&reply_iter, &value); + + dbus_message_unref (message); + dbus_message_unref (reply); + return (double) value; +} + +/** + * libhal_device_get_property_bool: + * @ctx: the context for the connection to hald + * @udi: the Unique Device Id + * @key: name of the property + * @error: pointer to an initialized dbus error object for returning errors or NULL + * + * Get the value of a property of type bool. + * + * Returns: Property value (boolean) + */ +dbus_bool_t +libhal_device_get_property_bool (LibHalContext *ctx, + const char *udi, const char *key, DBusError *error) +{ + DBusMessage *message; + DBusMessage *reply; + DBusMessageIter iter, reply_iter; + dbus_bool_t value; + DBusError _error; + + LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); + + message = dbus_message_new_method_call ("org.freedesktop.Hal", udi, + "org.freedesktop.Hal.Device", + "GetPropertyBoolean"); + if (message == NULL) { + fprintf (stderr, + "%s %d : Couldn't allocate D-BUS message\n", + __FILE__, __LINE__); + return FALSE; + } + + dbus_message_iter_init_append (message, &iter); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key); + + dbus_error_init (&_error); + reply = dbus_connection_send_with_reply_and_block (ctx->connection, + message, -1, + &_error); + + dbus_move_error (&_error, error); + if (error != NULL && dbus_error_is_set (error)) { + dbus_message_unref (message); + return FALSE; + } + if (reply == NULL) { + dbus_message_unref (message); + return FALSE; + } + + dbus_message_iter_init (reply, &reply_iter); + + /* now analyze reply */ + if (dbus_message_iter_get_arg_type (&reply_iter) != + DBUS_TYPE_BOOLEAN) { + fprintf (stderr, + "%s %d : property '%s' for device '%s' is not " + "of type bool\n", __FILE__, __LINE__, key, udi); + dbus_message_unref (message); + dbus_message_unref (reply); + return FALSE; + } + dbus_message_iter_get_basic (&reply_iter, &value); + + dbus_message_unref (message); + dbus_message_unref (reply); + return value; +} + + +/* generic helper */ +static dbus_bool_t +libhal_device_set_property_helper (LibHalContext *ctx, + const char *udi, + const char *key, + int type, + const char *str_value, + dbus_int32_t int_value, + dbus_uint64_t uint64_value, + double double_value, + dbus_bool_t bool_value, + DBusError *error) +{ + DBusMessage *message; + DBusMessage *reply; + DBusMessageIter iter; + char *method_name = NULL; + + LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); + + /** @todo sanity check incoming params */ + switch (type) { + case DBUS_TYPE_INVALID: + method_name = "RemoveProperty"; + break; + case DBUS_TYPE_STRING: + method_name = "SetPropertyString"; + break; + case DBUS_TYPE_INT32: + case DBUS_TYPE_UINT64: + method_name = "SetPropertyInteger"; + break; + case DBUS_TYPE_DOUBLE: + method_name = "SetPropertyDouble"; + break; + case DBUS_TYPE_BOOLEAN: + method_name = "SetPropertyBoolean"; + break; + + default: + /* cannot happen; is not callable from outside this file */ + break; + } + + message = dbus_message_new_method_call ("org.freedesktop.Hal", udi, + "org.freedesktop.Hal.Device", + method_name); + if (message == NULL) { + fprintf (stderr, + "%s %d : Couldn't allocate D-BUS message\n", + __FILE__, __LINE__); + return FALSE; + } + + dbus_message_iter_init_append (message, &iter); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key); + switch (type) { + case DBUS_TYPE_STRING: + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &str_value); + break; + case DBUS_TYPE_INT32: + dbus_message_iter_append_basic (&iter, DBUS_TYPE_INT32, &int_value); + break; + case DBUS_TYPE_UINT64: + dbus_message_iter_append_basic (&iter, DBUS_TYPE_UINT64, &uint64_value); + break; + case DBUS_TYPE_DOUBLE: + dbus_message_iter_append_basic (&iter, DBUS_TYPE_DOUBLE, &double_value); + break; + case DBUS_TYPE_BOOLEAN: + dbus_message_iter_append_basic (&iter, DBUS_TYPE_BOOLEAN, &bool_value); + break; + } + + + reply = dbus_connection_send_with_reply_and_block (ctx->connection, + message, -1, + error); + if (dbus_error_is_set (error)) { + dbus_message_unref (message); + return FALSE; + } + + if (reply == NULL) { + dbus_message_unref (message); + return FALSE; + } + + dbus_message_unref (message); + dbus_message_unref (reply); + + return TRUE; +} + +/** + * libhal_device_set_property_string: + * @ctx: the context for the connection to hald + * @udi: the Unique Device Id + * @key: name of the property + * @value: value of the property; a UTF8 string + * @error: pointer to an initialized dbus error object for returning errors or NULL + * + * Set a property of type string. + * + * Returns: TRUE if the property was set, FALSE if the device didn't + * exist or the property had a different type. + */ +dbus_bool_t +libhal_device_set_property_string (LibHalContext *ctx, + const char *udi, + const char *key, + const char *value, + DBusError *error) +{ + return libhal_device_set_property_helper (ctx, udi, key, + DBUS_TYPE_STRING, + value, 0, 0, 0.0f, FALSE, error); +} + +/** + * libhal_device_set_property_int: + * @ctx: the context for the connection to hald + * @udi: the Unique Device Id + * @key: name of the property + * @value: value of the property + * @error: pointer to an initialized dbus error object for returning errors or NULL + * + * Set a property of type signed integer. + * + * Returns: TRUE if the property was set, FALSE if the device didn't + * exist or the property had a different type. + */ +dbus_bool_t +libhal_device_set_property_int (LibHalContext *ctx, const char *udi, + const char *key, dbus_int32_t value, DBusError *error) +{ + return libhal_device_set_property_helper (ctx, udi, key, + DBUS_TYPE_INT32, + NULL, value, 0, 0.0f, FALSE, error); +} + +/** + * libhal_device_set_property_uint64: + * @ctx: the context for the connection to hald + * @udi: the Unique Device Id + * @key: name of the property + * @value: value of the property + * @error: pointer to an initialized dbus error object for returning errors or NULL + * + * Set a property of type unsigned integer. + * + * Returns: TRUE if the property was set, FALSE if the device didn't + * exist or the property had a different type. + */ +dbus_bool_t +libhal_device_set_property_uint64 (LibHalContext *ctx, const char *udi, + const char *key, dbus_uint64_t value, DBusError *error) +{ + return libhal_device_set_property_helper (ctx, udi, key, + DBUS_TYPE_UINT64, + NULL, 0, value, 0.0f, FALSE, error); +} + +/** + * libhal_device_set_property_double: + * @ctx: the context for the connection to hald + * @udi: the Unique Device Id + * @key: name of the property + * @value: value of the property + * @error: pointer to an initialized dbus error object for returning errors or NULL + * + * Set a property of type double. + * + * Returns: TRUE if the property was set, FALSE if the device didn't + * exist or the property had a different type. + */ +dbus_bool_t +libhal_device_set_property_double (LibHalContext *ctx, const char *udi, + const char *key, double value, DBusError *error) +{ + return libhal_device_set_property_helper (ctx, udi, key, + DBUS_TYPE_DOUBLE, + NULL, 0, 0, value, FALSE, error); +} + +/** + * libhal_device_set_property_bool: + * @ctx: the context for the connection to hald + * @udi: the Unique Device Id + * @key: name of the property + * @value: value of the property + * @error: pointer to an initialized dbus error object for returning errors or NULL + * + * Set a property of type bool. + * + * Returns: TRUE if the property was set, FALSE if the device didn't + * exist or the property had a different type. + */ +dbus_bool_t +libhal_device_set_property_bool (LibHalContext *ctx, const char *udi, + const char *key, dbus_bool_t value, DBusError *error) +{ + return libhal_device_set_property_helper (ctx, udi, key, + DBUS_TYPE_BOOLEAN, + NULL, 0, 0, 0.0f, value, error); +} + + +/** + * libhal_device_remove_property: + * @ctx: the context for the connection to hald + * @udi: the Unique Device Id + * @key: name of the property + * @error: pointer to an initialized dbus error object for returning errors or NULL + * + * Remove a property. + * + * Returns: TRUE if the property was set, FALSE if the device didn't + * exist + */ +dbus_bool_t +libhal_device_remove_property (LibHalContext *ctx, + const char *udi, const char *key, DBusError *error) +{ + return libhal_device_set_property_helper (ctx, udi, key, DBUS_TYPE_INVALID, + /* DBUS_TYPE_INVALID means remove */ + NULL, 0, 0, 0.0f, FALSE, error); +} + +/** + * libhal_device_property_strlist_append: + * @ctx: the context for the connection to hald + * @udi: the Unique Device Id + * @key: name of the property + * @value: value to append to property + * @error: pointer to an initialized dbus error object for returning errors or NULL + * + * Append to a property of type strlist. + * + * Returns: TRUE if the value was appended, FALSE if the device didn't + * exist or the property had a different type. + */ +dbus_bool_t +libhal_device_property_strlist_append (LibHalContext *ctx, + const char *udi, + const char *key, + const char *value, + DBusError *error) +{ + DBusMessage *message; + DBusMessage *reply; + DBusMessageIter iter; + + LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); + + message = dbus_message_new_method_call ("org.freedesktop.Hal", udi, + "org.freedesktop.Hal.Device", + "StringListAppend"); + if (message == NULL) { + fprintf (stderr, + "%s %d : Couldn't allocate D-BUS message\n", + __FILE__, __LINE__); + return FALSE; + } + dbus_message_iter_init_append (message, &iter); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &value); + + reply = dbus_connection_send_with_reply_and_block (ctx->connection, + message, -1, + error); + if (dbus_error_is_set (error)) { + dbus_message_unref (message); + return FALSE; + } + if (reply == NULL) { + dbus_message_unref (message); + return FALSE; + } + return TRUE; +} + +/** + * libhal_device_property_strlist_prepend: + * @ctx: the context for the connection to hald + * @udi: the Unique Device Id + * @key: name of the property + * @value: value to prepend to property + * @error: pointer to an initialized dbus error object for returning errors or NULL + * + * Prepend to a property of type strlist. + * + * Returns: TRUE if the value was prepended, FALSE if the device + * didn't exist or the property had a different type. + */ +dbus_bool_t +libhal_device_property_strlist_prepend (LibHalContext *ctx, + const char *udi, + const char *key, + const char *value, + DBusError *error) +{ + DBusMessage *message; + DBusMessage *reply; + DBusMessageIter iter; + + LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); + + message = dbus_message_new_method_call ("org.freedesktop.Hal", udi, + "org.freedesktop.Hal.Device", + "StringListPrepend"); + if (message == NULL) { + fprintf (stderr, + "%s %d : Couldn't allocate D-BUS message\n", + __FILE__, __LINE__); + return FALSE; + } + dbus_message_iter_init_append (message, &iter); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &value); + + reply = dbus_connection_send_with_reply_and_block (ctx->connection, + message, -1, + error); + if (dbus_error_is_set (error)) { + dbus_message_unref (message); + return FALSE; + } + if (reply == NULL) { + dbus_message_unref (message); + return FALSE; + } + return TRUE; +} + +/** + * libhal_device_property_strlist_remove_index: + * @ctx: the context for the connection to hald + * @udi: the Unique Device Id + * @key: name of the property + * @idx: index of string to remove in the strlist + * @error: pointer to an initialized dbus error object for returning errors or NULL + * + * Remove a specified string from a property of type strlist. + * + * Returns: TRUE if the string was removed, FALSE if the device didn't + * exist or the property had a different type. + */ +dbus_bool_t +libhal_device_property_strlist_remove_index (LibHalContext *ctx, + const char *udi, + const char *key, + unsigned int idx, + DBusError *error) +{ + DBusMessage *message; + DBusMessage *reply; + DBusMessageIter iter; + + LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); + + message = dbus_message_new_method_call ("org.freedesktop.Hal", udi, + "org.freedesktop.Hal.Device", + "StringListRemoveIndex"); + if (message == NULL) { + fprintf (stderr, + "%s %d : Couldn't allocate D-BUS message\n", + __FILE__, __LINE__); + return FALSE; + } + dbus_message_iter_init_append (message, &iter); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_UINT32, &idx); + + reply = dbus_connection_send_with_reply_and_block (ctx->connection, + message, -1, + error); + if (dbus_error_is_set (error)) { + dbus_message_unref (message); + return FALSE; + } + if (reply == NULL) { + dbus_message_unref (message); + return FALSE; + } + return TRUE; +} + +/** + * libhal_device_property_strlist_remove: + * @ctx: the context for the connection to hald + * @udi: the Unique Device Id + * @key: name of the property + * @value: the string to remove + * @error: pointer to an initialized dbus error object for returning errors or NULL + * + * Remove a specified string from a property of type strlist. + * + * Returns: TRUE if the string was removed, FALSE if the device didn't + * exist or the property had a different type. + */ +dbus_bool_t +libhal_device_property_strlist_remove (LibHalContext *ctx, + const char *udi, + const char *key, + const char *value, DBusError *error) +{ + DBusMessage *message; + DBusMessage *reply; + DBusMessageIter iter; + + LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); + + message = dbus_message_new_method_call ("org.freedesktop.Hal", udi, + "org.freedesktop.Hal.Device", + "StringListRemove"); + if (message == NULL) { + fprintf (stderr, + "%s %d : Couldn't allocate D-BUS message\n", + __FILE__, __LINE__); + return FALSE; + } + dbus_message_iter_init_append (message, &iter); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &value); + + reply = dbus_connection_send_with_reply_and_block (ctx->connection, + message, -1, + error); + if (dbus_error_is_set (error)) { + dbus_message_unref (message); + return FALSE; + } + if (reply == NULL) { + dbus_message_unref (message); + return FALSE; + } + return TRUE; +} + + +/** + * libhal_device_lock: + * @ctx: the context for the connection to hald + * @udi: the Unique Device Id + * @reason_to_lock: a user-presentable reason why the device is locked. + * @reason_why_locked: a pointer to store the reason why the device cannot be locked on failure, or NULL + * @error: pointer to an initialized dbus error object for returning errors or NULL + * + * Take an advisory lock on the device. + * + * Returns: TRUE if the lock was obtained, FALSE otherwise + */ +dbus_bool_t +libhal_device_lock (LibHalContext *ctx, + const char *udi, + const char *reason_to_lock, + char **reason_why_locked, DBusError *error) +{ + DBusMessage *message; + DBusMessageIter iter; + DBusMessage *reply; + + LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); + + if (reason_why_locked != NULL) + *reason_why_locked = NULL; + + message = dbus_message_new_method_call ("org.freedesktop.Hal", + udi, + "org.freedesktop.Hal.Device", + "Lock"); + + if (message == NULL) { + fprintf (stderr, + "%s %d : Couldn't allocate D-BUS message\n", + __FILE__, __LINE__); + return FALSE; + } + + dbus_message_iter_init_append (message, &iter); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &reason_to_lock); + + + reply = dbus_connection_send_with_reply_and_block (ctx->connection, + message, -1, + error); + + if (dbus_error_is_set (error)) { + if (strcmp (error->name, + "org.freedesktop.Hal.DeviceAlreadyLocked") == 0) { + if (reason_why_locked != NULL) { + *reason_why_locked = + dbus_malloc0 (strlen (error->message) + 1); + strcpy (*reason_why_locked, error->message); + } + } + + dbus_message_unref (message); + return FALSE; + } + + dbus_message_unref (message); + + if (reply == NULL) + return FALSE; + + dbus_message_unref (reply); + + return TRUE; +} + +/** + * libhal_device_unlock: + * @ctx: the context for the connection to hald + * @udi: the Unique Device Id + * @error: pointer to an initialized dbus error object for returning errors or NULL + * + * Release an advisory lock on the device. + * + * Returns: TRUE if the device was successfully unlocked, + * FALSE otherwise + */ +dbus_bool_t +libhal_device_unlock (LibHalContext *ctx, + const char *udi, DBusError *error) +{ + DBusMessage *message; + DBusMessage *reply; + + LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); + + message = dbus_message_new_method_call ("org.freedesktop.Hal", + udi, + "org.freedesktop.Hal.Device", + "Unlock"); + + if (message == NULL) { + fprintf (stderr, + "%s %d : Couldn't allocate D-BUS message\n", + __FILE__, __LINE__); + return FALSE; + } + + + reply = dbus_connection_send_with_reply_and_block (ctx->connection, + message, -1, + error); + + if (dbus_error_is_set (error)) { + dbus_message_unref (message); + return FALSE; + } + + dbus_message_unref (message); + + if (reply == NULL) + return FALSE; + + dbus_message_unref (reply); + + return TRUE; +} + + +/** + * libhal_new_device: + * @ctx: the context for the connection to hald + * @error: pointer to an initialized dbus error object for returning errors or NULL + * + * Create a new device object which will be hidden from applications + * until the CommitToGdl(), ie. libhal_device_commit_to_gdl(), method + * is called. Note that the program invoking this method needs to run + * with super user privileges. + * + * Returns: Temporary device unique id or NULL if there was a + * problem. This string must be freed by the caller. + */ +char * +libhal_new_device (LibHalContext *ctx, DBusError *error) +{ + DBusMessage *message; + DBusMessage *reply; + DBusMessageIter reply_iter; + char *value; + char *dbus_str; + + LIBHAL_CHECK_LIBHALCONTEXT(ctx, NULL); + + message = dbus_message_new_method_call ("org.freedesktop.Hal", + "/org/freedesktop/Hal/Manager", + "org.freedesktop.Hal.Manager", + "NewDevice"); + if (message == NULL) { + fprintf (stderr, + "%s %d : Couldn't allocate D-BUS message\n", + __FILE__, __LINE__); + return NULL; + } + + + reply = dbus_connection_send_with_reply_and_block (ctx->connection, + message, -1, + error); + if (dbus_error_is_set (error)) { + dbus_message_unref (message); + return NULL; + } + if (reply == NULL) { + dbus_message_unref (message); + return NULL; + } + + dbus_message_iter_init (reply, &reply_iter); + + /* now analyze reply */ + if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_STRING) { + fprintf (stderr, + "%s %d : expected a string in reply to NewDevice\n", + __FILE__, __LINE__); + dbus_message_unref (message); + dbus_message_unref (reply); + return NULL; + } + + dbus_message_iter_get_basic (&reply_iter, &dbus_str); + value = (char *) ((dbus_str != NULL) ? strdup (dbus_str) : NULL); + if (value == NULL) { + fprintf (stderr, "%s %d : error allocating memory\n", + __FILE__, __LINE__); + } + + dbus_message_unref (message); + dbus_message_unref (reply); + return value; +} + + +/** + * libhal_device_commit_to_gdl: + * @ctx: the context for the connection to hald + * @temp_udi: the temporary unique device id as returned by libhal_new_device() + * @udi: the new unique device id. + * @error: pointer to an initialized dbus error object for returning errors or NULL + * + * When a hidden device has been built using the NewDevice method, + * ie. libhal_new_device(), and the org.freedesktop.Hal.Device + * interface this function will commit it to the global device list. + * + * This means that the device object will be visible to applications + * and the HAL daemon will possibly attempt to boot the device + * (depending on the property RequireEnable). + * + * Note that the program invoking this method needs to run with super + * user privileges. + * + * Returns: FALSE if the given unique device id is already in use. + */ +dbus_bool_t +libhal_device_commit_to_gdl (LibHalContext *ctx, + const char *temp_udi, const char *udi, DBusError *error) +{ + DBusMessage *message; + DBusMessage *reply; + DBusMessageIter iter; + + LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); + + message = dbus_message_new_method_call ("org.freedesktop.Hal", + "/org/freedesktop/Hal/Manager", + "org.freedesktop.Hal.Manager", + "CommitToGdl"); + if (message == NULL) { + fprintf (stderr, + "%s %d : Couldn't allocate D-BUS message\n", + __FILE__, __LINE__); + return FALSE; + } + + dbus_message_iter_init_append (message, &iter); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &temp_udi); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &udi); + + + reply = dbus_connection_send_with_reply_and_block (ctx->connection, + message, -1, + error); + if (dbus_error_is_set (error)) { + dbus_message_unref (message); + return FALSE; + } + if (reply == NULL) { + dbus_message_unref (message); + return FALSE; + } + + dbus_message_unref (message); + dbus_message_unref (reply); + return TRUE; +} + +/** + * libhal_remove_device: + * @ctx: the context for the connection to hald + * @udi: the Unique device id. + * @error: pointer to an initialized dbus error object for returning errors or NULL + * + * This method can be invoked when a device is removed. The HAL daemon + * will shut down the device. Note that the device may still be in the + * device list if the Persistent property is set to true. + * + * Note that the program invoking this method needs to run with super + * user privileges. + * + * Returns: TRUE if the device was removed, FALSE otherwise + */ +dbus_bool_t +libhal_remove_device (LibHalContext *ctx, const char *udi, DBusError *error) +{ + DBusMessage *message; + DBusMessage *reply; + DBusMessageIter iter; + + LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); + + message = dbus_message_new_method_call ("org.freedesktop.Hal", + "/org/freedesktop/Hal/Manager", + "org.freedesktop.Hal.Manager", + "Remove"); + if (message == NULL) { + fprintf (stderr, + "%s %d : Couldn't allocate D-BUS message\n", + __FILE__, __LINE__); + return FALSE; + } + + dbus_message_iter_init_append (message, &iter); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &udi); + + + reply = dbus_connection_send_with_reply_and_block (ctx->connection, + message, -1, + error); + if (dbus_error_is_set (error)) { + dbus_message_unref (message); + return FALSE; + } + if (reply == NULL) { + dbus_message_unref (message); + return FALSE; + } + + dbus_message_unref (message); + dbus_message_unref (reply); + return TRUE; +} + +/** + * libhal_device_exists: + * @ctx: the context for the connection to hald + * @udi: the Unique device id. + * @error: pointer to an initialized dbus error object for returning errors or NULL + * + * Determine if a device exists. + * + * Returns: TRUE if the device exists + */ +dbus_bool_t +libhal_device_exists (LibHalContext *ctx, const char *udi, DBusError *error) +{ + DBusMessage *message; + DBusMessage *reply; + DBusMessageIter iter, reply_iter; + dbus_bool_t value; + DBusError _error; + + LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); + + message = dbus_message_new_method_call ("org.freedesktop.Hal", + "/org/freedesktop/Hal/Manager", + "org.freedesktop.Hal.Manager", + "DeviceExists"); + if (message == NULL) { + fprintf (stderr, + "%s %d : Couldn't allocate D-BUS message\n", + __FILE__, __LINE__); + return FALSE; + } + + dbus_message_iter_init_append (message, &iter); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &udi); + + dbus_error_init (&_error); + reply = dbus_connection_send_with_reply_and_block (ctx->connection, + message, -1, + &_error); + + dbus_move_error (&_error, error); + if (error != NULL && dbus_error_is_set (error)) { + dbus_message_unref (message); + return FALSE; + } + if (reply == NULL) { + dbus_message_unref (message); + return FALSE; + } + + dbus_message_iter_init (reply, &reply_iter); + + /* now analyze reply */ + if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_BOOLEAN) { + fprintf (stderr, + "%s %d : expected a bool in reply to DeviceExists\n", + __FILE__, __LINE__); + dbus_message_unref (message); + dbus_message_unref (reply); + return FALSE; + } + + dbus_message_iter_get_basic (&reply_iter, &value); + + dbus_message_unref (message); + dbus_message_unref (reply); + return value; +} + +/** + * libhal_device_property_exists: + * @ctx: the context for the connection to hald + * @udi: the Unique device id. + * @key: name of the property + * @error: pointer to an initialized dbus error object for returning errors or NULL + * + * Determine if a property on a device exists. + * + * Returns: TRUE if the device exists, FALSE otherwise + */ +dbus_bool_t +libhal_device_property_exists (LibHalContext *ctx, + const char *udi, const char *key, DBusError *error) +{ + DBusMessage *message; + DBusMessage *reply; + DBusMessageIter iter, reply_iter; + dbus_bool_t value; + DBusError _error; + + LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); + + message = dbus_message_new_method_call ("org.freedesktop.Hal", udi, + "org.freedesktop.Hal.Device", + "PropertyExists"); + if (message == NULL) { + fprintf (stderr, + "%s %d : Couldn't allocate D-BUS message\n", + __FILE__, __LINE__); + return FALSE; + } + + dbus_message_iter_init_append (message, &iter); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key); + + dbus_error_init (&_error); + reply = dbus_connection_send_with_reply_and_block (ctx->connection, + message, -1, + &_error); + + dbus_move_error (&_error, error); + if (error != NULL && dbus_error_is_set (error)) { + dbus_message_unref (message); + return FALSE; + } + if (reply == NULL) { + dbus_message_unref (message); + return FALSE; + } + + dbus_message_iter_init (reply, &reply_iter); + + /* now analyse reply */ + if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_BOOLEAN) { + fprintf (stderr, "%s %d : expected a bool in reply to " + "PropertyExists\n", __FILE__, __LINE__); + dbus_message_unref (message); + dbus_message_unref (reply); + return FALSE; + } + + dbus_message_iter_get_basic (&reply_iter, &value); + + dbus_message_unref (message); + dbus_message_unref (reply); + return value; +} + +/** + * libhal_merge_properties: + * @ctx: the context for the connection to hald + * @target_udi: the Unique device id of target device to merge to + * @source_udi: the Unique device id of device to merge from + * @error: pointer to an initialized dbus error object for returning errors or NULL + * + * Merge properties from one device to another. + * + * Returns: TRUE if the properties were merged, FALSE otherwise + */ +dbus_bool_t +libhal_merge_properties (LibHalContext *ctx, + const char *target_udi, const char *source_udi, DBusError *error) +{ + DBusMessage *message; + DBusMessage *reply; + DBusMessageIter iter; + + LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); + + message = dbus_message_new_method_call ("org.freedesktop.Hal", + "/org/freedesktop/Hal/Manager", + "org.freedesktop.Hal.Manager", + "MergeProperties"); + if (message == NULL) { + fprintf (stderr, + "%s %d : Couldn't allocate D-BUS message\n", + __FILE__, __LINE__); + return FALSE; + } + + dbus_message_iter_init_append (message, &iter); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &target_udi); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &source_udi); + + + reply = dbus_connection_send_with_reply_and_block (ctx->connection, + message, -1, + error); + if (dbus_error_is_set (error)) { + dbus_message_unref (message); + return FALSE; + } + if (reply == NULL) { + dbus_message_unref (message); + return FALSE; + } + + dbus_message_unref (message); + dbus_message_unref (reply); + return TRUE; +} + +/** + * libhal_device_matches: + * @ctx: the context for the connection to hald + * @udi1: the Unique Device Id for device 1 + * @udi2: the Unique Device Id for device 2 + * @property_namespace: the namespace for set of devices, e.g. "usb" + * @error: pointer to an initialized dbus error object for returning errors or NULL + * + * Check a set of properties for two devices matches. + * + * Checks that all properties where keys, starting with a given value + * (namespace), of the first device is in the second device and that + * they got the same value and type. + * + * Note that the other inclusion isn't tested, so there could be + * properties (from the given namespace) in the second device not + * present in the first device. + * + * Returns: TRUE if all properties starting with the given namespace + * parameter from one device is in the other and have the same value. + */ +dbus_bool_t +libhal_device_matches (LibHalContext *ctx, + const char *udi1, const char *udi2, + const char *property_namespace, DBusError *error) +{ + DBusMessage *message; + DBusMessage *reply; + DBusMessageIter iter, reply_iter; + dbus_bool_t value; + DBusError _error; + + LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); + + message = dbus_message_new_method_call ("org.freedesktop.Hal", + "/org/freedesktop/Hal/Manager", + "org.freedesktop.Hal.Manager", + "DeviceMatches"); + if (message == NULL) { + fprintf (stderr, + "%s %d : Couldn't allocate D-BUS message\n", + __FILE__, __LINE__); + return FALSE; + } + + dbus_message_iter_init_append (message, &iter); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, udi1); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, udi2); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, property_namespace); + + dbus_error_init (&_error); + reply = dbus_connection_send_with_reply_and_block (ctx->connection, + message, -1, + &_error); + + dbus_move_error (&_error, error); + if (error != NULL && dbus_error_is_set (error)) { + dbus_message_unref (message); + return FALSE; + } + if (reply == NULL) { + dbus_message_unref (message); + return FALSE; + } + /* now analyse reply */ + dbus_message_iter_init (reply, &reply_iter); + + if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_BOOLEAN) { + fprintf (stderr, + "%s %d : expected a bool in reply to DeviceMatches\n", + __FILE__, __LINE__); + dbus_message_unref (message); + dbus_message_unref (reply); + return FALSE; + } + + dbus_message_iter_get_basic (&reply_iter, &value); + + dbus_message_unref (message); + dbus_message_unref (reply); + return value; +} + +/** + * libhal_device_print: + * @ctx: the context for the connection to hald + * @udi: the Unique Device Id + * @error: pointer to an initialized dbus error object for returning errors or NULL + * + * Print a device to stdout; useful for debugging. + * + * Returns: TRUE if device's information could be obtained, FALSE otherwise + */ +dbus_bool_t +libhal_device_print (LibHalContext *ctx, const char *udi, DBusError *error) +{ + int type; + char *key; + LibHalPropertySet *pset; + LibHalPropertySetIterator i; + + LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); + + printf ("device_id = %s\n", udi); + + if ((pset = libhal_device_get_all_properties (ctx, udi, error)) == NULL) + return FALSE; + + for (libhal_psi_init (&i, pset); libhal_psi_has_more (&i); + libhal_psi_next (&i)) { + type = libhal_psi_get_type (&i); + key = libhal_psi_get_key (&i); + + switch (type) { + case LIBHAL_PROPERTY_TYPE_STRING: + printf (" %s = '%s' (string)\n", key, + libhal_psi_get_string (&i)); + break; + case LIBHAL_PROPERTY_TYPE_INT32: + printf (" %s = %d = 0x%x (int)\n", key, + libhal_psi_get_int (&i), + libhal_psi_get_int (&i)); + break; + case LIBHAL_PROPERTY_TYPE_UINT64: + printf (" %s = %llu = 0x%llx (uint64)\n", key, + (long long unsigned int) libhal_psi_get_uint64 (&i), + (long long unsigned int) libhal_psi_get_uint64 (&i)); + break; + case LIBHAL_PROPERTY_TYPE_BOOLEAN: + printf (" %s = %s (bool)\n", key, + (libhal_psi_get_bool (&i) ? "true" : + "false")); + break; + case LIBHAL_PROPERTY_TYPE_DOUBLE: + printf (" %s = %g (double)\n", key, + libhal_psi_get_double (&i)); + break; + case LIBHAL_PROPERTY_TYPE_STRLIST: + { + unsigned int j; + char **str_list; + + str_list = libhal_psi_get_strlist (&i); + printf (" %s = [", key); + for (j = 0; str_list[j] != NULL; j++) { + printf ("'%s'", str_list[j]); + if (str_list[j+1] != NULL) + printf (", "); + } + printf ("] (string list)\n"); + + break; + } + default: + printf (" *** unknown type for key %s\n", key); + break; + } + } + + libhal_free_property_set (pset); + + return TRUE; +} + +/** + * libhal_manager_find_device_string_match: + * @ctx: the context for the connection to hald + * @key: name of the property + * @value: the value to match + * @num_devices: pointer to store number of devices + * @error: pointer to an initialized dbus error object for returning errors or NULL + * + * Find a device in the GDL where a single string property matches a + * given value. + * + * Returns: UDI of devices; free with libhal_free_string_array() + */ +char ** +libhal_manager_find_device_string_match (LibHalContext *ctx, + const char *key, + const char *value, int *num_devices, DBusError *error) +{ + DBusMessage *message; + DBusMessage *reply; + DBusMessageIter iter, iter_array, reply_iter; + char **hal_device_names; + DBusError _error; + + LIBHAL_CHECK_LIBHALCONTEXT(ctx, NULL); + + message = dbus_message_new_method_call ("org.freedesktop.Hal", + "/org/freedesktop/Hal/Manager", + "org.freedesktop.Hal.Manager", + "FindDeviceStringMatch"); + if (message == NULL) { + fprintf (stderr, + "%s %d : Couldn't allocate D-BUS message\n", + __FILE__, __LINE__); + return NULL; + } + + dbus_message_iter_init_append (message, &iter); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &value); + + dbus_error_init (&_error); + reply = dbus_connection_send_with_reply_and_block (ctx->connection, + message, -1, + &_error); + + dbus_move_error (&_error, error); + if (error != NULL && dbus_error_is_set (error)) { + dbus_message_unref (message); + return NULL; + } + if (reply == NULL) { + dbus_message_unref (message); + return NULL; + } + /* now analyse reply */ + dbus_message_iter_init (reply, &reply_iter); + + if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_ARRAY) { + fprintf (stderr, "%s %d : wrong reply from hald. Expecting an array.\n", __FILE__, __LINE__); + return NULL; + } + + dbus_message_iter_recurse (&reply_iter, &iter_array); + + hal_device_names = libhal_get_string_array_from_iter (&iter_array, num_devices); + + dbus_message_unref (reply); + dbus_message_unref (message); + + return hal_device_names; +} + + +/** + * libhal_device_add_capability: + * @ctx: the context for the connection to hald + * @udi: the Unique Device Id + * @capability: the capability name to add + * @error: pointer to an initialized dbus error object for returning errors or NULL + * + * Assign a capability to a device. + * + * Returns: TRUE if the capability was added, FALSE if the device didn't exist + */ +dbus_bool_t +libhal_device_add_capability (LibHalContext *ctx, + const char *udi, const char *capability, DBusError *error) +{ + DBusMessage *message; + DBusMessage *reply; + DBusMessageIter iter; + + LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); + + message = dbus_message_new_method_call ("org.freedesktop.Hal", udi, + "org.freedesktop.Hal.Device", + "AddCapability"); + if (message == NULL) { + fprintf (stderr, + "%s %d : Couldn't allocate D-BUS message\n", + __FILE__, __LINE__); + return FALSE; + } + + dbus_message_iter_init_append (message, &iter); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &capability); + + + reply = dbus_connection_send_with_reply_and_block (ctx->connection, + message, -1, + error); + if (dbus_error_is_set (error)) { + dbus_message_unref (message); + return FALSE; + } + + if (reply == NULL) { + dbus_message_unref (message); + return FALSE; + } + + dbus_message_unref (reply); + dbus_message_unref (message); + return TRUE; +} + +/** + * libhal_device_query_capability: + * @ctx: the context for the connection to hald + * @udi: the Unique Device Id + * @capability: the capability name + * @error: pointer to an initialized dbus error object for returning errors or NULL + * + * Check if a device has a capability. The result is undefined if the + * device doesn't exist. + * + * Returns: TRUE if the device has the capability, otherwise FALSE + */ +dbus_bool_t +libhal_device_query_capability (LibHalContext *ctx, const char *udi, const char *capability, DBusError *error) +{ + char **caps; + unsigned int i; + dbus_bool_t ret; + + LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); + + ret = FALSE; + + caps = libhal_device_get_property_strlist (ctx, udi, "info.capabilities", error); + if (caps != NULL) { + for (i = 0; caps[i] != NULL; i++) { + if (strcmp (caps[i], capability) == 0) { + ret = TRUE; + break; + } + } + libhal_free_string_array (caps); + } + + return ret; +} + +/** + * libhal_find_device_by_capability: + * @ctx: the context for the connection to hald + * @capability: the capability name + * @num_devices: pointer to store number of devices + * @error: pointer to an initialized dbus error object for returning errors or NULL + * + * Find devices with a given capability. + * + * Returns: UDI of devices; free with libhal_free_string_array() + */ +char ** +libhal_find_device_by_capability (LibHalContext *ctx, + const char *capability, int *num_devices, DBusError *error) +{ + DBusMessage *message; + DBusMessage *reply; + DBusMessageIter iter, iter_array, reply_iter; + char **hal_device_names; + DBusError _error; + + LIBHAL_CHECK_LIBHALCONTEXT(ctx, NULL); + + message = dbus_message_new_method_call ("org.freedesktop.Hal", + "/org/freedesktop/Hal/Manager", + "org.freedesktop.Hal.Manager", + "FindDeviceByCapability"); + if (message == NULL) { + fprintf (stderr, + "%s %d : Couldn't allocate D-BUS message\n", + __FILE__, __LINE__); + return NULL; + } + + dbus_message_iter_init_append (message, &iter); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &capability); + + dbus_error_init (&_error); + reply = dbus_connection_send_with_reply_and_block (ctx->connection, + message, -1, + &_error); + + dbus_move_error (&_error, error); + if (error != NULL && dbus_error_is_set (error)) { + dbus_message_unref (message); + return NULL; + } + if (reply == NULL) { + dbus_message_unref (message); + return NULL; + } + /* now analyse reply */ + dbus_message_iter_init (reply, &reply_iter); + + if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_ARRAY) { + fprintf (stderr, "%s %d : wrong reply from hald. Expecting an array.\n", __FILE__, __LINE__); + return NULL; + } + + dbus_message_iter_recurse (&reply_iter, &iter_array); + + hal_device_names = libhal_get_string_array_from_iter (&iter_array, num_devices); + + dbus_message_unref (reply); + dbus_message_unref (message); + + return hal_device_names; +} + +/** + * libhal_device_property_watch_all: + * @ctx: the context for the connection to hald + * @error: pointer to an initialized dbus error object for returning errors or NULL + * + * Watch all devices, ie. the device_property_changed callback is + * invoked when the properties on any device changes. + * + * Returns: TRUE only if the operation succeeded + */ +dbus_bool_t +libhal_device_property_watch_all (LibHalContext *ctx, DBusError *error) +{ + LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); + + dbus_bus_add_match (ctx->connection, + "type='signal'," + "interface='org.freedesktop.Hal.Device'," + "sender='org.freedesktop.Hal'", error); + if (dbus_error_is_set (error)) { + return FALSE; + } + return TRUE; +} + + +/** + * libhal_device_add_property_watch: + * @ctx: the context for the connection to hald + * @udi: the Unique Device Id + * @error: pointer to an initialized dbus error object for returning errors or NULL + * + * Add a watch on a device, so the device_property_changed callback is + * invoked when the properties on the given device changes. + * + * The application itself is responsible for deleting the watch, using + * libhal_device_remove_property_watch, if the device is removed. + * + * Returns: TRUE only if the operation succeeded + */ +dbus_bool_t +libhal_device_add_property_watch (LibHalContext *ctx, const char *udi, DBusError *error) +{ + char buf[512]; + + LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); + + snprintf (buf, 512, + "type='signal'," + "interface='org.freedesktop.Hal.Device'," + "sender='org.freedesktop.Hal'," "path=%s", udi); + + dbus_bus_add_match (ctx->connection, buf, error); + if (dbus_error_is_set (error)) { + return FALSE; + } + return TRUE; +} + + +/** + * libhal_device_remove_property_watch: + * @ctx: the context for the connection to hald + * @udi: the Unique Device Id + * @error: pointer to an initialized dbus error object for returning errors or NULL + * + * Remove a watch on a device. + * + * Returns: TRUE only if the operation succeeded + */ +dbus_bool_t +libhal_device_remove_property_watch (LibHalContext *ctx, const char *udi, DBusError *error) +{ + char buf[512]; + + LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); + + snprintf (buf, 512, + "type='signal'," + "interface='org.freedesktop.Hal.Device'," + "sender='org.freedesktop.Hal'," "path=%s", udi); + + dbus_bus_remove_match (ctx->connection, buf, error); + if (dbus_error_is_set (error)) { + return FALSE; + } + return TRUE; +} + + +/** + * libhal_ctx_new: + * + * Create a new LibHalContext + * + * Returns: a new uninitialized LibHalContext object + */ +LibHalContext * +libhal_ctx_new (void) +{ + LibHalContext *ctx; + + if (!libhal_already_initialized_once) { + bindtextdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR); + bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); + + libhal_already_initialized_once = TRUE; + } + + ctx = calloc (1, sizeof (LibHalContext)); + if (ctx == NULL) { + fprintf (stderr, + "%s %d : Failed to allocate %d bytes\n", + __FILE__, __LINE__, sizeof (LibHalContext)); + return NULL; + } + + ctx->is_initialized = FALSE; + ctx->is_shutdown = FALSE; + ctx->connection = NULL; + ctx->is_direct = FALSE; + + return ctx; +} + +/** + * libhal_ctx_set_cache: + * @ctx: context to enable/disable cache for + * @use_cache: whether or not to use cache + * + * Enable or disable caching. Note: Caching is not actually + * implemented yet. + * + * Returns: TRUE if cache was successfully enabled/disabled, FALSE otherwise + */ +dbus_bool_t +libhal_ctx_set_cache (LibHalContext *ctx, dbus_bool_t use_cache) +{ + LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); + + ctx->cache_enabled = use_cache; + return TRUE; +} + +/** + * libhal_ctx_set_dbus_connection: + * @ctx: context to set connection for + * @conn: DBus connection to use + * + * Set DBus connection to use to talk to hald. + * + * Returns: TRUE if connection was successfully set, FALSE otherwise + */ +dbus_bool_t +libhal_ctx_set_dbus_connection (LibHalContext *ctx, DBusConnection *conn) +{ + LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); + + if (conn == NULL) + return FALSE; + + ctx->connection = conn; + return TRUE; +} + +/** + * libhal_ctx_get_dbus_connection: + * @ctx: context to get connection for + * + * Get DBus connection used for talking to hald. + * + * Returns: DBus connection to use or NULL + */ +DBusConnection * +libhal_ctx_get_dbus_connection (LibHalContext *ctx) +{ + LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); + + return ctx->connection; +} + + +/** + * libhal_ctx_init: + * @ctx: Context for connection to hald (D-BUS connection should be set with libhal_ctx_set_dbus_connection) + * @error: pointer to an initialized dbus error object for returning errors or NULL + * + * Initialize the connection to hald. + * + * Returns: TRUE if initialization succeeds, FALSE otherwise + */ +dbus_bool_t +libhal_ctx_init (LibHalContext *ctx, DBusError *error) +{ + DBusError _error; + dbus_bool_t hald_exists; + + LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); + + if (ctx->connection == NULL) + return FALSE; + + dbus_error_init (&_error); + hald_exists = dbus_bus_name_has_owner (ctx->connection, "org.freedesktop.Hal", &_error); + dbus_move_error (&_error, error); + if (error != NULL && dbus_error_is_set (error)) { + return FALSE; + } + + if (!hald_exists) { + return FALSE; + } + + + if (!dbus_connection_add_filter (ctx->connection, filter_func, ctx, NULL)) { + return FALSE; + } + + dbus_bus_add_match (ctx->connection, + "type='signal'," + "interface='org.freedesktop.Hal.Manager'," + "sender='org.freedesktop.Hal'," + "path='/org/freedesktop/Hal/Manager'", &_error); + dbus_move_error (&_error, error); + if (error != NULL && dbus_error_is_set (error)) { + return FALSE; + } + ctx->is_initialized = TRUE; + ctx->is_direct = FALSE; + + return TRUE; +} + +/** + * libhal_ctx_init_direct: + * @error: pointer to an initialized dbus error object for returning errors or NULL + * + * Create an already initialized connection to hald. This function should only be used by HAL helpers. + * + * Returns: A pointer to an already initialized LibHalContext + */ +LibHalContext * +libhal_ctx_init_direct (DBusError *error) +{ + char *hald_addr; + LibHalContext *ctx; + DBusError _error; + + ctx = libhal_ctx_new (); + if (ctx == NULL) + goto out; + + if (((hald_addr = getenv ("HALD_DIRECT_ADDR"))) == NULL) { + libhal_ctx_free (ctx); + ctx = NULL; + goto out; + } + + dbus_error_init (&_error); + ctx->connection = dbus_connection_open (hald_addr, &_error); + dbus_move_error (&_error, error); + if (error != NULL && dbus_error_is_set (error)) { + libhal_ctx_free (ctx); + ctx = NULL; + goto out; + } + + ctx->is_initialized = TRUE; + ctx->is_direct = TRUE; + +out: + return ctx; +} + +/** + * libhal_ctx_shutdown: + * @ctx: the context for the connection to hald + * @error: pointer to an initialized dbus error object for returning errors or NULL + * + * Shut down a connection to hald. + * + * Returns: TRUE if connection successfully shut down, FALSE otherwise + */ +dbus_bool_t +libhal_ctx_shutdown (LibHalContext *ctx, DBusError *error) +{ + DBusError myerror; + + LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); + + if (ctx->is_direct) { + /* for some reason dbus_connection_set_exit_on_disconnect doesn't work yet so don't unref */ + /*dbus_connection_unref (ctx->connection);*/ + } else { + dbus_error_init (&myerror); + dbus_bus_remove_match (ctx->connection, + "type='signal'," + "interface='org.freedesktop.Hal.Manager'," + "sender='org.freedesktop.Hal'," + "path='/org/freedesktop/Hal/Manager'", &myerror); + if (dbus_error_is_set (&myerror)) { + dbus_move_error (&myerror, error); + fprintf (stderr, "%s %d : Error unsubscribing to signals, error=%s\n", + __FILE__, __LINE__, error->message); + /** @todo clean up */ + } + + /* TODO: remove other matches */ + + dbus_connection_remove_filter (ctx->connection, filter_func, ctx); + } + + ctx->is_initialized = FALSE; + + return TRUE; +} + +/** + * libhal_ctx_free: + * @ctx: pointer to a LibHalContext + * + * Free a LibHalContext resource. + * + * Returns: TRUE + */ +dbus_bool_t +libhal_ctx_free (LibHalContext *ctx) +{ + free (ctx); + return TRUE; +} + +/** + * libhal_ctx_set_device_added: + * @ctx: the context for the connection to hald + * @callback: the function to call when a device is added + * + * Set the callback for when a device is added + * + * Returns: TRUE if callback was successfully set, FALSE otherwise + */ +dbus_bool_t +libhal_ctx_set_device_added (LibHalContext *ctx, LibHalDeviceAdded callback) +{ + LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); + + ctx->device_added = callback; + return TRUE; +} + +/** + * libhal_ctx_set_device_removed: + * @ctx: the context for the connection to hald + * @callback: the function to call when a device is removed + * + * Set the callback for when a device is removed. + * + * Returns: TRUE if callback was successfully set, FALSE otherwise + */ +dbus_bool_t +libhal_ctx_set_device_removed (LibHalContext *ctx, LibHalDeviceRemoved callback) +{ + LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); + + ctx->device_removed = callback; + return TRUE; +} + +/** + * libhal_ctx_set_device_new_capability: + * @ctx: the context for the connection to hald + * @callback: the function to call when a device gains a new capability + * + * Set the callback for when a device gains a new capability. + * + * Returns: TRUE if callback was successfully set, FALSE otherwise + */ +dbus_bool_t +libhal_ctx_set_device_new_capability (LibHalContext *ctx, LibHalDeviceNewCapability callback) +{ + LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); + + ctx->device_new_capability = callback; + return TRUE; +} + +/** + * libhal_ctx_set_device_lost_capability: + * @ctx: the context for the connection to hald + * @callback: the function to call when a device loses a capability + * + * Set the callback for when a device loses a capability + * + * Returns: TRUE if callback was successfully set, FALSE otherwise + */ +dbus_bool_t +libhal_ctx_set_device_lost_capability (LibHalContext *ctx, LibHalDeviceLostCapability callback) +{ + LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); + + ctx->device_lost_capability = callback; + return TRUE; +} + +/** + * libhal_ctx_set_device_property_modified: + * @ctx: the context for the connection to hald + * @callback: the function to call when a property is modified on a device + * + * Set the callback for when a property is modified on a device. + * + * Returns: TRUE if callback was successfully set, FALSE otherwise + */ +dbus_bool_t +libhal_ctx_set_device_property_modified (LibHalContext *ctx, LibHalDevicePropertyModified callback) +{ + LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); + + ctx->device_property_modified = callback; + return TRUE; +} + +/** + * libhal_ctx_set_device_condition: + * @ctx: the context for the connection to hald + * @callback: the function to call when a device emits a condition + * + * Set the callback for when a device emits a condition + * + * Returns: TRUE if callback was successfully set, FALSE otherwise + */ +dbus_bool_t +libhal_ctx_set_device_condition (LibHalContext *ctx, LibHalDeviceCondition callback) +{ + LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); + + ctx->device_condition = callback; + return TRUE; +} + +/** + * libhal_string_array_length: + * @str_array: array of strings to consider + * + * Get the length of an array of strings. + * + * Returns: Number of strings in array + */ +unsigned int +libhal_string_array_length (char **str_array) +{ + unsigned int i; + + if (str_array == NULL) + return 0; + + for (i = 0; str_array[i] != NULL; i++) + ; + + return i; +} + + +/** + * libhal_device_rescan: + * @ctx: the context for the connection to hald + * @udi: the Unique id of device + * @error: pointer to an initialized dbus error object for returning errors or NULL + * + * TODO document me. + * + * Returns: Whether the operation succeeded + */ +dbus_bool_t +libhal_device_rescan (LibHalContext *ctx, const char *udi, DBusError *error) +{ + DBusMessage *message; + DBusMessageIter reply_iter; + DBusMessage *reply; + dbus_bool_t result; + + LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); + + message = dbus_message_new_method_call ("org.freedesktop.Hal", udi, + "org.freedesktop.Hal.Device", + "Rescan"); + + if (message == NULL) { + fprintf (stderr, + "%s %d : Couldn't allocate D-BUS message\n", + __FILE__, __LINE__); + return FALSE; + } + + reply = dbus_connection_send_with_reply_and_block (ctx->connection, + message, -1, + error); + + if (dbus_error_is_set (error)) { + dbus_message_unref (message); + return FALSE; + } + + dbus_message_unref (message); + + if (reply == NULL) + return FALSE; + + dbus_message_iter_init (reply, &reply_iter); + if (dbus_message_iter_get_arg_type (&reply_iter) != + DBUS_TYPE_BOOLEAN) { + dbus_message_unref (message); + dbus_message_unref (reply); + return FALSE; + } + dbus_message_iter_get_basic (&reply_iter, &result); + + dbus_message_unref (reply); + + return result; +} + +/** + * libhal_device_reprobe: + * @ctx: the context for the connection to hald + * @udi: the Unique id of device + * @error: pointer to an initialized dbus error object for returning errors or NULL + * + * TODO document me. + * + * Returns: Whether the operation succeeded + */ +dbus_bool_t +libhal_device_reprobe (LibHalContext *ctx, const char *udi, DBusError *error) +{ + DBusMessage *message; + DBusMessageIter reply_iter; + DBusMessage *reply; + dbus_bool_t result; + + LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); + + message = dbus_message_new_method_call ("org.freedesktop.Hal", + udi, + "org.freedesktop.Hal.Device", + "Reprobe"); + + if (message == NULL) { + fprintf (stderr, + "%s %d : Couldn't allocate D-BUS message\n", + __FILE__, __LINE__); + return FALSE; + } + + reply = dbus_connection_send_with_reply_and_block (ctx->connection, + message, -1, + error); + + if (dbus_error_is_set (error)) { + dbus_message_unref (message); + return FALSE; + } + + dbus_message_unref (message); + + if (reply == NULL) + return FALSE; + + dbus_message_iter_init (reply, &reply_iter); + if (dbus_message_iter_get_arg_type (&reply_iter) != + DBUS_TYPE_BOOLEAN) { + dbus_message_unref (message); + dbus_message_unref (reply); + return FALSE; + } + dbus_message_iter_get_basic (&reply_iter, &result); + + dbus_message_unref (reply); + + return result; +} + +/** + * libhal_device_emit_condition: + * @ctx: the context for the connection to hald + * @udi: the Unique Device Id + * @condition_name: user-readable name of condition + * @condition_details: user-readable details of condition + * @error: pointer to an initialized dbus error object for returning errors or NULL + * + * Emit a condition from a device. Can only be used from hald helpers. + * + * Returns: TRUE if condition successfully emitted, + * FALSE otherwise + */ +dbus_bool_t libhal_device_emit_condition (LibHalContext *ctx, + const char *udi, + const char *condition_name, + const char *condition_details, + DBusError *error) +{ + DBusMessage *message; + DBusMessageIter iter; + DBusMessageIter reply_iter; + DBusMessage *reply; + dbus_bool_t result; + + LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); + + message = dbus_message_new_method_call ("org.freedesktop.Hal", + udi, + "org.freedesktop.Hal.Device", + "EmitCondition"); + + if (message == NULL) { + fprintf (stderr, + "%s %d : Couldn't allocate D-BUS message\n", + __FILE__, __LINE__); + return FALSE; + } + + dbus_message_iter_init_append (message, &iter); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &condition_name); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &condition_details); + + reply = dbus_connection_send_with_reply_and_block (ctx->connection, + message, -1, + error); + + if (dbus_error_is_set (error)) { + dbus_message_unref (message); + return FALSE; + } + + dbus_message_unref (message); + + if (reply == NULL) + return FALSE; + + dbus_message_iter_init (reply, &reply_iter); + if (dbus_message_iter_get_arg_type (&reply_iter) != + DBUS_TYPE_BOOLEAN) { + dbus_message_unref (message); + dbus_message_unref (reply); + return FALSE; + } + dbus_message_iter_get_basic (&reply_iter, &result); + + dbus_message_unref (reply); + + return result; +} + +/** + * libhal_device_addon_is_ready: + * @ctx: the context for the connection to hald + * @udi: the Unique Device Id + * @error: pointer to an initialized dbus error object for returning errors or NULL + * + * HAL addon's must call this method when they are done initializing the device object. The HAL + * daemon will wait for all addon's to call this. + * + * Can only be used from hald helpers. + * + * Returns: TRUE if the HAL daemon received the message, FALSE otherwise + */ +dbus_bool_t +libhal_device_addon_is_ready (LibHalContext *ctx, const char *udi, DBusError *error) +{ + DBusMessage *message; + DBusMessageIter iter; + DBusMessageIter reply_iter; + DBusMessage *reply; + dbus_bool_t result; + + LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); + + message = dbus_message_new_method_call ("org.freedesktop.Hal", + udi, + "org.freedesktop.Hal.Device", + "AddonIsReady"); + + if (message == NULL) { + fprintf (stderr, + "%s %d : Couldn't allocate D-BUS message\n", + __FILE__, __LINE__); + return FALSE; + } + + dbus_message_iter_init_append (message, &iter); + + reply = dbus_connection_send_with_reply_and_block (ctx->connection, + message, -1, + error); + + if (dbus_error_is_set (error)) { + dbus_message_unref (message); + return FALSE; + } + + dbus_message_unref (message); + + if (reply == NULL) + return FALSE; + + dbus_message_iter_init (reply, &reply_iter); + if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_BOOLEAN) { + dbus_message_unref (message); + dbus_message_unref (reply); + return FALSE; + } + dbus_message_iter_get_basic (&reply_iter, &result); + + dbus_message_unref (reply); + return result; +} + +/** + * libhal_device_claim_interface: + * @ctx: the context for the connection to hald + * @udi: the Unique Device Id + * @interface_name: Name of interface to claim, e.g. org.freedesktop.Hal.Device.FoobarKindOfThing + * @introspection_xml: Introspection XML containing what would be inside the interface XML tag + * @error: pointer to an initialized dbus error object for returning errors or NULL + * + * Claim an interface for a device. All messages to this interface + * will be forwarded to the helper. Can only be used from hald + * helpers. + * + * Returns: TRUE if interface was claimed, FALSE otherwise + */ +dbus_bool_t +libhal_device_claim_interface (LibHalContext *ctx, + const char *udi, + const char *interface_name, + const char *introspection_xml, + DBusError *error) +{ + DBusMessage *message; + DBusMessageIter iter; + DBusMessageIter reply_iter; + DBusMessage *reply; + dbus_bool_t result; + + LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); + + message = dbus_message_new_method_call ("org.freedesktop.Hal", + udi, + "org.freedesktop.Hal.Device", + "ClaimInterface"); + + if (message == NULL) { + fprintf (stderr, + "%s %d : Couldn't allocate D-BUS message\n", + __FILE__, __LINE__); + return FALSE; + } + + dbus_message_iter_init_append (message, &iter); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &interface_name); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &introspection_xml); + + reply = dbus_connection_send_with_reply_and_block (ctx->connection, + message, -1, + error); + + if (dbus_error_is_set (error)) { + dbus_message_unref (message); + return FALSE; + } + + dbus_message_unref (message); + + if (reply == NULL) + return FALSE; + + dbus_message_iter_init (reply, &reply_iter); + if (dbus_message_iter_get_arg_type (&reply_iter) != + DBUS_TYPE_BOOLEAN) { + dbus_message_unref (message); + dbus_message_unref (reply); + return FALSE; + } + dbus_message_iter_get_basic (&reply_iter, &result); + + dbus_message_unref (reply); + + return result; +} + + + +struct LibHalChangeSetElement_s; + +typedef struct LibHalChangeSetElement_s LibHalChangeSetElement; + +struct LibHalChangeSetElement_s { + char *key; + int change_type; + union { + char *val_str; + dbus_int32_t val_int; + dbus_uint64_t val_uint64; + double val_double; + dbus_bool_t val_bool; + char **val_strlist; + } value; + LibHalChangeSetElement *next; + LibHalChangeSetElement *prev; +}; + +struct LibHalChangeSet_s { + char *udi; + LibHalChangeSetElement *head; + LibHalChangeSetElement *tail; +}; + +/** + * libhal_device_new_changeset: + * @udi: unique device identifier + * + * Request a new changeset object. Used for changing multiple properties at once. Useful when + * performance is critical and also for atomically updating several properties. + * + * Returns: A new changeset object or NULL on error + */ +LibHalChangeSet * +libhal_device_new_changeset (const char *udi) +{ + LibHalChangeSet *changeset; + + changeset = calloc (1, sizeof (LibHalChangeSet)); + if (changeset == NULL) + goto out; + + changeset->udi = strdup (udi); + if (changeset->udi == NULL) { + free (changeset); + changeset = NULL; + goto out; + } + + changeset->head = NULL; + changeset->tail = NULL; + +out: + return changeset; +} + +static void +libhal_changeset_append (LibHalChangeSet *changeset, LibHalChangeSetElement *elem) +{ + if (changeset->head == NULL) { + changeset->head = elem; + changeset->tail = elem; + elem->next = NULL; + elem->prev = NULL; + } else { + elem->prev = changeset->tail; + elem->next = NULL; + elem->prev->next = elem; + changeset->tail = elem; + } +} + + +/** + * libhal_device_set_property_string: + * @changeset: the changeset + * @key: key of property + * @value: the value to set + * + * Set a property. + * + * Returns: FALSE on OOM + */ +dbus_bool_t +libhal_changeset_set_property_string (LibHalChangeSet *changeset, const char *key, const char *value) +{ + LibHalChangeSetElement *elem; + + elem = calloc (1, sizeof (LibHalChangeSetElement)); + if (elem == NULL) + goto out; + elem->key = strdup (key); + if (elem->key == NULL) { + free (elem); + elem = NULL; + goto out; + } + + elem->change_type = LIBHAL_PROPERTY_TYPE_STRING; + elem->value.val_str = strdup (value); + if (elem->value.val_str == NULL) { + free (elem->key); + free (elem); + elem = NULL; + goto out; + } + + libhal_changeset_append (changeset, elem); +out: + return elem != NULL; +} + +/** + * libhal_device_set_property_int: + * @changeset: the changeset + * @key: key of property + * @value: the value to set + * + * Set a property. + * + * Returns: FALSE on OOM + */ +dbus_bool_t +libhal_changeset_set_property_int (LibHalChangeSet *changeset, const char *key, dbus_int32_t value) +{ + LibHalChangeSetElement *elem; + + elem = calloc (1, sizeof (LibHalChangeSetElement)); + if (elem == NULL) + goto out; + elem->key = strdup (key); + if (elem->key == NULL) { + free (elem); + elem = NULL; + goto out; + } + + elem->change_type = LIBHAL_PROPERTY_TYPE_INT32; + elem->value.val_int = value; + + libhal_changeset_append (changeset, elem); +out: + return elem != NULL; +} + +/** + * libhal_device_set_property_uint64: + * @changeset: the changeset + * @key: key of property + * @value: the value to set + * + * Set a property. + * + * Returns: FALSE on OOM + */ +dbus_bool_t +libhal_changeset_set_property_uint64 (LibHalChangeSet *changeset, const char *key, dbus_uint64_t value) +{ + LibHalChangeSetElement *elem; + + elem = calloc (1, sizeof (LibHalChangeSetElement)); + if (elem == NULL) + goto out; + elem->key = strdup (key); + if (elem->key == NULL) { + free (elem); + elem = NULL; + goto out; + } + + elem->change_type = LIBHAL_PROPERTY_TYPE_UINT64; + elem->value.val_uint64 = value; + + libhal_changeset_append (changeset, elem); +out: + return elem != NULL; +} + +/** + * libhal_device_set_property_double: + * @changeset: the changeset + * @key: key of property + * @value: the value to set + * + * Set a property. + * + * Returns: FALSE on OOM + */ +dbus_bool_t +libhal_changeset_set_property_double (LibHalChangeSet *changeset, const char *key, double value) +{ + LibHalChangeSetElement *elem; + + elem = calloc (1, sizeof (LibHalChangeSetElement)); + if (elem == NULL) + goto out; + elem->key = strdup (key); + if (elem->key == NULL) { + free (elem); + elem = NULL; + goto out; + } + + elem->change_type = LIBHAL_PROPERTY_TYPE_DOUBLE; + elem->value.val_double = value; + + libhal_changeset_append (changeset, elem); +out: + return elem != NULL; +} + +/** + * libhal_device_set_property_bool: + * @changeset: the changeset + * @key: key of property + * @value: the value to set + * + * Set a property. + * + * Returns: FALSE on OOM + */ +dbus_bool_t +libhal_changeset_set_property_bool (LibHalChangeSet *changeset, const char *key, dbus_bool_t value) +{ + LibHalChangeSetElement *elem; + + elem = calloc (1, sizeof (LibHalChangeSetElement)); + if (elem == NULL) + goto out; + elem->key = strdup (key); + if (elem->key == NULL) { + free (elem); + elem = NULL; + goto out; + } + + elem->change_type = LIBHAL_PROPERTY_TYPE_BOOLEAN; + elem->value.val_bool = value; + + libhal_changeset_append (changeset, elem); +out: + return elem != NULL; +} + +/** + * libhal_device_set_property_strlist: + * @changeset: the changeset + * @key: key of property + * @value: the value to set - NULL terminated array of strings + * + * Set a property. + * + * Returns: FALSE on OOM + */ +dbus_bool_t +libhal_changeset_set_property_strlist (LibHalChangeSet *changeset, const char *key, const char **value) +{ + LibHalChangeSetElement *elem; + char **value_copy; + int len; + int i, j; + + elem = calloc (1, sizeof (LibHalChangeSetElement)); + if (elem == NULL) + goto out; + elem->key = strdup (key); + if (elem->key == NULL) { + free (elem); + elem = NULL; + goto out; + } + + for (i = 0; value[i] != NULL; i++) + ; + len = i; + + value_copy = calloc (len + 1, sizeof (char *)); + if (value_copy == NULL) { + free (elem->key); + free (elem); + elem = NULL; + goto out; + } + + for (i = 0; i < len; i++) { + value_copy[i] = strdup (value[i]); + if (value_copy[i] == NULL) { + for (j = 0; j < i; j++) { + free (value_copy[j]); + } + free (value_copy); + free (elem->key); + free (elem); + elem = NULL; + goto out; + } + } + value_copy[i] = NULL; + + elem->change_type = LIBHAL_PROPERTY_TYPE_STRLIST; + elem->value.val_strlist = value_copy; + + libhal_changeset_append (changeset, elem); +out: + return elem != NULL; +} + +/** + * libhal_device_commit_changeset: + * @ctx: the context for the connection to hald + * @changeset: the changeset to commit + * @error: pointer to an initialized dbus error object for returning errors or NULL + * + * Commit a changeset to the daemon. + * + * Returns: True if the changeset was committed on the daemon side + */ +dbus_bool_t +libhal_device_commit_changeset (LibHalContext *ctx, LibHalChangeSet *changeset, DBusError *error) +{ + LibHalChangeSetElement *elem; + DBusMessage *message; + DBusMessage *reply; + DBusError _error; + DBusMessageIter iter; + DBusMessageIter sub; + DBusMessageIter sub2; + DBusMessageIter sub3; + DBusMessageIter sub4; + int i; + + LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); + + if (changeset->head == NULL) { + return TRUE; + } + + message = dbus_message_new_method_call ("org.freedesktop.Hal", changeset->udi, + "org.freedesktop.Hal.Device", + "SetMultipleProperties"); + + if (message == NULL) { + fprintf (stderr, "%s %d : Couldn't allocate D-BUS message\n", __FILE__, __LINE__); + return FALSE; + } + + dbus_message_iter_init_append (message, &iter); + + dbus_message_iter_open_container (&iter, + DBUS_TYPE_ARRAY, + DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING + DBUS_TYPE_STRING_AS_STRING + DBUS_TYPE_VARIANT_AS_STRING + DBUS_DICT_ENTRY_END_CHAR_AS_STRING, + &sub); + + for (elem = changeset->head; elem != NULL; elem = elem->next) { + dbus_message_iter_open_container (&sub, + DBUS_TYPE_DICT_ENTRY, + NULL, + &sub2); + dbus_message_iter_append_basic (&sub2, DBUS_TYPE_STRING, &(elem->key)); + + switch (elem->change_type) { + case LIBHAL_PROPERTY_TYPE_STRING: + dbus_message_iter_open_container (&sub2, DBUS_TYPE_VARIANT, DBUS_TYPE_STRING_AS_STRING, &sub3); + dbus_message_iter_append_basic (&sub3, DBUS_TYPE_STRING, &(elem->value.val_str)); + dbus_message_iter_close_container (&sub2, &sub3); + break; + case LIBHAL_PROPERTY_TYPE_STRLIST: + dbus_message_iter_open_container (&sub2, DBUS_TYPE_VARIANT, + DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING, &sub3); + dbus_message_iter_open_container (&sub3, DBUS_TYPE_ARRAY, + DBUS_TYPE_STRING_AS_STRING, &sub4); + for (i = 0; elem->value.val_strlist[i] != NULL; i++) { + dbus_message_iter_append_basic (&sub4, DBUS_TYPE_STRING, + &(elem->value.val_strlist[i])); + } + dbus_message_iter_close_container (&sub3, &sub4); + dbus_message_iter_close_container (&sub2, &sub3); + break; + case LIBHAL_PROPERTY_TYPE_INT32: + dbus_message_iter_open_container (&sub2, DBUS_TYPE_VARIANT, DBUS_TYPE_INT32_AS_STRING, &sub3); + dbus_message_iter_append_basic (&sub3, DBUS_TYPE_INT32, &(elem->value.val_int)); + dbus_message_iter_close_container (&sub2, &sub3); + break; + case LIBHAL_PROPERTY_TYPE_UINT64: + dbus_message_iter_open_container (&sub2, DBUS_TYPE_VARIANT, DBUS_TYPE_UINT64_AS_STRING, &sub3); + dbus_message_iter_append_basic (&sub3, DBUS_TYPE_UINT64, &(elem->value.val_uint64)); + dbus_message_iter_close_container (&sub2, &sub3); + break; + case LIBHAL_PROPERTY_TYPE_DOUBLE: + dbus_message_iter_open_container (&sub2, DBUS_TYPE_VARIANT, DBUS_TYPE_DOUBLE_AS_STRING, &sub3); + dbus_message_iter_append_basic (&sub3, DBUS_TYPE_DOUBLE, &(elem->value.val_double)); + dbus_message_iter_close_container (&sub2, &sub3); + break; + case LIBHAL_PROPERTY_TYPE_BOOLEAN: + dbus_message_iter_open_container (&sub2, DBUS_TYPE_VARIANT, DBUS_TYPE_BOOLEAN_AS_STRING,&sub3); + dbus_message_iter_append_basic (&sub3, DBUS_TYPE_BOOLEAN, &(elem->value.val_bool)); + dbus_message_iter_close_container (&sub2, &sub3); + break; + default: + fprintf (stderr, "%s %d : unknown change_type %d\n", __FILE__, __LINE__, elem->change_type); + break; + } + dbus_message_iter_close_container (&sub, &sub2); + } + + dbus_message_iter_close_container (&iter, &sub); + + + dbus_error_init (&_error); + reply = dbus_connection_send_with_reply_and_block (ctx->connection, + message, -1, + &_error); + + dbus_move_error (&_error, error); + if (error != NULL && dbus_error_is_set (error)) { + fprintf (stderr, + "%s %d : %s\n", + __FILE__, __LINE__, error->message); + + dbus_message_unref (message); + return FALSE; + } + + if (reply == NULL) { + dbus_message_unref (message); + return FALSE; + } + + return TRUE; +} + +/** + * libhal_device_free_changeset: + * @changeset: the changeset to free + * + * Free a changeset. + */ +void +libhal_device_free_changeset (LibHalChangeSet *changeset) +{ + LibHalChangeSetElement *elem; + LibHalChangeSetElement *elem2; + + for (elem = changeset->head; elem != NULL; elem = elem2) { + elem2 = elem->next; + + switch (elem->change_type) { + case LIBHAL_PROPERTY_TYPE_STRING: + free (elem->value.val_str); + break; + case LIBHAL_PROPERTY_TYPE_STRLIST: + libhal_free_string_array (elem->value.val_strlist); + break; + /* explicit fallthrough */ + case LIBHAL_PROPERTY_TYPE_INT32: + case LIBHAL_PROPERTY_TYPE_UINT64: + case LIBHAL_PROPERTY_TYPE_DOUBLE: + case LIBHAL_PROPERTY_TYPE_BOOLEAN: + break; + default: + fprintf (stderr, "%s %d : unknown change_type %d\n", __FILE__, __LINE__, elem->change_type); + break; + } + free (elem); + } + + free (changeset->udi); + free (changeset); +} diff --git a/usr/src/lib/hal/libhal/common/libhal.h b/usr/src/lib/hal/libhal/common/libhal.h new file mode 100644 index 0000000000..9962da1ec0 --- /dev/null +++ b/usr/src/lib/hal/libhal/common/libhal.h @@ -0,0 +1,604 @@ +/*************************************************************************** + * CVSID: $Id$ + * + * libhal.h : HAL daemon C convenience library headers + * + * Copyright (C) 2003 David Zeuthen, <david@fubar.dk> + * + * Licensed under the Academic Free License version 2.1 + * + * This program 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 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + **************************************************************************/ + +#ifndef LIBHAL_H +#define LIBHAL_H + +#include <dbus/dbus.h> + +#if defined(__cplusplus) +extern "C" { +#if 0 +} /* shut up emacs indenting */ +#endif +#endif + +#if defined(__GNUC__) +#define LIBHAL_DEPRECATED __attribute__ ((deprecated)) +#else +#define LIBHAL_DEPRECATED +#endif + + +#define LIBHAL_FREE_DBUS_ERROR(_dbus_error_) \ + do { \ + if (dbus_error_is_set(_dbus_error_)) \ + dbus_error_free (_dbus_error_); \ + else \ + fprintf (stderr, \ + "%s %d : INFO: called LIBHAL_FREE_DBUS_ERROR " \ + "but dbusError was not set.\n", \ + __FILE__, __LINE__); \ + } while (0) + + +/** + * LIBHAL_CHECK_LIBHALCONTEXT: + * @_ctx_: the context + * @_ret_: what to use for return value if context is invalid + * + * Handy macro for checking whether a context is valid. + */ +#define LIBHAL_CHECK_LIBHALCONTEXT(_ctx_, _ret_) \ + do { \ + if (_ctx_ == NULL) { \ + fprintf (stderr, \ + "%s %d : LibHalContext *ctx is NULL\n", \ + __FILE__, __LINE__); \ + return _ret_; \ + } \ + } while(0) + +/** + * LibHalPropertyType: + * + * Possible types for properties on hal device objects + */ +typedef enum { + /** Used to report error condition */ + LIBHAL_PROPERTY_TYPE_INVALID = DBUS_TYPE_INVALID, + + /** Type for 32-bit signed integer property */ + LIBHAL_PROPERTY_TYPE_INT32 = DBUS_TYPE_INT32, + + /** Type for 64-bit unsigned integer property */ + LIBHAL_PROPERTY_TYPE_UINT64 = DBUS_TYPE_UINT64, + + /** Type for double precision floating point property */ + LIBHAL_PROPERTY_TYPE_DOUBLE = DBUS_TYPE_DOUBLE, + + /** Type for boolean property */ + LIBHAL_PROPERTY_TYPE_BOOLEAN = DBUS_TYPE_BOOLEAN, + + /** Type for UTF-8 string property */ + LIBHAL_PROPERTY_TYPE_STRING = DBUS_TYPE_STRING, + + /** Type for list of UTF-8 strings property */ + LIBHAL_PROPERTY_TYPE_STRLIST = ((int) (DBUS_TYPE_STRING<<8)+('l')) +} LibHalPropertyType; + + +typedef struct LibHalContext_s LibHalContext; + +/** + * LibHalIntegrateDBusIntoMainLoop: + * @ctx: context for connection to hald + * @dbus_connection: DBus connection to use in ctx + * + * Type for function in application code that integrates a + * DBusConnection object into its own mainloop. + */ +typedef void (*LibHalIntegrateDBusIntoMainLoop) (LibHalContext *ctx, + DBusConnection *dbus_connection); + +/** + * LibHalDeviceAdded: + * @ctx: context for connection to hald + * @udi: the Unique Device Id + * + * Type for callback when a device is added. + */ +typedef void (*LibHalDeviceAdded) (LibHalContext *ctx, + const char *udi); + +/** + * LibHalDeviceRemoved: + * @ctx: context for connection to hald + * @udi: the Unique Device Id + * + * Type for callback when a device is removed. + */ +typedef void (*LibHalDeviceRemoved) (LibHalContext *ctx, + const char *udi); + +/** + * LibHalDeviceNewCapability: + * @ctx: context for connection to hald + * @udi: the Unique Device Id + * @capability: capability of the device + * + * Type for callback when a device gains a new capability. + * + */ +typedef void (*LibHalDeviceNewCapability) (LibHalContext *ctx, + const char *udi, + const char *capability); + +/** + * LibHalDeviceLostCapability: + * @ctx: context for connection to hald + * @udi: the Unique Device Id + * @capability: capability of the device + * + * Type for callback when a device loses a capability. + * + */ +typedef void (*LibHalDeviceLostCapability) (LibHalContext *ctx, + const char *udi, + const char *capability); + +/** + * LibHalDevicePropertyModified: + * @ctx: context for connection to hald + * @udi: the Unique Device Id + * @key: name of the property that has changed + * @is_removed: whether or not property was removed + * @is_added: whether or not property was added + * + * Type for callback when a property of a device changes. + */ +typedef void (*LibHalDevicePropertyModified) (LibHalContext *ctx, + const char *udi, + const char *key, + dbus_bool_t is_removed, + dbus_bool_t is_added); + +/** + * LibHalDeviceCondition: + * @ctx: context for connection to hald + * @udi: the Unique Device Id + * @condition_name: name of the condition, e.g. ProcessorOverheating. Consult the HAL spec for details + * @condition_detail: detail of condition + * + * Type for callback when a non-continuous condition occurs on a device. + */ +typedef void (*LibHalDeviceCondition) (LibHalContext *ctx, + const char *udi, + const char *condition_name, + const char *condition_detail); + + +/* Create a new context for a connection with hald */ +LibHalContext *libhal_ctx_new (void); + +/* Enable or disable caching */ +dbus_bool_t libhal_ctx_set_cache (LibHalContext *ctx, dbus_bool_t use_cache); + +/* Set DBus connection to use to talk to hald. */ +dbus_bool_t libhal_ctx_set_dbus_connection (LibHalContext *ctx, DBusConnection *conn); + +/* Get DBus connection to use to talk to hald. */ +DBusConnection *libhal_ctx_get_dbus_connection (LibHalContext *ctx); + +/* Set user data for the context */ +dbus_bool_t libhal_ctx_set_user_data (LibHalContext *ctx, void *user_data); + +/* Get user data for the context */ +void* libhal_ctx_get_user_data (LibHalContext *ctx); + +/* Set the callback for when a device is added */ +dbus_bool_t libhal_ctx_set_device_added (LibHalContext *ctx, LibHalDeviceAdded callback); + +/* Set the callback for when a device is removed */ +dbus_bool_t libhal_ctx_set_device_removed (LibHalContext *ctx, LibHalDeviceRemoved callback); + +/* Set the callback for when a device gains a new capability */ +dbus_bool_t libhal_ctx_set_device_new_capability (LibHalContext *ctx, LibHalDeviceNewCapability callback); + +/* Set the callback for when a device loses a capability */ +dbus_bool_t libhal_ctx_set_device_lost_capability (LibHalContext *ctx, LibHalDeviceLostCapability callback); + +/* Set the callback for when a property is modified on a device */ +dbus_bool_t libhal_ctx_set_device_property_modified (LibHalContext *ctx, LibHalDevicePropertyModified callback); + +/* Set the callback for when a device emits a condition */ +dbus_bool_t libhal_ctx_set_device_condition (LibHalContext *ctx, LibHalDeviceCondition callback); + +/* Initialize the connection to hald */ +dbus_bool_t libhal_ctx_init (LibHalContext *ctx, DBusError *error); + +/* Shut down a connection to hald */ +dbus_bool_t libhal_ctx_shutdown (LibHalContext *ctx, DBusError *error); + +/* Free a LibHalContext resource */ +dbus_bool_t libhal_ctx_free (LibHalContext *ctx); + +/* Create an already initialized connection to hald */ +LibHalContext *libhal_ctx_init_direct (DBusError *error); + +/* Get all devices in the Global Device List (GDL). */ +char **libhal_get_all_devices (LibHalContext *ctx, int *num_devices, DBusError *error); + +/* Determine if a device exists. */ +dbus_bool_t libhal_device_exists (LibHalContext *ctx, const char *udi, DBusError *error); + +/* Print a device to stdout; useful for debugging. */ +dbus_bool_t libhal_device_print (LibHalContext *ctx, const char *udi, DBusError *error); + +/* Determine if a property on a device exists. */ +dbus_bool_t libhal_device_property_exists (LibHalContext *ctx, + const char *udi, + const char *key, + DBusError *error); + +/* Get the value of a property of type string. */ +char *libhal_device_get_property_string (LibHalContext *ctx, + const char *udi, + const char *key, + DBusError *error); + +/* Get the value of a property of type signed integer. */ +dbus_int32_t libhal_device_get_property_int (LibHalContext *ctx, + const char *udi, + const char *key, + DBusError *error); + +/* Get the value of a property of type unsigned integer. */ +dbus_uint64_t libhal_device_get_property_uint64 (LibHalContext *ctx, + const char *udi, + const char *key, + DBusError *error); + +/* Get the value of a property of type double. */ +double libhal_device_get_property_double (LibHalContext *ctx, + const char *udi, + const char *key, + DBusError *error); + +/* Get the value of a property of type bool. */ +dbus_bool_t libhal_device_get_property_bool (LibHalContext *ctx, + const char *udi, + const char *key, + DBusError *error); + +/* Get the value of a property of type string list. */ +char **libhal_device_get_property_strlist (LibHalContext *ctx, + const char *udi, + const char *key, + DBusError *error); + +/* Set a property of type string. */ +dbus_bool_t libhal_device_set_property_string (LibHalContext *ctx, + const char *udi, + const char *key, + const char *value, + DBusError *error); + +/* Set a property of type signed integer. */ +dbus_bool_t libhal_device_set_property_int (LibHalContext *ctx, + const char *udi, + const char *key, + dbus_int32_t value, + DBusError *error); + +/* Set a property of type unsigned integer. */ +dbus_bool_t libhal_device_set_property_uint64 (LibHalContext *ctx, + const char *udi, + const char *key, + dbus_uint64_t value, + DBusError *error); + +/* Set a property of type double. */ +dbus_bool_t libhal_device_set_property_double (LibHalContext *ctx, + const char *udi, + const char *key, + double value, + DBusError *error); + +/* Set a property of type bool. */ +dbus_bool_t libhal_device_set_property_bool (LibHalContext *ctx, + const char *udi, + const char *key, + dbus_bool_t value, + DBusError *error); + +/* Append to a property of type strlist. */ +dbus_bool_t libhal_device_property_strlist_append (LibHalContext *ctx, + const char *udi, + const char *key, + const char *value, + DBusError *error); + +/* Prepend to a property of type strlist. */ +dbus_bool_t libhal_device_property_strlist_prepend (LibHalContext *ctx, + const char *udi, + const char *key, + const char *value, + DBusError *error); + +/* Remove a specified string from a property of type strlist. */ +dbus_bool_t libhal_device_property_strlist_remove_index (LibHalContext *ctx, + const char *udi, + const char *key, + unsigned int idx, + DBusError *error); + +/* Remove a specified string from a property of type strlist. */ +dbus_bool_t libhal_device_property_strlist_remove (LibHalContext *ctx, + const char *udi, + const char *key, + const char *value, + DBusError *error); + +/* Remove a property. */ +dbus_bool_t libhal_device_remove_property (LibHalContext *ctx, + const char *udi, + const char *key, + DBusError *error); + +/* Query a property type of a device. */ +LibHalPropertyType libhal_device_get_property_type (LibHalContext *ctx, + const char *udi, + const char *key, + DBusError *error); + +struct LibHalChangeSet_s; +typedef struct LibHalChangeSet_s LibHalChangeSet; + +LibHalChangeSet *libhal_device_new_changeset (const char *udi); + +dbus_bool_t libhal_changeset_set_property_string (LibHalChangeSet *changeset, + const char *key, + const char *value); + +dbus_bool_t libhal_changeset_set_property_int (LibHalChangeSet *changeset, + const char *key, + dbus_int32_t value); + +dbus_bool_t libhal_changeset_set_property_uint64 (LibHalChangeSet *changeset, + const char *key, + dbus_uint64_t value); + +dbus_bool_t libhal_changeset_set_property_double (LibHalChangeSet *changeset, + const char *key, + double value); + +dbus_bool_t libhal_changeset_set_property_bool (LibHalChangeSet *changeset, + const char *key, + dbus_bool_t value); + +dbus_bool_t libhal_changeset_set_property_strlist (LibHalChangeSet *changeset, + const char *key, + const char **value); + +dbus_bool_t libhal_device_commit_changeset (LibHalContext *ctx, + LibHalChangeSet *changeset, + DBusError *error); + +void libhal_device_free_changeset (LibHalChangeSet *changeset); + + +struct LibHalProperty_s; +typedef struct LibHalProperty_s LibHalProperty; + +struct LibHalPropertySet_s; +typedef struct LibHalPropertySet_s LibHalPropertySet; + + +/* Retrieve all the properties on a device. */ +LibHalPropertySet *libhal_device_get_all_properties (LibHalContext *ctx, + const char *udi, + DBusError *error); + +/* Free a property set earlier obtained with libhal_device_get_all_properties(). */ +void libhal_free_property_set (LibHalPropertySet *set); + +/* Get the number of properties in a property set. */ +unsigned int libhal_property_set_get_num_elems (LibHalPropertySet *set); + +/** + * LibHalPropertySetIterator: + * + * Iterator for inspecting all properties. Do not access any members; + * use the libhal_psi_* family of functions instead. + */ +struct LibHalPropertySetIterator_s { + LibHalPropertySet *set; /**< Property set we are iterating over */ + unsigned int idx; /**< Index into current element */ + LibHalProperty *cur_prop; /**< Current property being visited */ + void *reservered0; /**< Reserved for future use */ + void *reservered1; /**< Reserved for future use */ +}; + + +typedef struct LibHalPropertySetIterator_s LibHalPropertySetIterator; + +/* Initialize a property set iterator. */ +void libhal_psi_init (LibHalPropertySetIterator *iter, LibHalPropertySet *set); + +/* Determine whether there are more properties to iterate over */ +dbus_bool_t libhal_psi_has_more (LibHalPropertySetIterator *iter); + +/* Advance iterator to next property. */ +void libhal_psi_next (LibHalPropertySetIterator *iter); + +/* Get type of property. */ +LibHalPropertyType libhal_psi_get_type (LibHalPropertySetIterator *iter); + +/* Get the key of a property. */ +char *libhal_psi_get_key (LibHalPropertySetIterator *iter); + +/* Get the value of a property of type string. */ +char *libhal_psi_get_string (LibHalPropertySetIterator *iter); + +/* Get the value of a property of type signed integer. */ +dbus_int32_t libhal_psi_get_int (LibHalPropertySetIterator *iter); + +/* Get the value of a property of type unsigned integer. */ +dbus_uint64_t libhal_psi_get_uint64 (LibHalPropertySetIterator *iter); + +/* Get the value of a property of type double. */ +double libhal_psi_get_double (LibHalPropertySetIterator *iter); + +/* Get the value of a property of type bool. */ +dbus_bool_t libhal_psi_get_bool (LibHalPropertySetIterator *iter); + +/* Get the value of a property of type string list. */ +char **libhal_psi_get_strlist (LibHalPropertySetIterator *iter); + +/* Get the length of an array of strings */ +unsigned int libhal_string_array_length (char **str_array); + +/* Frees a NULL-terminated array of strings. If passed NULL, does nothing. */ +void libhal_free_string_array (char **str_array); + +/* Frees a nul-terminated string */ +void libhal_free_string (char *str); + +/* Create a new device object which will be hidden from applications + * until the CommitToGdl(), ie. libhal_device_commit_to_gdl(), method is called. + */ +char *libhal_new_device (LibHalContext *ctx, DBusError *error); + +/* When a hidden device has been built using the NewDevice method, ie. + * libhal_new_device(), and the org.freedesktop.Hal.Device interface + * this function will commit it to the global device list. + */ +dbus_bool_t libhal_device_commit_to_gdl (LibHalContext *ctx, + const char *temp_udi, + const char *udi, + DBusError *error); + +/* This method can be invoked when a device is removed. The HAL daemon + * will shut down the device. Note that the device may still be in the device + * list if the Persistent property is set to true. + */ +dbus_bool_t libhal_remove_device (LibHalContext *ctx, + const char *udi, + DBusError *error); + +/* Merge properties from one device to another. */ +dbus_bool_t libhal_merge_properties (LibHalContext *ctx, + const char *target_udi, + const char *source_udi, + DBusError *error); + +/* Check a set of properties for two devices matches. */ +dbus_bool_t libhal_device_matches (LibHalContext *ctx, + const char *udi1, + const char *udi2, + const char *property_namespace, + DBusError *error); + +/* Find a device in the GDL where a single string property matches a + * given value. + */ +char **libhal_manager_find_device_string_match (LibHalContext *ctx, + const char *key, + const char *value, + int *num_devices, + DBusError *error); + +/* Assign a capability to a device. */ +dbus_bool_t libhal_device_add_capability (LibHalContext *ctx, + const char *udi, + const char *capability, + DBusError *error); + +/* Check if a device has a capability. The result is undefined if the + * device doesn't exist. + */ +dbus_bool_t libhal_device_query_capability (LibHalContext *ctx, + const char *udi, + const char *capability, + DBusError *error); + +/* Find devices with a given capability. */ +char **libhal_find_device_by_capability (LibHalContext *ctx, + const char *capability, + int *num_devices, + DBusError *error); + +/* Watch all devices, ie. the device_property_changed callback is + * invoked when the properties on any device changes. + */ +dbus_bool_t libhal_device_property_watch_all (LibHalContext *ctx, + DBusError *error); + +/* Add a watch on a device, so the device_property_changed callback is + * invoked when the properties on the given device changes. + */ +dbus_bool_t libhal_device_add_property_watch (LibHalContext *ctx, + const char *udi, + DBusError *error); + +/* Remove a watch on a device */ +dbus_bool_t libhal_device_remove_property_watch (LibHalContext *ctx, + const char *udi, + DBusError *error); + +/* Take an advisory lock on the device. */ +dbus_bool_t libhal_device_lock (LibHalContext *ctx, + const char *udi, + const char *reason_to_lock, + char **reason_why_locked, + DBusError *error); + +/* Release an advisory lock on the device. */ +dbus_bool_t libhal_device_unlock (LibHalContext *ctx, + const char *udi, + DBusError *error); + +dbus_bool_t libhal_device_rescan (LibHalContext *ctx, + const char *udi, + DBusError *error); + +dbus_bool_t libhal_device_reprobe (LibHalContext *ctx, + const char *udi, + DBusError *error); + +/* Emit a condition from a device (for hald helpers only) */ +dbus_bool_t libhal_device_emit_condition (LibHalContext *ctx, + const char *udi, + const char *condition_name, + const char *condition_details, + DBusError *error); + +/* Claim an interface for a device (for hald helpers only) */ +dbus_bool_t libhal_device_claim_interface (LibHalContext *ctx, + const char *udi, + const char *interface_name, + const char *introspection_xml, + DBusError *error); + +/* hald waits for all addons to call this function before announcing the addon (for hald helpers only) */ +dbus_bool_t libhal_device_addon_is_ready (LibHalContext *ctx, const char *udi, DBusError *error); + + +#if defined(__cplusplus) +} +#endif + +#endif /* LIBHAL_H */ diff --git a/usr/src/lib/hal/libhal/common/llib-lhal b/usr/src/lib/hal/libhal/common/llib-lhal new file mode 100644 index 0000000000..d89da6716b --- /dev/null +++ b/usr/src/lib/hal/libhal/common/llib-lhal @@ -0,0 +1,30 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ +#pragma ident "%Z%%M% %I% %E% SMI" + +/* LINTLIBRARY */ +/* PROTOLIB1 */ + +#include <hal/libhal.h> diff --git a/usr/src/lib/hal/libhal/common/mapfile-vers b/usr/src/lib/hal/libhal/common/mapfile-vers new file mode 100644 index 0000000000..19177567bd --- /dev/null +++ b/usr/src/lib/hal/libhal/common/mapfile-vers @@ -0,0 +1,119 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +SUNW_1.1 { + global: + libhal_ctx_new; + libhal_ctx_set_cache; + libhal_ctx_set_dbus_connection; + libhal_ctx_get_dbus_connection; + libhal_ctx_set_user_data; + libhal_ctx_get_user_data; + libhal_ctx_set_device_added; + libhal_ctx_set_device_removed; + libhal_ctx_set_device_new_capability; + libhal_ctx_set_device_lost_capability; + libhal_ctx_set_device_property_modified; + libhal_ctx_set_device_condition; + libhal_ctx_init; + libhal_ctx_shutdown; + libhal_ctx_free; + libhal_ctx_init_direct; + libhal_get_all_devices; + libhal_device_exists; + libhal_device_print; + libhal_device_property_exists; + libhal_device_get_property_string; + libhal_device_get_property_int; + libhal_device_get_property_uint64; + libhal_device_get_property_double; + libhal_device_get_property_bool; + libhal_device_get_property_strlist; + libhal_device_set_property_string; + libhal_device_set_property_int; + libhal_device_set_property_uint64; + libhal_device_set_property_double; + libhal_device_set_property_bool; + libhal_device_property_strlist_append; + libhal_device_property_strlist_prepend; + libhal_device_property_strlist_remove_index; + libhal_device_property_strlist_remove; + libhal_device_remove_property; + libhal_device_get_property_type; + libhal_device_new_changeset; + libhal_changeset_set_property_string; + libhal_changeset_set_property_int; + libhal_changeset_set_property_uint64; + libhal_changeset_set_property_double; + libhal_changeset_set_property_bool; + libhal_changeset_set_property_strlist; + libhal_device_commit_changeset; + libhal_device_free_changeset; + libhal_device_get_all_properties; + libhal_free_property_set; + libhal_property_set_get_num_elems; + libhal_psi_init; + libhal_psi_has_more; + libhal_psi_next; + libhal_psi_get_type; + libhal_psi_get_key; + libhal_psi_get_string; + libhal_psi_get_int; + libhal_psi_get_uint64; + libhal_psi_get_double; + libhal_psi_get_bool; + libhal_psi_get_strlist; + libhal_string_array_length; + libhal_free_string_array; + libhal_free_string; + libhal_new_device; + libhal_device_commit_to_gdl; + libhal_remove_device; + libhal_merge_properties; + libhal_device_matches; + libhal_manager_find_device_string_match; + libhal_device_add_capability; + libhal_device_query_capability; + libhal_find_device_by_capability; + libhal_device_property_watch_all; + libhal_device_add_property_watch; + libhal_device_remove_property_watch; + libhal_device_lock; + libhal_device_unlock; + libhal_device_rescan; + libhal_device_reprobe; + libhal_device_emit_condition; + libhal_device_claim_interface; + libhal_device_addon_is_ready; +}; + +SUNWprivate_1.1 { + global: + SUNWprivate_1.1; + local: + *; +}; diff --git a/usr/src/lib/hal/libhal/i386/Makefile b/usr/src/lib/hal/libhal/i386/Makefile new file mode 100644 index 0000000000..8643a8305f --- /dev/null +++ b/usr/src/lib/hal/libhal/i386/Makefile @@ -0,0 +1,30 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#ident "%Z%%M% %I% %E% SMI" +# + +include ../Makefile.com + +install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTLINT) $(ROOTLIBPC) $(ROOTMAJLINK) diff --git a/usr/src/lib/hal/libhal/sparc/Makefile b/usr/src/lib/hal/libhal/sparc/Makefile new file mode 100644 index 0000000000..8643a8305f --- /dev/null +++ b/usr/src/lib/hal/libhal/sparc/Makefile @@ -0,0 +1,30 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#ident "%Z%%M% %I% %E% SMI" +# + +include ../Makefile.com + +install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTLINT) $(ROOTLIBPC) $(ROOTMAJLINK) diff --git a/usr/src/lib/libbsm/audit_event.txt b/usr/src/lib/libbsm/audit_event.txt index 9e383aa97f..da1ab9aabe 100644 --- a/usr/src/lib/libbsm/audit_event.txt +++ b/usr/src/lib/libbsm/audit_event.txt @@ -423,6 +423,11 @@ 6227:AUE_zlogin:login - zlogin:lo 6228:AUE_su_logout:su logout:lo 6229:AUE_role_logout:role logout:lo +6230:AUE_attach:attach device:ot +6231:AUE_detach:detach device:ot +6232:AUE_remove:remove/eject device:ot +6233:AUE_pool_import:import device into pool:ot +6234:AUE_pool_export:export device from pool:ot # # Trusted Extensions events: # diff --git a/usr/src/lib/libbsm/common/adt_event.h b/usr/src/lib/libbsm/common/adt_event.h index 91ab333548..f55e446097 100644 --- a/usr/src/lib/libbsm/common/adt_event.h +++ b/usr/src/lib/libbsm/common/adt_event.h @@ -93,6 +93,8 @@ enum adt_login_text { ADT_LOGIN_ANON_USER /* No anonymous */ }; #define ADT_admin_authenticate 3 +#define ADT_attach 42 +#define ADT_detach 43 #define ADT_filesystem_add 4 #define ADT_filesystem_delete 5 #define ADT_filesystem_modify 6 @@ -108,10 +110,13 @@ enum adt_login_text { #define ADT_network_modify 9 #define ADT_newgrp_login 41 #define ADT_passwd 27 +#define ADT_pool_export 46 +#define ADT_pool_import 45 #define ADT_printer_add 10 #define ADT_printer_delete 11 #define ADT_printer_modify 12 #define ADT_prof_cmd 24 +#define ADT_remove 44 #define ADT_rlogin 28 #define ADT_role_login 13 #define ADT_role_logout 40 @@ -140,6 +145,22 @@ struct adt_admin_authenticate { /* ADT_admin_authenticate */ }; typedef struct adt_admin_authenticate adt_admin_authenticate_t; +struct adt_attach { /* ADT_attach */ + char *auth_used; /* required */ + char *mount_point; /* required */ + char *device; /* required */ + char *options; /* optional */ +}; +typedef struct adt_attach adt_attach_t; + +struct adt_detach { /* ADT_detach */ + char *auth_used; /* required */ + char *mount_point; /* required */ + char *device; /* required */ + char *options; /* optional */ +}; +typedef struct adt_detach adt_detach_t; + struct adt_filesystem_add { /* ADT_filesystem_add */ char *object_name; /* required */ char *domain; /* optional */ @@ -248,6 +269,20 @@ struct adt_passwd { /* ADT_passwd */ }; typedef struct adt_passwd adt_passwd_t; +struct adt_pool_export { /* ADT_pool_export */ + char *auth_used; /* required */ + char *pool; /* required */ + char *device; /* required */ +}; +typedef struct adt_pool_export adt_pool_export_t; + +struct adt_pool_import { /* ADT_pool_import */ + char *auth_used; /* required */ + char *pool; /* required */ + char *device; /* required */ +}; +typedef struct adt_pool_import adt_pool_import_t; + struct adt_printer_add { /* ADT_printer_add */ char *object_name; /* required */ char *domain; /* optional */ @@ -294,6 +329,13 @@ struct adt_prof_cmd { /* ADT_prof_cmd */ }; typedef struct adt_prof_cmd adt_prof_cmd_t; +struct adt_remove { /* ADT_remove */ + char *auth_used; /* required */ + char *mount_point; /* optional */ + char *device; /* required */ +}; +typedef struct adt_remove adt_remove_t; + struct adt_rlogin { /* ADT_rlogin */ enum adt_login_text message; /* optional */ }; @@ -439,6 +481,8 @@ typedef struct adt_zone_state adt_zone_state_t; union adt_event_data { adt_admin_authenticate_t adt_admin_authenticate; + adt_attach_t adt_attach; + adt_detach_t adt_detach; adt_filesystem_add_t adt_filesystem_add; adt_filesystem_delete_t adt_filesystem_delete; adt_filesystem_modify_t adt_filesystem_modify; @@ -454,10 +498,13 @@ union adt_event_data { adt_network_modify_t adt_network_modify; adt_newgrp_login_t adt_newgrp_login; adt_passwd_t adt_passwd; + adt_pool_export_t adt_pool_export; + adt_pool_import_t adt_pool_import; adt_printer_add_t adt_printer_add; adt_printer_delete_t adt_printer_delete; adt_printer_modify_t adt_printer_modify; adt_prof_cmd_t adt_prof_cmd; + adt_remove_t adt_remove; adt_rlogin_t adt_rlogin; adt_role_login_t adt_role_login; adt_role_logout_t adt_role_logout; diff --git a/usr/src/lib/libbsm/common/adt_xlate.c b/usr/src/lib/libbsm/common/adt_xlate.c index 452a102492..1da827d5f7 100644 --- a/usr/src/lib/libbsm/common/adt_xlate.c +++ b/usr/src/lib/libbsm/common/adt_xlate.c @@ -73,6 +73,50 @@ static struct translation X_admin_authenticate = { &XX_admin_authenticate[0], &XX_admin_authenticate[0] }; +static struct entry XX_attach[6] = { + {AUT_SUBJECT, 1, NULL, &(XX_attach[1]), + 0, 0, 0, NULL}, + {AUT_UAUTH, 1, &adr1[0], &(XX_attach[2]), + 0, 1, 0, NULL}, + {AUT_PATH, 1, &adr1[0], &(XX_attach[3]), + 0, 1, 0, NULL}, + {AUT_PATH, 1, &adr1[0], &(XX_attach[4]), + 0, 1, 0, NULL}, + {AUT_TEXT, 1, &adr1[0], &(XX_attach[5]), + 0, 0, 0, NULL}, + {AUT_RETURN, 1, NULL, NULL, + 0, 0, 0, NULL} +}; +static struct translation X_attach = { + 0, + ADT_attach, + AUE_attach, + 6, + &XX_attach[0], + &XX_attach[0] +}; +static struct entry XX_detach[6] = { + {AUT_SUBJECT, 1, NULL, &(XX_detach[1]), + 0, 0, 0, NULL}, + {AUT_UAUTH, 1, &adr1[0], &(XX_detach[2]), + 0, 1, 0, NULL}, + {AUT_PATH, 1, &adr1[0], &(XX_detach[3]), + 0, 1, 0, NULL}, + {AUT_PATH, 1, &adr1[0], &(XX_detach[4]), + 0, 1, 0, NULL}, + {AUT_TEXT, 1, &adr1[0], &(XX_detach[5]), + 0, 0, 0, NULL}, + {AUT_RETURN, 1, NULL, NULL, + 0, 0, 0, NULL} +}; +static struct translation X_detach = { + 0, + ADT_detach, + AUE_detach, + 6, + &XX_detach[0], + &XX_detach[0] +}; static struct entry XX_filesystem_add[7] = { {AUT_SUBJECT, 1, NULL, &(XX_filesystem_add[1]), 0, 0, 0, NULL}, @@ -373,6 +417,46 @@ static struct translation X_passwd = { &XX_passwd[0], &XX_passwd[0] }; +static struct entry XX_pool_export[5] = { + {AUT_SUBJECT, 1, NULL, &(XX_pool_export[1]), + 0, 0, 0, NULL}, + {AUT_UAUTH, 1, &adr1[0], &(XX_pool_export[2]), + 0, 1, 0, NULL}, + {AUT_TEXT, 1, &adr1[0], &(XX_pool_export[3]), + 0, 1, 0, NULL}, + {AUT_PATH, 1, &adr1[0], &(XX_pool_export[4]), + 0, 1, 0, NULL}, + {AUT_RETURN, 1, NULL, NULL, + 0, 0, 0, NULL} +}; +static struct translation X_pool_export = { + 0, + ADT_pool_export, + AUE_pool_export, + 5, + &XX_pool_export[0], + &XX_pool_export[0] +}; +static struct entry XX_pool_import[5] = { + {AUT_SUBJECT, 1, NULL, &(XX_pool_import[1]), + 0, 0, 0, NULL}, + {AUT_UAUTH, 1, &adr1[0], &(XX_pool_import[2]), + 0, 1, 0, NULL}, + {AUT_TEXT, 1, &adr1[0], &(XX_pool_import[3]), + 0, 1, 0, NULL}, + {AUT_PATH, 1, &adr1[0], &(XX_pool_import[4]), + 0, 1, 0, NULL}, + {AUT_RETURN, 1, NULL, NULL, + 0, 0, 0, NULL} +}; +static struct translation X_pool_import = { + 0, + ADT_pool_import, + AUE_pool_import, + 5, + &XX_pool_import[0], + &XX_pool_import[0] +}; static struct entry XX_printer_add[7] = { {AUT_SUBJECT, 1, NULL, &(XX_printer_add[1]), 0, 0, 0, NULL}, @@ -471,6 +555,26 @@ static struct translation X_prof_cmd = { &XX_prof_cmd[0], &XX_prof_cmd[0] }; +static struct entry XX_remove[5] = { + {AUT_SUBJECT, 1, NULL, &(XX_remove[1]), + 0, 0, 0, NULL}, + {AUT_UAUTH, 1, &adr1[0], &(XX_remove[2]), + 0, 1, 0, NULL}, + {AUT_PATH, 1, &adr1[0], &(XX_remove[3]), + 0, 0, 0, NULL}, + {AUT_PATH, 1, &adr1[0], &(XX_remove[4]), + 0, 1, 0, NULL}, + {AUT_RETURN, 1, NULL, NULL, + 0, 0, 0, NULL} +}; +static struct translation X_remove = { + 0, + ADT_remove, + AUE_remove, + 5, + &XX_remove[0], + &XX_remove[0] +}; static struct entry XX_rlogin[3] = { {AUT_SUBJECT, 1, NULL, &(XX_rlogin[1]), 0, 0, 0, NULL}, @@ -875,8 +979,10 @@ static struct translation X_zone_state = { &XX_zone_state[0], &XX_zone_state[0] }; -struct translation *xlate_table[42] = { +struct translation *xlate_table[47] = { &X_admin_authenticate, + &X_attach, + &X_detach, &X_filesystem_add, &X_filesystem_delete, &X_filesystem_modify, @@ -892,10 +998,13 @@ struct translation *xlate_table[42] = { &X_network_modify, &X_newgrp_login, &X_passwd, + &X_pool_export, + &X_pool_import, &X_printer_add, &X_printer_delete, &X_printer_modify, &X_prof_cmd, + &X_remove, &X_rlogin, &X_role_login, &X_role_logout, diff --git a/usr/src/lib/libbsm/common/adt_xml.txt b/usr/src/lib/libbsm/common/adt_xml.txt index 8efee26724..222dfaf59c 100644 --- a/usr/src/lib/libbsm/common/adt_xml.txt +++ b/usr/src/lib/libbsm/common/adt_xml.txt @@ -737,8 +737,114 @@ Use is subject to license terms. </entry> </event> + <event id="AUE_generic_mountable" type="generic" omit="always"> + <!-- + + User device mounting related functions + + --> + <entry id="subject"> + <internal token="subject"/> + <external opt="none"/> + </entry> + <entry id="auth_used"> + <internal token="uauth"/> + <external opt="required" type="char *"/> + </entry> + <entry id="mount_point"> + <internal token="path"/> + <external opt="required" type="char *"/> + </entry> + <entry id="device"> + <internal token="path"/> + <external opt="required" type="char *"/> + </entry> + <entry id="options"> + <internal token="text"/> + <external opt="optional" type="char *"/> + </entry> + <entry id="return"> + <internal token="return"/> + <external opt="none"/> + </entry> + </event> + + <event id="AUE_attach" instance_of="AUE_generic_mountable" + header="0" idNo="42" omit="JNI"> + </event> + <event id="AUE_detach" instance_of="AUE_generic_mountable" + header="0" idNo="43" omit="JNI"> + </event> + <event id="AUE_remove" header="0" idNo="44" omit="JNI"> + <entry id="subject"> + <internal token="subject"/> + <external opt="none"/> + </entry> + <entry id="auth_used"> + <internal token="uauth"/> + <external opt="required" type="char *"/> + </entry> + <entry id="mount_point"> + <internal token="path"/> + <external opt="optional" type="char *"/> + </entry> + <entry id="device"> + <internal token="path"/> + <external opt="required" type="char *"/> + </entry> + <entry id="return"> + <internal token="return"/> + <external opt="none"/> + </entry> + </event> + + <event id="AUE_pool_import" header="0" idNo="45" omit="JNI"> + <entry id="subject"> + <internal token="subject"/> + <external opt="none"/> + </entry> + <entry id="auth_used"> + <internal token="uauth"/> + <external opt="required" type="char *"/> + </entry> + <entry id="pool"> + <internal token="text"/> + <external opt="required" type="char *"/> + </entry> + <entry id="device"> + <internal token="path"/> + <external opt="required" type="char *"/> + </entry> + <entry id="return"> + <internal token="return"/> + <external opt="none"/> + </entry> + </event> + <event id="AUE_pool_export" header="0" idNo="46" omit="JNI"> + <entry id="subject"> + <internal token="subject"/> + <external opt="none"/> + </entry> + <entry id="auth_used"> + <internal token="uauth"/> + <external opt="required" type="char *"/> + </entry> + <entry id="pool"> + <internal token="text"/> + <external opt="required" type="char *"/> + </entry> + <entry id="device"> + <internal token="path"/> + <external opt="required" type="char *"/> + </entry> + <entry id="return"> + <internal token="return"/> + <external opt="none"/> + </entry> + </event> + <!-- add new everts here with the next higher idNo --> -<!-- Highest idNo is 41, so next is 42, then fix this comment --> +<!-- Highest idNo is 46, so next is 47, then fix this comment --> <!-- end of C Only events --> diff --git a/usr/src/lib/libdevinfo/devinfo_devperm.c b/usr/src/lib/libdevinfo/devinfo_devperm.c index 412eb74fc8..18e2409065 100644 --- a/usr/src/lib/libdevinfo/devinfo_devperm.c +++ b/usr/src/lib/libdevinfo/devinfo_devperm.c @@ -87,6 +87,7 @@ setdevaccess(char *dev, uid_t uid, gid_t gid, mode_t mode, { int err = 0, local_errno; char errstring[MAX_LINELEN]; + struct stat st; if (chown(dev, uid, gid) == -1) { if (errno == ENOENT) /* no such file */ @@ -95,17 +96,22 @@ setdevaccess(char *dev, uid_t uid, gid_t gid, mode_t mode, local_errno = errno; } - while (fdetach(dev) == 0) { - if (chown(dev, uid, gid) == -1) { - err = -1; - local_errno = errno; + /* + * don't fdetach block devices, as it will unmount them + */ + if (!((stat(dev, &st) == 0) && ((st.st_mode & S_IFMT) == S_IFBLK))) { + while (fdetach(dev) == 0) { + if (chown(dev, uid, gid) == -1) { + err = -1; + local_errno = errno; + } + } + if (err && errmsg) { + (void) snprintf(errstring, MAX_LINELEN, + "failed to chown device %s: %s\n", + dev, strerror(local_errno)); + (*errmsg)(errstring); } - } - if (err && errmsg) { - (void) snprintf(errstring, MAX_LINELEN, - "failed to chown device %s: %s\n", - dev, strerror(local_errno)); - (*errmsg)(errstring); } /* diff --git a/usr/src/lib/libdiskmgt/Makefile.com b/usr/src/lib/libdiskmgt/Makefile.com index 350c1248fd..735889cc8b 100644 --- a/usr/src/lib/libdiskmgt/Makefile.com +++ b/usr/src/lib/libdiskmgt/Makefile.com @@ -37,7 +37,7 @@ include ../../Makefile.lib LIBS = $(DYNLIB) $(LINTLIB) LDLIBS += -ldevinfo -ladm -ldevid -lkstat -lsysevent \ - -lvolmgt -lnvpair -lefi -lc + -lnvpair -lefi -lc LDFLAGS += -R/opt/VRTSvxvm/lib SRCDIR = ../common diff --git a/usr/src/lib/libdiskmgt/common/disks_private.h b/usr/src/lib/libdiskmgt/common/disks_private.h index 2d738dfcbf..0f782bc383 100644 --- a/usr/src/lib/libdiskmgt/common/disks_private.h +++ b/usr/src/lib/libdiskmgt/common/disks_private.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -98,7 +97,6 @@ typedef struct disk { char *device_id; /* string encoded device id */ ddi_devid_t devid; /* decoded device id */ char *kernel_name; /* handles drives w/ no devlinks */ - char *volm_path; char *product_id; char *vendor_id; controller_t **controllers; @@ -111,7 +109,6 @@ typedef struct disk { int rpm; int wide; int cd_rom; - int volm_path_set; } disk_t; typedef struct descriptor { @@ -196,7 +193,6 @@ descriptor_t *media_get_descriptor_by_name(char *name, int *errp); char *media_get_name(descriptor_t *desc); nvlist_t *media_get_attributes(descriptor_t *desc, int *errp); nvlist_t *media_get_stats(descriptor_t *desc, int stat_type, int *errp); -int media_get_volm_path(disk_t *diskp, char *mediapath, int size); int media_make_descriptors(); int media_read_info(int fd, struct dk_minfo *minfo); int media_read_name(disk_t *dp, char *mname, int size); diff --git a/usr/src/lib/libdiskmgt/common/drive.c b/usr/src/lib/libdiskmgt/common/drive.c index b3f32c70d6..825348ce9f 100644 --- a/usr/src/lib/libdiskmgt/common/drive.c +++ b/usr/src/lib/libdiskmgt/common/drive.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -626,99 +625,12 @@ drive_make_descriptors() /* * This function opens the disk generically (any slice). - * - * Opening the disk could fail because the disk is managed by the volume - * manager. Handle this if that is the case. Note that the media APIs don't - * always return a device. If the media has slices (e.g. a solaris install - * CD-ROM) then media_findname(volname) returns a directory with per slice - * devices underneath. We need to open one of those devices in this case. */ int drive_open_disk(disk_t *diskp, char *opath, int len) { - char rmmedia_devpath[MAXPATHLEN]; - - if (diskp->removable && media_get_volm_path(diskp, rmmedia_devpath, - sizeof (rmmedia_devpath))) { - - int fd; - struct stat buf; - - if (rmmedia_devpath[0] == 0) { - /* removable but no media */ - return (-1); - } - - if ((fd = open(rmmedia_devpath, O_RDONLY|O_NDELAY)) < 0) { - return (-1); - } - - if (fstat(fd, &buf) != 0) { - (void) close(fd); - return (-1); - } - - if (S_ISCHR(buf.st_mode)) { - /* opened, is device, so done */ - if (opath != NULL) { - (void) strlcpy(opath, rmmedia_devpath, len); - } - return (fd); - - } else if (S_ISDIR(buf.st_mode)) { - /* disk w/ slices so handle the directory */ - DIR *dirp; - struct dirent *dentp; - int dfd; - - /* each device file in the dir represents a slice */ - - if ((dirp = fdopendir(fd)) == NULL) { - (void) close(fd); - return (-1); - } - - while ((dentp = readdir(dirp)) != NULL) { - char slice_path[MAXPATHLEN]; - - if (libdiskmgt_str_eq(".", dentp->d_name) || - libdiskmgt_str_eq("..", dentp->d_name)) { - continue; - } - - (void) snprintf(slice_path, sizeof (slice_path), "%s/%s", - rmmedia_devpath, dentp->d_name); - - if ((dfd = open(slice_path, O_RDONLY|O_NDELAY)) < 0) { - continue; - } - - if (fstat(dfd, &buf) == 0 && S_ISCHR(buf.st_mode)) { - /* opened, is device, so done */ - (void) closedir(dirp); - if (opath != NULL) { - (void) strlcpy(opath, slice_path, len); - } - return (dfd); - } - - /* not a device, keep looking */ - (void) close(dfd); - } - - /* did not find a device under the rmmedia_path */ - (void) closedir(dirp); - return (-1); - } - - /* didn't find a device under volume management control */ - (void) close(fd); - return (-1); - } - /* - * Not removable media under volume management control so just open the - * first devpath. + * Just open the first devpath. */ if (diskp->aliases != NULL && diskp->aliases->devpaths != NULL) { if (opath != NULL) { diff --git a/usr/src/lib/libdiskmgt/common/findevs.c b/usr/src/lib/libdiskmgt/common/findevs.c index 5a5bd4fc15..42d57d428a 100644 --- a/usr/src/lib/libdiskmgt/common/findevs.c +++ b/usr/src/lib/libdiskmgt/common/findevs.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -977,15 +976,6 @@ create_disk(char *deviceid, char *kernel_name, struct search_args *args) /* not a "CD-ROM" or Floppy */ diskp->removable = get_prop(REMOVABLE_PROP, args->node); - if (diskp->removable == -1) { - /* - * This is a workaround. Hotpluggable devices don't export - * a "removable-media" property, but they are treated as - * removable media devices by vold to implement automount. - * Once vold is EOL'ed, it should be removed. - */ - diskp->removable = get_prop(HOTPLUGGABLE_PROP, args->node); - } if (diskp->removable == -1) { diskp->removable = 0; @@ -1026,8 +1016,6 @@ create_disk(char *deviceid, char *kernel_name, struct search_args *args) diskp->drv_type = DM_DT_FIXED; } } - diskp->volm_path_set = 0; - diskp->volm_path = NULL; diskp->next = args->disk_listp; args->disk_listp = diskp; diff --git a/usr/src/lib/libdiskmgt/common/media.c b/usr/src/lib/libdiskmgt/common/media.c index ac29898ede..9f6ee99ff1 100644 --- a/usr/src/lib/libdiskmgt/common/media.c +++ b/usr/src/lib/libdiskmgt/common/media.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -38,7 +37,6 @@ #include <sys/types.h> #include <unistd.h> #include <sys/vtoc.h> -#include <volmgt.h> #include <sys/efi_partition.h> #include "libdiskmgt.h" @@ -51,7 +49,7 @@ static descriptor_t **apply_filter(descriptor_t **media, int filter[], int *errp); static int get_attrs(disk_t *dp, int fd, nvlist_t *attrs); -static int get_non_volm_name(disk_t *dp, char *mname, int size); +static int get_rmm_name(disk_t *dp, char *mname, int size); static int get_media_type(uint_t media_type); static int desc_ok(descriptor_t *dp); @@ -215,90 +213,6 @@ media_get_stats(descriptor_t *dp, int stat_type, int *errp) return (NULL); } -/* - * Get the removable media volume manager devpath for the disk. This is the - * name we need to open that will work with vold. - * Return 1 if under volm control, 0 if not under volm control. - * The string in mediapath will be empty if the drive is under volm control - * but there is no media loaded. - */ -int -media_get_volm_path(disk_t *diskp, char *mediapath, int size) -{ - char vname[MAXPATHLEN]; - char *volname; - char *media_name; - - if (!diskp->removable || !volmgt_running()) { - return (0); - } - - /* - * The volume manager is running, so we have to check if this removable - * drive is under volm control or not. - */ - - /* - * We must check if this drive is under volume management control and - * what devpath to use. - * Note that we have to do this every time for drives that are not - * under the control of the volume manager, since the volume manager - * might have taken control since the last time we checked. - */ - if (diskp->volm_path_set == 0) { - alias_t *ap; - slice_t *dp; - - if ((ap = diskp->aliases) == NULL) { - return (0); - } - - /* Check each devpath to see if it is under volm control. */ - dp = ap->devpaths; - while (dp != NULL) { - slice_rdsk2dsk(dp->devpath, vname, sizeof (vname)); - if (volmgt_inuse(vname)) { - break; - } - - dp = dp->next; - } - - if (dp != NULL) { - /* Volume manager is managing the devpath that dp points to. */ - diskp->volm_path = dp->devpath; - diskp->volm_path_set = 1; - } - } - - if (diskp->volm_path_set == 0) { - /* The volume manager is not managing any of the devpaths. */ - return (0); - } - - if (dm_debug > 1) { - (void) fprintf(stderr, "INFO: chk vol: %s\n", diskp->volm_path); - } - - slice_rdsk2dsk(diskp->volm_path, vname, sizeof (vname)); - volname = volmgt_symname(vname); - if (volname == NULL) { - mediapath[0] = 0; - return (1); - } - - media_name = media_findname(volname); - free(volname); - if (media_name == NULL) { - mediapath[0] = 0; - return (1); - } - - (void) strlcpy(mediapath, media_name, size); - free(media_name); - return (1); -} - int media_make_descriptors() { @@ -357,9 +271,6 @@ media_read_info(int fd, struct dk_minfo *minfo) int media_read_name(disk_t *dp, char *mname, int size) { - int under_volm; - char rmmedia_devpath[MAXPATHLEN]; - mname[0] = 0; if (!dp->removable) { @@ -371,24 +282,7 @@ media_read_name(disk_t *dp, char *mname, int size) } /* This is a removable media drive. */ - - /* Get 1 if under volm control, 0 if not */ - under_volm = media_get_volm_path(dp, rmmedia_devpath, - sizeof (rmmedia_devpath)); - - if (under_volm) { - /* under volm control */ - if (rmmedia_devpath[0] == 0) { - /* no media */ - return (0); - } - (void) strlcpy(mname, rmmedia_devpath, size); - return (1); - - } else { - /* not under volm control */ - return (get_non_volm_name(dp, mname, size)); - } + return (get_rmm_name(dp, mname, size)); } static descriptor_t ** @@ -636,10 +530,10 @@ get_media_type(uint_t media_type) } /* - * This function handles removable media not under volume management. + * This function handles removable media. */ static int -get_non_volm_name(disk_t *dp, char *mname, int size) +get_rmm_name(disk_t *dp, char *mname, int size) { int loaded; int fd; diff --git a/usr/src/lib/libdiskmgt/common/partition.c b/usr/src/lib/libdiskmgt/common/partition.c index 49fa757330..e1f29479b9 100644 --- a/usr/src/lib/libdiskmgt/common/partition.c +++ b/usr/src/lib/libdiskmgt/common/partition.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -604,89 +603,8 @@ has_slices(descriptor_t *desc, int *errp) static int open_disk(disk_t *diskp, char *opath, int len) { - char rmmedia_devpath[MAXPATHLEN]; - - if (diskp->removable && media_get_volm_path(diskp, rmmedia_devpath, - sizeof (rmmedia_devpath))) { - - int fd; - struct stat buf; - - if (rmmedia_devpath[0] == 0) { - /* removable but no media */ - return (-1); - } - - if ((fd = open(rmmedia_devpath, O_RDONLY|O_NDELAY)) < 0) { - return (-1); - } - - if (fstat(fd, &buf) != 0) { - (void) close(fd); - return (-1); - } - - if (S_ISCHR(buf.st_mode)) { - /* opened, is device, so done */ - if (opath != NULL) { - (void) strlcpy(opath, rmmedia_devpath, len); - } - return (fd); - - } else if (S_ISDIR(buf.st_mode)) { - /* disk w/ slices so handle the directory */ - DIR *dirp; - struct dirent *dentp; - int dfd; - - /* each device file in the dir represents a slice */ - - if ((dirp = fdopendir(fd)) == NULL) { - (void) close(fd); - return (-1); - } - - while ((dentp = readdir(dirp)) != NULL) { - char slice_path[MAXPATHLEN]; - - if (libdiskmgt_str_eq(".", dentp->d_name) || - libdiskmgt_str_eq("..", dentp->d_name)) { - continue; - } - - (void) snprintf(slice_path, sizeof (slice_path), "%s/%s", - rmmedia_devpath, dentp->d_name); - - if ((dfd = open(slice_path, O_RDONLY|O_NDELAY)) < 0) { - continue; - } - - if (fstat(dfd, &buf) == 0 && S_ISCHR(buf.st_mode)) { - /* opened, is device, so done */ - (void) closedir(dirp); - if (opath != NULL) { - (void) strlcpy(opath, slice_path, len); - } - return (dfd); - } - - /* not a device, keep looking */ - (void) close(dfd); - } - - /* did not find a device under the rmmedia_path */ - (void) closedir(dirp); - return (-1); - } - - /* didn't find a device under volume management control */ - (void) close(fd); - return (-1); - } - /* - * Not removable media under volume management control so just open the - * first devpath. + * Just open the first devpath. */ if (diskp->aliases != NULL && diskp->aliases->devpaths != NULL) { #ifdef sparc diff --git a/usr/src/lib/libdiskmgt/common/slice.c b/usr/src/lib/libdiskmgt/common/slice.c index e94c443cfb..2e76e43671 100644 --- a/usr/src/lib/libdiskmgt/common/slice.c +++ b/usr/src/lib/libdiskmgt/common/slice.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -73,17 +72,9 @@ static int desc_ok(descriptor_t *dp); static void dsk2rdsk(char *dsk, char *rdsk, int size); static int get_attrs(descriptor_t *dp, int fd, nvlist_t *attrs); static descriptor_t **get_fixed_assocs(descriptor_t *desc, int *errp); -static descriptor_t **get_removable_assocs(descriptor_t *desc, char *volm_path, - int *errp); static int get_slice_num(slice_t *devp); static int match_fixed_name(disk_t *dp, char *name, int *errp); -static int match_removable_name(disk_t *dp, char *name, int *errp); static int make_fixed_descriptors(disk_t *dp); -static int make_removable_descriptors(disk_t *dp); -static int make_volm_dir_descriptors(disk_t *dp, int fd, - char *volm_path); -static int num_removable_slices(int fd, struct stat *bufp, - char *volm_path); descriptor_t ** slice_get_assoc_descriptors(descriptor_t *desc, dm_desc_type_t type, @@ -114,35 +105,13 @@ slice_get_assoc_descriptors(descriptor_t *desc, dm_desc_type_t type, descriptor_t ** slice_get_assocs(descriptor_t *desc, int *errp) { - int under_volm = 0; - char volm_path[MAXPATHLEN]; - /* Just check the first drive name. */ if (desc->p.disk->aliases == NULL) { *errp = 0; return (libdiskmgt_empty_desc_array(errp)); } - if (desc->p.disk->removable) { - if ((under_volm = media_get_volm_path(desc->p.disk, volm_path, - sizeof (volm_path)))) { - if (volm_path[0] == 0) { - /* no media */ - *errp = 0; - return (libdiskmgt_empty_desc_array(errp)); - } - } - } - - if (desc->p.disk->removable) { - if (under_volm) { - return (get_removable_assocs(desc, volm_path, errp)); - } else { - return (get_fixed_assocs(desc, errp)); - } - } else { - return (get_fixed_assocs(desc, errp)); - } + return (get_fixed_assocs(desc, errp)); } nvlist_t * @@ -188,24 +157,21 @@ slice_get_descriptor_by_name(char *name, int *errp) disk_t *dp; for (dp = cache_get_disklist(); dp != NULL; dp = dp->next) { - if (dp->removable) { - found = match_removable_name(dp, name, errp); - } else { found = match_fixed_name(dp, name, errp); - } - if (found) { - char mname[MAXPATHLEN]; + if (found) { + char mname[MAXPATHLEN]; - if (*errp != 0) { - return (NULL); - } + if (*errp != 0) { + return (NULL); + } - mname[0] = 0; - (void) media_read_name(dp, mname, sizeof (mname)); + mname[0] = 0; + (void) media_read_name(dp, mname, sizeof (mname)); - return (cache_get_desc(DM_SLICE, dp, name, mname, errp)); - } + return (cache_get_desc(DM_SLICE, dp, name, mname, + errp)); + } } *errp = ENODEV; @@ -310,11 +276,7 @@ slice_make_descriptors() while (dp != NULL) { int error; - if (dp->removable) { - error = make_removable_descriptors(dp); - } else { - error = make_fixed_descriptors(dp); - } + error = make_fixed_descriptors(dp); if (error != 0) { return (error); } @@ -750,140 +712,6 @@ get_fixed_assocs(descriptor_t *desc, int *errp) return (slices); } -/* - * Called for loaded removable media under volume management control. - */ -static descriptor_t ** -get_removable_assocs(descriptor_t *desc, char *volm_path, int *errp) -{ - int pos; - int fd; - int cnt; - struct stat buf; - descriptor_t **slices; - char *media_name = NULL; - char devpath[MAXPATHLEN]; - - /* get the media name from the descriptor */ - if (desc->type == DM_MEDIA) { - media_name = desc->name; - } else { - /* must be a DM_PARTITION */ - media_name = desc->secondary_name; - } - - /* - * For removable media under volm control the volm_path will - * either be a device (if the media is made up of a single slice) or - * a directory (if the media has multiple slices) with the slices - * as devices contained in the directory. - */ - - if ((fd = open(volm_path, O_RDONLY|O_NDELAY)) < 0 || - fstat(fd, &buf) != 0) { - *errp = ENODEV; - return (NULL); - } - - cnt = num_removable_slices(fd, &buf, volm_path); - - /* allocate the array for the descriptors */ - slices = calloc(cnt + 1, sizeof (descriptor_t *)); - if (slices == NULL) { - *errp = ENOMEM; - return (NULL); - } - - slice_rdsk2dsk(volm_path, devpath, sizeof (devpath)); - - pos = 0; - *errp = 0; - if (S_ISCHR(buf.st_mode)) { - struct dk_minfo minfo; - - /* Make sure media has readable label */ - if (media_read_info(fd, &minfo)) { - int status; - int data_format = FMT_UNKNOWN; - struct vtoc vtoc; - struct dk_gpt *efip; - - if ((status = read_vtoc(fd, &vtoc)) >= 0) { - data_format = FMT_VTOC; - } else if (status == VT_ENOTSUP && - efi_alloc_and_read(fd, &efip) >= 0) { - data_format = FMT_EFI; - } - - if (data_format != FMT_UNKNOWN) { - /* has a readable label */ - slices[pos++] = - cache_get_desc(DM_SLICE, desc->p.disk, - devpath, media_name, errp); - } - } - (void) close(fd); - } else if (S_ISDIR(buf.st_mode)) { - DIR *dirp; - struct dirent *dentp; - - /* rewind, num_removable_slices already traversed */ - (void) lseek(fd, 0, SEEK_SET); - - if ((dirp = fdopendir(fd)) == NULL) { - *errp = errno; - (void) close(fd); - return (NULL); - } - - while ((dentp = readdir(dirp)) != NULL) { - int dfd; - int is_dev = 0; - char slice_path[MAXPATHLEN]; - - if (libdiskmgt_str_eq(".", dentp->d_name) || - libdiskmgt_str_eq("..", dentp->d_name)) { - continue; - } - - (void) snprintf(slice_path, sizeof (slice_path), - "%s/%s", devpath, dentp->d_name); - - if ((dfd = open(slice_path, O_RDONLY|O_NDELAY)) >= 0) { - struct stat buf; - - if (fstat(dfd, &buf) == 0 && - S_ISCHR(buf.st_mode)) { - is_dev = 1; - } - (void) close(dfd); - } - - if (!is_dev) { - continue; - } - - slices[pos++] = cache_get_desc(DM_SLICE, desc->p.disk, - slice_path, media_name, errp); - if (*errp != 0) { - break; - } - } - (void) closedir(dirp); - } else { - (void) close(fd); - } - - slices[pos] = NULL; - - if (*errp != 0) { - cache_free_descriptors(slices); - return (NULL); - } - - return (slices); -} - static int get_slice_num(slice_t *devp) { @@ -979,141 +807,6 @@ make_fixed_descriptors(disk_t *dp) } /* - * For removable media under volm control we have to do some special handling. - * We don't use the vtoc and /dev/dsk devpaths, since the slices are named - * under the /vol fs. - */ -static int -make_removable_descriptors(disk_t *dp) -{ - char volm_path[MAXPATHLEN]; - int error; - int fd; - - /* - * If this removable drive is not under volm control, just use - * normal handling. - */ - if (!media_get_volm_path(dp, volm_path, sizeof (volm_path))) { - return (make_fixed_descriptors(dp)); - } - - if (volm_path[0] == 0) { - /* no media */ - return (0); - } - - /* - * For removable media under volm control the rmmedia_devapth will - * either be a device (if the media is made up of a single slice) or - * a directory (if the media has multiple slices) with the slices - * as devices contained in the directory. - */ - error = 0; - if ((fd = open(volm_path, O_RDONLY|O_NDELAY)) >= 0) { - struct stat buf; - - if (fstat(fd, &buf) == 0) { - if (S_ISCHR(buf.st_mode)) { - int status; - int data_format = FMT_UNKNOWN; - struct dk_minfo minfo; - int error; - struct vtoc vtoc; - struct dk_gpt *efip; - char devpath[MAXPATHLEN]; - - /* Make sure media has readable label */ - if (!media_read_info(fd, &minfo)) { - /* no media */ - return (0); - } - - if ((status = read_vtoc(fd, &vtoc)) >= 0) { - data_format = FMT_VTOC; - } else if (status == VT_ENOTSUP && - efi_alloc_and_read(fd, &efip) >= 0) { - data_format = FMT_EFI; - } - - if (data_format == FMT_UNKNOWN) { - /* no readable label */ - return (0); - } - - slice_rdsk2dsk(volm_path, devpath, sizeof (devpath)); - /* The media name is the volm_path in this case. */ - cache_load_desc(DM_SLICE, dp, devpath, volm_path, &error); - - } else if (S_ISDIR(buf.st_mode)) { - /* each device file in the dir represents a slice */ - error = make_volm_dir_descriptors(dp, fd, volm_path); - } - } - (void) close(fd); - } - - return (error); -} - -/* - * This handles removable media with slices under volume management control. - * In this case we have a dir which is the media name and each slice on the - * media is a device file in this dir. - */ -static int -make_volm_dir_descriptors(disk_t *dp, int dirfd, char *volm_path) -{ - int error; - DIR *dirp; - struct dirent *dentp; - char devpath[MAXPATHLEN]; - - dirfd = dup(dirfd); - if (dirfd < 0) - return (0); - if ((dirp = fdopendir(dirfd)) == NULL) { - (void) close(dirfd); - return (0); - } - - slice_rdsk2dsk(volm_path, devpath, sizeof (devpath)); - - error = 0; - while ((dentp = readdir(dirp)) != NULL) { - int fd; - char slice_path[MAXPATHLEN]; - - if (libdiskmgt_str_eq(".", dentp->d_name) || - libdiskmgt_str_eq("..", dentp->d_name)) { - continue; - } - - (void) snprintf(slice_path, sizeof (slice_path), "%s/%s", - devpath, dentp->d_name); - - if ((fd = open(slice_path, O_RDONLY|O_NDELAY)) >= 0) { - struct stat buf; - - /* The media name is the volm_path in this case. */ - if (fstat(fd, &buf) == 0 && S_ISCHR(buf.st_mode)) { - cache_load_desc(DM_SLICE, dp, slice_path, - volm_path, &error); - if (error != 0) { - (void) close(fd); - break; - } - } - - (void) close(fd); - } - } - (void) closedir(dirp); - - return (error); -} - -/* * Just look for the name on the devpaths we have cached. Return 1 if we * find the name and the size of that slice is non-zero. */ @@ -1206,161 +899,3 @@ match_fixed_name(disk_t *diskp, char *name, int *errp) *errp = ENODEV; return (1); } - -static int -match_removable_name(disk_t *diskp, char *name, int *errp) -{ - char volm_path[MAXPATHLEN]; - int found; - int fd; - struct stat buf; - - /* - * If this removable drive is not under volm control, just use - * normal handling. - */ - if (!media_get_volm_path(diskp, volm_path, sizeof (volm_path))) { - return (match_fixed_name(diskp, name, errp)); - } - - if (volm_path[0] == 0) { - /* no media */ - *errp = 0; - return (0); - } - - /* - * For removable media under volm control the rmmedia_devapth will - * either be a device (if the media is made up of a single slice) or - * a directory (if the media has multiple slices) with the slices - * as devices contained in the directory. - */ - - *errp = 0; - - if ((fd = open(volm_path, O_RDONLY|O_NDELAY)) == -1 || - fstat(fd, &buf) != 0) { - return (0); - } - - found = 0; - - if (S_ISCHR(buf.st_mode)) { - char devpath[MAXPATHLEN]; - - slice_rdsk2dsk(volm_path, devpath, sizeof (devpath)); - if (libdiskmgt_str_eq(name, devpath)) { - found = 1; - } - (void) close(fd); - return (found); - } else if (S_ISDIR(buf.st_mode)) { - /* each device file in the dir represents a slice */ - DIR *dirp; - struct dirent *dentp; - char devpath[MAXPATHLEN]; - - if ((dirp = fdopendir(fd)) == NULL) { - (void) close(fd); - return (0); - } - - slice_rdsk2dsk(volm_path, devpath, sizeof (devpath)); - - while ((dentp = readdir(dirp)) != NULL) { - char slice_path[MAXPATHLEN]; - - if (libdiskmgt_str_eq(".", dentp->d_name) || - libdiskmgt_str_eq("..", dentp->d_name)) { - continue; - } - - (void) snprintf(slice_path, sizeof (slice_path), - "%s/%s", devpath, dentp->d_name); - - if (libdiskmgt_str_eq(name, slice_path)) { - /* found name, check device */ - int dfd; - int is_dev = 0; - - dfd = open(slice_path, O_RDONLY|O_NDELAY); - if (dfd >= 0) { - struct stat buf; - - if (fstat(dfd, &buf) == 0 && - S_ISCHR(buf.st_mode)) { - is_dev = 1; - } - (void) close(dfd); - } - - /* we found the name */ - found = 1; - - if (!is_dev) { - *errp = ENODEV; - } - - break; - } - } - (void) closedir(dirp); - } else { - (void) close(fd); - } - - return (found); -} - -static int -num_removable_slices(int fd, struct stat *bufp, char *volm_path) -{ - int cnt = 0; - - if (S_ISCHR(bufp->st_mode)) - return (1); - - if (S_ISDIR(bufp->st_mode)) { - /* each device file in the dir represents a slice */ - DIR *dirp; - struct dirent *dentp; - char devpath[MAXPATHLEN]; - - fd = dup(fd); - - if (fd < 0) - return (0); - - if ((dirp = fdopendir(fd)) == NULL) { - (void) close(fd); - return (0); - } - - slice_rdsk2dsk(volm_path, devpath, sizeof (devpath)); - - while ((dentp = readdir(dirp)) != NULL) { - int dfd; - char slice_path[MAXPATHLEN]; - - if (libdiskmgt_str_eq(".", dentp->d_name) || - libdiskmgt_str_eq("..", dentp->d_name)) { - continue; - } - - (void) snprintf(slice_path, sizeof (slice_path), - "%s/%s", devpath, dentp->d_name); - - if ((dfd = open(slice_path, O_RDONLY|O_NDELAY)) >= 0) { - struct stat buf; - - if (fstat(dfd, &buf) == 0 && - S_ISCHR(buf.st_mode)) { - cnt++; - } - (void) close(dfd); - } - } - (void) closedir(dirp); - } - return (cnt); -} diff --git a/usr/src/lib/libsecdb/auth_attr.txt b/usr/src/lib/libsecdb/auth_attr.txt index b667fa61dc..5a2ec0e67f 100644 --- a/usr/src/lib/libsecdb/auth_attr.txt +++ b/usr/src/lib/libsecdb/auth_attr.txt @@ -40,6 +40,11 @@ solaris.device.config:::Configure Device Attributes::help=DevConfig.html solaris.device.grant:::Delegate Device Administration::help=DevGrant.html solaris.device.revoke:::Revoke or Reclaim Device::help=DevRevoke.html solaris.device.cdrw:::CD-R/RW Recording Authorizations::help=DevCDRW.html +solaris.device.mount.:::Device Mount::help=DevMount.html +solaris.device.mount.alloptions.fixed:::Device Mount Fixed With All Options::help=DevMount.html +solaris.device.mount.alloptions.removable:::Device Mount Removable With All Options::help=DevMount.html +solaris.device.mount.fixed:::Device Mount Fixed::help=DevMount.html +solaris.device.mount.removable:::Device Mount Removable::help=DevMount.html # solaris.dhcpmgr.:::DHCP Service Management::help=DhcpmgrHeader.html solaris.dhcpmgr.write:::Modify DHCP Service Configuration::help=DhcpmgrWrite.html @@ -82,8 +87,10 @@ solaris.smf.manage.:::Manage All SMF Service States::help=SmfManageHeader.html solaris.smf.manage.autofs:::Manage Automount Service States::help=SmfAutofsStates.html solaris.smf.manage.bind:::Manage DNS Service States::help=BindStates.html solaris.smf.manage.cron:::Manage Cron Service States::help=SmfCronStates.html +solaris.smf.manage.hal:::Manage HAL Service States::help=SmfHALStates.html solaris.smf.manage.name-service-cache:::Manage Name Service Cache Daemon Service States::help=SmfNscdStates.html solaris.smf.manage.power:::Manage Power Management Service States::help=SmfPowerStates.html +solaris.smf.manage.rmvolmgr:::Manage Rmvolmgr Service States::help=SmfRmvolmgrStates.html solaris.smf.manage.rpc.bind:::Manage RPC Program number mapper::help=SmfRPCBind.html solaris.smf.manage.sendmail:::Manage Sendmail Service States::help=SmfSendmailStates.html solaris.smf.manage.ssh:::Manage Secure Shell Service States::help=SmfSshStates.html diff --git a/usr/src/lib/libsecdb/prof_attr.txt b/usr/src/lib/libsecdb/prof_attr.txt index b18e06d42c..a79f9aabe4 100644 --- a/usr/src/lib/libsecdb/prof_attr.txt +++ b/usr/src/lib/libsecdb/prof_attr.txt @@ -20,7 +20,7 @@ # # -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" @@ -39,11 +39,12 @@ Device Management:::Control Access to Removable Media:auths=solaris.device.*;hel Printer Management:::Manage printers, daemons, spooling:help=RtPrntAdmin.html Cron Management:::Manage at and cron jobs:auths=solaris.jobs.*,solaris.smf.manage.cron;help=RtCronMngmnt.html Log Management:::Manage log files:help=RtLogMngmnt.html -Basic Solaris User:::Automatically assigned rights:auths=solaris.profmgr.read,solaris.jobs.user,solaris.mail.mailq;profiles=All;help=RtDefault.html +Basic Solaris User:::Automatically assigned rights:auths=solaris.profmgr.read,solaris.jobs.user,solaris.mail.mailq,solaris.device.mount.removable;profiles=All;help=RtDefault.html Device Security:::Manage devices and Volume Manager:auths=solaris.device.*;help=RtDeviceSecurity.html DHCP Management:::Manage the DHCP service:auths=solaris.dhcpmgr.*;help=RtDHCPMngmnt.html File System Management:::Manage, mount, share file systems:auths=solaris.smf.manage.autofs;help=RtFileSysMngmnt.html File System Security:::Manage file system security attributes:help=RtFileSysSecurity.html +HAL Management:::Manage HAL SMF service:auths=solaris.smf.manage.hal;help=RtHALMngmnt.html Mail Management:::Manage sendmail & queues:auths=solaris.smf.manage.sendmail;help=RtMailMngmnt.html Maintenance and Repair:::Maintain and repair a system:auths=solaris.smf.manage.system-log;help=RtMaintAndRepair.html Media Backup:::Backup files and file systems:help=RtMediaBkup.html @@ -57,6 +58,7 @@ Name Service Security:::Security related name service scripts/commands:help=RtNa Object Access Management:::Change ownership and permission on files:help=RtObAccessMngmnt.html Process Management:::Manage current processes and processors:auths=solaris.smf.manage.cron,solaris.smf.manage.power;help=RtProcManagement.html Rights Delegation:::Delegate ability to assign rights to users and roles:auths=solaris.role.delegate,solaris.profmgr.delegate,solaris.grant;help=RtRightsDelegate.html +Rmvolmgr Management:::Manage Removable Volume Manager SMF service:auths=solaris.smf.manage.rmvolmgr;help=RtRmvolmgrMngmnt.html Service Management:::Manage services:auths=solaris.smf.manage,solaris.smf.modify Service Operator:::Administer services:auths=solaris.smf.manage,solaris.smf.modify.framework Software Installation:::Add application software to the system:help=RtSoftwareInstall.html diff --git a/usr/src/lib/libvolmgt/Makefile.com b/usr/src/lib/libvolmgt/Makefile.com index 0a5a1187b6..c91a0027a1 100644 --- a/usr/src/lib/libvolmgt/Makefile.com +++ b/usr/src/lib/libvolmgt/Makefile.com @@ -28,8 +28,7 @@ LIBRARY= libvolmgt.a VERS=.1 -OBJECTS= volattr.o volutil.o volprivate.o volname.o volmgt_fsi.o \ - volmgt_fsidbi.o volmgt_on_private.o +OBJECTS= volmgt.o volprivate.o volmgt_on_private.o # include library definitions include ../../Makefile.lib diff --git a/usr/src/lib/libvolmgt/common/llib-lvolmgt b/usr/src/lib/libvolmgt/common/llib-lvolmgt index ed4277a32b..1f12243534 100644 --- a/usr/src/lib/libvolmgt/common/llib-lvolmgt +++ b/usr/src/lib/libvolmgt/common/llib-lvolmgt @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -23,8 +22,8 @@ /* PROTOLIB1 */ /* - * Copyright(c) 1997 by Sun Microsystems, Inc. - * All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -40,7 +39,6 @@ #include <sys/types.h> #include <sys/stat.h> #include <sys/param.h> -#include <sys/vol.h> /* volmgt_fsi.c */ int volmgt_acquire(char *, char *, int, char **, pid_t *); diff --git a/usr/src/lib/libvolmgt/common/volattr.c b/usr/src/lib/libvolmgt/common/volattr.c deleted file mode 100644 index 3e97f08449..0000000000 --- a/usr/src/lib/libvolmgt/common/volattr.c +++ /dev/null @@ -1,337 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright (c) 1996 by Sun Microsystems, Inc. - * All rights reserved. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <stdio.h> -#include <fcntl.h> -#include <string.h> -#include <unistd.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/param.h> -#include <sys/vol.h> -#include <errno.h> - -/* - * returns the "value" of the attribute. - * If the attribute is boolean and is TRUE, - * "true" is returned. If the boolean is - * FALSE, NULL is returned. If the attribute - * doesn't exist, NULL is returned. The pointer - * returned by media_getattr has been malloc'd and - * it is the callers responsibility to free it. - */ -/* - * arc approved interface - * - can not be modified without approval from an arc - * - * committment level: - * public - * - * description: - * media_getattr: returns the value for an attribute for a piece of - * removable media. - * - * arguments: - * path - Path to the media in /vol. Can be the block or character - * device. - * - * attr - name of the attribute. - * - * return value(s): - * returns NULL or a pointer to a string that contains the value for - * the requested attribute. - * - * NULL can mean: - * - the media doesn't exist - * - there is no more space for malloc(3) - * - the attribute doesn't exist for the named media - * - the attribute is a boolean and is FALSE - * - * the pointer to the string must be free'd with free(3). - * - * preconditions: - * volume management (vold) must be running. - */ -char * -media_getattr(char *vol_path, char *attr) -{ - int fd = -1; - struct stat64 sb; - char valuebuf[MAX_ATTR_LEN+1]; - struct vioc_gattr ga; - char *res; - - - if ((fd = open(vol_path, O_RDONLY|O_NDELAY)) < 0) { -#ifdef DEBUG - perror(vol_path); -#endif - res = NULL; - goto dun; - } - - if (fstat64(fd, &sb) < 0) { -#ifdef DEBUG - perror(vol_path); -#endif - res = NULL; - goto dun; - } - - /* ensure we have either a blk- or char-spcl device */ - if (!S_ISBLK(sb.st_mode) && !S_ISCHR(sb.st_mode)) { -#ifdef DEBUG - (void) fprintf(stderr, - "media_getattr: %s not a block or raw device\n", - vol_path); -#endif - res = NULL; - goto dun; - } - - ga.ga_value = valuebuf; - ga.ga_val_len = MAX_ATTR_LEN; - ga.ga_attr = attr; - ga.ga_attr_len = strlen(attr); - - /* try to get the attribute */ - if (ioctl(fd, VOLIOCGATTR, &ga) < 0) { - /* errno ENOENT here just means prop not found */ -#ifdef DEBUG - if (errno != ENOENT) { - perror(vol_path); - } -#endif - res = NULL; - goto dun; - } - - /* successfully got the attribute */ - res = strdup(valuebuf); - -dun: - if (fd >= 0) { - (void) close(fd); - } - return (res); -} - - -/* - * sets the attribute "attr" to value "value". - * - * If value == "" the flag is - * considered to be a TRUE boolean. - * - * If value == 0, it is considered to be a FALSE boolean. - * returns TRUE on success, FALSE on failure. - * - * Can fail for reasons of permission, or if you - * write a read-only attribute. - */ - -/* - * arc approved interface - * - can not be modified without approval from an arc - * - * committment level: - * public - * - * description: - * media_setattr: set an attribute for a piece of media to a - * particular value. - * - * arguments: - * path - Path to the media in /vol. Can be the block or character - * device. - * - * attr - name of the attribute. - * - * value - value of the attribute. If value == "", the flag is - * considered to be a boolean that is TRUE. If value == 0, it - * is considered to be a FALSE boolean. - * - * return value(s): - * TRUE on success, FALSE for failure. - * - * Can fail because: - * - don't have permission to set the attribute because caller - * is not the owner of the media and attribute is a "system" - * attribute. - * - * - don't have permission to set the attribute because the - * attribute is a "system" attribute and is read-only. - * - * preconditions: - * volume management must be running. - */ -int -media_setattr(char *vol_path, char *attr, char *value) -{ - int fd = -1; - struct stat64 sb; - struct vioc_sattr sa; - int res; - - - if ((fd = open(vol_path, O_RDONLY|O_NDELAY)) < 0) { -#ifdef DEBUG - perror(vol_path); -#endif - res = FALSE; - goto dun; - } - - if (fstat64(fd, &sb) < 0) { -#ifdef DEBUG - perror(vol_path); -#endif - res = FALSE; - goto dun; - } - - /* ensure we have either a blk- or char-spcl device */ - if (!S_ISBLK(sb.st_mode) && !S_ISCHR(sb.st_mode)) { -#ifdef DEBUG - (void) fprintf(stderr, - "media_setattr: %s not a block or raw device\n", - vol_path); -#endif - res = FALSE; - goto dun; - } - - sa.sa_attr = attr; - sa.sa_attr_len = strlen(attr); - sa.sa_value = value; - sa.sa_value_len = strlen(value); - - /* try to set the attribute */ - if (ioctl(fd, VOLIOCSATTR, &sa) < 0) { -#ifdef DEBUG - perror(vol_path); -#endif - res = FALSE; - goto dun; - } - - /* successfully set the attribute */ - res = TRUE; - -dun: - if (fd >= 0) { - (void) close(fd); - } - return (res); -} - - -/* - * Returns the "id" of a volume. If the returned value - * & VOLID_TMP, the volume is temporary and this value - * cannot be relied upon across reboots. - */ -/* - * arc approved interface - * - can not be modified without approval from an arc - * - * committment level: - * public - * - * description: - * media_getid: return the "id" of a piece of media. - * - * arguments: - * path - Path to the media in /vol. Can be the block or character - * device. - * return value(s): - * returns a u_longlong_t that is the "id" of the volume. - * - * preconditions: - * volume management must be running. - */ -u_longlong_t -media_getid(char *vol_path) -{ - int fd = -1; - struct stat64 sb; - char path[MAXNAMELEN+1]; - struct vioc_info info; - u_longlong_t res; - - - if ((fd = open(vol_path, O_RDONLY|O_NDELAY)) < 0) { -#ifdef DEBUG - perror(vol_path); -#endif - res = 0; - goto dun; - - } - - if (fstat64(fd, &sb) < 0) { -#ifdef DEBUG - perror(vol_path); -#endif - res = 0; - goto dun; - } - - /* ensure we have either a blk- or char-spcl device */ - if (!S_ISBLK(sb.st_mode) && !S_ISCHR(sb.st_mode)) { -#ifdef DEBUG - (void) fprintf(stderr, - "media_getid: %s not a block or raw device\n", - vol_path); -#endif - res = 0; - goto dun; - } - - memset(path, 0, MAXNAMELEN+1); - info.vii_devpath = path; - info.vii_pathlen = MAXNAMELEN; - - /* try to get the id */ - if (ioctl(fd, VOLIOCINFO, &info) < 0) { -#ifdef DEBUG - perror(vol_path); -#endif - res = 0; - goto dun; - } - - /* successfully got the id */ - res = info.vii_id; - -dun: - if (fd >= 0) { - (void) close(fd); - } - return (res); -} diff --git a/usr/src/lib/libvolmgt/common/volmgt.c b/usr/src/lib/libvolmgt/common/volmgt.c new file mode 100644 index 0000000000..b16910d233 --- /dev/null +++ b/usr/src/lib/libvolmgt/common/volmgt.c @@ -0,0 +1,631 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <string.h> +#include <dirent.h> +#include <fcntl.h> +#include <string.h> +#include <errno.h> +#include <limits.h> +#include <unistd.h> +#include <sys/mkdev.h> +#include <volmgt.h> +#include <ctype.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/param.h> +#include "volmgt_private.h" + +/* + * arc approved interface + * - can not be modified without approval from an arc + * + * committment level: + * public + * + * description: + * volmgt_running: check to see if volume management is running. + * + * arguments: + * none. + * + * return value(s): + * TRUE if volume management is running, FALSE if not. + * + * preconditions: + * none. + */ +int +volmgt_running(void) +{ + /* vold is dead */ + return (FALSE); +} + + +/* + * arc approved interface + * - can not be modified without approval from an arc + * + * committment level: + * public + * + * description: + * volmgt_inuse: check to see if volume management is currently + * managing a particular device. + * + * arguments: + * path - the name of the device in /dev. For example, + * "/dev/rdiskette". + * + * return value(s): + * TRUE if volume management is managing the device, FALSE if not. + * + * preconditions: + * none. + */ +/* ARGSUSED */ +int +volmgt_inuse(char *path) +{ + return (FALSE); +} + + +/* + * arc approved interface + * - can not be modified without approval from an arc + * + * committment level: + * public + * + * description: + * volmgt_check: have volume management look at its devices to check + * for media having arrived. Since volume management can't + * automatically check all types of devices, this function is provided + * to allow applications to cause the check to happen automatically. + * + * arguments: + * path - the name of the device in /dev. For example, + * /dev/rdiskette. If path is NULL, all "checkable" devices are + * checked. + * + * return value(s): + * TRUE if media was found in the device, FALSE if not. + * + * preconditions: + * volume management must be running. + */ +/* ARGSUSED */ +int +volmgt_check(char *path) +{ + return (FALSE); +} + + +/* + * arc approved interface + * - can not be modified without approval from an arc + * + * committment level: + * public + * + * description: + * volmgt_ownspath: check to see if the given path is contained in + * the volume management name space. + * + * arguments: + * path - string containing the path. + * + * return value(s): + * TRUE if the path is owned by volume management, FALSE if not. + * Will return FALSE if volume management isn't running. + * + * preconditions: + * none. + */ +/* ARGSUSED */ +int +volmgt_ownspath(char *path) +{ + return (FALSE); +} + + +/* + * arc approved interface + * - can not be modified without approval from an arc + * + * committment level: + * public + * + * description: + * volmgt_root: return the root of where the volume management + * name space is mounted. + * + * arguments: + * none. + * + * return value(s): + * Returns a pointer to a static string containing the path to the + * volume management root (e.g. "/vol"). + * Will return NULL if volume management isn't running. + * + * preconditions: + * none. + */ +const char * +volmgt_root(void) +{ + static const char *vold_root = "/dev"; + + return (vold_root); +} + + +/* + * arc approved interface + * - can not be modified without approval from an arc + * + * committment level: + * public + * + * description: + * volmgt_symname: Returns the volume management symbolic name + * for a given device. If an application wants to determine + * what the symbolic name (e.g. "floppy0") for the /dev/rdiskette + * device would be, this is the function to use. + * + * arguments: + * path - a string containing the /dev device name. For example, + * "/dev/diskette" or "/dev/rdiskette". + * + * Note: must be a block- or char-spcl device, and have a non-zero + * st_rdev (real device) stat() value. + * + * return value(s): + * pointer to a string containing the symbolic name. + * + * NULL indicates that volume management isn't managing that device. + * + * The string must be free(3)'d. + * + * preconditions: + * none. + */ +/* ARGSUSED */ +char * +volmgt_symname(char *path) +{ + return (NULL); +} + + +/* + * arc approved interface + * - can not be modified without approval from an arc + * + * committment level: + * public + * + * description: + * volmgt_symdev: Returns the device given the volume management + * symbolic name. If an application wants to determine + * what the device associated with a particular symbolic name + * might be, this is the function to use. + * + * arguments: + * path - a string containing the symbolic device name. For example, + * "cdrom0" or "floppy0". + * + * return value(s): + * pointer to a string containing the /dev name. + * + * NULL indicates that volume management isn't managing that device. + * + * The string must be free(3)'d. + * + * preconditions: + * none. + */ +/* ARGSUSED */ +char * +volmgt_symdev(char *symname) +{ + return (NULL); +} + + +/* + * arc approved interface + * - can not be modified without approval from an arc + * + * committment level: + * public + * + * description: + * volmgt_feat_enabled: check to see if a volume management feature + * is available + * + * arguments: + * feat_str - a string containing the feature to be checked for + * + * return value(s): + * return non-zero if the specified feature is available in + * volume management, else return zero + * + * preconditions: + * none. + */ + + +/* + * the following is a lit of the "feature" available in volmgt + * + * this list is meant to be updated when new features (that users may + * want to use) are added to volmgt + * + * note: feature strings added should be all lower case, and spaces are + * discouraged + * + * (see psarc/1995/138 for more info) + */ +static char *volmgt_feat_list[] = { +#ifdef DIRECT_DEV_ACCESS_WORKING + "direct-dev-access", /* access through /dev co-exists */ +#endif + "floppy-summit-interfaces", /* volmgt_{acquire,release} */ + NULL +}; + + +int +volmgt_feature_enabled(char *feat_str) +{ + return (0); +} +/* + * arc approved interface + * - can not be modified without approval from an arc + * + * committment level: + * uncommitted + * + * description: + * volmgt_acquire: try to acquire the volmgt advisory device reservation + * for a specific device. + * + * arguments: + * dev - a device name to attempt reserving. This string can be: + * - a full path name to a device + * - a symbolic device name (e.g. floppy0) + * + * id - a reservation string that hopefully describes the application + * making this reservation. + * + * pid - a pointer to a pid_t type. If this argument is not NULL + * and the requested device is already reserved, the process + * id of the reservation owner will be returned in this + * location. + * + * ovr - an override indicator. If set to non-zero, the caller requests + * that this reservation be made unconditionally. + * + * err - the address of a pointer to a string which is to receive the + * id argument used when the current device was reserved. This + * is only used when the current reservation attempt fails due + * to an already existing reservation for this device. + * + * return value(s): + * A non-zero indicator if successful. + * + * A zero indicator if unsuccessful. If errno is EBUSY, then the err + * argument will be set to point to the string that the process currently + * holding the reservation supplied when reserving the device. It is up + * to the caller to release the storage occupied by the string via + * free(3C) when no longer needed. + * + * preconditions: + * none + */ +/* ARGSUSED */ +int +volmgt_acquire(char *dev, char *id, int ovr, char **err, pid_t *pidp) +{ + return (0); +} + + +/* + * arc approved interface + * - can not be modified without approval from an arc + * + * committment level: + * uncommitted + * + * description: + * volmgt_release: try to release the volmgt advisory device reservation + * for a specific device. + * + * arguments: + * dev - a device name to attempt reserving. This string can be: + * - a full path name to a device + * - a symbolic device name (e.g. floppy0) + * + * return value(s): + * A non-zero indicator if successful + * A zero indicator if unsuccessful + * + * preconditions: + * none + */ +int +volmgt_release(char *dev) +{ + return (0); +} + + +/* + * returns the "value" of the attribute. + * If the attribute is boolean and is TRUE, + * "true" is returned. If the boolean is + * FALSE, NULL is returned. If the attribute + * doesn't exist, NULL is returned. The pointer + * returned by media_getattr has been malloc'd and + * it is the callers responsibility to free it. + */ +/* + * arc approved interface + * - can not be modified without approval from an arc + * + * committment level: + * public + * + * description: + * media_getattr: returns the value for an attribute for a piece of + * removable media. + * + * arguments: + * path - Path to the media in /vol. Can be the block or character + * device. + * + * attr - name of the attribute. + * + * return value(s): + * returns NULL or a pointer to a string that contains the value for + * the requested attribute. + * + * NULL can mean: + * - the media doesn't exist + * - there is no more space for malloc(3) + * - the attribute doesn't exist for the named media + * - the attribute is a boolean and is FALSE + * + * the pointer to the string must be free'd with free(3). + * + * preconditions: + * volume management (vold) must be running. + */ +/* ARGSUSED */ +char * +media_getattr(char *vol_path, char *attr) +{ + return (NULL); +} + + +/* + * sets the attribute "attr" to value "value". + * + * If value == "" the flag is + * considered to be a TRUE boolean. + * + * If value == 0, it is considered to be a FALSE boolean. + * returns TRUE on success, FALSE on failure. + * + * Can fail for reasons of permission, or if you + * write a read-only attribute. + */ + +/* + * arc approved interface + * - can not be modified without approval from an arc + * + * committment level: + * public + * + * description: + * media_setattr: set an attribute for a piece of media to a + * particular value. + * + * arguments: + * path - Path to the media in /vol. Can be the block or character + * device. + * + * attr - name of the attribute. + * + * value - value of the attribute. If value == "", the flag is + * considered to be a boolean that is TRUE. If value == 0, it + * is considered to be a FALSE boolean. + * + * return value(s): + * TRUE on success, FALSE for failure. + * + * Can fail because: + * - don't have permission to set the attribute because caller + * is not the owner of the media and attribute is a "system" + * attribute. + * + * - don't have permission to set the attribute because the + * attribute is a "system" attribute and is read-only. + * + * preconditions: + * volume management must be running. + */ +/* ARGSUSED */ +int +media_setattr(char *vol_path, char *attr, char *value) +{ + return (FALSE); +} + + +/* + * Returns the "id" of a volume. If the returned value + * & VOLID_TMP, the volume is temporary and this value + * cannot be relied upon across reboots. + */ +/* + * arc approved interface + * - can not be modified without approval from an arc + * + * committment level: + * public + * + * description: + * media_getid: return the "id" of a piece of media. + * + * arguments: + * path - Path to the media in /vol. Can be the block or character + * device. + * return value(s): + * returns a u_longlong_t that is the "id" of the volume. + * + * preconditions: + * volume management must be running. + */ +u_longlong_t +media_getid(char *vol_path) +{ + return (0); +} +/* + * arc approved interface (pending) + * - can not be modified without approval from an arc + * + * committment level: + * public + * + * description: + * media_findname: try to come up with the character device when + * provided with a starting point. This interface provides the + * application programmer to provide "user friendly" names and + * easily determine the "/vol" name. + * + * arguments: + * start - a string describing a device. This string can be: + * - a full path name to a device (insures it's a + * character device by using getfullrawname()). + * - a full path name to a volume management media name + * with partitions (will return the lowest numbered + * raw partition. + * - the name of a piece of media (e.g. "fred"). + * - a symbolic device name (e.g. floppy0, cdrom0, etc) + * - a name like "floppy" or "cdrom". Will pick the lowest + * numbered device with media in it. + * + * return value(s): + * A pointer to a string that contains the character device + * most appropriate to the "start" argument. + * + * NULL indicates that we were unable to find media based on "start". + * + * The string must be free(3)'d. + * + * preconditions: + * none. + */ +/* ARGSUSED */ +char * +media_findname(char *start) +{ + /* XXX can use HAL nicknames here */ + return (NULL); +} + +struct alias { + char *alias; + char *name; +}; + +/* + * "old" aliases -- used to be used when vold wasn't running + */ +static struct alias device_aliases[] = { + { "fd", "/dev/rdiskette" }, + { "fd0", "/dev/rdiskette" }, + { "fd1", "/dev/rdiskette1" }, + { "diskette", "/dev/rdiskette" }, + { "diskette0", "/dev/rdiskette0" }, + { "diskette1", "/dev/rdiskette1" }, + { "rdiskette", "/dev/rdiskette" }, + { "rdiskette0", "/dev/rdiskette0" }, + { "rdiskette1", "/dev/rdiskette1" }, + { "floppy", "/dev/rdiskette" }, + { "floppy0", "/dev/rdiskette0" }, + { "floppy1", "/dev/rdiskette1" }, + { "cd", "cdrom0" }, + { "cd0", "cdrom0" }, + { "cd1", "cdrom1" }, + { NULL, NULL } +}; + +/* + * This is an ON Consolidation Private interface. + */ +/* ARGSUSED */ +char * +_media_oldaliases(char *start) +{ + struct alias *s; + char *p; + char *res = NULL; + + for (s = device_aliases; s->alias != NULL; s++) { + if (strcmp(start, s->alias) == 0) { + res = strdup(s->name); + break; + } + } + + return (res); +} + + +/* + * This is an ON Consolidation Private interface. + * + * Print out the aliases available to the program user. Changes + * depending in whether volume management is running. + */ +void +_media_printaliases(void) +{ +} diff --git a/usr/src/lib/libvolmgt/common/volmgt_fsi.c b/usr/src/lib/libvolmgt/common/volmgt_fsi.c deleted file mode 100644 index 31db6db23c..0000000000 --- a/usr/src/lib/libvolmgt/common/volmgt_fsi.c +++ /dev/null @@ -1,401 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright (c) 1996 by Sun Microsystems, Inc. - * All rights reserved. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <stdio.h> -#include <unistd.h> -#include <stdlib.h> -#include <string.h> -#include <strings.h> -#include <volmgt.h> -#include <errno.h> -#include <sys/types.h> -#include <sys/mkdev.h> -#include <sys/ddi.h> -#include <sys/stat.h> -#include <sys/errno.h> -#include <rpc/types.h> -#include "volmgt.h" -#include "volmgt_private.h" -#include "volmgt_fsi_private.h" - -/* just utnil volmgt.h is up to date */ -#ifndef VOL_RSV_MAXIDLEN -#define VOL_RSV_MAXIDLEN 256 -#endif - - -/* this routine used by both acquire and release */ -static char *fsi_xlate_name(char *); - -/* - * arc approved interface - * - can not be modified without approval from an arc - * - * committment level: - * uncommitted - * - * description: - * volmgt_acquire: try to acquire the volmgt advisory device reservation - * for a specific device. - * - * arguments: - * dev - a device name to attempt reserving. This string can be: - * - a full path name to a device - * - a symbolic device name (e.g. floppy0) - * - * id - a reservation string that hopefully describes the application - * making this reservation. - * - * pid - a pointer to a pid_t type. If this argument is not NULL - * and the requested device is already reserved, the process - * id of the reservation owner will be returned in this - * location. - * - * ovr - an override indicator. If set to non-zero, the caller requests - * that this reservation be made unconditionally. - * - * err - the address of a pointer to a string which is to receive the - * id argument used when the current device was reserved. This - * is only used when the current reservation attempt fails due - * to an already existing reservation for this device. - * - * return value(s): - * A non-zero indicator if successful. - * - * A zero indicator if unsuccessful. If errno is EBUSY, then the err - * argument will be set to point to the string that the process currently - * holding the reservation supplied when reserving the device. It is up - * to the caller to release the storage occupied by the string via - * free(3C) when no longer needed. - * - * preconditions: - * none - */ -int -volmgt_acquire(char *dev, char *id, int ovr, char **err, pid_t *pidp) -{ - char *targ_name = NULL; - struct stat sb; - dev_t idev; - vol_dbid_t dbid = (vol_dbid_t)-1; - vol_db_entry_t dbe; - vol_db_entry_t *dbp; - int retval = 0; /* default return => ERROR */ - int reterr = 0; - - -#ifdef DEBUG - denter("volmgt_acquire(\"%s\", \"%s\", %s, %#p, %#p): entering\n", - dev ? dev : "<null ptr>", id ? id : "<null ptr>", - ovr ? "TRUE" : "FALSE", err, pidp); -#endif - /* - * the supplied arguments must not be NULL - */ - if ((dev == NULL) || (id == NULL) || (err == NULL)) { - errno = EINVAL; - goto dun; - } - - /* - * the id string must not be longer than the maximum allowable - * number of characters - */ - if (strlen(id) > VOL_RSV_MAXIDLEN) { - errno = E2BIG; - goto dun; - } - - if ((targ_name = fsi_xlate_name(dev)) == NULL) { - goto dun; - } - - /* - * convert 'char *dev' to major/minor pair - */ - if (stat(targ_name, &sb) < 0) { - goto dun; - } - idev = sb.st_rdev; - - /* - * open the database file - */ - if ((dbid = vol_db_open()) < 0) { - goto dun; - } - - if ((dbp = vol_db_find(dbid, idev)) == NULL) { - /* - * the entry wasn't found, so reserve it - */ - dbe.dev_major = major(idev); - dbe.dev_minor = minor(idev); - dbe.pid = getpid(); - dbe.id_tag = id; - if (vol_db_insert(dbid, &dbe) != 0) { - retval = 1; /* success! */ - } - } else { - if (ovr || (vol_db_proc_find(dbp->pid) == 0)) { - /* - * the entry exists but either override was specified - * or the process holding the reservation is no longer - * active - * - * in either case we'll usurp the reservation - */ - if (vol_db_remove(dbid, idev) != 0) { - /* reserve the device */ - dbe.dev_major = major(idev); - dbe.dev_minor = minor(idev); - dbe.pid = getpid(); - dbe.id_tag = id; - if (vol_db_insert(dbid, &dbe) != 0) { - retval = 1; - } - } - - } else { - - /* - * the entry exists and override was NOT specified - */ - - /* - * optionally return the pid of the reservation - * owner - */ - if (pidp != NULL) { - *pidp = dbp->pid; - } - - *err = strdup(dbp->id_tag); - reterr = EBUSY; - } - vol_db_free(dbp); /* Release the entry */ - } - - - /* - * if an error was encountered (currently only EBUSY supported) - * set errno to reflect it - */ - if (reterr != 0) { - errno = reterr; - } - -dun: - if ((int)dbid >= 0) { - (void) vol_db_close(dbid); - } - if (targ_name != NULL) { - free(targ_name); - } -#ifdef DEBUG - dexit("volmgt_acquire: returning %s\n", retval ? "TRUE" : "FALSE"); -#endif - return (retval); -} - - -/* - * arc approved interface - * - can not be modified without approval from an arc - * - * committment level: - * uncommitted - * - * description: - * volmgt_release: try to release the volmgt advisory device reservation - * for a specific device. - * - * arguments: - * dev - a device name to attempt reserving. This string can be: - * - a full path name to a device - * - a symbolic device name (e.g. floppy0) - * - * return value(s): - * A non-zero indicator if successful - * A zero indicator if unsuccessful - * - * preconditions: - * none - */ -int -volmgt_release(char *dev) -{ - char *targ_name = NULL; - struct stat sb; - long idev; - vol_dbid_t dbid; - vol_db_entry_t *dbp; - int retval = 0; /* default return => FAILURE */ - int reterr = 0; - - -#ifdef DEBUG - denter("volmgt_release(\"%s\"): entering\n", dev ? dev : "<null ptr>"); -#endif - /* - * first let's do some minimal validation of the supplied arguments - */ - - /* - * the supplied argument must not be NULL - */ - if (dev == NULL) { - errno = EINVAL; - goto dun; - } - - if ((targ_name = fsi_xlate_name(dev)) == NULL) { - goto dun; - } - - /* - * convert 'char *dev' to major/minor pair - */ - if (stat(targ_name, &sb) < 0) { - goto dun; - } - idev = sb.st_rdev; - - /* - * open the database file - */ - if ((dbid = vol_db_open()) < 0) { - goto dun; - } - - if ((dbp = vol_db_find(dbid, idev)) == NULL) { - /* the entry wasn't found so I can't clear reservation */ - errno = ENOENT; - goto dun; - } - - /* the entry was found so make sure I can clear it */ - if (dbp->pid == getpid()) { - /* - * the reservation was made by me, clear it - */ - if (vol_db_remove(dbid, idev) != 0) { - retval = 1; - } - } else { - /* - * the entry wasn't made by me - */ - reterr = EBUSY; - } - vol_db_free(dbp); - - /* - * if an error was encountered (currently only EBUSY supported) - * set errno to reflect it - */ - if (reterr != 0) { - errno = reterr; - } -dun: - if ((int)dbid >= 0) { - (void) vol_db_close(dbid); - } - if (targ_name != NULL) { - free(targ_name); - } -#ifdef DEBUG - dexit("volmgt_release: returning %s\n", retval ? "TRUE" : "FALSE"); -#endif - return (retval); -} - - -/* - * translate suplied vol name into a pathname - * - * if volmgt is running, this pathname will be in /vol (or its equiv) - * - * if volmgt is not running then this path may be anywhere - * - * in either case the pathname will *not* be verified as a blk/chr dev - * - * if the return value is non-null then it's been alloced - * - * NOTE: assume "vol" is not a NULL ptr - */ -static char * -fsi_xlate_name(char *vol) -{ - char *res = NULL; /* result to return */ - char *vr; /* volmgt root dir */ - bool_t vm_running = volmgt_running(); /* volmgt running? */ - - -#ifdef DEBUG - denter("fsi_xlate_name(\"%s\"): entering\n", vol); -#endif - - /* is it an absolute pathname ?? */ - if (*vol == '/') { - - if (vm_running) { - /* pathname must be in the /vol namespace */ - vr = (char *)volmgt_root(); - if (strncmp(vol, vr, strlen(vr)) != 0) { - /* not a cool pathname */ - errno = EINVAL; /* XXX: is this correct */ - goto dun; - } - } - - res = strdup(vol); - - } else { - - /* - * if volmgt is running we can try to dereference it - * if volmgt isn't running then just give up - */ - - if (!vm_running) { - /* some unknown "name" */ - errno = ENOENT; - goto dun; - } - - res = volmgt_symdev(vol); - - } - -dun: -#ifdef DEBUG - dexit("fsi_xlate_name: returning %s\n", res ? res : "<null ptr>"); -#endif - return (res); -} diff --git a/usr/src/lib/libvolmgt/common/volmgt_fsi_private.h b/usr/src/lib/libvolmgt/common/volmgt_fsi_private.h deleted file mode 100644 index c6ed86b86c..0000000000 --- a/usr/src/lib/libvolmgt/common/volmgt_fsi_private.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright (c) 1996, by Sun Microsystems, Inc. - * All rights reserved. - */ - -#ifndef _VOLMGT_FSI_PRIVATE_H -#define _VOLMGT_FSI_PRIVATE_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * this file defines the interface between the FSI routines and - * the database-like routines that support them - * - * also included are declarations that the FSI routines use and which - * may be useful to the database implementation module - */ - - -/* - * defines for volmgt device advisory locking (aka Floppy Summit Interace) - */ -#define VOL_MAXIDLEN 256 /* max length of id_tag string */ - -/* - * the volmgt device reservation database consists of ASCII records - * composed of 4 fields: - * - * dev major||dev minor||pid||Identification string(id) - * - * where: - * dev = the major/minor device pair that uniquely identifies - * the device that is reserved - * - * pid = the process identifier of the reserving process - * - * id = a character string that the reserving process wants - * returned to other processes attempting to reserve this - * device - */ - -typedef struct vol_db_entry { - major_t dev_major; /* device for reservation (major) */ - minor_t dev_minor; /* device for reservation (minor) */ - pid_t pid; /* process id of the reserver */ - char *id_tag; /* identifier string of the reserver */ -} vol_db_entry_t; - - -/* - * dbid type - */ -typedef int vol_dbid_t; - -extern vol_dbid_t vol_db_open(void); -extern int vol_db_close(vol_dbid_t); -extern int vol_db_insert(vol_dbid_t, vol_db_entry_t *); -extern int vol_db_remove(vol_dbid_t, dev_t); -extern vol_db_entry_t *vol_db_find(vol_dbid_t, dev_t); -extern void vol_db_free(vol_db_entry_t *); -extern int vol_db_proc_find(pid_t); - - -#ifdef __cplusplus -} -#endif - -#endif /* _VOLMGT_FSI_PRIVATE_H */ diff --git a/usr/src/lib/libvolmgt/common/volmgt_fsidbi.c b/usr/src/lib/libvolmgt/common/volmgt_fsidbi.c deleted file mode 100644 index 5a08d7b06b..0000000000 --- a/usr/src/lib/libvolmgt/common/volmgt_fsidbi.c +++ /dev/null @@ -1,725 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <stdio.h> -#include <unistd.h> -#include <string.h> -#include <strings.h> -#include <malloc.h> -#include <volmgt.h> -#include <sys/stat.h> -#include <errno.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <signal.h> -#include <sys/types.h> -#include <sys/mkdev.h> -#include "volmgt_private.h" -#include "volmgt_fsi_private.h" - - -/* just utnil volmgt.h is up to date */ -#ifndef VOL_RSV_MAXIDLEN -#define VOL_RSV_MAXIDLEN 256 -#endif - - -/* - * volmgt_fsidbi -- volmgt FSI db interface routines - * - * routines supplied: - * - * vol_dbid_t vol_db_open(void) - * int vol_db_close(vol_dbid_t) - * int vol_db_insert(vol_dbid_t, vol_db_entry_t *) - * int vol_db_remove(vol_dbid_t, dev_t) - * vol_db_entry_t *vol_db_find(vol_dbid_t, dev_t) - * void vol_db_free(vol_db_entry_t *) - * int vol_db_proc_find(pid_t) - */ - -/* name of our database file */ -#define VOL_DB_PATH "/tmp/.volmgt_reserv_db" - -/* mode for our database file */ -#define VOL_DB_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH) - -/* for reading from and writing to the database */ -#define READ_FORMAT "%d||%d||%d||%[^\n]" -#define WRITE_FORMAT "%d||%d||%d||%s\n" - -/* - * The next two defines indicate the number of fields we expect to find in a - * database record. The first is the number of fields if no comment was - * provided (which seems unlikely since volmgt_acquire() demands a comment of - * some kind) and the other one is the number of fields to expect if a - * comment is included. - */ -#define NUM_FIELDS_WO_COMMENT 3 -#define NUM_FIELDS_W_COMMENT 4 - -/* maximum record size */ -#define VOL_MAX_RECSIZE (VOL_RSV_MAXIDLEN + 20) - - - -/* - * internal list data - */ - -#define MAX_INTERNAL_DB_LIST_SIZE 64 /* should be big enough! */ - -static FILE *db_list[MAX_INTERNAL_DB_LIST_SIZE]; - - -/* - * add the supplied file ptr to our list of file ptrs (if it'll fit) - * - * return it's index in the list (after type casting) if successful, else - * return -1 - */ -static vol_dbid_t -add_to_list(FILE *fp) -{ - int i; - vol_dbid_t ret_val = (vol_dbid_t)-1; - - -#ifdef DEBUG - denter("add_to_list(%#x): entering\n", (char *)fp); -#endif - - - for (i = 0; i < MAX_INTERNAL_DB_LIST_SIZE; i++) { - if (db_list[i] == NULL) { - db_list[i] = fp; - ret_val = (vol_dbid_t)i; -#ifdef DEBUG - dprintf("add_to_list: adding at location %d\n", i); -#endif - break; - } -#ifdef DEBUG - dprintf("add_to_list: location %d already taken\n", i); -#endif - } - -#ifdef DEBUG - dexit("add_to_list: returning %d\n", (int)ret_val); -#endif - return (ret_val); -} - - -/* - * return the file ptr given the dbid - */ -static FILE * -db_to_fp(vol_dbid_t dbid) -{ - FILE *ret_val = NULL; - - -#ifdef DEBUG - denter("db_to_fp(%d): entering\n", (int)dbid); -#endif - if (((int)dbid >= 0) && ((int)dbid < MAX_INTERNAL_DB_LIST_SIZE)) { - ret_val = db_list[dbid]; - } - -#ifdef DEBUG - dexit("db_to_fp: returning %#p\n", (char *)ret_val); -#endif - return (ret_val); -} - - -/* - * remove the specified entry from the internal db - */ -static void -rem_from_list(vol_dbid_t dbid) -{ - if (((int)dbid >= 0) && ((int)dbid < MAX_INTERNAL_DB_LIST_SIZE)) { - db_list[dbid] = NULL; - } -} - - -/* - * committment level: - * project private - * - * description: - * vol_db_open: creates/opens volmgt Device Reservation Database. - * If the database file doesn't exist it is created and opened, - * otherwise it just is opened. The file mode is updated to insure - * that it is readable and writeable by the world. Then an advisory - * write file lock is taken out on the entire file. Any process - * attempting to gain access to the file via vol_db_open() will sleep - * attempting to set the file lock should another process currently have - * the lock set. On success, a FILE pointer is returned to the caller. - * - * arguments: - * none - * - * return value(s): - * a small non-negative integer if successful, else -1 - * - * preconditions: - * none - */ -vol_dbid_t -vol_db_open(void) -{ - const char *dbpath = VOL_DB_PATH; - FILE *fp = NULL; - flock_t flock; - int fd; - int status; - vol_dbid_t ret_val = (vol_dbid_t)-1; - - -#ifdef DEBUG - denter("vol_db_open(): entering\n"); -#endif - if ((status = access(dbpath, F_OK | R_OK | W_OK)) < 0) { - /* - * file doesn't exist so create it, open for update, and - * make sure the file mode is read/write-able by the world - */ - if ((fp = fopen(dbpath, "w+F")) == NULL) { -#ifdef DEBUG - dprintf("can't open (w+) \"%s\" (%d)\n", - dbpath, errno); -#endif - goto dun; - } - } else { - /* does exist so open it for update */ - if ((fp = fopen(dbpath, "r+F")) == NULL) { -#ifdef DEBUG - dprintf("can't open (r+) \"%s\" (%d)\n", - dbpath, errno); -#endif - goto dun; - } - } - - fd = fileno(fp); - - if (status < 0) { - if (fchmod(fd, VOL_DB_MODE) < 0) { - (void) fclose(fp); - fp = NULL; -#ifdef DEBUG - dprintf("can't fchmod \"%s\" to %o (%d)\n", - dbpath, VOL_DB_MODE, errno); -#endif - goto dun; - } - } - - /* - * set advisory lock on database file - */ - flock.l_type = F_WRLCK; - flock.l_start = 0; - flock.l_len = 0; - flock.l_whence = SEEK_SET; - - if (fcntl(fd, F_SETLKW, &flock) < 0) { - (void) fclose(fp); - fp = NULL; -#ifdef DEBUG - dprintf("can't fcntl (lock) \"%s\" (%d)\n", - dbpath, errno); -#endif - goto dun; - } - - /* the file is open and locked -- try to keep track of it */ - ret_val = add_to_list(fp); - -dun: -#ifdef DEBUG - dexit("vol_db_open: returning %d\n", ret_val); -#endif - return (ret_val); -} - - -/* - * committment level: - * project private - * - * description: - * vol_db_close: close the volmgt Device Reservation Database. The - * database file is unconditionally closed. - * - * arguments: - * dbid - an identifier for the database to be closed - * - * return value(s): - * 0 -> all went okay - * non-zero - an error - * - * preconditions: - * The volmgt database has already been opened by vol_db_open(). - */ -int -vol_db_close(vol_dbid_t dbid) -{ - FILE *fp; - int ret_val = -1; /* default => failure */ - - -#ifdef DEBUG - denter("volmgt_db_close(%d): entering\n", (int)dbid); -#endif - if ((fp = db_to_fp(dbid)) != NULL) { - if (fclose(fp) == 0) { - rem_from_list(dbid); - ret_val = 0; /* success */ - } - } - -#ifdef DEBUG - dexit("volmgt_db_close: returning %d (%s)\n", ret_val, - ret_val == 0 ? "SUCCESS" : "FAILURE"); -#endif - return (ret_val); -} - - -/* - * committment level: - * project private - * - * description: - * vol_db_insert:insert a record into the volmgt Device Reservation - * database. The file is simply positioned to EOF and the requested - * entry written. - * - * The semantics for use of this primitive depend on the caller having - * previously called vol_db_find() to determine whether the record already - * exists or not. Multiple calls to vol_db_insert() for the same record - * will result in the existence of duplicate records. - * - * arguments: - * dbid - an identifier for the database to be accessed - * ep - pointer to a vol_db_entry structure describing the record to - * be inserted. - * - * return value(s): - * 0/FALSE failure - * 1/TRUE success - * - * preconditions: - * The volmgt database has already been opened by vol_db_open(). - */ -int -vol_db_insert(vol_dbid_t dbid, vol_db_entry_t *ep) -{ - FILE *fp; - int ret_val = 0; /* default => failure */ - - -#ifdef DEBUG - denter("volmgt_db_insert(%d, [(%d.%d), %d, ...]): entering\n", dbid, - ep->dev_major, ep->dev_minor, ep->pid); -#endif - /* get the file ptr for the supplied dbid */ - if ((fp = db_to_fp(dbid)) == NULL) { - goto dun; - } - - /* just skip to EOF */ - if (fseek(fp, 0, SEEK_END) < 0) { -#ifdef DEBUG - dprintf("volmgt_db_insert: fseek failed (%d)\n", errno); -#endif - goto dun; - } - - /* append record to file */ - if (fprintf(fp, WRITE_FORMAT, ep->dev_major, ep->dev_minor, - ep->pid, ep->id_tag) < 0) { -#ifdef DEBUG - dprintf("volmgt_db_insert: fprintf failed (%d)\n", errno); -#endif - goto dun; - } - - ret_val = 1; /* success */ -dun: -#ifdef DEBUG - dexit("volmgt_db_insert: returning %s\n", ret_val ? "TRUE" : "FALSE"); -#endif - return (ret_val); -} - - -/* - * committment level: - * project private - * - * description: - * vol_db_remove: remove a device entry from the volmgt Device - * Reservation Database. The database file is scanned sequentially - * from file offset 0 looking for a match with the supplied dev argument. - * A match indicates that the device is currently reserved. Note that the - * decision to allow a user to remove a database entry must be made by - * a higher level entity. This function will blindly remove an entry - * if it exists and silently ignore the non-existence of a requested - * record. - * - * This function is a little kludgier than the rest in this module. To - * avoid having to deal with issues related to creation of a new file - * each time an entry is removed, the entire file contents are buffered - * into a malloc'ed memory block and then scanned from there. Each non- - * matching entry scanned from the buffer is written back to the database - * file (which gets rewound following the file read). If a matching - * entry(s) is found it is simply skipped over. Once the file has been - * rewritten it is truncated by the length of the removed entry(s). In - * other words, if multiple entries for the same record exist, they will - * all be removed. - * - * arguments: - * dbid - an identifier for the database to be accessed - * dev - the major/minor device pair uniquely identifying the record to - * be removed from the database. - * - * return value(s): - * An integer describing the success or failure of the operation. - * - * preconditions: - * The volmgt database has already been opened by vol_db_open(). - */ -int -vol_db_remove(vol_dbid_t dbid, dev_t dev) -{ - FILE *fp; - int count; /* ttl record length in buf */ - int nitems; /* no. items scanned */ - char *iobp = NULL; /* ptr to malloc'ed I/O buf */ - char *tiobp; /* temp I/O buf ptr */ - struct stat sb; /* for stat(2) */ - major_t fdev_major; /* major dev read from database */ - minor_t fdev_minor; /* minor dev read from database */ - major_t dev_major; /* major dev (from passed dev_t) */ - minor_t dev_minor; /* minor_dev (from passed dev_t) */ - pid_t fpid; /* pid read from database */ - int flen; /* length of file read */ - int dlen = 0; /* datum length */ - char buf[VOL_MAX_RECSIZE]; /* dest buf for scanning */ - int ret_val = 0; /* default -> failure */ - - -#ifdef DEBUG - denter("volmgt_db_remove(%d): entering\n", dbid); -#endif - /* get the file ptr for the supplied dbid */ - if ((fp = db_to_fp(dbid)) == NULL) { - goto dun; - } - - /* - * make sure database file is rewound since it is sequential - * - * this also insures that any buffered data is flushed prior to - * the next I/O operation - */ - rewind(fp); - - /* - * get a buffer big enough for reading the entire file - */ - if (fstat(fileno(fp), &sb) < 0) { - goto dun; - } - - if ((iobp = (char *)malloc((size_t)sb.st_size)) == NULL) { - goto dun; - } - - /* - * fill buffer with file contents - */ - if ((flen = fread(iobp, 1, (size_t)sb.st_size, fp)) != sb.st_size) { - goto dun; - } - - rewind(fp); - tiobp = iobp; - - /* - * translate dev_t passed in to major and minro numbers - */ - dev_major = major(dev); - dev_minor = minor(dev); - - /* - * while data remains in the buffer, scan records looking for the - * device we want to remove - * - * copy non-matching entries back to the database file - */ - while (flen > 0) { - - /* include newline */ - count = (int)(strchr(tiobp, '\n') - tiobp) + 1; - - nitems = sscanf(tiobp, READ_FORMAT, &fdev_major, &fdev_minor, - &fpid, buf); - - if (fdev_major == dev_major && fdev_minor == dev_minor) { - dlen += count; - } else { - switch (nitems) { - case NUM_FIELDS_WO_COMMENT: - buf[0] = '\0'; /* string was NULL */ - break; - case NUM_FIELDS_W_COMMENT: - /* normal record -- do nothing */ - break; - default: - /* - * something is wrong, try to restore - * the file to its original state - */ - rewind(fp); - if (fwrite(iobp, 1, (size_t)sb.st_size, fp) != - sb.st_size) { - goto dun; - } - break; - } - if (fprintf(fp, WRITE_FORMAT, fdev_major, fdev_minor, - fpid, buf) < 0) { - goto dun; - } - } - - tiobp += count; - flen -= count; - } - - /* - * truncate file by the length of the record removed - */ - if (ftruncate(fileno(fp), sb.st_size - dlen) < 0) { - /* - * something is wrong, try to restore - * the file to its original state - */ - rewind(fp); - if (fwrite(iobp, 1, (size_t)sb.st_size, fp) != sb.st_size) { - goto dun; - } - } - - /* - * done with the buffer, free it - */ - free(iobp); - - ret_val = 1; /* success */ -dun: - if (iobp != NULL) { - free(iobp); - } -#ifdef DEBUG - dexit("volmgt_db_remove: returning %s\n", ret_val ? "TRUE" : "FALSE"); -#endif - return (ret_val); -} - - -/* - * committment level: - * project private - * - * description: - * vol_db_find: locate a device entry in the volmgt Device Reservation - * Database. The database file is scanned looking for an entry matching - * the supplied device argument. If a match is found a pointer to a - * vol_db_entry_t is returned to the caller. If no match is found - * a NULL pointer is returned. The memory space for the structure whose - * address is returned is allocated by malloc and it is the caller's - * responsibility to insure that this space is freed. This can be - * done using the vol_db_free() function. - * - * arguments: - * dbid - an identifier for the database to be accessed - * dev - the major/minor device pair uniquely identifying the record to - * be found. - * - * return value(s): - * A pointer to a vol_db_entry. If the entry wasn't found a NULL - * pointer is returned. - * - * preconditions: - * The volmgt database has already been opened by vol_db_open(). - */ -vol_db_entry_t * -vol_db_find(vol_dbid_t dbid, dev_t dev) -{ - FILE *fp; - major_t fdev_major; /* major device read from database */ - minor_t fdev_minor; /* minor device read from database */ - major_t dev_major; /* major device (from passed dev_t) */ - minor_t dev_minor; /* minor device (from passed dev_t) */ - pid_t fpid; /* process id read from database */ - int nitems; /* number of items scanned */ - vol_db_entry_t *retval = NULL; - vol_db_entry_t *ep; - char buf[VOL_MAX_RECSIZE]; /* scann dest buf */ - - -#ifdef DEBUG - denter("volmgt_db_find(%d, (%d)%d.%d): entering\n", dbid, - dev, major(dev), minor(dev)); -#endif - /* get the file ptr for the supplied dbid */ - if ((fp = db_to_fp(dbid)) == NULL) { - goto dun; - } - - /* - * make sure database file is rewound since it is sequential - * - * this also insures that any buffered data is flushed prior to - * the next I/O operation - */ - rewind(fp); - - /* - * convert dev_t to major and minor numbers - */ - dev_major = major(dev); - dev_minor = minor(dev); - - /* - * scan each line looking for the requested device - */ - while ((nitems = fscanf(fp, READ_FORMAT, &fdev_major, &fdev_minor, - &fpid, buf)) > 0) { - - if (fdev_major == dev_major && fdev_minor == dev_minor) { - /* the device entry was found, return it */ - - if ((ep = (vol_db_entry_t *) - malloc(sizeof (vol_db_entry_t))) == NULL) { - break; - } - - ep->dev_major = fdev_major; - ep->dev_minor = fdev_minor; - ep->pid = fpid; - if (nitems == NUM_FIELDS_WO_COMMENT) { - buf[0] = '\0'; /* string was NULL */ - } else if (nitems != NUM_FIELDS_W_COMMENT) { - break; /* bad record */ - } - ep->id_tag = strdup(buf); - retval = ep; /* success */ - break; - } - } -dun: -#ifdef DEBUG - dexit("volmgt_db_find: returning %#p\n", (char *)retval); -#endif - return (retval); -} - - -/* - * committment level: - * project private - * - * description: - * vol_db_free: free a vol_db_entry_t allocated by vol_db_find(). - * This function is provided for symmetry with vol_db_find(). Since - * the find function allocates memory to contain the found database - * entry via malloc, this function can be called to release that memory - * block. - * - * arguments: - * entry - pointer to a vol_db_entry structure that was allocated by - * vol_db_find(). - * - * return value(s): - * An integer describing the success or failure of the operation. The - * operation always succeeds since free(3C) always returns void and - * doesn't set errno. - * - * preconditions: - * none - */ -void -vol_db_free(vol_db_entry_t *entry) -{ - /* - * check that a non-NULL pointer was supplied prior to dereferencing - */ - if (entry != NULL) { - if (entry->id_tag != NULL) { - free(entry->id_tag); - } - free(entry); - } -} - - -/* - * committment level: - * project private - * - * description: - * vol_db_proc_find: see if a process identified by *pid* is currently - * in the process table. Send the zero signal to the process identified - * by *pid*. If the process is found kill(2) will return a value of 0. - * This corresponds to a success condition for vol_db_proc_find(). - * - * - * arguments: - * pid - the process id of the process to locate. - * - * return value(s): - * An integer describing the success or failure of the operation. - * - * preconditions: - * none - */ -int -vol_db_proc_find(pid_t pid) -{ - return ((kill(pid, 0) != 0) ? 0 : 1); -} diff --git a/usr/src/lib/libvolmgt/common/volmgt_on_private.c b/usr/src/lib/libvolmgt/common/volmgt_on_private.c index 2dd2f6f2cc..0535d07325 100644 --- a/usr/src/lib/libvolmgt/common/volmgt_on_private.c +++ b/usr/src/lib/libvolmgt/common/volmgt_on_private.c @@ -50,7 +50,6 @@ #include <sys/param.h> #include <sys/wait.h> #include <sys/mnttab.h> -#include <sys/vol.h> #include "volmgt_private.h" @@ -84,60 +83,25 @@ _dev_mounted(char *path) int ret_val = 0; - -#ifdef DEBUG - denter("_dev_mounted(%s): entering\n", path); -#endif - /* ensure we have the block spcl pathname */ if ((cn = (char *)volmgt_getfullrawname(path)) == NULL) { -#ifdef DEBUG - dprintf("_dev_mounted: volmgt_getfullrawname failed\n"); -#endif goto dun; } -#ifdef DEBUG_OPEN - dprintf("_dev_mounted: fopen()ing \"%s\"\n", MNTTAB); -#endif if ((fp = fopen(MNTTAB, "rF")) == NULL) { /* mtab is gone... let him go */ -#ifdef DEBUG - perror(MNTTAB); -#endif goto dun; } -#ifdef DEBUG_OPEN - dprintf("_dev_mounted: open()ing \"%s\"\n", cn); -#endif if ((fd = open(cn, O_RDONLY|O_NDELAY)) < 0) { -#ifdef DEBUG - dprintf("_dev_mounted: can't open \"%s\" (%d)\n", cn, errno); -#endif goto dun; } -#ifdef DEBUG_STAT - dprintf("_dev_mounted: fstat()ing \"%s\"\n", cn); -#endif if (fstat64(fd, &sb) < 0) { -#ifdef DEBUG - dprintf("_dev_mounted: stat of \"%s\" failed (%d)\n", cn, - errno); -#endif goto dun; } -#ifdef DEBUG_IOCTL - dprintf("_dev_mounted: ioctl(%s, DKIOCINFO)\n", cn); -#endif if (ioctl(fd, DKIOCINFO, &info) != 0) { -#ifdef DEBUG - dprintf( - "_dev_mounted: ioctl(DKIOCINFO) on \"%s\" failed (%d)\n", - cn, errno); -#endif goto dun; } @@ -155,10 +119,6 @@ dun: if (fd >= 0) { (void) close(fd); } -#ifdef DEBUG - dexit("_dev_mounted: returning %s\n", - ret_val ? "TRUE" : "FALSE"); -#endif return (ret_val); } @@ -187,14 +147,8 @@ _dev_unmount(char *path) int volume_is_not_managed; char *pathbuf, *absname; -#ifdef DEBUG - denter("_dev_unmount(%s): entering\n", path); -#endif if ((bn = (char *)volmgt_getfullblkname(path)) == NULL) { -#ifdef DEBUG - dprintf("_dev_unmount: volmgt_getfullblkname failed\n"); -#endif goto dun; } @@ -298,9 +252,6 @@ _dev_unmount(char *path) dun: -#ifdef DEBUG - dexit("_dev_unmount: returning %s\n", ret_val ? "TRUE" : "FALSE"); -#endif return (ret_val); } @@ -351,30 +302,14 @@ vol_getmntdev(FILE *fp, struct mnttab *mp, dev_t dev, struct dk_cinfo *ip) } /* open the device */ -#ifdef DEBUG_OPEN - dprintf("vol_getmntdev: open()ing \"%s\"\n", cn); -#endif if ((fd = open(cn, O_RDONLY|O_NDELAY)) < 0) { /* if we can't open it *assume* it's not a match */ -#ifdef DEBUG - dprintf( - "vol_getmntdev: open of \"%s\" (%s) failed (%d)\n", - cn, mp->mnt_fstype, errno); -#endif free(cn); continue; } /* stat the device */ -#ifdef DEBUG_STAT - dprintf("vol_getmntdev: fstat()ing \"%s\"\n", cn); -#endif if (fstat64(fd, &sb) < 0) { -#ifdef DEBUG - dprintf( - "vol_getmntdev: stat of \"%s\" (%s) failed (%d)\n", - cn, mp->mnt_fstype, errno); -#endif free(cn); (void) close(fd); continue; /* ain't there: can't be a match */ @@ -382,11 +317,6 @@ vol_getmntdev(FILE *fp, struct mnttab *mp, dev_t dev, struct dk_cinfo *ip) /* ensure we have a spcl device (a double check) */ if (!S_ISBLK(sb.st_mode) && !S_ISCHR(sb.st_mode)) { -#ifdef DEBUG - dprintf( - "vol_getmntdev: \"%s\" not a blk- or chr-spcl device\n", - cn); -#endif free(cn); (void) close(fd); continue; @@ -413,16 +343,8 @@ vol_getmntdev(FILE *fp, struct mnttab *mp, dev_t dev, struct dk_cinfo *ip) continue; } -#ifdef DEBUG_IOCTL - dprintf("vol_getmntdev: ioctl(%s, DKIOCINFO)\n", cn); -#endif /* one last check -- for diff. slices of the same dev/unit */ if (ioctl(fd, DKIOCINFO, &dkinfo) < 0) { -#ifdef DEBUG - dprintf( - "vol_getmntdev: ioctl(DKIOCINFO) of \"%s\" failed (%d)\n", - cn, errno); -#endif free(cn); (void) close(fd); continue; @@ -446,10 +368,6 @@ vol_getmntdev(FILE *fp, struct mnttab *mp, dev_t dev, struct dk_cinfo *ip) /* go around again */ } -#ifdef DEBUG - dexit("vol_getmntdev: returning %d (%s)\n", ret_val, - ret_val == 1 ? "SUCCESS" : "FAILURE"); -#endif return (ret_val); } @@ -501,21 +419,8 @@ get_media_info(char *path, char **mtypep, int *mnump, char **spclp) struct mnttab mnt; int ret_val = FALSE; - - -#ifdef DEBUG - denter("get_media_info(%s): entering\n", path); -#endif - -#ifdef DEBUG_OPEN - dprintf("get_media_info: fopen()ing \"%s\"\n", MNTTAB); -#endif if ((fp = fopen(MNTTAB, "rF")) == NULL) { /* mtab is gone... let him go */ -#ifdef DEBUG - dprintf("get_media_info: can't open \"%s\" (%d)\n", MNTTAB, - errno); -#endif goto dun; } @@ -527,36 +432,15 @@ get_media_info(char *path, char **mtypep, int *mnump, char **spclp) goto dun; } -#ifdef DEBUG_OPEN - dprintf("get_media_info: open()ing \"%s\"\n", cn); -#endif if ((fd = open(cn, O_RDONLY|O_NDELAY)) < 0) { -#ifdef DEBUG - dprintf("get_media_info(): can't open \"%s\" (%d)\n", cn, - errno); -#endif goto dun; } -#ifdef DEBUG_STAT - dprintf("get_media_info: fstat()ing \"%s\"\n", cn); -#endif if (fstat64(fd, &sb) < 0) { -#ifdef DEBUG - dprintf("get_media_info: can't stat \"%s\" (%d)\n", cn, errno); -#endif goto dun; } -#ifdef DEBUG_IOCTL - dprintf("get_media_info: ioctl(%s, DKIOCINFO)\n", cn); -#endif if (ioctl(fd, DKIOCINFO, &info) != 0) { -#ifdef DEBUG - dprintf( - "get_media_info: ioctl(DKIOCINFO) on \"%s\" failed (%d)\n", - cn, errno); -#endif goto dun; } @@ -589,20 +473,10 @@ get_media_info(char *path, char **mtypep, int *mnump, char **spclp) /* get the first part of the mount point (e.g. "floppy") */ cp = mnt.mnt_mountp; if (*cp++ != '/') { -#ifdef DEBUG - dprintf( - "get_media_info warning: no leading '/' in mount point \"%s\"\n", - mnt.mnt_mountp); -#endif goto dun; } mtype = cp; if ((cp = strchr(mtype, '/')) == NULL) { -#ifdef DEBUG - dprintf( - "get_media_info warning: no 2nd '/' in mount point \"%s\"\n", - mnt.mnt_mountp); -#endif goto dun; } *cp++ = NULLC; @@ -613,11 +487,6 @@ get_media_info(char *path, char **mtypep, int *mnump, char **spclp) /* scan for the symlink that points to our volname */ if ((dirp = opendir(mnt_dir)) == NULL) { -#ifdef DEBUG - dprintf( - "get_media_info warning: can't open directory \"%s\"\n", - mnt_dir); -#endif goto dun; } mtype_len = strlen(mtype); @@ -634,9 +503,6 @@ get_media_info(char *path, char **mtypep, int *mnump, char **spclp) (void) sprintf(lpath, "%s/%s", mnt_dir, dp->d_name); -#ifdef DEBUG_STAT - dprintf("get_media_info: lstat()ing \"%s\"\n", lpath); -#endif if (lstat64(lpath, &sb) < 0) { continue; /* what? */ } @@ -713,10 +579,6 @@ call_unmount_prog(int mi_gotten, int use_rmm, char *mtype, int mnum, #endif /* create a child to unmount the path */ if ((pid = fork()) < 0) { -#ifdef DEBUG - dprintf("error in call_unmount_prog: fork failed (errno %d)\n", - errno); -#endif goto dun; } @@ -775,9 +637,6 @@ call_unmount_prog(int mi_gotten, int use_rmm, char *mtype, int mnum, mi_gotten ? spcl : bn, NULL); } -#ifdef DEBUG - dprintf("call_unmount_prog: exec failed (errno %d)\n", errno); -#endif exit(-1); /*NOTREACHED*/ } @@ -792,8 +651,5 @@ call_unmount_prog(int mi_gotten, int use_rmm, char *mtype, int mnum, } dun: -#ifdef DEBUG - dexit("call_unmount_prog: returning %s\n", ret_val ? "TRUE" : "FALSE"); -#endif return (ret_val); } diff --git a/usr/src/lib/libvolmgt/common/volmgt_private.h b/usr/src/lib/libvolmgt/common/volmgt_private.h index 6ee2db9f00..7f5f004904 100644 --- a/usr/src/lib/libvolmgt/common/volmgt_private.h +++ b/usr/src/lib/libvolmgt/common/volmgt_private.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,8 +19,8 @@ * CDDL HEADER END */ /* - * Copyright (c) 1995-1996, by Sun Microsystems, Inc. - * All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. */ #ifndef _VOLMGT_PRIVATE_H @@ -36,15 +35,8 @@ extern "C" { /* * Interfaces that are private to the volmgt library. */ -char *getrawpart0(char *path); char *volmgt_getfullblkname(char *n); char *volmgt_getfullrawname(char *n); -char *volmgt_completename(char *name); -char *concat_paths(char *s, char *head, char *tail, char *opt_tail2); - -#define DEFAULT_ROOT "/vol" -#define DEFAULT_CONFIG "/etc/vold.conf" -#define MAXARGC 100 #ifndef TRUE #define TRUE 1 diff --git a/usr/src/lib/libvolmgt/common/volname.c b/usr/src/lib/libvolmgt/common/volname.c deleted file mode 100644 index d04ffa22cf..0000000000 --- a/usr/src/lib/libvolmgt/common/volname.c +++ /dev/null @@ -1,778 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright (c) 1996 by Sun Microsystems, Inc. - * All rights reserved. - */ - -/*LINTLIBRARY*/ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <dirent.h> -#include <string.h> -#include <errno.h> -#include <limits.h> -#include <unistd.h> -#include <volmgt.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/param.h> -#include <sys/vol.h> - -#include "volmgt_private.h" - - - -#define ALIAS_DIR "dev/aliases" -#define HACKNAME_MAX 5 /* max aliases to try */ -#define NUMBUF_SZ 10 /* big enough for HACKNAME */ - - -/* a shortcut for checkinf for absolute pathnames */ -#define IS_ABS_PATH(p) (*(p) == '/') - - -/* - * arc approved interface (pending) - * - can not be modified without approval from an arc - * - * committment level: - * public - * - * description: - * media_findname: try to come up with the character device when - * provided with a starting point. This interface provides the - * application programmer to provide "user friendly" names and - * easily determine the "/vol" name. - * - * arguments: - * start - a string describing a device. This string can be: - * - a full path name to a device (insures it's a - * character device by using getfullrawname()). - * - a full path name to a volume management media name - * with partitions (will return the lowest numbered - * raw partition. - * - the name of a piece of media (e.g. "fred"). - * - a symbolic device name (e.g. floppy0, cdrom0, etc) - * - a name like "floppy" or "cdrom". Will pick the lowest - * numbered device with media in it. - * - * return value(s): - * A pointer to a string that contains the character device - * most appropriate to the "start" argument. - * - * NULL indicates that we were unable to find media based on "start". - * - * The string must be free(3)'d. - * - * preconditions: - * none. - */ -char * -media_findname(char *start) -{ - static char *media_findname_work(char *); - char *s = NULL; - - - /* - * This is just a wrapper to implement the volmgt_check nastyness. - */ -#ifdef DEBUG - denter("media_findname(%s): entering\n", start ? start : "<null ptr>"); -#endif - - if (start == NULL) { - errno = EFAULT; - goto dun; - } - - /* - * If we don't get positive results, we kick volume management - * to ask it to look in the floppy drive. - * - * XXX: maybe this should be configurable ??? - */ - if ((s = media_findname_work(start)) == NULL) { -#ifdef DEBUG - dprintf("media_findname: calling volcheck and trying again\n"); -#endif - (void) volmgt_check(NULL); - s = media_findname_work(start); - } - -dun: -#ifdef DEBUG - dexit("media_findname: returning \"%s\"\n", s ? s : "<null ptr>"); -#endif - return (s); -} - - -/* - * Return a raw name, given a starting point. - * - * Assume: input string ptr is not null - */ -static char * -media_findname_work(char *start) -{ - extern char *vol_basename(char *); - static void volmgt_deref_link(char *, char *, char *); - char pathbuf[MAXPATHLEN+1]; - char *rv; - char *s; - char linkbuf[MAXNAMELEN+1]; - char *nameptr; - struct stat64 sb; - int n; - int i; - static const char *vold_root = NULL; - static char vold_alias_dir[MAXPATHLEN+1]; - char *res = NULL; - DIR *dirp = NULL; - struct dirent64 *dp; - - - -#ifdef DEBUG - denter("media_findname_work(%s): entering\n", start); -#endif - - if (vold_root == NULL) { - vold_root = volmgt_root(); - (void) concat_paths(vold_alias_dir, (char *)vold_root, - (char *)ALIAS_DIR, NULL); - } - - /* - * if this is an absolute path name then - * if it's a symlink deref it - * if it's a raw device then we're done - * else if it's a directory then look for a dev under it - */ - if (IS_ABS_PATH(start)) { - - /* try to get data on name passed in */ - if (lstat64(start, &sb) < 0) { -#ifdef DEBUG - dprintf( - "media_findname_work: lstat of \"%s\" (errno %d)\n", - start, errno); -#endif - goto dun; /* error exit */ - } - - /* - * if is this a link to something else (e.g. ".../floppy0") - * and it's in the volmgt namespace, then deref it - */ - if (S_ISLNK(sb.st_mode) && (strncmp(start, vold_alias_dir, - strlen(vold_alias_dir)) == 0)) { - - /* it's a symlink */ - if ((n = readlink(start, linkbuf, MAXNAMELEN)) <= 0) { - /* we can't read the link */ -#ifdef DEBUG - dprintf( - "media_findname_work: readlink(\"%s\") failed (errno %d)\n", - start, errno); -#endif - goto dun; /* error exit */ - } - linkbuf[n] = NULLC; - - /* dereference the link */ - volmgt_deref_link(pathbuf, start, linkbuf); - - /* stat where "start" pointed at */ - if (stat64(pathbuf, &sb) < 0) { -#ifdef DEBUG - dprintf( - "media_findname_work: stat failed on \"%s\" (errno %d)\n", - pathbuf, errno); -#endif - goto dun; /* error exit */ - } - nameptr = pathbuf; - - } else { - nameptr = start; - } - - /* do we already have a char-spcl device ?? */ - if (S_ISCHR(sb.st_mode)) { - /* - * absoluate pathname of a char-spcl device passed in - */ - res = strdup(nameptr); - goto dun; /* success */ - } - - /* not a char-spcl device -- is it a dir ?? */ - if (S_ISDIR(sb.st_mode)) { - /* open the dir and find first char-spcl device */ - if ((s = getrawpart0(nameptr)) != NULL) { - /* - * absoluate pathname to a directory passed - * in, under which there is at least one - * char-spcl device - */ - free(s); - res = strdup(nameptr); - goto dun; /* success */ - } - } - - /* - * try to get the char-spcl name if this is a blk-spcl - * - * XXX: shouldn't we ensure this is a blk spcl device? - */ - rv = volmgt_getfullrawname(nameptr); - if ((rv == NULL) || (*rv == NULLC)) { - goto dun; /* error exit */ - } - - /* stat the fullrawname device (to see if it's char-spcl) */ - if (stat64(rv, &sb) < 0) { -#ifdef DEBUG - dprintf( - "media_findname_work: stat of \"%s\" (errno %d)\n", - rv, errno); -#endif - goto dun; /* error exit */ - } - - /* have we found the char-spcl device ?? */ - if (S_ISCHR(sb.st_mode)) { - /* - * absolute pathname to block device supplied and - * converted to an absoluate pathname to a char device - */ - res = rv; /* already malloc'ed */ - goto dun; /* success */ - } - - /* - * fullrawname not a char-spcl device -- is it a dir ?? - * - * XXX: didn't we already check for a directory name - * being supplied above? - */ - if (S_ISDIR(sb.st_mode)) { - /* open dir and find first char-spcl device */ - if ((s = getrawpart0(rv)) != NULL) { - /* - * the absolute pathname of directory - * containing at least one char-spcl device - * was passed in - */ - free(s); - res = strdup(rv); - goto dun; /* success */ - } - } - - /* having a full pathname didn't help us */ - goto dun; /* failure -- pathname not found */ - } - - /* - * Ok, now we check to see if it's an alias. - * Note here that in the case of an alias, we prefer - * to return what the alias (symbolic link) points - * at, rather than the symbolic link. Makes for - * nicer printouts and such. - */ - (void) concat_paths(pathbuf, vold_alias_dir, start, NULL); - -#ifdef DEBUG - dprintf("media_findname_work: looking for \"%s\"\n", pathbuf); -#endif - - if (stat64(pathbuf, &sb) == 0) { -#ifdef DEBUG - dprintf("media_findname_work: is \"%s\" a chr-spcl dev?\n", - pathbuf); -#endif - /* is this a char-spcl device ?? */ - if (S_ISCHR(sb.st_mode)) { - /* it's probably a link, so ... */ - if ((n = readlink(pathbuf, - linkbuf, MAXNAMELEN)) <= 0) { - /* - * error (since we are in the symlink - * directory) not a link, but just punt - * anyway - */ - res = strdup(pathbuf); - } else { - /* it was a link */ - linkbuf[n] = NULLC; - res = strdup(linkbuf); - } - goto dun; /* success */ - } - -#ifdef DEBUG - dprintf("media_findname_work: not chr-spcl -- is it a dir?\n"); -#endif - /* not a char-spcl device -- is it a dir ?? */ - if (S_ISDIR(sb.st_mode)) { - /* it's probably a link, so ... */ - if ((n = readlink(pathbuf, - linkbuf, MAXNAMELEN)) <= 0) { - /* - * error, but just punt anyway - */ - nameptr = pathbuf; - s = getrawpart0(pathbuf); - } else { - /* it was a link */ - linkbuf[n] = NULLC; - /* open dir, finding first char-spcl dev */ - nameptr = linkbuf; - s = getrawpart0(linkbuf); - } - if (s != NULL) { - free(s); - res = strdup(nameptr); - goto dun; - } - } - } - - /* - * check all aliases in the alias dir, to see if any match - */ - if ((dirp = opendir(vold_alias_dir)) == NULL) { - goto try_hack; - } - - while (dp = readdir64(dirp)) { - - /* skip uninteresting entries */ - if (strcmp(dp->d_name, ".") == 0) { - continue; - } - if (strcmp(dp->d_name, "..") == 0) { - continue; - } - -#ifdef DEBUG - dprintf("media_findname_work: scanning alias \"%s\" ...\n", - dp->d_name); -#endif - /* - * open the link and see if it points at our entry - */ - (void) concat_paths(pathbuf, vold_alias_dir, dp->d_name, - NULL); - if ((n = readlink(pathbuf, linkbuf, MAXNAMELEN)) <= 0) { -#ifdef DEBUG - dprintf( - "media_findname_work: readlink(\"%s\") failed (errno %d)\n", - pathbuf, errno); -#endif - continue; - } - linkbuf[n] = NULLC; - -#ifdef DEBUG - dprintf("media_findname_work: scanning link \"%s\" ...\n", - linkbuf); -#endif - if (strcmp(vol_basename(linkbuf), start) == 0) { - - /* we *think* we've found a match */ - - if (stat64(linkbuf, &sb) == 0) { - - if (S_ISCHR(sb.st_mode)) { - res = strdup(linkbuf); - goto dun; - } - - if (S_ISDIR(sb.st_mode)) { - res = getrawpart0(linkbuf); - if (res != NULL) { - free(res); - res = strdup(linkbuf); - } - goto dun; - } - - } - - } - } - -try_hack: - - /* - * Ok, well maybe that's not it. Let's try the - * hackname alias. - */ - - /* - * This creates the "hack" name. The model - * is that xx# has the alias xx. So, cdrom# - * and floppy# (the most frequent case) can - * be referred to as cdrom and floppy. - * We poke at what we consider to be a reasonable number of - * devices (currently 5) before giving up. - */ - - for (i = 0; i < HACKNAME_MAX; i++) { - char num_buf[NUMBUF_SZ]; - - - (void) sprintf(num_buf, "%d", i); - (void) concat_paths(pathbuf, vold_alias_dir, start, num_buf); - - if (stat64(pathbuf, &sb) == 0) { - - /* is it a char-spcl device ?? */ - if (S_ISCHR(sb.st_mode)) { - /* it's probably a link, so... */ - if ((n = readlink(pathbuf, - linkbuf, MAXNAMELEN)) <= 0) { - /* it wasn't a link */ - res = strdup(pathbuf); - } else { - /* it was a link */ - linkbuf[n] = NULLC; - res = strdup(linkbuf); - } - goto dun; - } - - /* not a char-spcl device -- is it a dir ?? */ - if (S_ISDIR(sb.st_mode)) { - /* it's probably a link, so ... */ - if ((n = readlink(pathbuf, - linkbuf, MAXNAMELEN)) <= 0) { - /* get fist char-spcl dev in dir */ - nameptr = pathbuf; - s = getrawpart0(pathbuf); - } else { - /* it was a link */ - linkbuf[n] = NULLC; - /* get fist char-spcl dev in dir */ - nameptr = linkbuf; - s = getrawpart0(linkbuf); - } - if (s != NULL) { - free(s); - res = strdup(nameptr); - goto dun; - } - } - } - } - -#ifdef DEBUG - dprintf("media_findname_work: %s didn't match any test!\n", start); -#endif - -dun: - if (dirp != NULL) { - (void) closedir(dirp); - } - -#ifdef DEBUG - dexit("media_findname_work: returning \"%s\"\n", - res ? res : "<null ptr>"); -#endif - return (res); -} - - -/* - * deref the link (in link_buf) read from path_buf into res_buf - * - * if there's any problem then just return the contents of the link buffer - */ -static void -volmgt_deref_link(char *res_buf, char *path_buf, char *link_buf) -{ - static char *vol_dirname(char *); - char buf[MAXPATHLEN+1]; - char *path_dirname; - - - if (IS_ABS_PATH(link_buf)) { - - /* degenerate case -- link is okay the way it is */ - (void) strncpy(res_buf, link_buf, MAXPATHLEN); - - } else { - - /* link pathname is relative */ - - /* get a writable copy of the orig path */ - (void) strncpy(buf, path_buf, MAXPATHLEN); - - /* get the dir from the orig path */ - if ((path_dirname = vol_dirname(buf)) == NULL) { - - /* oh oh -- just use the link contents */ - (void) strncpy(res_buf, link_buf, MAXPATHLEN); - - } else { - - /* concat the orig dir with the link path (if room) */ - (void) concat_paths(res_buf, path_dirname, link_buf, - NULL); - } - } -} - - -/* - * return the dirname part of a path (i.e. all but last component) - * - * NOTE: may destuctively change "path" (i.e. it may write a null over - * the last slash in the path to convert it into a dirname) - */ -static char * -vol_dirname(char *path) -{ - char *cp; - - - /* find the last seperator in the path */ - if ((cp = strrchr(path, '/')) == NULL) { - /* must be just a local name -- use the local dir */ - return ("."); - } - - /* replace the last slash with a null */ - *cp = NULLC; - - /* return all but the last component */ - return (path); -} - - -/* - * This function runs through the list of "old" aliases to - * see if someone is calling a device by an old name before - * the glory of volume management. - */ - -struct alias { - char *alias; - char *name; -}; - -static struct alias volmgt_aliases[] = { - { "fd", "floppy0" }, - { "fd0", "floppy0" }, - { "fd1", "floppy1" }, - { "diskette", "floppy0" }, - { "diskette0", "floppy0" }, - { "diskette1", "floppy1" }, - { "rdiskette", "floppy0" }, - { "rdiskette0", "floppy0" }, - { "rdiskette1", "floppy1" }, - { "cd", "cdrom0" }, - { "cd0", "cdrom0" }, - { "cd1", "cdrom1" }, - { "sr", "cdrom0" }, - { "sr0", "cdrom0" }, - { "/dev/sr0", "cdrom0" }, - { "/dev/rsr0", "cdrom0" }, - { "", ""} -}; - - -/* - * "old" aliases -- XXX: only make sense if vold not running? - */ -static struct alias device_aliases[] = { - { "fd", "/dev/rdiskette" }, - { "fd0", "/dev/rdiskette" }, - { "fd1", "/dev/rdiskette1" }, - { "diskette", "/dev/rdiskette" }, - { "diskette0", "/dev/rdiskette0" }, - { "diskette1", "/dev/rdiskette1" }, - { "rdiskette", "/dev/rdiskette" }, - { "rdiskette0", "/dev/rdiskette0" }, - { "rdiskette1", "/dev/rdiskette1" }, - { "floppy", "/dev/rdiskette" }, - { "floppy0", "/dev/rdiskette0" }, - { "floppy1", "/dev/rdiskette1" }, - { "cd", "cdrom0" }, - { "cd0", "cdrom0" }, - { "cd1", "cdrom1" }, - { "", ""} -}; - - -/* - * This is an ON Consolidation Private interface. - */ -char * -_media_oldaliases(char *start) -{ - struct alias *s, *ns; - char *p; - char *res; - - - -#ifdef DEBUG - denter("_media_oldaliases(%s): entering\n", start); -#endif - - for (s = device_aliases; *s->alias != NULLC; s++) { - if (strcmp(start, s->alias) == 0) { - break; - } - } - - /* we don't recognize that alias at all */ - if (*s->alias == NULLC) { -#ifdef DEBUG - dprintf("_media_oldaliases: failed\n"); -#endif - res = NULL; - goto dun; - } - - /* if volume management isn't running at all, give him back the name */ - if (!volmgt_running()) { -#ifdef DEBUG - dprintf("_media_oldaliases: no vold!\n"); -#endif - res = strdup(s->name); - goto dun; - } - /* - * If volume management is managing that device, look up the - * volume management name. - */ - if (volmgt_inuse(s->name)) { - for (s = volmgt_aliases; *s->alias != NULLC; s++) { - if (strcmp(start, s->alias) == 0) { - res = strdup(s->name); - goto dun; - } - } -#ifdef DEBUG - dprintf("_media_oldaliases: failed\n"); -#endif - res = NULL; - goto dun; - } - - /* - * If volume management isn't managing the device, it's possible - * that he's given us an alias that we should recognize, but the - * default name is wrong. For example a user might have his - * cdrom on controller 1, being managed by volume management, - * but we would think it isn't because volmgt_inuse just told - * us that c0t6d0s2 isn't being managed. So, before we return - * the /dev name, we'll test the alias out using media_findname. - * If media_findname can't make sense out of the alias, it probably - * means that we really, really aren't managing the device and - * should just return the /dev name. Whew. Isn't this grody? - */ - - for (ns = volmgt_aliases; *ns->alias != NULLC; ns++) { - if (strcmp(start, ns->alias) == 0) { - if ((p = media_findname_work(ns->name))) { - res = p; - goto dun; - } else { - break; - } - } - } - - res = strdup(s->name); -dun: -#ifdef DEBUG - dexit("_media_oldaliases: returning %s\n", res ? res : "<null ptr>"); -#endif - return (res); -} - - -/* - * This is an ON Consolidation Private interface. - * - * Print out the aliases available to the program user. Changes - * depending in whether volume management is running. - */ -void -_media_printaliases(void) -{ - struct alias *s; - DIR *dirp; - struct dirent64 *dp; - char pathbuf[MAXPATHLEN+1]; - char *p; - static const char *vold_root = NULL; - - - - if (vold_root == NULL) { - vold_root = volmgt_root(); - } - - if (!volmgt_running()) { - /* no volume management */ - for (s = device_aliases; *s->alias != NULLC; s++) { - (void) printf("\t%s -> %s\n", s->alias, s->name); - } - return; - } - - for (s = volmgt_aliases; *s->alias != NULLC; s++) { - (void) printf("\t%s -> %s\n", s->alias, s->name); - } - - (void) concat_paths(pathbuf, (char *)vold_root, ALIAS_DIR, NULL); - - if ((dirp = opendir(pathbuf)) == NULL) { - return; - } - while (dp = readdir64(dirp)) { - if (strcmp(dp->d_name, ".") == 0) { - continue; - } - if (strcmp(dp->d_name, "..") == 0) { - continue; - } - if ((p = media_findname(dp->d_name)) != NULL) { - (void) printf("\t%s -> %s\n", dp->d_name, p); - } - } - (void) closedir(dirp); -} diff --git a/usr/src/lib/libvolmgt/common/volprivate.c b/usr/src/lib/libvolmgt/common/volprivate.c index 989405c06b..9ef56f329e 100644 --- a/usr/src/lib/libvolmgt/common/volprivate.c +++ b/usr/src/lib/libvolmgt/common/volprivate.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,8 +19,8 @@ * CDDL HEADER END */ /* - * Copyright (c) 1995-1997 by Sun Microsystems, Inc. - * All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -42,79 +41,10 @@ #include <sys/types.h> #include <sys/stat.h> #include <sys/param.h> -#include <sys/vol.h> -#ifdef DEBUG #include <sys/varargs.h> -#endif #include "volmgt_private.h" - -/* - * We have been passed a path which (presumably) is a volume. - * We look through the directory until we find a name which is - * a character device. - */ -char * -getrawpart0(char *path) -{ - DIR *dirp = NULL; - struct dirent64 *dp; - static char fname[MAXPATHLEN+1]; - struct stat64 sb; - char *res; - int len; - - - - /* open the directory */ - if ((dirp = opendir(path)) == NULL) { - res = NULL; - goto dun; - } - - /* get length of directory part */ - len = strlen(path); - - /* scan the directory */ - while (dp = readdir64(dirp)) { - - /* skip "." and ".." */ - if (strcmp(dp->d_name, ".") == 0) { - continue; - } - if (strcmp(dp->d_name, "..") == 0) { - continue; - } - - /* ensure we have room for this name */ - if ((len + strlen(dp->d_name) + 1) > MAXPATHLEN) { - /* XXX: just give up? */ - continue; - } - - /* create a pathname for this device */ - (void) concat_paths(fname, path, dp->d_name, NULL); - if (stat64(fname, &sb) < 0) { - continue; /* this shouldn't happen */ - } - /* check for a char-spcl device */ - if (S_ISCHR(sb.st_mode)) { - res = strdup(fname); - goto dun; - } - } - - /* raw part not found */ - res = NULL; -dun: - if (dirp != NULL) { - (void) closedir(dirp); - } - return (res); -} - - /* * fix the getfull{raw,blk}name problem for the fd and diskette case * @@ -236,72 +166,6 @@ dun: } -/* - * volctl_name -- return name of volctl device - */ -const char * -volctl_name(void) -{ - static char dev_name[] = "/dev/" VOLCTLNAME; - - return (dev_name); -} - - -/* - * concat_paths -- create a pathname from two (or three) components - * - * truncate the result if it is too large - * - * assume that res has a defined length of MAXPATHLEN+1 - * - * ("head" and "tail" are required, but "tail2" is optional) - */ -char * -concat_paths(char *res, char *head, char *tail, char *tail2) -{ - int head_len = strlen(head); - int len_avail = MAXPATHLEN; - - - - /* put in as much of the head as will fit */ - (void) strncpy(res, head, len_avail); - len_avail -= head_len; - - /* see if there is room to proceed */ - if (len_avail > 0) { - char *cp = res + head_len; - - /* there is room to append a slash */ - *cp++ = '/'; - len_avail--; - - /* see if there is room to proceed */ - if (len_avail > 0) { - int tail_len = strlen(tail); - - /* there is room to append the tail */ - (void) strncpy(cp, tail, len_avail); - cp += tail_len; - len_avail -= tail_len; - - /* see if there is room to proceed */ - if ((len_avail > 0) && (tail2 != NULL)) { - - /* there is room to add tail2 (and need) */ - (void) strncpy(cp, tail2, len_avail); - } - } - } - - /* null terminate result (just in case) and return */ - res[MAXPATHLEN] = NULLC; - return (res); -} - - - #ifdef DEBUG /* diff --git a/usr/src/lib/libvolmgt/common/volutil.c b/usr/src/lib/libvolmgt/common/volutil.c deleted file mode 100644 index fbb241f53f..0000000000 --- a/usr/src/lib/libvolmgt/common/volutil.c +++ /dev/null @@ -1,662 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright (c) 1996 by Sun Microsystems, Inc. - * All rights reserved. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <stdio.h> -#include <string.h> -#include <dirent.h> -#include <fcntl.h> -#include <string.h> -#include <errno.h> -#include <limits.h> -#include <unistd.h> -#ifdef DEBUG_IOCTL -#include <sys/mkdev.h> -#endif -#include <volmgt.h> -#include <ctype.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/param.h> -#include <sys/vol.h> -#include "volmgt_private.h" - - - - -const char *volctl_name(void); - -/* - * arc approved interface - * - can not be modified without approval from an arc - * - * committment level: - * public - * - * description: - * volmgt_running: check to see if volume management is running. - * - * arguments: - * none. - * - * return value(s): - * TRUE if volume management is running, FALSE if not. - * - * preconditions: - * none. - */ -int -volmgt_running(void) -{ - const char *volctl_dev = volctl_name(); - int res; - - -#ifdef DEBUG - denter("volmgt_running: entering\n"); -#endif - res = volmgt_inuse((char *)volctl_dev); -#ifdef DEBUG - dexit("volmgt_running: returning %s\n", res ? "TRUE" : "FALSE"); -#endif - return (res); -} - - -/* - * arc approved interface - * - can not be modified without approval from an arc - * - * committment level: - * public - * - * description: - * volmgt_inuse: check to see if volume management is currently - * managing a particular device. - * - * arguments: - * path - the name of the device in /dev. For example, - * "/dev/rdiskette". - * - * return value(s): - * TRUE if volume management is managing the device, FALSE if not. - * - * preconditions: - * none. - */ -int -volmgt_inuse(char *path) -{ - const char *volctl_dev = volctl_name(); - struct stat64 sb; - int fd = -1; - int ret_val; - - - -#ifdef DEBUG - denter("volmgt_inuse(%s): entering\n", - path != NULL ? path : "<null string>"); -#endif -#ifdef DEBUG_STAT - dprintf("volmgt_inuse: stat()ing \"%s\"\n", path); -#endif - if (stat64(path, &sb) < 0) { - ret_val = FALSE; - goto dun; - } - -#ifdef DEBUG_OPEN - dprintf("volmgt_inuse: open()ing \"%s\"\n", volctl_dev); -#endif - if ((fd = open(volctl_dev, O_RDWR)) < 0) { -#ifdef DEBUG - perror(volctl_dev); -#endif - ret_val = FALSE; - goto dun; - } - -#ifdef DEBUG_IOCTL - dprintf("volmgt_inuse: ioctl(%s, VOLIOCINUSE)\n", volctl_dev); -#endif - if (ioctl(fd, VOLIOCINUSE, sb.st_rdev) < 0) { - ret_val = FALSE; - goto dun; - } - ret_val = TRUE; -dun: - if (fd >= 0) { - (void) close(fd); - } -#ifdef DEBUG - dexit("volmgt_inuse: returning %s\n", ret_val ? "TRUE" : "FALSE"); -#endif - return (ret_val); -} - - -/* - * arc approved interface - * - can not be modified without approval from an arc - * - * committment level: - * public - * - * description: - * volmgt_check: have volume management look at its devices to check - * for media having arrived. Since volume management can't - * automatically check all types of devices, this function is provided - * to allow applications to cause the check to happen automatically. - * - * arguments: - * path - the name of the device in /dev. For example, - * /dev/rdiskette. If path is NULL, all "checkable" devices are - * checked. - * - * return value(s): - * TRUE if media was found in the device, FALSE if not. - * - * preconditions: - * volume management must be running. - */ -int -volmgt_check(char *path) -{ - const char *volctl_dev = volctl_name(); - struct stat64 sb; - int fd = -1; - int ret_val; - - - -#ifdef DEBUG - denter("volmgt_check(%s): entering\n", - path != NULL ? path : "<null string>"); -#endif - - if (path != NULL) { -#ifdef DEBUG_STAT - dprintf("volmgt_check: stat()ing \"%s\"\n", path); -#endif - if (stat64(path, &sb) < 0) { - ret_val = FALSE; - goto dun; - } - } - -#ifdef DEBUG_OPEN - dprintf("volmgt_check: open()ing \"%s\"\n", volctl_dev); -#endif - if ((fd = open(volctl_dev, O_RDWR)) < 0) { -#ifdef DEBUG - perror(volctl_dev); -#endif - ret_val = FALSE; - goto dun; - } - - /* if "no device" specified, that means "all devices" */ - if (path == NULL) { - sb.st_rdev = NODEV; - } - -#ifdef DEBUG_IOCTL - dprintf("volmgt_check: ioctl(%s, VOLIOCCHECK)\n", volctl_dev); -#endif - if (ioctl(fd, VOLIOCCHECK, sb.st_rdev) < 0) { - ret_val = FALSE; - goto dun; - } - ret_val = TRUE; -dun: - if (fd >= 0) { - (void) close(fd); - } -#ifdef DEBUG - dexit("volmgt_check: returning %s\n", - ret_val != NULL ? "TRUE" : "FALSE"); -#endif - return (ret_val); -} - - -/* - * arc approved interface - * - can not be modified without approval from an arc - * - * committment level: - * public - * - * description: - * volmgt_ownspath: check to see if the given path is contained in - * the volume management name space. - * - * arguments: - * path - string containing the path. - * - * return value(s): - * TRUE if the path is owned by volume management, FALSE if not. - * Will return FALSE if volume management isn't running. - * - * preconditions: - * none. - */ -int -volmgt_ownspath(char *path) -{ - static const char *vold_root = NULL; - static uint vold_root_len; - int ret_val; - - - - if (vold_root == NULL) { - vold_root = volmgt_root(); - vold_root_len = strlen(vold_root); - } - - if (strncmp(path, vold_root, vold_root_len) == 0) { - ret_val = TRUE; - } else { - ret_val = FALSE; - } - return (ret_val); -} - - -/* - * arc approved interface - * - can not be modified without approval from an arc - * - * committment level: - * public - * - * description: - * volmgt_root: return the root of where the volume management - * name space is mounted. - * - * arguments: - * none. - * - * return value(s): - * Returns a pointer to a static string containing the path to the - * volume management root (e.g. "/vol"). - * Will return NULL if volume management isn't running. - * - * preconditions: - * none. - */ -const char * -volmgt_root(void) -{ - static char vold_root[MAXPATHLEN+1] = ""; - struct vol_str vstr; - const char *volctl_dev = volctl_name(); - int fd = -1; - - - vstr.data = vold_root; - vstr.data_len = MAXPATHLEN; - -#ifdef DEBUG - denter("volmgt_root: entering\n"); -#endif - - if (*vold_root != NULLC) { - goto dun; - } - -#ifdef DEBUG_OPEN - dprintf("volmgt_root: open()ing \"%s\"\n", volctl_dev); -#endif - if ((fd = open(volctl_dev, O_RDWR)) < 0) { -#ifdef DEBUG - perror(volctl_dev); -#endif - /* a guess is better than nothing? */ - (void) strncpy(vold_root, DEFAULT_ROOT, MAXPATHLEN); - goto dun; - } - -#ifdef DEBUG_IOCTL - dprintf("volmgt_root: ioctl(%s, VOLIOCROOT)\n", volctl_dev); -#endif - if (ioctl(fd, VOLIOCROOT, &vstr) < 0) { -#ifdef DEBUG - dprintf( - "volmgt_root: ioctl(VOLIOCROOT) on \"%s\" failed (errno %d)\n", - volctl_dev, errno); -#endif - (void) strncpy(vold_root, DEFAULT_ROOT, MAXPATHLEN); - goto dun; - } - -dun: - if (fd >= 0) { - (void) close(fd); - } -#ifdef DEBUG - dexit("volmgt_root: returning \"%s\"\n", vold_root); -#endif - return ((const char *)vold_root); -} - - -/* - * arc approved interface - * - can not be modified without approval from an arc - * - * committment level: - * public - * - * description: - * volmgt_symname: Returns the volume management symbolic name - * for a given device. If an application wants to determine - * what the symbolic name (e.g. "floppy0") for the /dev/rdiskette - * device would be, this is the function to use. - * - * arguments: - * path - a string containing the /dev device name. For example, - * "/dev/diskette" or "/dev/rdiskette". - * - * Note: must be a block- or char-spcl device, and have a non-zero - * st_rdev (real device) stat() value. - * - * return value(s): - * pointer to a string containing the symbolic name. - * - * NULL indicates that volume management isn't managing that device. - * - * The string must be free(3)'d. - * - * preconditions: - * none. - */ -char * -volmgt_symname(char *path) -{ - const char *volctl_dev = volctl_name(); - int fd = -1; - struct stat64 sb; - struct vioc_symname sn; - char *result = NULL; - char symbuf[VOL_SYMNAME_LEN+1] = ""; - - - -#ifdef DEBUG - denter("volmgt_symname(%s): entering\n", path ? path : "<null ptr>"); -#endif - - /* just in case */ - if (path == NULL) { -#ifdef DEBUG - dprintf("volmgt_symname error: input path is null!\n"); -#endif - errno = EFAULT; - goto dun; - } - -#ifdef DEBUG_STAT - dprintf("volmgt_symname: stat()ing \"%s\"\n", path); -#endif - if (stat64(path, &sb) != 0) { -#ifdef DEBUG - dprintf("volmgt_symname error: can't stat \"%s\" (errno %d)\n", - path, errno); -#endif - goto dun; - } - - /* ensure we have a spcl device with a non-zero st_rdev */ - if (!S_ISCHR(sb.st_mode) && !S_ISBLK(sb.st_mode)) { -#ifdef DEBUG - dprintf("volmgt_symname error: %s not blk- or chr-spcl\n", - path); -#endif - errno = EINVAL; - goto dun; - } - if (sb.st_rdev == (dev_t)0) { -#ifdef DEBUG - dprintf("volmgt_symname error: dev_t of %s is zero!\n", - path); -#endif - errno = EINVAL; - } - -#ifdef DEBUG_OPEN - dprintf("volmgt_symname: open()ing \"%s\"\n", volctl_dev); -#endif - if ((fd = open(volctl_dev, O_RDWR)) < 0) { -#ifdef DEBUG - dprintf("volmgt_symname error: can't open \"%s\" (errno %d)\n", - volctl_dev, errno); -#endif - goto dun; - } - - sn.sn_dev = sb.st_rdev; - sn.sn_symname = symbuf; - sn.sn_pathlen = VOL_SYMNAME_LEN; -#ifdef DEBUG_IOCTL - dprintf( - "volmgt_symname: ioctl(%s, VOLIOCSYMNAME, {%d.%d, %#x, %d})ing\n", - volctl_dev, major(sn.sn_dev), minor(sn.sn_dev), sn.sn_symname, - sn.sn_pathlen); -#endif - if (ioctl(fd, VOLIOCSYMNAME, &sn) == 0) { - result = strdup(symbuf); - } -#ifdef DEBUG - else { - dprintf( - "volmgt_symname: ioctl(VOLIOCSYMNAME) failed (errno %d)\n", - errno); - } -#endif - -dun: - if (fd >= 0) { - (void) close(fd); - } - -#ifdef DEBUG - dexit("volmgt_symname: returning \"%s\"\n", - result != NULL ? result : "<null ptr>"); -#endif - - return (result); -} - - -/* - * arc approved interface - * - can not be modified without approval from an arc - * - * committment level: - * public - * - * description: - * volmgt_symdev: Returns the device given the volume management - * symbolic name. If an application wants to determine - * what the device associated with a particular symbolic name - * might be, this is the function to use. - * - * arguments: - * path - a string containing the symbolic device name. For example, - * "cdrom0" or "floppy0". - * - * return value(s): - * pointer to a string containing the /dev name. - * - * NULL indicates that volume management isn't managing that device. - * - * The string must be free(3)'d. - * - * preconditions: - * none. - */ -char * -volmgt_symdev(char *symname) -{ - const char *volctl_dev = volctl_name(); - int fd = -1; - struct vioc_symdev sd; - char *result = NULL; - char devbuf[VOL_SYMDEV_LEN+1] = ""; - - -#ifdef DEBUG - denter("volmgt_symdev(%s): entering\n", symname); -#endif - -#ifdef DEBUG_OPEN - dprintf("volmgt_symdev: open()ing \"%s\"\n", volctl_dev); -#endif - if ((fd = open(volctl_dev, O_RDWR)) < 0) { -#ifdef DEBUG - dprintf("volmgt_symdev error: can't open \"%s\" (errno %d)\n", - volctl_dev, errno); -#endif - goto dun; - } - - sd.sd_symname = symname; - sd.sd_symnamelen = strlen(symname); - sd.sd_symdevname = devbuf; - sd.sd_pathlen = VOL_SYMDEV_LEN; -#ifdef DEBUG_IOCTL - dprintf("volmgt_symdev: ioctl(%s, VOLIOCSYMDEV)\n", volctl_dev); - dprintf("sd.sd_symname = %s\n", sd.sd_symname); - dprintf("sd.sd_symnamelen = %d\n", sd.sd_symnamelen); - dprintf("sd.sd_symdevname = %s\n", sd.sd_symdevname); - dprintf("sd.sd_pathlen = %d\n", sd.sd_pathlen); - dprintf("---- make the ioctl for VOLIOCSYMDEV ----\n"); -#endif - - if (ioctl(fd, VOLIOCSYMDEV, &sd) == 0) { - result = strdup(devbuf); - } - -#ifdef DEBUG - else { - dprintf( - "volmgt_symdev: VOLIOCSYMDEV ioctl failed (errno %d)\n", - errno); - } -#endif - -dun: - if (fd >= 0) { - (void) close(fd); - } - -#ifdef DEBUG - dexit("volmgt_symdev: returning \"%s\"\n", - result != NULL ? result : "<null ptr>"); -#endif - - return (result); -} - - -/* - * arc approved interface - * - can not be modified without approval from an arc - * - * committment level: - * public - * - * description: - * volmgt_feat_enabled: check to see if a volume management feature - * is available - * - * arguments: - * feat_str - a string containing the feature to be checked for - * - * return value(s): - * return non-zero if the specified feature is available in - * volume management, else return zero - * - * preconditions: - * none. - */ - - -/* - * the following is a lit of the "feature" available in volmgt - * - * this list is meant to be updated when new features (that users may - * want to use) are added to volmgt - * - * note: feature strings added should be all lower case, and spaces are - * discouraged - * - * (see psarc/1995/138 for more info) - */ -static char *volmgt_feat_list[] = { -#ifdef DIRECT_DEV_ACCESS_WORKING - "direct-dev-access", /* access through /dev co-exists */ -#endif - "floppy-summit-interfaces", /* volmgt_{acquire,release} */ - NULL -}; - - -int -volmgt_feature_enabled(char *feat_str) -{ - int i; - char *cp; - int res = 0; - - - /* ensure no hoser can core dump us */ - if (feat_str == NULL) { - errno = EFAULT; - return (0); /* I guess this isn't a match */ - } - - /* ensure feat string passed in is all lower case (as feats are) */ - for (cp = feat_str; *cp != NULLC; cp++) { - if (isupper(*cp)) { - *cp = _tolower(*cp); - } - } - - /* now scan for a match */ - for (i = 0; volmgt_feat_list[i] != NULL; i++) { - if (strcmp(volmgt_feat_list[i], feat_str) == 0) { - res++; - break; - } - } - - return (res); -} diff --git a/usr/src/lib/policykit/Makefile b/usr/src/lib/policykit/Makefile new file mode 100644 index 0000000000..b60b67f7a1 --- /dev/null +++ b/usr/src/lib/policykit/Makefile @@ -0,0 +1,56 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +include ../Makefile.lib +include $(SRC)/lib/policykit/Makefile.policykit + +SUBDIRS = libpolkit +HDRSUBDIRS = libpolkit + +all := TARGET= all +clean := TARGET= clean +clobber := TARGET= clobber +install := TARGET= install +install_h := TARGET= install_h + +.KEEP_STATE: + +all clean clobber install: $(SUBDIRS) + +install_h: $(ROOTHDRDIR) $(ROOTHDRS) $(SUBDIRS) + +# +# Don't check 3rd party headers. +# +check: + +$(SUBDIRS): FRC + @cd $@; pwd; $(MAKE) $(TARGET) + +FRC: + +include ../Makefile.targ diff --git a/usr/src/lib/policykit/Makefile.com b/usr/src/lib/policykit/Makefile.com new file mode 100644 index 0000000000..2dc67c1614 --- /dev/null +++ b/usr/src/lib/policykit/Makefile.com @@ -0,0 +1,54 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +include $(SRC)/lib/Makefile.lib +include $(SRC)/lib/policykit/Makefile.policykit + +CPPFLAGS = $(POLICYKIT_DBUS_CPPFLAGS) $(POLICYKIT_GLIB_CPPFLAGS) $(CPPFLAGS.master) + +C99MODE = $(C99_ENABLE) + +ROOTLIBPCDIR = $(ROOT)/usr/lib/pkgconfig +ROOTLIBPC = $(LIBPCSRC:%=$(ROOTLIBPCDIR)/%) + +CLOBBERFILES += $(LIBPCSRC) + +# +# Ensure `all' is the default target. +# +all: + +$(ROOTLIBPCDIR): + $(INS.dir) + +$(ROOTLIBPC): $(ROOTLIBPCDIR) $(LIBPCSRC) + $(INS.file) $(LIBPCSRC) + +$(LIBPCSRC): ../common/$(LIBPCSRC).in + $(SED) -e "s@__VERSION__@$(POLICYKIT_VERSION)@" \ + < ../common/$(LIBPCSRC).in > $(LIBPCSRC) + diff --git a/usr/src/lib/policykit/Makefile.policykit b/usr/src/lib/policykit/Makefile.policykit new file mode 100644 index 0000000000..8b8cff0fe1 --- /dev/null +++ b/usr/src/lib/policykit/Makefile.policykit @@ -0,0 +1,36 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# +# Definitions common for PolicyKit +# + +POLICYKIT_VERSION = 0.2 + +POLICYKIT_DBUS_CPPFLAGS = -DDBUS_API_SUBJECT_TO_CHANGE -I/usr/include/dbus-1.0 -I/usr/lib/dbus-1.0/include +POLICYKIT_GLIB_CPPFLAGS = -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include + +POLICYKIT_DBUS_LDLIBS = -ldbus-1 +POLICYKIT_GLIB_LDLIBS = -lglib-2.0 diff --git a/usr/src/lib/policykit/libpolkit/Makefile b/usr/src/lib/policykit/libpolkit/Makefile new file mode 100644 index 0000000000..76b1fd758e --- /dev/null +++ b/usr/src/lib/policykit/libpolkit/Makefile @@ -0,0 +1,52 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" + +include ../../Makefile.lib +include ../Makefile.com + +HDRS = libpolkit.h +HDRDIR = common +ROOTHDRDIR = $(ROOT)/usr/include/libpolkit + +SUBDIRS = $(MACH) + +all := TARGET= all +clean := TARGET= clean +clobber := TARGET= clobber +install := TARGET= install + +.KEEP_STATE: + +all clean clobber install: $(SUBDIRS) + +install_h: $(ROOTHDRS) + +$(SUBDIRS): FRC + @cd $@; pwd; $(MAKE) $(TARGET) + +FRC: + +include $(SRC)/lib/Makefile.targ diff --git a/usr/src/lib/policykit/libpolkit/Makefile.com b/usr/src/lib/policykit/libpolkit/Makefile.com new file mode 100644 index 0000000000..0fb2f8a7f6 --- /dev/null +++ b/usr/src/lib/policykit/libpolkit/Makefile.com @@ -0,0 +1,59 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# +# usr/src/lib/policykit/libpolkit/Makefile.com +# + +LIBRARY = libpolkit.a +VERS = .0.0.0 +VERS_MAJ = .0 +OBJECTS = libpolkit-rbac.o +LIBPCSRC = polkit.pc + +include ../../Makefile.com + +LIBS = $(DYNLIB) $(LINTLIB) +LDLIBS += $(POLICYKIT_GLIB_LDLIBS) +LDLIBS += -lc -lsecdb +$(LINTLIB) := SRCS = $(SRCDIR)/$(LINTSRC) + +SRCDIR = ../common + +CFLAGS += $(CCVERBOSE) +CPPFLAGS += -DPACKAGE_LOCALE_DIR=\"/usr/lib/locale\" + +ROOTMAJLINK = $(ROOTLIBDIR)/$(LIBRARY:.a=.so)$(VERS_MAJ) + +.KEEP_STATE: + +all: $(LIBS) + +lint: + +$(ROOTMAJLINK): + -$(RM) $@; $(SYMLINK) $(DYNLIB) $@ + +include $(SRC)/lib/Makefile.targ diff --git a/usr/src/lib/policykit/libpolkit/common/libpolkit-rbac.c b/usr/src/lib/policykit/libpolkit/common/libpolkit-rbac.c new file mode 100644 index 0000000000..a0c757f622 --- /dev/null +++ b/usr/src/lib/policykit/libpolkit/common/libpolkit-rbac.c @@ -0,0 +1,204 @@ +/*************************************************************************** + * + * libpolkit-rbac.c : RBAC implementation of the libpolkit API + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + * Licensed under the Academic Free License version 2.1 + * + **************************************************************************/ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <pwd.h> +#include <grp.h> +#include <unistd.h> +#include <errno.h> +#include <auth_attr.h> +#include <secdb.h> + +#include <glib.h> +#include <dbus/dbus-glib.h> + +#include "libpolkit.h" + +#define LIBPOLKIT_MAGIC 0x3117beef + +#ifdef __SUNPRO_C +#define __FUNCTION__ __func__ +#endif + +#define LIBPOLKIT_CHECK_CONTEXT(_ctx_, _ret_) \ + do { \ + if (_ctx_ == NULL) { \ + g_warning ("%s: given LibPolKitContext is NULL", \ + __FUNCTION__); \ + return _ret_; \ + } \ + if (_ctx_->magic != LIBPOLKIT_MAGIC) { \ + g_warning ("%s: given LibPolKitContext is invalid (read magic 0x%08x, should be 0x%08x)", \ + __FUNCTION__, _ctx_->magic, LIBPOLKIT_MAGIC); \ + return _ret_; \ + } \ + } while(0) + + +struct LibPolKitContext_s +{ + guint32 magic; +}; + +/** Get a new context. + * + * @return Pointer to new context or NULL if an error occured + */ +LibPolKitContext * +libpolkit_new_context (DBusConnection *connection) +{ + LibPolKitContext *ctx; + + ctx = g_new0 (LibPolKitContext, 1); + ctx->magic = LIBPOLKIT_MAGIC; + + return ctx; +} + +/** Free a context + * + * @param ctx The context obtained from libpolkit_new_context + * @return Pointer to new context or NULL if an error occured + */ +gboolean +libpolkit_free_context (LibPolKitContext *ctx) +{ + LIBPOLKIT_CHECK_CONTEXT (ctx, FALSE); + + ctx->magic = 0; + g_free (ctx); + return TRUE; +} + +LibPolKitResult +libpolkit_get_allowed_resources_for_privilege_for_uid (LibPolKitContext *ctx, + const char *user, + const char *privilege, + GList **resources, + GList **restrictions, + int *num_non_temporary) +{ + LibPolKitResult res; + char **resource_list; + int num_resources; + char **restriction_list; + int num_restrictions; + + LIBPOLKIT_CHECK_CONTEXT (ctx, LIBPOLKIT_RESULT_INVALID_CONTEXT); + + res = LIBPOLKIT_RESULT_ERROR; + *resources = NULL; + *restrictions = NULL; + + res = LIBPOLKIT_RESULT_OK; + + return res; +} + +LibPolKitResult +libpolkit_is_uid_allowed_for_privilege (LibPolKitContext *ctx, + const char *system_bus_unique_name, + const char *user, + const char *privilege, + const char *resource, + gboolean *out_is_allowed, + gboolean *out_is_temporary, + char **out_is_privileged_but_restricted_to_system_bus_unique_name) +{ + LibPolKitResult res; + const char *myresource = ""; + const char *mysystem_bus_unique_name = ""; + char *but_restricted_to = NULL; + uid_t uid; + struct passwd *pw; + char *authname; + int i; + gboolean authname_free = FALSE; + + LIBPOLKIT_CHECK_CONTEXT (ctx, LIBPOLKIT_RESULT_INVALID_CONTEXT); + + uid = (uid_t)atol (user); + if ((pw = getpwuid (uid)) == NULL) { + *out_is_allowed = FALSE; + *out_is_temporary = FALSE; + return LIBPOLKIT_RESULT_NO_SUCH_USER; + } + + /* map PolicyKit privilege to RBAC authorization */ + if (strcmp (privilege, "hal-storage-removable-mount") == 0) { + authname = "solaris.device.mount.removable"; + } else if (strcmp (privilege, "hal-storage-removable-mount-all-options") == 0) { + authname = "solaris.device.mount.alloptions.removable"; + } else if (strcmp (privilege, "hal-storage-fixed-mount") == 0) { + authname = "solaris.device.mount.fixed"; + } else if (strcmp (privilege, "hal-storage-fixed-mount-all-options") == 0) { + authname = "solaris.device.mount.alloptions.fixed"; + } else { + /* replace '-' with '.' */ + authname = g_strdup (privilege); + authname_free = TRUE; + for (i = 0; i < strlen (authname); i++) { + if (authname[i] == '-') { + authname[i] = '.'; + } + } + } + + *out_is_allowed = (chkauthattr(authname, pw->pw_name) != 0); + *out_is_temporary = FALSE; + + if (authname_free) { + g_free(authname); + } + + return LIBPOLKIT_RESULT_OK; +} + +LibPolKitResult +libpolkit_get_privilege_list (LibPolKitContext *ctx, + GList **result) +{ + LibPolKitResult res; + char **privilege_list; + int num_privileges = 0; + int i; + + LIBPOLKIT_CHECK_CONTEXT (ctx, LIBPOLKIT_RESULT_INVALID_CONTEXT); + + *result = NULL; + + for (i = 0; i < num_privileges; i++) { + *result = g_list_append (*result, g_strdup (privilege_list[i])); + } + + res = LIBPOLKIT_RESULT_OK; + + return res; +} + +LibPolKitResult +libpolkit_revoke_temporary_privilege (LibPolKitContext *ctx, + const char *user, + const char *privilege, + const char *resource, + gboolean *result) +{ + return LIBPOLKIT_RESULT_OK; +} diff --git a/usr/src/lib/policykit/libpolkit/common/libpolkit.h b/usr/src/lib/policykit/libpolkit/common/libpolkit.h new file mode 100644 index 0000000000..28b4319c7e --- /dev/null +++ b/usr/src/lib/policykit/libpolkit/common/libpolkit.h @@ -0,0 +1,77 @@ +/*************************************************************************** + * + * libpolkit.h : Wraps a subset of methods on the PolicyKit daemon + * + * Copyright (C) 2006 David Zeuthen, <david@fubar.dk> + * + * Licensed under the Academic Free License version 2.1 + * + * This program 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 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + **************************************************************************/ + +#ifndef LIBPOLKIT_H +#define LIBPOLKIT_H + +#include <stdio.h> +#include <unistd.h> +#include <sys/types.h> +#include <glib.h> +#include <dbus/dbus.h> + +typedef enum { + LIBPOLKIT_RESULT_OK, + LIBPOLKIT_RESULT_ERROR, + LIBPOLKIT_RESULT_INVALID_CONTEXT, + LIBPOLKIT_RESULT_NOT_PRIVILEGED, + LIBPOLKIT_RESULT_NO_SUCH_PRIVILEGE, + LIBPOLKIT_RESULT_NO_SUCH_USER +} LibPolKitResult; + +struct LibPolKitContext_s; +typedef struct LibPolKitContext_s LibPolKitContext; + +LibPolKitContext *libpolkit_new_context (DBusConnection *connection); + +gboolean libpolkit_free_context (LibPolKitContext *ctx); + +LibPolKitResult libpolkit_get_privilege_list (LibPolKitContext *ctx, + GList **result); + +LibPolKitResult libpolkit_is_uid_allowed_for_privilege (LibPolKitContext *ctx, + const char *system_bus_unique_name, + const char *user, + const char *privilege, + const char *resource, + gboolean *out_is_allowed, + gboolean *out_is_temporary, + char **out_is_privileged_but_restricted_to_system_bus_unique_name); + +LibPolKitResult libpolkit_revoke_temporary_privilege (LibPolKitContext *ctx, + const char *user, + const char *privilege, + const char *resource, + gboolean *result); + +LibPolKitResult libpolkit_get_allowed_resources_for_privilege_for_uid (LibPolKitContext *ctx, + const char *user, + const char *privilege, + GList **resources, + GList **restrictions, + int *num_non_temporary); + +#endif /* LIBPOLKIT_H */ + + diff --git a/usr/src/lib/policykit/libpolkit/common/llib-lpolkit b/usr/src/lib/policykit/libpolkit/common/llib-lpolkit new file mode 100644 index 0000000000..5762753ad8 --- /dev/null +++ b/usr/src/lib/policykit/libpolkit/common/llib-lpolkit @@ -0,0 +1,30 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ +#pragma ident "%Z%%M% %I% %E% SMI" + +/* LINTLIBRARY */ +/* PROTOLIB1 */ + +#include <libpolkit/libpolkit.h> diff --git a/usr/src/lib/policykit/libpolkit/common/mapfile-vers b/usr/src/lib/policykit/libpolkit/common/mapfile-vers new file mode 100644 index 0000000000..d125ced778 --- /dev/null +++ b/usr/src/lib/policykit/libpolkit/common/mapfile-vers @@ -0,0 +1,43 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +SUNW_1.1 { + global: + libpolkit_new_context; + libpolkit_free_context; + libpolkit_get_privilege_list; + libpolkit_is_uid_allowed_for_privilege; + libpolkit_revoke_temporary_privilege; + libpolkit_get_allowed_resources_for_privilege_for_uid; +}; + +SUNWprivate_1.1 { + global: + SUNWprivate_1.1; + local: + *; +}; diff --git a/usr/src/lib/policykit/libpolkit/common/polkit.pc.in b/usr/src/lib/policykit/libpolkit/common/polkit.pc.in new file mode 100644 index 0000000000..c6e8793d4a --- /dev/null +++ b/usr/src/lib/policykit/libpolkit/common/polkit.pc.in @@ -0,0 +1,19 @@ +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# Licensed under the Academic Free License version 2.1 +# +# ident "%Z%%M% %I% %E% SMI" + +prefix=/usr +exec_prefix=${prefix} +libdir=${exec_prefix}/lib +includedir=${prefix}/include + +Name: libpolkit +Description: library for querying and setting system-wide policy +Version: __VERSION__ +Requires: glib-2.0 +Libs: -L${libdir} -lpolkit +Cflags: -I${includedir}/libpolkit diff --git a/usr/src/lib/policykit/libpolkit/i386/Makefile b/usr/src/lib/policykit/libpolkit/i386/Makefile new file mode 100644 index 0000000000..8643a8305f --- /dev/null +++ b/usr/src/lib/policykit/libpolkit/i386/Makefile @@ -0,0 +1,30 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#ident "%Z%%M% %I% %E% SMI" +# + +include ../Makefile.com + +install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTLINT) $(ROOTLIBPC) $(ROOTMAJLINK) diff --git a/usr/src/lib/policykit/libpolkit/sparc/Makefile b/usr/src/lib/policykit/libpolkit/sparc/Makefile new file mode 100644 index 0000000000..8643a8305f --- /dev/null +++ b/usr/src/lib/policykit/libpolkit/sparc/Makefile @@ -0,0 +1,30 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#ident "%Z%%M% %I% %E% SMI" +# + +include ../Makefile.com + +install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTLINT) $(ROOTLIBPC) $(ROOTMAJLINK) |
