mmd.c

Go to the documentation of this file.
00001 /*
00002  * mmd.c
00003  * Makes an MSDOS directory
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  * Preserve the file modification times after the fclose()
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  * Open the named file for read, create the cluster chain, return the
00043  * directory structure or NULL on error.
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         /* will it fit? At least one cluster must be free */
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         /* this allocates the first cluster for our directory */
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         /* get command line options */
00145 
00146         init_clash_handling(& arg.ch);
00147 
00148         /* get command line options */
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 }

Generated on Fri Apr 14 22:56:56 2006 for minix by  doxygen 1.4.6