1 /* Copyright 1986-1992 Emmet P. Gray.
2 * Copyright 1996-2002,2007-2009 Alain Knaff.
3 * This file is part of mtools.
5 * Mtools is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * Mtools is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with Mtools. If not, see <http://www.gnu.org/licenses/>.
19 * Makes an MSDOS directory
25 #include "sysincludes.h"
31 #include "nameclash.h"
36 * Preserve the file modification times after the fclose()
39 typedef struct Arg_t {
50 typedef struct CreateArg_t {
58 * Open the named file for read, create the cluster chain, return the
59 * directory structure or NULL on error.
61 static int makeit(dos_name_t *dosname,
64 direntry_t *targetEntry)
67 CreateArg_t *arg = (CreateArg_t *) arg0;
71 /* will it fit? At least one cluster must be free */
72 if (!getfreeMinClusters(targetEntry->Dir, 1))
75 mk_entry(dosname, ATTR_DIR, 1, 0, arg->mtime, &targetEntry->dir);
76 Target = OpenFileByDirentry(targetEntry);
78 fprintf(stderr,"Could not open Target\n");
82 /* this allocates the first cluster for our directory */
84 initializeDirentry(&subEntry, Target);
87 GET_DATA(targetEntry->Dir, 0, 0, 0, &fat);
88 if (fat == fat32RootCluster(targetEntry->Dir)) {
91 mk_entry_from_base(".. ", ATTR_DIR, fat, 0, arg->mtime, &subEntry.dir);
94 FLUSH((Stream_t *) Target);
96 GET_DATA(Target, 0, 0, 0, &fat);
97 mk_entry_from_base(". ", ATTR_DIR, fat, 0, arg->mtime, &subEntry.dir);
100 mk_entry(dosname, ATTR_DIR | arg->attr, fat, 0, arg->mtime,
102 arg->NewDir = Target;
107 static void usage(int ret) NORETURN;
108 static void usage(int ret)
111 "Mtools version %s, dated %s\n", mversion, mdate);
113 "Usage: %s [-D clash_option] file targetfile\n", progname);
115 " %s [-D clash_option] file [files...] target_directory\n",
120 Stream_t *createDir(Stream_t *Dir, const char *filename, ClashHandling_t *ch,
121 unsigned char attr, time_t mtime)
130 if (!getfreeMinClusters(Dir, 1))
133 ret = mwrite_one(Dir, filename, 0, makeit, &arg, ch);
140 static int createDirCallback(direntry_t *entry, MainParam_t *mp)
145 ret = createDir(mp->File, mp->targetName, &((Arg_t *)(mp->arg))->ch,
146 ATTR_DIR, getTimeNow(&now));
156 void mmd(int argc, char **argv, int type)
161 /* get command line options */
163 init_clash_handling(& arg.ch);
165 /* get command line options */
166 if(helpFlag(argc, argv))
168 while ((c = getopt(argc, argv, "i:D:oh")) != EOF) {
171 set_cmd_line_image(optarg);
176 handle_clash_options(&arg.ch, c);
179 if(handle_clash_options(&arg.ch, *optarg))
190 if (argc - optind < 1)
194 arg.mp.arg = (void *) &arg;
195 arg.mp.openflags = O_RDWR;
196 arg.mp.callback = createDirCallback;
197 arg.mp.lookupflags = OPEN_PARENT | DO_OPEN_DIRS;
198 exit(main_loop(&arg.mp, argv + optind, argc - optind));