📄 fdisk.c
字号:
// Check for window close events if ((windowComponentEventGet(createDialog, &event) > 0) && (event.type == EVENT_WINDOW_CLOSE)) { windowDestroy(createDialog); return; } // Check for keyboard events if ((windowComponentEventGet(startCylField, &event) > 0) && (event.type == EVENT_KEY_DOWN) && (event.key == (unsigned char) 10)) break; if ((windowComponentEventGet(endCylField, &event) > 0) && (event.type == EVENT_KEY_DOWN) && (event.key == (unsigned char) 10)) break; // Done multitaskerYield(); } type = queryPrimaryLogical(primLogRadio); if (type == partition_none) return; windowComponentGetData(startCylField, startCyl, 10); windowComponentGetData(endCylField, endCyl, 10); windowDestroy(createDialog); } else { if (type == partition_any) { // Does the user prefer primary or logical? type = queryPrimaryLogical(NULL); if (type == partition_none) return; } else printf("\nCreating %s partition\n", ((type == partition_primary)? "primary" : "logical")); // Don't create a logical slice on the first cylinder if ((type == partition_logical) && (minStartCylinder == 0)) minStartCylinder = 1; printf("\n"STARTCYL_MESSAGE", or 'Q' to quit:\n-> ", minStartCylinder, maxEndCylinder); status = readLine("0123456789Qq", startCyl, 10); if (status < 0) continue; if ((startCyl[0] == 'Q') || (startCyl[0] == 'q')) return; printf("\n"ENDCYL_MESSAGE", or 'Q' to quit:\n-> ", atoi(startCyl), maxEndCylinder, cylsToMb(table->disk, (maxEndCylinder - minStartCylinder + 1)), (maxEndCylinder - minStartCylinder + 1)); status = readLine("0123456789CcMmQq", endCyl, 10); if (status < 0) return; if ((endCyl[0] == 'Q') || (endCyl[0] == 'q')) return; } startCylinder = atoi(startCyl); // Make sure the start cylinder is legit if ((startCylinder < minStartCylinder) || (startCylinder > maxEndCylinder)) { error("Invalid starting cylinder number"); continue; } count = (strlen(endCyl) - 1); if ((endCyl[count] == 'M') || (endCyl[count] == 'm')) { units = units_mb; endCyl[count] = '\0'; } else if ((endCyl[count] == 'C') || (endCyl[count] == 'c')) { units = units_cylsize; endCyl[count] = '\0'; } count = atoi(endCyl); switch (units) { case units_mb: endCylinder = (startCylinder + mbToCyls(table->disk, count) - 1); break; case units_cylsize: endCylinder = (startCylinder + count - 1); break; default: endCylinder = count; break; } if ((endCylinder < minStartCylinder) || (endCylinder > maxEndCylinder)) { error("Invalid ending cylinder number"); continue; } break; } newSliceNumber = doCreate(sliceNumber, type, startCylinder, endCylinder); if (newSliceNumber < 0) return; if (setType(newSliceNumber) < 0) // Cancelled. Remove it again. doDelete(newSliceNumber); else // The setType() will increase the 'changes pending' if it succeeded, // so we don't do it here. table->selectedSlice = newSliceNumber; return;}static int mountedCheck(slice *entry){ // If the slice is mounted, query whether to ignore, unmount, or cancel int status = 0; int choice = 0; char tmpChar[160]; disk tmpDisk; char character; if (entry->diskName[0] && (diskGet(entry->diskName, &tmpDisk) >= 0)) { if (!tmpDisk.mounted) // Not mounted return (status = 0); // Mounted. Prompt. sprintf(tmpChar, "The partition is mounted as %s. It is STRONGLY " "recommended\nthat you unmount before continuing", tmpDisk.mountPoint); if (graphics) choice = windowNewChoiceDialog(window, "Partition Is Mounted", tmpChar, (char *[]) { "Ignore", "Unmount", "Cancel" }, 3, 1); else { printf("\n%s (I)gnore/(U)nmount/(C)ancel?: ", tmpChar); textInputSetEcho(0); while(1) { character = getchar(); if ((character == 'i') || (character == 'I')) { printf("Ignore\n"); choice = 0; break; } else if ((character == 'u') || (character == 'U')) { printf("Unmount\n"); choice = 1; break; } else if ((character == 'c') || (character == 'C')) { printf("Cancel\n"); choice = 2; break; } } textInputSetEcho(1); } if (choice == 0) // Ignore return (status = 0); if ((choice < 0) || (choice == 2)) // Cancelled return (status = ERR_CANCELLED); if (choice == 1) { // Try to unmount the filesystem status = filesystemUnmount(tmpDisk.mountPoint); if (status < 0) error("Unable to unmount %s", tmpDisk.mountPoint); return (status); } } // The disk probably doesn't exist (yet). So, it obviously can't be // mounted return (status = 0);}static void format(int sliceNumber){ // Prompt, and format a slice int status = 0; slice *formatSlice = &table->slices[sliceNumber]; char *fsTypes[] = { "FAT", "EXT2", "Linux-swap", "None" }; char *fatTypes[] = { "Default", "FAT12", "FAT16", "FAT32" }; const char *chooseString = "Choose the filesystem type:"; const char *fatString = "Choose the FAT type:"; int typeNum = 0; char typeName[16]; char tmpChar[160]; if (table->changesPending) { error("A partition format cannot be undone, and it is required that\n" "you write your other changes to disk before continuing."); return; } status = mountedCheck(formatSlice); if (status < 0) return; if (graphics) { sprintf(tmpChar, "Format Partition %s", formatSlice->showSliceName); typeNum = windowNewRadioDialog(window, tmpChar, chooseString, fsTypes, 4, 0); } else typeNum = vshCursorMenu(chooseString, fsTypes, 4, 0); if (typeNum < 0) return; strncpy(typeName, fsTypes[typeNum], 16); // If the filesystem type is FAT, additionally offer to let the user // choose the subtype if (!strncasecmp(typeName, "fat", 3)) { if (graphics) typeNum = windowNewRadioDialog(window, "FAT Type", fatString, fatTypes, 4, 0); else typeNum = vshCursorMenu(fatString, fatTypes, 4, 0); if (typeNum < 0) return; strncpy(typeName, fatTypes[typeNum], 16); if (!strcasecmp(typeName, "default")) strcpy(typeName, "FAT"); } if (!strcasecmp(typeName, "none")) { sprintf(tmpChar, "Unformat partition %s? (This change cannot be " "undone)", formatSlice->showSliceName); if (!yesOrNo(tmpChar)) return; status = filesystemClobber(formatSlice->diskName); } else { sprintf(tmpChar, "Format partition %s as %s?\n(This change cannot be " "undone)", formatSlice->showSliceName, typeName); if (!yesOrNo(tmpChar)) return; // Do the format sprintf(tmpChar, "/programs/format %s -s -t %s %s", (graphics? "" : "-T"), typeName, formatSlice->diskName); status = system(tmpChar); } if (status < 0) error("Error during format"); else { sprintf(tmpChar, "Format complete"); if (graphics) windowNewInfoDialog(window, "Success", tmpChar); else { printf("%s\n", tmpChar); pause(); } } // Make the slice list makeSliceList(table); return;}static void defragment(int sliceNumber){ // Prompt, and defragment a slice int status = 0; slice *defragSlice = &table->slices[sliceNumber]; progress prog; objectKey progressDialog = NULL; char tmpChar[160]; if (table->changesPending) { error("A partition defragmentation cannot be undone, and it is " "required\nthat you write your other changes to disk before " "continuing."); return; } sprintf(tmpChar, "Defragment partition %s?\n(This change cannot be " "undone)", defragSlice->showSliceName); if (!yesOrNo(tmpChar)) return; status = mountedCheck(defragSlice); if (status < 0) return; sprintf(tmpChar, "Please use this feature with caution; it is not\n" "well tested. Continue?"); if (graphics) { if (!windowNewQueryDialog(window, "New Feature", tmpChar)) return; } else { if (!yesOrNo(tmpChar)) return; } // Do the defrag bzero((void *) &prog, sizeof(progress)); if (graphics) progressDialog = windowNewProgressDialog(window, "Defragmenting...", &prog); else vshProgressBar(&prog); status = filesystemDefragment(defragSlice->diskName, &prog); if (graphics && progressDialog) windowProgressDialogDestroy(progressDialog); else vshProgressBarDestroy(&prog); if (status < 0) error("Error during defragmentation"); else { sprintf(tmpChar, "Defragmentation complete"); if (graphics) windowNewInfoDialog(window, "Success", tmpChar); else { printf("%s\n", tmpChar); pause(); } } return;}static void hide(int sliceNumber){ if (PARTITION_TYPEID_IS_HIDDEN(table->slices[sliceNumber].raw.tag)) table->slices[sliceNumber].raw.tag -= 0x10; else if (PARTITION_TYPEID_IS_HIDEABLE(table->slices[sliceNumber].raw.tag)) table->slices[sliceNumber].raw.tag += 0x10; else return; table->changesPending += 1; // Update the slice list updateSliceList(table);}static void info(int sliceNumber){ // Print info about a slice slice *infoSlice = &table->slices[sliceNumber]; char *buff = NULL; buff = malloc(1024); if (buff == NULL) return; if (infoSlice->raw.tag) sprintf(buff, "PARTITION %s INFO:\n\nActive : %s\nType ID : %02x\n", infoSlice->showSliceName, (infoSlice->raw.flags & SLICEFLAG_BOOTABLE? "yes" : "no"), infoSlice->raw.tag); else sprintf(buff, "EMPTY SPACE INFO:\n\n"); sprintf((buff + strlen(buff)), "Starting Cyl/Hd/Sect: %u/%u/%u\nEnding " "Cyl/Hd/Sect : %u/%u/%u\nLogical start sector: %u\nLogical size: " "%u", infoSlice->raw.geom.startCylinder, infoSlice->raw.geom.startHead, infoSlice->raw.geom.startSector, infoSlice->raw.geom.endCylinder, infoSlice->raw.geom.endHead, infoSlice->raw.geom.endSector, infoSlice->raw.startLogical, infoSlice->raw.sizeLogical); if (graphics) windowNewInfoDialog(window, "Info", buff); else { printf("\n%s\n", buff); pause(); } free(buff);}static void undo(void){ // Undo changes if (table->changesPending) { // Re-scan from the original raw slices. makeSliceList(table); table->selectedSlice = 0; table->changesPending = 0; }}static void writeChanges(partitionTable *t, int confirm){ int status = 0; if (t->changesPending) { if (confirm && !yesOrNo("Committing changes to disk. Are you SURE?")) return; // Write out the partition table status = writePartitionTable(t); if (status < 0) error("Unable to write the partition table of %s.", t->disk->name); // Tell the kernel to reexamine the partition tables diskReadPartitions(t->disk->name); // Make the slice list. makeSliceList(t); }}static void formatTime(char *string, unsigned seconds){ strcpy(string, "Time remaining: "); if (seconds > 3600) sprintf((string + strlen(string)), "%d hour%s %d minute%s", (seconds / 3600), ((seconds > 7200)? "s" : ""), ((seconds % 3600) / 60), ((seconds > 120)? "s" : "")); else if (seconds > 60) sprintf((string + strlen(string)), "%d minute%s", (seconds / 60), ((seconds > 120)? "s" : "")); else sprintf((string + strlen(string)), "less than 1 minute");}static int doMove(int sliceNumber, unsigned newStartCylinder){ int status = 0; unsigned newStartLogical = 0; unsigned newEndLogical = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -