Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/bdsh/cmds/modules/cp/cp.c

    r1737bfb re367f5b8  
    3030#include <stdlib.h>
    3131#include <unistd.h>
     32#include <io/console.h>
     33#include <io/keycode.h>
    3234#include <getopt.h>
    3335#include <str.h>
     
    4648
    4749static const char *cmdname = "cp";
     50static console_ctrl_t *con;
    4851
    4952static struct option const long_options[] = {
    5053        { "buffer", required_argument, 0, 'b' },
    5154        { "force", no_argument, 0, 'f' },
     55        { "interactive", no_argument, 0, 'i'},
    5256        { "recursive", no_argument, 0, 'r' },
    5357        { "help", no_argument, 0, 'h' },
     
    139143}
    140144
     145static bool get_user_decision(bool bdefault, const char *message, ...)
     146{
     147        va_list args;
     148
     149        va_start(args, message);
     150        vprintf(message, args);
     151        va_end(args);
     152
     153        while (true) {
     154                kbd_event_t ev;
     155                console_flush(con);
     156                console_get_kbd_event(con, &ev);
     157                if ((ev.type != KEY_PRESS)
     158                    || (ev.mods & (KM_CTRL | KM_ALT)) != 0) {
     159                        continue;
     160                }
     161
     162                switch(ev.key) {
     163                case KC_Y:
     164                        printf("y\n");
     165                        return true;
     166                case KC_N:
     167                        printf("n\n");
     168                        return false;
     169                case KC_ENTER:
     170                        printf("%c\n", bdefault ? 'Y' : 'N');
     171                        return bdefault;
     172                default:
     173                        break;
     174                }
     175        }
     176}
     177
    141178static int64_t do_copy(const char *src, const char *dest,
    142     size_t blen, int vb, int recursive, int force)
     179    size_t blen, int vb, int recursive, int force, int interactive)
    143180{
    144181        int r = -1;
     
    192229                        /* e.g. cp file_name existing_file */
    193230
    194                         /* dest already exists, if force is set we will
    195                          * try to remove it.
     231                        /* dest already exists,
     232                         * if force is set we will try to remove it.
     233                         * if interactive is set user input is required.
    196234                         */
    197                         if (force) {
     235                        if (force && !interactive) {
    198236                                if (unlink(dest_path)) {
    199237                                        printf("Unable to remove %s\n",
     
    201239                                        goto exit;
    202240                                }
     241                        } else if (!force && interactive) {
     242                                bool overwrite = get_user_decision(false,
     243                                    "File already exists: %s. Overwrite? [y/N]: ",
     244                                    dest_path);
     245                                if (overwrite) {
     246                                        printf("Overwriting file: %s\n", dest_path);
     247                                        if (unlink(dest_path)) {
     248                                                printf("Unable to remove %s\n", dest_path);
     249                                                goto exit;
     250                                        }
     251                                } else {
     252                                        printf("Not overwriting file: %s\n", dest_path);
     253                                        r = 0;
     254                                        goto exit;
     255                                }
    203256                        } else {
    204                                 printf("file already exists: %s\n", dest_path);
     257                                printf("File already exists: %s\n", dest_path);
    205258                                goto exit;
    206259                        }
     
    302355                        /* Recursively call do_copy() */
    303356                        r = do_copy(src_dent, dest_dent, blen, vb, recursive,
    304                             force);
     357                            force, interactive);
    305358                        if (r)
    306359                                goto exit;
     
    315368        return r;
    316369}
    317 
    318370
    319371static int64_t copy_file(const char *src, const char *dest,
     
    380432            "  -v, --version    Print version information and exit\n"
    381433            "  -V, --verbose    Be annoyingly noisy about what's being done\n"
    382             "  -f, --force      Do not complain when <dest> exists\n"
     434            "  -f, --force      Do not complain when <dest> exists (overrides a previous -i)\n"
     435            "  -i, --interactive Ask what to do when <dest> exists (overrides a previous -f)\n"
    383436            "  -r, --recursive  Copy entire directories\n"
    384437            "  -b, --buffer ## Set the read buffer size to ##\n";
     
    397450        unsigned int argc, verbose = 0;
    398451        int buffer = 0, recursive = 0;
    399         int force = 0;
     452        int force = 0, interactive = 0;
    400453        int c, opt_ind;
    401454        int64_t ret;
    402455
     456        con = console_init(stdin, stdout);
    403457        argc = cli_count_args(argv);
    404458
    405459        for (c = 0, optind = 0, opt_ind = 0; c != -1;) {
    406                 c = getopt_long(argc, argv, "hvVfrb:", long_options, &opt_ind);
     460                c = getopt_long(argc, argv, "hvVfirb:", long_options, &opt_ind);
    407461                switch (c) {
    408462                case 'h':
     
    416470                        break;
    417471                case 'f':
     472                        interactive = 0;
    418473                        force = 1;
     474                        break;
     475                case 'i':
     476                        force = 0;
     477                        interactive = 1;
    419478                        break;
    420479                case 'r':
     
    426485                                    "(should be a number greater than zero)\n",
    427486                                    cmdname);
     487                                console_done(con);
    428488                                return CMD_FAILURE;
    429489                        }
     
    442502                printf("%s: invalid number of arguments. Try %s --help\n",
    443503                    cmdname, cmdname);
     504                console_done(con);
    444505                return CMD_FAILURE;
    445506        }
    446507
    447508        ret = do_copy(argv[optind], argv[optind + 1], buffer, verbose,
    448             recursive, force);
     509            recursive, force, interactive);
     510
     511        console_done(con);
    449512
    450513        if (ret == 0)
Note: See TracChangeset for help on using the changeset viewer.