a799ab7370347b15f839723cefe775252826362b
[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
76         unsigned long sect_per_track;
77         int tracks_match=0;
78         int hidden;
79         
80         if(helpFlag(argc, argv))
81                 usage(0);
82         while ((c = getopt(argc, argv, "i:vh")) != EOF) {
83                 switch (c) {
84                         case 'i':
85                                 set_cmd_line_image(optarg, 0);
86                                 break;
87                         case 'v':
88                                 verbose = 1;
89                                 break;
90                         case 'h':
91                                 usage(0);
92                         default:
93                                 usage(1);
94                 }
95         }
96
97         if(argc == optind)
98                 usage(1);
99
100         for(;optind < argc; optind++) {
101                 if(!argv[optind][0] || argv[optind][1] != ':')
102                         usage(1);
103                 drive = toupper(argv[optind][0]);
104
105                 if(! (Stream = find_device(drive, O_RDONLY, &dev, &boot, 
106                                            name, &media, 0, NULL)))
107                         exit(1);
108
109                 tot_sectors = DWORD_S(bigsect);
110                 SET_INT(tot_sectors, WORD_S(psect));
111                 sector_size = WORD_S(secsiz);
112                 size_code=2;
113                 for(i=0; i<7; i++) {
114                         if(sector_size == 128 << i) {
115                                 size_code = i;
116                                 break;
117                         }
118                 }
119                 printf("device information:\n");
120                 printf("===================\n");
121                 printf("filename=\"%s\"\n", name);
122                 printf("sectors per track: %d\n", dev.sectors);
123                 printf("heads: %d\n", dev.heads);
124                 printf("cylinders: %d\n\n", dev.tracks);
125
126                 sect_per_track = dev.sectors * dev.heads;
127                 if(sect_per_track != 0) {
128                         printf("mformat command line: mformat ");
129                         hidden = DWORD_S(nhs);
130                         if(tot_sectors ==
131                            dev.tracks * sect_per_track - hidden % sect_per_track) {
132                                 tracks_match=1;
133                                 printf("-t %d", dev.tracks);
134                         } else {
135                                 printf("-T %ld", tot_sectors);
136                         }
137                         printf (" -h %d -s %d ", dev.heads, dev.sectors);
138                         if(hidden || !tracks_match)
139                                 printf("-H %d ", hidden);
140                         if(size_code != 2)
141                                 printf("-S %d ",size_code);
142                         printf("%c:\n", tolower(drive));
143                         printf("\n");
144                 }
145                 printf("bootsector information\n");
146                 printf("======================\n");
147                 printf("banner:\"%8s\"\n", boot.boot.banner);
148                 printf("sector size: %d bytes\n", WORD_S(secsiz));
149                 printf("cluster size: %d sectors\n", boot.boot.clsiz);
150                 printf("reserved (boot) sectors: %d\n", WORD_S(nrsvsect));
151                 printf("fats: %d\n", boot.boot.nfat);
152                 printf("max available root directory slots: %d\n", 
153                        WORD_S(dirents));
154                 printf("small size: %d sectors\n", WORD_S(psect));
155                 printf("media descriptor byte: 0x%x\n", boot.boot.descr);
156                 printf("sectors per fat: %d\n", WORD_S(fatlen));
157                 printf("sectors per track: %d\n", WORD_S(nsect));
158                 printf("heads: %d\n", WORD_S(nheads));
159                 printf("hidden sectors: %d\n", DWORD_S(nhs));
160                 printf("big size: %d sectors\n", DWORD_S(bigsect));
161
162                 if(WORD_S(fatlen)) {
163                     labelBlock = &boot.boot.ext.old.labelBlock;
164                 } else {
165                     labelBlock = &boot.boot.ext.fat32.labelBlock;
166                 }
167
168                 printf("physical drive id: 0x%x\n", 
169                        labelBlock->physdrive);
170                 printf("reserved=0x%x\n", 
171                        labelBlock->reserved);
172                 printf("dos4=0x%x\n", 
173                        labelBlock->dos4);
174                 printf("serial number: %08X\n", 
175                        _DWORD(labelBlock->serial));
176                 printf("disk label=\"%11.11s\"\n", 
177                        labelBlock->label);
178                 printf("disk type=\"%8.8s\"\n", 
179                        labelBlock->fat_type);
180
181                 if(!WORD_S(fatlen)){
182                         printf("Big fatlen=%u\n",
183                                DWORD_S(ext.fat32.bigFat));
184                         printf("Extended flags=0x%04x\n",
185                                WORD_S(ext.fat32.extFlags));
186                         printf("FS version=0x%04x\n",
187                                WORD_S(ext.fat32.fsVersion));
188                         printf("rootCluster=%u\n",
189                                DWORD_S(ext.fat32.rootCluster));
190                         if(WORD_S(ext.fat32.infoSector) != MAX16)
191                                 printf("infoSector location=%d\n",
192                                        WORD_S(ext.fat32.infoSector));
193                         if(WORD_S(ext.fat32.backupBoot) != MAX16)
194                                 printf("backup boot sector=%d\n",
195                                        WORD_S(ext.fat32.backupBoot));
196                         displayInfosector(Stream,&boot);
197                 }
198
199                 if(verbose) {
200                         int size;
201                         unsigned char *buf;
202
203                         printf("\n");
204                         size = WORD_S(secsiz);
205                         
206                         buf = (unsigned char *) malloc(size);
207                         if(!buf) {
208                                 fprintf(stderr, "Out of memory error\n");
209                                 exit(1);
210                         }
211
212                         size = READS(Stream, buf, (mt_off_t) 0, size);
213                         if(size < 0) {
214                                 perror("read boot sector");
215                                 exit(1);
216                         }
217
218                         print_sector("Boot sector hexdump", buf, size);
219                 }
220         }
221         FREE(&Stream);
222         exit(0);
223 }