[Midnightbsd-cvs] src [11551] trunk/usr.bin/dpv: add dpv

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Sat Jul 7 17:50:34 EDT 2018


Revision: 11551
          http://svnweb.midnightbsd.org/src/?rev=11551
Author:   laffer1
Date:     2018-07-07 17:50:34 -0400 (Sat, 07 Jul 2018)
Log Message:
-----------
add dpv

Added Paths:
-----------
    trunk/usr.bin/dpv/
    trunk/usr.bin/dpv/Makefile
    trunk/usr.bin/dpv/dpv.1
    trunk/usr.bin/dpv/dpv.c
    trunk/usr.bin/dpv/dpv_util.h

Added: trunk/usr.bin/dpv/Makefile
===================================================================
--- trunk/usr.bin/dpv/Makefile	                        (rev 0)
+++ trunk/usr.bin/dpv/Makefile	2018-07-07 21:50:34 UTC (rev 11551)
@@ -0,0 +1,13 @@
+# $MidnightBSD$
+# $FreeBSD: stable/10/usr.bin/dpv/Makefile 275040 2014-11-25 13:47:53Z dteske $
+
+PROG=		dpv
+
+CFLAGS+=	-I${.CURDIR}
+
+DPADD=		${LIBDPV} ${LIBDIALOG} ${LIBFIGPAR} ${LIBNCURSESW} ${LIBUTIL} ${LIBM}
+LDADD=		-ldpv -ldialog -lfigpar -lncursesw -lutil -lm
+
+WARNS?=		6
+
+.include <bsd.prog.mk>


Property changes on: trunk/usr.bin/dpv/Makefile
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/usr.bin/dpv/dpv.1
===================================================================
--- trunk/usr.bin/dpv/dpv.1	                        (rev 0)
+++ trunk/usr.bin/dpv/dpv.1	2018-07-07 21:50:34 UTC (rev 11551)
@@ -0,0 +1,434 @@
+.\" $MidnightBSD$
+.\" Copyright (c) 2013-2016 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: stable/10/usr.bin/dpv/dpv.1 306378 2016-09-27 19:00:22Z pluknet $
+.\"
+.Dd Jan 26, 2016
+.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 k
+Keep tite.
+Prevent visually distracting initialization/exit routines for scripts running
+.Xr dialog 1
+several times.
+.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
+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
+.Sh SEE ALSO
+.Xr dialog 1 ,
+.Xr dialog 3 ,
+.Xr sh 1 ,
+.Xr Xdialog 1
+.Sh HISTORY
+A
+.Nm
+utility first appeared in
+.Fx 10.2 .
+.Sh AUTHORS
+.An Devin Teske Aq dteske at FreeBSD.org
+.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
+embedded "\\Z" sequences
+.Dc
+in
+.Xr dialog 1
+for additional information.


Property changes on: trunk/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 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/usr.bin/dpv/dpv.c
===================================================================
--- trunk/usr.bin/dpv/dpv.c	                        (rev 0)
+++ trunk/usr.bin/dpv/dpv.c	2018-07-07 21:50:34 UTC (rev 11551)
@@ -0,0 +1,546 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013-2016 Devin Teske <dteske at FreeBSD.org>
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/usr.bin/dpv/dpv.c 295110 2016-02-01 00:58:07Z dteske $");
+
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#define _BSD_SOURCE /* to get dprintf() prototype in stdio.h below */
+#include <dialog.h>
+#include <dpv.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <string_m.h>
+#include <unistd.h>
+
+#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:klL: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 'k': /* keep tite */
+			config->keep_tite = TRUE;
+			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!?");
+
+	if (!config->keep_tite)
+		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: trunk/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 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/usr.bin/dpv/dpv_util.h
===================================================================
--- trunk/usr.bin/dpv/dpv_util.h	                        (rev 0)
+++ trunk/usr.bin/dpv/dpv_util.h	2018-07-07 21:50:34 UTC (rev 11551)
@@ -0,0 +1,69 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013-2014 Devin Teske <dteske at FreeBSD.org>
+ * 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: stable/10/usr.bin/dpv/dpv_util.h 274116 2014-11-04 23:46:01Z dteske $
+ */
+
+#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: trunk/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 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property


More information about the Midnightbsd-cvs mailing list