~martin-decky/helenos/rcu

« back to all changes in this revision

Viewing changes to uspace/app/bdsh/cmds/modules/cp/cp.c

  • Committer: Vojtech Horky
  • Date: 2012-05-23 12:03:26 UTC
  • mfrom: (1443.1.19 misc)
  • mto: This revision was merged to the branch mainline in revision 1479.
  • Revision ID: vojtechhorky@users.sourceforge.net-20120523120326-jv50stjymxmh598s
Merge GSOC-originated patches 

Merge from lp:~vojtech-horky/helenos/misc.

The merge includes:
 * Switching to previous directory with `cd -' in Bdsh
 * Interactive mode for cp module in Bdsh
 * Implementation of sleep command
 * printf and echo for Bdsh
 * Rewrite of the mkdir module
 * Ctrl-arrow jumps over words in the editor
 * The scripts work with Python 3

Show diffs side-by-side

added added

removed removed

Lines of Context:
29
29
#include <stdio.h>
30
30
#include <stdlib.h>
31
31
#include <unistd.h>
 
32
#include <io/console.h>
 
33
#include <io/keycode.h>
32
34
#include <getopt.h>
33
35
#include <str.h>
34
36
#include <fcntl.h>
45
47
#define CP_DEFAULT_BUFLEN  1024
46
48
 
47
49
static const char *cmdname = "cp";
 
50
static console_ctrl_t *con;
48
51
 
49
52
static struct option const long_options[] = {
50
53
        { "buffer", required_argument, 0, 'b' },
51
54
        { "force", no_argument, 0, 'f' },
 
55
        { "interactive", no_argument, 0, 'i'},
52
56
        { "recursive", no_argument, 0, 'r' },
53
57
        { "help", no_argument, 0, 'h' },
54
58
        { "version", no_argument, 0, 'v' },
138
142
        str_append(path1, path1_size, path2);
139
143
}
140
144
 
 
145
static 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
 
141
178
static 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)
143
180
{
144
181
        int r = -1;
145
182
        char dest_path[PATH_MAX];
191
228
                } else if (dest_type == TYPE_FILE) {
192
229
                        /* e.g. cp file_name existing_file */
193
230
 
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.
196
234
                         */
197
 
                        if (force) {
 
235
                        if (force && !interactive) {
198
236
                                if (unlink(dest_path)) {
199
237
                                        printf("Unable to remove %s\n",
200
238
                                            dest_path);
201
239
                                        goto exit;
202
240
                                }
 
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
                                }
203
256
                        } else {
204
 
                                printf("file already exists: %s\n", dest_path);
 
257
                                printf("File already exists: %s\n", dest_path);
205
258
                                goto exit;
206
259
                        }
207
260
                }
301
354
 
302
355
                        /* Recursively call do_copy() */
303
356
                        r = do_copy(src_dent, dest_dent, blen, vb, recursive,
304
 
                            force);
 
357
                            force, interactive);
305
358
                        if (r)
306
359
                                goto exit;
307
360
 
315
368
        return r;
316
369
}
317
370
 
318
 
 
319
371
static int64_t copy_file(const char *src, const char *dest,
320
372
        size_t blen, int vb)
321
373
{
379
431
            "  -h, --help       A short option summary\n"
380
432
            "  -v, --version    Print version information and exit\n"
381
433
            "  -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"
383
436
            "  -r, --recursive  Copy entire directories\n"
384
437
            "  -b, --buffer ## Set the read buffer size to ##\n";
385
438
        if (level == HELP_SHORT) {
396
449
{
397
450
        unsigned int argc, verbose = 0;
398
451
        int buffer = 0, recursive = 0;
399
 
        int force = 0;
 
452
        int force = 0, interactive = 0;
400
453
        int c, opt_ind;
401
454
        int64_t ret;
402
455
 
 
456
        con = console_init(stdin, stdout);
403
457
        argc = cli_count_args(argv);
404
458
 
405
459
        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);
407
461
                switch (c) { 
408
462
                case 'h':
409
463
                        help_cmd_cp(1);
415
469
                        verbose = 1;
416
470
                        break;
417
471
                case 'f':
 
472
                        interactive = 0;
418
473
                        force = 1;
419
474
                        break;
 
475
                case 'i':
 
476
                        force = 0;
 
477
                        interactive = 1;
 
478
                        break;
420
479
                case 'r':
421
480
                        recursive = 1;
422
481
                        break;
425
484
                                printf("%s: Invalid buffer specification, "
426
485
                                    "(should be a number greater than zero)\n",
427
486
                                    cmdname);
 
487
                                console_done(con);
428
488
                                return CMD_FAILURE;
429
489
                        }
430
490
                        if (verbose)
441
501
        if (argc != 2) {
442
502
                printf("%s: invalid number of arguments. Try %s --help\n",
443
503
                    cmdname, cmdname);
 
504
                console_done(con);
444
505
                return CMD_FAILURE;
445
506
        }
446
507
 
447
508
        ret = do_copy(argv[optind], argv[optind + 1], buffer, verbose,
448
 
            recursive, force);
 
509
            recursive, force, interactive);
 
510
 
 
511
        console_done(con);
449
512
 
450
513
        if (ret == 0)
451
514
                return CMD_SUCCESS;