ia64/xen-unstable

view tools/misc/lomount/lomount.c @ 8740:3d7ea7972b39

Update patches for linux 2.6.15.

Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
author cl349@firebug.cl.cam.ac.uk
date Thu Feb 02 17:16:00 2006 +0000 (2006-02-02)
parents cd95b96a172e
children dfa7ba9c1296
line source
1 /*
2 * lomount - utility to mount partitions in a hard disk image
3 *
4 * Copyright (c) 2004 Jim Brown
5 * Copyright (c) 2004 Brad Watson
6 * Copyright (c) 2004 Mulyadi Santosa
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 * THE SOFTWARE.
25 */
27 #include <unistd.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <strings.h>
32 #include <errno.h>
34 #define BUF 4096
36 //#define SECSIZE 4096 /* arbitrarilly large (it's probably just 512) */
37 #define SECSIZE 512
39 struct pentry
40 {
41 unsigned char bootable;
42 unsigned char start_head;
43 unsigned int start_cylinder;
44 unsigned char start_sector;
45 unsigned char system;
46 unsigned char end_head;
47 unsigned int end_cylinder;
48 unsigned char end_sector;
49 unsigned long start_sector_abs;
50 unsigned long no_of_sectors_abs;
51 };
53 char * progname;
55 int loadptable(const char *argv, struct pentry parttbl[], struct pentry **exttbl)
56 {
57 FILE *fd;
58 int i, valid, total_known_sectors = 0;
59 unsigned char *pi;
60 unsigned char data [SECSIZE];
61 unsigned long extent = 0, old_extent = 0, e_count = 1;
62 struct pentry exttbls[4];
64 fd = fopen(argv, "r");
65 if (fd == NULL)
66 {
67 perror ("lomount");
68 return 1;
69 }
70 i = fread (&data, 1, sizeof (data), fd);
71 if (i < SECSIZE)
72 {
73 fprintf (stderr, "%s: could not read the entire first sector\n", progname);
74 return 1;
75 }
76 for (i = 0;i < 4;i++)
77 {
78 pi = &data [446 + 16 * i];
79 parttbl [i].bootable = *pi;
80 parttbl [i].start_head = *(pi + 1);
81 parttbl [i].start_cylinder = *(pi + 3) | ((*(pi + 2) << 2) & 0x300);
82 parttbl [i].start_sector = *(pi + 2) & 0x3f;
83 parttbl [i].system = *(pi + 4);
84 parttbl [i].end_head = *(pi + 5);
85 parttbl [i].end_cylinder = *(pi + 7) | ((*(pi + 6) << 2) & 0x300);
86 parttbl [i].end_sector = *(pi + 6) & 0x3f;
87 parttbl [i].start_sector_abs =
88 (unsigned long) *(pi + 8) | ((unsigned long) *(pi + 9) << 8) | ((unsigned long) *(pi + 10) << 16) | ((unsigned long) *(pi + 11) << 24);
89 parttbl [i].no_of_sectors_abs =
90 (unsigned long) *(pi + 12) | ((unsigned long) *(pi + 13) << 8) | ((unsigned long) *(pi + 14) << 16) | ((unsigned long) *(pi + 15) << 24);
91 if (parttbl[i].system == 0xF || parttbl[i].system == 0x5)
92 {
93 extent = parttbl[i].start_sector_abs * SECSIZE;
94 /* save the location of the "real" extended partition */
95 old_extent = extent;
96 }
97 }
98 valid = (data [510] == 0x55 && data [511] == 0xaa) ? 1 : 0;
99 for (i = 0; i < 4; i++)
100 {
101 total_known_sectors += parttbl[i].no_of_sectors_abs;
102 }
103 /* Extended Partition layout format was obtained from
104 http://wigner.cped.ornl.gov/the-gang/att-0520/03-Partition.htm */
105 #ifdef DEBUG
106 if (extent != 0)
107 {
108 printf("extended partition detected at offset %d\n", extent);
109 }
110 #endif
111 while (extent != 0)
112 {
113 /* according to realloc(3) passing NULL as pointer is same as calling malloc() */
114 exttbl[0] = realloc(exttbl[0], e_count * sizeof(struct pentry));
115 fseek(fd, extent, SEEK_SET);
116 i = fread (&data, 1, sizeof (data), fd);
117 if (i < SECSIZE)
118 {
119 fprintf (stderr, "%s: could not read the entire first sector\n", progname);
120 return 1;
121 }
122 /* only first 2 entrys are used in extented partition tables */
123 for (i = 0;i < 2;i++)
124 {
125 pi = &data [446 + 16 * i];
126 exttbls [i].bootable = *pi;
127 exttbls [i].start_head = *(pi + 1);
128 exttbls [i].start_cylinder = *(pi + 3) | ((*(pi + 2) << 2) & 0x300);
129 exttbls [i].start_sector = *(pi + 2) & 0x3f;
130 exttbls [i].system = *(pi + 4);
131 exttbls [i].end_head = *(pi + 5);
132 exttbls [i].end_cylinder = *(pi + 7) | ((*(pi + 6) << 2) & 0x300);
133 exttbls [i].end_sector = *(pi + 6) & 0x3f;
134 exttbls [i].start_sector_abs =
135 (unsigned long) *(pi + 8) | ((unsigned long) *(pi + 9) << 8) | ((unsigned long) *(pi + 10) << 16) | ((unsigned long) *(pi + 11) << 24);
136 exttbls [i].no_of_sectors_abs =
137 (unsigned long) *(pi + 12) | ((unsigned long) *(pi + 13) << 8) | ((unsigned long) *(pi + 14) << 16) | ((unsigned long) *(pi + 15) << 24);
138 if (i == 0)
139 {
140 //memmove((void *)exttbl[e_count-1], (void *)exttbls[i], sizeof(struct pentry));
141 //memmove() seems broken!
142 exttbl[0][e_count-1].bootable = exttbls [i].bootable;
143 exttbl[0][e_count-1].start_head = exttbls [i].start_head;
144 exttbl[0][e_count-1].start_cylinder = exttbls [i].start_cylinder;
145 exttbl[0][e_count-1].start_sector = exttbls [i].start_sector;
146 exttbl[0][e_count-1].system = exttbls [i].system;
147 exttbl[0][e_count-1].end_head = exttbls [i].end_head;
148 exttbl[0][e_count-1].end_cylinder = exttbls [i].end_cylinder;
149 exttbl[0][e_count-1].end_sector = exttbls [i].end_sector;
150 exttbl[0][e_count-1].start_sector_abs = exttbls [i].start_sector_abs;
151 exttbl[0][e_count-1].no_of_sectors_abs = exttbls [i].no_of_sectors_abs;
152 /* adjust for start of image instead of start of ext partition */
153 exttbl[0][e_count-1].start_sector_abs += (extent/SECSIZE);
154 #ifdef DEBUG
155 printf("extent %d start_sector_abs %d\n", extent, exttbl[0][e_count-1].start_sector_abs);
156 #endif
157 //else if (parttbl[i].system == 0x5)
158 }
159 else if (i == 1)
160 {
161 extent = (exttbls[i].start_sector_abs * SECSIZE);
162 if (extent)
163 extent += old_extent;
164 }
165 }
166 e_count ++;
167 }
168 //fclose (fd);
169 //the above segfaults (?!!!)
170 #ifdef DEBUG
171 printf("e_count = %d\n", e_count);
172 #endif
173 return valid;
174 }
176 int main(int argc, char ** argv)
177 {
178 struct pentry perttbl [4];
179 struct pentry *exttbl[1], *parttbl;
180 char buf[BUF], argv2[BUF], diskimage[BUF];
181 int partition = 1, sec, num = 0, pnum = 0, len = BUF, i, f = 0, valid;
182 progname = argv[0];
183 exttbl[0] = NULL;
184 for (i = 1; i < argc; i ++)
185 {
186 if (strncmp(argv[i], "-diskimage", BUF)==0)
187 {
188 strncpy(diskimage, argv[i+1], BUF);
189 i++; f = 1;
190 }
191 else if (strncmp(argv[i], "-partition", BUF)==0)
192 {
193 partition = atoi(argv[i+1]);
194 i++;
195 if (partition < 1) partition = 1;
196 }
197 else
198 {
199 strncat(argv2, argv[i], len);
200 strncat(argv2, " ", len-1);
201 len -= strlen(argv[i]);
202 len--;
203 }
204 }
205 if (!f)
206 {
207 printf("You must specify -diskimage and -partition\n");
208 printf("ex. lomount -t fs-type -diskimage hda.img -partition 1 /mnt\n");
209 return 0;
210 }
211 valid = loadptable(diskimage, perttbl, exttbl);
212 if (!valid)
213 {
214 printf("Warning: disk image does not appear to describe a valid partition table.\n");
215 }
216 /* NOTE: need to make sure this always rounds down */
217 //sec = total_known_sectors / sizeof_diskimage;
218 /* The above doesn't work unless the disk image is completely filled by
219 partitions ... unused space will thrown off the sector size. The calculation
220 assumes the disk image is completely filled, and that the few sectors used
221 to store the partition table/MBR are few enough that the calculated value is
222 off by (larger than) a value less than one. */
223 sec = 512; /* TODO: calculate real sector size */
224 #ifdef DEBUG
225 printf("sec: %d\n", sec);
226 #endif
227 if (partition > 4)
228 {
229 if (exttbl[0] == NULL)
230 {
231 printf("No extended partitions were found in %s.\n", diskimage);
232 return 2;
233 }
234 parttbl = exttbl[0];
235 if (parttbl[partition-5].no_of_sectors_abs == 0)
236 {
237 printf("Partition %d was not found in %s.\n", partition, diskimage);
238 return 3;
239 }
240 partition -= 4;
241 }
242 else
243 {
244 parttbl = perttbl;
245 if (parttbl[partition-1].no_of_sectors_abs == 0)
246 {
247 printf("Partition %d was not found in %s.\n", partition, diskimage);
248 return 3;
249 }
250 }
251 num = parttbl[partition-1].start_sector_abs;
252 pnum = sec * num;
253 #ifdef DEBUG
254 printf("offset = %d\n", pnum);
255 #endif
256 snprintf(buf, BUF, "mount -oloop,offset=%d %s %s", pnum, diskimage, argv2);
257 #ifdef DEBUG
258 printf("%s\n", buf);
259 #endif
260 system(buf);
261 return 0;
262 }