1 /*
   2     libparted - a library for manipulating disk partitions
   3     Copyright (C) 1999, 2000, 2001, 2007 Free Software Foundation, Inc.
   4 
   5     This program is free software; you can redistribute it and/or modify
   6     it under the terms of the GNU General Public License as published by
   7     the Free Software Foundation; either version 3 of the License, or
   8     (at your option) any later version.
   9 
  10     This program is distributed in the hope that it will be useful,
  11     but WITHOUT ANY WARRANTY; without even the implied warranty of
  12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13     GNU General Public License for more details.
  14 
  15     You should have received a copy of the GNU General Public License
  16     along with this program.  If not, see <http://www.gnu.org/licenses/>.
  17 */
  18 
  19 #include <config.h>
  20 #include "configmake.h"
  21 
  22 #include <parted/parted.h>
  23 #include <parted/debug.h>
  24 
  25 #ifdef linux
  26 #  include <parted/linux.h>
  27 #elif defined(__BEOS__)
  28 #  include <parted/beos.h>
  29 #elif defined(__sun)
  30 #  include <parted/solaris.h>
  31 #else
  32 #  include <parted/gnu.h>
  33 #endif
  34 
  35 #if ENABLE_NLS
  36 #  include <locale.h>
  37 #  include <libintl.h>
  38 #  define _(String) dgettext (PACKAGE, String)
  39 #else
  40 #  define _(String) (String)
  41 #endif /* ENABLE_NLS */
  42 
  43 const PedArchitecture* ped_architecture;
  44 
  45 /* ped_malloc() debugging.  Stick the address and size of memory blocks that
  46  * weren't ped_free()d in here, and an exception will be thrown when it is
  47  * allocated.  That way, you can find out what, exactly, the allocated thing
  48  * is, and where it is created.
  49  */
  50 typedef struct
  51 {
  52     void*       pointer;
  53     size_t      size;
  54 } pointer_size_type;
  55 
  56 /* IMHO, none of the DEBUG-related code below is useful, and the
  57    ped_malloc memset code is actually quite harmful: it masked at
  58    least two nasty bugs that were fixed in June of 2007.  */
  59 #undef DEBUG
  60 #ifdef DEBUG
  61 static pointer_size_type dodgy_malloc_list[] = {
  62  {0,            0},
  63  {0,            0},
  64  {0,            0},
  65  {0,            0},
  66  {0,            0},
  67  {0,            0},
  68  {0,            0},
  69  {0,            0},
  70  {0,            0},
  71  {0,            0}
  72 };
  73 
  74 static int      dodgy_memory_active[100];
  75 #endif /* DEBUG */
  76 
  77 int
  78 ped_set_architecture (const PedArchitecture* arch)
  79 {
  80         PED_ASSERT (ped_device_get_next (NULL) == NULL, return 0);
  81 
  82         ped_architecture = arch;
  83         return 1;
  84 }
  85 
  86 extern void ped_disk_aix_init ();
  87 extern void ped_disk_bsd_init ();
  88 extern void ped_disk_dvh_init ();
  89 extern void ped_disk_gpt_init ();
  90 extern void ped_disk_loop_init ();
  91 extern void ped_disk_mac_init ();
  92 extern void ped_disk_msdos_init ();
  93 extern void ped_disk_pc98_init ();
  94 extern void ped_disk_sun_init ();
  95 extern void ped_disk_amiga_init ();
  96 extern void ped_disk_dasd_init ();
  97 
  98 static void
  99 init_disk_types ()
 100 {
 101         ped_disk_loop_init ();  /* must be last in the probe list */
 102 
 103 #if defined(__s390__) || defined(__s390x__)
 104         ped_disk_dasd_init();
 105 #endif
 106 
 107         ped_disk_sun_init ();
 108 #ifdef ENABLE_PC98
 109         ped_disk_pc98_init ();
 110 #endif
 111         ped_disk_msdos_init ();
 112         ped_disk_mac_init ();
 113         ped_disk_gpt_init ();
 114         ped_disk_dvh_init ();
 115         ped_disk_bsd_init ();
 116         ped_disk_amiga_init ();
 117         ped_disk_aix_init ();
 118 }
 119 
 120 #ifdef ENABLE_FS
 121 extern void ped_file_system_amiga_init (void);
 122 extern void ped_file_system_xfs_init (void);
 123 extern void ped_file_system_ufs_init (void);
 124 extern void ped_file_system_reiserfs_init (void);
 125 extern void ped_file_system_ntfs_init (void);
 126 extern void ped_file_system_linux_swap_init (void);
 127 extern void ped_file_system_jfs_init (void);
 128 extern void ped_file_system_hfs_init (void);
 129 extern void ped_file_system_fat_init (void);
 130 extern void ped_file_system_ext2_init (void);
 131 extern void ped_file_system_solaris_x86_init (void);
 132 
 133 static void
 134 init_file_system_types ()
 135 {
 136         ped_file_system_amiga_init ();
 137         ped_file_system_xfs_init ();
 138         ped_file_system_ufs_init ();
 139         ped_file_system_reiserfs_init ();
 140         ped_file_system_ntfs_init ();
 141         ped_file_system_linux_swap_init ();
 142         ped_file_system_jfs_init ();
 143         ped_file_system_hfs_init ();
 144         ped_file_system_fat_init ();
 145         ped_file_system_ext2_init ();
 146         ped_file_system_solaris_x86_init ();
 147 }
 148 #endif /* ENABLE_FS */
 149 
 150 extern void ped_disk_aix_done ();
 151 extern void ped_disk_bsd_done ();
 152 extern void ped_disk_dvh_done ();
 153 extern void ped_disk_gpt_done ();
 154 extern void ped_disk_loop_done ();
 155 extern void ped_disk_mac_done ();
 156 extern void ped_disk_msdos_done ();
 157 extern void ped_disk_pc98_done ();
 158 extern void ped_disk_sun_done ();
 159 extern void ped_disk_amiga_done ();
 160 extern void ped_disk_dasd_done ();
 161 
 162 static void
 163 done_disk_types ()
 164 {
 165 #if defined(__s390__) || (__s390x__)
 166         ped_disk_dasd_done ();
 167 #endif
 168         ped_disk_sun_done ();
 169 #ifdef ENABLE_PC98
 170         ped_disk_pc98_done ();
 171 #endif
 172         ped_disk_msdos_done ();
 173         ped_disk_mac_done ();
 174         ped_disk_loop_done ();
 175         ped_disk_gpt_done ();
 176         ped_disk_dvh_done ();
 177         ped_disk_bsd_done ();
 178         ped_disk_amiga_done ();
 179         ped_disk_aix_done ();
 180 }
 181 
 182 static void _init() __attribute__ ((constructor));
 183 
 184 static void
 185 _init()
 186 {
 187 #ifdef ENABLE_NLS
 188         bindtextdomain (PACKAGE, LOCALEDIR);
 189 #endif
 190 
 191         init_disk_types ();
 192 
 193 #ifdef ENABLE_FS
 194         init_file_system_types ();
 195 #endif
 196 
 197         /* FIXME: a better way of doing this? */
 198 #ifdef linux
 199         ped_set_architecture (&ped_linux_arch);
 200 #elif defined(__BEOS__)
 201         ped_set_architecture (&ped_beos_arch);
 202 #elif defined (__sun)
 203         ped_set_architecture (&ped_solaris_arch);
 204 #else
 205         ped_set_architecture (&ped_gnu_arch);
 206 #endif
 207 
 208 #ifdef DEBUG
 209         memset (dodgy_memory_active, 0, sizeof (dodgy_memory_active));
 210 #endif
 211 }
 212 
 213 #ifdef ENABLE_FS
 214 extern void ped_file_system_ext2_done (void);
 215 extern void ped_file_system_fat_done (void);
 216 extern void ped_file_system_hfs_done (void);
 217 extern void ped_file_system_jfs_done (void);
 218 extern void ped_file_system_linux_swap_done (void);
 219 extern void ped_file_system_ntfs_done (void);
 220 extern void ped_file_system_reiserfs_done (void);
 221 extern void ped_file_system_ufs_done (void);
 222 extern void ped_file_system_xfs_done (void);
 223 extern void ped_file_system_amiga_done (void);
 224 
 225 static void
 226 done_file_system_types ()
 227 {
 228         ped_file_system_ext2_done ();
 229         ped_file_system_fat_done ();
 230         ped_file_system_hfs_done ();
 231         ped_file_system_jfs_done ();
 232         ped_file_system_linux_swap_done ();
 233         ped_file_system_ntfs_done ();
 234         ped_file_system_reiserfs_done ();
 235         ped_file_system_ufs_done ();
 236         ped_file_system_xfs_done ();
 237         ped_file_system_amiga_done ();
 238 }
 239 #endif /* ENABLE_FS */
 240 
 241 static void _done() __attribute__ ((destructor));
 242 
 243 static void
 244 _done()
 245 {
 246         ped_device_free_all ();
 247 
 248         done_disk_types ();
 249 
 250 #ifdef ENABLE_FS
 251         done_file_system_types ();
 252 #endif
 253 }
 254 
 255 const char*
 256 ped_get_version ()
 257 {
 258         return VERSION;
 259 }
 260 
 261 #ifdef DEBUG
 262 static void
 263 _check_dodgy_pointer (const void* ptr, size_t size, int is_malloc)
 264 {
 265         int             i;
 266 
 267         for (i=0; dodgy_malloc_list[i].pointer; i++) {
 268                 if (dodgy_malloc_list[i].pointer != ptr)
 269                         continue;
 270                 if (is_malloc && dodgy_malloc_list[i].size != size)
 271                         continue;
 272                 if (!is_malloc && !dodgy_memory_active[i])
 273                         continue;
 274 
 275 
 276                 if (is_malloc) {
 277                         ped_exception_throw (
 278                                 PED_EXCEPTION_INFORMATION,
 279                                 PED_EXCEPTION_OK,
 280                                 "Dodgy malloc(%x) == %p occurred (active==%d)",
 281                                 size, ptr, dodgy_memory_active[i]);
 282                         dodgy_memory_active[i]++;
 283                 } else {
 284                         ped_exception_throw (
 285                                 PED_EXCEPTION_INFORMATION,
 286                                 PED_EXCEPTION_OK,
 287                                 "Dodgy free(%p) occurred (active==%d)",
 288                                 ptr, dodgy_memory_active[i]);
 289                         dodgy_memory_active[i]--;
 290                 }
 291 
 292                 return;
 293         }
 294 }
 295 #endif /* DEBUG */
 296 
 297 void*
 298 ped_malloc (size_t size)
 299 {
 300         void*           mem;
 301 
 302         mem = (void*) malloc (size);
 303         if (!mem) {
 304                 ped_exception_throw (PED_EXCEPTION_FATAL, PED_EXCEPTION_CANCEL,
 305                                      _("Out of memory."));
 306                 return NULL;
 307         }
 308 
 309 #ifdef DEBUG
 310         memset (mem, 0xff, size);
 311         _check_dodgy_pointer (mem, size, 1);
 312 #endif
 313 
 314         return mem;
 315 }
 316 
 317 int
 318 ped_realloc (void** old, size_t size)
 319 {
 320         void*           mem;
 321 
 322         mem = (void*) realloc (*old, size);
 323         if (!mem) {
 324                 ped_exception_throw (PED_EXCEPTION_FATAL, PED_EXCEPTION_CANCEL,
 325                                      _("Out of memory."));
 326                 return 0;
 327         }
 328         *old = mem;
 329         return 1;
 330 }
 331 
 332 
 333 void* ped_calloc (size_t size)
 334 {
 335         void* buf = ped_malloc (size);
 336 
 337         memset (buf, 0, size);
 338 
 339         return buf;
 340 }
 341 
 342 
 343 void
 344 ped_free (void* ptr)
 345 {
 346 #ifdef DEBUG
 347         _check_dodgy_pointer (ptr, 0, 0);
 348 #endif
 349 
 350         free (ptr);
 351 }