Import packaging files
[parted/debian/parted.git] / debian / patches / kfreebsd-gnu.dpatch
1 #! /bin/sh /usr/share/dpatch/dpatch-run
2 ## kfreebsd-gnu.dpatch by Otavio Salvador <otavio@debian.org>
3 ##
4 ## All lines beginning with `## DP:' are a description of the patch.
5 ## DP: This dpatch was make to include the patch built by Robert Millan.
6 ## DP: Closes: #363381
7 ## DP: Upstream: not merged
8
9 @DPATCH@
10 diff -urNad parted-1.7.0~/configure.ac parted-1.7.0/configure.ac
11 --- parted-1.7.0~/configure.ac  2006-05-19 03:54:01.000000000 -0300
12 +++ parted-1.7.0/configure.ac   2006-05-19 03:54:02.000000000 -0300
13 @@ -48,6 +48,8 @@
14         linux*) OS=linux ;;
15         gnu*)   OS=gnu ;;
16         beos*)  OS=beos ;;
17 +       freebsd* | kfreebsd*-gnu)
18 +                       OS=freebsd ;;
19         *)      AC_MSG_ERROR([Unknown or unsupported OS "$host_os".  Only "linux", "gnu" and "beos" are supported in this version of GNU Parted.]) ;;
20  esac
21  AC_SUBST(OS)
22 @@ -164,6 +166,7 @@
23         #include <sys/types.h>
24         #include <unistd.h>
25  ])
26 +AC_CHECK_TYPE(loff_t, long long)
27  
28  AM_ENABLE_SHARED
29  if test "$OS" = linux -a $ac_cv_sizeof_off_t -lt 8; then
30 @@ -331,6 +334,20 @@
31         OS_LIBS="$OS_LIBS -lsocket"
32  fi     
33  
34 +dnl FreeBSD (and GNU/kFreeBSD):
35 +if test "$OS" = freebsd; then
36 +dnl    CFLAGS="$CFLAGS -D_GNU_SOURCE=1"
37 +
38 +dnl libgeom
39 +       AC_CHECK_LIB(geom, gctl_get_handle,
40 +               OS_LIBS="$OS_LIBS -lgeom",
41 +               AC_MSG_ERROR(
42 +GNU Parted requires libgeom when running on FreeBSD or derivative systems.
43 +               )
44 +               exit
45 +       )
46 +fi
47 +
48  AC_SUBST(OS_LIBS)
49  
50  dnl One day, gettext might support libtool...
51 @@ -352,7 +369,7 @@
52         exit
53  )
54  
55 -AC_CHECK_HEADERS(getopt.h) 
56 +AC_CHECK_HEADERS(getopt.h endian.h sys/endian.h)
57  
58  dnl required for libparted/llseek.c  (TODO: make linux-x86 only)
59  if test "$OS" = linux; then
60 @@ -399,7 +416,9 @@
61  
62  
63  dnl Checks for library functions.
64 -AC_CHECK_FUNCS(sigaction)
65 +if test "$OS" != freebsd; then
66 +   AC_CHECK_FUNCS(sigaction)
67 +fi
68  AC_CHECK_FUNCS(getuid)
69  
70  if test "$with_readline" = yes; then
71 diff -urNad parted-1.7.0~/include/parted/Makefile.am parted-1.7.0/include/parted/Makefile.am
72 --- parted-1.7.0~/include/parted/Makefile.am    2006-05-19 03:54:01.000000000 -0300
73 +++ parted-1.7.0/include/parted/Makefile.am     2006-05-19 03:54:02.000000000 -0300
74 @@ -1,6 +1,7 @@
75  partedincludedir      =        $(includedir)/parted
76  partedinclude_HEADERS = gnu.h          \
77                         linux.h         \
78 +                       freebsd.h       \
79                         constraint.h    \
80                         debug.h         \
81                         device.h        \
82 diff -urNad parted-1.7.0~/include/parted/freebsd.h parted-1.7.0/include/parted/freebsd.h
83 --- parted-1.7.0~/include/parted/freebsd.h      1969-12-31 21:00:00.000000000 -0300
84 +++ parted-1.7.0/include/parted/freebsd.h       2006-05-19 03:54:02.000000000 -0300
85 @@ -0,0 +1,47 @@
86 +/*
87 +    libparted - a library for manipulating disk partitions
88 +    Copyright (C) 2001 Free Software Foundation, Inc.
89 +
90 +    This program is free software; you can redistribute it and/or modify
91 +    it under the terms of the GNU General Public License as published by
92 +    the Free Software Foundation; either version 2 of the License, or
93 +    (at your option) any later version.
94 +
95 +    This program is distributed in the hope that it will be useful,
96 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
97 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
98 +    GNU General Public License for more details.
99 +
100 +    You should have received a copy of the GNU General Public License
101 +    along with this program; if not, write to the Free Software
102 +    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
103 +*/
104 +
105 +#ifndef PED_FREEBSD_H_INCLUDED
106 +#define PED_FREEBSD_H_INCLUDED
107 +
108 +#include <parted/parted.h>
109 +#include <parted/device.h>
110 +
111 +#include <sys/param.h>
112 +
113 +#if !defined(__FreeBSD_version) && defined(__FreeBSD_kernel_version)
114 +#define __FreeBSD_version __FreeBSD_kernel_version
115 +#endif
116 +
117 +#define FREEBSD_SPECIFIC(dev)  ((FreeBSDSpecific*) (dev)->arch_specific)
118 +
119 +typedef        struct _FreeBSDSpecific FreeBSDSpecific;
120 +
121 +struct _FreeBSDSpecific {
122 +#if (__FreeBSD_version >= 500000) && (__FreeBSD_version < 600000)
123 +       unsigned char channel;
124 +       unsigned char device;
125 +#endif
126 +       int     fd;
127 +};
128 +
129 +extern PedArchitecture ped_freebsd_arch;
130 +
131 +#endif /* PED_FREEBSD_H_INCLUDED */
132 +
133 diff -urNad parted-1.7.0~/libparted/Makefile.am parted-1.7.0/libparted/Makefile.am
134 --- parted-1.7.0~/libparted/Makefile.am 2006-05-19 03:54:01.000000000 -0300
135 +++ parted-1.7.0/libparted/Makefile.am  2006-05-19 03:54:02.000000000 -0300
136 @@ -28,7 +28,8 @@
137  
138  EXTRA_libparted_la_SOURCES    = arch/linux.c           \
139                                 arch/gnu.c \
140 -                               arch/beos.c
141 +                               arch/beos.c \
142 +                               arch/freebsd.c
143  
144  libparted_la_LIBADD   = @OS_LIBS@                      \
145                         fs/libfs.la                     \
146 diff -urNad parted-1.7.0~/libparted/arch/freebsd.c parted-1.7.0/libparted/arch/freebsd.c
147 --- parted-1.7.0~/libparted/arch/freebsd.c      1969-12-31 21:00:00.000000000 -0300
148 +++ parted-1.7.0/libparted/arch/freebsd.c       2006-05-19 03:54:02.000000000 -0300
149 @@ -0,0 +1,1197 @@
150 +/*
151 +    libparted - a library for manipulating disk partitions
152 +    Copyright (C) 1999 - 2005 Free Software Foundation, Inc.
153 +
154 +    This program is free software; you can redistribute it and/or modify
155 +    it under the terms of the GNU General Public License as published by
156 +    the Free Software Foundation; either version 2 of the License, or
157 +    (at your option) any later version.
158 +
159 +    This program is distributed in the hope that it will be useful,
160 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
161 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
162 +    GNU General Public License for more details.
163 +
164 +    You should have received a copy of the GNU General Public License
165 +    along with this program; if not, write to the Free Software
166 +    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
167 +*/
168 +
169 +#include "config.h"
170 +
171 +#include <parted/parted.h>
172 +#include <parted/debug.h>
173 +#include <parted/unit.h>
174 +#include <parted/freebsd.h>
175 +
176 +#include <ctype.h>
177 +#include <errno.h>
178 +#include <fcntl.h>
179 +#include <stdint.h>
180 +#include <stdio.h>
181 +#include <string.h>
182 +#include <unistd.h>
183 +#include <paths.h>
184 +#include <libgeom.h>
185 +#include <sys/param.h>
186 +#include <sys/ucred.h>
187 +#include <sys/mount.h>
188 +#include <sys/ioctl.h>
189 +#include <sys/sysctl.h>
190 +#include <sys/stat.h>
191 +#include <sys/types.h>
192 +#include <sys/disk.h>
193 +#include <sys/ata.h>
194 +
195 +#if ENABLE_NLS
196 +#  include <libintl.h>
197 +#  define _(String) dgettext (PACKAGE, String)
198 +#else
199 +#  define _(String) (String)
200 +#endif /* ENABLE_NLS */
201 +
202 +static char* _device_get_part_path (PedDevice* dev, int num);
203 +static int _partition_is_mounted_by_path (const char* path);
204 +
205 +static int
206 +_device_stat (PedDevice* dev, struct stat * dev_stat)
207 +{
208 +       PED_ASSERT (dev != NULL, return 0);
209 +       PED_ASSERT (!dev->external_mode, return 0);
210 +
211 +       while (1) {
212 +               if (!stat (dev->path, dev_stat)) {
213 +                       return 1;
214 +               } else {
215 +                       if (ped_exception_throw (
216 +                               PED_EXCEPTION_ERROR,
217 +                               PED_EXCEPTION_RETRY_CANCEL,
218 +                               _("Could not stat device %s - %s."),
219 +                               dev->path,
220 +                               strerror (errno))
221 +                                       != PED_EXCEPTION_RETRY)
222 +                               return 0;
223 +               }
224 +       }
225 +}
226 +
227 +static int
228 +_device_probe_type (PedDevice* dev)
229 +{
230 +       struct stat             dev_stat;
231 +       char *np;
232 +       PedExceptionOption      ex_status;
233 +
234 +#if (__FreeBSD_version >= 500000) && (__FreeBSD_version < 600000)
235 +       FreeBSDSpecific*        arch_specific = FREEBSD_SPECIFIC (dev);
236 +#endif
237 +       
238 +       if (!_device_stat (dev, &dev_stat))
239 +               return 0;
240 +       
241 +       if (!S_ISCHR(dev_stat.st_mode)) {
242 +               dev->type = PED_DEVICE_FILE;
243 +               return 1;
244 +       }
245 +
246 +       /* On FreeBSD ad0 ist the ATA device */
247 +       np = strrchr(dev->path, '/');
248 +       if(np == NULL)
249 +       {
250 +               dev->type = PED_DEVICE_UNKNOWN;
251 +               return 0;
252 +       }
253 +       np += 1; /* advance past '/' */
254 +       
255 +       if(strncmp(np, "ad", 2) == 0)
256 +       {
257 +               dev->type = PED_DEVICE_IDE;
258 +
259 +               /* ad0 -> channel 0, master
260 +                * ad1 -> channel 0, slave
261 +                * ad2 -> channel 1, master
262 +                * ad3 -> channel 1, slave
263 +                */
264 +#if (__FreeBSD_version >= 500000) && (__FreeBSD_version < 600000)
265 +               switch(*(np+3))
266 +               {
267 +               case 0:
268 +                       arch_specific->channel = 0;
269 +                       arch_specific->device = 0;
270 +                       break;
271 +               case 1:
272 +                       arch_specific->channel = 0;
273 +                       arch_specific->device = 1;
274 +                       break;
275 +               case 2:
276 +                       arch_specific->channel = 1;
277 +                       arch_specific->device = 0;
278 +                       break;
279 +               case 4:
280 +                       arch_specific->channel = 1;
281 +                       arch_specific->device = 1;
282 +                       break;
283 +               }
284 +#endif
285 +               
286 +       }
287 +       else
288 +       {
289 +               dev->type = PED_DEVICE_UNKNOWN;
290 +       }
291 +       
292 +       return 1;
293 +}
294 +
295 +static int
296 +_device_get_sector_size (PedDevice* dev)
297 +{
298 +       FreeBSDSpecific*        arch_specific = FREEBSD_SPECIFIC (dev);
299 +       u_int sector_size = PED_SECTOR_SIZE_DEFAULT; /*makes Valgrind happy*/
300 +
301 +       PED_ASSERT (dev->open_count, return 0);
302 +
303 +       if (ioctl (arch_specific->fd, DIOCGSECTORSIZE, &sector_size) == -1)
304 +               return PED_SECTOR_SIZE_DEFAULT;
305 +
306 +       if (sector_size != PED_SECTOR_SIZE_DEFAULT) {
307 +               if (ped_exception_throw (
308 +                       PED_EXCEPTION_BUG,
309 +                       PED_EXCEPTION_IGNORE_CANCEL,
310 +                       _("The sector size on %s is %d bytes.  Parted is known "
311 +                       "not to work properly with drives with sector sizes "
312 +                       "other than %d bytes."),
313 +                       dev->path,
314 +                       sector_size,
315 +                       PED_SECTOR_SIZE_DEFAULT)
316 +                               == PED_EXCEPTION_IGNORE)
317 +                       return sector_size;
318 +               else
319 +                       return PED_SECTOR_SIZE_DEFAULT;
320 +       }
321 +
322 +       return sector_size;
323 +}
324 +
325 +static PedSector
326 +_device_get_length (PedDevice* dev)
327 +{
328 +       FreeBSDSpecific* arch_specific = FREEBSD_SPECIFIC (dev);
329 +       off_t bytes = 0;
330 +
331 +       PED_ASSERT (dev->open_count > 0, return 0);
332 +
333 +       if(ioctl(arch_specific->fd, DIOCGMEDIASIZE, &bytes) == 0) {
334 +               return bytes / PED_SECTOR_SIZE_DEFAULT;
335 +       }
336 +       
337 +       return 0;
338 +}
339 +
340 +
341 +#if (__FreeBSD_version >= 500000) && (__FreeBSD_version < 600000)
342 +# define freebsd_get_ata_params freebsd_get_ata_params_compat5
343 +#elif (__FreeBSD_version >= 600000)
344 +# define freebsd_get_ata_params freebsd_get_ata_params_compat6
345 +#else
346 +# error "parted currently compiles on FreeBSD 5.X and 6.X only"
347 +#endif
348 +
349 +#if (__FreeBSD_version >= 500000) && (__FreeBSD_version < 600000)
350 +
351 +static int freebsd_get_ata_params_compat5(PedDevice *dev,
352 +                                                                                 struct ata_params *ap)
353 +{
354 +       struct ata_cmd iocmd;
355 +       int fd, ret;
356 +       FreeBSDSpecific*                arch_specific = FREEBSD_SPECIFIC (dev);
357 +
358 +       if ((fd = open("/dev/ata", O_RDWR)) == -1)
359 +       {
360 +               ped_exception_throw (
361 +                       PED_EXCEPTION_ERROR,
362 +                       PED_EXCEPTION_CANCEL,
363 +                       _("Could not get open /dev/ata."));
364 +
365 +               ret = -1;
366 +               goto out;
367 +       }
368 +       
369 +       bzero(&iocmd, sizeof(struct ata_cmd));
370 +       iocmd.channel = arch_specific->channel;
371 +       iocmd.device = arch_specific->device;
372 +       iocmd.cmd = ATAGPARM;
373 +       
374 +       if (ioctl(fd, IOCATA, &iocmd) == -1)
375 +       {
376 +               ped_exception_throw (
377 +                       PED_EXCEPTION_ERROR,
378 +                       PED_EXCEPTION_CANCEL,
379 +                       _("Could not get ATA parameters. Please"
380 +                         "contact the maintainer."));
381 +
382 +               ret = -1;
383 +               goto out;
384 +       }
385 +       
386 +       if (iocmd.u.param.type[arch_specific->device]) {
387 +               *ap = iocmd.u.param.params[arch_specific->device];
388 +       } else
389 +       {
390 +               ped_exception_throw (
391 +                       PED_EXCEPTION_ERROR,
392 +                       PED_EXCEPTION_CANCEL,
393 +                       _("Could not get ATA parameters. Please"
394 +                         "contact the maintainer."));
395 +               ret = -1;
396 +               goto out;
397 +       }
398 +
399 +       ret = 0;
400 +       
401 +out:
402 +       close(fd);
403 +       
404 +       return ret;
405 +}
406 +
407 +#elif __FreeBSD_version >= 600000
408 +
409 +static int freebsd_get_ata_params_compat6(PedDevice *dev,
410 +                                                                                 struct ata_params *ap)
411 +{
412 +       FreeBSDSpecific*                arch_specific = FREEBSD_SPECIFIC (dev);
413 +
414 +       return ioctl (arch_specific->fd, IOCATAGPARM, &ap);
415 +}
416 +
417 +#endif
418 +
419 +static int
420 +_device_probe_geometry (PedDevice* dev)
421 +{
422 +       FreeBSDSpecific*                arch_specific = FREEBSD_SPECIFIC (dev);
423 +       struct stat             dev_stat;
424 +       struct ata_params ap;
425 +
426 +       if (!_device_stat (dev, &dev_stat))
427 +               return 0;
428 +       PED_ASSERT (S_ISCHR (dev_stat.st_mode), return 0);
429 +
430 +       dev->length = _device_get_length (dev);
431 +       if (!dev->length)
432 +               return 0;
433 +
434 +       dev->sector_size = _device_get_sector_size (dev);
435 +       if (!dev->sector_size)
436 +               return 0;
437 +
438 +       dev->bios_geom.sectors = 63;
439 +       dev->bios_geom.heads = 255;
440 +       dev->bios_geom.cylinders
441 +               = dev->length / (63 * 255)
442 +                       / (dev->sector_size / PED_SECTOR_SIZE_DEFAULT);
443 +
444 +       if (freebsd_get_ata_params (dev, &ap) == 0) {
445 +               dev->hw_geom.sectors = ap.sectors;
446 +               dev->hw_geom.heads = ap.heads;
447 +               dev->hw_geom.cylinders = ap.cylinders;
448 +       } else {
449 +               dev->hw_geom = dev->bios_geom;
450 +       }
451 +
452 +       return 1;
453 +}
454 +
455 +static char*
456 +strip_name(char* str)
457 +{
458 +       int     i;
459 +       int     end = 0;
460 +
461 +       for (i = 0; str[i] != 0; i++) {
462 +               if (!isspace (str[i])
463 +                   || (isspace (str[i]) && !isspace (str[i+1]) && str[i+1])) {
464 +                       str [end] = str[i];
465 +                       end++;
466 +               }
467 +       }
468 +       str[end] = 0;
469 +       return strdup (str);
470 +}
471 +
472 +static int
473 +init_ide (PedDevice* dev)
474 +{
475 +       FreeBSDSpecific* arch_specific = FREEBSD_SPECIFIC(dev);
476 +       struct stat     dev_stat;
477 +       struct ata_params ap;
478 +       PedExceptionOption ex_status;
479 +       char vendor_buf[64];
480 +
481 +       if (!_device_stat (dev, &dev_stat))
482 +               goto error;
483 +
484 +       if (!ped_device_open (dev))
485 +               goto error;
486 +
487 +       if (freebsd_get_ata_params (dev, &ap) == -1) {
488 +               ex_status = ped_exception_throw (
489 +                       PED_EXCEPTION_WARNING,
490 +                       PED_EXCEPTION_IGNORE_CANCEL,
491 +                       _("Could not get identity of device %s - %s"),
492 +                       dev->path, strerror (errno));
493 +               switch (ex_status) {
494 +               case PED_EXCEPTION_CANCEL:
495 +                       goto error_close_dev;
496 +
497 +               case PED_EXCEPTION_UNHANDLED:
498 +                       ped_exception_catch ();
499 +               case PED_EXCEPTION_IGNORE:
500 +                       dev->model = strdup(_("IDE"));
501 +               }
502 +       } else {
503 +               snprintf(vendor_buf, 64, "%s/%s", ap.model, ap.revision);
504 +               dev->model = strip_name (vendor_buf);
505 +       }
506 +
507 +       if (!_device_probe_geometry (dev))
508 +               goto error_close_dev;
509 +
510 +       ped_device_close (dev);
511 +       return 1;
512 +
513 +error_close_dev:
514 +       ped_device_close (dev);
515 +error:
516 +       return 0;
517 +}
518 +
519 +static int
520 +init_file (PedDevice* dev)
521 +{
522 +       struct stat     dev_stat;
523
524 +       if (!_device_stat (dev, &dev_stat))
525 +               goto error;
526 +       if (!ped_device_open (dev))
527 +               goto error;
528 +
529 +       if (S_ISCHR(dev_stat.st_mode))
530 +               dev->length = _device_get_length (dev);
531 +       else
532 +               dev->length = dev_stat.st_size / 512;
533 +       if (dev->length <= 0) {
534 +               ped_exception_throw (
535 +                       PED_EXCEPTION_ERROR,
536 +                       PED_EXCEPTION_CANCEL,
537 +                       _("The device %s is zero-length, and can't possibly "
538 +                         "store a file system or partition table.  Perhaps "
539 +                         "you selected the wrong device?"),
540 +                       dev->path);
541 +               goto error_close_dev;
542 +       }
543 +
544 +       ped_device_close (dev);
545 +
546 +       dev->bios_geom.cylinders = dev->length / 4 / 32;
547 +       dev->bios_geom.heads = 4;
548 +       dev->bios_geom.sectors = 32;
549 +       dev->hw_geom = dev->bios_geom;
550 +       dev->sector_size = 512;
551 +       dev->model = strdup ("");
552 +       return 1;
553 +
554 +error_close_dev:
555 +       ped_device_close (dev);
556 +error:
557 +       return 0;
558 +}
559 +
560 +static int
561 +init_generic (PedDevice* dev, char* model_name)
562 +{
563 +       struct stat             dev_stat;
564 +       PedExceptionOption      ex_status;
565 +
566 +       if (!_device_stat (dev, &dev_stat))
567 +               goto error;
568 +
569 +       if (!ped_device_open (dev))
570 +               goto error;
571 +
572 +       ped_exception_fetch_all ();
573 +       if (_device_probe_geometry (dev)) {
574 +               ped_exception_leave_all ();
575 +       } else {
576 +               /* hack to allow use of files, for testing */
577 +               ped_exception_catch ();
578 +               ped_exception_leave_all ();
579 +
580 +               ex_status = ped_exception_throw (
581 +                               PED_EXCEPTION_WARNING,
582 +                               PED_EXCEPTION_IGNORE_CANCEL,
583 +                               _("Unable to determine geometry of "
584 +                               "file/device.  You should not use Parted "
585 +                               "unless you REALLY know what you're doing!"));
586 +               switch (ex_status) {
587 +                       case PED_EXCEPTION_CANCEL:
588 +                               goto error_close_dev;
589 +
590 +                       case PED_EXCEPTION_UNHANDLED:
591 +                               ped_exception_catch ();
592 +                       case PED_EXCEPTION_IGNORE:
593 +                               ; // just workaround for gcc 3.0
594 +               }
595 +
596 +               /* what should we stick in here? */
597 +               dev->length = dev_stat.st_size / PED_SECTOR_SIZE_DEFAULT;
598 +               dev->bios_geom.cylinders = dev->length / 4 / 32;
599 +               dev->bios_geom.heads = 4;
600 +               dev->bios_geom.sectors = 32;
601 +               dev->sector_size = PED_SECTOR_SIZE_DEFAULT;
602 +       }
603 +
604 +       dev->model = strdup (model_name);
605 +
606 +       ped_device_close (dev);
607 +       return 1;
608 +
609 +error_close_dev:
610 +       ped_device_close (dev);
611 +error:
612 +       return 0;
613 +}
614 +
615 +static PedDevice*
616 +freebsd_new (const char* path)
617 +{
618 +       PedDevice*      dev;
619 +
620 +       PED_ASSERT (path != NULL, return NULL);
621 +
622 +       dev = (PedDevice*) ped_malloc (sizeof (PedDevice));
623 +       if (!dev)
624 +               goto error;
625 +
626 +       dev->path = strdup (path);
627 +       if (!dev->path)
628 +               goto error_free_dev;
629 +
630 +       dev->arch_specific
631 +               = (FreeBSDSpecific*) ped_malloc (sizeof (FreeBSDSpecific));
632 +       if (!dev->arch_specific)
633 +               goto error_free_path;
634 +
635 +       dev->open_count = 0;
636 +       dev->read_only = 0;
637 +       dev->external_mode = 0;
638 +       dev->dirty = 0;
639 +       dev->boot_dirty = 0;
640 +
641 +       if (!_device_probe_type (dev))
642 +               goto error_free_arch_specific;
643 +       
644 +       switch (dev->type) {
645 +       case PED_DEVICE_IDE:
646 +               if (!init_ide (dev))
647 +                       goto error_free_arch_specific;
648 +               break;
649 +
650 +       default:
651 +               ped_exception_throw (PED_EXCEPTION_NO_FEATURE,
652 +                               PED_EXCEPTION_CANCEL,
653 +                               _("ped_device_new()  Unsupported device type"));
654 +               goto error_free_arch_specific;
655 +       }
656 +       return dev;
657 +
658 +error_free_arch_specific:
659 +       ped_free (dev->arch_specific);
660 +error_free_path:
661 +       ped_free (dev->path);
662 +error_free_dev:
663 +       ped_free (dev);
664 +error:
665 +       return NULL;
666 +}
667 +
668 +static void
669 +freebsd_destroy (PedDevice* dev)
670 +{
671 +       ped_free (dev->arch_specific);
672 +       ped_free (dev->path);
673 +       ped_free (dev->model);
674 +       ped_free (dev);
675 +}
676 +
677 +static int
678 +freebsd_is_busy (PedDevice* dev)
679 +{
680 +       int     i;
681 +       char*   part_name;
682 +
683 +       if (_partition_is_mounted_by_path (dev->path))
684 +               return 1;
685 +
686 +       for (i = 0; i < 32; i++) {
687 +               int status;
688 +
689 +               part_name = _device_get_part_path (dev, i);
690 +               if (!part_name)
691 +                       return 1;
692 +               status = _partition_is_mounted_by_path (part_name);
693 +               ped_free (part_name);
694 +
695 +               if (status)
696 +                       return 1;
697 +       }
698 +
699 +       return 0;
700 +}
701 +
702 +#if (__FreeBSD_version >= 500000) && (__FreeBSD_version < 600000)
703 +# define _flush_cache freebsd_flush_cache_compat5
704 +#elif (__FreeBSD_version >= 600000)
705 +# define _flush_cache freebsd_flush_cache_compat6
706 +#else
707 +# error "parted currently compiles on FreeBSD 5.X and 6.X only"
708 +#endif
709 +
710 +#if (__FreeBSD_version >= 500000) && (__FreeBSD_version < 600000)
711 +
712 +static void
713 +freebsd_flush_cache_compat5 (PedDevice* dev)
714 +{
715 +       FreeBSDSpecific*        arch_specific = FREEBSD_SPECIFIC (dev);
716 +       int fd;
717 +       struct ata_cmd iocmd;
718 +
719 +       if (freebsd_is_busy(dev))
720 +               printf("FreeBSD: Device %s is mounted. Not flushing cache.\n",
721 +                          dev->path);
722 +       
723 +       if ((fd = open("/dev/ata", O_RDWR)) == -1)
724 +       {
725 +               ped_exception_throw (
726 +                       PED_EXCEPTION_ERROR,
727 +                       PED_EXCEPTION_CANCEL,
728 +                       _("Could not open /dev/ata."));
729 +
730 +               goto out;
731 +       }
732 +
733 +       if (dev->read_only)
734 +               goto out;
735 +       dev->dirty = 0;
736 +       
737 +       bzero(&iocmd, sizeof(struct ata_cmd));
738 +       iocmd.channel = arch_specific->channel;
739 +       iocmd.device = arch_specific->device;
740 +       iocmd.cmd = ATAREQUEST;
741 +       iocmd.u.request.u.ata.command = ATA_FLUSHCACHE;
742 +       
743 +       if (ioctl(fd, IOCATA, &iocmd) == -1)
744 +       {
745 +               ped_exception_throw (
746 +                       PED_EXCEPTION_ERROR,
747 +                       PED_EXCEPTION_CANCEL,
748 +                       _("Could not flush cache."));
749 +               
750 +               goto out;
751 +       }
752 +
753 +out:
754 +       close (fd);
755 +       
756 +       return;
757 +}
758 +
759 +#elif __FreeBSD_version >= 600000
760 +
761 +static void
762 +freebsd_flush_cache_compat6 (PedDevice* dev)
763 +{
764 +       FreeBSDSpecific*        arch_specific = FREEBSD_SPECIFIC (dev);
765 +       struct ata_ioc_request ioreq;
766 +
767 +       if (freebsd_is_busy(dev))
768 +               printf("FreeBSD: Device %s is mounted. Not flushing cache.\n",
769 +                          dev->path);
770 +       
771 +       if (dev->read_only)
772 +               return;
773 +       dev->dirty = 0;
774 +       
775 +       bzero(&ioreq, sizeof(struct ata_ioc_request));
776 +       ioreq.u.ata.command = ATA_FLUSHCACHE;
777 +       
778 +       if (ioctl(arch_specific->fd, IOCATAREQUEST, &ioreq) == -1)
779 +       {
780 +               ped_exception_throw (
781 +                       PED_EXCEPTION_ERROR,
782 +                       PED_EXCEPTION_CANCEL,
783 +                       _("Could not flush cache."));
784 +               return;
785 +       }
786 +
787 +       return;
788 +}
789 +
790 +#endif
791 +
792 +/* By default, kernel of FreeBSD does not allow overwriting MBR */
793 +#define GEOM_SYSCTL    "kern.geom.debugflags"
794 +
795 +static int
796 +freebsd_open (PedDevice* dev)
797 +{
798 +       int old_flags, flags;
799 +       size_t sizeof_int = sizeof (int);
800 +       FreeBSDSpecific*        arch_specific = FREEBSD_SPECIFIC (dev);
801 +
802 +retry:
803 +       if (sysctlbyname (GEOM_SYSCTL, &old_flags, &sizeof_int, NULL, 0) != 0)
804 +               ped_exception_throw (PED_EXCEPTION_WARNING, PED_EXCEPTION_OK,
805 +                                                        _("Unable to get %s sysctl (%s)."), GEOM_SYSCTL,
806 +                                                        strerror (errno));
807 +
808 +       if ((old_flags & 0x10) == 0)
809 +       {
810 +               /* "allow foot shooting", see geom(4) */
811 +               flags = old_flags | 0x10;
812 +               
813 +               if (sysctlbyname (GEOM_SYSCTL, NULL, NULL, &flags, sizeof (int)) != 0)
814 +               {
815 +                       flags = old_flags;
816 +                       ped_exception_throw (PED_EXCEPTION_WARNING, PED_EXCEPTION_OK,
817 +                                                                _("Unable to set %s sysctl (%s)."), GEOM_SYSCTL,
818 +                                                                strerror (errno));
819 +               }
820 +       }
821 +       else
822 +               flags = old_flags;
823 +
824 +       arch_specific->fd = open (dev->path, O_RDWR);
825 +
826 +       if (flags != old_flags)
827 +       {
828 +               if (sysctlbyname (GEOM_SYSCTL, NULL, NULL, &old_flags, sizeof (int)) != 0)
829 +                       ped_exception_throw (PED_EXCEPTION_WARNING, PED_EXCEPTION_OK,
830 +                                                                _("Unable to set %s sysctl (%s)."), GEOM_SYSCTL,
831 +                                                                strerror (errno));
832 +       }
833 +       
834 +       if (arch_specific->fd == -1) {
835 +               char*   rw_error_msg = strerror (errno);
836 +
837 +               arch_specific->fd = open (dev->path, O_RDONLY);
838 +               if (arch_specific->fd == -1) {
839 +                       if (ped_exception_throw (
840 +                               PED_EXCEPTION_ERROR,
841 +                               PED_EXCEPTION_RETRY_CANCEL,
842 +                               _("Error opening %s: %s"),
843 +                               dev->path, strerror (errno))
844 +                                       != PED_EXCEPTION_RETRY) {
845 +                               return 0;
846 +                       } else {
847 +                               goto retry;
848 +                       }
849 +               } else {
850 +                       ped_exception_throw (
851 +                               PED_EXCEPTION_WARNING,
852 +                               PED_EXCEPTION_OK,
853 +                               _("Unable to open %s read-write (%s).  %s has "
854 +                                 "been opened read-only."),
855 +                               dev->path, rw_error_msg, dev->path);
856 +                       dev->read_only = 1;
857 +               }
858 +       } else {
859 +               dev->read_only = 0;
860 +       }
861 +
862 +       _flush_cache (dev);
863 +
864 +       return 1;
865 +}
866 +
867 +static int
868 +freebsd_refresh_open (PedDevice* dev)
869 +{
870 +       return 1;
871 +}
872 +
873 +static int
874 +freebsd_close (PedDevice* dev)
875 +{
876 +       FreeBSDSpecific*                arch_specific = FREEBSD_SPECIFIC (dev);
877 +
878 +       if (dev->dirty)
879 +               _flush_cache (dev);
880 +       close (arch_specific->fd);
881 +       return 1;
882 +}
883 +
884 +static int
885 +freebsd_refresh_close (PedDevice* dev)
886 +{
887 +       if (dev->dirty)
888 +               _flush_cache (dev);
889 +       return 1;
890 +}
891 +
892 +static int
893 +_device_seek (const PedDevice* dev, PedSector sector)
894 +{
895 +       FreeBSDSpecific*        arch_specific;
896 +       off_t   pos;
897 +       
898 +       PED_ASSERT (dev != NULL, return 0);
899 +       PED_ASSERT (!dev->external_mode, return 0);
900 +       
901 +       arch_specific = FREEBSD_SPECIFIC (dev);
902 +
903 +       pos = sector * PED_SECTOR_SIZE_DEFAULT;
904 +       return lseek (arch_specific->fd, pos, SEEK_SET) == pos;
905 +}
906 +
907 +static int
908 +freebsd_read (const PedDevice* dev, void* buffer, PedSector start, PedSector count)
909 +{
910 +       FreeBSDSpecific*                arch_specific = FREEBSD_SPECIFIC (dev);
911 +       int                     status;
912 +       PedExceptionOption      ex_status;
913 +       size_t                  read_length = count * PED_SECTOR_SIZE_DEFAULT;
914 +
915 +       while (1) {
916 +               if (_device_seek (dev, start))
917 +                       break;
918 +
919 +               ex_status = ped_exception_throw (
920 +                       PED_EXCEPTION_ERROR,
921 +                       PED_EXCEPTION_RETRY_IGNORE_CANCEL,
922 +                       _("%s during seek for read on %s"),
923 +                       strerror (errno), dev->path);
924 +
925 +               switch (ex_status) {
926 +                       case PED_EXCEPTION_IGNORE:
927 +                               return 1;
928 +
929 +                       case PED_EXCEPTION_RETRY:
930 +                               break;
931 +
932 +                       case PED_EXCEPTION_UNHANDLED:
933 +                               ped_exception_catch ();
934 +                       case PED_EXCEPTION_CANCEL:
935 +                               return 0;
936 +               }
937 +       }
938 +
939 +       while (1) {
940 +               status = read (arch_specific->fd, buffer, read_length);
941 +               if (status == count * PED_SECTOR_SIZE_DEFAULT) break;
942 +               if (status > 0) {
943 +                       read_length -= status;
944 +                       buffer += status;
945 +                       continue;
946 +               }
947 +
948 +               ex_status = ped_exception_throw (
949 +                       PED_EXCEPTION_ERROR,
950 +                       PED_EXCEPTION_RETRY_IGNORE_CANCEL,
951 +                       _("%s during read on %s"),
952 +                       strerror (errno),
953 +                       dev->path);
954 +
955 +               switch (ex_status) {
956 +                       case PED_EXCEPTION_IGNORE:
957 +                               return 1;
958 +
959 +                       case PED_EXCEPTION_RETRY:
960 +                               break;
961 +
962 +                       case PED_EXCEPTION_UNHANDLED:
963 +                               ped_exception_catch ();
964 +                       case PED_EXCEPTION_CANCEL:
965 +                               return 0;
966 +               }
967 +       }
968 +
969 +       return 1;
970 +}
971 +
972 +static int
973 +freebsd_write (PedDevice* dev, const void* buffer, PedSector start,
974 +            PedSector count)
975 +{
976 +       FreeBSDSpecific*                arch_specific = FREEBSD_SPECIFIC (dev);
977 +       int                     status;
978 +       PedExceptionOption      ex_status;
979 +       size_t                  write_length = count * PED_SECTOR_SIZE_DEFAULT;
980 +
981 +       if (dev->read_only) {
982 +               if (ped_exception_throw (
983 +                       PED_EXCEPTION_ERROR,
984 +                       PED_EXCEPTION_IGNORE_CANCEL,
985 +                       _("Can't write to %s, because it is opened read-only."),
986 +                       dev->path)
987 +                               != PED_EXCEPTION_IGNORE)
988 +                       return 0;
989 +               else
990 +                       return 1;
991 +       }
992 +
993 +       while (1) {
994 +               if (_device_seek (dev, start))
995 +                       break;
996 +
997 +               ex_status = ped_exception_throw (
998 +                       PED_EXCEPTION_ERROR, PED_EXCEPTION_RETRY_IGNORE_CANCEL,
999 +                       _("%s during seek for write on %s"),
1000 +                       strerror (errno), dev->path);
1001 +
1002 +               switch (ex_status) {
1003 +                       case PED_EXCEPTION_IGNORE:
1004 +                               return 1;
1005 +
1006 +                       case PED_EXCEPTION_RETRY:
1007 +                               break;
1008 +
1009 +                       case PED_EXCEPTION_UNHANDLED:
1010 +                               ped_exception_catch ();
1011 +                       case PED_EXCEPTION_CANCEL:
1012 +                               return 0;
1013 +               }
1014 +       }
1015 +
1016 +#ifdef READ_ONLY
1017 +       printf ("ped_device_write (\"%s\", %p, %d, %d)\n",
1018 +               dev->path, buffer, (int) start, (int) count);
1019 +#else
1020 +       dev->dirty = 1;
1021 +       while (1) {
1022 +               status = write (arch_specific->fd, buffer, write_length);
1023 +               if (status == count * PED_SECTOR_SIZE_DEFAULT) break;
1024 +               if (status > 0) {
1025 +                       write_length -= status;
1026 +                       buffer += status;
1027 +                       continue;
1028 +               }
1029 +
1030 +               ex_status = ped_exception_throw (
1031 +                       PED_EXCEPTION_ERROR,
1032 +                       PED_EXCEPTION_RETRY_IGNORE_CANCEL,
1033 +                       _("%s during write on %s"),
1034 +                       strerror (errno), dev->path);
1035 +
1036 +               switch (ex_status) {
1037 +                       case PED_EXCEPTION_IGNORE:
1038 +                               return 1;
1039 +
1040 +                       case PED_EXCEPTION_RETRY:
1041 +                               break;
1042 +
1043 +                       case PED_EXCEPTION_UNHANDLED:
1044 +                               ped_exception_catch ();
1045 +                       case PED_EXCEPTION_CANCEL:
1046 +                               return 0;
1047 +               }
1048 +       }
1049 +#endif /* !READ_ONLY */
1050 +       return 1;
1051 +}
1052 +
1053 +/* returns the number of sectors that are ok.
1054 + */
1055 +static PedSector
1056 +freebsd_check (PedDevice* dev, void* buffer, PedSector start, PedSector count)
1057 +{
1058 +       FreeBSDSpecific*        arch_specific = FREEBSD_SPECIFIC (dev);
1059 +       PedSector       done = 0;
1060 +       int             status;
1061 +
1062 +       if (!_device_seek (dev, start))
1063 +               return 0;
1064 +
1065 +       for (done = 0; done < count; done += status / PED_SECTOR_SIZE_DEFAULT) {
1066 +               status = read (arch_specific->fd, buffer,
1067 +                              (size_t) ((count-done) * PED_SECTOR_SIZE_DEFAULT));
1068 +               if (status < 0)
1069 +                       break;
1070 +       }
1071 +
1072 +       return done;
1073 +}
1074 +
1075 +static int
1076 +_do_fsync (PedDevice* dev)
1077 +{
1078 +       FreeBSDSpecific*                arch_specific = FREEBSD_SPECIFIC (dev);
1079 +       int                     status;
1080 +       PedExceptionOption      ex_status;
1081 +
1082 +       while (1) {
1083 +               status = fsync (arch_specific->fd);
1084 +               if (status >= 0) break;
1085 +
1086 +               ex_status = ped_exception_throw (
1087 +                       PED_EXCEPTION_ERROR,
1088 +                       PED_EXCEPTION_RETRY_IGNORE_CANCEL,
1089 +                       _("%s during write on %s"),
1090 +                       strerror (errno), dev->path);
1091 +
1092 +               switch (ex_status) {
1093 +                       case PED_EXCEPTION_IGNORE:
1094 +                               return 1;
1095 +
1096 +                       case PED_EXCEPTION_RETRY:
1097 +                               break;
1098 +
1099 +                       case PED_EXCEPTION_UNHANDLED:
1100 +                               ped_exception_catch ();
1101 +                       case PED_EXCEPTION_CANCEL:
1102 +                               return 0;
1103 +               }
1104 +       } 
1105 +       return 1;
1106 +}
1107 +
1108 +static int
1109 +freebsd_sync (PedDevice* dev)
1110 +{
1111 +       PED_ASSERT (dev != NULL, return 0);
1112 +       PED_ASSERT (!dev->external_mode, return 0);
1113 +
1114 +       if (dev->read_only)
1115 +               return 1;
1116 +       if (!_do_fsync (dev))
1117 +               return 0;
1118 +       _flush_cache (dev);
1119 +       return 1;
1120 +}
1121 +
1122 +static int
1123 +freebsd_sync_fast (PedDevice* dev)
1124 +{
1125 +       PED_ASSERT (dev != NULL, return 0);
1126 +       PED_ASSERT (!dev->external_mode, return 0);
1127 +
1128 +       if (dev->read_only)
1129 +               return 1;
1130 +       if (!_do_fsync (dev))
1131 +               return 0;
1132 +       /* no cache flush... */
1133 +       return 1;
1134 +}
1135 +
1136 +/* XXX code from /usr/src/lib/libdisk/disk.c */
1137 +static int
1138 +_probe_standard_devices ()
1139 +{
1140 +       char            dev_name [16];
1141 +       char            dev_type [16];
1142 +       char            fullpath [256];
1143 +       int             ret;
1144 +       char*           conftxt;
1145 +       char*           cptr;
1146 +       size_t          txtsize;
1147 +
1148 +
1149 +       ret = sysctlbyname("kern.geom.conftxt", NULL, &txtsize, NULL, 0);
1150 +       if (ret) {
1151 +               printf("kern.geom.conftxt sysctl not available, giving up!");
1152 +               return 0;
1153 +       }
1154 +       conftxt = ped_malloc(txtsize+1);
1155 +       if (conftxt == NULL) {
1156 +               printf("cannot malloc memory for conftxt");
1157 +               return 0;
1158 +       }
1159 +       ret = sysctlbyname("kern.geom.conftxt", conftxt, &txtsize, NULL, 0);
1160 +       if (ret) {
1161 +               printf("error reading kern.geom.conftxt from the system");
1162 +               free (conftxt);
1163 +               return 0;
1164 +       }
1165 +
1166 +       cptr = conftxt;
1167 +       
1168 +       while (sscanf (cptr, "%*d %s %s",
1169 +                                  dev_type, dev_name) != EOF) {
1170 +               if (strcmp(dev_type, "DISK") == 0)
1171 +               {
1172 +                       strcpy (fullpath, _PATH_DEV);
1173 +                       strcat (fullpath, dev_name);
1174 +                       printf("FreeBSD: probing %s...\n", fullpath);
1175 +                       _ped_device_probe (fullpath);
1176 +               }
1177 +               
1178 +               cptr = strchr(cptr, '\n');
1179 +               cptr++;
1180 +       }
1181 +
1182 +       ped_free(conftxt);
1183 +       
1184 +       return 1;
1185 +}
1186 +
1187 +static void
1188 +freebsd_probe_all ()
1189 +{
1190 +       _probe_standard_devices ();
1191 +}
1192 +
1193 +static char*
1194 +_device_get_part_path (PedDevice* dev, int num)
1195 +{
1196 +       int             path_len = strlen (dev->path);
1197 +       int             result_len = path_len + 16;
1198 +       char*           result;
1199 +
1200 +       result = (char*) ped_malloc (result_len);
1201 +       if (!result)
1202 +               return NULL;
1203 +
1204 +       /* append slice number (ad0, partition 1 => ad0s1)*/
1205 +       snprintf (result, result_len, "%ss%d", dev->path, num);
1206 +       
1207 +       return result;
1208 +}
1209 +
1210 +static char*
1211 +freebsd_partition_get_path (const PedPartition* part)
1212 +{
1213 +       return _device_get_part_path (part->disk->dev, part->num);
1214 +}
1215 +
1216 +/* XXX code from /usr/src/sbin/mount/mount.c:getmntpt() */
1217 +static int
1218 +_partition_is_mounted_by_path (const char *path)
1219 +{
1220 +       struct stat part_stat, mntdevstat;
1221 +       struct statfs *mntbuf, *statfsp;
1222 +       char *devname;
1223 +       char device[256];
1224 +       int mntsize, i;
1225 +       
1226 +       if (stat (path, &part_stat) != 0)
1227 +               return 0;
1228 +
1229 +       if (!S_ISCHR(part_stat.st_mode))
1230 +               return 0;
1231 +
1232 +       mntsize = getmntinfo(&mntbuf, MNT_NOWAIT);
1233 +       for (i = 0; i < mntsize; i++) {
1234 +               statfsp = &mntbuf[i];
1235 +               devname = statfsp->f_mntfromname;
1236 +               if (*devname != '/') {
1237 +                       strcpy(device, _PATH_DEV);
1238 +                       strcat(device, devname);
1239 +                       strcpy(statfsp->f_mntfromname, device);
1240 +               }
1241 +               if (stat(devname, &mntdevstat) == 0 &&
1242 +                       mntdevstat.st_rdev == part_stat.st_rdev)
1243 +                       return 1;
1244 +       }
1245 +
1246 +       return 0;
1247 +}
1248 +
1249 +static int
1250 +_partition_is_mounted (const PedPartition *part)
1251 +{
1252 +       dev_t dev;
1253 +       if (!ped_partition_is_active (part))
1254 +               return 0;
1255 +       
1256 +       return _partition_is_mounted_by_path (part->disk->dev->path);
1257 +}
1258 +
1259 +static int
1260 +freebsd_partition_is_busy (const PedPartition* part)
1261 +{
1262 +       PedPartition*   walk;
1263 +
1264 +       PED_ASSERT (part != NULL, return 0);
1265 +
1266 +       if (_partition_is_mounted (part))
1267 +               return 1;
1268 +       if (part->type == PED_PARTITION_EXTENDED) {
1269 +               for (walk = part->part_list; walk; walk = walk->next) {
1270 +                       if (freebsd_partition_is_busy (walk))
1271 +                               return 1;
1272 +               }
1273 +       }
1274 +       return 0;
1275 +}
1276 +
1277 +/* XXX maybe read the MBR again and hand it over to geom? */
1278 +static int
1279 +_kernel_reread_part_table (PedDevice* dev)
1280 +{
1281 +       FreeBSDSpecific*        arch_specific = FREEBSD_SPECIFIC (dev);
1282 +       int             retry_count = 5;
1283 +       struct gctl_req *grq;
1284 +       char mbr_buf[512];
1285 +       const char *q;
1286 +       
1287 +       sync();
1288 +
1289 +       freebsd_read (dev, mbr_buf, 0, 1);
1290 +
1291 +       grq = gctl_get_handle();
1292 +       gctl_ro_param(grq, "verb", -1, "write MBR");
1293 +       gctl_ro_param(grq, "class", -1, "MBR");
1294 +       q = strrchr(dev->path, '/');
1295 +       if (q == NULL)
1296 +               q = dev->path;
1297 +       else
1298 +               q++;
1299 +       gctl_ro_param(grq, "geom", -1, q);
1300 +       gctl_ro_param(grq, "data", dev->sector_size, mbr_buf);
1301 +       q = gctl_issue(grq);
1302 +       if (q == NULL) {
1303 +               gctl_free(grq);
1304 +               return(0);
1305 +       }
1306 +       
1307 +       gctl_free(grq);
1308 +
1309 +       return 1;
1310 +}
1311 +
1312 +static int
1313 +freebsd_disk_commit (PedDisk* disk)
1314 +{
1315 +       if (disk->dev->type != PED_DEVICE_FILE)
1316 +               return _kernel_reread_part_table (disk->dev);
1317 +
1318 +       return 1;
1319 +}
1320 +
1321 +static PedDeviceArchOps freebsd_dev_ops = {
1322 +       _new:                   freebsd_new,
1323 +       destroy:                freebsd_destroy,
1324 +       is_busy:                freebsd_is_busy,
1325 +       open:                   freebsd_open,
1326 +       refresh_open:   freebsd_refresh_open,
1327 +       close:                  freebsd_close,
1328 +       refresh_close:  freebsd_refresh_close,
1329 +       read:                   freebsd_read,
1330 +       write:                  freebsd_write,
1331 +       check:                  freebsd_check,
1332 +       sync:                   freebsd_sync,
1333 +       sync_fast:              freebsd_sync_fast,
1334 +       probe_all:              freebsd_probe_all
1335 +};
1336 +
1337 +PedDiskArchOps freebsd_disk_ops =  {
1338 +       partition_get_path:     freebsd_partition_get_path,
1339 +       partition_is_busy:      freebsd_partition_is_busy,
1340 +       disk_commit:            freebsd_disk_commit
1341 +};
1342 +
1343 +PedArchitecture ped_freebsd_arch = {
1344 +       dev_ops:        &freebsd_dev_ops,
1345 +       disk_ops:       &freebsd_disk_ops
1346 +};
1347 diff -urNad parted-1.7.0~/libparted/fs/xfs/platform_defs.h parted-1.7.0/libparted/fs/xfs/platform_defs.h
1348 --- parted-1.7.0~/libparted/fs/xfs/platform_defs.h      2006-05-19 03:54:01.000000000 -0300
1349 +++ parted-1.7.0/libparted/fs/xfs/platform_defs.h       2006-05-19 03:54:02.000000000 -0300
1350 @@ -38,7 +38,11 @@
1351  #include <stdio.h>
1352  #include <stdarg.h>
1353  #include <assert.h>
1354 -#include <endian.h>
1355 +#if HAVE_ENDIAN_H
1356 +# include <endian.h>
1357 +#elif HAVE_SYS_ENDIAN_H
1358 +# include <sys/endian.h>
1359 +#endif
1360  #include <stddef.h>
1361  #include <stdlib.h>
1362  #include <string.h>
1363 diff -urNad parted-1.7.0~/libparted/labels/bsd.c parted-1.7.0/libparted/labels/bsd.c
1364 --- parted-1.7.0~/libparted/labels/bsd.c        2006-05-19 03:54:01.000000000 -0300
1365 +++ parted-1.7.0/libparted/labels/bsd.c 2006-05-19 03:54:02.000000000 -0300
1366 @@ -24,6 +24,8 @@
1367  
1368  #include <string.h>
1369  
1370 +#include <sys/types.h>
1371 +
1372  #include <parted/parted.h>
1373  #include <parted/debug.h>
1374  #include <parted/endian.h>
1375 diff -urNad parted-1.7.0~/libparted/labels/sun.c parted-1.7.0/libparted/labels/sun.c
1376 --- parted-1.7.0~/libparted/labels/sun.c        2006-05-19 03:54:01.000000000 -0300
1377 +++ parted-1.7.0/libparted/labels/sun.c 2006-05-19 03:54:02.000000000 -0300
1378 @@ -24,6 +24,8 @@
1379  
1380  #include <string.h>
1381  
1382 +#include <sys/types.h>
1383 +
1384  #include <parted/parted.h>
1385  #include <parted/debug.h>
1386  #include <parted/endian.h>
1387 diff -urNad parted-1.7.0~/libparted/libparted.c parted-1.7.0/libparted/libparted.c
1388 --- parted-1.7.0~/libparted/libparted.c 2006-05-19 03:54:01.000000000 -0300
1389 +++ parted-1.7.0/libparted/libparted.c  2006-05-19 03:54:02.000000000 -0300
1390 @@ -26,6 +26,8 @@
1391  #  include <parted/linux.h>
1392  #elif defined(__BEOS__)
1393  #  include <parted/beos.h>
1394 +#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1395 +#  include <parted/freebsd.h>
1396  #else
1397  #  include <parted/gnu.h>
1398  #endif
1399 @@ -182,6 +184,8 @@
1400         ped_set_architecture (&ped_linux_arch);
1401  #elif defined(__BEOS__)
1402         ped_set_architecture (&ped_beos_arch);
1403 +#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1404 +       ped_set_architecture (&ped_freebsd_arch);
1405  #else
1406         ped_set_architecture (&ped_gnu_arch);
1407  #endif