Merge lp:~psusi/ubuntu/natty/gparted/fix-dmraid into lp:ubuntu/natty/gparted

Proposed by Phillip Susi
Status: Merged
Merge reported by: Michael Terry
Merged at revision: not available
Proposed branch: lp:~psusi/ubuntu/natty/gparted/fix-dmraid
Merge into: lp:ubuntu/natty/gparted
Diff against target: 18685 lines (+7773/-5774)
16 files modified
.pc/.quilt_patches (+1/-0)
.pc/.quilt_series (+1/-0)
.pc/02_enable-libparted-dmraid-2.patch/README (+159/-0)
.pc/02_enable-libparted-dmraid-2.patch/configure.in (+203/-0)
.pc/02_enable-libparted-dmraid-2.patch/src/GParted_Core.cc (+3116/-0)
.pc/applied-patches (+1/-0)
README (+12/-4)
config.h.in (+6/-0)
configure (+3913/-5766)
configure.in (+20/-0)
debian/changelog (+9/-0)
debian/patches/02_enable-libparted-dmraid-2.patch (+293/-0)
debian/patches/series (+1/-0)
debian/rules (+1/-1)
src/Dialog_Progress.cc (+5/-1)
src/GParted_Core.cc (+32/-2)
To merge this branch: bzr merge lp:~psusi/ubuntu/natty/gparted/fix-dmraid
Reviewer Review Type Date Requested Status
Michael Terry Approve
Ubuntu branches Pending
Review via email: mp+50836@code.launchpad.net

Description of the change

Cherry pick upstream commit adding a configure option to phase out internal dmraid specific handling and leave it up to libparted, which now handles it correctly. This fixes a serious bug in natty where gparted caused duplicate devices to be created for the same partition. See bug #719129.

To post a comment you must log in.
Revision history for this message
Michael Terry (mterry) wrote :

I'm merging this, but I'm going to make a few changes:
 * Call 'update-maintainer' to update the Maintainer field of debian/control if there are Ubuntu modifications
 * Easier than keeping patches to 'configure' around is to use dh_autoreconf to generate a modified configure from a modified configure.in

