[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.