From: "Daniel P. Berrange" <berrange@xxxxxxxxxx> --- cfg.mk | 16 +- daemon/libvirtd.c | 2 +- daemon/remote.c | 2 +- po/POTFILES.in | 2 +- python/libvirt-override.c | 2 +- src/Makefile.am | 5 +- src/conf/capabilities.c | 2 +- src/conf/cpu_conf.c | 2 +- src/conf/cpu_conf.h | 2 +- src/conf/device_conf.c | 2 +- src/conf/device_conf.h | 2 +- src/conf/domain_conf.c | 2 +- src/conf/domain_conf.h | 2 +- src/conf/interface_conf.c | 2 +- src/conf/interface_conf.h | 2 +- src/conf/netdev_bandwidth_conf.c | 2 +- src/conf/network_conf.c | 2 +- src/conf/node_device_conf.c | 2 +- src/conf/node_device_conf.h | 2 +- src/conf/nwfilter_conf.h | 2 +- src/conf/secret_conf.c | 2 +- src/conf/secret_conf.h | 2 +- src/conf/snapshot_conf.c | 2 +- src/conf/storage_conf.c | 2 +- src/conf/storage_conf.h | 2 +- src/conf/storage_encryption_conf.c | 2 +- src/conf/storage_encryption_conf.h | 2 +- src/cpu/cpu_powerpc.c | 2 +- src/cpu/cpu_x86.c | 2 +- src/datatypes.c | 2 +- src/driver.c | 2 +- src/esx/esx_device_monitor.c | 2 +- src/esx/esx_driver.c | 2 +- src/esx/esx_interface_driver.c | 2 +- src/esx/esx_network_driver.c | 2 +- src/esx/esx_nwfilter_driver.c | 2 +- src/esx/esx_secret_driver.c | 2 +- src/esx/esx_storage_backend_iscsi.c | 2 +- src/esx/esx_storage_backend_vmfs.c | 2 +- src/esx/esx_util.c | 2 +- src/esx/esx_vi.c | 2 +- src/esx/esx_vi_types.c | 2 +- src/fdstream.c | 2 +- src/hyperv/hyperv_device_monitor.c | 2 +- src/hyperv/hyperv_driver.c | 2 +- src/hyperv/hyperv_interface_driver.c | 2 +- src/hyperv/hyperv_network_driver.c | 2 +- src/hyperv/hyperv_nwfilter_driver.c | 2 +- src/hyperv/hyperv_secret_driver.c | 2 +- src/hyperv/hyperv_storage_driver.c | 2 +- src/hyperv/hyperv_util.c | 2 +- src/hyperv/hyperv_wmi.c | 2 +- src/locking/lock_daemon.c | 2 +- src/locking/lock_daemon_dispatch.c | 2 +- src/locking/lock_driver_lockd.c | 2 +- src/locking/lock_driver_sanlock.c | 2 +- src/locking/lock_manager.c | 2 +- src/lxc/lxc_container.c | 2 +- src/lxc/lxc_controller.c | 4 +- src/lxc/lxc_driver.c | 2 +- src/lxc/lxc_fuse.h | 2 +- src/network/bridge_driver.c | 2 +- src/node_device/node_device_driver.c | 2 +- src/node_device/node_device_udev.c | 2 +- src/nodeinfo.c | 2 +- src/openvz/openvz_conf.c | 2 +- src/openvz/openvz_driver.c | 2 +- src/parallels/parallels_driver.c | 2 +- src/phyp/phyp_driver.c | 2 +- src/qemu/qemu_bridge_filter.c | 2 +- src/qemu/qemu_capabilities.c | 2 +- src/qemu/qemu_cgroup.c | 2 +- src/qemu/qemu_command.c | 2 +- src/qemu/qemu_conf.c | 2 +- src/qemu/qemu_driver.c | 2 +- src/qemu/qemu_migration.c | 2 +- src/qemu/qemu_process.c | 2 +- src/remote/remote_driver.c | 2 +- src/rpc/virkeepalive.c | 2 +- src/rpc/virnetclient.c | 2 +- src/rpc/virnetclientprogram.c | 2 +- src/rpc/virnetmessage.c | 2 +- src/rpc/virnetserver.c | 2 +- src/rpc/virnetsocket.c | 2 +- src/rpc/virnetsshsession.c | 2 +- src/rpc/virnettlscontext.c | 2 +- src/secret/secret_driver.c | 2 +- src/security/security_apparmor.c | 2 +- src/security/security_dac.c | 2 +- src/security/security_selinux.c | 4 +- src/security/virt-aa-helper.c | 2 +- src/storage/parthelper.c | 2 +- src/storage/storage_backend.c | 2 +- src/storage/storage_backend_disk.c | 2 +- src/storage/storage_backend_iscsi.c | 2 +- src/storage/storage_backend_rbd.c | 2 +- src/storage/storage_backend_sheepdog.c | 2 +- src/storage/storage_driver.c | 2 +- src/test/test_driver.c | 2 +- src/uml/uml_conf.c | 2 +- src/uml/uml_driver.c | 2 +- src/util/iohelper.c | 2 +- src/util/util.c | 3131 -------------------------------- src/util/util.h | 284 --- src/util/uuid.c | 2 +- src/util/viraudit.c | 2 +- src/util/virauth.c | 2 +- src/util/virauthconfig.c | 2 +- src/util/virbitmap.c | 2 +- src/util/vircgroup.c | 2 +- src/util/vircommand.c | 2 +- src/util/vircommand.h | 2 +- src/util/virconf.c | 2 +- src/util/virdnsmasq.c | 2 +- src/util/vireventpoll.c | 2 +- src/util/virhooks.c | 2 +- src/util/virhooks.h | 2 +- src/util/virinitctl.c | 2 +- src/util/virjson.c | 2 +- src/util/virkeycode.h | 2 +- src/util/virkeyfile.c | 2 +- src/util/virlockspace.c | 2 +- src/util/virlog.c | 2 +- src/util/virnetdevbridge.c | 2 +- src/util/virnetdevmacvlan.c | 2 +- src/util/virnetdevopenvswitch.h | 2 +- src/util/virnetdevtap.c | 2 +- src/util/virnetdevvportprofile.h | 2 +- src/util/virpidfile.c | 2 +- src/util/virprocess.c | 2 +- src/util/virrandom.c | 2 +- src/util/virsexpr.c | 2 +- src/util/virsocketaddr.c | 2 +- src/util/virstatslinux.c | 2 +- src/util/virstoragefile.h | 2 +- src/util/virsysinfo.c | 2 +- src/util/virsysinfo.h | 2 +- src/util/virterror.c | 2 +- src/util/virtime.c | 2 +- src/util/virtypedparam.c | 2 +- src/util/viruri.c | 2 +- src/util/virusb.c | 2 +- src/util/virutil.c | 3131 ++++++++++++++++++++++++++++++++ src/util/virutil.h | 284 +++ src/util/xml.c | 2 +- src/vbox/vbox_MSCOMGlue.c | 2 +- src/vbox/vbox_XPCOMCGlue.c | 2 +- src/vbox/vbox_driver.c | 2 +- src/vmware/vmware_driver.c | 2 +- src/xen/block_stats.c | 2 +- src/xen/xen_driver.c | 2 +- src/xen/xen_hypervisor.c | 2 +- src/xen/xend_internal.c | 2 +- src/xen/xm_internal.c | 2 +- src/xenapi/xenapi_driver.c | 2 +- src/xenapi/xenapi_utils.c | 2 +- tests/commandhelper.c | 2 +- tests/commandtest.c | 2 +- tests/esxutilstest.c | 2 +- tests/eventtest.c | 2 +- tests/libvirtdconftest.c | 2 +- tests/nodeinfotest.c | 2 +- tests/openvzutilstest.c | 2 +- tests/qemumonitortest.c | 2 +- tests/qemumonitortestutils.c | 2 +- tests/securityselinuxtest.c | 2 +- tests/testutils.c | 2 +- tests/utiltest.c | 2 +- tests/virauthconfigtest.c | 2 +- tests/virbuftest.c | 2 +- tests/virdrivermoduletest.c | 2 +- tests/virhashtest.c | 2 +- tests/virkeyfiletest.c | 2 +- tests/virlockspacetest.c | 2 +- tests/virnetmessagetest.c | 2 +- tests/virnetsockettest.c | 2 +- tests/virnettlscontexttest.c | 2 +- tests/virshtest.c | 2 +- tests/virstringtest.c | 2 +- tests/virtimetest.c | 2 +- tests/viruritest.c | 2 +- tools/console.c | 2 +- tools/virsh-domain.c | 2 +- tools/virsh-host.c | 2 +- tools/virsh-interface.c | 2 +- tools/virsh-network.c | 2 +- tools/virsh-nodedev.c | 2 +- tools/virsh-nwfilter.c | 2 +- tools/virsh-pool.c | 2 +- tools/virsh-secret.c | 2 +- tools/virsh-snapshot.c | 2 +- tools/virsh-volume.c | 2 +- tools/virsh.c | 2 +- tools/virt-host-validate-common.c | 2 +- 194 files changed, 3616 insertions(+), 3615 deletions(-) delete mode 100644 src/util/util.c delete mode 100644 src/util/util.h create mode 100644 src/util/virutil.c create mode 100644 src/util/virutil.h diff --git a/cfg.mk b/cfg.mk index 0a66797..a269f77 100644 --- a/cfg.mk +++ b/cfg.mk @@ -745,7 +745,7 @@ $(srcdir)/src/remote/remote_client_bodies.h: $(srcdir)/src/remote/remote_protoco # List all syntax-check exemptions: exclude_file_name_regexp--sc_avoid_strcase = ^tools/virsh\.h$$ -_src1=libvirt|fdstream|qemu/qemu_monitor|util/(vircommand|util)|xen/xend_internal|rpc/virnetsocket|lxc/lxc_controller|locking/lock_daemon +_src1=libvirt|fdstream|qemu/qemu_monitor|util/(vircommand|virutil)|xen/xend_internal|rpc/virnetsocket|lxc/lxc_controller|locking/lock_daemon exclude_file_name_regexp--sc_avoid_write = \ ^(src/($(_src1))|daemon/libvirtd|tools/console|tests/(shunload|virnettlscontext)test)\.c$$ @@ -764,13 +764,13 @@ exclude_file_name_regexp--sc_po_check = ^(docs/|src/rpc/gendispatch\.pl$$) exclude_file_name_regexp--sc_prohibit_VIR_ERR_NO_MEMORY = \ ^(include/libvirt/virterror\.h|daemon/dispatch\.c|src/util/virterror\.c)$$ -exclude_file_name_regexp--sc_prohibit_access_xok = ^src/util/util\.c$$ +exclude_file_name_regexp--sc_prohibit_access_xok = ^src/util/virutil\.c$$ exclude_file_name_regexp--sc_prohibit_always_true_header_tests = \ ^python/(libvirt-(qemu-)?override|typewrappers)\.c$$ exclude_file_name_regexp--sc_prohibit_asprintf = \ - ^(bootstrap.conf$$|src/util/util\.c$$|examples/domain-events/events-c/event-test\.c$$) + ^(bootstrap.conf$$|src/util/virutil\.c$$|examples/domain-events/events-c/event-test\.c$$) exclude_file_name_regexp--sc_prohibit_close = \ (\.p[yl]$$|^docs/|^(src/util/virfile\.c|src/libvirt\.c)$$) @@ -782,10 +782,10 @@ _src2=src/(util/vircommand|libvirt|lxc/lxc_controller|locking/lock_daemon) exclude_file_name_regexp--sc_prohibit_fork_wrappers = \ (^($(_src2)|tests/testutils|daemon/libvirtd)\.c$$) -exclude_file_name_regexp--sc_prohibit_gethostname = ^src/util/util\.c$$ +exclude_file_name_regexp--sc_prohibit_gethostname = ^src/util/virutil\.c$$ exclude_file_name_regexp--sc_prohibit_internal_functions = \ - ^src/(util/(viralloc|util|virfile)\.[hc]|esx/esx_vi\.c)$$ + ^src/(util/(viralloc|virutil|virfile)\.[hc]|esx/esx_vi\.c)$$ exclude_file_name_regexp--sc_prohibit_newline_at_end_of_diagnostic = \ ^src/rpc/gendispatch\.pl$$ @@ -797,14 +797,14 @@ exclude_file_name_regexp--sc_prohibit_raw_allocation = \ ^(src/util/viralloc\.[ch]|examples/.*)$$ exclude_file_name_regexp--sc_prohibit_readlink = \ - ^src/(util/util|lxc/lxc_container)\.c$$ + ^src/(util/virutil|lxc/lxc_container)\.c$$ -exclude_file_name_regexp--sc_prohibit_setuid = ^src/util/util\.c$$ +exclude_file_name_regexp--sc_prohibit_setuid = ^src/util/virutil\.c$$ exclude_file_name_regexp--sc_prohibit_sprintf = \ ^(docs/hacking\.html\.in)|(examples/systemtap/.*stp)|(src/dtrace2systemtap\.pl)|(src/rpc/gensystemtap\.pl)$$ -exclude_file_name_regexp--sc_prohibit_strncpy = ^src/util/util\.c$$ +exclude_file_name_regexp--sc_prohibit_strncpy = ^src/util/virutil\.c$$ exclude_file_name_regexp--sc_prohibit_strtol = \ ^src/(util/virsexpr|(vbox|xen|xenxs)/.*)\.c$$ diff --git a/daemon/libvirtd.c b/daemon/libvirtd.c index dc1d2c5..edc899e 100644 --- a/daemon/libvirtd.c +++ b/daemon/libvirtd.c @@ -43,7 +43,7 @@ #include "libvirtd.h" #include "libvirtd-config.h" -#include "util.h" +#include "virutil.h" #include "uuid.h" #include "remote_driver.h" #include "viralloc.h" diff --git a/daemon/remote.c b/daemon/remote.c index eb75281..0b5a3db 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -35,7 +35,7 @@ #include "datatypes.h" #include "viralloc.h" #include "virlog.h" -#include "util.h" +#include "virutil.h" #include "stream.h" #include "uuid.h" #include "libvirt/libvirt-qemu.h" diff --git a/po/POTFILES.in b/po/POTFILES.in index c17c63c..8a24fd4 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -138,7 +138,6 @@ src/test/test_driver.c src/uml/uml_conf.c src/uml/uml_driver.c src/util/iohelper.c -src/util/util.c src/util/viraudit.c src/util/virauth.c src/util/virauthconfig.c @@ -180,6 +179,7 @@ src/util/virtime.c src/util/virtypedparam.c src/util/viruri.c src/util/virusb.c +src/util/virutil.c src/util/xml.c src/vbox/vbox_MSCOMGlue.c src/vbox/vbox_XPCOMCGlue.c diff --git a/python/libvirt-override.c b/python/libvirt-override.c index 644f34d..91e82c6 100644 --- a/python/libvirt-override.c +++ b/python/libvirt-override.c @@ -27,7 +27,7 @@ #include "viralloc.h" #include "virtypedparam.h" #include "ignore-value.h" -#include "util.h" +#include "virutil.h" #ifndef __CYGWIN__ extern void initlibvirtmod(void); diff --git a/src/Makefile.am b/src/Makefile.am index d8d96f8..1303edd 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -54,7 +54,6 @@ augeastest_DATA = # helper APIs for various purposes UTIL_SOURCES = \ util/uuid.c util/uuid.h \ - util/util.c util/util.h \ util/viralloc.c util/viralloc.h \ util/viratomic.h util/viratomic.c \ util/viraudit.c util/viraudit.h \ @@ -114,7 +113,9 @@ UTIL_SOURCES = \ util/virstring.h util/virstring.c \ util/virtime.h util/virtime.c \ util/virusb.c util/virusb.h \ - util/viruri.h util/viruri.c + util/viruri.h util/viruri.c \ + util/virutil.c util/virutil.h \ + $(NULL) EXTRA_DIST += $(srcdir)/util/virkeymaps.h $(srcdir)/util/keymaps.csv \ $(srcdir)/util/virkeycode-mapgen.py diff --git a/src/conf/capabilities.c b/src/conf/capabilities.c index 9ac18e2..e46a594 100644 --- a/src/conf/capabilities.c +++ b/src/conf/capabilities.c @@ -28,7 +28,7 @@ #include "capabilities.h" #include "virbuffer.h" #include "viralloc.h" -#include "util.h" +#include "virutil.h" #include "uuid.h" #include "cpu_conf.h" #include "virterror_internal.h" diff --git a/src/conf/cpu_conf.c b/src/conf/cpu_conf.c index 23941c5..95c6ca1 100644 --- a/src/conf/cpu_conf.c +++ b/src/conf/cpu_conf.c @@ -25,7 +25,7 @@ #include "virterror_internal.h" #include "viralloc.h" -#include "util.h" +#include "virutil.h" #include "virbuffer.h" #include "cpu_conf.h" #include "domain_conf.h" diff --git a/src/conf/cpu_conf.h b/src/conf/cpu_conf.h index 357057d..7bec912 100644 --- a/src/conf/cpu_conf.h +++ b/src/conf/cpu_conf.h @@ -24,7 +24,7 @@ #ifndef __VIR_CPU_CONF_H__ # define __VIR_CPU_CONF_H__ -# include "util.h" +# include "virutil.h" # include "virbuffer.h" # include "xml.h" # include "virbitmap.h" diff --git a/src/conf/device_conf.c b/src/conf/device_conf.c index c3ca2d6..4efafc4 100644 --- a/src/conf/device_conf.c +++ b/src/conf/device_conf.c @@ -26,7 +26,7 @@ #include "viralloc.h" #include "xml.h" #include "uuid.h" -#include "util.h" +#include "virutil.h" #include "virbuffer.h" #include "device_conf.h" diff --git a/src/conf/device_conf.h b/src/conf/device_conf.h index c1bf096..52e4ac5 100644 --- a/src/conf/device_conf.h +++ b/src/conf/device_conf.h @@ -28,7 +28,7 @@ # include <libxml/xpath.h> # include "internal.h" -# include "util.h" +# include "virutil.h" # include "virthread.h" # include "virbuffer.h" diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index b3c3557..ab1fe2a 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -38,7 +38,7 @@ #include "verify.h" #include "xml.h" #include "uuid.h" -#include "util.h" +#include "virutil.h" #include "virbuffer.h" #include "virlog.h" #include "nwfilter_conf.h" diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 56aece2..df6e376 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -32,7 +32,7 @@ # include "capabilities.h" # include "storage_encryption_conf.h" # include "cpu_conf.h" -# include "util.h" +# include "virutil.h" # include "virthread.h" # include "virhash.h" # include "virsocketaddr.h" diff --git a/src/conf/interface_conf.c b/src/conf/interface_conf.c index 046a8a1..e4b088a 100644 --- a/src/conf/interface_conf.c +++ b/src/conf/interface_conf.c @@ -30,7 +30,7 @@ #include "viralloc.h" #include "xml.h" #include "uuid.h" -#include "util.h" +#include "virutil.h" #include "virbuffer.h" #define VIR_FROM_THIS VIR_FROM_INTERFACE diff --git a/src/conf/interface_conf.h b/src/conf/interface_conf.h index d6f98f1..e636c35 100644 --- a/src/conf/interface_conf.h +++ b/src/conf/interface_conf.h @@ -29,7 +29,7 @@ # include <libxml/xpath.h> # include "internal.h" -# include "util.h" +# include "virutil.h" # include "virthread.h" /* There is currently 3 types of interfaces */ diff --git a/src/conf/netdev_bandwidth_conf.c b/src/conf/netdev_bandwidth_conf.c index 35f067c..e64aeff 100644 --- a/src/conf/netdev_bandwidth_conf.c +++ b/src/conf/netdev_bandwidth_conf.c @@ -24,7 +24,7 @@ #include "netdev_bandwidth_conf.h" #include "virterror_internal.h" -#include "util.h" +#include "virutil.h" #include "viralloc.h" #include "domain_conf.h" diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c index 1932851..42f3593 100644 --- a/src/conf/network_conf.c +++ b/src/conf/network_conf.c @@ -40,7 +40,7 @@ #include "viralloc.h" #include "xml.h" #include "uuid.h" -#include "util.h" +#include "virutil.h" #include "virbuffer.h" #include "c-ctype.h" #include "virfile.h" diff --git a/src/conf/node_device_conf.c b/src/conf/node_device_conf.c index 045f05d..12819c8 100644 --- a/src/conf/node_device_conf.c +++ b/src/conf/node_device_conf.c @@ -33,7 +33,7 @@ #include "node_device_conf.h" #include "viralloc.h" #include "xml.h" -#include "util.h" +#include "virutil.h" #include "virbuffer.h" #include "uuid.h" #include "virpci.h" diff --git a/src/conf/node_device_conf.h b/src/conf/node_device_conf.h index 9860f67..12c36d8 100644 --- a/src/conf/node_device_conf.h +++ b/src/conf/node_device_conf.h @@ -26,7 +26,7 @@ # define __VIR_NODE_DEVICE_CONF_H__ # include "internal.h" -# include "util.h" +# include "virutil.h" # include "virthread.h" # include <libxml/tree.h> diff --git a/src/conf/nwfilter_conf.h b/src/conf/nwfilter_conf.h index d597064..2ca44b3 100644 --- a/src/conf/nwfilter_conf.h +++ b/src/conf/nwfilter_conf.h @@ -28,7 +28,7 @@ # include "internal.h" -# include "util.h" +# include "virutil.h" # include "virhash.h" # include "xml.h" # include "virbuffer.h" diff --git a/src/conf/secret_conf.c b/src/conf/secret_conf.c index 5188c7a..a65cf92 100644 --- a/src/conf/secret_conf.c +++ b/src/conf/secret_conf.c @@ -29,7 +29,7 @@ #include "viralloc.h" #include "secret_conf.h" #include "virterror_internal.h" -#include "util.h" +#include "virutil.h" #include "xml.h" #include "uuid.h" diff --git a/src/conf/secret_conf.h b/src/conf/secret_conf.h index 2064286..6079d5b 100644 --- a/src/conf/secret_conf.h +++ b/src/conf/secret_conf.h @@ -24,7 +24,7 @@ # define __VIR_SECRET_CONF_H__ # include "internal.h" -# include "util.h" +# include "virutil.h" VIR_ENUM_DECL(virSecretUsageType) diff --git a/src/conf/snapshot_conf.c b/src/conf/snapshot_conf.c index 5c40e97..810d2bf 100644 --- a/src/conf/snapshot_conf.c +++ b/src/conf/snapshot_conf.c @@ -42,7 +42,7 @@ #include "secret_conf.h" #include "snapshot_conf.h" #include "virstoragefile.h" -#include "util.h" +#include "virutil.h" #include "uuid.h" #include "virfile.h" #include "virterror_internal.h" diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c index 5cd2393..38bb471 100644 --- a/src/conf/storage_conf.c +++ b/src/conf/storage_conf.c @@ -41,7 +41,7 @@ #include "xml.h" #include "uuid.h" #include "virbuffer.h" -#include "util.h" +#include "virutil.h" #include "viralloc.h" #include "virfile.h" diff --git a/src/conf/storage_conf.h b/src/conf/storage_conf.h index 573c3db..ad16eca 100644 --- a/src/conf/storage_conf.h +++ b/src/conf/storage_conf.h @@ -25,7 +25,7 @@ # define __VIR_STORAGE_CONF_H__ # include "internal.h" -# include "util.h" +# include "virutil.h" # include "storage_encryption_conf.h" # include "virthread.h" diff --git a/src/conf/storage_encryption_conf.c b/src/conf/storage_encryption_conf.c index 8d3ceac..139c37c 100644 --- a/src/conf/storage_encryption_conf.c +++ b/src/conf/storage_encryption_conf.c @@ -31,7 +31,7 @@ #include "viralloc.h" #include "storage_conf.h" #include "storage_encryption_conf.h" -#include "util.h" +#include "virutil.h" #include "xml.h" #include "virterror_internal.h" #include "uuid.h" diff --git a/src/conf/storage_encryption_conf.h b/src/conf/storage_encryption_conf.h index 40a8497..57ab1a0 100644 --- a/src/conf/storage_encryption_conf.h +++ b/src/conf/storage_encryption_conf.h @@ -25,7 +25,7 @@ # include "internal.h" # include "virbuffer.h" -# include "util.h" +# include "virutil.h" # include <libxml/tree.h> diff --git a/src/cpu/cpu_powerpc.c b/src/cpu/cpu_powerpc.c index 6b6c325..40a2d88 100644 --- a/src/cpu/cpu_powerpc.c +++ b/src/cpu/cpu_powerpc.c @@ -28,7 +28,7 @@ #include "virlog.h" #include "viralloc.h" -#include "util.h" +#include "virutil.h" #include "cpu.h" #include "cpu_map.h" diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c index 93ee111..b932b93 100644 --- a/src/cpu/cpu_x86.c +++ b/src/cpu/cpu_x86.c @@ -27,7 +27,7 @@ #include "virlog.h" #include "viralloc.h" -#include "util.h" +#include "virutil.h" #include "cpu.h" #include "cpu_map.h" #include "cpu_x86.h" diff --git a/src/datatypes.c b/src/datatypes.c index 0907c7d..07aefcc 100644 --- a/src/datatypes.c +++ b/src/datatypes.c @@ -27,7 +27,7 @@ #include "virlog.h" #include "viralloc.h" #include "uuid.h" -#include "util.h" +#include "virutil.h" #define VIR_FROM_THIS VIR_FROM_NONE diff --git a/src/driver.c b/src/driver.c index 23dc329..0a5fe05 100644 --- a/src/driver.c +++ b/src/driver.c @@ -27,7 +27,7 @@ #include "driver.h" #include "viralloc.h" #include "virlog.h" -#include "util.h" +#include "virutil.h" #include "configmake.h" #define DEFAULT_DRIVER_DIR LIBDIR "/libvirt/connection-driver" diff --git a/src/esx/esx_device_monitor.c b/src/esx/esx_device_monitor.c index 854fc38..7cc6ac0 100644 --- a/src/esx/esx_device_monitor.c +++ b/src/esx/esx_device_monitor.c @@ -25,7 +25,7 @@ #include <config.h> #include "internal.h" -#include "util.h" +#include "virutil.h" #include "viralloc.h" #include "virlog.h" #include "uuid.h" diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c index 0fe9a67..2c0297c 100644 --- a/src/esx/esx_driver.c +++ b/src/esx/esx_driver.c @@ -28,7 +28,7 @@ #include "domain_conf.h" #include "snapshot_conf.h" #include "virauth.h" -#include "util.h" +#include "virutil.h" #include "viralloc.h" #include "virlog.h" #include "uuid.h" diff --git a/src/esx/esx_interface_driver.c b/src/esx/esx_interface_driver.c index fea67ab..524886f 100644 --- a/src/esx/esx_interface_driver.c +++ b/src/esx/esx_interface_driver.c @@ -25,7 +25,7 @@ #include <config.h> #include "internal.h" -#include "util.h" +#include "virutil.h" #include "viralloc.h" #include "virlog.h" #include "uuid.h" diff --git a/src/esx/esx_network_driver.c b/src/esx/esx_network_driver.c index fec7e72..0fc2603 100644 --- a/src/esx/esx_network_driver.c +++ b/src/esx/esx_network_driver.c @@ -26,7 +26,7 @@ #include "md5.h" #include "internal.h" -#include "util.h" +#include "virutil.h" #include "viralloc.h" #include "virlog.h" #include "uuid.h" diff --git a/src/esx/esx_nwfilter_driver.c b/src/esx/esx_nwfilter_driver.c index 7a05a5a..ecee0fb 100644 --- a/src/esx/esx_nwfilter_driver.c +++ b/src/esx/esx_nwfilter_driver.c @@ -25,7 +25,7 @@ #include <config.h> #include "internal.h" -#include "util.h" +#include "virutil.h" #include "viralloc.h" #include "virlog.h" #include "uuid.h" diff --git a/src/esx/esx_secret_driver.c b/src/esx/esx_secret_driver.c index 2969b19..722d3f7 100644 --- a/src/esx/esx_secret_driver.c +++ b/src/esx/esx_secret_driver.c @@ -24,7 +24,7 @@ #include <config.h> #include "internal.h" -#include "util.h" +#include "virutil.h" #include "viralloc.h" #include "virlog.h" #include "uuid.h" diff --git a/src/esx/esx_storage_backend_iscsi.c b/src/esx/esx_storage_backend_iscsi.c index 5ad885a..3c3ab7d 100644 --- a/src/esx/esx_storage_backend_iscsi.c +++ b/src/esx/esx_storage_backend_iscsi.c @@ -28,7 +28,7 @@ #include "internal.h" #include "md5.h" -#include "util.h" +#include "virutil.h" #include "viralloc.h" #include "virlog.h" #include "uuid.h" diff --git a/src/esx/esx_storage_backend_vmfs.c b/src/esx/esx_storage_backend_vmfs.c index 4886fc3..c57e070 100644 --- a/src/esx/esx_storage_backend_vmfs.c +++ b/src/esx/esx_storage_backend_vmfs.c @@ -31,7 +31,7 @@ #include "internal.h" #include "md5.h" -#include "util.h" +#include "virutil.h" #include "viralloc.h" #include "virlog.h" #include "uuid.h" diff --git a/src/esx/esx_util.c b/src/esx/esx_util.c index bcda9df..9b2e576 100644 --- a/src/esx/esx_util.c +++ b/src/esx/esx_util.c @@ -28,7 +28,7 @@ #include "internal.h" #include "datatypes.h" -#include "util.h" +#include "virutil.h" #include "viralloc.h" #include "virlog.h" #include "uuid.h" diff --git a/src/esx/esx_vi.c b/src/esx/esx_vi.c index 37b6e0f..2cc8002 100644 --- a/src/esx/esx_vi.c +++ b/src/esx/esx_vi.c @@ -29,7 +29,7 @@ #include "virbuffer.h" #include "viralloc.h" #include "virlog.h" -#include "util.h" +#include "virutil.h" #include "uuid.h" #include "vmx.h" #include "xml.h" diff --git a/src/esx/esx_vi_types.c b/src/esx/esx_vi_types.c index b93223d..d1f91ff 100644 --- a/src/esx/esx_vi_types.c +++ b/src/esx/esx_vi_types.c @@ -31,7 +31,7 @@ #include "datatypes.h" #include "viralloc.h" #include "virlog.h" -#include "util.h" +#include "virutil.h" #include "esx_vi.h" #include "esx_vi_types.h" diff --git a/src/fdstream.c b/src/fdstream.c index 39e92b8..f7f101e 100644 --- a/src/fdstream.c +++ b/src/fdstream.c @@ -37,7 +37,7 @@ #include "datatypes.h" #include "virlog.h" #include "viralloc.h" -#include "util.h" +#include "virutil.h" #include "virfile.h" #include "configmake.h" diff --git a/src/hyperv/hyperv_device_monitor.c b/src/hyperv/hyperv_device_monitor.c index d6edb76..10d559f 100644 --- a/src/hyperv/hyperv_device_monitor.c +++ b/src/hyperv/hyperv_device_monitor.c @@ -26,7 +26,7 @@ #include "internal.h" #include "virterror_internal.h" #include "datatypes.h" -#include "util.h" +#include "virutil.h" #include "viralloc.h" #include "virlog.h" #include "uuid.h" diff --git a/src/hyperv/hyperv_driver.c b/src/hyperv/hyperv_driver.c index 749c7f0..d777bd8 100644 --- a/src/hyperv/hyperv_driver.c +++ b/src/hyperv/hyperv_driver.c @@ -27,7 +27,7 @@ #include "datatypes.h" #include "domain_conf.h" #include "virauth.h" -#include "util.h" +#include "virutil.h" #include "viralloc.h" #include "virlog.h" #include "uuid.h" diff --git a/src/hyperv/hyperv_interface_driver.c b/src/hyperv/hyperv_interface_driver.c index 43c7dd7..af37de3 100644 --- a/src/hyperv/hyperv_interface_driver.c +++ b/src/hyperv/hyperv_interface_driver.c @@ -26,7 +26,7 @@ #include "internal.h" #include "virterror_internal.h" #include "datatypes.h" -#include "util.h" +#include "virutil.h" #include "viralloc.h" #include "virlog.h" #include "uuid.h" diff --git a/src/hyperv/hyperv_network_driver.c b/src/hyperv/hyperv_network_driver.c index 06b051b..cafc956 100644 --- a/src/hyperv/hyperv_network_driver.c +++ b/src/hyperv/hyperv_network_driver.c @@ -26,7 +26,7 @@ #include "internal.h" #include "virterror_internal.h" #include "datatypes.h" -#include "util.h" +#include "virutil.h" #include "viralloc.h" #include "virlog.h" #include "uuid.h" diff --git a/src/hyperv/hyperv_nwfilter_driver.c b/src/hyperv/hyperv_nwfilter_driver.c index 7452b7a..46c57b7 100644 --- a/src/hyperv/hyperv_nwfilter_driver.c +++ b/src/hyperv/hyperv_nwfilter_driver.c @@ -26,7 +26,7 @@ #include "internal.h" #include "virterror_internal.h" #include "datatypes.h" -#include "util.h" +#include "virutil.h" #include "viralloc.h" #include "virlog.h" #include "uuid.h" diff --git a/src/hyperv/hyperv_secret_driver.c b/src/hyperv/hyperv_secret_driver.c index 04a6ada..ea8fa7e 100644 --- a/src/hyperv/hyperv_secret_driver.c +++ b/src/hyperv/hyperv_secret_driver.c @@ -26,7 +26,7 @@ #include "internal.h" #include "virterror_internal.h" #include "datatypes.h" -#include "util.h" +#include "virutil.h" #include "viralloc.h" #include "virlog.h" #include "uuid.h" diff --git a/src/hyperv/hyperv_storage_driver.c b/src/hyperv/hyperv_storage_driver.c index b2817a2..7549801 100644 --- a/src/hyperv/hyperv_storage_driver.c +++ b/src/hyperv/hyperv_storage_driver.c @@ -26,7 +26,7 @@ #include "internal.h" #include "virterror_internal.h" #include "datatypes.h" -#include "util.h" +#include "virutil.h" #include "viralloc.h" #include "virlog.h" #include "uuid.h" diff --git a/src/hyperv/hyperv_util.c b/src/hyperv/hyperv_util.c index 016d415..69a57c6 100644 --- a/src/hyperv/hyperv_util.c +++ b/src/hyperv/hyperv_util.c @@ -24,7 +24,7 @@ #include "internal.h" #include "datatypes.h" -#include "util.h" +#include "virutil.h" #include "viralloc.h" #include "virlog.h" #include "uuid.h" diff --git a/src/hyperv/hyperv_wmi.c b/src/hyperv/hyperv_wmi.c index 69e7283..f4afdce 100644 --- a/src/hyperv/hyperv_wmi.c +++ b/src/hyperv/hyperv_wmi.c @@ -29,7 +29,7 @@ #include "datatypes.h" #include "virlog.h" #include "viralloc.h" -#include "util.h" +#include "virutil.h" #include "uuid.h" #include "virbuffer.h" #include "hyperv_private.h" diff --git a/src/locking/lock_daemon.c b/src/locking/lock_daemon.c index 3d90c57..df9923e 100644 --- a/src/locking/lock_daemon.c +++ b/src/locking/lock_daemon.c @@ -33,7 +33,7 @@ #include "lock_daemon.h" #include "lock_daemon_config.h" -#include "util.h" +#include "virutil.h" #include "virfile.h" #include "virpidfile.h" #include "virprocess.h" diff --git a/src/locking/lock_daemon_dispatch.c b/src/locking/lock_daemon_dispatch.c index 78c9726..def7c2f 100644 --- a/src/locking/lock_daemon_dispatch.c +++ b/src/locking/lock_daemon_dispatch.c @@ -24,7 +24,7 @@ #include "rpc/virnetserver.h" #include "rpc/virnetserverclient.h" -#include "util.h" +#include "virutil.h" #include "virlog.h" #include "lock_daemon.h" diff --git a/src/locking/lock_driver_lockd.c b/src/locking/lock_driver_lockd.c index cee530d..547db85 100644 --- a/src/locking/lock_driver_lockd.c +++ b/src/locking/lock_driver_lockd.c @@ -26,7 +26,7 @@ #include "viralloc.h" #include "virlog.h" #include "uuid.h" -#include "util.h" +#include "virutil.h" #include "virfile.h" #include "virterror_internal.h" #include "rpc/virnetclient.h" diff --git a/src/locking/lock_driver_sanlock.c b/src/locking/lock_driver_sanlock.c index e520444..511543a 100644 --- a/src/locking/lock_driver_sanlock.c +++ b/src/locking/lock_driver_sanlock.c @@ -40,7 +40,7 @@ #include "virlog.h" #include "virterror_internal.h" #include "viralloc.h" -#include "util.h" +#include "virutil.h" #include "virfile.h" #include "md5.h" #include "virconf.h" diff --git a/src/locking/lock_manager.c b/src/locking/lock_manager.c index f938b04..d73e184 100644 --- a/src/locking/lock_manager.c +++ b/src/locking/lock_manager.c @@ -25,7 +25,7 @@ #include "lock_driver_nop.h" #include "virterror_internal.h" #include "virlog.h" -#include "util.h" +#include "virutil.h" #include "viralloc.h" #include "uuid.h" diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c index f3c6e19..050a4c1 100644 --- a/src/lxc/lxc_container.c +++ b/src/lxc/lxc_container.c @@ -56,7 +56,7 @@ #include "virterror_internal.h" #include "virlog.h" #include "lxc_container.h" -#include "util.h" +#include "virutil.h" #include "viralloc.h" #include "virnetdevveth.h" #include "uuid.h" diff --git a/src/lxc/lxc_controller.c b/src/lxc/lxc_controller.c index 6b6ec82..a8e99f2 100644 --- a/src/lxc/lxc_controller.c +++ b/src/lxc/lxc_controller.c @@ -54,7 +54,7 @@ #include "virterror_internal.h" #include "virlog.h" -#include "util.h" +#include "virutil.h" #include "lxc_conf.h" #include "lxc_container.h" @@ -64,7 +64,7 @@ #include "virnetdev.h" #include "virnetdevveth.h" #include "viralloc.h" -#include "util.h" +#include "virutil.h" #include "virfile.h" #include "virpidfile.h" #include "vircommand.h" diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index 57c1767..e513b76 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -44,7 +44,7 @@ #include "lxc_driver.h" #include "lxc_process.h" #include "viralloc.h" -#include "util.h" +#include "virutil.h" #include "virnetdevbridge.h" #include "virnetdevveth.h" #include "nodeinfo.h" diff --git a/src/lxc/lxc_fuse.h b/src/lxc/lxc_fuse.h index 9878017..93964a4 100644 --- a/src/lxc/lxc_fuse.h +++ b/src/lxc/lxc_fuse.h @@ -32,7 +32,7 @@ # endif # include "lxc_conf.h" -# include "util.h" +# include "virutil.h" # include "viralloc.h" struct virLXCMeminfo { diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c index 2db9197..dbbd49c 100644 --- a/src/network/bridge_driver.c +++ b/src/network/bridge_driver.c @@ -52,7 +52,7 @@ #include "driver.h" #include "virbuffer.h" #include "virpidfile.h" -#include "util.h" +#include "virutil.h" #include "vircommand.h" #include "viralloc.h" #include "uuid.h" diff --git a/src/node_device/node_device_driver.c b/src/node_device/node_device_driver.c index d914816..6cc1837 100644 --- a/src/node_device/node_device_driver.c +++ b/src/node_device/node_device_driver.c @@ -37,7 +37,7 @@ #include "node_device_conf.h" #include "node_device_hal.h" #include "node_device_driver.h" -#include "util.h" +#include "virutil.h" #define VIR_FROM_THIS VIR_FROM_NODEDEV diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c index 7289a72..d350955 100644 --- a/src/node_device/node_device_udev.c +++ b/src/node_device/node_device_udev.c @@ -35,7 +35,7 @@ #include "virlog.h" #include "viralloc.h" #include "uuid.h" -#include "util.h" +#include "virutil.h" #include "virbuffer.h" #include "virpci.h" diff --git a/src/nodeinfo.c b/src/nodeinfo.c index b14e63b..65f4431 100644 --- a/src/nodeinfo.c +++ b/src/nodeinfo.c @@ -42,7 +42,7 @@ #include "viralloc.h" #include "nodeinfo.h" #include "physmem.h" -#include "util.h" +#include "virutil.h" #include "virlog.h" #include "virterror_internal.h" #include "count-one-bits.h" diff --git a/src/openvz/openvz_conf.c b/src/openvz/openvz_conf.c index 6e0f6eb..b0c9c5f 100644 --- a/src/openvz/openvz_conf.c +++ b/src/openvz/openvz_conf.c @@ -49,7 +49,7 @@ #include "uuid.h" #include "virbuffer.h" #include "viralloc.h" -#include "util.h" +#include "virutil.h" #include "nodeinfo.h" #include "virfile.h" #include "vircommand.h" diff --git a/src/openvz/openvz_driver.c b/src/openvz/openvz_driver.c index a35a6b1..a407193 100644 --- a/src/openvz/openvz_driver.c +++ b/src/openvz/openvz_driver.c @@ -50,7 +50,7 @@ #include "openvz_driver.h" #include "openvz_util.h" #include "virbuffer.h" -#include "util.h" +#include "virutil.h" #include "openvz_conf.h" #include "nodeinfo.h" #include "viralloc.h" diff --git a/src/parallels/parallels_driver.c b/src/parallels/parallels_driver.c index 07c1463..87d098e 100644 --- a/src/parallels/parallels_driver.c +++ b/src/parallels/parallels_driver.c @@ -44,7 +44,7 @@ #include "datatypes.h" #include "virterror_internal.h" #include "viralloc.h" -#include "util.h" +#include "virutil.h" #include "virlog.h" #include "vircommand.h" #include "configmake.h" diff --git a/src/phyp/phyp_driver.c b/src/phyp/phyp_driver.c index ad56686..25b96b4 100644 --- a/src/phyp/phyp_driver.c +++ b/src/phyp/phyp_driver.c @@ -45,7 +45,7 @@ #include "internal.h" #include "virauth.h" -#include "util.h" +#include "virutil.h" #include "datatypes.h" #include "virbuffer.h" #include "viralloc.h" diff --git a/src/qemu/qemu_bridge_filter.c b/src/qemu/qemu_bridge_filter.c index 08a9f1a..6d84f47 100644 --- a/src/qemu/qemu_bridge_filter.c +++ b/src/qemu/qemu_bridge_filter.c @@ -25,7 +25,7 @@ #include "virebtables.h" #include "qemu_conf.h" #include "qemu_driver.h" -#include "util.h" +#include "virutil.h" #include "virterror_internal.h" #include "virlog.h" diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 46f8540..7a27183 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -27,7 +27,7 @@ #include "viralloc.h" #include "virlog.h" #include "virterror_internal.h" -#include "util.h" +#include "virutil.h" #include "virfile.h" #include "virpidfile.h" #include "virprocess.h" diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c index b47fb78..9db7ad9 100644 --- a/src/qemu/qemu_cgroup.c +++ b/src/qemu/qemu_cgroup.c @@ -30,7 +30,7 @@ #include "virlog.h" #include "viralloc.h" #include "virterror_internal.h" -#include "util.h" +#include "virutil.h" #include "domain_audit.h" #define VIR_FROM_THIS VIR_FROM_QEMU diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 464288f..23ccffe 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -31,7 +31,7 @@ #include "viralloc.h" #include "virlog.h" #include "virterror_internal.h" -#include "util.h" +#include "virutil.h" #include "virfile.h" #include "uuid.h" #include "c-ctype.h" diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index d6bc1fc..be88d77 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -43,7 +43,7 @@ #include "uuid.h" #include "virbuffer.h" #include "virconf.h" -#include "util.h" +#include "virutil.h" #include "viralloc.h" #include "datatypes.h" #include "xml.h" diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 170f15d..15b773b 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -63,7 +63,7 @@ #include "virlog.h" #include "datatypes.h" #include "virbuffer.h" -#include "util.h" +#include "virutil.h" #include "nodeinfo.h" #include "virstatslinux.h" #include "capabilities.h" diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index a77beb6..1e83e3c 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -39,7 +39,7 @@ #include "virlog.h" #include "virterror_internal.h" #include "viralloc.h" -#include "util.h" +#include "virutil.h" #include "virfile.h" #include "datatypes.h" #include "fdstream.h" diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 794596b..d4eaa9e 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -57,7 +57,7 @@ #include "virhooks.h" #include "virfile.h" #include "virpidfile.h" -#include "util.h" +#include "virutil.h" #include "c-ctype.h" #include "nodeinfo.h" #include "domain_audit.h" diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index 2edf6e6..ac7dc87 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -39,7 +39,7 @@ #include "remote_protocol.h" #include "qemu_protocol.h" #include "viralloc.h" -#include "util.h" +#include "virutil.h" #include "virfile.h" #include "vircommand.h" #include "intprops.h" diff --git a/src/rpc/virkeepalive.c b/src/rpc/virkeepalive.c index 5c14e14..18be350 100644 --- a/src/rpc/virkeepalive.c +++ b/src/rpc/virkeepalive.c @@ -26,7 +26,7 @@ #include "virthread.h" #include "virfile.h" #include "virlog.h" -#include "util.h" +#include "virutil.h" #include "virterror_internal.h" #include "virnetsocket.h" #include "virkeepaliveprotocol.h" diff --git a/src/rpc/virnetclient.c b/src/rpc/virnetclient.c index 85787f0..9347f0b 100644 --- a/src/rpc/virnetclient.c +++ b/src/rpc/virnetclient.c @@ -34,7 +34,7 @@ #include "virthread.h" #include "virfile.h" #include "virlog.h" -#include "util.h" +#include "virutil.h" #include "virterror_internal.h" #define VIR_FROM_THIS VIR_FROM_RPC diff --git a/src/rpc/virnetclientprogram.c b/src/rpc/virnetclientprogram.c index 00948e0..eff4a4c 100644 --- a/src/rpc/virnetclientprogram.c +++ b/src/rpc/virnetclientprogram.c @@ -31,7 +31,7 @@ #include "viralloc.h" #include "virterror_internal.h" #include "virlog.h" -#include "util.h" +#include "virutil.h" #include "virfile.h" #include "virthread.h" diff --git a/src/rpc/virnetmessage.c b/src/rpc/virnetmessage.c index f273811..b2da65b 100644 --- a/src/rpc/virnetmessage.c +++ b/src/rpc/virnetmessage.c @@ -28,7 +28,7 @@ #include "virterror_internal.h" #include "virlog.h" #include "virfile.h" -#include "util.h" +#include "virutil.h" #define VIR_FROM_THIS VIR_FROM_RPC diff --git a/src/rpc/virnetserver.c b/src/rpc/virnetserver.c index b48af5e..47a6293 100644 --- a/src/rpc/virnetserver.c +++ b/src/rpc/virnetserver.c @@ -33,7 +33,7 @@ #include "virterror_internal.h" #include "virthread.h" #include "virthreadpool.h" -#include "util.h" +#include "virutil.h" #include "virfile.h" #include "virnetservermdns.h" #include "virdbus.h" diff --git a/src/rpc/virnetsocket.c b/src/rpc/virnetsocket.c index 442850a..a959c30 100644 --- a/src/rpc/virnetsocket.c +++ b/src/rpc/virnetsocket.c @@ -41,7 +41,7 @@ #include "c-ctype.h" #include "virnetsocket.h" -#include "util.h" +#include "virutil.h" #include "viralloc.h" #include "virterror_internal.h" #include "virlog.h" diff --git a/src/rpc/virnetsshsession.c b/src/rpc/virnetsshsession.c index 663b7cd..ad8bd48 100644 --- a/src/rpc/virnetsshsession.c +++ b/src/rpc/virnetsshsession.c @@ -31,7 +31,7 @@ #include "virlog.h" #include "configmake.h" #include "virthread.h" -#include "util.h" +#include "virutil.h" #include "virterror_internal.h" #include "virobject.h" diff --git a/src/rpc/virnettlscontext.c b/src/rpc/virnettlscontext.c index 1ff40cf..b01de8c 100644 --- a/src/rpc/virnettlscontext.c +++ b/src/rpc/virnettlscontext.c @@ -32,7 +32,7 @@ #include "viralloc.h" #include "virterror_internal.h" -#include "util.h" +#include "virutil.h" #include "virlog.h" #include "virthread.h" #include "configmake.h" diff --git a/src/secret/secret_driver.c b/src/secret/secret_driver.c index 672ff54..8dfd921 100644 --- a/src/secret/secret_driver.c +++ b/src/secret/secret_driver.c @@ -37,7 +37,7 @@ #include "secret_conf.h" #include "secret_driver.h" #include "virthread.h" -#include "util.h" +#include "virutil.h" #include "uuid.h" #include "virterror_internal.h" #include "virfile.h" diff --git a/src/security/security_apparmor.c b/src/security/security_apparmor.c index d28189f..4027cdf 100644 --- a/src/security/security_apparmor.c +++ b/src/security/security_apparmor.c @@ -38,7 +38,7 @@ #include "internal.h" #include "security_apparmor.h" -#include "util.h" +#include "virutil.h" #include "viralloc.h" #include "virterror_internal.h" #include "datatypes.h" diff --git a/src/security/security_dac.c b/src/security/security_dac.c index f9752ef..3104f42 100644 --- a/src/security/security_dac.c +++ b/src/security/security_dac.c @@ -25,7 +25,7 @@ #include "security_dac.h" #include "virterror_internal.h" -#include "util.h" +#include "virutil.h" #include "viralloc.h" #include "virlog.h" #include "virpci.h" diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c index 8918257..ccba258 100644 --- a/src/security/security_selinux.c +++ b/src/security/security_selinux.c @@ -34,7 +34,7 @@ #include "security_driver.h" #include "security_selinux.h" #include "virterror_internal.h" -#include "util.h" +#include "virutil.h" #include "viralloc.h" #include "virlog.h" #include "virpci.h" @@ -43,7 +43,7 @@ #include "virfile.h" #include "virhash.h" #include "virrandom.h" -#include "util.h" +#include "virutil.h" #include "virconf.h" #define VIR_FROM_THIS VIR_FROM_SECURITY diff --git a/src/security/virt-aa-helper.c b/src/security/virt-aa-helper.c index 4945f7c..5cfa3ff 100644 --- a/src/security/virt-aa-helper.c +++ b/src/security/virt-aa-helper.c @@ -41,7 +41,7 @@ #include "internal.h" #include "virbuffer.h" -#include "util.h" +#include "virutil.h" #include "viralloc.h" #include "vircommand.h" diff --git a/src/storage/parthelper.c b/src/storage/parthelper.c index 5417ced..83f8279 100644 --- a/src/storage/parthelper.c +++ b/src/storage/parthelper.c @@ -41,7 +41,7 @@ #include <unistd.h> #include <locale.h> -#include "util.h" +#include "virutil.h" #include "c-ctype.h" #include "configmake.h" diff --git a/src/storage/storage_backend.c b/src/storage/storage_backend.c index 9b98dbb..29272f1 100644 --- a/src/storage/storage_backend.c +++ b/src/storage/storage_backend.c @@ -47,7 +47,7 @@ #include "datatypes.h" #include "virterror_internal.h" -#include "util.h" +#include "virutil.h" #include "viralloc.h" #include "internal.h" #include "secret_conf.h" diff --git a/src/storage/storage_backend_disk.c b/src/storage/storage_backend_disk.c index 8759b3a..aceb82b 100644 --- a/src/storage/storage_backend_disk.c +++ b/src/storage/storage_backend_disk.c @@ -29,7 +29,7 @@ #include "virterror_internal.h" #include "virlog.h" #include "storage_backend_disk.h" -#include "util.h" +#include "virutil.h" #include "viralloc.h" #include "vircommand.h" #include "configmake.h" diff --git a/src/storage/storage_backend_iscsi.c b/src/storage/storage_backend_iscsi.c index ecb8f8e..e91c4b1 100644 --- a/src/storage/storage_backend_iscsi.c +++ b/src/storage/storage_backend_iscsi.c @@ -37,7 +37,7 @@ #include "virterror_internal.h" #include "storage_backend_scsi.h" #include "storage_backend_iscsi.h" -#include "util.h" +#include "virutil.h" #include "viralloc.h" #include "virlog.h" #include "virfile.h" diff --git a/src/storage/storage_backend_rbd.c b/src/storage/storage_backend_rbd.c index e1f07ab..ffa3234 100644 --- a/src/storage/storage_backend_rbd.c +++ b/src/storage/storage_backend_rbd.c @@ -25,7 +25,7 @@ #include "virterror_internal.h" #include "storage_backend_rbd.h" #include "storage_conf.h" -#include "util.h" +#include "virutil.h" #include "viralloc.h" #include "virlog.h" #include "base64.h" diff --git a/src/storage/storage_backend_sheepdog.c b/src/storage/storage_backend_sheepdog.c index d3b9d87..1046ac9 100644 --- a/src/storage/storage_backend_sheepdog.c +++ b/src/storage/storage_backend_sheepdog.c @@ -30,7 +30,7 @@ #include "storage_backend_sheepdog.h" #include "storage_conf.h" #include "vircommand.h" -#include "util.h" +#include "virutil.h" #include "viralloc.h" #include "virlog.h" diff --git a/src/storage/storage_driver.c b/src/storage/storage_driver.c index aebf8bb..d93617c 100644 --- a/src/storage/storage_driver.c +++ b/src/storage/storage_driver.c @@ -39,7 +39,7 @@ #include "virterror_internal.h" #include "datatypes.h" #include "driver.h" -#include "util.h" +#include "virutil.h" #include "storage_driver.h" #include "storage_conf.h" #include "viralloc.h" diff --git a/src/test/test_driver.c b/src/test/test_driver.c index 185bb3b..da76367 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -36,7 +36,7 @@ #include "datatypes.h" #include "test_driver.h" #include "virbuffer.h" -#include "util.h" +#include "virutil.h" #include "uuid.h" #include "capabilities.h" #include "viralloc.h" diff --git a/src/uml/uml_conf.c b/src/uml/uml_conf.c index 6da311b..b2057e8 100644 --- a/src/uml/uml_conf.c +++ b/src/uml/uml_conf.c @@ -39,7 +39,7 @@ #include "uuid.h" #include "virbuffer.h" #include "virconf.h" -#include "util.h" +#include "virutil.h" #include "viralloc.h" #include "nodeinfo.h" #include "virlog.h" diff --git a/src/uml/uml_driver.c b/src/uml/uml_driver.c index b20998f..05fb7f2 100644 --- a/src/uml/uml_driver.c +++ b/src/uml/uml_driver.c @@ -47,7 +47,7 @@ #include "uml_driver.h" #include "uml_conf.h" #include "virbuffer.h" -#include "util.h" +#include "virutil.h" #include "nodeinfo.h" #include "virstatslinux.h" #include "capabilities.h" diff --git a/src/util/iohelper.c b/src/util/iohelper.c index dcb5c14..40b04f9 100644 --- a/src/util/iohelper.c +++ b/src/util/iohelper.c @@ -33,7 +33,7 @@ #include <stdio.h> #include <stdlib.h> -#include "util.h" +#include "virutil.h" #include "virthread.h" #include "virfile.h" #include "viralloc.h" diff --git a/src/util/util.c b/src/util/util.c deleted file mode 100644 index c7d4aa5..0000000 --- a/src/util/util.c +++ /dev/null @@ -1,3131 +0,0 @@ -/* - * utils.c: common, generic utility functions - * - * Copyright (C) 2006-2012 Red Hat, Inc. - * Copyright (C) 2006 Daniel P. Berrange - * Copyright (C) 2006, 2007 Binary Karma - * Copyright (C) 2006 Shuveb Hussain - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see - * <http://www.gnu.org/licenses/>. - * - * Author: Daniel P. Berrange <berrange@xxxxxxxxxx> - * File created Jul 18, 2007 - Shuveb Hussain <shuveb@xxxxxxxxxxxxxxx> - */ - -#include <config.h> - -#include <stdio.h> -#include <stdarg.h> -#include <stdlib.h> -#include <unistd.h> -#include <fcntl.h> -#include <errno.h> -#include <poll.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <sys/ioctl.h> -#include <sys/wait.h> -#if HAVE_MMAP -# include <sys/mman.h> -#endif -#include <string.h> -#include <signal.h> -#include <termios.h> -#include <pty.h> -#include <locale.h> - -#if HAVE_LIBDEVMAPPER_H -# include <libdevmapper.h> -#endif - -#ifdef HAVE_PATHS_H -# include <paths.h> -#endif -#include <netdb.h> -#ifdef HAVE_GETPWUID_R -# include <pwd.h> -# include <grp.h> -#endif -#if HAVE_CAPNG -# include <cap-ng.h> -#endif -#if defined HAVE_MNTENT_H && defined HAVE_GETMNTENT_R -# include <mntent.h> -#endif - -#ifdef WIN32 -# ifdef HAVE_WINSOCK2_H -# include <winsock2.h> -# endif -# include <windows.h> -# include <shlobj.h> -#endif - -#include "c-ctype.h" -#include "dirname.h" -#include "virterror_internal.h" -#include "virlog.h" -#include "virbuffer.h" -#include "util.h" -#include "virstoragefile.h" -#include "viralloc.h" -#include "virthread.h" -#include "verify.h" -#include "virfile.h" -#include "vircommand.h" -#include "nonblocking.h" -#include "passfd.h" -#include "virprocess.h" - -#ifndef NSIG -# define NSIG 32 -#endif - -verify(sizeof(gid_t) <= sizeof(unsigned int) && - sizeof(uid_t) <= sizeof(unsigned int)); - -#define VIR_FROM_THIS VIR_FROM_NONE - -/* Like read(), but restarts after EINTR */ -ssize_t -saferead(int fd, void *buf, size_t count) -{ - size_t nread = 0; - while (count > 0) { - ssize_t r = read(fd, buf, count); - if (r < 0 && errno == EINTR) - continue; - if (r < 0) - return r; - if (r == 0) - return nread; - buf = (char *)buf + r; - count -= r; - nread += r; - } - return nread; -} - -/* Like write(), but restarts after EINTR */ -ssize_t -safewrite(int fd, const void *buf, size_t count) -{ - size_t nwritten = 0; - while (count > 0) { - ssize_t r = write(fd, buf, count); - - if (r < 0 && errno == EINTR) - continue; - if (r < 0) - return r; - if (r == 0) - return nwritten; - buf = (const char *)buf + r; - count -= r; - nwritten += r; - } - return nwritten; -} - -#ifdef HAVE_POSIX_FALLOCATE -int safezero(int fd, off_t offset, off_t len) -{ - int ret = posix_fallocate(fd, offset, len); - if (ret == 0) - return 0; - errno = ret; - return -1; -} -#else - -# ifdef HAVE_MMAP -int safezero(int fd, off_t offset, off_t len) -{ - int r; - char *buf; - - /* memset wants the mmap'ed file to be present on disk so create a - * sparse file - */ - r = ftruncate(fd, offset + len); - if (r < 0) - return -1; - - buf = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, offset); - if (buf == MAP_FAILED) - return -1; - - memset(buf, 0, len); - munmap(buf, len); - - return 0; -} - -# else /* HAVE_MMAP */ - -int safezero(int fd, off_t offset, off_t len) -{ - int r; - char *buf; - unsigned long long remain, bytes; - - if (lseek(fd, offset, SEEK_SET) < 0) - return -1; - - /* Split up the write in small chunks so as not to allocate lots of RAM */ - remain = len; - bytes = 1024 * 1024; - - r = VIR_ALLOC_N(buf, bytes); - if (r < 0) { - errno = ENOMEM; - return -1; - } - - while (remain) { - if (bytes > remain) - bytes = remain; - - r = safewrite(fd, buf, bytes); - if (r < 0) { - VIR_FREE(buf); - return -1; - } - - /* safewrite() guarantees all data will be written */ - remain -= bytes; - } - VIR_FREE(buf); - return 0; -} -# endif /* HAVE_MMAP */ -#endif /* HAVE_POSIX_FALLOCATE */ - -int virFileStripSuffix(char *str, - const char *suffix) -{ - int len = strlen(str); - int suffixlen = strlen(suffix); - - if (len < suffixlen) - return 0; - - if (!STREQ(str + len - suffixlen, suffix)) - return 0; - - str[len-suffixlen] = '\0'; - - return 1; -} - -char * -virArgvToString(const char *const *argv) -{ - int len, i; - char *ret, *p; - - for (len = 1, i = 0; argv[i]; i++) - len += strlen(argv[i]) + 1; - - if (VIR_ALLOC_N(ret, len) < 0) - return NULL; - p = ret; - - for (i = 0; argv[i]; i++) { - if (i != 0) - *(p++) = ' '; - - strcpy(p, argv[i]); - p += strlen(argv[i]); - } - - *p = '\0'; - - return ret; -} - -#ifndef WIN32 - -int virSetInherit(int fd, bool inherit) { - int fflags; - if ((fflags = fcntl(fd, F_GETFD)) < 0) - return -1; - if (inherit) - fflags &= ~FD_CLOEXEC; - else - fflags |= FD_CLOEXEC; - if ((fcntl(fd, F_SETFD, fflags)) < 0) - return -1; - return 0; -} - -#else /* WIN32 */ - -int virSetInherit(int fd ATTRIBUTE_UNUSED, bool inherit ATTRIBUTE_UNUSED) -{ - /* FIXME: Currently creating child processes is not supported on - * Win32, so there is no point in failing calls that are only relevant - * when creating child processes. So just pretend that we changed the - * inheritance property of the given fd as requested. */ - return 0; -} - -#endif /* WIN32 */ - -int virSetBlocking(int fd, bool blocking) { - return set_nonblocking_flag(fd, !blocking); -} - -int virSetNonBlock(int fd) { - return virSetBlocking(fd, false); -} - -int virSetCloseExec(int fd) -{ - return virSetInherit(fd, false); -} - -int -virPipeReadUntilEOF(int outfd, int errfd, - char **outbuf, char **errbuf) { - - struct pollfd fds[2]; - int i; - int finished[2]; - - fds[0].fd = outfd; - fds[0].events = POLLIN; - fds[0].revents = 0; - finished[0] = 0; - fds[1].fd = errfd; - fds[1].events = POLLIN; - fds[1].revents = 0; - finished[1] = 0; - - while (!(finished[0] && finished[1])) { - - if (poll(fds, ARRAY_CARDINALITY(fds), -1) < 0) { - if ((errno == EAGAIN) || (errno == EINTR)) - continue; - goto pollerr; - } - - for (i = 0; i < ARRAY_CARDINALITY(fds); ++i) { - char data[1024], **buf; - int got, size; - - if (!(fds[i].revents)) - continue; - else if (fds[i].revents & POLLHUP) - finished[i] = 1; - - if (!(fds[i].revents & POLLIN)) { - if (fds[i].revents & POLLHUP) - continue; - - virReportError(VIR_ERR_INTERNAL_ERROR, - "%s", _("Unknown poll response.")); - goto error; - } - - got = read(fds[i].fd, data, sizeof(data)); - - if (got == sizeof(data)) - finished[i] = 0; - - if (got == 0) { - finished[i] = 1; - continue; - } - if (got < 0) { - if (errno == EINTR) - continue; - if (errno == EAGAIN) - break; - goto pollerr; - } - - buf = ((fds[i].fd == outfd) ? outbuf : errbuf); - size = (*buf ? strlen(*buf) : 0); - if (VIR_REALLOC_N(*buf, size+got+1) < 0) { - virReportOOMError(); - goto error; - } - memmove(*buf+size, data, got); - (*buf)[size+got] = '\0'; - } - continue; - - pollerr: - virReportSystemError(errno, - "%s", _("poll error")); - goto error; - } - - return 0; - -error: - VIR_FREE(*outbuf); - VIR_FREE(*errbuf); - return -1; -} - -/* Like gnulib's fread_file, but read no more than the specified maximum - number of bytes. If the length of the input is <= max_len, and - upon error while reading that data, it works just like fread_file. */ -static char * -saferead_lim(int fd, size_t max_len, size_t *length) -{ - char *buf = NULL; - size_t alloc = 0; - size_t size = 0; - int save_errno; - - for (;;) { - int count; - int requested; - - if (size + BUFSIZ + 1 > alloc) { - alloc += alloc / 2; - if (alloc < size + BUFSIZ + 1) - alloc = size + BUFSIZ + 1; - - if (VIR_REALLOC_N(buf, alloc) < 0) { - save_errno = errno; - break; - } - } - - /* Ensure that (size + requested <= max_len); */ - requested = MIN(size < max_len ? max_len - size : 0, - alloc - size - 1); - count = saferead(fd, buf + size, requested); - size += count; - - if (count != requested || requested == 0) { - save_errno = errno; - if (count < 0) - break; - buf[size] = '\0'; - *length = size; - return buf; - } - } - - VIR_FREE(buf); - errno = save_errno; - return NULL; -} - -/* A wrapper around saferead_lim that maps a failure due to - exceeding the maximum size limitation to EOVERFLOW. */ -int -virFileReadLimFD(int fd, int maxlen, char **buf) -{ - size_t len; - char *s; - - if (maxlen <= 0) { - errno = EINVAL; - return -1; - } - s = saferead_lim(fd, maxlen+1, &len); - if (s == NULL) - return -1; - if (len > maxlen || (int)len != len) { - VIR_FREE(s); - /* There was at least one byte more than MAXLEN. - Set errno accordingly. */ - errno = EOVERFLOW; - return -1; - } - *buf = s; - return len; -} - -int virFileReadAll(const char *path, int maxlen, char **buf) -{ - int fd = open(path, O_RDONLY); - if (fd < 0) { - virReportSystemError(errno, _("Failed to open file '%s'"), path); - return -1; - } - - int len = virFileReadLimFD(fd, maxlen, buf); - VIR_FORCE_CLOSE(fd); - if (len < 0) { - virReportSystemError(errno, _("Failed to read file '%s'"), path); - return -1; - } - - return len; -} - -/* Truncate @path and write @str to it. If @mode is 0, ensure that - @path exists; otherwise, use @mode if @path must be created. - Return 0 for success, nonzero for failure. - Be careful to preserve any errno value upon failure. */ -int virFileWriteStr(const char *path, const char *str, mode_t mode) -{ - int fd; - - if (mode) - fd = open(path, O_WRONLY|O_TRUNC|O_CREAT, mode); - else - fd = open(path, O_WRONLY|O_TRUNC); - if (fd == -1) - return -1; - - if (safewrite(fd, str, strlen(str)) < 0) { - VIR_FORCE_CLOSE(fd); - return -1; - } - - /* Use errno from failed close only if there was no write error. */ - if (VIR_CLOSE(fd) != 0) - return -1; - - return 0; -} - -int virFileMatchesNameSuffix(const char *file, - const char *name, - const char *suffix) -{ - int filelen = strlen(file); - int namelen = strlen(name); - int suffixlen = strlen(suffix); - - if (filelen == (namelen + suffixlen) && - STREQLEN(file, name, namelen) && - STREQLEN(file + namelen, suffix, suffixlen)) - return 1; - else - return 0; -} - -int virFileHasSuffix(const char *str, - const char *suffix) -{ - int len = strlen(str); - int suffixlen = strlen(suffix); - - if (len < suffixlen) - return 0; - - return STRCASEEQ(str + len - suffixlen, suffix); -} - -#define SAME_INODE(Stat_buf_1, Stat_buf_2) \ - ((Stat_buf_1).st_ino == (Stat_buf_2).st_ino \ - && (Stat_buf_1).st_dev == (Stat_buf_2).st_dev) - -/* Return nonzero if checkLink and checkDest - refer to the same file. Otherwise, return 0. */ -int virFileLinkPointsTo(const char *checkLink, - const char *checkDest) -{ - struct stat src_sb; - struct stat dest_sb; - - return (stat(checkLink, &src_sb) == 0 - && stat(checkDest, &dest_sb) == 0 - && SAME_INODE(src_sb, dest_sb)); -} - - - -static int -virFileResolveLinkHelper(const char *linkpath, - bool intermediatePaths, - char **resultpath) -{ - struct stat st; - - *resultpath = NULL; - - /* We don't need the full canonicalization of intermediate - * directories, if linkpath is absolute and the basename is - * already a non-symlink. */ - if (IS_ABSOLUTE_FILE_NAME(linkpath) && !intermediatePaths) { - if (lstat(linkpath, &st) < 0) - return -1; - - if (!S_ISLNK(st.st_mode)) { - if (!(*resultpath = strdup(linkpath))) - return -1; - return 0; - } - } - - *resultpath = canonicalize_file_name(linkpath); - - return *resultpath == NULL ? -1 : 0; -} - -/* - * Attempt to resolve a symbolic link, returning an - * absolute path where only the last component is guaranteed - * not to be a symlink. - * - * Return 0 if path was not a symbolic, or the link was - * resolved. Return -1 with errno set upon error - */ -int virFileResolveLink(const char *linkpath, - char **resultpath) -{ - return virFileResolveLinkHelper(linkpath, false, resultpath); -} - -/* - * Attempt to resolve a symbolic link, returning an - * absolute path where every component is guaranteed - * not to be a symlink. - * - * Return 0 if path was not a symbolic, or the link was - * resolved. Return -1 with errno set upon error - */ -int virFileResolveAllLinks(const char *linkpath, - char **resultpath) -{ - return virFileResolveLinkHelper(linkpath, true, resultpath); -} - -/* - * Check whether the given file is a link. - * Returns 1 in case of the file being a link, 0 in case it is not - * a link and the negative errno in all other cases. - */ -int virFileIsLink(const char *linkpath) -{ - struct stat st; - - if (lstat(linkpath, &st) < 0) - return -errno; - - return S_ISLNK(st.st_mode) != 0; -} - - -/* - * Finds a requested executable file in the PATH env. e.g.: - * "kvm-img" will return "/usr/bin/kvm-img" - * - * You must free the result - */ -char *virFindFileInPath(const char *file) -{ - char *path = NULL; - char *pathiter; - char *pathseg; - char *fullpath = NULL; - - if (file == NULL) - return NULL; - - /* if we are passed an absolute path (starting with /), return a - * copy of that path, after validating that it is executable - */ - if (IS_ABSOLUTE_FILE_NAME(file)) { - if (virFileIsExecutable(file)) - return strdup(file); - else - return NULL; - } - - /* If we are passed an anchored path (containing a /), then there - * is no path search - it must exist in the current directory - */ - if (strchr(file, '/')) { - if (virFileIsExecutable(file)) - ignore_value(virFileAbsPath(file, &path)); - return path; - } - - /* copy PATH env so we can tweak it */ - path = getenv("PATH"); - - if (path == NULL || (path = strdup(path)) == NULL) - return NULL; - - /* for each path segment, append the file to search for and test for - * it. return it if found. - */ - pathiter = path; - while ((pathseg = strsep(&pathiter, ":")) != NULL) { - if (virAsprintf(&fullpath, "%s/%s", pathseg, file) < 0 || - virFileIsExecutable(fullpath)) - break; - VIR_FREE(fullpath); - } - - VIR_FREE(path); - return fullpath; -} - -bool virFileIsDir(const char *path) -{ - struct stat s; - return (stat(path, &s) == 0) && S_ISDIR(s.st_mode); -} - -bool virFileExists(const char *path) -{ - return access(path, F_OK) == 0; -} - -/* Check that a file is regular and has executable bits. If false is - * returned, errno is valid. - * - * Note: In the presence of ACLs, this may return true for a file that - * would actually fail with EACCES for a given user, or false for a - * file that the user could actually execute, but setups with ACLs - * that weird are unusual. */ -bool -virFileIsExecutable(const char *file) -{ - struct stat sb; - - /* We would also want to check faccessat if we cared about ACLs, - * but we don't. */ - if (stat(file, &sb) < 0) - return false; - if (S_ISREG(sb.st_mode) && (sb.st_mode & 0111) != 0) - return true; - errno = S_ISDIR(sb.st_mode) ? EISDIR : EACCES; - return false; -} - -#ifndef WIN32 -/* Check that a file is accessible under certain - * user & gid. - * @mode can be F_OK, or a bitwise combination of R_OK, W_OK, and X_OK. - * see 'man access' for more details. - * Returns 0 on success, -1 on fail with errno set. - */ -int -virFileAccessibleAs(const char *path, int mode, - uid_t uid, gid_t gid) -{ - pid_t pid = 0; - int status, ret = 0; - int forkRet = 0; - - if (uid == getuid() && - gid == getgid()) - return access(path, mode); - - forkRet = virFork(&pid); - - if (pid < 0) { - return -1; - } - - if (pid) { /* parent */ - if (virProcessWait(pid, &status) < 0) { - /* virProcessWait() already - * reported error */ - return -1; - } - - if (!WIFEXITED(status)) { - errno = EINTR; - return -1; - } - - if (status) { - errno = WEXITSTATUS(status); - return -1; - } - - return 0; - } - - /* child. - * Return positive value here. Parent - * will change it to negative one. */ - - if (forkRet < 0) { - ret = errno; - goto childerror; - } - - if (virSetUIDGID(uid, gid) < 0) { - ret = errno; - goto childerror; - } - - if (access(path, mode) < 0) - ret = errno; - -childerror: - if ((ret & 0xFF) != ret) { - VIR_WARN("unable to pass desired return value %d", ret); - ret = 0xFF; - } - - _exit(ret); -} - -/* virFileOpenForceOwnerMode() - an internal utility function called - * only by virFileOpenAs(). Sets the owner and mode of the file - * opened as "fd" if it's not correct AND the flags say it should be - * forced. */ -static int -virFileOpenForceOwnerMode(const char *path, int fd, mode_t mode, - uid_t uid, gid_t gid, unsigned int flags) -{ - int ret = 0; - struct stat st; - - if (!(flags & (VIR_FILE_OPEN_FORCE_OWNER | VIR_FILE_OPEN_FORCE_MODE))) - return 0; - - if (fstat(fd, &st) == -1) { - ret = -errno; - virReportSystemError(errno, _("stat of '%s' failed"), path); - return ret; - } - /* NB: uid:gid are never "-1" (default) at this point - the caller - * has always changed -1 to the value of get[gu]id(). - */ - if ((flags & VIR_FILE_OPEN_FORCE_OWNER) && - ((st.st_uid != uid) || (st.st_gid != gid)) && - (fchown(fd, uid, gid) < 0)) { - ret = -errno; - virReportSystemError(errno, - _("cannot chown '%s' to (%u, %u)"), - path, (unsigned int) uid, - (unsigned int) gid); - return ret; - } - if ((flags & VIR_FILE_OPEN_FORCE_MODE) && - ((mode & (S_IRWXU|S_IRWXG|S_IRWXO)) != - (st.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO))) && - (fchmod(fd, mode) < 0)) { - ret = -errno; - virReportSystemError(errno, - _("cannot set mode of '%s' to %04o"), - path, mode); - return ret; - } - return ret; -} - -/* virFileOpenForked() - an internal utility function called only by - * virFileOpenAs(). It forks, then the child does setuid+setgid to - * given uid:gid and attempts to open the file, while the parent just - * calls recvfd to get the open fd back from the child. returns the - * fd, or -errno if there is an error. */ -static int -virFileOpenForked(const char *path, int openflags, mode_t mode, - uid_t uid, gid_t gid, unsigned int flags) -{ - pid_t pid; - int waitret, status, ret = 0; - int fd = -1; - int pair[2] = { -1, -1 }; - int forkRet; - - /* parent is running as root, but caller requested that the - * file be opened as some other user and/or group). The - * following dance avoids problems caused by root-squashing - * NFS servers. */ - - if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) < 0) { - ret = -errno; - virReportSystemError(errno, - _("failed to create socket needed for '%s'"), - path); - return ret; - } - - forkRet = virFork(&pid); - if (pid < 0) - return -errno; - - if (pid == 0) { - - /* child */ - - VIR_FORCE_CLOSE(pair[0]); /* preserves errno */ - if (forkRet < 0) { - /* error encountered and logged in virFork() after the fork. */ - ret = -errno; - goto childerror; - } - - /* set desired uid/gid, then attempt to create the file */ - - if (virSetUIDGID(uid, gid) < 0) { - ret = -errno; - goto childerror; - } - - if ((fd = open(path, openflags, mode)) < 0) { - ret = -errno; - virReportSystemError(errno, - _("child process failed to create file '%s'"), - path); - goto childerror; - } - - /* File is successfully open. Set permissions if requested. */ - ret = virFileOpenForceOwnerMode(path, fd, mode, uid, gid, flags); - if (ret < 0) - goto childerror; - - do { - ret = sendfd(pair[1], fd); - } while (ret < 0 && errno == EINTR); - - if (ret < 0) { - ret = -errno; - virReportSystemError(errno, "%s", - _("child process failed to send fd to parent")); - goto childerror; - } - - childerror: - /* ret tracks -errno on failure, but exit value must be positive. - * If the child exits with EACCES, then the parent tries again. */ - /* XXX This makes assumptions about errno being < 255, which is - * not true on Hurd. */ - VIR_FORCE_CLOSE(pair[1]); - if (ret < 0) { - VIR_FORCE_CLOSE(fd); - } - ret = -ret; - if ((ret & 0xff) != ret) { - VIR_WARN("unable to pass desired return value %d", ret); - ret = 0xff; - } - _exit(ret); - } - - /* parent */ - - VIR_FORCE_CLOSE(pair[1]); - - do { - fd = recvfd(pair[0], 0); - } while (fd < 0 && errno == EINTR); - VIR_FORCE_CLOSE(pair[0]); /* NB: this preserves errno */ - - if (fd < 0 && errno != EACCES) { - ret = -errno; - while (waitpid(pid, NULL, 0) == -1 && errno == EINTR); - return ret; - } - - /* wait for child to complete, and retrieve its exit code */ - while ((waitret = waitpid(pid, &status, 0) == -1) - && (errno == EINTR)); - if (waitret == -1) { - ret = -errno; - virReportSystemError(errno, - _("failed to wait for child creating '%s'"), - path); - VIR_FORCE_CLOSE(fd); - return ret; - } - if (!WIFEXITED(status) || (ret = -WEXITSTATUS(status)) == -EACCES || - fd == -1) { - /* fall back to the simpler method, which works better in - * some cases */ - VIR_FORCE_CLOSE(fd); - if (flags & VIR_FILE_OPEN_NOFORK) { - /* If we had already tried opening w/o fork+setuid and - * failed, no sense trying again. Just set return the - * original errno that we got at that time (by - * definition, always either EACCES or EPERM - EACCES - * is close enough). - */ - return -EACCES; - } - if ((fd = open(path, openflags, mode)) < 0) - return -errno; - ret = virFileOpenForceOwnerMode(path, fd, mode, uid, gid, flags); - if (ret < 0) { - VIR_FORCE_CLOSE(fd); - return ret; - } - } - return fd; -} - -/** - * virFileOpenAs: - * @path: file to open or create - * @openflags: flags to pass to open - * @mode: mode to use on creation or when forcing permissions - * @uid: uid that should own file on creation - * @gid: gid that should own file - * @flags: bit-wise or of VIR_FILE_OPEN_* flags - * - * Open @path, and return an fd to the open file. @openflags contains - * the flags normally passed to open(2), while those in @flags are - * used internally. If @flags includes VIR_FILE_OPEN_NOFORK, then try - * opening the file while executing with the current uid:gid - * (i.e. don't fork+setuid+setgid before the call to open()). If - * @flags includes VIR_FILE_OPEN_FORK, then try opening the file while - * the effective user id is @uid (by forking a child process); this - * allows one to bypass root-squashing NFS issues; NOFORK is always - * tried before FORK (the absence of both flags is treated identically - * to (VIR_FILE_OPEN_NOFORK | VIR_FILE_OPEN_FORK)). If @flags includes - * VIR_FILE_OPEN_FORCE_OWNER, then ensure that @path is owned by - * uid:gid before returning (even if it already existed with a - * different owner). If @flags includes VIR_FILE_OPEN_FORCE_MODE, - * ensure it has those permissions before returning (again, even if - * the file already existed with different permissions). The return - * value (if non-negative) is the file descriptor, left open. Returns - * -errno on failure. */ -int -virFileOpenAs(const char *path, int openflags, mode_t mode, - uid_t uid, gid_t gid, unsigned int flags) -{ - int ret = 0, fd = -1; - - /* allow using -1 to mean "current value" */ - if (uid == (uid_t) -1) - uid = getuid(); - if (gid == (gid_t) -1) - gid = getgid(); - - /* treat absence of both flags as presence of both for simpler - * calling. */ - if (!(flags & (VIR_FILE_OPEN_NOFORK|VIR_FILE_OPEN_FORK))) - flags |= VIR_FILE_OPEN_NOFORK|VIR_FILE_OPEN_FORK; - - if ((flags & VIR_FILE_OPEN_NOFORK) - || (getuid() != 0) - || ((uid == 0) && (gid == 0))) { - - if ((fd = open(path, openflags, mode)) < 0) { - ret = -errno; - } else { - ret = virFileOpenForceOwnerMode(path, fd, mode, uid, gid, flags); - if (ret < 0) - goto error; - } - } - - /* If we either 1) didn't try opening as current user at all, or - * 2) failed, and errno/virStorageFileIsSharedFS indicate we might - * be successful if we try as a different uid, then try doing - * fork+setuid+setgid before opening. - */ - if ((fd < 0) && (flags & VIR_FILE_OPEN_FORK)) { - - if (ret < 0) { - /* An open(2) that failed due to insufficient permissions - * could return one or the other of these depending on OS - * version and circumstances. Any other errno indicates a - * problem that couldn't be remedied by fork+setuid - * anyway. */ - if (ret != -EACCES && ret != -EPERM) - goto error; - - /* On Linux we can also verify the FS-type of the - * directory. (this is a NOP on other platforms). */ - switch (virStorageFileIsSharedFS(path)) { - case 1: - /* it was on a network share, so we'll re-try */ - break; - case -1: - /* failure detecting fstype */ - virReportSystemError(errno, _("couldn't determine fs type " - "of mount containing '%s'"), path); - goto error; - case 0: - default: - /* file isn't on a recognized network FS */ - goto error; - } - } - - /* passed all prerequisites - retry the open w/fork+setuid */ - if ((fd = virFileOpenForked(path, openflags, mode, uid, gid, flags)) < 0) { - ret = fd; - fd = -1; - goto error; - } - } - - /* File is successfully opened */ - - return fd; - -error: - if (fd < 0) { - /* whoever failed the open last has already set ret = -errno */ - virReportSystemError(-ret, openflags & O_CREAT - ? _("failed to create file '%s'") - : _("failed to open file '%s'"), - path); - } else { - /* some other failure after the open succeeded */ - VIR_FORCE_CLOSE(fd); - } - return ret; -} - -/* return -errno on failure, or 0 on success */ -static int virDirCreateNoFork(const char *path, mode_t mode, uid_t uid, gid_t gid, - unsigned int flags) { - int ret = 0; - struct stat st; - - if ((mkdir(path, mode) < 0) - && !((errno == EEXIST) && (flags & VIR_DIR_CREATE_ALLOW_EXIST))) { - ret = -errno; - virReportSystemError(errno, _("failed to create directory '%s'"), - path); - goto error; - } - - if (stat(path, &st) == -1) { - ret = -errno; - virReportSystemError(errno, _("stat of '%s' failed"), path); - goto error; - } - if (((st.st_uid != uid) || (st.st_gid != gid)) - && (chown(path, uid, gid) < 0)) { - ret = -errno; - virReportSystemError(errno, _("cannot chown '%s' to (%u, %u)"), - path, (unsigned int) uid, (unsigned int) gid); - goto error; - } - if ((flags & VIR_DIR_CREATE_FORCE_PERMS) - && (chmod(path, mode) < 0)) { - ret = -errno; - virReportSystemError(errno, - _("cannot set mode of '%s' to %04o"), - path, mode); - goto error; - } -error: - return ret; -} - -/* return -errno on failure, or 0 on success */ -int virDirCreate(const char *path, mode_t mode, - uid_t uid, gid_t gid, unsigned int flags) { - struct stat st; - pid_t pid; - int waitret; - int status, ret = 0; - - /* allow using -1 to mean "current value" */ - if (uid == (uid_t) -1) - uid = getuid(); - if (gid == (gid_t) -1) - gid = getgid(); - - if ((!(flags & VIR_DIR_CREATE_AS_UID)) - || (getuid() != 0) - || ((uid == 0) && (gid == 0)) - || ((flags & VIR_DIR_CREATE_ALLOW_EXIST) && (stat(path, &st) >= 0))) { - return virDirCreateNoFork(path, mode, uid, gid, flags); - } - - int forkRet = virFork(&pid); - - if (pid < 0) { - ret = -errno; - return ret; - } - - if (pid) { /* parent */ - /* wait for child to complete, and retrieve its exit code */ - while ((waitret = waitpid(pid, &status, 0) == -1) && (errno == EINTR)); - if (waitret == -1) { - ret = -errno; - virReportSystemError(errno, - _("failed to wait for child creating '%s'"), - path); - goto parenterror; - } - if (!WIFEXITED(status) || (ret = -WEXITSTATUS(status)) == -EACCES) { - /* fall back to the simpler method, which works better in - * some cases */ - return virDirCreateNoFork(path, mode, uid, gid, flags); - } -parenterror: - return ret; - } - - /* child */ - - if (forkRet < 0) { - /* error encountered and logged in virFork() after the fork. */ - goto childerror; - } - - /* set desired uid/gid, then attempt to create the directory */ - - if (virSetUIDGID(uid, gid) < 0) { - ret = -errno; - goto childerror; - } - if (mkdir(path, mode) < 0) { - ret = -errno; - if (ret != -EACCES) { - /* in case of EACCES, the parent will retry */ - virReportSystemError(errno, _("child failed to create directory '%s'"), - path); - } - goto childerror; - } - /* check if group was set properly by creating after - * setgid. If not, try doing it with chown */ - if (stat(path, &st) == -1) { - ret = -errno; - virReportSystemError(errno, - _("stat of '%s' failed"), path); - goto childerror; - } - if ((st.st_gid != gid) && (chown(path, -1, gid) < 0)) { - ret = -errno; - virReportSystemError(errno, - _("cannot chown '%s' to group %u"), - path, (unsigned int) gid); - goto childerror; - } - if ((flags & VIR_DIR_CREATE_FORCE_PERMS) - && chmod(path, mode) < 0) { - virReportSystemError(errno, - _("cannot set mode of '%s' to %04o"), - path, mode); - goto childerror; - } -childerror: - _exit(ret); -} - -#else /* WIN32 */ - -int -virFileAccessibleAs(const char *path, - int mode, - uid_t uid ATTRIBUTE_UNUSED, - gid_t gid ATTRIBUTE_UNUSED) -{ - - VIR_WARN("Ignoring uid/gid due to WIN32"); - - return access(path, mode); -} - -/* return -errno on failure, or 0 on success */ -int virFileOpenAs(const char *path ATTRIBUTE_UNUSED, - int openflags ATTRIBUTE_UNUSED, - mode_t mode ATTRIBUTE_UNUSED, - uid_t uid ATTRIBUTE_UNUSED, - gid_t gid ATTRIBUTE_UNUSED, - unsigned int flags_unused ATTRIBUTE_UNUSED) -{ - virReportError(VIR_ERR_INTERNAL_ERROR, - "%s", _("virFileOpenAs is not implemented for WIN32")); - - return -ENOSYS; -} - -int virDirCreate(const char *path ATTRIBUTE_UNUSED, - mode_t mode ATTRIBUTE_UNUSED, - uid_t uid ATTRIBUTE_UNUSED, - gid_t gid ATTRIBUTE_UNUSED, - unsigned int flags_unused ATTRIBUTE_UNUSED) -{ - virReportError(VIR_ERR_INTERNAL_ERROR, - "%s", _("virDirCreate is not implemented for WIN32")); - - return -ENOSYS; -} -#endif /* WIN32 */ - -static int virFileMakePathHelper(char *path, mode_t mode) -{ - struct stat st; - char *p; - - VIR_DEBUG("path=%s mode=0%o", path, mode); - - if (stat(path, &st) >= 0) { - if (S_ISDIR(st.st_mode)) - return 0; - - errno = ENOTDIR; - return -1; - } - - if (errno != ENOENT) - return -1; - - if ((p = strrchr(path, '/')) == NULL) { - errno = EINVAL; - return -1; - } - - if (p != path) { - *p = '\0'; - - if (virFileMakePathHelper(path, mode) < 0) - return -1; - - *p = '/'; - } - - if (mkdir(path, mode) < 0 && errno != EEXIST) - return -1; - - return 0; -} - -/** - * Creates the given directory with mode 0777 if it's not already existing. - * - * Returns 0 on success, or -1 if an error occurred (in which case, errno - * is set appropriately). - */ -int virFileMakePath(const char *path) -{ - return virFileMakePathWithMode(path, 0777); -} - -int -virFileMakePathWithMode(const char *path, - mode_t mode) -{ - int ret = -1; - char *tmp; - - if ((tmp = strdup(path)) == NULL) - goto cleanup; - - ret = virFileMakePathHelper(tmp, mode); - -cleanup: - VIR_FREE(tmp); - return ret; -} - -/* Build up a fully qualified path for a config file to be - * associated with a persistent guest or network */ -char * -virFileBuildPath(const char *dir, const char *name, const char *ext) -{ - char *path; - - if (ext == NULL) { - if (virAsprintf(&path, "%s/%s", dir, name) < 0) { - virReportOOMError(); - return NULL; - } - } else { - if (virAsprintf(&path, "%s/%s%s", dir, name, ext) < 0) { - virReportOOMError(); - return NULL; - } - } - - return path; -} - -/* Open a non-blocking master side of a pty. If ttyName is not NULL, - * then populate it with the name of the slave. If rawmode is set, - * also put the master side into raw mode before returning. */ -#ifndef WIN32 -int virFileOpenTty(int *ttymaster, - char **ttyName, - int rawmode) -{ - /* XXX A word of caution - on some platforms (Solaris and HP-UX), - * additional ioctl() calls are needs after opening the slave - * before it will cause isatty() to return true. Should we make - * virFileOpenTty also return the opened slave fd, so the caller - * doesn't have to worry about that mess? */ - int ret = -1; - int slave = -1; - char *name = NULL; - - /* Unfortunately, we can't use the name argument of openpty, since - * there is no guarantee on how large the buffer has to be. - * Likewise, we can't use the termios argument: we have to use - * read-modify-write since there is no portable way to initialize - * a struct termios without use of tcgetattr. */ - if (openpty(ttymaster, &slave, NULL, NULL, NULL) < 0) - return -1; - - /* What a shame that openpty cannot atomically set FD_CLOEXEC, but - * that using posix_openpt/grantpt/unlockpt/ptsname is not - * thread-safe, and that ptsname_r is not portable. */ - if (virSetNonBlock(*ttymaster) < 0 || - virSetCloseExec(*ttymaster) < 0) - goto cleanup; - - /* While Linux supports tcgetattr on either the master or the - * slave, Solaris requires it to be on the slave. */ - if (rawmode) { - struct termios ttyAttr; - if (tcgetattr(slave, &ttyAttr) < 0) - goto cleanup; - - cfmakeraw(&ttyAttr); - - if (tcsetattr(slave, TCSADRAIN, &ttyAttr) < 0) - goto cleanup; - } - - /* ttyname_r on the slave is required by POSIX, while ptsname_r on - * the master is a glibc extension, and the POSIX ptsname is not - * thread-safe. Since openpty gave us both descriptors, guess - * which way we will determine the name? :) */ - if (ttyName) { - /* Initial guess of 64 is generally sufficient; rely on ERANGE - * to tell us if we need to grow. */ - size_t len = 64; - int rc; - - if (VIR_ALLOC_N(name, len) < 0) - goto cleanup; - - while ((rc = ttyname_r(slave, name, len)) == ERANGE) { - if (VIR_RESIZE_N(name, len, len, len) < 0) - goto cleanup; - } - if (rc != 0) { - errno = rc; - goto cleanup; - } - *ttyName = name; - name = NULL; - } - - ret = 0; - -cleanup: - if (ret != 0) - VIR_FORCE_CLOSE(*ttymaster); - VIR_FORCE_CLOSE(slave); - VIR_FREE(name); - - return ret; -} -#else /* WIN32 */ -int virFileOpenTty(int *ttymaster ATTRIBUTE_UNUSED, - char **ttyName ATTRIBUTE_UNUSED, - int rawmode ATTRIBUTE_UNUSED) -{ - /* mingw completely lacks pseudo-terminals, and the gnulib - * replacements are not (yet) license compatible. */ - errno = ENOSYS; - return -1; -} -#endif /* WIN32 */ - -bool virFileIsAbsPath(const char *path) -{ - if (!path) - return false; - - if (VIR_FILE_IS_DIR_SEPARATOR(path[0])) - return true; - -#ifdef WIN32 - if (c_isalpha(path[0]) && - path[1] == ':' && - VIR_FILE_IS_DIR_SEPARATOR(path[2])) - return true; -#endif - - return false; -} - - -const char *virFileSkipRoot(const char *path) -{ -#ifdef WIN32 - /* Skip \\server\share or //server/share */ - if (VIR_FILE_IS_DIR_SEPARATOR(path[0]) && - VIR_FILE_IS_DIR_SEPARATOR(path[1]) && - path[2] && - !VIR_FILE_IS_DIR_SEPARATOR(path[2])) - { - const char *p = strchr(path + 2, VIR_FILE_DIR_SEPARATOR); - const char *q = strchr(path + 2, '/'); - - if (p == NULL || (q != NULL && q < p)) - p = q; - - if (p && p > path + 2 && p[1]) { - path = p + 1; - - while (path[0] && - !VIR_FILE_IS_DIR_SEPARATOR(path[0])) - path++; - - /* Possibly skip a backslash after the share name */ - if (VIR_FILE_IS_DIR_SEPARATOR(path[0])) - path++; - - return path; - } - } -#endif - - /* Skip initial slashes */ - if (VIR_FILE_IS_DIR_SEPARATOR(path[0])) { - while (VIR_FILE_IS_DIR_SEPARATOR(path[0])) - path++; - - return path; - } - -#ifdef WIN32 - /* Skip X:\ */ - if (c_isalpha(path[0]) && - path[1] == ':' && - VIR_FILE_IS_DIR_SEPARATOR(path[2])) - return path + 3; -#endif - - return path; -} - - - -/* - * Creates an absolute path for a potentially relative path. - * Return 0 if the path was not relative, or on success. - * Return -1 on error. - * - * You must free the result. - */ -int virFileAbsPath(const char *path, char **abspath) -{ - char *buf; - - if (path[0] == '/') { - if (!(*abspath = strdup(path))) - return -1; - } else { - buf = getcwd(NULL, 0); - if (buf == NULL) - return -1; - - if (virAsprintf(abspath, "%s/%s", buf, path) < 0) { - VIR_FREE(buf); - return -1; - } - VIR_FREE(buf); - } - - return 0; -} - -/* Remove spurious / characters from a path. The result must be freed */ -char * -virFileSanitizePath(const char *path) -{ - const char *cur = path; - char *cleanpath; - int idx = 0; - - cleanpath = strdup(path); - if (!cleanpath) { - virReportOOMError(); - return NULL; - } - - /* Need to sanitize: - * // -> // - * /// -> / - * /../foo -> /../foo - * /foo///bar/ -> /foo/bar - */ - - /* Starting with // is valid posix, but ///foo == /foo */ - if (cur[0] == '/' && cur[1] == '/' && cur[2] != '/') { - idx = 2; - cur += 2; - } - - /* Sanitize path in place */ - while (*cur != '\0') { - if (*cur != '/') { - cleanpath[idx++] = *cur++; - continue; - } - - /* Skip all extra / */ - while (*++cur == '/') - continue; - - /* Don't add a trailing / */ - if (idx != 0 && *cur == '\0') - break; - - cleanpath[idx++] = '/'; - } - cleanpath[idx] = '\0'; - - return cleanpath; -} - -/* Like strtol, but produce an "int" result, and check more carefully. - Return 0 upon success; return -1 to indicate failure. - When END_PTR is NULL, the byte after the final valid digit must be NUL. - Otherwise, it's like strtol and lets the caller check any suffix for - validity. This function is careful to return -1 when the string S - represents a number that is not representable as an "int". */ -int -virStrToLong_i(char const *s, char **end_ptr, int base, int *result) -{ - long int val; - char *p; - int err; - - errno = 0; - val = strtol(s, &p, base); /* exempt from syntax-check */ - err = (errno || (!end_ptr && *p) || p == s || (int) val != val); - if (end_ptr) - *end_ptr = p; - if (err) - return -1; - *result = val; - return 0; -} - -/* Just like virStrToLong_i, above, but produce an "unsigned int" value. */ -int -virStrToLong_ui(char const *s, char **end_ptr, int base, unsigned int *result) -{ - unsigned long int val; - char *p; - int err; - - errno = 0; - val = strtoul(s, &p, base); /* exempt from syntax-check */ - err = (errno || (!end_ptr && *p) || p == s || (unsigned int) val != val); - if (end_ptr) - *end_ptr = p; - if (err) - return -1; - *result = val; - return 0; -} - -/* Just like virStrToLong_i, above, but produce a "long" value. */ -int -virStrToLong_l(char const *s, char **end_ptr, int base, long *result) -{ - long int val; - char *p; - int err; - - errno = 0; - val = strtol(s, &p, base); /* exempt from syntax-check */ - err = (errno || (!end_ptr && *p) || p == s); - if (end_ptr) - *end_ptr = p; - if (err) - return -1; - *result = val; - return 0; -} - -/* Just like virStrToLong_i, above, but produce an "unsigned long" value. */ -int -virStrToLong_ul(char const *s, char **end_ptr, int base, unsigned long *result) -{ - unsigned long int val; - char *p; - int err; - - errno = 0; - val = strtoul(s, &p, base); /* exempt from syntax-check */ - err = (errno || (!end_ptr && *p) || p == s); - if (end_ptr) - *end_ptr = p; - if (err) - return -1; - *result = val; - return 0; -} - -/* Just like virStrToLong_i, above, but produce a "long long" value. */ -int -virStrToLong_ll(char const *s, char **end_ptr, int base, long long *result) -{ - long long val; - char *p; - int err; - - errno = 0; - val = strtoll(s, &p, base); /* exempt from syntax-check */ - err = (errno || (!end_ptr && *p) || p == s); - if (end_ptr) - *end_ptr = p; - if (err) - return -1; - *result = val; - return 0; -} - -/* Just like virStrToLong_i, above, but produce an "unsigned long long" value. */ -int -virStrToLong_ull(char const *s, char **end_ptr, int base, unsigned long long *result) -{ - unsigned long long val; - char *p; - int err; - - errno = 0; - val = strtoull(s, &p, base); /* exempt from syntax-check */ - err = (errno || (!end_ptr && *p) || p == s); - if (end_ptr) - *end_ptr = p; - if (err) - return -1; - *result = val; - return 0; -} - -int -virStrToDouble(char const *s, - char **end_ptr, - double *result) -{ - double val; - char *p; - int err; - - errno = 0; - val = strtod(s, &p); /* exempt from syntax-check */ - err = (errno || (!end_ptr && *p) || p == s); - if (end_ptr) - *end_ptr = p; - if (err) - return -1; - *result = val; - return 0; -} - -/* Convert C from hexadecimal character to integer. */ -int -virHexToBin(unsigned char c) -{ - switch (c) { - default: return c - '0'; - case 'a': case 'A': return 10; - case 'b': case 'B': return 11; - case 'c': case 'C': return 12; - case 'd': case 'D': return 13; - case 'e': case 'E': return 14; - case 'f': case 'F': return 15; - } -} - -/* Scale an integer VALUE in-place by an optional case-insensitive - * SUFFIX, defaulting to SCALE if suffix is NULL or empty (scale is - * typically 1 or 1024). Recognized suffixes include 'b' or 'bytes', - * as well as power-of-two scaling via binary abbreviations ('KiB', - * 'MiB', ...) or their one-letter counterpart ('k', 'M', ...), and - * power-of-ten scaling via SI abbreviations ('KB', 'MB', ...). - * Ensure that the result does not exceed LIMIT. Return 0 on success, - * -1 with error message raised on failure. */ -int -virScaleInteger(unsigned long long *value, const char *suffix, - unsigned long long scale, unsigned long long limit) -{ - if (!suffix || !*suffix) { - if (!scale) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("invalid scale %llu"), scale); - return -1; - } - suffix = ""; - } else if (STRCASEEQ(suffix, "b") || STRCASEEQ(suffix, "byte") || - STRCASEEQ(suffix, "bytes")) { - scale = 1; - } else { - int base; - - if (!suffix[1] || STRCASEEQ(suffix + 1, "iB")) { - base = 1024; - } else if (c_tolower(suffix[1]) == 'b' && !suffix[2]) { - base = 1000; - } else { - virReportError(VIR_ERR_INVALID_ARG, - _("unknown suffix '%s'"), suffix); - return -1; - } - scale = 1; - switch (c_tolower(*suffix)) { - case 'e': - scale *= base; - /* fallthrough */ - case 'p': - scale *= base; - /* fallthrough */ - case 't': - scale *= base; - /* fallthrough */ - case 'g': - scale *= base; - /* fallthrough */ - case 'm': - scale *= base; - /* fallthrough */ - case 'k': - scale *= base; - break; - default: - virReportError(VIR_ERR_INVALID_ARG, - _("unknown suffix '%s'"), suffix); - return -1; - } - } - - if (*value && *value >= (limit / scale)) { - virReportError(VIR_ERR_OVERFLOW, _("value too large: %llu%s"), - *value, suffix); - return -1; - } - *value *= scale; - return 0; -} - -/** - * virSkipSpaces: - * @str: pointer to the char pointer used - * - * Skip potential blanks, this includes space tabs, line feed, - * carriage returns. - */ -void -virSkipSpaces(const char **str) -{ - const char *cur = *str; - - while (c_isspace(*cur)) - cur++; - *str = cur; -} - -/** - * virSkipSpacesAndBackslash: - * @str: pointer to the char pointer used - * - * Like virSkipSpaces, but also skip backslashes erroneously emitted - * by xend - */ -void -virSkipSpacesAndBackslash(const char **str) -{ - const char *cur = *str; - - while (c_isspace(*cur) || *cur == '\\') - cur++; - *str = cur; -} - -/** - * virTrimSpaces: - * @str: string to modify to remove all trailing spaces - * @endp: track the end of the string - * - * If @endp is NULL on entry, then all spaces prior to the trailing - * NUL in @str are removed, by writing NUL into the appropriate - * location. If @endp is non-NULL but points to a NULL pointer, - * then all spaces prior to the trailing NUL in @str are removed, - * NUL is written to the new string end, and endp is set to the - * location of the (new) string end. If @endp is non-NULL and - * points to a non-NULL pointer, then that pointer is used as - * the end of the string, endp is set to the (new) location, but - * no NUL pointer is written into the string. - */ -void -virTrimSpaces(char *str, char **endp) -{ - char *end; - - if (!endp || !*endp) - end = str + strlen(str); - else - end = *endp; - while (end > str && c_isspace(end[-1])) - end--; - if (endp) { - if (!*endp) - *end = '\0'; - *endp = end; - } else { - *end = '\0'; - } -} - -/** - * virSkipSpacesBackwards: - * @str: start of string - * @endp: on entry, *endp must be NULL or a location within @str, on exit, - * will be adjusted to skip trailing spaces, or to NULL if @str had nothing - * but spaces. - */ -void -virSkipSpacesBackwards(const char *str, char **endp) -{ - /* Casting away const is safe, since virTrimSpaces does not - * modify string with this particular usage. */ - char *s = (char*) str; - - if (!*endp) - *endp = s + strlen(s); - virTrimSpaces(s, endp); - if (s == *endp) - *endp = NULL; -} - -/** - * virParseNumber: - * @str: pointer to the char pointer used - * - * Parse an unsigned number - * - * Returns the unsigned number or -1 in case of error. @str will be - * updated to skip the number. - */ -int -virParseNumber(const char **str) -{ - int ret = 0; - const char *cur = *str; - - if ((*cur < '0') || (*cur > '9')) - return -1; - - while (c_isdigit(*cur)) { - unsigned int c = *cur - '0'; - - if ((ret > INT_MAX / 10) || - ((ret == INT_MAX / 10) && (c > INT_MAX % 10))) - return -1; - ret = ret * 10 + c; - cur++; - } - *str = cur; - return ret; -} - - -/** - * virParseVersionString: - * @str: const char pointer to the version string - * @version: unsigned long pointer to output the version number - * @allowMissing: true to treat 3 like 3.0.0, false to error out on - * missing minor or micro - * - * Parse an unsigned version number from a version string. Expecting - * 'major.minor.micro' format, ignoring an optional suffix. - * - * The major, minor and micro numbers are encoded into a single version number: - * - * 1000000 * major + 1000 * minor + micro - * - * Returns the 0 for success, -1 for error. - */ -int -virParseVersionString(const char *str, unsigned long *version, - bool allowMissing) -{ - unsigned int major, minor = 0, micro = 0; - char *tmp; - - if (virStrToLong_ui(str, &tmp, 10, &major) < 0) - return -1; - - if (!allowMissing && *tmp != '.') - return -1; - - if ((*tmp == '.') && virStrToLong_ui(tmp + 1, &tmp, 10, &minor) < 0) - return -1; - - if (!allowMissing && *tmp != '.') - return -1; - - if ((*tmp == '.') && virStrToLong_ui(tmp + 1, &tmp, 10, µ) < 0) - return -1; - - if (major > UINT_MAX / 1000000 || minor > 999 || micro > 999) - return -1; - - *version = 1000000 * major + 1000 * minor + micro; - - return 0; -} - -/** - * virVasprintf - * - * like glibc's vasprintf but makes sure *strp == NULL on failure - */ -int -virVasprintf(char **strp, const char *fmt, va_list list) -{ - int ret; - - if ((ret = vasprintf(strp, fmt, list)) == -1) - *strp = NULL; - - return ret; -} - -/** - * virAsprintf - * - * like glibc's_asprintf but makes sure *strp == NULL on failure - */ -int -virAsprintf(char **strp, const char *fmt, ...) -{ - va_list ap; - int ret; - - va_start(ap, fmt); - ret = virVasprintf(strp, fmt, ap); - va_end(ap); - return ret; -} - -/** - * virStrncpy - * - * A safe version of strncpy. The last parameter is the number of bytes - * available in the destination string, *not* the number of bytes you want - * to copy. If the destination is not large enough to hold all n of the - * src string bytes plus a \0, NULL is returned and no data is copied. - * If the destination is large enough to hold the n bytes plus \0, then the - * string is copied and a pointer to the destination string is returned. - */ -char * -virStrncpy(char *dest, const char *src, size_t n, size_t destbytes) -{ - char *ret; - - if (n > (destbytes - 1)) - return NULL; - - ret = strncpy(dest, src, n); - /* strncpy NULL terminates iff the last character is \0. Therefore - * force the last byte to be \0 - */ - dest[n] = '\0'; - - return ret; -} - -/** - * virStrcpy - * - * A safe version of strcpy. The last parameter is the number of bytes - * available in the destination string, *not* the number of bytes you want - * to copy. If the destination is not large enough to hold all n of the - * src string bytes plus a \0, NULL is returned and no data is copied. - * If the destination is large enough to hold the source plus \0, then the - * string is copied and a pointer to the destination string is returned. - */ -char * -virStrcpy(char *dest, const char *src, size_t destbytes) -{ - return virStrncpy(dest, src, strlen(src), destbytes); -} - -int virEnumFromString(const char *const*types, - unsigned int ntypes, - const char *type) -{ - unsigned int i; - if (!type) - return -1; - - for (i = 0 ; i < ntypes ; i++) - if (STREQ(types[i], type)) - return i; - - return -1; -} - -/* In case thread-safe locales are available */ -#if HAVE_NEWLOCALE - -static locale_t virLocale; - -static int -virLocaleOnceInit(void) -{ - virLocale = newlocale(LC_ALL_MASK, "C", (locale_t)0); - if (!virLocale) - return -1; - return 0; -} - -VIR_ONCE_GLOBAL_INIT(virLocale) -#endif - -/** - * virDoubleToStr - * - * converts double to string with C locale (thread-safe). - * - * Returns -1 on error, size of the string otherwise. - */ -int -virDoubleToStr(char **strp, double number) -{ - int ret = -1; - -#if HAVE_NEWLOCALE - - locale_t old_loc; - - if (virLocaleInitialize() < 0) - goto error; - - old_loc = uselocale(virLocale); - ret = virAsprintf(strp, "%lf", number); - uselocale(old_loc); - -#else - - char *radix, *tmp; - struct lconv *lc; - - if ((ret = virAsprintf(strp, "%lf", number) < 0)) - goto error; - - lc = localeconv(); - radix = lc->decimal_point; - tmp = strstr(*strp, radix); - if (tmp) { - *tmp = '.'; - if (strlen(radix) > 1) - memmove(tmp + 1, tmp + strlen(radix), strlen(*strp) - (tmp - *strp)); - } - -#endif /* HAVE_NEWLOCALE */ - error: - return ret; -} - - -/** - * Format @val as a base-10 decimal number, in the - * buffer @buf of size @buflen. To allocate a suitable - * sized buffer, the INT_BUFLEN(int) macro should be - * used - * - * Returns pointer to start of the number in @buf - */ -char * -virFormatIntDecimal(char *buf, size_t buflen, int val) -{ - char *p = buf + buflen - 1; - *p = '\0'; - if (val >= 0) { - do { - *--p = '0' + (val % 10); - val /= 10; - } while (val != 0); - } else { - do { - *--p = '0' - (val % 10); - val /= 10; - } while (val != 0); - *--p = '-'; - } - return p; -} - - -const char *virEnumToString(const char *const*types, - unsigned int ntypes, - int type) -{ - if (type < 0 || type >= ntypes) - return NULL; - - return types[type]; -} - -/* Translates a device name of the form (regex) /^[fhv]d[a-z]+[0-9]*$/ - * into the corresponding index (e.g. sda => 0, hdz => 25, vdaa => 26) - * Note that any trailing string of digits is simply ignored. - * @param name The name of the device - * @return name's index, or -1 on failure - */ -int virDiskNameToIndex(const char *name) { - const char *ptr = NULL; - int idx = 0; - static char const* const drive_prefix[] = {"fd", "hd", "vd", "sd", "xvd", "ubd"}; - unsigned int i; - - for (i = 0; i < ARRAY_CARDINALITY(drive_prefix); i++) { - if (STRPREFIX(name, drive_prefix[i])) { - ptr = name + strlen(drive_prefix[i]); - break; - } - } - - if (!ptr) - return -1; - - for (i = 0; *ptr; i++) { - if (!c_islower(*ptr)) - break; - - idx = (idx + (i < 1 ? 0 : 1)) * 26; - idx += *ptr - 'a'; - ptr++; - } - - /* Count the trailing digits. */ - size_t n_digits = strspn(ptr, "0123456789"); - if (ptr[n_digits] != '\0') - return -1; - - return idx; -} - -char *virIndexToDiskName(int idx, const char *prefix) -{ - char *name = NULL; - int i, k, offset; - - if (idx < 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("Disk index %d is negative"), idx); - return NULL; - } - - for (i = 0, k = idx; k >= 0; ++i, k = k / 26 - 1) { } - - offset = strlen(prefix); - - if (VIR_ALLOC_N(name, offset + i + 1)) { - virReportOOMError(); - return NULL; - } - - strcpy(name, prefix); - name[offset + i] = '\0'; - - for (i = i - 1, k = idx; k >= 0; --i, k = k / 26 - 1) { - name[offset + i] = 'a' + (k % 26); - } - - return name; -} - -#ifndef AI_CANONIDN -# define AI_CANONIDN 0 -#endif - -/* Who knew getting a hostname could be so delicate. In Linux (and Unices - * in general), many things depend on "hostname" returning a value that will - * resolve one way or another. In the modern world where networks frequently - * come and go this is often being hard-coded to resolve to "localhost". If - * it *doesn't* resolve to localhost, then we would prefer to have the FQDN. - * That leads us to 3 possibilities: - * - * 1) gethostname() returns an FQDN (not localhost) - we return the string - * as-is, it's all of the information we want - * 2) gethostname() returns "localhost" - we return localhost; doing further - * work to try to resolve it is pointless - * 3) gethostname() returns a shortened hostname - in this case, we want to - * try to resolve this to a fully-qualified name. Therefore we pass it - * to getaddrinfo(). There are two possible responses: - * a) getaddrinfo() resolves to a FQDN - return the FQDN - * b) getaddrinfo() fails or resolves to localhost - in this case, the - * data we got from gethostname() is actually more useful than what - * we got from getaddrinfo(). Return the value from gethostname() - * and hope for the best. - */ -char *virGetHostname(virConnectPtr conn ATTRIBUTE_UNUSED) -{ - int r; - char hostname[HOST_NAME_MAX+1], *result; - struct addrinfo hints, *info; - - r = gethostname(hostname, sizeof(hostname)); - if (r == -1) { - virReportSystemError(errno, - "%s", _("failed to determine host name")); - return NULL; - } - NUL_TERMINATE(hostname); - - if (STRPREFIX(hostname, "localhost") || strchr(hostname, '.')) { - /* in this case, gethostname returned localhost (meaning we can't - * do any further canonicalization), or it returned an FQDN (and - * we don't need to do any further canonicalization). Return the - * string as-is; it's up to callers to check whether "localhost" - * is allowed. - */ - result = strdup(hostname); - goto check_and_return; - } - - /* otherwise, it's a shortened, non-localhost, hostname. Attempt to - * canonicalize the hostname by running it through getaddrinfo - */ - - memset(&hints, 0, sizeof(hints)); - hints.ai_flags = AI_CANONNAME|AI_CANONIDN; - hints.ai_family = AF_UNSPEC; - r = getaddrinfo(hostname, NULL, &hints, &info); - if (r != 0) { - VIR_WARN("getaddrinfo failed for '%s': %s", - hostname, gai_strerror(r)); - result = strdup(hostname); - goto check_and_return; - } - - /* Tell static analyzers about getaddrinfo semantics. */ - sa_assert(info); - - if (info->ai_canonname == NULL || - STRPREFIX(info->ai_canonname, "localhost")) - /* in this case, we tried to canonicalize and we ended up back with - * localhost. Ignore the canonicalized name and just return the - * original hostname - */ - result = strdup(hostname); - else - /* Caller frees this string. */ - result = strdup(info->ai_canonname); - - freeaddrinfo(info); - -check_and_return: - if (result == NULL) - virReportOOMError(); - return result; -} - -#ifdef HAVE_GETPWUID_R -enum { - VIR_USER_ENT_DIRECTORY, - VIR_USER_ENT_NAME, -}; - -static char *virGetUserEnt(uid_t uid, - int field) -{ - char *strbuf; - char *ret; - struct passwd pwbuf; - struct passwd *pw = NULL; - long val = sysconf(_SC_GETPW_R_SIZE_MAX); - size_t strbuflen = val; - int rc; - - /* sysconf is a hint; if it fails, fall back to a reasonable size */ - if (val < 0) - strbuflen = 1024; - - if (VIR_ALLOC_N(strbuf, strbuflen) < 0) { - virReportOOMError(); - return NULL; - } - - /* - * From the manpage (terrifying but true): - * - * ERRORS - * 0 or ENOENT or ESRCH or EBADF or EPERM or ... - * The given name or uid was not found. - */ - while ((rc = getpwuid_r(uid, &pwbuf, strbuf, strbuflen, &pw)) == ERANGE) { - if (VIR_RESIZE_N(strbuf, strbuflen, strbuflen, strbuflen) < 0) { - virReportOOMError(); - VIR_FREE(strbuf); - return NULL; - } - } - if (rc != 0 || pw == NULL) { - virReportSystemError(rc, - _("Failed to find user record for uid '%u'"), - (unsigned int) uid); - VIR_FREE(strbuf); - return NULL; - } - - if (field == VIR_USER_ENT_DIRECTORY) - ret = strdup(pw->pw_dir); - else - ret = strdup(pw->pw_name); - - VIR_FREE(strbuf); - if (!ret) - virReportOOMError(); - - return ret; -} - -static char *virGetGroupEnt(gid_t gid) -{ - char *strbuf; - char *ret; - struct group grbuf; - struct group *gr = NULL; - long val = sysconf(_SC_GETGR_R_SIZE_MAX); - size_t strbuflen = val; - int rc; - - /* sysconf is a hint; if it fails, fall back to a reasonable size */ - if (val < 0) - strbuflen = 1024; - - if (VIR_ALLOC_N(strbuf, strbuflen) < 0) { - virReportOOMError(); - return NULL; - } - - /* - * From the manpage (terrifying but true): - * - * ERRORS - * 0 or ENOENT or ESRCH or EBADF or EPERM or ... - * The given name or gid was not found. - */ - while ((rc = getgrgid_r(gid, &grbuf, strbuf, strbuflen, &gr)) == ERANGE) { - if (VIR_RESIZE_N(strbuf, strbuflen, strbuflen, strbuflen) < 0) { - virReportOOMError(); - VIR_FREE(strbuf); - return NULL; - } - } - if (rc != 0 || gr == NULL) { - virReportSystemError(rc, - _("Failed to find group record for gid '%u'"), - (unsigned int) gid); - VIR_FREE(strbuf); - return NULL; - } - - ret = strdup(gr->gr_name); - - VIR_FREE(strbuf); - if (!ret) - virReportOOMError(); - - return ret; -} - -char *virGetUserDirectory(void) -{ - return virGetUserEnt(geteuid(), VIR_USER_ENT_DIRECTORY); -} - -static char *virGetXDGDirectory(const char *xdgenvname, const char *xdgdefdir) -{ - const char *path = getenv(xdgenvname); - char *ret = NULL; - char *home = virGetUserEnt(geteuid(), VIR_USER_ENT_DIRECTORY); - - if (path && path[0]) { - if (virAsprintf(&ret, "%s/libvirt", path) < 0) - goto no_memory; - } else { - if (virAsprintf(&ret, "%s/%s/libvirt", home, xdgdefdir) < 0) - goto no_memory; - } - - cleanup: - VIR_FREE(home); - return ret; - no_memory: - virReportOOMError(); - goto cleanup; -} - -char *virGetUserConfigDirectory(void) -{ - return virGetXDGDirectory("XDG_CONFIG_HOME", ".config"); -} - -char *virGetUserCacheDirectory(void) -{ - return virGetXDGDirectory("XDG_CACHE_HOME", ".cache"); -} - -char *virGetUserRuntimeDirectory(void) -{ - const char *path = getenv("XDG_RUNTIME_DIR"); - - if (!path || !path[0]) { - return virGetUserCacheDirectory(); - } else { - char *ret; - - if (virAsprintf(&ret, "%s/libvirt", path) < 0) { - virReportOOMError(); - return NULL; - } - - return ret; - } -} - -char *virGetUserName(uid_t uid) -{ - return virGetUserEnt(uid, VIR_USER_ENT_NAME); -} - -char *virGetGroupName(gid_t gid) -{ - return virGetGroupEnt(gid); -} - -/* Search in the password database for a user id that matches the user name - * `name`. Returns 0 on success, -1 on failure or 1 if name cannot be found. - */ -static int -virGetUserIDByName(const char *name, uid_t *uid) -{ - char *strbuf = NULL; - struct passwd pwbuf; - struct passwd *pw = NULL; - long val = sysconf(_SC_GETPW_R_SIZE_MAX); - size_t strbuflen = val; - int rc; - int ret = -1; - - /* sysconf is a hint; if it fails, fall back to a reasonable size */ - if (val < 0) - strbuflen = 1024; - - if (VIR_ALLOC_N(strbuf, strbuflen) < 0) { - virReportOOMError(); - goto cleanup; - } - - while ((rc = getpwnam_r(name, &pwbuf, strbuf, strbuflen, &pw)) == ERANGE) { - if (VIR_RESIZE_N(strbuf, strbuflen, strbuflen, strbuflen) < 0) { - virReportOOMError(); - goto cleanup; - } - } - - if (!pw) { - if (rc != 0) { - char buf[1024]; - /* log the possible error from getpwnam_r. Unfortunately error - * reporting from this function is bad and we can't really - * rely on it, so we just report that the user wasn't found */ - VIR_WARN("User record for user '%s' was not found: %s", - name, virStrerror(rc, buf, sizeof(buf))); - } - - ret = 1; - goto cleanup; - } - - *uid = pw->pw_uid; - ret = 0; - -cleanup: - VIR_FREE(strbuf); - - return ret; -} - -/* Try to match a user id based on `user`. The default behavior is to parse - * `user` first as a user name and then as a user id. However if `user` - * contains a leading '+', the rest of the string is always parsed as a uid. - * - * Returns 0 on success and -1 otherwise. - */ -int -virGetUserID(const char *user, uid_t *uid) -{ - unsigned int uint_uid; - - if (*user == '+') { - user++; - } else { - int rc = virGetUserIDByName(user, uid); - if (rc <= 0) - return rc; - } - - if (virStrToLong_ui(user, NULL, 10, &uint_uid) < 0 || - ((uid_t) uint_uid) != uint_uid) { - virReportError(VIR_ERR_INVALID_ARG, _("Failed to parse user '%s'"), - user); - return -1; - } - - *uid = uint_uid; - - return 0; -} - -/* Search in the group database for a group id that matches the group name - * `name`. Returns 0 on success, -1 on failure or 1 if name cannot be found. - */ -static int -virGetGroupIDByName(const char *name, gid_t *gid) -{ - char *strbuf = NULL; - struct group grbuf; - struct group *gr = NULL; - long val = sysconf(_SC_GETGR_R_SIZE_MAX); - size_t strbuflen = val; - int rc; - int ret = -1; - - /* sysconf is a hint; if it fails, fall back to a reasonable size */ - if (val < 0) - strbuflen = 1024; - - if (VIR_ALLOC_N(strbuf, strbuflen) < 0) { - virReportOOMError(); - goto cleanup; - } - - while ((rc = getgrnam_r(name, &grbuf, strbuf, strbuflen, &gr)) == ERANGE) { - if (VIR_RESIZE_N(strbuf, strbuflen, strbuflen, strbuflen) < 0) { - virReportOOMError(); - goto cleanup; - } - } - - if (!gr) { - if (rc != 0) { - char buf[1024]; - /* log the possible error from getgrnam_r. Unfortunately error - * reporting from this function is bad and we can't really - * rely on it, so we just report that the user wasn't found */ - VIR_WARN("Group record for user '%s' was not found: %s", - name, virStrerror(rc, buf, sizeof(buf))); - } - - ret = 1; - goto cleanup; - } - - *gid = gr->gr_gid; - ret = 0; - -cleanup: - VIR_FREE(strbuf); - - return ret; -} - -/* Try to match a group id based on `group`. The default behavior is to parse - * `group` first as a group name and then as a group id. However if `group` - * contains a leading '+', the rest of the string is always parsed as a guid. - * - * Returns 0 on success and -1 otherwise. - */ -int -virGetGroupID(const char *group, gid_t *gid) -{ - unsigned int uint_gid; - - if (*group == '+') { - group++; - } else { - int rc = virGetGroupIDByName(group, gid); - if (rc <= 0) - return rc; - } - - if (virStrToLong_ui(group, NULL, 10, &uint_gid) < 0 || - ((gid_t) uint_gid) != uint_gid) { - virReportError(VIR_ERR_INVALID_ARG, _("Failed to parse group '%s'"), - group); - return -1; - } - - *gid = uint_gid; - - return 0; -} - -/* Set the real and effective uid and gid to the given values, and call - * initgroups so that the process has all the assumed group membership of - * that uid. return 0 on success, -1 on failure (the original system error - * remains in errno). - */ -int -virSetUIDGID(uid_t uid, gid_t gid) -{ - int err; - char *buf = NULL; - - if (gid > 0) { - if (setregid(gid, gid) < 0) { - virReportSystemError(err = errno, - _("cannot change to '%d' group"), - (unsigned int) gid); - goto error; - } - } - - if (uid > 0) { -# ifdef HAVE_INITGROUPS - struct passwd pwd, *pwd_result; - size_t bufsize; - int rc; - - bufsize = sysconf(_SC_GETPW_R_SIZE_MAX); - if (bufsize == -1) - bufsize = 16384; - - if (VIR_ALLOC_N(buf, bufsize) < 0) { - virReportOOMError(); - err = ENOMEM; - goto error; - } - while ((rc = getpwuid_r(uid, &pwd, buf, bufsize, - &pwd_result)) == ERANGE) { - if (VIR_RESIZE_N(buf, bufsize, bufsize, bufsize) < 0) { - virReportOOMError(); - err = ENOMEM; - goto error; - } - } - - if (rc) { - virReportSystemError(err = rc, _("cannot getpwuid_r(%d)"), - (unsigned int) uid); - goto error; - } - - if (!pwd_result) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("getpwuid_r failed to retrieve data " - "for uid '%d'"), - (unsigned int) uid); - err = EINVAL; - goto error; - } - - if (initgroups(pwd.pw_name, pwd.pw_gid) < 0) { - virReportSystemError(err = errno, - _("cannot initgroups(\"%s\", %d)"), - pwd.pw_name, (unsigned int) pwd.pw_gid); - goto error; - } -# endif - if (setreuid(uid, uid) < 0) { - virReportSystemError(err = errno, - _("cannot change to uid to '%d'"), - (unsigned int) uid); - goto error; - } - } - - VIR_FREE(buf); - return 0; - -error: - VIR_FREE(buf); - errno = err; - return -1; -} - -#else /* ! HAVE_GETPWUID_R */ - -# ifdef WIN32 -/* These methods are adapted from GLib2 under terms of LGPLv2+ */ -static int -virGetWin32SpecialFolder(int csidl, char **path) -{ - char buf[MAX_PATH+1]; - LPITEMIDLIST pidl = NULL; - int ret = 0; - - *path = NULL; - - if (SHGetSpecialFolderLocation(NULL, csidl, &pidl) == S_OK) { - if (SHGetPathFromIDList(pidl, buf)) { - if (!(*path = strdup(buf))) { - virReportOOMError(); - ret = -1; - } - } - CoTaskMemFree(pidl); - } - return ret; -} - -static int -virGetWin32DirectoryRoot(char **path) -{ - char windowsdir[MAX_PATH]; - int ret = 0; - - *path = NULL; - - if (GetWindowsDirectory(windowsdir, ARRAY_CARDINALITY(windowsdir))) - { - const char *tmp; - /* Usually X:\Windows, but in terminal server environments - * might be an UNC path, AFAIK. - */ - tmp = virFileSkipRoot(windowsdir); - if (VIR_FILE_IS_DIR_SEPARATOR(tmp[-1]) && - tmp[-2] != ':') - tmp--; - - windowsdir[tmp - windowsdir] = '\0'; - } else { - strcpy(windowsdir, "C:\\"); - } - - if (!(*path = strdup(windowsdir))) { - virReportOOMError(); - ret = -1; - } - - return ret; -} - - - -char * -virGetUserDirectory(void) -{ - const char *dir; - char *ret; - - dir = getenv("HOME"); - - /* Only believe HOME if it is an absolute path and exists */ - if (dir) { - if (!virFileIsAbsPath(dir) || - !virFileExists(dir)) - dir = NULL; - } - - /* In case HOME is Unix-style (it happens), convert it to - * Windows style. - */ - if (dir) { - char *p; - while ((p = strchr(dir, '/')) != NULL) - *p = '\\'; - } - - if (!dir) - /* USERPROFILE is probably the closest equivalent to $HOME? */ - dir = getenv("USERPROFILE"); - - if (dir) { - if (!(ret = strdup(dir))) { - virReportOOMError(); - return NULL; - } - } - - if (!ret && - virGetWin32SpecialFolder(CSIDL_PROFILE, &ret) < 0) - return NULL; - - if (!ret && - virGetWin32DirectoryRoot(&ret) < 0) - return NULL; - - if (!ret) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("Unable to determine home directory")); - return NULL; - } - - return ret; -} - -char * -virGetUserConfigDirectory(void) -{ - char *ret; - if (virGetWin32SpecialFolder(CSIDL_LOCAL_APPDATA, &ret) < 0) - return NULL; - - if (!ret) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("Unable to determine config directory")); - return NULL; - } - return ret; -} - -char * -virGetUserCacheDirectory(void) -{ - char *ret; - if (virGetWin32SpecialFolder(CSIDL_INTERNET_CACHE, &ret) < 0) - return NULL; - - if (!ret) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("Unable to determine config directory")); - return NULL; - } - return ret; -} - -char * -virGetUserRuntimeDirectory(void) -{ - return virGetUserCacheDirectory(); -} -# else /* !HAVE_GETPWUID_R && !WIN32 */ -char * -virGetUserDirectory(void) -{ - virReportError(VIR_ERR_INTERNAL_ERROR, - "%s", _("virGetUserDirectory is not available")); - - return NULL; -} - -char * -virGetUserConfigDirectory(void) -{ - virReportError(VIR_ERR_INTERNAL_ERROR, - "%s", _("virGetUserConfigDirectory is not available")); - - return NULL; -} - -char * -virGetUserCacheDirectory(void) -{ - virReportError(VIR_ERR_INTERNAL_ERROR, - "%s", _("virGetUserCacheDirectory is not available")); - - return NULL; -} - -char * -virGetUserRuntimeDirectory(void) -{ - virReportError(VIR_ERR_INTERNAL_ERROR, - "%s", _("virGetUserRuntimeDirectory is not available")); - - return NULL; -} -# endif /* ! HAVE_GETPWUID_R && ! WIN32 */ - -char * -virGetUserName(uid_t uid ATTRIBUTE_UNUSED) -{ - virReportError(VIR_ERR_INTERNAL_ERROR, - "%s", _("virGetUserName is not available")); - - return NULL; -} - -int virGetUserID(const char *name ATTRIBUTE_UNUSED, - uid_t *uid ATTRIBUTE_UNUSED) -{ - virReportError(VIR_ERR_INTERNAL_ERROR, - "%s", _("virGetUserID is not available")); - - return 0; -} - - -int virGetGroupID(const char *name ATTRIBUTE_UNUSED, - gid_t *gid ATTRIBUTE_UNUSED) -{ - virReportError(VIR_ERR_INTERNAL_ERROR, - "%s", _("virGetGroupID is not available")); - - return 0; -} - -int -virSetUIDGID(uid_t uid ATTRIBUTE_UNUSED, - gid_t gid ATTRIBUTE_UNUSED) -{ - virReportError(VIR_ERR_INTERNAL_ERROR, - "%s", _("virSetUIDGID is not available")); - return -1; -} - -char * -virGetGroupName(gid_t gid ATTRIBUTE_UNUSED) -{ - virReportError(VIR_ERR_INTERNAL_ERROR, - "%s", _("virGetGroupName is not available")); - - return NULL; -} -#endif /* HAVE_GETPWUID_R */ - - -#if defined HAVE_MNTENT_H && defined HAVE_GETMNTENT_R -/* search /proc/mounts for mount point of *type; return pointer to - * malloc'ed string of the path if found, otherwise return NULL - * with errno set to an appropriate value. - */ -char *virFileFindMountPoint(const char *type) -{ - FILE *f; - struct mntent mb; - char mntbuf[1024]; - char *ret = NULL; - - f = setmntent("/proc/mounts", "r"); - if (!f) - return NULL; - - while (getmntent_r(f, &mb, mntbuf, sizeof(mntbuf))) { - if (STREQ(mb.mnt_type, type)) { - ret = strdup(mb.mnt_dir); - goto cleanup; - } - } - - if (!ret) - errno = ENOENT; - -cleanup: - endmntent(f); - - return ret; -} - -#else /* defined HAVE_MNTENT_H && defined HAVE_GETMNTENT_R */ - -char * -virFileFindMountPoint(const char *type ATTRIBUTE_UNUSED) -{ - errno = ENOSYS; - - return NULL; -} - -#endif /* defined HAVE_MNTENT_H && defined HAVE_GETMNTENT_R */ - -#if defined(UDEVADM) || defined(UDEVSETTLE) -void virFileWaitForDevices(void) -{ -# ifdef UDEVADM - const char *const settleprog[] = { UDEVADM, "settle", NULL }; -# else - const char *const settleprog[] = { UDEVSETTLE, NULL }; -# endif - int exitstatus; - - if (access(settleprog[0], X_OK) != 0) - return; - - /* - * NOTE: we ignore errors here; this is just to make sure that any device - * nodes that are being created finish before we try to scan them. - * If this fails for any reason, we still have the backup of polling for - * 5 seconds for device nodes. - */ - if (virRun(settleprog, &exitstatus) < 0) - {} -} -#else -void virFileWaitForDevices(void) {} -#endif - -int virBuildPathInternal(char **path, ...) -{ - char *path_component = NULL; - virBuffer buf = VIR_BUFFER_INITIALIZER; - va_list ap; - int ret = 0; - - va_start(ap, path); - - path_component = va_arg(ap, char *); - virBufferAdd(&buf, path_component, -1); - - while ((path_component = va_arg(ap, char *)) != NULL) - { - virBufferAddChar(&buf, '/'); - virBufferAdd(&buf, path_component, -1); - } - - va_end(ap); - - *path = virBufferContentAndReset(&buf); - if (*path == NULL) { - ret = -1; - } - - return ret; -} - -#if HAVE_LIBDEVMAPPER_H -bool -virIsDevMapperDevice(const char *dev_name) -{ - struct stat buf; - - if (!stat(dev_name, &buf) && - S_ISBLK(buf.st_mode) && - dm_is_dm_major(major(buf.st_rdev))) - return true; - - return false; -} -#else -bool virIsDevMapperDevice(const char *dev_name ATTRIBUTE_UNUSED) -{ - return false; -} -#endif - -bool -virValidateWWN(const char *wwn) { - int i; - - for (i = 0; wwn[i]; i++) - if (!c_isxdigit(wwn[i])) - break; - - if (i != 16 || wwn[i]) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("Malformed wwn: %s")); - return false; - } - - return true; -} - -bool -virStrIsPrint(const char *str) -{ - int i; - - for (i = 0; str[i]; i++) - if (!c_isprint(str[i])) - return false; - - return true; -} diff --git a/src/util/util.h b/src/util/util.h deleted file mode 100644 index 6d5dd03..0000000 --- a/src/util/util.h +++ /dev/null @@ -1,284 +0,0 @@ -/* - * utils.h: common, generic utility functions - * - * Copyright (C) 2010-2012 Red Hat, Inc. - * Copyright (C) 2006, 2007 Binary Karma - * Copyright (C) 2006 Shuveb Hussain - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see - * <http://www.gnu.org/licenses/>. - * - * File created Jul 18, 2007 - Shuveb Hussain <shuveb@xxxxxxxxxxxxxxx> - */ - -#ifndef __VIR_UTIL_H__ -# define __VIR_UTIL_H__ - -# include "verify.h" -# include "internal.h" -# include <unistd.h> -# include <sys/select.h> -# include <sys/types.h> -# include <stdarg.h> - -# ifndef MIN -# define MIN(a, b) ((a) < (b) ? (a) : (b)) -# endif -# ifndef MAX -# define MAX(a, b) ((a) > (b) ? (a) : (b)) -# endif - -ssize_t saferead(int fd, void *buf, size_t count) ATTRIBUTE_RETURN_CHECK; -ssize_t safewrite(int fd, const void *buf, size_t count) - ATTRIBUTE_RETURN_CHECK; -int safezero(int fd, off_t offset, off_t len) - ATTRIBUTE_RETURN_CHECK; - -int virSetBlocking(int fd, bool blocking) ATTRIBUTE_RETURN_CHECK; -int virSetNonBlock(int fd) ATTRIBUTE_RETURN_CHECK; -int virSetInherit(int fd, bool inherit) ATTRIBUTE_RETURN_CHECK; -int virSetCloseExec(int fd) ATTRIBUTE_RETURN_CHECK; - -int virPipeReadUntilEOF(int outfd, int errfd, - char **outbuf, char **errbuf); - -int virSetUIDGID(uid_t uid, gid_t gid); - -int virFileReadLimFD(int fd, int maxlen, char **buf) ATTRIBUTE_RETURN_CHECK; - -int virFileReadAll(const char *path, int maxlen, char **buf) ATTRIBUTE_RETURN_CHECK; - -int virFileWriteStr(const char *path, const char *str, mode_t mode) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; - -int virFileMatchesNameSuffix(const char *file, - const char *name, - const char *suffix); - -int virFileHasSuffix(const char *str, - const char *suffix); - -int virFileStripSuffix(char *str, - const char *suffix) ATTRIBUTE_RETURN_CHECK; - -int virFileLinkPointsTo(const char *checkLink, - const char *checkDest); - -int virFileResolveLink(const char *linkpath, - char **resultpath) ATTRIBUTE_RETURN_CHECK; -int virFileResolveAllLinks(const char *linkpath, - char **resultpath) ATTRIBUTE_RETURN_CHECK; - -int virFileIsLink(const char *linkpath) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; - -char *virFindFileInPath(const char *file); - -bool virFileIsDir (const char *file) ATTRIBUTE_NONNULL(1); -bool virFileExists(const char *file) ATTRIBUTE_NONNULL(1); -bool virFileIsExecutable(const char *file) ATTRIBUTE_NONNULL(1); - -char *virFileSanitizePath(const char *path); - -enum { - VIR_FILE_OPEN_NONE = 0, - VIR_FILE_OPEN_NOFORK = (1 << 0), - VIR_FILE_OPEN_FORK = (1 << 1), - VIR_FILE_OPEN_FORCE_MODE = (1 << 2), - VIR_FILE_OPEN_FORCE_OWNER = (1 << 3), -}; -int virFileAccessibleAs(const char *path, int mode, - uid_t uid, gid_t gid) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; -int virFileOpenAs(const char *path, int openflags, mode_t mode, - uid_t uid, gid_t gid, - unsigned int flags) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; - -enum { - VIR_DIR_CREATE_NONE = 0, - VIR_DIR_CREATE_AS_UID = (1 << 0), - VIR_DIR_CREATE_FORCE_PERMS = (1 << 1), - VIR_DIR_CREATE_ALLOW_EXIST = (1 << 2), -}; -int virDirCreate(const char *path, mode_t mode, uid_t uid, gid_t gid, - unsigned int flags) ATTRIBUTE_RETURN_CHECK; -int virFileMakePath(const char *path) ATTRIBUTE_RETURN_CHECK; -int virFileMakePathWithMode(const char *path, - mode_t mode) ATTRIBUTE_RETURN_CHECK; - -char *virFileBuildPath(const char *dir, - const char *name, - const char *ext) ATTRIBUTE_RETURN_CHECK; - - -# ifdef WIN32 -/* On Win32, the canonical directory separator is the backslash, and - * the search path separator is the semicolon. Note that also the - * (forward) slash works as directory separator. - */ -# define VIR_FILE_DIR_SEPARATOR '\\' -# define VIR_FILE_DIR_SEPARATOR_S "\\" -# define VIR_FILE_IS_DIR_SEPARATOR(c) ((c) == VIR_FILE_DIR_SEPARATOR || (c) == '/') -# define VIR_FILE_PATH_SEPARATOR ';' -# define VIR_FILE_PATH_SEPARATOR_S ";" - -# else /* !WIN32 */ - -# define VIR_FILE_DIR_SEPARATOR '/' -# define VIR_FILE_DIR_SEPARATOR_S "/" -# define VIR_FILE_IS_DIR_SEPARATOR(c) ((c) == VIR_FILE_DIR_SEPARATOR) -# define VIR_FILE_PATH_SEPARATOR ':' -# define VIR_FILE_PATH_SEPARATOR_S ":" - -# endif /* !WIN32 */ - -bool virFileIsAbsPath(const char *path); -int virFileAbsPath(const char *path, - char **abspath) ATTRIBUTE_RETURN_CHECK; -const char *virFileSkipRoot(const char *path); - -int virFileOpenTty(int *ttymaster, - char **ttyName, - int rawmode); - -char *virArgvToString(const char *const *argv); - -int virStrToLong_i(char const *s, - char **end_ptr, - int base, - int *result); - -int virStrToLong_ui(char const *s, - char **end_ptr, - int base, - unsigned int *result); -int virStrToLong_l(char const *s, - char **end_ptr, - int base, - long *result); -int virStrToLong_ul(char const *s, - char **end_ptr, - int base, - unsigned long *result); -int virStrToLong_ll(char const *s, - char **end_ptr, - int base, - long long *result); -int virStrToLong_ull(char const *s, - char **end_ptr, - int base, - unsigned long long *result); -int virStrToDouble(char const *s, - char **end_ptr, - double *result); - -int virScaleInteger(unsigned long long *value, const char *suffix, - unsigned long long scale, unsigned long long limit) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; - -int virHexToBin(unsigned char c); - -void virSkipSpaces(const char **str) ATTRIBUTE_NONNULL(1); -void virSkipSpacesAndBackslash(const char **str) ATTRIBUTE_NONNULL(1); -void virTrimSpaces(char *str, char **endp) ATTRIBUTE_NONNULL(1); -void virSkipSpacesBackwards(const char *str, char **endp) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); - -int virParseNumber(const char **str); -int virParseVersionString(const char *str, unsigned long *version, - bool allowMissing); -int virAsprintf(char **strp, const char *fmt, ...) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_FMT_PRINTF(2, 3); -int virVasprintf(char **strp, const char *fmt, va_list list) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_FMT_PRINTF(2, 0); -char *virStrncpy(char *dest, const char *src, size_t n, size_t destbytes) - ATTRIBUTE_RETURN_CHECK; -char *virStrcpy(char *dest, const char *src, size_t destbytes) - ATTRIBUTE_RETURN_CHECK; -# define virStrcpyStatic(dest, src) virStrcpy((dest), (src), sizeof(dest)) - -int virDoubleToStr(char **strp, double number) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; - -char *virFormatIntDecimal(char *buf, size_t buflen, int val) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; - -int virDiskNameToIndex(const char* str); -char *virIndexToDiskName(int idx, const char *prefix); - -int virEnumFromString(const char *const*types, - unsigned int ntypes, - const char *type); - -const char *virEnumToString(const char *const*types, - unsigned int ntypes, - int type); - -# define VIR_ENUM_IMPL(name, lastVal, ...) \ - static const char *const name ## TypeList[] = { __VA_ARGS__ }; \ - verify(ARRAY_CARDINALITY(name ## TypeList) == lastVal); \ - const char *name ## TypeToString(int type) { \ - return virEnumToString(name ## TypeList, \ - ARRAY_CARDINALITY(name ## TypeList), \ - type); \ - } \ - int name ## TypeFromString(const char *type) { \ - return virEnumFromString(name ## TypeList, \ - ARRAY_CARDINALITY(name ## TypeList), \ - type); \ - } - -# define VIR_ENUM_DECL(name) \ - const char *name ## TypeToString(int type); \ - int name ## TypeFromString(const char*type); - -# ifndef HAVE_GETUID -static inline int getuid (void) { return 0; } -# endif - -# ifndef HAVE_GETEUID -static inline int geteuid (void) { return 0; } -# endif - -# ifndef HAVE_GETGID -static inline int getgid (void) { return 0; } -# endif - -char *virGetHostname(virConnectPtr conn); - -char *virGetUserDirectory(void); -char *virGetUserConfigDirectory(void); -char *virGetUserCacheDirectory(void); -char *virGetUserRuntimeDirectory(void); -char *virGetUserName(uid_t uid); -char *virGetGroupName(gid_t gid); -int virGetUserID(const char *name, - uid_t *uid) ATTRIBUTE_RETURN_CHECK; -int virGetGroupID(const char *name, - gid_t *gid) ATTRIBUTE_RETURN_CHECK; - -char *virFileFindMountPoint(const char *type); - -void virFileWaitForDevices(void); - -# define virBuildPath(path, ...) virBuildPathInternal(path, __VA_ARGS__, NULL) -int virBuildPathInternal(char **path, ...) ATTRIBUTE_SENTINEL; - -bool virIsDevMapperDevice(const char *dev_name) ATTRIBUTE_NONNULL(1); - -bool virValidateWWN(const char *wwn); - -bool virStrIsPrint(const char *str); -#endif /* __VIR_UTIL_H__ */ diff --git a/src/util/uuid.c b/src/util/uuid.c index 5232ba9..57cfaa6 100644 --- a/src/util/uuid.c +++ b/src/util/uuid.c @@ -35,7 +35,7 @@ #include "c-ctype.h" #include "internal.h" -#include "util.h" +#include "virutil.h" #include "virterror_internal.h" #include "virlog.h" #include "viralloc.h" diff --git a/src/util/viraudit.c b/src/util/viraudit.c index a807b76..05189d5 100644 --- a/src/util/viraudit.c +++ b/src/util/viraudit.c @@ -30,7 +30,7 @@ #include "virterror_internal.h" #include "virlog.h" #include "viraudit.h" -#include "util.h" +#include "virutil.h" #include "virfile.h" #include "viralloc.h" diff --git a/src/util/virauth.c b/src/util/virauth.c index c4c5676..cbb16ec 100644 --- a/src/util/virauth.c +++ b/src/util/virauth.c @@ -25,7 +25,7 @@ #include <stdlib.h> #include "virauth.h" -#include "util.h" +#include "virutil.h" #include "viralloc.h" #include "virlog.h" #include "datatypes.h" diff --git a/src/util/virauthconfig.c b/src/util/virauthconfig.c index a0f0be5..d60f7bf 100644 --- a/src/util/virauthconfig.c +++ b/src/util/virauthconfig.c @@ -26,7 +26,7 @@ #include "virkeyfile.h" #include "viralloc.h" -#include "util.h" +#include "virutil.h" #include "virlog.h" #include "virterror_internal.h" diff --git a/src/util/virbitmap.c b/src/util/virbitmap.c index cb9606b..b4ba3ef 100644 --- a/src/util/virbitmap.c +++ b/src/util/virbitmap.c @@ -33,7 +33,7 @@ #include "virbitmap.h" #include "viralloc.h" #include "virbuffer.h" -#include "util.h" +#include "virutil.h" #include "c-ctype.h" #include "count-one-bits.h" diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c index 5c628cc..48cba93 100644 --- a/src/util/vircgroup.c +++ b/src/util/vircgroup.c @@ -38,7 +38,7 @@ #include <dirent.h> #include "internal.h" -#include "util.h" +#include "virutil.h" #include "viralloc.h" #include "vircgroup.h" #include "virlog.h" diff --git a/src/util/vircommand.c b/src/util/vircommand.c index 6e17a8d..d059586 100644 --- a/src/util/vircommand.c +++ b/src/util/vircommand.c @@ -36,7 +36,7 @@ #include "vircommand.h" #include "viralloc.h" #include "virterror_internal.h" -#include "util.h" +#include "virutil.h" #include "virlog.h" #include "virfile.h" #include "virpidfile.h" diff --git a/src/util/vircommand.h b/src/util/vircommand.h index 4c88165..9b7117d 100644 --- a/src/util/vircommand.h +++ b/src/util/vircommand.h @@ -23,7 +23,7 @@ # define __VIR_COMMAND_H__ # include "internal.h" -# include "util.h" +# include "virutil.h" # include "virbuffer.h" typedef struct _virCommand virCommand; diff --git a/src/util/virconf.c b/src/util/virconf.c index 2f6d60e..7e4c8c1 100644 --- a/src/util/virconf.c +++ b/src/util/virconf.c @@ -33,7 +33,7 @@ #include "virterror_internal.h" #include "virbuffer.h" #include "virconf.h" -#include "util.h" +#include "virutil.h" #include "c-ctype.h" #include "virlog.h" #include "viralloc.h" diff --git a/src/util/virdnsmasq.c b/src/util/virdnsmasq.c index 918610a..6b9abd9 100644 --- a/src/util/virdnsmasq.c +++ b/src/util/virdnsmasq.c @@ -41,7 +41,7 @@ #include "datatypes.h" #include "virbitmap.h" #include "virdnsmasq.h" -#include "util.h" +#include "virutil.h" #include "vircommand.h" #include "viralloc.h" #include "virterror_internal.h" diff --git a/src/util/vireventpoll.c b/src/util/vireventpoll.c index 1180fda..afb0e05 100644 --- a/src/util/vireventpoll.c +++ b/src/util/vireventpoll.c @@ -35,7 +35,7 @@ #include "virlog.h" #include "vireventpoll.h" #include "viralloc.h" -#include "util.h" +#include "virutil.h" #include "virfile.h" #include "virterror_internal.h" #include "virtime.h" diff --git a/src/util/virhooks.c b/src/util/virhooks.c index ad3a371..54a869a 100644 --- a/src/util/virhooks.c +++ b/src/util/virhooks.c @@ -32,7 +32,7 @@ #include "virterror_internal.h" #include "virhooks.h" -#include "util.h" +#include "virutil.h" #include "virlog.h" #include "viralloc.h" #include "virfile.h" diff --git a/src/util/virhooks.h b/src/util/virhooks.h index 0ca376f..56573df 100644 --- a/src/util/virhooks.h +++ b/src/util/virhooks.h @@ -25,7 +25,7 @@ # define __VIR_HOOKS_H__ # include "internal.h" -# include "util.h" +# include "virutil.h" enum virHookDriverType { VIR_HOOK_DRIVER_DAEMON = 0, /* Daemon related events */ diff --git a/src/util/virinitctl.c b/src/util/virinitctl.c index 91a948f..f8ac673 100644 --- a/src/util/virinitctl.c +++ b/src/util/virinitctl.c @@ -29,7 +29,7 @@ #include "internal.h" #include "virinitctl.h" #include "virterror_internal.h" -#include "util.h" +#include "virutil.h" #include "viralloc.h" #include "virfile.h" diff --git a/src/util/virjson.c b/src/util/virjson.c index 4fa5363..4c9797c 100644 --- a/src/util/virjson.c +++ b/src/util/virjson.c @@ -27,7 +27,7 @@ #include "viralloc.h" #include "virterror_internal.h" #include "virlog.h" -#include "util.h" +#include "virutil.h" #if HAVE_YAJL # include <yajl/yajl_gen.h> diff --git a/src/util/virkeycode.h b/src/util/virkeycode.h index 1522f77..a2e1391 100644 --- a/src/util/virkeycode.h +++ b/src/util/virkeycode.h @@ -22,7 +22,7 @@ #ifndef __VIR_UTIL_VIRTKEYCODE_H__ # define __VIR_UTIL_VIRTKEYCODE_H__ -# include "util.h" +# include "virutil.h" # include "libvirt/libvirt.h" VIR_ENUM_DECL(virKeycodeSet); diff --git a/src/util/virkeyfile.c b/src/util/virkeyfile.c index fc61cf5..99e5cd7 100644 --- a/src/util/virkeyfile.c +++ b/src/util/virkeyfile.c @@ -28,7 +28,7 @@ #include "c-ctype.h" #include "virlog.h" #include "viralloc.h" -#include "util.h" +#include "virutil.h" #include "virhash.h" #include "virkeyfile.h" #include "virterror_internal.h" diff --git a/src/util/virlockspace.c b/src/util/virlockspace.c index 961e171..81a1d81 100644 --- a/src/util/virlockspace.c +++ b/src/util/virlockspace.c @@ -25,7 +25,7 @@ #include "virlog.h" #include "viralloc.h" #include "virterror_internal.h" -#include "util.h" +#include "virutil.h" #include "virfile.h" #include "virhash.h" #include "virthread.h" diff --git a/src/util/virlog.c b/src/util/virlog.c index 0c6c13a..43a59b4 100644 --- a/src/util/virlog.c +++ b/src/util/virlog.c @@ -43,7 +43,7 @@ #include "virterror_internal.h" #include "virlog.h" #include "viralloc.h" -#include "util.h" +#include "virutil.h" #include "virbuffer.h" #include "virthread.h" #include "virfile.h" diff --git a/src/util/virnetdevbridge.c b/src/util/virnetdevbridge.c index eb341a2..4de88e3 100644 --- a/src/util/virnetdevbridge.c +++ b/src/util/virnetdevbridge.c @@ -24,7 +24,7 @@ #include "virnetdevbridge.h" #include "virterror_internal.h" -#include "util.h" +#include "virutil.h" #include "virfile.h" #include "viralloc.h" #include "intprops.h" diff --git a/src/util/virnetdevmacvlan.c b/src/util/virnetdevmacvlan.c index 0f7107b..953d76b 100644 --- a/src/util/virnetdevmacvlan.c +++ b/src/util/virnetdevmacvlan.c @@ -29,7 +29,7 @@ #include "virnetdevmacvlan.h" #include "virmacaddr.h" -#include "util.h" +#include "virutil.h" #include "virterror_internal.h" #define VIR_FROM_THIS VIR_FROM_NET diff --git a/src/util/virnetdevopenvswitch.h b/src/util/virnetdevopenvswitch.h index 147cd6f..3216ea0 100644 --- a/src/util/virnetdevopenvswitch.h +++ b/src/util/virnetdevopenvswitch.h @@ -25,7 +25,7 @@ # define __VIR_NETDEV_OPENVSWITCH_H__ # include "internal.h" -# include "util.h" +# include "virutil.h" # include "virnetdevvportprofile.h" # include "virnetdevvlan.h" diff --git a/src/util/virnetdevtap.c b/src/util/virnetdevtap.c index 339d636..3565bbd 100644 --- a/src/util/virnetdevtap.c +++ b/src/util/virnetdevtap.c @@ -32,7 +32,7 @@ #include "virterror_internal.h" #include "viralloc.h" #include "virlog.h" -#include "util.h" +#include "virutil.h" #include <sys/ioctl.h> #include <net/if.h> diff --git a/src/util/virnetdevvportprofile.h b/src/util/virnetdevvportprofile.h index c4585a8..cc106b8 100644 --- a/src/util/virnetdevvportprofile.h +++ b/src/util/virnetdevvportprofile.h @@ -25,7 +25,7 @@ # include "internal.h" # include "uuid.h" -# include "util.h" +# include "virutil.h" # include "virmacaddr.h" # define LIBVIRT_IFLA_VF_PORT_PROFILE_MAX 40 diff --git a/src/util/virpidfile.c b/src/util/virpidfile.c index 3b3322b..29097e3 100644 --- a/src/util/virpidfile.c +++ b/src/util/virpidfile.c @@ -30,7 +30,7 @@ #include "virpidfile.h" #include "virfile.h" #include "viralloc.h" -#include "util.h" +#include "virutil.h" #include "intprops.h" #include "virlog.h" #include "virterror_internal.h" diff --git a/src/util/virprocess.c b/src/util/virprocess.c index 155e4e2..b276643 100644 --- a/src/util/virprocess.c +++ b/src/util/virprocess.c @@ -31,7 +31,7 @@ #include "virterror_internal.h" #include "viralloc.h" #include "virlog.h" -#include "util.h" +#include "virutil.h" #define VIR_FROM_THIS VIR_FROM_NONE diff --git a/src/util/virrandom.c b/src/util/virrandom.c index 1dd96cf..1b6de6b 100644 --- a/src/util/virrandom.c +++ b/src/util/virrandom.c @@ -29,7 +29,7 @@ #include "virrandom.h" #include "virthread.h" #include "count-one-bits.h" -#include "util.h" +#include "virutil.h" #include "virterror_internal.h" #include "virlog.h" diff --git a/src/util/virsexpr.c b/src/util/virsexpr.c index 80c24c4..8b70404 100644 --- a/src/util/virsexpr.c +++ b/src/util/virsexpr.c @@ -19,7 +19,7 @@ #include "virterror_internal.h" #include "virsexpr.h" -#include "util.h" +#include "virutil.h" #include "viralloc.h" #define VIR_FROM_THIS VIR_FROM_SEXPR diff --git a/src/util/virsocketaddr.c b/src/util/virsocketaddr.c index 488ff4b..0f2f23d 100644 --- a/src/util/virsocketaddr.c +++ b/src/util/virsocketaddr.c @@ -25,7 +25,7 @@ #include "virsocketaddr.h" #include "virterror_internal.h" -#include "util.h" +#include "virutil.h" #include <netdb.h> diff --git a/src/util/virstatslinux.c b/src/util/virstatslinux.c index 9359db9..135df75 100644 --- a/src/util/virstatslinux.c +++ b/src/util/virstatslinux.c @@ -34,7 +34,7 @@ # include "virterror_internal.h" # include "datatypes.h" -# include "util.h" +# include "virutil.h" # include "virstatslinux.h" # include "viralloc.h" # include "virfile.h" diff --git a/src/util/virstoragefile.h b/src/util/virstoragefile.h index 6fbd275..abf319a 100644 --- a/src/util/virstoragefile.h +++ b/src/util/virstoragefile.h @@ -24,7 +24,7 @@ #ifndef __VIR_STORAGE_FILE_H__ # define __VIR_STORAGE_FILE_H__ -# include "util.h" +# include "virutil.h" enum virStorageFileFormat { VIR_STORAGE_FILE_AUTO_SAFE = -2, diff --git a/src/util/virsysinfo.c b/src/util/virsysinfo.c index 13d3c22..88e4f5c 100644 --- a/src/util/virsysinfo.c +++ b/src/util/virsysinfo.c @@ -32,7 +32,7 @@ #include "virterror_internal.h" #include "virsysinfo.h" -#include "util.h" +#include "virutil.h" #include "virlog.h" #include "viralloc.h" #include "vircommand.h" diff --git a/src/util/virsysinfo.h b/src/util/virsysinfo.h index 0b1f000..dded51b 100644 --- a/src/util/virsysinfo.h +++ b/src/util/virsysinfo.h @@ -25,7 +25,7 @@ # define __VIR_SYSINFOS_H__ # include "internal.h" -# include "util.h" +# include "virutil.h" # include "virbuffer.h" enum virSysinfoType { diff --git a/src/util/virterror.c b/src/util/virterror.c index 6c773d3..a586738 100644 --- a/src/util/virterror.c +++ b/src/util/virterror.c @@ -32,7 +32,7 @@ #include "virlog.h" #include "viralloc.h" #include "virthread.h" -#include "util.h" +#include "virutil.h" virThreadLocal virLastErr; diff --git a/src/util/virtime.c b/src/util/virtime.c index f9fc282..c614380 100644 --- a/src/util/virtime.c +++ b/src/util/virtime.c @@ -37,7 +37,7 @@ #include <sys/time.h> #include "virtime.h" -#include "util.h" +#include "virutil.h" #include "viralloc.h" #include "virterror_internal.h" diff --git a/src/util/virtypedparam.c b/src/util/virtypedparam.c index e08530e..60fb485 100644 --- a/src/util/virtypedparam.c +++ b/src/util/virtypedparam.c @@ -25,7 +25,7 @@ #include <stdarg.h> #include "viralloc.h" -#include "util.h" +#include "virutil.h" #include "virterror_internal.h" #define VIR_FROM_THIS VIR_FROM_NONE diff --git a/src/util/viruri.c b/src/util/viruri.c index f48079d..e59cd5a 100644 --- a/src/util/viruri.c +++ b/src/util/viruri.c @@ -23,7 +23,7 @@ #include "viruri.h" #include "viralloc.h" -#include "util.h" +#include "virutil.h" #include "virterror_internal.h" #include "virbuffer.h" diff --git a/src/util/virusb.c b/src/util/virusb.c index 9786e86..c053c44 100644 --- a/src/util/virusb.c +++ b/src/util/virusb.c @@ -34,7 +34,7 @@ #include "virusb.h" #include "virlog.h" #include "viralloc.h" -#include "util.h" +#include "virutil.h" #include "virterror_internal.h" #define USB_SYSFS "/sys/bus/usb" diff --git a/src/util/virutil.c b/src/util/virutil.c new file mode 100644 index 0000000..9fb1c6f --- /dev/null +++ b/src/util/virutil.c @@ -0,0 +1,3131 @@ +/* + * utils.c: common, generic utility functions + * + * Copyright (C) 2006-2012 Red Hat, Inc. + * Copyright (C) 2006 Daniel P. Berrange + * Copyright (C) 2006, 2007 Binary Karma + * Copyright (C) 2006 Shuveb Hussain + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <http://www.gnu.org/licenses/>. + * + * Author: Daniel P. Berrange <berrange@xxxxxxxxxx> + * File created Jul 18, 2007 - Shuveb Hussain <shuveb@xxxxxxxxxxxxxxx> + */ + +#include <config.h> + +#include <stdio.h> +#include <stdarg.h> +#include <stdlib.h> +#include <unistd.h> +#include <fcntl.h> +#include <errno.h> +#include <poll.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <sys/ioctl.h> +#include <sys/wait.h> +#if HAVE_MMAP +# include <sys/mman.h> +#endif +#include <string.h> +#include <signal.h> +#include <termios.h> +#include <pty.h> +#include <locale.h> + +#if HAVE_LIBDEVMAPPER_H +# include <libdevmapper.h> +#endif + +#ifdef HAVE_PATHS_H +# include <paths.h> +#endif +#include <netdb.h> +#ifdef HAVE_GETPWUID_R +# include <pwd.h> +# include <grp.h> +#endif +#if HAVE_CAPNG +# include <cap-ng.h> +#endif +#if defined HAVE_MNTENT_H && defined HAVE_GETMNTENT_R +# include <mntent.h> +#endif + +#ifdef WIN32 +# ifdef HAVE_WINSOCK2_H +# include <winsock2.h> +# endif +# include <windows.h> +# include <shlobj.h> +#endif + +#include "c-ctype.h" +#include "dirname.h" +#include "virterror_internal.h" +#include "virlog.h" +#include "virbuffer.h" +#include "virutil.h" +#include "virstoragefile.h" +#include "viralloc.h" +#include "virthread.h" +#include "verify.h" +#include "virfile.h" +#include "vircommand.h" +#include "nonblocking.h" +#include "passfd.h" +#include "virprocess.h" + +#ifndef NSIG +# define NSIG 32 +#endif + +verify(sizeof(gid_t) <= sizeof(unsigned int) && + sizeof(uid_t) <= sizeof(unsigned int)); + +#define VIR_FROM_THIS VIR_FROM_NONE + +/* Like read(), but restarts after EINTR */ +ssize_t +saferead(int fd, void *buf, size_t count) +{ + size_t nread = 0; + while (count > 0) { + ssize_t r = read(fd, buf, count); + if (r < 0 && errno == EINTR) + continue; + if (r < 0) + return r; + if (r == 0) + return nread; + buf = (char *)buf + r; + count -= r; + nread += r; + } + return nread; +} + +/* Like write(), but restarts after EINTR */ +ssize_t +safewrite(int fd, const void *buf, size_t count) +{ + size_t nwritten = 0; + while (count > 0) { + ssize_t r = write(fd, buf, count); + + if (r < 0 && errno == EINTR) + continue; + if (r < 0) + return r; + if (r == 0) + return nwritten; + buf = (const char *)buf + r; + count -= r; + nwritten += r; + } + return nwritten; +} + +#ifdef HAVE_POSIX_FALLOCATE +int safezero(int fd, off_t offset, off_t len) +{ + int ret = posix_fallocate(fd, offset, len); + if (ret == 0) + return 0; + errno = ret; + return -1; +} +#else + +# ifdef HAVE_MMAP +int safezero(int fd, off_t offset, off_t len) +{ + int r; + char *buf; + + /* memset wants the mmap'ed file to be present on disk so create a + * sparse file + */ + r = ftruncate(fd, offset + len); + if (r < 0) + return -1; + + buf = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, offset); + if (buf == MAP_FAILED) + return -1; + + memset(buf, 0, len); + munmap(buf, len); + + return 0; +} + +# else /* HAVE_MMAP */ + +int safezero(int fd, off_t offset, off_t len) +{ + int r; + char *buf; + unsigned long long remain, bytes; + + if (lseek(fd, offset, SEEK_SET) < 0) + return -1; + + /* Split up the write in small chunks so as not to allocate lots of RAM */ + remain = len; + bytes = 1024 * 1024; + + r = VIR_ALLOC_N(buf, bytes); + if (r < 0) { + errno = ENOMEM; + return -1; + } + + while (remain) { + if (bytes > remain) + bytes = remain; + + r = safewrite(fd, buf, bytes); + if (r < 0) { + VIR_FREE(buf); + return -1; + } + + /* safewrite() guarantees all data will be written */ + remain -= bytes; + } + VIR_FREE(buf); + return 0; +} +# endif /* HAVE_MMAP */ +#endif /* HAVE_POSIX_FALLOCATE */ + +int virFileStripSuffix(char *str, + const char *suffix) +{ + int len = strlen(str); + int suffixlen = strlen(suffix); + + if (len < suffixlen) + return 0; + + if (!STREQ(str + len - suffixlen, suffix)) + return 0; + + str[len-suffixlen] = '\0'; + + return 1; +} + +char * +virArgvToString(const char *const *argv) +{ + int len, i; + char *ret, *p; + + for (len = 1, i = 0; argv[i]; i++) + len += strlen(argv[i]) + 1; + + if (VIR_ALLOC_N(ret, len) < 0) + return NULL; + p = ret; + + for (i = 0; argv[i]; i++) { + if (i != 0) + *(p++) = ' '; + + strcpy(p, argv[i]); + p += strlen(argv[i]); + } + + *p = '\0'; + + return ret; +} + +#ifndef WIN32 + +int virSetInherit(int fd, bool inherit) { + int fflags; + if ((fflags = fcntl(fd, F_GETFD)) < 0) + return -1; + if (inherit) + fflags &= ~FD_CLOEXEC; + else + fflags |= FD_CLOEXEC; + if ((fcntl(fd, F_SETFD, fflags)) < 0) + return -1; + return 0; +} + +#else /* WIN32 */ + +int virSetInherit(int fd ATTRIBUTE_UNUSED, bool inherit ATTRIBUTE_UNUSED) +{ + /* FIXME: Currently creating child processes is not supported on + * Win32, so there is no point in failing calls that are only relevant + * when creating child processes. So just pretend that we changed the + * inheritance property of the given fd as requested. */ + return 0; +} + +#endif /* WIN32 */ + +int virSetBlocking(int fd, bool blocking) { + return set_nonblocking_flag(fd, !blocking); +} + +int virSetNonBlock(int fd) { + return virSetBlocking(fd, false); +} + +int virSetCloseExec(int fd) +{ + return virSetInherit(fd, false); +} + +int +virPipeReadUntilEOF(int outfd, int errfd, + char **outbuf, char **errbuf) { + + struct pollfd fds[2]; + int i; + int finished[2]; + + fds[0].fd = outfd; + fds[0].events = POLLIN; + fds[0].revents = 0; + finished[0] = 0; + fds[1].fd = errfd; + fds[1].events = POLLIN; + fds[1].revents = 0; + finished[1] = 0; + + while (!(finished[0] && finished[1])) { + + if (poll(fds, ARRAY_CARDINALITY(fds), -1) < 0) { + if ((errno == EAGAIN) || (errno == EINTR)) + continue; + goto pollerr; + } + + for (i = 0; i < ARRAY_CARDINALITY(fds); ++i) { + char data[1024], **buf; + int got, size; + + if (!(fds[i].revents)) + continue; + else if (fds[i].revents & POLLHUP) + finished[i] = 1; + + if (!(fds[i].revents & POLLIN)) { + if (fds[i].revents & POLLHUP) + continue; + + virReportError(VIR_ERR_INTERNAL_ERROR, + "%s", _("Unknown poll response.")); + goto error; + } + + got = read(fds[i].fd, data, sizeof(data)); + + if (got == sizeof(data)) + finished[i] = 0; + + if (got == 0) { + finished[i] = 1; + continue; + } + if (got < 0) { + if (errno == EINTR) + continue; + if (errno == EAGAIN) + break; + goto pollerr; + } + + buf = ((fds[i].fd == outfd) ? outbuf : errbuf); + size = (*buf ? strlen(*buf) : 0); + if (VIR_REALLOC_N(*buf, size+got+1) < 0) { + virReportOOMError(); + goto error; + } + memmove(*buf+size, data, got); + (*buf)[size+got] = '\0'; + } + continue; + + pollerr: + virReportSystemError(errno, + "%s", _("poll error")); + goto error; + } + + return 0; + +error: + VIR_FREE(*outbuf); + VIR_FREE(*errbuf); + return -1; +} + +/* Like gnulib's fread_file, but read no more than the specified maximum + number of bytes. If the length of the input is <= max_len, and + upon error while reading that data, it works just like fread_file. */ +static char * +saferead_lim(int fd, size_t max_len, size_t *length) +{ + char *buf = NULL; + size_t alloc = 0; + size_t size = 0; + int save_errno; + + for (;;) { + int count; + int requested; + + if (size + BUFSIZ + 1 > alloc) { + alloc += alloc / 2; + if (alloc < size + BUFSIZ + 1) + alloc = size + BUFSIZ + 1; + + if (VIR_REALLOC_N(buf, alloc) < 0) { + save_errno = errno; + break; + } + } + + /* Ensure that (size + requested <= max_len); */ + requested = MIN(size < max_len ? max_len - size : 0, + alloc - size - 1); + count = saferead(fd, buf + size, requested); + size += count; + + if (count != requested || requested == 0) { + save_errno = errno; + if (count < 0) + break; + buf[size] = '\0'; + *length = size; + return buf; + } + } + + VIR_FREE(buf); + errno = save_errno; + return NULL; +} + +/* A wrapper around saferead_lim that maps a failure due to + exceeding the maximum size limitation to EOVERFLOW. */ +int +virFileReadLimFD(int fd, int maxlen, char **buf) +{ + size_t len; + char *s; + + if (maxlen <= 0) { + errno = EINVAL; + return -1; + } + s = saferead_lim(fd, maxlen+1, &len); + if (s == NULL) + return -1; + if (len > maxlen || (int)len != len) { + VIR_FREE(s); + /* There was at least one byte more than MAXLEN. + Set errno accordingly. */ + errno = EOVERFLOW; + return -1; + } + *buf = s; + return len; +} + +int virFileReadAll(const char *path, int maxlen, char **buf) +{ + int fd = open(path, O_RDONLY); + if (fd < 0) { + virReportSystemError(errno, _("Failed to open file '%s'"), path); + return -1; + } + + int len = virFileReadLimFD(fd, maxlen, buf); + VIR_FORCE_CLOSE(fd); + if (len < 0) { + virReportSystemError(errno, _("Failed to read file '%s'"), path); + return -1; + } + + return len; +} + +/* Truncate @path and write @str to it. If @mode is 0, ensure that + @path exists; otherwise, use @mode if @path must be created. + Return 0 for success, nonzero for failure. + Be careful to preserve any errno value upon failure. */ +int virFileWriteStr(const char *path, const char *str, mode_t mode) +{ + int fd; + + if (mode) + fd = open(path, O_WRONLY|O_TRUNC|O_CREAT, mode); + else + fd = open(path, O_WRONLY|O_TRUNC); + if (fd == -1) + return -1; + + if (safewrite(fd, str, strlen(str)) < 0) { + VIR_FORCE_CLOSE(fd); + return -1; + } + + /* Use errno from failed close only if there was no write error. */ + if (VIR_CLOSE(fd) != 0) + return -1; + + return 0; +} + +int virFileMatchesNameSuffix(const char *file, + const char *name, + const char *suffix) +{ + int filelen = strlen(file); + int namelen = strlen(name); + int suffixlen = strlen(suffix); + + if (filelen == (namelen + suffixlen) && + STREQLEN(file, name, namelen) && + STREQLEN(file + namelen, suffix, suffixlen)) + return 1; + else + return 0; +} + +int virFileHasSuffix(const char *str, + const char *suffix) +{ + int len = strlen(str); + int suffixlen = strlen(suffix); + + if (len < suffixlen) + return 0; + + return STRCASEEQ(str + len - suffixlen, suffix); +} + +#define SAME_INODE(Stat_buf_1, Stat_buf_2) \ + ((Stat_buf_1).st_ino == (Stat_buf_2).st_ino \ + && (Stat_buf_1).st_dev == (Stat_buf_2).st_dev) + +/* Return nonzero if checkLink and checkDest + refer to the same file. Otherwise, return 0. */ +int virFileLinkPointsTo(const char *checkLink, + const char *checkDest) +{ + struct stat src_sb; + struct stat dest_sb; + + return (stat(checkLink, &src_sb) == 0 + && stat(checkDest, &dest_sb) == 0 + && SAME_INODE(src_sb, dest_sb)); +} + + + +static int +virFileResolveLinkHelper(const char *linkpath, + bool intermediatePaths, + char **resultpath) +{ + struct stat st; + + *resultpath = NULL; + + /* We don't need the full canonicalization of intermediate + * directories, if linkpath is absolute and the basename is + * already a non-symlink. */ + if (IS_ABSOLUTE_FILE_NAME(linkpath) && !intermediatePaths) { + if (lstat(linkpath, &st) < 0) + return -1; + + if (!S_ISLNK(st.st_mode)) { + if (!(*resultpath = strdup(linkpath))) + return -1; + return 0; + } + } + + *resultpath = canonicalize_file_name(linkpath); + + return *resultpath == NULL ? -1 : 0; +} + +/* + * Attempt to resolve a symbolic link, returning an + * absolute path where only the last component is guaranteed + * not to be a symlink. + * + * Return 0 if path was not a symbolic, or the link was + * resolved. Return -1 with errno set upon error + */ +int virFileResolveLink(const char *linkpath, + char **resultpath) +{ + return virFileResolveLinkHelper(linkpath, false, resultpath); +} + +/* + * Attempt to resolve a symbolic link, returning an + * absolute path where every component is guaranteed + * not to be a symlink. + * + * Return 0 if path was not a symbolic, or the link was + * resolved. Return -1 with errno set upon error + */ +int virFileResolveAllLinks(const char *linkpath, + char **resultpath) +{ + return virFileResolveLinkHelper(linkpath, true, resultpath); +} + +/* + * Check whether the given file is a link. + * Returns 1 in case of the file being a link, 0 in case it is not + * a link and the negative errno in all other cases. + */ +int virFileIsLink(const char *linkpath) +{ + struct stat st; + + if (lstat(linkpath, &st) < 0) + return -errno; + + return S_ISLNK(st.st_mode) != 0; +} + + +/* + * Finds a requested executable file in the PATH env. e.g.: + * "kvm-img" will return "/usr/bin/kvm-img" + * + * You must free the result + */ +char *virFindFileInPath(const char *file) +{ + char *path = NULL; + char *pathiter; + char *pathseg; + char *fullpath = NULL; + + if (file == NULL) + return NULL; + + /* if we are passed an absolute path (starting with /), return a + * copy of that path, after validating that it is executable + */ + if (IS_ABSOLUTE_FILE_NAME(file)) { + if (virFileIsExecutable(file)) + return strdup(file); + else + return NULL; + } + + /* If we are passed an anchored path (containing a /), then there + * is no path search - it must exist in the current directory + */ + if (strchr(file, '/')) { + if (virFileIsExecutable(file)) + ignore_value(virFileAbsPath(file, &path)); + return path; + } + + /* copy PATH env so we can tweak it */ + path = getenv("PATH"); + + if (path == NULL || (path = strdup(path)) == NULL) + return NULL; + + /* for each path segment, append the file to search for and test for + * it. return it if found. + */ + pathiter = path; + while ((pathseg = strsep(&pathiter, ":")) != NULL) { + if (virAsprintf(&fullpath, "%s/%s", pathseg, file) < 0 || + virFileIsExecutable(fullpath)) + break; + VIR_FREE(fullpath); + } + + VIR_FREE(path); + return fullpath; +} + +bool virFileIsDir(const char *path) +{ + struct stat s; + return (stat(path, &s) == 0) && S_ISDIR(s.st_mode); +} + +bool virFileExists(const char *path) +{ + return access(path, F_OK) == 0; +} + +/* Check that a file is regular and has executable bits. If false is + * returned, errno is valid. + * + * Note: In the presence of ACLs, this may return true for a file that + * would actually fail with EACCES for a given user, or false for a + * file that the user could actually execute, but setups with ACLs + * that weird are unusual. */ +bool +virFileIsExecutable(const char *file) +{ + struct stat sb; + + /* We would also want to check faccessat if we cared about ACLs, + * but we don't. */ + if (stat(file, &sb) < 0) + return false; + if (S_ISREG(sb.st_mode) && (sb.st_mode & 0111) != 0) + return true; + errno = S_ISDIR(sb.st_mode) ? EISDIR : EACCES; + return false; +} + +#ifndef WIN32 +/* Check that a file is accessible under certain + * user & gid. + * @mode can be F_OK, or a bitwise combination of R_OK, W_OK, and X_OK. + * see 'man access' for more details. + * Returns 0 on success, -1 on fail with errno set. + */ +int +virFileAccessibleAs(const char *path, int mode, + uid_t uid, gid_t gid) +{ + pid_t pid = 0; + int status, ret = 0; + int forkRet = 0; + + if (uid == getuid() && + gid == getgid()) + return access(path, mode); + + forkRet = virFork(&pid); + + if (pid < 0) { + return -1; + } + + if (pid) { /* parent */ + if (virProcessWait(pid, &status) < 0) { + /* virProcessWait() already + * reported error */ + return -1; + } + + if (!WIFEXITED(status)) { + errno = EINTR; + return -1; + } + + if (status) { + errno = WEXITSTATUS(status); + return -1; + } + + return 0; + } + + /* child. + * Return positive value here. Parent + * will change it to negative one. */ + + if (forkRet < 0) { + ret = errno; + goto childerror; + } + + if (virSetUIDGID(uid, gid) < 0) { + ret = errno; + goto childerror; + } + + if (access(path, mode) < 0) + ret = errno; + +childerror: + if ((ret & 0xFF) != ret) { + VIR_WARN("unable to pass desired return value %d", ret); + ret = 0xFF; + } + + _exit(ret); +} + +/* virFileOpenForceOwnerMode() - an internal utility function called + * only by virFileOpenAs(). Sets the owner and mode of the file + * opened as "fd" if it's not correct AND the flags say it should be + * forced. */ +static int +virFileOpenForceOwnerMode(const char *path, int fd, mode_t mode, + uid_t uid, gid_t gid, unsigned int flags) +{ + int ret = 0; + struct stat st; + + if (!(flags & (VIR_FILE_OPEN_FORCE_OWNER | VIR_FILE_OPEN_FORCE_MODE))) + return 0; + + if (fstat(fd, &st) == -1) { + ret = -errno; + virReportSystemError(errno, _("stat of '%s' failed"), path); + return ret; + } + /* NB: uid:gid are never "-1" (default) at this point - the caller + * has always changed -1 to the value of get[gu]id(). + */ + if ((flags & VIR_FILE_OPEN_FORCE_OWNER) && + ((st.st_uid != uid) || (st.st_gid != gid)) && + (fchown(fd, uid, gid) < 0)) { + ret = -errno; + virReportSystemError(errno, + _("cannot chown '%s' to (%u, %u)"), + path, (unsigned int) uid, + (unsigned int) gid); + return ret; + } + if ((flags & VIR_FILE_OPEN_FORCE_MODE) && + ((mode & (S_IRWXU|S_IRWXG|S_IRWXO)) != + (st.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO))) && + (fchmod(fd, mode) < 0)) { + ret = -errno; + virReportSystemError(errno, + _("cannot set mode of '%s' to %04o"), + path, mode); + return ret; + } + return ret; +} + +/* virFileOpenForked() - an internal utility function called only by + * virFileOpenAs(). It forks, then the child does setuid+setgid to + * given uid:gid and attempts to open the file, while the parent just + * calls recvfd to get the open fd back from the child. returns the + * fd, or -errno if there is an error. */ +static int +virFileOpenForked(const char *path, int openflags, mode_t mode, + uid_t uid, gid_t gid, unsigned int flags) +{ + pid_t pid; + int waitret, status, ret = 0; + int fd = -1; + int pair[2] = { -1, -1 }; + int forkRet; + + /* parent is running as root, but caller requested that the + * file be opened as some other user and/or group). The + * following dance avoids problems caused by root-squashing + * NFS servers. */ + + if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) < 0) { + ret = -errno; + virReportSystemError(errno, + _("failed to create socket needed for '%s'"), + path); + return ret; + } + + forkRet = virFork(&pid); + if (pid < 0) + return -errno; + + if (pid == 0) { + + /* child */ + + VIR_FORCE_CLOSE(pair[0]); /* preserves errno */ + if (forkRet < 0) { + /* error encountered and logged in virFork() after the fork. */ + ret = -errno; + goto childerror; + } + + /* set desired uid/gid, then attempt to create the file */ + + if (virSetUIDGID(uid, gid) < 0) { + ret = -errno; + goto childerror; + } + + if ((fd = open(path, openflags, mode)) < 0) { + ret = -errno; + virReportSystemError(errno, + _("child process failed to create file '%s'"), + path); + goto childerror; + } + + /* File is successfully open. Set permissions if requested. */ + ret = virFileOpenForceOwnerMode(path, fd, mode, uid, gid, flags); + if (ret < 0) + goto childerror; + + do { + ret = sendfd(pair[1], fd); + } while (ret < 0 && errno == EINTR); + + if (ret < 0) { + ret = -errno; + virReportSystemError(errno, "%s", + _("child process failed to send fd to parent")); + goto childerror; + } + + childerror: + /* ret tracks -errno on failure, but exit value must be positive. + * If the child exits with EACCES, then the parent tries again. */ + /* XXX This makes assumptions about errno being < 255, which is + * not true on Hurd. */ + VIR_FORCE_CLOSE(pair[1]); + if (ret < 0) { + VIR_FORCE_CLOSE(fd); + } + ret = -ret; + if ((ret & 0xff) != ret) { + VIR_WARN("unable to pass desired return value %d", ret); + ret = 0xff; + } + _exit(ret); + } + + /* parent */ + + VIR_FORCE_CLOSE(pair[1]); + + do { + fd = recvfd(pair[0], 0); + } while (fd < 0 && errno == EINTR); + VIR_FORCE_CLOSE(pair[0]); /* NB: this preserves errno */ + + if (fd < 0 && errno != EACCES) { + ret = -errno; + while (waitpid(pid, NULL, 0) == -1 && errno == EINTR); + return ret; + } + + /* wait for child to complete, and retrieve its exit code */ + while ((waitret = waitpid(pid, &status, 0) == -1) + && (errno == EINTR)); + if (waitret == -1) { + ret = -errno; + virReportSystemError(errno, + _("failed to wait for child creating '%s'"), + path); + VIR_FORCE_CLOSE(fd); + return ret; + } + if (!WIFEXITED(status) || (ret = -WEXITSTATUS(status)) == -EACCES || + fd == -1) { + /* fall back to the simpler method, which works better in + * some cases */ + VIR_FORCE_CLOSE(fd); + if (flags & VIR_FILE_OPEN_NOFORK) { + /* If we had already tried opening w/o fork+setuid and + * failed, no sense trying again. Just set return the + * original errno that we got at that time (by + * definition, always either EACCES or EPERM - EACCES + * is close enough). + */ + return -EACCES; + } + if ((fd = open(path, openflags, mode)) < 0) + return -errno; + ret = virFileOpenForceOwnerMode(path, fd, mode, uid, gid, flags); + if (ret < 0) { + VIR_FORCE_CLOSE(fd); + return ret; + } + } + return fd; +} + +/** + * virFileOpenAs: + * @path: file to open or create + * @openflags: flags to pass to open + * @mode: mode to use on creation or when forcing permissions + * @uid: uid that should own file on creation + * @gid: gid that should own file + * @flags: bit-wise or of VIR_FILE_OPEN_* flags + * + * Open @path, and return an fd to the open file. @openflags contains + * the flags normally passed to open(2), while those in @flags are + * used internally. If @flags includes VIR_FILE_OPEN_NOFORK, then try + * opening the file while executing with the current uid:gid + * (i.e. don't fork+setuid+setgid before the call to open()). If + * @flags includes VIR_FILE_OPEN_FORK, then try opening the file while + * the effective user id is @uid (by forking a child process); this + * allows one to bypass root-squashing NFS issues; NOFORK is always + * tried before FORK (the absence of both flags is treated identically + * to (VIR_FILE_OPEN_NOFORK | VIR_FILE_OPEN_FORK)). If @flags includes + * VIR_FILE_OPEN_FORCE_OWNER, then ensure that @path is owned by + * uid:gid before returning (even if it already existed with a + * different owner). If @flags includes VIR_FILE_OPEN_FORCE_MODE, + * ensure it has those permissions before returning (again, even if + * the file already existed with different permissions). The return + * value (if non-negative) is the file descriptor, left open. Returns + * -errno on failure. */ +int +virFileOpenAs(const char *path, int openflags, mode_t mode, + uid_t uid, gid_t gid, unsigned int flags) +{ + int ret = 0, fd = -1; + + /* allow using -1 to mean "current value" */ + if (uid == (uid_t) -1) + uid = getuid(); + if (gid == (gid_t) -1) + gid = getgid(); + + /* treat absence of both flags as presence of both for simpler + * calling. */ + if (!(flags & (VIR_FILE_OPEN_NOFORK|VIR_FILE_OPEN_FORK))) + flags |= VIR_FILE_OPEN_NOFORK|VIR_FILE_OPEN_FORK; + + if ((flags & VIR_FILE_OPEN_NOFORK) + || (getuid() != 0) + || ((uid == 0) && (gid == 0))) { + + if ((fd = open(path, openflags, mode)) < 0) { + ret = -errno; + } else { + ret = virFileOpenForceOwnerMode(path, fd, mode, uid, gid, flags); + if (ret < 0) + goto error; + } + } + + /* If we either 1) didn't try opening as current user at all, or + * 2) failed, and errno/virStorageFileIsSharedFS indicate we might + * be successful if we try as a different uid, then try doing + * fork+setuid+setgid before opening. + */ + if ((fd < 0) && (flags & VIR_FILE_OPEN_FORK)) { + + if (ret < 0) { + /* An open(2) that failed due to insufficient permissions + * could return one or the other of these depending on OS + * version and circumstances. Any other errno indicates a + * problem that couldn't be remedied by fork+setuid + * anyway. */ + if (ret != -EACCES && ret != -EPERM) + goto error; + + /* On Linux we can also verify the FS-type of the + * directory. (this is a NOP on other platforms). */ + switch (virStorageFileIsSharedFS(path)) { + case 1: + /* it was on a network share, so we'll re-try */ + break; + case -1: + /* failure detecting fstype */ + virReportSystemError(errno, _("couldn't determine fs type " + "of mount containing '%s'"), path); + goto error; + case 0: + default: + /* file isn't on a recognized network FS */ + goto error; + } + } + + /* passed all prerequisites - retry the open w/fork+setuid */ + if ((fd = virFileOpenForked(path, openflags, mode, uid, gid, flags)) < 0) { + ret = fd; + fd = -1; + goto error; + } + } + + /* File is successfully opened */ + + return fd; + +error: + if (fd < 0) { + /* whoever failed the open last has already set ret = -errno */ + virReportSystemError(-ret, openflags & O_CREAT + ? _("failed to create file '%s'") + : _("failed to open file '%s'"), + path); + } else { + /* some other failure after the open succeeded */ + VIR_FORCE_CLOSE(fd); + } + return ret; +} + +/* return -errno on failure, or 0 on success */ +static int virDirCreateNoFork(const char *path, mode_t mode, uid_t uid, gid_t gid, + unsigned int flags) { + int ret = 0; + struct stat st; + + if ((mkdir(path, mode) < 0) + && !((errno == EEXIST) && (flags & VIR_DIR_CREATE_ALLOW_EXIST))) { + ret = -errno; + virReportSystemError(errno, _("failed to create directory '%s'"), + path); + goto error; + } + + if (stat(path, &st) == -1) { + ret = -errno; + virReportSystemError(errno, _("stat of '%s' failed"), path); + goto error; + } + if (((st.st_uid != uid) || (st.st_gid != gid)) + && (chown(path, uid, gid) < 0)) { + ret = -errno; + virReportSystemError(errno, _("cannot chown '%s' to (%u, %u)"), + path, (unsigned int) uid, (unsigned int) gid); + goto error; + } + if ((flags & VIR_DIR_CREATE_FORCE_PERMS) + && (chmod(path, mode) < 0)) { + ret = -errno; + virReportSystemError(errno, + _("cannot set mode of '%s' to %04o"), + path, mode); + goto error; + } +error: + return ret; +} + +/* return -errno on failure, or 0 on success */ +int virDirCreate(const char *path, mode_t mode, + uid_t uid, gid_t gid, unsigned int flags) { + struct stat st; + pid_t pid; + int waitret; + int status, ret = 0; + + /* allow using -1 to mean "current value" */ + if (uid == (uid_t) -1) + uid = getuid(); + if (gid == (gid_t) -1) + gid = getgid(); + + if ((!(flags & VIR_DIR_CREATE_AS_UID)) + || (getuid() != 0) + || ((uid == 0) && (gid == 0)) + || ((flags & VIR_DIR_CREATE_ALLOW_EXIST) && (stat(path, &st) >= 0))) { + return virDirCreateNoFork(path, mode, uid, gid, flags); + } + + int forkRet = virFork(&pid); + + if (pid < 0) { + ret = -errno; + return ret; + } + + if (pid) { /* parent */ + /* wait for child to complete, and retrieve its exit code */ + while ((waitret = waitpid(pid, &status, 0) == -1) && (errno == EINTR)); + if (waitret == -1) { + ret = -errno; + virReportSystemError(errno, + _("failed to wait for child creating '%s'"), + path); + goto parenterror; + } + if (!WIFEXITED(status) || (ret = -WEXITSTATUS(status)) == -EACCES) { + /* fall back to the simpler method, which works better in + * some cases */ + return virDirCreateNoFork(path, mode, uid, gid, flags); + } +parenterror: + return ret; + } + + /* child */ + + if (forkRet < 0) { + /* error encountered and logged in virFork() after the fork. */ + goto childerror; + } + + /* set desired uid/gid, then attempt to create the directory */ + + if (virSetUIDGID(uid, gid) < 0) { + ret = -errno; + goto childerror; + } + if (mkdir(path, mode) < 0) { + ret = -errno; + if (ret != -EACCES) { + /* in case of EACCES, the parent will retry */ + virReportSystemError(errno, _("child failed to create directory '%s'"), + path); + } + goto childerror; + } + /* check if group was set properly by creating after + * setgid. If not, try doing it with chown */ + if (stat(path, &st) == -1) { + ret = -errno; + virReportSystemError(errno, + _("stat of '%s' failed"), path); + goto childerror; + } + if ((st.st_gid != gid) && (chown(path, -1, gid) < 0)) { + ret = -errno; + virReportSystemError(errno, + _("cannot chown '%s' to group %u"), + path, (unsigned int) gid); + goto childerror; + } + if ((flags & VIR_DIR_CREATE_FORCE_PERMS) + && chmod(path, mode) < 0) { + virReportSystemError(errno, + _("cannot set mode of '%s' to %04o"), + path, mode); + goto childerror; + } +childerror: + _exit(ret); +} + +#else /* WIN32 */ + +int +virFileAccessibleAs(const char *path, + int mode, + uid_t uid ATTRIBUTE_UNUSED, + gid_t gid ATTRIBUTE_UNUSED) +{ + + VIR_WARN("Ignoring uid/gid due to WIN32"); + + return access(path, mode); +} + +/* return -errno on failure, or 0 on success */ +int virFileOpenAs(const char *path ATTRIBUTE_UNUSED, + int openflags ATTRIBUTE_UNUSED, + mode_t mode ATTRIBUTE_UNUSED, + uid_t uid ATTRIBUTE_UNUSED, + gid_t gid ATTRIBUTE_UNUSED, + unsigned int flags_unused ATTRIBUTE_UNUSED) +{ + virReportError(VIR_ERR_INTERNAL_ERROR, + "%s", _("virFileOpenAs is not implemented for WIN32")); + + return -ENOSYS; +} + +int virDirCreate(const char *path ATTRIBUTE_UNUSED, + mode_t mode ATTRIBUTE_UNUSED, + uid_t uid ATTRIBUTE_UNUSED, + gid_t gid ATTRIBUTE_UNUSED, + unsigned int flags_unused ATTRIBUTE_UNUSED) +{ + virReportError(VIR_ERR_INTERNAL_ERROR, + "%s", _("virDirCreate is not implemented for WIN32")); + + return -ENOSYS; +} +#endif /* WIN32 */ + +static int virFileMakePathHelper(char *path, mode_t mode) +{ + struct stat st; + char *p; + + VIR_DEBUG("path=%s mode=0%o", path, mode); + + if (stat(path, &st) >= 0) { + if (S_ISDIR(st.st_mode)) + return 0; + + errno = ENOTDIR; + return -1; + } + + if (errno != ENOENT) + return -1; + + if ((p = strrchr(path, '/')) == NULL) { + errno = EINVAL; + return -1; + } + + if (p != path) { + *p = '\0'; + + if (virFileMakePathHelper(path, mode) < 0) + return -1; + + *p = '/'; + } + + if (mkdir(path, mode) < 0 && errno != EEXIST) + return -1; + + return 0; +} + +/** + * Creates the given directory with mode 0777 if it's not already existing. + * + * Returns 0 on success, or -1 if an error occurred (in which case, errno + * is set appropriately). + */ +int virFileMakePath(const char *path) +{ + return virFileMakePathWithMode(path, 0777); +} + +int +virFileMakePathWithMode(const char *path, + mode_t mode) +{ + int ret = -1; + char *tmp; + + if ((tmp = strdup(path)) == NULL) + goto cleanup; + + ret = virFileMakePathHelper(tmp, mode); + +cleanup: + VIR_FREE(tmp); + return ret; +} + +/* Build up a fully qualified path for a config file to be + * associated with a persistent guest or network */ +char * +virFileBuildPath(const char *dir, const char *name, const char *ext) +{ + char *path; + + if (ext == NULL) { + if (virAsprintf(&path, "%s/%s", dir, name) < 0) { + virReportOOMError(); + return NULL; + } + } else { + if (virAsprintf(&path, "%s/%s%s", dir, name, ext) < 0) { + virReportOOMError(); + return NULL; + } + } + + return path; +} + +/* Open a non-blocking master side of a pty. If ttyName is not NULL, + * then populate it with the name of the slave. If rawmode is set, + * also put the master side into raw mode before returning. */ +#ifndef WIN32 +int virFileOpenTty(int *ttymaster, + char **ttyName, + int rawmode) +{ + /* XXX A word of caution - on some platforms (Solaris and HP-UX), + * additional ioctl() calls are needs after opening the slave + * before it will cause isatty() to return true. Should we make + * virFileOpenTty also return the opened slave fd, so the caller + * doesn't have to worry about that mess? */ + int ret = -1; + int slave = -1; + char *name = NULL; + + /* Unfortunately, we can't use the name argument of openpty, since + * there is no guarantee on how large the buffer has to be. + * Likewise, we can't use the termios argument: we have to use + * read-modify-write since there is no portable way to initialize + * a struct termios without use of tcgetattr. */ + if (openpty(ttymaster, &slave, NULL, NULL, NULL) < 0) + return -1; + + /* What a shame that openpty cannot atomically set FD_CLOEXEC, but + * that using posix_openpt/grantpt/unlockpt/ptsname is not + * thread-safe, and that ptsname_r is not portable. */ + if (virSetNonBlock(*ttymaster) < 0 || + virSetCloseExec(*ttymaster) < 0) + goto cleanup; + + /* While Linux supports tcgetattr on either the master or the + * slave, Solaris requires it to be on the slave. */ + if (rawmode) { + struct termios ttyAttr; + if (tcgetattr(slave, &ttyAttr) < 0) + goto cleanup; + + cfmakeraw(&ttyAttr); + + if (tcsetattr(slave, TCSADRAIN, &ttyAttr) < 0) + goto cleanup; + } + + /* ttyname_r on the slave is required by POSIX, while ptsname_r on + * the master is a glibc extension, and the POSIX ptsname is not + * thread-safe. Since openpty gave us both descriptors, guess + * which way we will determine the name? :) */ + if (ttyName) { + /* Initial guess of 64 is generally sufficient; rely on ERANGE + * to tell us if we need to grow. */ + size_t len = 64; + int rc; + + if (VIR_ALLOC_N(name, len) < 0) + goto cleanup; + + while ((rc = ttyname_r(slave, name, len)) == ERANGE) { + if (VIR_RESIZE_N(name, len, len, len) < 0) + goto cleanup; + } + if (rc != 0) { + errno = rc; + goto cleanup; + } + *ttyName = name; + name = NULL; + } + + ret = 0; + +cleanup: + if (ret != 0) + VIR_FORCE_CLOSE(*ttymaster); + VIR_FORCE_CLOSE(slave); + VIR_FREE(name); + + return ret; +} +#else /* WIN32 */ +int virFileOpenTty(int *ttymaster ATTRIBUTE_UNUSED, + char **ttyName ATTRIBUTE_UNUSED, + int rawmode ATTRIBUTE_UNUSED) +{ + /* mingw completely lacks pseudo-terminals, and the gnulib + * replacements are not (yet) license compatible. */ + errno = ENOSYS; + return -1; +} +#endif /* WIN32 */ + +bool virFileIsAbsPath(const char *path) +{ + if (!path) + return false; + + if (VIR_FILE_IS_DIR_SEPARATOR(path[0])) + return true; + +#ifdef WIN32 + if (c_isalpha(path[0]) && + path[1] == ':' && + VIR_FILE_IS_DIR_SEPARATOR(path[2])) + return true; +#endif + + return false; +} + + +const char *virFileSkipRoot(const char *path) +{ +#ifdef WIN32 + /* Skip \\server\share or //server/share */ + if (VIR_FILE_IS_DIR_SEPARATOR(path[0]) && + VIR_FILE_IS_DIR_SEPARATOR(path[1]) && + path[2] && + !VIR_FILE_IS_DIR_SEPARATOR(path[2])) + { + const char *p = strchr(path + 2, VIR_FILE_DIR_SEPARATOR); + const char *q = strchr(path + 2, '/'); + + if (p == NULL || (q != NULL && q < p)) + p = q; + + if (p && p > path + 2 && p[1]) { + path = p + 1; + + while (path[0] && + !VIR_FILE_IS_DIR_SEPARATOR(path[0])) + path++; + + /* Possibly skip a backslash after the share name */ + if (VIR_FILE_IS_DIR_SEPARATOR(path[0])) + path++; + + return path; + } + } +#endif + + /* Skip initial slashes */ + if (VIR_FILE_IS_DIR_SEPARATOR(path[0])) { + while (VIR_FILE_IS_DIR_SEPARATOR(path[0])) + path++; + + return path; + } + +#ifdef WIN32 + /* Skip X:\ */ + if (c_isalpha(path[0]) && + path[1] == ':' && + VIR_FILE_IS_DIR_SEPARATOR(path[2])) + return path + 3; +#endif + + return path; +} + + + +/* + * Creates an absolute path for a potentially relative path. + * Return 0 if the path was not relative, or on success. + * Return -1 on error. + * + * You must free the result. + */ +int virFileAbsPath(const char *path, char **abspath) +{ + char *buf; + + if (path[0] == '/') { + if (!(*abspath = strdup(path))) + return -1; + } else { + buf = getcwd(NULL, 0); + if (buf == NULL) + return -1; + + if (virAsprintf(abspath, "%s/%s", buf, path) < 0) { + VIR_FREE(buf); + return -1; + } + VIR_FREE(buf); + } + + return 0; +} + +/* Remove spurious / characters from a path. The result must be freed */ +char * +virFileSanitizePath(const char *path) +{ + const char *cur = path; + char *cleanpath; + int idx = 0; + + cleanpath = strdup(path); + if (!cleanpath) { + virReportOOMError(); + return NULL; + } + + /* Need to sanitize: + * // -> // + * /// -> / + * /../foo -> /../foo + * /foo///bar/ -> /foo/bar + */ + + /* Starting with // is valid posix, but ///foo == /foo */ + if (cur[0] == '/' && cur[1] == '/' && cur[2] != '/') { + idx = 2; + cur += 2; + } + + /* Sanitize path in place */ + while (*cur != '\0') { + if (*cur != '/') { + cleanpath[idx++] = *cur++; + continue; + } + + /* Skip all extra / */ + while (*++cur == '/') + continue; + + /* Don't add a trailing / */ + if (idx != 0 && *cur == '\0') + break; + + cleanpath[idx++] = '/'; + } + cleanpath[idx] = '\0'; + + return cleanpath; +} + +/* Like strtol, but produce an "int" result, and check more carefully. + Return 0 upon success; return -1 to indicate failure. + When END_PTR is NULL, the byte after the final valid digit must be NUL. + Otherwise, it's like strtol and lets the caller check any suffix for + validity. This function is careful to return -1 when the string S + represents a number that is not representable as an "int". */ +int +virStrToLong_i(char const *s, char **end_ptr, int base, int *result) +{ + long int val; + char *p; + int err; + + errno = 0; + val = strtol(s, &p, base); /* exempt from syntax-check */ + err = (errno || (!end_ptr && *p) || p == s || (int) val != val); + if (end_ptr) + *end_ptr = p; + if (err) + return -1; + *result = val; + return 0; +} + +/* Just like virStrToLong_i, above, but produce an "unsigned int" value. */ +int +virStrToLong_ui(char const *s, char **end_ptr, int base, unsigned int *result) +{ + unsigned long int val; + char *p; + int err; + + errno = 0; + val = strtoul(s, &p, base); /* exempt from syntax-check */ + err = (errno || (!end_ptr && *p) || p == s || (unsigned int) val != val); + if (end_ptr) + *end_ptr = p; + if (err) + return -1; + *result = val; + return 0; +} + +/* Just like virStrToLong_i, above, but produce a "long" value. */ +int +virStrToLong_l(char const *s, char **end_ptr, int base, long *result) +{ + long int val; + char *p; + int err; + + errno = 0; + val = strtol(s, &p, base); /* exempt from syntax-check */ + err = (errno || (!end_ptr && *p) || p == s); + if (end_ptr) + *end_ptr = p; + if (err) + return -1; + *result = val; + return 0; +} + +/* Just like virStrToLong_i, above, but produce an "unsigned long" value. */ +int +virStrToLong_ul(char const *s, char **end_ptr, int base, unsigned long *result) +{ + unsigned long int val; + char *p; + int err; + + errno = 0; + val = strtoul(s, &p, base); /* exempt from syntax-check */ + err = (errno || (!end_ptr && *p) || p == s); + if (end_ptr) + *end_ptr = p; + if (err) + return -1; + *result = val; + return 0; +} + +/* Just like virStrToLong_i, above, but produce a "long long" value. */ +int +virStrToLong_ll(char const *s, char **end_ptr, int base, long long *result) +{ + long long val; + char *p; + int err; + + errno = 0; + val = strtoll(s, &p, base); /* exempt from syntax-check */ + err = (errno || (!end_ptr && *p) || p == s); + if (end_ptr) + *end_ptr = p; + if (err) + return -1; + *result = val; + return 0; +} + +/* Just like virStrToLong_i, above, but produce an "unsigned long long" value. */ +int +virStrToLong_ull(char const *s, char **end_ptr, int base, unsigned long long *result) +{ + unsigned long long val; + char *p; + int err; + + errno = 0; + val = strtoull(s, &p, base); /* exempt from syntax-check */ + err = (errno || (!end_ptr && *p) || p == s); + if (end_ptr) + *end_ptr = p; + if (err) + return -1; + *result = val; + return 0; +} + +int +virStrToDouble(char const *s, + char **end_ptr, + double *result) +{ + double val; + char *p; + int err; + + errno = 0; + val = strtod(s, &p); /* exempt from syntax-check */ + err = (errno || (!end_ptr && *p) || p == s); + if (end_ptr) + *end_ptr = p; + if (err) + return -1; + *result = val; + return 0; +} + +/* Convert C from hexadecimal character to integer. */ +int +virHexToBin(unsigned char c) +{ + switch (c) { + default: return c - '0'; + case 'a': case 'A': return 10; + case 'b': case 'B': return 11; + case 'c': case 'C': return 12; + case 'd': case 'D': return 13; + case 'e': case 'E': return 14; + case 'f': case 'F': return 15; + } +} + +/* Scale an integer VALUE in-place by an optional case-insensitive + * SUFFIX, defaulting to SCALE if suffix is NULL or empty (scale is + * typically 1 or 1024). Recognized suffixes include 'b' or 'bytes', + * as well as power-of-two scaling via binary abbreviations ('KiB', + * 'MiB', ...) or their one-letter counterpart ('k', 'M', ...), and + * power-of-ten scaling via SI abbreviations ('KB', 'MB', ...). + * Ensure that the result does not exceed LIMIT. Return 0 on success, + * -1 with error message raised on failure. */ +int +virScaleInteger(unsigned long long *value, const char *suffix, + unsigned long long scale, unsigned long long limit) +{ + if (!suffix || !*suffix) { + if (!scale) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("invalid scale %llu"), scale); + return -1; + } + suffix = ""; + } else if (STRCASEEQ(suffix, "b") || STRCASEEQ(suffix, "byte") || + STRCASEEQ(suffix, "bytes")) { + scale = 1; + } else { + int base; + + if (!suffix[1] || STRCASEEQ(suffix + 1, "iB")) { + base = 1024; + } else if (c_tolower(suffix[1]) == 'b' && !suffix[2]) { + base = 1000; + } else { + virReportError(VIR_ERR_INVALID_ARG, + _("unknown suffix '%s'"), suffix); + return -1; + } + scale = 1; + switch (c_tolower(*suffix)) { + case 'e': + scale *= base; + /* fallthrough */ + case 'p': + scale *= base; + /* fallthrough */ + case 't': + scale *= base; + /* fallthrough */ + case 'g': + scale *= base; + /* fallthrough */ + case 'm': + scale *= base; + /* fallthrough */ + case 'k': + scale *= base; + break; + default: + virReportError(VIR_ERR_INVALID_ARG, + _("unknown suffix '%s'"), suffix); + return -1; + } + } + + if (*value && *value >= (limit / scale)) { + virReportError(VIR_ERR_OVERFLOW, _("value too large: %llu%s"), + *value, suffix); + return -1; + } + *value *= scale; + return 0; +} + +/** + * virSkipSpaces: + * @str: pointer to the char pointer used + * + * Skip potential blanks, this includes space tabs, line feed, + * carriage returns. + */ +void +virSkipSpaces(const char **str) +{ + const char *cur = *str; + + while (c_isspace(*cur)) + cur++; + *str = cur; +} + +/** + * virSkipSpacesAndBackslash: + * @str: pointer to the char pointer used + * + * Like virSkipSpaces, but also skip backslashes erroneously emitted + * by xend + */ +void +virSkipSpacesAndBackslash(const char **str) +{ + const char *cur = *str; + + while (c_isspace(*cur) || *cur == '\\') + cur++; + *str = cur; +} + +/** + * virTrimSpaces: + * @str: string to modify to remove all trailing spaces + * @endp: track the end of the string + * + * If @endp is NULL on entry, then all spaces prior to the trailing + * NUL in @str are removed, by writing NUL into the appropriate + * location. If @endp is non-NULL but points to a NULL pointer, + * then all spaces prior to the trailing NUL in @str are removed, + * NUL is written to the new string end, and endp is set to the + * location of the (new) string end. If @endp is non-NULL and + * points to a non-NULL pointer, then that pointer is used as + * the end of the string, endp is set to the (new) location, but + * no NUL pointer is written into the string. + */ +void +virTrimSpaces(char *str, char **endp) +{ + char *end; + + if (!endp || !*endp) + end = str + strlen(str); + else + end = *endp; + while (end > str && c_isspace(end[-1])) + end--; + if (endp) { + if (!*endp) + *end = '\0'; + *endp = end; + } else { + *end = '\0'; + } +} + +/** + * virSkipSpacesBackwards: + * @str: start of string + * @endp: on entry, *endp must be NULL or a location within @str, on exit, + * will be adjusted to skip trailing spaces, or to NULL if @str had nothing + * but spaces. + */ +void +virSkipSpacesBackwards(const char *str, char **endp) +{ + /* Casting away const is safe, since virTrimSpaces does not + * modify string with this particular usage. */ + char *s = (char*) str; + + if (!*endp) + *endp = s + strlen(s); + virTrimSpaces(s, endp); + if (s == *endp) + *endp = NULL; +} + +/** + * virParseNumber: + * @str: pointer to the char pointer used + * + * Parse an unsigned number + * + * Returns the unsigned number or -1 in case of error. @str will be + * updated to skip the number. + */ +int +virParseNumber(const char **str) +{ + int ret = 0; + const char *cur = *str; + + if ((*cur < '0') || (*cur > '9')) + return -1; + + while (c_isdigit(*cur)) { + unsigned int c = *cur - '0'; + + if ((ret > INT_MAX / 10) || + ((ret == INT_MAX / 10) && (c > INT_MAX % 10))) + return -1; + ret = ret * 10 + c; + cur++; + } + *str = cur; + return ret; +} + + +/** + * virParseVersionString: + * @str: const char pointer to the version string + * @version: unsigned long pointer to output the version number + * @allowMissing: true to treat 3 like 3.0.0, false to error out on + * missing minor or micro + * + * Parse an unsigned version number from a version string. Expecting + * 'major.minor.micro' format, ignoring an optional suffix. + * + * The major, minor and micro numbers are encoded into a single version number: + * + * 1000000 * major + 1000 * minor + micro + * + * Returns the 0 for success, -1 for error. + */ +int +virParseVersionString(const char *str, unsigned long *version, + bool allowMissing) +{ + unsigned int major, minor = 0, micro = 0; + char *tmp; + + if (virStrToLong_ui(str, &tmp, 10, &major) < 0) + return -1; + + if (!allowMissing && *tmp != '.') + return -1; + + if ((*tmp == '.') && virStrToLong_ui(tmp + 1, &tmp, 10, &minor) < 0) + return -1; + + if (!allowMissing && *tmp != '.') + return -1; + + if ((*tmp == '.') && virStrToLong_ui(tmp + 1, &tmp, 10, µ) < 0) + return -1; + + if (major > UINT_MAX / 1000000 || minor > 999 || micro > 999) + return -1; + + *version = 1000000 * major + 1000 * minor + micro; + + return 0; +} + +/** + * virVasprintf + * + * like glibc's vasprintf but makes sure *strp == NULL on failure + */ +int +virVasprintf(char **strp, const char *fmt, va_list list) +{ + int ret; + + if ((ret = vasprintf(strp, fmt, list)) == -1) + *strp = NULL; + + return ret; +} + +/** + * virAsprintf + * + * like glibc's_asprintf but makes sure *strp == NULL on failure + */ +int +virAsprintf(char **strp, const char *fmt, ...) +{ + va_list ap; + int ret; + + va_start(ap, fmt); + ret = virVasprintf(strp, fmt, ap); + va_end(ap); + return ret; +} + +/** + * virStrncpy + * + * A safe version of strncpy. The last parameter is the number of bytes + * available in the destination string, *not* the number of bytes you want + * to copy. If the destination is not large enough to hold all n of the + * src string bytes plus a \0, NULL is returned and no data is copied. + * If the destination is large enough to hold the n bytes plus \0, then the + * string is copied and a pointer to the destination string is returned. + */ +char * +virStrncpy(char *dest, const char *src, size_t n, size_t destbytes) +{ + char *ret; + + if (n > (destbytes - 1)) + return NULL; + + ret = strncpy(dest, src, n); + /* strncpy NULL terminates iff the last character is \0. Therefore + * force the last byte to be \0 + */ + dest[n] = '\0'; + + return ret; +} + +/** + * virStrcpy + * + * A safe version of strcpy. The last parameter is the number of bytes + * available in the destination string, *not* the number of bytes you want + * to copy. If the destination is not large enough to hold all n of the + * src string bytes plus a \0, NULL is returned and no data is copied. + * If the destination is large enough to hold the source plus \0, then the + * string is copied and a pointer to the destination string is returned. + */ +char * +virStrcpy(char *dest, const char *src, size_t destbytes) +{ + return virStrncpy(dest, src, strlen(src), destbytes); +} + +int virEnumFromString(const char *const*types, + unsigned int ntypes, + const char *type) +{ + unsigned int i; + if (!type) + return -1; + + for (i = 0 ; i < ntypes ; i++) + if (STREQ(types[i], type)) + return i; + + return -1; +} + +/* In case thread-safe locales are available */ +#if HAVE_NEWLOCALE + +static locale_t virLocale; + +static int +virLocaleOnceInit(void) +{ + virLocale = newlocale(LC_ALL_MASK, "C", (locale_t)0); + if (!virLocale) + return -1; + return 0; +} + +VIR_ONCE_GLOBAL_INIT(virLocale) +#endif + +/** + * virDoubleToStr + * + * converts double to string with C locale (thread-safe). + * + * Returns -1 on error, size of the string otherwise. + */ +int +virDoubleToStr(char **strp, double number) +{ + int ret = -1; + +#if HAVE_NEWLOCALE + + locale_t old_loc; + + if (virLocaleInitialize() < 0) + goto error; + + old_loc = uselocale(virLocale); + ret = virAsprintf(strp, "%lf", number); + uselocale(old_loc); + +#else + + char *radix, *tmp; + struct lconv *lc; + + if ((ret = virAsprintf(strp, "%lf", number) < 0)) + goto error; + + lc = localeconv(); + radix = lc->decimal_point; + tmp = strstr(*strp, radix); + if (tmp) { + *tmp = '.'; + if (strlen(radix) > 1) + memmove(tmp + 1, tmp + strlen(radix), strlen(*strp) - (tmp - *strp)); + } + +#endif /* HAVE_NEWLOCALE */ + error: + return ret; +} + + +/** + * Format @val as a base-10 decimal number, in the + * buffer @buf of size @buflen. To allocate a suitable + * sized buffer, the INT_BUFLEN(int) macro should be + * used + * + * Returns pointer to start of the number in @buf + */ +char * +virFormatIntDecimal(char *buf, size_t buflen, int val) +{ + char *p = buf + buflen - 1; + *p = '\0'; + if (val >= 0) { + do { + *--p = '0' + (val % 10); + val /= 10; + } while (val != 0); + } else { + do { + *--p = '0' - (val % 10); + val /= 10; + } while (val != 0); + *--p = '-'; + } + return p; +} + + +const char *virEnumToString(const char *const*types, + unsigned int ntypes, + int type) +{ + if (type < 0 || type >= ntypes) + return NULL; + + return types[type]; +} + +/* Translates a device name of the form (regex) /^[fhv]d[a-z]+[0-9]*$/ + * into the corresponding index (e.g. sda => 0, hdz => 25, vdaa => 26) + * Note that any trailing string of digits is simply ignored. + * @param name The name of the device + * @return name's index, or -1 on failure + */ +int virDiskNameToIndex(const char *name) { + const char *ptr = NULL; + int idx = 0; + static char const* const drive_prefix[] = {"fd", "hd", "vd", "sd", "xvd", "ubd"}; + unsigned int i; + + for (i = 0; i < ARRAY_CARDINALITY(drive_prefix); i++) { + if (STRPREFIX(name, drive_prefix[i])) { + ptr = name + strlen(drive_prefix[i]); + break; + } + } + + if (!ptr) + return -1; + + for (i = 0; *ptr; i++) { + if (!c_islower(*ptr)) + break; + + idx = (idx + (i < 1 ? 0 : 1)) * 26; + idx += *ptr - 'a'; + ptr++; + } + + /* Count the trailing digits. */ + size_t n_digits = strspn(ptr, "0123456789"); + if (ptr[n_digits] != '\0') + return -1; + + return idx; +} + +char *virIndexToDiskName(int idx, const char *prefix) +{ + char *name = NULL; + int i, k, offset; + + if (idx < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Disk index %d is negative"), idx); + return NULL; + } + + for (i = 0, k = idx; k >= 0; ++i, k = k / 26 - 1) { } + + offset = strlen(prefix); + + if (VIR_ALLOC_N(name, offset + i + 1)) { + virReportOOMError(); + return NULL; + } + + strcpy(name, prefix); + name[offset + i] = '\0'; + + for (i = i - 1, k = idx; k >= 0; --i, k = k / 26 - 1) { + name[offset + i] = 'a' + (k % 26); + } + + return name; +} + +#ifndef AI_CANONIDN +# define AI_CANONIDN 0 +#endif + +/* Who knew getting a hostname could be so delicate. In Linux (and Unices + * in general), many things depend on "hostname" returning a value that will + * resolve one way or another. In the modern world where networks frequently + * come and go this is often being hard-coded to resolve to "localhost". If + * it *doesn't* resolve to localhost, then we would prefer to have the FQDN. + * That leads us to 3 possibilities: + * + * 1) gethostname() returns an FQDN (not localhost) - we return the string + * as-is, it's all of the information we want + * 2) gethostname() returns "localhost" - we return localhost; doing further + * work to try to resolve it is pointless + * 3) gethostname() returns a shortened hostname - in this case, we want to + * try to resolve this to a fully-qualified name. Therefore we pass it + * to getaddrinfo(). There are two possible responses: + * a) getaddrinfo() resolves to a FQDN - return the FQDN + * b) getaddrinfo() fails or resolves to localhost - in this case, the + * data we got from gethostname() is actually more useful than what + * we got from getaddrinfo(). Return the value from gethostname() + * and hope for the best. + */ +char *virGetHostname(virConnectPtr conn ATTRIBUTE_UNUSED) +{ + int r; + char hostname[HOST_NAME_MAX+1], *result; + struct addrinfo hints, *info; + + r = gethostname(hostname, sizeof(hostname)); + if (r == -1) { + virReportSystemError(errno, + "%s", _("failed to determine host name")); + return NULL; + } + NUL_TERMINATE(hostname); + + if (STRPREFIX(hostname, "localhost") || strchr(hostname, '.')) { + /* in this case, gethostname returned localhost (meaning we can't + * do any further canonicalization), or it returned an FQDN (and + * we don't need to do any further canonicalization). Return the + * string as-is; it's up to callers to check whether "localhost" + * is allowed. + */ + result = strdup(hostname); + goto check_and_return; + } + + /* otherwise, it's a shortened, non-localhost, hostname. Attempt to + * canonicalize the hostname by running it through getaddrinfo + */ + + memset(&hints, 0, sizeof(hints)); + hints.ai_flags = AI_CANONNAME|AI_CANONIDN; + hints.ai_family = AF_UNSPEC; + r = getaddrinfo(hostname, NULL, &hints, &info); + if (r != 0) { + VIR_WARN("getaddrinfo failed for '%s': %s", + hostname, gai_strerror(r)); + result = strdup(hostname); + goto check_and_return; + } + + /* Tell static analyzers about getaddrinfo semantics. */ + sa_assert(info); + + if (info->ai_canonname == NULL || + STRPREFIX(info->ai_canonname, "localhost")) + /* in this case, we tried to canonicalize and we ended up back with + * localhost. Ignore the canonicalized name and just return the + * original hostname + */ + result = strdup(hostname); + else + /* Caller frees this string. */ + result = strdup(info->ai_canonname); + + freeaddrinfo(info); + +check_and_return: + if (result == NULL) + virReportOOMError(); + return result; +} + +#ifdef HAVE_GETPWUID_R +enum { + VIR_USER_ENT_DIRECTORY, + VIR_USER_ENT_NAME, +}; + +static char *virGetUserEnt(uid_t uid, + int field) +{ + char *strbuf; + char *ret; + struct passwd pwbuf; + struct passwd *pw = NULL; + long val = sysconf(_SC_GETPW_R_SIZE_MAX); + size_t strbuflen = val; + int rc; + + /* sysconf is a hint; if it fails, fall back to a reasonable size */ + if (val < 0) + strbuflen = 1024; + + if (VIR_ALLOC_N(strbuf, strbuflen) < 0) { + virReportOOMError(); + return NULL; + } + + /* + * From the manpage (terrifying but true): + * + * ERRORS + * 0 or ENOENT or ESRCH or EBADF or EPERM or ... + * The given name or uid was not found. + */ + while ((rc = getpwuid_r(uid, &pwbuf, strbuf, strbuflen, &pw)) == ERANGE) { + if (VIR_RESIZE_N(strbuf, strbuflen, strbuflen, strbuflen) < 0) { + virReportOOMError(); + VIR_FREE(strbuf); + return NULL; + } + } + if (rc != 0 || pw == NULL) { + virReportSystemError(rc, + _("Failed to find user record for uid '%u'"), + (unsigned int) uid); + VIR_FREE(strbuf); + return NULL; + } + + if (field == VIR_USER_ENT_DIRECTORY) + ret = strdup(pw->pw_dir); + else + ret = strdup(pw->pw_name); + + VIR_FREE(strbuf); + if (!ret) + virReportOOMError(); + + return ret; +} + +static char *virGetGroupEnt(gid_t gid) +{ + char *strbuf; + char *ret; + struct group grbuf; + struct group *gr = NULL; + long val = sysconf(_SC_GETGR_R_SIZE_MAX); + size_t strbuflen = val; + int rc; + + /* sysconf is a hint; if it fails, fall back to a reasonable size */ + if (val < 0) + strbuflen = 1024; + + if (VIR_ALLOC_N(strbuf, strbuflen) < 0) { + virReportOOMError(); + return NULL; + } + + /* + * From the manpage (terrifying but true): + * + * ERRORS + * 0 or ENOENT or ESRCH or EBADF or EPERM or ... + * The given name or gid was not found. + */ + while ((rc = getgrgid_r(gid, &grbuf, strbuf, strbuflen, &gr)) == ERANGE) { + if (VIR_RESIZE_N(strbuf, strbuflen, strbuflen, strbuflen) < 0) { + virReportOOMError(); + VIR_FREE(strbuf); + return NULL; + } + } + if (rc != 0 || gr == NULL) { + virReportSystemError(rc, + _("Failed to find group record for gid '%u'"), + (unsigned int) gid); + VIR_FREE(strbuf); + return NULL; + } + + ret = strdup(gr->gr_name); + + VIR_FREE(strbuf); + if (!ret) + virReportOOMError(); + + return ret; +} + +char *virGetUserDirectory(void) +{ + return virGetUserEnt(geteuid(), VIR_USER_ENT_DIRECTORY); +} + +static char *virGetXDGDirectory(const char *xdgenvname, const char *xdgdefdir) +{ + const char *path = getenv(xdgenvname); + char *ret = NULL; + char *home = virGetUserEnt(geteuid(), VIR_USER_ENT_DIRECTORY); + + if (path && path[0]) { + if (virAsprintf(&ret, "%s/libvirt", path) < 0) + goto no_memory; + } else { + if (virAsprintf(&ret, "%s/%s/libvirt", home, xdgdefdir) < 0) + goto no_memory; + } + + cleanup: + VIR_FREE(home); + return ret; + no_memory: + virReportOOMError(); + goto cleanup; +} + +char *virGetUserConfigDirectory(void) +{ + return virGetXDGDirectory("XDG_CONFIG_HOME", ".config"); +} + +char *virGetUserCacheDirectory(void) +{ + return virGetXDGDirectory("XDG_CACHE_HOME", ".cache"); +} + +char *virGetUserRuntimeDirectory(void) +{ + const char *path = getenv("XDG_RUNTIME_DIR"); + + if (!path || !path[0]) { + return virGetUserCacheDirectory(); + } else { + char *ret; + + if (virAsprintf(&ret, "%s/libvirt", path) < 0) { + virReportOOMError(); + return NULL; + } + + return ret; + } +} + +char *virGetUserName(uid_t uid) +{ + return virGetUserEnt(uid, VIR_USER_ENT_NAME); +} + +char *virGetGroupName(gid_t gid) +{ + return virGetGroupEnt(gid); +} + +/* Search in the password database for a user id that matches the user name + * `name`. Returns 0 on success, -1 on failure or 1 if name cannot be found. + */ +static int +virGetUserIDByName(const char *name, uid_t *uid) +{ + char *strbuf = NULL; + struct passwd pwbuf; + struct passwd *pw = NULL; + long val = sysconf(_SC_GETPW_R_SIZE_MAX); + size_t strbuflen = val; + int rc; + int ret = -1; + + /* sysconf is a hint; if it fails, fall back to a reasonable size */ + if (val < 0) + strbuflen = 1024; + + if (VIR_ALLOC_N(strbuf, strbuflen) < 0) { + virReportOOMError(); + goto cleanup; + } + + while ((rc = getpwnam_r(name, &pwbuf, strbuf, strbuflen, &pw)) == ERANGE) { + if (VIR_RESIZE_N(strbuf, strbuflen, strbuflen, strbuflen) < 0) { + virReportOOMError(); + goto cleanup; + } + } + + if (!pw) { + if (rc != 0) { + char buf[1024]; + /* log the possible error from getpwnam_r. Unfortunately error + * reporting from this function is bad and we can't really + * rely on it, so we just report that the user wasn't found */ + VIR_WARN("User record for user '%s' was not found: %s", + name, virStrerror(rc, buf, sizeof(buf))); + } + + ret = 1; + goto cleanup; + } + + *uid = pw->pw_uid; + ret = 0; + +cleanup: + VIR_FREE(strbuf); + + return ret; +} + +/* Try to match a user id based on `user`. The default behavior is to parse + * `user` first as a user name and then as a user id. However if `user` + * contains a leading '+', the rest of the string is always parsed as a uid. + * + * Returns 0 on success and -1 otherwise. + */ +int +virGetUserID(const char *user, uid_t *uid) +{ + unsigned int uint_uid; + + if (*user == '+') { + user++; + } else { + int rc = virGetUserIDByName(user, uid); + if (rc <= 0) + return rc; + } + + if (virStrToLong_ui(user, NULL, 10, &uint_uid) < 0 || + ((uid_t) uint_uid) != uint_uid) { + virReportError(VIR_ERR_INVALID_ARG, _("Failed to parse user '%s'"), + user); + return -1; + } + + *uid = uint_uid; + + return 0; +} + +/* Search in the group database for a group id that matches the group name + * `name`. Returns 0 on success, -1 on failure or 1 if name cannot be found. + */ +static int +virGetGroupIDByName(const char *name, gid_t *gid) +{ + char *strbuf = NULL; + struct group grbuf; + struct group *gr = NULL; + long val = sysconf(_SC_GETGR_R_SIZE_MAX); + size_t strbuflen = val; + int rc; + int ret = -1; + + /* sysconf is a hint; if it fails, fall back to a reasonable size */ + if (val < 0) + strbuflen = 1024; + + if (VIR_ALLOC_N(strbuf, strbuflen) < 0) { + virReportOOMError(); + goto cleanup; + } + + while ((rc = getgrnam_r(name, &grbuf, strbuf, strbuflen, &gr)) == ERANGE) { + if (VIR_RESIZE_N(strbuf, strbuflen, strbuflen, strbuflen) < 0) { + virReportOOMError(); + goto cleanup; + } + } + + if (!gr) { + if (rc != 0) { + char buf[1024]; + /* log the possible error from getgrnam_r. Unfortunately error + * reporting from this function is bad and we can't really + * rely on it, so we just report that the user wasn't found */ + VIR_WARN("Group record for user '%s' was not found: %s", + name, virStrerror(rc, buf, sizeof(buf))); + } + + ret = 1; + goto cleanup; + } + + *gid = gr->gr_gid; + ret = 0; + +cleanup: + VIR_FREE(strbuf); + + return ret; +} + +/* Try to match a group id based on `group`. The default behavior is to parse + * `group` first as a group name and then as a group id. However if `group` + * contains a leading '+', the rest of the string is always parsed as a guid. + * + * Returns 0 on success and -1 otherwise. + */ +int +virGetGroupID(const char *group, gid_t *gid) +{ + unsigned int uint_gid; + + if (*group == '+') { + group++; + } else { + int rc = virGetGroupIDByName(group, gid); + if (rc <= 0) + return rc; + } + + if (virStrToLong_ui(group, NULL, 10, &uint_gid) < 0 || + ((gid_t) uint_gid) != uint_gid) { + virReportError(VIR_ERR_INVALID_ARG, _("Failed to parse group '%s'"), + group); + return -1; + } + + *gid = uint_gid; + + return 0; +} + +/* Set the real and effective uid and gid to the given values, and call + * initgroups so that the process has all the assumed group membership of + * that uid. return 0 on success, -1 on failure (the original system error + * remains in errno). + */ +int +virSetUIDGID(uid_t uid, gid_t gid) +{ + int err; + char *buf = NULL; + + if (gid > 0) { + if (setregid(gid, gid) < 0) { + virReportSystemError(err = errno, + _("cannot change to '%d' group"), + (unsigned int) gid); + goto error; + } + } + + if (uid > 0) { +# ifdef HAVE_INITGROUPS + struct passwd pwd, *pwd_result; + size_t bufsize; + int rc; + + bufsize = sysconf(_SC_GETPW_R_SIZE_MAX); + if (bufsize == -1) + bufsize = 16384; + + if (VIR_ALLOC_N(buf, bufsize) < 0) { + virReportOOMError(); + err = ENOMEM; + goto error; + } + while ((rc = getpwuid_r(uid, &pwd, buf, bufsize, + &pwd_result)) == ERANGE) { + if (VIR_RESIZE_N(buf, bufsize, bufsize, bufsize) < 0) { + virReportOOMError(); + err = ENOMEM; + goto error; + } + } + + if (rc) { + virReportSystemError(err = rc, _("cannot getpwuid_r(%d)"), + (unsigned int) uid); + goto error; + } + + if (!pwd_result) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("getpwuid_r failed to retrieve data " + "for uid '%d'"), + (unsigned int) uid); + err = EINVAL; + goto error; + } + + if (initgroups(pwd.pw_name, pwd.pw_gid) < 0) { + virReportSystemError(err = errno, + _("cannot initgroups(\"%s\", %d)"), + pwd.pw_name, (unsigned int) pwd.pw_gid); + goto error; + } +# endif + if (setreuid(uid, uid) < 0) { + virReportSystemError(err = errno, + _("cannot change to uid to '%d'"), + (unsigned int) uid); + goto error; + } + } + + VIR_FREE(buf); + return 0; + +error: + VIR_FREE(buf); + errno = err; + return -1; +} + +#else /* ! HAVE_GETPWUID_R */ + +# ifdef WIN32 +/* These methods are adapted from GLib2 under terms of LGPLv2+ */ +static int +virGetWin32SpecialFolder(int csidl, char **path) +{ + char buf[MAX_PATH+1]; + LPITEMIDLIST pidl = NULL; + int ret = 0; + + *path = NULL; + + if (SHGetSpecialFolderLocation(NULL, csidl, &pidl) == S_OK) { + if (SHGetPathFromIDList(pidl, buf)) { + if (!(*path = strdup(buf))) { + virReportOOMError(); + ret = -1; + } + } + CoTaskMemFree(pidl); + } + return ret; +} + +static int +virGetWin32DirectoryRoot(char **path) +{ + char windowsdir[MAX_PATH]; + int ret = 0; + + *path = NULL; + + if (GetWindowsDirectory(windowsdir, ARRAY_CARDINALITY(windowsdir))) + { + const char *tmp; + /* Usually X:\Windows, but in terminal server environments + * might be an UNC path, AFAIK. + */ + tmp = virFileSkipRoot(windowsdir); + if (VIR_FILE_IS_DIR_SEPARATOR(tmp[-1]) && + tmp[-2] != ':') + tmp--; + + windowsdir[tmp - windowsdir] = '\0'; + } else { + strcpy(windowsdir, "C:\\"); + } + + if (!(*path = strdup(windowsdir))) { + virReportOOMError(); + ret = -1; + } + + return ret; +} + + + +char * +virGetUserDirectory(void) +{ + const char *dir; + char *ret; + + dir = getenv("HOME"); + + /* Only believe HOME if it is an absolute path and exists */ + if (dir) { + if (!virFileIsAbsPath(dir) || + !virFileExists(dir)) + dir = NULL; + } + + /* In case HOME is Unix-style (it happens), convert it to + * Windows style. + */ + if (dir) { + char *p; + while ((p = strchr(dir, '/')) != NULL) + *p = '\\'; + } + + if (!dir) + /* USERPROFILE is probably the closest equivalent to $HOME? */ + dir = getenv("USERPROFILE"); + + if (dir) { + if (!(ret = strdup(dir))) { + virReportOOMError(); + return NULL; + } + } + + if (!ret && + virGetWin32SpecialFolder(CSIDL_PROFILE, &ret) < 0) + return NULL; + + if (!ret && + virGetWin32DirectoryRoot(&ret) < 0) + return NULL; + + if (!ret) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Unable to determine home directory")); + return NULL; + } + + return ret; +} + +char * +virGetUserConfigDirectory(void) +{ + char *ret; + if (virGetWin32SpecialFolder(CSIDL_LOCAL_APPDATA, &ret) < 0) + return NULL; + + if (!ret) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Unable to determine config directory")); + return NULL; + } + return ret; +} + +char * +virGetUserCacheDirectory(void) +{ + char *ret; + if (virGetWin32SpecialFolder(CSIDL_INTERNET_CACHE, &ret) < 0) + return NULL; + + if (!ret) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Unable to determine config directory")); + return NULL; + } + return ret; +} + +char * +virGetUserRuntimeDirectory(void) +{ + return virGetUserCacheDirectory(); +} +# else /* !HAVE_GETPWUID_R && !WIN32 */ +char * +virGetUserDirectory(void) +{ + virReportError(VIR_ERR_INTERNAL_ERROR, + "%s", _("virGetUserDirectory is not available")); + + return NULL; +} + +char * +virGetUserConfigDirectory(void) +{ + virReportError(VIR_ERR_INTERNAL_ERROR, + "%s", _("virGetUserConfigDirectory is not available")); + + return NULL; +} + +char * +virGetUserCacheDirectory(void) +{ + virReportError(VIR_ERR_INTERNAL_ERROR, + "%s", _("virGetUserCacheDirectory is not available")); + + return NULL; +} + +char * +virGetUserRuntimeDirectory(void) +{ + virReportError(VIR_ERR_INTERNAL_ERROR, + "%s", _("virGetUserRuntimeDirectory is not available")); + + return NULL; +} +# endif /* ! HAVE_GETPWUID_R && ! WIN32 */ + +char * +virGetUserName(uid_t uid ATTRIBUTE_UNUSED) +{ + virReportError(VIR_ERR_INTERNAL_ERROR, + "%s", _("virGetUserName is not available")); + + return NULL; +} + +int virGetUserID(const char *name ATTRIBUTE_UNUSED, + uid_t *uid ATTRIBUTE_UNUSED) +{ + virReportError(VIR_ERR_INTERNAL_ERROR, + "%s", _("virGetUserID is not available")); + + return 0; +} + + +int virGetGroupID(const char *name ATTRIBUTE_UNUSED, + gid_t *gid ATTRIBUTE_UNUSED) +{ + virReportError(VIR_ERR_INTERNAL_ERROR, + "%s", _("virGetGroupID is not available")); + + return 0; +} + +int +virSetUIDGID(uid_t uid ATTRIBUTE_UNUSED, + gid_t gid ATTRIBUTE_UNUSED) +{ + virReportError(VIR_ERR_INTERNAL_ERROR, + "%s", _("virSetUIDGID is not available")); + return -1; +} + +char * +virGetGroupName(gid_t gid ATTRIBUTE_UNUSED) +{ + virReportError(VIR_ERR_INTERNAL_ERROR, + "%s", _("virGetGroupName is not available")); + + return NULL; +} +#endif /* HAVE_GETPWUID_R */ + + +#if defined HAVE_MNTENT_H && defined HAVE_GETMNTENT_R +/* search /proc/mounts for mount point of *type; return pointer to + * malloc'ed string of the path if found, otherwise return NULL + * with errno set to an appropriate value. + */ +char *virFileFindMountPoint(const char *type) +{ + FILE *f; + struct mntent mb; + char mntbuf[1024]; + char *ret = NULL; + + f = setmntent("/proc/mounts", "r"); + if (!f) + return NULL; + + while (getmntent_r(f, &mb, mntbuf, sizeof(mntbuf))) { + if (STREQ(mb.mnt_type, type)) { + ret = strdup(mb.mnt_dir); + goto cleanup; + } + } + + if (!ret) + errno = ENOENT; + +cleanup: + endmntent(f); + + return ret; +} + +#else /* defined HAVE_MNTENT_H && defined HAVE_GETMNTENT_R */ + +char * +virFileFindMountPoint(const char *type ATTRIBUTE_UNUSED) +{ + errno = ENOSYS; + + return NULL; +} + +#endif /* defined HAVE_MNTENT_H && defined HAVE_GETMNTENT_R */ + +#if defined(UDEVADM) || defined(UDEVSETTLE) +void virFileWaitForDevices(void) +{ +# ifdef UDEVADM + const char *const settleprog[] = { UDEVADM, "settle", NULL }; +# else + const char *const settleprog[] = { UDEVSETTLE, NULL }; +# endif + int exitstatus; + + if (access(settleprog[0], X_OK) != 0) + return; + + /* + * NOTE: we ignore errors here; this is just to make sure that any device + * nodes that are being created finish before we try to scan them. + * If this fails for any reason, we still have the backup of polling for + * 5 seconds for device nodes. + */ + if (virRun(settleprog, &exitstatus) < 0) + {} +} +#else +void virFileWaitForDevices(void) {} +#endif + +int virBuildPathInternal(char **path, ...) +{ + char *path_component = NULL; + virBuffer buf = VIR_BUFFER_INITIALIZER; + va_list ap; + int ret = 0; + + va_start(ap, path); + + path_component = va_arg(ap, char *); + virBufferAdd(&buf, path_component, -1); + + while ((path_component = va_arg(ap, char *)) != NULL) + { + virBufferAddChar(&buf, '/'); + virBufferAdd(&buf, path_component, -1); + } + + va_end(ap); + + *path = virBufferContentAndReset(&buf); + if (*path == NULL) { + ret = -1; + } + + return ret; +} + +#if HAVE_LIBDEVMAPPER_H +bool +virIsDevMapperDevice(const char *dev_name) +{ + struct stat buf; + + if (!stat(dev_name, &buf) && + S_ISBLK(buf.st_mode) && + dm_is_dm_major(major(buf.st_rdev))) + return true; + + return false; +} +#else +bool virIsDevMapperDevice(const char *dev_name ATTRIBUTE_UNUSED) +{ + return false; +} +#endif + +bool +virValidateWWN(const char *wwn) { + int i; + + for (i = 0; wwn[i]; i++) + if (!c_isxdigit(wwn[i])) + break; + + if (i != 16 || wwn[i]) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Malformed wwn: %s")); + return false; + } + + return true; +} + +bool +virStrIsPrint(const char *str) +{ + int i; + + for (i = 0; str[i]; i++) + if (!c_isprint(str[i])) + return false; + + return true; +} diff --git a/src/util/virutil.h b/src/util/virutil.h new file mode 100644 index 0000000..6d5dd03 --- /dev/null +++ b/src/util/virutil.h @@ -0,0 +1,284 @@ +/* + * utils.h: common, generic utility functions + * + * Copyright (C) 2010-2012 Red Hat, Inc. + * Copyright (C) 2006, 2007 Binary Karma + * Copyright (C) 2006 Shuveb Hussain + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <http://www.gnu.org/licenses/>. + * + * File created Jul 18, 2007 - Shuveb Hussain <shuveb@xxxxxxxxxxxxxxx> + */ + +#ifndef __VIR_UTIL_H__ +# define __VIR_UTIL_H__ + +# include "verify.h" +# include "internal.h" +# include <unistd.h> +# include <sys/select.h> +# include <sys/types.h> +# include <stdarg.h> + +# ifndef MIN +# define MIN(a, b) ((a) < (b) ? (a) : (b)) +# endif +# ifndef MAX +# define MAX(a, b) ((a) > (b) ? (a) : (b)) +# endif + +ssize_t saferead(int fd, void *buf, size_t count) ATTRIBUTE_RETURN_CHECK; +ssize_t safewrite(int fd, const void *buf, size_t count) + ATTRIBUTE_RETURN_CHECK; +int safezero(int fd, off_t offset, off_t len) + ATTRIBUTE_RETURN_CHECK; + +int virSetBlocking(int fd, bool blocking) ATTRIBUTE_RETURN_CHECK; +int virSetNonBlock(int fd) ATTRIBUTE_RETURN_CHECK; +int virSetInherit(int fd, bool inherit) ATTRIBUTE_RETURN_CHECK; +int virSetCloseExec(int fd) ATTRIBUTE_RETURN_CHECK; + +int virPipeReadUntilEOF(int outfd, int errfd, + char **outbuf, char **errbuf); + +int virSetUIDGID(uid_t uid, gid_t gid); + +int virFileReadLimFD(int fd, int maxlen, char **buf) ATTRIBUTE_RETURN_CHECK; + +int virFileReadAll(const char *path, int maxlen, char **buf) ATTRIBUTE_RETURN_CHECK; + +int virFileWriteStr(const char *path, const char *str, mode_t mode) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; + +int virFileMatchesNameSuffix(const char *file, + const char *name, + const char *suffix); + +int virFileHasSuffix(const char *str, + const char *suffix); + +int virFileStripSuffix(char *str, + const char *suffix) ATTRIBUTE_RETURN_CHECK; + +int virFileLinkPointsTo(const char *checkLink, + const char *checkDest); + +int virFileResolveLink(const char *linkpath, + char **resultpath) ATTRIBUTE_RETURN_CHECK; +int virFileResolveAllLinks(const char *linkpath, + char **resultpath) ATTRIBUTE_RETURN_CHECK; + +int virFileIsLink(const char *linkpath) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; + +char *virFindFileInPath(const char *file); + +bool virFileIsDir (const char *file) ATTRIBUTE_NONNULL(1); +bool virFileExists(const char *file) ATTRIBUTE_NONNULL(1); +bool virFileIsExecutable(const char *file) ATTRIBUTE_NONNULL(1); + +char *virFileSanitizePath(const char *path); + +enum { + VIR_FILE_OPEN_NONE = 0, + VIR_FILE_OPEN_NOFORK = (1 << 0), + VIR_FILE_OPEN_FORK = (1 << 1), + VIR_FILE_OPEN_FORCE_MODE = (1 << 2), + VIR_FILE_OPEN_FORCE_OWNER = (1 << 3), +}; +int virFileAccessibleAs(const char *path, int mode, + uid_t uid, gid_t gid) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; +int virFileOpenAs(const char *path, int openflags, mode_t mode, + uid_t uid, gid_t gid, + unsigned int flags) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; + +enum { + VIR_DIR_CREATE_NONE = 0, + VIR_DIR_CREATE_AS_UID = (1 << 0), + VIR_DIR_CREATE_FORCE_PERMS = (1 << 1), + VIR_DIR_CREATE_ALLOW_EXIST = (1 << 2), +}; +int virDirCreate(const char *path, mode_t mode, uid_t uid, gid_t gid, + unsigned int flags) ATTRIBUTE_RETURN_CHECK; +int virFileMakePath(const char *path) ATTRIBUTE_RETURN_CHECK; +int virFileMakePathWithMode(const char *path, + mode_t mode) ATTRIBUTE_RETURN_CHECK; + +char *virFileBuildPath(const char *dir, + const char *name, + const char *ext) ATTRIBUTE_RETURN_CHECK; + + +# ifdef WIN32 +/* On Win32, the canonical directory separator is the backslash, and + * the search path separator is the semicolon. Note that also the + * (forward) slash works as directory separator. + */ +# define VIR_FILE_DIR_SEPARATOR '\\' +# define VIR_FILE_DIR_SEPARATOR_S "\\" +# define VIR_FILE_IS_DIR_SEPARATOR(c) ((c) == VIR_FILE_DIR_SEPARATOR || (c) == '/') +# define VIR_FILE_PATH_SEPARATOR ';' +# define VIR_FILE_PATH_SEPARATOR_S ";" + +# else /* !WIN32 */ + +# define VIR_FILE_DIR_SEPARATOR '/' +# define VIR_FILE_DIR_SEPARATOR_S "/" +# define VIR_FILE_IS_DIR_SEPARATOR(c) ((c) == VIR_FILE_DIR_SEPARATOR) +# define VIR_FILE_PATH_SEPARATOR ':' +# define VIR_FILE_PATH_SEPARATOR_S ":" + +# endif /* !WIN32 */ + +bool virFileIsAbsPath(const char *path); +int virFileAbsPath(const char *path, + char **abspath) ATTRIBUTE_RETURN_CHECK; +const char *virFileSkipRoot(const char *path); + +int virFileOpenTty(int *ttymaster, + char **ttyName, + int rawmode); + +char *virArgvToString(const char *const *argv); + +int virStrToLong_i(char const *s, + char **end_ptr, + int base, + int *result); + +int virStrToLong_ui(char const *s, + char **end_ptr, + int base, + unsigned int *result); +int virStrToLong_l(char const *s, + char **end_ptr, + int base, + long *result); +int virStrToLong_ul(char const *s, + char **end_ptr, + int base, + unsigned long *result); +int virStrToLong_ll(char const *s, + char **end_ptr, + int base, + long long *result); +int virStrToLong_ull(char const *s, + char **end_ptr, + int base, + unsigned long long *result); +int virStrToDouble(char const *s, + char **end_ptr, + double *result); + +int virScaleInteger(unsigned long long *value, const char *suffix, + unsigned long long scale, unsigned long long limit) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; + +int virHexToBin(unsigned char c); + +void virSkipSpaces(const char **str) ATTRIBUTE_NONNULL(1); +void virSkipSpacesAndBackslash(const char **str) ATTRIBUTE_NONNULL(1); +void virTrimSpaces(char *str, char **endp) ATTRIBUTE_NONNULL(1); +void virSkipSpacesBackwards(const char *str, char **endp) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); + +int virParseNumber(const char **str); +int virParseVersionString(const char *str, unsigned long *version, + bool allowMissing); +int virAsprintf(char **strp, const char *fmt, ...) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_FMT_PRINTF(2, 3); +int virVasprintf(char **strp, const char *fmt, va_list list) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_FMT_PRINTF(2, 0); +char *virStrncpy(char *dest, const char *src, size_t n, size_t destbytes) + ATTRIBUTE_RETURN_CHECK; +char *virStrcpy(char *dest, const char *src, size_t destbytes) + ATTRIBUTE_RETURN_CHECK; +# define virStrcpyStatic(dest, src) virStrcpy((dest), (src), sizeof(dest)) + +int virDoubleToStr(char **strp, double number) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; + +char *virFormatIntDecimal(char *buf, size_t buflen, int val) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; + +int virDiskNameToIndex(const char* str); +char *virIndexToDiskName(int idx, const char *prefix); + +int virEnumFromString(const char *const*types, + unsigned int ntypes, + const char *type); + +const char *virEnumToString(const char *const*types, + unsigned int ntypes, + int type); + +# define VIR_ENUM_IMPL(name, lastVal, ...) \ + static const char *const name ## TypeList[] = { __VA_ARGS__ }; \ + verify(ARRAY_CARDINALITY(name ## TypeList) == lastVal); \ + const char *name ## TypeToString(int type) { \ + return virEnumToString(name ## TypeList, \ + ARRAY_CARDINALITY(name ## TypeList), \ + type); \ + } \ + int name ## TypeFromString(const char *type) { \ + return virEnumFromString(name ## TypeList, \ + ARRAY_CARDINALITY(name ## TypeList), \ + type); \ + } + +# define VIR_ENUM_DECL(name) \ + const char *name ## TypeToString(int type); \ + int name ## TypeFromString(const char*type); + +# ifndef HAVE_GETUID +static inline int getuid (void) { return 0; } +# endif + +# ifndef HAVE_GETEUID +static inline int geteuid (void) { return 0; } +# endif + +# ifndef HAVE_GETGID +static inline int getgid (void) { return 0; } +# endif + +char *virGetHostname(virConnectPtr conn); + +char *virGetUserDirectory(void); +char *virGetUserConfigDirectory(void); +char *virGetUserCacheDirectory(void); +char *virGetUserRuntimeDirectory(void); +char *virGetUserName(uid_t uid); +char *virGetGroupName(gid_t gid); +int virGetUserID(const char *name, + uid_t *uid) ATTRIBUTE_RETURN_CHECK; +int virGetGroupID(const char *name, + gid_t *gid) ATTRIBUTE_RETURN_CHECK; + +char *virFileFindMountPoint(const char *type); + +void virFileWaitForDevices(void); + +# define virBuildPath(path, ...) virBuildPathInternal(path, __VA_ARGS__, NULL) +int virBuildPathInternal(char **path, ...) ATTRIBUTE_SENTINEL; + +bool virIsDevMapperDevice(const char *dev_name) ATTRIBUTE_NONNULL(1); + +bool virValidateWWN(const char *wwn); + +bool virStrIsPrint(const char *str); +#endif /* __VIR_UTIL_H__ */ diff --git a/src/util/xml.c b/src/util/xml.c index caf26a3..05c7f33 100644 --- a/src/util/xml.c +++ b/src/util/xml.c @@ -33,7 +33,7 @@ #include "virterror_internal.h" #include "xml.h" #include "virbuffer.h" -#include "util.h" +#include "virutil.h" #include "viralloc.h" #include "virfile.h" diff --git a/src/vbox/vbox_MSCOMGlue.c b/src/vbox/vbox_MSCOMGlue.c index cab4398..36539f6 100644 --- a/src/vbox/vbox_MSCOMGlue.c +++ b/src/vbox/vbox_MSCOMGlue.c @@ -31,7 +31,7 @@ #include "internal.h" #include "viralloc.h" -#include "util.h" +#include "virutil.h" #include "virlog.h" #include "virterror_internal.h" #include "vbox_MSCOMGlue.h" diff --git a/src/vbox/vbox_XPCOMCGlue.c b/src/vbox/vbox_XPCOMCGlue.c index 5296127..1954ddb 100644 --- a/src/vbox/vbox_XPCOMCGlue.c +++ b/src/vbox/vbox_XPCOMCGlue.c @@ -38,7 +38,7 @@ #include "vbox_XPCOMCGlue.h" #include "internal.h" #include "viralloc.h" -#include "util.h" +#include "virutil.h" #include "virlog.h" #include "virterror_internal.h" diff --git a/src/vbox/vbox_driver.c b/src/vbox/vbox_driver.c index cd29e19..f2a0c8f 100644 --- a/src/vbox/vbox_driver.c +++ b/src/vbox/vbox_driver.c @@ -38,7 +38,7 @@ #include "vbox_driver.h" #include "vbox_glue.h" #include "virterror_internal.h" -#include "util.h" +#include "virutil.h" #define VIR_FROM_THIS VIR_FROM_VBOX diff --git a/src/vmware/vmware_driver.c b/src/vmware/vmware_driver.c index 233804e..12195bf 100644 --- a/src/vmware/vmware_driver.c +++ b/src/vmware/vmware_driver.c @@ -28,7 +28,7 @@ #include "datatypes.h" #include "virfile.h" #include "viralloc.h" -#include "util.h" +#include "virutil.h" #include "uuid.h" #include "vircommand.h" #include "vmx.h" diff --git a/src/xen/block_stats.c b/src/xen/block_stats.c index 126283b..3f7c97b 100644 --- a/src/xen/block_stats.c +++ b/src/xen/block_stats.c @@ -40,7 +40,7 @@ # include "virterror_internal.h" # include "datatypes.h" -# include "util.h" +# include "virutil.h" # include "block_stats.h" # include "viralloc.h" # include "virfile.h" diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c index 9b2fcf3..2b8496c 100644 --- a/src/xen/xen_driver.c +++ b/src/xen/xen_driver.c @@ -54,7 +54,7 @@ # include "xen_inotify.h" #endif #include "xml.h" -#include "util.h" +#include "virutil.h" #include "viralloc.h" #include "node_device_conf.h" #include "virpci.h" diff --git a/src/xen/xen_hypervisor.c b/src/xen/xen_hypervisor.c index 5c8fe37..f804620 100644 --- a/src/xen/xen_hypervisor.c +++ b/src/xen/xen_hypervisor.c @@ -67,7 +67,7 @@ #include "virlog.h" #include "datatypes.h" #include "driver.h" -#include "util.h" +#include "virutil.h" #include "xen_driver.h" #include "xen_hypervisor.h" #include "xs_internal.h" diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c index 6e8bc2f..7ffc5bb 100644 --- a/src/xen/xend_internal.c +++ b/src/xen/xend_internal.c @@ -34,7 +34,7 @@ #include "datatypes.h" #include "xend_internal.h" #include "driver.h" -#include "util.h" +#include "virutil.h" #include "virsexpr.h" #include "xen_sxpr.h" #include "virbuffer.h" diff --git a/src/xen/xm_internal.c b/src/xen/xm_internal.c index 2109972..e3206eb 100644 --- a/src/xen/xm_internal.c +++ b/src/xen/xm_internal.c @@ -45,7 +45,7 @@ #include "virhash.h" #include "virbuffer.h" #include "uuid.h" -#include "util.h" +#include "virutil.h" #include "viralloc.h" #include "virlog.h" #include "count-one-bits.h" diff --git a/src/xenapi/xenapi_driver.c b/src/xenapi/xenapi_driver.c index 0a0ac0e..04b24ab 100644 --- a/src/xenapi/xenapi_driver.c +++ b/src/xenapi/xenapi_driver.c @@ -31,7 +31,7 @@ #include "virterror_internal.h" #include "datatypes.h" #include "virauth.h" -#include "util.h" +#include "virutil.h" #include "uuid.h" #include "viralloc.h" #include "virbuffer.h" diff --git a/src/xenapi/xenapi_utils.c b/src/xenapi/xenapi_utils.c index 33aa4d7..15be403 100644 --- a/src/xenapi/xenapi_utils.c +++ b/src/xenapi/xenapi_utils.c @@ -29,7 +29,7 @@ #include "domain_conf.h" #include "virterror_internal.h" #include "datatypes.h" -#include "util.h" +#include "virutil.h" #include "uuid.h" #include "viralloc.h" #include "virbuffer.h" diff --git a/tests/commandhelper.c b/tests/commandhelper.c index 3c7fef5..39f3c53 100644 --- a/tests/commandhelper.c +++ b/tests/commandhelper.c @@ -27,7 +27,7 @@ #include <string.h> #include "internal.h" -#include "util.h" +#include "virutil.h" #include "viralloc.h" #include "virfile.h" #include "testutils.h" diff --git a/tests/commandtest.c b/tests/commandtest.c index b15c168..d6a285e 100644 --- a/tests/commandtest.c +++ b/tests/commandtest.c @@ -31,7 +31,7 @@ #include "testutils.h" #include "internal.h" #include "nodeinfo.h" -#include "util.h" +#include "virutil.h" #include "viralloc.h" #include "vircommand.h" #include "virfile.h" diff --git a/tests/esxutilstest.c b/tests/esxutilstest.c index b65009b..55b3623 100644 --- a/tests/esxutilstest.c +++ b/tests/esxutilstest.c @@ -9,7 +9,7 @@ # include "internal.h" # include "viralloc.h" # include "testutils.h" -# include "util.h" +# include "virutil.h" # include "vmx/vmx.h" # include "esx/esx_util.h" # include "esx/esx_vi_types.h" diff --git a/tests/eventtest.c b/tests/eventtest.c index 6d00ea8..16a693c 100644 --- a/tests/eventtest.c +++ b/tests/eventtest.c @@ -30,7 +30,7 @@ #include "internal.h" #include "virthread.h" #include "virlog.h" -#include "util.h" +#include "virutil.h" #include "vireventpoll.h" #define NUM_FDS 31 diff --git a/tests/libvirtdconftest.c b/tests/libvirtdconftest.c index 0365ade..c1d94d2 100644 --- a/tests/libvirtdconftest.c +++ b/tests/libvirtdconftest.c @@ -24,7 +24,7 @@ #include "testutils.h" #include "daemon/libvirtd-config.h" -#include "util.h" +#include "virutil.h" #include "c-ctype.h" #include "virterror_internal.h" #include "virlog.h" diff --git a/tests/nodeinfotest.c b/tests/nodeinfotest.c index c79788e..d900eb9 100644 --- a/tests/nodeinfotest.c +++ b/tests/nodeinfotest.c @@ -8,7 +8,7 @@ #include "testutils.h" #include "internal.h" #include "nodeinfo.h" -#include "util.h" +#include "virutil.h" #include "virfile.h" #if ! (defined __linux__ && (defined(__x86_64__) || \ diff --git a/tests/openvzutilstest.c b/tests/openvzutilstest.c index 80701a2..9fb7178 100644 --- a/tests/openvzutilstest.c +++ b/tests/openvzutilstest.c @@ -9,7 +9,7 @@ # include "internal.h" # include "viralloc.h" # include "testutils.h" -# include "util.h" +# include "virutil.h" # include "openvz/openvz_conf.h" static int diff --git a/tests/qemumonitortest.c b/tests/qemumonitortest.c index 21a6828..285dfa8 100644 --- a/tests/qemumonitortest.c +++ b/tests/qemumonitortest.c @@ -10,7 +10,7 @@ # include "internal.h" # include "viralloc.h" # include "testutils.h" -# include "util.h" +# include "virutil.h" # include "qemu/qemu_monitor.h" struct testEscapeString diff --git a/tests/qemumonitortestutils.c b/tests/qemumonitortestutils.c index cc38803..b82eb5d 100644 --- a/tests/qemumonitortestutils.c +++ b/tests/qemumonitortestutils.c @@ -30,7 +30,7 @@ #include "qemu/qemu_monitor.h" #include "rpc/virnetsocket.h" #include "viralloc.h" -#include "util.h" +#include "virutil.h" #include "virlog.h" #include "virterror_internal.h" diff --git a/tests/securityselinuxtest.c b/tests/securityselinuxtest.c index 045c9c0..b523c79 100644 --- a/tests/securityselinuxtest.c +++ b/tests/securityselinuxtest.c @@ -31,7 +31,7 @@ #include "internal.h" #include "testutils.h" #include "viralloc.h" -#include "util.h" +#include "virutil.h" #include "virlog.h" #include "virterror_internal.h" #include "security/security_manager.h" diff --git a/tests/testutils.c b/tests/testutils.c index c6b1d23..d88af21 100644 --- a/tests/testutils.c +++ b/tests/testutils.c @@ -40,7 +40,7 @@ #include "testutils.h" #include "internal.h" #include "viralloc.h" -#include "util.h" +#include "virutil.h" #include "virthread.h" #include "virterror_internal.h" #include "virbuffer.h" diff --git a/tests/utiltest.c b/tests/utiltest.c index 4fbb25c..9d18652 100644 --- a/tests/utiltest.c +++ b/tests/utiltest.c @@ -8,7 +8,7 @@ #include "internal.h" #include "viralloc.h" #include "testutils.h" -#include "util.h" +#include "virutil.h" static void diff --git a/tests/virauthconfigtest.c b/tests/virauthconfigtest.c index 9e7dac5..2ad237d 100644 --- a/tests/virauthconfigtest.c +++ b/tests/virauthconfigtest.c @@ -24,7 +24,7 @@ #include <signal.h> #include "testutils.h" -#include "util.h" +#include "virutil.h" #include "virterror_internal.h" #include "viralloc.h" #include "virlog.h" diff --git a/tests/virbuftest.c b/tests/virbuftest.c index ec93939..7f9ee66 100644 --- a/tests/virbuftest.c +++ b/tests/virbuftest.c @@ -5,7 +5,7 @@ #include <string.h> #include "internal.h" -#include "util.h" +#include "virutil.h" #include "testutils.h" #include "virbuffer.h" #include "viralloc.h" diff --git a/tests/virdrivermoduletest.c b/tests/virdrivermoduletest.c index e06179f..cab47d3 100644 --- a/tests/virdrivermoduletest.c +++ b/tests/virdrivermoduletest.c @@ -21,7 +21,7 @@ #include <config.h> #include "testutils.h" -#include "util.h" +#include "virutil.h" #include "virterror_internal.h" #include "viralloc.h" #include "virlog.h" diff --git a/tests/virhashtest.c b/tests/virhashtest.c index a2a40c6..6e4f267 100644 --- a/tests/virhashtest.c +++ b/tests/virhashtest.c @@ -10,7 +10,7 @@ #include "virhashdata.h" #include "testutils.h" #include "viralloc.h" -#include "util.h" +#include "virutil.h" #include "virlog.h" diff --git a/tests/virkeyfiletest.c b/tests/virkeyfiletest.c index ad5a516..33f64c1 100644 --- a/tests/virkeyfiletest.c +++ b/tests/virkeyfiletest.c @@ -24,7 +24,7 @@ #include <signal.h> #include "testutils.h" -#include "util.h" +#include "virutil.h" #include "virterror_internal.h" #include "viralloc.h" #include "virlog.h" diff --git a/tests/virlockspacetest.c b/tests/virlockspacetest.c index 80478d9..c434f47 100644 --- a/tests/virlockspacetest.c +++ b/tests/virlockspacetest.c @@ -25,7 +25,7 @@ #include <sys/stat.h> #include "testutils.h" -#include "util.h" +#include "virutil.h" #include "virterror_internal.h" #include "viralloc.h" #include "virlog.h" diff --git a/tests/virnetmessagetest.c b/tests/virnetmessagetest.c index e3517e8..4e7a1fd 100644 --- a/tests/virnetmessagetest.c +++ b/tests/virnetmessagetest.c @@ -24,7 +24,7 @@ #include <signal.h> #include "testutils.h" -#include "util.h" +#include "virutil.h" #include "virterror_internal.h" #include "viralloc.h" #include "virlog.h" diff --git a/tests/virnetsockettest.c b/tests/virnetsockettest.c index 399c4fd..819257b 100644 --- a/tests/virnetsockettest.c +++ b/tests/virnetsockettest.c @@ -28,7 +28,7 @@ #include <netdb.h> #include "testutils.h" -#include "util.h" +#include "virutil.h" #include "virterror_internal.h" #include "viralloc.h" #include "virlog.h" diff --git a/tests/virnettlscontexttest.c b/tests/virnettlscontexttest.c index 27078ea..d945181 100644 --- a/tests/virnettlscontexttest.c +++ b/tests/virnettlscontexttest.c @@ -27,7 +27,7 @@ #include <gnutls/x509.h> #include "testutils.h" -#include "util.h" +#include "virutil.h" #include "virterror_internal.h" #include "viralloc.h" #include "virlog.h" diff --git a/tests/virshtest.c b/tests/virshtest.c index 72f2a1e..8741d47 100644 --- a/tests/virshtest.c +++ b/tests/virshtest.c @@ -6,7 +6,7 @@ #include "internal.h" #include "xml.h" -#include "util.h" +#include "virutil.h" #include "testutils.h" #ifdef WIN32 diff --git a/tests/virstringtest.c b/tests/virstringtest.c index a8f4c79..58ab843 100644 --- a/tests/virstringtest.c +++ b/tests/virstringtest.c @@ -23,7 +23,7 @@ #include <stdlib.h> #include "testutils.h" -#include "util.h" +#include "virutil.h" #include "virterror_internal.h" #include "viralloc.h" #include "virlog.h" diff --git a/tests/virtimetest.c b/tests/virtimetest.c index 7d7a2d6..1c22d07 100644 --- a/tests/virtimetest.c +++ b/tests/virtimetest.c @@ -24,7 +24,7 @@ #include <signal.h> #include "testutils.h" -#include "util.h" +#include "virutil.h" #include "virterror_internal.h" #include "viralloc.h" #include "virlog.h" diff --git a/tests/viruritest.c b/tests/viruritest.c index 57d3895..ad59270 100644 --- a/tests/viruritest.c +++ b/tests/viruritest.c @@ -24,7 +24,7 @@ #include <signal.h> #include "testutils.h" -#include "util.h" +#include "virutil.h" #include "virterror_internal.h" #include "viralloc.h" #include "virlog.h" diff --git a/tools/console.c b/tools/console.c index d031308..d024d38 100644 --- a/tools/console.c +++ b/tools/console.c @@ -39,7 +39,7 @@ # include "internal.h" # include "console.h" # include "virlog.h" -# include "util.h" +# include "virutil.h" # include "virfile.h" # include "viralloc.h" # include "virthread.h" diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index b0b0c94..244ffb8 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -43,7 +43,7 @@ #include "conf/domain_conf.h" #include "console.h" #include "viralloc.h" -#include "util.h" +#include "virutil.h" #include "virfile.h" #include "virkeycode.h" #include "virmacaddr.h" diff --git a/tools/virsh-host.c b/tools/virsh-host.c index 2d59a75..0ad4296 100644 --- a/tools/virsh-host.c +++ b/tools/virsh-host.c @@ -34,7 +34,7 @@ #include "internal.h" #include "virbuffer.h" #include "viralloc.h" -#include "util.h" +#include "virutil.h" #include "virsh-domain.h" #include "xml.h" #include "virtypedparam.h" diff --git a/tools/virsh-interface.c b/tools/virsh-interface.c index 40216c6..ea8a6c5 100644 --- a/tools/virsh-interface.c +++ b/tools/virsh-interface.c @@ -34,7 +34,7 @@ #include "internal.h" #include "virbuffer.h" #include "viralloc.h" -#include "util.h" +#include "virutil.h" #include "xml.h" virInterfacePtr diff --git a/tools/virsh-network.c b/tools/virsh-network.c index 66ee7e3..918dee6 100644 --- a/tools/virsh-network.c +++ b/tools/virsh-network.c @@ -34,7 +34,7 @@ #include "internal.h" #include "virbuffer.h" #include "viralloc.h" -#include "util.h" +#include "virutil.h" #include "xml.h" #include "conf/network_conf.h" diff --git a/tools/virsh-nodedev.c b/tools/virsh-nodedev.c index 7e569b3..974e495 100644 --- a/tools/virsh-nodedev.c +++ b/tools/virsh-nodedev.c @@ -34,7 +34,7 @@ #include "internal.h" #include "virbuffer.h" #include "viralloc.h" -#include "util.h" +#include "virutil.h" #include "xml.h" #include "conf/node_device_conf.h" diff --git a/tools/virsh-nwfilter.c b/tools/virsh-nwfilter.c index c3dba0c..1480d13 100644 --- a/tools/virsh-nwfilter.c +++ b/tools/virsh-nwfilter.c @@ -34,7 +34,7 @@ #include "internal.h" #include "virbuffer.h" #include "viralloc.h" -#include "util.h" +#include "virutil.h" #include "xml.h" virNWFilterPtr diff --git a/tools/virsh-pool.c b/tools/virsh-pool.c index 6e29604..b3177e0 100644 --- a/tools/virsh-pool.c +++ b/tools/virsh-pool.c @@ -34,7 +34,7 @@ #include "internal.h" #include "virbuffer.h" #include "viralloc.h" -#include "util.h" +#include "virutil.h" #include "xml.h" #include "conf/storage_conf.h" diff --git a/tools/virsh-secret.c b/tools/virsh-secret.c index d81e8ce..a29454f 100644 --- a/tools/virsh-secret.c +++ b/tools/virsh-secret.c @@ -35,7 +35,7 @@ #include "base64.h" #include "virbuffer.h" #include "viralloc.h" -#include "util.h" +#include "virutil.h" #include "xml.h" static virSecretPtr diff --git a/tools/virsh-snapshot.c b/tools/virsh-snapshot.c index 3fecde6..8428282 100644 --- a/tools/virsh-snapshot.c +++ b/tools/virsh-snapshot.c @@ -36,7 +36,7 @@ #include "internal.h" #include "virbuffer.h" #include "viralloc.h" -#include "util.h" +#include "virutil.h" #include "virsh-domain.h" #include "xml.h" #include "conf/snapshot_conf.h" diff --git a/tools/virsh-volume.c b/tools/virsh-volume.c index ebfe52d..6f2c591 100644 --- a/tools/virsh-volume.c +++ b/tools/virsh-volume.c @@ -36,7 +36,7 @@ #include "internal.h" #include "virbuffer.h" #include "viralloc.h" -#include "util.h" +#include "virutil.h" #include "virfile.h" #include "virsh-pool.h" #include "xml.h" diff --git a/tools/virsh.c b/tools/virsh.c index 91a9677..bfeaaa1 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -58,7 +58,7 @@ #include "base64.h" #include "virbuffer.h" #include "console.h" -#include "util.h" +#include "virutil.h" #include "viralloc.h" #include "xml.h" #include "libvirt/libvirt-qemu.h" diff --git a/tools/virt-host-validate-common.c b/tools/virt-host-validate-common.c index cd75eba..34a527f 100644 --- a/tools/virt-host-validate-common.c +++ b/tools/virt-host-validate-common.c @@ -27,7 +27,7 @@ #include <unistd.h> #include <sys/utsname.h> -#include "util.h" +#include "virutil.h" #include "viralloc.h" #include "virfile.h" #include "virt-host-validate-common.h" -- 1.7.11.7 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list