Changeset 4c53333 in mainline for uspace/app/bdsh


Ignore:
Timestamp:
2013-07-11T08:21:10Z (13 years ago)
Author:
Maurizio Lombardi <m.lombardi85@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
64e63ce1
Parents:
80445cf (diff), c8bb1633 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

merge mainline changes

Location:
uspace/app/bdsh
Files:
13 added
4 deleted
22 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/bdsh/Makefile

    r80445cf r4c53333  
    2929
    3030USPACE_PREFIX = ../..
    31 LIBS = $(LIBBLOCK_PREFIX)/libblock.a $(LIBCLUI_PREFIX)/libclui.a \
    32         $(LIBFMTUTIL_PREFIX)/libfmtutil.a
    33 EXTRA_CFLAGS = -I$(LIBBLOCK_PREFIX) -I$(LIBCLUI_PREFIX) \
    34         -I$(LIBFMTUTIL_PREFIX) -I. -Icmds/ -Icmds/builtins -Icmds/modules
     31LIBS = $(LIBCLUI_PREFIX)/libclui.a $(LIBFMTUTIL_PREFIX)/libfmtutil.a
     32EXTRA_CFLAGS = -I$(LIBCLUI_PREFIX) -I$(LIBFMTUTIL_PREFIX) \
     33        -I. -Icmds/ -Icmds/builtins -Icmds/modules
    3534BINARY = bdsh
    3635
     
    4039        cmds/modules/mkfile/mkfile.c \
    4140        cmds/modules/rm/rm.c \
    42         cmds/modules/bdd/bdd.c \
    4341        cmds/modules/cat/cat.c \
    4442        cmds/modules/touch/touch.c \
     
    4846        cmds/modules/cp/cp.c \
    4947        cmds/modules/mv/mv.c \
     48        cmds/modules/printf/printf.c \
     49        cmds/modules/echo/echo.c \
    5050        cmds/modules/mount/mount.c \
    5151        cmds/modules/unmount/unmount.c \
    5252        cmds/modules/kcon/kcon.c \
     53        cmds/modules/cmp/cmp.c \
    5354        cmds/builtins/batch/batch.c \
    5455        cmds/builtins/exit/exit.c \
  • uspace/app/bdsh/TODO

    r80445cf r4c53333  
    3030* Add wrappers for signal, sigaction to make ports to modules easier
    3131
    32 * Add 'echo' and 'printf' modules.
    33 
    3432Regarding POSIX:
    3533----------------
  • uspace/app/bdsh/cmds/builtins/batch/batch.c

    r80445cf r4c53333  
    2929#include <stdio.h>
    3030#include <stdlib.h>
     31#include <stdbool.h>
     32#include <errno.h>
    3133#include "config.h"
    3234#include "util.h"
     
    4446        if (level == HELP_SHORT) {
    4547                printf(
    46                 "\n  batch [filename]\n"
     48                "\n  batch [filename] [-c]\n"
    4749                "  Issues commands stored in the file.\n"
    4850                "  Each command must correspond to the single line in the file.\n\n");
     
    5456                "  separate groups of commands. There is no support for comments,\n"
    5557                "  variables, recursion or other programming constructs - the `batch'\n"
    56                 "  command is indeed very trivial.\n\n");
     58                "  command is indeed very trivial.\n"
     59                "  If the filename is followed by -c, execution continues even if some\n"
     60                "  of the commands failed.\n\n");
    5761        }
    5862
     
    6569{
    6670        unsigned int argc;
     71        bool continue_despite_errors = false;
    6772
    6873        /* Count the arguments */
     
    7277                printf("%s - no input file provided.\n", cmdname);
    7378                return CMD_FAILURE;
     79        }
     80
     81        if (argc > 2) {
     82                if (str_cmp(argv[2], "-c") == 0)
     83                        continue_despite_errors = true;
    7484        }
    7585
     
    99109                                        rc = process_input(&fusr);
    100110                                        /* fusr->line was freed by process_input() */
     111                                        if ((rc != EOK) && continue_despite_errors) {
     112                                                /* Mute the error. */
     113                                                rc = EOK;
     114                                        }
    101115                                }
    102116                                if (rc == 0 && c != EOF) {
  • uspace/app/bdsh/cmds/builtins/cd/cd.c

    r80445cf r4c53333  
    4141static const char *cmdname = "cd";
    4242
     43/* Previous directory variables.
     44 *
     45 * Declaring them static to avoid many "== NULL" checks.
     46 * PATH_MAX is not that big to cause any problems with memory overhead.
     47 */
     48static char previous_directory[PATH_MAX] = "";
     49static char previous_directory_tmp[PATH_MAX];
     50static bool previous_directory_valid = true;
     51static bool previous_directory_set = false;
     52
     53static int chdir_and_remember(const char *new_dir) {
     54
     55        char *ok = getcwd(previous_directory_tmp, PATH_MAX);
     56        previous_directory_valid = ok != NULL;
     57        previous_directory_set = true;
     58
     59        int rc = chdir(new_dir);
     60        if (rc != EOK) {
     61                return rc;
     62        }
     63
     64        str_cpy(previous_directory, PATH_MAX, previous_directory_tmp);
     65        return EOK;
     66}
     67
    4368void help_cmd_cd(unsigned int level)
    4469{
     
    5580}
    5681
     82
    5783/* This is a very rudamentary 'cd' command. It is not 'link smart' (yet) */
    5884
     
    6288
    6389        argc = cli_count_args(argv);
     90
     91        /* Handle cd -- -. Override to switch to a directory named '-' */
     92        bool hyphen_override = false;
     93        char *target_directory = argv[1];
     94        if (argc == 3) {
     95                if (!str_cmp(argv[1], "--")) {
     96                        hyphen_override = true;
     97                        argc--;
     98                        target_directory = argv[2];
     99                }
     100        }
    64101
    65102        /* We don't yet play nice with whitespace, a getopt implementation should
     
    79116        }
    80117
    81         /* We have the correct # of arguments
    82      * TODO: handle tidle (~) expansion? */
     118        /* We have the correct # of arguments */
     119        // TODO: handle tidle (~) expansion? */
    83120
    84         rc = chdir(argv[1]);
     121        /* Handle 'cd -' first. */
     122        if (!str_cmp(target_directory, "-") && !hyphen_override) {
     123                if (!previous_directory_valid) {
     124                        cli_error(CL_EFAIL, "Cannot switch to previous directory");
     125                        return CMD_FAILURE;
     126                }
     127                if (!previous_directory_set) {
     128                        cli_error(CL_EFAIL, "No previous directory to switch to");
     129                        return CMD_FAILURE;
     130                }
     131                char *prev_dup = str_dup(previous_directory);
     132                if (prev_dup == NULL) {
     133                        cli_error(CL_ENOMEM, "Cannot switch to previous directory");
     134                        return CMD_FAILURE;
     135                }
     136                rc = chdir_and_remember(prev_dup);
     137                free(prev_dup);
     138        } else {
     139                rc = chdir_and_remember(target_directory);
     140        }
    85141
    86142        if (rc == 0) {
     
    93149                        break;
    94150                case ENOENT:
    95                         cli_error(CL_ENOENT, "Invalid directory `%s'", argv[1]);
     151                        cli_error(CL_ENOENT, "Invalid directory `%s'", target_directory);
    96152                        break;
    97153                default:
    98                         cli_error(CL_EFAIL, "Unable to change to `%s'", argv[1]);
     154                        cli_error(CL_EFAIL, "Unable to change to `%s'", target_directory);
    99155                        break;
    100156                }
  • uspace/app/bdsh/cmds/modules/cat/cat.c

    r80445cf r4c53333  
    6262static sysarg_t console_rows = 0;
    6363static bool should_quit = false;
     64static bool dash_represents_stdin = false;
    6465
    6566static console_ctrl_t *console = NULL;
     
    7374        { "more", no_argument, 0, 'm' },
    7475        { "hex", no_argument, 0, 'x' },
     76        { "stdin", no_argument, 0, 's' },
    7577        { 0, 0, 0, 0 }
    7678};
     
    9395                "  -m, --more       Pause after each screen full\n"
    9496                "  -x, --hex        Print bytes as hex values\n"
     97                "  -s  --stdin      Treat `-' in file list as standard input\n"
    9598                "Currently, %s is under development, some options don't work.\n",
    9699                cmdname, cmdname);
     
    114117static void waitkey()
    115118{
    116         kbd_event_t ev;
     119        cons_event_t ev;
     120        kbd_event_t *kev;
    117121       
    118122        while (true) {
    119                 if (!console_get_kbd_event(console, &ev)) {
     123                if (!console_get_event(console, &ev)) {
    120124                        return;
    121125                }
    122                 if (ev.type == KEY_PRESS) {
    123                         if (ev.key == KC_ESCAPE || ev.key == KC_Q) {
     126                if (ev.type == CEV_KEY && ev.ev.key.type == KEY_PRESS) {
     127                        kev = &ev.ev.key;
     128                       
     129                        if (kev->key == KC_ESCAPE || kev->key == KC_Q) {
    124130                                should_quit = true;
    125131                                return;
    126132                        }
    127                         if (ev.key == KC_C) {
     133                        if (kev->key == KC_C) {
    128134                                paging_enabled = false;
    129135                                return;
    130136                        }
    131                         if (ev.key == KC_ENTER || ev.key == KC_SPACE ||
    132                             ev.key == KC_PAGE_DOWN) {
     137                        if (kev->key == KC_ENTER || kev->key == KC_SPACE ||
     138                            kev->key == KC_PAGE_DOWN) {
    133139                                return;
    134140                        }
     
    172178        off64_t file_size = 0, length = 0;
    173179
    174         fd = open(fname, O_RDONLY);
     180        bool reading_stdin = dash_represents_stdin && (str_cmp(fname, "-") == 0);
     181       
     182        if (reading_stdin) {
     183                fd = fileno(stdin);
     184                /* Allow storing the whole UTF-8 character. */
     185                blen = STR_BOUNDS(1);
     186        } else
     187                fd = open(fname, O_RDONLY);
     188       
    175189        if (fd < 0) {
    176190                printf("Unable to open %s\n", fname);
     
    207221
    208222        do {
    209                 bytes = read(fd, buff + copied_bytes, (
    210                         (length != CAT_FULL_FILE && length - (off64_t)count <= (off64_t)(blen - copied_bytes)) ?
    211                         (size_t)(length - count) :
    212                         (blen - copied_bytes) ) );
     223                size_t bytes_to_read;
     224                if (reading_stdin) {
     225                        bytes_to_read = 1;
     226                } else {
     227                        if ((length != CAT_FULL_FILE) &&
     228                            (length - (off64_t)count <= (off64_t)(blen - copied_bytes))) {
     229                                bytes_to_read = (size_t) (length - count);
     230                        } else {
     231                                bytes_to_read = blen - copied_bytes;
     232                        }
     233                }
     234               
     235                bytes = read(fd, buff + copied_bytes, bytes_to_read);
    213236                bytes += copied_bytes;
    214237                copied_bytes = 0;
     
    242265                        reads++;
    243266                }
     267               
     268                if (reading_stdin)
     269                        fflush(stdout);
    244270        } while (bytes > 0 && !should_quit && (count < length || length == CAT_FULL_FILE));
    245271
     
    284310
    285311        for (c = 0, optind = 0, opt_ind = 0; c != -1;) {
    286                 c = getopt_long(argc, argv, "xhvmH:t:b:", long_options, &opt_ind);
     312                c = getopt_long(argc, argv, "xhvmH:t:b:s", long_options, &opt_ind);
    287313                switch (c) {
    288314                case 'h':
     
    318344                        hex = true;
    319345                        break;
     346                case 's':
     347                        dash_represents_stdin = true;
     348                        break;
    320349                }
    321350        }
  • uspace/app/bdsh/cmds/modules/cat/cat.h

    r80445cf r4c53333  
    44/* Prototypes for the cat command, excluding entry points */
    55
    6 static unsigned int cat_file(const char *, size_t, bool, off64_t, off64_t, bool);
    7 
    86#endif /* CAT_H */
    97
  • uspace/app/bdsh/cmds/modules/cp/cp.c

    r80445cf r4c53333  
    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                cons_event_t ev;
     155                console_flush(con);
     156                console_get_event(con, &ev);
     157                if (ev.type != CEV_KEY || ev.ev.key.type != KEY_PRESS ||
     158                    (ev.ev.key.mods & (KM_CTRL | KM_ALT)) != 0) {
     159                        continue;
     160                }
     161
     162                switch(ev.ev.key.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)
  • uspace/app/bdsh/cmds/modules/help/help.c

    r80445cf r4c53333  
    9898        builtin_t *cmd;
    9999        module_t *mod;
    100         unsigned int i;
    101100
    102101        printf("\n  Bdsh built-in commands:\n");
     
    104103
    105104        /* First, show a list of built in commands that are available in this mode */
    106         for (cmd = builtins; cmd->name != NULL; cmd++, i++) {
     105        for (cmd = builtins; cmd->name != NULL; cmd++) {
    107106                        if (is_builtin_alias(cmd->name))
    108107                                printf("   %-16s\tAlias for `%s'\n", cmd->name,
     
    112111        }
    113112
    114         i = 0;
    115 
    116113        /* Now, show a list of module commands that are available in this mode */
    117         for (mod = modules; mod->name != NULL; mod++, i++) {
     114        for (mod = modules; mod->name != NULL; mod++) {
    118115                        if (is_module_alias(mod->name))
    119116                                printf("   %-16s\tAlias for `%s'\n", mod->name,
  • uspace/app/bdsh/cmds/modules/help/help.h

    r80445cf r4c53333  
    33
    44/* Prototypes for the help command (excluding entry points) */
    5 static int is_mod_or_builtin(char *);
    65
    76#endif
  • uspace/app/bdsh/cmds/modules/ls/ls.c

    r80445cf r4c53333  
    315315{
    316316        if (stat(path, &de->s)) {
    317                 cli_error(CL_ENOENT, path);
     317                cli_error(CL_ENOENT, "%s", path);
    318318                return LS_BOGUS;
    319319        }
  • uspace/app/bdsh/cmds/modules/mkdir/mkdir.c

    r80445cf r4c53333  
    3636#include <stdarg.h>
    3737#include <str.h>
     38#include <errno.h>
     39#include <str_error.h>
     40#include <vfs/vfs.h>
    3841
    3942#include "config.h"
     
    8386/* This is kind of clunky, but effective for now */
    8487static unsigned int
    85 create_directory(const char *path, unsigned int p)
     88create_directory(const char *user_path, bool create_parents)
    8689{
    87         DIR *dirp;
    88         char *tmp = NULL, *buff = NULL, *wdp = NULL;
    89         char *dirs[255];
    90         unsigned int absolute = 0, i = 0, ret = 0;
    91 
    92         /* Its a good idea to allocate path, plus we (may) need a copy of
    93          * path to tokenize if parents are specified */
    94         if (NULL == (tmp = str_dup(path))) {
     90        /* Ensure we would always work with absolute and canonified path. */
     91        char *path = absolutize(user_path, NULL);
     92        if (path == NULL) {
    9593                cli_error(CL_ENOMEM, "%s: path too big?", cmdname);
    9694                return 1;
    9795        }
    9896
    99         if (NULL == (wdp = (char *) malloc(PATH_MAX))) {
    100                 cli_error(CL_ENOMEM, "%s: could not alloc cwd", cmdname);
    101                 free(tmp);
    102                 return 1;
    103         }
    104 
    105         /* The only reason for wdp is to be (optionally) verbose */
    106         getcwd(wdp, PATH_MAX);
    107 
    108         /* Typical use without specifying the creation of parents */
    109         if (p == 0) {
    110                 dirp = opendir(tmp);
    111                 if (dirp) {
    112                         cli_error(CL_EEXISTS, "%s: can not create %s, try -p", cmdname, path);
    113                         closedir(dirp);
    114                         goto finit;
    115                 }
    116                 if (-1 == (mkdir(tmp, 0))) {
    117                         cli_error(CL_EFAIL, "%s: could not create %s", cmdname, path);
    118                         goto finit;
    119                 }
    120         }
    121 
    122         /* Parents need to be created, path has to be broken up */
    123 
    124         /* See if path[0] is a slash, if so we have to remember to append it */
    125         if (tmp[0] == '/')
    126                 absolute = 1;
    127 
    128         /* TODO: Canonify the path prior to tokenizing it, see below */
    129         dirs[i] = strtok(tmp, "/");
    130         while (dirs[i] && i < 255)
    131                 dirs[++i] = strtok(NULL, "/");
    132 
    133         if (NULL == dirs[0])
    134                 return 1;
    135 
    136         if (absolute == 1) {
    137                 asprintf(&buff, "/%s", dirs[0]);
    138                 mkdir(buff, 0);
    139                 chdir(buff);
    140                 free(buff);
    141                 getcwd(wdp, PATH_MAX);
    142                 i = 1;
     97        int rc;
     98        int ret = 0;
     99
     100        if (!create_parents) {
     101                rc = mkdir(path, 0);
     102                if (rc != EOK) {
     103                        cli_error(CL_EFAIL, "%s: could not create %s (%s)",
     104                            cmdname, path, str_error(rc));
     105                        ret = 1;
     106                }
    143107        } else {
    144                 i = 0;
    145         }
    146 
    147         while (dirs[i] != NULL) {
    148                 /* Sometimes make or scripts conjoin odd paths. Account for something
    149                  * like this: ../../foo/bar/../foo/foofoo/./bar */
    150                 if (!str_cmp(dirs[i], "..") || !str_cmp(dirs[i], ".")) {
    151                         if (0 != (chdir(dirs[i]))) {
    152                                 cli_error(CL_EFAIL, "%s: impossible path: %s",
    153                                         cmdname, path);
    154                                 ret ++;
    155                                 goto finit;
    156                         }
    157                         getcwd(wdp, PATH_MAX);
    158                 } else {
    159                         if (-1 == (mkdir(dirs[i], 0))) {
    160                                 cli_error(CL_EFAIL,
    161                                         "%s: failed at %s/%s", wdp, dirs[i]);
    162                                 ret ++;
    163                                 goto finit;
    164                         }
    165                         if (0 != (chdir(dirs[i]))) {
    166                                 cli_error(CL_EFAIL, "%s: failed creating %s\n",
    167                                         cmdname, dirs[i]);
    168                                 ret ++;
     108                /* Create the parent directories as well. */
     109                size_t off = 0;
     110                while (1) {
     111                        size_t prev_off = off;
     112                        wchar_t cur_char = str_decode(path, &off, STR_NO_LIMIT);
     113                        if ((cur_char == 0) || (cur_char == U_SPECIAL)) {
    169114                                break;
    170115                        }
    171                 }
    172                 i++;
    173         }
    174         goto finit;
    175 
    176 finit:
    177         free(wdp);
    178         free(tmp);
     116                        if (cur_char != '/') {
     117                                continue;
     118                        }
     119                        if (prev_off == 0) {
     120                                continue;
     121                        }
     122                        /*
     123                         * If we are here, it means that:
     124                         * - we found /
     125                         * - it is not the first / (no need to create root
     126                         *   directory)
     127                         *
     128                         * We would now overwrite the / with 0 to terminate the
     129                         * string (that shall be okay because we are
     130                         * overwriting at the beginning of UTF sequence).
     131                         * That would allow us to create the directories
     132                         * in correct nesting order.
     133                         *
     134                         * Notice that we ignore EEXIST errors as some of
     135                         * the parent directories may already exist.
     136                         */
     137                        char slash_char = path[prev_off];
     138                        path[prev_off] = 0;
     139                        rc = mkdir(path, 0);
     140                        if (rc == EEXIST) {
     141                                rc = EOK;
     142                        }
     143
     144                        if (rc != EOK) {
     145                                cli_error(CL_EFAIL, "%s: could not create %s (%s)",
     146                                    cmdname, path, str_error(rc));
     147                                ret = 1;
     148                                goto leave;
     149                        }
     150
     151                        path[prev_off] = slash_char;
     152                }
     153                /* Create the final directory. */
     154                rc = mkdir(path, 0);
     155                if (rc != EOK) {
     156                        cli_error(CL_EFAIL, "%s: could not create %s (%s)",
     157                            cmdname, path, str_error(rc));
     158                        ret = 1;
     159                }
     160        }
     161
     162leave:
     163        free(path);
    179164        return ret;
    180165}
     
    182167int cmd_mkdir(char **argv)
    183168{
    184         unsigned int argc, create_parents = 0, i, ret = 0, follow = 0;
    185         unsigned int verbose = 0;
     169        unsigned int argc, i, ret = 0;
     170        bool create_parents = false, follow = false, verbose = false;
    186171        int c, opt_ind;
    187         char *cwd;
    188172
    189173        argc = cli_count_args(argv);
     
    193177                switch (c) {
    194178                case 'p':
    195                         create_parents = 1;
     179                        create_parents = true;
    196180                        break;
    197181                case 'v':
    198                         verbose = 1;
     182                        verbose = true;
    199183                        break;
    200184                case 'h':
     
    205189                        return CMD_SUCCESS;
    206190                case 'f':
    207                         follow = 1;
     191                        follow = true;
    208192                        break;
    209193                case 'm':
     
    221205        }
    222206
    223         if (NULL == (cwd = (char *) malloc(PATH_MAX))) {
    224                 cli_error(CL_ENOMEM, "%s: could not allocate cwd", cmdname);
    225                 return CMD_FAILURE;
    226         }
    227 
    228         memset(cwd, 0, sizeof(cwd));
    229         getcwd(cwd, PATH_MAX);
    230 
    231207        for (i = optind; argv[i] != NULL; i++) {
    232                 if (verbose == 1)
     208                if (verbose)
    233209                        printf("%s: creating %s%s\n",
    234210                                cmdname, argv[i],
     
    237213        }
    238214
    239         if (follow == 0)
    240                 chdir(cwd);
    241 
    242         free(cwd);
     215        if (follow && (argv[optind] != NULL)) {
     216                chdir(argv[optind]);
     217        }
    243218
    244219        if (ret)
  • uspace/app/bdsh/cmds/modules/mkdir/mkdir.h

    r80445cf r4c53333  
    44/* Prototypes for the mkdir command, excluding entry points */
    55
    6 static unsigned int create_directory(const char *, unsigned int);
    76#endif /* MKDIR_H */
    87
  • uspace/app/bdsh/cmds/modules/modules.h

    r80445cf r4c53333  
    5050#include "mkfile/entry.h"
    5151#include "rm/entry.h"
    52 #include "bdd/entry.h"
    5352#include "cat/entry.h"
    5453#include "touch/entry.h"
     
    6160#include "unmount/entry.h"
    6261#include "kcon/entry.h"
     62#include "printf/entry.h"
     63#include "echo/entry.h"
     64#include "cmp/entry.h"
    6365
    6466/* Each .def function fills the module_t struct with the individual name, entry
     
    7173#include "mkfile/mkfile_def.h"
    7274#include "rm/rm_def.h"
    73 #include "bdd/bdd_def.h"
    7475#include "cat/cat_def.h"
    7576#include "touch/touch_def.h"
     
    8283#include "unmount/unmount_def.h"
    8384#include "kcon/kcon_def.h"
     85#include "printf/printf_def.h"
     86#include "echo/echo_def.h"
     87#include "cmp/cmp_def.h"
    8488
    8589        {NULL, NULL, NULL, NULL}
  • uspace/app/bdsh/cmds/modules/pwd/pwd.c

    r80445cf r4c53333  
    5555        }
    5656
    57         memset(buff, 0, sizeof(buff));
     57        memset(buff, 0, PATH_MAX);
    5858        getcwd(buff, PATH_MAX);
    5959
  • uspace/app/bdsh/cmds/modules/rm/rm.c

    r80445cf r4c53333  
    4646#define RM_VERSION "0.0.1"
    4747
    48 static rm_job_t rm;
    49 
    5048static struct option const long_options[] = {
    5149        { "help", no_argument, 0, 'h' },
     
    5755};
    5856
     57/* Return values for rm_scope() */
     58#define RM_BOGUS 0
     59#define RM_FILE  1
     60#define RM_DIR   2
     61
     62/* Flags for rm_update() */
     63#define _RM_ENTRY   0
     64#define _RM_ADVANCE 1
     65#define _RM_REWIND  2
     66#define _RM_EXIT    3
     67
     68/* A simple job structure */
     69typedef struct {
     70        /* Options set at run time */
     71        unsigned int force;      /* -f option */
     72        unsigned int recursive;  /* -r option */
     73        unsigned int safe;       /* -s option */
     74
     75        /* Keeps track of the job in progress */
     76        int advance; /* How far deep we've gone since entering */
     77        DIR *entry;  /* Entry point to the tree being removed */
     78        char *owd;   /* Where we were when we invoked rm */
     79        char *cwd;   /* Current directory being transversed */
     80        char *nwd;   /* Next directory to be transversed */
     81
     82        /* Counters */
     83        int f_removed; /* Number of files unlinked */
     84        int d_removed; /* Number of directories unlinked */
     85} rm_job_t;
     86
     87static rm_job_t rm;
     88
     89static unsigned int rm_recursive(const char *);
     90
    5991static unsigned int rm_start(rm_job_t *rm)
    6092{
     
    6799        if (NULL == (rm->nwd = (char *) malloc(PATH_MAX)))
    68100                return 0;
    69         memset(rm->nwd, 0, sizeof(rm->nwd));
     101        memset(rm->nwd, 0, PATH_MAX);
    70102
    71103        if (NULL == (rm->owd = (char *) malloc(PATH_MAX)))
    72104                return 0;
    73         memset(rm->owd, 0, sizeof(rm->owd));
     105        memset(rm->owd, 0, PATH_MAX);
    74106
    75107        if (NULL == (rm->cwd = (char *) malloc(PATH_MAX)))
    76108                return 0;
    77         memset(rm->cwd, 0, sizeof(rm->cwd));
     109        memset(rm->cwd, 0, PATH_MAX);
    78110
    79111        chdir(".");
     
    95127        if (NULL != rm->cwd)
    96128                free(rm->cwd);
     129}
     130
     131static unsigned int rm_single(const char *path)
     132{
     133        if (unlink(path)) {
     134                cli_error(CL_EFAIL, "rm: could not remove file %s", path);
     135                return 1;
     136        }
     137        return 0;
     138}
     139
     140static unsigned int rm_scope(const char *path)
     141{
     142        int fd;
     143        DIR *dirp;
     144
     145        dirp = opendir(path);
     146        if (dirp) {
     147                closedir(dirp);
     148                return RM_DIR;
     149        }
     150
     151        fd = open(path, O_RDONLY);
     152        if (fd > 0) {
     153                close(fd);
     154                return RM_FILE;
     155        }
     156
     157        return RM_BOGUS;
    97158}
    98159
     
    154215
    155216        return ret + 1;
    156 }
    157 
    158 static unsigned int rm_single(const char *path)
    159 {
    160         if (unlink(path)) {
    161                 cli_error(CL_EFAIL, "rm: could not remove file %s", path);
    162                 return 1;
    163         }
    164         return 0;
    165 }
    166 
    167 static unsigned int rm_scope(const char *path)
    168 {
    169         int fd;
    170         DIR *dirp;
    171 
    172         dirp = opendir(path);
    173         if (dirp) {
    174                 closedir(dirp);
    175                 return RM_DIR;
    176         }
    177 
    178         fd = open(path, O_RDONLY);
    179         if (fd > 0) {
    180                 close(fd);
    181                 return RM_FILE;
    182         }
    183 
    184         return RM_BOGUS;
    185217}
    186218
     
    266298                        break;
    267299                }
    268                 memset(buff, 0, sizeof(buff));
     300                memset(buff, 0, len);
    269301                snprintf(buff, len, "%s", argv[i]);
    270302
  • uspace/app/bdsh/cmds/modules/rm/rm.h

    r80445cf r4c53333  
    22#define RM_H
    33
    4 /* Return values for rm_scope() */
    5 #define RM_BOGUS 0
    6 #define RM_FILE  1
    7 #define RM_DIR   2
    8 
    9 /* Flags for rm_update() */
    10 #define _RM_ENTRY   0
    11 #define _RM_ADVANCE 1
    12 #define _RM_REWIND  2
    13 #define _RM_EXIT    3
    14 
    15 /* A simple job structure */
    16 typedef struct {
    17         /* Options set at run time */
    18         unsigned int force;      /* -f option */
    19         unsigned int recursive;  /* -r option */
    20         unsigned int safe;       /* -s option */
    21 
    22         /* Keeps track of the job in progress */
    23         int advance; /* How far deep we've gone since entering */
    24         DIR *entry;  /* Entry point to the tree being removed */
    25         char *owd;   /* Where we were when we invoked rm */
    26         char *cwd;   /* Current directory being transversed */
    27         char *nwd;   /* Next directory to be transversed */
    28 
    29         /* Counters */
    30         int f_removed; /* Number of files unlinked */
    31         int d_removed; /* Number of directories unlinked */
    32 } rm_job_t;
    33 
    34 
    354/* Prototypes for the rm command, excluding entry points */
    36 static unsigned int rm_start(rm_job_t *);
    37 static void rm_end(rm_job_t *rm);
    38 static unsigned int rm_recursive(const char *);
    39 static unsigned int rm_single(const char *);
    40 static unsigned int rm_scope(const char *);
    415
    426#endif /* RM_H */
  • uspace/app/bdsh/cmds/modules/sleep/sleep.c

    r80445cf r4c53333  
    2727 */
    2828
     29#include <errno.h>
    2930#include <stdio.h>
    3031#include <stdlib.h>
     32#include <unistd.h>
    3133#include "config.h"
    3234#include "util.h"
     
    4143void help_cmd_sleep(unsigned int level)
    4244{
    43         printf("This is the %s help for '%s'.\n",
    44                 level ? EXT_HELP : SHORT_HELP, cmdname);
     45        if (level == HELP_SHORT) {
     46                printf("`%s' pauses for a given time interval\n", cmdname);
     47        } else {
     48                help_cmd_sleep(HELP_SHORT);
     49                printf(
     50                    "Usage:  %s <duration>\n"
     51                    "The duration is a decimal number of seconds.\n",
     52                    cmdname);
     53        }
     54
    4555        return;
     56}
     57
     58/** Convert string containing decimal seconds to useconds_t.
     59 *
     60 * @param nptr   Pointer to string.
     61 * @param result Result of the conversion.
     62 * @return EOK if conversion was successful.
     63 */
     64static int decimal_to_useconds(const char *nptr, useconds_t *result)
     65{
     66        int ret;
     67        uint64_t whole_seconds;
     68        uint64_t frac_seconds;
     69        const char *endptr;
     70
     71        /* Check for whole seconds */
     72        if (*nptr == '.') {
     73                whole_seconds = 0;
     74                endptr = (char *)nptr;
     75        } else {
     76                ret = str_uint64_t(nptr, &endptr, 10, false, &whole_seconds);
     77                if (ret != EOK)
     78                        return ret;
     79        }
     80
     81        /* Check for fractional seconds */
     82        if (*endptr == '\0') {
     83                frac_seconds = 0;
     84        } else if (*endptr == '.' && endptr[1] == '\0') {
     85                frac_seconds = 0;
     86        } else if (*endptr == '.') {
     87                nptr = endptr + 1;
     88                ret = str_uint64_t(nptr, &endptr, 10, true, &frac_seconds);
     89                if (ret != EOK)
     90                        return ret;
     91
     92                int ndigits = endptr - nptr;
     93                for (; ndigits < 6; ndigits++)
     94                        frac_seconds *= 10;
     95                for (; ndigits > 6; ndigits--)
     96                        frac_seconds /= 10;
     97        } else {
     98                return EINVAL;
     99        }
     100
     101        /* Check for overflow */
     102        useconds_t total = whole_seconds * 1000000 + frac_seconds;
     103        if (total / 1000000 != whole_seconds)
     104                return EOVERFLOW;
     105
     106        *result = total;
     107
     108        return EOK;
    46109}
    47110
     
    49112int cmd_sleep(char **argv)
    50113{
     114        int ret;
    51115        unsigned int argc;
    52         unsigned int i;
     116        useconds_t duration = 0;
    53117
    54118        /* Count the arguments */
    55         for (argc = 0; argv[argc] != NULL; argc ++);
     119        argc = cli_count_args(argv);
    56120
    57         printf("%s %s\n", TEST_ANNOUNCE, cmdname);
    58         printf("%d arguments passed to %s", argc - 1, cmdname);
    59 
    60         if (argc < 2) {
    61                 printf("\n");
    62                 return CMD_SUCCESS;
     121        if (argc != 2) {
     122                printf("%s - incorrect number of arguments. Try `help %s'\n",
     123                    cmdname, cmdname);
     124                return CMD_FAILURE;
    63125        }
    64126
    65         printf(":\n");
    66         for (i = 1; i < argc; i++)
    67                 printf("[%d] -> %s\n", i, argv[i]);
     127        ret = decimal_to_useconds(argv[1], &duration);
     128        if (ret != EOK) {
     129                printf("%s - invalid duration.\n", cmdname);
     130                return CMD_FAILURE;
     131        }
     132
     133        (void) usleep(duration);
    68134
    69135        return CMD_SUCCESS;
  • uspace/app/bdsh/compl.c

    r80445cf r4c53333  
    2828 */
    2929
    30 #include <bool.h>
     30#include <stdbool.h>
    3131#include <dirent.h>
    3232#include <errno.h>
  • uspace/app/bdsh/config.h

    r80445cf r4c53333  
    5555#define PACKAGE_STRING "The brain dead shell"
    5656#define PACKAGE_TARNAME "bdsh"
    57 #define PACKAGE_VERSION "0.0.1"
    58 
    59 
    60 
     57#define PACKAGE_VERSION "0.1.0"
  • uspace/app/bdsh/errors.h

    r80445cf r4c53333  
    3030#define ERRORS_H
    3131
     32#include <io/verify.h>
     33
    3234/* Various error levels */
    3335#define CL_EFATAL  -1
     
    4648extern volatile int cli_errno;
    4749
    48 extern void cli_error(int, const char *, ...);
     50extern void cli_error(int, const char *, ...)
     51    PRINTF_ATTRIBUTE(2, 3);
    4952
    5053#endif
  • uspace/app/bdsh/exec.c

    r80445cf r4c53333  
    8383        /* We now have n places to look for the command */
    8484        for (i = 0; search_dir[i] != NULL; i++) {
    85                 memset(found, 0, sizeof(found));
     85                memset(found, 0, PATH_MAX);
    8686                snprintf(found, PATH_MAX, "%s/%s", search_dir[i], cmd);
    8787                if (-1 != try_access(found)) {
  • uspace/app/bdsh/input.c

    r80445cf r4c53333  
    4141#include <errno.h>
    4242#include <assert.h>
    43 #include <bool.h>
     43#include <stdbool.h>
    4444#include <tinput.h>
    4545
     
    6767int process_input(cliuser_t *usr)
    6868{
    69         token_t *tokens = calloc(WORD_MAX, sizeof(token_t));
    70         if (tokens == NULL)
     69        token_t *tokens_buf = calloc(WORD_MAX, sizeof(token_t));
     70        if (tokens_buf == NULL)
    7171                return ENOMEM;
     72        token_t *tokens = tokens_buf;
    7273       
    7374        char *cmd[WORD_MAX];
     
    8081
    8182        if (usr->line == NULL) {
    82                 free(tokens);
     83                free(tokens_buf);
    8384                return CL_EFAIL;
    8485        }
     
    213214        }
    214215        tok_fini(&tok);
    215         free(tokens);
     216        free(tokens_buf);
    216217
    217218        return rc;
     
    268269        if (rc != EOK) {
    269270                /* Error in communication with console */
     271                cli_quit = 1;
    270272                return;
    271273        }
Note: See TracChangeset for help on using the changeset viewer.