int check_dos_label(struct fdisk_context *cxt) { int i; if (!valid_part_table_flag(cxt->mbr)) return 0; dos_init(cxt); for (i = 0; i < 4; i++) { struct pte *pe = &ptes[i]; if (IS_EXTENDED (pe->part_table->sys_ind)) { if (partitions != 4) fprintf(stderr, _("Ignoring extra extended " "partition %d\n"), i + 1); else read_extended(cxt, i); } } for (i = 3; i < partitions; i++) { struct pte *pe = &ptes[i]; if (!valid_part_table_flag(pe->sectorbuffer)) { fprintf(stderr, _("Warning: invalid flag 0x%04x of partition " "table %d will be corrected by w(rite)\n"), part_table_flag(pe->sectorbuffer), i + 1); pe->changed = 1; } } return 1; }
void dos_delete_partition(int i) { struct pte *pe = &ptes[i]; struct partition *p = pe->part_table; struct partition *q = pe->ext_pointer; /* Note that for the fifth partition (i == 4) we don't actually decrement partitions. */ if (i < 4) { if (IS_EXTENDED (p->sys_ind) && i == ext_index) { partitions = 4; ptes[ext_index].ext_pointer = NULL; extended_offset = 0; } clear_partition(p); } else if (!q->sys_ind && i > 4) { /* the last one in the chain - just delete */ --partitions; --i; clear_partition(ptes[i].ext_pointer); ptes[i].changed = 1; } else { /* not the last one - further ones will be moved down */ if (i > 4) { /* delete this link in the chain */ p = ptes[i-1].ext_pointer; *p = *q; set_start_sect(p, get_start_sect(q)); set_nr_sects(p, get_nr_sects(q)); ptes[i-1].changed = 1; } else if (partitions > 5) { /* 5 will be moved to 4 */ /* the first logical in a longer chain */ struct pte *pe = &ptes[5]; if (pe->part_table) /* prevent SEGFAULT */ set_start_sect(pe->part_table, get_partition_start(pe) - extended_offset); pe->offset = extended_offset; pe->changed = 1; } if (partitions > 5) { partitions--; while (i < partitions) { ptes[i] = ptes[i+1]; i++; } } else /* the only logical: clear only */ clear_partition(ptes[i].part_table); } }
void dos_add_partition(struct fdisk_context *cxt, int n, int sys) { char mesg[256]; /* 48 does not suffice in Japanese */ int i, read = 0; struct partition *p = ptes[n].part_table; struct partition *q = ptes[ext_index].part_table; sector_t start, stop = 0, limit, temp, first[partitions], last[partitions]; if (p && p->sys_ind) { printf(_("Partition %d is already defined. Delete " "it before re-adding it.\n"), n + 1); return; } fill_bounds(first, last); if (n < 4) { start = sector_offset; if (display_in_cyl_units || !cxt->total_sectors) limit = cxt->geom.heads * cxt->geom.sectors * cxt->geom.cylinders - 1; else limit = cxt->total_sectors - 1; if (limit > UINT_MAX) limit = UINT_MAX; if (extended_offset) { first[ext_index] = extended_offset; last[ext_index] = get_start_sect(q) + get_nr_sects(q) - 1; } } else { start = extended_offset + sector_offset; limit = get_start_sect(q) + get_nr_sects(q) - 1; } if (display_in_cyl_units) for (i = 0; i < partitions; i++) first[i] = (cround(first[i]) - 1) * units_per_sector; snprintf(mesg, sizeof(mesg), _("First %s"), str_units(SINGULAR)); do { sector_t dflt, aligned; temp = start; dflt = start = get_unused_start(n, start, first, last); /* the default sector should be aligned and unused */ do { aligned = align_lba_in_range(cxt, dflt, dflt, limit); dflt = get_unused_start(n, aligned, first, last); } while (dflt != aligned && dflt > aligned && dflt < limit); if (dflt >= limit) dflt = start; if (start > limit) break; if (start >= temp+units_per_sector && read) { printf(_("Sector %llu is already allocated\n"), temp); temp = start; read = 0; } if (!read && start == temp) { sector_t i = start; start = read_int(cxt, cround(i), cround(dflt), cround(limit), 0, mesg); if (display_in_cyl_units) { start = (start - 1) * units_per_sector; if (start < i) start = i; } read = 1; } } while (start != temp || !read); if (n > 4) { /* NOT for fifth partition */ struct pte *pe = &ptes[n]; pe->offset = start - sector_offset; if (pe->offset == extended_offset) { /* must be corrected */ pe->offset++; if (sector_offset == 1) start++; } } for (i = 0; i < partitions; i++) { struct pte *pe = &ptes[i]; if (start < pe->offset && limit >= pe->offset) limit = pe->offset - 1; if (start < first[i] && limit >= first[i]) limit = first[i] - 1; } if (start > limit) { printf(_("No free sectors available\n")); if (n > 4) partitions--; return; } if (cround(start) == cround(limit)) { stop = limit; } else { int is_suffix_used = 0; snprintf(mesg, sizeof(mesg), _("Last %1$s, +%2$s or +size{K,M,G}"), str_units(SINGULAR), str_units(PLURAL)); stop = read_int_with_suffix(cxt, cround(start), cround(limit), cround(limit), cround(start), mesg, &is_suffix_used); if (display_in_cyl_units) { stop = stop * units_per_sector - 1; if (stop >limit) stop = limit; } if (is_suffix_used && alignment_required) { /* the last sector has not been exactly requested (but * defined by +size{K,M,G} convention), so be smart * and align the end of the partition. The next * partition will start at phy.block boundary. */ stop = align_lba_in_range(cxt, stop, start, limit) - 1; if (stop > limit) stop = limit; } } set_partition(cxt, n, 0, start, stop, sys); if (n > 4) set_partition(cxt, n - 1, 1, ptes[n].offset, stop, EXTENDED); if (IS_EXTENDED (sys)) { struct pte *pe4 = &ptes[4]; struct pte *pen = &ptes[n]; ext_index = n; pen->ext_pointer = p; pe4->offset = extended_offset = start; pe4->sectorbuffer = xcalloc(1, cxt->sector_size); pe4->part_table = pt_offset(pe4->sectorbuffer, 0); pe4->ext_pointer = pe4->part_table + 1; pe4->changed = 1; partitions = 5; } }
static void read_extended(struct fdisk_context *cxt, int ext) { int i; struct pte *pex; struct partition *p, *q; ext_index = ext; pex = &ptes[ext]; pex->ext_pointer = pex->part_table; p = pex->part_table; if (!get_start_sect(p)) { fprintf(stderr, _("Bad offset in primary extended partition\n")); return; } while (IS_EXTENDED (p->sys_ind)) { struct pte *pe = &ptes[partitions]; if (partitions >= MAXIMUM_PARTS) { /* This is not a Linux restriction, but this program uses arrays of size MAXIMUM_PARTS. Do not try to `improve' this test. */ struct pte *pre = &ptes[partitions-1]; fprintf(stderr, _("Warning: omitting partitions after #%d.\n" "They will be deleted " "if you save this partition table.\n"), partitions); clear_partition(pre->ext_pointer); pre->changed = 1; return; } read_pte(cxt, partitions, extended_offset + get_start_sect(p)); if (!extended_offset) extended_offset = get_start_sect(p); q = p = pt_offset(pe->sectorbuffer, 0); for (i = 0; i < 4; i++, p++) if (get_nr_sects(p)) { if (IS_EXTENDED (p->sys_ind)) { if (pe->ext_pointer) fprintf(stderr, _("Warning: extra link " "pointer in partition table" " %d\n"), partitions + 1); else pe->ext_pointer = p; } else if (p->sys_ind) { if (pe->part_table) fprintf(stderr, _("Warning: ignoring extra " "data in partition table" " %d\n"), partitions + 1); else pe->part_table = p; } } /* very strange code here... */ if (!pe->part_table) { if (q != pe->ext_pointer) pe->part_table = q; else pe->part_table = q + 1; } if (!pe->ext_pointer) { if (q != pe->part_table) pe->ext_pointer = q; else pe->ext_pointer = q + 1; } p = pe->ext_pointer; partitions++; } /* remove empty links */ remove: for (i = 4; i < partitions; i++) { struct pte *pe = &ptes[i]; if (!get_nr_sects(pe->part_table) && (partitions > 5 || ptes[4].part_table->sys_ind)) { printf(_("omitting empty partition (%d)\n"), i+1); dos_delete_partition(i); goto remove; /* numbering changed */ } } }
static u_int ieee802_11_radio_print(const u_char *p, u_int length, u_int caplen) { #define BITNO_32(x) (((x) >> 16) ? 16 + BITNO_16((x) >> 16) : BITNO_16((x))) #define BITNO_16(x) (((x) >> 8) ? 8 + BITNO_8((x) >> 8) : BITNO_8((x))) #define BITNO_8(x) (((x) >> 4) ? 4 + BITNO_4((x) >> 4) : BITNO_4((x))) #define BITNO_4(x) (((x) >> 2) ? 2 + BITNO_2((x) >> 2) : BITNO_2((x))) #define BITNO_2(x) (((x) & 2) ? 1 : 0) #define BIT(n) (1 << n) #define IS_EXTENDED(__p) \ (EXTRACT_LE_32BITS(__p) & BIT(IEEE80211_RADIOTAP_EXT)) != 0 struct cpack_state cpacker; struct ieee80211_radiotap_header *hdr; u_int32_t present, next_present; u_int32_t *presentp, *last_presentp; enum ieee80211_radiotap_type bit; int bit0; const u_char *iter; u_int len; int pad; if (caplen < sizeof(*hdr)) { printf("[|802.11]"); return caplen; } hdr = (struct ieee80211_radiotap_header *)p; len = EXTRACT_LE_16BITS(&hdr->it_len); if (caplen < len) { printf("[|802.11]"); return caplen; } for (last_presentp = &hdr->it_present; IS_EXTENDED(last_presentp) && (u_char*)(last_presentp + 1) <= p + len; last_presentp++); /* are there more bitmap extensions than bytes in header? */ if (IS_EXTENDED(last_presentp)) { printf("[|802.11]"); return caplen; } iter = (u_char*)(last_presentp + 1); if (cpack_init(&cpacker, (u_int8_t*)iter, len - (iter - p)) != 0) { /* XXX */ printf("[|802.11]"); return caplen; } /* Assume no Atheros padding between 802.11 header and body */ pad = 0; for (bit0 = 0, presentp = &hdr->it_present; presentp <= last_presentp; presentp++, bit0 += 32) { for (present = EXTRACT_LE_32BITS(presentp); present; present = next_present) { /* clear the least significant bit that is set */ next_present = present & (present - 1); /* extract the least significant bit that is set */ bit = (enum ieee80211_radiotap_type) (bit0 + BITNO_32(present ^ next_present)); if (print_radiotap_field(&cpacker, bit, &pad) != 0) goto out; } } out: return len + ieee802_11_print(p + len, length - len, caplen - len, pad); #undef BITNO_32 #undef BITNO_16 #undef BITNO_8 #undef BITNO_4 #undef BITNO_2 #undef BIT }