/* nparted - a frontend to libparted for manipulating disk partitions thinked to dbootstrap Copyright (C) 1998-2000 Mario Teijeiro Otero Esteve Fernández Jaime Villate La Espiral Mario Teijeiro Otero Esteve Fernández < esteve@crosswinds.net > Jaime Villate La Espiral http://www.laespiral.org This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "nparted.h" int do_list_free (PedDevice *dev, newtComponent free_list) { PedDisk *disk; PedPartition *part; strech *list_strech,*p,*new,*extend,*walk; disk=ped_disk_open(dev); if(!disk) goto error; part=NULL; p=list_strech=extend=NULL; while ( (part=ped_disk_next_partition(disk,part))!=NULL){ if(part->type==PED_PARTITION_FREESPACE){ #ifdef DEBUG_NPARTED sprintf(ptrb,"mirando particion free (%Ld,%Ld) ", part->geom.start,part->geom.end); ped_exception_throw(PED_EXCEPTION_ERROR, PED_EXCEPTION_OK, ptrb); ped_exception_catch(); #endif if ( part->geom.start==part->geom.end) continue; new=(strech*)NP_malloc(sizeof(strech)); new->start=part->geom.start; new->end=part->geom.end; new->next=NULL; if(list_strech==NULL){ list_strech=new; p=new; }else{ p->next=new; p=new; } } /* esto ya es un poco más chungo,hay que sacar a pelo los trozos * libres elinando del pedazo de la particion extendida los trozos * que ya son particiones lógicas*/ if(part->type==PED_PARTITION_EXTENDED &&part->num!=-1){ if (extend!=NULL){ ped_exception_throw(PED_EXCEPTION_ERROR, PED_EXCEPTION_OK, _("Can't have two parts extended in one disk")); ped_exception_catch(); goto error_disk_close; } extend=(strech*)NP_malloc(sizeof(strech)); extend->start=part->geom.start+63;/*Por ser extendida los primeros 63 sectores son ocupados*/ extend->end=part->geom.end; extend->next=NULL; if(list_strech==NULL){ list_strech=extend; p=extend; }else{ p->next=extend; p=extend; } } /* Eliminamos estos trozos de la particion extendida, primero buscamos * el trozo al cual pertencemos y lo dividimos en dos( antes y despues * de la partición lógica, suponemos que libparted nos las da ordenadas*/ if(part->type==PED_PARTITION_LOGICAL){ walk=extend; while (walk!=NULL){ #ifdef DEBUG_NPARTED sprintf(ptrb,"miando si (%Ld,%Ld) está dentro de (%Ld,%Ld)", part->geom.start,part->geom.end,walk->start,walk->end); ped_exception_throw(PED_EXCEPTION_ERROR, PED_EXCEPTION_OK, ptrb); ped_exception_catch(); #endif if (BETWEEN(part->geom.start,walk->start,walk->end) ){ #ifdef DEBUG_NPARTED ped_exception_throw(PED_EXCEPTION_ERROR, PED_EXCEPTION_OK, "Si estaba"); ped_exception_catch(); #endif new=(strech*)NP_malloc(sizeof(strech)); new->start=part->geom.end+64; new->end=walk->end; walk->end=part->geom.start-1; /* introucimos en la lista general */ new->next=walk->next; walk->next=new; if(new->next==NULL) p=new; break; } walk=walk->next; } } } p=list_strech; while(p){ if(p->startend){ sprintf(ptrb,"%Ld<=>%Ld",SEC2CIL(dev,p->start),SEC2CIL(dev,p->end)); newtListboxAppendEntry(free_list,ptrb,p); } new =p; p=p->next; } /* Ya tenemos en list_strech la lista de todos los huecos libres */ ped_disk_close(disk); return 1; error_disk_close: ped_disk_close(disk); error: return 0; } static int grow_strech(PedDevice *dev,strech *tramo){ PedPartition *part; PedDisk *disk=ped_disk_open(dev); disk=ped_disk_open(dev); if(!disk) goto error; part=NULL; part=ped_disk_get_partition_by_sector(disk, tramo->start); if (part!=NULL){ tramo->end=part->geom.end; ped_disk_close(disk); return 1; } ped_disk_close(disk); return 0; error: return 0; } static int check_strech(PedDevice *dev, strech *tramo){ PedPartition *part; PedDisk *disk; disk=ped_disk_open(dev); if(!disk) goto error; part=NULL; part=ped_disk_get_partition_by_sector(disk, tramo->start); if (part==NULL) goto error_close_disk; if (part->type!=PED_PARTITION_LOGICAL&&part->type!=PED_PARTITION_PRIMARY){ part=ped_disk_get_partition_by_sector(disk, tramo->end); if (part->type!=PED_PARTITION_LOGICAL&&part->type!=PED_PARTITION_PRIMARY){ ped_disk_close(disk); return 1; } } error_close_disk: ped_disk_close(disk); return 0; error: return 0; } int add_partition ( PedDevice *dev ){ newtComponent form,grow,inicio,fin, tam,fs,sel_fs,free_list,ok,cancel,ans,dofs,sel_ptype,ptype; char fs_type[20]; PedSector tamano; strech *ptramo,*tramo,p; char part_type; int ret,salir=0; /* ******************************************************************** * * INTERFAZ * * ******************************************************************** */ tramo=&p; sprintf(ptrb,_("Adding a part to %s"),dev->path); newtCenteredWindow(mainwin_size.width, mainwin_size.height, ptrb); form=newtForm(NULL,NULL,0); free_list=newtListbox(5,3,10,NEWT_FLAG_SCROLL|NEWT_FLAG_RETURNEXIT); newtListboxSetWidth(free_list,27); do_list_free(dev, free_list); grow=newtCheckbox(mainwin_size.width-42,2,_("Growable"),' ',NULL,NULL); dofs=newtCheckbox(mainwin_size.width-42,4,_("Do fyle sistem"),' ',NULL,NULL); sel_ptype=newtCompactButton(mainwin_size.width-42,8,_("Select partition type")); ptype=newtLabel(mainwin_size.width-15,8,"Primary"); part_type='p'; inicio=newtEntry(mainwin_size.width-15,2,NULL,10,NULL,NEWT_ENTRY_SCROLL |NEWT_FLAG_RETURNEXIT); fin=newtEntry(mainwin_size.width-15,4,NULL,10,NULL,NEWT_ENTRY_SCROLL |NEWT_FLAG_RETURNEXIT); tam=newtEntry(mainwin_size.width-15,6,NULL,10,NULL,NEWT_ENTRY_SCROLL |NEWT_FLAG_RETURNEXIT); sel_fs=newtCompactButton(mainwin_size.width-42,10,_("Select file system")); fs=newtLabel(mainwin_size.width-15,10,"ext2"); ok=newtButton(5,16,_("Create")); cancel=newtButton(mainwin_size.width-30,16,_("Cancel")); newtFormAddComponents(form, free_list, newtLabel(6,2,_("free strechs")), grow,dofs, inicio, newtLabel(mainwin_size.width-23,2,_("Start")), newtLabel(mainwin_size.width-5,2,_(" Cil.")), fin, newtLabel(mainwin_size.width-23,4,_("End")), newtLabel(mainwin_size.width-5,4,_(" Cil.")), newtLabel(mainwin_size.width-5,4,_(" Cil.")), tam, newtLabel(mainwin_size.width-23,6,_("Size")), newtLabel(mainwin_size.width-5,6,_(" Mb")), fs,sel_fs,ok,cancel,sel_ptype,ptype,NULL); strcpy(fs_type,"ext2"); /* ************************************************************ * * PROCESS * * ************************************************************ */ do{ ans=newtRunForm(form); if(ans==sel_ptype){ part_type=select_partition_type(); switch (part_type){ case 'p': newtLabelSetText(ptype,_("Primary")); break; case 'e': newtLabelSetText(ptype,_("Extend")); break; case 'l': newtLabelSetText(ptype,_("Logic")); break; } } if(ans==sel_fs){ char *aux; aux=select_file_system(); if(aux!=NULL){ strcpy(fs_type,aux); newtLabelSetText(fs,fs_type); } } if(ans==ok){ tramo->start=is_sector_valid(newtEntryGetValue(inicio)); tramo->end=is_sector_valid(newtEntryGetValue(fin)); if (tramo->start==-1||tramo->end==-1){ ped_exception_throw(PED_EXCEPTION_ERROR, PED_EXCEPTION_OK, _("a number is needed")); ped_exception_catch(); newtEntrySet(fin,"",1); newtEntrySet(inicio,"",1); newtEntrySet(tam,"",1); continue; } tramo->start=CIL2SEC(dev,tramo->start); if (tramo->start<64) tramo->start=64; tramo->end=CIL2SEC(dev,tramo->end+1)-1; /* No nos podemos ir fuera del disco */ if (tramo->end>=dev->length-1) tramo->end=dev->length-1; if (newtCheckboxGetValue(grow)=='*'){ grow_strech(dev,tramo); } /* Miramos si el tramo pedido está disponible */ if(!check_strech(dev,tramo)){ ped_exception_throw(PED_EXCEPTION_ERROR, PED_EXCEPTION_OK, _("Out limits")); ped_exception_catch(); newtEntrySet(fin,"",1); newtEntrySet(inicio,"",1); newtEntrySet(tam,"",1); continue; } if (part_type=='e'&& newtCheckboxGetValue(dofs)=='*'){ ped_exception_throw(PED_EXCEPTION_ERROR, PED_EXCEPTION_OK, _("I can't do filesystem on a extended partition")); ped_exception_catch(); continue; } /* Pedimos confirmacion*/ sprintf(ptrb,_("Are you sure create in %s a %c partition of type %s from %Ld to %Ld?") ,dev->path,part_type,fs_type,tramo->start, tramo->end); if(ped_exception_throw(PED_EXCEPTION_INFORMATION, PED_EXCEPTION_YES|PED_EXCEPTION_NO, ptrb)==PED_EXCEPTION_NO){ ped_exception_catch(); continue; } /*Creamos la partición */ if (newtCheckboxGetValue(dofs)=='*'){ ret=do_mkpartfs(&dev,part_type,fs_type, tramo->start, tramo->end); if (!ret) goto error; salir=1; } else{ ret=do_mkpart(&dev,part_type,fs_type, tramo->start, tramo->end); if (!ret) goto error; salir=1; } } if(ans==cancel){ salir=1; } if(ans==free_list){ ptramo=newtListboxGetCurrent(free_list); sprintf(ptrb,"%Ld",SEC2CIL(dev,ptramo->start)); newtEntrySet(inicio,ptrb,1); sprintf(ptrb,"%Ld",SEC2CIL(dev,ptramo->end)); newtEntrySet(fin,ptrb,1); sprintf(ptrb,"%d", (int)SEC2MB(ptramo->end - ptramo->start+1)); newtEntrySet(tam,ptrb,1); } if(ans==inicio||ans==fin){ tramo->start=is_sector_valid(newtEntryGetValue(inicio)); tramo->end=is_sector_valid(newtEntryGetValue(fin)); if (tramo->start==-1||tramo->end==-1){ ped_exception_throw(PED_EXCEPTION_ERROR, PED_EXCEPTION_OK, _("a number is needed")); ped_exception_catch(); newtEntrySet(fin,"",1); newtEntrySet(inicio,"",1); newtEntrySet(tam,"",1); }else{ tramo->start=CIL2SEC(dev,tramo->start); if (tramo->start<64) tramo->start=64; tramo->end=CIL2SEC(dev,tramo->end+1)-1; if(!check_strech(dev,tramo)){ ped_exception_throw(PED_EXCEPTION_ERROR, PED_EXCEPTION_OK, _("Out limits")); ped_exception_catch(); newtEntrySet(fin,"",1); newtEntrySet(inicio,"",1); newtEntrySet(tam,"",1); }else{ sprintf(ptrb,"%d", (int)SEC2MB((tramo->end-tramo->start+1))); newtEntrySet(tam,ptrb,1); } } } if(ans==tam){ tramo->start=is_sector_valid(newtEntryGetValue(inicio)); tamano=is_sector_valid(newtEntryGetValue(tam)); if (tramo->start==-1|| tamano==-1){ ped_exception_throw(PED_EXCEPTION_ERROR, PED_EXCEPTION_OK, _("a number is needed")); ped_exception_catch(); }else{ tramo->start=CIL2SEC(dev,tramo->start); if (tramo->start<64) tramo->start=64; tramo->end=MB2SEC(tamano)+tramo->start; if(!check_strech(dev,tramo)){ ped_exception_throw(PED_EXCEPTION_ERROR, PED_EXCEPTION_OK, _("Out limits")); ped_exception_catch(); newtEntrySet(fin,"",1); newtEntrySet(inicio,"",1); newtEntrySet(tam,"",1); }else{ sprintf(ptrb,"%d", (int)SEC2CIL(dev,tramo->end)); newtEntrySet(fin,ptrb,1); } } } newtListboxClear(free_list); do_list_free(dev, free_list); }while(!salir); error: newtFormDestroy(form); newtPopWindow(); return 0; }