/* ------------------------------ $Id: vm-skel.c,v 1.1 2002/10/21 07:16:29 marquet Exp $ ------------------------------------------------------------ Volume manager skeleton. Philippe Marquet, october 2002 1- you must complete the NYI (not yet implemented) functions 2- you may add commands (format, etc.) */ #include #include #include #include #include #include /* * MBR */ struct mbr_desc_t mbr; /* ------------------------------ command list ------------------------------------------------------------*/ struct _cmd { char *name; void (*fun) (struct _cmd *c); char *comment; }; static void list(struct _cmd *c); static void new(struct _cmd *c); static void del(struct _cmd *c); static void help(struct _cmd *c) ; static void save(struct _cmd *c); static void quit(struct _cmd *c); static void xit(struct _cmd *c); static void none(struct _cmd *c) ; static struct _cmd commands [] = { {"list", list, "display the partition table"}, {"new", new, "create a new partition"}, {"del", del, "delete a partition"}, {"save", save, "save the MBR"}, {"quit", quit, "save the MBR and quit"}, {"exit", xit, "exit (without saving)"}, {"help", help, "display this help"}, {0, none, "unknown command, try help"} } ; /* ------------------------------ dialog and execute ------------------------------------------------------------*/ static void execute(const char *name) { struct _cmd *c = commands; while (c->name && strcmp (name, c->name)) c++; (*c->fun)(c); } static void loop(void) { char name[64]; while (printf("> "), scanf("%62s", name) == 1) execute(name) ; } /* ------------------------------ command execution ------------------------------------------------------------*/ static void list(struct _cmd *c) { struct dskinfo_t info = dskinfo(); uint16_t sec=1, cyl=0; int partno=0, volid=0; printf("Part#\tCyl#\tSec#\tSize\tType\n"); while ( (cyl < info.nb_cyl) && (sec < info.nb_sec) ) { /* Afficher les espaces libres */ int next_cyl=0; int next_sec=0; int freesize=0; if ( volid == mbr.vol_count ) { next_cyl = info.nb_cyl; next_sec = info.nb_sec; } else { next_cyl = mbr.volume[volid].num_cyl; next_sec = mbr.volume[volid].num_sec; } /* Calculer l'espace libre */ freesize = (next_cyl - cyl) * info.nb_sec - sec + next_sec; if ( freesize > 0 ) { printf("--\t%u\t%u\t%u\tFree Space\n", cyl, sec, freesize); cyl = next_cyl; sec = next_sec; //partno++; } /* S'il y a encore des partitions */ if ( volid < mbr.vol_count ) { printf("hd%u\t%u\t%u\t%u\t", partno, mbr.volume[volid].num_cyl, mbr.volume[volid].num_sec, mbr.volume[volid].size); switch( mbr.volume[volid].vol_type ) { case VOLT_BASE: printf("Base\n"); break; case VOLT_ANNEX: printf("Annex\n"); break; case VOLT_OTHER: printf("Other\n"); break; default: printf("Unrecognized volume type !\n"); } cyl = cylinder_of_block(volid, mbr.volume[volid].size); sec = sector_of_block(volid, mbr.volume[volid].size); partno++; volid++; } } } static void new(struct _cmd *c) { unsigned int cyl, sect, size; printf("Cylindre : "); scanf("%u", &cyl); printf("Secteur : "); scanf("%u", §); printf("Taille (en blocs) : "); scanf("%u", &size); if ( cyl < 0 || sect < 0 || size < 1 ) { printf("Erreur de données.\n"); return; } if ( cyl == 0 && sect == 0 ) { printf("La partition doit démarrer à (0, 1) au minimum\n"); return; } struct vol_desc_t newvol; newvol.magic_key = VOLUME_MAGIC; newvol.num_cyl = cyl; newvol.num_sec = sect; newvol.size = size; newvol.vol_type = VOLT_BASE; mbr.volume[mbr.vol_count++] = newvol; } static void del(struct _cmd *c) { int delno; printf("Numero de partition : "); scanf("%u", &delno); if ( delno < mbr.vol_count ) { int i; for(i=delno; i<(mbr.vol_count-1); i++) { mbr.volume[i] = mbr.volume[i+1]; } mbr.vol_count--; printf("Parition supprimée\n"); } else printf("Parition inexistante\n"); } static void save(struct _cmd *c) { save_mbr(&mbr); printf("MBR Sauvé\n"); } static void quit(struct _cmd *c) { save_mbr(&mbr); printf("MBR Sauvé\n"); exit(EXIT_SUCCESS); } static void do_xit() { exit(EXIT_SUCCESS); } static void xit(struct _cmd *dummy) { do_xit(); } static void help(struct _cmd *dummy) { struct _cmd *c = commands; for (; c->name; c++) printf ("%s\t-- %s\n", c->name, c->comment); } static void none(struct _cmd *c) { printf ("%s\n", c->comment) ; } static void emptyIT() { return; } int main(int argc, char **argv) { int i; /* init hardware */ if( initHardware("hardware.ini") == 0 ) { fprintf(stderr, "Error in hardware initialization\n"); exit(EXIT_FAILURE); } /* Interreupt handlers */ for(i=0; i<16; i++) IRQVECTOR[i] = emptyIT; /* Allows all IT */ _mask(1); if ( load_mbr(&mbr) == MBR_FAILURE ) printf("Attention, le MBR était corrompu, un nouveau a été créé pour vous.\n"); /* dialog with user */ loop(); /* abnormal end of dialog (cause EOF for xample) */ do_xit(); /* make gcc -W happy */ exit(EXIT_SUCCESS); }