static void sgi_write_table(void) { sgilabel->csum = 0; sgilabel->csum = SGI_SSWAP32(two_s_complement_32bit_sum( (unsigned int*)sgilabel, sizeof(*sgilabel))); assert(two_s_complement_32bit_sum( (unsigned int*)sgilabel, sizeof(*sgilabel)) == 0); if (lseek(fd, 0, SEEK_SET) < 0) fdisk_fatal(unable_to_seek); if (write(fd, sgilabel, SECTOR_SIZE) != SECTOR_SIZE) fdisk_fatal(unable_to_write); if (!strncmp((char*)sgilabel->directory[0].vol_file_name, "sgilabel", 8)) { /* * keep this habit of first writing the "sgilabel". * I never tested whether it works without (AN 981002). */ sgiinfo *info = fill_sgiinfo(); int infostartblock = SGI_SSWAP32(sgilabel->directory[0].vol_file_start); if (lseek(fd, infostartblock*SECTOR_SIZE, SEEK_SET) < 0) fdisk_fatal(unable_to_seek); if (write(fd, info, SECTOR_SIZE) != SECTOR_SIZE) fdisk_fatal(unable_to_write); free(info); } }
/* * Read a xbsd_disklabel from sector 0 or from the starting sector of p. * If it has the right magic, return 1. */ static int xbsd_readlabel(struct partition *p) { struct xbsd_disklabel *d; int t, sector; if (!bsd_globals_ptr) bsd_globals_ptr = xzalloc(sizeof(*bsd_globals_ptr)); d = &xbsd_dlabel; /* p is used only to get the starting sector */ #if !defined(__alpha__) sector = (p ? get_start_sect(p) : 0); #else sector = 0; #endif seek_sector(sector); if (BSD_BBSIZE != full_read(dev_fd, disklabelbuffer, BSD_BBSIZE)) fdisk_fatal(unable_to_read); memmove(d, &disklabelbuffer[BSD_LABELSECTOR * SECTOR_SIZE + BSD_LABELOFFSET], sizeof(struct xbsd_disklabel)); if (d->d_magic != BSD_DISKMAGIC || d->d_magic2 != BSD_DISKMAGIC) return 0; for (t = d->d_npartitions; t < BSD_MAXPARTITIONS; t++) { d->d_partitions[t].p_size = 0; d->d_partitions[t].p_offset = 0; d->d_partitions[t].p_fstype = BSD_FS_UNUSED; } if (d->d_npartitions > BSD_MAXPARTITIONS) printf("Warning: too many partitions (%u, maximum is %u)\n", d->d_npartitions, BSD_MAXPARTITIONS); return 1; }
static int check_gpt_label(void) { struct partition *first = pt_offset(MBRbuffer, 0); struct pte pe; uint32_t crc; /* LBA 0 contains the legacy MBR */ if (!valid_part_table_flag(MBRbuffer) || first->sys_ind != LEGACY_GPT_TYPE ) { current_label_type = 0; return 0; } /* LBA 1 contains the GPT header */ read_pte(&pe, 1); gpt_hdr = (void *)pe.sectorbuffer; if (gpt_hdr->magic != SWAP_LE64(GPT_MAGIC)) { current_label_type = 0; return 0; } if (!global_crc32_table) { global_crc32_table = crc32_filltable(NULL, 0); } crc = SWAP_LE32(gpt_hdr->hdr_crc32); gpt_hdr->hdr_crc32 = 0; if (gpt_crc32(gpt_hdr, SWAP_LE32(gpt_hdr->hdr_size)) != crc) { /* FIXME: read the backup table */ puts("\nwarning: GPT header CRC is invalid\n"); } n_parts = SWAP_LE32(gpt_hdr->n_parts); part_entry_len = SWAP_LE32(gpt_hdr->part_entry_len); if (n_parts > GPT_MAX_PARTS || part_entry_len > GPT_MAX_PART_ENTRY_LEN || SWAP_LE32(gpt_hdr->hdr_size) > sector_size ) { puts("\nwarning: unable to parse GPT disklabel\n"); current_label_type = 0; return 0; } part_array_len = n_parts * part_entry_len; part_array = xmalloc(part_array_len); seek_sector(SWAP_LE64(gpt_hdr->first_part_lba)); if (full_read(dev_fd, part_array, part_array_len) != part_array_len) { fdisk_fatal(unable_to_read); } if (gpt_crc32(part_array, part_array_len) != gpt_hdr->part_array_crc32) { /* FIXME: read the backup table */ puts("\nwarning: GPT array CRC is invalid\n"); } puts("Found valid GPT with protective MBR; using GPT\n"); current_label_type = LABEL_GPT; return 1; }