summaryrefslogtreecommitdiffstats
path: root/meta/recipes-devtools/dosfstools/dosfstools/mkdosfs-dir.patch
diff options
context:
space:
mode:
authorRichard Purdie <rpurdie@linux.intel.com>2010-08-27 15:14:24 +0100
committerRichard Purdie <rpurdie@linux.intel.com>2010-08-27 15:29:45 +0100
commit29d6678fd546377459ef75cf54abeef5b969b5cf (patch)
tree8edd65790e37a00d01c3f203f773fe4b5012db18 /meta/recipes-devtools/dosfstools/dosfstools/mkdosfs-dir.patch
parentda49de6885ee1bc424e70bc02f21f6ab920efb55 (diff)
downloadpoky-29d6678fd546377459ef75cf54abeef5b969b5cf.tar.gz
Major layout change to the packages directory
Having one monolithic packages directory makes it hard to find things and is generally overwhelming. This commit splits it into several logical sections roughly based on function, recipes.txt gives more information about the classifications used. The opportunity is also used to switch from "packages" to "recipes" as used in OpenEmbedded as the term "packages" can be confusing to people and has many different meanings. Not all recipes have been classified yet, this is just a first pass at separating things out. Some packages are moved to meta-extras as they're no longer actively used or maintained. Signed-off-by: Richard Purdie <rpurdie@linux.intel.com>
Diffstat (limited to 'meta/recipes-devtools/dosfstools/dosfstools/mkdosfs-dir.patch')
-rw-r--r--meta/recipes-devtools/dosfstools/dosfstools/mkdosfs-dir.patch634
1 files changed, 634 insertions, 0 deletions
diff --git a/meta/recipes-devtools/dosfstools/dosfstools/mkdosfs-dir.patch b/meta/recipes-devtools/dosfstools/dosfstools/mkdosfs-dir.patch
new file mode 100644
index 0000000000..8f753b052c
--- /dev/null
+++ b/meta/recipes-devtools/dosfstools/dosfstools/mkdosfs-dir.patch
@@ -0,0 +1,634 @@
1diff -urN dosfstools-2.10.orig/mkdosfs/mkdosfs.c dosfstools-2.10/mkdosfs/mkdosfs.c
2--- dosfstools-2.10.orig/mkdosfs/mkdosfs.c 2004-08-02 20:48:45.000000000 -0700
3+++ dosfstools-2.10/mkdosfs/mkdosfs.c 2004-08-02 20:49:44.296953792 -0700
4@@ -18,6 +18,10 @@
5 as a rule), and not the block. For example the boot block does not
6 occupy a full cluster.
7
8+ June 2004 - Jordan Crouse (info.linux@amd.com)
9+ Added -d <directory> support to populate the image
10+ Copyright (C) 2004, Advanced Micro Devices, All Rights Reserved
11+
12 Fixes/additions May 1998 by Roman Hodek
13 <Roman.Hodek@informatik.uni-erlangen.de>:
14 - Atari format support
15@@ -71,6 +75,8 @@
16 #include <unistd.h>
17 #include <time.h>
18 #include <errno.h>
19+#include <libgen.h>
20+#include <dirent.h>
21
22 #if __BYTE_ORDER == __BIG_ENDIAN
23
24@@ -124,6 +130,8 @@
25 }
26 #endif
27
28+#define ROUND_UP(value, divisor) (value + (divisor - (value % divisor))) / divisor
29+
30 /* Constant definitions */
31
32 #define TRUE 1 /* Boolean constants */
33@@ -163,7 +171,6 @@
34 #define ATTR_VOLUME 8 /* volume label */
35 #define ATTR_DIR 16 /* directory */
36 #define ATTR_ARCH 32 /* archived */
37-
38 #define ATTR_NONE 0 /* no attribute bits */
39 #define ATTR_UNUSED (ATTR_VOLUME | ATTR_ARCH | ATTR_SYS | ATTR_HIDDEN)
40 /* attribute bits that are copied "as is" */
41@@ -258,6 +265,19 @@
42 __u32 reserved2[4];
43 };
44
45+/* This stores up to 13 chars of the name */
46+
47+struct msdos_dir_slot {
48+ __u8 id; /* sequence number for slot */
49+ __u8 name0_4[10]; /* first 5 characters in name */
50+ __u8 attr; /* attribute byte */
51+ __u8 reserved; /* always 0 */
52+ __u8 alias_checksum; /* checksum for 8.3 alias */
53+ __u8 name5_10[12]; /* 6 more characters in name */
54+ __u16 start; /* starting cluster number, 0 in long slots */
55+ __u8 name11_12[4]; /* last 2 characters in name */
56+};
57+
58 struct msdos_dir_entry
59 {
60 char name[8], ext[3]; /* name and extension */
61@@ -306,6 +326,15 @@
62
63 #define MESSAGE_OFFSET 29 /* Offset of message in above code */
64
65+/* Special structure to keep track of directories as we add them for the -d option */
66+
67+struct dir_entry {
68+ int root; /* Specifies if this is the root dir or not */
69+ int count; /* Number of items in the table */
70+ int entries; /* Number of entries in the table */
71+ struct msdos_dir_entry *table; /* Pointer to the entry table */
72+};
73+
74 /* Global variables - the root of all evil :-) - see these and weep! */
75
76 static char *template_boot_code; /* Variable to store a full template boot sector in */
77@@ -339,6 +368,9 @@
78 static int size_root_dir; /* Size of the root directory in bytes */
79 static int sectors_per_cluster = 0; /* Number of sectors per disk cluster */
80 static int root_dir_entries = 0; /* Number of root directory entries */
81+static int root_dir_num_entries = 0;
82+static int last_cluster_written = 0;
83+
84 static char *blank_sector; /* Blank sector - all zeros */
85
86
87@@ -411,7 +443,6 @@
88 }
89 }
90
91-
92 /* Mark a specified sector as having a particular value in it's FAT entry */
93
94 static void
95@@ -1262,6 +1293,9 @@
96 die ("unable to allocate space for root directory in memory");
97 }
98
99+
100+ last_cluster_written = 2;
101+
102 memset(root_dir, 0, size_root_dir);
103 if ( memcmp(volume_name, " ", 11) )
104 {
105@@ -1310,11 +1344,11 @@
106 }
107
108 if (!(blank_sector = malloc( sector_size )))
109- die( "Out of memory" );
110+ die( "Out of memory" );
111+
112 memset(blank_sector, 0, sector_size);
113 }
114-
115-
116+
117 /* Write the new filesystem's data tables to wherever they're going to end up! */
118
119 #define error(str) \
120@@ -1336,7 +1370,7 @@
121 do { \
122 int __size = (size); \
123 if (write (dev, buf, __size) != __size) \
124- error ("failed whilst writing " errstr); \
125+ error ("failed whilst writing " errstr); \
126 } while(0)
127
128
129@@ -1407,6 +1441,452 @@
130 free (fat); /* Free up the fat table space reserved during setup_tables */
131 }
132
133+/* Add a file to the specified directory entry, and also write it into the image */
134+
135+static void copy_filename(char *filename, char *base, char *ext) {
136+
137+ char *ch = filename;
138+ int i, len;
139+
140+ memset(base, 0x20, 8);
141+ memset(ext, 0x20, 3);
142+
143+ for(len = 0 ; *ch && *ch != '.'; ch++) {
144+ base[len++] = toupper(*ch);
145+ if (len == 8) break;
146+ }
147+
148+ for ( ; *ch && *ch != '.'; ch++);
149+ if (*ch) ch++;
150+
151+ for(len = 0 ; *ch; ch++) {
152+ ext[len++] = toupper(*ch);
153+ if (len == 3) break;
154+ }
155+}
156+
157+/* Check for an .attrib.<filename> file, and read the attributes therein */
158+
159+/* We are going to be pretty pedantic about this. The file needs 3
160+ bytes at the beginning, the attributes are listed in this order:
161+
162+ (H)idden|(S)ystem|(A)rchived
163+
164+ A capital HSA means to enable it, anything else will disable it
165+ (I recommend a '-') The unix user attributes will still be used
166+ for write access.
167+
168+ For example, to enable system file access for ldlinux.sys, write
169+ the following to .attrib.ldlinux.sys: -S-
170+*/
171+
172+unsigned char check_attrib_file(char *dir, char *filename) {
173+
174+ char attrib[4] = { '-', '-', '-' };
175+ unsigned char *buffer = 0;
176+ int ret = ATTR_NONE;
177+ int fd = -1;
178+
179+ buffer = (char *) calloc(1, strlen(dir) + strlen(filename) + 10);
180+ if (!buffer) return ATTR_NONE;
181+
182+ sprintf(buffer, "%s/.attrib.%s", dir, filename);
183+
184+ if (access(buffer, R_OK))
185+ goto exit_attrib;
186+
187+ if ((fd = open(buffer, O_RDONLY, 0)) < 0)
188+ goto exit_attrib;
189+
190+ if (read(fd, attrib, 3) < 0)
191+ goto exit_attrib;
192+
193+ if (attrib[0] == 'H') ret |= ATTR_HIDDEN;
194+ if (attrib[1] == 'S') ret |= ATTR_SYS;
195+ if (attrib[2] == 'A') ret |= ATTR_ARCH;
196+
197+ printf("%s: Setting atrribute %x\n", filename, ret);
198+
199+ exit_attrib:
200+ if (fd >= 0) close(fd);
201+ if (buffer) free(buffer);
202+
203+ return ret;
204+}
205+
206+static void copy_name(char *buffer, int size, char **pointer) {
207+ int i;
208+
209+ for(i = 0; i < size; i += 2) {
210+ if (*pointer) {
211+ buffer[i] = **pointer;
212+ buffer[i + 1] = 0x00;
213+ *pointer = **pointer ? *pointer + 1 : 0;
214+ }
215+ else {
216+ buffer[i] = 0xFF;
217+ buffer[i + 1] = 0xFF;
218+ }
219+ }
220+}
221+
222+static int add_file(char *filename, struct dir_entry *dir, unsigned char attr)
223+{
224+ struct stat stat;
225+ struct msdos_dir_entry *entry;
226+ int infile = 0;
227+ int sectors, clusters;
228+ struct tm *ctime;
229+ int c, s;
230+ int ptr;
231+ char *buffer, *base;
232+ int start;
233+ int usedsec, totalsec;
234+
235+ char name83[8], ext83[3];
236+
237+ struct msdos_dir_slot *slot;
238+ int i;
239+ char *p;
240+
241+ /* The root directory is static, everything else grows as needed */
242+
243+ if (dir->root) {
244+ if (dir->count == dir->entries) {
245+ printf("Error - too many directory entries\n");
246+ }
247+ }
248+ else {
249+ if (dir->count == dir->entries) {
250+ if (!dir->table)
251+ dir->table =
252+ (struct msdos_dir_entry *) malloc(sizeof(struct msdos_dir_entry));
253+ else {
254+ dir->table =
255+ (struct msdos_dir_entry *) realloc(dir->table, (dir->entries + 1) *
256+ sizeof(struct msdos_dir_entry));
257+
258+ memset(&dir->table[dir->entries], 0, sizeof(struct msdos_dir_entry));
259+ }
260+
261+ dir->entries++;
262+ }
263+ }
264+
265+ infile = open(filename, O_RDONLY, 0);
266+ if (!infile) return;
267+
268+ if (fstat(infile, &stat))
269+ goto exit_add;
270+
271+ if (S_ISCHR(stat.st_mode) ||S_ISBLK(stat.st_mode) ||
272+ S_ISFIFO(stat.st_mode) || S_ISLNK(stat.st_mode)) {
273+ printf("Error - cannot create a special file in a FATFS\n");
274+ goto exit_add;
275+ }
276+
277+ /* FIXME: This isn't very pretty */
278+
279+ usedsec = start_data_sector + (size_root_dir / sector_size) +
280+ (last_cluster_written * bs.cluster_size);
281+
282+ totalsec = blocks * BLOCK_SIZE / sector_size;
283+
284+ /* Figure out how many sectors / clustors the file requires */
285+
286+ sectors = ROUND_UP(stat.st_size, sector_size);
287+ clusters = ROUND_UP(sectors, (int) bs.cluster_size);
288+
289+ if (usedsec + sectors > totalsec) {
290+ printf("Error - %s is too big (%d vs %d)\n", filename, sectors, totalsec - usedsec);
291+ close(infile);
292+ return -1;
293+ }
294+
295+ printf("ADD %s\n", filename);
296+
297+ /* Grab the basename of the file */
298+ base = basename(filename);
299+
300+ /* Extract out the 8.3 name */
301+ copy_filename(base, name83, ext83);
302+
303+ /* Make an extended name slot */
304+
305+ slot = (struct msdos_dir_slot *) &dir->table[dir->count++];
306+ slot->id = 'A';
307+ slot->attr = 0x0F;
308+ slot->reserved = 0;
309+ slot->start = 0;
310+
311+ slot->alias_checksum = 0;
312+
313+ for(i = 0; i < 8; i++)
314+ slot->alias_checksum = (((slot->alias_checksum&1)<<7)|((slot->alias_checksum&0xfe)>>1)) + name83[i];
315+
316+ for(i = 0; i < 3; i++)
317+ slot->alias_checksum = (((slot->alias_checksum&1)<<7)|((slot->alias_checksum&0xfe)>>1)) + ext83[i];
318+
319+ p = base;
320+
321+ copy_name(slot->name0_4, 10, &p);
322+ copy_name(slot->name5_10, 12, &p);
323+ copy_name(slot->name11_12, 4, &p);
324+
325+
326+ /* Get the entry from the root filesytem */
327+ entry = &dir->table[dir->count++];
328+
329+ strncpy(entry->name, name83, 8);
330+ strncpy(entry->ext, ext83, 3);
331+
332+
333+ /* If the user has it read only, then add read only to the incoming
334+ attribute settings */
335+
336+ if (!(stat.st_mode & S_IWUSR)) attr |= ATTR_RO;
337+ entry->attr = attr;
338+
339+ /* Set the access time on the file */
340+ ctime = localtime(&create_time);
341+
342+ entry->time = CT_LE_W((unsigned short)((ctime->tm_sec >> 1) +
343+ (ctime->tm_min << 5) + (ctime->tm_hour << 11)));
344+
345+ entry->date = CT_LE_W((unsigned short)(ctime->tm_mday +
346+ ((ctime->tm_mon+1) << 5) +
347+ ((ctime->tm_year-80) << 9)));
348+
349+ entry->ctime_ms = 0;
350+ entry->ctime = entry->time;
351+ entry->cdate = entry->date;
352+ entry->adate = entry->date;
353+ entry->size = stat.st_size;
354+
355+ start = last_cluster_written;
356+
357+ entry->start = CT_LE_W(start); /* start sector */
358+ entry->starthi = CT_LE_W((start & 0xFFFF0000) >> 16); /* High start sector (for FAT32) */
359+
360+ /* We mark all of the clusters we use in the FAT */
361+
362+ for(c = 0; c < clusters; c++ ) {
363+ int free;
364+ int next = c == (clusters - 1) ? FAT_EOF : start + c + 1;
365+ mark_FAT_cluster(start + c, next);
366+ last_cluster_written++;
367+ }
368+
369+ /* This confused me too - cluster 2 starts after the
370+ root directory data - search me as to why */
371+
372+ ptr = (start_data_sector * sector_size) + size_root_dir;
373+ ptr += (start - 2) * bs.cluster_size * sector_size;
374+
375+ buffer = (char *) malloc(sector_size);
376+
377+ if (!buffer) {
378+ printf("Error - couldn't allocate memory\n");
379+ goto exit_add;
380+ }
381+
382+ /* Write the file into the file block */
383+
384+ seekto(ptr, "datafile");
385+
386+ while(1) {
387+ int size = read(infile, buffer, sector_size);
388+ if (size <= 0) break;
389+
390+ writebuf(buffer, size, "data");
391+ }
392+
393+ exit_add:
394+ if (infile) close(infile);
395+}
396+
397+/* Add a new directory to the specified directory entry, and in turn populate
398+ it with its own files */
399+
400+/* FIXME: This should check to make sure there is enough size to add itself */
401+
402+static void add_directory(char *filename, struct dir_entry *dir) {
403+
404+ struct dir_entry *newdir = 0;
405+ struct msdos_dir_entry *entry;
406+ struct tm *ctime;
407+ DIR *rddir = opendir(filename);
408+ struct dirent *dentry = 0;
409+ int remain;
410+ char *data;
411+
412+ /* If the directory doesn't exist */
413+ if (!rddir) return;
414+
415+ if (dir->root) {
416+ if (dir->count == dir->entries) {
417+ printf("Error - too many directory entries\n");
418+ goto exit_add_dir;
419+ }
420+ }
421+ else {
422+ if (dir->count == dir->entries) {
423+ if (!dir->table)
424+ dir->table = (struct msdos_dir_entry *) malloc(sizeof(struct msdos_dir_entry));
425+ else {
426+ dir->table = (struct msdos_dir_entry *) realloc(dir->table, (dir->entries + 1) *
427+ sizeof(struct msdos_dir_entry));
428+
429+ /* Zero it out to avoid issues */
430+ memset(&dir->table[dir->entries], 0, sizeof(struct msdos_dir_entry));
431+ }
432+ dir->entries++;
433+ }
434+ }
435+
436+ /* Now, create a new directory entry for the new directory */
437+ newdir = (struct dir_entry *) calloc(1, sizeof(struct dir_entry));
438+ if (!newdir) goto exit_add_dir;
439+
440+ entry = &dir->table[dir->count++];
441+
442+ strncpy(entry->name, basename(filename), sizeof(entry->name));
443+
444+ entry->attr = ATTR_DIR;
445+ ctime = localtime(&create_time);
446+
447+ entry->time = CT_LE_W((unsigned short)((ctime->tm_sec >> 1) +
448+ (ctime->tm_min << 5) + (ctime->tm_hour << 11)));
449+
450+ entry->date = CT_LE_W((unsigned short)(ctime->tm_mday +
451+ ((ctime->tm_mon+1) << 5) +
452+ ((ctime->tm_year-80) << 9)));
453+
454+ entry->ctime_ms = 0;
455+ entry->ctime = entry->time;
456+ entry->cdate = entry->date;
457+ entry->adate = entry->date;
458+
459+ /* Now, read the directory */
460+
461+ while((dentry = readdir(rddir))) {
462+ struct stat st;
463+ char *buffer;
464+
465+ if (!strcmp(dentry->d_name, ".") || !strcmp(dentry->d_name, ".."))
466+ continue;
467+
468+ /* DOS wouldn't like a typical unix . (dot) file, so we skip those too */
469+ if (dentry->d_name[0] == '.') continue;
470+
471+ buffer = malloc(strlen(filename) + strlen(dentry->d_name) + 3);
472+ if (!buffer) continue;
473+
474+ sprintf(buffer, "%s/%s", filename, dentry->d_name);
475+ if (!stat(buffer, &st)) {
476+ if (S_ISDIR(st.st_mode))
477+ add_directory(buffer, newdir);
478+ else if (S_ISREG(st.st_mode)) {
479+ unsigned char attrib = check_attrib_file(filename, dentry->d_name);
480+ add_file(buffer, newdir, attrib);
481+ }
482+ }
483+
484+ free(buffer);
485+ }
486+
487+ /* Now that the entire directory has been written, go ahead and write the directory
488+ entry as well */
489+
490+ entry->start = CT_LE_W(last_cluster_written);
491+ entry->starthi = CT_LE_W((last_cluster_written & 0xFFFF0000) >> 16);
492+ entry->size = newdir->count * sizeof(struct msdos_dir_entry);
493+
494+ remain = entry->size;
495+ data = (char *) newdir->table;
496+
497+ while(remain) {
498+ int size =
499+ remain > bs.cluster_size * sector_size ? bs.cluster_size * sector_size : remain;
500+
501+ int pos = (start_data_sector * sector_size) + size_root_dir;
502+ pos += (last_cluster_written - 2) * bs.cluster_size * sector_size;
503+
504+ seekto(pos, "add_dir");
505+ writebuf(data, size, "add_dir");
506+
507+ remain -= size;
508+ data += size;
509+
510+ mark_FAT_cluster(last_cluster_written, remain ? last_cluster_written + 1 : FAT_EOF);
511+ last_cluster_written++;
512+ }
513+
514+ exit_add_dir:
515+ if (rddir) closedir(rddir);
516+ if (newdir->table) free(newdir->table);
517+ if (newdir) free(newdir);
518+}
519+
520+/* Given a directory, add all the files and directories to the root directory of the
521+ image.
522+*/
523+
524+static void add_root_directory(char *dirname)
525+{
526+ DIR *dir = opendir(dirname);
527+ struct dirent *entry = 0;
528+ struct dir_entry *newdir = 0;
529+
530+ if (!dir) {
531+ printf("Error - directory %s does not exist\n", dirname);
532+ return;
533+ }
534+
535+ /* Create the root directory structure - this is a bit different then
536+ above, because the table already exists, we just refer to it. */
537+
538+ newdir = (struct dir_entry *) calloc(1,sizeof(struct dir_entry));
539+
540+ if (!newdir) {
541+ closedir(dir);
542+ return;
543+ }
544+
545+ newdir->entries = root_dir_entries;
546+ newdir->root = 1;
547+ newdir->count = 0;
548+ newdir->table = root_dir;
549+
550+ while((entry = readdir(dir))) {
551+ struct stat st;
552+ char *buffer;
553+
554+ if (!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, ".."))
555+ continue;
556+
557+ /* DOS wouldn't like a typical unix . (dot) file, so we skip those too */
558+ if (entry->d_name[0] == '.') continue;
559+
560+ buffer = malloc(strlen(dirname) + strlen(entry->d_name) + 3);
561+ if (!buffer) continue;
562+
563+ sprintf(buffer, "%s/%s", dirname, entry->d_name);
564+ if (!stat(buffer, &st)) {
565+ if (S_ISDIR(st.st_mode))
566+ add_directory(buffer, newdir);
567+ else if (S_ISREG(st.st_mode)) {
568+ unsigned char attrib = check_attrib_file(dirname, entry->d_name);
569+ add_file(buffer, newdir, attrib);
570+ }
571+ }
572+
573+ free(buffer);
574+ }
575+
576+ closedir(dir);
577+ if (newdir) free(newdir);
578+}
579
580 /* Report the command usage and return a failure error code */
581
582@@ -1418,9 +1898,9 @@
583 [-m boot-msg-file] [-n volume-name] [-i volume-id] [-B bootcode]\n\
584 [-s sectors-per-cluster] [-S logical-sector-size] [-f number-of-FATs]\n\
585 [-F fat-size] [-r root-dir-entries] [-R reserved-sectors]\n\
586- /dev/name [blocks]\n");
587+ [-d directory] /dev/name [blocks]\n");
588 }
589-
590+
591 /*
592 * ++roman: On m68k, check if this is an Atari; if yes, turn on Atari variant
593 * of MS-DOS filesystem by default.
594@@ -1458,6 +1938,8 @@
595 int c;
596 char *tmp;
597 char *listfile = NULL;
598+ char *dirname = NULL;
599+
600 FILE *msgfile;
601 struct stat statbuf;
602 int i = 0, pos, ch;
603@@ -1477,7 +1959,7 @@
604 printf ("%s " VERSION " (" VERSION_DATE ")\n",
605 program_name);
606
607- while ((c = getopt (argc, argv, "AcCf:F:Ii:l:m:n:r:R:s:S:v:B:b")) != EOF)
608+ while ((c = getopt (argc, argv, "AcCd:f:F:Ii:l:m:n:r:R:s:S:v:B:b")) != EOF)
609 /* Scan the command line for options */
610 switch (c)
611 {
612@@ -1502,6 +1984,10 @@
613 create = TRUE;
614 break;
615
616+ case 'd':
617+ dirname = optarg;
618+ break;
619+
620 case 'f': /* f : Choose number of FATs */
621 nr_fats = (int) strtol (optarg, &tmp, 0);
622 if (*tmp || nr_fats < 1 || nr_fats > 4)
623@@ -1796,8 +2282,10 @@
624 else if (listfile)
625 get_list_blocks (listfile);
626
627- write_tables (); /* Write the file system tables away! */
628
629+ if (dirname) add_root_directory(dirname);
630+
631+ write_tables (); /* Write the file system tables away! */
632 exit (0); /* Terminate with no errors! */
633 }
634