Add history and config-struct to recurse
For loop detection, a history is mandatory. In the process of also adding a flexible struct to recurse, the recurse-definition was moved to fs.h. The motivation behind the struct is to allow easy extensions to the recurse-function without having to change the prototypes of all functions in the process. Adding flags is really simple as well now. Using the recursor-struct, it's also easier to see which defaults apply to a program (for instance, which type of follow, ...). Another change was to add proper stat-lstat-usage in recurse. It was wrong before.
This commit is contained in:
		
							
								
								
									
										16
									
								
								chgrp.c
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								chgrp.c
									
									
									
									
									
								
							@@ -5,6 +5,7 @@
 | 
			
		||||
#include <grp.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
#include "fs.h"
 | 
			
		||||
#include "util.h"
 | 
			
		||||
 | 
			
		||||
static struct stat st;
 | 
			
		||||
@@ -14,12 +15,12 @@ static gid_t gid = -1;
 | 
			
		||||
static int   ret = 0;
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
chgrp(const char *path, int depth, void *data)
 | 
			
		||||
chgrp(const char *path, void *data, struct recursor *r)
 | 
			
		||||
{
 | 
			
		||||
	char *chownf_name;
 | 
			
		||||
	int (*chownf)(const char *, uid_t, gid_t);
 | 
			
		||||
 | 
			
		||||
	if (recurse_follow == 'P' || (recurse_follow == 'H' && depth) || (hflag && !depth)) {
 | 
			
		||||
	if (r->follow == 'P' || (r->follow == 'H' && r->depth) || (hflag && !(r->depth))) {
 | 
			
		||||
		chownf_name = "lchown";
 | 
			
		||||
		chownf = lchown;
 | 
			
		||||
	} else {
 | 
			
		||||
@@ -31,7 +32,7 @@ chgrp(const char *path, int depth, void *data)
 | 
			
		||||
		weprintf("%s %s:", chownf_name, path);
 | 
			
		||||
		ret = 1;
 | 
			
		||||
	} else if (Rflag) {
 | 
			
		||||
		recurse(path, chgrp, depth, NULL);
 | 
			
		||||
		recurse(path, NULL, r);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -45,6 +46,7 @@ int
 | 
			
		||||
main(int argc, char *argv[])
 | 
			
		||||
{
 | 
			
		||||
	struct group *gr;
 | 
			
		||||
	struct recursor r = { .fn = chgrp, .hist = NULL, .depth = 0, .follow = 'P', .flags = 0 };
 | 
			
		||||
 | 
			
		||||
	ARGBEGIN {
 | 
			
		||||
	case 'h':
 | 
			
		||||
@@ -56,7 +58,7 @@ main(int argc, char *argv[])
 | 
			
		||||
	case 'H':
 | 
			
		||||
	case 'L':
 | 
			
		||||
	case 'P':
 | 
			
		||||
		recurse_follow = ARGC();
 | 
			
		||||
		r.follow = ARGC();
 | 
			
		||||
		break;
 | 
			
		||||
	default:
 | 
			
		||||
		usage();
 | 
			
		||||
@@ -74,14 +76,14 @@ main(int argc, char *argv[])
 | 
			
		||||
	}
 | 
			
		||||
	gid = gr->gr_gid;
 | 
			
		||||
 | 
			
		||||
	for (; *argv; argc--, argv++) {
 | 
			
		||||
	for (argc--, argv++; *argv; argc--, argv++) {
 | 
			
		||||
		if (stat(*argv, &st) < 0) {
 | 
			
		||||
			weprintf("stat %s:", *argv);
 | 
			
		||||
			ret = 1;
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
		chgrp(*argv, 0, NULL);
 | 
			
		||||
		chgrp(*argv, NULL, &r);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return ret;
 | 
			
		||||
	return ret || recurse_status;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										12
									
								
								chmod.c
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								chmod.c
									
									
									
									
									
								
							@@ -1,6 +1,7 @@
 | 
			
		||||
/* See LICENSE file for copyright and license details. */
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
 | 
			
		||||
#include "fs.h"
 | 
			
		||||
#include "util.h"
 | 
			
		||||
 | 
			
		||||
static int    Rflag   = 0;
 | 
			
		||||
@@ -9,7 +10,7 @@ static mode_t mask    = 0;
 | 
			
		||||
static int    ret     = 0;
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
chmodr(const char *path, int depth, void *data)
 | 
			
		||||
chmodr(const char *path, void *data, struct recursor *r)
 | 
			
		||||
{
 | 
			
		||||
	struct stat st;
 | 
			
		||||
	mode_t m;
 | 
			
		||||
@@ -25,7 +26,7 @@ chmodr(const char *path, int depth, void *data)
 | 
			
		||||
		weprintf("chmod %s:", path);
 | 
			
		||||
		ret = 1;
 | 
			
		||||
	} else if (Rflag)
 | 
			
		||||
		recurse(path, chmodr, depth, NULL);
 | 
			
		||||
		recurse(path, NULL, r);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@@ -37,6 +38,7 @@ usage(void)
 | 
			
		||||
int
 | 
			
		||||
main(int argc, char *argv[])
 | 
			
		||||
{
 | 
			
		||||
	struct recursor r = { .fn = chmodr, .hist = NULL, .depth = 0, .follow = 'P', .flags = 0};
 | 
			
		||||
	size_t i;
 | 
			
		||||
 | 
			
		||||
	argv0 = *(argv++);
 | 
			
		||||
@@ -52,7 +54,7 @@ main(int argc, char *argv[])
 | 
			
		||||
			case 'H':
 | 
			
		||||
			case 'L':
 | 
			
		||||
			case 'P':
 | 
			
		||||
				recurse_follow = (*argv)[i];
 | 
			
		||||
				r.follow = (*argv)[i];
 | 
			
		||||
				break;
 | 
			
		||||
			case 'r': case 'w': case 'x': case 's': case 't':
 | 
			
		||||
				/* -[rwxst] are valid modes, so we're done */
 | 
			
		||||
@@ -80,7 +82,7 @@ done:
 | 
			
		||||
		usage();
 | 
			
		||||
 | 
			
		||||
	for (--argc, ++argv; *argv; argc--, argv++)
 | 
			
		||||
		chmodr(*argv, 0, NULL);
 | 
			
		||||
		chmodr(*argv, NULL, &r);
 | 
			
		||||
 | 
			
		||||
	return ret;
 | 
			
		||||
	return ret || recurse_status;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										17
									
								
								chown.c
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								chown.c
									
									
									
									
									
								
							@@ -7,6 +7,7 @@
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
#include "fs.h"
 | 
			
		||||
#include "util.h"
 | 
			
		||||
 | 
			
		||||
static int   hflag = 0;
 | 
			
		||||
@@ -16,12 +17,12 @@ static gid_t gid = -1;
 | 
			
		||||
static int   ret = 0;
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
chownpwgr(const char *path, int depth, void *data)
 | 
			
		||||
chownpwgr(const char *path, void *data, struct recursor *r)
 | 
			
		||||
{
 | 
			
		||||
	char *chownf_name;
 | 
			
		||||
	int (*chownf)(const char *, uid_t, gid_t);
 | 
			
		||||
 | 
			
		||||
	if (recurse_follow == 'P' || (recurse_follow == 'H' && depth) || (hflag && !depth)) {
 | 
			
		||||
	if (r->follow == 'P' || (r->follow == 'H' && r->depth) || (hflag && !(r->depth))) {
 | 
			
		||||
		chownf_name = "lchown";
 | 
			
		||||
		chownf = lchown;
 | 
			
		||||
	} else {
 | 
			
		||||
@@ -33,7 +34,7 @@ chownpwgr(const char *path, int depth, void *data)
 | 
			
		||||
		weprintf("%s %s:", chownf_name, path);
 | 
			
		||||
		ret = 1;
 | 
			
		||||
	} else if (Rflag) {
 | 
			
		||||
		recurse(path, chownpwgr, depth, NULL);
 | 
			
		||||
		recurse(path, NULL, r);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -46,10 +47,12 @@ usage(void)
 | 
			
		||||
int
 | 
			
		||||
main(int argc, char *argv[])
 | 
			
		||||
{
 | 
			
		||||
	struct passwd *pw;
 | 
			
		||||
	struct group *gr;
 | 
			
		||||
	struct passwd *pw;
 | 
			
		||||
	struct recursor r = { .fn = chownpwgr, .hist = NULL, .depth = 0, .follow = 'P', .flags = 0};
 | 
			
		||||
	char *owner, *group;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	ARGBEGIN {
 | 
			
		||||
	case 'h':
 | 
			
		||||
		hflag = 1;
 | 
			
		||||
@@ -61,7 +64,7 @@ main(int argc, char *argv[])
 | 
			
		||||
	case 'H':
 | 
			
		||||
	case 'L':
 | 
			
		||||
	case 'P':
 | 
			
		||||
		recurse_follow = ARGC();
 | 
			
		||||
		r.follow = ARGC();
 | 
			
		||||
		break;
 | 
			
		||||
	default:
 | 
			
		||||
		usage();
 | 
			
		||||
@@ -97,7 +100,7 @@ main(int argc, char *argv[])
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	for (argc--, argv++; *argv; argc--, argv++)
 | 
			
		||||
		chownpwgr(*argv, 0, NULL);
 | 
			
		||||
		chownpwgr(*argv, NULL, &r);
 | 
			
		||||
 | 
			
		||||
	return ret;
 | 
			
		||||
	return ret || recurse_status;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										24
									
								
								du.c
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								du.c
									
									
									
									
									
								
							@@ -8,6 +8,7 @@
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
 | 
			
		||||
#include "fs.h"
 | 
			
		||||
#include "util.h"
 | 
			
		||||
 | 
			
		||||
static size_t maxdepth = SIZE_MAX;
 | 
			
		||||
@@ -34,24 +35,24 @@ nblks(blkcnt_t blocks)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
du(const char *path, int depth, void *total)
 | 
			
		||||
du(const char *path, void *total, struct recursor *r)
 | 
			
		||||
{
 | 
			
		||||
	struct stat st;
 | 
			
		||||
	size_t subtotal = 0;
 | 
			
		||||
 | 
			
		||||
	if (lstat(path, &st) < 0) {
 | 
			
		||||
		if (!depth || errno != ENOENT)
 | 
			
		||||
		if (!(r->depth) || errno != ENOENT)
 | 
			
		||||
			weprintf("stat %s:", path);
 | 
			
		||||
		if (!depth)
 | 
			
		||||
		if (!(r->depth))
 | 
			
		||||
			ret = 1;
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (S_ISDIR(st.st_mode))
 | 
			
		||||
		recurse(path, du, depth, &subtotal);
 | 
			
		||||
		recurse(path, &subtotal, r);
 | 
			
		||||
	*((size_t *)total) += subtotal + nblks(st.st_blocks);
 | 
			
		||||
 | 
			
		||||
	if (!sflag && depth <= maxdepth && (S_ISDIR(st.st_mode) || aflag))
 | 
			
		||||
	if (!sflag && r->depth <= maxdepth && (S_ISDIR(st.st_mode) || aflag))
 | 
			
		||||
		printpath(subtotal + nblks(st.st_blocks), path);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -64,8 +65,9 @@ usage(void)
 | 
			
		||||
int
 | 
			
		||||
main(int argc, char *argv[])
 | 
			
		||||
{
 | 
			
		||||
	int kflag = 0, dflag = 0;
 | 
			
		||||
	struct recursor r = { .fn = du, .hist = NULL, .depth = 0, .follow = 'P', .flags = 0};
 | 
			
		||||
	size_t n = 0;
 | 
			
		||||
	int kflag = 0, dflag = 0;
 | 
			
		||||
	char *bsize;
 | 
			
		||||
 | 
			
		||||
	ARGBEGIN {
 | 
			
		||||
@@ -86,12 +88,12 @@ main(int argc, char *argv[])
 | 
			
		||||
		sflag = 1;
 | 
			
		||||
		break;
 | 
			
		||||
	case 'x':
 | 
			
		||||
		recurse_samedev = 1;
 | 
			
		||||
		r.flags |= SAMEDEV;
 | 
			
		||||
		break;
 | 
			
		||||
	case 'H':
 | 
			
		||||
	case 'L':
 | 
			
		||||
	case 'P':
 | 
			
		||||
		recurse_follow = ARGC();
 | 
			
		||||
		r.follow = ARGC();
 | 
			
		||||
		break;
 | 
			
		||||
	default:
 | 
			
		||||
		usage();
 | 
			
		||||
@@ -107,16 +109,16 @@ main(int argc, char *argv[])
 | 
			
		||||
		blksize = 1024;
 | 
			
		||||
 | 
			
		||||
	if (!argc) {
 | 
			
		||||
		du(".", 0, &n);
 | 
			
		||||
		du(".", &n, &r);
 | 
			
		||||
		if (sflag && !ret)
 | 
			
		||||
			printpath(nblks(n), ".");
 | 
			
		||||
	} else {
 | 
			
		||||
		for (; *argv; argc--, argv++) {
 | 
			
		||||
			du(argv[0], 0, &n);
 | 
			
		||||
			du(argv[0], &n, &r);
 | 
			
		||||
			if (sflag && !ret)
 | 
			
		||||
				printpath(n, argv[0]);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return ret;
 | 
			
		||||
	return ret || recurse_status;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										26
									
								
								fs.h
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								fs.h
									
									
									
									
									
								
							@@ -1,4 +1,24 @@
 | 
			
		||||
/* See LICENSE file for copyright and license details. */
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
 | 
			
		||||
struct history {
 | 
			
		||||
        struct history *prev;
 | 
			
		||||
        dev_t dev;
 | 
			
		||||
        ino_t ino;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct recursor {
 | 
			
		||||
        void (*fn)(const char *, void *, struct recursor *);
 | 
			
		||||
        struct history *hist;
 | 
			
		||||
        int depth;
 | 
			
		||||
        int follow;
 | 
			
		||||
        int flags;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
        SAMEDEV = 1 << 0,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
extern int cp_aflag;
 | 
			
		||||
extern int cp_fflag;
 | 
			
		||||
extern int cp_pflag;
 | 
			
		||||
@@ -11,5 +31,9 @@ extern int rm_fflag;
 | 
			
		||||
extern int rm_rflag;
 | 
			
		||||
extern int rm_status;
 | 
			
		||||
 | 
			
		||||
extern int recurse_status;
 | 
			
		||||
 | 
			
		||||
void recurse(const char *, void *, struct recursor *);
 | 
			
		||||
 | 
			
		||||
int cp(const char *, const char *, int);
 | 
			
		||||
void rm(const char *, int, void *);
 | 
			
		||||
void rm(const char *, void *, struct recursor *);
 | 
			
		||||
 
 | 
			
		||||
@@ -9,37 +9,61 @@
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
#include "../fs.h"
 | 
			
		||||
#include "../util.h"
 | 
			
		||||
 | 
			
		||||
int recurse_follow  = 'P';
 | 
			
		||||
int recurse_samedev = 0;
 | 
			
		||||
int recurse_status = 0;
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
recurse(const char *path, void (*fn)(const char *, int, void *), int depth, void *data)
 | 
			
		||||
recurse(const char *path, void *data, struct recursor *r)
 | 
			
		||||
{
 | 
			
		||||
	struct dirent *d;
 | 
			
		||||
	struct stat lst, st, dst;
 | 
			
		||||
	struct history *new, *h;
 | 
			
		||||
	struct stat st, dst;
 | 
			
		||||
	DIR *dp;
 | 
			
		||||
	char subpath[PATH_MAX];
 | 
			
		||||
	int (*statf)(const char *, struct stat *);
 | 
			
		||||
	char subpath[PATH_MAX], *statf_name;
 | 
			
		||||
 | 
			
		||||
	if (lstat(path, &lst) < 0) {
 | 
			
		||||
		if (errno != ENOENT)
 | 
			
		||||
			weprintf("lstat %s:", path);
 | 
			
		||||
	if (r->follow == 'P' || (r->follow == 'H' && r->depth)) {
 | 
			
		||||
		statf_name = "lstat";
 | 
			
		||||
		statf = lstat;
 | 
			
		||||
	} else {
 | 
			
		||||
		statf_name = "stat";
 | 
			
		||||
		statf = stat;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (statf(path, &st) < 0) {
 | 
			
		||||
		if (errno != ENOENT) {
 | 
			
		||||
			weprintf("%s %s:", statf_name, path);
 | 
			
		||||
			recurse_status = 1;
 | 
			
		||||
		}
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	if (stat(path, &st) < 0) {
 | 
			
		||||
		if (errno != ENOENT)
 | 
			
		||||
			weprintf("stat %s:", path);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	if (!S_ISDIR(lst.st_mode) && !(S_ISLNK(lst.st_mode) && S_ISDIR(st.st_mode) &&
 | 
			
		||||
	    !(recurse_follow == 'P' || (recurse_follow == 'H' && depth > 0))))
 | 
			
		||||
	if (!S_ISDIR(st.st_mode))
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	if (!(dp = opendir(path)))
 | 
			
		||||
		eprintf("opendir %s:", path);
 | 
			
		||||
	new = emalloc(sizeof(struct history));
 | 
			
		||||
 | 
			
		||||
	new->prev  = r->hist;
 | 
			
		||||
	r->hist    = new;
 | 
			
		||||
	new->dev   = st.st_dev;
 | 
			
		||||
	new->ino   = st.st_ino;
 | 
			
		||||
 | 
			
		||||
	for (h = new->prev; h; h = h->prev)
 | 
			
		||||
		if (h->dev == st.st_dev && h->ino == st.st_ino)
 | 
			
		||||
			return;
 | 
			
		||||
 | 
			
		||||
	if (!(dp = opendir(path))) {
 | 
			
		||||
		weprintf("opendir %s:", path);
 | 
			
		||||
		recurse_status = 1;
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	while ((d = readdir(dp))) {
 | 
			
		||||
		if (r->follow == 'H') {
 | 
			
		||||
			statf_name = "lstat";
 | 
			
		||||
			statf = lstat;
 | 
			
		||||
		}
 | 
			
		||||
		if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, ".."))
 | 
			
		||||
			continue;
 | 
			
		||||
		if (strlcpy(subpath, path, PATH_MAX) >= PATH_MAX)
 | 
			
		||||
@@ -48,11 +72,16 @@ recurse(const char *path, void (*fn)(const char *, int, void *), int depth, void
 | 
			
		||||
			eprintf("strlcat: path too long\n");
 | 
			
		||||
		if (strlcat(subpath, d->d_name, PATH_MAX) >= PATH_MAX)
 | 
			
		||||
			eprintf("strlcat: path too long\n");
 | 
			
		||||
		if (recurse_samedev && lstat(subpath, &dst) < 0) {
 | 
			
		||||
			if (errno != ENOENT)
 | 
			
		||||
				weprintf("stat %s:", subpath);
 | 
			
		||||
		} else if (!(recurse_samedev && dst.st_dev != lst.st_dev))
 | 
			
		||||
			fn(subpath, depth + 1, data);
 | 
			
		||||
		if ((r->flags & SAMEDEV) && statf(subpath, &dst) < 0) {
 | 
			
		||||
			if (errno != ENOENT) {
 | 
			
		||||
				weprintf("%s %s:", statf_name, subpath);
 | 
			
		||||
				recurse_status = 1;
 | 
			
		||||
			}
 | 
			
		||||
		} else if (!((r->flags & SAMEDEV) && dst.st_dev != st.st_dev)) {
 | 
			
		||||
			r->depth++;
 | 
			
		||||
			(r->fn)(subpath, data, r);
 | 
			
		||||
			r->depth--;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	closedir(dp);
 | 
			
		||||
 
 | 
			
		||||
@@ -10,10 +10,10 @@ int rm_rflag = 0;
 | 
			
		||||
int rm_status = 0;
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
rm(const char *path, int depth, void *data)
 | 
			
		||||
rm(const char *path, void *data, struct recursor *r)
 | 
			
		||||
{
 | 
			
		||||
	if (rm_rflag)
 | 
			
		||||
		recurse(path, rm, depth, NULL);
 | 
			
		||||
		recurse(path, NULL, r);
 | 
			
		||||
	if (remove(path) < 0) {
 | 
			
		||||
		if (!rm_fflag)
 | 
			
		||||
			weprintf("remove %s:", path);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										4
									
								
								mv.c
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								mv.c
									
									
									
									
									
								
							@@ -12,6 +12,8 @@ static int mv_status = 0;
 | 
			
		||||
static int
 | 
			
		||||
mv(const char *s1, const char *s2, int depth)
 | 
			
		||||
{
 | 
			
		||||
	struct recursor r = { .fn = rm, .hist = NULL, .depth = 0, .follow = 'P', .flags = 0};
 | 
			
		||||
 | 
			
		||||
	if (!rename(s1, s2))
 | 
			
		||||
		return (mv_status = 0);
 | 
			
		||||
	if (errno == EXDEV) {
 | 
			
		||||
@@ -19,7 +21,7 @@ mv(const char *s1, const char *s2, int depth)
 | 
			
		||||
		cp_HLPflag = 'P';
 | 
			
		||||
		rm_rflag = 1;
 | 
			
		||||
		cp(s1, s2, depth);
 | 
			
		||||
		rm(s1, 0, NULL);
 | 
			
		||||
		rm(s1, NULL, &r);
 | 
			
		||||
		return (mv_status = cp_status || rm_status);
 | 
			
		||||
	}
 | 
			
		||||
	mv_status = 1;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										6
									
								
								rm.c
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								rm.c
									
									
									
									
									
								
							@@ -11,6 +11,8 @@ usage(void)
 | 
			
		||||
int
 | 
			
		||||
main(int argc, char *argv[])
 | 
			
		||||
{
 | 
			
		||||
	struct recursor r = { .fn = rm, .hist = NULL, .depth = 0, .follow = 'P', .flags = 0};
 | 
			
		||||
 | 
			
		||||
	ARGBEGIN {
 | 
			
		||||
	case 'f':
 | 
			
		||||
		rm_fflag = 1;
 | 
			
		||||
@@ -31,7 +33,7 @@ main(int argc, char *argv[])
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for (; *argv; argc--, argv++)
 | 
			
		||||
		rm(*argv, 0, NULL);
 | 
			
		||||
		rm(*argv, NULL, &r);
 | 
			
		||||
 | 
			
		||||
	return rm_status;
 | 
			
		||||
	return rm_status || recurse_status;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										12
									
								
								tar.c
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								tar.c
									
									
									
									
									
								
							@@ -9,6 +9,7 @@
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
#include "fs.h"
 | 
			
		||||
#include "util.h"
 | 
			
		||||
 | 
			
		||||
struct header {
 | 
			
		||||
@@ -234,10 +235,10 @@ print(char * fname, int l, char b[BLKSIZ])
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
c(const char *path, int depth, void *data)
 | 
			
		||||
c(const char *path, void *data, struct recursor *r)
 | 
			
		||||
{
 | 
			
		||||
	archive(path);
 | 
			
		||||
	recurse(path, c, depth, NULL);
 | 
			
		||||
	recurse(path, NULL, r);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@@ -266,6 +267,7 @@ int
 | 
			
		||||
main(int argc, char *argv[])
 | 
			
		||||
{
 | 
			
		||||
	FILE *fp;
 | 
			
		||||
	struct recursor r = { .fn = c, .hist = NULL, .depth = 0, .follow = 'P', .flags = 0};
 | 
			
		||||
	struct stat st;
 | 
			
		||||
	char *file = NULL, *dir = ".", mode = '\0';
 | 
			
		||||
 | 
			
		||||
@@ -293,7 +295,7 @@ main(int argc, char *argv[])
 | 
			
		||||
		filtermode = ARGC();
 | 
			
		||||
		break;
 | 
			
		||||
	case 'h':
 | 
			
		||||
		recurse_follow = 'L';
 | 
			
		||||
		r.follow = 'L';
 | 
			
		||||
		break;
 | 
			
		||||
	default:
 | 
			
		||||
		usage();
 | 
			
		||||
@@ -316,7 +318,7 @@ main(int argc, char *argv[])
 | 
			
		||||
			tarfile = stdout;
 | 
			
		||||
		}
 | 
			
		||||
		chdir(dir);
 | 
			
		||||
		c(argv[0], 0, NULL);
 | 
			
		||||
		c(argv[0], NULL, &r);
 | 
			
		||||
		break;
 | 
			
		||||
	case 't':
 | 
			
		||||
	case 'x':
 | 
			
		||||
@@ -342,5 +344,5 @@ main(int argc, char *argv[])
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
	return recurse_status;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										3
									
								
								util.h
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								util.h
									
									
									
									
									
								
							@@ -65,9 +65,6 @@ mode_t getumask(void);
 | 
			
		||||
char *humansize(double);
 | 
			
		||||
mode_t parsemode(const char *, mode_t, mode_t);
 | 
			
		||||
void putword(const char *);
 | 
			
		||||
extern int recurse_follow;
 | 
			
		||||
extern int recurse_samedev;
 | 
			
		||||
void recurse(const char *, void (*)(const char *, int, void *), int, void *);
 | 
			
		||||
#undef strtonum
 | 
			
		||||
long long strtonum(const char *, long long, long long, const char **);
 | 
			
		||||
long long enstrtonum(int, const char *, long long, long long);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user