~ubuntu-branches/ubuntu/lucid/loop-aes-utils/lucid-security

« back to all changes in this revision

Viewing changes to fdisk/fdisksunlabel.c

  • Committer: Bazaar Package Importer
  • Author(s): Max Vozeler
  • Date: 2008-08-22 11:57:17 UTC
  • mfrom: (8.1.3 intrepid)
  • Revision ID: james.westby@ubuntu.com-20080822115717-v8wfa8pxwlfvyje0
Tags: 2.13.1-4
* patches/losetup_add_option_f.dpatch: 
  - Added to support "find next free loop" in losetup.
    (closes: #495682)

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
#include "nls.h"
22
22
 
23
23
#include <endian.h>
24
 
#include "../defines.h"         /* for HAVE_scsi_h */
25
 
#ifdef HAVE_scsi_h
 
24
#ifdef HAVE_SCSI_SCSI_H
26
25
#define u_char  unsigned char
27
26
#include <scsi/scsi.h>          /* SCSI_IOCTL_GET_IDLUN */
28
27
#undef u_char
37
36
static int     scsi_disk = 0;
38
37
static int     floppy = 0;
39
38
 
40
 
#define LINUX_SWAP      0x82
41
 
#define LINUX_NATIVE    0x83
42
 
 
43
39
struct systypes sun_sys_types[] = {
44
 
        {0, N_("Empty")},
45
 
        {1, N_("Boot")},
46
 
        {2, N_("SunOS root")},
47
 
        {SUNOS_SWAP, N_("SunOS swap")},
48
 
        {4, N_("SunOS usr")},
49
 
        {WHOLE_DISK, N_("Whole disk")},
50
 
        {6, N_("SunOS stand")},
51
 
        {7, N_("SunOS var")},
52
 
        {8, N_("SunOS home")},
53
 
        {LINUX_SWAP, N_("Linux swap")},
54
 
        {LINUX_NATIVE, N_("Linux native")},
55
 
        {0x8e, N_("Linux LVM")},
56
 
        {0xfd, N_("Linux raid autodetect")},/* New (2.2.x) raid partition
57
 
                                               with autodetect using
58
 
                                               persistent superblock */
 
40
        {SUN_TAG_UNASSIGNED, N_("Unassigned")},
 
41
        {SUN_TAG_BOOT, N_("Boot")},
 
42
        {SUN_TAG_ROOT, N_("SunOS root")},
 
43
        {SUN_TAG_SWAP, N_("SunOS swap")},
 
44
        {SUN_TAG_USR, N_("SunOS usr")},
 
45
        {SUN_TAG_BACKUP, N_("Whole disk")},
 
46
        {SUN_TAG_STAND, N_("SunOS stand")},
 
47
        {SUN_TAG_VAR, N_("SunOS var")},
 
48
        {SUN_TAG_HOME, N_("SunOS home")},
 
49
        {SUN_TAG_ALTSCTR, N_("SunOS alt sectors")},
 
50
        {SUN_TAG_CACHE, N_("SunOS cachefs")},
 
51
        {SUN_TAG_RESERVED, N_("SunOS reserved")},
 
52
        {SUN_TAG_LINUX_SWAP, N_("Linux swap")},
 
53
        {SUN_TAG_LINUX_NATIVE, N_("Linux native")},
 
54
        {SUN_TAG_LINUX_LVM, N_("Linux LVM")},
 
55
        {SUN_TAG_LINUX_RAID, N_("Linux raid autodetect")},
59
56
        { 0, NULL }
60
57
};
61
58
 
66
63
        return (((__u32)(x) & 0xFF) << 24) | (((__u32)(x) & 0xFF00) << 8) | (((__u32)(x) & 0xFF0000) >> 8) | (((__u32)(x) & 0xFF000000) >> 24);
67
64
}
68
65
 
69
 
int
70
 
get_num_sectors(struct sun_partition p) {
71
 
        return SSWAP32(p.num_sectors);
72
 
}
 
66
#define SSWAP16(x) (other_endian ? __swap16(x) \
 
67
                                 : (__u16)(x))
 
68
#define SSWAP32(x) (other_endian ? __swap32(x) \
 
69
                                 : (__u32)(x))
73
70
 
74
71
#ifndef IDE0_MAJOR
75
72
#define IDE0_MAJOR 3
77
74
#ifndef IDE1_MAJOR
78
75
#define IDE1_MAJOR 22
79
76
#endif
80
 
