Move more things around

This commit is contained in:
Roberto E. Vargas Caballero 2024-03-13 13:47:59 +01:00
parent ba7741a7bc
commit bbd10e0d30
36 changed files with 0 additions and 367 deletions

View File

@ -1,66 +0,0 @@
.Dd February 2, 2015
.Dt DD 1
.Os ubase
.Sh NAME
.Nm dd
.Nd convert and copy a file
.Sh SYNOPSIS
.Nm
.Op Ar operand...
.Sh DESCRIPTION
.Nm
copies the standard input to the standard output. By default input data is
read and written in 64kB blocks. When finished,
.Nm
displays the number of records read and written as well as the total number
of bytes copied.
.Nm
syncs the filesystem once it is done copying. If you want to disable that use
the
.Ar nosync
option.
.Sh OPTIONS
.Bl -tag -width Ds
.It Ar bs Ns Op Ar =N
If
.Ar bs
is not specified, the default blocksize is 64kB. If
.Ar bs
is specified
without setting it to a specific value then an optimal value between the
source and target filesystem will be selected. If this process fails it will
fallback to the system's pagesize. Adjust
.Ar N
to set the block size of the transfers in bytes.
.It Ar count=N
Copy only
.Ar N
input blocks.
.It Ar direct
Use direct I/O for data.
.It Ar if=file
Read input from
.Ar file
instead of the standard input.
.It Ar nosync
Do not sync the filesystem once we are done copying.
.It Ar quiet
Enable quiet output.
.It Ar of=file
Write output to
.Ar file
instead of the standard output. If an initial portion of the output
.Ar file
is skipped using the seek operand, the output file is truncated at that
point.
.It Ar seek=N
Seek
.Ar N
blocks from the beginning of the output before copying.
.It Ar skip=N
Skip
.Ar N
blocks from the beginning of the input before copying.
.It Ar conv=notrunc
Do not truncate the output file.
.El

View File

