Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 3336 → Rev 3337

/branches/shell/uspace/app/bdsh/cmds/modules/rm/rm.c
33,6 → 33,9
#include <unistd.h>
#include <fcntl.h>
#include <dirent.h>
#include <assert.h>
#include <getopt.h>
 
#include "config.h"
#include "errors.h"
#include "util.h"
41,10 → 44,73
#include "cmds.h"
 
static char *cmdname = "rm";
#define RM_VERSION "0.0.1"
 
static rm_job_t rm;
 
static struct option long_options[] = {
{ "help", no_argument, 0, 'h' },
{ "version", no_argument, 0, 'v' },
{ "recursive", no_argument, 0, 'r' },
{ "force", no_argument, 0, 'f' },
{ "safe", no_argument, 0, 's' },
{ 0, 0, 0, 0 }
};
 
unsigned int rm_start(rm_job_t *rm)
{
rm->recursive = 0;
rm->force = 0;
rm->safe = 0;
 
/* Make sure we can allocate enough memory to store
* what is needed in the job structure */
if (NULL == (rm->nwd = (char *) malloc(PATH_MAX)))
return 0;
memset(rm->nwd, 0, sizeof(rm->nwd));
 
if (NULL == (rm->owd = (char *) malloc(PATH_MAX)))
return 0;
memset(rm->owd, 0, sizeof(rm->owd));
 
if (NULL == (rm->cwd = (char *) malloc(PATH_MAX)))
return 0;
memset(rm->cwd, 0, sizeof(rm->cwd));
 
chdir(".");
 
if (NULL == (getcwd(rm->owd, PATH_MAX)))
return 0;
 
return 1;
}
 
void rm_end(rm_job_t *rm)
{
if (NULL != rm->nwd)
free(rm->nwd);
 
if (NULL != rm->owd)
free(rm->owd);
 
if (NULL != rm->cwd)
free(rm->cwd);
 
return;
}
 
unsigned int rm_recursive(const char *path)
{
cli_error(CL_ENOTSUP, "I do not yet remove directories");
int rc;
 
/* First see if it will just go away */
rc = rmdir(path);
if (rc == 0)
return 0;
 
/* Its not empty, recursively scan it */
cli_error(CL_ENOTSUP,
"Can not remove %s, directory not empty", path);
return 1;
}
 
84,9 → 150,16
printf("`%s' removes files and directories.\n", cmdname);
} else {
help_cmd_rm(HELP_SHORT);
printf(" %s <path> If <path> is a directory, all files and "
"directories\n within will be unconditionally removed.\n",
cmdname);
printf(
"Usage: %s [options] <path>\n"
"Options:\n"
" -h, --help A short option summary\n"
" -v, --version Print version information and exit\n"
" -r, --recursive Recursively remove sub directories\n"
" -f, --force Do not prompt prior to removing files\n"
" -s, --safe Stop if directories change during removal\n\n"
"Currently, %s is under development, some options don't work.\n",
cmdname, cmdname);
}
return CMD_VOID;
}
96,35 → 169,82
{
unsigned int argc;
unsigned int i, scope, ret = 0;
char *buff;
int c, opt_ind;
size_t len;
char *buff = NULL;
 
/* Count the arguments */
for (argc = 0; argv[argc] != NULL; argc ++);
 
if (argc < 2) {
cli_error(CL_EFAIL,
"%s - insufficient arguments. Try `help %s extended'",
cmdname, cmdname);
"%s: insufficient arguments. Try %s --help", cmdname, cmdname);
return CMD_FAILURE;
}
 
for (i = 1; i < argc; i++) {
buff = cli_strdup(argv[i]);
if (!rm_start(&rm)) {
cli_error(CL_ENOMEM, "%s: could not initialize", cmdname);
rm_end(&rm);
return CMD_FAILURE;
}
 
for (c = 0, optind = 0, opt_ind = 0; c != -1;) {
c = getopt_long(argc, argv, "hvrfs", long_options, &opt_ind);
switch (c) {
case 'h':
help_cmd_rm(HELP_LONG);
return CMD_SUCCESS;
case 'v':
printf("%s\n", RM_VERSION);
return CMD_SUCCESS;
case 'r':
rm.recursive = 1;
break;
case 'f':
rm.force = 1;
break;
case 's':
rm.safe = 1;
break;
}
}
 
if (optind == argc) {
cli_error(CL_EFAIL,
"%s: insufficient arguments. Try %s --help", cmdname, cmdname);
rm_end(&rm);
return CMD_FAILURE;
}
 
i = optind;
while (NULL != argv[i]) {
len = strlen(argv[i]) + 2;
buff = (char *) realloc(buff, len);
assert(buff != NULL);
memset(buff, 0, sizeof(buff));
snprintf(buff, len, argv[i]);
 
scope = rm_scope(buff);
switch (scope) {
case RM_BOGUS:
cli_error(CL_ENOENT, "Can not unlink %s", buff);
break;
case RM_BOGUS: /* FIXME */
case RM_FILE:
ret += rm_single(buff);
break;
case RM_DIR:
ret += rm_recursive(buff);
if (! rm.recursive) {
printf("%s is a directory, use -r to remove it.\n", buff);
ret ++;
} else {
ret += rm_recursive(buff);
}
break;
}
free(buff);
i++;
}
 
if (NULL != buff)
free(buff);
 
rm_end(&rm);
 
if (ret)
return CMD_FAILURE;
else