Index: stable/10/Makefile.inc1 =================================================================== --- stable/10/Makefile.inc1 (revision 275039) +++ stable/10/Makefile.inc1 (revision 275040) @@ -1,2010 +1,2014 @@ # # $FreeBSD$ # # Make command line options: # -DNO_CLEANDIR run ${MAKE} clean, instead of ${MAKE} cleandir # -DNO_CLEAN do not clean at all # -DDB_FROM_SRC use the user/group databases in src/etc instead of # the system database when installing. # -DNO_SHARE do not go into share subdir # -DKERNFAST define NO_KERNEL{CONFIG,CLEAN,DEPEND,OBJ} # -DNO_KERNELCONFIG do not run config in ${MAKE} buildkernel # -DNO_KERNELCLEAN do not run ${MAKE} clean in ${MAKE} buildkernel # -DNO_KERNELDEPEND do not run ${MAKE} depend in ${MAKE} buildkernel # -DNO_KERNELOBJ do not run ${MAKE} obj in ${MAKE} buildkernel # -DNO_PORTSUPDATE do not update ports in ${MAKE} update # -DNO_ROOT install without using root privilege # -DNO_DOCUPDATE do not update doc in ${MAKE} update # -DNO_CTF do not run the DTrace CTF conversion tools on built objects # LOCAL_DIRS="list of dirs" to add additional dirs to the SUBDIR list # LOCAL_ITOOLS="list of tools" to add additional tools to the ITOOLS list # LOCAL_LIB_DIRS="list of dirs" to add additional dirs to libraries target # LOCAL_MTREE="list of mtree files" to process to allow local directories # to be created before files are installed # LOCAL_TOOL_DIRS="list of dirs" to add additional dirs to the build-tools # list # METALOG="path to metadata log" to write permission and ownership # when NO_ROOT is set. (default: ${DESTDIR}/METALOG) # TARGET="machine" to crossbuild world for a different machine type # TARGET_ARCH= may be required when a TARGET supports multiple endians # BUILDENV_SHELL= shell to launch for the buildenv target (def:/bin/sh) # WORLD_FLAGS= additional flags to pass to make(1) during buildworld # KERNEL_FLAGS= additional flags to pass to make(1) during buildkernel # # The intended user-driven targets are: # buildworld - rebuild *everything*, including glue to help do upgrades # installworld- install everything built by "buildworld" # doxygen - build API documentation of the kernel # update - convenient way to update your source tree (eg: svn/svnup) # # Standard targets (not defined here) are documented in the makefiles in # /usr/share/mk. These include: # obj depend all install clean cleandepend cleanobj .if !defined(TARGET) || !defined(TARGET_ARCH) .error "Both TARGET and TARGET_ARCH must be defined." .endif .include .include .include # We must do share/info early so that installation of info `dir' # entries works correctly. Do it first since it is less likely to # grow dependencies on include and lib than vice versa. # # We must do lib/ and libexec/ before bin/, because if installworld # installs a new /bin/sh, the 'make' command will *immediately* # use that new version. And the new (dynamically-linked) /bin/sh # will expect to find appropriate libraries in /lib and /libexec. # SRCDIR?= ${.CURDIR} .if defined(SUBDIR_OVERRIDE) SUBDIR= ${SUBDIR_OVERRIDE} .else SUBDIR= share/info lib libexec SUBDIR+=bin .if ${MK_GAMES} != "no" SUBDIR+=games .endif .if ${MK_CDDL} != "no" SUBDIR+=cddl .endif SUBDIR+=gnu include .if ${MK_KERBEROS} != "no" SUBDIR+=kerberos5 .endif .if ${MK_RESCUE} != "no" SUBDIR+=rescue .endif SUBDIR+=sbin .if ${MK_CRYPT} != "no" SUBDIR+=secure .endif .if !defined(NO_SHARE) SUBDIR+=share .endif SUBDIR+=sys usr.bin usr.sbin .if ${MK_TESTS} != "no" SUBDIR+= tests .endif .if ${MK_OFED} != "no" SUBDIR+=contrib/ofed .endif # # We must do etc/ last for install/distribute to work. # SUBDIR+=etc # These are last, since it is nice to at least get the base system # rebuilt before you do them. .for _DIR in ${LOCAL_LIB_DIRS} ${LOCAL_DIRS} .if exists(${.CURDIR}/${_DIR}/Makefile) SUBDIR+= ${_DIR} .endif .endfor .endif .if defined(NOCLEAN) NO_CLEAN= ${NOCLEAN} .endif .if defined(NO_CLEANDIR) CLEANDIR= clean cleandepend .else CLEANDIR= cleandir .endif LOCAL_TOOL_DIRS?= BUILDENV_SHELL?=/bin/sh SVN?= /usr/local/bin/svn SVNFLAGS?= -r HEAD MAKEOBJDIRPREFIX?= /usr/obj .if !defined(OSRELDATE) .if exists(/usr/include/osreldate.h) OSRELDATE!= awk '/^\#define[[:space:]]*__FreeBSD_version/ { print $$3 }' \ /usr/include/osreldate.h .else OSRELDATE= 0 .endif .endif .if !defined(VERSION) REVISION!= make -C ${SRCDIR}/release -V REVISION BRANCH!= make -C ${SRCDIR}/release -V BRANCH SRCRELDATE!= awk '/^\#define[[:space:]]*__FreeBSD_version/ { print $$3 }' \ ${SRCDIR}/sys/sys/param.h VERSION= FreeBSD ${REVISION}-${BRANCH:C/-p[0-9]+$//} ${TARGET_ARCH} ${SRCRELDATE} .endif KNOWN_ARCHES?= amd64 arm armeb/arm armv6/arm i386 i386/pc98 ia64 mips mipsel/mips mips64el/mips mips64/mips mipsn32el/mips mipsn32/mips powerpc powerpc64/powerpc sparc64 .if ${TARGET} == ${TARGET_ARCH} _t= ${TARGET} .else _t= ${TARGET_ARCH}/${TARGET} .endif .for _t in ${_t} .if empty(KNOWN_ARCHES:M${_t}) .error Unknown target ${TARGET_ARCH}:${TARGET}. .endif .endfor .if ${TARGET} == ${MACHINE} TARGET_CPUTYPE?=${CPUTYPE} .else TARGET_CPUTYPE?= .endif .if !empty(TARGET_CPUTYPE) _TARGET_CPUTYPE=${TARGET_CPUTYPE} .else _TARGET_CPUTYPE=dummy .endif _CPUTYPE!= MAKEFLAGS= CPUTYPE=${_TARGET_CPUTYPE} ${MAKE} \ -f /dev/null -m ${.CURDIR}/share/mk -V CPUTYPE .if ${_CPUTYPE} != ${_TARGET_CPUTYPE} .error CPUTYPE global should be set with ?=. .endif .if make(buildworld) BUILD_ARCH!= uname -p .if ${MACHINE_ARCH} != ${BUILD_ARCH} .error To cross-build, set TARGET_ARCH. .endif .endif .if ${MACHINE} == ${TARGET} && ${MACHINE_ARCH} == ${TARGET_ARCH} && !defined(CROSS_BUILD_TESTING) OBJTREE= ${MAKEOBJDIRPREFIX} .else OBJTREE= ${MAKEOBJDIRPREFIX}/${TARGET}.${TARGET_ARCH} .endif WORLDTMP= ${OBJTREE}${.CURDIR}/tmp # /usr/games added for fortune which depend on strfile BPATH= ${WORLDTMP}/legacy/usr/sbin:${WORLDTMP}/legacy/usr/bin:${WORLDTMP}/legacy/usr/games:${WORLDTMP}/legacy/bin XPATH= ${WORLDTMP}/usr/sbin:${WORLDTMP}/usr/bin:${WORLDTMP}/usr/games STRICTTMPPATH= ${BPATH}:${XPATH} TMPPATH= ${STRICTTMPPATH}:${PATH} # # Avoid running mktemp(1) unless actually needed. # It may not be functional, e.g., due to new ABI # when in the middle of installing over this system. # .if make(distributeworld) || make(installworld) INSTALLTMP!= /usr/bin/mktemp -d -u -t install .endif # # Building a world goes through the following stages # # 1. legacy stage [BMAKE] # This stage is responsible for creating compatibility # shims that are needed by the bootstrap-tools, # build-tools and cross-tools stages. # 1. bootstrap-tools stage [BMAKE] # This stage is responsible for creating programs that # are needed for backward compatibility reasons. They # are not built as cross-tools. # 2. build-tools stage [TMAKE] # This stage is responsible for creating the object # tree and building any tools that are needed during # the build process. # 3. cross-tools stage [XMAKE] # This stage is responsible for creating any tools that # are needed for cross-builds. A cross-compiler is one # of them. # 4. world stage [WMAKE] # This stage actually builds the world. # 5. install stage (optional) [IMAKE] # This stage installs a previously built world. # BOOTSTRAPPING?= 0 # Common environment for world related stages CROSSENV= MAKEOBJDIRPREFIX=${OBJTREE} \ MACHINE_ARCH=${TARGET_ARCH} \ MACHINE=${TARGET} \ CPUTYPE=${TARGET_CPUTYPE} .if ${MK_GROFF} != "no" CROSSENV+= GROFF_BIN_PATH=${WORLDTMP}/legacy/usr/bin \ GROFF_FONT_PATH=${WORLDTMP}/legacy/usr/share/groff_font \ GROFF_TMAC_PATH=${WORLDTMP}/legacy/usr/share/tmac .endif # bootstrap-tools stage BMAKEENV= INSTALL="sh ${.CURDIR}/tools/install.sh" \ PATH=${BPATH}:${PATH} \ WORLDTMP=${WORLDTMP} \ VERSION="${VERSION}" \ MAKEFLAGS="-m ${.CURDIR}/tools/build/mk ${.MAKEFLAGS}" \ COMPILER_TYPE=${COMPILER_TYPE} BMAKE= MAKEOBJDIRPREFIX=${WORLDTMP} \ ${BMAKEENV} ${MAKE} ${WORLD_FLAGS} -f Makefile.inc1 \ DESTDIR= \ BOOTSTRAPPING=${OSRELDATE} \ SSP_CFLAGS= \ -DWITHOUT_HTML -DWITHOUT_INFO -DNO_LINT -DWITHOUT_MAN \ -DNO_PIC -DNO_PROFILE -DNO_SHARED \ -DNO_CPU_CFLAGS -DNO_WARNS -DNO_CTF -DEARLY_BUILD -DNO_TESTS # build-tools stage TMAKE= MAKEOBJDIRPREFIX=${OBJTREE} \ ${BMAKEENV} ${MAKE} ${WORLD_FLAGS} -f Makefile.inc1 \ TARGET=${TARGET} TARGET_ARCH=${TARGET_ARCH} \ DESTDIR= \ BOOTSTRAPPING=${OSRELDATE} \ SSP_CFLAGS= \ -DNO_LINT \ -DNO_CPU_CFLAGS -DNO_WARNS -DNO_CTF -DEARLY_BUILD -DNO_TESTS # cross-tools stage XMAKE= TOOLS_PREFIX=${WORLDTMP} ${BMAKE} \ TARGET=${TARGET} TARGET_ARCH=${TARGET_ARCH} \ -DWITHOUT_GDB -DNO_TESTS # kernel-tools stage KTMAKEENV= INSTALL="sh ${.CURDIR}/tools/install.sh" \ PATH=${BPATH}:${PATH} \ WORLDTMP=${WORLDTMP} \ VERSION="${VERSION}" \ COMPILER_TYPE=${COMPILER_TYPE} KTMAKE= TOOLS_PREFIX=${WORLDTMP} MAKEOBJDIRPREFIX=${WORLDTMP} \ ${KTMAKEENV} ${MAKE} ${WORLD_FLAGS} -f Makefile.inc1 \ DESTDIR= \ BOOTSTRAPPING=${OSRELDATE} \ SSP_CFLAGS= \ -DWITHOUT_HTML -DWITHOUT_INFO -DNO_LINT -DWITHOUT_MAN \ -DNO_PIC -DNO_PROFILE -DNO_SHARED \ -DNO_CPU_CFLAGS -DNO_WARNS -DNO_CTF -DEARLY_BUILD # world stage WMAKEENV= ${CROSSENV} \ _SHLIBDIRPREFIX=${WORLDTMP} \ _LDSCRIPTROOT= \ VERSION="${VERSION}" \ INSTALL="sh ${.CURDIR}/tools/install.sh" \ PATH=${TMPPATH} # make hierarchy HMAKE= PATH=${TMPPATH} ${MAKE} LOCAL_MTREE=${LOCAL_MTREE:Q} .if defined(NO_ROOT) HMAKE+= PATH=${TMPPATH} METALOG=${METALOG} -DNO_ROOT .endif .if ${MK_CDDL} == "no" WMAKEENV+= NO_CTF=1 .endif .if defined(CROSS_TOOLCHAIN_PREFIX) CROSS_COMPILER_PREFIX?=${CROSS_TOOLCHAIN_PREFIX} CROSS_BINUTILS_PREFIX?=${CROSS_TOOLCHAIN_PREFIX} .endif XCOMPILERS= CC CXX CPP .for COMPILER in ${XCOMPILERS} .if defined(CROSS_COMPILER_PREFIX) X${COMPILER}?= ${CROSS_COMPILER_PREFIX}${${COMPILER}} .else X${COMPILER}?= ${${COMPILER}} .endif .endfor XBINUTILS= AS AR LD NM OBJDUMP RANLIB STRINGS .for BINUTIL in ${XBINUTILS} .if defined(CROSS_BINUTILS_PREFIX) X${BINUTIL}?= ${CROSS_BINUTILS_PREFIX}${${BINUTIL}} .else X${BINUTIL}?= ${${BINUTIL}} .endif .endfor WMAKEENV+= CC="${XCC} ${XFLAGS}" CXX="${XCXX} ${XFLAGS}" \ CPP="${XCPP} ${XFLAGS}" \ AS="${XAS}" AR="${XAR}" LD="${XLD}" NM=${XNM} \ OBJDUMP=${XOBJDUMP} RANLIB=${XRANLIB} STRINGS=${XSTRINGS} .if ${XCC:T:Mgcc} == "gcc" WMAKE_COMPILER_TYPE= gcc .elif ${XCC:T:Mclang} == "clang" WMAKE_COMPILER_TYPE= clang .elif ${MK_CLANG_IS_CC} == "no" WMAKE_COMPILER_TYPE= gcc .else WMAKE_COMPILER_TYPE= clang .endif IMAKE_COMPILER_TYPE= COMPILER_TYPE=${WMAKE_COMPILER_TYPE} .if ${XCC:M/*} XFLAGS= --sysroot=${WORLDTMP} .if defined(CROSS_BINUTILS_PREFIX) # In the case of xdev-build tools, CROSS_BINUTILS_PREFIX won't be a # directory, but the compiler will look in the right place for it's # tools so we don't need to tell it where to look. .if exists(${CROSS_BINUTILS_PREFIX}) XFLAGS+= -B${CROSS_BINUTILS_PREFIX} .endif .else XFLAGS+= -B${WORLDTMP}/usr/bin .endif .if ${TARGET_ARCH} != ${MACHINE_ARCH} && ${WMAKE_COMPILER_TYPE} == "clang" .if (${TARGET_ARCH} == "arm" || ${TARGET_ARCH} == "armv6") && \ ${MK_ARM_EABI} != "no" TARGET_ABI= gnueabi .else TARGET_ABI= unknown .endif TARGET_TRIPLE?= ${TARGET_ARCH:C/amd64/x86_64/}-${TARGET_ABI}-freebsd10.0 XFLAGS+= -target ${TARGET_TRIPLE} .endif .endif WMAKEENV+= COMPILER_TYPE=${WMAKE_COMPILER_TYPE} WMAKE= ${WMAKEENV} ${MAKE} ${WORLD_FLAGS} -f Makefile.inc1 DESTDIR=${WORLDTMP} .if ${TARGET_ARCH} == "amd64" || ${TARGET_ARCH} == "powerpc64" # 32 bit world LIB32TMP= ${OBJTREE}${.CURDIR}/lib32 .if ${TARGET_ARCH} == "amd64" .if empty(TARGET_CPUTYPE) LIB32CPUFLAGS= -march=i686 -mmmx -msse -msse2 .else LIB32CPUFLAGS= -march=${TARGET_CPUTYPE} .endif LIB32WMAKEENV= MACHINE=i386 MACHINE_ARCH=i386 \ MACHINE_CPU="i686 mmx sse sse2" LIB32WMAKEFLAGS= \ AS="${AS} --32" \ LD="${LD} -m elf_i386_fbsd -Y P,${LIB32TMP}/usr/lib32" .elif ${TARGET_ARCH} == "powerpc64" .if empty(TARGET_CPUTYPE) LIB32CPUFLAGS= -mcpu=powerpc .else LIB32CPUFLAGS= -mcpu=${TARGET_CPUTYPE} .endif LIB32WMAKEENV= MACHINE=powerpc MACHINE_ARCH=powerpc LIB32WMAKEFLAGS= \ LD="${LD} -m elf32ppc_fbsd" .endif LIB32FLAGS= -m32 ${LIB32CPUFLAGS} -DCOMPAT_32BIT \ -isystem ${LIB32TMP}/usr/include/ \ -L${LIB32TMP}/usr/lib32 \ -B${LIB32TMP}/usr/lib32 .if ${XCC:M/*} LIB32FLAGS+= --sysroot=${WORLDTMP} .endif # Yes, the flags are redundant. LIB32WMAKEENV+= MAKEOBJDIRPREFIX=${OBJTREE}/lib32 \ _SHLIBDIRPREFIX=${LIB32TMP} \ _LDSCRIPTROOT=${LIB32TMP} \ VERSION="${VERSION}" \ INSTALL="sh ${.CURDIR}/tools/install.sh" \ PATH=${TMPPATH} \ LIBDIR=/usr/lib32 \ SHLIBDIR=/usr/lib32 \ LIBPRIVATEDIR=/usr/lib32/private \ COMPILER_TYPE=${WMAKE_COMPILER_TYPE} \ DTRACE="${DTRACE} -32" LIB32WMAKEFLAGS+= \ CC="${XCC} ${LIB32FLAGS}" \ CXX="${XCXX} ${LIB32FLAGS}" \ DESTDIR=${LIB32TMP} \ -DCOMPAT_32BIT \ -DLIBRARIES_ONLY \ -DNO_CPU_CFLAGS \ -DNO_CTF \ -DNO_LINT \ -DNO_TESTS LIB32WMAKE= ${LIB32WMAKEENV} ${MAKE} ${LIB32WMAKEFLAGS} \ -DWITHOUT_MAN -DWITHOUT_INFO -DWITHOUT_HTML LIB32IMAKE= ${LIB32WMAKE:NINSTALL=*:NDESTDIR=*:N_LDSCRIPTROOT=*} -DNO_INCS \ ${IMAKE_INSTALL} .endif IMAKEENV= ${CROSSENV:N_LDSCRIPTROOT=*} IMAKE= ${IMAKEENV} ${MAKE} -f Makefile.inc1 \ ${IMAKE_INSTALL} ${IMAKE_MTREE} ${IMAKE_COMPILER_TYPE} .if empty(.MAKEFLAGS:M-n) IMAKEENV+= PATH=${STRICTTMPPATH}:${INSTALLTMP} \ LD_LIBRARY_PATH=${INSTALLTMP} \ PATH_LOCALE=${INSTALLTMP}/locale IMAKE+= __MAKE_SHELL=${INSTALLTMP}/sh .else IMAKEENV+= PATH=${TMPPATH}:${INSTALLTMP} .endif .if defined(DB_FROM_SRC) INSTALLFLAGS+= -N ${.CURDIR}/etc MTREEFLAGS+= -N ${.CURDIR}/etc .endif _INSTALL_DDIR= ${DESTDIR}/${DISTDIR} INSTALL_DDIR= ${_INSTALL_DDIR:S://:/:g:C:/$::} .if defined(NO_ROOT) METALOG?= ${DESTDIR}/${DISTDIR}/METALOG IMAKE+= -DNO_ROOT METALOG=${METALOG} INSTALLFLAGS+= -U -M ${METALOG} -D ${INSTALL_DDIR} MTREEFLAGS+= -W .endif .if defined(DB_FROM_SRC) || defined(NO_ROOT) IMAKE_INSTALL= INSTALL="install ${INSTALLFLAGS}" IMAKE_MTREE= MTREE_CMD="nmtree ${MTREEFLAGS}" .endif # kernel stage KMAKEENV= ${WMAKEENV} KMAKE= ${KMAKEENV} ${MAKE} ${.MAKEFLAGS} ${KERNEL_FLAGS} KERNEL=${INSTKERNNAME} # # buildworld # # Attempt to rebuild the entire system, with reasonable chance of # success, regardless of how old your existing system is. # _worldtmp: .if ${.CURDIR:C/[^,]//g} != "" # The m4 build of sendmail files doesn't like it if ',' is used # anywhere in the path of it's files. @echo @echo "*** Error: path to source tree contains a comma ','" @echo false .endif @echo @echo "--------------------------------------------------------------" @echo ">>> Rebuilding the temporary build tree" @echo "--------------------------------------------------------------" .if !defined(NO_CLEAN) rm -rf ${WORLDTMP} .if defined(LIB32TMP) rm -rf ${LIB32TMP} .endif .else rm -rf ${WORLDTMP}/legacy/usr/include # XXX - These three can depend on any header file. rm -f ${OBJTREE}${.CURDIR}/usr.bin/kdump/ioctl.c rm -f ${OBJTREE}${.CURDIR}/usr.bin/kdump/kdump_subr.c rm -f ${OBJTREE}${.CURDIR}/usr.bin/truss/ioctl.c .endif .for _dir in \ lib usr legacy/bin legacy/usr mkdir -p ${WORLDTMP}/${_dir} .endfor mtree -deU -f ${.CURDIR}/etc/mtree/BSD.usr.dist \ -p ${WORLDTMP}/legacy/usr >/dev/null .if ${MK_GROFF} != "no" mtree -deU -f ${.CURDIR}/etc/mtree/BSD.groff.dist \ -p ${WORLDTMP}/legacy/usr >/dev/null .endif mtree -deU -f ${.CURDIR}/etc/mtree/BSD.usr.dist \ -p ${WORLDTMP}/usr >/dev/null mtree -deU -f ${.CURDIR}/etc/mtree/BSD.include.dist \ -p ${WORLDTMP}/usr/include >/dev/null ln -sf ${.CURDIR}/sys ${WORLDTMP} .if ${MK_DEBUG_FILES} != "no" # We could instead disable debug files for these build stages mtree -deU -f ${.CURDIR}/etc/mtree/BSD.debug.dist \ -p ${WORLDTMP}/legacy/usr/lib >/dev/null mtree -deU -f ${.CURDIR}/etc/mtree/BSD.debug.dist \ -p ${WORLDTMP}/usr/lib >/dev/null .endif .if ${MK_TESTS} != "no" mtree -deU -f ${.CURDIR}/etc/mtree/BSD.tests.dist \ -p ${WORLDTMP}/usr >/dev/null .endif .for _mtree in ${LOCAL_MTREE} mtree -deU -f ${.CURDIR}/${_mtree} -p ${WORLDTMP} > /dev/null .endfor _legacy: @echo @echo "--------------------------------------------------------------" @echo ">>> stage 1.1: legacy release compatibility shims" @echo "--------------------------------------------------------------" ${_+_}cd ${.CURDIR}; ${BMAKE} legacy _bootstrap-tools: @echo @echo "--------------------------------------------------------------" @echo ">>> stage 1.2: bootstrap tools" @echo "--------------------------------------------------------------" ${_+_}cd ${.CURDIR}; ${BMAKE} bootstrap-tools _cleanobj: .if !defined(NO_CLEAN) @echo @echo "--------------------------------------------------------------" @echo ">>> stage 2.1: cleaning up the object tree" @echo "--------------------------------------------------------------" ${_+_}cd ${.CURDIR}; ${WMAKE} ${CLEANDIR:S/^/par-/} .if defined(LIB32TMP) ${_+_}cd ${.CURDIR}; ${LIB32WMAKE} -f Makefile.inc1 ${CLEANDIR:S/^/par-/} .endif .endif _obj: @echo @echo "--------------------------------------------------------------" @echo ">>> stage 2.2: rebuilding the object tree" @echo "--------------------------------------------------------------" ${_+_}cd ${.CURDIR}; ${WMAKE} par-obj _build-tools: @echo @echo "--------------------------------------------------------------" @echo ">>> stage 2.3: build tools" @echo "--------------------------------------------------------------" ${_+_}cd ${.CURDIR}; ${TMAKE} build-tools _cross-tools: @echo @echo "--------------------------------------------------------------" @echo ">>> stage 3: cross tools" @echo "--------------------------------------------------------------" ${_+_}cd ${.CURDIR}; ${XMAKE} cross-tools ${_+_}cd ${.CURDIR}; ${XMAKE} kernel-tools _includes: @echo @echo "--------------------------------------------------------------" @echo ">>> stage 4.1: building includes" @echo "--------------------------------------------------------------" ${_+_}cd ${.CURDIR}; ${WMAKE} SHARED=symlinks par-includes _libraries: @echo @echo "--------------------------------------------------------------" @echo ">>> stage 4.2: building libraries" @echo "--------------------------------------------------------------" ${_+_}cd ${.CURDIR}; \ ${WMAKE} -DNO_FSCHG -DWITHOUT_HTML -DWITHOUT_INFO -DNO_LINT \ -DWITHOUT_MAN -DNO_PROFILE -DNO_TESTS libraries _depend: @echo @echo "--------------------------------------------------------------" @echo ">>> stage 4.3: make dependencies" @echo "--------------------------------------------------------------" ${_+_}cd ${.CURDIR}; ${WMAKE} par-depend everything: @echo @echo "--------------------------------------------------------------" @echo ">>> stage 4.4: building everything" @echo "--------------------------------------------------------------" ${_+_}cd ${.CURDIR}; ${WMAKE} par-all .if defined(LIB32TMP) build32: @echo @echo "--------------------------------------------------------------" @echo ">>> stage 5.1: building 32 bit shim libraries" @echo "--------------------------------------------------------------" mkdir -p ${LIB32TMP}/usr/include mtree -deU -f ${.CURDIR}/etc/mtree/BSD.usr.dist \ -p ${LIB32TMP}/usr >/dev/null mtree -deU -f ${.CURDIR}/etc/mtree/BSD.include.dist \ -p ${LIB32TMP}/usr/include >/dev/null .if ${MK_DEBUG_FILES} != "no" mtree -deU -f ${.CURDIR}/etc/mtree/BSD.debug.dist \ -p ${LIB32TMP}/usr/lib >/dev/null .endif mkdir -p ${WORLDTMP} ln -sf ${.CURDIR}/sys ${WORLDTMP} .for _t in obj includes cd ${.CURDIR}/include; ${LIB32WMAKE} DIRPRFX=include/ ${_t} cd ${.CURDIR}/lib; ${LIB32WMAKE} DIRPRFX=lib/ ${_t} .if ${MK_CDDL} != "no" cd ${.CURDIR}/cddl/lib; ${LIB32WMAKE} DIRPRFX=cddl/lib/ ${_t} .endif cd ${.CURDIR}/gnu/lib; ${LIB32WMAKE} DIRPRFX=gnu/lib/ ${_t} .if ${MK_CRYPT} != "no" cd ${.CURDIR}/secure/lib; ${LIB32WMAKE} DIRPRFX=secure/lib/ ${_t} .endif .if ${MK_KERBEROS} != "no" cd ${.CURDIR}/kerberos5/lib; ${LIB32WMAKE} DIRPRFX=kerberos5/lib ${_t} .endif .endfor .for _dir in usr.bin/lex/lib cd ${.CURDIR}/${_dir}; ${LIB32WMAKE} DIRPRFX=${_dir}/ obj .endfor .for _dir in lib/ncurses/ncurses lib/ncurses/ncursesw lib/libmagic cd ${.CURDIR}/${_dir}; \ WORLDTMP=${WORLDTMP} \ MAKEFLAGS="-m ${.CURDIR}/tools/build/mk ${.MAKEFLAGS}" \ MAKEOBJDIRPREFIX=${OBJTREE}/lib32 ${MAKE} SSP_CFLAGS= DESTDIR= \ DIRPRFX=${_dir}/ -DNO_LINT -DNO_CPU_CFLAGS -DNO_WARNS -DNO_CTF \ -DEARLY_BUILD build-tools .endfor cd ${.CURDIR}; \ ${LIB32WMAKE} -f Makefile.inc1 libraries .for _t in obj depend all cd ${.CURDIR}/libexec/rtld-elf; PROG=ld-elf32.so.1 ${LIB32WMAKE} \ DIRPRFX=libexec/rtld-elf/ ${_t} cd ${.CURDIR}/usr.bin/ldd; PROG=ldd32 ${LIB32WMAKE} \ DIRPRFX=usr.bin/ldd ${_t} .endfor distribute32 install32: cd ${.CURDIR}/lib; ${LIB32IMAKE} ${.TARGET:S/32$//} .if ${MK_CDDL} != "no" cd ${.CURDIR}/cddl/lib; ${LIB32IMAKE} ${.TARGET:S/32$//} .endif cd ${.CURDIR}/gnu/lib; ${LIB32IMAKE} ${.TARGET:S/32$//} .if ${MK_CRYPT} != "no" cd ${.CURDIR}/secure/lib; ${LIB32IMAKE} ${.TARGET:S/32$//} .endif .if ${MK_KERBEROS} != "no" cd ${.CURDIR}/kerberos5/lib; ${LIB32IMAKE} ${.TARGET:S/32$//} .endif cd ${.CURDIR}/libexec/rtld-elf; \ PROG=ld-elf32.so.1 ${LIB32IMAKE} ${.TARGET:S/32$//} cd ${.CURDIR}/usr.bin/ldd; PROG=ldd32 ${LIB32IMAKE} ${.TARGET:S/32$//} .endif WMAKE_TGTS= .if !defined(SUBDIR_OVERRIDE) WMAKE_TGTS+= _worldtmp _legacy _bootstrap-tools .endif WMAKE_TGTS+= _cleanobj _obj _build-tools .if !defined(SUBDIR_OVERRIDE) WMAKE_TGTS+= _cross-tools .endif WMAKE_TGTS+= _includes _libraries _depend everything .if defined(LIB32TMP) && ${MK_LIB32} != "no" WMAKE_TGTS+= build32 .endif buildworld: buildworld_prologue ${WMAKE_TGTS} buildworld_epilogue .ORDER: buildworld_prologue ${WMAKE_TGTS} buildworld_epilogue buildworld_prologue: @echo "--------------------------------------------------------------" @echo ">>> World build started on `LC_ALL=C date`" @echo "--------------------------------------------------------------" buildworld_epilogue: @echo @echo "--------------------------------------------------------------" @echo ">>> World build completed on `LC_ALL=C date`" @echo "--------------------------------------------------------------" # # We need to have this as a target because the indirection between Makefile # and Makefile.inc1 causes the correct PATH to be used, rather than a # modification of the current environment's PATH. In addition, we need # to quote multiword values. # buildenvvars: @echo ${WMAKEENV:Q} buildenv: @echo Entering world for ${TARGET_ARCH}:${TARGET} @cd ${.CURDIR} && env ${WMAKEENV} ${BUILDENV_SHELL} || true TOOLCHAIN_TGTS= ${WMAKE_TGTS:N_depend:Neverything:Nbuild32} toolchain: ${TOOLCHAIN_TGTS} kernel-toolchain: ${TOOLCHAIN_TGTS:N_includes:N_libraries} # # installcheck # # Checks to be sure system is ready for installworld/installkernel. # installcheck: _installcheck_world _installcheck_kernel _installcheck_world: _installcheck_kernel: # # Require DESTDIR to be set if installing for a different architecture or # using the user/group database in the source tree. # .if ${TARGET_ARCH} != ${MACHINE_ARCH} || ${TARGET} != ${MACHINE} || \ defined(DB_FROM_SRC) .if !make(distributeworld) _installcheck_world: __installcheck_DESTDIR _installcheck_kernel: __installcheck_DESTDIR __installcheck_DESTDIR: .if !defined(DESTDIR) || empty(DESTDIR) @echo "ERROR: Please set DESTDIR!"; \ false .endif .endif .endif .if !defined(DB_FROM_SRC) # # Check for missing UIDs/GIDs. # CHECK_UIDS= auditdistd CHECK_GIDS= audit .if ${MK_SENDMAIL} != "no" CHECK_UIDS+= smmsp CHECK_GIDS+= smmsp .endif .if ${MK_PF} != "no" CHECK_UIDS+= proxy CHECK_GIDS+= proxy authpf .endif .if ${MK_UNBOUND} != "no" CHECK_UIDS+= unbound CHECK_GIDS+= unbound .endif _installcheck_world: __installcheck_UGID __installcheck_UGID: .for uid in ${CHECK_UIDS} @if ! `id -u ${uid} >/dev/null 2>&1`; then \ echo "ERROR: Required ${uid} user is missing, see /usr/src/UPDATING."; \ false; \ fi .endfor .for gid in ${CHECK_GIDS} @if ! `find / -prune -group ${gid} >/dev/null 2>&1`; then \ echo "ERROR: Required ${gid} group is missing, see /usr/src/UPDATING."; \ false; \ fi .endfor .endif # # Required install tools to be saved in a scratch dir for safety. # .if ${MK_INFO} != "no" _install-info= install-info .endif .if ${MK_ZONEINFO} != "no" _zoneinfo= zic tzsetup .endif .if exists(/usr/sbin/nmtree) _nmtree_itools= nmtree .endif ITOOLS= [ awk cap_mkdb cat chflags chmod chown \ date echo egrep find grep id install ${_install-info} \ ln lockf make mkdir mtree ${_nmtree_itools} mv pwd_mkdb \ rm sed sh sysctl test true uname wc ${_zoneinfo} \ ${LOCAL_ITOOLS} # # distributeworld # # Distributes everything compiled by a `buildworld'. # # installworld # # Installs everything compiled by a 'buildworld'. # # Non-base distributions produced by the base system EXTRA_DISTRIBUTIONS= doc .if ${MK_GAMES} != "no" EXTRA_DISTRIBUTIONS+= games .endif .if defined(LIB32TMP) && ${MK_LIB32} != "no" EXTRA_DISTRIBUTIONS+= lib32 .endif .if ${MK_TESTS} != "no" EXTRA_DISTRIBUTIONS+= tests .endif MTREE_MAGIC?= mtree 2.0 distributeworld installworld: _installcheck_world mkdir -p ${INSTALLTMP} progs=$$(for prog in ${ITOOLS}; do \ if progpath=`which $$prog`; then \ echo $$progpath; \ else \ echo "Required tool $$prog not found in PATH." >&2; \ exit 1; \ fi; \ done); \ libs=$$(ldd -f "%o %p\n" -f "%o %p\n" $$progs 2>/dev/null | sort -u | \ while read line; do \ set -- $$line; \ if [ "$$2 $$3" != "not found" ]; then \ echo $$2; \ else \ echo "Required library $$1 not found." >&2; \ exit 1; \ fi; \ done); \ cp $$libs $$progs ${INSTALLTMP} cp -R $${PATH_LOCALE:-"/usr/share/locale"} ${INSTALLTMP}/locale .if defined(NO_ROOT) echo "#${MTREE_MAGIC}" > ${METALOG} .endif .if make(distributeworld) .for dist in ${EXTRA_DISTRIBUTIONS} -mkdir ${DESTDIR}/${DISTDIR}/${dist} mtree -deU -f ${.CURDIR}/etc/mtree/BSD.root.dist \ -p ${DESTDIR}/${DISTDIR}/${dist} >/dev/null mtree -deU -f ${.CURDIR}/etc/mtree/BSD.usr.dist \ -p ${DESTDIR}/${DISTDIR}/${dist}/usr >/dev/null mtree -deU -f ${.CURDIR}/etc/mtree/BSD.include.dist \ -p ${DESTDIR}/${DISTDIR}/${dist}/usr/include >/dev/null .if ${MK_DEBUG_FILES} != "no" mtree -deU -f ${.CURDIR}/etc/mtree/BSD.debug.dist \ -p ${DESTDIR}/${DISTDIR}/${dist}/usr/lib >/dev/null .endif .if ${MK_TESTS} != "no" && ${dist} == "tests" mtree -deU -f ${.CURDIR}/etc/mtree/BSD.tests.dist \ -p ${DESTDIR}/${DISTDIR}/${dist}/usr >/dev/null .endif .if defined(NO_ROOT) ${IMAKEENV} nmtree -C -f ${.CURDIR}/etc/mtree/BSD.root.dist | \ sed -e 's#^\./#./${dist}/#' >> ${METALOG} ${IMAKEENV} nmtree -C -f ${.CURDIR}/etc/mtree/BSD.usr.dist | \ sed -e 's#^\./#./${dist}/usr/#' >> ${METALOG} ${IMAKEENV} nmtree -C -f ${.CURDIR}/etc/mtree/BSD.include.dist | \ sed -e 's#^\./#./${dist}/usr/include/#' >> ${METALOG} .endif .endfor -mkdir ${DESTDIR}/${DISTDIR}/base cd ${.CURDIR}/etc; ${CROSSENV} PATH=${TMPPATH} ${MAKE} \ METALOG=${METALOG} ${IMAKE_INSTALL} ${IMAKE_MTREE} \ DISTBASE=/base DESTDIR=${DESTDIR}/${DISTDIR}/base \ LOCAL_MTREE=${LOCAL_MTREE:Q} distrib-dirs .endif ${_+_}cd ${.CURDIR}; ${IMAKE} re${.TARGET:S/world$//}; \ ${IMAKEENV} rm -rf ${INSTALLTMP} .if make(distributeworld) .for dist in ${EXTRA_DISTRIBUTIONS} find ${DESTDIR}/${DISTDIR}/${dist} -mindepth 1 -empty -delete .endfor .if defined(NO_ROOT) .for dist in base ${EXTRA_DISTRIBUTIONS} @# For each file that exists in this dist, print the corresponding @# line from the METALOG. This relies on the fact that @# a line containing only the filename will sort immediatly before @# the relevant mtree line. cd ${DESTDIR}/${DISTDIR}; \ find ./${dist} | sort -u ${METALOG} - | \ awk 'BEGIN { print "#${MTREE_MAGIC}" } !/ type=/ { file = $$1 } / type=/ { if ($$1 == file) { sub(/^\.\/${dist}\//, "./"); print } }' > \ ${DESTDIR}/${DISTDIR}/${dist}.meta .endfor .if ${MK_DEBUG_FILES} != "no" . for dist in base ${EXTRA_DISTRIBUTIONS} @# For each file that exists in this dist, print the corresponding @# line from the METALOG. This relies on the fact that @# a line containing only the filename will sort immediatly before @# the relevant mtree line. cd ${DESTDIR}/${DISTDIR}; \ find ./${dist}/usr/lib/debug | sort -u ${METALOG} - | \ awk 'BEGIN { print "#${MTREE_MAGIC}" } !/ type=/ { file = $$1 } / type=/ { if ($$1 == file) { sub(/^\.\/${dist}\//, "./"); print } }' > \ ${DESTDIR}/${DISTDIR}/${dist}.debug.meta . endfor .endif .endif .endif packageworld: .for dist in base ${EXTRA_DISTRIBUTIONS} .if defined(NO_ROOT) ${_+_}cd ${DESTDIR}/${DISTDIR}/${dist}; \ tar cvJf ${DESTDIR}/${DISTDIR}/${dist}.txz \ --exclude usr/lib/debug \ @${DESTDIR}/${DISTDIR}/${dist}.meta .else ${_+_}cd ${DESTDIR}/${DISTDIR}/${dist}; \ tar cvJf ${DESTDIR}/${DISTDIR}/${dist}.txz \ --exclude usr/lib/debug . .endif .endfor .if ${MK_DEBUG_FILES} != "no" . for dist in base ${EXTRA_DISTRIBUTIONS} . if defined(NO_ROOT) ${_+_}cd ${DESTDIR}/${DISTDIR}/${dist}; \ tar cvJf ${DESTDIR}/${DISTDIR}/${dist}.debug.txz \ @${DESTDIR}/${DISTDIR}/${dist}.debug.meta . else ${_+_}cd ${DESTDIR}/${DISTDIR}/${dist}; \ tar cvJfL ${DESTDIR}/${DISTDIR}/${dist}.debug.txz \ usr/lib/debug . endif . endfor .endif # # reinstall # # If you have a build server, you can NFS mount the source and obj directories # and do a 'make reinstall' on the *client* to install new binaries from the # most recent server build. # reinstall: .MAKE @echo "--------------------------------------------------------------" @echo ">>> Making hierarchy" @echo "--------------------------------------------------------------" ${_+_}cd ${.CURDIR}; ${MAKE} -f Makefile.inc1 \ LOCAL_MTREE=${LOCAL_MTREE:Q} hierarchy @echo @echo "--------------------------------------------------------------" @echo ">>> Installing everything" @echo "--------------------------------------------------------------" ${_+_}cd ${.CURDIR}; ${MAKE} -f Makefile.inc1 install .if defined(LIB32TMP) && ${MK_LIB32} != "no" ${_+_}cd ${.CURDIR}; ${MAKE} -f Makefile.inc1 install32 .endif redistribute: .MAKE @echo "--------------------------------------------------------------" @echo ">>> Distributing everything" @echo "--------------------------------------------------------------" ${_+_}cd ${.CURDIR}; ${MAKE} -f Makefile.inc1 distribute .if defined(LIB32TMP) && ${MK_LIB32} != "no" ${_+_}cd ${.CURDIR}; ${MAKE} -f Makefile.inc1 distribute32 \ DISTRIBUTION=lib32 .endif distrib-dirs distribution: .MAKE cd ${.CURDIR}/etc; ${CROSSENV} PATH=${TMPPATH} ${MAKE} \ ${IMAKE_INSTALL} ${IMAKE_MTREE} METALOG=${METALOG} ${.TARGET} # # buildkernel and installkernel # # Which kernels to build and/or install is specified by setting # KERNCONF. If not defined a GENERIC kernel is built/installed. # Only the existing (depending TARGET) config files are used # for building kernels and only the first of these is designated # as the one being installed. # # Note that we have to use TARGET instead of TARGET_ARCH when # we're in kernel-land. Since only TARGET_ARCH is (expected) to # be set to cross-build, we have to make sure TARGET is set # properly. .if defined(KERNFAST) NO_KERNELCLEAN= t NO_KERNELCONFIG= t NO_KERNELDEPEND= t NO_KERNELOBJ= t # Shortcut for KERNCONF=Blah -DKERNFAST is now KERNFAST=Blah .if !defined(KERNCONF) && ${KERNFAST} != "1" KERNCONF=${KERNFAST} .endif .endif .if ${TARGET_ARCH} == "powerpc64" KERNCONF?= GENERIC64 .else KERNCONF?= GENERIC .endif INSTKERNNAME?= kernel KERNSRCDIR?= ${.CURDIR}/sys KRNLCONFDIR= ${KERNSRCDIR}/${TARGET}/conf KRNLOBJDIR= ${OBJTREE}${KERNSRCDIR} KERNCONFDIR?= ${KRNLCONFDIR} BUILDKERNELS= INSTALLKERNEL= .for _kernel in ${KERNCONF} .if exists(${KERNCONFDIR}/${_kernel}) BUILDKERNELS+= ${_kernel} .if empty(INSTALLKERNEL) INSTALLKERNEL= ${_kernel} .endif .endif .endfor buildkernel ${WMAKE_TGTS} ${.ALLTARGETS:M_*}: .MAKE # # buildkernel # # Builds all kernels defined by BUILDKERNELS. # buildkernel: .if empty(BUILDKERNELS) @echo "ERROR: Missing kernel configuration file(s) (${KERNCONF})."; \ false .endif @echo .for _kernel in ${BUILDKERNELS} @echo "--------------------------------------------------------------" @echo ">>> Kernel build for ${_kernel} started on `LC_ALL=C date`" @echo "--------------------------------------------------------------" @echo "===> ${_kernel}" mkdir -p ${KRNLOBJDIR} .if !defined(NO_KERNELCONFIG) @echo @echo "--------------------------------------------------------------" @echo ">>> stage 1: configuring the kernel" @echo "--------------------------------------------------------------" cd ${KRNLCONFDIR}; \ PATH=${TMPPATH} \ config ${CONFIGARGS} -d ${KRNLOBJDIR}/${_kernel} \ -I '${KERNCONFDIR}' '${KERNCONFDIR}/${_kernel}' .endif .if !defined(NO_CLEAN) && !defined(NO_KERNELCLEAN) @echo @echo "--------------------------------------------------------------" @echo ">>> stage 2.1: cleaning up the object tree" @echo "--------------------------------------------------------------" cd ${KRNLOBJDIR}/${_kernel}; ${KMAKE} ${CLEANDIR} .endif .if !defined(NO_KERNELOBJ) @echo @echo "--------------------------------------------------------------" @echo ">>> stage 2.2: rebuilding the object tree" @echo "--------------------------------------------------------------" cd ${KRNLOBJDIR}/${_kernel}; ${KMAKE} obj .endif @echo @echo "--------------------------------------------------------------" @echo ">>> stage 2.3: build tools" @echo "--------------------------------------------------------------" ${_+_}cd ${.CURDIR}; ${KTMAKE} kernel-tools .if !defined(NO_KERNELDEPEND) @echo @echo "--------------------------------------------------------------" @echo ">>> stage 3.1: making dependencies" @echo "--------------------------------------------------------------" cd ${KRNLOBJDIR}/${_kernel}; ${KMAKE} depend -DNO_MODULES_OBJ .endif @echo @echo "--------------------------------------------------------------" @echo ">>> stage 3.2: building everything" @echo "--------------------------------------------------------------" cd ${KRNLOBJDIR}/${_kernel}; ${KMAKE} all -DNO_MODULES_OBJ @echo "--------------------------------------------------------------" @echo ">>> Kernel build for ${_kernel} completed on `LC_ALL=C date`" @echo "--------------------------------------------------------------" .endfor # # installkernel, etc. # # Install the kernel defined by INSTALLKERNEL # installkernel installkernel.debug \ reinstallkernel reinstallkernel.debug: _installcheck_kernel .if empty(INSTALLKERNEL) @echo "ERROR: No kernel \"${KERNCONF}\" to install."; \ false .endif @echo "--------------------------------------------------------------" @echo ">>> Installing kernel ${INSTALLKERNEL}" @echo "--------------------------------------------------------------" cd ${KRNLOBJDIR}/${INSTALLKERNEL}; \ ${CROSSENV} PATH=${TMPPATH} \ ${MAKE} ${IMAKE_INSTALL} KERNEL=${INSTKERNNAME} ${.TARGET:S/kernel//} distributekernel distributekernel.debug: .if empty(INSTALLKERNEL) @echo "ERROR: No kernel \"${KERNCONF}\" to install."; \ false .endif mkdir -p ${DESTDIR}/${DISTDIR} .if defined(NO_ROOT) echo "#${MTREE_MAGIC}" > ${DESTDIR}/${DISTDIR}/kernel.premeta .endif cd ${KRNLOBJDIR}/${INSTALLKERNEL}; \ ${IMAKEENV} ${IMAKE_INSTALL:S/METALOG/kernel.premeta/} \ ${IMAKE_MTREE} PATH=${TMPPATH} ${MAKE} KERNEL=${INSTKERNNAME} \ DESTDIR=${INSTALL_DDIR}/kernel \ ${.TARGET:S/distributekernel/install/} .if defined(NO_ROOT) sed -e 's|^./kernel|.|' ${DESTDIR}/${DISTDIR}/kernel.premeta > \ ${DESTDIR}/${DISTDIR}/kernel.meta .endif .for _kernel in ${BUILDKERNELS:S/${INSTALLKERNEL}//} .if defined(NO_ROOT) echo "#${MTREE_MAGIC}" > ${DESTDIR}/${DISTDIR}/kernel.${_kernel}.premeta .endif cd ${KRNLOBJDIR}/${_kernel}; \ ${IMAKEENV} ${IMAKE_INSTALL:S/METALOG/kernel.${_kernel}.premeta/} \ ${IMAKE_MTREE} PATH=${TMPPATH} ${MAKE} \ KERNEL=${INSTKERNNAME}.${_kernel} \ DESTDIR=${INSTALL_DDIR}/kernel.${_kernel} \ ${.TARGET:S/distributekernel/install/} .if defined(NO_ROOT) sed -e 's|^./kernel|.|' \ ${DESTDIR}/${DISTDIR}/kernel.${_kernel}.premeta > \ ${DESTDIR}/${DISTDIR}/kernel.${_kernel}.meta .endif .endfor packagekernel: .if defined(NO_ROOT) cd ${DESTDIR}/${DISTDIR}/kernel; \ tar cvJf ${DESTDIR}/${DISTDIR}/kernel.txz \ @${DESTDIR}/${DISTDIR}/kernel.meta .for _kernel in ${BUILDKERNELS:S/${INSTALLKERNEL}//} cd ${DESTDIR}/${DISTDIR}/kernel.${_kernel}; \ tar cvJf ${DESTDIR}/${DISTDIR}/kernel.${_kernel}.txz \ @${DESTDIR}/${DISTDIR}/kernel.${_kernel}.meta .endfor .else cd ${DESTDIR}/${DISTDIR}/kernel; \ tar cvJf ${DESTDIR}/${DISTDIR}/kernel.txz . .for _kernel in ${BUILDKERNELS:S/${INSTALLKERNEL}//} cd ${DESTDIR}/${DISTDIR}/kernel.${_kernel}; \ tar cvJf ${DESTDIR}/${DISTDIR}/kernel.${_kernel}.txz . .endfor .endif # # doxygen # # Build the API documentation with doxygen # doxygen: @if [ ! -x `/usr/bin/which doxygen` ]; then \ echo "You need doxygen (devel/doxygen) to generate the API documentation of the kernel." | /usr/bin/fmt; \ exit 1; \ fi cd ${.CURDIR}/tools/kerneldoc/subsys && ${MAKE} obj all # # update # # Update the source tree(s), by running svn/svnup to update to the # latest copy. # update: .if (defined(CVS_UPDATE) || defined(SUP_UPDATE)) && !defined(SVN_UPDATE) @echo "--------------------------------------------------------------" @echo "CVS_UPDATE and SUP_UPDATE are no longer supported." @echo "Please see: https://wiki.freebsd.org/CvsIsDeprecated" @echo "--------------------------------------------------------------" @exit 1 .endif .if defined(SVN_UPDATE) @echo "--------------------------------------------------------------" @echo ">>> Updating ${.CURDIR} using Subversion" @echo "--------------------------------------------------------------" @(cd ${.CURDIR} && ${SVN} update ${SVNFLAGS}) .endif # # ------------------------------------------------------------------------ # # From here onwards are utility targets used by the 'make world' and # related targets. If your 'world' breaks, you may like to try to fix # the problem and manually run the following targets to attempt to # complete the build. Beware, this is *not* guaranteed to work, you # need to have a pretty good grip on the current state of the system # to attempt to manually finish it. If in doubt, 'make world' again. # # # legacy: Build compatibility shims for the next three targets # legacy: .if ${BOOTSTRAPPING} < 700055 && ${BOOTSTRAPPING} != 0 @echo "ERROR: Source upgrades from versions prior to 7.0 not supported."; \ false .endif .for _tool in tools/build ${_+_}@${ECHODIR} "===> ${_tool} (obj,includes,depend,all,install)"; \ cd ${.CURDIR}/${_tool} && \ ${MAKE} DIRPRFX=${_tool}/ obj && \ ${MAKE} DIRPRFX=${_tool}/ DESTDIR=${MAKEOBJDIRPREFIX}/legacy includes && \ ${MAKE} DIRPRFX=${_tool}/ depend && \ ${MAKE} DIRPRFX=${_tool}/ all && \ ${MAKE} DIRPRFX=${_tool}/ DESTDIR=${MAKEOBJDIRPREFIX}/legacy install .endfor # # bootstrap-tools: Build tools needed for compatibility # .if ${MK_GAMES} != "no" _strfile= games/fortune/strfile .endif .if ${MK_CXX} != "no" _gperf= gnu/usr.bin/gperf .endif .if ${MK_GROFF} != "no" _groff= gnu/usr.bin/groff .endif .if ${MK_VT} != "no" _vtfontcvt= usr.bin/vtfontcvt .endif .if ${BOOTSTRAPPING} < 800022 _ar= usr.bin/ar .endif .if ${BOOTSTRAPPING} < 800013 _mklocale= usr.bin/mklocale .endif .if ${BOOTSTRAPPING} < 900002 _sed= usr.bin/sed .endif .if ${BOOTSTRAPPING} < 1000002 _m4= usr.bin/m4 .endif .if ${BOOTSTRAPPING} < 1000013 _yacc= lib/liby \ usr.bin/yacc .endif .if ${BOOTSTRAPPING} < 1000014 _crunch= usr.sbin/crunch .endif .if ${BOOTSTRAPPING} < 1000026 _nmtree= lib/libnetbsd \ usr.sbin/nmtree .endif .if ${BOOTSTRAPPING} < 1000027 _cat= bin/cat .endif .if ${BOOTSTRAPPING} < 1000033 _lex= usr.bin/lex .endif .if ${BOOTSTRAPPING} >= 900040 && ${BOOTSTRAPPING} < 900041 _awk= usr.bin/awk .endif .if ${MK_BSNMP} != "no" _gensnmptree= usr.sbin/bsnmpd/gensnmptree .endif .if ${MK_CLANG} != "no" _clang_tblgen= \ lib/clang/libllvmsupport \ lib/clang/libllvmtablegen \ usr.bin/clang/tblgen \ usr.bin/clang/clang-tblgen .endif # dtrace tools are required for older bootstrap env and cross-build .if ${MK_CDDL} != "no" && \ ((${BOOTSTRAPPING} < 1000034 && \ !(${BOOTSTRAPPING} >= 901505 && ${BOOTSTRAPPING} < 999999)) \ || (${MACHINE} != ${TARGET} || ${MACHINE_ARCH} != ${TARGET_ARCH})) _dtrace_tools= cddl/usr.bin/sgsmsg cddl/lib/libctf lib/libelf \ lib/libdwarf cddl/usr.bin/ctfconvert cddl/usr.bin/ctfmerge .endif # Default to building the GPL DTC, but build the BSDL one if users explicitly # request it. _dtc= usr.bin/dtc .if ${MK_GPL_DTC} != "no" _dtc= gnu/usr.bin/dtc .endif .if ${MK_KERBEROS} != "no" _kerberos5_bootstrap_tools= \ kerberos5/tools/make-roken \ kerberos5/lib/libroken \ kerberos5/lib/libvers \ kerberos5/tools/asn1_compile \ kerberos5/tools/slc \ usr.bin/compile_et .endif # Please document (add comment) why something is in 'bootstrap-tools'. # Try to bound the building of the bootstrap-tool to just the # FreeBSD versions that need the tool built at this stage of the build. bootstrap-tools: .MAKE .for _tool in \ ${_clang_tblgen} \ ${_kerberos5_bootstrap_tools} \ ${_dtrace_tools} \ ${_strfile} \ ${_gperf} \ ${_groff} \ ${_ar} \ ${_dtc} \ ${_awk} \ ${_cat} \ usr.bin/lorder \ usr.bin/makewhatis \ ${_mklocale} \ usr.bin/rpcgen \ ${_sed} \ ${_yacc} \ ${_m4} \ ${_lex} \ lib/libmd \ usr.bin/xinstall \ ${_gensnmptree} \ usr.sbin/config \ ${_crunch} \ ${_nmtree} \ ${_vtfontcvt} ${_+_}@${ECHODIR} "===> ${_tool} (obj,depend,all,install)"; \ cd ${.CURDIR}/${_tool} && \ ${MAKE} DIRPRFX=${_tool}/ obj && \ ${MAKE} DIRPRFX=${_tool}/ depend && \ ${MAKE} DIRPRFX=${_tool}/ all && \ ${MAKE} DIRPRFX=${_tool}/ DESTDIR=${MAKEOBJDIRPREFIX}/legacy install .endfor # # build-tools: Build special purpose build tools # .if !defined(NO_SHARE) _share= share/syscons/scrnmaps .endif .if ${MK_GCC} != "no" _gcc_tools= gnu/usr.bin/cc/cc_tools .endif .if ${MK_RESCUE} != "no" _rescue= rescue/rescue .endif build-tools: .MAKE .for _tool in \ bin/csh \ bin/sh \ ${_rescue} \ ${LOCAL_TOOL_DIRS} \ lib/ncurses/ncurses \ lib/ncurses/ncursesw \ ${_share} \ usr.bin/awk \ lib/libmagic \ usr.bin/mkesdb_static \ usr.bin/mkcsmapper_static \ usr.bin/vi/catalog ${_+_}@${ECHODIR} "===> ${_tool} (obj,build-tools)"; \ cd ${.CURDIR}/${_tool} && \ ${MAKE} DIRPRFX=${_tool}/ obj && \ ${MAKE} DIRPRFX=${_tool}/ build-tools .endfor .for _tool in \ ${_gcc_tools} ${_+_}@${ECHODIR} "===> ${_tool} (obj,depend,all)"; \ cd ${.CURDIR}/${_tool} && \ ${MAKE} DIRPRFX=${_tool}/ obj && \ ${MAKE} DIRPRFX=${_tool}/ depend && \ ${MAKE} DIRPRFX=${_tool}/ all .endfor # # kernel-tools: Build kernel-building tools # kernel-tools: .MAKE mkdir -p ${MAKEOBJDIRPREFIX}/usr mtree -deU -f ${.CURDIR}/etc/mtree/BSD.usr.dist \ -p ${MAKEOBJDIRPREFIX}/usr >/dev/null # # cross-tools: Build cross-building tools # .if !defined(TARGET_ARCH) && defined(XDEV_ARCH) TARGET_ARCH= ${XDEV_ARCH} .endif .if ${TARGET_ARCH} != ${MACHINE_ARCH} || ${BOOTSTRAPPING} < 800035 .if ${TARGET_ARCH} == "amd64" || ${TARGET_ARCH} == "i386" _btxld= usr.sbin/btxld .endif .endif .if ${TARGET_ARCH} != ${MACHINE_ARCH} .if ${MK_RESCUE} != "no" || defined(RELEASEDIR) _crunchide= usr.sbin/crunch/crunchide .endif .if ${TARGET_ARCH} == "i386" && defined(RELEASEDIR) _kgzip= usr.sbin/kgzip .endif .endif .if ${XAS:M/*} == "" && ${MK_BINUTILS} != "no" _binutils= gnu/usr.bin/binutils .endif # If an full path to an external cross compiler is given, don't build # a cross compiler. .if ${XCC:M/*} == "" && ${MK_CROSS_COMPILER} != "no" .if ${MK_CLANG_IS_CC} != "no" || ${CC:T:Mclang} == "clang" _clang= usr.bin/clang _clang_libs= lib/clang .else _cc= gnu/usr.bin/cc .endif # The boot2 for pc98 requires gcc. .if ${TARGET} == "pc98" _cc= gnu/usr.bin/cc .endif .endif cross-tools: .MAKE .for _tool in \ ${_clang_libs} \ ${_clang} \ ${_binutils} \ ${_cc} \ usr.bin/xlint/lint1 usr.bin/xlint/lint2 usr.bin/xlint/xlint \ ${_btxld} \ ${_crunchide} \ ${_kgzip} ${_+_}@${ECHODIR} "===> ${_tool} (obj,depend,all,install)"; \ cd ${.CURDIR}/${_tool} && \ ${MAKE} DIRPRFX=${_tool}/ obj && \ ${MAKE} DIRPRFX=${_tool}/ depend && \ ${MAKE} DIRPRFX=${_tool}/ all && \ ${MAKE} DIRPRFX=${_tool}/ DESTDIR=${MAKEOBJDIRPREFIX} install .endfor # # hierarchy - ensure that all the needed directories are present # hierarchy hier: .MAKE cd ${.CURDIR}/etc && ${HMAKE} distrib-dirs # # libraries - build all libraries, and install them under ${DESTDIR}. # # The list of libraries with dependents (${_prebuild_libs}) and their # interdependencies (__L) are built automatically by the # ${.CURDIR}/tools/make_libdeps.sh script. # libraries: .MAKE cd ${.CURDIR} && \ ${MAKE} -f Makefile.inc1 _prereq_libs && \ ${MAKE} -f Makefile.inc1 _startup_libs && \ ${MAKE} -f Makefile.inc1 _prebuild_libs && \ ${MAKE} -f Makefile.inc1 _generic_libs # # static libgcc.a prerequisite for shared libc # _prereq_libs= gnu/lib/libssp/libssp_nonshared gnu/lib/libgcc lib/libcompiler_rt # These dependencies are not automatically generated: # # gnu/lib/csu, gnu/lib/libgcc, lib/csu and lib/libc must be built before # all shared libraries for ELF. # _startup_libs= gnu/lib/csu .if exists(${.CURDIR}/lib/csu/${MACHINE_ARCH}-elf) _startup_libs+= lib/csu/${MACHINE_ARCH}-elf .elif exists(${.CURDIR}/lib/csu/${MACHINE_ARCH}) _startup_libs+= lib/csu/${MACHINE_ARCH} .else _startup_libs+= lib/csu/${MACHINE_CPUARCH} .endif _startup_libs+= gnu/lib/libgcc _startup_libs+= lib/libcompiler_rt _startup_libs+= lib/libc _startup_libs+= lib/libc_nonshared .if ${MK_LIBCPLUSPLUS} != "no" _startup_libs+= lib/libcxxrt .endif gnu/lib/libgcc__L: lib/libc__L gnu/lib/libgcc__L: lib/libc_nonshared__L .if ${MK_LIBCPLUSPLUS} != "no" lib/libcxxrt__L: gnu/lib/libgcc__L .endif _prebuild_libs= ${_kerberos5_lib_libasn1} \ ${_kerberos5_lib_libhdb} \ ${_kerberos5_lib_libheimbase} \ ${_kerberos5_lib_libheimntlm} \ ${_kerberos5_lib_libheimsqlite} \ ${_kerberos5_lib_libheimipcc} \ ${_kerberos5_lib_libhx509} ${_kerberos5_lib_libkrb5} \ ${_kerberos5_lib_libroken} \ ${_kerberos5_lib_libwind} \ ${_lib_atf} \ lib/libbz2 ${_libcom_err} lib/libcrypt \ lib/libelf lib/libexpat \ + lib/libfigpar \ ${_lib_libgssapi} ${_lib_libipx} \ lib/libkiconv lib/libkvm lib/liblzma lib/libmd \ lib/ncurses/ncurses lib/ncurses/ncursesw \ lib/libopie lib/libpam ${_lib_libthr} \ lib/libradius lib/libsbuf lib/libtacplus \ ${_cddl_lib_libumem} ${_cddl_lib_libnvpair} \ ${_cddl_lib_libavl} \ ${_cddl_lib_libzfs_core} \ lib/libutil ${_lib_libypclnt} lib/libz lib/msun \ ${_secure_lib_libcrypto} ${_lib_libldns} \ - ${_secure_lib_libssh} ${_secure_lib_libssl} + ${_secure_lib_libssh} ${_secure_lib_libssl} \ + gnu/lib/libdialog .if ${MK_GNUCXX} != no _prebuild_libs+= gnu/lib/libstdc++ gnu/lib/libsupc++ gnu/lib/libstdc++__L: lib/msun__L .endif .if defined(WITH_ATF) || ${MK_TESTS} != "no" .if !defined(WITH_ATF) # Ensure that the ATF libraries will be built during make libraries, even # though they will have -DNO_TESTS MAKE+= -DWITH_ATF .endif _lib_atf= lib/atf .endif .if ${MK_LIBTHR} != "no" _lib_libthr= lib/libthr .endif .if ${MK_OFED} != "no" _ofed_lib= contrib/ofed/usr.lib/ .endif _generic_libs= ${_cddl_lib} gnu/lib ${_kerberos5_lib} lib ${_secure_lib} usr.bin/lex/lib ${_ofed_lib} .for _DIR in ${LOCAL_LIB_DIRS} .if exists(${.CURDIR}/${_DIR}/Makefile) _generic_libs+= ${_DIR} .endif .endfor lib/libopie__L lib/libtacplus__L: lib/libmd__L .if ${MK_CDDL} != "no" _cddl_lib_libumem= cddl/lib/libumem _cddl_lib_libnvpair= cddl/lib/libnvpair _cddl_lib_libavl= cddl/lib/libavl _cddl_lib_libzfs_core= cddl/lib/libzfs_core _cddl_lib= cddl/lib cddl/lib/libzfs_core__L: cddl/lib/libnvpair__L .endif .if ${MK_CRYPT} != "no" .if ${MK_OPENSSL} != "no" _secure_lib_libcrypto= secure/lib/libcrypto _secure_lib_libssl= secure/lib/libssl lib/libradius__L secure/lib/libssl__L: secure/lib/libcrypto__L .if ${MK_LDNS} != "no" _lib_libldns= lib/libldns lib/libldns__L: secure/lib/libcrypto__L .endif .if ${MK_OPENSSH} != "no" _secure_lib_libssh= secure/lib/libssh secure/lib/libssh__L: lib/libz__L secure/lib/libcrypto__L lib/libcrypt__L .if ${MK_LDNS} != "no" secure/lib/libssh__L: lib/libldns__L .endif .if ${MK_KERBEROS_SUPPORT} != "no" secure/lib/libssh__L: lib/libgssapi__L kerberos5/lib/libkrb5__L \ kerberos5/lib/libhx509__L kerberos5/lib/libasn1__L lib/libcom_err__L \ lib/libmd__L kerberos5/lib/libroken__L .endif .endif .endif _secure_lib= secure/lib .endif .if ${MK_KERBEROS} != "no" kerberos5/lib/libasn1__L: lib/libcom_err__L kerberos5/lib/libroken__L kerberos5/lib/libhdb__L: kerberos5/lib/libasn1__L lib/libcom_err__L \ kerberos5/lib/libkrb5__L kerberos5/lib/libroken__L \ kerberos5/lib/libwind__L kerberos5/lib/libheimsqlite__L kerberos5/lib/libheimntlm__L: secure/lib/libcrypto__L kerberos5/lib/libkrb5__L \ kerberos5/lib/libroken__L lib/libcom_err__L kerberos5/lib/libhx509__L: kerberos5/lib/libasn1__L lib/libcom_err__L \ secure/lib/libcrypto__L kerberos5/lib/libroken__L kerberos5/lib/libwind__L kerberos5/lib/libkrb5__L: kerberos5/lib/libasn1__L lib/libcom_err__L \ lib/libcrypt__L secure/lib/libcrypto__L kerberos5/lib/libhx509__L \ kerberos5/lib/libroken__L kerberos5/lib/libwind__L \ kerberos5/lib/libheimbase__L kerberos5/lib/libheimipcc__L kerberos5/lib/libroken__L: lib/libcrypt__L kerberos5/lib/libwind__L: kerberos5/lib/libroken__L lib/libcom_err__L kerberos5/lib/libheimbase__L: lib/libthr__L kerberos5/lib/libheimipcc__L: kerberos5/lib/libroken__L kerberos5/lib/libheimbase__L lib/libthr__L kerberos5/lib/libheimsqlite__L: lib/libthr__L .endif .if ${MK_GSSAPI} != "no" _lib_libgssapi= lib/libgssapi .endif .if ${MK_IPX} != "no" _lib_libipx= lib/libipx .endif .if ${MK_KERBEROS} != "no" _kerberos5_lib= kerberos5/lib _kerberos5_lib_libasn1= kerberos5/lib/libasn1 _kerberos5_lib_libhdb= kerberos5/lib/libhdb _kerberos5_lib_libheimbase= kerberos5/lib/libheimbase _kerberos5_lib_libkrb5= kerberos5/lib/libkrb5 _kerberos5_lib_libhx509= kerberos5/lib/libhx509 _kerberos5_lib_libroken= kerberos5/lib/libroken _kerberos5_lib_libheimntlm= kerberos5/lib/libheimntlm _kerberos5_lib_libheimsqlite= kerberos5/lib/libheimsqlite _kerberos5_lib_libheimipcc= kerberos5/lib/libheimipcc _kerberos5_lib_libwind= kerberos5/lib/libwind _libcom_err= lib/libcom_err .endif .if ${MK_NIS} != "no" _lib_libypclnt= lib/libypclnt .endif .if ${MK_OPENSSL} == "no" lib/libradius__L: lib/libmd__L .endif + +gnu/lib/libdialog__L: lib/msun__L lib/ncurses/ncursesw__L .for _lib in ${_prereq_libs} ${_lib}__PL: .PHONY .MAKE .if exists(${.CURDIR}/${_lib}) ${_+_}@${ECHODIR} "===> ${_lib} (obj,depend,all,install)"; \ cd ${.CURDIR}/${_lib} && \ ${MAKE} -DNO_TESTS DIRPRFX=${_lib}/ obj && \ ${MAKE} -DNO_TESTS DIRPRFX=${_lib}/ depend && \ ${MAKE} -DNO_TESTS -DNO_PROFILE -DNO_PIC \ DIRPRFX=${_lib}/ all && \ ${MAKE} -DNO_TESTS -DNO_PROFILE -DNO_PIC \ DIRPRFX=${_lib}/ install .endif .endfor .for _lib in ${_startup_libs} ${_prebuild_libs:Nlib/libpam} ${_generic_libs} ${_lib}__L: .PHONY .MAKE .if exists(${.CURDIR}/${_lib}) ${_+_}@${ECHODIR} "===> ${_lib} (obj,depend,all,install)"; \ cd ${.CURDIR}/${_lib} && \ ${MAKE} -DNO_TESTS DIRPRFX=${_lib}/ obj && \ ${MAKE} -DNO_TESTS DIRPRFX=${_lib}/ depend && \ ${MAKE} -DNO_TESTS DIRPRFX=${_lib}/ all && \ ${MAKE} -DNO_TESTS DIRPRFX=${_lib}/ install .endif .endfor # libpam is special: we need to build static PAM modules before # static PAM library, and dynamic PAM library before dynamic PAM # modules. lib/libpam__L: .PHONY .MAKE ${_+_}@${ECHODIR} "===> lib/libpam (obj,depend,all,install)"; \ cd ${.CURDIR}/lib/libpam && \ ${MAKE} -DNO_TESTS DIRPRFX=lib/libpam/ obj && \ ${MAKE} -DNO_TESTS DIRPRFX=lib/libpam/ depend && \ ${MAKE} -DNO_TESTS DIRPRFX=lib/libpam/ \ -D_NO_LIBPAM_SO_YET all && \ ${MAKE} -DNO_TESTS DIRPRFX=lib/libpam/ \ -D_NO_LIBPAM_SO_YET install _prereq_libs: ${_prereq_libs:S/$/__PL/} _startup_libs: ${_startup_libs:S/$/__L/} _prebuild_libs: ${_prebuild_libs:S/$/__L/} _generic_libs: ${_generic_libs:S/$/__L/} .for __target in all clean cleandepend cleandir depend includes obj .for entry in ${SUBDIR} ${entry}.${__target}__D: .PHONY .MAKE ${_+_}@set -e; if test -d ${.CURDIR}/${entry}.${MACHINE_ARCH}; then \ ${ECHODIR} "===> ${DIRPRFX}${entry}.${MACHINE_ARCH} (${__target})"; \ edir=${entry}.${MACHINE_ARCH}; \ cd ${.CURDIR}/$${edir}; \ else \ ${ECHODIR} "===> ${DIRPRFX}${entry} (${__target})"; \ edir=${entry}; \ cd ${.CURDIR}/$${edir}; \ fi; \ ${MAKE} ${__target} DIRPRFX=${DIRPRFX}$${edir}/ .endfor par-${__target}: ${SUBDIR:S/$/.${__target}__D/} .endfor .include .if make(check-old) || make(check-old-dirs) || \ make(check-old-files) || make(check-old-libs) || \ make(delete-old) || make(delete-old-dirs) || \ make(delete-old-files) || make(delete-old-libs) # # check for / delete old files section # .include "ObsoleteFiles.inc" OLD_LIBS_MESSAGE="Please be sure no application still uses those libraries, \ else you can not start such an application. Consult UPDATING for more \ information regarding how to cope with the removal/revision bump of a \ specific library." .if !defined(BATCH_DELETE_OLD_FILES) RM_I=-i .else RM_I=-v .endif delete-old-files: @echo ">>> Removing old files (only deletes safe to delete libs)" # Ask for every old file if the user really wants to remove it. # It's annoying, but better safe than sorry. # NB: We cannot pass the list of OLD_FILES as a parameter because the # argument list will get too long. Using .for/.endfor make "loops" will make # the Makefile parser segfault. @exec 3<&0; \ cd ${.CURDIR}; \ ${MAKE} -f ${.CURDIR}/Makefile.inc1 ${.MAKEFLAGS} ${.TARGET} \ -V OLD_FILES -V "OLD_FILES:Musr/share/*.gz:R" | xargs -n1 | \ while read file; do \ if [ -f "${DESTDIR}/$${file}" -o -L "${DESTDIR}/$${file}" ]; then \ chflags noschg "${DESTDIR}/$${file}" 2>/dev/null || true; \ rm ${RM_I} "${DESTDIR}/$${file}" <&3; \ fi; \ done # Remove catpages without corresponding manpages. @exec 3<&0; \ find ${DESTDIR}/usr/share/man/cat* ! -type d | \ sed -ep -e's:${DESTDIR}/usr/share/man/cat:${DESTDIR}/usr/share/man/man:' | \ while read catpage; do \ read manpage; \ if [ ! -e "$${manpage}" ]; then \ rm ${RM_I} $${catpage} <&3; \ fi; \ done @echo ">>> Old files removed" check-old-files: @echo ">>> Checking for old files" @cd ${.CURDIR}; \ ${MAKE} -f ${.CURDIR}/Makefile.inc1 ${.MAKEFLAGS} ${.TARGET} \ -V OLD_FILES -V "OLD_FILES:Musr/share/*.gz:R" | xargs -n1 | \ while read file; do \ if [ -f "${DESTDIR}/$${file}" -o -L "${DESTDIR}/$${file}" ]; then \ echo "${DESTDIR}/$${file}"; \ fi; \ done # Check for catpages without corresponding manpages. @find ${DESTDIR}/usr/share/man/cat* ! -type d | \ sed -ep -e's:${DESTDIR}/usr/share/man/cat:${DESTDIR}/usr/share/man/man:' | \ while read catpage; do \ read manpage; \ if [ ! -e "$${manpage}" ]; then \ echo $${catpage}; \ fi; \ done delete-old-libs: @echo ">>> Removing old libraries" @echo "${OLD_LIBS_MESSAGE}" | fmt @exec 3<&0; \ cd ${.CURDIR}; \ ${MAKE} -f ${.CURDIR}/Makefile.inc1 ${.MAKEFLAGS} ${.TARGET} \ -V OLD_LIBS | xargs -n1 | \ while read file; do \ if [ -f "${DESTDIR}/$${file}" -o -L "${DESTDIR}/$${file}" ]; then \ chflags noschg "${DESTDIR}/$${file}" 2>/dev/null || true; \ rm ${RM_I} "${DESTDIR}/$${file}" <&3; \ fi; \ for ext in debug symbols; do \ if ! [ -e "${DESTDIR}/$${file}" ] && [ -f \ "${DESTDIR}${DEBUGDIR}/$${file}.$${ext}" ]; then \ rm ${RM_I} "${DESTDIR}${DEBUGDIR}/$${file}.$${ext}" \ <&3; \ fi; \ done; \ done @echo ">>> Old libraries removed" check-old-libs: @echo ">>> Checking for old libraries" @cd ${.CURDIR}; \ ${MAKE} -f ${.CURDIR}/Makefile.inc1 ${.MAKEFLAGS} ${.TARGET} \ -V OLD_LIBS | xargs -n1 | \ while read file; do \ if [ -f "${DESTDIR}/$${file}" -o -L "${DESTDIR}/$${file}" ]; then \ echo "${DESTDIR}/$${file}"; \ fi; \ for ext in debug symbols; do \ if [ -f "${DESTDIR}${DEBUGDIR}/$${file}.$${ext}" ]; then \ echo "${DESTDIR}${DEBUGDIR}/$${file}.$${ext}"; \ fi; \ done; \ done delete-old-dirs: @echo ">>> Removing old directories" @cd ${.CURDIR}; \ ${MAKE} -f ${.CURDIR}/Makefile.inc1 ${.MAKEFLAGS} ${.TARGET} \ -V OLD_DIRS | xargs -n1 | sort -r | \ while read dir; do \ if [ -d "${DESTDIR}/$${dir}" ]; then \ rmdir -v "${DESTDIR}/$${dir}" || true; \ elif [ -L "${DESTDIR}/$${dir}" ]; then \ echo "${DESTDIR}/$${dir} is a link, please remove everything manually."; \ fi; \ done @echo ">>> Old directories removed" check-old-dirs: @echo ">>> Checking for old directories" @cd ${.CURDIR}; \ ${MAKE} -f ${.CURDIR}/Makefile.inc1 ${.MAKEFLAGS} ${.TARGET} \ -V OLD_DIRS | xargs -n1 | \ while read dir; do \ if [ -d "${DESTDIR}/$${dir}" ]; then \ echo "${DESTDIR}/$${dir}"; \ elif [ -L "${DESTDIR}/$${dir}" ]; then \ echo "${DESTDIR}/$${dir} is a link, please remove everything manually."; \ fi; \ done delete-old: delete-old-files delete-old-dirs @echo "To remove old libraries run '${MAKE} delete-old-libs'." check-old: check-old-files check-old-libs check-old-dirs @echo "To remove old files and directories run '${MAKE} delete-old'." @echo "To remove old libraries run '${MAKE} delete-old-libs'." .endif # # showconfig - show build configuration. # showconfig: @${MAKE} -n -f bsd.own.mk -V dummy -dg1 2>&1 | grep ^MK_ | sort .if !empty(KRNLOBJDIR) && !empty(KERNCONF) DTBOUTPUTPATH= ${KRNLOBJDIR}/${KERNCONF}/ .if !defined(FDT_DTS_FILE) || empty(FDT_DTS_FILE) .if exists(${KERNCONFDIR}/${KERNCONF}) FDT_DTS_FILE!= awk 'BEGIN {FS="="} /^makeoptions[[:space:]]+FDT_DTS_FILE/ {print $$2}' \ '${KERNCONFDIR}/${KERNCONF}' ; echo .endif .endif .endif .if !defined(DTBOUTPUTPATH) || !exists(${DTBOUTPUTPATH}) DTBOUTPUTPATH= ${.CURDIR} .endif # # Build 'standalone' Device Tree Blob # builddtb: @PATH=${TMPPATH} MACHINE=${TARGET} \ ${.CURDIR}/sys/tools/fdt/make_dtb.sh ${.CURDIR}/sys \ "${FDT_DTS_FILE}" ${DTBOUTPUTPATH} ############### .if defined(XDEV) && defined(XDEV_ARCH) .if ${XDEV} == ${MACHINE} && ${XDEV_ARCH} == ${MACHINE_ARCH} XDEV_CPUTYPE?=${CPUTYPE} .else XDEV_CPUTYPE?=${TARGET_CPUTYPE} .endif NOFUN=-DNO_FSCHG -DWITHOUT_HTML -DWITHOUT_INFO -DNO_LINT \ -DWITHOUT_MAN -DWITHOUT_NLS -DNO_PROFILE \ -DWITHOUT_KERBEROS -DWITHOUT_RESCUE -DNO_TESTS -DNO_WARNS \ TARGET=${XDEV} TARGET_ARCH=${XDEV_ARCH} \ CPUTYPE=${XDEV_CPUTYPE} XDDIR=${XDEV_ARCH}-freebsd XDTP?=/usr/${XDDIR} .if ${XDTP:N/*} .error XDTP variable should be an absolute path .endif CDBENV=MAKEOBJDIRPREFIX=${MAKEOBJDIRPREFIX}/${XDDIR} \ INSTALL="sh ${.CURDIR}/tools/install.sh" CDENV= ${CDBENV} \ _SHLIBDIRPREFIX=${XDDESTDIR} \ TOOLS_PREFIX=${XDTP} CD2CFLAGS=-isystem ${XDDESTDIR}/usr/include -L${XDDESTDIR}/usr/lib \ --sysroot=${XDDESTDIR}/ -B${XDDESTDIR}/usr/libexec \ -B${XDDESTDIR}/usr/bin -B${XDDESTDIR}/usr/lib CD2ENV=${CDENV} CC="${CC} ${CD2CFLAGS}" CXX="${CXX} ${CD2CFLAGS}" \ CPP="${CPP} ${CD2CFLAGS}" \ MACHINE=${XDEV} MACHINE_ARCH=${XDEV_ARCH} CDTMP= ${MAKEOBJDIRPREFIX}/${XDDIR}/${.CURDIR}/tmp CDMAKE=${CDENV} PATH=${CDTMP}/usr/bin:${PATH} ${MAKE} ${NOFUN} CD2MAKE=${CD2ENV} PATH=${CDTMP}/usr/bin:${XDDESTDIR}/usr/bin:${PATH} ${MAKE} ${NOFUN} XDDESTDIR=${DESTDIR}/${XDTP} .if !defined(OSREL) OSREL!= uname -r | sed -e 's/[-(].*//' .endif .ORDER: xdev-build xdev-install xdev: xdev-build xdev-install .ORDER: _xb-worldtmp _xb-bootstrap-tools _xb-build-tools _xb-cross-tools xdev-build: _xb-worldtmp _xb-bootstrap-tools _xb-build-tools _xb-cross-tools _xb-worldtmp: mkdir -p ${CDTMP}/usr mtree -deU -f ${.CURDIR}/etc/mtree/BSD.usr.dist \ -p ${CDTMP}/usr >/dev/null _xb-bootstrap-tools: .for _tool in \ ${_clang_tblgen} ${_+_}@${ECHODIR} "===> ${_tool} (obj,depend,all,install)"; \ cd ${.CURDIR}/${_tool} && \ ${CDMAKE} DIRPRFX=${_tool}/ obj && \ ${CDMAKE} DIRPRFX=${_tool}/ depend && \ ${CDMAKE} DIRPRFX=${_tool}/ all && \ ${CDMAKE} DIRPRFX=${_tool}/ DESTDIR=${CDTMP} install .endfor _xb-build-tools: ${_+_}@cd ${.CURDIR}; \ ${CDBENV} ${MAKE} -f Makefile.inc1 ${NOFUN} build-tools _xb-cross-tools: .for _tool in \ ${_binutils} \ usr.bin/ar \ ${_clang_libs} \ ${_clang} \ ${_cc} ${_+_}@${ECHODIR} "===> xdev ${_tool} (obj,depend,all)"; \ cd ${.CURDIR}/${_tool} && \ ${CDMAKE} DIRPRFX=${_tool}/ obj && \ ${CDMAKE} DIRPRFX=${_tool}/ depend && \ ${CDMAKE} DIRPRFX=${_tool}/ all .endfor _xi-mtree: ${_+_}@${ECHODIR} "mtree populating ${XDDESTDIR}" mkdir -p ${XDDESTDIR} mtree -deU -f ${.CURDIR}/etc/mtree/BSD.root.dist \ -p ${XDDESTDIR} >/dev/null mtree -deU -f ${.CURDIR}/etc/mtree/BSD.usr.dist \ -p ${XDDESTDIR}/usr >/dev/null mtree -deU -f ${.CURDIR}/etc/mtree/BSD.include.dist \ -p ${XDDESTDIR}/usr/include >/dev/null .if ${MK_TESTS} != "no" mtree -deU -f ${.CURDIR}/etc/mtree/BSD.tests.dist \ -p ${XDDESTDIR}/usr >/dev/null .endif .ORDER: xdev-build _xi-mtree _xi-cross-tools _xi-includes _xi-libraries _xi-links xdev-install: xdev-build _xi-mtree _xi-cross-tools _xi-includes _xi-libraries _xi-links _xi-cross-tools: @echo "_xi-cross-tools" .for _tool in \ ${_binutils} \ usr.bin/ar \ ${_clang_libs} \ ${_clang} \ ${_cc} ${_+_}@${ECHODIR} "===> xdev ${_tool} (install)"; \ cd ${.CURDIR}/${_tool}; \ ${CDMAKE} DIRPRFX=${_tool}/ install DESTDIR=${XDDESTDIR} .endfor _xi-includes: ${_+_}cd ${.CURDIR}; ${CD2MAKE} -f Makefile.inc1 par-includes \ DESTDIR=${XDDESTDIR} _xi-libraries: ${_+_}cd ${.CURDIR}; ${CD2MAKE} -f Makefile.inc1 libraries \ DESTDIR=${XDDESTDIR} _xi-links: ${_+_}cd ${XDDESTDIR}/usr/bin; \ mkdir -p ../../../../usr/bin; \ for i in *; do \ ln -sf ../../${XDTP}/usr/bin/$$i \ ../../../../usr/bin/${XDDIR}-$$i; \ ln -sf ../../${XDTP}/usr/bin/$$i \ ../../../../usr/bin/${XDDIR}${OSREL}-$$i; \ done .else xdev xdev-build xdev-install: @echo "*** Error: Both XDEV and XDEV_ARCH must be defined for \"${.TARGET}\" target" .endif Index: stable/10/gnu/lib/libdialog/Makefile =================================================================== --- stable/10/gnu/lib/libdialog/Makefile (revision 275039) +++ stable/10/gnu/lib/libdialog/Makefile (revision 275040) @@ -1,20 +1,23 @@ # $FreeBSD$ DIALOG= ${.CURDIR}/../../../contrib/dialog LIB= dialog SHLIB_MAJOR= 8 SRCS= argv.c arrows.c buildlist.c buttons.c calendar.c checklist.c \ columns.c dlg_keys.c editbox.c fselect.c formbox.c guage.c \ help.c inputbox.c inputstr.c menubox.c mixedform.c \ mixedgauge.c mouse.c mousewget.c msgbox.c pause.c prgbox.c \ progressbox.c rangebox.c rc.c tailbox.c textbox.c timebox.c \ trace.c treeview.c ui_getc.c util.c version.c yesno.c INCS= dialog.h dlg_colors.h dlg_config.h dlg_keys.h MAN= dialog.3 +DPADD= ${LIBNCURSESW} ${LIBM} +LDADD= -lncursesw -lm + CFLAGS+= -I${.CURDIR} -I${DIALOG} -D_XOPEN_SOURCE_EXTENDED -DGCC_UNUSED=__unused .PATH: ${DIALOG} WARNS?= 1 .include Index: stable/10/lib/Makefile =================================================================== --- stable/10/lib/Makefile (revision 275039) +++ stable/10/lib/Makefile (revision 275040) @@ -1,291 +1,293 @@ # @(#)Makefile 8.1 (Berkeley) 6/4/93 # $FreeBSD$ .include # The SUBDIR_ORDERED list is a small set of libraries which are used by many # of the other libraries. These are built first with a .WAIT between them # and the main list to avoid needing a SUBDIR_DEPEND line on every library # naming just these few items. SUBDIR_ORDERED= ${_csu} \ .WAIT \ libc \ libc_nonshared \ libcompiler_rt \ ${_libcplusplus} \ ${_libcxxrt} \ libelf \ msun # The main list; please keep these sorted alphabetically. SUBDIR= ${SUBDIR_ORDERED} \ .WAIT \ libalias \ libarchive \ ${_libatm} \ libauditd \ libbegemot \ libblocksruntime \ ${_libbluetooth} \ ${_libbsnmp} \ libbsm \ libbz2 \ libcalendar \ libcam \ ${_libcom_err} \ libcompat \ libcrypt \ libdevinfo \ libdevstat \ + libdpv \ libdwarf \ libedit \ ${_libefi} \ libexecinfo \ libexpat \ libfetch \ + libfigpar \ libgeom \ ${_libgpib} \ ${_libgssapi} \ ${_librpcsec_gss} \ ${_libiconv_modules} \ libipsec \ ${_libipx} \ libjail \ libkiconv \ libkvm \ ${_libldns} \ liblzma \ libmagic \ libmandoc \ libmemstat \ libmd \ ${_libmilter} \ ${_libmp} \ ${_libnandfs} \ libnetbsd \ ${_libnetgraph} \ ${_libngatm} \ libopie \ libpam \ libpcap \ ${_libpmc} \ ${_libproc} \ libprocstat \ libradius \ librpcsvc \ librt \ ${_librtld_db} \ libsbuf \ ${_libsdp} \ ${_libsm} \ ${_libsmb} \ ${_libsmdb} \ ${_libsmutil} \ libstand \ libstdbuf \ libstdthreads \ libtacplus \ ${_libtelnet} \ ${_libthr} \ libthread_db \ libucl \ libufs \ libugidfw \ libulog \ ${_libunbound} \ ${_libusbhid} \ ${_libusb} \ libutil \ ${_libvgl} \ ${_libvmmapi} \ libwrap \ liby \ ${_libypclnt} \ libyaml \ libz \ ncurses \ ${_atf} \ ${_clang} \ ${_tests} # Inter-library dependencies. When the makefile for a library contains LDADD # libraries, those libraries should be listed as build order dependencies here. SUBDIR_DEPEND_libarchive= libz libbz2 libexpat liblzma libmd SUBDIR_DEPEND_libatm= libmd SUBDIR_DEPEND_libauditdm= libbsm SUBDIR_DEPEND_libbsnmp= ${_libnetgraph} SUBDIR_DEPEND_libc++= libcxxrt SUBDIR_DEPEND_libc= libcompiler_rt SUBDIR_DEPEND_libcam= libsbuf SUBDIR_DEPEND_libdevstat= libkvm -SUBDIR_DEPEND_libdiaglog= ncurses +SUBDIR_DEPEND_libdpv= libfigpar ncurses libutil SUBDIR_DEPEND_libedit= ncurses SUBDIR_DEPEND_libg++= msun SUBDIR_DEPEND_libgeom= libexpat libsbuf SUBDIR_DEPEND_liblibrpcsec_gss= libgssapi SUBDIR_DEPEND_libmagic= libz SUBDIR_DEPEND_libmemstat= libkvm SUBDIR_DEPEND_libopie= libmd SUBDIR_DEPEND_libpam= libcrypt libopie libradius librpcsvc libtacplus libutil ${_libypclnt} ${_libcom_err} SUBDIR_DEPEND_libpjdlog= libutil SUBDIR_DEPEND_libprocstat= libkvm libutil SUBDIR_DEPEND_libradius= libmd SUBDIR_DEPEND_libreadline= ncurses SUBDIR_DEPEND_libsmb= libkiconv SUBDIR_DEPEND_libstdc++= msun SUBDIR_DEPEND_libtacplus= libmd SUBDIR_DEPEND_libulog= libmd SUBDIR_DEPEND_libunbound= ${_libldns} .if exists(${.CURDIR}/csu/${MACHINE_ARCH}-elf) _csu=csu/${MACHINE_ARCH}-elf .elif exists(${.CURDIR}/csu/${MACHINE_ARCH}) _csu=csu/${MACHINE_ARCH} .elif exists(${.CURDIR}/csu/${MACHINE_CPUARCH}/Makefile) _csu=csu/${MACHINE_CPUARCH} .else _csu=csu .endif # NB: keep these sorted by MK_* knobs .if ${MK_ATM} != "no" _libngatm= libngatm .endif .if ${MK_BLUETOOTH} != "no" _libbluetooth= libbluetooth _libsdp= libsdp .endif .if ${MK_BSNMP} != "no" _libbsnmp= libbsnmp .endif .if ${MK_CLANG} != "no" && !defined(COMPAT_32BIT) _clang= clang .endif .if ${MK_GPIB} != "no" _libgpib= libgpib .endif .if ${MK_GSSAPI} != "no" _libgssapi= libgssapi _librpcsec_gss= librpcsec_gss .endif .if ${MK_ICONV} != "no" _libiconv_modules= libiconv_modules .endif .if ${MK_KERBEROS_SUPPORT} != "no" _libcom_err= libcom_err .endif .if ${MK_IPX} != "no" _libipx= libipx .endif .if ${MK_LDNS} != "no" _libldns= libldns .endif .if ${MK_LIBCPLUSPLUS} != "no" _libcxxrt= libcxxrt _libcplusplus= libc++ .endif .if ${MK_LIBTHR} != "no" _libthr= libthr .endif .if ${MK_NAND} != "no" _libnandfs= libnandfs .endif .if ${MK_NETGRAPH} != "no" _libnetgraph= libnetgraph .endif .if ${MK_NIS} != "no" _libypclnt= libypclnt .endif .if ${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "amd64" _libsmb= libsmb _libvgl= libvgl _libproc= libproc _librtld_db= librtld_db .endif .if ${MACHINE_CPUARCH} == "amd64" _libvmmapi= libvmmapi .endif .if ${MACHINE_CPUARCH} == "ia64" _libefi= libefi _libsmb= libsmb .endif .if ${MACHINE_CPUARCH} == "mips" _libproc= libproc _librtld_db= librtld_db .endif .if ${MACHINE_CPUARCH} == "powerpc" _libproc= libproc _librtld_db= librtld_db _libsmb= libsmb .endif .if ${MACHINE_CPUARCH} == "sparc64" _libsmb= libsmb .endif .if ${MK_OPENSSL} != "no" _libmp= libmp .endif .if ${MK_PMC} != "no" _libpmc= libpmc .endif .if ${MK_SENDMAIL} != "no" _libmilter= libmilter _libsm= libsm _libsmdb= libsmdb _libsmutil= libsmutil .endif .if ${MK_TELNET} != "no" _libtelnet= libtelnet .endif .if ${MK_TESTS} != "no" _atf= atf _tests= tests .endif .if ${MK_UNBOUND} != "no" _libunbound= libunbound .endif .if ${MK_USB} != "no" _libusbhid= libusbhid _libusb= libusb .endif .if !defined(LIBRARIES_ONLY) afterinstall: ${INSTALL_SYMLINK} ../include ${DESTDIR}/usr/lib/include .endif .if !make(install) SUBDIR_PARALLEL= .endif .include Index: stable/10/lib/libdpv/Makefile =================================================================== --- stable/10/lib/libdpv/Makefile (nonexistent) +++ stable/10/lib/libdpv/Makefile (revision 275040) @@ -0,0 +1,18 @@ +# $FreeBSD$ + +LIB= dpv +SHLIB_MAJOR= 1 +INCS= dpv.h +MAN= dpv.3 +MLINKS= dpv.3 dpv_free.3 + +DPADD= ${LIBDIALOG} ${LIBFIGPAR} ${LIBNCURSESW} ${LIBUTIL} +LDADD= -ldialog -lfigpar -lncursesw -lutil + +SRCS= dialog_util.c dialogrc.c dprompt.c dpv.c status.c util.c + +CFLAGS+= -I${.CURDIR} + +WARNS?= 6 + +.include Property changes on: stable/10/lib/libdpv/Makefile ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: stable/10/lib/libdpv/dialog_util.c =================================================================== --- stable/10/lib/libdpv/dialog_util.c (nonexistent) +++ stable/10/lib/libdpv/dialog_util.c (revision 275040) @@ -0,0 +1,633 @@ +/*- + * Copyright (c) 2013-2014 Devin Teske + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dialog_util.h" +#include "dpv.h" +#include "dpv_private.h" + +extern char **environ; + +#define TTY_DEFAULT_ROWS 24 +#define TTY_DEFAULT_COLS 80 + +/* [X]dialog(1) characteristics */ +uint8_t dialog_test = 0; +uint8_t use_dialog = 0; +uint8_t use_libdialog = 1; +uint8_t use_xdialog = 0; +uint8_t use_color = 1; +char dialog[PATH_MAX] = DIALOG; + +/* [X]dialog(1) functionality */ +char *title = NULL; +char *backtitle = NULL; +int dheight = 0; +int dwidth = 0; +static char *dargv[64] = { NULL }; + +/* TTY/Screen characteristics */ +static struct winsize *maxsize = NULL; + +/* Function prototypes */ +static void tty_maxsize_update(void); +static void x11_maxsize_update(void); + +/* + * Update row/column fields of `maxsize' global (used by dialog_maxrows() and + * dialog_maxcols()). If the `maxsize' pointer is NULL, it will be initialized. + * The `ws_row' and `ws_col' fields of `maxsize' are updated to hold current + * maximum height and width (respectively) for a dialog(1) widget based on the + * active TTY size. + * + * This function is called automatically by dialog_maxrows/cols() to reflect + * changes in terminal size in-between calls. + */ +static void +tty_maxsize_update(void) +{ + int fd = STDIN_FILENO; + struct termios t; + + if (maxsize == NULL) { + if ((maxsize = malloc(sizeof(struct winsize))) == NULL) + errx(EXIT_FAILURE, "Out of memory?!"); + memset((void *)maxsize, '\0', sizeof(struct winsize)); + } + + if (!isatty(fd)) + fd = open("/dev/tty", O_RDONLY); + if ((tcgetattr(fd, &t) < 0) || (ioctl(fd, TIOCGWINSZ, maxsize) < 0)) { + maxsize->ws_row = TTY_DEFAULT_ROWS; + maxsize->ws_col = TTY_DEFAULT_COLS; + } +} + +/* + * Update row/column fields of `maxsize' global (used by dialog_maxrows() and + * dialog_maxcols()). If the `maxsize' pointer is NULL, it will be initialized. + * The `ws_row' and `ws_col' fields of `maxsize' are updated to hold current + * maximum height and width (respectively) for an Xdialog(1) widget based on + * the active video resolution of the X11 environment. + * + * This function is called automatically by dialog_maxrows/cols() to initialize + * `maxsize'. Since video resolution changes are less common and more obtrusive + * than changes to terminal size, the dialog_maxrows/cols() functions only call + * this function when `maxsize' is set to NULL. + */ +static void +x11_maxsize_update(void) +{ + FILE *f = NULL; + char *cols; + char *cp; + char *rows; + char cmdbuf[LINE_MAX]; + char rbuf[LINE_MAX]; + + if (maxsize == NULL) { + if ((maxsize = malloc(sizeof(struct winsize))) == NULL) + errx(EXIT_FAILURE, "Out of memory?!"); + memset((void *)maxsize, '\0', sizeof(struct winsize)); + } + + /* Assemble the command necessary to get X11 sizes */ + snprintf(cmdbuf, LINE_MAX, "%s --print-maxsize 2>&1", dialog); + + fflush(STDIN_FILENO); /* prevent popen(3) from seeking on stdin */ + + if ((f = popen(cmdbuf, "r")) == NULL) { + if (debug) + warnx("WARNING! Command `%s' failed", cmdbuf); + return; + } + + /* Read in the line returned from Xdialog(1) */ + if ((fgets(rbuf, LINE_MAX, f) == NULL) || (pclose(f) < 0)) + return; + + /* Check for X11-related errors */ + if (strncmp(rbuf, "Xdialog: Error", 14) == 0) + return; + + /* Parse expected output: MaxSize: YY, XXX */ + if ((rows = strchr(rbuf, ' ')) == NULL) + return; + if ((cols = strchr(rows, ',')) != NULL) { + /* strtonum(3) doesn't like trailing junk */ + *(cols++) = '\0'; + if ((cp = strchr(cols, '\n')) != NULL) + *cp = '\0'; + } + + /* Convert to unsigned short */ + maxsize->ws_row = (unsigned short)strtonum( + rows, 0, USHRT_MAX, (const char **)NULL); + maxsize->ws_col = (unsigned short)strtonum( + cols, 0, USHRT_MAX, (const char **)NULL); +} + +/* + * Return the current maximum height (rows) for an [X]dialog(1) widget. + */ +int +dialog_maxrows(void) +{ + + if (use_xdialog && maxsize == NULL) + x11_maxsize_update(); /* initialize maxsize for GUI */ + else if (!use_xdialog) + tty_maxsize_update(); /* update maxsize for TTY */ + return (maxsize->ws_row); +} + +/* + * Return the current maximum width (cols) for an [X]dialog(1) widget. + */ +int +dialog_maxcols(void) +{ + + if (use_xdialog && maxsize == NULL) + x11_maxsize_update(); /* initialize maxsize for GUI */ + else if (!use_xdialog) + tty_maxsize_update(); /* update maxsize for TTY */ + + if (use_dialog || use_libdialog) { + if (use_shadow) + return (maxsize->ws_col - 2); + else + return (maxsize->ws_col); + } else + return (maxsize->ws_col); +} + +/* + * Return the current maximum width (cols) for the terminal. + */ +int +tty_maxcols(void) +{ + + if (use_xdialog && maxsize == NULL) + x11_maxsize_update(); /* initialize maxsize for GUI */ + else if (!use_xdialog) + tty_maxsize_update(); /* update maxsize for TTY */ + + return (maxsize->ws_col); +} + +/* + * Spawn an [X]dialog(1) `--gauge' box with a `--prompt' value of init_prompt. + * Writes the resulting process ID to the pid_t pointed at by `pid'. Returns a + * file descriptor (int) suitable for writing data to the [X]dialog(1) instance + * (data written to the file descriptor is seen as standard-in by the spawned + * [X]dialog(1) process). + */ +int +dialog_spawn_gauge(char *init_prompt, pid_t *pid) +{ + char dummy_init[2] = ""; + char *cp; + int height; + int width; + int error; + posix_spawn_file_actions_t action; +#if DIALOG_SPAWN_DEBUG + unsigned int i; +#endif + unsigned int n = 0; + int stdin_pipe[2] = { -1, -1 }; + + /* Override `dialog' with a path from ENV_DIALOG if provided */ + if ((cp = getenv(ENV_DIALOG)) != NULL) + snprintf(dialog, PATH_MAX, "%s", cp); + + /* For Xdialog(1), set ENV_XDIALOG_HIGH_DIALOG_COMPAT */ + setenv(ENV_XDIALOG_HIGH_DIALOG_COMPAT, "1", 1); + + /* Constrain the height/width */ + height = dialog_maxrows(); + if (backtitle != NULL) + height -= use_shadow ? 5 : 4; + if (dheight < height) + height = dheight; + width = dialog_maxcols(); + if (dwidth < width) + width = dwidth; + + /* Populate argument array */ + dargv[n++] = dialog; + if (title != NULL) { + if ((dargv[n] = malloc(8)) == NULL) + errx(EXIT_FAILURE, "Out of memory?!"); + sprintf(dargv[n++], "--title"); + dargv[n++] = title; + } + if (backtitle != NULL) { + if ((dargv[n] = malloc(12)) == NULL) + errx(EXIT_FAILURE, "Out of memory?!"); + sprintf(dargv[n++], "--backtitle"); + dargv[n++] = backtitle; + } + if (use_color) { + if ((dargv[n] = malloc(11)) == NULL) + errx(EXIT_FAILURE, "Out of memory?!"); + sprintf(dargv[n++], "--colors"); + } + if (use_xdialog) { + if ((dargv[n] = malloc(7)) == NULL) + errx(EXIT_FAILURE, "Out of memory?!"); + sprintf(dargv[n++], "--left"); + + /* + * NOTE: Xdialog(1)'s `--wrap' appears to be broken for the + * `--gauge' widget prompt-updates. Add it anyway (in-case it + * gets fixed in some later release). + */ + if ((dargv[n] = malloc(7)) == NULL) + errx(EXIT_FAILURE, "Out of memory?!"); + sprintf(dargv[n++], "--wrap"); + } + if ((dargv[n] = malloc(8)) == NULL) + errx(EXIT_FAILURE, "Out of memory?!"); + sprintf(dargv[n++], "--gauge"); + dargv[n++] = use_xdialog ? dummy_init : init_prompt; + if ((dargv[n] = malloc(40)) == NULL) + errx(EXIT_FAILURE, "Out of memory?!"); + snprintf(dargv[n++], 40, "%u", height); + if ((dargv[n] = malloc(40)) == NULL) + errx(EXIT_FAILURE, "Out of memory?!"); + snprintf(dargv[n++], 40, "%u", width); + dargv[n] = NULL; + + /* Open a pipe(2) to communicate with [X]dialog(1) */ + if (pipe(stdin_pipe) < 0) + err(EXIT_FAILURE, "%s: pipe(2)", __func__); + + /* Fork [X]dialog(1) process */ +#if DIALOG_SPAWN_DEBUG + fprintf(stderr, "%s: spawning `", __func__); + for (i = 0; i < n; i++) { + if (i == 0) + fprintf(stderr, "%s", dargv[i]); + else if (*dargv[i] == '-' && *(dargv[i] + 1) == '-') + fprintf(stderr, " %s", dargv[i]); + else + fprintf(stderr, " \"%s\"", dargv[i]); + } + fprintf(stderr, "'\n"); +#endif + posix_spawn_file_actions_init(&action); + posix_spawn_file_actions_adddup2(&action, stdin_pipe[0], STDIN_FILENO); + posix_spawn_file_actions_addclose(&action, stdin_pipe[1]); + error = posix_spawnp(pid, dialog, &action, + (const posix_spawnattr_t *)NULL, dargv, environ); + if (error != 0) + err(EXIT_FAILURE, "%s: posix_spawnp(3)", __func__); + + /* NB: Do not free(3) *dargv[], else SIGSEGV */ + + return (stdin_pipe[1]); +} + +/* + * Returns the number of lines in buffer pointed to by `prompt'. Takes both + * newlines and escaped-newlines into account. + */ +unsigned int +dialog_prompt_numlines(const char *prompt, uint8_t nlstate) +{ + uint8_t nls = nlstate; /* See dialog_prompt_nlstate() */ + const char *cp = prompt; + unsigned int nlines = 1; + + if (prompt == NULL || *prompt == '\0') + return (0); + + while (*cp != '\0') { + if (use_dialog) { + if (strncmp(cp, "\\n", 2) == 0) { + cp++; + nlines++; + nls = TRUE; /* See declaration comment */ + } else if (*cp == '\n') { + if (!nls) + nlines++; + nls = FALSE; /* See declaration comment */ + } + } else if (use_libdialog) { + if (*cp == '\n') + nlines++; + } else if (strncmp(cp, "\\n", 2) == 0) { + cp++; + nlines++; + } + cp++; + } + + return (nlines); +} + +/* + * Returns the length in bytes of the longest line in buffer pointed to by + * `prompt'. Takes newlines and escaped newlines into account. Also discounts + * dialog(1) color escape codes if enabled (via `use_color' global). + */ +unsigned int +dialog_prompt_longestline(const char *prompt, uint8_t nlstate) +{ + uint8_t backslash = 0; + uint8_t nls = nlstate; /* See dialog_prompt_nlstate() */ + const char *p = prompt; + int longest = 0; + int n = 0; + + /* `prompt' parameter is required */ + if (prompt == NULL) + return (0); + if (*prompt == '\0') + return (0); /* shortcut */ + + /* Loop until the end of the string */ + while (*p != '\0') { + /* dialog(1) and dialog(3) will render literal newlines */ + if (use_dialog || use_libdialog) { + if (*p == '\n') { + if (!use_libdialog && nls) + n++; + else { + if (n > longest) + longest = n; + n = 0; + } + nls = FALSE; /* See declaration comment */ + p++; + continue; + } + } + + /* Check for backslash character */ + if (*p == '\\') { + /* If second backslash, count as a single-char */ + if ((backslash ^= 1) == 0) + n++; + } else if (backslash) { + if (*p == 'n' && !use_libdialog) { /* new line */ + /* NB: dialog(3) ignores escaped newlines */ + nls = TRUE; /* See declaration comment */ + if (n > longest) + longest = n; + n = 0; + } else if (use_color && *p == 'Z') { + if (*++p != '\0') + p++; + backslash = 0; + continue; + } else /* [X]dialog(1)/dialog(3) only expand those */ + n += 2; + + backslash = 0; + } else + n++; + p++; + } + if (n > longest) + longest = n; + + return (longest); +} + +/* + * Returns a pointer to the last line in buffer pointed to by `prompt'. Takes + * both newlines (if using dialog(1) versus Xdialog(1)) and escaped newlines + * into account. If no newlines (escaped or otherwise) appear in the buffer, + * `prompt' is returned. If passed a NULL pointer, returns NULL. + */ +char * +dialog_prompt_lastline(char *prompt, uint8_t nlstate) +{ + uint8_t nls = nlstate; /* See dialog_prompt_nlstate() */ + char *lastline; + char *p; + + if (prompt == NULL) + return (NULL); + if (*prompt == '\0') + return (prompt); /* shortcut */ + + lastline = p = prompt; + while (*p != '\0') { + /* dialog(1) and dialog(3) will render literal newlines */ + if (use_dialog || use_libdialog) { + if (*p == '\n') { + if (use_libdialog || !nls) + lastline = p + 1; + nls = FALSE; /* See declaration comment */ + } + } + /* dialog(3) does not expand escaped newlines */ + if (use_libdialog) { + p++; + continue; + } + if (*p == '\\' && *(p + 1) != '\0' && *(++p) == 'n') { + nls = TRUE; /* See declaration comment */ + lastline = p + 1; + } + p++; + } + + return (lastline); +} + +/* + * Returns the number of extra lines generated by wrapping the text in buffer + * pointed to by `prompt' within `ncols' columns (for prompts, this should be + * dwidth - 4). Also discounts dialog(1) color escape codes if enabled (via + * `use_color' global). + */ +int +dialog_prompt_wrappedlines(char *prompt, int ncols, uint8_t nlstate) +{ + uint8_t backslash = 0; + uint8_t nls = nlstate; /* See dialog_prompt_nlstate() */ + char *cp; + char *p = prompt; + int n = 0; + int wlines = 0; + + /* `prompt' parameter is required */ + if (p == NULL) + return (0); + if (*p == '\0') + return (0); /* shortcut */ + + /* Loop until the end of the string */ + while (*p != '\0') { + /* dialog(1) and dialog(3) will render literal newlines */ + if (use_dialog || use_libdialog) { + if (*p == '\n') { + if (use_dialog || !nls) + n = 0; + nls = FALSE; /* See declaration comment */ + } + } + + /* Check for backslash character */ + if (*p == '\\') { + /* If second backslash, count as a single-char */ + if ((backslash ^= 1) == 0) + n++; + } else if (backslash) { + if (*p == 'n' && !use_libdialog) { /* new line */ + /* NB: dialog(3) ignores escaped newlines */ + nls = TRUE; /* See declaration comment */ + n = 0; + } else if (use_color && *p == 'Z') { + if (*++p != '\0') + p++; + backslash = 0; + continue; + } else /* [X]dialog(1)/dialog(3) only expand those */ + n += 2; + + backslash = 0; + } else + n++; + + /* Did we pass the width barrier? */ + if (n > ncols) { + /* + * Work backward to find the first whitespace on-which + * dialog(1) will wrap the line (but don't go before + * the start of this line). + */ + cp = p; + while (n > 1 && !isspace(*cp)) { + cp--; + n--; + } + if (n > 0 && isspace(*cp)) + p = cp; + wlines++; + n = 1; + } + + p++; + } + + return (wlines); +} + +/* + * Returns zero if the buffer pointed to by `prompt' contains an escaped + * newline but only if appearing after any/all literal newlines. This is + * specific to dialog(1) and does not apply to Xdialog(1). + * + * As an attempt to make shell scripts easier to read, dialog(1) will "eat" + * the first literal newline after an escaped newline. This however has a bug + * in its implementation in that rather than allowing `\\n\n' to be treated + * similar to `\\n' or `\n', dialog(1) expands the `\\n' and then translates + * the following literal newline (with or without characters between [!]) into + * a single space. + * + * If you want to be compatible with Xdialog(1), it is suggested that you not + * use literal newlines (they aren't supported); but if you have to use them, + * go right ahead. But be forewarned... if you set $DIALOG in your environment + * to something other than `cdialog' (our current dialog(1)), then it should + * do the same thing w/respect to how to handle a literal newline after an + * escaped newline (you could do no wrong by translating every literal newline + * into a space but only when you've previously encountered an escaped one; + * this is what dialog(1) is doing). + * + * The ``newline state'' (or nlstate for short; as I'm calling it) is helpful + * if you plan to combine multiple strings into a single prompt text. In lead- + * up to this procedure, a common task is to calculate and utilize the widths + * and heights of each piece of prompt text to later be combined. However, if + * (for example) the first string ends in a positive newline state (has an + * escaped newline without trailing literal), the first literal newline in the + * second string will be mangled. + * + * The return value of this function should be used as the `nlstate' argument + * to dialog_*() functions that require it to allow accurate calculations in + * the event such information is needed. + */ +uint8_t +dialog_prompt_nlstate(const char *prompt) +{ + const char *cp; + + if (prompt == NULL) + return 0; + + /* + * Work our way backward from the end of the string for efficiency. + */ + cp = prompt + strlen(prompt); + while (--cp >= prompt) { + /* + * If we get to a literal newline first, this prompt ends in a + * clean state for rendering with dialog(1). Otherwise, if we + * get to an escaped newline first, this prompt ends in an un- + * clean state (following literal will be mangled; see above). + */ + if (*cp == '\n') + return (0); + else if (*cp == 'n' && --cp > prompt && *cp == '\\') + return (1); + } + + return (0); /* no newlines (escaped or otherwise) */ +} + +/* + * Free allocated items initialized by tty_maxsize_update() and + * x11_maxsize_update() + */ +void +dialog_maxsize_free(void) +{ + if (maxsize != NULL) { + free(maxsize); + maxsize = NULL; + } +} Property changes on: stable/10/lib/libdpv/dialog_util.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: stable/10/lib/libdpv/dialogrc.c =================================================================== --- stable/10/lib/libdpv/dialogrc.c (nonexistent) +++ stable/10/lib/libdpv/dialogrc.c (revision 275040) @@ -0,0 +1,359 @@ +/*- + * Copyright (c) 2013-2014 Devin Teske + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dialogrc.h" + +#define STR_BUFSIZE 255 + +/* dialog(1) `.dialogrc' characteristics */ +uint8_t use_colors = 1; +uint8_t use_shadow = 1; +char gauge_color[STR_BUFSIZE] = "47b"; /* (BLUE,WHITE,ON) */ +char separator[STR_BUFSIZE] = ""; + +/* Function prototypes */ +static int setattr(struct fp_config *, uint32_t, char *, char *); +static int setbool(struct fp_config *, uint32_t, char *, char *); +static int setnum(struct fp_config *, uint32_t, char *, char *); +static int setstr(struct fp_config *, uint32_t, char *, char *); + +/* + * Anatomy of DIALOGRC (~/.dialogrc by default) + * NOTE: Must appear after private function prototypes (above) + * NB: Brace-initialization of union requires cast to *first* member of union + */ +static struct fp_config dialogrc_config[] = { + /* TYPE Directive DEFAULT HANDLER */ + {FP_TYPE_INT, "aspect", {(void *)0}, &setnum}, + {FP_TYPE_STR, "separate_widget", {separator}, &setstr}, + {FP_TYPE_INT, "tab_len", {(void *)0}, &setnum}, + {FP_TYPE_BOOL, "visit_items", {(void *)0}, &setbool}, + {FP_TYPE_BOOL, "use_shadow", {(void *)1}, &setbool}, + {FP_TYPE_BOOL, "use_colors", {(void *)1}, &setbool}, + {FP_TYPE_STR, "screen_color", {NULL}, &setattr}, + {FP_TYPE_STR, "shadow_color", {NULL}, &setattr}, + {FP_TYPE_STR, "dialog_color", {NULL}, &setattr}, + {FP_TYPE_STR, "title_color", {NULL}, &setattr}, + {FP_TYPE_STR, "border_color", {NULL}, &setattr}, + {FP_TYPE_STR, "button_active_color", {NULL}, &setattr}, + {FP_TYPE_STR, "button_inactive_color", {NULL}, &setattr}, + {FP_TYPE_STR, "button_key_active_color", {NULL}, &setattr}, + {FP_TYPE_STR, "button_key_inactive_color", {NULL}, &setattr}, + {FP_TYPE_STR, "button_label_active_color", {NULL}, &setattr}, + {FP_TYPE_STR, "button_label_inactive_color",{NULL}, &setattr}, + {FP_TYPE_STR, "inputbox_color", {NULL}, &setattr}, + {FP_TYPE_STR, "inputbox_border_color", {NULL}, &setattr}, + {FP_TYPE_STR, "searchbox_color", {NULL}, &setattr}, + {FP_TYPE_STR, "searchbox_title_color", {NULL}, &setattr}, + {FP_TYPE_STR, "searchbox_border_color", {NULL}, &setattr}, + {FP_TYPE_STR, "position_indicator_color", {NULL}, &setattr}, + {FP_TYPE_STR, "menubox_color", {NULL}, &setattr}, + {FP_TYPE_STR, "menubox_border_color", {NULL}, &setattr}, + {FP_TYPE_STR, "item_color", {NULL}, &setattr}, + {FP_TYPE_STR, "item_selected_color", {NULL}, &setattr}, + {FP_TYPE_STR, "tag_color", {NULL}, &setattr}, + {FP_TYPE_STR, "tag_selected_color", {NULL}, &setattr}, + {FP_TYPE_STR, "tag_key_color", {NULL}, &setattr}, + {FP_TYPE_STR, "tag_key_selected_color", {NULL}, &setattr}, + {FP_TYPE_STR, "check_color", {NULL}, &setattr}, + {FP_TYPE_STR, "check_selected_color", {NULL}, &setattr}, + {FP_TYPE_STR, "uarrow_color", {NULL}, &setattr}, + {FP_TYPE_STR, "darrow_color", {NULL}, &setattr}, + {FP_TYPE_STR, "itemhelp_color", {NULL}, &setattr}, + {FP_TYPE_STR, "form_active_text_color", {NULL}, &setattr}, + {FP_TYPE_STR, "form_text_color", {NULL}, &setattr}, + {FP_TYPE_STR, "form_item_readonly_color", {NULL}, &setattr}, + {FP_TYPE_STR, "gauge_color", {gauge_color}, &setattr}, + {0, NULL, {0}, NULL} +}; + +/* + * figpar call-back for interpreting value as .dialogrc `Attribute' + */ +static int +setattr(struct fp_config *option, uint32_t line __unused, + char *directive __unused, char *value) +{ + char *cp = value; + char *val; + size_t len; + char attrbuf[4]; + + if (option == NULL) { + warnx("%s:%d:%s: Missing callback parameter", __FILE__, + __LINE__, __func__); + return (-1); /* Abort processing */ + } + + /* Allocate memory for the data if not already done */ + if (option->value.str == NULL) { + if ((option->value.str = malloc(STR_BUFSIZE)) == NULL) + return (-1); + } + + /* + * If the first character is left-parenthesis, the format is + * `(background,foreground,highlight)' otherwise, we should take it + * as a reference to another color. + */ + if (*cp != '(') { + /* Copy the [current] value from the referenced color */ + val = dialogrc_config_option(cp)->value.str; + if (val != NULL) + snprintf(option->value.str, STR_BUFSIZE, "%s", val); + + return (0); + } else + cp++; + + strtolower(cp); + + /* Initialize the attrbuf (fg,bg,hi,NUL) */ + attrbuf[0] = '0'; + attrbuf[1] = '0'; + attrbuf[2] = 'B'; /* \ZB = disable; \Zb = enable (see dialog(1)) */ + attrbuf[3] = '\0'; + + /* Interpret the foreground color */ + if (strncmp(cp, "red,", 4) == 0) attrbuf[0] = '1'; + else if (strncmp(cp, "green,", 6) == 0) attrbuf[0] = '2'; + else if (strncmp(cp, "yellow,", 7) == 0) attrbuf[0] = '3'; + else if (strncmp(cp, "blue,", 5) == 0) attrbuf[0] = '4'; + else if (strncmp(cp, "magenta,", 8) == 0) attrbuf[0] = '5'; + else if (strncmp(cp, "cyan,", 5) == 0) attrbuf[0] = '6'; + else if (strncmp(cp, "white,", 6) == 0) attrbuf[0] = '7'; + else if (strncmp(cp, "black,", 6) == 0) attrbuf[0] = '8'; + + /* Advance to the background color */ + cp = strchr(cp, ','); + if (cp == NULL) + goto write_attrbuf; + else + cp++; + + /* Interpret the background color */ + if (strncmp(cp, "red,", 4) == 0) attrbuf[1] = '1'; + else if (strncmp(cp, "green,", 6) == 0) attrbuf[1] = '2'; + else if (strncmp(cp, "yellow,", 7) == 0) attrbuf[1] = '3'; + else if (strncmp(cp, "blue,", 5) == 0) attrbuf[1] = '4'; + else if (strncmp(cp, "magenta,", 8) == 0) attrbuf[1] = '5'; + else if (strncmp(cp, "cyan,", 5) == 0) attrbuf[1] = '6'; + else if (strncmp(cp, "white,", 6) == 0) attrbuf[1] = '7'; + else if (strncmp(cp, "black,", 6) == 0) attrbuf[1] = '8'; + + /* Advance to the highlight */ + cp = strchr(cp, ','); + if (cp == NULL) + goto write_attrbuf; + else + cp++; + + /* Trim trailing parenthesis */ + len = strlen(cp); + if (cp[len - 1] == ')') + cp[len - 1] = '\0'; + + /* Interpret the highlight (initialized to off above) */ + if (strcmp(cp, "on") == 0 || strncmp(cp, "on,", 3) == 0) + attrbuf[2] = 'b'; /* \Zb = enable bold (see dialog(1)) */ + +write_attrbuf: + sprintf(option->value.str, "%s", attrbuf); + + return (0); +} + +/* + * figpar call-back for interpreting value as .dialogrc `Boolean' + */ +static int +setbool(struct fp_config *option, uint32_t line __unused, + char *directive __unused, char *value) +{ + + if (option == NULL) { + warnx("%s:%d:%s: Missing callback parameter", __FILE__, + __LINE__, __func__); + return (-1); /* Abort processing */ + } + + /* Assume ON, check for OFF (case-insensitive) */ + option->value.boolean = 1; + strtolower(value); + if (strcmp(value, "off") == 0) + option->value.boolean = 0; + + return (0); +} + +/* + * figpar call-back for interpreting value as .dialogrc `Number' + */ +static int +setnum(struct fp_config *option, uint32_t line __unused, + char *directive __unused, char *value) +{ + + if (option == NULL) { + warnx("%s:%d:%s: Missing callback parameter", __FILE__, + __LINE__, __func__); + return (-1); /* Abort processing */ + } + + /* Convert the string to a 32-bit signed integer */ + option->value.num = (int32_t)strtol(value, (char **)NULL, 10); + + return (0); +} + +/* + * figpar call-back for interpreting value as .dialogrc `String' + */ +static int +setstr(struct fp_config *option, uint32_t line __unused, + char *directive __unused, char *value) +{ + size_t len; + + if (option == NULL) { + warnx("%s:%d:%s: Missing callback parameter", __FILE__, + __LINE__, __func__); + return (-1); /* Abort processing */ + } + + /* Allocate memory for the data if not already done */ + if (option->value.str == NULL) { + if ((option->value.str = malloc(STR_BUFSIZE)) == NULL) + return (-1); + } + + /* Trim leading quote */ + if (*value == '"') + value++; + + /* Write the data into the buffer */ + snprintf(option->value.str, STR_BUFSIZE, "%s", value); + + /* Trim trailing quote */ + len = strlen(option->value.str); + if (option->value.str[len - 1] == '"') + option->value.str[len - 1] = '\0'; + + return (0); +} + +/* + * Parse (in order of preference) $DIALOGRC or `$HOME/.dialogrc'. Returns zero + * on success, -1 on failure (and errno should be consulted). + */ +int +parse_dialogrc(void) +{ + char *cp; + int res; + size_t len; + char path[PATH_MAX]; + + /* Allow $DIALOGRC to override `$HOME/.dialogrc' default */ + if ((cp = getenv(ENV_DIALOGRC)) != NULL && *cp != '\0') + snprintf(path, PATH_MAX, "%s", cp); + else if ((cp = getenv(ENV_HOME)) != NULL) { + /* Copy $HOME into buffer and append trailing `/' if missing */ + snprintf(path, PATH_MAX, "%s", cp); + len = strlen(path); + cp = path + len; + if (len > 0 && len < (PATH_MAX - 1) && *(cp - 1) != '/') { + *cp++ = '/'; + *cp = '\0'; + len++; + } + + /* If we still have room, shove in the name of rc file */ + if (len < (PATH_MAX - 1)) + snprintf(cp, PATH_MAX - len, "%s", DIALOGRC); + } else { + /* Like dialog(1), don't process a file if $HOME is unset */ + errno = ENOENT; + return (-1); + } + + /* Process file (either $DIALOGRC if set, or `$HOME/.dialogrc') */ + res = parse_config(dialogrc_config, path, NULL, FP_BREAK_ON_EQUALS); + + /* Set some globals based on what we parsed */ + use_shadow = dialogrc_config_option("use_shadow")->value.boolean; + use_colors = dialogrc_config_option("use_colors")->value.boolean; + snprintf(gauge_color, STR_BUFSIZE, "%s", + dialogrc_config_option("gauge_color")->value.str); + + return (res); +} + +/* + * Return a pointer to the `.dialogrc' config option specific to `directive' or + * static fp_dummy_config (full of NULLs) if none found (see + * get_config_option(3); part of figpar(3)). + */ +struct fp_config * +dialogrc_config_option(const char *directive) +{ + return (get_config_option(dialogrc_config, directive)); +} + +/* + * Free allocated items initialized by setattr() (via parse_config() callback + * matrix [dialogrc_config] used in parse_dialogrc() above). + */ +void +dialogrc_free(void) +{ + char *value; + uint32_t n; + + for (n = 0; dialogrc_config[n].directive != NULL; n++) { + if (dialogrc_config[n].action != &setattr) + continue; + value = dialogrc_config[n].value.str; + if (value != NULL && value != gauge_color) { + free(dialogrc_config[n].value.str); + dialogrc_config[n].value.str = NULL; + } + } +} Property changes on: stable/10/lib/libdpv/dialogrc.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: stable/10/lib/libdpv/dialogrc.h =================================================================== --- stable/10/lib/libdpv/dialogrc.h (nonexistent) +++ stable/10/lib/libdpv/dialogrc.h (revision 275040) @@ -0,0 +1,56 @@ +/*- + * Copyright (c) 2013-2014 Devin Teske + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _DIALOGRC_H_ +#define _DIALOGRC_H_ + +#include + +#include + +/* dialog(3) dlg_color_table[] attributes */ +#define GAUGE_ATTR 33 /* entry used for gauge_color */ + +/* dialog(1) characteristics */ +#define DIALOGRC ".dialogrc" +#define ENV_DIALOGRC "DIALOGRC" +#define ENV_HOME "HOME" + +/* dialog(1) `.dialogrc' characteristics */ +extern uint8_t use_colors; +extern uint8_t use_shadow; +extern char gauge_color[]; +extern char separator[]; + +__BEGIN_DECLS +void dialogrc_free(void); +int parse_dialogrc(void); +struct fp_config *dialogrc_config_option(const char *_directive); +__END_DECLS + +#endif /* !_DIALOGRC_H_ */ Property changes on: stable/10/lib/libdpv/dialogrc.h ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: stable/10/lib/libdpv/dpv.c =================================================================== --- stable/10/lib/libdpv/dpv.c (nonexistent) +++ stable/10/lib/libdpv/dpv.c (revision 275040) @@ -0,0 +1,721 @@ +/*- + * Copyright (c) 2013-2014 Devin Teske + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dialog_util.h" +#include "dialogrc.h" +#include "dprompt.h" +#include "dpv.h" +#include "dpv_private.h" +#include "status.h" +#include "util.h" + +/* Test Mechanics (Only used when dpv_config.options |= DPV_TEST_MODE) */ +#define INCREMENT 1 /* Increment % per-pass test-mode */ +#define XDIALOG_INCREMENT 15 /* different for slower Xdialog(1) */ +static uint8_t increment = INCREMENT; + +/* Debugging */ +uint8_t debug = FALSE; + +/* Data to process */ +int dpv_interrupt = FALSE; +int dpv_abort = FALSE; +unsigned int dpv_nfiles = 0; + +/* Data processing */ +long long dpv_overall_read = 0; +static char pathbuf[PATH_MAX]; + +/* Extra display information */ +uint8_t no_labels = FALSE; /* dpv_config.options & DPV_NO_LABELS */ +uint8_t wide = FALSE; /* dpv_config.options & DPV_WIDE_MODE */ +char *aprompt = NULL; /* dpv_config.aprompt */ +char *msg_done = NULL; /* dpv_config.msg_done */ +char *msg_fail = NULL; /* dpv_config.msg_fail */ +char *msg_pending = NULL; /* dpv_config.msg_pending */ +char *pprompt = NULL; /* dpv_config.pprompt */ + +/* Status-Line format for when using dialog(3) */ +static const char *status_format_custom = NULL; +static char status_format_default[DPV_STATUS_FORMAT_MAX]; + +/* + * Takes a pointer to a dpv_config structure containing layout details and + * pointer to initial element in a linked-list of dpv_file_node structures, + * each presenting a file to process. Executes the `action' function passed-in + * as a member to the `config' structure argument. + */ +int +dpv(struct dpv_config *config, struct dpv_file_node *file_list) +{ + char c; + uint8_t keep_going; + uint8_t nls = FALSE; /* See dialog_prompt_nlstate() */ + uint8_t no_overrun = FALSE; + uint8_t pprompt_nls = FALSE; /* See dialog_prompt_nlstate() */ + uint8_t shrink_label_size = FALSE; + mode_t mask; + uint16_t options; + char *cp; + char *fc; + char *last; + char *name; + char *output; + const char *status_fmt; + const char *path_fmt; + enum dpv_display display_type; + enum dpv_output output_type; + enum dpv_status status; + int (*action)(struct dpv_file_node *file, int out); + int backslash; + int dialog_last_update = 0; + int dialog_old_nthfile = 0; + int dialog_old_seconds = -1; + int dialog_out = STDOUT_FILENO; + int dialog_update_usec = 0; + int dialog_updates_per_second; + int files_left; + int max_cols; + int nthfile = 0; + int output_out; + int overall = 0; + int pct; + int res; + int seconds; + int status_last_update = 0; + int status_old_nthfile = 0; + int status_old_seconds = -1; + int status_update_usec = 0; + int status_updates_per_second; + pid_t output_pid; + pid_t pid; + size_t len; + struct dpv_file_node *curfile; + struct dpv_file_node *first_file; + struct dpv_file_node *list_head; + struct timeval now; + struct timeval start; + char init_prompt[PROMPT_MAX + 1] = ""; + + /* Initialize globals to default values */ + aprompt = NULL; + pprompt = NULL; + options = 0; + action = NULL; + backtitle = NULL; + debug = FALSE; + dialog_test = FALSE; + dialog_updates_per_second = DIALOG_UPDATES_PER_SEC; + display_limit = DISPLAY_LIMIT_DEFAULT; + display_type = DPV_DISPLAY_LIBDIALOG; + label_size = LABEL_SIZE_DEFAULT; + msg_done = NULL; + msg_fail = NULL; + msg_pending = NULL; + no_labels = FALSE; + output = NULL; + output_type = DPV_OUTPUT_NONE; + pbar_size = PBAR_SIZE_DEFAULT; + status_format_custom = NULL; + status_updates_per_second = STATUS_UPDATES_PER_SEC; + title = NULL; + wide = FALSE; + + /* Process config options (overriding defaults) */ + if (config != NULL) { + if (config->aprompt != NULL) { + if (aprompt == NULL) { + aprompt = malloc(DPV_APROMPT_MAX); + if (aprompt == NULL) + return (-1); + } + snprintf(aprompt, DPV_APROMPT_MAX, "%s", + config->aprompt); + } + if (config->pprompt != NULL) { + if (pprompt == NULL) { + pprompt = malloc(DPV_PPROMPT_MAX + 2); + /* +2 is for implicit "\n" appended later */ + if (pprompt == NULL) + return (-1); + } + snprintf(pprompt, DPV_APROMPT_MAX, "%s", + config->pprompt); + } + + options = config->options; + action = config->action; + backtitle = config->backtitle; + debug = config->debug; + dialog_test = ((options & DPV_TEST_MODE) != 0); + dialog_updates_per_second = config->dialog_updates_per_second; + display_limit = config->display_limit; + display_type = config->display_type; + label_size = config->label_size; + msg_done = (char *)config->msg_done; + msg_fail = (char *)config->msg_fail; + msg_pending = (char *)config->msg_pending; + no_labels = ((options & DPV_NO_LABELS) != 0); + no_overrun = ((options & DPV_NO_OVERRUN) != 0); + output = config->output; + output_type = config->output_type; + pbar_size = config->pbar_size; + status_updates_per_second = config->status_updates_per_second; + title = config->title; + wide = ((options & DPV_WIDE_MODE) != 0); + + /* Enforce some minimums (pedantic) */ + if (display_limit < -1) + display_limit = -1; + if (label_size < -1) + label_size = -1; + if (pbar_size < -1) + pbar_size = -1; + + /* For the mini-pbar, -1 means hide, zero is invalid unless + * only one file is given */ + if (pbar_size == 0) { + if (file_list == NULL || file_list->next == NULL) + pbar_size = -1; + else + pbar_size = PBAR_SIZE_DEFAULT; + } + + /* For the label, -1 means auto-size, zero is invalid unless + * specifically requested through the use of options flag */ + if (label_size == 0 && no_labels == FALSE) + label_size = LABEL_SIZE_DEFAULT; + + /* Status update should not be zero */ + if (status_updates_per_second == 0) + status_updates_per_second = STATUS_UPDATES_PER_SEC; + } /* config != NULL */ + + /* Process the type of display we've been requested to produce */ + switch (display_type) { + case DPV_DISPLAY_STDOUT: + debug = TRUE; + use_color = FALSE; + use_dialog = FALSE; + use_libdialog = FALSE; + use_xdialog = FALSE; + break; + case DPV_DISPLAY_DIALOG: + use_color = TRUE; + use_dialog = TRUE; + use_libdialog = FALSE; + use_xdialog = FALSE; + break; + case DPV_DISPLAY_XDIALOG: + snprintf(dialog, PATH_MAX, XDIALOG); + use_color = FALSE; + use_dialog = FALSE; + use_libdialog = FALSE; + use_xdialog = TRUE; + break; + default: + use_color = TRUE; + use_dialog = FALSE; + use_libdialog = TRUE; + use_xdialog = FALSE; + break; + } /* display_type */ + + /* Enforce additional minimums that require knowing our display type */ + if (dialog_updates_per_second == 0) + dialog_updates_per_second = use_xdialog ? + XDIALOG_UPDATES_PER_SEC : DIALOG_UPDATES_PER_SEC; + + /* Allow forceful override of use_color */ + if (config != NULL && (config->options & DPV_USE_COLOR) != 0) + use_color = TRUE; + + /* Count the number of files in provided list of dpv_file_node's */ + if (use_dialog && pprompt != NULL && *pprompt != '\0') + pprompt_nls = dialog_prompt_nlstate(pprompt); + + max_cols = dialog_maxcols(); + if (label_size == -1) + shrink_label_size = TRUE; + + /* Process file arguments */ + for (curfile = file_list; curfile != NULL; curfile = curfile->next) { + dpv_nfiles++; + + /* dialog(3) only expands literal newlines */ + if (use_libdialog) strexpandnl(curfile->name); + + /* Optionally calculate label size for file */ + if (shrink_label_size) { + nls = FALSE; + name = curfile->name; + if (curfile == file_list) + nls = pprompt_nls; + last = (char *)dialog_prompt_lastline(name, nls); + if (use_dialog) { + c = *last; + *last = '\0'; + nls = dialog_prompt_nlstate(name); + *last = c; + } + len = dialog_prompt_longestline(last, nls); + if ((int)len > (label_size - 3)) { + if (label_size > 0) + label_size += 3; + label_size = len; + /* Room for ellipsis (unless NULL) */ + if (label_size > 0) + label_size += 3; + } + + if (max_cols > 0 && label_size > (max_cols - pbar_size + - 9)) + label_size = max_cols - pbar_size - 9; + } + + if (debug) + warnx("label=[%s] path=[%s] size=%lli", + curfile->name, curfile->path, curfile->length); + } /* file_list */ + + /* Optionally process the contents of DIALOGRC (~/.dialogrc) */ + if (use_dialog) { + res = parse_dialogrc(); + if (debug && res == 0) { + warnx("Successfully read `%s' config file", DIALOGRC); + warnx("use_shadow = %i (Boolean)", use_shadow); + warnx("use_colors = %i (Boolean)", use_colors); + warnx("gauge_color=[%s] (FBH)", gauge_color); + } + } else if (use_libdialog) { + init_dialog(stdin, stdout); + use_shadow = dialog_state.use_shadow; + use_colors = dialog_state.use_colors; + gauge_color[0] = 48 + dlg_color_table[GAUGE_ATTR].fg; + gauge_color[1] = 48 + dlg_color_table[GAUGE_ATTR].bg; + gauge_color[2] = dlg_color_table[GAUGE_ATTR].hilite ? + 'b' : 'B'; + gauge_color[3] = '\0'; + end_dialog(); + if (debug) { + warnx("Finished initializing dialog(3) library"); + warnx("use_shadow = %i (Boolean)", use_shadow); + warnx("use_colors = %i (Boolean)", use_colors); + warnx("gauge_color=[%s] (FBH)", gauge_color); + } + } + + /* Enable mini progress bar automatically for stdin streams if unable + * to calculate progress (missing `lines:' syntax). */ + if (dpv_nfiles <= 1 && file_list != NULL && file_list->length < 0 && + !dialog_test) + pbar_size = PBAR_SIZE_DEFAULT; + + /* If $USE_COLOR is set and non-NULL enable color; otherwise disable */ + if ((cp = getenv(ENV_USE_COLOR)) != 0) + use_color = *cp != '\0' ? 1 : 0; + + /* Print error and return `-1' if not given at least one name */ + if (dpv_nfiles == 0) { + warnx("%s: no labels provided", __func__); + return (-1); + } else if (debug) + warnx("%s: %u label%s provided", __func__, dpv_nfiles, + dpv_nfiles == 1 ? "" : "s"); + + /* If only one file and pbar size is zero, default to `-1' */ + if (dpv_nfiles <= 1 && pbar_size == 0) + pbar_size = -1; + + /* Print some debugging information */ + if (debug) { + warnx("%s: %s(%i) max rows x cols = %i x %i", + __func__, use_xdialog ? XDIALOG : DIALOG, + use_libdialog ? 3 : 1, dialog_maxrows(), + dialog_maxcols()); + } + + /* Xdialog(1) updates a lot slower than dialog(1) */ + if (dialog_test && use_xdialog) + increment = XDIALOG_INCREMENT; + + /* Always add implicit newline to pprompt (when specified) */ + if (pprompt != NULL && *pprompt != '\0') { + len = strlen(pprompt); + /* + * NOTE: pprompt = malloc(PPROMPT_MAX + 2) + * NOTE: (see getopt(2) section above for pprompt allocation) + */ + pprompt[len++] = '\\'; + pprompt[len++] = 'n'; + pprompt[len++] = '\0'; + } + + /* Xdialog(1) requires newlines (a) escaped and (b) in triplicate */ + if (use_xdialog && pprompt != NULL) { + /* Replace `\n' with `\n\\n\n' in pprompt */ + len = strlen(pprompt); + len += strcount(pprompt, "\\n") * 2; + if (len > DPV_PPROMPT_MAX) + errx(EXIT_FAILURE, "%s: Oops, pprompt buffer overflow " + "(%zu > %i)", __func__, len, DPV_PPROMPT_MAX); + if (replaceall(pprompt, "\\n", "\n\\n\n") < 0) + err(EXIT_FAILURE, "%s: replaceall()", __func__); + } + /* libdialog requires literal newlines */ + else if (use_libdialog && pprompt != NULL) + strexpandnl(pprompt); + + /* Xdialog(1) requires newlines (a) escaped and (b) in triplicate */ + if (use_xdialog && aprompt != NULL) { + /* Replace `\n' with `\n\\n\n' in aprompt */ + len = strlen(aprompt); + len += strcount(aprompt, "\\n") * 2; + if (len > DPV_APROMPT_MAX) + errx(EXIT_FAILURE, "%s: Oops, aprompt buffer overflow " + " (%zu > %i)", __func__, len, DPV_APROMPT_MAX); + if (replaceall(aprompt, "\\n", "\n\\n\n") < 0) + err(EXIT_FAILURE, "%s: replaceall()", __func__); + } + /* libdialog requires literal newlines */ + else if (use_libdialog && aprompt != NULL) + strexpandnl(aprompt); + + /* + * Warn user about an obscure dialog(1) bug (neither Xdialog(1) nor + * libdialog are affected) in the `--gauge' widget. If the first non- + * whitespace letter of "{new_prompt}" in "XXX\n{new_prompt}\nXXX\n" + * is a number, the number can sometimes be mistaken for a percentage + * to the overall progressbar. Other nasty side-effects such as the + * entire prompt not displaying or displaying improperly are caused by + * this bug too. + * + * NOTE: When we can use color, we have a work-around... prefix the + * output with `\Zn' (used to terminate ANSI and reset to normal). + */ + if (use_dialog && !use_color) { + backslash = 0; + + /* First, check pprompt (falls through if NULL) */ + fc = pprompt; + while (fc != NULL && *fc != '\0') { + if (*fc == '\n') /* leading literal newline OK */ + break; + if (!isspace(*fc) && *fc != '\\' && backslash == 0) + break; + else if (backslash > 0 && *fc != 'n') + break; + else if (*fc == '\\') { + backslash++; + if (backslash > 2) + break; /* we're safe */ + } + fc++; + } + /* First non-whitespace character that dialog(1) will see */ + if (fc != NULL && *fc >= '0' && *fc <= '9') + warnx("%s: WARNING! text argument to `-p' begins with " + "a number (not recommended)", __func__); + else if (fc > pprompt) + warnx("%s: WARNING! text argument to `-p' begins with " + "whitespace (not recommended)", __func__); + + /* + * If no pprompt or pprompt is all whitespace, check the first + * file name provided to make sure it is alright too. + */ + if ((pprompt == NULL || *fc == '\0') && file_list != NULL) { + first_file = file_list; + fc = first_file->name; + while (fc != NULL && *fc != '\0' && isspace(*fc)) + fc++; + /* First non-whitespace char that dialog(1) will see */ + if (fc != NULL && *fc >= '0' && *fc <= '9') + warnx("%s: WARNING! File name `%s' begins " + "with a number (use `-p text' for safety)", + __func__, first_file->name); + } + } + + dprompt_init(file_list); + /* Reads: label_size pbar_size pprompt aprompt dpv_nfiles */ + /* Inits: dheight and dwidth */ + + if (!debug) { + /* Internally create the initial `--gauge' prompt text */ + dprompt_recreate(file_list, (struct dpv_file_node *)NULL, 0); + + /* Spawn [X]dialog(1) `--gauge', returning pipe descriptor */ + if (use_libdialog) { + status_printf(""); + dprompt_libprint(pprompt, aprompt, 0); + } else { + dprompt_sprint(init_prompt, pprompt, aprompt); + dialog_out = dialog_spawn_gauge(init_prompt, &pid); + dprompt_dprint(dialog_out, pprompt, aprompt, 0); + } + } /* !debug */ + + /* Seed the random(3) generator */ + if (dialog_test) + srandom(0xf1eeface); + + /* Set default/custom status line format */ + if (dpv_nfiles > 1) { + snprintf(status_format_default, DPV_STATUS_FORMAT_MAX, "%s", + DPV_STATUS_MANY); + status_format_custom = config->status_many; + } else { + snprintf(status_format_default, DPV_STATUS_FORMAT_MAX, "%s", + DPV_STATUS_SOLO); + status_format_custom = config->status_solo; + } + + /* Add test mode identifier to default status line if enabled */ + if (dialog_test && (strlen(status_format_default) + 12) < + DPV_STATUS_FORMAT_MAX) + strcat(status_format_default, " [TEST MODE]"); + + /* Verify custom status format */ + status_fmt = fmtcheck(status_format_custom, status_format_default); + if (status_format_custom != NULL && + status_fmt == status_format_default) { + warnx("WARNING! Invalid status_format configuration `%s'", + status_format_custom); + warnx("Default status_format `%s'", status_format_default); + } + + /* Record when we started (used to prevent updating too quickly) */ + (void)gettimeofday(&start, (struct timezone *)NULL); + + /* Calculate number of microseconds in-between sub-second updates */ + if (status_updates_per_second != 0) + status_update_usec = 1000000 / status_updates_per_second; + if (dialog_updates_per_second != 0) + dialog_update_usec = 1000000 / dialog_updates_per_second; + + /* + * Process the file list [serially] (one for each argument passed) + */ + files_left = dpv_nfiles; + list_head = file_list; + for (curfile = file_list; curfile != NULL; curfile = curfile->next) { + keep_going = TRUE; + output_out = -1; + pct = 0; + nthfile++; + files_left--; + + if (dpv_interrupt) + break; + if (dialog_test) + pct = 0 - increment; + + /* Attempt to spawn output program for this file */ + if (!dialog_test && output != NULL) { + mask = umask(0022); + (void)umask(mask); + + switch (output_type) { + case DPV_OUTPUT_SHELL: + output_out = shell_spawn_pipecmd(output, + curfile->name, &output_pid); + break; + case DPV_OUTPUT_FILE: + path_fmt = fmtcheck(output, "%s"); + if (path_fmt == output) + len = snprintf(pathbuf, + PATH_MAX, output, curfile->name); + else + len = snprintf(pathbuf, + PATH_MAX, "%s", output); + if (len >= PATH_MAX) { + warnx("%s:%d:%s: pathbuf[%u] too small" + "to hold output argument", + __FILE__, __LINE__, __func__, + PATH_MAX); + return (-1); + } + if ((output_out = open(pathbuf, + O_CREAT|O_WRONLY, DEFFILEMODE & ~mask)) + < 0) { + warn("%s", pathbuf); + return (-1); + } + break; + default: + break; + } + } + + while (!dpv_interrupt && keep_going) { + if (dialog_test) { + usleep(50000); + pct += increment; + dpv_overall_read += + (int)(random() / 512 / dpv_nfiles); + /* 512 limits fake readout to Megabytes */ + } else if (action != NULL) + pct = action(curfile, output_out); + + if (no_overrun || dialog_test) + keep_going = (pct < 100); + else { + status = curfile->status; + keep_going = (status == DPV_STATUS_RUNNING); + } + + /* Get current time and calculate seconds elapsed */ + gettimeofday(&now, (struct timezone *)NULL); + now.tv_sec = now.tv_sec - start.tv_sec; + now.tv_usec = now.tv_usec - start.tv_usec; + if (now.tv_usec < 0) + now.tv_sec--, now.tv_usec += 1000000; + seconds = now.tv_sec + (now.tv_usec / 1000000.0); + + /* Update dialog (be it dialog(3), dialog(1), etc.) */ + if ((dialog_updates_per_second != 0 && + ( + seconds != dialog_old_seconds || + now.tv_usec - dialog_last_update >= + dialog_update_usec || + nthfile != dialog_old_nthfile + )) || pct == 100 + ) { + /* Calculate overall progress (rounding up) */ + overall = (100 * nthfile - 100 + pct) / + dpv_nfiles; + if (((100 * nthfile - 100 + pct) * 10 / + dpv_nfiles % 100) > 50) + overall++; + + dprompt_recreate(list_head, curfile, pct); + + if (use_libdialog && !debug) { + /* Update dialog(3) widget */ + dprompt_libprint(pprompt, aprompt, + overall); + } else { + /* stdout, dialog(1), or Xdialog(1) */ + dprompt_dprint(dialog_out, pprompt, + aprompt, overall); + fsync(dialog_out); + } + dialog_old_seconds = seconds; + dialog_old_nthfile = nthfile; + dialog_last_update = now.tv_usec; + } + + /* Update the status line */ + if ((use_libdialog && !debug) && + status_updates_per_second != 0 && + ( + keep_going != TRUE || + seconds != status_old_seconds || + now.tv_usec - status_last_update >= + status_update_usec || + nthfile != status_old_nthfile + ) + ) { + status_printf(status_fmt, dpv_overall_read, + (dpv_overall_read / (seconds == 0 ? 1 : + seconds) * 1.0), + 1, /* XXX until we add parallelism XXX */ + files_left); + status_old_seconds = seconds; + status_old_nthfile = nthfile; + status_last_update = now.tv_usec; + } + } + + if (!dialog_test && output_out >= 0) { + close(output_out); + waitpid(output_pid, (int *)NULL, 0); + } + + if (dpv_abort) + break; + + /* Advance head of list when we hit the max display lines */ + if (display_limit > 0 && nthfile % display_limit == 0) + list_head = curfile->next; + } + + if (!debug) { + if (use_libdialog) + end_dialog(); + else { + close(dialog_out); + waitpid(pid, (int *)NULL, 0); + } + if (!dpv_interrupt) + printf("\n"); + } else + warnx("%s: %lli lines read", __func__, dpv_overall_read); + + if (dpv_interrupt || dpv_abort) + return (-1); + else + return (0); +} + +/* + * Free allocated items initialized by dpv() + */ +void +dpv_free(void) +{ + dialogrc_free(); + dprompt_free(); + dialog_maxsize_free(); + if (aprompt != NULL) { + free(aprompt); + aprompt = NULL; + } + if (pprompt != NULL) { + free(pprompt); + pprompt = NULL; + } + status_free(); +} Property changes on: stable/10/lib/libdpv/dpv.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: stable/10/lib/libdpv/dialog_util.h =================================================================== --- stable/10/lib/libdpv/dialog_util.h (nonexistent) +++ stable/10/lib/libdpv/dialog_util.h (revision 275040) @@ -0,0 +1,73 @@ +/*- + * Copyright (c) 2013-2014 Devin Teske + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _DIALOG_UTIL_H_ +#define _DIALOG_UTIL_H_ + +#include + +#include "dialogrc.h" + +#define DIALOG_SPAWN_DEBUG 0 /* Debug spawning of [X]dialog(1) */ + +/* dialog(3) and [X]dialog(1) characteristics */ +#define DIALOG "dialog" +#define XDIALOG "Xdialog" +#define PROMPT_MAX 16384 +#define ENV_DIALOG "DIALOG" +#define ENV_USE_COLOR "USE_COLOR" +#define ENV_XDIALOG_HIGH_DIALOG_COMPAT "XDIALOG_HIGH_DIALOG_COMPAT" +extern uint8_t dialog_test; +extern uint8_t use_libdialog; +extern uint8_t use_dialog; +extern uint8_t use_xdialog; +extern uint8_t use_color; +extern char dialog[]; + +/* dialog(3) and [X]dialog(1) functionality */ +extern char *title, *backtitle; +extern int dheight, dwidth; + +__BEGIN_DECLS +uint8_t dialog_prompt_nlstate(const char *_prompt); +void dialog_gauge_free(void); +void dialog_maxsize_free(void); +char *dialog_prompt_lastline(char *_prompt, uint8_t _nlstate); +int dialog_maxcols(void); +int dialog_maxrows(void); +int dialog_prompt_wrappedlines(char *_prompt, int _ncols, + uint8_t _nlstate); +int dialog_spawn_gauge(char *_init_prompt, pid_t *_pid); +int tty_maxcols(void); +#define tty_maxrows() dialog_maxrows() +unsigned int dialog_prompt_longestline(const char *_prompt, + uint8_t _nlstate); +unsigned int dialog_prompt_numlines(const char *_prompt, uint8_t _nlstate); +__END_DECLS + +#endif /* !_DIALOG_UTIL_H_ */ Property changes on: stable/10/lib/libdpv/dialog_util.h ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: stable/10/lib/libdpv/dprompt.c =================================================================== --- stable/10/lib/libdpv/dprompt.c (nonexistent) +++ stable/10/lib/libdpv/dprompt.c (revision 275040) @@ -0,0 +1,770 @@ +/*- + * Copyright (c) 2013-2014 Devin Teske + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include + +#define _BSD_SOURCE /* to get dprintf() prototype in stdio.h below */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dialog_util.h" +#include "dialogrc.h" +#include "dprompt.h" +#include "dpv.h" +#include "dpv_private.h" + +#define FLABEL_MAX 1024 + +static int fheight = 0; /* initialized by dprompt_init() */ +static char dprompt[PROMPT_MAX + 1] = ""; +static char *dprompt_pos = (char *)(0); /* treated numerically */ + +/* Display characteristics */ +#define FM_DONE 0x01 +#define FM_FAIL 0x02 +#define FM_PEND 0x04 +static uint8_t dprompt_free_mask; +static char *done = NULL; +static char *fail = NULL; +static char *pend = NULL; +int display_limit = DISPLAY_LIMIT_DEFAULT; /* Max entries to show */ +int label_size = LABEL_SIZE_DEFAULT; /* Max width for labels */ +int pbar_size = PBAR_SIZE_DEFAULT; /* Mini-progressbar size */ +static int gauge_percent = 0; +static int done_size, done_lsize, done_rsize; +static int fail_size, fail_lsize, fail_rsize; +static int mesg_size, mesg_lsize, mesg_rsize; +static int pend_size, pend_lsize, pend_rsize; +static int pct_lsize, pct_rsize; +static void *gauge = NULL; +#define SPIN_SIZE 4 +static char spin[SPIN_SIZE + 1] = "/-\\|"; +static char msg[PROMPT_MAX + 1]; +static char *spin_cp = spin; + +/* Function prototypes */ +static char spin_char(void); +static int dprompt_add_files(struct dpv_file_node *file_list, + struct dpv_file_node *curfile, int pct); + +/* + * Returns a pointer to the current spin character in the spin string and + * advances the global position to the next character for the next call. + */ +static char +spin_char(void) +{ + char ch; + + if (spin_cp == '\0') + spin_cp = spin; + ch = *spin_cp; + + /* Advance the spinner to the next char */ + if (++spin_cp >= (spin + SPIN_SIZE)) + spin_cp = spin; + + return (ch); +} + +/* + * Initialize heights and widths based on various strings and environment + * variables (such as ENV_USE_COLOR). + */ +void +dprompt_init(struct dpv_file_node *file_list) +{ + uint8_t nls = 0; + int len; + int max_cols; + int max_rows; + int nthfile; + int numlines; + struct dpv_file_node *curfile; + + /* + * Initialize dialog(3) `colors' support and draw backtitle + */ + if (use_libdialog && !debug) { + init_dialog(stdin, stdout); + dialog_vars.colors = 1; + if (backtitle != NULL) { + dialog_vars.backtitle = (char *)backtitle; + dlg_put_backtitle(); + } + } + + /* Calculate width of dialog(3) or [X]dialog(1) --gauge box */ + dwidth = label_size + pbar_size + 9; + + /* + * Calculate height of dialog(3) or [X]dialog(1) --gauge box + */ + dheight = 5; + max_rows = dialog_maxrows(); + /* adjust max_rows for backtitle and/or dialog(3) statusLine */ + if (backtitle != NULL) + max_rows -= use_shadow ? 3 : 2; + if (use_libdialog && use_shadow) + max_rows -= 2; + /* add lines for `-p text' */ + numlines = dialog_prompt_numlines(pprompt, 0); + if (debug) + warnx("`-p text' is %i line%s long", numlines, + numlines == 1 ? "" : "s"); + dheight += numlines; + /* adjust dheight for various implementations */ + if (use_dialog) { + dheight -= dialog_prompt_nlstate(pprompt); + nls = dialog_prompt_nlstate(pprompt); + } else if (use_xdialog) { + if (pprompt == NULL || *pprompt == '\0') + dheight++; + } else if (use_libdialog) { + if (pprompt != NULL && *pprompt != '\0') + dheight--; + } + /* limit the number of display items (necessary per dialog(1,3)) */ + if (display_limit == 0 || display_limit > DPV_DISPLAY_LIMIT) + display_limit = DPV_DISPLAY_LIMIT; + /* verify fheight will fit (stop if we hit 1) */ + for (; display_limit > 0; display_limit--) { + nthfile = numlines = 0; + fheight = (int)dpv_nfiles > display_limit ? + (unsigned int)display_limit : dpv_nfiles; + for (curfile = file_list; curfile != NULL; + curfile = curfile->next) { + nthfile++; + numlines += dialog_prompt_numlines(curfile->name, nls); + if ((nthfile % display_limit) == 0) { + if (numlines > fheight) + fheight = numlines; + numlines = nthfile = 0; + } + } + if (numlines > fheight) + fheight = numlines; + if ((dheight + fheight + + (int)dialog_prompt_numlines(aprompt, use_dialog) - + (use_dialog ? (int)dialog_prompt_nlstate(aprompt) : 0)) + <= max_rows) + break; + } + /* don't show any items if we run the risk of hitting a blank set */ + if ((max_rows - (use_shadow ? 5 : 4)) >= fheight) + dheight += fheight; + else + fheight = 0; + /* add lines for `-a text' */ + numlines = dialog_prompt_numlines(aprompt, use_dialog); + if (debug) + warnx("`-a text' is %i line%s long", numlines, + numlines == 1 ? "" : "s"); + dheight += numlines; + + /* If using Xdialog(1), adjust accordingly (based on testing) */ + if (use_xdialog) + dheight += dheight / 4; + + /* For wide mode, long prefix (`pprompt') or append (`aprompt') + * strings will bump width */ + if (wide) { + len = (int)dialog_prompt_longestline(pprompt, 0); /* !nls */ + if ((len + 4) > dwidth) + dwidth = len + 4; + len = (int)dialog_prompt_longestline(aprompt, 1); /* nls */ + if ((len + 4) > dwidth) + dwidth = len + 4; + } + + /* Enforce width constraints to maximum values */ + max_cols = dialog_maxcols(); + if (max_cols > 0 && dwidth > max_cols) + dwidth = max_cols; + + /* Optimize widths to sane values*/ + if (pbar_size > dwidth - 9) { + pbar_size = dwidth - 9; + label_size = 0; + /* -9 = "| - [" ... "] |" */ + } + if (pbar_size < 0) + label_size = dwidth - 8; + /* -8 = "| " ... " - |" */ + else if (label_size > (dwidth - pbar_size - 9) || wide) + label_size = no_labels ? 0 : dwidth - pbar_size - 9; + /* -9 = "| " ... " - [" ... "] |" */ + + /* Hide labels if requested */ + if (no_labels) + label_size = 0; + + /* Touch up the height (now that we know dwidth) */ + dheight += dialog_prompt_wrappedlines(pprompt, dwidth - 4, 0); + dheight += dialog_prompt_wrappedlines(aprompt, dwidth - 4, 1); + + if (debug) + warnx("dheight = %i dwidth = %i fheight = %i", + dheight, dwidth, fheight); + + /* Calculate left/right portions of % */ + pct_lsize = (pbar_size - 4) / 2; /* -4 == printf("%-3s%%", pct) */ + pct_rsize = pct_lsize; + /* If not evenly divisible by 2, increment the right-side */ + if ((pct_rsize + pct_rsize + 4) != pbar_size) + pct_rsize++; + + /* Initialize "Done" text */ + if (done == NULL && (done = msg_done) == NULL) { + if ((done = getenv(ENV_MSG_DONE)) != NULL) + done_size = strlen(done); + else { + done_size = strlen(DPV_DONE_DEFAULT); + if ((done = malloc(done_size + 1)) == NULL) + errx(EXIT_FAILURE, "Out of memory?!"); + dprompt_free_mask |= FM_DONE; + snprintf(done, done_size + 1, DPV_DONE_DEFAULT); + } + } + if (pbar_size < done_size) { + done_lsize = done_rsize = 0; + *(done + pbar_size) = '\0'; + done_size = pbar_size; + } else { + /* Calculate left/right portions for mini-progressbar */ + done_lsize = (pbar_size - done_size) / 2; + done_rsize = done_lsize; + /* If not evenly divisible by 2, increment the right-side */ + if ((done_rsize + done_size + done_lsize) != pbar_size) + done_rsize++; + } + + /* Initialize "Fail" text */ + if (fail == NULL && (fail = msg_fail) == NULL) { + if ((fail = getenv(ENV_MSG_FAIL)) != NULL) + fail_size = strlen(fail); + else { + fail_size = strlen(DPV_FAIL_DEFAULT); + if ((fail = malloc(fail_size + 1)) == NULL) + errx(EXIT_FAILURE, "Out of memory?!"); + dprompt_free_mask |= FM_FAIL; + snprintf(fail, fail_size + 1, DPV_FAIL_DEFAULT); + } + } + if (pbar_size < fail_size) { + fail_lsize = fail_rsize = 0; + *(fail + pbar_size) = '\0'; + fail_size = pbar_size; + } else { + /* Calculate left/right portions for mini-progressbar */ + fail_lsize = (pbar_size - fail_size) / 2; + fail_rsize = fail_lsize; + /* If not evenly divisible by 2, increment the right-side */ + if ((fail_rsize + fail_size + fail_lsize) != pbar_size) + fail_rsize++; + } + + /* Initialize "Pending" text */ + if (pend == NULL && (pend = msg_pending) == NULL) { + if ((pend = getenv(ENV_MSG_PENDING)) != NULL) + pend_size = strlen(pend); + else { + pend_size = strlen(DPV_PENDING_DEFAULT); + if ((pend = malloc(pend_size + 1)) == NULL) + errx(EXIT_FAILURE, "Out of memory?!"); + dprompt_free_mask |= FM_PEND; + snprintf(pend, pend_size + 1, DPV_PENDING_DEFAULT); + } + } + if (pbar_size < pend_size) { + pend_lsize = pend_rsize = 0; + *(pend + pbar_size) = '\0'; + pend_size = pbar_size; + } else { + /* Calculate left/right portions for mini-progressbar */ + pend_lsize = (pbar_size - pend_size) / 2; + pend_rsize = pend_lsize; + /* If not evenly divisible by 2, increment the right-side */ + if ((pend_rsize + pend_lsize + pend_size) != pbar_size) + pend_rsize++; + } + + if (debug) + warnx("label_size = %i pbar_size = %i", label_size, pbar_size); + + dprompt_clear(); +} + +/* + * Clear the [X]dialog(1) `--gauge' prompt buffer. + */ +void +dprompt_clear(void) +{ + + *dprompt = '\0'; + dprompt_pos = dprompt; +} + +/* + * Append to the [X]dialog(1) `--gauge' prompt buffer. Syntax is like printf(3) + * and returns the number of bytes appended to the buffer. + */ +int +dprompt_add(const char *format, ...) +{ + int len; + va_list ap; + + if (dprompt_pos >= (dprompt + PROMPT_MAX)) + return (0); + + va_start(ap, format); + len = vsnprintf(dprompt_pos, (size_t)(PROMPT_MAX - + (dprompt_pos - dprompt)), format, ap); + va_end(ap); + if (len == -1) + errx(EXIT_FAILURE, "%s: Oops, dprompt buffer overflow", + __func__); + + if ((dprompt_pos + len) < (dprompt + PROMPT_MAX)) + dprompt_pos += len; + else + dprompt_pos = dprompt + PROMPT_MAX; + + return (len); +} + +/* + * Append active files to the [X]dialog(1) `--gauge' prompt buffer. Syntax + * requires a pointer to the head of the dpv_file_node linked-list. Returns the + * number of files processed successfully. + */ +static int +dprompt_add_files(struct dpv_file_node *file_list, + struct dpv_file_node *curfile, int pct) +{ + char c; + char bold_code = 'b'; /* default: enabled */ + char color_code = '4'; /* default: blue */ + uint8_t after_curfile = curfile != NULL ? FALSE : TRUE; + uint8_t nls = 0; + char *cp; + char *lastline; + char *name; + const char *bg_code; + const char *estext; + const char *format; + enum dprompt_state dstate; + int estext_lsize; + int estext_rsize; + int estext_size; + int flabel_size; + int hlen; + int lsize; + int nlines = 0; + int nthfile = 0; + int pwidth; + int rsize; + struct dpv_file_node *fp; + char flabel[FLABEL_MAX + 1]; + char human[32]; + char pbar[pbar_size + 16]; /* +15 for optional color */ + char pbar_cap[sizeof(pbar)]; + char pbar_fill[sizeof(pbar)]; + + + /* Override color defaults with that of main progress bar */ + if (use_colors || use_shadow) { /* NB: shadow enables color */ + color_code = gauge_color[0]; + /* NB: str[1] aka bg is unused */ + bold_code = gauge_color[2]; + } + + /* + * Create mini-progressbar for current file (if applicable) + */ + *pbar = '\0'; + if (pbar_size >= 0 && pct >= 0 && curfile != NULL && + (curfile->length >= 0 || dialog_test)) { + snprintf(pbar, pbar_size + 1, "%*s%3u%%%*s", pct_lsize, "", + pct, pct_rsize, ""); + if (use_color) { + /* Calculate the fill-width of progressbar */ + pwidth = pct * pbar_size / 100; + /* Round up based on one-tenth of a percent */ + if ((pct * pbar_size % 100) > 50) + pwidth++; + + /* + * Make two copies of pbar. Make one represent the fill + * and the other the remainder (cap). We'll insert the + * ANSI delimiter in between. + */ + *pbar_fill = '\0'; + *pbar_cap = '\0'; + strncat(pbar_fill, (const char *)(pbar), dwidth); + *(pbar_fill + pwidth) = '\0'; + strncat(pbar_cap, (const char *)(pbar+pwidth), dwidth); + + /* Finalize the mini [color] progressbar */ + snprintf(pbar, sizeof(pbar), + "\\Z%c\\Zr\\Z%c%s%s%s\\Zn", bold_code, color_code, + pbar_fill, "\\ZR", pbar_cap); + } + } + + for (fp = file_list; fp != NULL; fp = fp->next) { + flabel_size = label_size; + name = fp->name; + nthfile++; + + /* + * Support multiline filenames (where the filename is taken as + * the last line and the text leading up to the last line can + * be used as (for example) a heading/separator between files. + */ + if (use_dialog) + nls = dialog_prompt_nlstate(pprompt); + nlines += dialog_prompt_numlines(name, nls); + lastline = dialog_prompt_lastline(name, 1); + if (name != lastline) { + c = *lastline; + *lastline = '\0'; + dprompt_add("%s", name); + *lastline = c; + name = lastline; + } + + /* Support color codes (for dialog(1,3)) in file names */ + if ((use_dialog || use_libdialog) && use_color) { + cp = name; + while (*cp != '\0') { + if (*cp == '\\' && *(cp + 1) != '\0' && + *(++cp) == 'Z' && *(cp + 1) != '\0') { + cp++; + flabel_size += 3; + } + cp++; + } + if (flabel_size > FLABEL_MAX) + flabel_size = FLABEL_MAX; + } + + /* If no mini-progressbar, increase label width */ + if (pbar_size < 0 && flabel_size <= FLABEL_MAX - 2 && + no_labels == FALSE) + flabel_size += 2; + + /* If name is too long, add an ellipsis */ + if (snprintf(flabel, flabel_size + 1, "%s", name) > + flabel_size) sprintf(flabel + flabel_size - 3, "..."); + + /* + * Append the label (processing the current file differently) + */ + if (fp == curfile && pct < 100) { + /* + * Add an ellipsis to current file name if it will fit. + * There may be an ellipsis already from truncating the + * label (in which case, we already have one). + */ + cp = flabel + strlen(flabel); + if (cp < (flabel + flabel_size)) + snprintf(cp, flabel_size - + (cp - flabel) + 1, "..."); + + /* Append label (with spinner and optional color) */ + dprompt_add("%s%-*s%s %c", use_color ? "\\Zb" : "", + flabel_size, flabel, use_color ? "\\Zn" : "", + spin_char()); + } else + dprompt_add("%-*s%s %s", flabel_size, + flabel, use_color ? "\\Zn" : "", " "); + + /* + * Append pbar/status (processing the current file differently) + */ + dstate = DPROMPT_NONE; + if (fp->msg != NULL) + dstate = DPROMPT_CUSTOM_MSG; + else if (pbar_size < 0) + dstate = DPROMPT_NONE; + else if (pbar_size < 4) + dstate = DPROMPT_MINIMAL; + else if (after_curfile) + dstate = DPROMPT_PENDING; + else if (fp == curfile) { + if (*pbar == '\0') { + if (fp->length < 0) + dstate = DPROMPT_DETAILS; + else if (fp->status == DPV_STATUS_RUNNING) + dstate = DPROMPT_DETAILS; + else + dstate = DPROMPT_END_STATE; + } + else if (dialog_test) /* status/length ignored */ + dstate = pct < 100 ? + DPROMPT_PBAR : DPROMPT_END_STATE; + else if (fp->status == DPV_STATUS_RUNNING) + dstate = fp->length < 0 ? + DPROMPT_DETAILS : DPROMPT_PBAR; + else /* not running */ + dstate = fp->length < 0 ? + DPROMPT_DETAILS : DPROMPT_END_STATE; + } else { /* before curfile */ + if (dialog_test) + dstate = DPROMPT_END_STATE; + else + dstate = fp->length < 0 ? + DPROMPT_DETAILS : DPROMPT_END_STATE; + } + format = use_color ? + " [\\Z%c%s%-*s%s%-*s\\Zn]\\n" : + " [%-*s%s%-*s]\\n"; + if (fp->status == DPV_STATUS_FAILED) { + bg_code = "\\Zr\\Z1"; /* Red */ + estext_lsize = fail_lsize; + estext_rsize = fail_rsize; + estext_size = fail_size; + estext = fail; + } else { /* e.g., DPV_STATUS_DONE */ + bg_code = "\\Zr\\Z2"; /* Green */ + estext_lsize = done_lsize; + estext_rsize = done_rsize; + estext_size = done_size; + estext = done; + } + switch (dstate) { + case DPROMPT_PENDING: /* Future file(s) */ + dprompt_add(" [%-*s%s%-*s]\\n", + pend_lsize, "", pend, pend_rsize, ""); + break; + case DPROMPT_PBAR: /* Current file */ + dprompt_add(" [%s]\\n", pbar); + break; + case DPROMPT_END_STATE: /* Past/Current file(s) */ + if (use_color) + dprompt_add(format, bold_code, bg_code, + estext_lsize, "", estext, + estext_rsize, ""); + else + dprompt_add(format, + estext_lsize, "", estext, + estext_rsize, ""); + break; + case DPROMPT_DETAILS: /* Past/Current file(s) */ + humanize_number(human, pbar_size + 2, fp->read, "", + HN_AUTOSCALE, HN_NOSPACE | HN_DIVISOR_1000); + + /* Calculate center alignment */ + hlen = (int)strlen(human); + lsize = (pbar_size - hlen) / 2; + rsize = lsize; + if ((lsize+hlen+rsize) != pbar_size) + rsize++; + + if (use_color) + dprompt_add(format, bold_code, bg_code, + lsize, "", human, rsize, ""); + else + dprompt_add(format, + lsize, "", human, rsize, ""); + break; + case DPROMPT_CUSTOM_MSG: /* File-specific message override */ + snprintf(msg, PROMPT_MAX + 1, "%s", fp->msg); + if (pbar_size < (mesg_size = strlen(msg))) { + mesg_lsize = mesg_rsize = 0; + *(msg + pbar_size) = '\0'; + mesg_size = pbar_size; + } else { + mesg_lsize = (pbar_size - mesg_size) / 2; + mesg_rsize = mesg_lsize; + if ((mesg_rsize + mesg_size + mesg_lsize) + != pbar_size) + mesg_rsize++; + } + if (use_color) + dprompt_add(format, bold_code, bg_code, + mesg_lsize, "", msg, mesg_rsize, ""); + else + dprompt_add(format, mesg_lsize, "", msg, + mesg_rsize, ""); + break; + case DPROMPT_MINIMAL: /* Short progress bar, minimal room */ + if (use_color) + dprompt_add(format, bold_code, bg_code, + pbar_size, "", "", 0, ""); + else + dprompt_add(format, pbar_size, "", "", 0, ""); + break; + case DPROMPT_NONE: /* pbar_size < 0 */ + /* FALLTHROUGH */ + default: + dprompt_add(" \\n"); + /* + * NB: Leading space required for the case when + * spin_char() returns a single backslash [\] which + * without the space, changes the meaning of `\n' + */ + } + + /* Stop building if we've hit the internal limit */ + if (nthfile >= display_limit) + break; + + /* If this is the current file, all others are pending */ + if (fp == curfile) + after_curfile = TRUE; + } + + /* + * Since we cannot change the height/width of the [X]dialog(1) widget + * after spawn, to make things look nice let's pad the height so that + * the `-a text' always appears in the same spot. + * + * NOTE: fheight is calculated in dprompt_init(). It represents the + * maximum height required to display the set of items (broken up into + * pieces of display_limit chunks) whose names contain the most + * newlines for any given set. + */ + while (nlines < fheight) { + dprompt_add("\n"); + nlines++; + } + + return (nthfile); +} + +/* + * Process the dpv_file_node linked-list of named files, re-generating the + * [X]dialog(1) `--gauge' prompt text for the current state of transfers. + */ +void +dprompt_recreate(struct dpv_file_node *file_list, + struct dpv_file_node *curfile, int pct) +{ + size_t len; + + /* + * Re-Build the prompt text + */ + dprompt_clear(); + if (display_limit > 0) + dprompt_add_files(file_list, curfile, pct); + + /* Xdialog(1) requires newlines (a) escaped and (b) in triplicate */ + if (use_xdialog) { + /* Replace `\n' with `\n\\n\n' in dprompt */ + len = strlen(dprompt); + len += strcount(dprompt, "\\n") * 5; /* +5 chars per count */ + if (len > PROMPT_MAX) + errx(EXIT_FAILURE, "%s: Oops, dprompt buffer overflow " + "(%zu > %i)", __func__, len, PROMPT_MAX); + if (replaceall(dprompt, "\\n", "\n\\n\n") < 0) + err(EXIT_FAILURE, "%s: replaceall()", __func__); + } + else if (use_libdialog) + strexpandnl(dprompt); +} + +/* + * Print the [X]dialog(1) `--gauge' prompt text to a buffer. + */ +int +dprompt_sprint(char * restrict str, const char *prefix, const char *append) +{ + + return (snprintf(str, PROMPT_MAX, "%s%s%s%s", use_color ? "\\Zn" : "", + prefix ? prefix : "", dprompt, append ? append : "")); +} + +/* + * Print the [X]dialog(1) `--gauge' prompt text to file descriptor fd (could + * be STDOUT_FILENO or a pipe(2) file descriptor to actual [X]dialog(1)). + */ +void +dprompt_dprint(int fd, const char *prefix, const char *append, int overall) +{ + int percent = gauge_percent; + + if (overall >= 0 && overall <= 100) + gauge_percent = percent = overall; + dprintf(fd, "XXX\n%s%s%s%s\nXXX\n%i\n", use_color ? "\\Zn" : "", + prefix ? prefix : "", dprompt, append ? append : "", percent); + fsync(fd); +} + +/* + * Print the dialog(3) `gauge' prompt text using libdialog. + */ +void +dprompt_libprint(const char *prefix, const char *append, int overall) +{ + int percent = gauge_percent; + char buf[DPV_PPROMPT_MAX + DPV_APROMPT_MAX + DPV_DISPLAY_LIMIT * 1024]; + + dprompt_sprint(buf, prefix, append); + + if (overall >= 0 && overall <= 100) + gauge_percent = percent = overall; + gauge = dlg_reallocate_gauge(gauge, title == NULL ? "" : title, + buf, dheight, dwidth, percent); + dlg_update_gauge(gauge, percent); +} + +/* + * Free allocated items initialized by dprompt_init() + */ +void +dprompt_free(void) +{ + if ((dprompt_free_mask & FM_DONE) != 0) { + dprompt_free_mask ^= FM_DONE; + free(done); + done = NULL; + } + if ((dprompt_free_mask & FM_FAIL) != 0) { + dprompt_free_mask ^= FM_FAIL; + free(fail); + fail = NULL; + } + if ((dprompt_free_mask & FM_PEND) != 0) { + dprompt_free_mask ^= FM_PEND; + free(pend); + pend = NULL; + } +} Property changes on: stable/10/lib/libdpv/dprompt.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: stable/10/lib/libdpv/dprompt.h =================================================================== --- stable/10/lib/libdpv/dprompt.h (nonexistent) +++ stable/10/lib/libdpv/dprompt.h (revision 275040) @@ -0,0 +1,59 @@ +/*- + * Copyright (c) 2013-2014 Devin Teske + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _DPROMPT_H_ +#define _DPROMPT_H_ + +#include + +#include "dpv.h" + +/* Display characteristics */ +#define ENV_MSG_DONE "msg_done" +#define ENV_MSG_FAIL "msg_fail" +#define ENV_MSG_PENDING "msg_pending" +extern int display_limit; +extern int label_size; +extern int pbar_size; + +__BEGIN_DECLS +void dprompt_clear(void); +void dprompt_dprint(int _fd, const char *_prefix, const char *_append, + int _overall); +void dprompt_free(void); +void dprompt_init(struct dpv_file_node *_file_list); +void dprompt_libprint(const char *_prefix, const char *_append, + int _overall); +void dprompt_recreate(struct dpv_file_node *_file_list, + struct dpv_file_node *_curfile, int _pct); +int dprompt_add(const char *_format, ...); +int dprompt_sprint(char * restrict _str, const char *_prefix, + const char *_append); +__END_DECLS + +#endif /* !_DPROMPT_H_ */ Property changes on: stable/10/lib/libdpv/dprompt.h ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: stable/10/lib/libdpv/dpv.3 =================================================================== --- stable/10/lib/libdpv/dpv.3 (nonexistent) +++ stable/10/lib/libdpv/dpv.3 (revision 275040) @@ -0,0 +1,510 @@ +.\" Copyright (c) 2013-2014 Devin Teske +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd Oct 24, 2014 +.Dt DPV 3 +.Os +.Sh NAME +.Nm dpv +.Nd dialog progress view library +.Sh LIBRARY +.Lb libdpv +.Sh SYNOPSIS +.In dpv.h +.Ft int +.Fo dpv +.Fa "struct dpv_config *config, struct dpv_file_node *file_list" +.Fc +.Ft void +.Fo dpv_free +.Fa "void" +.Fc +.Sh DESCRIPTION +The +.Nm +library provides an interface for creating complex +.Dq gauge +widgets for displaying progress on various actions. +The +.Nm +library can display progress with one of +.Xr dialog 3 , +.Xr dialog 1 , +or +.Xr Xdialog 1 +.Pq x11/xdialog from the ports tree . +.Pp +The +.Fn dpv +.Fa config +argument contains the following properties for configuring global display +features: +.Bd -literal -offset indent +struct dpv_config { + enum dpv_display display_type; /* Def. DPV_DISPLAY_LIBDIALOG */ + enum dpv_output output_type; /* Default DPV_OUTPUT_NONE */ + int debug; /* Enable debug on stderr */ + int display_limit; /* Files/page. Default -1 */ + int label_size; /* Label size. Default 28 */ + int pbar_size; /* Mini-progress size */ + int dialog_updates_per_second; /* Default 16 */ + int status_updates_per_second; /* Default 2 */ + uint16_t options; /* Default 0 (none) */ + char *title; /* Widget title */ + char *backtitle; /* Widget backtitle */ + char *aprompt; /* Append. Default NULL */ + char *pprompt; /* Prefix. Default NULL */ + char *msg_done; /* Default `Done' */ + char *msg_fail; /* Default `Fail' */ + char *msg_pending; /* Default `Pending' */ + char *output; /* Output format string */ + const char *status_solo; /* dialog(3) solo-status format. + * Default DPV_STATUS_SOLO */ + const char *status_many; /* dialog(3) many-status format. + * Default DPV_STATUS_MANY */ + + /* + * Function pointer; action to perform data transfer + */ + int (*action)(struct dpv_file_node *file, int out); +}; + +enum dpv_display { + DPV_DISPLAY_LIBDIALOG = 0, /* Use dialog(3) (default) */ + DPV_DISPLAY_STDOUT, /* Use stdout */ + DPV_DISPLAY_DIALOG, /* Use spawned dialog(1) */ + DPV_DISPLAY_XDIALOG, /* Use spawned Xdialog(1) */ +}; + +enum dpv_output { + DPV_OUTPUT_NONE = 0, /* No output (default) */ + DPV_OUTPUT_FILE, /* Read `output' member as file path */ + DPV_OUTPUT_SHELL, /* Read `output' member as shell cmd */ +}; +.Ed +.Pp +The +.Va options +member of the +.Fn dpv +.Fa config +argument is a mask of bit fields indicating various processing options. +Possible flags are as follows: +.Bl -tag -width DPV_NO_OVERRUN +.It Dv DPV_TEST_MODE +Enable test mode. +In test mode, the +.Fn action +callback of the +.Fa config +argument is not called but instead simulated-data is used to drive progress. +Appends +.Dq [TEST MODE] +to the status line +.Po +to override, set the +.Va status_format +member of the +.Fn dpv +.Fa config +argument; +e.g., to +.Dv DPV_STATUS_DEFAULT +.Pc . +.It Dv DPV_WIDE_MODE +Enable wide mode. +In wide mode, the length of the +.Va aprompt +and +.Va pprompt +members of the +.Fn dpv +.Fa config +argument will bump the width of the gauge widget. +Prompts wider than the maximum width will wrap +.Po +unless using +.Xr Xdialog 1 ; +see BUGS section below +.Pc . +.It Dv DPV_NO_LABELS +Disables the display of labels associated with each transfer +.Po +.Va label_size +member of +.Fn dpv +.Fa config +argument is ignored +.Pc . +.It Dv DPV_USE_COLOR +Force the use of color even if the +.Va display_type +does not support color +.Po +.Ev USE_COLOR +environment variable is ignored +.Pc . +.It Dv DPV_NO_OVERRUN +When enabled, callbacks for the current +.Vt dpv_file_node +are terminated when +.Fn action +returns 100 or greater +.Po +alleviates the need to change the +.Va status +of the current +.Vt dpv_file_node +but may also cause file truncation if the stream exceeds expected length +.Pc . +.El +.Pp +The +.Fa file_list +argument to +.Fn dpv +is a pointer to a +.Dq linked-list , +described as follows in +.In dpv.h : +.Bd -literal -offset indent +struct dpv_file_node { + enum dpv_status status; /* status of read operation */ + char *msg; /* display instead of "Done/Fail" */ + char *name; /* name of file to read */ + char *path; /* path to file */ + long long length; /* expected size */ + long long read; /* number units read (e.g., bytes) */ + struct dpv_file_node *next;/* pointer to next (end with NULL) */ +}; +.Ed +.Pp +For each of the items in the +.Fa file_list +.Dq linked-list +argument, the +.Fn action +callback member of the +.Fn dpv +.Fa config +argument is called. +The +.Fn action +function should perform a +.Dq nominal +action on the file and return. +The return value of +.Vt int +represents the current progress percentage +.Pq 0-100 +for the current file. +.Pp +The +.Fn action +callback provides two variables for each call. +.Fa file +provides a reference to the current +.Vt dpv_file_node +being processed. +.Fa out +provides a file descriptor where the data should go. +.Pp +If the +.Va output +member of the +.Fn dpv +.Fa config +argument was set to DPV_OUTPUT_NONE +.Pq default ; when invoking Fn dpv , +the +.Fa out +file descriptor of +.Fn action +will be zero and should be ignored. +If +.Fa output +was set to DPV_OUTPUT_FILE, +.Fa out +will be an open file descriptor to a file. +If +.Fa output +was set to DPV_OUTPUT_SHELL, +.Fa out +will be an open file descriptor to a pipe for a spawned shell program. +When +.Fa out +is greater than zero, you should write any data you have read back to +.Fa out . +.Pp +To abort +.Fn dpv , +either from the +.Fn action +callback or asynchronously from a signal handler, two globals are provided via +.In dpv.h : +.Bd -literal -offset indent +extern int dpv_interrupt; /* Set to TRUE in interrupt handler */ +extern int dpv_abort; /* Set to true in callback to abort */ +.Ed +.Pp +These globals are not automatically reset and must be manually maintained. +Don't forget to reset these globals before subsequent invocations of +.Fn dpv +when making multiple calls from the same program. +.Pp +In addition, the +.Va status +member of the +.Fn action +.Fa file +argument can be used to control callbacks for the current file. +The +.Va status +member can be set to any of the following from +.In dpv.h : +.Bd -literal -offset indent +enum dpv_status { + DPV_STATUS_RUNNING = 0, /* Running (default) */ + DPV_STATUS_DONE, /* Completed */ + DPV_STATUS_FAILED, /* Oops, something went wrong */ +}; +.Ed +.Pp +The default +.Fa status +is zero, DPV_STATUS_RUNING, which keeps the callbacks coming for the current +.Fn file . +Setting +.Ql file->status +to anything other than DPV_STATUS_RUNNING will cause +.Fn dpv +to loop to the next file, effecting the next callback, if any. +.Pp +The +.Fn action +callback is responsible for calculating percentages and +.Pq recommended +maintaining a +.Nm +global counter so +.Fn dpv +can display throughput statistics. +Percentages are reported through the +.Vt int +return value of the +.Fn action +callback. +Throughput statistics are calculated from the following global +.Vt int +in +.In dpv.h : +.Bd -literal -offset indent +extern int dpv_overall_read; +.Ed +.Pp +This should be set to the number of bytes that have been read for all files. +Throughput information is displayed in the status line +.Pq only available when using Xr dialog 3 +at the bottom of the screen. +See DPV_DISPLAY_LIBDIALOG above. +.Pp +Note that +.Va dpv_overall_read +does not have to represent bytes. +For example, you can change the +.Va status_format +to display something other than +.Dq Li bytes +and increment +.Va dpv_overall_read +accordingly +.Pq e.g., counting lines . +.Pp +When +.Fn dpv +is processing the current file, the +.Va length +and +.Va read +members of the +.Fn action +.Fa file +argument are used for calculating the display of mini progress bars +.Po +if enabled; see +.Va pbar_size +above +.Pc . +If the +.Va length +member of the current +.Fa file +is less than zero +.Pq indicating an unknown file length , +a +.Xr humanize_number 3 +version of the +.Va read +member is used instead of a traditional progress bar. +Otherwise a progress bar is calculated as percentage read to file length. +.Fn action +callback must maintain these member values for mini-progress bars. +.Pp +The +.Fn dpv_free +function performs +.Xr free 3 +on private global variables initialized by +.Fn dpv . +.Sh ENVIRONMENT +The following environment variables are referenced by +.Nm : +.Bl -tag -width ".Ev USE_COLOR" +.It Ev DIALOG +Override command string used to launch +.Xr dialog 1 +.Pq requires Dv DPV_DISPLAY_DIALOG +or +.Xr Xdialog 1 +.Pq requires Dv DPV_DISPLAY_XDIALOG ; +default is either +.Ql dialog +.Pq for Dv DPV_DISPLAY_DIALOG +or +.Ql Xdialog +.Pq for Dv DPV_DISPLAY_XDIALOG . +.It Ev DIALOGRC +If set and non-NULL, path to +.Ql .dialogrc +file. +.It Ev HOME +If +.Ql Ev $DIALOGRC +is either not set or NULL, used as a prefix to +.Ql .dialogrc +.Pq i.e., Ql $HOME/.dialogrc . +.It Ev USE_COLOR +If set and NULL, disables the use of color when using +.Xr dialog 1 +.Pq does not apply to Xr Xdialog 1 . +.It Ev msg_done Ev msg_fail Ev msg_pending +Internationalization strings for overriding the default English strings +.Ql Done , +.Ql Fail , +and +.Ql Pending +respectively. +To prevent their usage, explicitly set the +.Va msg_done , +.Va msg_fail , +and +.Va msg_pending +members of +.Fn dpv +.Fa config +argument to default macros +.Pq DPV_DONE_DEFAULT, DPV_FAIL_DEFAULT, and DPV_PENDING_DEFAULT +or desired values. +.El +.Sh FILES +.Bl -tag -width ".Pa $HOME/.dialogrc" -compact +.It Pa $HOME/.dialogrc +.El +.Sh SEE ALSO +.Xr dialog 1 , +.Xr dialog 3 , +.Xr Xdialog 1 +.Sh HISTORY +The +.Nm +library first appeared in +.Fx 11.0 . +.Sh AUTHORS +.An Devin Teske Aq dteske@FreeBSD.org +.Sh BUGS +.Xr Xdialog 1 , +when given both +.Ql Fl -title Ar title +.Po +see above +.Ql Va title +member of +.Va struct dpv_config +.Pc +and +.Ql Fl -backtitle Ar backtitle +.Po +see above +.Ql Va backtitle +member of +.Va struct dpv_config +.Pc , +displays the backtitle in place of the title and vice-versa. +.Pp +.Xr Xdialog 1 +does not wrap long prompt texts received after initial launch. +This is a known issue with the +.Ql --gauge +widget in +.Xr Xdialog 1 . +Embed escaped newlines within prompt text(s) to force line breaks. +.Pp +.Xr dialog 1 +does not display the first character after a series of escaped escape-sequences +(e.g., ``\\\\n'' produces ``\\'' instead of ``\\n''). +This is a known issue with +.Xr dialog 1 +and does not affect +.Xr dialog 3 +or +.Xr Xdialog 1 . +.Pp +If your application ignores +.Ev USE_COLOR +when set and NULL before calling +.Xr dpv 3 +with color escape sequences anyway, +.Xr dialog 3 +and +.Xr dialog 1 +may not render properly. +Workaround is to detect when +.Ev USE_COLOR +is set and NULL and either not use color escape sequences at that time or use +.Xr unsetenv 3 +to unset +.Ev USE_COLOR , +forcing interpretation of color sequences. +This does not effect +.Xr Xdialog 1 , +which renders the color escape sequences as plain text. +See +.Do Li +embedded "\\Z" sequences +.Dc +in +.Xr dialog 1 +for additional information. Property changes on: stable/10/lib/libdpv/dpv.3 ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: stable/10/lib/libdpv/dpv.h =================================================================== --- stable/10/lib/libdpv/dpv.h (nonexistent) +++ stable/10/lib/libdpv/dpv.h (revision 275040) @@ -0,0 +1,161 @@ +/*- + * Copyright (c) 2013-2014 Devin Teske + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _DPV_H_ +#define _DPV_H_ + +#include + +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#endif + +/* Data to process */ +extern long long dpv_overall_read; + +/* Interrupt flag */ +extern int dpv_interrupt; /* Set to TRUE in interrupt handler */ +extern int dpv_abort; /* Set to true in callback to abort */ + +/* + * Display types for use with display_type member of dpv_config structure + */ +enum dpv_display { + DPV_DISPLAY_LIBDIALOG = 0, /* Display using dialog(3) (default) */ + DPV_DISPLAY_STDOUT, /* Display on stdout */ + DPV_DISPLAY_DIALOG, /* Display using spawned dialog(1) */ + DPV_DISPLAY_XDIALOG, /* Display using spawned Xdialog(1) */ +}; + +/* + * Output types for use with output_type member of dpv_config structure + */ +enum dpv_output { + DPV_OUTPUT_NONE = 0, /* No output (default) */ + DPV_OUTPUT_FILE, /* Read `output' member as file path */ + DPV_OUTPUT_SHELL, /* Read `output' member as shell cmd */ +}; + +/* + * Activity types for use with status member of dpv_file_node structure. + * If you set a status other than DPV_STATUS_RUNNING on the current file in the + * action callback of dpv_config structure, you'll end callbacks for that + * dpv_file_node. + */ +enum dpv_status { + DPV_STATUS_RUNNING = 0, /* Running (default) */ + DPV_STATUS_DONE, /* Completed */ + DPV_STATUS_FAILED, /* Oops, something went wrong */ +}; + +/* + * Anatomy of file option; pass an array of these as dpv() file_list argument + * terminated with a NULL pointer. + */ +struct dpv_file_node { + enum dpv_status status; /* status of read operation */ + char *msg; /* display instead of "Done/Fail" */ + char *name; /* name of file to read */ + char *path; /* path to file */ + long long length; /* expected size */ + long long read; /* number units read (e.g., bytes) */ + struct dpv_file_node *next; /* pointer to next (end with NULL) */ +}; + +/* + * Anatomy of config option to pass as dpv() config argument + */ +struct dpv_config { + enum dpv_display display_type; /* Display (default TYPE_LIBDIALOG) */ + enum dpv_output output_type; /* Output (default TYPE_NONE) */ + int debug; /* Enable debugging output on stderr */ + int display_limit; /* Files per `page'. Default -1 */ + int label_size; /* Label size. Default 28 */ + int pbar_size; /* Mini-progress size. See dpv(3) */ + int dialog_updates_per_second; /* Progress updates/s. Default 16 */ + int status_updates_per_second; /* dialog(3) status updates/second. + * Default 2 */ + uint16_t options; /* Special options. Default 0 */ + char *title; /* widget title */ + char *backtitle; /* Widget backtitle */ + char *aprompt; /* Prompt append. Default NULL */ + char *pprompt; /* Prompt prefix. Default NULL */ + char *msg_done; /* Progress text. Default `Done' */ + char *msg_fail; /* Progress text. Default `Fail' */ + char *msg_pending; /* Progress text. Default `Pending' */ + char *output; /* Output format string; see dpv(3) */ + const char *status_solo; /* dialog(3) solo-status format. + * Default DPV_STATUS_SOLO */ + const char *status_many; /* dialog(3) many-status format. + * Default DPV_STATUS_MANY */ + + /* + * Function pointer; action to perform data transfer + */ + int (*action)(struct dpv_file_node *file, int out); +}; + +/* + * Macros for dpv() options bitmask argument + */ +#define DPV_TEST_MODE 0x0001 /* Test mode (fake reading data) */ +#define DPV_WIDE_MODE 0x0002 /* prefix/append bump dialog width */ +#define DPV_NO_LABELS 0x0004 /* Hide file_node.name labels */ +#define DPV_USE_COLOR 0x0008 /* Override to force color output */ +#define DPV_NO_OVERRUN 0x0010 /* Stop transfers when they hit 100% */ + +/* + * Limits (modify with extreme care) + */ +#define DPV_APROMPT_MAX 4096 /* Buffer size for `-a text' */ +#define DPV_DISPLAY_LIMIT 10 /* Max file progress lines */ +#define DPV_PPROMPT_MAX 4096 /* Buffer size for `-p text' */ +#define DPV_STATUS_FORMAT_MAX 80 /* Buffer size for `-u format' */ + +/* + * Extra display information + */ +#define DPV_STATUS_SOLO "%'10lli bytes read @ %'9.1f bytes/sec." +#define DPV_STATUS_MANY (DPV_STATUS_SOLO " [%i/%i busy/wait]") + +/* + * Strings + */ +#define DPV_DONE_DEFAULT "Done" +#define DPV_FAIL_DEFAULT "Fail" +#define DPV_PENDING_DEFAULT "Pending" + +__BEGIN_DECLS +void dpv_free(void); +int dpv(struct dpv_config *_config, struct dpv_file_node *_file_list); +__END_DECLS + +#endif /* !_DPV_H_ */ Property changes on: stable/10/lib/libdpv/dpv.h ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: stable/10/lib/libdpv/dpv_private.h =================================================================== --- stable/10/lib/libdpv/dpv_private.h (nonexistent) +++ stable/10/lib/libdpv/dpv_private.h (revision 275040) @@ -0,0 +1,66 @@ +/*- + * Copyright (c) 2013-2014 Devin Teske + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _DPV_PRIVATE_H_ +#define _DPV_PRIVATE_H_ + +#include + +/* Debugging */ +extern uint8_t debug; + +/* Data to process */ +extern unsigned int dpv_nfiles; + +/* Extra display information */ +extern uint8_t no_labels; +extern uint8_t wide; +extern char *msg_done, *msg_fail, *msg_pending; +extern char *pprompt, *aprompt; +extern const char status_format[]; + +/* Defaults */ +#define DIALOG_UPDATES_PER_SEC 16 +#define XDIALOG_UPDATES_PER_SEC 4 +#define DISPLAY_LIMIT_DEFAULT 0 /* Auto-calculate */ +#define LABEL_SIZE_DEFAULT 28 +#define PBAR_SIZE_DEFAULT 17 +#define STATUS_UPDATES_PER_SEC 2 + +/* states for dprompt_add_files() of dprompt.c */ +enum dprompt_state { + DPROMPT_NONE = 0, /* Default */ + DPROMPT_PENDING, /* Pending */ + DPROMPT_PBAR, /* Progress bar */ + DPROMPT_END_STATE, /* Done/Fail */ + DPROMPT_DETAILS, /* dpv_file_node->read */ + DPROMPT_CUSTOM_MSG, /* dpv_file_node->msg */ + DPROMPT_MINIMAL, /* whitespace */ +}; + +#endif /* !_DPV_PRIVATE_H_ */ Property changes on: stable/10/lib/libdpv/dpv_private.h ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: stable/10/lib/libdpv/status.c =================================================================== --- stable/10/lib/libdpv/status.c (nonexistent) +++ stable/10/lib/libdpv/status.c (revision 275040) @@ -0,0 +1,111 @@ +/*- + * Copyright (c) 2013-2014 Devin Teske + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include + +#include "dialog_util.h" +#include "status.h" + +/* static globals */ +static char *status_buf = NULL; +static int status_bufsize = -1; +static int status_row; +static int status_width; + +/* + * Print a `one-liner' status message at the bottom of the screen. Messages are + * trimmed to fit within the console length (ANSI coloring not accounted for). + */ +void +status_printf(const char *fmt, ...) +{ + int n, attrs; + chtype color = dlg_color_pair(dlg_color_table[BUTTON_ACTIVE_ATTR].fg, + dlg_color_table[SCREEN_ATTR].bg) | A_BOLD; + va_list args; + + status_row = tty_maxrows() - 1; + status_width = tty_maxcols(); + + /* NULL is a special convention meaning "erase the old stuff" */ + if (fmt == NULL) { + move(status_row, 0); + clrtoeol(); + return; + } + + /* Resize buffer if terminal width is greater */ + if ((status_width + 1) > status_bufsize) { + status_buf = realloc(status_buf, status_width + 1); + if (status_buf == NULL) { + status_bufsize = -1; + return; + } + status_bufsize = status_width + 1; + } + + /* Print the message within a space-filled buffer */ + memset(status_buf, ' ', status_width); + va_start(args, fmt); + n = vsnprintf(status_buf, status_width + 1, fmt, args); + va_end(args); + + /* If vsnprintf(3) produced less bytes than the maximum, change the + * implicitly-added NUL-terminator into a space and terminate at max */ + if (n < status_width) { + status_buf[n] = ' '; + status_buf[status_width] = '\0'; + } + + /* Print text in screen bg, button active fg, and bold */ + attrs = getattrs(stdscr); + attrset(color); + mvaddstr(status_row, 0, status_buf); + attrset(attrs); + + /* Seat the cursor over the last character at absolute lower-right */ + move(status_row, status_width - 1); + refresh(); +} + +/* + * Free allocated items initialized by status_printf() + */ +void +status_free(void) +{ + if (status_buf != NULL) { + free(status_buf); + status_buf = NULL; + } +} Property changes on: stable/10/lib/libdpv/status.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: stable/10/lib/libdpv/status.h =================================================================== --- stable/10/lib/libdpv/status.h (nonexistent) +++ stable/10/lib/libdpv/status.h (revision 275040) @@ -0,0 +1,43 @@ +/*- + * Copyright (c) 2013-2014 Devin Teske + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _STATUS_H_ +#define _STATUS_H_ + +#include + +/* dialog(3) dlg_color_table[] attributes */ +#define SCREEN_ATTR 0 /* entry used for status line bg */ +#define BUTTON_ACTIVE_ATTR 5 /* entry used for status line fg */ + +__BEGIN_DECLS +void status_free(void); +void status_printf(const char *_format, ...); +__END_DECLS + +#endif /* !_STATUS_H_ */ Property changes on: stable/10/lib/libdpv/status.h ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: stable/10/lib/libdpv/util.c =================================================================== --- stable/10/lib/libdpv/util.c (nonexistent) +++ stable/10/lib/libdpv/util.c (revision 275040) @@ -0,0 +1,107 @@ +/*- + * Copyright (c) 2013-2014 Devin Teske + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include + +#include "util.h" + +extern char **environ; +static char cmdbuf[CMDBUFMAX] = ""; +static char shellcmd[PATH_MAX] = PATH_SHELL; +static char *shellcmd_argv[6] = { + shellcmd, + __DECONST(char *, "-c"), + cmdbuf, + __DECONST(char *, "--"), + shellcmd, + NULL, +}; + +/* + * Spawn a sh(1) command. Writes the resulting process ID to the pid_t pointed + * at by `pid'. Returns a file descriptor (int) suitable for writing data to + * the spawned command (data written to file descriptor is seen as standard-in + * by the spawned sh(1) command). Returns `-1' if unable to spawn command. + * + * If cmd contains a single "%s" sequence, replace it with label if non-NULL. + */ +int +shell_spawn_pipecmd(const char *cmd, const char *label, pid_t *pid) +{ + int error; + int len; + posix_spawn_file_actions_t action; +#if SHELL_SPAWN_DEBUG + unsigned int i; +#endif + int stdin_pipe[2] = { -1, -1 }; + + /* Populate argument array */ + if (label != NULL && fmtcheck(cmd, "%s") == cmd) + len = snprintf(cmdbuf, CMDBUFMAX, cmd, label); + else + len = snprintf(cmdbuf, CMDBUFMAX, "%s", cmd); + if (len >= CMDBUFMAX) { + warnx("%s:%d:%s: cmdbuf[%u] too small to hold cmd argument", + __FILE__, __LINE__, __func__, CMDBUFMAX); + return (-1); + } + + /* Open a pipe to communicate with [X]dialog(1) */ + if (pipe(stdin_pipe) < 0) + err(EXIT_FAILURE, "%s: pipe(2)", __func__); + + /* Fork sh(1) process */ +#if SHELL_SPAWN_DEBUG + fprintf(stderr, "%s: spawning `", __func__); + for (i = 0; shellcmd_argv[i] != NULL; i++) { + if (i == 0) + fprintf(stderr, "%s", shellcmd_argv[i]); + else if (i == 2) + fprintf(stderr, " '%s'", shellcmd_argv[i]); + else + fprintf(stderr, " %s", shellcmd_argv[i]); + } + fprintf(stderr, "'\n"); +#endif + posix_spawn_file_actions_init(&action); + posix_spawn_file_actions_adddup2(&action, stdin_pipe[0], STDIN_FILENO); + posix_spawn_file_actions_addclose(&action, stdin_pipe[1]); + error = posix_spawnp(pid, shellcmd, &action, + (const posix_spawnattr_t *)NULL, shellcmd_argv, environ); + if (error != 0) + err(EXIT_FAILURE, "%s: posix_spawnp(3)", __func__); + + return stdin_pipe[1]; +} Property changes on: stable/10/lib/libdpv/util.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: stable/10/lib/libdpv/util.h =================================================================== --- stable/10/lib/libdpv/util.h (nonexistent) +++ stable/10/lib/libdpv/util.h (revision 275040) @@ -0,0 +1,50 @@ +/*- + * Copyright (c) 2013-2014 Devin Teske + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _UTIL_H_ +#define _UTIL_H_ + +#include + +#include + +#define SHELL_SPAWN_DEBUG 0 /* Debug spawning of sh(1) commands */ + +#ifdef _PATH_BSHELL +#define PATH_SHELL _PATH_BSHELL +#else +#define PATH_SHELL "/bin/sh" +#endif + +#define CMDBUFMAX 4096 + +__BEGIN_DECLS +int shell_spawn_pipecmd(const char *_cmd, const char *_label, pid_t *_pid); +__END_DECLS + +#endif /* !_UTIL_H_ */ Property changes on: stable/10/lib/libdpv/util.h ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: stable/10/lib/libfigpar/Makefile =================================================================== --- stable/10/lib/libfigpar/Makefile (nonexistent) +++ stable/10/lib/libfigpar/Makefile (revision 275040) @@ -0,0 +1,21 @@ +# $FreeBSD$ + +LIB= figpar +SHLIB_MAJOR= 0 +INCS= figpar.h string_m.h +MAN= figpar.3 +MLINKS= figpar.3 get_config_option.3 \ + figpar.3 parse_config.3 \ + figpar.3 replaceall.3 \ + figpar.3 strcount.3 \ + figpar.3 strexpand.3 \ + figpar.3 strexpandnl.3 \ + figpar.3 strtolower.3 + +CFLAGS+= -I${.CURDIR} + +SRCS= figpar.c string_m.c + +WARNS?= 6 + +.include Property changes on: stable/10/lib/libfigpar/Makefile ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: stable/10/lib/libfigpar/figpar.3 =================================================================== --- stable/10/lib/libfigpar/figpar.3 (nonexistent) +++ stable/10/lib/libfigpar/figpar.3 (revision 275040) @@ -0,0 +1,251 @@ +.\" Copyright (c) 2013-2014 Devin Teske +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd Oct 24, 2014 +.Dt FIGPAR 3 +.Os +.Sh NAME +.Nm figpar , +.Nm parse_config , +.Nm get_config_option +.Nd configuration file parsing library +.Sh LIBRARY +.Lb libfigpar +.Sh SYNOPSIS +.In figpar.h +.Ft int +.Fo parse_config +.Fa "struct fp_config options[], const char *path" +.Fa "int \*[lp]*unknown\*[rp]\*[lp]struct fp_config *option, uint32_t line" +.Fa "char *directive, char *value\*[rp], uint8_t processing_options" +.Fc +.Ft "struct fp_config *" +.Fo get_config_option +.Fa "struct fp_config options[], const char *directive" +.Fc +.In string_m.h +.Ft int +.Fo replaceall +.Fa "char *source, const char *find, const char *replace" +.Fc +.Ft unsigned int +.Fo strcount +.Fa "const char *source, const char *find" +.Fc +.Ft void +.Fo strexpand +.Fa "char *source" +.Fc +.Ft void +.Fo strexpandnl +.Fa "char *source" +.Fc +.Ft void +.Fo strtolower +.Fa "char *source" +.Fc +.Sh DESCRIPTION +The +.Nm +library provides a light-weight, portable framework for parsing configuration +files. +The library uses +.Xr open 2 , +.Xr read 2 , +and +.Xr lseek 2 +within the file pointed to by +.Fa path +to find directives and values which are then made available to the application. +.Pp +Due to the fact that configuration files may have basic syntax differences, +the library does not attempt to impose any structure on the data but instead +provides raw data to a set of callback functions. +These callback functions can in-turn initiate abort through their return value, +allowing custom syntax validation during parsing. +.Pp +Configuration directives, types, and callback functions are provided through +data structures defined in +.In figpar.h : +.Bd -literal -offset indent +struct fp_config { + enum fp_cfgtype type; /* value type */ + const char *directive; /* keyword */ + union fp_cfgvalue value; /* value */ + + /* Pointer to function used when directive is found */ + int (*action)(struct fp_config *option, uint32_t line, + char *directive, char *value); +}; + +enum fp_cfgtype { + FP_TYPE_NONE = 0x0000, /* for directives with no value */ + FP_TYPE_BOOL = 0x0001, /* boolean */ + FP_TYPE_INT = 0x0002, /* signed 32 bit integer */ + FP_TYPE_UINT = 0x0004, /* unsigned 32 bit integer */ + FP_TYPE_STR = 0x0008, /* string pointer */ + FP_TYPE_STRARRAY = 0x0010, /* string array pointer */ + FP_TYPE_DATA1 = 0x0020, /* void data type-1 (whatever) */ + FP_TYPE_DATA2 = 0x0040, /* void data type-2 (whatever) */ + FP_TYPE_DATA3 = 0x0080, /* void data type-3 (whatever) */ + FP_TYPE_RESERVED1 = 0x0100, /* reserved data type-1 (future) */ + FP_TYPE_RESERVED2 = 0x0200, /* reserved data type-2 (future) */ + FP_TYPE_RESERVED3 = 0x0400, /* reserved data type-3 (future) */ +}; + +union fp_cfgvalue { + void *data; /* Pointer to NUL-terminated string */ + char *str; /* Pointer to NUL-terminated string */ + char **strarray; /* Pointer to an array of strings */ + int32_t num; /* Signed 32-bit integer value */ + uint32_t u_num; /* Unsigned 32-bit integer value */ + uint32_t boolean:1; /* Boolean integer value (0 or 1) */ +}; +.Ed +.Pp +The +.Fa processing_options +argument to +.Fn parse_config +is a mask of bit fields which indicate various +processing options. +The possible flags are as follows: +.Bl -tag -width FP_BREAK_ON_SEMICOLON +.It Dv FP_BREAK_ON_EQUALS +An equals sign +.Pq Ql Li = +is normally considered part of the directive. +This flag enables terminating the directive at the equals sign. +Also makes equals sign optional and transient. +.It Dv FP_BREAK_ON_SEMICOLON +A semicolon +.Pq Ql Li \; +is normally considered part of the value. +This flag enables terminating the value at the semicolon. +Also allows multiple statements on a single line separated by semicolon. +.It Dv FP_CASE_SENSITIVE +Normally directives are matched case insensitively using +.Xr fnmatch 3 . +This flag enables directive matching to be case sensitive. +.It Dv FP_REQUIRE_EQUALS +If a directive is not followed by an equals, processing is aborted. +.It Dv FP_STRICT_EQUALS +Equals must be part of the directive to be considered a delimiter between +directive and value. +.El +.Pp +The +.Fa options +struct array pointer can be NULL and every directive will invoke the +.Fn unknown +function argument. +.Pp +The directive for each fp_config item in the +.Fn parse_config +options argument is matched against each parsed directive using +.Xr fnmatch 3 +until a match is found. +If a match is found, the +.Fn action +function for that fp_config directive is invoked with the line number, +directive, and value. +Otherwise if no match, the +.Fn unknown +function is invoked +.Pq with the same arguments . +.Pp +If either +.Fa action +or +.Fa unknown +return non-zero, +.Fn parse_config +aborts reading the file and returns the error value to its caller. +.Pp +.Fn get_config_option +traverses the options-array and returns the option that matches via +.Xr strcmp 3 , +or if no match a pointer to a static dummy struct is returned +.Pq whose values are all zero or NULL . +.Pp +The use of +.Fa "struct fp_config" +is entirely optional as-is the use of +.Fa "enum fp_cfgtype" +or +.Fa "union fp_cfgvalue" . +For example, you could choose to pass a NULL pointer to +.Fn parse_config +for the first argument and then provide a simple +.Fa unknown +function based on +.Xr queue 3 +that populates a singly-linked list of your own struct containing the +.Fa directive +and +.Fa value . +.Pp +In addition, the following miscellaneous string manipulation routines are +provided by +.In string_m.h : +.Bl -tag -width strexpandnl() +.It Fn replaceall +Replace all occurrences of +.Fa find +in +.Fa source +with +.Fa replace . +.It Fn strcount +Count the number of occurrences of one string that appear in the +.Fa source +string. +Return value is the total count. +An example use would be if you need to know how large a block of memory needs +to be for a +.Fn replaceall +series. +.It Fn strexpand +Expand escape sequences in a buffer pointed to by +.Fa source . +.It Fn strexpandnl +Expand only the escaped newlines in a buffer pointed to by +.Fa source . +.It Fn strtolower +Convert a string to lower case. +.El +.Sh SEE ALSO +.Xr queue 3 +.Sh HISTORY +The +.Nm +library first appeared in +.Fx 11.0 . +.Sh AUTHORS +.An Devin Teske Aq dteske@FreeBSD.org +.Sh BUGS +This is the first implementation of the library, +and the interface may be subject to refinement. Property changes on: stable/10/lib/libfigpar/figpar.3 ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: stable/10/lib/libfigpar/figpar.c =================================================================== --- stable/10/lib/libfigpar/figpar.c (nonexistent) +++ stable/10/lib/libfigpar/figpar.c (revision 275040) @@ -0,0 +1,469 @@ +/*- + * Copyright (c) 2002-2014 Devin Teske + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "figpar.h" +#include "string_m.h" + +struct fp_config fp_dummy_config = {0, NULL, {0}, NULL}; + +/* + * Search for config option (struct fp_config) in the array of config options, + * returning the struct whose directive matches the given parameter. If no + * match is found, a pointer to the static dummy array (above) is returned. + * + * This is to eliminate dependency on the index position of an item in the + * array, since the index position is more apt to be changed as code grows. + */ +struct fp_config * +get_config_option(struct fp_config options[], const char *directive) +{ + uint32_t n; + + /* Check arguments */ + if (options == NULL || directive == NULL) + return (&fp_dummy_config); + + /* Loop through the array, return the index of the first match */ + for (n = 0; options[n].directive != NULL; n++) + if (strcmp(options[n].directive, directive) == 0) + return (&(options[n])); + + /* Re-initialize the dummy variable in case it was written to */ + fp_dummy_config.directive = NULL; + fp_dummy_config.type = 0; + fp_dummy_config.action = NULL; + fp_dummy_config.value.u_num = 0; + + return (&fp_dummy_config); +} + +/* + * Parse the configuration file at `path' and execute the `action' call-back + * functions for any directives defined by the array of config options (first + * argument). + * + * For unknown directives that are encountered, you can optionally pass a + * call-back function for the third argument to be called for unknowns. + * + * Returns zero on success; otherwise returns -1 and errno should be consulted. +*/ +int +parse_config(struct fp_config options[], const char *path, + int (*unknown)(struct fp_config *option, uint32_t line, char *directive, + char *value), uint16_t processing_options) +{ + uint8_t bequals; + uint8_t bsemicolon; + uint8_t case_sensitive; + uint8_t comment = 0; + uint8_t end; + uint8_t found; + uint8_t have_equals = 0; + uint8_t quote; + uint8_t require_equals; + uint8_t strict_equals; + char p[2]; + char *directive; + char *t; + char *value; + int error; + int fd; + ssize_t r = 1; + uint32_t dsize; + uint32_t line = 1; + uint32_t n; + uint32_t vsize; + uint32_t x; + off_t charpos; + off_t curpos; + char rpath[PATH_MAX]; + + /* Sanity check: if no options and no unknown function, return */ + if (options == NULL && unknown == NULL) + return (-1); + + /* Processing options */ + bequals = (processing_options & FP_BREAK_ON_EQUALS) == 0 ? 0 : 1; + bsemicolon = (processing_options & FP_BREAK_ON_SEMICOLON) == 0 ? 0 : 1; + case_sensitive = (processing_options & FP_CASE_SENSITIVE) == 0 ? 0 : 1; + require_equals = (processing_options & FP_REQUIRE_EQUALS) == 0 ? 0 : 1; + strict_equals = (processing_options & FP_STRICT_EQUALS) == 0 ? 0 : 1; + + /* Initialize strings */ + directive = value = 0; + vsize = dsize = 0; + + /* Resolve the file path */ + if (realpath(path, rpath) == 0) + return (-1); + + /* Open the file */ + if ((fd = open(rpath, O_RDONLY)) < 0) + return (-1); + + /* Read the file until EOF */ + while (r != 0) { + r = read(fd, p, 1); + + /* skip to the beginning of a directive */ + while (r != 0 && (isspace(*p) || *p == '#' || comment || + (bsemicolon && *p == ';'))) { + if (*p == '#') + comment = 1; + else if (*p == '\n') { + comment = 0; + line++; + } + r = read(fd, p, 1); + } + /* Test for EOF; if EOF then no directive was found */ + if (r == 0) { + close(fd); + return (0); + } + + /* Get the current offset */ + curpos = lseek(fd, 0, SEEK_CUR) - 1; + if (curpos == -1) { + close(fd); + return (-1); + } + + /* Find the length of the directive */ + for (n = 0; r != 0; n++) { + if (isspace(*p)) + break; + if (bequals && *p == '=') { + have_equals = 1; + break; + } + if (bsemicolon && *p == ';') + break; + r = read(fd, p, 1); + } + + /* Test for EOF, if EOF then no directive was found */ + if (n == 0 && r == 0) { + close(fd); + return (0); + } + + /* Go back to the beginning of the directive */ + error = (int)lseek(fd, curpos, SEEK_SET); + if (error == (curpos - 1)) { + close(fd); + return (-1); + } + + /* Allocate and read the directive into memory */ + if (n > dsize) { + if ((directive = realloc(directive, n + 1)) == NULL) { + close(fd); + return (-1); + } + dsize = n; + } + r = read(fd, directive, n); + + /* Advance beyond the equals sign if appropriate/desired */ + if (bequals && *p == '=') { + if (lseek(fd, 1, SEEK_CUR) != -1) + r = read(fd, p, 1); + if (strict_equals && isspace(*p)) + *p = '\n'; + } + + /* Terminate the string */ + directive[n] = '\0'; + + /* Convert directive to lower case before comparison */ + if (!case_sensitive) + strtolower(directive); + + /* Move to what may be the start of the value */ + if (!(bsemicolon && *p == ';') && + !(strict_equals && *p == '=')) { + while (r != 0 && isspace(*p) && *p != '\n') + r = read(fd, p, 1); + } + + /* An equals sign may have stopped us, should we eat it? */ + if (r != 0 && bequals && *p == '=' && !strict_equals) { + have_equals = 1; + r = read(fd, p, 1); + while (r != 0 && isspace(*p) && *p != '\n') + r = read(fd, p, 1); + } + + /* If no value, allocate a dummy value and jump to action */ + if (r == 0 || *p == '\n' || *p == '#' || + (bsemicolon && *p == ';')) { + /* Initialize the value if not already done */ + if (value == NULL && (value = malloc(1)) == NULL) { + close(fd); + return (-1); + } + value[0] = '\0'; + goto call_function; + } + + /* Get the current offset */ + curpos = lseek(fd, 0, SEEK_CUR) - 1; + if (curpos == -1) { + close(fd); + return (-1); + } + + /* Find the end of the value */ + quote = 0; + end = 0; + while (r != 0 && end == 0) { + /* Advance to the next character if we know we can */ + if (*p != '\"' && *p != '#' && *p != '\n' && + (!bsemicolon || *p != ';')) { + r = read(fd, p, 1); + continue; + } + + /* + * If we get this far, we've hit an end-key + */ + + /* Get the current offset */ + charpos = lseek(fd, 0, SEEK_CUR) - 1; + if (charpos == -1) { + close(fd); + return (-1); + } + + /* + * Go back so we can read the character before the key + * to check if the character is escaped (which means we + * should continue). + */ + error = (int)lseek(fd, -2, SEEK_CUR); + if (error == -3) { + close(fd); + return (-1); + } + r = read(fd, p, 1); + + /* + * Count how many backslashes there are (an odd number + * means the key is escaped, even means otherwise). + */ + for (n = 1; *p == '\\'; n++) { + /* Move back another offset to read */ + error = (int)lseek(fd, -2, SEEK_CUR); + if (error == -3) { + close(fd); + return (-1); + } + r = read(fd, p, 1); + } + + /* Move offset back to the key and read it */ + error = (int)lseek(fd, charpos, SEEK_SET); + if (error == (charpos - 1)) { + close(fd); + return (-1); + } + r = read(fd, p, 1); + + /* + * If an even number of backslashes was counted meaning + * key is not escaped, we should evaluate what to do. + */ + if ((n & 1) == 1) { + switch (*p) { + case '\"': + /* + * Flag current sequence of characters + * to follow as being quoted (hashes + * are not considered comments). + */ + quote = !quote; + break; + case '#': + /* + * If we aren't in a quoted series, we + * just hit an inline comment and have + * found the end of the value. + */ + if (!quote) + end = 1; + break; + case '\n': + /* + * Newline characters must always be + * escaped, whether inside a quoted + * series or not, otherwise they + * terminate the value. + */ + end = 1; + case ';': + if (!quote && bsemicolon) + end = 1; + break; + } + } else if (*p == '\n') + /* Escaped newline character. increment */ + line++; + + /* Advance to the next character */ + r = read(fd, p, 1); + } + + /* Get the current offset */ + charpos = lseek(fd, 0, SEEK_CUR) - 1; + if (charpos == -1) { + close(fd); + return (-1); + } + + /* Get the length of the value */ + n = (uint32_t)(charpos - curpos); + if (r != 0) /* more to read, but don't read ending key */ + n--; + + /* Move offset back to the beginning of the value */ + error = (int)lseek(fd, curpos, SEEK_SET); + if (error == (curpos - 1)) { + close(fd); + return (-1); + } + + /* Allocate and read the value into memory */ + if (n > vsize) { + if ((value = realloc(value, n + 1)) == NULL) { + close(fd); + return (-1); + } + vsize = n; + } + r = read(fd, value, n); + + /* Terminate the string */ + value[n] = '\0'; + + /* Cut trailing whitespace off by termination */ + t = value + n; + while (isspace(*--t)) + *t = '\0'; + + /* Escape the escaped quotes (replaceall is in string_m.c) */ + x = strcount(value, "\\\""); /* in string_m.c */ + if (x != 0 && (n + x) > vsize) { + if ((value = realloc(value, n + x + 1)) == NULL) { + close(fd); + return (-1); + } + vsize = n + x; + } + if (replaceall(value, "\\\"", "\\\\\"") < 0) { + /* Replace operation failed for some unknown reason */ + close(fd); + return (-1); + } + + /* Remove all new line characters */ + if (replaceall(value, "\\\n", "") < 0) { + /* Replace operation failed for some unknown reason */ + close(fd); + return (-1); + } + + /* Resolve escape sequences */ + strexpand(value); /* in string_m.c */ + +call_function: + /* Abort if we're seeking only assignments */ + if (require_equals && !have_equals) + return (-1); + + found = have_equals = 0; /* reset */ + + /* If there are no options defined, call unknown and loop */ + if (options == NULL && unknown != NULL) { + error = unknown(NULL, line, directive, value); + if (error != 0) { + close(fd); + return (error); + } + continue; + } + + /* Loop through the array looking for a match for the value */ + for (n = 0; options[n].directive != NULL; n++) { + error = fnmatch(options[n].directive, directive, + FNM_NOESCAPE); + if (error == 0) { + found = 1; + /* Call function for array index item */ + if (options[n].action != NULL) { + error = options[n].action( + &options[n], + line, directive, value); + if (error != 0) { + close(fd); + return (error); + } + } + } else if (error != FNM_NOMATCH) { + /* An error has occurred */ + close(fd); + return (-1); + } + } + if (!found && unknown != NULL) { + /* + * No match was found for the value we read from the + * file; call function designated for unknown values. + */ + error = unknown(NULL, line, directive, value); + if (error != 0) { + close(fd); + return (error); + } + } + } + + close(fd); + return (0); +} Property changes on: stable/10/lib/libfigpar/figpar.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: stable/10/lib/libfigpar/figpar.h =================================================================== --- stable/10/lib/libfigpar/figpar.h (nonexistent) +++ stable/10/lib/libfigpar/figpar.h (revision 275040) @@ -0,0 +1,99 @@ +/*- + * Copyright (c) 2002-2014 Devin Teske + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _FIGPAR_H_ +#define _FIGPAR_H_ + +#include + +/* + * Union for storing various types of data in a single common container. + */ +union fp_cfgvalue { + void *data; /* Pointer to NUL-terminated string */ + char *str; /* Pointer to NUL-terminated string */ + char **strarray; /* Pointer to an array of strings */ + int32_t num; /* Signed 32-bit integer value */ + uint32_t u_num; /* Unsigned 32-bit integer value */ + uint32_t boolean:1; /* Boolean integer value (0 or 1) */ +}; + +/* + * Option types (based on above cfgvalue union) + */ +enum fp_cfgtype { + FP_TYPE_NONE = 0x0000, /* for directives with no value */ + FP_TYPE_BOOL = 0x0001, /* boolean */ + FP_TYPE_INT = 0x0002, /* signed 32 bit integer */ + FP_TYPE_UINT = 0x0004, /* unsigned 32 bit integer */ + FP_TYPE_STR = 0x0008, /* string pointer */ + FP_TYPE_STRARRAY = 0x0010, /* string array pointer */ + FP_TYPE_DATA1 = 0x0020, /* void data type-1 (whatever) */ + FP_TYPE_DATA2 = 0x0040, /* void data type-2 (whatever) */ + FP_TYPE_DATA3 = 0x0080, /* void data type-3 (whatever) */ + FP_TYPE_RESERVED1 = 0x0100, /* reserved data type-1 (future) */ + FP_TYPE_RESERVED2 = 0x0200, /* reserved data type-2 (future) */ + FP_TYPE_RESERVED3 = 0x0400, /* reserved data type-3 (future) */ +}; + +/* + * Options to parse_config() for processing_options bitmask + */ +#define FP_BREAK_ON_EQUALS 0x0001 /* stop reading directive at `=' */ +#define FP_BREAK_ON_SEMICOLON 0x0002 /* `;' starts a new line */ +#define FP_CASE_SENSITIVE 0x0004 /* directives are case sensitive */ +#define FP_REQUIRE_EQUALS 0x0008 /* assignment directives only */ +#define FP_STRICT_EQUALS 0x0010 /* `=' must be part of directive */ + +/* + * Anatomy of a config file option + */ +struct fp_config { + enum fp_cfgtype type; /* Option value type */ + const char *directive; /* config file keyword */ + union fp_cfgvalue value; /* NB: set by action */ + + /* + * Function pointer; action to be taken when the directive is found + */ + int (*action)(struct fp_config *option, uint32_t line, char *directive, + char *value); +}; +extern struct fp_config fp_dummy_config; + +__BEGIN_DECLS +int parse_config(struct fp_config _options[], + const char *_path, + int (*_unknown)(struct fp_config *_option, + uint32_t _line, char *_directive, char *_value), + uint16_t _processing_options); +struct fp_config *get_config_option(struct fp_config _options[], + const char *_directive); +__END_DECLS + +#endif /* _FIGPAR_H_ */ Property changes on: stable/10/lib/libfigpar/figpar.h ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: stable/10/lib/libfigpar/string_m.c =================================================================== --- stable/10/lib/libfigpar/string_m.c (nonexistent) +++ stable/10/lib/libfigpar/string_m.c (revision 275040) @@ -0,0 +1,309 @@ +/*- + * Copyright (c) 2001-2014 Devin Teske + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include + +#include +#include +#include +#include +#include + +#include "string_m.h" + +/* + * Counts the number of occurrences of one string that appear in the source + * string. Return value is the total count. + * + * An example use would be if you need to know how large a block of memory + * needs to be for a replaceall() series. + */ +unsigned int +strcount(const char *source, const char *find) +{ + const char *p = source; + size_t flen; + unsigned int n = 0; + + /* Both parameters are required */ + if (source == NULL || find == NULL) + return (0); + + /* Cache the length of find element */ + flen = strlen(find); + if (strlen(source) == 0 || flen == 0) + return (0); + + /* Loop until the end of the string */ + while (*p != '\0') { + if (strncmp(p, find, flen) == 0) { /* found an instance */ + p += flen; + n++; + } else + p++; + } + + return (n); +} + +/* + * Replaces all occurrences of `find' in `source' with `replace'. + * + * You should not pass a string constant as the first parameter, it needs to be + * a pointer to an allocated block of memory. The block of memory that source + * points to should be large enough to hold the result. If the length of the + * replacement string is greater than the length of the find string, the result + * will be larger than the original source string. To allocate enough space for + * the result, use the function strcount() declared above to determine the + * number of occurrences and how much larger the block size needs to be. + * + * If source is not large enough, the application will crash. The return value + * is the length (in bytes) of the result. + * + * When an error occurs, -1 is returned and the global variable errno is set + * accordingly. Returns zero on success. + */ +int +replaceall(char *source, const char *find, const char *replace) +{ + char *p; + char *t; + char *temp; + size_t flen; + size_t rlen; + size_t slen; + uint32_t n = 0; + + errno = 0; /* reset global error number */ + + /* Check that we have non-null parameters */ + if (source == NULL) + return (0); + if (find == NULL) + return (strlen(source)); + + /* Cache the length of the strings */ + slen = strlen(source); + flen = strlen(find); + rlen = replace ? strlen(replace) : 0; + + /* Cases where no replacements need to be made */ + if (slen == 0 || flen == 0 || slen < flen) + return (slen); + + /* If replace is longer than find, we'll need to create a temp copy */ + if (rlen > flen) { + temp = malloc(slen + 1); + if (errno != 0) /* could not allocate memory */ + return (-1); + strcpy(temp, source); + } else + temp = source; + + /* Reconstruct the string with the replacements */ + p = source; t = temp; /* position elements */ + + while (*t != '\0') { + if (strncmp(t, find, flen) == 0) { + /* found an occurrence */ + for (n = 0; replace && replace[n]; n++) + *p++ = replace[n]; + t += flen; + } else + *p++ = *t++; /* copy character and increment */ + } + + /* Terminate the string */ + *p = '\0'; + + /* Free the temporary allocated memory */ + if (temp != source) + free(temp); + + /* Return the length of the completed string */ + return (strlen(source)); +} + +/* + * Expands escape sequences in a buffer pointed to by `source'. This function + * steps through each character, and converts escape sequences such as "\n", + * "\r", "\t" and others into their respective meanings. + * + * You should not pass a string constant or literal to this function or the + * program will likely segmentation fault when it tries to modify the data. + * + * The string length will either shorten or stay the same depending on whether + * any escape sequences were converted but the amount of memory allocated does + * not change. + * + * Interpreted sequences are: + * + * \0NNN character with octal value NNN (0 to 3 digits) + * \N character with octal value N (0 thru 7) + * \a alert (BEL) + * \b backslash + * \f form feed + * \n new line + * \r carriage return + * \t horizontal tab + * \v vertical tab + * \xNN byte with hexadecimal value NN (1 to 2 digits) + * + * All other sequences are unescaped (ie. '\"' and '\#'). + */ +void strexpand(char *source) +{ + uint8_t c; + char *chr; + char *pos; + char d[4]; + + /* Initialize position elements */ + pos = chr = source; + + /* Loop until we hit the end of the string */ + while (*pos != '\0') { + if (*chr != '\\') { + *pos = *chr; /* copy character to current offset */ + pos++; + chr++; + continue; + } + + /* Replace the backslash with the correct character */ + switch (*++chr) { + case 'a': *pos = '\a'; break; /* bell/alert (BEL) */ + case 'b': *pos = '\b'; break; /* backspace */ + case 'f': *pos = '\f'; break; /* form feed */ + case 'n': *pos = '\n'; break; /* new line */ + case 'r': *pos = '\r'; break; /* carriage return */ + case 't': *pos = '\t'; break; /* horizontal tab */ + case 'v': *pos = '\v'; break; /* vertical tab */ + case 'x': /* hex value (1 to 2 digits)(\xNN) */ + d[2] = '\0'; /* pre-terminate the string */ + + /* verify next two characters are hex */ + d[0] = isxdigit(*(chr+1)) ? *++chr : '\0'; + if (d[0] != '\0') + d[1] = isxdigit(*(chr+1)) ? *++chr : '\0'; + + /* convert the characters to decimal */ + c = (uint8_t)strtoul(d, 0, 16); + + /* assign the converted value */ + *pos = (c != 0 || d[0] == '0') ? c : *++chr; + break; + case '0': /* octal value (0 to 3 digits)(\0NNN) */ + d[3] = '\0'; /* pre-terminate the string */ + + /* verify next three characters are octal */ + d[0] = (isdigit(*(chr+1)) && *(chr+1) < '8') ? + *++chr : '\0'; + if (d[0] != '\0') + d[1] = (isdigit(*(chr+1)) && *(chr+1) < '8') ? + *++chr : '\0'; + if (d[1] != '\0') + d[2] = (isdigit(*(chr+1)) && *(chr+1) < '8') ? + *++chr : '\0'; + + /* convert the characters to decimal */ + c = (uint8_t)strtoul(d, 0, 8); + + /* assign the converted value */ + *pos = c; + break; + default: /* single octal (\0..7) or unknown sequence */ + if (isdigit(*chr) && *chr < '8') { + d[0] = *chr; + d[1] = '\0'; + *pos = (uint8_t)strtoul(d, 0, 8); + } else + *pos = *chr; + } + + /* Increment to next offset, possible next escape sequence */ + pos++; + chr++; + } +} + +/* + * Expand only the escaped newlines in a buffer pointed to by `source'. This + * function steps through each character, and converts the "\n" sequence into + * a literal newline and the "\\n" sequence into "\n". + * + * You should not pass a string constant or literal to this function or the + * program will likely segmentation fault when it tries to modify the data. + * + * The string length will either shorten or stay the same depending on whether + * any escaped newlines were converted but the amount of memory allocated does + * not change. + */ +void strexpandnl(char *source) +{ + uint8_t backslash = 0; + char *cp1; + char *cp2; + + /* Replace '\n' with literal in dprompt */ + cp1 = cp2 = source; + while (*cp2 != '\0') { + *cp1 = *cp2; + if (*cp2 == '\\') + backslash++; + else if (*cp2 != 'n') + backslash = 0; + else if (backslash > 0) { + *(--cp1) = (backslash & 1) == 1 ? '\n' : 'n'; + backslash = 0; + } + cp1++; + cp2++; + } + *cp1 = *cp2; +} + +/* + * Convert a string to lower case. You should not pass a string constant to + * this function. Only pass pointers to allocated memory with null terminated + * string data. + */ +void +strtolower(char *source) +{ + char *p = source; + + if (source == NULL) + return; + + while (*p != '\0') { + *p = tolower(*p); + p++; /* would have just used `*p++' but gcc 3.x warns */ + } +} Property changes on: stable/10/lib/libfigpar/string_m.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: stable/10/lib/libfigpar/string_m.h =================================================================== --- stable/10/lib/libfigpar/string_m.h (nonexistent) +++ stable/10/lib/libfigpar/string_m.h (revision 275040) @@ -0,0 +1,43 @@ +/*- + * Copyright (c) 2001-2014 Devin Teske + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _STRING_M_H_ +#define _STRING_M_H_ + +#include + +__BEGIN_DECLS +void strexpand(char *_source); +void strexpandnl(char *_source); +void strtolower(char *_source); +int replaceall(char *_source, const char *_find, + const char *_replace); +unsigned int strcount(const char *_source, const char *_find); +__END_DECLS + +#endif /* !_STRING_M_H_ */ Property changes on: stable/10/lib/libfigpar/string_m.h ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: stable/10/share/mk/bsd.libnames.mk =================================================================== --- stable/10/share/mk/bsd.libnames.mk (revision 275039) +++ stable/10/share/mk/bsd.libnames.mk (revision 275040) @@ -1,175 +1,177 @@ # $FreeBSD$ # The include file define library names. # Other include files (e.g. bsd.prog.mk, bsd.lib.mk) include this # file where necessary. .if !target(____) .error bsd.libnames.mk cannot be included directly. .endif LIBCRT0?= ${DESTDIR}${LIBDIR}/crt0.o LIBALIAS?= ${DESTDIR}${LIBDIR}/libalias.a LIBARCHIVE?= ${DESTDIR}${LIBDIR}/libarchive.a LIBASN1?= ${DESTDIR}${LIBDIR}/libasn1.a LIBATF_C?= ${DESTDIR}${LIBPRIVATEDIR}/libatf-c.a LIBATF_CXX?= ${DESTDIR}${LIBPRIVATEDIR}/libatf-c++.a LIBATM?= ${DESTDIR}${LIBDIR}/libatm.a LIBAUDITD?= ${DESTDIR}${LIBDIR}/libauditd.a LIBAVL?= ${DESTDIR}${LIBDIR}/libavl.a LIBBEGEMOT?= ${DESTDIR}${LIBDIR}/libbegemot.a LIBBLUETOOTH?= ${DESTDIR}${LIBDIR}/libbluetooth.a LIBBSDXML?= ${DESTDIR}${LIBDIR}/libbsdxml.a LIBBSM?= ${DESTDIR}${LIBDIR}/libbsm.a LIBBSNMP?= ${DESTDIR}${LIBDIR}/libbsnmp.a LIBBZ2?= ${DESTDIR}${LIBDIR}/libbz2.a .if ${MK_LIBCPLUSPLUS} != "no" LIBCXXRT?= ${DESTDIR}${LIBDIR}/libcxxrt.a LIBCPLUSPLUS?= ${DESTDIR}${LIBDIR}/libc++.a .endif LIBC?= ${DESTDIR}${LIBDIR}/libc.a LIBC_PIC?= ${DESTDIR}${LIBDIR}/libc_pic.a LIBCALENDAR?= ${DESTDIR}${LIBDIR}/libcalendar.a LIBCAM?= ${DESTDIR}${LIBDIR}/libcam.a LIBCOM_ERR?= ${DESTDIR}${LIBDIR}/libcom_err.a LIBCOMPAT?= ${DESTDIR}${LIBDIR}/libcompat.a LIBCRYPT?= ${DESTDIR}${LIBDIR}/libcrypt.a LIBCRYPTO?= ${DESTDIR}${LIBDIR}/libcrypto.a LIBCTF?= ${DESTDIR}${LIBDIR}/libctf.a LIBCURSES?= ${DESTDIR}${LIBDIR}/libcurses.a LIBDEVINFO?= ${DESTDIR}${LIBDIR}/libdevinfo.a LIBDEVSTAT?= ${DESTDIR}${LIBDIR}/libdevstat.a LIBDIALOG?= ${DESTDIR}${LIBDIR}/libdialog.a LIBDNS?= ${DESTDIR}${LIBDIR}/libdns.a +LIBDPV?= ${DESTDIR}${LIBDIR}/libdpv.a LIBDTRACE?= ${DESTDIR}${LIBDIR}/libdtrace.a LIBDWARF?= ${DESTDIR}${LIBDIR}/libdwarf.a LIBEDIT?= ${DESTDIR}${LIBDIR}/libedit.a LIBELF?= ${DESTDIR}${LIBDIR}/libelf.a LIBEXECINFO?= ${DESTDIR}${LIBDIR}/libexecinfo.a LIBFETCH?= ${DESTDIR}${LIBDIR}/libfetch.a +LIBFIGPAR?= ${DESTDIR}${LIBDIR}/libfigpar.a LIBFL?= "don't use LIBFL, use LIBL" LIBFORM?= ${DESTDIR}${LIBDIR}/libform.a LIBG2C?= ${DESTDIR}${LIBDIR}/libg2c.a LIBGCC?= ${DESTDIR}${LIBDIR}/libgcc.a LIBGCC_PIC?= ${DESTDIR}${LIBDIR}/libgcc_pic.a LIBGEOM?= ${DESTDIR}${LIBDIR}/libgeom.a LIBGNUREGEX?= ${DESTDIR}${LIBDIR}/libgnuregex.a LIBGSSAPI?= ${DESTDIR}${LIBDIR}/libgssapi.a LIBGSSAPI_KRB5?= ${DESTDIR}${LIBDIR}/libgssapi_krb5.a LIBHDB?= ${DESTDIR}${LIBDIR}/libhdb.a LIBHISTORY?= ${DESTDIR}${LIBDIR}/libhistory.a LIBHEIMBASE?= ${DESTDIR}${LIBDIR}/libheimbase.a LIBHEIMIPCC?= ${DESTDIR}${LIBPRIVATEDIR}/libheimipcc.a LIBHEIMIPCS?= ${DESTDIR}${LIBPRIVATEDIR}/libheimipcs.a LIBHEIMNTLM?= ${DESTDIR}${LIBDIR}/libheimntlm.a LIBHEIMSQLITE?= ${DESTDIR}${LIBDIR}/libheimsqlite.a LIBHX509?= ${DESTDIR}${LIBDIR}/libhx509.a LIBIPSEC?= ${DESTDIR}${LIBDIR}/libipsec.a .if ${MK_IPX} != "no" LIBIPX?= ${DESTDIR}${LIBDIR}/libipx.a .endif LIBJAIL?= ${DESTDIR}${LIBDIR}/libjail.a LIBKADM5CLNT?= ${DESTDIR}${LIBDIR}/libkadm5clnt.a LIBKADM5SRV?= ${DESTDIR}${LIBDIR}/libkadm5srv.a LIBKAFS5?= ${DESTDIR}${LIBDIR}/libkafs5.a LIBKDC?= ${DESTDIR}${LIBDIR}/libkdc.a LIBKEYCAP?= ${DESTDIR}${LIBDIR}/libkeycap.a LIBKICONV?= ${DESTDIR}${LIBDIR}/libkiconv.a LIBKRB5?= ${DESTDIR}${LIBDIR}/libkrb5.a LIBKVM?= ${DESTDIR}${LIBDIR}/libkvm.a LIBL?= ${DESTDIR}${LIBDIR}/libl.a .if ${MK_LDNS} != "no" LIBLDNS?= ${DESTDIR}${LIBPRIVATEDIR}/libldns.a .endif LIBLN?= "don't use LIBLN, use LIBL" LIBLZMA?= ${DESTDIR}${LIBDIR}/liblzma.a LIBM?= ${DESTDIR}${LIBDIR}/libm.a LIBMAGIC?= ${DESTDIR}${LIBDIR}/libmagic.a LIBMD?= ${DESTDIR}${LIBDIR}/libmd.a LIBMEMSTAT?= ${DESTDIR}${LIBDIR}/libmemstat.a LIBMENU?= ${DESTDIR}${LIBDIR}/libmenu.a .if ${MK_SENDMAIL} != "no" LIBMILTER?= ${DESTDIR}${LIBDIR}/libmilter.a .endif LIBMP?= ${DESTDIR}${LIBDIR}/libmp.a LIBNCURSES?= ${DESTDIR}${LIBDIR}/libncurses.a LIBNCURSESW?= ${DESTDIR}${LIBDIR}/libncursesw.a LIBNETGRAPH?= ${DESTDIR}${LIBDIR}/libnetgraph.a LIBNGATM?= ${DESTDIR}${LIBDIR}/libngatm.a LIBNVPAIR?= ${DESTDIR}${LIBDIR}/libnvpair.a LIBOPIE?= ${DESTDIR}${LIBDIR}/libopie.a # The static PAM library doesn't know its secondary dependencies, # so we have to specify them explicitly. LIBPAM?= ${DESTDIR}${LIBDIR}/libpam.a MINUSLPAM= -lpam .if defined(LDFLAGS) && !empty(LDFLAGS:M-static) .if ${MK_KERBEROS} != "no" LIBPAM+= ${LIBKRB5} ${LIBHX509} ${LIBASN1} ${LIBCRYPTO} ${LIBCRYPT} \ ${LIBROKEN} ${LIBCOM_ERR} MINUSLPAM+= -lkrb5 -lhx509 -lasn1 -lcrypto -lcrypt -lroken -lcom_err .endif LIBPAM+= ${LIBRADIUS} ${LIBTACPLUS} ${LIBCRYPT} \ ${LIBUTIL} ${LIBOPIE} ${LIBMD} MINUSLPAM+= -lradius -ltacplus -lcrypt \ -lutil -lopie -lmd .if ${MK_OPENSSH} != "no" LIBPAM+= ${LIBSSH} ${LIBCRYPTO} ${LIBCRYPT} MINUSLPAM+= -lssh -lcrypto -lcrypt .endif .if ${MK_NIS} != "no" LIBPAM+= ${LIBYPCLNT} MINUSLPAM+= -lypclnt .endif .endif LIBPANEL?= ${DESTDIR}${LIBDIR}/libpanel.a LIBPCAP?= ${DESTDIR}${LIBDIR}/libpcap.a LIBPMC?= ${DESTDIR}${LIBDIR}/libpmc.a LIBPROC?= ${DESTDIR}${LIBDIR}/libproc.a LIBPROCSTAT?= ${DESTDIR}${LIBDIR}/libprocstat.a LIBPTHREAD?= ${DESTDIR}${LIBDIR}/libpthread.a LIBRADIUS?= ${DESTDIR}${LIBDIR}/libradius.a LIBREADLINE?= ${DESTDIR}${LIBDIR}/libreadline.a LIBROKEN?= ${DESTDIR}${LIBDIR}/libroken.a LIBRPCSVC?= ${DESTDIR}${LIBDIR}/librpcsvc.a LIBRPCSEC_GSS?= ${DESTDIR}${LIBDIR}/librpcsec_gss.a LIBRT?= ${DESTDIR}${LIBDIR}/librt.a LIBRTLD_DB?= ${DESTDIR}${LIBDIR}/librtld_db.a LIBSBUF?= ${DESTDIR}${LIBDIR}/libsbuf.a LIBSDP?= ${DESTDIR}${LIBDIR}/libsdp.a LIBSMB?= ${DESTDIR}${LIBDIR}/libsmb.a LIBSSH?= ${DESTDIR}${LIBPRIVATEDIR}/libssh.a LIBSSL?= ${DESTDIR}${LIBDIR}/libssl.a LIBSSP_NONSHARED?= ${DESTDIR}${LIBDIR}/libssp_nonshared.a LIBSTAND?= ${DESTDIR}${LIBDIR}/libstand.a LIBSTDCPLUSPLUS?= ${DESTDIR}${LIBDIR}/libstdc++.a LIBTACPLUS?= ${DESTDIR}${LIBDIR}/libtacplus.a LIBTERMCAP?= ${DESTDIR}${LIBDIR}/libtermcap.a LIBTERMLIB?= "don't use LIBTERMLIB, use LIBTERMCAP" LIBTINFO?= "don't use LIBTINFO, use LIBNCURSES" LIBUCL?= ${DESTDIR}${LIBPRIVATEDIR}/libucl.a LIBUFS?= ${DESTDIR}${LIBDIR}/libufs.a LIBUGIDFW?= ${DESTDIR}${LIBDIR}/libugidfw.a LIBUMEM?= ${DESTDIR}${LIBDIR}/libumem.a .if ${MK_UNBOUND} != "no" LIBUNBOUND?= ${DESTDIR}${LIBPRIVATEDIR}/libunbound.a .endif LIBUSBHID?= ${DESTDIR}${LIBDIR}/libusbhid.a LIBUSB?= ${DESTDIR}${LIBDIR}/libusb.a LIBULOG?= ${DESTDIR}${LIBDIR}/libulog.a LIBUTIL?= ${DESTDIR}${LIBDIR}/libutil.a LIBUUTIL?= ${DESTDIR}${LIBDIR}/libuutil.a LIBVGL?= ${DESTDIR}${LIBDIR}/libvgl.a LIBVMMAPI?= ${DESTDIR}${LIBDIR}/libvmmapi.a LIBWIND?= ${DESTDIR}${LIBDIR}/libwind.a LIBWRAP?= ${DESTDIR}${LIBDIR}/libwrap.a LIBXPG4?= ${DESTDIR}${LIBDIR}/libxpg4.a LIBY?= ${DESTDIR}${LIBDIR}/liby.a LIBYAML?= ${DESTDIR}${LIBPRIVATEDIR}/libyaml.a LIBYPCLNT?= ${DESTDIR}${LIBDIR}/libypclnt.a LIBZ?= ${DESTDIR}${LIBDIR}/libz.a LIBZFS?= ${DESTDIR}${LIBDIR}/libzfs.a LIBZFS_CORE?= ${DESTDIR}${LIBDIR}/libzfs_core.a LIBZPOOL?= ${DESTDIR}${LIBDIR}/libzpool.a Index: stable/10/sys/sys/param.h =================================================================== --- stable/10/sys/sys/param.h (revision 275039) +++ stable/10/sys/sys/param.h (revision 275040) @@ -1,347 +1,347 @@ /*- * Copyright (c) 1982, 1986, 1989, 1993 * The Regents of the University of California. All rights reserved. * (c) UNIX System Laboratories, Inc. * All or some portions of this file are derived from material licensed * to the University of California by American Telephone and Telegraph * Co. or Unix System Laboratories, Inc. and are reproduced herein with * the permission of UNIX System Laboratories, Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)param.h 8.3 (Berkeley) 4/4/95 * $FreeBSD$ */ #ifndef _SYS_PARAM_H_ #define _SYS_PARAM_H_ #include #define BSD 199506 /* System version (year & month). */ #define BSD4_3 1 #define BSD4_4 1 /* * __FreeBSD_version numbers are documented in the Porter's Handbook. * If you bump the version for any reason, you should update the documentation * there. * Currently this lives here in the doc/ repository: * * head/en_US.ISO8859-1/books/porters-handbook/book.xml * * scheme is: Rxx * 'R' is in the range 0 to 4 if this is a release branch or * x.0-CURRENT before RELENG_*_0 is created, otherwise 'R' is * in the range 5 to 9. */ #undef __FreeBSD_version -#define __FreeBSD_version 1001502 /* Master, propagated to newvers */ +#define __FreeBSD_version 1001503 /* Master, propagated to newvers */ /* * __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD, * which by definition is always true on FreeBSD. This macro is also defined * on other systems that use the kernel of FreeBSD, such as GNU/kFreeBSD. * * It is tempting to use this macro in userland code when we want to enable * kernel-specific routines, and in fact it's fine to do this in code that * is part of FreeBSD itself. However, be aware that as presence of this * macro is still not widespread (e.g. older FreeBSD versions, 3rd party * compilers, etc), it is STRONGLY DISCOURAGED to check for this macro in * external applications without also checking for __FreeBSD__ as an * alternative. */ #undef __FreeBSD_kernel__ #define __FreeBSD_kernel__ #ifdef _KERNEL #define P_OSREL_SIGWAIT 700000 #define P_OSREL_SIGSEGV 700004 #define P_OSREL_MAP_ANON 800104 #define P_OSREL_MAJOR(x) ((x) / 100000) #endif #ifndef LOCORE #include #endif /* * Machine-independent constants (some used in following include files). * Redefined constants are from POSIX 1003.1 limits file. * * MAXCOMLEN should be >= sizeof(ac_comm) (see ) */ #include #define MAXCOMLEN 19 /* max command name remembered */ #define MAXINTERP PATH_MAX /* max interpreter file name length */ #define MAXLOGNAME 33 /* max login name length (incl. NUL) */ #define MAXUPRC CHILD_MAX /* max simultaneous processes */ #define NCARGS ARG_MAX /* max bytes for an exec function */ #define NGROUPS (NGROUPS_MAX+1) /* max number groups */ #define NOFILE OPEN_MAX /* max open files per process */ #define NOGROUP 65535 /* marker for empty group set member */ #define MAXHOSTNAMELEN 256 /* max hostname size */ #define SPECNAMELEN 63 /* max length of devicename */ /* More types and definitions used throughout the kernel. */ #ifdef _KERNEL #include #include #ifndef LOCORE #include #include #endif #ifndef FALSE #define FALSE 0 #endif #ifndef TRUE #define TRUE 1 #endif #endif #ifndef _KERNEL /* Signals. */ #include #endif /* Machine type dependent parameters. */ #include #ifndef _KERNEL #include #endif #ifndef DEV_BSHIFT #define DEV_BSHIFT 9 /* log2(DEV_BSIZE) */ #endif #define DEV_BSIZE (1<>PAGE_SHIFT) #endif /* * btodb() is messy and perhaps slow because `bytes' may be an off_t. We * want to shift an unsigned type to avoid sign extension and we don't * want to widen `bytes' unnecessarily. Assume that the result fits in * a daddr_t. */ #ifndef btodb #define btodb(bytes) /* calculates (bytes / DEV_BSIZE) */ \ (sizeof (bytes) > sizeof(long) \ ? (daddr_t)((unsigned long long)(bytes) >> DEV_BSHIFT) \ : (daddr_t)((unsigned long)(bytes) >> DEV_BSHIFT)) #endif #ifndef dbtob #define dbtob(db) /* calculates (db * DEV_BSIZE) */ \ ((off_t)(db) << DEV_BSHIFT) #endif #define PRIMASK 0x0ff #define PCATCH 0x100 /* OR'd with pri for tsleep to check signals */ #define PDROP 0x200 /* OR'd with pri to stop re-entry of interlock mutex */ #define NZERO 0 /* default "nice" */ #define NBBY 8 /* number of bits in a byte */ #define NBPW sizeof(int) /* number of bytes per word (integer) */ #define CMASK 022 /* default file mask: S_IWGRP|S_IWOTH */ #define NODEV (dev_t)(-1) /* non-existent device */ /* * File system parameters and macros. * * MAXBSIZE - Filesystems are made out of blocks of at most MAXBSIZE bytes * per block. MAXBSIZE may be made larger without effecting * any existing filesystems as long as it does not exceed MAXPHYS, * and may be made smaller at the risk of not being able to use * filesystems which require a block size exceeding MAXBSIZE. * * BKVASIZE - Nominal buffer space per buffer, in bytes. BKVASIZE is the * minimum KVM memory reservation the kernel is willing to make. * Filesystems can of course request smaller chunks. Actual * backing memory uses a chunk size of a page (PAGE_SIZE). * * If you make BKVASIZE too small you risk seriously fragmenting * the buffer KVM map which may slow things down a bit. If you * make it too big the kernel will not be able to optimally use * the KVM memory reserved for the buffer cache and will wind * up with too-few buffers. * * The default is 16384, roughly 2x the block size used by a * normal UFS filesystem. */ #define MAXBSIZE 65536 /* must be power of 2 */ #define BKVASIZE 16384 /* must be power of 2 */ #define BKVAMASK (BKVASIZE-1) /* * MAXPATHLEN defines the longest permissible path length after expanding * symbolic links. It is used to allocate a temporary buffer from the buffer * pool in which to do the name expansion, hence should be a power of two, * and must be less than or equal to MAXBSIZE. MAXSYMLINKS defines the * maximum number of symbolic links that may be expanded in a path name. * It should be set high enough to allow all legitimate uses, but halt * infinite loops reasonably quickly. */ #define MAXPATHLEN PATH_MAX #define MAXSYMLINKS 32 /* Bit map related macros. */ #define setbit(a,i) (((unsigned char *)(a))[(i)/NBBY] |= 1<<((i)%NBBY)) #define clrbit(a,i) (((unsigned char *)(a))[(i)/NBBY] &= ~(1<<((i)%NBBY))) #define isset(a,i) \ (((const unsigned char *)(a))[(i)/NBBY] & (1<<((i)%NBBY))) #define isclr(a,i) \ ((((const unsigned char *)(a))[(i)/NBBY] & (1<<((i)%NBBY))) == 0) /* Macros for counting and rounding. */ #ifndef howmany #define howmany(x, y) (((x)+((y)-1))/(y)) #endif #define nitems(x) (sizeof((x)) / sizeof((x)[0])) #define rounddown(x, y) (((x)/(y))*(y)) #define rounddown2(x, y) ((x)&(~((y)-1))) /* if y is power of two */ #define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) /* to any y */ #define roundup2(x, y) (((x)+((y)-1))&(~((y)-1))) /* if y is powers of two */ #define powerof2(x) ((((x)-1)&(x))==0) /* Macros for min/max. */ #define MIN(a,b) (((a)<(b))?(a):(b)) #define MAX(a,b) (((a)>(b))?(a):(b)) #ifdef _KERNEL /* * Basic byte order function prototypes for non-inline functions. */ #ifndef LOCORE #ifndef _BYTEORDER_PROTOTYPED #define _BYTEORDER_PROTOTYPED __BEGIN_DECLS __uint32_t htonl(__uint32_t); __uint16_t htons(__uint16_t); __uint32_t ntohl(__uint32_t); __uint16_t ntohs(__uint16_t); __END_DECLS #endif #endif #ifndef lint #ifndef _BYTEORDER_FUNC_DEFINED #define _BYTEORDER_FUNC_DEFINED #define htonl(x) __htonl(x) #define htons(x) __htons(x) #define ntohl(x) __ntohl(x) #define ntohs(x) __ntohs(x) #endif /* !_BYTEORDER_FUNC_DEFINED */ #endif /* lint */ #endif /* _KERNEL */ /* * Scale factor for scaled integers used to count %cpu time and load avgs. * * The number of CPU `tick's that map to a unique `%age' can be expressed * by the formula (1 / (2 ^ (FSHIFT - 11))). The maximum load average that * can be calculated (assuming 32 bits) can be closely approximated using * the formula (2 ^ (2 * (16 - FSHIFT))) for (FSHIFT < 15). * * For the scheduler to maintain a 1:1 mapping of CPU `tick' to `%age', * FSHIFT must be at least 11; this gives us a maximum load avg of ~1024. */ #define FSHIFT 11 /* bits to right of fixed binary point */ #define FSCALE (1<> (PAGE_SHIFT - DEV_BSHIFT)) #define ctodb(db) /* calculates pages to devblks */ \ ((db) << (PAGE_SHIFT - DEV_BSHIFT)) /* * Old spelling of __containerof(). */ #define member2struct(s, m, x) \ ((struct s *)(void *)((char *)(x) - offsetof(struct s, m))) /* * Access a variable length array that has been declared as a fixed * length array. */ #define __PAST_END(array, offset) (((__typeof__(*(array)) *)(array))[offset]) #endif /* _SYS_PARAM_H_ */ Index: stable/10/usr.bin/Makefile =================================================================== --- stable/10/usr.bin/Makefile (revision 275039) +++ stable/10/usr.bin/Makefile (revision 275040) @@ -1,388 +1,389 @@ # From: @(#)Makefile 8.3 (Berkeley) 1/7/94 # $FreeBSD$ .include # XXX MISSING: deroff diction graph learn plot # spell spline struct xsend # XXX Use GNU versions: diff ld patch # Moved to secure: bdes # SUBDIR= alias \ apply \ asa \ awk \ banner \ basename \ brandelf \ bsdiff \ bzip2 \ bzip2recover \ cap_mkdb \ chat \ chpass \ cksum \ ${_clang} \ cmp \ col \ colldef \ colrm \ column \ comm \ compress \ cpuset \ csplit \ ctlstat \ cut \ dirname \ + dpv \ du \ ee \ elf2aout \ elfdump \ enigma \ env \ expand \ false \ fetch \ file \ find \ finger \ fmt \ fold \ fstat \ fsync \ ftp \ gcore \ gencat \ getconf \ getent \ getopt \ grep \ gzip \ head \ hexdump \ ${_iconv} \ id \ ipcrm \ ipcs \ iscsictl \ join \ jot \ ${_kdump} \ keylogin \ keylogout \ killall \ ktrace \ ktrdump \ lam \ lastcomm \ ldd \ leave \ less \ lessecho \ lesskey \ limits \ locale \ lock \ lockf \ logger \ login \ logins \ logname \ look \ lorder \ lsvfs \ lzmainfo \ m4 \ ${_makewhatis} \ ${_man} \ mandoc \ mesg \ minigzip \ ministat \ ${_mkcsmapper} \ mkdep \ ${_mkesdb} \ mkfifo \ mkimg \ mklocale \ mktemp \ mkulzma \ mkuzip \ mt \ ncal \ netstat \ newgrp \ nfsstat \ nice \ nl \ nohup \ opieinfo \ opiekey \ opiepasswd \ pagesize \ passwd \ paste \ patch \ pathchk \ perror \ pr \ printenv \ printf \ procstat \ protect \ rctl \ renice \ rev \ revoke \ rpcinfo \ rs \ rup \ rusers \ rwall \ script \ sed \ send-pr \ seq \ shar \ showmount \ sockstat \ sort \ split \ stat \ stdbuf \ su \ systat \ tabs \ tail \ talk \ tar \ tcopy \ tee \ ${_tests} \ tftp \ time \ tip \ top \ touch \ tput \ tr \ true \ truncate \ ${_truss} \ tset \ tsort \ tty \ uname \ unexpand \ uniq \ unzip \ units \ unvis \ uudecode \ uuencode \ vi \ vis \ vmstat \ w \ wall \ wc \ what \ whereis \ which \ whois \ write \ xargs \ xinstall \ ${_xlint} \ ${_xstr} \ xz \ xzdec \ ${_yacc} \ yes \ ${_ypcat} \ ${_ypmatch} \ ${_ypwhich} # NB: keep these sorted by MK_* knobs .if ${MK_AT} != "no" SUBDIR+= at .endif .if ${MK_ATM} != "no" SUBDIR+= atm .endif .if ${MK_BLUETOOTH} != "no" SUBDIR+= bluetooth .endif .if ${MK_BSD_CPIO} != "no" SUBDIR+= cpio .endif .if ${MK_CALENDAR} != "no" SUBDIR+= calendar .endif .if ${MK_CLANG} != "no" _clang= clang .endif .if ${MK_GPL_DTC} != "yes" SUBDIR+= dtc .endif .if ${MK_GROFF} != "no" SUBDIR+= vgrind .endif .if ${MK_HESIOD} != "no" SUBDIR+= hesinfo .endif .if ${MK_ICONV} != "no" _iconv= iconv _mkcsmapper= mkcsmapper _mkesdb= mkesdb .endif .if ${MK_KDUMP} != "no" SUBDIR+= kdump SUBDIR+= truss .endif .if ${MK_KERBEROS_SUPPORT} != "no" SUBDIR+= compile_et .endif .if ${MK_LDNS_UTILS} != "no" SUBDIR+= drill SUBDIR+= host .endif .if ${MK_LIBTHR} != "no" SUBDIR+= csup .endif .if ${MK_LOCATE} != "no" SUBDIR+= locate .endif # XXX msgs? .if ${MK_MAIL} != "no" SUBDIR+= biff SUBDIR+= from SUBDIR+= mail SUBDIR+= msgs .endif .if ${MK_MAKE} != "no" .if ${MK_BMAKE} != "no" SUBDIR+= bmake .else SUBDIR+= make .endif .endif .if ${MK_MAN_UTILS} != "no" SUBDIR+= catman _makewhatis= makewhatis _man= man .endif .if ${MK_NETCAT} != "no" SUBDIR+= nc .endif .if ${MK_NIS} != "no" SUBDIR+= ypcat SUBDIR+= ypmatch SUBDIR+= ypwhich .endif .if ${MK_OPENSSH} != "no" SUBDIR+= ssh-copy-id .endif .if ${MK_OPENSSL} != "no" SUBDIR+= bc SUBDIR+= chkey SUBDIR+= dc SUBDIR+= newkey .endif .if ${MK_QUOTAS} != "no" SUBDIR+= quota .endif .if ${MK_RCMDS} != "no" SUBDIR+= rlogin SUBDIR+= rsh SUBDIR+= ruptime SUBDIR+= rwho .endif .if ${MK_SENDMAIL} != "no" SUBDIR+= vacation .endif .if ${MK_TELNET} != "no" SUBDIR+= telnet .endif .if ${MK_TESTS} != "no" _tests= tests .endif .if ${MK_TEXTPROC} != "no" SUBDIR+= checknr SUBDIR+= colcrt SUBDIR+= ul .endif .if ${MK_TOOLCHAIN} != "no" SUBDIR+= ar SUBDIR+= c89 SUBDIR+= c99 SUBDIR+= ctags SUBDIR+= file2c SUBDIR+= gprof SUBDIR+= indent SUBDIR+= lex SUBDIR+= mkstr SUBDIR+= rpcgen SUBDIR+= unifdef SUBDIR+= xlint SUBDIR+= xstr SUBDIR+= yacc .endif .if ${MK_VT} != "no" SUBDIR+= vtfontcvt .endif .if ${MK_USB} != "no" SUBDIR+= usbhidaction SUBDIR+= usbhidctl .endif .if ${MK_UTMPX} != "no" SUBDIR+= last SUBDIR+= users SUBDIR+= who .endif .if ${MK_SVN} == "yes" || ${MK_SVNLITE} == "yes" SUBDIR+= svn .endif .include SUBDIR:= ${SUBDIR:O} SUBDIR_PARALLEL= .include Index: stable/10/usr.bin/dpv/Makefile =================================================================== --- stable/10/usr.bin/dpv/Makefile (nonexistent) +++ stable/10/usr.bin/dpv/Makefile (revision 275040) @@ -0,0 +1,12 @@ +# $FreeBSD$ + +PROG= dpv + +CFLAGS+= -I${.CURDIR} + +DPADD= ${LIBDPV} ${LIBDIALOG} ${LIBFIGPAR} ${LIBNCURSESW} ${LIBUTIL} ${LIBM} +LDADD= -ldpv -ldialog -lfigpar -lncursesw -lutil -lm + +WARNS?= 6 + +.include Property changes on: stable/10/usr.bin/dpv/Makefile ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: stable/10/usr.bin/dpv/dpv.c =================================================================== --- stable/10/usr.bin/dpv/dpv.c (nonexistent) +++ stable/10/usr.bin/dpv/dpv.c (revision 275040) @@ -0,0 +1,541 @@ +/*- + * Copyright (c) 2013-2014 Devin Teske + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include + +#define _BSD_SOURCE /* to get dprintf() prototype in stdio.h below */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dpv_util.h" + +/* Debugging */ +static uint8_t debug = FALSE; + +/* Data to process */ +static struct dpv_file_node *file_list = NULL; +static unsigned int nfiles = 0; + +/* Data processing */ +static uint8_t line_mode = FALSE; +static uint8_t no_overrun = FALSE; +static char *buf = NULL; +static int fd = -1; +static int output_type = DPV_OUTPUT_NONE; +static size_t bsize; +static char rpath[PATH_MAX]; + +/* Extra display information */ +static uint8_t multiple = FALSE; /* `-m' */ +static char *pgm; /* set to argv[0] by main() */ + +/* Function prototypes */ +static void sig_int(int sig); +static void usage(void); +int main(int argc, char *argv[]); +static int operate_common(struct dpv_file_node *file, int out); +static int operate_on_bytes(struct dpv_file_node *file, int out); +static int operate_on_lines(struct dpv_file_node *file, int out); + +static int +operate_common(struct dpv_file_node *file, int out) +{ + struct stat sb; + + /* Open the file if necessary */ + if (fd < 0) { + if (multiple) { + /* Resolve the file path and attempt to open it */ + if (realpath(file->path, rpath) == 0 || + (fd = open(rpath, O_RDONLY)) < 0) { + warn("%s", file->path); + file->status = DPV_STATUS_FAILED; + return (-1); + } + } else { + /* Assume stdin, but if that's a TTY instead use the + * highest numbered file descriptor (obtained by + * generating new fd and then decrementing). + * + * NB: /dev/stdin should always be open(2)'able + */ + fd = STDIN_FILENO; + if (isatty(fd)) { + fd = open("/dev/stdin", O_RDONLY); + close(fd--); + } + + /* This answer might be wrong, if dpv(3) has (by + * request) opened an output file or pipe. If we + * told dpv(3) to open a file, subtract one from + * previous answer. If instead we told dpv(3) to + * prepare a pipe output, subtract two. + */ + switch(output_type) { + case DPV_OUTPUT_FILE: + fd -= 1; + break; + case DPV_OUTPUT_SHELL: + fd -= 2; + break; + } + } + } + + /* Allocate buffer if necessary */ + if (buf == NULL) { + /* Use output block size as buffer size if available */ + if (out >= 0) { + if (fstat(out, &sb) != 0) { + warn("%i", out); + file->status = DPV_STATUS_FAILED; + return (-1); + } + if (S_ISREG(sb.st_mode)) { + if (sysconf(_SC_PHYS_PAGES) > + PHYSPAGES_THRESHOLD) + bsize = MIN(BUFSIZE_MAX, MAXPHYS * 8); + else + bsize = BUFSIZE_SMALL; + } else + bsize = MAX(sb.st_blksize, + (blksize_t)sysconf(_SC_PAGESIZE)); + } else + bsize = MIN(BUFSIZE_MAX, MAXPHYS * 8); + + /* Attempt to allocate */ + if ((buf = malloc(bsize+1)) == NULL) { + end_dialog(); + err(EXIT_FAILURE, "Out of memory?!"); + } + } + + return (0); +} + +static int +operate_on_bytes(struct dpv_file_node *file, int out) +{ + int progress; + ssize_t r, w; + + if (operate_common(file, out) < 0) + return (-1); + + /* [Re-]Fill the buffer */ + if ((r = read(fd, buf, bsize)) <= 0) { + if (fd != STDIN_FILENO) + close(fd); + fd = -1; + file->status = DPV_STATUS_DONE; + return (100); + } + + /* [Re-]Dump the buffer */ + if (out >= 0) { + if ((w = write(out, buf, r)) < 0) { + end_dialog(); + err(EXIT_FAILURE, "output"); + } + fsync(out); + } + + dpv_overall_read += r; + file->read += r; + + /* Calculate percentage of completion (if possible) */ + if (file->length >= 0) { + progress = (file->read * 100 / (file->length > 0 ? + file->length : 1)); + + /* If no_overrun, do not return 100% until read >= length */ + if (no_overrun && progress == 100 && file->read < file->length) + progress--; + + return (progress); + } else + return (-1); +} + +static int +operate_on_lines(struct dpv_file_node *file, int out) +{ + char *p; + int progress; + ssize_t r, w; + + if (operate_common(file, out) < 0) + return (-1); + + /* [Re-]Fill the buffer */ + if ((r = read(fd, buf, bsize)) <= 0) { + if (fd != STDIN_FILENO) + close(fd); + fd = -1; + file->status = DPV_STATUS_DONE; + return (100); + } + buf[r] = '\0'; + + /* [Re-]Dump the buffer */ + if (out >= 0) { + if ((w = write(out, buf, r)) < 0) { + end_dialog(); + err(EXIT_FAILURE, "output"); + } + fsync(out); + } + + /* Process the buffer for number of lines */ + for (p = buf; p != NULL && *p != '\0';) + if ((p = strchr(p, '\n')) != NULL) + dpv_overall_read++, p++, file->read++; + + /* Calculate percentage of completion (if possible) */ + if (file->length >= 0) { + progress = (file->read * 100 / file->length); + + /* If no_overrun, do not return 100% until read >= length */ + if (no_overrun && progress == 100 && file->read < file->length) + progress--; + + return (progress); + } else + return (-1); +} + +/* + * Takes a list of names that are to correspond to input streams coming from + * stdin or fifos and produces necessary config to drive dpv(3) `--gauge' + * widget. If the `-d' flag is used, output is instead send to terminal + * standard output (and the output can then be saved to a file, piped into + * custom [X]dialog(1) invocation, or whatever. + */ +int +main(int argc, char *argv[]) +{ + char dummy; + int ch; + int n = 0; + size_t config_size = sizeof(struct dpv_config); + size_t file_node_size = sizeof(struct dpv_file_node); + struct dpv_config *config; + struct dpv_file_node *curfile; + struct sigaction act; + + pgm = argv[0]; /* store a copy of invocation name */ + + /* Allocate config structure */ + if ((config = malloc(config_size)) == NULL) + errx(EXIT_FAILURE, "Out of memory?!"); + memset((void *)(config), '\0', config_size); + + /* + * Process command-line options + */ + while ((ch = getopt(argc, argv, + "a:b:dDhi:I:lL:mn:No:p:P:t:TU:wx:X")) != -1) { + switch(ch) { + case 'a': /* additional message text to append */ + if (config->aprompt == NULL) { + config->aprompt = malloc(DPV_APROMPT_MAX); + if (config->aprompt == NULL) + errx(EXIT_FAILURE, "Out of memory?!"); + } + snprintf(config->aprompt, DPV_APROMPT_MAX, "%s", + optarg); + break; + case 'b': /* [X]dialog(1) backtitle */ + if (config->backtitle != NULL) + free((char *)config->backtitle); + config->backtitle = malloc(strlen(optarg) + 1); + if (config->backtitle == NULL) + errx(EXIT_FAILURE, "Out of memory?!"); + *(config->backtitle) = '\0'; + strcat(config->backtitle, optarg); + break; + case 'd': /* debugging */ + debug = TRUE; + config->debug = debug; + break; + case 'D': /* use dialog(1) instead of libdialog */ + config->display_type = DPV_DISPLAY_DIALOG; + break; + case 'h': /* help/usage */ + usage(); + break; /* NOTREACHED */ + case 'i': /* status line format string for single-file */ + config->status_solo = optarg; + break; + case 'I': /* status line format string for many-files */ + config->status_many = optarg; + break; + case 'l': /* Line mode */ + line_mode = TRUE; + break; + case 'L': /* custom label size */ + config->label_size = + (int)strtol(optarg, (char **)NULL, 10); + if (config->label_size == 0 && errno == EINVAL) + errx(EXIT_FAILURE, + "`-L' argument must be numeric"); + else if (config->label_size < -1) + config->label_size = -1; + break; + case 'm': /* enable multiple file arguments */ + multiple = TRUE; + break; + case 'o': /* `-o path' for sending data-read to file */ + output_type = DPV_OUTPUT_FILE; + config->output_type = DPV_OUTPUT_FILE; + config->output = optarg; + break; + case 'n': /* custom number of files per `page' */ + config->display_limit = + (int)strtol(optarg, (char **)NULL, 10); + if (config->display_limit == 0 && errno == EINVAL) + errx(EXIT_FAILURE, + "`-n' argument must be numeric"); + else if (config->display_limit < 0) + config->display_limit = -1; + break; + case 'N': /* No overrun (truncate reads of known-length) */ + no_overrun = TRUE; + config->options |= DPV_NO_OVERRUN; + break; + case 'p': /* additional message text to use as prefix */ + if (config->pprompt == NULL) { + config->pprompt = malloc(DPV_PPROMPT_MAX + 2); + if (config->pprompt == NULL) + errx(EXIT_FAILURE, "Out of memory?!"); + /* +2 is for implicit "\n" appended later */ + } + snprintf(config->pprompt, DPV_PPROMPT_MAX, "%s", + optarg); + break; + case 'P': /* custom size for mini-progressbar */ + config->pbar_size = + (int)strtol(optarg, (char **)NULL, 10); + if (config->pbar_size == 0 && errno == EINVAL) + errx(EXIT_FAILURE, + "`-P' argument must be numeric"); + else if (config->pbar_size < -1) + config->pbar_size = -1; + break; + case 't': /* [X]dialog(1) title */ + if (config->title != NULL) + free(config->title); + config->title = malloc(strlen(optarg) + 1); + if (config->title == NULL) + errx(EXIT_FAILURE, "Out of memory?!"); + *(config->title) = '\0'; + strcat(config->title, optarg); + break; + case 'T': /* test mode (don't read data, fake it) */ + config->options |= DPV_TEST_MODE; + break; + case 'U': /* updates per second */ + config->status_updates_per_second = + (int)strtol(optarg, (char **)NULL, 10); + if (config->status_updates_per_second == 0 && + errno == EINVAL) + errx(EXIT_FAILURE, + "`-U' argument must be numeric"); + break; + case 'w': /* `-p' and `-a' widths bump [X]dialog(1) width */ + config->options |= DPV_WIDE_MODE; + break; + case 'x': /* `-x cmd' for sending data-read to sh(1) code */ + output_type = DPV_OUTPUT_SHELL; + config->output_type = DPV_OUTPUT_SHELL; + config->output = optarg; + break; + case 'X': /* X11 support through x11/xdialog */ + config->display_type = DPV_DISPLAY_XDIALOG; + break; + case '?': /* unknown argument (based on optstring) */ + /* FALLTHROUGH */ + default: /* unhandled argument (based on switch) */ + usage(); + /* NOTREACHED */ + } + } + argc -= optind; + argv += optind; + + /* Process remaining arguments as list of names to display */ + for (curfile = file_list; n < argc; n++) { + nfiles++; + + /* Allocate a new struct for the file argument */ + if (curfile == NULL) { + if ((curfile = malloc(file_node_size)) == NULL) + errx(EXIT_FAILURE, "Out of memory?!"); + memset((void *)(curfile), '\0', file_node_size); + file_list = curfile; + } else { + if ((curfile->next = malloc(file_node_size)) == NULL) + errx(EXIT_FAILURE, "Out of memory?!"); + memset((void *)(curfile->next), '\0', file_node_size); + curfile = curfile->next; + } + curfile->name = argv[n]; + + /* Read possible `lines:' prefix from label syntax */ + if (sscanf(curfile->name, "%lli:%c", &(curfile->length), + &dummy) == 2) + curfile->name = strchr(curfile->name, ':') + 1; + else + curfile->length = -1; + + /* Read path argument if enabled */ + if (multiple) { + if (++n >= argc) + errx(EXIT_FAILURE, "Missing path argument " + "for label number %i", nfiles); + curfile->path = argv[n]; + } else + break; + } + + /* Display usage and exit if not given at least one name */ + if (nfiles == 0) { + warnx("no labels provided"); + usage(); + /* NOTREACHED */ + } + + /* + * Set cleanup routine for Ctrl-C action + */ + if (config->display_type == DPV_DISPLAY_LIBDIALOG) { + act.sa_handler = sig_int; + sigaction(SIGINT, &act, 0); + } + + /* Set status formats and action */ + if (line_mode) { + config->status_solo = LINE_STATUS_SOLO; + config->status_many = LINE_STATUS_SOLO; + config->action = operate_on_lines; + } else { + config->status_solo = BYTE_STATUS_SOLO; + config->status_many = BYTE_STATUS_SOLO; + config->action = operate_on_bytes; + } + + /* + * Hand off to dpv(3)... + */ + if (dpv(config, file_list) != 0 && debug) + warnx("dpv(3) returned error!?"); + + end_dialog(); + dpv_free(); + + exit(EXIT_SUCCESS); +} + +/* + * Interrupt handler to indicate we received a Ctrl-C interrupt. + */ +static void +sig_int(int sig __unused) +{ + dpv_interrupt = TRUE; +} + +/* + * Print short usage statement to stderr and exit with error status. + */ +static void +usage(void) +{ + + if (debug) /* No need for usage */ + exit(EXIT_FAILURE); + + fprintf(stderr, "Usage: %s [options] bytes:label\n", pgm); + fprintf(stderr, " %s [options] -m bytes1:label1 path1 " + "[bytes2:label2 path2 ...]\n", pgm); + fprintf(stderr, "OPTIONS:\n"); +#define OPTFMT "\t%-14s %s\n" + fprintf(stderr, OPTFMT, "-a text", + "Append text. Displayed below file progress indicators."); + fprintf(stderr, OPTFMT, "-b backtitle", + "String to be displayed on the backdrop, at top-left."); + fprintf(stderr, OPTFMT, "-d", + "Debug. Write to standard output instead of dialog."); + fprintf(stderr, OPTFMT, "-D", + "Use dialog(1) instead of dialog(3) [default]."); + fprintf(stderr, OPTFMT, "-h", + "Produce this output on standard error and exit."); + fprintf(stderr, OPTFMT, "-i format", + "Customize status line format. See fdpv(1) for details."); + fprintf(stderr, OPTFMT, "-I format", + "Customize status line format. See fdpv(1) for details."); + fprintf(stderr, OPTFMT, "-L size", + "Label size. Must be a number greater than 0, or -1."); + fprintf(stderr, OPTFMT, "-m", + "Enable processing of multiple file argiments."); + fprintf(stderr, OPTFMT, "-n num", + "Display at-most num files per screen. Default is -1."); + fprintf(stderr, OPTFMT, "-N", + "No overrun. Stop reading input at stated length, if any."); + fprintf(stderr, OPTFMT, "-o file", + "Output data to file. First %s replaced with label text."); + fprintf(stderr, OPTFMT, "-p text", + "Prefix text. Displayed above file progress indicators."); + fprintf(stderr, OPTFMT, "-P size", + "Mini-progressbar size. Must be a number greater than 3."); + fprintf(stderr, OPTFMT, "-t title", + "Title string to be displayed at top of dialog(1) box."); + fprintf(stderr, OPTFMT, "-T", + "Test mode. Don't actually read any data, but fake it."); + fprintf(stderr, OPTFMT, "-U num", + "Update status line num times per-second. Default is 2."); + fprintf(stderr, OPTFMT, "-w", + "Wide. Width of `-p' and `-a' text bump dialog(1) width."); + fprintf(stderr, OPTFMT, "-x cmd", + "Send data to executed cmd. First %s replaced with label."); + fprintf(stderr, OPTFMT, "-X", + "X11. Use Xdialog(1) instead of dialog(1)."); + exit(EXIT_FAILURE); +} Property changes on: stable/10/usr.bin/dpv/dpv.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: stable/10/usr.bin/dpv/dpv.1 =================================================================== --- stable/10/usr.bin/dpv/dpv.1 (nonexistent) +++ stable/10/usr.bin/dpv/dpv.1 (revision 275040) @@ -0,0 +1,430 @@ +.\" Copyright (c) 2013-2014 Devin Teske +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd Sep 7, 2014 +.Dt DPV 1 +.Os +.Sh NAME +.Nm dpv +.Nd stream data from stdin or multiple paths with dialog progress view +.Sh SYNOPSIS +.Nm +.Op options +.Ar [bytes:]label +.Nm +.Op options +.Fl m +.Ar [bytes1:]label1 +.Ar path1 +.Op Ar [bytes2:]label2 path2 ... +.Sh DESCRIPTION +.Nm +provides a dialog progress view, allowing a user to see current throughput rate +and total data transferred for one or more streams. +.Pp +The +.Nm +utility has two main modes for processing input. +.Pp +The default input mode, without +.Ql Fl m , +.Nm +reads bytes from standard input. +A label for the data must be provided. +.Pp +The secondary input mode, with +.Ql Fl m , +.Nm +reads multiple paths +.Pq up to 2047 or Dq ARG_MAX/2-1 , +sequentially. +.Pp +Data read in either mode is either thrown away +.Pq default , +sent to a spawned instance of the program specified via +.Ql Fl x Ar cmd , +or sent to a unique file specified by +.Ql Fl o Ar file . +.Pp +With or without +.Ql Fl m , +progress is displayed using one of +.Xr dialog 3 +.Pq default , +.Xr dialog 1 +.Pq see Ql Fl D , +or instead +.Xr Xdialog 1 +.Pq see Ql Fl X . +.Pp +The following options are available: +.Bl -tag -width ".Fl b Ar backtitle" +.It Fl a Ar text +Display +.Ar text +below the file progress indicator(s). +.It Fl b Ar backtitle +Display +.Ar backtitle +on the backdrop, at top-left, behind the dialog widget. +When using +.Xr Xdialog 1 , +this is displayed inside the window +.Pq at the top +followed by a separator line. +.It Fl d +Debug mode. +Print dialog prompt data to standard out and provide additional debugging on +standard error. +.It Fl D +Do not use the default interface of +.Xr dialog 3 , +but instead spawn an instance of +.Xr dialog 1 . +The path to +.Xr dialog 1 +is taken from the +.Ev DIALOG +environment variable or simply +.Dq Li dialog +if unset or NULL. +.It Fl h +Produce a short syntax usage with brief option descriptions and exit. +Output is produced on standard error. +.It Fl i Ar format +Customize the single-file format string used to update the status line. +Ignored when using either +.Ql Fl D +or +.Ql Fl X +which lack the ability to display the status line +.Pq containing bytes/rate/thread information . +Default value +is +.Dq Li %'10lli bytes read @ %'9.1f bytes/sec. . +This format is used when handling one file. +.It Fl I Ar format +Customize the multi-file format string used to update the status line. +Ignored when using either +.Ql Fl D +or +.Ql Fl X +which lack the ability to display the status line +.Pq containing bytes/rate/thread information . +Default value +is +.Dq Li %'10lli bytes read @ %'9.1f bytes/sec. [%i/%i busy/wait] . +This format is used when handling more than one file. +.It Fl l +Line mode. Read lines from input instead of bytes. +.It Fl L Ar size +Label size. +If negative, shrink to longest label width. +.It Fl m +Multi-input mode. +Instead of reading bytes from standard input, read from a set of paths +.Pq one for each label . +By default, each path is processed sequentially in the order given. +.It Fl n Ar num +Display at-most +.Ar num +progress indicators per screen. +If zero, display as many as possible. +If negative, only display the main progress indicator. +Default is 0. +Maximum value is 10. +.It Fl N +No overrun. +If enabled, stop reading known-length inputs when input reaches stated length. +.It Fl o Ar file +Output data to +.Ar file . +The first occurrence of +.Ql %s +.Pq if any +in +.Ql Ar file +will be replaced with the +.Ar label +text. +.It Fl p Ar text +Display +.Ar text +above the file progress indicator(s). +.It Fl P Ar size +Mini-progressbar size. +If negative, don't display mini-progressbars +.Pq only the large overall progress indicator is shown . +If zero, auto-adjust based on number of files to read. +When zero and only one file to read, defaults to -1. +When zero and more than one file to read, defaults to 17. +.It Fl t Ar title +Display +.Ar title +atop the dialog box. +Note that if you use this option at the same time as +.Ql Fl X +and +.Ql Fl b Ar backtitle , +the +.Ar backtitle +and +.Ar title +are effectively switched +.Pq see BUGS section below . +.It Fl T +Test mode. +Simulate reading a number of bytes, divided evenly across the number of files, +while stepping through each percent value of each file to process. +Appends +.Dq Li [TEST MODE] +to the status line +.Pq to override, use Ql Fl u Ar format . +No data is actually read. +.It Fl U Ar num +Update status line +.Ar num +times per-second. +Default value is +.Ql Li 2 . +A value of +.Ql Li 0 +disables status line updates. +If negative, update the status line as fast as possible. +Ignored when using either +.Ql Fl D +or +.Ql Fl X +which lack the ability to display the status line +.Pq containing bytes/rate/thread information . +.It Fl w +Wide mode. +Allows long +.Ar text +arguments used with +.Ql Fl p +and +.Ql Fl a +to bump the dialog width. +Prompts wider than the maximum width will wrap +.Pq unless using Xr Xdialog 1 ; see BUGS section below . +.It Fl x Ar cmd +Execute +.Ar cmd +.Pq via Xr sh 1 +and send it data that has been read. +Data is available to +.Ar cmd +on standard input. +With +.Ql Fl m , +.Ar cmd +is executed once for each +.Ar path +argument. +The first occurrence of +.Ql %s +.Pq if any +in +.Ql Ar cmd +will be replaced with the +.Ar label +text. +.It Fl X +Enable X11 mode by using +.Xr Xdialog 1 +instead of +.Xr dialog 1 +or +.Xr dialog 3 . +.El +.Sh ENVIRONMENT +The following environment variables are referenced by +.Nm : +.Bl -tag -width ".Ev USE_COLOR" +.It Ev DIALOG +Override command string used to launch +.Xr dialog 1 +.Pq requires Ql Fl D +or +.Xr Xdialog 1 +.Pq requires Ql Fl X ; +default is either +.Ql dialog +.Pq for Ql Fl D +or +.Ql Xdialog +.Pq for Ql Fl X . +.It Ev DIALOGRC +If set and non-NULL, path to +.Ql .dialogrc +file. +.It Ev HOME +If +.Ql Ev $DIALOGRC +is either not set or NULL, used as a prefix to +.Ql .dialogrc +.Pq i.e., Ql $HOME/.dialogrc . +.It Ev USE_COLOR +If set and NULL, disables the use of color when using +.Xr dialog 1 +.Pq does not apply to Xr Xdialog 1 . +.El +.Sh DEPENDENCIES +If using +.Ql Fl D , +.Xr dialog 1 +is required. +.Pp +If using +.Ql Fl X , +.Xr Xdialog 1 +is required. +.Sh FILES +.Bl -tag -width ".Pa $HOME/.dialogrc" -compact +.It Pa $HOME/.dialogrc +.El +.Sh EXAMPLES +.Pp +Simple example to show how fast +.Xr yes 1 +produces lines +.Pq usually about ten-million per-second; your results may vary : +.Bd -literal -offset indent +yes | dpv -l yes +.Ed +.Pp +Display progress while timing how long it takes +.Xr yes 1 +to produce a half-billion lines +.Pq usually under one minute; your results may vary : +.Bd -literal -offset indent +time yes | dpv -Nl 500000000:yes +.Ed +.Pp +An example to watch how quickly a file is transferred using +.Xr nc 1 : +.Bd -literal -offset indent +dpv -x "nc -w 1 somewhere.com 3000" -m label file +.Ed +.Pp +A similar example, transferring a file from another process and passing the +expected size to +.Nm : +.Bd -literal -offset indent +cat file | dpv -x "nc -w 1 somewhere.com 3000" 12345:label +.Ed +.Pp +A more complicated example: +.Bd -literal -offset indent +tar cf - . | dpv -x "gzip -9 > out.tgz" \\ + $( du -s . | awk '{print $1 * 1024}' ):label +.Ed +.Pp +Taking an image of a disk: +.Bd -literal -offset indent +dpv -o disk-image.img -m label /dev/ada0 +.Ed +.Pp +Writing an image back to a disk: +.Bd -literal -offset indent +dpv -o /dev/ada0 -m label disk-image.img +.Ed +.Pp +Zeroing a disk: +.Bd -literal -offset indent +dpv -o /dev/md42 < /dev/zero +.Ed +.Pp +.Sh BUGS +.Xr Xdialog 1 , +when given both +.Ql Fl -title Ar title +.Pq see above Ql Fl t Ar title +and +.Ql Fl -backtitle Ar backtitle +.Pq see above Ql Fl b Ar backtitle , +displays the backtitle in place of the title and vice-versa. +.Pp +.Xr Xdialog 1 +does not wrap long prompt texts received after initial launch. +This is a known issue with the +.Ql --gauge +widget in +.Xr Xdialog 1 . +.Pp +.Xr dialog 1 +does not display the first character after a series of escaped escape-sequences +(e.g., ``\\\\n'' produces ``\\'' instead of ``\\n''). +This is a known issue with +.Xr dialog 1 +and does not affect +.Xr dialog 3 +or +.Xr Xdialog 1 . +.Pp +If your application ignores +.Ev USE_COLOR +when set and NULL before calling +.Xr dpv 1 +with color escape sequences anyway, +.Xr dialog 3 +and +.Xr dialog 1 +may not render properly. +Workaround is to detect when +.Ev USE_COLOR +is set and NULL and either not use color escape sequences at that time or use +.Xr unset 1 +.Xr [ sh 1 ] +or +.Xr unsetenv 1 +.Xr [ csh 1 ] +to unset +.Ev USE_COLOR , +forcing interpretation of color sequences. +This does not effect +.Xr Xdialog 1 , +which renders the color escape sequences as plain text. +See +.Do Li +embedded "\\Z" sequences +.Dc +in +.Xr dialog 1 +for additional information. +.Sh SEE ALSO +.Xr dialog 1 , +.Xr dialog 3 , +.Xr sh 1 , +.Xr Xdialog 1 +.Sh HISTORY +A +.Nm +utility first appeared in +.Fx 11.0 . +.Sh AUTHORS +.An Devin Teske Aq dteske@FreeBSD.org Property changes on: stable/10/usr.bin/dpv/dpv.1 ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: stable/10/usr.bin/dpv/dpv_util.h =================================================================== --- stable/10/usr.bin/dpv/dpv_util.h (nonexistent) +++ stable/10/usr.bin/dpv/dpv_util.h (revision 275040) @@ -0,0 +1,68 @@ +/*- + * Copyright (c) 2013-2014 Devin Teske + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _DPV_UTIL_H_ +#define _DPV_UTIL_H_ + +/* Limits */ +#define BUFSIZE_MAX (2 * 1024 * 1024) + /* Buffer size for read(2) input */ +#ifndef MAXPHYS +#define MAXPHYS (128 * 1024) + /* max raw I/O transfer size */ +#endif + +/* + * Memory strategry threshold, in pages: if physmem is larger than this, + * use a large buffer. + */ +#define PHYSPAGES_THRESHOLD (32 * 1024) + +/* + * Small (default) buffer size in bytes. It's inefficient for this to be + * smaller than MAXPHYS. + */ +#define BUFSIZE_SMALL (MAXPHYS) + +/* + * Math macros + */ +#undef MIN +#define MIN(x,y) ((x) < (y) ? (x) : (y)) +#undef MAX +#define MAX(x,y) ((x) > (y) ? (x) : (y)) + +/* + * Extra display information + */ +#define BYTE_STATUS_SOLO "%'10lli bytes read @ %'9.1f bytes/sec." +#define BYTE_STATUS_MANY (BYTE_STATUS_SOLO " [%i/%i busy/wait]") +#define LINE_STATUS_SOLO "%'10lli lines read @ %'9.1f lines/sec." +#define LINE_STATUS_MANY (LINE_STATUS_SOLO " [%i/%i busy/wait]") + +#endif /* !_DPV_UTIL_H_ */ Property changes on: stable/10/usr.bin/dpv/dpv_util.h ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: stable/10 =================================================================== --- stable/10 (revision 275039) +++ stable/10 (revision 275040) Property changes on: stable/10 ___________________________________________________________________ Modified: svn:mergeinfo ## -0,0 +0,1 ## Merged /head:r274116,274120-274121,274123-274124,274144,274146,274159,274192,274203,274209,274226,274270,274851