diff options
author | Kibum Kim <kb0929.kim@samsung.com> | 2012-01-07 00:51:21 +0900 |
---|---|---|
committer | Kibum Kim <kb0929.kim@samsung.com> | 2012-01-07 00:51:21 +0900 |
commit | 3a86c1cb91d7b0790a983f7eb62d0b7cfcd37a46 (patch) | |
tree | b1d92f450ba2165bd6001552e5c10cb661b12b8a /lib | |
parent | 3fe782bd1c0128efa1c830bf7ccf0f5395f93f4a (diff) | |
download | util-linux-3a86c1cb91d7b0790a983f7eb62d0b7cfcd37a46.tar.gz util-linux-3a86c1cb91d7b0790a983f7eb62d0b7cfcd37a46.tar.bz2 util-linux-3a86c1cb91d7b0790a983f7eb62d0b7cfcd37a46.zip |
Git init
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Makefile.am | 15 | ||||
-rw-r--r-- | lib/Makefile.in | 569 | ||||
-rw-r--r-- | lib/blkdev.c | 144 | ||||
-rw-r--r-- | lib/canonicalize.c | 152 | ||||
-rw-r--r-- | lib/env.c | 73 | ||||
-rw-r--r-- | lib/fsprobe.c | 254 | ||||
-rw-r--r-- | lib/ismounted.c | 199 | ||||
-rw-r--r-- | lib/linux_version.c | 25 | ||||
-rw-r--r-- | lib/md5.c | 259 | ||||
-rw-r--r-- | lib/pttype.c | 292 | ||||
-rw-r--r-- | lib/setproctitle.c | 109 | ||||
-rw-r--r-- | lib/strverscmp.c | 120 | ||||
-rw-r--r-- | lib/wholedisk.c | 58 |
13 files changed, 2269 insertions, 0 deletions
diff --git a/lib/Makefile.am b/lib/Makefile.am new file mode 100644 index 0000000..0b64806 --- /dev/null +++ b/lib/Makefile.am @@ -0,0 +1,15 @@ +include $(top_srcdir)/config/include-Makefile.am + +AM_CPPFLAGS += -DTEST_PROGRAM + +noinst_PROGRAMS = test_blkdev test_ismounted test_pttype test_wholedisk + +test_blkdev_SOURCES = blkdev.c +test_ismounted_SOURCES = ismounted.c +test_pttype_SOURCES = pttype.c +test_wholedisk_SOURCES = wholedisk.c + +if LINUX +test_blkdev_SOURCES += linux_version.c +endif + diff --git a/lib/Makefile.in b/lib/Makefile.in new file mode 100644 index 0000000..a28cf33 --- /dev/null +++ b/lib/Makefile.in @@ -0,0 +1,569 @@ +# Makefile.in generated by automake 1.11 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +DIST_COMMON = $(dist_noinst_DATA) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in $(top_srcdir)/config/include-Makefile.am +noinst_PROGRAMS = test_blkdev$(EXEEXT) test_ismounted$(EXEEXT) \ + test_pttype$(EXEEXT) test_wholedisk$(EXEEXT) +@LINUX_TRUE@am__append_1 = linux_version.c +subdir = lib +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/gettext.m4 \ + $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/lib-ld.m4 \ + $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \ + $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \ + $(top_srcdir)/m4/tls.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +PROGRAMS = $(noinst_PROGRAMS) +am__test_blkdev_SOURCES_DIST = blkdev.c linux_version.c +@LINUX_TRUE@am__objects_1 = linux_version.$(OBJEXT) +am_test_blkdev_OBJECTS = blkdev.$(OBJEXT) $(am__objects_1) +test_blkdev_OBJECTS = $(am_test_blkdev_OBJECTS) +test_blkdev_LDADD = $(LDADD) +am_test_ismounted_OBJECTS = ismounted.$(OBJEXT) +test_ismounted_OBJECTS = $(am_test_ismounted_OBJECTS) +test_ismounted_LDADD = $(LDADD) +am_test_pttype_OBJECTS = pttype.$(OBJEXT) +test_pttype_OBJECTS = $(am_test_pttype_OBJECTS) +test_pttype_LDADD = $(LDADD) +am_test_wholedisk_OBJECTS = wholedisk.$(OBJEXT) +test_wholedisk_OBJECTS = $(am_test_wholedisk_OBJECTS) +test_wholedisk_LDADD = $(LDADD) +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/config/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(test_blkdev_SOURCES) $(test_ismounted_SOURCES) \ + $(test_pttype_SOURCES) $(test_wholedisk_SOURCES) +DIST_SOURCES = $(am__test_blkdev_SOURCES_DIST) \ + $(test_ismounted_SOURCES) $(test_pttype_SOURCES) \ + $(test_wholedisk_SOURCES) +DATA = $(dist_noinst_DATA) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BLKID = @BLKID@ +BLKID_CFLAGS = @BLKID_CFLAGS@ +BLKID_LIBS = @BLKID_LIBS@ +BLKID_LIBS_STATIC = @BLKID_LIBS_STATIC@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GMSGFMT = @GMSGFMT@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTLLIBS = @INTLLIBS@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBBLKID_VERSION = @LIBBLKID_VERSION@ +LIBBLKID_VERSION_INFO = @LIBBLKID_VERSION_INFO@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBUUID_VERSION = @LIBUUID_VERSION@ +LIBUUID_VERSION_INFO = @LIBUUID_VERSION_INFO@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +MKINSTALLDIRS = @MKINSTALLDIRS@ +MSGFMT = @MSGFMT@ +MSGMERGE = @MSGMERGE@ +NCURSES_LIBS = @NCURSES_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ +PKG_CONFIG = @PKG_CONFIG@ +POSUB = @POSUB@ +RANLIB = @RANLIB@ +SED = @SED@ +SELINUX_LIBS = @SELINUX_LIBS@ +SELINUX_LIBS_STATIC = @SELINUX_LIBS_STATIC@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +SUID_CFLAGS = @SUID_CFLAGS@ +SUID_LDFLAGS = @SUID_LDFLAGS@ +USE_NLS = @USE_NLS@ +UUID_CFLAGS = @UUID_CFLAGS@ +UUID_LIBS = @UUID_LIBS@ +VERSION = @VERSION@ +VOLID = @VOLID@ +XGETTEXT = @XGETTEXT@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libdirname = @libdirname@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +lt_ECHO = @lt_ECHO@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +usrbin_execdir = @usrbin_execdir@ +usrlib_execdir = @usrlib_execdir@ +usrsbin_execdir = @usrsbin_execdir@ +AM_CPPFLAGS = -include $(top_builddir)/config.h \ + -I$(top_srcdir)/include -DLOCALEDIR=\"$(localedir)\" \ + -DTEST_PROGRAM +AM_CFLAGS = -fsigned-char +AM_LDFLAGS = + +# Automake (at least up to 1.10) mishandles dist_man_MANS inside conditionals. +# Unlike with other dist primaries, the files are not distributed if the +# conditional is false. +# Work the bug around until it is fixed: +dist_noinst_DATA = $(dist_man_MANS) + +# Paths to in-tree libraries (use ul_ prefix to avoid possible collisions) +# +# blkid +ul_libblkid_srcdir = $(top_srcdir)/shlibs/blkid/src +ul_libblkid_builddir = $(top_builddir)/shlibs/blkid/src +ul_libblkid_la = $(top_builddir)/shlibs/blkid/src/libblkid.la + +# uuid +ul_libuuid_srcdir = $(top_srcdir)/shlibs/uuid/src +ul_libuuid_builddir = $(top_builddir)/shlibs/uuid/src +ul_libuuid_la = $(top_builddir)/shlibs/uuid/src/libuuid.la +test_blkdev_SOURCES = blkdev.c $(am__append_1) +test_ismounted_SOURCES = ismounted.c +test_pttype_SOURCES = pttype.c +test_wholedisk_SOURCES = wholedisk.c +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(top_srcdir)/config/include-Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign lib/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstPROGRAMS: + @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list +test_blkdev$(EXEEXT): $(test_blkdev_OBJECTS) $(test_blkdev_DEPENDENCIES) + @rm -f test_blkdev$(EXEEXT) + $(LINK) $(test_blkdev_OBJECTS) $(test_blkdev_LDADD) $(LIBS) +test_ismounted$(EXEEXT): $(test_ismounted_OBJECTS) $(test_ismounted_DEPENDENCIES) + @rm -f test_ismounted$(EXEEXT) + $(LINK) $(test_ismounted_OBJECTS) $(test_ismounted_LDADD) $(LIBS) +test_pttype$(EXEEXT): $(test_pttype_OBJECTS) $(test_pttype_DEPENDENCIES) + @rm -f test_pttype$(EXEEXT) + $(LINK) $(test_pttype_OBJECTS) $(test_pttype_LDADD) $(LIBS) +test_wholedisk$(EXEEXT): $(test_wholedisk_OBJECTS) $(test_wholedisk_DEPENDENCIES) + @rm -f test_wholedisk$(EXEEXT) + $(LINK) $(test_wholedisk_OBJECTS) $(test_wholedisk_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/blkdev.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ismounted.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/linux_version.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pttype.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wholedisk.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(PROGRAMS) $(DATA) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstPROGRAMS ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am + + +$(ul_libblkid_la): + $(MAKE) -C $(ul_libblkid_builddir) + +$(ul_libuuid_la): + $(MAKE) -C $(ul_libuuid_builddir) + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/lib/blkdev.c b/lib/blkdev.c new file mode 100644 index 0000000..7c6c7ba --- /dev/null +++ b/lib/blkdev.c @@ -0,0 +1,144 @@ + +#include <sys/types.h> +#include <sys/ioctl.h> +#include <unistd.h> + +#include "blkdev.h" +#include "linux_version.h" + +static long +blkdev_valid_offset (int fd, off_t offset) { + char ch; + + if (lseek (fd, offset, 0) < 0) + return 0; + if (read (fd, &ch, 1) < 1) + return 0; + return 1; +} + +off_t +blkdev_find_size (int fd) { + off_t high, low; + + low = 0; + for (high = 1; high > 0 && blkdev_valid_offset (fd, high); high *= 2) + low = high; + while (low < high - 1) + { + const off_t mid = (low + high) / 2; + + if (blkdev_valid_offset (fd, mid)) + low = mid; + else + high = mid; + } + blkdev_valid_offset (fd, 0); + return (low + 1); +} + +/* get size in bytes */ +int +blkdev_get_size(int fd, unsigned long long *bytes) +{ + /* TODO: use stat as well */ + +#ifdef BLKGETSIZE64 +#ifdef __linux__ + int ver = get_linux_version(); + /* kernels 2.4.15-2.4.17, had a broken BLKGETSIZE64 */ + if (ver >= KERNEL_VERSION (2,6,0) || + (ver >= KERNEL_VERSION (2,4,18) && ver < KERNEL_VERSION (2,5,0))) +#endif + if (ioctl(fd, BLKGETSIZE64, bytes) >= 0) + return 0; +#endif /* BLKGETSIZE64 */ + +#ifdef BLKGETSIZE + { + unsigned long size; + + if (ioctl(fd, BLKGETSIZE, &size) >= 0) { + *bytes = ((unsigned long long)size << 9); + return 0; + } + } + + return -1; +#endif /* BLKGETSIZE */ + + *bytes = blkdev_find_size(fd); + return 0; +} + +/* get 512-byte sector count */ +int +blkdev_get_sectors(int fd, unsigned long long *sectors) +{ + unsigned long long bytes; + + if (blkdev_get_size(fd, &bytes) == 0) { + *sectors = (bytes >> 9); + return 0; + } + + return -1; +} + +/* get hardware sector size */ +int +blkdev_get_sector_size(int fd, int *sector_size) +{ +#ifdef BLKSSZGET +#ifdef __linux__ + if (get_linux_version() < KERNEL_VERSION(2,3,3)) { + *sector_size = DEFAULT_SECTOR_SIZE; + return 0; + } +#endif + if (ioctl(fd, BLKSSZGET, sector_size) >= 0) + return 0; + + return -1; +#else + *sector_size = DEFAULT_SECTOR_SIZE; + return 0; +#endif +} + + +#ifdef TEST_PROGRAM +#include <stdio.h> +#include <stdlib.h> +#include <fcntl.h> +#include <err.h> +int +main(int argc, char **argv) +{ + unsigned long long bytes; + unsigned long long sectors; + int sector_size; + int fd; + + if (argc != 2) { + fprintf(stderr, "usage: %s device\n", argv[0]); + exit(EXIT_FAILURE); + } + + if ((fd = open(argv[1], O_RDONLY)) < 0) + err(EXIT_FAILURE, "open %s failed", argv[1]); + + if (blkdev_get_size(fd, &bytes) < 0) + err(EXIT_FAILURE, "blkdev_get_size() failed"); + if (blkdev_get_sectors(fd, §ors) < 0) + err(EXIT_FAILURE, "blkdev_get_sectors() failed"); + if (blkdev_get_sector_size(fd, §or_size) < 0) + err(EXIT_FAILURE, "blkdev_get_sector_size() failed"); + + printf("bytes %llu\n", bytes); + printf("sectors %llu\n", sectors); + printf("sectorsize %d\n", sector_size); + + return EXIT_SUCCESS; +} +#endif /* TEST_PROGRAM */ diff --git a/lib/canonicalize.c b/lib/canonicalize.c new file mode 100644 index 0000000..b888fbb --- /dev/null +++ b/lib/canonicalize.c @@ -0,0 +1,152 @@ +/* + * canonicalize.c -- canonicalize pathname by removing symlinks + * Copyright (C) 1993 Rick Sladkey <jrs@world.std.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library Public License for more details. + * + */ + +/* + * This routine is part of libc. We include it nevertheless, + * since the libc version has some security flaws. + * + * TODO: use canonicalize_file_name() when exist in glibc + */ +#include <unistd.h> +#include <string.h> +#include <errno.h> +#include <stdlib.h> + +#include "canonicalize.h" + +#ifndef MAXSYMLINKS +# define MAXSYMLINKS 256 +#endif + +static char * +myrealpath(const char *path, char *resolved_path, int maxreslth) { + int readlinks = 0; + char *npath; + char link_path[PATH_MAX+1]; + int n; + char *buf = NULL; + + npath = resolved_path; + + /* If it's a relative pathname use getcwd for starters. */ + if (*path != '/') { + if (!getcwd(npath, maxreslth-2)) + return NULL; + npath += strlen(npath); + if (npath[-1] != '/') + *npath++ = '/'; + } else { + *npath++ = '/'; + path++; + } + + /* Expand each slash-separated pathname component. */ + while (*path != '\0') { + /* Ignore stray "/" */ + if (*path == '/') { + path++; + continue; + } + if (*path == '.' && (path[1] == '\0' || path[1] == '/')) { + /* Ignore "." */ + path++; + continue; + } + if (*path == '.' && path[1] == '.' && + (path[2] == '\0' || path[2] == '/')) { + /* Backup for ".." */ + path += 2; + while (npath > resolved_path+1 && + (--npath)[-1] != '/') + ; + continue; + } + /* Safely copy the next pathname component. */ + while (*path != '\0' && *path != '/') { + if (npath-resolved_path > maxreslth-2) { + errno = ENAMETOOLONG; + goto err; + } + *npath++ = *path++; + } + + /* Protect against infinite loops. */ + if (readlinks++ > MAXSYMLINKS) { + errno = ELOOP; + goto err; + } + + /* See if last pathname component is a symlink. */ + *npath = '\0'; + n = readlink(resolved_path, link_path, PATH_MAX); + if (n < 0) { + /* EINVAL means the file exists but isn't a symlink. */ + if (errno != EINVAL) + goto err; + } else { + int m; + char *newbuf; + + /* Note: readlink doesn't add the null byte. */ + link_path[n] = '\0'; + if (*link_path == '/') + /* Start over for an absolute symlink. */ + npath = resolved_path; + else + /* Otherwise back up over this component. */ + while (*(--npath) != '/') + ; + + /* Insert symlink contents into path. */ + m = strlen(path); + newbuf = malloc(m + n + 1); + if (!newbuf) + goto err; + memcpy(newbuf, link_path, n); + memcpy(newbuf + n, path, m + 1); + free(buf); + path = buf = newbuf; + } + *npath++ = '/'; + } + /* Delete trailing slash but don't whomp a lone slash. */ + if (npath != resolved_path+1 && npath[-1] == '/') + npath--; + /* Make sure it's null terminated. */ + *npath = '\0'; + + free(buf); + return resolved_path; + + err: + free(buf); + return NULL; +} + +char * +canonicalize_path(const char *path) { + char canonical[PATH_MAX+2]; + + if (path == NULL) + return NULL; + + if (myrealpath (path, canonical, PATH_MAX+1)) + return strdup(canonical); + + return strdup(path); +} + + diff --git a/lib/env.c b/lib/env.c new file mode 100644 index 0000000..82fadf5 --- /dev/null +++ b/lib/env.c @@ -0,0 +1,73 @@ +/* + * Security checks of environment + * Added from shadow-utils package + * by Arkadiusz Mi¶kiewicz <misiek@pld.ORG.PL> + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "env.h" + +extern char **environ; + +static char * const forbid[] = { + "_RLD_=", + "BASH_ENV=", /* GNU creeping featurism strikes again... */ + "ENV=", + "HOME=", + "IFS=", + "KRB_CONF=", + "LD_", /* anything with the LD_ prefix */ + "LIBPATH=", + "MAIL=", + "NLSPATH=", + "PATH=", + "SHELL=", + "SHLIB_PATH=", + (char *) 0 +}; + +/* these are allowed, but with no slashes inside + (to work around security problems in GNU gettext) */ +static char * const noslash[] = { + "LANG=", + "LANGUAGE=", + "LC_", /* anything with the LC_ prefix */ + (char *) 0 +}; + +void +sanitize_env(void) +{ + char **envp = environ; + char * const *bad; + char **cur; + char **move; + + for (cur = envp; *cur; cur++) { + for (bad = forbid; *bad; bad++) { + if (strncmp(*cur, *bad, strlen(*bad)) == 0) { + for (move = cur; *move; move++) + *move = *(move + 1); + cur--; + break; + } + } + } + + for (cur = envp; *cur; cur++) { + for (bad = noslash; *bad; bad++) { + if (strncmp(*cur, *bad, strlen(*bad)) != 0) + continue; + if (!strchr(*cur, '/')) + continue; /* OK */ + for (move = cur; *move; move++) + *move = *(move + 1); + cur--; + break; + } + } +} + diff --git a/lib/fsprobe.c b/lib/fsprobe.c new file mode 100644 index 0000000..2643c09 --- /dev/null +++ b/lib/fsprobe.c @@ -0,0 +1,254 @@ +#include <stdio.h> +#include <string.h> +#include <fcntl.h> +#include <errno.h> +#include <unistd.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <stdlib.h> + +#ifdef HAVE_BLKID_BLKID_H +#include <blkid/blkid.h> +#else +#include <blkid.h> +#endif + +#include "blkdev.h" +#include "canonicalize.h" +#include "pathnames.h" +#include "fsprobe.h" + +static blkid_cache blcache; + +#ifdef HAVE_BLKID_EVALUATE_TAG +/* ask kernel developers why we need such ugly open() method... */ +static int +open_device(const char *devname) +{ + int retries = 0; + + do { + int fd = open(devname, O_RDONLY); + if (fd >= 0) + return fd; +#ifdef ENOMEDIUM + /* ENOMEDIUM is Linux-only */ + if (errno != ENOMEDIUM) + break; +#else + break; +#endif + if (retries >= CRDOM_NOMEDIUM_RETRIES) + break; + ++retries; + sleep(3); + } while(1); + + return -1; +} +#endif + +/* + * Parses NAME=value, returns -1 on parse error, 0 success. The success is also + * when the 'spec' doesn't contain name=value pair (because the spec could be + * a devname too). In particular case the pointer 'name' is set to NULL. + */ +int +fsprobe_parse_spec(const char *spec, char **name, char **value) +{ + *name = NULL; + *value = NULL; + + if (strchr(spec, '=')) + return blkid_parse_tag_string(spec, name, value); + + return 0; +} + +char * +fsprobe_get_devname_by_spec(const char *spec) +{ + char *name, *value; + + if (!spec) + return NULL; + if (fsprobe_parse_spec(spec, &name, &value) != 0) + return NULL; /* parse error */ + if (name) { + char *nspec = NULL; + + if (!strcmp(name,"LABEL")) + nspec = fsprobe_get_devname_by_label(value); + else if (!strcmp(name,"UUID")) + nspec = fsprobe_get_devname_by_uuid(value); + + free(name); + free(value); + return nspec; + } + + return canonicalize_path(spec); +} + +void +fsprobe_init(void) +{ + blcache = NULL; +} + +int +fsprobe_known_fstype(const char *fstype) +{ + return blkid_known_fstype(fstype); +} + +#ifdef HAVE_BLKID_EVALUATE_TAG +/* + * libblkid from util-linux-ng + * -- recommended + */ +static blkid_probe blprobe; + +void +fsprobe_exit(void) +{ + if (blprobe) + blkid_free_probe(blprobe); + if (blcache) + blkid_put_cache(blcache); +} + +/* returns device LABEL, UUID, FSTYPE, ... by low-level + * probing interface + */ +static char * +fsprobe_get_value(const char *name, const char *devname) +{ + int fd; + const char *data = NULL; + + if (!devname || !name) + return NULL; + fd = open_device(devname); + if (fd < 0) + return NULL; + if (!blprobe) + blprobe = blkid_new_probe(); + if (!blprobe) + goto done; + if (blkid_probe_set_device(blprobe, fd, 0, 0)) + goto done; + if (blkid_probe_set_request(blprobe, BLKID_PROBREQ_LABEL | + BLKID_PROBREQ_UUID | BLKID_PROBREQ_TYPE )) + goto done; + if (blkid_do_safeprobe(blprobe)) + goto done; + if (blkid_probe_lookup_value(blprobe, name, &data, NULL)) + goto done; +done: + close(fd); + return data ? strdup((char *) data) : NULL; +} + +char * +fsprobe_get_label_by_devname(const char *devname) +{ + return fsprobe_get_value("LABEL", devname); +} + +char * +fsprobe_get_uuid_by_devname(const char *devname) +{ + return fsprobe_get_value("UUID", devname); +} + +char * +fsprobe_get_fstype_by_devname(const char *devname) +{ + return fsprobe_get_value("TYPE", devname); +} + +char * +fsprobe_get_devname_by_uuid(const char *uuid) +{ + return blkid_evaluate_tag("UUID", uuid, &blcache); +} + +char * +fsprobe_get_devname_by_label(const char *label) +{ + return blkid_evaluate_tag("LABEL", label, &blcache); +} + +#else /* !HAVE_BLKID_EVALUATE_TAG */ + +/* + * Classic libblkid (from e2fsprogs) without blkid_evaluate_tag() + * -- deprecated + */ +#define BLKID_EMPTY_CACHE "/dev/null" + +void +fsprobe_exit(void) +{ + if (blcache) + blkid_put_cache(blcache); +} + +char * +fsprobe_get_devname_by_uuid(const char *uuid) +{ + if (!blcache) + blkid_get_cache(&blcache, NULL); + + return blkid_get_devname(blcache, "UUID", uuid); +} + +char * +fsprobe_get_devname_by_label(const char *label) +{ + if (!blcache) + blkid_get_cache(&blcache, NULL); + + return blkid_get_devname(blcache, "LABEL", label); +} + +char * +fsprobe_get_fstype_by_devname(const char *devname) +{ + blkid_cache c; + char *tp; + + if (blcache) + return blkid_get_tag_value(blcache, "TYPE", devname); + + /* The cache is not initialized yet. Use empty cache rather than waste + * time with /etc/blkid.tab. It seems that probe FS is faster than + * parse the cache file. -- kzak (17-May-2007) + */ + blkid_get_cache(&c, BLKID_EMPTY_CACHE); + tp = blkid_get_tag_value(c, "TYPE", devname); + blkid_put_cache(c); + + return tp; +} + +char * +fsprobe_get_label_by_devname(const char *devname) +{ + if (!blcache) + blkid_get_cache(&blcache, NULL); + + return blkid_get_tag_value(blcache, "LABEL", devname); +} + +char * +fsprobe_get_uuid_by_devname(const char *devname) +{ + if (!blcache) + blkid_get_cache(&blcache, NULL); + + return blkid_get_tag_value(blcache, "UUID", devname); +} + +#endif /* !HAVE_BLKID_EVALUATE_TAG */ diff --git a/lib/ismounted.c b/lib/ismounted.c new file mode 100644 index 0000000..fbe91f9 --- /dev/null +++ b/lib/ismounted.c @@ -0,0 +1,199 @@ +/* + * ismounted.c --- Check to see if the filesystem was mounted + * + * Copyright (C) 1995,1996,1997,1998,1999,2000,2008 Theodore Ts'o. + * + * This file may be redistributed under the terms of the GNU Public + * License. + */ +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> +#include <errno.h> +#include <fcntl.h> +#include <mntent.h> +#include <string.h> +#include <sys/stat.h> +#include <ctype.h> + +#include "pathnames.h" +#include "ismounted.h" + +/* + * ext2fs_check_if_mounted flags + */ +#define MF_MOUNTED 1 + +static char *skip_over_blank(char *cp) +{ + while (*cp && isspace(*cp)) + cp++; + return cp; +} + +static char *skip_over_word(char *cp) +{ + while (*cp && !isspace(*cp)) + cp++; + return cp; +} + +static char *parse_word(char **buf) +{ + char *word, *next; + + word = *buf; + if (*word == 0) + return 0; + + word = skip_over_blank(word); + next = skip_over_word(word); + if (*next) + *next++ = 0; + *buf = next; + return word; +} + +/* + * Helper function which checks a file in /etc/mtab format to see if a + * filesystem is mounted. Returns an error if the file doesn't exist + * or can't be opened. + */ +static int check_mntent_file(const char *mtab_file, const char *file, + int *mount_flags) +{ + struct stat st_buf; + int retval = 0; + dev_t file_dev=0, file_rdev=0; + ino_t file_ino=0; + FILE *f; + char buf[1024], *device = 0, *mnt_dir = 0, *cp; + + *mount_flags = 0; + if ((f = setmntent (mtab_file, "r")) == NULL) + return errno; + if (stat(file, &st_buf) == 0) { + if (S_ISBLK(st_buf.st_mode)) { +#ifndef __GNU__ /* The GNU hurd is broken with respect to stat devices */ + file_rdev = st_buf.st_rdev; +#endif /* __GNU__ */ + } else { + file_dev = st_buf.st_dev; + file_ino = st_buf.st_ino; + } + } + while (1) { + if (!fgets(buf, sizeof(buf), f)) { + device = mnt_dir = 0; + break; + } + buf[sizeof(buf)-1] = 0; + + cp = buf; + device = parse_word(&cp); + if (!device || *device == '#') + return 0; /* Ignore blank lines and comments */ + mnt_dir = parse_word(&cp); + + if (device[0] != '/') + continue; + + if (strcmp(file, device) == 0) + break; + if (stat(device, &st_buf) == 0) { + if (S_ISBLK(st_buf.st_mode)) { +#ifndef __GNU__ + if (file_rdev && (file_rdev == st_buf.st_rdev)) + break; +#endif /* __GNU__ */ + } else { + if (file_dev && ((file_dev == st_buf.st_dev) && + (file_ino == st_buf.st_ino))) + break; + } + } + } + + if (mnt_dir == 0) { +#ifndef __GNU__ /* The GNU hurd is broken with respect to stat devices */ + /* + * Do an extra check to see if this is the root device. We + * can't trust /etc/mtab, and /proc/mounts will only list + * /dev/root for the root filesystem. Argh. Instead we + * check if the given device has the same major/minor number + * as the device that the root directory is on. + */ + if (file_rdev && (stat("/", &st_buf) == 0) && + (st_buf.st_dev == file_rdev)) + *mount_flags = MF_MOUNTED; +#endif /* __GNU__ */ + goto errout; + } +#ifndef __GNU__ /* The GNU hurd is deficient; what else is new? */ + /* Validate the entry in case /etc/mtab is out of date */ + /* + * We need to be paranoid, because some broken distributions + * (read: Slackware) don't initialize /etc/mtab before checking + * all of the non-root filesystems on the disk. + */ + if (stat(mnt_dir, &st_buf) < 0) { + retval = errno; + if (retval == ENOENT) { +#ifdef DEBUG + printf("Bogus entry in %s! (%s does not exist)\n", + mtab_file, mnt_dir); +#endif /* DEBUG */ + retval = 0; + } + goto errout; + } + if (file_rdev && (st_buf.st_dev != file_rdev)) { +#ifdef DEBUG + printf("Bogus entry in %s! (%s not mounted on %s)\n", + mtab_file, file, mnt_dir); +#endif /* DEBUG */ + goto errout; + } +#endif /* __GNU__ */ + *mount_flags = MF_MOUNTED; + + retval = 0; +errout: + endmntent (f); + return retval; +} + +int is_mounted(const char *file) +{ + int retval; + int mount_flags = 0; + +#ifdef __linux__ + retval = check_mntent_file(_PATH_PROC_MOUNTS, file, &mount_flags); + if (retval) + return 0; + if (mount_flags) + return 1; +#endif /* __linux__ */ + retval = check_mntent_file(_PATH_MOUNTED, file, &mount_flags); + if (retval) + return 0; + return mount_flags; +} + +#ifdef TEST_PROGRAM +int main(int argc, char **argv) +{ + if (argc < 2) { + fprintf(stderr, "Usage: %s device\n", argv[0]); + return EXIT_FAILURE; + } + + if (is_mounted(argv[1])) { + printf("mounted\n"); + return EXIT_SUCCESS; + } + printf("not mounted\n"); + return EXIT_FAILURE; +} +#endif /* DEBUG */ diff --git a/lib/linux_version.c b/lib/linux_version.c new file mode 100644 index 0000000..f9fbd8d --- /dev/null +++ b/lib/linux_version.c @@ -0,0 +1,25 @@ +#include <stdio.h> +#include <sys/utsname.h> + +#include "linux_version.h" + +int +get_linux_version (void) +{ + static int kver = -1; + struct utsname uts; + int major; + int minor; + int teeny; + + if (kver != -1) + return kver; + if (uname (&uts)) + kver = 0; + else if (sscanf (uts.release, "%d.%d.%d", &major, &minor, &teeny) != 3) + kver = 0; + else + kver = KERNEL_VERSION (major, minor, teeny); + + return kver; +} diff --git a/lib/md5.c b/lib/md5.c new file mode 100644 index 0000000..3069845 --- /dev/null +++ b/lib/md5.c @@ -0,0 +1,259 @@ +/* + * This code implements the MD5 message-digest algorithm. + * The algorithm is due to Ron Rivest. This code was + * written by Colin Plumb in 1993, no copyright is claimed. + * This code is in the public domain; do with it what you wish. + * + * Equivalent code is available from RSA Data Security, Inc. + * This code has been tested against that, and is equivalent, + * except that you don't need to include two pages of legalese + * with every copy. + * + * To compute the message digest of a chunk of bytes, declare an + * MD5Context structure, pass it to MD5Init, call MD5Update as + * needed on buffers full of bytes, and then call MD5Final, which + * will fill a supplied 16-byte array with the digest. + */ +#include <endian.h> +#include <string.h> /* for memcpy() */ + +#include "md5.h" + +#if !defined __BYTE_ORDER || !(__BYTE_ORDER == __LITTLE_ENDIAN) && !(__BYTE_ORDER == __BIG_ENDIAN) +#error missing __BYTE_ORDER +#endif + +#if (__BYTE_ORDER == __LITTLE_ENDIAN) +#define byteReverse(buf, len) /* Nothing */ +#else +void byteReverse(unsigned char *buf, unsigned longs); + +#ifndef ASM_MD5 +/* + * Note: this code is harmless on little-endian machines. + */ +void byteReverse(unsigned char *buf, unsigned longs) +{ + uint32_t t; + do { + t = (uint32_t) ((unsigned) buf[3] << 8 | buf[2]) << 16 | + ((unsigned) buf[1] << 8 | buf[0]); + *(uint32_t *) buf = t; + buf += 4; + } while (--longs); +} +#endif +#endif + +/* + * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious + * initialization constants. + */ +void MD5Init(struct MD5Context *ctx) +{ + ctx->buf[0] = 0x67452301; + ctx->buf[1] = 0xefcdab89; + ctx->buf[2] = 0x98badcfe; + ctx->buf[3] = 0x10325476; + + ctx->bits[0] = 0; + ctx->bits[1] = 0; +} + +/* + * Update context to reflect the concatenation of another buffer full + * of bytes. + */ +void MD5Update(struct MD5Context *ctx, unsigned char const *buf, unsigned len) +{ + uint32_t t; + + /* Update bitcount */ + + t = ctx->bits[0]; + if ((ctx->bits[0] = t + ((uint32_t) len << 3)) < t) + ctx->bits[1]++; /* Carry from low to high */ + ctx->bits[1] += len >> 29; + + t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */ + + /* Handle any leading odd-sized chunks */ + + if (t) { + unsigned char *p = (unsigned char *) ctx->in + t; + + t = 64 - t; + if (len < t) { + memcpy(p, buf, len); + return; + } + memcpy(p, buf, t); + byteReverse(ctx->in, 16); + MD5Transform(ctx->buf, (uint32_t *) ctx->in); + buf += t; + len -= t; + } + /* Process data in 64-byte chunks */ + + while (len >= 64) { + memcpy(ctx->in, buf, 64); + byteReverse(ctx->in, 16); + MD5Transform(ctx->buf, (uint32_t *) ctx->in); + buf += 64; + len -= 64; + } + + /* Handle any remaining bytes of data. */ + + memcpy(ctx->in, buf, len); +} + +/* + * Final wrapup - pad to 64-byte boundary with the bit pattern + * 1 0* (64-bit count of bits processed, MSB-first) + */ +void MD5Final(unsigned char digest[16], struct MD5Context *ctx) +{ + unsigned count; + unsigned char *p; + + /* Compute number of bytes mod 64 */ + count = (ctx->bits[0] >> 3) & 0x3F; + + /* Set the first char of padding to 0x80. This is safe since there is + always at least one byte free */ + p = ctx->in + count; + *p++ = 0x80; + + /* Bytes of padding needed to make 64 bytes */ + count = 64 - 1 - count; + + /* Pad out to 56 mod 64 */ + if (count < 8) { + /* Two lots of padding: Pad the first block to 64 bytes */ + memset(p, 0, count); + byteReverse(ctx->in, 16); + MD5Transform(ctx->buf, (uint32_t *) ctx->in); + + /* Now fill the next block with 56 bytes */ + memset(ctx->in, 0, 56); + } else { + /* Pad block to 56 bytes */ + memset(p, 0, count - 8); + } + byteReverse(ctx->in, 14); + + /* Append length in bits and transform */ + ((uint32_t *) ctx->in)[14] = ctx->bits[0]; + ((uint32_t *) ctx->in)[15] = ctx->bits[1]; + + MD5Transform(ctx->buf, (uint32_t *) ctx->in); + byteReverse((unsigned char *) ctx->buf, 4); + memcpy(digest, ctx->buf, 16); + memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */ +} + +#ifndef ASM_MD5 + +/* The four core functions - F1 is optimized somewhat */ + +/* #define F1(x, y, z) (x & y | ~x & z) */ +#define F1(x, y, z) (z ^ (x & (y ^ z))) +#define F2(x, y, z) F1(z, x, y) +#define F3(x, y, z) (x ^ y ^ z) +#define F4(x, y, z) (y ^ (x | ~z)) + +/* This is the central step in the MD5 algorithm. */ +#define MD5STEP(f, w, x, y, z, data, s) \ + ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x ) + +/* + * The core of the MD5 algorithm, this alters an existing MD5 hash to + * reflect the addition of 16 longwords of new data. MD5Update blocks + * the data and converts bytes into longwords for this routine. + */ +void MD5Transform(uint32_t buf[4], uint32_t const in[16]) +{ + register uint32_t a, b, c, d; + + a = buf[0]; + b = buf[1]; + c = buf[2]; + d = buf[3]; + + MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); + MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); + MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); + MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); + MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); + MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); + MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); + MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); + MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); + MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); + MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); + MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); + MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); + MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); + MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); + MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); + + MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); + MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); + MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); + MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); + MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); + MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); + MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); + MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); + MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); + MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); + MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); + MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); + MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); + MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); + MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); + MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); + + MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); + MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); + MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); + MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); + MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); + MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); + MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); + MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); + MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); + MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); + MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); + MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); + MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); + MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); + MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); + MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); + + MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); + MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); + MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); + MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); + MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); + MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); + MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); + MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); + MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); + MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); + MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); + MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); + MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); + MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); + MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); + MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); + + buf[0] += a; + buf[1] += b; + buf[2] += c; + buf[3] += d; +} + +#endif + diff --git a/lib/pttype.c b/lib/pttype.c new file mode 100644 index 0000000..c2294f1 --- /dev/null +++ b/lib/pttype.c @@ -0,0 +1,292 @@ +/* + * Based on libdisk from xfsprogs and Linux fdisk. + * + * Copyright (c) 2000-2001 Silicon Graphics, Inc. + * Copyright (C) 2009 Karel Zak <kzak@redhat.com> + */ +#include <stdio.h> +#include <fcntl.h> +#include <unistd.h> +#include <sys/types.h> +#include <netinet/in.h> +#include <stdlib.h> + +#include "blkdev.h" + +/* we need to read two sectors, beacuse BSD label offset is 512 */ +#define PTTYPE_BUFSIZ (2 * DEFAULT_SECTOR_SIZE) /* 1024 */ + +/* + * SGI + */ +struct sgi_device_parameter { /* 48 bytes */ + unsigned char skew; + unsigned char gap1; + unsigned char gap2; + unsigned char sparecyl; + unsigned short pcylcount; + unsigned short head_vol0; + unsigned short ntrks; /* tracks in cyl 0 or vol 0 */ + unsigned char cmd_tag_queue_depth; + unsigned char unused0; + unsigned short unused1; + unsigned short nsect; /* sectors/tracks in cyl 0 or vol 0 */ + unsigned short bytes; + unsigned short ilfact; + unsigned int flags; /* controller flags */ + unsigned int datarate; + unsigned int retries_on_error; + unsigned int ms_per_word; + unsigned short xylogics_gap1; + unsigned short xylogics_syncdelay; + unsigned short xylogics_readdelay; + unsigned short xylogics_gap2; + unsigned short xylogics_readgate; + unsigned short xylogics_writecont; +}; + +#define SGI_VOLHDR 0x00 +/* 1 and 2 were used for drive types no longer supported by SGI */ +#define SGI_SWAP 0x03 +/* 4 and 5 were for filesystem types SGI haven't ever supported on MIPS CPUs */ +#define SGI_VOLUME 0x06 +#define SGI_EFS 0x07 +#define SGI_LVOL 0x08 +#define SGI_RLVOL 0x09 +#define SGI_XFS 0x0a +#define SGI_XFSLOG 0x0b +#define SGI_XLV 0x0c +#define SGI_XVM 0x0d +#define ENTIRE_DISK SGI_VOLUME +/* + * controller flags + */ +#define SECTOR_SLIP 0x01 +#define SECTOR_FWD 0x02 +#define TRACK_FWD 0x04 +#define TRACK_MULTIVOL 0x08 +#define IGNORE_ERRORS 0x10 +#define RESEEK 0x20 +#define CMDTAGQ_ENABLE 0x40 + +struct sgi_volume_header { + unsigned int magic; /* expect SGI_LABEL_MAGIC */ + unsigned short boot_part; /* active boot partition */ + unsigned short swap_part; /* active swap partition */ + unsigned char boot_file[16]; /* name of the bootfile */ + struct sgi_device_parameter devparam; /* 1 * 48 bytes */ + struct volume_directory { /* 15 * 16 bytes */ + unsigned char vol_file_name[8]; /* a character array */ + unsigned int vol_file_start; /* number of logical block */ + unsigned int vol_file_size; /* number of bytes */ + } directory[15]; + struct sgi_partition { /* 16 * 12 bytes */ + unsigned int num_sectors; /* number of blocks */ + unsigned int start_sector; /* must be cylinder aligned */ + unsigned int id; + } partitions[16]; + unsigned int csum; + unsigned int fillbytes; +}; + +#define SGI_LABEL_MAGIC 0x0be5a941 + +static uint32_t +twos_complement_32bit_sum(u_int32_t *base, int size) +{ + int i; + u_int32_t sum = 0; + + size = size / sizeof(u_int32_t); + for (i = 0; i < size; i++) + sum = sum - ntohl(base[i]); + return sum; +} + +static int +sgi_parttable(unsigned char *base) +{ + u_int32_t csum; + struct sgi_volume_header *vh = (struct sgi_volume_header *) base; + + if (ntohl(vh->magic) != SGI_LABEL_MAGIC) + return 0; + csum = twos_complement_32bit_sum((uint32_t *)vh, + sizeof(struct sgi_volume_header)); + return !csum; +} + +/* + * DOS + */ +static int +dos_parttable(unsigned char *base) +{ + return (base[510] == 0x55 && base[511] == 0xaa); +} + +/* + * AIX + */ +typedef struct { + unsigned int magic; /* expect AIX_LABEL_MAGIC */ + /* ... */ +} aix_partition; + +#define AIX_LABEL_MAGIC 0xc9c2d4c1 +#define AIX_LABEL_MAGIC_SWAPPED 0xc1d4c2c9 +#define aixlabel(x) ((aix_partition *)x) + +static int +aix_parttable(unsigned char *base) +{ + return (aixlabel(base)->magic == AIX_LABEL_MAGIC || + aixlabel(base)->magic == AIX_LABEL_MAGIC_SWAPPED); +} + +/* + * SUN + */ +typedef struct { + unsigned char info[128]; /* Informative text string */ + unsigned char spare0[14]; + struct sun_info { + unsigned char spare1; + unsigned char id; + unsigned char spare2; + unsigned char flags; + } infos[8]; + unsigned char spare1[246]; /* Boot information etc. */ + unsigned short rspeed; /* Disk rotational speed */ + unsigned short pcylcount; /* Physical cylinder count */ + unsigned short sparecyl; /* extra sects per cylinder */ + unsigned char spare2[4]; /* More magic... */ + unsigned short ilfact; /* Interleave factor */ + unsigned short ncyl; /* Data cylinder count */ + unsigned short nacyl; /* Alt. cylinder count */ + unsigned short ntrks; /* Tracks per cylinder */ + unsigned short nsect; /* Sectors per track */ + unsigned char spare3[4]; /* Even more magic... */ + struct sun_partition { + u_int32_t start_cylinder; + u_int32_t num_sectors; + } partitions[8]; + unsigned short magic; /* Magic number */ + unsigned short csum; /* Label xor'd checksum */ +} sun_partition; + +#define SUN_LABEL_MAGIC 0xDABE +#define SUN_LABEL_MAGIC_SWAPPED 0xBEDA +#define sunlabel(x) ((sun_partition *)x) + +static int +sun_parttable(unsigned char *base) +{ + unsigned short *ush; + int csum = 0; + + if (sunlabel(base)->magic != SUN_LABEL_MAGIC && + sunlabel(base)->magic != SUN_LABEL_MAGIC_SWAPPED) + return csum; + ush = ((unsigned short *) (sunlabel(base) + 1)) - 1; + while (ush >= (unsigned short *)sunlabel(base)) + csum ^= *ush--; + return !csum; +} + +/* + * MAC + */ +typedef struct { + unsigned short magic; + /* ... */ +} mac_partition; + +#define MAC_LABEL_MAGIC 0x4552 +#define MAC_PARTITION_MAGIC 0x504d +#define MAC_OLD_PARTITION_MAGIC 0x5453 +#define maclabel(x) ((mac_partition *)x) + +static int +mac_parttable(unsigned char *base) +{ + return (ntohs(maclabel(base)->magic) == MAC_LABEL_MAGIC || + ntohs(maclabel(base)->magic) == MAC_PARTITION_MAGIC || + ntohs(maclabel(base)->magic) == MAC_OLD_PARTITION_MAGIC); +} + +/* + * BSD subpartitions listed in a disklabel, under a dos-like partition. + */ +#define BSD_DISKMAGIC 0x82564557UL /* The disk magic number */ +#define BSD_DISKMAGIC_SWAPED 0x57455682UL +struct bsd_disklabel { + uint32_t magic; /* the magic number */ + /* ... */ +}; + +static int +bsd_parttable(unsigned char *base) +{ + struct bsd_disklabel *l = (struct bsd_disklabel *) + (base + (DEFAULT_SECTOR_SIZE * 1)); + + return (l->magic == BSD_DISKMAGIC || l->magic == BSD_DISKMAGIC_SWAPED); +} + +const char * +get_pt_type_fd(int fd) +{ + char *type = NULL; + unsigned char buf[PTTYPE_BUFSIZ]; + + if (read(fd, buf, PTTYPE_BUFSIZ) != PTTYPE_BUFSIZ) + ; + else { + if (sgi_parttable(buf)) + type = "SGI"; + else if (sun_parttable(buf)) + type = "Sun"; + else if (aix_parttable(buf)) + type = "AIX"; + else if (dos_parttable(buf)) + type = "DOS"; + else if (mac_parttable(buf)) + type = "Mac"; + else if (bsd_parttable(buf)) + type = "BSD"; + } + return type; +} + +const char * +get_pt_type(const char *device) +{ + int fd; + const char *type; + + fd = open(device, O_RDONLY); + if (fd == -1) + return NULL; + type = get_pt_type_fd(fd); + close(fd); + return type; +} + +#ifdef TEST_PROGRAM +int +main(int argc, char **argv) +{ + const char *type; + + if (argc < 2) { + fprintf(stderr, "usage: %s <device>\n", argv[0]); + exit(EXIT_FAILURE); + } + + type = get_pt_type(argv[1]); + if (type) + printf("Partition type: %s\n", type); + exit(EXIT_SUCCESS); +} +#endif diff --git a/lib/setproctitle.c b/lib/setproctitle.c new file mode 100644 index 0000000..319bc6a --- /dev/null +++ b/lib/setproctitle.c @@ -0,0 +1,109 @@ +/* proctitle code - we know this to work only on linux... */ + +/* +** SETPROCTITLE -- set process title for ps (from sendmail) +** +** Parameters: +** fmt -- a printf style format string. +** +** Returns: +** none. +** +** Side Effects: +** Clobbers argv of our main procedure so ps(1) will +** display the title. +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdarg.h> +#include "setproctitle.h" + +#ifndef SPT_BUFSIZE +#define SPT_BUFSIZE 2048 +#endif + +extern char** environ; + +static char** argv0; +static int argv_lth; + +void +initproctitle (int argc, char **argv) { + int i; + char **envp = environ; + + /* + * Move the environment so we can reuse the memory. + * (Code borrowed from sendmail.) + * WARNING: ugly assumptions on memory layout here; + * if this ever causes problems, #undef DO_PS_FIDDLING + */ + for (i = 0; envp[i] != NULL; i++) + continue; + environ = (char **) malloc(sizeof(char *) * (i + 1)); + if (environ == NULL) + return; + for (i = 0; envp[i] != NULL; i++) + if ((environ[i] = strdup(envp[i])) == NULL) + return; + environ[i] = NULL; + + argv0 = argv; + if (i > 0) + argv_lth = envp[i-1] + strlen(envp[i-1]) - argv0[0]; + else + argv_lth = argv0[argc-1] + strlen(argv0[argc-1]) - argv0[0]; +} + +#if 0 +/* Nice code, but many places do not know about vsnprintf ... */ +void +setproctitle (const char *fmt,...) { + int i; + char buf[SPT_BUFSIZE]; + va_list ap; + + if (!argv0) + return; + + va_start(ap, fmt); + (void) vsnprintf(buf, SPT_BUFSIZE, fmt, ap); + va_end(ap); + + i = strlen (buf); + if (i > argv_lth - 2) { + i = argv_lth - 2; + buf[i] = '\0'; + } + memset(argv0[0], '\0', argv_lth); /* clear the memory area */ + (void) strcpy (argv0[0], buf); + + argv0[1] = NULL; +} +#else +void +setproctitle (const char *prog, const char *txt) { + int i; + char buf[SPT_BUFSIZE]; + + if (!argv0) + return; + + if (strlen(prog) + strlen(txt) + 5 > SPT_BUFSIZE) + return; + + (void) sprintf(buf, "%s -- %s", prog, txt); + + i = strlen (buf); + if (i > argv_lth - 2) { + i = argv_lth - 2; + buf[i] = '\0'; + } + memset(argv0[0], '\0', argv_lth); /* clear the memory area */ + (void) strcpy (argv0[0], buf); + + argv0[1] = NULL; +} +#endif diff --git a/lib/strverscmp.c b/lib/strverscmp.c new file mode 100644 index 0000000..4405f80 --- /dev/null +++ b/lib/strverscmp.c @@ -0,0 +1,120 @@ +/* Compare strings while treating digits characters numerically. + Copyright (C) 1997, 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Jean-François Bignolles <bignolle@ecoledoc.ibp.fr>, 1997. + + The GNU C 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. + + The GNU C 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 the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <string.h> +#include <ctype.h> +#include <dirent.h> + +/* states: S_N: normal, S_I: comparing integral part, S_F: comparing + fractionnal parts, S_Z: idem but with leading Zeroes only */ +#define S_N 0x0 +#define S_I 0x4 +#define S_F 0x8 +#define S_Z 0xC + +/* result_type: CMP: return diff; LEN: compare using len_diff/diff */ +#define CMP 2 +#define LEN 3 + + +/* Compare S1 and S2 as strings holding indices/version numbers, + returning less than, equal to or greater than zero if S1 is less than, + equal to or greater than S2 (for more info, see the texinfo doc). +*/ + +int +strverscmp (s1, s2) + const char *s1; + const char *s2; +{ + const unsigned char *p1 = (const unsigned char *) s1; + const unsigned char *p2 = (const unsigned char *) s2; + unsigned char c1, c2; + int state; + int diff; + + /* Symbol(s) 0 [1-9] others (padding) + Transition (10) 0 (01) d (00) x (11) - */ + static const unsigned int next_state[] = + { + /* state x d 0 - */ + /* S_N */ S_N, S_I, S_Z, S_N, + /* S_I */ S_N, S_I, S_I, S_I, + /* S_F */ S_N, S_F, S_F, S_F, + /* S_Z */ S_N, S_F, S_Z, S_Z + }; + + static const int result_type[] = + { + /* state x/x x/d x/0 x/- d/x d/d d/0 d/- + 0/x 0/d 0/0 0/- -/x -/d -/0 -/- */ + + /* S_N */ CMP, CMP, CMP, CMP, CMP, LEN, CMP, CMP, + CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, + /* S_I */ CMP, -1, -1, CMP, +1, LEN, LEN, CMP, + +1, LEN, LEN, CMP, CMP, CMP, CMP, CMP, + /* S_F */ CMP, CMP, CMP, CMP, CMP, LEN, CMP, CMP, + CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, + /* S_Z */ CMP, +1, +1, CMP, -1, CMP, CMP, CMP, + -1, CMP, CMP, CMP + }; + + if (p1 == p2) + return 0; + + c1 = *p1++; + c2 = *p2++; + /* Hint: '0' is a digit too. */ + state = S_N | ((c1 == '0') + (isdigit (c1) != 0)); + + while ((diff = c1 - c2) == 0 && c1 != '\0') + { + state = next_state[state]; + c1 = *p1++; + c2 = *p2++; + state |= (c1 == '0') + (isdigit (c1) != 0); + } + + state = result_type[state << 2 | (((c2 == '0') + (isdigit (c2) != 0)))]; + + switch (state) + { + case CMP: + return diff; + + case LEN: + while (isdigit (*p1++)) + if (!isdigit (*p2++)) + return 1; + + return isdigit (*p2) ? -1 : diff; + + default: + return state; + } +} + + +int +version_sort (const void *a, const void *b) +{ + return strverscmp ((*(const struct dirent **) a)->d_name, + (*(const struct dirent **) b)->d_name); +} diff --git a/lib/wholedisk.c b/lib/wholedisk.c new file mode 100644 index 0000000..35f143d --- /dev/null +++ b/lib/wholedisk.c @@ -0,0 +1,58 @@ + +#include <stdio.h> +#include <stdlib.h> +#include <ctype.h> + +#include "blkdev.h" +#include "wholedisk.h" + +int is_whole_disk_fd(int fd, const char *name) +{ +#ifdef HDIO_GETGEO + struct hd_geometry geometry; + int i = 0; + + if (fd != -1) + i = ioctl(fd, HDIO_GETGEO, &geometry); + if (i == 0) + return geometry.start == 0; +#endif + /* + * The "silly heuristic" is still sexy for us, because + * for example Xen doesn't implement HDIO_GETGEO for virtual + * block devices (/dev/xvda). + * + * -- kzak@redhat.com (23-Feb-2006) + */ + while (*name) + name++; + return !isdigit(name[-1]); +} + +int is_whole_disk(const char *name) +{ + int fd = -1, res = 0; +#ifdef HDIO_GETGEO + fd = open(name, O_RDONLY); + if (fd != -1) +#endif + res = is_whole_disk_fd(fd, name); + + if (fd != -1) + close(fd); + return res; +} + +#ifdef TEST_PROGRAM +int main(int argc, char **argv) +{ + if (argc < 2) { + fprintf(stderr, "usage: %s <device>\n", argv[0]); + exit(EXIT_FAILURE); + } + + printf("%s: is%s whole disk\n", argv[1], + is_whole_disk(argv[1]) ? "" : " NOT"); + exit(EXIT_SUCCESS); +} +#endif |