@ -1,301 +0,0 @@
/* (C) 2011-2012 Sebastian Krahmer all rights reserved.
*
* Optimized dd, to speed up backups etc.
*
* Permission has been granted to release this code under MIT/X.
* The original code is at https://github.com/stealth/odd. This
* version of the code has been modified by sin@2f30.org.
*/
#include <sys/ioctl.h>
#include <sys/mount.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/vfs.h>
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include "util.h"
struct dd_config {
const char *in, *out;
uint64_t skip, seek, count, b_in, b_out, rec_in, rec_out;
off_t fsize;
blksize_t bs;
char quiet, nosync, notrunc, direct;
time_t t_start, t_end;
};
static int sigint = 0;
static void
sig_int(int unused_1, siginfo_t *unused_2, void *unused_3)
{
(void) unused_1;
(void) unused_2;
(void) unused_3;
sigint = 1;
}
static int
prepare_copy(struct dd_config *ddc, int *ifd, int *ofd)
{
struct stat st;
int fli = O_RDONLY|O_LARGEFILE|O_NOCTTY, flo = O_WRONLY|O_LARGEFILE|O_CREAT|O_NOATIME|O_NOCTTY;
long pagesize;
if (ddc->direct) {
fli |= O_DIRECT;
flo |= O_DIRECT;
}
if (!ddc->in) *ifd = 0;
else if ((*ifd = open(ddc->in, fli)) < 0)
return -1;
if (fstat(*ifd, &st) < 0)
return -1;
ddc->fsize = st.st_size;
/* If "bsize" is not given, use optimum of both FS' */
if (!ddc->bs) {
struct statfs fst;
memset(&fst, 0, sizeof(fst));
pagesize = sysconf(_SC_PAGESIZE);
if (pagesize <= 0)
pagesize = 0x1000;
if (statfs(ddc->out, &fst) < 0 || fst.f_bsize == 0)
fst.f_bsize = pagesize;
if ((unsigned long)fst.f_bsize > (unsigned long)st.st_blksize)
ddc->bs = fst.f_bsize;
else
ddc->bs = st.st_blksize;
if (ddc->bs == 0)
ddc->bs = pagesize;
}
/* check if device or regular file */
if (!S_ISREG(st.st_mode)) {
if (S_ISBLK(st.st_mode)) {
if (ioctl(*ifd, BLKGETSIZE64, &ddc->fsize) < 0) {
close(*ifd);
return -1;
}
} else {
ddc->fsize = (off_t)-1;
}
}
/* skip and seek are in block items */
ddc->skip *= ddc->bs;
ddc->seek *= ddc->bs;
/* skip more bytes than are inside source file? */
if (ddc->fsize != (off_t)-1 && ddc->skip >= (uint64_t)ddc->fsize) {
errno = EINVAL;
close(*ifd);
return -1;
}
if (!ddc->seek && !ddc->notrunc)
flo |= O_TRUNC;
if (!ddc->out) *ofd = 1;
else if ((*ofd = open(ddc->out, flo, st.st_mode)) < 0) {
close(*ifd);
return -1;
}
if (ddc->seek && !ddc->notrunc) {
if (fstat(*ofd, &st) < 0)
return -1;
if (!S_ISREG(st.st_mode))
;
else if (ftruncate(*ofd, ddc->seek) < 0)
return -1;
}
if (lseek(*ifd, ddc->skip, SEEK_CUR) < 0) {
char buffer[ddc->bs];
for (uint64_t i = 0; i < ddc->skip; i += ddc->bs) {
if (read(*ifd, &buffer, ddc->bs) < 0) {
errno = EINVAL;
close(*ifd);
return -1;
}
}
}
lseek(*ofd, ddc->seek, SEEK_CUR);
posix_fadvise(*ifd, ddc->skip, 0, POSIX_FADV_SEQUENTIAL);
posix_fadvise(*ofd, 0, 0, POSIX_FADV_DONTNEED);
/* count is in block items too */
ddc->count *= ddc->bs;
/* If no count is given, its the filesize minus skip offset */
if (ddc->count == (uint64_t) -1)
ddc->count = ddc->fsize - ddc->skip;
return 0;
}
static int
copy_splice(struct dd_config *ddc)
{
int ifd, ofd, p[2] = {-1, -1};
ssize_t r = 0;
size_t n = 0;
if (prepare_copy(ddc, &ifd, &ofd) < 0)
return -1;
if (pipe(p) < 0) {
close(ifd); close(ofd);
close(p[0]); close(p[1]);
return -1;
}
#ifdef F_SETPIPE_SZ
for (n = 29; n >= 20; --n) {
if (fcntl(p[0], F_SETPIPE_SZ, 1<<n) != -1)
break;
}
errno = 0;
#endif
n = ddc->bs;
for (;ddc->b_out != ddc->count && !sigint;) {
if (r < 0)
break;
if (n > ddc->count - ddc->b_out)
n = ddc->count - ddc->b_out;
r = splice(ifd, NULL, p[1], NULL, n, SPLICE_F_MORE);
if (r <= 0)
break;
++ddc->rec_in;
r = splice(p[0], NULL, ofd, NULL, r, SPLICE_F_MORE);
if (r <= 0)
break;
ddc->b_out += r;
++ddc->rec_out;
}
if (sigint)
fprintf(stderr, "SIGINT! Aborting ...\n");
close(ifd);
close(ofd);
close(p[0]);
close(p[1]);
if (r < 0)
return -1;
return 0;
}
static int
copy(struct dd_config *ddc)
{
int r = 0;
ddc->t_start = time(NULL);
r = copy_splice(ddc);
ddc->t_end = time(NULL);
/* avoid div by zero */
if (ddc->t_start == ddc->t_end)
++ddc->t_end;
return r;
}
static void
print_stat(const struct dd_config *ddc)
{
if (ddc->quiet)
return;
fprintf(stderr, "%"PRIu64" records in\n", ddc->rec_in);
fprintf(stderr, "%"PRIu64" records out\n", ddc->rec_out);
fprintf(stderr, "%"PRIu64" bytes (%"PRIu64" MB) copied", ddc->b_out,
ddc->b_out/(1<<20));
fprintf(stderr, ", %lu s, %f MB/s\n",
(unsigned long)ddc->t_end - ddc->t_start,
((double)(ddc->b_out/(1<<20)))/(ddc->t_end - ddc->t_start));
}
static void
usage(void)
{
eprintf("usage: %s [-h] [if=infile] [of=outfile] [bs[=N]] [seek=N] "
"[skip=N] [count=N] [direct] [quiet] [nosync]"
"[conv=notrunc]\n", argv0);
}
int
main(int argc, char *argv[])
{
int i = 0;
char buf[1024];
struct dd_config config;
struct sigaction sa;
argv0 = argv[0];
memset(&config, 0, sizeof(config));
config.bs = 1<<16;
config.in = NULL;
config.out = NULL;
config.count = (uint64_t) -1;
/* emulate 'dd' argument parsing */
for (i = 1; i < argc; ++i) {
memset(buf, 0, sizeof(buf));
if (strncmp(argv[i], "if=", 3) == 0)
config.in = argv[i]+3;
else if (strncmp(argv[i], "of=", 3) == 0)
config.out = argv[i]+3;
else if (sscanf(argv[i], "skip=%1023s", buf) == 1)
config.skip = estrtoul(buf, 0);
else if (sscanf(argv[i], "seek=%1023s", buf) == 1)
config.seek = estrtoul(buf, 0);
else if (sscanf(argv[i], "count=%1023s", buf) == 1)
config.count = estrtoul(buf, 0);
else if (strcmp(argv[i], "direct") == 0)
config.direct = 1;
else if (sscanf(argv[i], "bs=%1023s", buf) == 1)
config.bs = estrtoul(buf, 0);
else if (strcmp(argv[i], "bs") == 0)
config.bs = 0;
else if (strcmp(argv[i], "quiet") == 0)
config.quiet = 1;
else if (strcmp(argv[i], "nosync") == 0)
config.nosync = 1;
else if (strcmp(argv[i], "conv=notrunc") == 0)
config.notrunc = 1;
else if (strcmp(argv[i], "-h") == 0)
usage();
}
signal(SIGPIPE, SIG_IGN);
sa.sa_flags = SA_SIGINFO;
sigemptyset(&sa.sa_mask);
sa.sa_sigaction = sig_int;
if (sigaction(SIGINT, &sa, NULL) == -1)
weprintf("sigaction");
if (copy(&config) < 0)
weprintf("copy:");
print_stat(&config);
if (config.nosync == 0)
sync();
return errno;
}