Thanks for the contribution and cooperation with upstream in the bug about this!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file '.pc/.quilt_patches'
2--- .pc/.quilt_patches 1970-01-01 00:00:00 +0000
3+++ .pc/.quilt_patches 2011-02-23 00:37:58 +0000
4@@ -0,0 +1,1 @@
5+debian/patches
6
7=== added file '.pc/.quilt_series'
8--- .pc/.quilt_series 1970-01-01 00:00:00 +0000
9+++ .pc/.quilt_series 2011-02-23 00:37:58 +0000
10@@ -0,0 +1,1 @@
11+series
12
13=== added file '.pc/01_fix-desktop.patch/.timestamp'
14=== added directory '.pc/02_enable-libparted-dmraid-2.patch'
15=== added file '.pc/02_enable-libparted-dmraid-2.patch/.timestamp'
16=== added file '.pc/02_enable-libparted-dmraid-2.patch/README'
17--- .pc/02_enable-libparted-dmraid-2.patch/README 1970-01-01 00:00:00 +0000
18+++ .pc/02_enable-libparted-dmraid-2.patch/README 2011-02-23 00:37:58 +0000
19@@ -0,0 +1,159 @@
20+GPARTED
21+-------
22+Gparted is the Gnome Partition Editor for creating, reorganizing, and
23+deleting disk partitions.
24+
25+A hard disk is usually subdivided into one or more partitions. These
26+partitions are normally not re-sizable (making one smaller and the
27+adjacent one larger.) Gparted makes it possible for you to take a
28+hard disk and change the partition organization, while preserving the
29+partition contents.
30+
31+More specifically, Gparted enables you to create, destroy, resize,
32+move, check, label, and copy partitions, and the file systems
33+contained within. This is useful for creating space for new operating
34+systems, reorganizing disk usage, and mirroring one partition with
35+another (disk imaging).
36+
37+Gparted can also be used with storage devices other than hard disks,
38+such as USB flash drives, and memory cards.
39+
40+Visit http://gparted.sourceforge.net for more information.
41+
42+
43+NEWS
44+----
45+Information about changes to this release, and past releases can be
46+found in the file:
47+ NEWS
48+
49+
50+INSTALL
51+-------
52+a. Pre-built Binary
53+
54+ Many GNU/Linux distributions already provide a pre-built binary
55+ package for GParted. Instructions on how to install GParted on
56+ some distributions is given below:
57+
58+ (K)Ubuntu
59+ ---------
60+ sudo apt-get install gparted
61+
62+ Fedora
63+ ------
64+ su -
65+ yum install gparted
66+
67+b. Building from Source
68+
69+ Building Gparted from source requires that several dependencies are
70+ installed. These include:
71+ g++
72+ e2fsprogs
73+ parted
74+ gtkmm24
75+ gettext
76+ gnome-doc-utils - required if help documentation is to be built
77+
78+ On (K)Ubuntu, these dependencies may be obtained by running the
79+ following command;
80+ sudo apt-get install build-essential e2fsprogs uuid uuid-dev \
81+ gnome-common libparted-dev libgtkmm-2.4-dev \
82+ libdevmapper-dev gnome-doc-utils
83+
84+ On Fedora, you will need to run (as root);
85+ yum install gtkmm24-devel parted-devel e2fsprogs-devel gettext \
86+ perl(XML::Parser) desktop-file-utils
87+
88+ Briefly, the shell commands `./configure; make; make install' should
89+ configure, build, and install this package. If you wish to build
90+ this package without the help documentation use the --disable-doc
91+ flag:
92+ E.g., ./configure --disable-doc
93+
94+ The INSTALL file contains further GNU installation instructions.
95+
96+
97+COPYING
98+-------
99+The copying conditions can be found in the file:
100+ COPYING
101+
102+
103+DIRECTORIES
104+------------
105+compose - contains String::ucompose() function
106+
107+data - contains desktop icons
108+
109+doc - contains manual page documentation
110+
111+help - contains GParted Manual and international translations
112+
113+include - contains source header files
114+
115+m4 - contains macro files
116+
117+po - contains international language translations
118+
119+src - contains C++ source code
120+
121+
122+DISTRIBUTION NOTES
123+------------------
124+Gparted uses GNU libparted to detect and manipulate devices and partition
125+tables. Several optional packages provide additional file system support.
126+Optional packages include:
127+
128+ btrfs-tools
129+ e2fsprogs
130+ dosfstools
131+ mtools - required to read and write FAT16/32 volume labels
132+ hfsutils
133+ hfsprogs
134+ jfsutils
135+ ntfsprogs
136+ reiser4progs
137+ reiserfsprogs
138+ xfsprogs
139+
140+ NOTE: * If the vol_id command is in the search PATH, it will be used
141+ to read linux-swap, reiser4, hfs, and hfs+ file system
142+ volume labels.
143+ * If the blkid command is in the search path, it will be used
144+ to read file system UUIDs and labels. It is also used for
145+ ext4 file detection.
146+ blkid is part of the e2fsprogs package.
147+
148+
149+For Linux software RAID support, the following package is required:
150+ mdadm - tool to administer Linux MD arrays
151+
152+
153+For dmraid support, the following packages are required:
154+
155+ dmsetup - removes /dev/mapper entries
156+ dmraid - lists dmraid devices and creates /dev/mapper entries
157+
158+For GNU/Linux distribution dmraid support, the following are required:
159+ - kernel built with Device Mapping and Mirroring built. From menuconfig,
160+ it is under Device Drivers -> <something> (RAID & LVM).
161+ - dmraid drive arrays activated on boot (e.g., dmraid -ay).
162+
163+
164+Several more commands are optionally used by GParted if found on the system.
165+These commands include:
166+
167+ blkid - used to read volume labels and detect ext4 file systems
168+ vol_id - used to read volume labels
169+ udisks - used to prevent automounting of file systems
170+ devkit-disks - used to prevent automounting of file systems
171+ hal-lock - used to prevent automounting of file systems
172+ gksu - used to acquire root privileges in .desktop file,
173+ but only if available when gparted source is configured.
174+ kpartx - used in dmraid to create /dev/mapper entries such as
175+ /dev/mapper/isw_idedecefg_Volume0p1
176+ udevinfo - used in dmraid to query udev name
177+ udevadm - used in dmraid to query udev name
178+
179
180=== added file '.pc/02_enable-libparted-dmraid-2.patch/configure.in'
181--- .pc/02_enable-libparted-dmraid-2.patch/configure.in 1970-01-01 00:00:00 +0000
182+++ .pc/02_enable-libparted-dmraid-2.patch/configure.in 2011-02-23 00:37:58 +0000
183@@ -0,0 +1,203 @@
184+AC_INIT([gparted],[0.7.0],[https://bugzilla.gnome.org/enter_bug.cgi?product=gparted])
185+
186+AC_CONFIG_SRCDIR([src/main.cc])
187+AC_CONFIG_HEADERS([config.h])
188+AC_CONFIG_MACRO_DIR([m4])
189+
190+AM_INIT_AUTOMAKE([1.9 no-dist-gzip dist-bzip2])
191+AM_MAINTAINER_MODE
192+
193+
194+dnl======================
195+dnl checks for programs
196+dnl======================
197+AC_PROG_CC
198+AC_PROG_CXX
199+AM_PROG_LIBTOOL
200+
201+
202+dnl======================
203+dnl checks for other programs
204+dnl======================
205+AC_CHECK_PROG([GKSUPROG], [gksu], [gksu])
206+
207+
208+dnl======================
209+dnl i18n stuff
210+dnl======================
211+GETTEXT_PACKAGE=gparted
212+AC_SUBST([GETTEXT_PACKAGE])
213+AC_DEFINE_UNQUOTED([GETTEXT_PACKAGE], "$GETTEXT_PACKAGE", [description])
214+
215+AM_GLIB_GNU_GETTEXT
216+IT_PROG_INTLTOOL([0.35.5])
217+
218+
219+dnl======================
220+dnl checks for libs
221+dnl======================
222+AC_CHECK_LIB([uuid], [uuid_generate], [], AC_MSG_ERROR([*** uuid library (libuuid) not found]))
223+AC_CHECK_LIB([dl], [dlopen], [], AC_MSG_ERROR([*** dl library (libdl) not found]))
224+
225+
226+dnl libparted
227+LIBPARTED_VERSION=1.7.1
228+AC_MSG_CHECKING([for libparted >= $LIBPARTED_VERSION])
229+LIBS_save="$LIBS"
230+LIBS="-lparted -luuid -ldl"
231+AC_TRY_RUN([
232+#include <stdio.h>
233+#include <parted/parted.h>
234+
235+int main ()
236+{
237+ int min_major = 0;
238+ int min_minor = 0;
239+ int min_micro = 0;
240+ int major = 0;
241+ int minor = 0;
242+ int micro = 0;
243+
244+ if ( ( sscanf( "$LIBPARTED_VERSION", "%d.%d.%d", &min_major, &min_minor, &min_micro ) == 3 ) ||
245+ ( sscanf( "$LIBPARTED_VERSION", "%d.%d", &min_major, &min_minor ) == 2 ) ||
246+ ( sscanf( "$LIBPARTED_VERSION", "%d", &min_major ) == 1 )
247+ )
248+ {
249+ if ( ( sscanf( ped_get_version(), "%d.%d.%d", &major, &minor, &micro ) == 3 ) ||
250+ ( sscanf( ped_get_version(), "%d.%d", &major, &minor ) == 2 ) ||
251+ ( sscanf( ped_get_version(), "%d", &major ) == 1 )
252+ )
253+ {
254+ printf( "Found libparted %s\t", ped_get_version() ) ;
255+ return ! ( (major > min_major) ||
256+ ( (major == min_major) && (minor > min_minor) ) ||
257+ ( (major == min_major) && (minor == min_minor) && (micro >= min_micro) )
258+ ) ;
259+ }
260+ }
261+
262+ return 1 ;
263+}
264+], AC_MSG_RESULT([OK]), AC_MSG_ERROR([*** Requires libparted >= $LIBPARTED_VERSION. Perhaps development header files missing?]))
265+LIBS="$LIBS_save"
266+
267+
268+dnl======================
269+dnl check whether libparted >= 2.2 (has improved partition table re-read code)
270+dnl======================
271+LIBPARTED_VERSION=2.2
272+AC_MSG_CHECKING([if libparted >= $LIBPARTED_VERSION (has improved pt re-read)])
273+LIBS_save="$LIBS"
274+LIBS="-lparted -luuid -ldl"
275+need_work_around=yes
276+AC_TRY_RUN([
277+#include <stdio.h>
278+#include <parted/parted.h>
279+
280+int main ()
281+{
282+ int min_major = 0;
283+ int min_minor = 0;
284+ int min_micro = 0;
285+ int major = 0;
286+ int minor = 0;
287+ int micro = 0;
288+
289+ if ( ( sscanf( "$LIBPARTED_VERSION", "%d.%d.%d", &min_major, &min_minor, &min_micro ) == 3 ) ||
290+ ( sscanf( "$LIBPARTED_VERSION", "%d.%d", &min_major, &min_minor ) == 2 ) ||
291+ ( sscanf( "$LIBPARTED_VERSION", "%d", &min_major ) == 1 )
292+ )
293+ {
294+ if ( ( sscanf( ped_get_version(), "%d.%d.%d", &major, &minor, &micro ) == 3 ) ||
295+ ( sscanf( ped_get_version(), "%d.%d", &major, &minor ) == 2 ) ||
296+ ( sscanf( ped_get_version(), "%d", &major ) == 1 )
297+ )
298+ {
299+ return ! ( (major > min_major) ||
300+ ( (major == min_major) && (minor > min_minor) ) ||
301+ ( (major == min_major) && (minor == min_minor) && (micro >= min_micro) )
302+ ) ;
303+ }
304+ }
305+
306+ return 1 ;
307+}
308+], [AC_MSG_RESULT([yes])
309+ AC_DEFINE([HAVE_LIBPARTED_2_2_0_PLUS], [1], [Define to 1 if libparted contains improved partition table re-read code])
310+ need_pt_reread_work_around=no; support_sector_size_gt_512=yes]
311+, [AC_MSG_RESULT([no])
312+ need_pt_reread_work_around=yes; support_sector_size_gt_512=no]
313+)
314+LIBS="$LIBS_save"
315+
316+
317+dnl GTKMM
318+PKG_CHECK_MODULES([GTKMM], [gtkmm-2.4 > 2.8])
319+AC_SUBST([GTKMM_LIBS])
320+AC_SUBST([GTKMM_CFLAGS])
321+
322+
323+dnl GTKMM 2.16 needed for gtk_show_uri()
324+PKG_CHECK_EXISTS([gtkmm-2.4 >= 2.16.0],
325+ [AC_DEFINE([HAVE_GTK_SHOW_URI], 1, [Define to 1 if you have gtk_show_uri])],
326+ [])
327+
328+
329+dnl======================
330+dnl check whether to build documentation - Gnome-Doc-Utils
331+dnl======================
332+AC_ARG_ENABLE([doc],
333+ [ --disable-doc do not build documentation],,)
334+if test "x${enable_doc}" = "x" ; then
335+ enable_doc=yes
336+fi
337+
338+AC_MSG_CHECKING([whether documentation should be built])
339+if test ${enable_doc} = no; then
340+ AC_MSG_RESULT([no])
341+else
342+ AC_MSG_RESULT([yes])
343+fi
344+
345+if test ${enable_doc} = yes; then
346+ GNOME_DOC_INIT
347+else
348+ dnl Do not care if GDU is not found
349+ GNOME_DOC_INIT(,,[:])
350+ dnl Set #define HAVE_DISABLE_DOC 1 to indicate documentation not wanted
351+ AC_DEFINE([HAVE_DISABLE_DOC], [1], [Define to 1 if --disable-doc specified])
352+fi
353+
354+AM_CONDITIONAL([DISABLE_DOC], [test ${enable_doc} = no])
355+
356+
357+AC_CONFIG_FILES([
358+Makefile
359+compose/Makefile
360+data/Makefile
361+data/icons/Makefile
362+doc/Makefile
363+help/Makefile
364+include/Makefile
365+src/Makefile
366+po/Makefile.in
367+])
368+
369+AC_OUTPUT
370+
371+
372+dnl======================
373+dnl Summary
374+dnl======================
375+
376+echo ""
377+echo "================ Final configuration ==================="
378+echo " Installing into prefix : $prefix"
379+echo ""
380+echo " Build documentation? : $enable_doc"
381+echo ""
382+echo " Need part table re-read work around? : $need_pt_reread_work_around"
383+echo " Supports sector sizes > 512 bytes? : $support_sector_size_gt_512"
384+echo ""
385+echo " If all settings are OK, type make and make install "
386+echo "========================================================"
387
388=== added directory '.pc/02_enable-libparted-dmraid-2.patch/src'
389=== added file '.pc/02_enable-libparted-dmraid-2.patch/src/GParted_Core.cc'
390--- .pc/02_enable-libparted-dmraid-2.patch/src/GParted_Core.cc 1970-01-01 00:00:00 +0000
391+++ .pc/02_enable-libparted-dmraid-2.patch/src/GParted_Core.cc 2011-02-23 00:37:58 +0000
392@@ -0,0 +1,3116 @@
393+/* Copyright (C) 2004 Bart 'plors' Hakvoort
394+ * Copyright (C) 2008, 2009, 2010 Curtis Gedak
395+ *
396+ * This program is free software; you can redistribute it and/or modify
397+ * it under the terms of the GNU General Public License as published by
398+ * the Free Software Foundation; either version 2 of the License, or
399+ * (at your option) any later version.
400+ *
401+ * This program is distributed in the hope that it will be useful,
402+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
403+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
404+ * GNU Library General Public License for more details.
405+ *
406+ * You should have received a copy of the GNU General Public License
407+ * along with this program; if not, write to the Free Software
408+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
409+ */
410+
411+#include "../include/Win_GParted.h"
412+#include "../include/GParted_Core.h"
413+#include "../include/DMRaid.h"
414+#include "../include/SWRaid.h"
415+#include "../include/FS_Info.h"
416+#include "../include/OperationCopy.h"
417+#include "../include/OperationCreate.h"
418+#include "../include/OperationDelete.h"
419+#include "../include/OperationFormat.h"
420+#include "../include/OperationResizeMove.h"
421+#include "../include/OperationLabelPartition.h"
422+
423+#include "../include/btrfs.h"
424+#include "../include/ext2.h"
425+#include "../include/ext3.h"
426+#include "../include/ext4.h"
427+#include "../include/fat16.h"
428+#include "../include/fat32.h"
429+#include "../include/linux_swap.h"
430+#include "../include/reiserfs.h"
431+#include "../include/ntfs.h"
432+#include "../include/xfs.h"
433+#include "../include/jfs.h"
434+#include "../include/hfs.h"
435+#include "../include/hfsplus.h"
436+#include "../include/reiser4.h"
437+#include "../include/ufs.h"
438+#include <set>
439+#include <cerrno>
440+#include <cstring>
441+#include <sys/statvfs.h>
442+#include <sys/types.h>
443+#include <sys/stat.h>
444+#include <unistd.h>
445+#include <dirent.h>
446+
447+std::vector<Glib::ustring> libparted_messages ; //see ped_exception_handler()
448+
449+namespace GParted
450+{
451+
452+GParted_Core::GParted_Core()
453+{
454+ lp_device = NULL ;
455+ lp_disk = NULL ;
456+ lp_partition = NULL ;
457+ p_filesystem = NULL ;
458+ thread_status_message = "" ;
459+
460+ ped_exception_set_handler( ped_exception_handler ) ;
461+
462+ //get valid flags ...
463+ for ( PedPartitionFlag flag = ped_partition_flag_next( static_cast<PedPartitionFlag>( NULL ) ) ;
464+ flag ;
465+ flag = ped_partition_flag_next( flag ) )
466+ flags .push_back( flag ) ;
467+
468+ //throw libpartedversion to the stdout to see which version is actually used.
469+ std::cout << "======================" << std::endl ;
470+ std::cout << "libparted : " << ped_get_version() << std::endl ;
471+ std::cout << "======================" << std::endl ;
472+
473+ //initialize file system list
474+ find_supported_filesystems() ;
475+}
476+
477+void GParted_Core::find_supported_filesystems()
478+{
479+ FILESYSTEMS .clear() ;
480+
481+ FS fs_notsupp;
482+
483+ btrfs fs_btrfs;
484+ FILESYSTEMS .push_back( fs_btrfs .get_filesystem_support() ) ;
485+
486+ ext2 fs_ext2;
487+ FILESYSTEMS .push_back( fs_ext2 .get_filesystem_support() ) ;
488+
489+ ext3 fs_ext3;
490+ FILESYSTEMS .push_back( fs_ext3 .get_filesystem_support() ) ;
491+
492+ ext4 fs_ext4;
493+ FILESYSTEMS .push_back( fs_ext4 .get_filesystem_support() ) ;
494+
495+ fat16 fs_fat16;
496+ FILESYSTEMS .push_back( fs_fat16 .get_filesystem_support() ) ;
497+
498+ fat32 fs_fat32;
499+ FILESYSTEMS .push_back( fs_fat32 .get_filesystem_support() ) ;
500+
501+ hfs fs_hfs;
502+ FILESYSTEMS .push_back( fs_hfs .get_filesystem_support() ) ;
503+
504+ hfsplus fs_hfsplus;
505+ FILESYSTEMS .push_back( fs_hfsplus .get_filesystem_support() ) ;
506+
507+ jfs fs_jfs;
508+ FILESYSTEMS .push_back( fs_jfs .get_filesystem_support() ) ;
509+
510+ linux_swap fs_linux_swap;
511+ FILESYSTEMS .push_back( fs_linux_swap .get_filesystem_support() ) ;
512+
513+ ntfs fs_ntfs;
514+ FILESYSTEMS .push_back( fs_ntfs .get_filesystem_support() ) ;
515+
516+ reiser4 fs_reiser4;
517+ FILESYSTEMS .push_back( fs_reiser4 .get_filesystem_support() ) ;
518+
519+ reiserfs fs_reiserfs;
520+ FILESYSTEMS .push_back( fs_reiserfs .get_filesystem_support() ) ;
521+
522+ ufs fs_ufs;
523+ FILESYSTEMS .push_back( fs_ufs .get_filesystem_support() ) ;
524+
525+ xfs fs_xfs;
526+ FILESYSTEMS .push_back( fs_xfs .get_filesystem_support() ) ;
527+
528+ //lvm2 physical volume -- not a file system
529+ fs_notsupp .filesystem = GParted::FS_LVM2 ;
530+ FILESYSTEMS .push_back( fs_notsupp ) ;
531+
532+ //luks encryption-- not a file system
533+ fs_notsupp .filesystem = GParted::FS_LUKS ;
534+ FILESYSTEMS .push_back( fs_notsupp ) ;
535+
536+ //unknown file system (default when no match is found)
537+ fs_notsupp .filesystem = GParted::FS_UNKNOWN ;
538+ FILESYSTEMS .push_back( fs_notsupp ) ;
539+}
540+
541+void GParted_Core::set_user_devices( const std::vector<Glib::ustring> & user_devices )
542+{
543+ this ->device_paths = user_devices ;
544+ this ->probe_devices = ! user_devices .size() ;
545+}
546+
547+void GParted_Core::set_devices( std::vector<Device> & devices )
548+{
549+ devices .clear() ;
550+ Device temp_device ;
551+ FS_Info fs_info( true ) ; //Refresh cache of file system information
552+ DMRaid dmraid( true ) ; //Refresh cache of dmraid device information
553+ SWRaid swraid( true ) ; //Refresh cache of swraid device information
554+
555+ init_maps() ;
556+
557+ //only probe if no devices were specified as arguments..
558+ if ( probe_devices )
559+ {
560+ device_paths .clear() ;
561+
562+ //FIXME: When libparted bug 194 is fixed, remove code to read:
563+ // /proc/partitions
564+ // This was a problem with no floppy drive yet BIOS indicated one existed.
565+ // http://parted.alioth.debian.org/cgi-bin/trac.cgi/ticket/194
566+ //
567+ //try to find all available devices
568+ std::ifstream proc_partitions( "/proc/partitions" ) ;
569+ if ( proc_partitions )
570+ {
571+ //parse device names from /proc/partitions
572+ std::string line ;
573+ std::string device ;
574+ while ( getline( proc_partitions, line ) )
575+ {
576+ //Whole disk devices are the ones we want.
577+ //Device names without a trailing digit refer to the whole disk.
578+ device = Utils::regexp_label(line, "^[\t ]+[0-9]+[\t ]+[0-9]+[\t ]+[0-9]+[\t ]+([^0-9]+)$") ;
579+ //Recognize /dev/mmcblk* devices.
580+ //E.g., device = /dev/mmcblk0, partition = /dev/mmcblk0p1
581+ if ( device == "" )
582+ device = Utils::regexp_label(line, "^[\t ]+[0-9]+[\t ]+[0-9]+[\t ]+[0-9]+[\t ]+(mmcblk[0-9]+)$") ;
583+ //Device names that end with a #[^p]# are HP Smart Array Devices (disks)
584+ //E.g., device = /dev/cciss/c0d0, partition = /dev/cciss/c0d0p1
585+ if ( device == "" )
586+ device = Utils::regexp_label(line, "^[\t ]+[0-9]+[\t ]+[0-9]+[\t ]+[0-9]+[\t ]+(.*[0-9]+[^p]{1}[0-9]+)$") ;
587+ if ( device != "" )
588+ {
589+ //try to have libparted detect the device and add it to the list
590+ device = "/dev/" + device;
591+ /*TO TRANSLATORS: looks like Scanning /dev/sda */
592+ set_thread_status_message( String::ucompose ( _("Scanning %1"), device ) ) ;
593+ ped_device_get( device .c_str() ) ;
594+ }
595+ }
596+ proc_partitions .close() ;
597+
598+ //Try to find all swraid devices
599+ if (swraid .is_swraid_supported() ) {
600+ std::vector<Glib::ustring> swraid_devices ;
601+ swraid .get_devices( swraid_devices ) ;
602+ for ( unsigned int k=0; k < swraid_devices .size(); k++ ) {
603+ set_thread_status_message( String::ucompose ( _("Scanning %1"), swraid_devices[k] ) ) ;
604+ ped_device_get( swraid_devices[k] .c_str() ) ;
605+ }
606+ }
607+
608+ //Try to find all dmraid devices
609+ if (dmraid .is_dmraid_supported() ) {
610+ std::vector<Glib::ustring> dmraid_devices ;
611+ dmraid .get_devices( dmraid_devices ) ;
612+ for ( unsigned int k=0; k < dmraid_devices .size(); k++ ) {
613+ set_thread_status_message( String::ucompose ( _("Scanning %1"), dmraid_devices[k] ) ) ;
614+ dmraid .create_dev_map_entries( dmraid_devices[k] ) ;
615+ settle_device( 1 ) ;
616+ ped_device_get( dmraid_devices[k] .c_str() ) ;
617+ }
618+ }
619+ }
620+ else
621+ {
622+ //file /proc/partitions doesn't exist so use libparted to probe devices
623+ ped_device_probe_all();
624+ }
625+
626+ lp_device = ped_device_get_next( NULL );
627+ while ( lp_device )
628+ {
629+ //only add this device if we can read the first sector (which means it's a real device)
630+ char * buf = static_cast<char *>( malloc( lp_device ->sector_size ) ) ;
631+ if ( buf )
632+ {
633+ /*TO TRANSLATORS: looks like Confirming /dev/sda */
634+ set_thread_status_message( String::ucompose ( _("Confirming %1"), lp_device ->path ) ) ;
635+ if ( ped_device_open( lp_device ) )
636+ {
637+#ifdef HAVE_LIBPARTED_2_2_0_PLUS
638+ //Devices with sector sizes of 512 bytes and higher are supported
639+ if ( ped_device_read( lp_device, buf, 0, 1 ) )
640+ device_paths .push_back( lp_device ->path ) ;
641+#else
642+ //Only devices with sector sizes of 512 bytes are well supported
643+ if ( lp_device ->sector_size != 512 )
644+ {
645+ /*TO TRANSLATORS: looks like Ignoring device /dev/sde with logical sector size of 2048 bytes. */
646+ Glib::ustring msg = String::ucompose ( _("Ignoring device %1 with logical sector size of %2 bytes."), lp_device ->path, lp_device ->sector_size ) ;
647+ msg += "\n" ;
648+ msg += _("GParted requires libparted version 2.2 or higher to support devices with sector sizes larger than 512 bytes.") ;
649+ std::cout << msg << std::endl << std::endl ;
650+ }
651+ else
652+ {
653+ if ( ped_device_read( lp_device, buf, 0, 1 ) )
654+ device_paths .push_back( lp_device ->path ) ;
655+ }
656+#endif
657+ ped_device_close( lp_device ) ;
658+ }
659+ free( buf ) ;
660+ }
661+ lp_device = ped_device_get_next( lp_device ) ;
662+ }
663+ close_device_and_disk() ;
664+
665+ std::sort( device_paths .begin(), device_paths .end() ) ;
666+ }
667+ else
668+ {
669+ //Device paths were passed in on the command line.
670+
671+ //Ensure that dmraid device entries are created
672+ for ( unsigned int t = 0 ; t < device_paths .size() ; t++ )
673+ {
674+ if ( dmraid .is_dmraid_supported() &&
675+ dmraid .is_dmraid_device( device_paths[t] ) )
676+ {
677+ dmraid .create_dev_map_entries( dmraid .get_dmraid_name( device_paths [t] ) ) ;
678+ }
679+ }
680+ }
681+
682+ for ( unsigned int t = 0 ; t < device_paths .size() ; t++ )
683+ {
684+ /*TO TRANSLATORS: looks like Searching /dev/sda partitions */
685+ set_thread_status_message( String::ucompose ( _("Searching %1 partitions"), device_paths[ t ] ) ) ;
686+ if ( open_device_and_disk( device_paths[ t ], false ) )
687+ {
688+ temp_device .Reset() ;
689+
690+ //device info..
691+ temp_device .add_path( device_paths[ t ] ) ;
692+ temp_device .add_paths( get_alternate_paths( temp_device .get_path() ) ) ;
693+
694+ temp_device .model = lp_device ->model ;
695+ temp_device .length = lp_device ->length ;
696+ temp_device .sector_size = lp_device ->sector_size ;
697+ temp_device .heads = lp_device ->bios_geom .heads ;
698+ temp_device .sectors = lp_device ->bios_geom .sectors ;
699+ temp_device .cylinders = lp_device ->bios_geom .cylinders ;
700+ temp_device .cylsize = temp_device .heads * temp_device .sectors ;
701+
702+ //make sure cylsize is at least 1 MiB
703+ if ( temp_device .cylsize < (MEBIBYTE / temp_device .sector_size) )
704+ temp_device .cylsize = (MEBIBYTE / temp_device .sector_size) ;
705+
706+ //normal harddisk
707+ if ( lp_disk )
708+ {
709+ temp_device .disktype = lp_disk ->type ->name ;
710+ temp_device .max_prims = ped_disk_get_max_primary_partition_count( lp_disk ) ;
711+
712+ set_device_partitions( temp_device ) ;
713+ set_mountpoints( temp_device .partitions ) ;
714+ set_used_sectors( temp_device .partitions ) ;
715+
716+ if ( temp_device .highest_busy )
717+ {
718+ temp_device .readonly = ! commit_to_os( 1 ) ;
719+ //Clear libparted messages. Typically these are:
720+ // The kernel was unable to re-read the partition table...
721+ libparted_messages .clear() ;
722+ }
723+ }
724+ //harddisk without disklabel
725+ else
726+ {
727+ temp_device .disktype =
728+ /* TO TRANSLATORS: unrecognized
729+ * means that the partition table for this
730+ * disk device is unknown or not recognized.
731+ */
732+ _("unrecognized") ;
733+ temp_device .max_prims = -1 ;
734+
735+ Partition partition_temp ;
736+ partition_temp .Set_Unallocated( temp_device .get_path(),
737+ 0,
738+ temp_device .length,
739+ temp_device .sector_size,
740+ false );
741+ //Place libparted messages in this unallocated partition
742+ partition_temp .messages .insert( partition_temp .messages .end(),
743+ libparted_messages. begin(),
744+ libparted_messages .end() ) ;
745+ libparted_messages .clear() ;
746+ temp_device .partitions .push_back( partition_temp );
747+ }
748+
749+ devices .push_back( temp_device ) ;
750+
751+ close_device_and_disk() ;
752+ }
753+ }
754+
755+ //clear leftover information...
756+ //NOTE that we cannot clear mountinfo since it might be needed in get_all_mountpoints()
757+ set_thread_status_message("") ;
758+ alternate_paths .clear() ;
759+ fstab_info .clear() ;
760+}
761+
762+void GParted_Core::set_thread_status_message( Glib::ustring msg )
763+{
764+ //Remember to clear status message when finished with thread.
765+ thread_status_message = msg ;
766+}
767+
768+Glib::ustring GParted_Core::get_thread_status_message( )
769+{
770+ return thread_status_message ;
771+}
772+
773+bool GParted_Core::snap_to_cylinder( const Device & device, Partition & partition, Glib::ustring & error )
774+{
775+ Sector diff = 0;
776+
777+ //Determine if partition size is less than a disk cylinder
778+ bool less_than_cylinder = false;
779+ if ( ( partition .sector_end - partition .sector_start ) < device .cylsize )
780+ less_than_cylinder = true;
781+
782+ if ( partition.type == TYPE_LOGICAL ||
783+ partition.sector_start == device .sectors
784+ )
785+ {
786+ //Must account the relative offset between:
787+ // (A) the Extended Boot Record sector and the next track of the
788+ // logical partition (usually 63 sectors), and
789+ // (B) the Master Boot Record sector and the next track of the first
790+ // primary partition
791+ diff = (partition .sector_start - device .sectors) % device .cylsize ;
792+ }
793+ else if ( partition.sector_start == 34 )
794+ {
795+ // (C) the GUID Partition Table (GPT) and the start of the data
796+ // partition at sector 34
797+ diff = (partition .sector_start - 34 ) % device .cylsize ;
798+ }
799+ else
800+ {
801+ diff = partition .sector_start % device .cylsize ;
802+ }
803+ if ( diff && ! partition .strict_start )
804+ {
805+ if ( diff < ( device .cylsize / 2 ) || less_than_cylinder )
806+ partition .sector_start -= diff ;
807+ else
808+ partition .sector_start += (device .cylsize - diff ) ;
809+ }
810+
811+ diff = (partition .sector_end +1) % device .cylsize ;
812+ if ( diff )
813+ {
814+ if ( diff < ( device .cylsize / 2 ) && ! less_than_cylinder )
815+ partition .sector_end -= diff ;
816+ else
817+ partition .sector_end += (device .cylsize - diff ) ;
818+ }
819+
820+ return true ;
821+}
822+
823+bool GParted_Core::snap_to_mebibyte( const Device & device, Partition & partition, Glib::ustring & error )
824+{
825+ Sector diff = 0;
826+ if ( partition .sector_start < 2 || partition .type == TYPE_LOGICAL )
827+ {
828+ //Must account the relative offset between:
829+ // (A) the Master Boot Record sector and the first primary/extended partition, and
830+ // (B) the Extended Boot Record sector and the logical partition
831+
832+ //If strict_start is set then do not adjust sector start.
833+ //If this partition is not simply queued for a reformat then
834+ // add space minimum to force alignment to next mebibyte.
835+ if ( (! partition .strict_start)
836+ && (partition .free_space_before == 0)
837+ && ( partition .status != STAT_FORMATTED)
838+ )
839+ {
840+ //Unless specifically told otherwise, the Linux kernel considers extended
841+ // boot records to be two sectors long, in order to "leave room for LILO".
842+ partition .sector_start += 2 ;
843+ }
844+ }
845+
846+ //Align start sector
847+ diff = Sector(partition .sector_start % ( MEBIBYTE / partition .sector_size ));
848+ if ( diff && ( (! partition .strict_start)
849+ || ( partition .strict_start
850+ && ( partition .status == STAT_NEW
851+ || partition .status == STAT_COPY
852+ )
853+ )
854+ )
855+ )
856+ partition .sector_start += ( (MEBIBYTE / partition .sector_size) - diff) ;
857+
858+ //If this is a logical partition not at end of drive then check to see if space is
859+ // required for a following logical partition Extended Boot Record
860+ if ( partition .type == TYPE_LOGICAL )
861+ {
862+ //Locate the extended partition that contains the logical partitions.
863+ int index_extended = -1 ;
864+ for ( unsigned int t = 0 ; t < device .partitions .size() ; t++ )
865+ {
866+ if ( device .partitions[ t ] .type == TYPE_EXTENDED )
867+ index_extended = t ;
868+ }
869+
870+ //If there is a following logical partition that starts a mebibyte or less
871+ // from the end of this partition, then reserve a mebibyte for the EBR.
872+ if ( index_extended != -1 )
873+ {
874+ for ( unsigned int t = 0; t < device .partitions[ index_extended ] .logicals .size(); t++ )
875+ {
876+ if ( ( device .partitions[ index_extended ] .logicals[ t ] .type == TYPE_LOGICAL )
877+ && ( device .partitions[ index_extended ] .logicals[ t ] .sector_start > partition .sector_end )
878+ && ( ( device .partitions[ index_extended ] .logicals[ t ] .sector_start - partition .sector_end )
879+ < ( MEBIBYTE / device .sector_size )
880+ )
881+ )
882+ partition .sector_end -= 1 ;
883+ }
884+ }
885+ }
886+
887+ //If this is a GPT partition table then reserve a mebibyte at the end of the device
888+ // for the backup partition table
889+ if ( device .disktype == "gpt"
890+ && ( ( device .length - partition .sector_end ) <= ( MEBIBYTE / device .sector_size ) )
891+ )
892+ {
893+ partition .sector_end -= 1 ;
894+ }
895+
896+ //Align end sector
897+ diff = (partition .sector_end + 1) % ( MEBIBYTE / partition .sector_size);
898+ if ( diff )
899+ partition .sector_end -= diff ;
900+
901+ return true ;
902+}
903+
904+bool GParted_Core::snap_to_alignment( const Device & device, Partition & partition, Glib::ustring & error )
905+{
906+ bool rc = true ;
907+
908+ if ( partition .alignment == ALIGN_CYLINDER )
909+ rc = snap_to_cylinder( device, partition, error ) ;
910+ else if ( partition .alignment == ALIGN_MEBIBYTE )
911+ rc = snap_to_mebibyte( device, partition, error ) ;
912+
913+ //Ensure that partition start and end are not beyond the ends of the disk device
914+ if ( partition .sector_start < 0 )
915+ partition .sector_start = 0 ;
916+ if ( partition .sector_end > device .length )
917+ partition .sector_end = device .length - 1 ;
918+
919+ //do some basic checks on the partition
920+ if ( partition .get_sector_length() <= 0 )
921+ {
922+ error = String::ucompose(
923+ /* TO TRANSLATORS: looks like A partition cannot have a length of -1 sectors */
924+ _("A partition cannot have a length of %1 sectors"),
925+ partition .get_sector_length() ) ;
926+ return false ;
927+ }
928+
929+ if ( partition .get_sector_length() < partition .sectors_used )
930+ {
931+ error = String::ucompose(
932+ /* TO TRANSLATORS: looks like A partition with used sectors (2048) greater than its length (1536) is not valid */
933+ _("A partition with used sectors (%1) greater than its length (%2) is not valid"),
934+ partition .sectors_used,
935+ partition .get_sector_length() ) ;
936+ return false ;
937+ }
938+
939+ //FIXME: it would be perfect if we could check for overlapping with adjacent partitions as well,
940+ //however, finding the adjacent partitions is not as easy as it seems and at this moment all the dialogs
941+ //already perform these checks. A perfect 'fixme-later' ;)
942+
943+ return rc ;
944+}
945+
946+bool GParted_Core::apply_operation_to_disk( Operation * operation )
947+{
948+ bool succes = false ;
949+ libparted_messages .clear() ;
950+
951+ if ( calibrate_partition( operation ->partition_original, operation ->operation_detail ) )
952+ switch ( operation ->type )
953+ {
954+ case OPERATION_DELETE:
955+ succes = Delete( operation ->partition_original, operation ->operation_detail ) ;
956+ break ;
957+ case OPERATION_CHECK:
958+ succes = check_repair_filesystem( operation ->partition_original, operation ->operation_detail ) &&
959+ maximize_filesystem( operation ->partition_original, operation ->operation_detail ) ;
960+ break ;
961+ case OPERATION_CREATE:
962+ succes = create( operation ->device,
963+ operation ->partition_new,
964+ operation ->operation_detail ) ;
965+ break ;
966+ case OPERATION_RESIZE_MOVE:
967+ //in case the to be resized/moved partition was a 'copy of..', we need a real path...
968+ operation ->partition_new .add_path( operation ->partition_original .get_path(), true ) ;
969+ succes = resize_move( operation ->device,
970+ operation ->partition_original,
971+ operation ->partition_new,
972+ operation ->operation_detail ) ;
973+ break ;
974+ case OPERATION_FORMAT:
975+ succes = format( operation ->partition_new, operation ->operation_detail ) ;
976+ break ;
977+ case OPERATION_COPY:
978+ //FIXME: in case of a new partition we should make sure the new partition is >= the source partition...
979+ //i think it's best to do this in the dialog_paste
980+ succes = ( operation ->partition_original .type == TYPE_UNALLOCATED ||
981+ calibrate_partition( operation ->partition_new, operation ->operation_detail ) ) &&
982+
983+ calibrate_partition( static_cast<OperationCopy*>( operation ) ->partition_copied,
984+ operation ->operation_detail ) &&
985+
986+ copy( static_cast<OperationCopy*>( operation ) ->partition_copied,
987+ operation ->partition_new,
988+ static_cast<OperationCopy*>( operation ) ->partition_copied .get_byte_length(),
989+ operation ->operation_detail ) ;
990+ break ;
991+ case OPERATION_LABEL_PARTITION:
992+ succes = label_partition( operation ->partition_new, operation ->operation_detail ) ;
993+ break ;
994+ }
995+
996+ if ( libparted_messages .size() > 0 )
997+ {
998+ operation ->operation_detail .add_child( OperationDetail( _("libparted messages"), STATUS_INFO ) ) ;
999+
1000+ for ( unsigned int t = 0 ; t < libparted_messages .size() ; t++ )
1001+ operation ->operation_detail .get_last_child() .add_child(
1002+ OperationDetail( libparted_messages[ t ], STATUS_NONE, FONT_ITALIC ) ) ;
1003+ }
1004+
1005+ return succes ;
1006+}
1007+
1008+bool GParted_Core::set_disklabel( const Glib::ustring & device_path, const Glib::ustring & disklabel )
1009+{
1010+ bool return_value = false ;
1011+
1012+ if ( open_device_and_disk( device_path, false ) )
1013+ {
1014+ PedDiskType *type = NULL ;
1015+ type = ped_disk_type_get( disklabel .c_str() ) ;
1016+
1017+ if ( type )
1018+ {
1019+ lp_disk = ped_disk_new_fresh( lp_device, type );
1020+
1021+ return_value = commit() ;
1022+ }
1023+
1024+ close_device_and_disk() ;
1025+ }
1026+
1027+ //delete and recreate disk entries if dmraid
1028+ DMRaid dmraid ;
1029+ if ( return_value && dmraid .is_dmraid_device( device_path ) )
1030+ {
1031+ dmraid .purge_dev_map_entries( device_path ) ;
1032+ dmraid .create_dev_map_entries( device_path ) ;
1033+ }
1034+
1035+ return return_value ;
1036+}
1037+
1038+bool GParted_Core::toggle_flag( const Partition & partition, const Glib::ustring & flag, bool state )
1039+{
1040+ bool succes = false ;
1041+
1042+ if ( open_device_and_disk( partition .device_path ) )
1043+ {
1044+ lp_partition = NULL ;
1045+ if ( partition .type == GParted::TYPE_EXTENDED )
1046+ lp_partition = ped_disk_extended_partition( lp_disk ) ;
1047+ else
1048+ lp_partition = ped_disk_get_partition_by_sector( lp_disk, partition .get_sector() ) ;
1049+
1050+ if ( lp_partition )
1051+ {
1052+ PedPartitionFlag lp_flag = ped_partition_flag_get_by_name( flag .c_str() ) ;
1053+
1054+ if ( lp_flag > 0 && ped_partition_set_flag( lp_partition, lp_flag, state ) )
1055+ succes = commit() ;
1056+ }
1057+
1058+ close_device_and_disk() ;
1059+ }
1060+
1061+ return succes ;
1062+}
1063+
1064+const std::vector<FS> & GParted_Core::get_filesystems() const
1065+{
1066+ return FILESYSTEMS ;
1067+}
1068+
1069+const FS & GParted_Core::get_fs( GParted::FILESYSTEM filesystem ) const
1070+{
1071+ for ( unsigned int t = 0 ; t < FILESYSTEMS .size() ; t++ )
1072+ if ( FILESYSTEMS[ t ] .filesystem == filesystem )
1073+ return FILESYSTEMS[ t ] ;
1074+
1075+ return FILESYSTEMS .back() ;
1076+}
1077+
1078+std::vector<Glib::ustring> GParted_Core::get_disklabeltypes()
1079+{
1080+ std::vector<Glib::ustring> disklabeltypes ;
1081+
1082+ //msdos should be first in the list
1083+ disklabeltypes .push_back( "msdos" ) ;
1084+
1085+ PedDiskType *disk_type ;
1086+ for ( disk_type = ped_disk_type_get_next( NULL ) ; disk_type ; disk_type = ped_disk_type_get_next( disk_type ) )
1087+ if ( Glib::ustring( disk_type->name ) != "msdos" )
1088+ disklabeltypes .push_back( disk_type->name ) ;
1089+
1090+ return disklabeltypes ;
1091+}
1092+
1093+std::vector<Glib::ustring> GParted_Core::get_all_mountpoints()
1094+{
1095+ std::vector<Glib::ustring> mountpoints ;
1096+
1097+ for ( iter_mp = mount_info .begin() ; iter_mp != mount_info .end() ; ++iter_mp )
1098+ mountpoints .insert( mountpoints .end(), iter_mp ->second .begin(), iter_mp ->second .end() ) ;
1099+
1100+ return mountpoints ;
1101+}
1102+
1103+std::map<Glib::ustring, bool> GParted_Core::get_available_flags( const Partition & partition )
1104+{
1105+ std::map<Glib::ustring, bool> flag_info ;
1106+
1107+ if ( open_device_and_disk( partition .device_path ) )
1108+ {
1109+ lp_partition = NULL ;
1110+ if ( partition .type == GParted::TYPE_EXTENDED )
1111+ lp_partition = ped_disk_extended_partition( lp_disk ) ;
1112+ else
1113+ lp_partition = ped_disk_get_partition_by_sector( lp_disk, partition .get_sector() ) ;
1114+
1115+ if ( lp_partition )
1116+ {
1117+ for ( unsigned int t = 0 ; t < flags .size() ; t++ )
1118+ if ( ped_partition_is_flag_available( lp_partition, flags[ t ] ) )
1119+ flag_info[ ped_partition_flag_get_name( flags[ t ] ) ] =
1120+ ped_partition_get_flag( lp_partition, flags[ t ] ) ;
1121+ }
1122+
1123+ close_device_and_disk() ;
1124+ }
1125+
1126+ return flag_info ;
1127+}
1128+
1129+Glib::ustring GParted_Core::get_libparted_version()
1130+{
1131+ return ped_get_version() ;
1132+}
1133+
1134+//private functions...
1135+
1136+void GParted_Core::init_maps()
1137+{
1138+ alternate_paths .clear() ;
1139+ mount_info .clear() ;
1140+ fstab_info .clear() ;
1141+
1142+ read_mountpoints_from_file( "/proc/mounts", mount_info ) ;
1143+ read_mountpoints_from_file_swaps( "/proc/swaps", mount_info ) ;
1144+ read_mountpoints_from_file( "/etc/mtab", mount_info ) ;
1145+ read_mountpoints_from_file( "/etc/fstab", fstab_info ) ;
1146+
1147+ //sort the mount points and remove duplicates.. (no need to do this for fstab_info)
1148+ for ( iter_mp = mount_info .begin() ; iter_mp != mount_info .end() ; ++iter_mp )
1149+ {
1150+ std::sort( iter_mp ->second .begin(), iter_mp ->second .end() ) ;
1151+
1152+ iter_mp ->second .erase(
1153+ std::unique( iter_mp ->second .begin(), iter_mp ->second .end() ),
1154+ iter_mp ->second .end() ) ;
1155+ }
1156+
1157+ //initialize alternate_paths...
1158+ std::string line ;
1159+ std::ifstream proc_partitions( "/proc/partitions" ) ;
1160+ if ( proc_partitions )
1161+ {
1162+ char c_str[4096+1] ;
1163+
1164+ while ( getline( proc_partitions, line ) )
1165+ if ( sscanf( line .c_str(), "%*d %*d %*d %4096s", c_str ) == 1 )
1166+ {
1167+ line = "/dev/" ;
1168+ line += c_str ;
1169+
1170+ //FIXME: it seems realpath is very unsafe to use (manpage)...
1171+ if ( file_test( line, Glib::FILE_TEST_EXISTS ) &&
1172+ realpath( line .c_str(), c_str ) &&
1173+ line != c_str )
1174+ {
1175+ //because we can make no assumption about which path libparted will detect
1176+ //we add all combinations.
1177+ alternate_paths[ c_str ] = line ;
1178+ alternate_paths[ line ] = c_str ;
1179+ }
1180+ }
1181+
1182+ proc_partitions .close() ;
1183+ }
1184+}
1185+
1186+void GParted_Core::read_mountpoints_from_file(
1187+ const Glib::ustring & filename,
1188+ std::map< Glib::ustring, std::vector<Glib::ustring> > & map )
1189+{
1190+ std::string line ;
1191+ Glib::ustring node ;
1192+ Glib::ustring mountpoint ;
1193+
1194+ std::ifstream file( filename .c_str() ) ;
1195+ if ( file )
1196+ {
1197+ while ( getline( file, line ) )
1198+ {
1199+ node = Utils::regexp_label( line, "^(/[^ \t]+)[ \t]+[^ \t]+" ) ;
1200+ mountpoint = Utils::regexp_label( line, "^/[^ \t]+[ \t]+([^ \t]+)" ) ;
1201+ if ( mountpoint .length() > 0 && node .length() > 0 )
1202+ {
1203+ //Only add node path(s) if mount point exists
1204+ if ( file_test( mountpoint, Glib::FILE_TEST_EXISTS ) )
1205+ {
1206+ map[ node ] .push_back( mountpoint ) ;
1207+
1208+ //If node is a symbolic link (e.g., /dev/root)
1209+ // then find real path and add entry
1210+ if ( file_test( node, Glib::FILE_TEST_IS_SYMLINK ) )
1211+ {
1212+ char c_str[4096+1] ;
1213+ //FIXME: it seems realpath is very unsafe to use (manpage)...
1214+ if ( realpath( node .c_str(), c_str ) != NULL )
1215+ map[ c_str ] .push_back( mountpoint ) ;
1216+ }
1217+ }
1218+ }
1219+ }
1220+
1221+ file .close() ;
1222+ }
1223+}
1224+
1225+void GParted_Core::read_mountpoints_from_file_swaps(
1226+ const Glib::ustring & filename,
1227+ std::map< Glib::ustring, std::vector<Glib::ustring> > & map )
1228+{
1229+ std::string line ;
1230+ std::string node ;
1231+
1232+ std::ifstream file( filename .c_str() ) ;
1233+ if ( file )
1234+ {
1235+ while ( getline( file, line ) )
1236+ {
1237+ node = Utils::regexp_label( line, "^(/[^ ]+)" ) ;
1238+ if ( node .size() > 0 )
1239+ map[ node ] .push_back( "" /* no mountpoint for swap */ ) ;
1240+ }
1241+ file .close() ;
1242+ }
1243+}
1244+
1245+std::vector<Glib::ustring> GParted_Core::get_alternate_paths( const Glib::ustring & path )
1246+{
1247+ std::vector<Glib::ustring> paths ;
1248+
1249+ iter = alternate_paths .find( path ) ;
1250+ if ( iter != alternate_paths .end() )
1251+ paths .push_back( iter ->second ) ;
1252+
1253+ return paths ;
1254+}
1255+
1256+Glib::ustring GParted_Core::get_partition_path( PedPartition * lp_partition )
1257+{
1258+ DMRaid dmraid; //Use cache of dmraid device information
1259+ char * lp_path; //we have to free the result of ped_partition_get_path()
1260+ Glib::ustring partition_path;
1261+
1262+ lp_path = ped_partition_get_path(lp_partition);
1263+ partition_path = lp_path;
1264+ free(lp_path);
1265+
1266+ //Ensure partition path name is compatible with dmraid
1267+ if ( dmraid .is_dmraid_supported()
1268+ && dmraid .is_dmraid_device( partition_path )
1269+ )
1270+ {
1271+ partition_path = dmraid .make_path_dmraid_compatible(partition_path);
1272+ }
1273+
1274+ return partition_path ;
1275+}
1276+
1277+void GParted_Core::set_device_partitions( Device & device )
1278+{
1279+ int EXT_INDEX = -1 ;
1280+ FS_Info fs_info ; //Use cache of file system information
1281+ DMRaid dmraid ; //Use cache of dmraid device information
1282+
1283+ //clear partitions
1284+ device .partitions .clear() ;
1285+
1286+ lp_partition = ped_disk_next_partition( lp_disk, NULL ) ;
1287+ while ( lp_partition )
1288+ {
1289+ libparted_messages .clear() ;
1290+ partition_temp .Reset() ;
1291+ bool partition_is_busy = false ;
1292+
1293+ //Retrieve partition path
1294+ Glib::ustring partition_path = get_partition_path( lp_partition );
1295+
1296+ switch ( lp_partition ->type )
1297+ {
1298+ case PED_PARTITION_NORMAL:
1299+ case PED_PARTITION_LOGICAL:
1300+ //Handle dmraid devices differently because the minor number might not
1301+ // match the last number of the partition filename as shown by "ls -l /dev/mapper"
1302+ // This mismatch causes incorrect identification of busy partitions in ped_partition_is_busy().
1303+ if ( dmraid .is_dmraid_device( device .get_path() ) )
1304+ {
1305+ //Try device_name + partition_number
1306+ iter_mp = mount_info .find( device .get_path() + Utils::num_to_str( lp_partition ->num ) ) ;
1307+ if ( iter_mp != mount_info .end() )
1308+ partition_is_busy = true ;
1309+ //Try device_name + p + partition_number
1310+ iter_mp = mount_info .find( device .get_path() + "p" + Utils::num_to_str( lp_partition ->num ) ) ;
1311+ if ( iter_mp != mount_info .end() )
1312+ partition_is_busy = true ;
1313+ }
1314+ else
1315+ partition_is_busy = ped_partition_is_busy( lp_partition ) ;
1316+
1317+ partition_temp .Set( device .get_path(),
1318+ partition_path,
1319+ lp_partition ->num,
1320+ lp_partition ->type == 0 ? GParted::TYPE_PRIMARY : GParted::TYPE_LOGICAL,
1321+ get_filesystem(),
1322+ lp_partition ->geom .start,
1323+ lp_partition ->geom .end,
1324+ device .sector_size,
1325+ lp_partition ->type,
1326+ partition_is_busy ) ;
1327+
1328+ partition_temp .add_paths( get_alternate_paths( partition_temp .get_path() ) ) ;
1329+ set_flags( partition_temp ) ;
1330+
1331+ if ( partition_temp .busy && partition_temp .partition_number > device .highest_busy )
1332+ device .highest_busy = partition_temp .partition_number ;
1333+
1334+ break ;
1335+
1336+ case PED_PARTITION_EXTENDED:
1337+ //Handle dmraid devices differently because the minor number might not
1338+ // match the last number of the partition filename as shown by "ls -l /dev/mapper"
1339+ // This mismatch causes incorrect identification of busy partitions in ped_partition_is_busy().
1340+ if ( dmraid .is_dmraid_device( device .get_path() ) )
1341+ {
1342+ for ( unsigned int k = 5; k < 255; k++ )
1343+ {
1344+ //Try device_name + [5 to 255]
1345+ iter_mp = mount_info .find( device .get_path() + Utils::num_to_str( k ) ) ;
1346+ if ( iter_mp != mount_info .end() )
1347+ partition_is_busy = true ;
1348+ //Try device_name + p + [5 to 255]
1349+ iter_mp = mount_info .find( device .get_path() + "p" + Utils::num_to_str( k ) ) ;
1350+ if ( iter_mp != mount_info .end() )
1351+ partition_is_busy = true ;
1352+ }
1353+ }
1354+ else
1355+ partition_is_busy = ped_partition_is_busy( lp_partition ) ;
1356+
1357+ partition_temp .Set( device .get_path(),
1358+ partition_path,
1359+ lp_partition ->num,
1360+ GParted::TYPE_EXTENDED,
1361+ GParted::FS_EXTENDED,
1362+ lp_partition ->geom .start,
1363+ lp_partition ->geom .end,
1364+ device .sector_size,
1365+ false,
1366+ partition_is_busy ) ;
1367+
1368+ partition_temp .add_paths( get_alternate_paths( partition_temp .get_path() ) ) ;
1369+ set_flags( partition_temp ) ;
1370+
1371+ EXT_INDEX = device .partitions .size() ;
1372+ break ;
1373+
1374+ default:
1375+ break;
1376+ }
1377+
1378+ //Avoid reading additional file system information if there is no path
1379+ if ( partition_temp .get_path() != "" )
1380+ {
1381+ bool label_found = false ;
1382+ partition_temp .label = fs_info .get_label( partition_temp .get_path(), label_found ) ;
1383+ if ( ! label_found )
1384+ read_label( partition_temp ) ;
1385+
1386+ partition_temp .uuid = fs_info .get_uuid( partition_temp .get_path() ) ;
1387+ }
1388+
1389+ partition_temp .messages .insert( partition_temp .messages .end(),
1390+ libparted_messages. begin(),
1391+ libparted_messages .end() ) ;
1392+
1393+ //if there's an end, there's a partition ;)
1394+ if ( partition_temp .sector_end > -1 )
1395+ {
1396+ if ( ! partition_temp .inside_extended )
1397+ device .partitions .push_back( partition_temp );
1398+ else
1399+ device .partitions[ EXT_INDEX ] .logicals .push_back( partition_temp ) ;
1400+ }
1401+
1402+ //next partition (if any)
1403+ lp_partition = ped_disk_next_partition( lp_disk, lp_partition ) ;
1404+ }
1405+
1406+ if ( EXT_INDEX > -1 )
1407+ insert_unallocated( device .get_path(),
1408+ device .partitions[ EXT_INDEX ] .logicals,
1409+ device .partitions[ EXT_INDEX ] .sector_start,
1410+ device .partitions[ EXT_INDEX ] .sector_end,
1411+ device .sector_size,
1412+ true ) ;
1413+
1414+ insert_unallocated( device .get_path(), device .partitions, 0, device .length -1, device .sector_size, false ) ;
1415+}
1416+
1417+GParted::FILESYSTEM GParted_Core::get_filesystem()
1418+{
1419+ char magic1[16] = "";
1420+ char magic2[16] = "";
1421+
1422+ //Check for LUKS encryption prior to libparted file system detection.
1423+ // Otherwise encrypted file systems such as ext3 will be detected by
1424+ // libparted as 'ext3'.
1425+
1426+ //LUKS encryption
1427+ char * buf = static_cast<char *>( malloc( lp_device ->sector_size ) ) ;
1428+ if ( buf )
1429+ {
1430+ ped_device_open( lp_device );
1431+ ped_geometry_read( & lp_partition ->geom, buf, 0, 1 ) ;
1432+ memcpy(magic1, buf+0, 6) ; //set binary magic data
1433+ ped_device_close( lp_device );
1434+ free( buf ) ;
1435+
1436+ if ( 0 == memcmp( magic1 , "LUKS\xBA\xBE", 6 ) )
1437+ {
1438+ temp = _( "Linux Unified Key Setup encryption is not yet supported." ) ;
1439+ temp += "\n" ;
1440+ partition_temp .messages .push_back( temp ) ;
1441+ return GParted::FS_LUKS ;
1442+ }
1443+ }
1444+
1445+ FS_Info fs_info ;
1446+ Glib::ustring fs_type = "" ;
1447+
1448+ //Standard libparted file system detection
1449+ if ( lp_partition && lp_partition ->fs_type )
1450+ {
1451+ fs_type = lp_partition ->fs_type ->name ;
1452+
1453+ //TODO: Temporary code to detect ext4.
1454+ // Replace when libparted >= 1.9.0 is chosen as minimum required version.
1455+ char * const path = ped_partition_get_path( lp_partition );
1456+
1457+ if (NULL != path)
1458+ {
1459+ temp = fs_info .get_fs_type( Glib::ustring( path ) ) ;
1460+ if ( temp == "ext4" || temp == "ext4dev" )
1461+ fs_type = temp ;
1462+ free( path );
1463+ }
1464+ }
1465+
1466+ //FS_Info (blkid) file system detection because current libparted (v2.2) does not
1467+ // appear to detect file systems for sector sizes other than 512 bytes.
1468+ if ( fs_type .empty() )
1469+ {
1470+ //TODO: blkid does not return anything for an "extended" partition. Need to handle this somehow
1471+ char * const path = ped_partition_get_path( lp_partition );
1472+ if (NULL != path)
1473+ {
1474+ fs_type = fs_info.get_fs_type( Glib::ustring( path ) ) ;
1475+ free( path );
1476+ }
1477+ }
1478+
1479+ if ( ! fs_type .empty() )
1480+ {
1481+ if ( fs_type == "extended" )
1482+ return GParted::FS_EXTENDED ;
1483+ else if ( fs_type == "btrfs" )
1484+ return GParted::FS_BTRFS ;
1485+ else if ( fs_type == "ext2" )
1486+ return GParted::FS_EXT2 ;
1487+ else if ( fs_type == "ext3" )
1488+ return GParted::FS_EXT3 ;
1489+ else if ( fs_type == "ext4" ||
1490+ fs_type == "ext4dev" )
1491+ return GParted::FS_EXT4 ;
1492+ else if ( fs_type == "linux-swap" ||
1493+ fs_type == "linux-swap(v1)" ||
1494+ fs_type == "linux-swap(new)" ||
1495+ fs_type == "linux-swap(v0)" ||
1496+ fs_type == "linux-swap(old)" ||
1497+ fs_type == "swap" )
1498+ return GParted::FS_LINUX_SWAP ;
1499+ else if ( fs_type == "fat16" )
1500+ return GParted::FS_FAT16 ;
1501+ else if ( fs_type == "fat32" )
1502+ return GParted::FS_FAT32 ;
1503+ else if ( fs_type == "ntfs" )
1504+ return GParted::FS_NTFS ;
1505+ else if ( fs_type == "reiserfs" )
1506+ return GParted::FS_REISERFS ;
1507+ else if ( fs_type == "xfs" )
1508+ return GParted::FS_XFS ;
1509+ else if ( fs_type == "jfs" )
1510+ return GParted::FS_JFS ;
1511+ else if ( fs_type == "hfs" )
1512+ return GParted::FS_HFS ;
1513+ else if ( fs_type == "hfs+" ||
1514+ fs_type == "hfsplus" )
1515+ return GParted::FS_HFSPLUS ;
1516+ else if ( fs_type == "ufs" )
1517+ return GParted::FS_UFS ;
1518+ }
1519+
1520+
1521+ //other file systems libparted couldn't detect (i've send patches for these file systems to the parted guys)
1522+ // - no patches sent to parted for lvm2, or luks
1523+
1524+ //reiser4
1525+ buf = static_cast<char *>( malloc( lp_device ->sector_size ) ) ;
1526+ if ( buf )
1527+ {
1528+ ped_device_open( lp_device );
1529+ ped_geometry_read( & lp_partition ->geom
1530+ , buf
1531+ , (65536 / lp_device ->sector_size)
1532+ , 1
1533+ ) ;
1534+ memcpy(magic1, buf+0, 7) ; //set binary magic data
1535+ ped_device_close( lp_device );
1536+ free( buf ) ;
1537+
1538+ if ( 0 == memcmp( magic1, "ReIsEr4", 7 ) )
1539+ return GParted::FS_REISER4 ;
1540+ }
1541+
1542+ //lvm2
1543+ //NOTE: lvm2 is not a file system but we do wish to recognize the Physical Volume
1544+ buf = static_cast<char *>( malloc( lp_device ->sector_size ) ) ;
1545+ if ( buf )
1546+ {
1547+ ped_device_open( lp_device );
1548+ if ( lp_device ->sector_size == 512 )
1549+ {
1550+ ped_geometry_read( & lp_partition ->geom, buf, 1, 1 ) ;
1551+ memcpy(magic1, buf+ 0, 8) ; // set binary magic data
1552+ memcpy(magic2, buf+24, 4) ; // set binary magic data
1553+ }
1554+ else
1555+ {
1556+ ped_geometry_read( & lp_partition ->geom, buf, 0, 1 ) ;
1557+ memcpy(magic1, buf+ 0+512, 8) ; // set binary magic data
1558+ memcpy(magic2, buf+24+512, 4) ; // set binary magic data
1559+ }
1560+ ped_device_close( lp_device );
1561+ free( buf ) ;
1562+
1563+ if ( 0 == memcmp( magic1, "LABELONE", 8 )
1564+ && 0 == memcmp( magic2, "LVM2", 4 ) )
1565+ {
1566+ temp = _( "Logical Volume Management is not yet supported." ) ;
1567+ temp += "\n" ;
1568+ partition_temp .messages .push_back( temp ) ;
1569+ return GParted::FS_LVM2 ;
1570+ }
1571+ }
1572+
1573+ //btrfs
1574+ const Sector BTRFS_SUPER_INFO_SIZE = 4096 ;
1575+ const Sector BTRFS_SUPER_INFO_OFFSET = (64 * 1024) ;
1576+ const char* const BTRFS_SIGNATURE = "_BHRfS_M" ;
1577+
1578+ char buf_btrfs[BTRFS_SUPER_INFO_SIZE] ;
1579+
1580+ ped_device_open( lp_device ) ;
1581+ ped_geometry_read( & lp_partition ->geom
1582+ , buf_btrfs
1583+ , (BTRFS_SUPER_INFO_OFFSET / lp_device ->sector_size)
1584+ , (BTRFS_SUPER_INFO_SIZE / lp_device ->sector_size)
1585+ ) ;
1586+ memcpy(magic1, buf_btrfs+64, strlen(BTRFS_SIGNATURE) ) ; //set binary magic data
1587+ ped_device_close( lp_device ) ;
1588+
1589+ if ( 0 == memcmp( magic1, BTRFS_SIGNATURE, strlen(BTRFS_SIGNATURE) ) )
1590+ {
1591+ return GParted::FS_BTRFS ;
1592+ }
1593+
1594+ //no file system found....
1595+ temp = _( "Unable to detect file system! Possible reasons are:" ) ;
1596+ temp += "\n-";
1597+ temp += _( "The file system is damaged" ) ;
1598+ temp += "\n-" ;
1599+ temp += _( "The file system is unknown to GParted" ) ;
1600+ temp += "\n-";
1601+ temp += _( "There is no file system available (unformatted)" ) ;
1602+
1603+ partition_temp .messages .push_back( temp ) ;
1604+
1605+ return GParted::FS_UNKNOWN ;
1606+}
1607+
1608+void GParted_Core::read_label( Partition & partition )
1609+{
1610+ if ( partition .type != TYPE_EXTENDED )
1611+ {
1612+ switch( get_fs( partition .filesystem ) .read_label )
1613+ {
1614+ case FS::EXTERNAL:
1615+ if ( set_proper_filesystem( partition .filesystem ) )
1616+ p_filesystem ->read_label( partition ) ;
1617+ break ;
1618+ case FS::LIBPARTED:
1619+ break ;
1620+
1621+ default:
1622+ break ;
1623+ }
1624+ }
1625+}
1626+
1627+void GParted_Core::insert_unallocated( const Glib::ustring & device_path,
1628+ std::vector<Partition> & partitions,
1629+ Sector start,
1630+ Sector end,
1631+ Byte_Value sector_size,
1632+ bool inside_extended )
1633+{
1634+ partition_temp .Reset() ;
1635+ partition_temp .Set_Unallocated( device_path, 0, 0, sector_size, inside_extended ) ;
1636+
1637+ //if there are no partitions at all..
1638+ if ( partitions .empty() )
1639+ {
1640+ partition_temp .sector_start = start ;
1641+ partition_temp .sector_end = end ;
1642+
1643+ partitions .push_back( partition_temp );
1644+
1645+ return ;
1646+ }
1647+
1648+ //start <---> first partition start
1649+ if ( (partitions .front() .sector_start - start) > (MEBIBYTE / sector_size) )
1650+ {
1651+ partition_temp .sector_start = start ;
1652+ partition_temp .sector_end = partitions .front() .sector_start -1 ;
1653+
1654+ partitions .insert( partitions .begin(), partition_temp );
1655+ }
1656+
1657+ //look for gaps in between
1658+ for ( unsigned int t =0 ; t < partitions .size() -1 ; t++ )
1659+ {
1660+ if ( ( ( partitions[ t + 1 ] .sector_start - partitions[ t ] .sector_end - 1 ) > (MEBIBYTE / sector_size) )
1661+ || ( ( partitions[ t + 1 ] .type != TYPE_LOGICAL ) // Only show exactly 1 MiB if following partition is not logical.
1662+ && ( ( partitions[ t + 1 ] .sector_start - partitions[ t ] .sector_end - 1 ) == (MEBIBYTE / sector_size) )
1663+ )
1664+ )
1665+ {
1666+ partition_temp .sector_start = partitions[ t ] .sector_end +1 ;
1667+ partition_temp .sector_end = partitions[ t +1 ] .sector_start -1 ;
1668+
1669+ partitions .insert( partitions .begin() + ++t, partition_temp );
1670+ }
1671+ }
1672+
1673+ //last partition end <---> end
1674+ if ( (end - partitions .back() .sector_end) >= (MEBIBYTE / sector_size) )
1675+ {
1676+ partition_temp .sector_start = partitions .back() .sector_end +1 ;
1677+ partition_temp .sector_end = end ;
1678+
1679+ partitions .push_back( partition_temp );
1680+ }
1681+}
1682+
1683+void GParted_Core::set_mountpoints( std::vector<Partition> & partitions )
1684+{
1685+ DMRaid dmraid ; //Use cache of dmraid device information
1686+ for ( unsigned int t = 0 ; t < partitions .size() ; t++ )
1687+ {
1688+ if ( ( partitions[ t ] .type == GParted::TYPE_PRIMARY ||
1689+ partitions[ t ] .type == GParted::TYPE_LOGICAL
1690+ ) &&
1691+ partitions[ t ] .filesystem != GParted::FS_LINUX_SWAP &&
1692+ partitions[ t ] .filesystem != GParted::FS_LVM2 &&
1693+ partitions[ t ] .filesystem != GParted::FS_LUKS
1694+ )
1695+ {
1696+ if ( partitions[ t ] .busy )
1697+ {
1698+ for ( unsigned int i = 0 ; i < partitions[ t ] .get_paths() .size() ; i++ )
1699+ {
1700+ //Handle dmraid devices differently because there may be more
1701+ // than one partition name.
1702+ // E.g., there might be names with and/or without a 'p' between
1703+ // the device name and partition number.
1704+ if ( dmraid .is_dmraid_device( partitions[ t ] .device_path ) )
1705+ {
1706+ //Try device_name + partition_number
1707+ iter_mp = mount_info .find( partitions[ t ] .device_path + Utils::num_to_str( partitions[ t ] .partition_number ) ) ;
1708+ if ( iter_mp != mount_info .end() )
1709+ {
1710+ partitions[ t ] .add_mountpoints( iter_mp ->second ) ;
1711+ break ;
1712+ }
1713+ //Try device_name + p + partition_number
1714+ iter_mp = mount_info .find( partitions[ t ] .device_path + "p" + Utils::num_to_str( partitions[ t ] .partition_number ) ) ;
1715+ if ( iter_mp != mount_info .end() )
1716+ {
1717+ partitions[ t ] .add_mountpoints( iter_mp ->second ) ;
1718+ break ;
1719+ }
1720+ }
1721+ else
1722+ {
1723+ iter_mp = mount_info .find( partitions[ t ] .get_paths()[ i ] ) ;
1724+ if ( iter_mp != mount_info .end() )
1725+ {
1726+ partitions[ t ] .add_mountpoints( iter_mp ->second ) ;
1727+ break ;
1728+ }
1729+ }
1730+ }
1731+
1732+ if ( partitions[ t ] .get_mountpoints() .empty() )
1733+ partitions[ t ] .messages .push_back( _("Unable to find mount point") ) ;
1734+ }
1735+ else
1736+ {
1737+ iter_mp = fstab_info .find( partitions[ t ] .get_path() );
1738+ if ( iter_mp != fstab_info .end() )
1739+ partitions[ t ] .add_mountpoints( iter_mp ->second ) ;
1740+ }
1741+ }
1742+ else if ( partitions[ t ] .type == GParted::TYPE_EXTENDED )
1743+ set_mountpoints( partitions[ t ] .logicals ) ;
1744+ }
1745+}
1746+
1747+void GParted_Core::set_used_sectors( std::vector<Partition> & partitions )
1748+{
1749+ struct statvfs sfs ;
1750+
1751+ for ( unsigned int t = 0 ; t < partitions .size() ; t++ )
1752+ {
1753+ if ( partitions[ t ] .filesystem != GParted::FS_LINUX_SWAP &&
1754+ partitions[ t ] .filesystem != GParted::FS_LUKS &&
1755+ partitions[ t ] .filesystem != GParted::FS_LVM2 &&
1756+ partitions[ t ] .filesystem != GParted::FS_UNKNOWN
1757+ )
1758+ {
1759+ if ( partitions[ t ] .type == GParted::TYPE_PRIMARY ||
1760+ partitions[ t ] .type == GParted::TYPE_LOGICAL )
1761+ {
1762+ if ( partitions[ t ] .busy )
1763+ {
1764+ if ( partitions[ t ] .get_mountpoints() .size() > 0 )
1765+ {
1766+ if ( statvfs( partitions[ t ] .get_mountpoint() .c_str(), &sfs ) == 0 )
1767+ partitions[ t ] .Set_Unused( sfs .f_bfree * (sfs .f_bsize / partitions[ t ] .sector_size) ) ;
1768+ else
1769+ partitions[ t ] .messages .push_back(
1770+ "statvfs (" +
1771+ partitions[ t ] .get_mountpoint() +
1772+ "): " +
1773+ Glib::strerror( errno ) ) ;
1774+ }
1775+ }
1776+ else
1777+ {
1778+ switch( get_fs( partitions[ t ] .filesystem ) .read )
1779+ {
1780+ case GParted::FS::EXTERNAL :
1781+ if ( set_proper_filesystem( partitions[ t ] .filesystem ) )
1782+ p_filesystem ->set_used_sectors( partitions[ t ] ) ;
1783+ break ;
1784+ case GParted::FS::LIBPARTED :
1785+ LP_set_used_sectors( partitions[ t ] ) ;
1786+ break ;
1787+
1788+ default:
1789+ break ;
1790+ }
1791+ }
1792+
1793+ if ( partitions[ t ] .sectors_used == -1 )
1794+ {
1795+ temp = _("Unable to read the contents of this file system!") ;
1796+ temp += "\n" ;
1797+ temp += _("Because of this some operations may be unavailable.") ;
1798+ if ( ! Utils::get_filesystem_software( partitions[ t ] .filesystem ) .empty() )
1799+ {
1800+ temp += "\n\n" ;
1801+ /*TO TRANSLATORS: looks like The following list of software packages is required for NTFS file system support: ntfsprogs. */
1802+ temp += String::ucompose( _("The following list of software packages is required for %1 file system support: %2."),
1803+ Utils::get_filesystem_string( partitions[ t ] .filesystem ),
1804+ Utils::get_filesystem_software( partitions[ t ] .filesystem )
1805+ ) ;
1806+ }
1807+ partitions[ t ] .messages .push_back( temp ) ;
1808+ }
1809+ }
1810+ else if ( partitions[ t ] .type == GParted::TYPE_EXTENDED )
1811+ set_used_sectors( partitions[ t ] .logicals ) ;
1812+ }
1813+ }
1814+}
1815+
1816+void GParted_Core::LP_set_used_sectors( Partition & partition )
1817+{
1818+ PedFileSystem *fs = NULL;
1819+ PedConstraint *constraint = NULL;
1820+
1821+ if ( lp_disk )
1822+ {
1823+ lp_partition = ped_disk_get_partition_by_sector( lp_disk, partition .get_sector() ) ;
1824+
1825+ if ( lp_partition )
1826+ {
1827+ fs = ped_file_system_open( & lp_partition ->geom );
1828+
1829+ if ( fs )
1830+ {
1831+ constraint = ped_file_system_get_resize_constraint( fs ) ;
1832+ if ( constraint )
1833+ {
1834+ partition .Set_Unused( partition .get_sector_length() - constraint ->min_size ) ;
1835+
1836+ ped_constraint_destroy( constraint );
1837+ }
1838+
1839+ ped_file_system_close( fs ) ;
1840+ }
1841+ }
1842+ }
1843+}
1844+
1845+void GParted_Core::set_flags( Partition & partition )
1846+{
1847+ for ( unsigned int t = 0 ; t < flags .size() ; t++ )
1848+ if ( ped_partition_is_flag_available( lp_partition, flags[ t ] ) &&
1849+ ped_partition_get_flag( lp_partition, flags[ t ] ) )
1850+ partition .flags .push_back( ped_partition_flag_get_name( flags[ t ] ) ) ;
1851+}
1852+
1853+bool GParted_Core::create( const Device & device, Partition & new_partition, OperationDetail & operationdetail )
1854+{
1855+ if ( new_partition .type == GParted::TYPE_EXTENDED )
1856+ {
1857+ return create_partition( new_partition, operationdetail ) ;
1858+ }
1859+ else if ( create_partition( new_partition, operationdetail, (get_fs( new_partition .filesystem ) .MIN / new_partition .sector_size) ) )
1860+ {
1861+ if ( new_partition .filesystem == GParted::FS_UNFORMATTED )
1862+ return true ;
1863+ else
1864+ return set_partition_type( new_partition, operationdetail ) &&
1865+ create_filesystem( new_partition, operationdetail ) ;
1866+ }
1867+
1868+ return false ;
1869+}
1870+
1871+bool GParted_Core::create_partition( Partition & new_partition, OperationDetail & operationdetail, Sector min_size )
1872+{
1873+ operationdetail .add_child( OperationDetail( _("create empty partition") ) ) ;
1874+
1875+ new_partition .partition_number = 0 ;
1876+
1877+ if ( open_device_and_disk( new_partition .device_path ) )
1878+ {
1879+ PedPartitionType type;
1880+ lp_partition = NULL ;
1881+ PedConstraint *constraint = NULL ;
1882+ PedFileSystemType* fs_type = NULL ;
1883+
1884+ //create new partition
1885+ switch ( new_partition .type )
1886+ {
1887+ case GParted::TYPE_PRIMARY:
1888+ type = PED_PARTITION_NORMAL ;
1889+ break ;
1890+ case GParted::TYPE_LOGICAL:
1891+ type = PED_PARTITION_LOGICAL ;
1892+ break ;
1893+ case GParted::TYPE_EXTENDED:
1894+ type = PED_PARTITION_EXTENDED ;
1895+ break ;
1896+
1897+ default :
1898+ type = PED_PARTITION_FREESPACE;
1899+ }
1900+
1901+ if ( new_partition .type != GParted::TYPE_EXTENDED )
1902+ fs_type = ped_file_system_type_get( "ext2" ) ;
1903+
1904+ lp_partition = ped_partition_new( lp_disk,
1905+ type,
1906+ fs_type,
1907+ new_partition .sector_start,
1908+ new_partition .sector_end ) ;
1909+
1910+ if ( lp_partition )
1911+ {
1912+ if ( new_partition .alignment == ALIGN_STRICT
1913+ || new_partition .alignment == ALIGN_MEBIBYTE
1914+ )
1915+ {
1916+ PedGeometry *geom = ped_geometry_new( lp_device,
1917+ new_partition .sector_start,
1918+ new_partition .get_sector_length() ) ;
1919+
1920+ if ( geom )
1921+ constraint = ped_constraint_exact( geom ) ;
1922+ }
1923+ else
1924+ constraint = ped_constraint_any( lp_device );
1925+
1926+ if ( constraint )
1927+ {
1928+ if ( min_size > 0 )
1929+ constraint ->min_size = min_size ;
1930+
1931+ if ( ped_disk_add_partition( lp_disk, lp_partition, constraint ) && commit() )
1932+ {
1933+ Glib::ustring partition_path = get_partition_path( lp_partition ) ;
1934+ new_partition .add_path( partition_path, true ) ;
1935+
1936+ new_partition .partition_number = lp_partition ->num ;
1937+ new_partition .sector_start = lp_partition ->geom .start ;
1938+ new_partition .sector_end = lp_partition ->geom .end ;
1939+
1940+ operationdetail .get_last_child() .add_child( OperationDetail(
1941+ String::ucompose( _("path: %1"), new_partition .get_path() ) + "\n" +
1942+ String::ucompose( _("start: %1"), new_partition .sector_start ) + "\n" +
1943+ String::ucompose( _("end: %1"), new_partition .sector_end ) + "\n" +
1944+ String::ucompose( _("size: %1 (%2)"),
1945+ new_partition .get_sector_length(),
1946+ Utils::format_size( new_partition .get_sector_length(), new_partition .sector_size ) ),
1947+ STATUS_NONE,
1948+ FONT_ITALIC ) ) ;
1949+ }
1950+
1951+ ped_constraint_destroy( constraint );
1952+ }
1953+ }
1954+
1955+ close_device_and_disk() ;
1956+ }
1957+
1958+ bool succes = new_partition .partition_number > 0 && erase_filesystem_signatures( new_partition ) ;
1959+
1960+ //create dev map entries if dmraid
1961+ DMRaid dmraid ;
1962+ if ( succes && dmraid .is_dmraid_device( new_partition .device_path ) )
1963+ succes = dmraid .create_dev_map_entries( new_partition, operationdetail .get_last_child() ) ;
1964+
1965+ operationdetail .get_last_child() .set_status( succes ? STATUS_SUCCES : STATUS_ERROR ) ;
1966+
1967+ return succes ;
1968+}
1969+
1970+bool GParted_Core::create_filesystem( const Partition & partition, OperationDetail & operationdetail )
1971+{
1972+ /*TO TRANSLATORS: looks like create new ext3 file system */
1973+ operationdetail .add_child( OperationDetail( String::ucompose(
1974+ _("create new %1 file system"),
1975+ Utils::get_filesystem_string( partition .filesystem ) ) ) ) ;
1976+
1977+ bool succes = false ;
1978+ switch ( get_fs( partition .filesystem ) .create )
1979+ {
1980+ case GParted::FS::NONE:
1981+ break ;
1982+ case GParted::FS::GPARTED:
1983+ break ;
1984+ case GParted::FS::LIBPARTED:
1985+ break ;
1986+ case GParted::FS::EXTERNAL:
1987+ succes = set_proper_filesystem( partition .filesystem ) &&
1988+ p_filesystem ->create( partition, operationdetail .get_last_child() ) ;
1989+
1990+ break ;
1991+ }
1992+
1993+ operationdetail .get_last_child() .set_status( succes ? STATUS_SUCCES : STATUS_ERROR ) ;
1994+ return succes ;
1995+}
1996+
1997+bool GParted_Core::format( const Partition & partition, OperationDetail & operationdetail )
1998+{
1999+ //remove all file system signatures...
2000+ erase_filesystem_signatures( partition ) ;
2001+
2002+ return set_partition_type( partition, operationdetail ) && create_filesystem( partition, operationdetail ) ;
2003+}
2004+
2005+bool GParted_Core::Delete( const Partition & partition, OperationDetail & operationdetail )
2006+{
2007+ operationdetail .add_child( OperationDetail( _("delete partition") ) ) ;
2008+
2009+ bool succes = false ;
2010+ if ( open_device_and_disk( partition .device_path ) )
2011+ {
2012+ if ( partition .type == TYPE_EXTENDED )
2013+ lp_partition = ped_disk_extended_partition( lp_disk ) ;
2014+ else
2015+ lp_partition = ped_disk_get_partition_by_sector( lp_disk, partition .get_sector() ) ;
2016+
2017+ succes = ped_disk_delete_partition( lp_disk, lp_partition ) && commit() ;
2018+
2019+ close_device_and_disk() ;
2020+ }
2021+
2022+ //delete partition dev mapper entry, and delete and recreate all other affected dev mapper entries if dmraid
2023+ DMRaid dmraid ;
2024+ if ( succes && dmraid .is_dmraid_device( partition .device_path ) )
2025+ {
2026+ //Open disk handle before and close after to prevent application crash.
2027+ if ( open_device_and_disk( partition .device_path ) )
2028+ {
2029+ if ( ! dmraid .delete_affected_dev_map_entries( partition, operationdetail .get_last_child() ) )
2030+ succes = false ; //comand failed
2031+
2032+ if ( ! dmraid .create_dev_map_entries( partition, operationdetail .get_last_child() ) )
2033+ succes = false ; //command failed
2034+
2035+ close_device_and_disk() ;
2036+ }
2037+ }
2038+
2039+ operationdetail .get_last_child() .set_status( succes ? STATUS_SUCCES : STATUS_ERROR ) ;
2040+ return succes ;
2041+}
2042+
2043+bool GParted_Core::label_partition( const Partition & partition, OperationDetail & operationdetail )
2044+{
2045+ if( partition .label .empty() ) {
2046+ operationdetail .add_child( OperationDetail( String::ucompose(
2047+ _("Clear partition label on %1"),
2048+ partition .get_path()
2049+ ) ) ) ;
2050+ } else {
2051+ operationdetail .add_child( OperationDetail( String::ucompose(
2052+ _("Set partition label to \"%1\" on %2"),
2053+ partition .label, partition .get_path()
2054+ ) ) ) ;
2055+ }
2056+
2057+ bool succes = false ;
2058+ if ( partition .type != TYPE_EXTENDED )
2059+ {
2060+ switch( get_fs( partition .filesystem ) .write_label )
2061+ {
2062+ case FS::EXTERNAL:
2063+ succes = set_proper_filesystem( partition .filesystem ) &&
2064+ p_filesystem ->write_label( partition, operationdetail .get_last_child() ) ;
2065+ break ;
2066+ case FS::LIBPARTED:
2067+ break ;
2068+
2069+ default:
2070+ break ;
2071+ }
2072+ }
2073+
2074+ operationdetail .get_last_child() .set_status( succes ? STATUS_SUCCES : STATUS_ERROR ) ;
2075+
2076+ return succes ;
2077+}
2078+
2079+bool GParted_Core::resize_move( const Device & device,
2080+ const Partition & partition_old,
2081+ Partition & partition_new,
2082+ OperationDetail & operationdetail )
2083+{
2084+ if ( (partition_new .alignment == ALIGN_STRICT)
2085+ || (partition_new .alignment == ALIGN_MEBIBYTE)
2086+ || partition_new .strict_start
2087+ || calculate_exact_geom( partition_old, partition_new, operationdetail )
2088+ )
2089+ {
2090+ if ( partition_old .type == TYPE_EXTENDED )
2091+ return resize_move_partition( partition_old, partition_new, operationdetail ) ;
2092+
2093+ if ( partition_new .sector_start == partition_old .sector_start )
2094+ return resize( partition_old, partition_new, operationdetail ) ;
2095+
2096+ if ( partition_new .get_sector_length() == partition_old .get_sector_length() )
2097+ return move( device, partition_old, partition_new, operationdetail ) ;
2098+
2099+ Partition temp ;
2100+ if ( partition_new .get_sector_length() > partition_old .get_sector_length() )
2101+ {
2102+ //first move, then grow. Since old.length < new.length and new.start is valid, temp is valid.
2103+ temp = partition_new ;
2104+ temp .sector_end = temp .sector_start + partition_old .get_sector_length() -1 ;
2105+ }
2106+
2107+ if ( partition_new .get_sector_length() < partition_old .get_sector_length() )
2108+ {
2109+ //first shrink, then move. Since new.length < old.length and old.start is valid, temp is valid.
2110+ temp = partition_old ;
2111+ temp .sector_end = partition_old .sector_start + partition_new .get_sector_length() -1 ;
2112+ }
2113+
2114+ PartitionAlignment previous_alignment = temp .alignment ;
2115+ temp .alignment = ALIGN_STRICT ;
2116+ bool succes = resize_move( device, partition_old, temp, operationdetail ) ;
2117+ temp .alignment = previous_alignment ;
2118+
2119+ return succes && resize_move( device, temp, partition_new, operationdetail ) ;
2120+ }
2121+
2122+ return false ;
2123+}
2124+
2125+bool GParted_Core::move( const Device & device,
2126+ const Partition & partition_old,
2127+ const Partition & partition_new,
2128+ OperationDetail & operationdetail )
2129+{
2130+ if ( partition_old .get_sector_length() != partition_new .get_sector_length() )
2131+ {
2132+ operationdetail .add_child( OperationDetail(
2133+ /* TO TRANSLATORS: moving requires old and new length to be the same
2134+ * means that the length in bytes of the old partition and new partition
2135+ * must be the same. If the sector sizes of the old partition and the
2136+ * new partition are the same, then the length in sectors must be the same.
2137+ */
2138+ _("moving requires old and new length to be the same"), STATUS_ERROR, FONT_ITALIC ) ) ;
2139+
2140+ return false ;
2141+ }
2142+
2143+ bool succes = false ;
2144+ if ( check_repair_filesystem( partition_old, operationdetail ) )
2145+ {
2146+ //NOTE: Logical partitions are preceded by meta data. To prevent this
2147+ // meta data from being overwritten we first expand the partition to
2148+ // encompass all of the space involved in the move. In this way we
2149+ // prevent overwriting the meta data for this partition when we move
2150+ // this partition to the left. We also prevent overwriting the meta
2151+ // data of a following partition when we move this partition to the
2152+ // right.
2153+ Partition partition_all_space = partition_old ;
2154+ partition_all_space .alignment = ALIGN_STRICT ;
2155+ if ( partition_new .sector_start < partition_all_space. sector_start )
2156+ partition_all_space .sector_start = partition_new. sector_start ;
2157+ if ( partition_new .sector_end > partition_all_space.sector_end )
2158+ partition_all_space .sector_end = partition_new. sector_end ;
2159+
2160+ //Make old partition all encompassing and if move file system fails
2161+ // then return partition table to original state
2162+ if ( resize_move_partition( partition_old, partition_all_space, operationdetail ) )
2163+ {
2164+ //Note move of file system is from old values to new values, not from
2165+ // the all encompassing values.
2166+ if ( ! move_filesystem( partition_old, partition_new, operationdetail ) )
2167+ {
2168+ operationdetail .add_child( OperationDetail( _("rollback last change to the partition table") ) ) ;
2169+
2170+ Partition partition_restore = partition_old ;
2171+ partition_restore .alignment = ALIGN_STRICT ; //Ensure that old partition boundaries are not modified
2172+ if ( resize_move_partition( partition_all_space, partition_restore, operationdetail .get_last_child() ) )
2173+ operationdetail .get_last_child() .set_status( STATUS_SUCCES ) ;
2174+ else
2175+ operationdetail .get_last_child() .set_status( STATUS_ERROR ) ;
2176+ }
2177+ else
2178+ succes = true ;
2179+ }
2180+
2181+ //Make new partition from all encompassing partition
2182+ succes = succes && resize_move_partition( partition_all_space, partition_new, operationdetail ) ;
2183+
2184+ succes = succes &&
2185+ update_bootsector( partition_new, operationdetail ) &&
2186+ check_repair_filesystem( partition_new, operationdetail ) &&
2187+ maximize_filesystem( partition_new, operationdetail ) ;
2188+ }
2189+
2190+ return succes ;
2191+}
2192+
2193+bool GParted_Core::move_filesystem( const Partition & partition_old,
2194+ const Partition & partition_new,
2195+ OperationDetail & operationdetail )
2196+{
2197+ if ( partition_new .sector_start < partition_old .sector_start )
2198+ operationdetail .add_child( OperationDetail( _("move file system to the left") ) ) ;
2199+ else if ( partition_new .sector_start > partition_old .sector_start )
2200+ operationdetail .add_child( OperationDetail( _("move file system to the right") ) ) ;
2201+ else
2202+ {
2203+ operationdetail .add_child( OperationDetail( _("move file system") ) ) ;
2204+ operationdetail .get_last_child() .add_child(
2205+ OperationDetail( _("new and old file system have the same position. Hence skipping this operation"),
2206+ STATUS_NONE,
2207+ FONT_ITALIC ) ) ;
2208+
2209+ operationdetail .get_last_child() .set_status( STATUS_SUCCES ) ;
2210+ return true ;
2211+ }
2212+
2213+ bool succes = false ;
2214+ switch ( get_fs( partition_old .filesystem ) .move )
2215+ {
2216+ case GParted::FS::NONE:
2217+ break ;
2218+ case GParted::FS::GPARTED:
2219+ succes = false ;
2220+ if ( partition_new .test_overlap( partition_old ) )
2221+ {
2222+ if ( copy_filesystem_simulation( partition_old, partition_new, operationdetail .get_last_child() ) )
2223+ {
2224+ operationdetail .get_last_child() .add_child( OperationDetail( _("perform real move") ) ) ;
2225+
2226+ Sector total_done ;
2227+ succes = copy_filesystem( partition_old,
2228+ partition_new,
2229+ operationdetail .get_last_child() .get_last_child(),
2230+ total_done ) ;
2231+
2232+ operationdetail .get_last_child() .get_last_child()
2233+ .set_status( succes ? STATUS_SUCCES : STATUS_ERROR ) ;
2234+ if ( ! succes )
2235+ {
2236+ rollback_transaction( partition_old,
2237+ partition_new,
2238+ operationdetail .get_last_child(),
2239+ total_done ) ;
2240+
2241+ check_repair_filesystem( partition_old, operationdetail ) ;
2242+ }
2243+ }
2244+ }
2245+ else
2246+ succes = copy_filesystem( partition_old, partition_new, operationdetail .get_last_child() ) ;
2247+
2248+ break ;
2249+ case GParted::FS::LIBPARTED:
2250+ succes = resize_move_filesystem_using_libparted( partition_old,
2251+ partition_new,
2252+ operationdetail .get_last_child() ) ;
2253+ break ;
2254+ case GParted::FS::EXTERNAL:
2255+ succes = set_proper_filesystem( partition_new .filesystem ) &&
2256+ p_filesystem ->move( partition_old
2257+ , partition_new
2258+ , operationdetail .get_last_child()
2259+ ) ;
2260+ break ;
2261+ }
2262+
2263+ operationdetail .get_last_child() .set_status( succes ? STATUS_SUCCES : STATUS_ERROR ) ;
2264+ return succes ;
2265+}
2266+
2267+bool GParted_Core::resize_move_filesystem_using_libparted( const Partition & partition_old,
2268+ const Partition & partition_new,
2269+ OperationDetail & operationdetail )
2270+{
2271+ operationdetail .add_child( OperationDetail( _("using libparted"), STATUS_NONE ) ) ;
2272+
2273+ bool return_value = false ;
2274+ if ( open_device_and_disk( partition_old .device_path ) )
2275+ {
2276+ PedFileSystem * fs = NULL ;
2277+ PedGeometry * lp_geom = NULL ;
2278+
2279+ lp_geom = ped_geometry_new( lp_device,
2280+ partition_old .sector_start,
2281+ partition_old .get_sector_length() ) ;
2282+ if ( lp_geom )
2283+ {
2284+ fs = ped_file_system_open( lp_geom );
2285+ if ( fs )
2286+ {
2287+ lp_geom = NULL ;
2288+ lp_geom = ped_geometry_new( lp_device,
2289+ partition_new .sector_start,
2290+ partition_new .get_sector_length() ) ;
2291+ if ( lp_geom )
2292+ return_value = ped_file_system_resize( fs, lp_geom, NULL ) && commit() ;
2293+
2294+ ped_file_system_close( fs );
2295+ }
2296+ }
2297+
2298+ close_device_and_disk() ;
2299+ }
2300+
2301+ return return_value ;
2302+}
2303+
2304+bool GParted_Core::resize( const Partition & partition_old,
2305+ const Partition & partition_new,
2306+ OperationDetail & operationdetail )
2307+{
2308+ if ( partition_old .sector_start != partition_new .sector_start )
2309+ {
2310+ operationdetail .add_child( OperationDetail(
2311+ _("resizing requires old and new start to be the same"), STATUS_ERROR, FONT_ITALIC ) ) ;
2312+
2313+ return false ;
2314+ }
2315+
2316+ bool succes = false ;
2317+ if ( check_repair_filesystem( partition_new, operationdetail ) )
2318+ {
2319+ succes = true ;
2320+
2321+ if ( succes && partition_new .get_sector_length() < partition_old .get_sector_length() )
2322+ succes = resize_filesystem( partition_old, partition_new, operationdetail ) ;
2323+
2324+ if ( succes )
2325+ succes = resize_move_partition( partition_old, partition_new, operationdetail ) ;
2326+
2327+ //these 2 are always executed, however, if 1 of them fails the whole operation fails
2328+ if ( ! check_repair_filesystem( partition_new, operationdetail ) )
2329+ succes = false ;
2330+
2331+ //expand file system to fit exactly in partition
2332+ if ( ! maximize_filesystem( partition_new, operationdetail ) )
2333+ succes = false ;
2334+
2335+ return succes ;
2336+ }
2337+
2338+ return false ;
2339+}
2340+
2341+bool GParted_Core::resize_move_partition( const Partition & partition_old,
2342+ const Partition & partition_new,
2343+ OperationDetail & operationdetail )
2344+{
2345+ //i'm not too happy with this, but i think it is the correct way from a i18n POV
2346+ enum Action
2347+ {
2348+ NONE = 0,
2349+ MOVE_RIGHT = 1,
2350+ MOVE_LEFT = 2,
2351+ GROW = 3,
2352+ SHRINK = 4,
2353+ MOVE_RIGHT_GROW = 5,
2354+ MOVE_RIGHT_SHRINK = 6,
2355+ MOVE_LEFT_GROW = 7,
2356+ MOVE_LEFT_SHRINK = 8
2357+ } ;
2358+ Action action = NONE ;
2359+
2360+ if ( partition_new .get_sector_length() > partition_old .get_sector_length() )
2361+ action = GROW ;
2362+ else if ( partition_new .get_sector_length() < partition_old .get_sector_length() )
2363+ action = SHRINK ;
2364+
2365+ if ( partition_new .sector_start > partition_old .sector_start &&
2366+ partition_new .sector_end > partition_old .sector_end )
2367+ action = action == GROW ? MOVE_RIGHT_GROW : action == SHRINK ? MOVE_RIGHT_SHRINK : MOVE_RIGHT ;
2368+ else if ( partition_new .sector_start < partition_old .sector_start &&
2369+ partition_new .sector_end < partition_old .sector_end )
2370+ action = action == GROW ? MOVE_LEFT_GROW : action == SHRINK ? MOVE_LEFT_SHRINK : MOVE_LEFT ;
2371+
2372+ Glib::ustring description ;
2373+ switch ( action )
2374+ {
2375+ case NONE :
2376+ description = _("resize/move partition") ;
2377+ break ;
2378+ case MOVE_RIGHT :
2379+ description = _("move partition to the right") ;
2380+ break ;
2381+ case MOVE_LEFT :
2382+ description = _("move partition to the left") ;
2383+ break ;
2384+ case GROW :
2385+ description = _("grow partition from %1 to %2") ;
2386+ break ;
2387+ case SHRINK :
2388+ description = _("shrink partition from %1 to %2") ;
2389+ break ;
2390+ case MOVE_RIGHT_GROW :
2391+ description = _("move partition to the right and grow it from %1 to %2") ;
2392+ break ;
2393+ case MOVE_RIGHT_SHRINK :
2394+ description = _("move partition to the right and shrink it from %1 to %2") ;
2395+ break ;
2396+ case MOVE_LEFT_GROW :
2397+ description = _("move partition to the left and grow it from %1 to %2") ;
2398+ break ;
2399+ case MOVE_LEFT_SHRINK :
2400+ description = _("move partition to the left and shrink it from %1 to %2") ;
2401+ break ;
2402+ }
2403+
2404+ if ( ! description .empty() && action != NONE && action != MOVE_LEFT && action != MOVE_RIGHT )
2405+ description = String::ucompose( description,
2406+ Utils::format_size( partition_old .get_sector_length(), partition_old .sector_size ),
2407+ Utils::format_size( partition_new .get_sector_length(), partition_new .sector_size ) ) ;
2408+
2409+ operationdetail .add_child( OperationDetail( description ) ) ;
2410+
2411+
2412+ if ( action == NONE )
2413+ {
2414+ operationdetail .get_last_child() .add_child(
2415+ OperationDetail( _("new and old partition have the same size and position. Hence skipping this operation"),
2416+ STATUS_NONE,
2417+ FONT_ITALIC ) ) ;
2418+
2419+ operationdetail .get_last_child() .set_status( STATUS_SUCCES ) ;
2420+ return true ;
2421+ }
2422+
2423+ operationdetail .get_last_child() .add_child(
2424+ OperationDetail(
2425+ String::ucompose( _("old start: %1"), partition_old .sector_start ) + "\n" +
2426+ String::ucompose( _("old end: %1"), partition_old .sector_end ) + "\n" +
2427+ String::ucompose( _("old size: %1 (%2)"),
2428+ partition_old .get_sector_length(),
2429+ Utils::format_size( partition_old .get_sector_length(), partition_old .sector_size ) ),
2430+ STATUS_NONE,
2431+ FONT_ITALIC ) ) ;
2432+
2433+ //finally the actual resize/move
2434+ bool return_value = false ;
2435+
2436+ PedConstraint *constraint = NULL ;
2437+ lp_partition = NULL ;
2438+
2439+ //sometimes the lp_partition ->geom .start,end and length values display random numbers
2440+ //after going out of the 'if ( lp_partition)' scope. That's why we use some variables here.
2441+ Sector new_start = -1, new_end = -1 ;
2442+
2443+ if ( open_device_and_disk( partition_old .device_path ) )
2444+ {
2445+ if ( partition_old .type == GParted::TYPE_EXTENDED )
2446+ lp_partition = ped_disk_extended_partition( lp_disk ) ;
2447+ else
2448+ lp_partition = ped_disk_get_partition_by_sector( lp_disk, partition_old .get_sector() ) ;
2449+
2450+ if ( lp_partition )
2451+ {
2452+ if ( (partition_new .alignment == ALIGN_STRICT)
2453+ || (partition_new .alignment == ALIGN_MEBIBYTE)
2454+ || partition_new .strict_start
2455+ ) {
2456+ PedGeometry *geom = ped_geometry_new( lp_device,
2457+ partition_new .sector_start,
2458+ partition_new .get_sector_length() ) ;
2459+ constraint = ped_constraint_exact( geom ) ;
2460+ }
2461+ else
2462+ constraint = ped_constraint_any( lp_device ) ;
2463+
2464+ if ( constraint )
2465+ {
2466+ if ( ped_disk_set_partition_geom( lp_disk,
2467+ lp_partition,
2468+ constraint,
2469+ partition_new .sector_start,
2470+ partition_new .sector_end ) )
2471+ {
2472+ new_start = lp_partition ->geom .start ;
2473+ new_end = lp_partition ->geom .end ;
2474+
2475+ return_value = commit() ;
2476+ }
2477+
2478+ ped_constraint_destroy( constraint );
2479+ }
2480+ }
2481+
2482+ close_device_and_disk() ;
2483+ }
2484+
2485+ if ( return_value )
2486+ {
2487+ operationdetail .get_last_child() .add_child(
2488+ OperationDetail(
2489+ String::ucompose( _("new start: %1"), new_start ) + "\n" +
2490+ String::ucompose( _("new end: %1"), new_end ) + "\n" +
2491+ String::ucompose( _("new size: %1 (%2)"),
2492+ new_end - new_start + 1,
2493+ Utils::format_size( new_end - new_start + 1, partition_new .sector_size ) ),
2494+ STATUS_NONE,
2495+ FONT_ITALIC ) ) ;
2496+
2497+ //update dev mapper entry if partition is dmraid.
2498+ DMRaid dmraid ;
2499+ if ( return_value && dmraid .is_dmraid_device( partition_new .device_path ) )
2500+ {
2501+ //Open disk handle before and close after to prevent application crash.
2502+ if ( open_device_and_disk( partition_new .device_path ) )
2503+ {
2504+ return_value = dmraid .update_dev_map_entry( partition_new, operationdetail .get_last_child() ) ;
2505+ close_device_and_disk() ;
2506+ }
2507+ }
2508+ }
2509+
2510+ operationdetail .get_last_child() .set_status( return_value ? STATUS_SUCCES : STATUS_ERROR ) ;
2511+
2512+ return return_value ;
2513+}
2514+
2515+bool GParted_Core::resize_filesystem( const Partition & partition_old,
2516+ const Partition & partition_new,
2517+ OperationDetail & operationdetail,
2518+ bool fill_partition )
2519+{
2520+ //by default 'grow' to accomodate expand_filesystem()
2521+ GParted::FS::Support action = get_fs( partition_old .filesystem ) .grow ;
2522+
2523+ if ( ! fill_partition )
2524+ {
2525+ if ( partition_new .get_sector_length() < partition_old .get_sector_length() )
2526+ {
2527+ operationdetail .add_child( OperationDetail( _("shrink file system") ) ) ;
2528+ action = get_fs( partition_old .filesystem ) .shrink ;
2529+ }
2530+ else if ( partition_new .get_sector_length() > partition_old .get_sector_length() )
2531+ operationdetail .add_child( OperationDetail( _("grow file system") ) ) ;
2532+ else
2533+ {
2534+ operationdetail .add_child( OperationDetail( _("resize file system") ) ) ;
2535+ operationdetail .get_last_child() .add_child(
2536+ OperationDetail(
2537+ _("new and old file system have the same size. Hence skipping this operation"),
2538+ STATUS_NONE,
2539+ FONT_ITALIC ) ) ;
2540+
2541+ operationdetail .get_last_child() .set_status( STATUS_SUCCES ) ;
2542+ return true ;
2543+ }
2544+ }
2545+
2546+ bool succes = false ;
2547+ switch ( action )
2548+ {
2549+ case GParted::FS::NONE:
2550+ break ;
2551+ case GParted::FS::GPARTED:
2552+ break ;
2553+ case GParted::FS::LIBPARTED:
2554+ succes = resize_move_filesystem_using_libparted( partition_old,
2555+ partition_new,
2556+ operationdetail .get_last_child() ) ;
2557+ break ;
2558+ case GParted::FS::EXTERNAL:
2559+ succes = set_proper_filesystem( partition_new .filesystem ) &&
2560+ p_filesystem ->resize( partition_new,
2561+ operationdetail .get_last_child(),
2562+ fill_partition ) ;
2563+ break ;
2564+ }
2565+
2566+ operationdetail .get_last_child() .set_status( succes ? STATUS_SUCCES : STATUS_ERROR ) ;
2567+ return succes ;
2568+}
2569+
2570+bool GParted_Core::maximize_filesystem( const Partition & partition, OperationDetail & operationdetail )
2571+{
2572+ operationdetail .add_child( OperationDetail( _("grow file system to fill the partition") ) ) ;
2573+
2574+ if ( get_fs( partition .filesystem ) .grow == GParted::FS::NONE )
2575+ {
2576+ operationdetail .get_last_child() .add_child(
2577+ OperationDetail( _("growing is not available for this file system"),
2578+ STATUS_NONE,
2579+ FONT_ITALIC ) ) ;
2580+
2581+ operationdetail .get_last_child() .set_status( STATUS_N_A ) ;
2582+ return true ;
2583+ }
2584+
2585+ return resize_filesystem( partition, partition, operationdetail, true ) ;
2586+}
2587+
2588+bool GParted_Core::copy( const Partition & partition_src,
2589+ Partition & partition_dst,
2590+ Byte_Value min_size,
2591+ OperationDetail & operationdetail )
2592+{
2593+ if ( partition_dst .get_byte_length() < partition_src .get_byte_length() )
2594+ {
2595+ operationdetail .add_child( OperationDetail(
2596+ _("the destination is smaller than the source partition"), STATUS_ERROR, FONT_ITALIC ) ) ;
2597+
2598+ return false ;
2599+ }
2600+
2601+ if ( check_repair_filesystem( partition_src, operationdetail ) )
2602+ {
2603+ bool succes = true ;
2604+ if ( partition_dst .status == GParted::STAT_COPY )
2605+ {
2606+ /* Handle situation where src sector size is smaller than dst sector size and an additional partial dst sector is required. */
2607+ succes = create_partition( partition_dst, operationdetail, ( (min_size + (partition_dst .sector_size - 1)) / partition_dst .sector_size ) ) ;
2608+ }
2609+
2610+ if ( succes && set_partition_type( partition_dst, operationdetail ) )
2611+ {
2612+ operationdetail .add_child( OperationDetail(
2613+ String::ucompose( _("copy file system of %1 to %2"),
2614+ partition_src .get_path(),
2615+ partition_dst .get_path() ) ) ) ;
2616+
2617+ switch ( get_fs( partition_dst .filesystem ) .copy )
2618+ {
2619+ case GParted::FS::GPARTED :
2620+ succes = copy_filesystem( partition_src,
2621+ partition_dst,
2622+ operationdetail .get_last_child() ) ;
2623+ break ;
2624+
2625+ case GParted::FS::LIBPARTED :
2626+ //FIXME: see if copying through libparted has any advantages
2627+ break ;
2628+
2629+ case GParted::FS::EXTERNAL :
2630+ succes = set_proper_filesystem( partition_dst .filesystem ) &&
2631+ p_filesystem ->copy( partition_src .get_path(),
2632+ partition_dst .get_path(),
2633+ operationdetail .get_last_child() ) ;
2634+ break ;
2635+
2636+ default :
2637+ succes = false ;
2638+ break ;
2639+ }
2640+
2641+ operationdetail .get_last_child() .set_status( succes ? STATUS_SUCCES : STATUS_ERROR ) ;
2642+
2643+ return succes &&
2644+ update_bootsector( partition_dst, operationdetail ) &&
2645+ check_repair_filesystem( partition_dst, operationdetail ) &&
2646+ maximize_filesystem( partition_dst, operationdetail ) ;
2647+ }
2648+ }
2649+
2650+ return false ;
2651+}
2652+
2653+bool GParted_Core::copy_filesystem_simulation( const Partition & partition_src,
2654+ const Partition & partition_dst,
2655+ OperationDetail & operationdetail )
2656+{
2657+ operationdetail .add_child( OperationDetail( _("perform read-only test") ) ) ;
2658+
2659+ bool succes = copy_filesystem( partition_src, partition_dst, operationdetail .get_last_child(), true ) ;
2660+
2661+ operationdetail .get_last_child() .set_status( succes ? STATUS_SUCCES : STATUS_ERROR ) ;
2662+ return succes ;
2663+}
2664+
2665+bool GParted_Core::copy_filesystem( const Partition & partition_src,
2666+ const Partition & partition_dst,
2667+ OperationDetail & operationdetail,
2668+ bool readonly )
2669+{
2670+ Sector dummy ;
2671+ return copy_filesystem( partition_src .device_path,
2672+ partition_dst .device_path,
2673+ partition_src .sector_start,
2674+ partition_dst .sector_start,
2675+ partition_src .sector_size,
2676+ partition_dst .sector_size,
2677+ partition_src .get_byte_length(),
2678+ operationdetail,
2679+ readonly,
2680+ dummy ) ;
2681+}
2682+
2683+bool GParted_Core::copy_filesystem( const Partition & partition_src,
2684+ const Partition & partition_dst,
2685+ OperationDetail & operationdetail,
2686+ Byte_Value & total_done )
2687+{
2688+ return copy_filesystem( partition_src .device_path,
2689+ partition_dst .device_path,
2690+ partition_src .sector_start,
2691+ partition_dst .sector_start,
2692+ partition_src .sector_size,
2693+ partition_dst .sector_size,
2694+ partition_src .get_byte_length(),
2695+ operationdetail,
2696+ false,
2697+ total_done ) ;
2698+}
2699+
2700+bool GParted_Core::copy_filesystem( const Glib::ustring & src_device,
2701+ const Glib::ustring & dst_device,
2702+ Sector src_start,
2703+ Sector dst_start,
2704+ Byte_Value src_sector_size,
2705+ Byte_Value dst_sector_size,
2706+ Byte_Value src_length,
2707+ OperationDetail & operationdetail,
2708+ bool readonly,
2709+ Byte_Value & total_done )
2710+{
2711+ operationdetail .add_child( OperationDetail( _("using internal algorithm"), STATUS_NONE ) ) ;
2712+ operationdetail .add_child( OperationDetail(
2713+ String::ucompose( readonly ?
2714+ /*TO TRANSLATORS: looks like read 1.00 MiB */
2715+ _("read %1") :
2716+ /*TO TRANSLATORS: looks like copy 1.00 MiB */
2717+ _("copy %1"),
2718+ Utils::format_size( src_length, 1 ) ),
2719+ STATUS_NONE ) ) ;
2720+
2721+ operationdetail .add_child( OperationDetail( _("finding optimal block size"), STATUS_NONE ) ) ;
2722+
2723+ Byte_Value benchmark_blocksize = readonly ? (2 * MEBIBYTE) : (1 * MEBIBYTE), N = (16 * MEBIBYTE) ;
2724+ Byte_Value optimal_blocksize = benchmark_blocksize ;
2725+ Sector offset_read = src_start ;
2726+ Sector offset_write = dst_start ;
2727+
2728+ //Handle situation where we need to perform the copy beginning
2729+ // with the end of the partition and finishing with the start.
2730+ if ( dst_start > src_start )
2731+ {
2732+ offset_read += (src_length/src_sector_size) - (N/src_sector_size) ;
2733+ /* Handle situation where src sector size is smaller than dst sector size and an additional partial dst sector is required. */
2734+ offset_write += ((src_length + (dst_sector_size - 1))/dst_sector_size) - (N/dst_sector_size) ;
2735+ }
2736+
2737+ total_done = 0 ;
2738+ Byte_Value done = 0 ;
2739+ Glib::Timer timer ;
2740+ double smallest_time = 1000000 ;
2741+ bool succes = true ;
2742+
2743+ //Benchmark copy times using different block sizes to determine optimal size
2744+ while ( succes &&
2745+ llabs( done ) + N <= src_length &&
2746+ benchmark_blocksize <= N )
2747+ {
2748+ timer .reset() ;
2749+ succes = copy_blocks( src_device,
2750+ dst_device,
2751+ offset_read + (done / src_sector_size),
2752+ offset_write + (done / dst_sector_size),
2753+ N,
2754+ benchmark_blocksize,
2755+ operationdetail .get_last_child(),
2756+ readonly,
2757+ total_done ) ;
2758+ timer.stop() ;
2759+
2760+ operationdetail .get_last_child() .get_last_child() .add_child( OperationDetail(
2761+ String::ucompose( _("%1 seconds"), timer .elapsed() ), STATUS_NONE, FONT_ITALIC ) ) ;
2762+
2763+ if ( timer .elapsed() <= smallest_time )
2764+ {
2765+ smallest_time = timer .elapsed() ;
2766+ optimal_blocksize = benchmark_blocksize ;
2767+ }
2768+ benchmark_blocksize *= 2 ;
2769+
2770+ if ( ( dst_start > src_start ) )
2771+ done -= N ;
2772+ else
2773+ done += N ;
2774+ }
2775+
2776+ if ( succes )
2777+ operationdetail .get_last_child() .add_child( OperationDetail( String::ucompose(
2778+ /*TO TRANSLATORS: looks like optimal block size is 1.00 MiB */
2779+ _("optimal block size is %1"),
2780+ Utils::format_size( optimal_blocksize, 1 ) ),
2781+ STATUS_NONE ) ) ;
2782+
2783+ if ( succes && llabs( done ) < src_length )
2784+ succes = copy_blocks( src_device,
2785+ dst_device,
2786+ src_start + ( dst_start > src_start ? 0 : (done / src_sector_size) ),
2787+ dst_start + ( dst_start > src_start ? 0 : (done / dst_sector_size) ),
2788+ src_length - llabs( done ),
2789+ optimal_blocksize,
2790+ operationdetail,
2791+ readonly,
2792+ total_done ) ;
2793+
2794+ operationdetail .add_child( OperationDetail(
2795+ String::ucompose( readonly ?
2796+ /*TO TRANSLATORS: looks like 1.00 MiB (1048576 B) read */
2797+ _("%1 (%2 B) read") :
2798+ /*TO TRANSLATORS: looks like 1.00 MiB (1048576 B) copied */
2799+ _("%1 (%2 B) copied"),
2800+ Utils::format_size( total_done, 1 ), total_done ),
2801+ STATUS_NONE ) ) ;
2802+ return succes ;
2803+}
2804+
2805+void GParted_Core::rollback_transaction( const Partition & partition_src,
2806+ const Partition & partition_dst,
2807+ OperationDetail & operationdetail,
2808+ Byte_Value total_done )
2809+{
2810+ if ( total_done > 0 )
2811+ {
2812+ operationdetail .add_child( OperationDetail( _("roll back last transaction") ) ) ;
2813+
2814+ //find out exactly which part of the file system was copied (and to where it was copied)..
2815+ Partition temp_src = partition_src ;
2816+ Partition temp_dst = partition_dst ;
2817+
2818+ if ( partition_dst .sector_start > partition_src .sector_start )
2819+ {
2820+ temp_src .sector_start = temp_src .sector_end - ( (total_done / temp_src .sector_size) - 1 ) ;
2821+ temp_dst .sector_start = temp_dst .sector_end - ( (total_done / temp_dst .sector_size) - 1 ) ;
2822+ }
2823+ else
2824+ {
2825+ temp_src .sector_end = temp_src .sector_start + ( (total_done / temp_src .sector_size) - 1 ) ;
2826+ temp_dst .sector_end = temp_dst .sector_start + ( (total_done / temp_dst .sector_size) - 1 ) ;
2827+ }
2828+
2829+ //and copy it back (NOTE the reversed dst and src)
2830+ bool succes = copy_filesystem( temp_dst, temp_src, operationdetail .get_last_child() ) ;
2831+
2832+ operationdetail .get_last_child() .set_status( succes ? STATUS_SUCCES : STATUS_ERROR ) ;
2833+ }
2834+}
2835+
2836+bool GParted_Core::check_repair_filesystem( const Partition & partition, OperationDetail & operationdetail )
2837+{
2838+ operationdetail .add_child( OperationDetail(
2839+ String::ucompose(
2840+ /* TO TRANSLATORS: looks like check file system on /dev/sda5 for errors and (if possible) fix them */
2841+ _("check file system on %1 for errors and (if possible) fix them"),
2842+ partition .get_path() ) ) ) ;
2843+
2844+ bool succes = false ;
2845+ switch ( get_fs( partition .filesystem ) .check )
2846+ {
2847+ case GParted::FS::NONE:
2848+ operationdetail .get_last_child() .add_child(
2849+ OperationDetail( _("checking is not available for this file system"),
2850+ STATUS_NONE,
2851+ FONT_ITALIC ) ) ;
2852+
2853+ operationdetail .get_last_child() .set_status( STATUS_N_A ) ;
2854+ return true ;
2855+
2856+ break ;
2857+ case GParted::FS::GPARTED:
2858+ break ;
2859+ case GParted::FS::LIBPARTED:
2860+ break ;
2861+ case GParted::FS::EXTERNAL:
2862+ succes = set_proper_filesystem( partition .filesystem ) &&
2863+ p_filesystem ->check_repair( partition, operationdetail .get_last_child() ) ;
2864+
2865+ break ;
2866+ }
2867+
2868+ operationdetail .get_last_child() .set_status( succes ? STATUS_SUCCES : STATUS_ERROR ) ;
2869+ return succes ;
2870+}
2871+
2872+bool GParted_Core::set_partition_type( const Partition & partition, OperationDetail & operationdetail )
2873+{
2874+ operationdetail .add_child( OperationDetail(
2875+ String::ucompose( _("set partition type on %1"), partition .get_path() ) ) ) ;
2876+
2877+ bool return_value = false ;
2878+
2879+ if ( open_device_and_disk( partition .device_path ) )
2880+ {
2881+ PedFileSystemType * fs_type =
2882+ ped_file_system_type_get( Utils::get_filesystem_string( partition .filesystem ) .c_str() ) ;
2883+
2884+ //If not found, and FS is linux-swap, then try linux-swap(v1)
2885+ if ( ! fs_type && Utils::get_filesystem_string( partition .filesystem ) == "linux-swap" )
2886+ fs_type = ped_file_system_type_get( "linux-swap(v1)" ) ;
2887+
2888+ //If not found, and FS is linux-swap, then try linux-swap(new)
2889+ if ( ! fs_type && Utils::get_filesystem_string( partition .filesystem ) == "linux-swap" )
2890+ fs_type = ped_file_system_type_get( "linux-swap(new)" ) ;
2891+
2892+ //default is Linux (83)
2893+ if ( ! fs_type )
2894+ fs_type = ped_file_system_type_get( "ext2" ) ;
2895+
2896+ if ( fs_type )
2897+ {
2898+ lp_partition = ped_disk_get_partition_by_sector( lp_disk, partition .get_sector() ) ;
2899+
2900+ if ( lp_partition &&
2901+ ped_partition_set_system( lp_partition, fs_type ) &&
2902+ commit() )
2903+ {
2904+ operationdetail .get_last_child() .add_child(
2905+ OperationDetail( String::ucompose( _("new partition type: %1"),
2906+ lp_partition ->fs_type ->name ),
2907+ STATUS_NONE,
2908+ FONT_ITALIC ) ) ;
2909+
2910+ return_value = true ;
2911+ }
2912+ }
2913+
2914+ close_device_and_disk() ;
2915+ }
2916+
2917+ operationdetail .get_last_child() .set_status( return_value ? STATUS_SUCCES : STATUS_ERROR ) ;
2918+ return return_value ;
2919+}
2920+
2921+void GParted_Core::set_progress_info( Byte_Value total,
2922+ Byte_Value done,
2923+ const Glib::Timer & timer,
2924+ OperationDetail & operationdetail,
2925+ bool readonly )
2926+{
2927+ operationdetail .fraction = done / static_cast<double>( total ) ;
2928+
2929+ std::time_t time_remaining = Utils::round( (total - done) / ( done / timer .elapsed() ) ) ;
2930+
2931+ operationdetail .progress_text =
2932+ String::ucompose( readonly ?
2933+ /*TO TRANSLATORS: looks like 1.00 MiB of 16.00 MiB read (00:01:59 remaining) */
2934+ _("%1 of %2 read (%3 remaining)") :
2935+ /*TO TRANSLATORS: looks like 1.00 MiB of 16.00 MiB copied (00:01:59 remaining) */
2936+ _("%1 of %2 copied (%3 remaining)"),
2937+ Utils::format_size( done, 1 ),
2938+ Utils::format_size( total,1 ),
2939+ Utils::format_time( time_remaining) ) ;
2940+
2941+ operationdetail .set_description(
2942+ String::ucompose( readonly ?
2943+ /*TO TRANSLATORS: looks like 1.00 MiB of 16.00 MiB read */
2944+ _("%1 of %2 read") :
2945+ /*TO TRANSLATORS: looks like 1.00 MiB of 16.00 MiB copied */
2946+ _("%1 of %2 copied"),
2947+ Utils::format_size( done, 1 ), Utils::format_size( total, 1 ) ),
2948+ FONT_ITALIC ) ;
2949+}
2950+
2951+bool GParted_Core::copy_blocks( const Glib::ustring & src_device,
2952+ const Glib::ustring & dst_device,
2953+ Sector src_start,
2954+ Sector dst_start,
2955+ Byte_Value length,
2956+ Byte_Value blocksize,
2957+ OperationDetail & operationdetail,
2958+ bool readonly,
2959+ Byte_Value & total_done )
2960+{
2961+ if ( blocksize > length )
2962+ blocksize = length ;
2963+
2964+ if ( readonly )
2965+ operationdetail .add_child( OperationDetail(
2966+ /*TO TRANSLATORS: looks like read 16.00 MiB using a block size of 1.00 MiB */
2967+ String::ucompose( _("read %1 using a block size of %2"), Utils::format_size( length, 1 ),
2968+ Utils::format_size( blocksize, 1 ) ) ) ) ;
2969+ else
2970+ operationdetail .add_child( OperationDetail(
2971+ /*TO TRANSLATORS: looks like copy 16.00 MiB using a block size of 1.00 MiB */
2972+ String::ucompose( _("copy %1 using a block size of %2"), Utils::format_size( length, 1 ),
2973+ Utils::format_size( blocksize, 1 ) ) ) ) ;
2974+
2975+ Byte_Value done = length % blocksize ;
2976+
2977+ bool succes = false ;
2978+ PedDevice *lp_device_src = ped_device_get( src_device .c_str() );
2979+ PedDevice *lp_device_dst = src_device != dst_device ? ped_device_get( dst_device .c_str() ) : lp_device_src ;
2980+
2981+ if ( lp_device_src && lp_device_dst && ped_device_open( lp_device_src ) && ped_device_open( lp_device_dst ) )
2982+ {
2983+ Byte_Value src_sector_size = lp_device_src ->sector_size ;
2984+ Byte_Value dst_sector_size = lp_device_dst ->sector_size ;
2985+
2986+ //Handle situation where we need to perform the copy beginning
2987+ // with the end of the partition and finishing with the start.
2988+ if ( dst_start > src_start )
2989+ {
2990+ blocksize -= 2*blocksize ;
2991+ done -= 2*done ;
2992+ src_start += ( (length / src_sector_size) - 1 ) ;
2993+ /* Handle situation where src sector size is smaller than dst sector size and an additional partial dst sector is required. */
2994+ dst_start += ( ((length + (dst_sector_size - 1))/ dst_sector_size) - 1 ) ;
2995+ }
2996+
2997+ Glib::ustring error_message ;
2998+ buf = static_cast<char *>( malloc( llabs( blocksize ) ) ) ;
2999+ if ( buf )
3000+ {
3001+ ped_device_sync( lp_device_dst ) ;
3002+
3003+ succes = true ;
3004+ if ( done != 0 )
3005+ succes = copy_block( lp_device_src,
3006+ lp_device_dst,
3007+ src_start,
3008+ dst_start,
3009+ done,
3010+ error_message,
3011+ readonly ) ;
3012+ if ( ! succes )
3013+ done = 0 ;
3014+
3015+ //add an empty sub which we will constantly update in the loop
3016+ operationdetail .get_last_child() .add_child( OperationDetail( "", STATUS_NONE ) ) ;
3017+
3018+ Glib::Timer timer_progress_timeout, timer_total ;
3019+ while( succes && llabs( done ) < length )
3020+ {
3021+ succes = copy_block( lp_device_src,
3022+ lp_device_dst,
3023+ src_start + (done / src_sector_size),
3024+ dst_start + (done / dst_sector_size),
3025+ blocksize,
3026+ error_message,
3027+ readonly ) ;
3028+ if ( succes )
3029+ done += blocksize ;
3030+
3031+ if ( timer_progress_timeout .elapsed() >= 0.5 )
3032+ {
3033+ set_progress_info( length,
3034+ llabs( done + blocksize ),
3035+ timer_total,
3036+ operationdetail .get_last_child() .get_last_child(),
3037+ readonly ) ;
3038+
3039+ timer_progress_timeout .reset() ;
3040+ }
3041+ }
3042+ //set progress bar current info on completion
3043+ set_progress_info( length,
3044+ llabs( done ),
3045+ timer_total,
3046+ operationdetail .get_last_child() .get_last_child(),
3047+ readonly ) ;
3048+
3049+ free( buf ) ;
3050+ }
3051+ else
3052+ error_message = Glib::strerror( errno ) ;
3053+
3054+ //reset fraction to -1 to make room for a new one (or a pulsebar)
3055+ operationdetail .get_last_child() .get_last_child() .fraction = -1 ;
3056+
3057+ //final description
3058+ operationdetail .get_last_child() .get_last_child() .set_description(
3059+ String::ucompose( readonly ?
3060+ /*TO TRANSLATORS: looks like 1.00 MiB of 16.00 MiB read */
3061+ _("%1 of %2 read") :
3062+ /*TO TRANSLATORS: looks like 1.00 MiB of 16.00 MiB copied */
3063+ _("%1 of %2 copied"),
3064+ Utils::format_size( llabs( done ), 1 ),
3065+ Utils::format_size( length, 1 ) ),
3066+ FONT_ITALIC ) ;
3067+
3068+ if ( ! succes && ! error_message .empty() )
3069+ operationdetail .get_last_child() .add_child(
3070+ OperationDetail( error_message, STATUS_NONE, FONT_ITALIC ) ) ;
3071+
3072+ total_done += llabs( done ) ;
3073+
3074+ //close and destroy the devices..
3075+ ped_device_close( lp_device_src ) ;
3076+ ped_device_destroy( lp_device_src ) ;
3077+
3078+ if ( src_device != dst_device )
3079+ {
3080+ ped_device_close( lp_device_dst ) ;
3081+ ped_device_destroy( lp_device_dst ) ;
3082+ }
3083+ }
3084+
3085+ operationdetail .get_last_child() .set_status( succes ? STATUS_SUCCES : STATUS_ERROR ) ;
3086+ return succes ;
3087+}
3088+
3089+bool GParted_Core::copy_block( PedDevice * lp_device_src,
3090+ PedDevice * lp_device_dst,
3091+ Sector offset_src,
3092+ Sector offset_dst,
3093+ Byte_Value block_length,
3094+ Glib::ustring & error_message,
3095+ bool readonly )
3096+{
3097+ Byte_Value sector_size_src = lp_device_src ->sector_size ;
3098+ Byte_Value sector_size_dst = lp_device_dst ->sector_size ;
3099+
3100+ //Handle case where src and dst sector sizes are different.
3101+ // E.g., 5 sectors x 512 bytes/sector = ??? 2048 byte sectors
3102+ Sector num_blocks_src = (llabs(block_length) + (sector_size_src - 1) ) / sector_size_src ;
3103+ Sector num_blocks_dst = (llabs(block_length) + (sector_size_dst - 1) ) / sector_size_dst ;
3104+
3105+ //Handle situation where we are performing copy operation beginning
3106+ // with the end of the partition and finishing with the start.
3107+ if ( block_length < 0 )
3108+ {
3109+ block_length = llabs( block_length ) ;
3110+ offset_src -= ( (block_length / sector_size_src) - 1 ) ;
3111+ /* Handle situation where src sector size is smaller than dst sector size and an additional partial dst sector is required. */
3112+ offset_dst -= ( ( (block_length + (sector_size_dst - 1)) / sector_size_dst) - 1 ) ;
3113+ }
3114+
3115+ if ( block_length != 0 )
3116+ {
3117+ if ( ped_device_read( lp_device_src, buf, offset_src, num_blocks_src ) )
3118+ {
3119+ if ( readonly || ped_device_write( lp_device_dst, buf, offset_dst, num_blocks_dst ) )
3120+ return true ;
3121+ else
3122+ error_message = String::ucompose( _("Error while writing block at sector %1"), offset_dst ) ;
3123+ }
3124+ else
3125+ error_message = String::ucompose( _("Error while reading block at sector %1"), offset_src ) ;
3126+ }
3127+
3128+ return false ;
3129+}
3130+
3131+bool GParted_Core::calibrate_partition( Partition & partition, OperationDetail & operationdetail )
3132+{
3133+ if ( partition .type == TYPE_PRIMARY || partition .type == TYPE_LOGICAL || partition .type == TYPE_EXTENDED )
3134+ {
3135+ operationdetail .add_child( OperationDetail( String::ucompose( _("calibrate %1"), partition .get_path() ) ) ) ;
3136+
3137+ bool succes = false ;
3138+ if ( open_device_and_disk( partition .device_path ) )
3139+ {
3140+ if ( partition .type == GParted::TYPE_EXTENDED )
3141+ lp_partition = ped_disk_extended_partition( lp_disk ) ;
3142+ else
3143+ lp_partition = ped_disk_get_partition_by_sector( lp_disk, partition .get_sector() ) ;
3144+
3145+ if ( lp_partition )//FIXME: add check to see if lp_partition ->type matches partition .type..
3146+ {
3147+ char * lp_path = ped_partition_get_path( lp_partition ) ;
3148+ partition .add_path( lp_path, true ) ;
3149+ free( lp_path ) ;
3150+
3151+ partition .sector_start = lp_partition ->geom .start ;
3152+ partition .sector_end = lp_partition ->geom .end ;
3153+
3154+ operationdetail .get_last_child() .add_child(
3155+ OperationDetail(
3156+ String::ucompose( _("path: %1"), partition .get_path() ) + "\n" +
3157+ String::ucompose( _("start: %1"), partition .sector_start ) + "\n" +
3158+ String::ucompose( _("end: %1"), partition .sector_end ) + "\n" +
3159+ String::ucompose( _("size: %1 (%2)"),
3160+ partition .get_sector_length(),
3161+ Utils::format_size( partition .get_sector_length(), partition .sector_size ) ),
3162+ STATUS_NONE,
3163+ FONT_ITALIC ) ) ;
3164+ succes = true ;
3165+ }
3166+
3167+ close_device_and_disk() ;
3168+ }
3169+
3170+ operationdetail .get_last_child() .set_status( succes ? STATUS_SUCCES : STATUS_ERROR ) ;
3171+ return succes ;
3172+ }
3173+ else //nothing to calibrate...
3174+ return true ;
3175+}
3176+
3177+bool GParted_Core::calculate_exact_geom( const Partition & partition_old,
3178+ Partition & partition_new,
3179+ OperationDetail & operationdetail )
3180+{
3181+ operationdetail .add_child( OperationDetail(
3182+ String::ucompose( _("calculate new size and position of %1"), partition_new .get_path() ) ) ) ;
3183+
3184+ operationdetail .get_last_child() .add_child(
3185+ OperationDetail(
3186+ String::ucompose( _("requested start: %1"), partition_new .sector_start ) + "\n" +
3187+ String::ucompose( _("requested end: %1"), partition_new .sector_end ) + "\n" +
3188+ String::ucompose( _("requested size: %1 (%2)"),
3189+ partition_new .get_sector_length(),
3190+ Utils::format_size( partition_new .get_sector_length(), partition_new .sector_size ) ),
3191+ STATUS_NONE,
3192+ FONT_ITALIC ) ) ;
3193+
3194+ bool succes = false ;
3195+ if ( open_device_and_disk( partition_old .device_path ) )
3196+ {
3197+ lp_partition = NULL ;
3198+
3199+ if ( partition_old .type == GParted::TYPE_EXTENDED )
3200+ lp_partition = ped_disk_extended_partition( lp_disk ) ;
3201+ else
3202+ lp_partition = ped_disk_get_partition_by_sector( lp_disk, partition_old .get_sector() ) ;
3203+
3204+ if ( lp_partition )
3205+ {
3206+ PedConstraint *constraint = NULL ;
3207+ constraint = ped_constraint_any( lp_device ) ;
3208+
3209+ if ( constraint )
3210+ {
3211+ //FIXME: if we insert a weird partitionnew geom here (e.g. start > end)
3212+ //ped_disk_set_partition_geom() will still return true (althoug an lp exception is written
3213+ //to stdout.. see if this also affect create_partition and resize_move_partition
3214+ //sended a patch to fix this to libparted list. will probably be in 1.7.2
3215+ if ( ped_disk_set_partition_geom( lp_disk,
3216+ lp_partition,
3217+ constraint,
3218+ partition_new .sector_start,
3219+ partition_new .sector_end ) )
3220+ {
3221+ partition_new .sector_start = lp_partition ->geom .start ;
3222+ partition_new .sector_end = lp_partition ->geom .end ;
3223+ succes = true ;
3224+ }
3225+
3226+ ped_constraint_destroy( constraint );
3227+ }
3228+ }
3229+
3230+ close_device_and_disk() ;
3231+ }
3232+
3233+ if ( succes )
3234+ {
3235+ operationdetail .get_last_child() .add_child(
3236+ OperationDetail(
3237+ String::ucompose( _("new start: %1"), partition_new .sector_start ) + "\n" +
3238+ String::ucompose( _("new end: %1"), partition_new .sector_end ) + "\n" +
3239+ String::ucompose( _("new size: %1 (%2)"),
3240+ partition_new .get_sector_length(),
3241+ Utils::format_size( partition_new .get_sector_length(), partition_new .sector_size ) ),
3242+ STATUS_NONE,
3243+ FONT_ITALIC ) ) ;
3244+
3245+ //Update dev mapper entry if partition is dmraid.
3246+ DMRaid dmraid ;
3247+ if ( succes && dmraid .is_dmraid_device( partition_new .device_path ) )
3248+ {
3249+ //Open disk handle before and close after to prevent application crash.
3250+ if ( open_device_and_disk( partition_new .device_path ) )
3251+ {
3252+ succes = dmraid .update_dev_map_entry( partition_new, operationdetail .get_last_child() ) ;
3253+ close_device_and_disk() ;
3254+ }
3255+ }
3256+ }
3257+
3258+ operationdetail .get_last_child() .set_status( succes ? STATUS_SUCCES : STATUS_ERROR ) ;
3259+ return succes ;
3260+}
3261+
3262+bool GParted_Core::set_proper_filesystem( const FILESYSTEM & filesystem )
3263+{
3264+ delete p_filesystem;
3265+
3266+ switch( filesystem )
3267+ {
3268+ case FS_BTRFS : p_filesystem = new btrfs() ; break ;
3269+ case FS_EXT2 : p_filesystem = new ext2() ; break ;
3270+ case FS_EXT3 : p_filesystem = new ext3() ; break ;
3271+ case FS_EXT4 : p_filesystem = new ext4() ; break ;
3272+ case FS_LINUX_SWAP : p_filesystem = new linux_swap() ; break ;
3273+ case FS_FAT16 : p_filesystem = new fat16() ; break ;
3274+ case FS_FAT32 : p_filesystem = new fat32() ; break ;
3275+ case FS_NTFS : p_filesystem = new ntfs() ; break ;
3276+ case FS_REISERFS : p_filesystem = new reiserfs() ; break ;
3277+ case FS_REISER4 : p_filesystem = new reiser4() ; break ;
3278+ case FS_XFS : p_filesystem = new xfs() ; break ;
3279+ case FS_JFS : p_filesystem = new jfs() ; break ;
3280+ case FS_HFS : p_filesystem = new hfs() ; break ;
3281+ case FS_HFSPLUS : p_filesystem = new hfsplus() ; break ;
3282+ case FS_UFS : p_filesystem = new ufs() ; break ;
3283+ default : p_filesystem = NULL ;
3284+ }
3285+
3286+ return p_filesystem ;
3287+}
3288+
3289+bool GParted_Core::erase_filesystem_signatures( const Partition & partition )
3290+{
3291+ bool return_value = false ;
3292+
3293+ if ( open_device_and_disk( partition .device_path ) )
3294+ {
3295+ lp_partition = ped_disk_get_partition_by_sector( lp_disk, partition .get_sector() ) ;
3296+
3297+ if ( lp_partition && ped_file_system_clobber( & lp_partition ->geom ) )
3298+ {
3299+ //file systems not yet supported by libparted
3300+ if ( ped_device_open( lp_device ) )
3301+ {
3302+ //reiser4 stores "ReIsEr4" at sector 128 with a sector size of 512 bytes
3303+ // FIXME writing block of partially uninitialized bytes (security/privacy)
3304+ return_value = ped_geometry_write( & lp_partition ->geom, "0000000", (65536 / lp_device ->sector_size), 1 ) ;
3305+
3306+ ped_device_close( lp_device ) ;
3307+ }
3308+ }
3309+
3310+ close_device_and_disk() ;
3311+ }
3312+
3313+ return return_value ;
3314+}
3315+
3316+bool GParted_Core::update_bootsector( const Partition & partition, OperationDetail & operationdetail )
3317+{
3318+ //only for ntfs atm...
3319+ //FIXME: this should probably be done in the fs classes...
3320+ if ( partition .filesystem == FS_NTFS )
3321+ {
3322+ //The NTFS file system stores a value in the boot record called the
3323+ // Number of Hidden Sectors. This value must match the partition start
3324+ // sector number in order for Windows to boot from the file system.
3325+ // For more details, refer to the NTFS Volume Boot Record at:
3326+ // http://www.geocities.com/thestarman3/asm/mbr/NTFSBR.htm
3327+
3328+ operationdetail .add_child( OperationDetail(
3329+ /*TO TRANSLATORS: update boot sector of ntfs file system on /dev/sdd1 */
3330+ String::ucompose( _("update boot sector of %1 file system on %2"),
3331+ Utils::get_filesystem_string( partition .filesystem ),
3332+ partition .get_path() ) ) ) ;
3333+
3334+ //convert start sector to hex string
3335+ std::stringstream ss ;
3336+ ss << std::hex << partition .sector_start ;
3337+ Glib::ustring hex = ss .str() ;
3338+
3339+ //fill with zeros and reverse...
3340+ hex .insert( 0, 8 - hex .length(), '0' ) ;
3341+ Glib::ustring reversed_hex ;
3342+ for ( int t = 6 ; t >= 0 ; t -=2 )
3343+ reversed_hex .append( hex .substr( t, 2 ) ) ;
3344+
3345+ //convert reversed hex codes into ascii characters
3346+ char buf[4] ;
3347+ for ( unsigned int k = 0; (k < 4 && k < (reversed_hex .length() / 2)); k++ )
3348+ {
3349+ Glib::ustring tmp_hex = "0x" + reversed_hex .substr( k * 2, 2 ) ;
3350+ buf[k] = (char)( std::strtol( tmp_hex .c_str(), NULL, 16 ) ) ;
3351+ }
3352+
3353+ //write new Number of Hidden Sectors value into NTFS boot sector at offset 0x1C
3354+ Glib::ustring error_message = "" ;
3355+ std::ofstream dev_file ;
3356+ dev_file .open( partition .get_path() .c_str(), std::ios::out | std::ios::binary ) ;
3357+ if ( dev_file .is_open() )
3358+ {
3359+ dev_file .seekp( 0x1C ) ;
3360+ if ( dev_file .good() )
3361+ {
3362+ dev_file .write( buf, 4 ) ;
3363+ if ( dev_file .bad() )
3364+ {
3365+ /*TO TRANSLATORS: looks like Error trying to write to boot sector in /dev/sdd1 */
3366+ error_message = String::ucompose( _("Error trying to write to boot sector in %1"), partition .get_path() ) ;
3367+ }
3368+ }
3369+ else
3370+ {
3371+ /*TO TRANSLATORS: looks like Error trying to seek to position 0x1C in /dev/sdd1 */
3372+ error_message = String::ucompose( _("Error trying to seek to position 0x1c in %1"), partition .get_path() ) ;
3373+ }
3374+ dev_file .close( ) ;
3375+ }
3376+ else
3377+ {
3378+ /*TO TRANSLATORS: looks like Error trying to open /dev/sdd1 */
3379+ error_message = String::ucompose( _("Error trying to open %1"), partition .get_path() ) ;
3380+ }
3381+
3382+ //append error messages if any found
3383+ bool succes = true ;
3384+ if ( ! error_message .empty() )
3385+ {
3386+ succes = false ;
3387+ error_message += "\n" ;
3388+ /*TO TRANSLATORS: looks like Failed to set the number of hidden sectors to 05ab4f00 in the ntfs boot record. */
3389+ error_message += String::ucompose( _("Failed to set the number of hidden sectors to %1 in the NTFS boot record."), reversed_hex ) ;
3390+ error_message += "\n" ;
3391+ error_message += String::ucompose( _("You might try the following command to correct the problem:"), reversed_hex ) ;
3392+ error_message += "\n" ;
3393+ error_message += String::ucompose( "echo %1 | xxd -r -p | dd conv=notrunc of=%2 bs=1 seek=28", reversed_hex, partition .get_path() ) ;
3394+ operationdetail .get_last_child() .add_child( OperationDetail( error_message, STATUS_NONE, FONT_ITALIC ) ) ;
3395+ }
3396+
3397+ operationdetail .get_last_child() .set_status( succes ? STATUS_SUCCES : STATUS_ERROR ) ;
3398+ return succes ;
3399+ }
3400+
3401+ return true ;
3402+}
3403+
3404+bool GParted_Core::open_device( const Glib::ustring & device_path )
3405+{
3406+ lp_device = ped_device_get( device_path .c_str() );
3407+
3408+ return lp_device ;
3409+}
3410+
3411+bool GParted_Core::open_device_and_disk( const Glib::ustring & device_path, bool strict )
3412+{
3413+ lp_device = NULL ;
3414+ lp_disk = NULL ;
3415+
3416+ if ( open_device( device_path ) )
3417+ {
3418+ lp_disk = ped_disk_new( lp_device );
3419+
3420+ //if ! disk and writeable it's probably a HD without disklabel.
3421+ //We return true here and deal with them in GParted_Core::get_devices
3422+ if ( lp_disk || ( ! strict && ! lp_device ->read_only ) )
3423+ return true ;
3424+
3425+ close_device_and_disk() ;
3426+ }
3427+
3428+ return false ;
3429+}
3430+
3431+void GParted_Core::close_disk()
3432+{
3433+ if ( lp_disk )
3434+ ped_disk_destroy( lp_disk ) ;
3435+
3436+ lp_disk = NULL ;
3437+}
3438+
3439+void GParted_Core::close_device_and_disk()
3440+{
3441+ close_disk() ;
3442+
3443+ if ( lp_device )
3444+ ped_device_destroy( lp_device ) ;
3445+
3446+ lp_device = NULL ;
3447+}
3448+
3449+bool GParted_Core::commit()
3450+{
3451+ bool succes = ped_disk_commit_to_dev( lp_disk ) ;
3452+
3453+ succes = commit_to_os( 10 ) && succes ;
3454+
3455+ return succes ;
3456+}
3457+
3458+bool GParted_Core::commit_to_os( std::time_t timeout )
3459+{
3460+ DMRaid dmraid ;
3461+ bool succes ;
3462+ if ( dmraid .is_dmraid_device( lp_disk ->dev ->path ) )
3463+ succes = true ;
3464+ else
3465+ {
3466+ succes = ped_disk_commit_to_os( lp_disk ) ;
3467+#ifndef HAVE_LIBPARTED_2_2_0_PLUS
3468+ //Work around to try to alleviate problems caused by
3469+ // bug #604298 - Failure to inform kernel of partition changes
3470+ // If not successful the first time, try one more time.
3471+ if ( ! succes )
3472+ {
3473+ sleep( 1 ) ;
3474+ succes = ped_disk_commit_to_os( lp_disk ) ;
3475+ }
3476+#endif
3477+ }
3478+
3479+ settle_device( timeout ) ;
3480+
3481+ return succes ;
3482+}
3483+
3484+void GParted_Core::settle_device( std::time_t timeout )
3485+{
3486+ if ( ! Glib::find_program_in_path( "udevsettle" ) .empty() )
3487+ Utils::execute_command( "udevsettle --timeout=" + Utils::num_to_str( timeout ) ) ;
3488+ else if ( ! Glib::find_program_in_path( "udevadm" ) .empty() )
3489+ Utils::execute_command( "udevadm settle --timeout=" + Utils::num_to_str( timeout ) ) ;
3490+ else
3491+ sleep( timeout ) ;
3492+}
3493+
3494+PedExceptionOption GParted_Core::ped_exception_handler( PedException * e )
3495+{
3496+ std::cout << e ->message << std::endl ;
3497+
3498+ libparted_messages .push_back( e->message ) ;
3499+
3500+ return PED_EXCEPTION_UNHANDLED ;
3501+}
3502+
3503+GParted_Core::~GParted_Core()
3504+{
3505+ delete p_filesystem;
3506+}
3507+
3508+} //GParted
3509
3510=== modified file '.pc/applied-patches'
3511--- .pc/applied-patches 2010-10-30 11:08:59 +0000
3512+++ .pc/applied-patches 2011-02-23 00:37:58 +0000
3513@@ -1,1 +1,2 @@
3514 01_fix-desktop.patch
3515+02_enable-libparted-dmraid-2.patch
3516
3517=== modified file 'README'
3518--- README 2010-10-30 11:08:59 +0000
3519+++ README 2011-02-23 00:37:58 +0000
3520@@ -67,11 +67,19 @@
3521 perl(XML::Parser) desktop-file-utils
3522
3523 Briefly, the shell commands `./configure; make; make install' should
3524- configure, build, and install this package. If you wish to build
3525- this package without the help documentation use the --disable-doc
3526- flag:
3527+ configure, build, and install this package.
3528+
3529+ If you wish to build this package without the help documentation use
3530+ the --disable-doc flag:
3531 E.g., ./configure --disable-doc
3532-
3533+
3534+ If you wish to build this package to use native libparted /dev/mapper
3535+ dmraid support use the --enable-libparted-dmraid flag:
3536+ E.g., ./configure --enable-libparted-dmraid
3537+
3538+ Please note that more than one configure flags can be used:
3539+ E.g., ./configure --disable-doc --enable-libparted-dmraid
3540+
3541 The INSTALL file contains further GNU installation instructions.
3542
3543
3544
3545=== modified file 'config.h.in'
3546--- config.h.in 2010-10-30 11:08:59 +0000
3547+++ config.h.in 2011-02-23 00:37:58 +0000
3548@@ -81,11 +81,17 @@
3549 /* Define to the one symbol short name of this package. */
3550 #undef PACKAGE_TARNAME
3551
3552+/* Define to the home page for this package. */
3553+#undef PACKAGE_URL
3554+
3555 /* Define to the version of this package. */
3556 #undef PACKAGE_VERSION
3557
3558 /* Define to 1 if you have the ANSI C header files. */
3559 #undef STDC_HEADERS
3560
3561+/* Define to 1 if --enable-libparted-dmraid specified */
3562+#undef USE_LIBPARTED_DMRAID
3563+
3564 /* Version number of package */
3565 #undef VERSION
3566
3567=== modified file 'configure'
3568--- configure 2010-10-30 11:08:59 +0000
3569+++ configure 2011-02-23 00:37:58 +0000
3570@@ -1,62 +1,85 @@
3571 #! /bin/sh
3572 # Guess values for system-dependent variables and create Makefiles.
3573-# Generated by GNU Autoconf 2.61 for gparted 0.7.0.
3574+# Generated by GNU Autoconf 2.67 for gparted 0.7.0.
3575 #
3576 # Report bugs to <https://bugzilla.gnome.org/enter_bug.cgi?product=gparted>.
3577 #
3578+#
3579 # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
3580-# 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
3581+# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software
3582+# Foundation, Inc.
3583+#
3584+#
3585 # This configure script is free software; the Free Software Foundation
3586 # gives unlimited permission to copy, distribute and modify it.
3587-## --------------------- ##
3588-## M4sh Initialization. ##
3589-## --------------------- ##
3590+## -------------------- ##
3591+## M4sh Initialization. ##
3592+## -------------------- ##
3593
3594 # Be more Bourne compatible
3595 DUALCASE=1; export DUALCASE # for MKS sh
3596-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
3597+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
3598 emulate sh
3599 NULLCMD=:
3600- # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
3601+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
3602 # is contrary to our usage. Disable this feature.
3603 alias -g '${1+"$@"}'='"$@"'
3604 setopt NO_GLOB_SUBST
3605 else
3606- case `(set -o) 2>/dev/null` in
3607- *posix*) set -o posix ;;
3608+ case `(set -o) 2>/dev/null` in #(
3609+ *posix*) :
3610+ set -o posix ;; #(
3611+ *) :
3612+ ;;
3613 esac
3614-
3615-fi
3616-
3617-
3618-
3619-
3620-# PATH needs CR
3621-# Avoid depending upon Character Ranges.
3622-as_cr_letters='abcdefghijklmnopqrstuvwxyz'
3623-as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
3624-as_cr_Letters=$as_cr_letters$as_cr_LETTERS
3625-as_cr_digits='0123456789'
3626-as_cr_alnum=$as_cr_Letters$as_cr_digits
3627+fi
3628+
3629+
3630+as_nl='
3631+'
3632+export as_nl
3633+# Printing a long string crashes Solaris 7 /usr/bin/printf.
3634+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
3635+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
3636+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
3637+# Prefer a ksh shell builtin over an external printf program on Solaris,
3638+# but without wasting forks for bash or zsh.
3639+if test -z "$BASH_VERSION$ZSH_VERSION" \
3640+ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
3641+ as_echo='print -r --'
3642+ as_echo_n='print -rn --'
3643+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
3644+ as_echo='printf %s\n'
3645+ as_echo_n='printf %s'
3646+else
3647+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
3648+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
3649+ as_echo_n='/usr/ucb/echo -n'
3650+ else
3651+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
3652+ as_echo_n_body='eval
3653+ arg=$1;
3654+ case $arg in #(
3655+ *"$as_nl"*)
3656+ expr "X$arg" : "X\\(.*\\)$as_nl";
3657+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
3658+ esac;
3659+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
3660+ '
3661+ export as_echo_n_body
3662+ as_echo_n='sh -c $as_echo_n_body as_echo'
3663+ fi
3664+ export as_echo_body
3665+ as_echo='sh -c $as_echo_body as_echo'
3666+fi
3667
3668 # The user is always right.
3669 if test "${PATH_SEPARATOR+set}" != set; then
3670- echo "#! /bin/sh" >conf$$.sh
3671- echo "exit 0" >>conf$$.sh
3672- chmod +x conf$$.sh
3673- if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
3674- PATH_SEPARATOR=';'
3675- else
3676- PATH_SEPARATOR=:
3677- fi
3678- rm -f conf$$.sh
3679-fi
3680-
3681-# Support unset when possible.
3682-if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
3683- as_unset=unset
3684-else
3685- as_unset=false
3686+ PATH_SEPARATOR=:
3687+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
3688+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
3689+ PATH_SEPARATOR=';'
3690+ }
3691 fi
3692
3693
3694@@ -65,20 +88,18 @@
3695 # there to prevent editors from complaining about space-tab.
3696 # (If _AS_PATH_WALK were called with IFS unset, it would disable word
3697 # splitting by setting IFS to empty value.)
3698-as_nl='
3699-'
3700 IFS=" "" $as_nl"
3701
3702 # Find who we are. Look in the path if we contain no directory separator.
3703-case $0 in
3704+case $0 in #((
3705 *[\\/]* ) as_myself=$0 ;;
3706 *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
3707 for as_dir in $PATH
3708 do
3709 IFS=$as_save_IFS
3710 test -z "$as_dir" && as_dir=.
3711- test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
3712-done
3713+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
3714+ done
3715 IFS=$as_save_IFS
3716
3717 ;;
3718@@ -89,354 +110,323 @@
3719 as_myself=$0
3720 fi
3721 if test ! -f "$as_myself"; then
3722- echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
3723- { (exit 1); exit 1; }
3724+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
3725+ exit 1
3726 fi
3727
3728-# Work around bugs in pre-3.0 UWIN ksh.
3729-for as_var in ENV MAIL MAILPATH
3730-do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
3731+# Unset variables that we do not need and which cause bugs (e.g. in
3732+# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
3733+# suppresses any "Segmentation fault" message there. '((' could
3734+# trigger a bug in pdksh 5.2.14.
3735+for as_var in BASH_ENV ENV MAIL MAILPATH
3736+do eval test x\${$as_var+set} = xset \
3737+ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
3738 done
3739 PS1='$ '
3740 PS2='> '
3741 PS4='+ '
3742
3743 # NLS nuisances.
3744-for as_var in \
3745- LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
3746- LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
3747- LC_TELEPHONE LC_TIME
3748-do
3749- if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
3750- eval $as_var=C; export $as_var
3751- else
3752- ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
3753- fi
3754-done
3755-
3756-# Required to use basename.
3757-if expr a : '\(a\)' >/dev/null 2>&1 &&
3758- test "X`expr 00001 : '.*\(...\)'`" = X001; then
3759- as_expr=expr
3760-else
3761- as_expr=false
3762-fi
3763-
3764-if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
3765- as_basename=basename
3766-else
3767- as_basename=false
3768-fi
3769-
3770-
3771-# Name of the executable.
3772-as_me=`$as_basename -- "$0" ||
3773-$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
3774- X"$0" : 'X\(//\)$' \| \
3775- X"$0" : 'X\(/\)' \| . 2>/dev/null ||
3776-echo X/"$0" |
3777- sed '/^.*\/\([^/][^/]*\)\/*$/{
3778- s//\1/
3779- q
3780- }
3781- /^X\/\(\/\/\)$/{
3782- s//\1/
3783- q
3784- }
3785- /^X\/\(\/\).*/{
3786- s//\1/
3787- q
3788- }
3789- s/.*/./; q'`
3790+LC_ALL=C
3791+export LC_ALL
3792+LANGUAGE=C
3793+export LANGUAGE
3794
3795 # CDPATH.
3796-$as_unset CDPATH
3797-
3798+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
3799
3800 if test "x$CONFIG_SHELL" = x; then
3801- if (eval ":") 2>/dev/null; then
3802+ as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
3803+ emulate sh
3804+ NULLCMD=:
3805+ # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
3806+ # is contrary to our usage. Disable this feature.
3807+ alias -g '\${1+\"\$@\"}'='\"\$@\"'
3808+ setopt NO_GLOB_SUBST
3809+else
3810+ case \`(set -o) 2>/dev/null\` in #(
3811+ *posix*) :
3812+ set -o posix ;; #(
3813+ *) :
3814+ ;;
3815+esac
3816+fi
3817+"
3818+ as_required="as_fn_return () { (exit \$1); }
3819+as_fn_success () { as_fn_return 0; }
3820+as_fn_failure () { as_fn_return 1; }
3821+as_fn_ret_success () { return 0; }
3822+as_fn_ret_failure () { return 1; }
3823+
3824+exitcode=0
3825+as_fn_success || { exitcode=1; echo as_fn_success failed.; }
3826+as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
3827+as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
3828+as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
3829+if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
3830+
3831+else
3832+ exitcode=1; echo positional parameters were not saved.
3833+fi
3834+test x\$exitcode = x0 || exit 1"
3835+ as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
3836+ as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
3837+ eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
3838+ test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
3839+test \$(( 1 + 1 )) = 2 || exit 1"
3840+ if (eval "$as_required") 2>/dev/null; then :
3841 as_have_required=yes
3842 else
3843 as_have_required=no
3844 fi
3845-
3846- if test $as_have_required = yes && (eval ":
3847-(as_func_return () {
3848- (exit \$1)
3849-}
3850-as_func_success () {
3851- as_func_return 0
3852-}
3853-as_func_failure () {
3854- as_func_return 1
3855-}
3856-as_func_ret_success () {
3857- return 0
3858-}
3859-as_func_ret_failure () {
3860- return 1
3861-}
3862-
3863-exitcode=0
3864-if as_func_success; then
3865- :
3866-else
3867- exitcode=1
3868- echo as_func_success failed.
3869-fi
3870-
3871-if as_func_failure; then
3872- exitcode=1
3873- echo as_func_failure succeeded.
3874-fi
3875-
3876-if as_func_ret_success; then
3877- :
3878-else
3879- exitcode=1
3880- echo as_func_ret_success failed.
3881-fi
3882-
3883-if as_func_ret_failure; then
3884- exitcode=1
3885- echo as_func_ret_failure succeeded.
3886-fi
3887-
3888-if ( set x; as_func_ret_success y && test x = \"\$1\" ); then
3889- :
3890-else
3891- exitcode=1
3892- echo positional parameters were not saved.
3893-fi
3894-
3895-test \$exitcode = 0) || { (exit 1); exit 1; }
3896-
3897-(
3898- as_lineno_1=\$LINENO
3899- as_lineno_2=\$LINENO
3900- test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" &&
3901- test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; }
3902-") 2> /dev/null; then
3903- :
3904-else
3905- as_candidate_shells=
3906- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
3907+ if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
3908+
3909+else
3910+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
3911+as_found=false
3912 for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
3913 do
3914 IFS=$as_save_IFS
3915 test -z "$as_dir" && as_dir=.
3916- case $as_dir in
3917+ as_found=:
3918+ case $as_dir in #(
3919 /*)
3920 for as_base in sh bash ksh sh5; do
3921- as_candidate_shells="$as_candidate_shells $as_dir/$as_base"
3922+ # Try only shells that exist, to save several forks.
3923+ as_shell=$as_dir/$as_base
3924+ if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
3925+ { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
3926+ CONFIG_SHELL=$as_shell as_have_required=yes
3927+ if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
3928+ break 2
3929+fi
3930+fi
3931 done;;
3932 esac
3933+ as_found=false
3934 done
3935+$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
3936+ { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
3937+ CONFIG_SHELL=$SHELL as_have_required=yes
3938+fi; }
3939 IFS=$as_save_IFS
3940
3941
3942- for as_shell in $as_candidate_shells $SHELL; do
3943- # Try only shells that exist, to save several forks.
3944- if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
3945- { ("$as_shell") 2> /dev/null <<\_ASEOF
3946-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
3947- emulate sh
3948- NULLCMD=:
3949- # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
3950- # is contrary to our usage. Disable this feature.
3951- alias -g '${1+"$@"}'='"$@"'
3952- setopt NO_GLOB_SUBST
3953-else
3954- case `(set -o) 2>/dev/null` in
3955- *posix*) set -o posix ;;
3956-esac
3957-
3958-fi
3959-
3960-
3961-:
3962-_ASEOF
3963-}; then
3964- CONFIG_SHELL=$as_shell
3965- as_have_required=yes
3966- if { "$as_shell" 2> /dev/null <<\_ASEOF
3967-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
3968- emulate sh
3969- NULLCMD=:
3970- # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
3971- # is contrary to our usage. Disable this feature.
3972- alias -g '${1+"$@"}'='"$@"'
3973- setopt NO_GLOB_SUBST
3974-else
3975- case `(set -o) 2>/dev/null` in
3976- *posix*) set -o posix ;;
3977-esac
3978-
3979-fi
3980-
3981-
3982-:
3983-(as_func_return () {
3984- (exit $1)
3985-}
3986-as_func_success () {
3987- as_func_return 0
3988-}
3989-as_func_failure () {
3990- as_func_return 1
3991-}
3992-as_func_ret_success () {
3993- return 0
3994-}
3995-as_func_ret_failure () {
3996- return 1
3997-}
3998-
3999-exitcode=0
4000-if as_func_success; then
4001- :
4002-else
4003- exitcode=1
4004- echo as_func_success failed.
4005-fi
4006-
4007-if as_func_failure; then
4008- exitcode=1
4009- echo as_func_failure succeeded.
4010-fi
4011-
4012-if as_func_ret_success; then
4013- :
4014-else
4015- exitcode=1
4016- echo as_func_ret_success failed.
4017-fi
4018-
4019-if as_func_ret_failure; then
4020- exitcode=1
4021- echo as_func_ret_failure succeeded.
4022-fi
4023-
4024-if ( set x; as_func_ret_success y && test x = "$1" ); then
4025- :
4026-else
4027- exitcode=1
4028- echo positional parameters were not saved.
4029-fi
4030-
4031-test $exitcode = 0) || { (exit 1); exit 1; }
4032-
4033-(
4034- as_lineno_1=$LINENO
4035- as_lineno_2=$LINENO
4036- test "x$as_lineno_1" != "x$as_lineno_2" &&
4037- test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; }
4038-
4039-_ASEOF
4040-}; then
4041- break
4042-fi
4043-
4044-fi
4045-
4046- done
4047-
4048- if test "x$CONFIG_SHELL" != x; then
4049- for as_var in BASH_ENV ENV
4050- do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
4051- done
4052- export CONFIG_SHELL
4053- exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"}
4054-fi
4055-
4056-
4057- if test $as_have_required = no; then
4058- echo This script requires a shell more modern than all the
4059- echo shells that I found on your system. Please install a
4060- echo modern shell, or manually run the script under such a
4061- echo shell if you do have one.
4062- { (exit 1); exit 1; }
4063-fi
4064-
4065-
4066-fi
4067-
4068-fi
4069-
4070-
4071-
4072-(eval "as_func_return () {
4073- (exit \$1)
4074-}
4075-as_func_success () {
4076- as_func_return 0
4077-}
4078-as_func_failure () {
4079- as_func_return 1
4080-}
4081-as_func_ret_success () {
4082- return 0
4083-}
4084-as_func_ret_failure () {
4085- return 1
4086-}
4087-
4088-exitcode=0
4089-if as_func_success; then
4090- :
4091-else
4092- exitcode=1
4093- echo as_func_success failed.
4094-fi
4095-
4096-if as_func_failure; then
4097- exitcode=1
4098- echo as_func_failure succeeded.
4099-fi
4100-
4101-if as_func_ret_success; then
4102- :
4103-else
4104- exitcode=1
4105- echo as_func_ret_success failed.
4106-fi
4107-
4108-if as_func_ret_failure; then
4109- exitcode=1
4110- echo as_func_ret_failure succeeded.
4111-fi
4112-
4113-if ( set x; as_func_ret_success y && test x = \"\$1\" ); then
4114- :
4115-else
4116- exitcode=1
4117- echo positional parameters were not saved.
4118-fi
4119-
4120-test \$exitcode = 0") || {
4121- echo No shell found that supports shell functions.
4122- echo Please tell autoconf@gnu.org about your system,
4123- echo including any error possibly output before this
4124- echo message
4125-}
4126-
4127-
4128-
4129- as_lineno_1=$LINENO
4130- as_lineno_2=$LINENO
4131- test "x$as_lineno_1" != "x$as_lineno_2" &&
4132- test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || {
4133-
4134- # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
4135- # uniformly replaced by the line number. The first 'sed' inserts a
4136- # line-number line after each line using $LINENO; the second 'sed'
4137- # does the real work. The second script uses 'N' to pair each
4138- # line-number line with the line containing $LINENO, and appends
4139- # trailing '-' during substitution so that $LINENO is not a special
4140- # case at line end.
4141- # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
4142- # scripts with optimization help from Paolo Bonzini. Blame Lee
4143- # E. McMahon (1931-1989) for sed's syntax. :-)
4144+ if test "x$CONFIG_SHELL" != x; then :
4145+ # We cannot yet assume a decent shell, so we have to provide a
4146+ # neutralization value for shells without unset; and this also
4147+ # works around shells that cannot unset nonexistent variables.
4148+ BASH_ENV=/dev/null
4149+ ENV=/dev/null
4150+ (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
4151+ export CONFIG_SHELL
4152+ exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"}
4153+fi
4154+
4155+ if test x$as_have_required = xno; then :
4156+ $as_echo "$0: This script requires a shell more modern than all"
4157+ $as_echo "$0: the shells that I found on your system."
4158+ if test x${ZSH_VERSION+set} = xset ; then
4159+ $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
4160+ $as_echo "$0: be upgraded to zsh 4.3.4 or later."
4161+ else
4162+ $as_echo "$0: Please tell bug-autoconf@gnu.org and
4163+$0: https://bugzilla.gnome.org/enter_bug.cgi?product=gparted
4164+$0: about your system, including any error possibly output
4165+$0: before this message. Then install a modern shell, or
4166+$0: manually run the script under such a shell if you do
4167+$0: have one."
4168+ fi
4169+ exit 1
4170+fi
4171+fi
4172+fi
4173+SHELL=${CONFIG_SHELL-/bin/sh}
4174+export SHELL
4175+# Unset more variables known to interfere with behavior of common tools.
4176+CLICOLOR_FORCE= GREP_OPTIONS=
4177+unset CLICOLOR_FORCE GREP_OPTIONS
4178+
4179+## --------------------- ##
4180+## M4sh Shell Functions. ##
4181+## --------------------- ##
4182+# as_fn_unset VAR
4183+# ---------------
4184+# Portably unset VAR.
4185+as_fn_unset ()
4186+{
4187+ { eval $1=; unset $1;}
4188+}
4189+as_unset=as_fn_unset
4190+
4191+# as_fn_set_status STATUS
4192+# -----------------------
4193+# Set $? to STATUS, without forking.
4194+as_fn_set_status ()
4195+{
4196+ return $1
4197+} # as_fn_set_status
4198+
4199+# as_fn_exit STATUS
4200+# -----------------
4201+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
4202+as_fn_exit ()
4203+{
4204+ set +e
4205+ as_fn_set_status $1
4206+ exit $1
4207+} # as_fn_exit
4208+
4209+# as_fn_mkdir_p
4210+# -------------
4211+# Create "$as_dir" as a directory, including parents if necessary.
4212+as_fn_mkdir_p ()
4213+{
4214+
4215+ case $as_dir in #(
4216+ -*) as_dir=./$as_dir;;
4217+ esac
4218+ test -d "$as_dir" || eval $as_mkdir_p || {
4219+ as_dirs=
4220+ while :; do
4221+ case $as_dir in #(
4222+ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
4223+ *) as_qdir=$as_dir;;
4224+ esac
4225+ as_dirs="'$as_qdir' $as_dirs"
4226+ as_dir=`$as_dirname -- "$as_dir" ||
4227+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
4228+ X"$as_dir" : 'X\(//\)[^/]' \| \
4229+ X"$as_dir" : 'X\(//\)$' \| \
4230+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
4231+$as_echo X"$as_dir" |
4232+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
4233+ s//\1/
4234+ q
4235+ }
4236+ /^X\(\/\/\)[^/].*/{
4237+ s//\1/
4238+ q
4239+ }
4240+ /^X\(\/\/\)$/{
4241+ s//\1/
4242+ q
4243+ }
4244+ /^X\(\/\).*/{
4245+ s//\1/
4246+ q
4247+ }
4248+ s/.*/./; q'`
4249+ test -d "$as_dir" && break
4250+ done
4251+ test -z "$as_dirs" || eval "mkdir $as_dirs"
4252+ } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
4253+
4254+
4255+} # as_fn_mkdir_p
4256+# as_fn_append VAR VALUE
4257+# ----------------------
4258+# Append the text in VALUE to the end of the definition contained in VAR. Take
4259+# advantage of any shell optimizations that allow amortized linear growth over
4260+# repeated appends, instead of the typical quadratic growth present in naive
4261+# implementations.
4262+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
4263+ eval 'as_fn_append ()
4264+ {
4265+ eval $1+=\$2
4266+ }'
4267+else
4268+ as_fn_append ()
4269+ {
4270+ eval $1=\$$1\$2
4271+ }
4272+fi # as_fn_append
4273+
4274+# as_fn_arith ARG...
4275+# ------------------
4276+# Perform arithmetic evaluation on the ARGs, and store the result in the
4277+# global $as_val. Take advantage of shells that can avoid forks. The arguments
4278+# must be portable across $(()) and expr.
4279+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
4280+ eval 'as_fn_arith ()
4281+ {
4282+ as_val=$(( $* ))
4283+ }'
4284+else
4285+ as_fn_arith ()
4286+ {
4287+ as_val=`expr "$@" || test $? -eq 1`
4288+ }
4289+fi # as_fn_arith
4290+
4291+
4292+# as_fn_error STATUS ERROR [LINENO LOG_FD]
4293+# ----------------------------------------
4294+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
4295+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
4296+# script with STATUS, using 1 if that was 0.
4297+as_fn_error ()
4298+{
4299+ as_status=$1; test $as_status -eq 0 && as_status=1
4300+ if test "$4"; then
4301+ as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
4302+ $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
4303+ fi
4304+ $as_echo "$as_me: error: $2" >&2
4305+ as_fn_exit $as_status
4306+} # as_fn_error
4307+
4308+if expr a : '\(a\)' >/dev/null 2>&1 &&
4309+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
4310+ as_expr=expr
4311+else
4312+ as_expr=false
4313+fi
4314+
4315+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
4316+ as_basename=basename
4317+else
4318+ as_basename=false
4319+fi
4320+
4321+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
4322+ as_dirname=dirname
4323+else
4324+ as_dirname=false
4325+fi
4326+
4327+as_me=`$as_basename -- "$0" ||
4328+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
4329+ X"$0" : 'X\(//\)$' \| \
4330+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
4331+$as_echo X/"$0" |
4332+ sed '/^.*\/\([^/][^/]*\)\/*$/{
4333+ s//\1/
4334+ q
4335+ }
4336+ /^X\/\(\/\/\)$/{
4337+ s//\1/
4338+ q
4339+ }
4340+ /^X\/\(\/\).*/{
4341+ s//\1/
4342+ q
4343+ }
4344+ s/.*/./; q'`
4345+
4346+# Avoid depending upon Character Ranges.
4347+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
4348+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
4349+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
4350+as_cr_digits='0123456789'
4351+as_cr_alnum=$as_cr_Letters$as_cr_digits
4352+
4353+
4354+ as_lineno_1=$LINENO as_lineno_1a=$LINENO
4355+ as_lineno_2=$LINENO as_lineno_2a=$LINENO
4356+ eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
4357+ test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
4358+ # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-)
4359 sed -n '
4360 p
4361 /[$]LINENO/=
4362@@ -453,8 +443,7 @@
4363 s/-\n.*//
4364 ' >$as_me.lineno &&
4365 chmod +x "$as_me.lineno" ||
4366- { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
4367- { (exit 1); exit 1; }; }
4368+ { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
4369
4370 # Don't try to exec as it changes $[0], causing all sort of problems
4371 # (the dirname of $[0] is not the place where we might find the
4372@@ -464,49 +453,40 @@
4373 exit
4374 }
4375
4376-
4377-if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
4378- as_dirname=dirname
4379-else
4380- as_dirname=false
4381-fi
4382-
4383 ECHO_C= ECHO_N= ECHO_T=
4384-case `echo -n x` in
4385+case `echo -n x` in #(((((
4386 -n*)
4387- case `echo 'x\c'` in
4388+ case `echo 'xy\c'` in
4389 *c*) ECHO_T=' ';; # ECHO_T is single tab character.
4390- *) ECHO_C='\c';;
4391+ xy) ECHO_C='\c';;
4392+ *) echo `echo ksh88 bug on AIX 6.1` > /dev/null
4393+ ECHO_T=' ';;
4394 esac;;
4395 *)
4396 ECHO_N='-n';;
4397 esac
4398
4399-if expr a : '\(a\)' >/dev/null 2>&1 &&
4400- test "X`expr 00001 : '.*\(...\)'`" = X001; then
4401- as_expr=expr
4402-else
4403- as_expr=false
4404-fi
4405-
4406 rm -f conf$$ conf$$.exe conf$$.file
4407 if test -d conf$$.dir; then
4408 rm -f conf$$.dir/conf$$.file
4409 else
4410 rm -f conf$$.dir
4411- mkdir conf$$.dir
4412+ mkdir conf$$.dir 2>/dev/null
4413 fi
4414-echo >conf$$.file
4415-if ln -s conf$$.file conf$$ 2>/dev/null; then
4416- as_ln_s='ln -s'
4417- # ... but there are two gotchas:
4418- # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
4419- # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
4420- # In both cases, we have to default to `cp -p'.
4421- ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
4422+if (echo >conf$$.file) 2>/dev/null; then
4423+ if ln -s conf$$.file conf$$ 2>/dev/null; then
4424+ as_ln_s='ln -s'
4425+ # ... but there are two gotchas:
4426+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
4427+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
4428+ # In both cases, we have to default to `cp -p'.
4429+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
4430+ as_ln_s='cp -p'
4431+ elif ln conf$$.file conf$$ 2>/dev/null; then
4432+ as_ln_s=ln
4433+ else
4434 as_ln_s='cp -p'
4435-elif ln conf$$.file conf$$ 2>/dev/null; then
4436- as_ln_s=ln
4437+ fi
4438 else
4439 as_ln_s='cp -p'
4440 fi
4441@@ -514,7 +494,7 @@
4442 rmdir conf$$.dir 2>/dev/null
4443
4444 if mkdir -p . 2>/dev/null; then
4445- as_mkdir_p=:
4446+ as_mkdir_p='mkdir -p "$as_dir"'
4447 else
4448 test -d ./-p && rmdir ./-p
4449 as_mkdir_p=false
4450@@ -531,12 +511,12 @@
4451 as_test_x='
4452 eval sh -c '\''
4453 if test -d "$1"; then
4454- test -d "$1/.";
4455+ test -d "$1/.";
4456 else
4457- case $1 in
4458- -*)set "./$1";;
4459+ case $1 in #(
4460+ -*)set "./$1";;
4461 esac;
4462- case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in
4463+ case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
4464 ???[sx]*):;;*)false;;esac;fi
4465 '\'' sh
4466 '
4467@@ -551,7 +531,6 @@
4468
4469
4470
4471-
4472 # Check that we are running under the correct shell.
4473 SHELL=${CONFIG_SHELL-/bin/sh}
4474
4475@@ -705,10 +684,11 @@
4476
4477 tagnames=${tagnames+${tagnames},}F77
4478
4479-exec 7<&0 </dev/null 6>&1
4480+test -n "$DJDIR" || exec 7<&0 </dev/null
4481+exec 6>&1
4482
4483 # Name of the host.
4484-# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
4485+# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,
4486 # so uname gets run too.
4487 ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
4488
4489@@ -723,7 +703,6 @@
4490 subdirs=
4491 MFLAGS=
4492 MAKEFLAGS=
4493-SHELL=${CONFIG_SHELL-/bin/sh}
4494
4495 # Identity of this package.
4496 PACKAGE_NAME='gparted'
4497@@ -731,6 +710,7 @@
4498 PACKAGE_VERSION='0.7.0'
4499 PACKAGE_STRING='gparted 0.7.0'
4500 PACKAGE_BUGREPORT='https://bugzilla.gnome.org/enter_bug.cgi?product=gparted'
4501+PACKAGE_URL=''
4502
4503 ac_unique_file="src/main.cc"
4504 # Factoring default headers for most tests.
4505@@ -769,172 +749,192 @@
4506 # include <unistd.h>
4507 #endif"
4508
4509-ac_subst_vars='SHELL
4510+ac_subst_vars='LTLIBOBJS
4511+LIBOBJS
4512+DISABLE_DOC_FALSE
4513+DISABLE_DOC_TRUE
4514+HAVE_GNOME_DOC_UTILS_FALSE
4515+HAVE_GNOME_DOC_UTILS_TRUE
4516+DISTCHECK_CONFIGURE_FLAGS
4517+ENABLE_SK_FALSE
4518+ENABLE_SK_TRUE
4519+DOC_USER_FORMATS
4520+OMF_DIR
4521+HELP_DIR
4522+GTKMM_LIBS
4523+GTKMM_CFLAGS
4524+PKG_CONFIG
4525+ALL_LINGUAS
4526+INTLTOOL_PERL
4527+INTLTOOL_UPDATE
4528+INTLTOOL_MERGE
4529+INTLTOOL_EXTRACT
4530+MSGMERGE
4531+INTLTOOL_POLICY_RULE
4532+INTLTOOL_SERVICE_RULE
4533+INTLTOOL_THEME_RULE
4534+INTLTOOL_SCHEMAS_RULE
4535+INTLTOOL_CAVES_RULE
4536+INTLTOOL_XML_NOMERGE_RULE
4537+INTLTOOL_XML_RULE
4538+INTLTOOL_KBD_RULE
4539+INTLTOOL_XAM_RULE
4540+INTLTOOL_UI_RULE
4541+INTLTOOL_SOUNDLIST_RULE
4542+INTLTOOL_SHEET_RULE
4543+INTLTOOL_SERVER_RULE
4544+INTLTOOL_PONG_RULE
4545+INTLTOOL_OAF_RULE
4546+INTLTOOL_PROP_RULE
4547+INTLTOOL_KEYS_RULE
4548+INTLTOOL_DIRECTORY_RULE
4549+INTLTOOL_DESKTOP_RULE
4550+MKINSTALLDIRS
4551+POSUB
4552+POFILES
4553+PO_IN_DATADIR_FALSE
4554+PO_IN_DATADIR_TRUE
4555+INTLLIBS
4556+INSTOBJEXT
4557+GMOFILES
4558+DATADIRNAME
4559+CATOBJEXT
4560+CATALOGS
4561+XGETTEXT
4562+GMSGFMT
4563+MSGFMT_OPTS
4564+MSGFMT
4565+USE_NLS
4566+GETTEXT_PACKAGE
4567+GKSUPROG
4568+LIBTOOL
4569+ac_ct_F77
4570+FFLAGS
4571+F77
4572+CXXCPP
4573+CPP
4574+NMEDIT
4575+DSYMUTIL
4576+RANLIB
4577+AR
4578+ECHO
4579+LN_S
4580+EGREP
4581+GREP
4582+SED
4583+host_os
4584+host_vendor
4585+host_cpu
4586+host
4587+build_os
4588+build_vendor
4589+build_cpu
4590+build
4591+am__fastdepCXX_FALSE
4592+am__fastdepCXX_TRUE
4593+CXXDEPMODE
4594+ac_ct_CXX
4595+CXXFLAGS
4596+CXX
4597+am__fastdepCC_FALSE
4598+am__fastdepCC_TRUE
4599+CCDEPMODE
4600+AMDEPBACKSLASH
4601+AMDEP_FALSE
4602+AMDEP_TRUE
4603+am__quote
4604+am__include
4605+DEPDIR
4606+OBJEXT
4607+EXEEXT
4608+ac_ct_CC
4609+CPPFLAGS
4610+LDFLAGS
4611+CFLAGS
4612+CC
4613+MAINT
4614+MAINTAINER_MODE_FALSE
4615+MAINTAINER_MODE_TRUE
4616+am__untar
4617+am__tar
4618+AMTAR
4619+am__leading_dot
4620+SET_MAKE
4621+AWK
4622+mkdir_p
4623+MKDIR_P
4624+INSTALL_STRIP_PROGRAM
4625+STRIP
4626+install_sh
4627+MAKEINFO
4628+AUTOHEADER
4629+AUTOMAKE
4630+AUTOCONF
4631+ACLOCAL
4632+VERSION
4633+PACKAGE
4634+CYGPATH_W
4635+am__isrc
4636+INSTALL_DATA
4637+INSTALL_SCRIPT
4638+INSTALL_PROGRAM
4639+target_alias
4640+host_alias
4641+build_alias
4642+LIBS
4643+ECHO_T
4644+ECHO_N
4645+ECHO_C
4646+DEFS
4647+mandir
4648+localedir
4649+libdir
4650+psdir
4651+pdfdir
4652+dvidir
4653+htmldir
4654+infodir
4655+docdir
4656+oldincludedir
4657+includedir
4658+localstatedir
4659+sharedstatedir
4660+sysconfdir
4661+datadir
4662+datarootdir
4663+libexecdir
4664+sbindir
4665+bindir
4666+program_transform_name
4667+prefix
4668+exec_prefix
4669+PACKAGE_URL
4670+PACKAGE_BUGREPORT
4671+PACKAGE_STRING
4672+PACKAGE_VERSION
4673+PACKAGE_TARNAME
4674+PACKAGE_NAME
4675 PATH_SEPARATOR
4676-PACKAGE_NAME
4677-PACKAGE_TARNAME
4678-PACKAGE_VERSION
4679-PACKAGE_STRING
4680-PACKAGE_BUGREPORT
4681-exec_prefix
4682-prefix
4683-program_transform_name
4684-bindir
4685-sbindir
4686-libexecdir
4687-datarootdir
4688-datadir
4689-sysconfdir
4690-sharedstatedir
4691-localstatedir
4692-includedir
4693-oldincludedir
4694-docdir
4695-infodir
4696-htmldir
4697-dvidir
4698-pdfdir
4699-psdir
4700-libdir
4701-localedir
4702-mandir
4703-DEFS
4704-ECHO_C
4705-ECHO_N
4706-ECHO_T
4707-LIBS
4708-build_alias
4709-host_alias
4710-target_alias
4711-INSTALL_PROGRAM
4712-INSTALL_SCRIPT
4713-INSTALL_DATA
4714-am__isrc
4715-CYGPATH_W
4716-PACKAGE
4717-VERSION
4718-ACLOCAL
4719-AUTOCONF
4720-AUTOMAKE
4721-AUTOHEADER
4722-MAKEINFO
4723-install_sh
4724-STRIP
4725-INSTALL_STRIP_PROGRAM
4726-mkdir_p
4727-AWK
4728-SET_MAKE
4729-am__leading_dot
4730-AMTAR
4731-am__tar
4732-am__untar
4733-MAINTAINER_MODE_TRUE
4734-MAINTAINER_MODE_FALSE
4735-MAINT
4736-CC
4737-CFLAGS
4738-LDFLAGS
4739-CPPFLAGS
4740-ac_ct_CC
4741-EXEEXT
4742-OBJEXT
4743-DEPDIR
4744-am__include
4745-am__quote
4746-AMDEP_TRUE
4747-AMDEP_FALSE
4748-AMDEPBACKSLASH
4749-CCDEPMODE
4750-am__fastdepCC_TRUE
4751-am__fastdepCC_FALSE
4752-CXX
4753-CXXFLAGS
4754-ac_ct_CXX
4755-CXXDEPMODE
4756-am__fastdepCXX_TRUE
4757-am__fastdepCXX_FALSE
4758-build
4759-build_cpu
4760-build_vendor
4761-build_os
4762-host
4763-host_cpu
4764-host_vendor
4765-host_os
4766-SED
4767-GREP
4768-EGREP
4769-LN_S
4770-ECHO
4771-AR
4772-RANLIB
4773-DSYMUTIL
4774-NMEDIT
4775-CPP
4776-CXXCPP
4777-F77
4778-FFLAGS
4779-ac_ct_F77
4780-LIBTOOL
4781-GKSUPROG
4782-GETTEXT_PACKAGE
4783-USE_NLS
4784-MSGFMT
4785-MSGFMT_OPTS
4786-GMSGFMT
4787-XGETTEXT
4788-CATALOGS
4789-CATOBJEXT
4790-DATADIRNAME
4791-GMOFILES
4792-INSTOBJEXT
4793-INTLLIBS
4794-PO_IN_DATADIR_TRUE
4795-PO_IN_DATADIR_FALSE
4796-POFILES
4797-POSUB
4798-MKINSTALLDIRS
4799-INTLTOOL_DESKTOP_RULE
4800-INTLTOOL_DIRECTORY_RULE
4801-INTLTOOL_KEYS_RULE
4802-INTLTOOL_PROP_RULE
4803-INTLTOOL_OAF_RULE
4804-INTLTOOL_PONG_RULE
4805-INTLTOOL_SERVER_RULE
4806-INTLTOOL_SHEET_RULE
4807-INTLTOOL_SOUNDLIST_RULE
4808-INTLTOOL_UI_RULE
4809-INTLTOOL_XAM_RULE
4810-INTLTOOL_KBD_RULE
4811-INTLTOOL_XML_RULE
4812-INTLTOOL_XML_NOMERGE_RULE
4813-INTLTOOL_CAVES_RULE
4814-INTLTOOL_SCHEMAS_RULE
4815-INTLTOOL_THEME_RULE
4816-INTLTOOL_SERVICE_RULE
4817-INTLTOOL_POLICY_RULE
4818-MSGMERGE
4819-INTLTOOL_EXTRACT
4820-INTLTOOL_MERGE
4821-INTLTOOL_UPDATE
4822-INTLTOOL_PERL
4823-ALL_LINGUAS
4824-PKG_CONFIG
4825-GTKMM_CFLAGS
4826-GTKMM_LIBS
4827-HELP_DIR
4828-OMF_DIR
4829-DOC_USER_FORMATS
4830-ENABLE_SK_TRUE
4831-ENABLE_SK_FALSE
4832-DISTCHECK_CONFIGURE_FLAGS
4833-HAVE_GNOME_DOC_UTILS_TRUE
4834-HAVE_GNOME_DOC_UTILS_FALSE
4835-DISABLE_DOC_TRUE
4836-DISABLE_DOC_FALSE
4837-LIBOBJS
4838-LTLIBOBJS'
4839+SHELL'
4840 ac_subst_files=''
4841+ac_user_opts='
4842+enable_option_checking
4843+enable_maintainer_mode
4844+enable_dependency_tracking
4845+enable_shared
4846+enable_static
4847+enable_fast_install
4848+with_gnu_ld
4849+enable_libtool_lock
4850+with_pic
4851+with_tags
4852+enable_doc
4853+with_help_dir
4854+with_omf_dir
4855+with_help_formats
4856+enable_scrollkeeper
4857+enable_libparted_dmraid
4858+'
4859 ac_precious_vars='build_alias
4860 host_alias
4861 target_alias
4862@@ -958,6 +958,8 @@
4863 # Initialize some variables set by options.
4864 ac_init_help=
4865 ac_init_version=false
4866+ac_unrecognized_opts=
4867+ac_unrecognized_sep=
4868 # The variables have the same names as the options, with
4869 # dashes changed to underlines.
4870 cache_file=/dev/null
4871@@ -1013,8 +1015,9 @@
4872 fi
4873
4874 case $ac_option in
4875- *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
4876- *) ac_optarg=yes ;;
4877+ *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
4878+ *=) ac_optarg= ;;
4879+ *) ac_optarg=yes ;;
4880 esac
4881
4882 # Accept the important Cygnus configure options, so we can diagnose typos.
4883@@ -1056,13 +1059,20 @@
4884 datarootdir=$ac_optarg ;;
4885
4886 -disable-* | --disable-*)
4887- ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
4888+ ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
4889 # Reject names that are not valid shell variable names.
4890- expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null &&
4891- { echo "$as_me: error: invalid feature name: $ac_feature" >&2
4892- { (exit 1); exit 1; }; }
4893- ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'`
4894- eval enable_$ac_feature=no ;;
4895+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
4896+ as_fn_error $? "invalid feature name: $ac_useropt"
4897+ ac_useropt_orig=$ac_useropt
4898+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
4899+ case $ac_user_opts in
4900+ *"
4901+"enable_$ac_useropt"
4902+"*) ;;
4903+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
4904+ ac_unrecognized_sep=', ';;
4905+ esac
4906+ eval enable_$ac_useropt=no ;;
4907
4908 -docdir | --docdir | --docdi | --doc | --do)
4909 ac_prev=docdir ;;
4910@@ -1075,13 +1085,20 @@
4911 dvidir=$ac_optarg ;;
4912
4913 -enable-* | --enable-*)
4914- ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
4915+ ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
4916 # Reject names that are not valid shell variable names.
4917- expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null &&
4918- { echo "$as_me: error: invalid feature name: $ac_feature" >&2
4919- { (exit 1); exit 1; }; }
4920- ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'`
4921- eval enable_$ac_feature=\$ac_optarg ;;
4922+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
4923+ as_fn_error $? "invalid feature name: $ac_useropt"
4924+ ac_useropt_orig=$ac_useropt
4925+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
4926+ case $ac_user_opts in
4927+ *"
4928+"enable_$ac_useropt"
4929+"*) ;;
4930+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
4931+ ac_unrecognized_sep=', ';;
4932+ esac
4933+ eval enable_$ac_useropt=\$ac_optarg ;;
4934
4935 -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
4936 | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
4937@@ -1272,22 +1289,36 @@
4938 ac_init_version=: ;;
4939
4940 -with-* | --with-*)
4941- ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
4942+ ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
4943 # Reject names that are not valid shell variable names.
4944- expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null &&
4945- { echo "$as_me: error: invalid package name: $ac_package" >&2
4946- { (exit 1); exit 1; }; }
4947- ac_package=`echo $ac_package | sed 's/[-.]/_/g'`
4948- eval with_$ac_package=\$ac_optarg ;;
4949+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
4950+ as_fn_error $? "invalid package name: $ac_useropt"
4951+ ac_useropt_orig=$ac_useropt
4952+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
4953+ case $ac_user_opts in
4954+ *"
4955+"with_$ac_useropt"
4956+"*) ;;
4957+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
4958+ ac_unrecognized_sep=', ';;
4959+ esac
4960+ eval with_$ac_useropt=\$ac_optarg ;;
4961
4962 -without-* | --without-*)
4963- ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
4964+ ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
4965 # Reject names that are not valid shell variable names.
4966- expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null &&
4967- { echo "$as_me: error: invalid package name: $ac_package" >&2
4968- { (exit 1); exit 1; }; }
4969- ac_package=`echo $ac_package | sed 's/[-.]/_/g'`
4970- eval with_$ac_package=no ;;
4971+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
4972+ as_fn_error $? "invalid package name: $ac_useropt"
4973+ ac_useropt_orig=$ac_useropt
4974+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
4975+ case $ac_user_opts in
4976+ *"
4977+"with_$ac_useropt"
4978+"*) ;;
4979+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
4980+ ac_unrecognized_sep=', ';;
4981+ esac
4982+ eval with_$ac_useropt=no ;;
4983
4984 --x)
4985 # Obsolete; use --with-x.
4986@@ -1307,25 +1338,25 @@
4987 | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
4988 x_libraries=$ac_optarg ;;
4989
4990- -*) { echo "$as_me: error: unrecognized option: $ac_option
4991-Try \`$0 --help' for more information." >&2
4992- { (exit 1); exit 1; }; }
4993+ -*) as_fn_error $? "unrecognized option: \`$ac_option'
4994+Try \`$0 --help' for more information"
4995 ;;
4996
4997 *=*)
4998 ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
4999 # Reject names that are not valid shell variable names.
5000- expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches

to all changes: