[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [tyndur-devel] [PATCH] rm folgende flags hinzugefügt: recursive, verbose, interactive
On Sat, Aug 15, 2009 at 10:20:52PM +0200, Patrick Kaufmann wrote:
> ---
> src/modules/c/shell/cmds/rm.c | 191 ++++++++++++++++++++++++++++++++++++++---
> 1 files changed, 180 insertions(+), 11 deletions(-)
>
> diff --git a/src/modules/c/shell/cmds/rm.c b/src/modules/c/shell/cmds/rm.c
> index a9d160f..19a7cc7 100644
> --- a/src/modules/c/shell/cmds/rm.c
> +++ b/src/modules/c/shell/cmds/rm.c
> @@ -39,8 +39,13 @@
> #include "unistd.h"
> #include "dir.h"
> #include <lost/config.h>
> +#include <getopt.h>
> +#include <collections.h>
> +#include <types.h>
> +#include <sys/stat.h>
>
> void rm_display_usage(void);
> +int rm_recursive(char* src_path, bool recurse, bool verbose, int interactive);
>
> #ifdef CONFIG_SHELL_BUILTIN_ONLY
> int shell_command_rm(int argc, char* argv[], const char* args)
> @@ -48,25 +53,189 @@ void rm_display_usage(void);
> int main(int argc, char* argv[])
> #endif
> {
> - if (argc != 2) {
> - rm_display_usage();
> - return -1;
> + static const struct option long_options[] =
> + {
> + { "recursive", no_argument, 0, 'r' },
> + { "help", no_argument, 0, 'h' },
> + { "verbose", no_argument, 0, 'v' },
> + { "interactive", optional_argument, 0, 'i' },
> + { "interactive", optional_argument, 0, 'I' },
Ist es sinnvoll, zweimal --interactive anzugeben? Ich würde erwarten,
dass er dann sowieso immer nur das erste nimmt.
> + { 0, 0, 0, 0 }
> + };
> +
> + int result = 0;
> + bool verbose = 0;
> + bool recursive = 0;
> + int directory = 0;
> + int interactive = 0;
> + char* src_path = NULL;
> +
> + list_t* sources = list_create();
> +
> + optind = 0;
> + opterr = 0;
> +
> + while (optind < argc) {
> + result = getopt_long(argc, argv, "vriIh", long_options, NULL);
> + if (result == -1) {
> + break;
> + }
> + switch (result) {
> + case 'r':
> + recursive = 1;
> + break;
> + case 'v':
> + verbose = 1;
> + break;
> + case 'i':
> + if ((optarg != NULL)) {
> + if (strcmp("always", optarg)) {
> + interactive = 2;
> + }
> + if (strcmp("once", optarg)) {
> + interactive = 1;
> + }
> + } else {
> + interactive = 1;
> + }
> + break;
> + case 'I':
> + if ((optarg != NULL)) {
> + if (strcmp("always", optarg)) {
> + interactive = 2;
> + }
> + if (strcmp("once", optarg)) {
> + interactive = 1;
> + }
> + } else {
> + interactive = 2;
> + }
> + break;
Dann könnte man sich nämlich hier einen if-Block sparen.
> + case 'h':
> + rm_display_usage();
> + return EXIT_SUCCESS;
> + case '?':
> + printf("rm: Unbekannter Parameter: '%c'\n", optopt);
> + return EXIT_FAILURE;
> + default:
> + break;
> + }
> }
> -
> - int result = io_remove_link(argv[1]);
> -
> - if (result != 0) {
> - puts("Fehler beim Loeschen des Links");
> +
> + if (!(optind < argc)) {
Wäre das als >= nicht lesbarer?
> + printf("Probiere \'rm --help\' fuer mehr Informationen\n");
> return EXIT_FAILURE;
> }
> + while (optind < argc) {
> + char* p = strdup(argv[optind++]);
> + int len = strlen(p);
> + if (p[len - 1] == '/') {
> + p[len - 1] = 0;
> + }
> + list_push(sources, p);
> + }
> +
> + while ((src_path = list_pop(sources))) {
> +
> + directory = is_directory(src_path);
> + if (directory) {
> + if (!recursive) {
> + printf("rm: \'%s/\' ist ein Ordner: Uebersprungen\n",
Verzeichnis heißt das Wort ;-)
> + src_path);
> + result = -1;
> + } else {
> + result += rm_recursive(src_path, TRUE, verbose, interactive);
> + }
> + } else {
> + result += rm_recursive(src_path, FALSE, verbose, interactive);
> + }
> + }
> + list_destroy(sources);
>
> +
> + if (result != 0) {
> + return EXIT_FAILURE;
> + }
> return EXIT_SUCCESS;
> }
>
> void rm_display_usage()
> {
> - puts("\nAufruf: rm <Pfad>");
> - puts("\nHardlink an <Pfad> loeschen. Falls es sich um den Letzten "
> - "handelt, wird die Datei/das Verzeichnis geloescht.");
> + puts("Aufruf: rm <Pfad>\n");
> + puts("Hardlink an <Pfad> loeschen. Falls es sich um den Letzten "
> + "handelt, wird die Datei/das Verzeichnis geloescht.\n"
> + "Optionen:\n"
> + " -r --recursive Verzeichnis rekursiv löschen\n"
> + " -v --verbose Statusmeldungen anzeigen\n"
> + " -i --interactive "
> + "Jedesmal fragen ob <Pfad> gelöscht werden soll\n"
> + " -I --interactive "
> + "Einmal fragen ob <Pfad> gelöscht werden soll\n"
> + " -h --help diese Hilfe anzeigen\n");
> +}
> +
> +int rm_recursive(char* src_path, bool recurse, bool verbose, int interactive)
> +{
> + int result = 0;
> + char* path = NULL;
> + io_resource_t* dir_res;
> + char c;
> + struct stat buf;
> + if ((stat(src_path, &buf))) {
> + printf("rm: \'%s\' ist inexistent\n", src_path);
> + return -1;
> + }
> +
> +
> + switch (interactive) {
> + case 1: // interactive_option = "always"
Dieser Kommentar am Zeilenende zeigt eigentlich deutlich, dass man hier
besser eine Konstante INTERACTIVE_ALWAYS statt einer magischen 1 benutzt
hätte.
> + printf("rm: \'%s\' loeschen? \n", src_path);
> + fflush(stdout);
> + while ((c = getchar()) == EOF);
> + if (c != 'y') {
> + printf("rm: \'%s\' übersprungen\n", src_path);
> + return -1; // Fehlschlag
> + }
> + break;
> + case 2: // interactive_option = "once"
> + printf("rm: \'%s\' loeschen? \n", src_path);
> + fflush(stdout);
> + while ((c = getchar()) == EOF);
> + if (c != 'y') {
> + printf("rm: \'%s\' übersprungen\n", src_path);
> + return -1;
> + }
> + interactive = 0;
> + break;
> + default: // interactive_option = NULL
> + break;
> + }
> + if (verbose) {
> + printf("removed \'%s\'\n", src_path);
Ups, falsche Sprache.