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;
}
|