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
ped_set_architecture(const PedArchitecture * arch)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
init_disk_types()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
init_file_system_types()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
done_disk_types()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
_init()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
done_file_system_types()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
_done()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*
ped_get_version()256 ped_get_version ()
257 {
258 return VERSION;
259 }
260
261 #ifdef DEBUG
262 static void
_check_dodgy_pointer(const void * ptr,size_t size,int is_malloc)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*
ped_malloc(size_t size)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
ped_realloc(void ** old,size_t size)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
ped_calloc(size_t size)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
ped_free(void * ptr)344 ped_free (void* ptr)
345 {
346 #ifdef DEBUG
347 _check_dodgy_pointer (ptr, 0, 0);
348 #endif
349
350 free (ptr);
351 }
352