void guess_device_type(int fd) {
 
77
void guess_device_type(int fd)
 
78
{
81
79
        struct stat bootstat;
82
80
 
83
81
        if (fstat (fd, &bootstat) < 0) {
98
96
        }
99
97
}
100
98
 
101
 
static void
102
 
set_sun_partition(int i, unsigned int start, unsigned int stop, int sysid) {
103
 
        sunlabel->infos[i].id = sysid;
 
99
static void set_sun_partition(int i, __u32 start, __u32 stop, __u16 sysid)
 
100
{
 
101
        sunlabel->part_tags[i].tag = SSWAP16(sysid);
 
102
        sunlabel->part_tags[i].flag = SSWAP16(0);
104
103
        sunlabel->partitions[i].start_cylinder =
105
104
                SSWAP32(start / (heads * sectors));
106
105
        sunlabel->partitions[i].num_sectors =
108
107
        set_changed(i);
109
108
}
110
109
 
111
 
void
112
 
sun_nolabel(void) {
 
110
void sun_nolabel(void)
 
111
{
113
112
        sun_label = 0;
114
113
        sunlabel->magic = 0;
115
114
        partitions = 4;
116
115
}
117
116
 
118
 
int
119
 
check_sun_label(void) {
 
117
int check_sun_label(void)
 
118
{
120
119
        unsigned short *ush;
121
120
        int csum;
122
121
 
127
126
                return 0;
128
127
        }
129
128
        other_endian = (sunlabel->magic == SUN_LABEL_MAGIC_SWAPPED);
 
129
 
130
130
        ush = ((unsigned short *) (sunlabel + 1)) - 1;
131
 
        for (csum = 0; ush >= (unsigned short *)sunlabel;) csum ^= *ush--;
 
131
        for (csum = 0; ush >= (unsigned short *)sunlabel;)
 
132
                csum ^= *ush--;
 
133
 
132
134
        if (csum) {
133
135
                fprintf(stderr,_("Detected sun disklabel with wrong checksum.\n"
134
136
                                "Probably you'll have to set all the values,\n"
135
137
                                "e.g. heads, sectors, cylinders and partitions\n"
136
138
                                "or force a fresh label (s command in main menu)\n"));
137
139
        } else {
138
 
                heads = SSWAP16(sunlabel->ntrks);
 
140
                int need_fixing = 0;
 
141
 
 
142
                heads = SSWAP16(sunlabel->nhead);
139
143
                cylinders = SSWAP16(sunlabel->ncyl);
140
144
                sectors = SSWAP16(sunlabel->nsect);
 
145
 
 
146
                if (sunlabel->version != SSWAP32(SUN_LABEL_VERSION)) {
 
147
                        fprintf(stderr,_("Detected sun disklabel with wrong version [0x%08x].\n"),
 
148
                                sunlabel->version);
 
149
                        need_fixing = 1;
 
150
                }
 
151
                if (sunlabel->sanity != SSWAP32(SUN_LABEL_SANE)) {
 
152
                        fprintf(stderr,_("Detected sun disklabel with wrong sanity [0x%08x].\n"),
 
153
                                sunlabel->sanity);
 
154
                        need_fixing = 1;
 
155
                }
 
156
                if (sunlabel->num_partitions != SSWAP16(SUN_NUM_PARTITIONS)) {
 
157
                        fprintf(stderr,_("Detected sun disklabel with wrong num_partitions [%u].\n"),
 
158
                                sunlabel->num_partitions);
 
159
                        need_fixing = 1;
 
160
                }
 
161
                if (need_fixing) {
 
162
                        fprintf(stderr, _("Warning: Wrong values need to be "
 
163
                                          "fixed up and will be corrected "
 
164
                                          "by w(rite)\n"));
 
165
                        sunlabel->version = SSWAP32(SUN_LABEL_VERSION);
 
166
                        sunlabel->sanity = SSWAP32(SUN_LABEL_SANE);
 
167
                        sunlabel->num_partitions = SSWAP16(SUN_NUM_PARTITIONS);
 
168
 
 
169
                        ush = (unsigned short *)sunlabel;
 
170
                        csum = 0;
 
171
                        while(ush < (unsigned short *)(&sunlabel->cksum))
 
172
                                csum ^= *ush++;
 
173
                        sunlabel->cksum = csum;
 
174
 
 
175
                        set_changed(0);
 
176
                }
141
177
        }
142
178
        update_units();
143
179
        sun_label = 1;
144
 
        partitions = 8;
 
180
        partitions = SUN_NUM_PARTITIONS;
145
181
        return 1;
146
182
}
147
183
 
148
 
struct sun_predefined_drives {
149
 
        char *vendor;
150
 
        char *model;
151
 
        unsigned short sparecyl;
152
 
        unsigned short ncyl;
153
 
        unsigned short nacyl;
154
 
        unsigned short pcylcount;
155
 
        unsigned short ntrks;
156
 
        unsigned short nsect;
157
 
        unsigned short rspeed;
158
 
} sun_drives[] = {
159
 
{"Quantum","ProDrive 80S",1,832,2,834,6,34,3662},
160
 
{"Quantum","ProDrive 105S",1,974,2,1019,6,35,3662},
161
 
{"CDC","Wren IV 94171-344",3,1545,2,1549,9,46,3600},
162
 
{"IBM","DPES-31080",0,4901,2,4903,4,108,5400},
163
 
{"IBM","DORS-32160",0,1015,2,1017,67,62,5400},
164
 
{"IBM","DNES-318350",0,11199,2,11474,10,320,7200},
165
 
{"SEAGATE","ST34371",0,3880,2,3882,16,135,7228},
166
 
{"","SUN0104",1,974,2,1019,6,35,3662},
167
 
{"","SUN0207",4,1254,2,1272,9,36,3600},
168
 
{"","SUN0327",3,1545,2,1549,9,46,3600},
169
 
{"","SUN0340",0,1538,2,1544,6,72,4200},
170
 
{"","SUN0424",2,1151,2,2500,9,80,4400},
171
 
{"","SUN0535",0,1866,2,2500,7,80,5400},
172
 
{"","SUN0669",5,1614,2,1632,15,54,3600},
173
 
{"","SUN1.0G",5,1703,2,1931,15,80,3597},
174
 
{"","SUN1.05",0,2036,2,2038,14,72,5400},
175
 
{"","SUN1.3G",6,1965,2,3500,17,80,5400},
176
 
{"","SUN2.1G",0,2733,2,3500,19,80,5400},
177
 
{"IOMEGA","Jaz",0,1019,2,1021,64,32,5394},
178
 
};
179
 
 
180
 
static struct sun_predefined_drives *
181
 
sun_autoconfigure_scsi(void) {
182
 
    struct sun_predefined_drives *p = NULL;
183
 
 
184
 
#ifdef SCSI_IOCTL_GET_IDLUN
185
 
    unsigned int id[2];
186
 
    char buffer[2048];
187
 
    char buffer2[2048];
188
 
    FILE *pfd;
189
 
    char *vendor;
190
 
    char *model;
191
 
    char *q;
192
 
    int i;
193
 
 
194
 
    if (!ioctl(fd, SCSI_IOCTL_GET_IDLUN, &id)) {
195
 
        sprintf(buffer,
196
 
            "Host: scsi%d Channel: %02d Id: %02d Lun: %02d\n",
197
 
#if 0                    
198
 
            ((id[0]>>24)&0xff)-/*PROC_SCSI_SCSI+PROC_SCSI_FILE*/33,
199
 
#else
200
 
            /* This is very wrong (works only if you have one HBA),
201
 
               but I haven't found a way how to get hostno
202
 
               from the current kernel */
203
 
            0,
204
 
#endif                        
205
 
            (id[0]>>16)&0xff,
206
 
            id[0]&0xff,
207
 
            (id[0]>>8)&0xff);
208
 
        pfd = fopen("/proc/scsi/scsi","r");
209
 
        if (pfd) {
210
 
            while (fgets(buffer2,2048,pfd)) {
211
 
                if (!strcmp(buffer, buffer2)) {
212
 
                    if (fgets(buffer2,2048,pfd)) {
213
 
                        q = strstr(buffer2,"Vendor: ");
214
 
                        if (q) {
215
 
                            q += 8;
216
 
                            vendor = q;
217
 
                            q = strstr(q," ");
218
 
                            *q++ = 0;   /* truncate vendor name */
219
 
                            q = strstr(q,"Model: ");
220
 
                            if (q) {
221
 
                                *q = 0;
222
 
                                q += 7;
223
 
                                model = q;
224
 
                                q = strstr(q," Rev: ");
225
 
                                if (q) {
226
 
                                    *q = 0;
227
 
                                    for (i = 0; i < SIZE(sun_drives); i++) {
228
 
                                        if (*sun_drives[i].vendor && strcasecmp(sun_drives[i].vendor, vendor))
229
 
                                            continue;
230
 
                                        if (!strstr(model, sun_drives[i].model))
231
 
                                            continue;
232
 
                                        printf(_("Autoconfigure found a %s%s%s\n"),sun_drives[i].vendor,(*sun_drives[i].vendor) ? " " : "",sun_drives[i].model);
233
 
                                        p = sun_drives + i;
234
 
                                        break;
235
 
                                    }
236
 
                                }
237
 
                            }
238
 
                        }
239
 
                    }
240
 
                    break;
241
 
                }
242
 
            }
243
 
            fclose(pfd);
244
 
        }
245
 
    }
246
 
#endif
247
 
    return p;
248
 
}
249
 
 
250
184
void create_sunlabel(void)
251
185
{
252
186
        struct hd_geometry geometry;
 
187
        unsigned long long llsectors, llcyls;
253
188
        unsigned int ndiv;
254
 
        int i;
255
 
        unsigned char c;
256
 
        struct sun_predefined_drives *p = NULL;
 
189
        int res, sec_fac;
257
190
 
258
191
        fprintf(stderr,
259
192
        _("Building a new sun disklabel. Changes will remain in memory only,\n"
266
199
#endif
267
200
        memset(MBRbuffer, 0, sizeof(MBRbuffer));
268
201
        sunlabel->magic = SSWAP16(SUN_LABEL_MAGIC);
269
 
        if (!floppy) {
270
 
            puts(_("Drive type\n"
271
 
                 "   ?   auto configure\n"
272
 
                 "   0   custom (with hardware detected defaults)"));
273
 
            for (i = 0; i < SIZE(sun_drives); i++) {
274
 
                printf("   %c   %s%s%s\n",
275
 
                       i + 'a', sun_drives[i].vendor,
276
 
                       (*sun_drives[i].vendor) ? " " : "",
277
 
                       sun_drives[i].model);
278
 
            }
279
 
            for (;;) {
280
 
                c = read_char(_("Select type (? for auto, 0 for custom): "));
281
 
                if (c >= 'a' && c < 'a' + SIZE(sun_drives)) {
282
 
                    p = sun_drives + c - 'a';
283
 
                    break;
284
 
                } else if (c >= 'A' && c < 'A' + SIZE(sun_drives)) {
285
 
                    p = sun_drives + c - 'A';
286
 
                    break;
287
 
                } else if (c == '0') {
288
 
                    break;
289
 
                } else if (c == '?' && scsi_disk) {
290
 
                    p = sun_autoconfigure_scsi();
291
 
                    if (!p)
292
 
                        printf(_("Autoconfigure failed.\n"));
293
 
                    else
294
 
                        break;
295
 
                }
296
 
            }
297
 
        }
298
 
        if (!p || floppy) {
299
 
            if (!ioctl(fd, HDIO_GETGEO, &geometry)) {
 
202
        sunlabel->sanity = SSWAP32(SUN_LABEL_SANE);
 
203
        sunlabel->version = SSWAP32(SUN_LABEL_VERSION);
 
204
        sunlabel->num_partitions = SSWAP16(SUN_NUM_PARTITIONS);
 
205
 
 
206
        res = disksize(fd, &llsectors);
 
207
        sec_fac = sector_size / 512;
 
208
 
 
209
        if (!ioctl(fd, HDIO_GETGEO, &geometry)) {
300
210
                heads = geometry.heads;
301
211
                sectors = geometry.sectors;
302
 
                cylinders = geometry.cylinders;
303
 
            } else {
304
 
                heads = 0;
305
 
                sectors = 0;
306
 
                cylinders = 0;
307
 
            }
308
 
            if (floppy) {
309
 
                sunlabel->nacyl = 0;
310
 
                sunlabel->pcylcount = SSWAP16(cylinders);
311
 
                sunlabel->rspeed = SSWAP16(300);
312
 
                sunlabel->ilfact = SSWAP16(1);
313
 
                sunlabel->sparecyl = 0;
314
 
            } else {
315
 
                heads = read_int(1,heads,1024,0,_("Heads"));
316
 
                sectors = read_int(1,sectors,1024,0,_("Sectors/track"));
317
 
                if (cylinders)
318
 
                    cylinders = read_int(1,cylinders-2,65535,0,_("Cylinders"));
319
 
                else
320
 
                    cylinders = read_int(1,0,65535,0,_("Cylinders"));
321
 
                sunlabel->nacyl =
322
 
                        SSWAP16(read_int(0,2,65535,0,
323
 
                                         _("Alternate cylinders")));
324
 
                sunlabel->pcylcount =
325
 
                        SSWAP16(read_int(0,cylinders+SSWAP16(sunlabel->nacyl),
326
 
                                         65535,0,_("Physical cylinders")));
327
 
                sunlabel->rspeed =
328
 
                        SSWAP16(read_int(1,5400,100000,0,
329
 
                                         _("Rotation speed (rpm)")));
330
 
                sunlabel->ilfact =
331
 
                        SSWAP16(read_int(1,1,32,0,_("Interleave factor")));
332
 
                sunlabel->sparecyl =
333
 
                        SSWAP16(read_int(0,0,sectors,0,
334
 
                                         _("Extra sectors per cylinder")));
335
 
            }
 
212
                if (res == 0) {
 
213
                        llcyls = llsectors / (heads * sectors * sec_fac);
 
214
                        cylinders = llcyls;
 
215
                        if (cylinders != llcyls)
 
216
                                cylinders = ~0;
 
217
                } else {
 
218
                        cylinders = geometry.cylinders;
 
219
                        fprintf(stderr,
 
220
                                _("Warning:  BLKGETSIZE ioctl failed on %s.  "
 
221
                                  "Using geometry cylinder value of %d.\n"
 
222
                                  "This value may be truncated for devices"
 
223
                                  " > 33.8 GB.\n"), disk_device, cylinders);
 
224
                }
336
225
        } else {
337
 
            sunlabel->sparecyl = SSWAP16(p->sparecyl);
338
 
            sunlabel->ncyl = SSWAP16(p->ncyl);
339
 
            sunlabel->nacyl = SSWAP16(p->nacyl);
340
 
            sunlabel->pcylcount = SSWAP16(p->pcylcount);
341
 
            sunlabel->ntrks = SSWAP16(p->ntrks);
342
 
            sunlabel->nsect = SSWAP16(p->nsect);
343
 
            sunlabel->rspeed = SSWAP16(p->rspeed);
344
 
            sunlabel->ilfact = SSWAP16(1);
345
 
            cylinders = p->ncyl;
346
 
            heads = p->ntrks;
347
 
            sectors = p->nsect;
348
 
            puts(_("You may change all the disk params from the x menu"));
 
226
                heads = read_int(1,1,1024,0,_("Heads"));
 
227
                sectors = read_int(1,1,1024,0,_("Sectors/track"));
 
228
                cylinders = read_int(1,1,65535,0,_("Cylinders"));
349
229
        }
350
230
 
351
 
        snprintf(sunlabel->info, sizeof(sunlabel->info),
352
 
                 "%s%s%s cyl %d alt %d hd %d sec %d", 
353
 
                 p ? p->vendor : "", (p && *p->vendor) ? " " : "",
354
 
                 p ? p->model
355
 
                   : (floppy ? _("3,5\" floppy") : _("Linux custom")),
356
 
                cylinders, SSWAP16(sunlabel->nacyl), heads, sectors);
 
231
        sunlabel->acyl   = SSWAP16(2);
 
232
        sunlabel->pcyl   = SSWAP16(cylinders);
 
233
        sunlabel->ncyl   = SSWAP16(cylinders - 2);
 
234
        sunlabel->rpm    = SSWAP16(5400);
 
235
        sunlabel->intrlv = SSWAP16(1);
 
236
        sunlabel->apc    = SSWAP16(0);
357
237
 
358
 
        sunlabel->ntrks = SSWAP16(heads);
 
238
        sunlabel->nhead = SSWAP16(heads);
359
239
        sunlabel->nsect = SSWAP16(sectors);
360
240
        sunlabel->ncyl = SSWAP16(cylinders);
361
 
        if (floppy)
362
 
            set_sun_partition(0, 0, cylinders * heads * sectors, LINUX_NATIVE);
363
 
        else {
364
 
            if (cylinders * heads * sectors >= 150 * 2048) {
 
241
 
 
242
        snprintf(sunlabel->label_id, sizeof(sunlabel->label_id),
 
243
                 "Linux cyl %d alt %d hd %d sec %llu",
 
244
                 cylinders, SSWAP16(sunlabel->acyl), heads, sectors);
 
245
 
 
246
        if (cylinders * heads * sectors >= 150 * 2048) {
365
247
                ndiv = cylinders - (50 * 2048 / (heads * sectors)); /* 50M swap */
366
 
            } else
 
248
        } else
367
249
                ndiv = cylinders * 2 / 3;
368
 
            set_sun_partition(0, 0, ndiv * heads * sectors, LINUX_NATIVE);
369
 
            set_sun_partition(1, ndiv * heads * sectors, cylinders * heads * sectors, LINUX_SWAP);
370
 
            sunlabel->infos[1].flags |= 0x01; /* Not mountable */
371
 
        }
372
 
        set_sun_partition(2, 0, cylinders * heads * sectors, WHOLE_DISK);
 
250
 
 
251
        set_sun_partition(0, 0, ndiv * heads * sectors,
 
252
                          SUN_TAG_LINUX_NATIVE);
 
253
        set_sun_partition(1, ndiv * heads * sectors,
 
254
                          cylinders * heads * sectors,
 
255
                          SUN_TAG_LINUX_SWAP);
 
256
        sunlabel->part_tags[1].flag |= SSWAP16(SUN_FLAG_UNMNT);
 
257
 
 
258
        set_sun_partition(2, 0, cylinders * heads * sectors, SUN_TAG_BACKUP);
 
259
 
373
260
        {
374
261
                unsigned short *ush = (unsigned short *)sunlabel;
375
262
                unsigned short csum = 0;
376
 
                while(ush < (unsigned short *)(&sunlabel->csum))
 
263
                while(ush < (unsigned short *)(&sunlabel->cksum))
377
264
                        csum ^= *ush++;
378
 
                sunlabel->csum = csum;
 
265
                sunlabel->cksum = csum;
379
266
        }
380
267
 
381
268
        set_all_unchanged();
383
270
        set_changed(0);
384
271
}
385
272
 
386
 
void
387
 
toggle_sunflags(int i, unsigned char mask) {
388
 
        if (sunlabel->infos[i].flags & mask)
389
 
                sunlabel->infos[i].flags &= ~mask;
390
 
        else sunlabel->infos[i].flags |= mask;
 
273
void toggle_sunflags(int i, __u16 mask)
 
274
{
 
275
        struct sun_tag_flag *p = &sunlabel->part_tags[i];
 
276
 
 
277
        p->flag ^= SSWAP16(mask);
 
278
 
391
279
        set_changed(i);
392
280
}
393
281
 
394
 
static void
395
 
fetch_sun(unsigned int *starts, unsigned int *lens, unsigned int *start, unsigned int *stop) {
 
282
static void fetch_sun(__u32 *starts, __u32 *lens, __u32 *start, __u32 *stop)
 
283
{
396
284
        int i, continuous = 1;
397
 
        *start = 0; *stop = cylinders * heads * sectors;
 
285
 
 
286
        *start = 0;
 
287
        *stop = cylinders * heads * sectors;
 
288
 
398
289
        for (i = 0; i < partitions; i++) {
399
 
                if (sunlabel->partitions[i].num_sectors
400
 
                    && sunlabel->infos[i].id
401
 
                    && sunlabel->infos[i].id != WHOLE_DISK) {
402
 
                        starts[i] = SSWAP32(sunlabel->partitions[i].start_cylinder) * heads * sectors;
403
 
                        lens[i] = SSWAP32(sunlabel->partitions[i].num_sectors);
 
290
                struct sun_partition *part = &sunlabel->partitions[i];
 
291
                struct sun_tag_flag *tag = &sunlabel->part_tags[i];
 
292
 
 
293
                if (part->num_sectors &&
 
294
                    tag->tag != SSWAP16(SUN_TAG_UNASSIGNED) &&
 
295
                    tag->tag != SSWAP16(SUN_TAG_BACKUP)) {
 
296
                        starts[i] = (SSWAP32(part->start_cylinder) *
 
297
                                     heads * sectors);
 
298
                        lens[i] = SSWAP32(part->num_sectors);
404
299
                        if (continuous) {
405
300
                                if (starts[i] == *start)
406
301
                                        *start += lens[i];
420
315
 
421
316
static unsigned int *verify_sun_starts;
422
317
 
423
 
static int
424
 
verify_sun_cmp(int *a, int *b) {
425
 
    if (*a == -1) return 1;
426
 
    if (*b == -1) return -1;
427
 
    if (verify_sun_starts[*a] > verify_sun_starts[*b]) return 1;
 
318
static int verify_sun_cmp(int *a, int *b)
 
319
{
 
320
    if (*a == -1)
 
321
            return 1;
 
322
    if (*b == -1)
 
323
            return -1;
 
324
    if (verify_sun_starts[*a] > verify_sun_starts[*b])
 
325
            return 1;
428
326
    return -1;
429
327
}
430
328
 
431
 
void
432
 
verify_sun(void) {
433
 
    unsigned int starts[8], lens[8], start, stop;
 
329
void verify_sun(void)
 
330
{
 
331
    __u32 starts[SUN_NUM_PARTITIONS], lens[SUN_NUM_PARTITIONS], start, stop;
434
332
    int i,j,k,starto,endo;
435
 
    int array[8];
 
333
    int array[SUN_NUM_PARTITIONS];
436
334
 
437
335
    verify_sun_starts = starts;
438
 
    fetch_sun(starts,lens,&start,&stop);
 
336
 
 
337
    fetch_sun(starts, lens, &start, &stop);
 
338
 
439
339
    for (k = 0; k < 7; k++) {
440
 
        for (i = 0; i < 8; i++) {
 
340
        for (i = 0; i < SUN_NUM_PARTITIONS; i++) {
441
341
            if (k && (lens[i] % (heads * sectors))) {
442
342
                printf(_("Partition %d doesn't end on cylinder boundary\n"), i+1);
443
343
            }
467
367
            }
468
368
        }
469
369
    }
470
 
    for (i = 0; i < 8; i++) {
 
370
    for (i = 0; i < SUN_NUM_PARTITIONS; i++) {
471
371
        if (lens[i])
472
372
            array[i] = i;
473
373
        else
481
381
    }
482
382
    stop = cylinders * heads * sectors;
483
383
    if (starts[array[0]])
484
 
        printf(_("Unused gap - sectors 0-%d\n"),starts[array[0]]);
 
384
        printf(_("Unused gap - sectors 0-%d\n"), starts[array[0]]);
485
385
    for (i = 0; i < 7 && array[i+1] != -1; i++) {
486
 
        printf(_("Unused gap - sectors %d-%d\n"),starts[array[i]]+lens[array[i]],starts[array[i+1]]);
 
386
        printf(_("Unused gap - sectors %d-%d\n"),
 
387
               (starts[array[i]] + lens[array[i]]),
 
388
               starts[array[i+1]]);
487
389
    }
488
 
    start = starts[array[i]]+lens[array[i]];
 
390
    start = (starts[array[i]] + lens[array[i]]);
489
391
    if (start < stop)
490
 
        printf(_("Unused gap - sectors %d-%d\n"),start,stop);
 
392
        printf(_("Unused gap - sectors %d-%d\n"), start, stop);
491
393
}
492
394
 
493
 
void
494
 
add_sun_partition(int n, int sys) {
495
 
        unsigned int start, stop, stop2;
496
 
        unsigned int starts[8], lens[8];
 
395
void add_sun_partition(int n, int sys)
 
396
{
 
397
        __u32 starts[SUN_NUM_PARTITIONS], lens[SUN_NUM_PARTITIONS];
 
398
        struct sun_partition *part = &sunlabel->partitions[n];
 
399
        struct sun_tag_flag *tag = &sunlabel->part_tags[n];
 
400
        __u32 start, stop, stop2;
497
401
        int whole_disk = 0;
498
402
                
499
403
        char mesg[256];
500
404
        int i, first, last;
501
405
 
502
 
        if (sunlabel->partitions[n].num_sectors && sunlabel->infos[n].id) {
 
406
        if (part->num_sectors && tag->tag != SSWAP16(SUN_TAG_UNASSIGNED)) {
503
407
                printf(_("Partition %d is already defined.  Delete "
504
408
                        "it before re-adding it.\n"), n + 1);
505
409
                return;
506
410
        }
507
411
        
508
 
        fetch_sun(starts,lens,&start,&stop);
 
412
        fetch_sun(starts, lens, &start, &stop);
509
413
        if (stop <= start) {
510
414
                if (n == 2)
511
415
                        whole_disk = 1;
601
505
        } else if (!whole_disk && last > stop)
602
506
                last = stop;
603
507
 
604
 
        if (whole_disk) sys = WHOLE_DISK;
 
508
        if (whole_disk)
 
509
                sys = SUN_TAG_BACKUP;
 
510
 
605
511
        set_sun_partition(n, first, last, sys);
606
512
}
607
513
 
608
 
void
609
 
sun_delete_partition(int i) {
 
514
void sun_delete_partition(int i)
 
515
{
 
516
        struct sun_partition *part = &sunlabel->partitions[i];
 
517
        struct sun_tag_flag *tag = &sunlabel->part_tags[i];
610
518
        unsigned int nsec;
611
519
 
612
 
        if (i == 2 && sunlabel->infos[i].id == WHOLE_DISK && 
613
 
            !sunlabel->partitions[i].start_cylinder && 
614
 
            (nsec = SSWAP32(sunlabel->partitions[i].num_sectors))
 
520
        if (i == 2 &&
 
521
            tag->tag == SSWAP16(SUN_TAG_BACKUP) &&
 
522
            !part->start_cylinder &&
 
523
            (nsec = SSWAP32(part->num_sectors))
615
524
              == heads * sectors * cylinders)
616
525
                printf(_("If you want to maintain SunOS/Solaris compatibility, "
617
526
                       "consider leaving this\n"
618
527
                       "partition as Whole disk (5), starting at 0, with %u "
619
528
                       "sectors\n"), nsec);
620
 
        sunlabel->infos[i].id = 0;
621
 
        sunlabel->partitions[i].num_sectors = 0;
 
529
        tag->tag = SSWAP16(SUN_TAG_UNASSIGNED);
 
530
        part->num_sectors = 0;
622
531
}
623
532
 
624
 
void
625
 
sun_change_sysid(int i, int sys) {
626
 
        if (sys == LINUX_SWAP && !sunlabel->partitions[i].start_cylinder) {
 
533
int sun_change_sysid(int i, __u16 sys)
 
534
{
 
535
        struct sun_partition *part = &sunlabel->partitions[i];
 
536
        struct sun_tag_flag *tag = &sunlabel->part_tags[i];
 
537
 
 
538
        if (sys == SUN_TAG_LINUX_SWAP && !part->start_cylinder) {
627
539
            read_chars(
628
540
              _("It is highly recommended that the partition at offset 0\n"
629
541
              "is UFS, EXT2FS filesystem or SunOS swap. Putting Linux swap\n"
631
543
              "Type YES if you're very sure you would like that partition\n"
632
544
              "tagged with 82 (Linux swap): "));
633
545
            if (strcmp (line_ptr, _("YES\n")))
634
 
                    return;
 
546
                    return 0;
635
547
        }
636
548
        switch (sys) {
637
 
        case SUNOS_SWAP:
638
 
        case LINUX_SWAP:
 
549
        case SUN_TAG_SWAP:
 
550
        case SUN_TAG_LINUX_SWAP:
639
551
                /* swaps are not mountable by default */
640
 
                sunlabel->infos[i].flags |= 0x01;
 
552
                tag->flag |= SSWAP16(SUN_FLAG_UNMNT);
641
553
                break;
642
554
        default:
643
555
                /* assume other types are mountable;
644
556
                   user can change it anyway */
645
 
                sunlabel->infos[i].flags &= ~0x01;
 
557
                tag->flag &= ~SSWAP16(SUN_FLAG_UNMNT);
646
558
                break;
647
559
        }
648
 
        sunlabel->infos[i].id = sys;
 
560
        tag->tag = SSWAP16(sys);
 
561
        return 1;
649
562
}
650
563
 
651
 
void
652
 
sun_list_table(int xtra) {
 
564
void sun_list_table(int xtra)
 
565
{
653
566
        int i, w;
654
567
        char *type;
655
568
 
656
569
        w = strlen(disk_device);
657
570
        if (xtra)
658
571
                printf(
659
 
                _("\nDisk %s (Sun disk label): %d heads, %d sectors, %d rpm\n"
 
572
                _("\nDisk %s (Sun disk label): %d heads, %llu sectors, %d rpm\n"
660
573
                "%d cylinders, %d alternate cylinders, %d physical cylinders\n"
661
574
                "%d extra sects/cyl, interleave %d:1\n"
662
 
                "%s\n"
 
575
                "Label ID: %s\n"
 
576
                "Volume ID: %s\n"
663
577
                "Units = %s of %d * 512 bytes\n\n"),
664
 
                       disk_device, heads, sectors, SSWAP16(sunlabel->rspeed),
665
 
                       cylinders, SSWAP16(sunlabel->nacyl),
666
 
                       SSWAP16(sunlabel->pcylcount),
667
 
                       SSWAP16(sunlabel->sparecyl),
668
 
                       SSWAP16(sunlabel->ilfact),
669
 
                       (char *)sunlabel,
 
578
                       disk_device, heads, sectors, SSWAP16(sunlabel->rpm),
 
579
                       cylinders, SSWAP16(sunlabel->acyl),
 
580
                       SSWAP16(sunlabel->pcyl),
 
581
                       SSWAP16(sunlabel->apc),
 
582
                       SSWAP16(sunlabel->intrlv),
 
583
                       sunlabel->label_id,
 
584
                       sunlabel->volume_id,
670
585
                       str_units(PLURAL), units_per_sector);
671
586
        else
672
587
                printf(
673
 
        _("\nDisk %s (Sun disk label): %d heads, %d sectors, %d cylinders\n"
 
588
        _("\nDisk %s (Sun disk label): %d heads, %llu sectors, %d cylinders\n"
674
589
        "Units = %s of %d * 512 bytes\n\n"),
675
590
                       disk_device, heads, sectors, cylinders,
676
591
                       str_units(PLURAL), units_per_sector);
678
593
        printf(_("%*s Flag    Start       End    Blocks   Id  System\n"),
679
594
               w + 1, _("Device"));
680
595
        for (i = 0 ; i < partitions; i++) {
681
 
                if (sunlabel->partitions[i].num_sectors) {
682
 
                        __u32 start = SSWAP32(sunlabel->partitions[i].start_cylinder) * heads * sectors;
683
 
                        __u32 len = SSWAP32(sunlabel->partitions[i].num_sectors);
 
596
                struct sun_partition *part = &sunlabel->partitions[i];
 
597
                struct sun_tag_flag *tag = &sunlabel->part_tags[i];
 
598
 
 
599
                if (part->num_sectors) {
 
600
                        __u32 start = SSWAP32(part->start_cylinder) * heads * sectors;
 
601
                        __u32 len = SSWAP32(part->num_sectors);
684
602
                        printf(
685
603
                            "%s %c%c %9ld %9ld %9ld%c  %2x  %s\n",
686
604
/* device */              partname(disk_device, i+1, w),
687
 
/* flags */               (sunlabel->infos[i].flags & 0x01) ? 'u' : ' ',
688
 
                          (sunlabel->infos[i].flags & 0x10) ? 'r' : ' ',
 
605
/* flags */               (tag->flag & SSWAP16(SUN_FLAG_UNMNT)) ? 'u' : ' ',
 
606
                          (tag->flag & SSWAP16(SUN_FLAG_RONLY)) ? 'r' : ' ',
689
607
/* start */               (long) scround(start),
690
608
/* end */                 (long) scround(start+len),
691
609
/* odd flag on end */     (long) len / 2, len & 1 ? '+' : ' ',
692
 
/* type id */             sunlabel->infos[i].id,
693
 
/* type name */           (type = partition_type(sunlabel->infos[i].id))
 
610
/* type id */             SSWAP16(tag->tag),
 
611
/* type name */           (type = partition_type(SSWAP16(tag->tag)))
694
612
                                ? type : _("Unknown"));
695
613
                }
696
614
        }
697
615
}
698
616
 
699
 
void
700
 
sun_set_alt_cyl(void) {
701
 
        sunlabel->nacyl =
702
 
                SSWAP16(read_int(0,SSWAP16(sunlabel->nacyl), 65535, 0,
 
617
void sun_set_alt_cyl(void)
 
618
{
 
619
        sunlabel->acyl =
 
620
                SSWAP16(read_int(0,SSWAP16(sunlabel->acyl), 65535, 0,
703
621
                                 _("Number of alternate cylinders")));
704
622
}
705
623
 
706
 
void
707
 
sun_set_ncyl(int cyl) {
 
624
void sun_set_ncyl(int cyl)
 
625
{
708
626
        sunlabel->ncyl = SSWAP16(cyl);
709
627
}
710
628
 
711
 
void
712
 
sun_set_xcyl(void) {
713
 
        sunlabel->sparecyl =
714
 
                SSWAP16(read_int(0, SSWAP16(sunlabel->sparecyl), sectors, 0,
 
629
void sun_set_xcyl(void)
 
630
{
 
631
        sunlabel->apc =
 
632
                SSWAP16(read_int(0, SSWAP16(sunlabel->apc), sectors, 0,
715
633
                                 _("Extra sectors per cylinder")));
716
634
}
717
635
 
718
 
void
719
 
sun_set_ilfact(void) {
720
 
        sunlabel->ilfact =
721
 
                SSWAP16(read_int(1, SSWAP16(sunlabel->ilfact), 32, 0,
 
636
void sun_set_ilfact(void)
 
637
{
 
638
        sunlabel->intrlv =
 
639
                SSWAP16(read_int(1, SSWAP16(sunlabel->intrlv), 32, 0,
722
640
                                 _("Interleave factor")));
723
641
}
724
642
 
725
 
void
726
 
sun_set_rspeed(void) {
727
 
        sunlabel->rspeed =
728
 
                SSWAP16(read_int(1, SSWAP16(sunlabel->rspeed), 100000, 0,
 
643
void sun_set_rspeed(void)
 
644
{
 
645
        sunlabel->rpm =
 
646
                SSWAP16(read_int(1, SSWAP16(sunlabel->rpm), 100000, 0,
729
647
                                 _("Rotation speed (rpm)")));
730
648
}
731
649
 
732
 
void
733
 
sun_set_pcylcount(void) {
734
 
        sunlabel->pcylcount =
735
 
                SSWAP16(read_int(0, SSWAP16(sunlabel->pcylcount), 65535, 0,
 
650
void sun_set_pcylcount(void)
 
651
{
 
652
        sunlabel->pcyl =
 
653
                SSWAP16(read_int(0, SSWAP16(sunlabel->pcyl), 65535, 0,
736
654
                                 _("Number of physical cylinders")));
737
655
}
738
656
 
739
 
void
740
 
sun_write_table(void) {
 
657
void sun_write_table(void)
 
658
{
741
659
        unsigned short *ush = (unsigned short *)sunlabel;
742
660
        unsigned short csum = 0;
743
661
 
744
 
        while(ush < (unsigned short *)(&sunlabel->csum))
 
662
        while(ush < (unsigned short *)(&sunlabel->cksum))
745
663
                csum ^= *ush++;
746
 
        sunlabel->csum = csum;
 
664
        sunlabel->cksum = csum;
747
665
        if (lseek(fd, 0, SEEK_SET) < 0)
748
666
                fatal(unable_to_seek);
749
667
        if (write(fd, sunlabel, SECTOR_SIZE) != SECTOR_SIZE)
750
668
                fatal(unable_to_write);
751
669
}
 
670
 
 
671
int sun_get_sysid(int i)
 
672
{
 
673
        return SSWAP16(sunlabel->part_tags[i].tag);
 
674
}