summaryrefslogtreecommitdiffstats
path: root/misc-utils
diff options
context:
space:
mode:
authorJindrich Novy2012-04-15 11:22:10 +0200
committerRuediger Meier2018-06-12 14:23:44 +0200
commitc23b4a230531da663fc35a478754c641866cb6df (patch)
tree3b791718812a1dc3e088596def485ff132317722 /misc-utils
parentfix possible buffer overflows, integer overflows, update man page (diff)
downloadkernel-qcow2-util-linux-c23b4a230531da663fc35a478754c641866cb6df.tar.gz
kernel-qcow2-util-linux-c23b4a230531da663fc35a478754c641866cb6df.tar.xz
kernel-qcow2-util-linux-c23b4a230531da663fc35a478754c641866cb6df.zip
do not allow to hardlink files across filesystems by default (#786719)
(use -f option to override)
Diffstat (limited to 'misc-utils')
-rw-r--r--misc-utils/hardlink.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/misc-utils/hardlink.c b/misc-utils/hardlink.c
index 51a71cf97..a7c72492d 100644
--- a/misc-utils/hardlink.c
+++ b/misc-utils/hardlink.c
@@ -18,7 +18,7 @@
Boston, MA 02111-1307, USA. */
/* Changes by Rémy Card to use constants and add option -n. */
-/* Changes by Jindrich Novy to add option -h, replace mmap(2), fix overflows */
+/* Changes by Jindrich Novy to add option -h, -f, replace mmap(2), fix overflows */
#define _GNU_SOURCE
#include <sys/types.h>
@@ -56,6 +56,7 @@ h *hps[NHASH];
int no_link = 0;
int verbose = 0;
int content_only = 0;
+int force = 0;
typedef struct _f {
struct _f *next;
@@ -97,11 +98,12 @@ void doexit(int i)
void usage(char *prog)
{
- fprintf (stderr, "Usage: %s [-cnvh] directories...\n", prog);
+ fprintf (stderr, "Usage: %s [-cnvhf] directories...\n", prog);
fprintf (stderr, " -c When finding candidates for linking, compare only file contents.\n");
fprintf (stderr, " -n Don't actually link anything, just report what would be done.\n");
fprintf (stderr, " -v Print summary after hardlinking.\n");
fprintf (stderr, " -vv Print every hardlinked file and bytes saved + summary.\n");
+ fprintf (stderr, " -f Force hardlinking across filesystems.\n");
fprintf (stderr, " -h Show help.\n");
exit(255);
}
@@ -139,7 +141,7 @@ void growstr(dynstr *str, size_t newlen)
doexit(4);
}
}
-
+dev_t dev = 0;
void rf (const char *name)
{
struct stat st, st2, st3;
@@ -147,6 +149,13 @@ void rf (const char *name)
nobjects++;
if (lstat (name, &st))
return;
+ if (st.st_dev != dev && !force) {
+ if (dev) {
+ fprintf(stderr, "%s is on different filesystem than the rest.\nUse -f option to override.\n", name);
+ doexit(6);
+ }
+ dev = st.st_dev;
+ }
if (S_ISDIR (st.st_mode)) {
d * dp = malloc(add3(sizeof(d), namelen, 1));
if (!dp) {
@@ -318,7 +327,7 @@ int main(int argc, char **argv)
int ch;
int i;
dynstr nam1 = {NULL, 0};
- while ((ch = getopt (argc, argv, "cnvh")) != -1) {
+ while ((ch = getopt (argc, argv, "cnvhf")) != -1) {
switch (ch) {
case 'n':
no_link++;
@@ -329,6 +338,9 @@ int main(int argc, char **argv)
case 'c':
content_only++;
break;
+ case 'f':
+ force=1;
+ break;
case 'h':
default:
usage(argv[0]);