Imported Upstream version 4.0.18
[platform/upstream/mtools.git] / minfo.c
1 /*  Copyright 1997-2003,2006,2007,2009 Alain Knaff.
2  *  This file is part of mtools.
3  *
4  *  Mtools is free software: you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation, either version 3 of the License, or
7  *  (at your option) any later version.
8  *
9  *  Mtools is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with Mtools.  If not, see <http://www.gnu.org/licenses/>.
16  *
17  * mlabel.c
18  * Make an MSDOS volume label
19  */
20
21 #include "sysincludes.h"
22 #include "msdos.h"
23 #include "mainloop.h"
24 #include "vfat.h"
25 #include "mtools.h"
26 #include "nameclash.h"
27
28 static void usage(int ret) NORETURN;
29 static void usage(int ret)
30 {
31         fprintf(stderr, 
32                 "Mtools version %s, dated %s\n", mversion, mdate);
33         fprintf(stderr, 
34                 "Usage: %s [-v] drive\n", progname);
35         exit(ret);
36 }
37
38
39 static void displayInfosector(Stream_t *Stream, union bootsector *boot)
40 {
41         InfoSector_t *infosec;
42
43         if(WORD(ext.fat32.infoSector) == MAX16)
44                 return;
45
46         infosec = (InfoSector_t *) safe_malloc(WORD(secsiz));
47         force_read(Stream, (char *) infosec, 
48                            (mt_off_t) WORD(secsiz) * WORD(ext.fat32.infoSector),
49                            WORD(secsiz));
50         printf("\nInfosector:\n");
51         printf("signature=0x%08x\n", _DWORD(infosec->signature1));
52         if(_DWORD(infosec->count) != MAX32)
53                 printf("free clusters=%u\n", _DWORD(infosec->count));
54         if(_DWORD(infosec->pos) != MAX32)
55                 printf("last allocated cluster=%u\n", _DWORD(infosec->pos));
56 }
57
58
59 void minfo(int argc, char **argv, int type)
60 {
61         union bootsector boot;
62
63         char name[EXPAND_BUF];
64         int media;
65         unsigned long tot_sectors;
66         int size_code;
67         int sector_size;
68         int i;
69         struct device dev;
70         char drive;
71         int verbose=0;
72         int c;
73         Stream_t *Stream;
74         struct label_blk_t *labelBlock;
75         int have_drive = 0;
76
77         unsigned long sect_per_track;
78         int tracks_match=0;
79         int hidden;
80
81         char *imgFile=NULL;
82         
83         if(helpFlag(argc, argv))
84                 usage(0);
85         while ((c = getopt(argc, argv, "i:vh")) != EOF) {
86                 switch (c) {
87                         case 'i':
88                                 set_cmd_line_image(optarg);
89                                 imgFile=optarg;
90                                 break;
91                         case 'v':
92                                 verbose = 1;
93                                 break;
94                         case 'h':
95                                 usage(0);
96                         default:
97                                 usage(1);
98                 }
99         }
100
101         for(;optind <= argc; optind++) {
102                 if(optind == argc) {
103                         if(have_drive)
104                                 break;
105                         drive = get_default_drive();
106                 } else {
107                         if(!argv[optind][0] || argv[optind][1] != ':')
108                                 usage(1);
109                         drive = toupper(argv[optind][0]);
110                 }
111                 have_drive = 1;
112
113                 if(! (Stream = find_device(drive, O_RDONLY, &dev, &boot, 
114                                            name, &media, 0, NULL)))
115                         exit(1);
116
117                 tot_sectors = DWORD_S(bigsect);
118                 SET_INT(tot_sectors, WORD_S(psect));
119                 sector_size = WORD_S(secsiz);
120                 size_code=2;
121                 for(i=0; i<7; i++) {
122                         if(sector_size == 128 << i) {
123                                 size_code = i;
124                                 break;
125                         }
126                 }
127                 printf("device information:\n");
128                 printf("===================\n");
129                 printf("filename=\"%s\"\n", name);
130                 printf("sectors per track: %d\n", dev.sectors);
131                 printf("heads: %d\n", dev.heads);
132                 printf("cylinders: %d\n\n", dev.tracks);
133
134                 sect_per_track = dev.sectors * dev.heads;
135                 if(sect_per_track != 0) {
136                         printf("mformat command line: mformat ");
137                         hidden = DWORD_S(nhs);
138                         if(tot_sectors ==
139                            dev.tracks * sect_per_track - hidden % sect_per_track) {
140                                 tracks_match=1;
141                                 printf("-t %d ", dev.tracks);
142                         } else {
143                                 printf("-T %ld ", tot_sectors);
144                         }
145                         if(imgFile != NULL)
146                                 printf("-i %s ", imgFile);
147                         printf (" -h %d -s %d ", dev.heads, dev.sectors);
148                         if(hidden || !tracks_match)
149                                 printf("-H %d ", hidden);
150                         if(size_code != 2)
151                                 printf("-S %d ",size_code);
152                         printf("%c:\n", tolower(drive));
153                         printf("\n");
154                 }
155                 printf("bootsector information\n");
156                 printf("======================\n");
157                 printf("banner:\"%.8s\"\n", boot.boot.banner);
158                 printf("sector size: %d bytes\n", WORD_S(secsiz));
159                 printf("cluster size: %d sectors\n", boot.boot.clsiz);
160                 printf("reserved (boot) sectors: %d\n", WORD_S(nrsvsect));
161                 printf("fats: %d\n", boot.boot.nfat);
162                 printf("max available root directory slots: %d\n", 
163                        WORD_S(dirents));
164                 printf("small size: %d sectors\n", WORD_S(psect));
165                 printf("media descriptor byte: 0x%x\n", boot.boot.descr);
166                 printf("sectors per fat: %d\n", WORD_S(fatlen));
167                 printf("sectors per track: %d\n", WORD_S(nsect));
168                 printf("heads: %d\n", WORD_S(nheads));
169                 printf("hidden sectors: %d\n", DWORD_S(nhs));
170                 printf("big size: %d sectors\n", DWORD_S(bigsect));
171
172                 if(WORD_S(fatlen)) {
173                     labelBlock = &boot.boot.ext.old.labelBlock;
174                 } else {
175                     labelBlock = &boot.boot.ext.fat32.labelBlock;
176                 }
177
178                 printf("physical drive id: 0x%x\n", 
179                        labelBlock->physdrive);
180                 printf("reserved=0x%x\n", 
181                        labelBlock->reserved);
182                 printf("dos4=0x%x\n", 
183                        labelBlock->dos4);
184                 printf("serial number: %08X\n", 
185                        _DWORD(labelBlock->serial));
186                 printf("disk label=\"%11.11s\"\n", 
187                        labelBlock->label);
188                 printf("disk type=\"%8.8s\"\n", 
189                        labelBlock->fat_type);
190
191                 if(!WORD_S(fatlen)){
192                         printf("Big fatlen=%u\n",
193                                DWORD_S(ext.fat32.bigFat));
194                         printf("Extended flags=0x%04x\n",
195                                WORD_S(ext.fat32.extFlags));
196                         printf("FS version=0x%04x\n",
197                                WORD_S(ext.fat32.fsVersion));
198                         printf("rootCluster=%u\n",
199                                DWORD_S(ext.fat32.rootCluster));
200                         if(WORD_S(ext.fat32.infoSector) != MAX16)
201                                 printf("infoSector location=%d\n",
202                                        WORD_S(ext.fat32.infoSector));
203                         if(WORD_S(ext.fat32.backupBoot) != MAX16)
204                                 printf("backup boot sector=%d\n",
205                                        WORD_S(ext.fat32.backupBoot));
206                         displayInfosector(Stream,&boot);
207                 }
208
209                 if(verbose) {
210                         int size;
211                         unsigned char *buf;
212
213                         printf("\n");
214                         size = WORD_S(secsiz);
215                         
216                         buf = (unsigned char *) malloc(size);
217                         if(!buf) {
218                                 fprintf(stderr, "Out of memory error\n");
219                                 exit(1);
220                         }
221
222                         size = READS(Stream, buf, (mt_off_t) 0, size);
223                         if(size < 0) {
224                                 perror("read boot sector");
225                                 exit(1);
226                         }
227
228                         print_sector("Boot sector hexdump", buf, size);
229                 }
230         }
231         FREE(&Stream);
232         exit(0);
233 }