File: declone.c

package info (click to toggle)
hxtools 20180301-1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 4,600 kB
  • sloc: ansic: 5,926; perl: 3,905; sh: 1,638; cpp: 342; makefile: 191; asm: 173
file content (72 lines) | stat: -rw-r--r-- 1,683 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
/*
 *	declone.c - unlink but preserve a file
 *	written by Jan Engelhardt, 2004-2007
 *
 *	This program is free software; you can redistribute it and/or
 *	modify it under the terms of the WTF Public License version 2 or
 *	(at your option) any later version.
 */
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define BLOCKSIZE 4096

static void dofile(const char *file)
{
	struct stat sb;
	ssize_t ret;
	char buffer[BLOCKSIZE];
	int in, out;

	if ((in = open(file, O_RDONLY)) < 0) {
		fprintf(stderr, "Could not open %s: %s\n",
		        file, strerror(errno));
		return;
	}
	if (fstat(in, &sb) < 0) {
		fprintf(stderr, "Could not stat %s: %s\n",
		        file, strerror(errno));
		return;
	}
	if (unlink(file) < 0) {
		fprintf(stderr, "Could not unlink %s: %s\n",
		        file, strerror(errno));
		return;
	}
	if ((out = open(file, O_WRONLY | O_TRUNC | O_CREAT,
	    sb.st_mode)) < 0) {
		fprintf(stderr, "Could not recreate/open file %s: %s\n",
		        file, strerror(errno));
		fgets(buffer, 4, stdin);
		return;
	}

	printf("* %s\n", file);
	fchown(out, sb.st_uid, sb.st_gid);
	fchmod(out, sb.st_mode);
	while ((ret = read(in, buffer, BLOCKSIZE)) > 0)
		if (write(out, buffer, ret) < 0) {
			fprintf(stderr, "Error during write to %s: "
			        "%s\n", file, strerror(errno));
			break;
		}

	if (ret < 0)
		fprintf(stderr, "Error during read on %s: %s\n",
		        file, strerror(errno));
	close(in);
	close(out);
}

int main(int argc, const char **argv)
{
	++argv;
	for (; --argc > 0 && *argv != NULL; ++argv)
		dofile(*argv);
	return EXIT_SUCCESS;
}