408 lines
12 KiB
C
408 lines
12 KiB
C
/*
|
|
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 <asimovi@teleline.es>
|
|
Esteve Fernández < esteve@crosswinds.net >
|
|
Jaime Villate <villate@fe.up.pt>
|
|
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->start<p->end){
|
|
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;
|
|
}
|