00001
00002
00003
00004
00005
00006
00007 #define LOWERCASE
00008
00009 #include "sysincludes.h"
00010 #include "msdos.h"
00011 #include "mtools.h"
00012 #include "vfat.h"
00013 #include "mainloop.h"
00014 #include "plain_io.h"
00015 #include "nameclash.h"
00016 #include "file.h"
00017 #include "fs.h"
00018
00019
00020
00021
00022
00023 typedef struct Arg_t {
00024 char *target;
00025 MainParam_t mp;
00026
00027 Stream_t *SrcDir;
00028 int entry;
00029 ClashHandling_t ch;
00030 Stream_t *targetDir;
00031 } Arg_t;
00032
00033
00034 typedef struct CreateArg_t {
00035 Stream_t *Dir;
00036 Stream_t *NewDir;
00037 unsigned char attr;
00038 time_t mtime;
00039 } CreateArg_t;
00040
00041
00042
00043
00044
00045 int makeit(char *dosname,
00046 char *longname,
00047 void *arg0,
00048 direntry_t *targetEntry)
00049 {
00050 Stream_t *Target;
00051 CreateArg_t *arg = (CreateArg_t *) arg0;
00052 int fat;
00053 direntry_t subEntry;
00054
00055
00056 if (!getfreeMinClusters(targetEntry->Dir, 1))
00057 return -1;
00058
00059 mk_entry(dosname, ATTR_DIR, 1, 0, arg->mtime, &targetEntry->dir);
00060 Target = OpenFileByDirentry(targetEntry);
00061 if(!Target){
00062 fprintf(stderr,"Could not open Target\n");
00063 return -1;
00064 }
00065
00066
00067
00068 initializeDirentry(&subEntry, Target);
00069
00070 subEntry.entry = 1;
00071 GET_DATA(targetEntry->Dir, 0, 0, 0, &fat);
00072 if (fat == fat32RootCluster(targetEntry->Dir)) {
00073 fat = 0;
00074 }
00075 mk_entry(".. ", ATTR_DIR, fat, 0, arg->mtime, &subEntry.dir);
00076 dir_write(&subEntry);
00077
00078 FLUSH((Stream_t *) Target);
00079 subEntry.entry = 0;
00080 GET_DATA(Target, 0, 0, 0, &fat);
00081 mk_entry(". ", ATTR_DIR, fat, 0, arg->mtime, &subEntry.dir);
00082 dir_write(&subEntry);
00083
00084 mk_entry(dosname, ATTR_DIR | arg->attr, fat, 0, arg->mtime,
00085 &targetEntry->dir);
00086 arg->NewDir = Target;
00087 return 0;
00088 }
00089
00090
00091 static void usage(void)
00092 {
00093 fprintf(stderr,
00094 "Mtools version %s, dated %s\n", mversion, mdate);
00095 fprintf(stderr,
00096 "Usage: %s [-D clash_option] file targetfile\n", progname);
00097 fprintf(stderr,
00098 " %s [-D clash_option] file [files...] target_directory\n",
00099 progname);
00100 exit(1);
00101 }
00102
00103 Stream_t *createDir(Stream_t *Dir, const char *filename, ClashHandling_t *ch,
00104 unsigned char attr, time_t mtime)
00105 {
00106 CreateArg_t arg;
00107 int ret;
00108
00109 arg.Dir = Dir;
00110 arg.attr = attr;
00111 arg.mtime = mtime;
00112
00113 if (!getfreeMinClusters(Dir, 1))
00114 return NULL;
00115
00116 ret = mwrite_one(Dir, filename,0, makeit, &arg, ch);
00117 if(ret < 1)
00118 return NULL;
00119 else
00120 return arg.NewDir;
00121 }
00122
00123 static int createDirCallback(direntry_t *entry, MainParam_t *mp)
00124 {
00125 Stream_t *ret;
00126 time_t now;
00127
00128 ret = createDir(mp->File, mp->targetName, &((Arg_t *)(mp->arg))->ch,
00129 ATTR_DIR, getTimeNow(&now));
00130 if(ret == NULL)
00131 return ERROR_ONE;
00132 else {
00133 FREE(&ret);
00134 return GOT_ONE;
00135 }
00136
00137 }
00138
00139 void mmd(int argc, char **argv, int type)
00140 {
00141 Arg_t arg;
00142 int c;
00143
00144
00145
00146 init_clash_handling(& arg.ch);
00147
00148
00149 while ((c = getopt(argc, argv, "D:o")) != EOF) {
00150 switch (c) {
00151 case '?':
00152 usage();
00153 case 'o':
00154 handle_clash_options(&arg.ch, c);
00155 break;
00156 case 'D':
00157 if(handle_clash_options(&arg.ch, *optarg))
00158 usage();
00159 break;
00160 default:
00161 break;
00162 }
00163 }
00164
00165 if (argc - optind < 1)
00166 usage();
00167
00168 init_mp(&arg.mp);
00169 arg.mp.arg = (void *) &arg;
00170 arg.mp.openflags = O_RDWR;
00171 arg.mp.callback = createDirCallback;
00172 arg.mp.lookupflags = OPEN_PARENT | DO_OPEN_DIRS;
00173 exit(main_loop(&arg.mp, argv + optind, argc - optind));
00174 }