📄 part.c
字号:
if (device < 0) { /* No device open? Then try to read first. */ event('r', op); if (device < 0) return; } near= op; dist= -1; for (op2= world; op2 != nil; op2= op2->next) { if (op2 == op || !(op2->flags & OF_MOD)) continue; dr= abs(op2->row - op->row); dc= abs(op2->col - op->col); d2= 25*dr*dr + dc*dc; if (op2->row != op->row && op2->col != op->col) d2+= 1000; switch (ev) { case 'h': /* Left */ if (op2->col >= op->col) d2= -1; break; case 'j': /* Down */ if (op2->row <= op->row) d2= -1; break; case 'k': /* Up */ if (op2->row >= op->row) d2= -1; break; case 'l': /* Right */ if (op2->col <= op->col) d2= -1; break; case 'H': /* Home */ if (op2->type == O_DEV) d2= 0; } if (d2 < dist) { near= op2; dist= d2; } } if (near != op) event(E_LEAVE, op); event(E_ENTER, near);}void m_updown(int ev, object_t *op)/* Move a partition table entry up or down. */{ int i, j; struct part_entry tmp; int tmpx; if (ev != ctrl('K') && ev != ctrl('J')) return; if (op->entry == nil) return; i= op->entry - table; if (ev == ctrl('K')) { if (i <= 1) return; j= i-1; } else { if (i >= NR_PARTITIONS) return; j= i+1; } tmp= table[i]; table[i]= table[j]; table[j]= tmp; tmpx= existing[i]; existing[i]= existing[j]; existing[j]= tmpx; sort(); dirty= 1; event(ev == ctrl('K') ? 'k' : 'j', op);}void m_enter(int ev, object_t *op)/* We've moved onto this object. */{ if (ev != E_ENTER && ev != ' ' && ev != '<' && ev != '>' && ev != 'X') return; curobj= op; typing= 0; magic= 0;}void m_leave(int ev, object_t *op)/* About to leave this object. */{ if (ev != E_LEAVE) return;}int within(unsigned *var, unsigned low, unsigned value, unsigned high)/* Only set *var to value if it looks reasonable. */{ if (low <= value && value <= high) { *var= value; return 1; } else return 0;}int lwithin(unsigned long *var, unsigned long low, unsigned long value, unsigned long high){ if (low <= value && value <= high) { *var= value; return 1; } else return 0;}int nextdevice(object_t *op, int delta)/* Select the next or previous device from the device list. */{ dev_t rdev; if (offset != 0) return 0; if (dirty) event(E_WRITE, op); if (dirty) return 0; if (device >= 0) { (void) close(device); device= -1; } recompute0(); rdev= curdev->rdev; if (delta < 0) { do curdev= curdev->prev; while (delta < -1 && major(curdev->rdev) == major(rdev) && curdev->rdev < rdev); } else { do curdev= curdev->next; while (delta > 1 && major(curdev->rdev) == major(rdev) && curdev->rdev > rdev); } return 1;}void check_ind(struct part_entry *pe)/* If there are no other partitions then make this new one active. */{ struct part_entry *pe2; if (pe->sysind != NO_PART) return; for (pe2= table + 1; pe2 < table + 1 + NR_PARTITIONS; pe2++) if (pe2->sysind != NO_PART || pe2->bootind & ACTIVE_FLAG) break; if (pe2 == table + 1 + NR_PARTITIONS) pe->bootind= ACTIVE_FLAG;}int check_existing(struct part_entry *pe)/* Check and if not ask if an existing partition may be modified. */{ static int expert= 0; int c; if (expert || pe == nil || !existing[pe - table]) return 1; stat_start(1); putstr("Do you wish to modify existing partitions? (y/n) "); fflush(stdout); while ((c= getchar()) != 'y' && c != 'n') {} putchr(c); stat_end(3); return (expert= (c == 'y'));}void m_modify(int ev, object_t *op)/* Increment, decrement, set, or toggle the value of an object, using * arithmetic tricks the author doesn't understand either. */{ object_t *op2; struct part_entry *pe= op->entry; int mul, delta; unsigned level= 1; unsigned long surplus; int radix= op->type == O_TYPHEX ? 0x10 : 10; unsigned long t; if (device < 0 && op->type != O_DEV) return; switch (ev) { case '-': mul= radix; delta= -1; typing= 0; break; case '+': mul= radix; delta= 1; typing= 0; break; case '\b': if (!typing) return; mul= 1; delta= 0; break; case '\r': typing= 0; return; default: if ('0' <= ev && ev <= '9') delta= ev - '0'; else if (radix == 0x10 && 'a' <= ev && ev <= 'f') delta= ev - 'a' + 10; else if (radix == 0x10 && 'A' <= ev && ev <= 'F') delta= ev - 'A' + 10; else return; mul= typing ? radix*radix : 0; typing= 1; } magic= 0; if (!check_existing(pe)) return; switch (op->type) { case O_DEV: if (ev != '-' && ev != '+') return; if (!nextdevice(op, delta)) return; break; case O_CYL: if (!within(&cylinders, 1, cylinders * mul / radix + delta, 1024)) return; recompute0(); break; case O_HEAD: if (!within(&heads, 1, heads * mul / radix + delta, 255)) return; recompute0(); break; case O_SEC: if (!within(§ors, 1, sectors * mul / radix + delta, 63)) return; recompute0(); break; case O_NUM: if (ev != '-' && ev != '+') return; for (op2= world; op2 != nil; op2= op2->next) { if (op2->type == O_NUM && ev == '+') op2->entry->bootind= 0; } op->entry->bootind= ev == '+' ? ACTIVE_FLAG : 0; break; case O_TYPHEX: check_ind(pe); pe->sysind= pe->sysind * mul / radix + delta; break; case O_TYPTXT: if (ev != '-' && ev != '+') return; check_ind(pe); pe->sysind= round_sysind(pe->sysind, delta); break; case O_SCYL: level= heads; case O_SHEAD: level*= sectors; case O_SSEC: if (op->type != O_SCYL && ev != '-' && ev != '+') return; case O_BASE: if (pe->sysind == NO_PART) memset(pe, 0, sizeof(*pe)); t= pe->lowsec; surplus= t % level; if (!lwithin(&t, 0L, (t / level * mul / radix + delta) * level + surplus, MAXSIZE)) return; if (howend == LAST || op->type != O_BASE) pe->size-= t - pe->lowsec; pe->lowsec= t; check_ind(pe); if (pe->sysind == NO_PART) pe->sysind= MINIX_PART; break; case O_LCYL: level= heads; case O_LHEAD: level*= sectors; case O_LSEC: if (op->type != O_LCYL && ev != '-' && ev != '+') return; if (pe->sysind == NO_PART) memset(pe, 0, sizeof(*pe)); t= pe->lowsec + pe->size - 1 + level; surplus= t % level - mul / radix * level; if (!lwithin(&t, 0L, (t / level * mul / radix + delta) * level + surplus, MAXSIZE)) return; pe->size= t - pe->lowsec + 1; check_ind(pe); if (pe->sysind == NO_PART) pe->sysind= MINIX_PART; break; case O_KB: level= 2; if (mul == 0) pe->size= 0; /* new value, no surplus */ case O_SIZE: if (pe->sysind == NO_PART) { if (op->type == O_KB || howend == SIZE) { /* First let loose magic to set the base. */ event('m', op); magic= 0; pe->size= 0; event(ev, op); return; } memset(pe, 0, sizeof(*pe)); } t= (op->type == O_KB || howend == SIZE) ? pe->size : pe->lowsec + pe->size - 1; surplus= t % level; if (!lwithin(&t, 0L, (t / level * mul / radix + delta) * level + surplus, MAXSIZE)) return; pe->size= (op->type == O_KB || howend == SIZE) ? t : t - pe->lowsec + 1; check_ind(pe); if (pe->sysind == NO_PART) pe->sysind= MINIX_PART; break; default: return; } /* The order among the entries may have changed. */ sort(); dirty= 1;}unsigned long spell[3 + 4 * (1+NR_PARTITIONS)];int nspells;objtype_t touching;void newspell(unsigned long charm)/* Add a new spell, descending order for the base, ascending for the size. */{ int i, j; if (charm - table[0].lowsec > table[0].size) return; for (i= 0; i < nspells; i++) { if (charm == spell[i]) return; /* duplicate */ if (touching == O_BASE) { if (charm == table[0].lowsec + table[0].size) return; if ((spell[0] - charm) < (spell[0] - spell[i])) break; } else { if (charm == table[0].lowsec) return; if ((charm - spell[0]) < (spell[i] - spell[0])) break; } } for (j= ++nspells; j > i; j--) spell[j]= spell[j-1]; spell[i]= charm;}void m_magic(int ev, object_t *op)/* Apply magic onto a base or size number. */{ struct part_entry *pe= op->entry, *pe2; int rough= (offset != 0 && extbase == 0); if (ev != 'm' || device < 0) return; typing= 0; if (!check_existing(pe)) return; if (magic == 0) { /* See what magic we can let loose on this value. */ nspells= 1; /* First spell, the current value. */ switch (op->type) { case O_SCYL: case O_SHEAD: /* Start of partition. */ case O_SSEC: case O_BASE: touching= O_BASE; spell[0]= pe->lowsec; break; case O_LCYL: case O_LHEAD: case O_LSEC: /* End of partition. */ case O_KB: case O_SIZE: touching= O_SIZE; spell[0]= pe->lowsec + pe->size; break; default: return; } if (pe->sysind == NO_PART) { memset(pe, 0, sizeof(*pe)); check_ind(pe); pe->sysind= MINIX_PART; spell[0]= 0; if (touching == O_SIZE) { /* First let loose magic on the base. */ object_t *op2; for (op2= world; op2 != nil; op2= op2->next) { if (op2->row == op->row && op2->type == O_BASE) { event('m', op2); } } magic= 0; event('m', op); return; } } /* Avoid the first sector on the device. */ if (spell[0] == table[0].lowsec) newspell(spell[0] + 1); /* Further interesting values are the the bases of other * partitions or their ends. */ for (pe2= table; pe2 < table + 1 + NR_PARTITIONS; pe2++) { if (pe2 == pe || pe2->sysind == NO_PART) continue; if (pe2->lowsec == table[0].lowsec) newspell(table[0].lowsec + 1); else newspell(pe2->lowsec); newspell(pe2->lowsec + pe2->size); if (touching == O_BASE && howend == SIZE) { newspell(pe2->lowsec - pe->size); newspell(pe2->lowsec + pe2->size - pe->size); } if (pe2->lowsec % sectors != 0) rough= 1; } /* Present values rounded up to the next cylinder unless * the table is already a mess. Use "start + 1 track" instead * of "start + 1 cylinder". Also add the end of the last * cylinder. */ if (!rough) { unsigned long n= spell[0]; if (n == table[0].lowsec) n++; n= (n + sectors - 1) / sectors * sectors; if (n != table[0].lowsec + sectors) n= (n + secpcyl - 1) / secpcyl * secpcyl; newspell(n); if (touching == O_SIZE) newspell(table[0].size / secpcyl * secpcyl); } } /* Magic has been applied, a spell needs to be chosen. */ if (++magic == nspells) magic= 0; if (touching == O_BASE) { if (howend == LAST) pe->size-= spell[magic] - pe->lowsec; pe->lowsec= spell[magic]; } else pe->size= spell[magic] - pe->lowsec; /* The order among the entries may have changed. */ sort(); dirty= 1;}typedef struct diving { struct diving *up; struct part_entry old0; char *oldsubname; char oldpart[6]; parttype_t oldparttype; unsigned long oldoffset; unsigned long oldextbase;} diving_t;diving_t *diving= nil;void m_in(int ev, object_t *op)/* Go down into a primary or extended partition. */{ diving_t *newdiv; struct part_entry *pe= op->entry, ext; int n; if (ev != '>' || device < 0 || pe == nil || pe == &table[0] || (!(pe->sysind == MINIX_PART && offset == 0) && pe->sysind != EXT_PART) || pe->size == 0) return; ext= *pe; if (extbase != 0) ext.size= extbase + extsize - ext.lowsec; if (dirty) event(E_WRITE, op); if (dirty) return; if (device >= 0) { close(device); device= -1; } newdiv= alloc(sizeof(*newdiv)); newdiv->old0= table[0]; newdiv->oldsubname= curdev->subname; strcpy(newdiv->oldpart, curdev->part); newdiv->oldparttype= curdev->parttype; newdiv->oldoffset= offset; newdiv->oldextbase= extbase; newdiv->up= diving; diving= newdiv; table[0]= ext; n= strlen(diving->oldsubname); curdev->subname= alloc((n + 3) * sizeof(curdev->subname[0])); strcpy(curdev->subname, diving->oldsubname); curdev->subname[n++]= ':'; curdev->subname[n++]= '0' + (pe - table); curdev->subname[n]= 0; if (curdev->parttype != DUNNO) curdev->parttype--; offset= ext.lowsec; if (ext.sysind == EXT_PART && extbase == 0) { extbase= ext.lowsec; extsize= ext.size; curdev->parttype= DUNNO; } if (curdev->parttype == SUBPART) { n= strlen(curdev->part); if (n == 5) { strcpy(curdev->part, curdev->part + 1); n--; } curdev->part[n-1] += sort_index[pe - table]; } submerged= 1; event('r', op);}void m_out(int ev, object_t *op)/* Go up from an extended or subpartition table to its enclosing. */{ diving_t *olddiv;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -