view rvinterf/etmsync/cleandir.c @ 620:dd162a4cb9fa

CHANGES: objective performance comparison instead of blind patch
author Mychaela Falconia <falcon@freecalypso.org>
date Thu, 27 Feb 2020 01:21:58 +0000
parents e6fe9d25377a
children
line wrap: on
line source

/*
 * The implementation of cleandir and rm-subtree commands lives here.
 */

#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include "etm.h"
#include "ffs.h"
#include "tmffs2.h"
#include "limits.h"
#include "ffslimits.h"
#include "localtypes.h"
#include "localstruct.h"
#include "exitcodes.h"

extern char *pathname_for_ffs_child();

cleandir_level(ffspath_dir)
	char *ffspath_dir;
{
	u_char rdstate[4];
	char rdbuf[MAX_FN_COMPONENT+1], ffspath_child[MAX_FULL_PATHNAME+1];
	char *childp;
	int nument, i, rc;
	struct stat_info stat;

	rc = do_opendir(ffspath_dir, rdstate, &nument);
	if (rc)
		return(rc);
	if (!nument)
		return(0);
	childp = pathname_for_ffs_child(ffspath_dir, ffspath_child);
	if (!childp) {
		printf("error: non-empty dir at the limit of pathname depth\n");
		return(ERROR_TARGET);
	}
	for (i = 0; i < nument; i++) {
		rc = do_readdir(rdstate, rdbuf, MAX_FN_COMPONENT+1);
		if (rc)
			return(rc);
		if (index(rdbuf, '/')) {
			printf("error: readdir result contains a slash\n");
			return(ERROR_TARGET);
		}
		strcpy(childp, rdbuf);
		rc = do_xlstat(ffspath_child, &stat);
		if (rc) {
			printf("xlstat failed on %s\n", ffspath_child);
			return(rc);
		}
		if (stat.type == OT_DIR) {
			rc = cleandir_level(ffspath_child);
			if (rc)
				return(rc);
		}
		rc = do_ffs_remove(ffspath_child, 0);
		if (rc)
			return(rc);
	}
	return(0);
}

cmd_cleandir(argc, argv)
	char **argv;
{
	int rc;

	rc = validate_ffs_pathname(argv[1]);
	if (rc < 0)
		return(ERROR_USAGE);	/* err msg already printed */
	if (rc == 0) {
		fprintf(stderr, "error: cleandir / is not allowed\n");
		return(ERROR_USAGE);
	}
	return cleandir_level(argv[1]);
}

cmd_rm_subtree(argc, argv)
	char **argv;
{
	char *pathname;
	int rc, minusf_mode, found;
	struct stat_info stat;

	if (argc == 2) {
		pathname = argv[1];
		minusf_mode = 0;
	} else {
		if (strcmp(argv[1], "-f")) {
			fprintf(stderr,
				"usage: rm-subtree [-f] ffs_pathname\n");
			return(ERROR_USAGE);
		}
		pathname = argv[2];
		minusf_mode = 1;
	}
	rc = validate_ffs_pathname(pathname);
	if (rc < 0)
		return(ERROR_USAGE);	/* err msg already printed */
	if (rc == 0) {
		fprintf(stderr, "error: rm-subtree / is not allowed\n");
		return(ERROR_USAGE);
	}
	if (minusf_mode) {
		rc = do_xlstat_notfoundok(pathname, &found, &stat);
		if (rc)
			return(rc);
		if (!found)
			return(0);
	} else {
		rc = do_xlstat(pathname, &stat);
		if (rc)
			return(rc);
	}
	if (stat.type != OT_DIR) {
		printf("error: %s exists and is not a directory\n", pathname);
		return(ERROR_TARGET);
	}
	rc = cleandir_level(pathname);
	if (rc)
		return(rc);
	return do_ffs_remove(pathname, 0);
}