OSDN Git Service

maint: update all FSF copyright year lists to include 2010
[android-x86/external-parted.git] / libparted / labels / pt-tools.c
1 /* partition table tools
2    Copyright (C) 2008-2010 Free Software Foundation, Inc.
3
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; either version 3 of the License, or
7    (at your option) any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program.  If not, see <http://www.gnu.org/licenses/>. */
16
17 #include <config.h>
18
19 #include <string.h>
20 #include <stdlib.h>
21
22 #include <parted/parted.h>
23 #include <parted/debug.h>
24
25 #include "pt-tools.h"
26
27 #if ENABLE_NLS
28 # include <libintl.h>
29 # define _(String) dgettext (PACKAGE, String)
30 #else
31 # define _(String) (String)
32 #endif /* ENABLE_NLS */
33
34 static char zero[16 * 1024];
35
36 /* Write a single sector to DISK, filling the first BUFLEN
37    bytes of that sector with data from BUF, and NUL-filling
38    any remaining bytes.  Return nonzero to indicate success,
39    zero otherwise.  */
40 int
41 ptt_write_sector (PedDisk const *disk, void const *buf, size_t buflen)
42 {
43   PED_ASSERT (buflen <= disk->dev->sector_size, return 0);
44   /* Allocate a big enough buffer for ped_device_write.  */
45   char *s0 = ped_malloc (disk->dev->sector_size);
46   if (s0 == NULL)
47     return 0;
48   /* Copy boot_code into the first part.  */
49   memcpy (s0, buf, buflen);
50   char *p = s0 + buflen;
51   /* Fill the rest with zeros.  */
52   memset (p, 0, disk->dev->sector_size - buflen);
53   int write_ok = ped_device_write (disk->dev, s0, 0, 1);
54   free (s0);
55
56   return write_ok;
57 }
58
59 /* Read N sectors, starting with sector SECTOR_NUM (which has length
60    DEV->sector_size) into malloc'd storage.  If the read fails, free
61    the memory and return zero without modifying *BUF.  Otherwise, set
62    *BUF to the new buffer and return 1.  */
63 int
64 ptt_read_sectors (PedDevice const *dev, PedSector start_sector,
65                   PedSector n_sectors, void **buf)
66 {
67   char *b = ped_malloc (n_sectors * dev->sector_size);
68   PED_ASSERT (b != NULL, return 0);
69   if (!ped_device_read (dev, b, start_sector, n_sectors)) {
70     free (b);
71     return 0;
72   }
73   *buf = b;
74   return 1;
75 }
76
77 /* Read sector, SECTOR_NUM (which has length DEV->sector_size) into malloc'd
78    storage.  If the read fails, free the memory and return zero without
79    modifying *BUF.  Otherwise, set *BUF to the new buffer and return 1.  */
80 int
81 ptt_read_sector (PedDevice const *dev, PedSector sector_num, void **buf)
82 {
83   return ptt_read_sectors (dev, sector_num, 1, buf);
84 }
85
86 /* Zero N sectors of DEV, starting with START.
87    Return nonzero to indicate success, zero otherwise.  */
88 int
89 ptt_clear_sectors (PedDevice *dev, PedSector start, PedSector n)
90 {
91   PED_ASSERT (dev->sector_size <= sizeof zero, return 0);
92   PedSector n_z_sectors = sizeof zero / dev->sector_size;
93   PedSector n_full = n / n_z_sectors;
94   PedSector i;
95   for (i = 0; i < n_full; i++)
96     {
97       if (!ped_device_write (dev, zero, start + n_z_sectors * i, n_z_sectors))
98         return 0;
99     }
100
101   PedSector rem = n - n_z_sectors * i;
102   return (rem == 0
103           ? 1 : ped_device_write (dev, zero, start + n_z_sectors * i, rem));
104 }
105
106 #include "pt-limit.c"
107
108 /* Throw an exception and return 0 if PART's starting sector number or
109    its length is greater than the maximum allowed value for LABEL_TYPE.
110    Otherwise, return 1.  */
111 int
112 ptt_partition_max_start_len (char const *pt_type, const PedPartition *part)
113 {
114   struct partition_limit const *pt_lim
115     = pt_limit_lookup (pt_type, strlen (pt_type));
116
117   /* If we don't have info on the type, return "true".  */
118   if (pt_lim == NULL)
119     return 1;
120
121   /* If the length in sectors exceeds the limit, you lose.  */
122   if (part->geom.length > pt_lim->max_length)
123     {
124       ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
125                            _("partition length of %jd sectors exceeds"
126                              " the %s-partition-table-imposed maximum"
127                              " of %jd"),
128                            part->geom.length,
129                            pt_type,
130                            UINT32_MAX);
131       return 0;
132     }
133
134   /* If the starting sector exceeds the limit, you lose.  */
135   if (part->geom.start > pt_lim->max_start_sector) {
136     ped_exception_throw (
137                          PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
138                          _("starting sector number, %jd exceeds"
139                            " the %s-partition-table-imposed maximum"
140                            " of %jd"),
141                          part->geom.start,
142                          pt_type,
143                          UINT32_MAX);
144     return 0;
145   }
146
147   return 1;
148 }
149
150 /* Set *MAX to the largest representation-imposed starting sector number
151    of a partition of type PT_TYPE and return 0.  If PT_TYPE is not
152    recognized, return -1.  */
153 int
154 ptt_partition_max_start_sector (char const *pt_type, PedSector *max)
155 {
156   struct partition_limit const *pt_lim
157     = pt_limit_lookup (pt_type, strlen (pt_type));
158   if (pt_lim == NULL)
159     return -1;
160
161   *max = pt_lim->max_start_sector;
162   return 0;
163 }
164
165 /* Set *MAX to the maximum representable length of a partition of type
166    PT_TYPE and return 0.  If PT_TYPE is not recognized, return -1.  */
167 int
168 ptt_partition_max_length (char const *pt_type, PedSector *max)
169 {
170   struct partition_limit const *pt_lim
171     = pt_limit_lookup (pt_type, strlen (pt_type));
172   if (pt_lim == NULL)
173     return -1;
174
175   *max = pt_lim->max_length;
176   return 0;
177 }