On 17.12.2012 15:57, Daniel P. Berrange wrote: > 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" Why do we have this include twice? One is sufficient .... > 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" Same applies here > > #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" > -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list