Changeset be8f92d in mainline


Ignore:
Timestamp:
2008-08-23T07:00:41Z (16 years ago)
Author:
Tim Post <echo@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
eb9618c
Parents:
5ab597d
Message:

mkdir is finished, -p / —parents options and more now functional

Location:
uspace/app/bdsh/cmds/modules/mkdir
Files:
2 edited

Legend:

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

    r5ab597d rbe8f92d  
    2929 */
    3030
    31 /* TODO:
    32  * Implement -p option when some type of getopt is ported */
    3331
    3432#include <stdio.h>
     
    3836#include <sys/types.h>
    3937#include <sys/stat.h>
     38#include <getopt.h>
     39#include <stdarg.h>
    4040
    4141#include "config.h"
    4242#include "errors.h"
     43#include "util.h"
    4344#include "entry.h"
    4445#include "mkdir.h"
    4546#include "cmds.h"
    4647
     48#define MKDIR_VERSION "0.0.1"
     49
    4750static char *cmdname = "mkdir";
    4851
    49 /* Dispays help for mkdir in various levels */
     52static struct option long_options[] = {
     53        {"parents", no_argument, 0, 'p'},
     54        {"verbose", no_argument, 0, 'v'},
     55        {"mode", required_argument, 0, 'm'},
     56        {"help", no_argument, 0, 'h'},
     57        {"version", no_argument, 0, 'V'},
     58        {"follow", no_argument, 0, 'f'},
     59        {0, 0, 0, 0}
     60};
     61
     62
    5063void * help_cmd_mkdir(unsigned int level)
    5164{
     
    5467        } else {
    5568                help_cmd_mkdir(HELP_SHORT);
    56                 printf("  `%s' <directory>\n", cmdname);
     69                printf(
     70                "Usage:  %s [options] <path>\n"
     71                "Options:\n"
     72                "  -h, --help       A short option summary\n"
     73                "  -V, --version    Print version information and exit\n"
     74                "  -p, --parents    Create needed parents for <path>\n"
     75                "  -m, --mode       Set permissions to [mode] (UNUSED)\n"
     76                "  -v, --verbose    Be extremely noisy about what is happening\n"
     77                "  -f, --follow     Go to the new directory once created\n"
     78                "Currently, %s is under development, some options don't work.\n",
     79                cmdname, cmdname);
    5780        }
    5881
     
    6083}
    6184
    62 /* Main entry point for mkdir, accepts an array of arguments */
     85/* This is kind of clunky, but effective for now */
     86unsigned int
     87create_directory(const char *path, unsigned int p)
     88{
     89        DIR *dirp;
     90        char *tmp = NULL, *buff = NULL, *wdp = NULL;
     91        char *dirs[255];
     92        unsigned int absolute = 0, i = 0, ret = 0;
     93
     94        /* Its a good idea to allocate path, plus we (may) need a copy of
     95         * path to tokenize if parents are specified */
     96        if (NULL == (tmp = cli_strdup(path))) {
     97                cli_error(CL_ENOMEM, "%s: path too big?", cmdname);
     98                return 1;
     99        }
     100
     101        if (NULL == (wdp = (char *) malloc(PATH_MAX))) {
     102                cli_error(CL_ENOMEM, "%s: could not alloc cwd", cmdname);
     103                free(tmp);
     104                return 1;
     105        }
     106
     107        /* The only reason for wdp is to be (optionally) verbose */
     108        getcwd(wdp, PATH_MAX);
     109
     110        /* Typical use without specifying the creation of parents */
     111        if (p == 0) {
     112                dirp = opendir(tmp);
     113                if (dirp) {
     114                        cli_error(CL_EEXISTS, "%s: can not create %s, try -p", cmdname, path);
     115                        closedir(dirp);
     116                        goto finit;
     117                }
     118                if (-1 == (mkdir(tmp, 0))) {
     119                        cli_error(CL_EFAIL, "%s: could not create %s", cmdname, path);
     120                        goto finit;
     121                }
     122        }
     123
     124        /* Parents need to be created, path has to be broken up */
     125
     126        /* See if path[0] is a slash, if so we have to remember to append it */
     127        if (tmp[0] == '/')
     128                absolute = 1;
     129
     130        /* TODO: Canonify the path prior to tokenizing it, see below */
     131        dirs[i] = cli_strtok(tmp, "/");
     132        while (dirs[i] && i < 255)
     133                dirs[++i] = cli_strtok(NULL, "/");
     134
     135        if (NULL == dirs[0])
     136                return 1;
     137
     138        if (absolute == 1) {
     139                asprintf(&buff, "/%s", dirs[0]);
     140                mkdir(buff, 0);
     141                chdir(buff);
     142                free(buff);
     143                getcwd(wdp, PATH_MAX);
     144                i = 1;
     145        } else {
     146                i = 0;
     147        }
     148
     149        while (dirs[i] != NULL) {
     150                /* Rewind to start of relative path */
     151                while (!strcmp(dirs[i], "..")) {
     152                        if (0 != (chdir(dirs[i]))) {
     153                                cli_error(CL_EFAIL, "%s: impossible path: %s",
     154                                        cmdname, path);
     155                                ret ++;
     156                                goto finit;
     157                        }
     158                        i++;
     159                }
     160                getcwd(wdp, PATH_MAX);
     161                /* Sometimes make or scripts conjoin odd paths. Account for something
     162                 * like this: ../../foo/bar/../foo/foofoo/./bar */
     163                if (!strcmp(dirs[i], "..") || !strcmp(dirs[i], ".")) {
     164                        chdir(dirs[i]);
     165                        getcwd(wdp, PATH_MAX);
     166                } else {
     167                        if (-1 == (mkdir(dirs[i], 0))) {
     168                                cli_error(CL_EFAIL,
     169                                        "%s: failed at %s/%s", wdp, dirs[i]);
     170                                goto finit;
     171                        }
     172                        if (0 != (chdir(dirs[i]))) {
     173                                cli_error(CL_EFAIL, "%s: failed creating %s\n",
     174                                        cmdname, dirs[i]);
     175                                ret ++;
     176                                break;
     177                        }
     178                }
     179                i++;
     180        }
     181        goto finit;
     182
     183finit:
     184        free(wdp);
     185        free(tmp);
     186        return ret;
     187}
     188
    63189int * cmd_mkdir(char **argv)
    64190{
    65         unsigned int argc;
    66         DIR *dirp;
    67 
    68         /* Count the arguments */
     191        unsigned int argc, create_parents = 0, i, ret = 0, follow = 0;
     192        unsigned int verbose = 0;
     193        int c, opt_ind;
     194        char *cwd;
     195
    69196        for (argc = 0; argv[argc] != NULL; argc ++);
    70197
    71         if (argc != 2) {
    72                 printf("%s - incorrect number of arguments. Try `help %s extended'\n",
     198        for (c = 0, optind = 0, opt_ind = 0; c != -1;) {
     199                c = getopt_long(argc, argv, "pvhVfm:", long_options, &opt_ind);
     200                switch (c) {
     201                case 'p':
     202                        create_parents = 1;
     203                        break;
     204                case 'v':
     205                        verbose = 1;
     206                        break;
     207                case 'h':
     208                        help_cmd_mkdir(HELP_LONG);
     209                        return CMD_SUCCESS;
     210                case 'V':
     211                        printf("%s\n", MKDIR_VERSION);
     212                        return CMD_SUCCESS;
     213                case 'f':
     214                        follow = 1;
     215                        break;
     216                case 'm':
     217                        printf("%s: [W] Ignoring mode %s\n", cmdname, optarg);
     218                        break;
     219                }
     220        }
     221
     222        argc -= optind;
     223
     224        if (argc < 1) {
     225                printf("%s - incorrect number of arguments. Try `%s --help'\n",
    73226                        cmdname, cmdname);
    74227                return CMD_FAILURE;
    75228        }
    76229
    77         dirp = opendir(argv[1]);
    78         if (dirp) {
    79                 closedir(dirp);
    80                 cli_error(CL_EEXISTS, "Can not create directory %s", argv[1]);
     230        if (NULL == (cwd = (char *) malloc(PATH_MAX))) {
     231                cli_error(CL_ENOMEM, "%s: could not allocate cwd", cmdname);
    81232                return CMD_FAILURE;
    82233        }
    83234
    84         if (mkdir(argv[1], 0) != 0) {
    85                 cli_error(CL_EFAIL, "Could not create %s", argv[1]);
     235        memset(cwd, 0, sizeof(cwd));
     236        getcwd(cwd, PATH_MAX);
     237
     238        for (i = optind; argv[i] != NULL; i++) {
     239                if (verbose == 1)
     240                        printf("%s: creating %s%s\n",
     241                                cmdname, argv[i],
     242                                create_parents ? " (and all parents)" : "");
     243                ret += create_directory(argv[i], create_parents);
     244        }
     245
     246        if (follow == 0)
     247                chdir(cwd);
     248
     249        free(cwd);
     250
     251        if (ret)
    86252                return CMD_FAILURE;
    87         }
    88 
    89         return CMD_SUCCESS;
     253        else
     254                return CMD_SUCCESS;
    90255}
    91256
  • uspace/app/bdsh/cmds/modules/mkdir/mkdir.h

    r5ab597d rbe8f92d  
    44/* Prototypes for the mkdir command, excluding entry points */
    55
    6 
     6extern unsigned int create_directory(const char *, unsigned int);
    77#endif /* MKDIR_H */
    88
Note: See TracChangeset for help on using the changeset viewer.