1 | /* Test program for doctoring the fat */
|
---|
2 |
|
---|
3 |
|
---|
4 | /*
|
---|
5 | * mcopy.c
|
---|
6 | * Copy an MSDOS files to and from Unix
|
---|
7 | *
|
---|
8 | */
|
---|
9 |
|
---|
10 |
|
---|
11 | #define LOWERCASE
|
---|
12 |
|
---|
13 | #include "sysincludes.h"
|
---|
14 | #include "msdos.h"
|
---|
15 | #include "mtools.h"
|
---|
16 | #include "vfat.h"
|
---|
17 | #include "mainloop.h"
|
---|
18 | #include "plain_io.h"
|
---|
19 | #include "nameclash.h"
|
---|
20 | #include "file.h"
|
---|
21 | #include "fs.h"
|
---|
22 | #include "fsP.h"
|
---|
23 |
|
---|
24 | typedef struct Arg_t {
|
---|
25 | char *target;
|
---|
26 | MainParam_t mp;
|
---|
27 | ClashHandling_t ch;
|
---|
28 | Stream_t *sourcefile;
|
---|
29 | unsigned long fat;
|
---|
30 | int markbad;
|
---|
31 | int setsize;
|
---|
32 | unsigned long size;
|
---|
33 | Fs_t *Fs;
|
---|
34 | } Arg_t;
|
---|
35 |
|
---|
36 | static int dos_doctorfat(direntry_t *entry, MainParam_t *mp)
|
---|
37 | {
|
---|
38 | Fs_t *Fs = getFs(mp->File);
|
---|
39 | Arg_t *arg=(Arg_t *) mp->arg;
|
---|
40 |
|
---|
41 | if(!arg->markbad && entry->entry != -3) {
|
---|
42 | /* if not root directory, change it */
|
---|
43 | set_word(entry->dir.start, arg->fat & 0xffff);
|
---|
44 | set_word(entry->dir.startHi, arg->fat >> 16);
|
---|
45 | if(arg->setsize)
|
---|
46 | set_dword(entry->dir.size, arg->size);
|
---|
47 | dir_write(entry);
|
---|
48 | }
|
---|
49 | arg->Fs = Fs;
|
---|
50 | return GOT_ONE;
|
---|
51 | }
|
---|
52 |
|
---|
53 | static int unix_doctorfat(MainParam_t *mp)
|
---|
54 | {
|
---|
55 | fprintf(stderr,"File does not reside on a Dos fs\n");
|
---|
56 | return ERROR_ONE;
|
---|
57 | }
|
---|
58 |
|
---|
59 |
|
---|
60 | static void usage(void)
|
---|
61 | {
|
---|
62 | fprintf(stderr,
|
---|
63 | "Mtools version %s, dated %s\n", mversion, mdate);
|
---|
64 | fprintf(stderr,
|
---|
65 | "Usage: %s [-b] [-o offset] [-s size] file fat\n", progname);
|
---|
66 | exit(1);
|
---|
67 | }
|
---|
68 |
|
---|
69 | void mdoctorfat(int argc, char **argv, int mtype)
|
---|
70 | {
|
---|
71 | Arg_t arg;
|
---|
72 | int c, ret;
|
---|
73 | long address, begin, end;
|
---|
74 | char *number, *eptr;
|
---|
75 | int i, j;
|
---|
76 | long offset;
|
---|
77 |
|
---|
78 | /* get command line options */
|
---|
79 |
|
---|
80 | init_clash_handling(& arg.ch);
|
---|
81 |
|
---|
82 | offset = 0;
|
---|
83 |
|
---|
84 | arg.markbad = 0;
|
---|
85 | arg.setsize = 0;
|
---|
86 |
|
---|
87 | /* get command line options */
|
---|
88 | while ((c = getopt(argc, argv, "bo:s:")) != EOF) {
|
---|
89 | switch (c) {
|
---|
90 | case 'b':
|
---|
91 | arg.markbad = 1;
|
---|
92 | break;
|
---|
93 | case 'o':
|
---|
94 | offset = strtoul(optarg,0,0);
|
---|
95 | break;
|
---|
96 | case 's':
|
---|
97 | arg.setsize=1;
|
---|
98 | arg.size = strtoul(optarg,0,0);
|
---|
99 | break;
|
---|
100 | case '?':
|
---|
101 | usage();
|
---|
102 | break;
|
---|
103 | }
|
---|
104 | }
|
---|
105 |
|
---|
106 | if (argc - optind < 2)
|
---|
107 | usage();
|
---|
108 |
|
---|
109 |
|
---|
110 | /* only 1 file to copy... */
|
---|
111 | init_mp(&arg.mp);
|
---|
112 | arg.mp.arg = (void *) &arg;
|
---|
113 |
|
---|
114 | arg.mp.callback = dos_doctorfat;
|
---|
115 | arg.mp.unixcallback = unix_doctorfat;
|
---|
116 |
|
---|
117 | arg.mp.lookupflags = ACCEPT_PLAIN | ACCEPT_DIR | DO_OPEN;
|
---|
118 | arg.mp.openflags = O_RDWR;
|
---|
119 | arg.fat = strtoul(argv[optind+1], 0, 0) + offset;
|
---|
120 | ret=main_loop(&arg.mp, argv + optind, 1);
|
---|
121 | if(ret)
|
---|
122 | exit(ret);
|
---|
123 | address = 0;
|
---|
124 | for(i=optind+1; i < argc; i++) {
|
---|
125 | number = argv[i];
|
---|
126 | if (*number == '<') {
|
---|
127 | number++;
|
---|
128 | }
|
---|
129 | begin = strtoul(number, &eptr, 0);
|
---|
130 | if (eptr && *eptr == '-') {
|
---|
131 | number = eptr+1;
|
---|
132 | end = strtoul(number, &eptr, 0);
|
---|
133 | } else {
|
---|
134 | end = begin;
|
---|
135 | }
|
---|
136 | if (eptr == number) {
|
---|
137 | fprintf(stderr, "Not a number: %s\n", number);
|
---|
138 | exit(-1);
|
---|
139 | }
|
---|
140 |
|
---|
141 | if (eptr && *eptr == '>') {
|
---|
142 | eptr++;
|
---|
143 | }
|
---|
144 | if (eptr && *eptr) {
|
---|
145 | fprintf(stderr, "Not a number: %s\n", eptr);
|
---|
146 | exit(-1);
|
---|
147 | }
|
---|
148 |
|
---|
149 | for (j=begin; j <= end; j++) {
|
---|
150 | if(arg.markbad) {
|
---|
151 | arg.Fs->fat_encode(arg.Fs, j+offset, arg.Fs->last_fat ^ 6 ^ 8);
|
---|
152 | } else {
|
---|
153 | if(address) {
|
---|
154 | arg.Fs->fat_encode(arg.Fs, address, j+offset);
|
---|
155 | }
|
---|
156 | address = j+offset;
|
---|
157 | }
|
---|
158 | }
|
---|
159 | }
|
---|
160 |
|
---|
161 | if (address && !arg.markbad) {
|
---|
162 | arg.Fs->fat_encode(arg.Fs, address, arg.Fs->end_fat);
|
---|
163 | }
|
---|
164 |
|
---|
165 | exit(ret);
|
---|
166 | }
|
---|