00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include <stdio.h>
00033 #include <stdlib.h>
00034 #include <dirent.h>
00035 #include <fcntl.h>
00036 #include <sys/types.h>
00037 #include <sys/stat.h>
00038 #include <getopt.h>
00039 #include <stdarg.h>
00040 #include <str.h>
00041
00042 #include "config.h"
00043 #include "errors.h"
00044 #include "util.h"
00045 #include "entry.h"
00046 #include "mkdir.h"
00047 #include "cmds.h"
00048
00049 #define MKDIR_VERSION "0.0.1"
00050
00051 static const char *cmdname = "mkdir";
00052
00053 static struct option const long_options[] = {
00054 {"parents", no_argument, 0, 'p'},
00055 {"verbose", no_argument, 0, 'v'},
00056 {"mode", required_argument, 0, 'm'},
00057 {"help", no_argument, 0, 'h'},
00058 {"version", no_argument, 0, 'V'},
00059 {"follow", no_argument, 0, 'f'},
00060 {0, 0, 0, 0}
00061 };
00062
00063
00064 void help_cmd_mkdir(unsigned int level)
00065 {
00066 if (level == HELP_SHORT) {
00067 printf("`%s' creates a new directory\n", cmdname);
00068 } else {
00069 help_cmd_mkdir(HELP_SHORT);
00070 printf(
00071 "Usage: %s [options] <path>\n"
00072 "Options:\n"
00073 " -h, --help A short option summary\n"
00074 " -V, --version Print version information and exit\n"
00075 " -p, --parents Create needed parents for <path>\n"
00076 " -m, --mode Set permissions to [mode] (UNUSED)\n"
00077 " -v, --verbose Be extremely noisy about what is happening\n"
00078 " -f, --follow Go to the new directory once created\n"
00079 "Currently, %s is under development, some options don't work.\n",
00080 cmdname, cmdname);
00081 }
00082
00083 return;
00084 }
00085
00086
00087 static unsigned int
00088 create_directory(const char *path, unsigned int p)
00089 {
00090 DIR *dirp;
00091 char *tmp = NULL, *buff = NULL, *wdp = NULL;
00092 char *dirs[255];
00093 unsigned int absolute = 0, i = 0, ret = 0;
00094
00095
00096
00097 if (NULL == (tmp = str_dup(path))) {
00098 cli_error(CL_ENOMEM, "%s: path too big?", cmdname);
00099 return 1;
00100 }
00101
00102 if (NULL == (wdp = (char *) malloc(PATH_MAX))) {
00103 cli_error(CL_ENOMEM, "%s: could not alloc cwd", cmdname);
00104 free(tmp);
00105 return 1;
00106 }
00107
00108
00109 getcwd(wdp, PATH_MAX);
00110
00111
00112 if (p == 0) {
00113 dirp = opendir(tmp);
00114 if (dirp) {
00115 cli_error(CL_EEXISTS, "%s: can not create %s, try -p", cmdname, path);
00116 closedir(dirp);
00117 goto finit;
00118 }
00119 if (-1 == (mkdir(tmp, 0))) {
00120 cli_error(CL_EFAIL, "%s: could not create %s", cmdname, path);
00121 goto finit;
00122 }
00123 }
00124
00125
00126
00127
00128 if (tmp[0] == '/')
00129 absolute = 1;
00130
00131
00132 dirs[i] = strtok(tmp, "/");
00133 while (dirs[i] && i < 255)
00134 dirs[++i] = strtok(NULL, "/");
00135
00136 if (NULL == dirs[0])
00137 return 1;
00138
00139 if (absolute == 1) {
00140 asprintf(&buff, "/%s", dirs[0]);
00141 mkdir(buff, 0);
00142 chdir(buff);
00143 free(buff);
00144 getcwd(wdp, PATH_MAX);
00145 i = 1;
00146 } else {
00147 i = 0;
00148 }
00149
00150 while (dirs[i] != NULL) {
00151
00152
00153 if (!str_cmp(dirs[i], "..") || !str_cmp(dirs[i], ".")) {
00154 if (0 != (chdir(dirs[i]))) {
00155 cli_error(CL_EFAIL, "%s: impossible path: %s",
00156 cmdname, path);
00157 ret ++;
00158 goto finit;
00159 }
00160 getcwd(wdp, PATH_MAX);
00161 } else {
00162 if (-1 == (mkdir(dirs[i], 0))) {
00163 cli_error(CL_EFAIL,
00164 "%s: failed at %s/%s", wdp, dirs[i]);
00165 ret ++;
00166 goto finit;
00167 }
00168 if (0 != (chdir(dirs[i]))) {
00169 cli_error(CL_EFAIL, "%s: failed creating %s\n",
00170 cmdname, dirs[i]);
00171 ret ++;
00172 break;
00173 }
00174 }
00175 i++;
00176 }
00177 goto finit;
00178
00179 finit:
00180 free(wdp);
00181 free(tmp);
00182 return ret;
00183 }
00184
00185 int cmd_mkdir(char **argv)
00186 {
00187 unsigned int argc, create_parents = 0, i, ret = 0, follow = 0;
00188 unsigned int verbose = 0;
00189 int c, opt_ind;
00190 char *cwd;
00191
00192 argc = cli_count_args(argv);
00193
00194 for (c = 0, optind = 0, opt_ind = 0; c != -1;) {
00195 c = getopt_long(argc, argv, "pvhVfm:", long_options, &opt_ind);
00196 switch (c) {
00197 case 'p':
00198 create_parents = 1;
00199 break;
00200 case 'v':
00201 verbose = 1;
00202 break;
00203 case 'h':
00204 help_cmd_mkdir(HELP_LONG);
00205 return CMD_SUCCESS;
00206 case 'V':
00207 printf("%s\n", MKDIR_VERSION);
00208 return CMD_SUCCESS;
00209 case 'f':
00210 follow = 1;
00211 break;
00212 case 'm':
00213 printf("%s: [W] Ignoring mode %s\n", cmdname, optarg);
00214 break;
00215 }
00216 }
00217
00218 argc -= optind;
00219
00220 if (argc < 1) {
00221 printf("%s - incorrect number of arguments. Try `%s --help'\n",
00222 cmdname, cmdname);
00223 return CMD_FAILURE;
00224 }
00225
00226 if (NULL == (cwd = (char *) malloc(PATH_MAX))) {
00227 cli_error(CL_ENOMEM, "%s: could not allocate cwd", cmdname);
00228 return CMD_FAILURE;
00229 }
00230
00231 memset(cwd, 0, sizeof(cwd));
00232 getcwd(cwd, PATH_MAX);
00233
00234 for (i = optind; argv[i] != NULL; i++) {
00235 if (verbose == 1)
00236 printf("%s: creating %s%s\n",
00237 cmdname, argv[i],
00238 create_parents ? " (and all parents)" : "");
00239 ret += create_directory(argv[i], create_parents);
00240 }
00241
00242 if (follow == 0)
00243 chdir(cwd);
00244
00245 free(cwd);
00246
00247 if (ret)
00248 return CMD_FAILURE;
00249 else
00250 return CMD_SUCCESS;
00251 }
00252