Tue Jul 2 14:59:01 2013 UTC ()
Update newfs_udf to allow for creating file images with -F and specifying
sector sizes with -S.

For this i had to recycle the -S parameter but its preserved as an extension
to the -P parameter. These parameters are hardly ever use though since using
either or both the origional -S and the -P parameter without specific values
would break the standard. Also the -F now has a double meaning.


(reinoud)
diff -r1.9 -r1.10 src/sbin/newfs_udf/newfs_udf.8
diff -r1.12 -r1.13 src/sbin/newfs_udf/newfs_udf.c

cvs diff -r1.9 -r1.10 src/sbin/newfs_udf/newfs_udf.8 (expand / switch to unified diff)

--- src/sbin/newfs_udf/newfs_udf.8 2013/06/29 20:41:47 1.9
+++ src/sbin/newfs_udf/newfs_udf.8 2013/07/02 14:59:01 1.10
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1.\" $NetBSD: newfs_udf.8,v 1.9 2013/06/29 20:41:47 reinoud Exp $ 1.\" $NetBSD: newfs_udf.8,v 1.10 2013/07/02 14:59:01 reinoud Exp $
2.\" 2.\"
3.\" Copyright (c) 2008 Reinoud Zandijk 3.\" Copyright (c) 2008 Reinoud Zandijk
4.\" All rights reserved. 4.\" All rights reserved.
5.\" 5.\"
6.\" Redistribution and use in source and binary forms, with or without 6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions 7.\" modification, are permitted provided that the following conditions
8.\" are met: 8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright 9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer. 10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright 11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in 12.\" notice, this list of conditions and the following disclaimer in
13.\" the documentation and/or other materials provided with the 13.\" the documentation and/or other materials provided with the
14.\" distribution. 14.\" distribution.
@@ -16,80 +16,84 @@ @@ -16,80 +16,84 @@
16.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS 16.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS
17.\" OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17.\" OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY 19.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY
20.\" DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20.\" DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 21.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
22.\" GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22.\" GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 23.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
24.\" IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24.\" IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25.\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 25.\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26.\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26.\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27.\" 27.\"
28.\" 28.\"
29.Dd June 29, 2013 29.Dd July 2, 2013
30.Dt NEWFS_UDF 8 30.Dt NEWFS_UDF 8
31.Os 31.Os
32.Sh NAME 32.Sh NAME
33.Nm newfs_udf 33.Nm newfs_udf
34.Nd construct a new UDF file system 34.Nd construct a new UDF file system
35.Sh SYNOPSIS 35.Sh SYNOPSIS
36.Nm 36.Nm
37.Op Fl cFM 37.Op Fl cFM
38.Op Fl L Ar loglabel 38.Op Fl L Ar loglabel
39.Op Fl P Ar discid 39.Op Fl P Ar discid
40.Op Fl p Ar percentage 40.Op Fl p Ar percentage
41.Op Fl S Ar setlabel 41.Op Fl S Ar sectorsize
42.Op Fl s Ar size 42.Op Fl s Ar size
43.Op Fl t Ar gmtoff 43.Op Fl t Ar gmtoff
44.Op Fl V Ar max_udf 44.Op Fl V Ar max_udf
45.Op Fl v Ar min_udf 45.Op Fl v Ar min_udf
46.Ar special 46.Ar special
47.Sh DESCRIPTION 47.Sh DESCRIPTION
48The 48The
49.Nm 49.Nm
50utility creates an UDF file system on device 50utility creates an UDF file system on device
51.Ar special 51.Ar special
52suitable for the media currently inserted. 52suitable for the media currently inserted.
53.Pp 53.Pp
54The options are as follow: 54The options are as follow:
55.Bl -tag -width indent 55.Bl -tag -width indent
56.It Fl c 56.It Fl c
57Perform a crude surface check first to weed out disc faults on rewritable 57Perform a crude surface check first to weed out disc faults on rewritable
58media. 58media.
59.It Fl F 59.It Fl F
60Force file system construction on non-empty recordable media. 60Force file system construction on non-empty recordable media or create an
 61image file.
61.It Fl L Ar loglabel 62.It Fl L Ar loglabel
62Set the disc logical label to the specified 63Set the disc logical label to the specified
63.Ar loglabel . 64.Ar loglabel .
64.It Fl M 65.It Fl M
65Disable metadata partition creation when selected UDF version or media dictates 66Disable metadata partition creation when selected UDF version or media dictates
66this. 67this.
67For strict conformance and interchange, don't disable this unless 68For strict conformance and interchange, don't disable this unless
68its causing problems. 69its causing problems.
69.It Fl P Ar discid 70.It Fl P Ar discid
70Set the physical disc label to the specified 71Set the physical disc label to the specified
71.Ar discid . 72.Ar discid .
 73Prepend
 74.Ar discid
 75with volsetname separated with a ':' if wanted.
72For strict conformance and interchange, don't set this manually. 76For strict conformance and interchange, don't set this manually.
73.It Fl p Ar percentage 77.It Fl p Ar percentage
74Percentage of partition to be initially reserved for metadata on the Metadata 78Percentage of partition to be initially reserved for metadata on the Metadata
75partition. 79partition.
76It defaults to 20 %. 80It defaults to 20 %.
77.It Fl S Ar setlabel 81.It Fl S Ar sectorsize
78Set the disc set label to the specified 82Set the sectorsize for image files.
79.Ar setlabel . 
80For strict conformance and interchange, don't set this manually. 83For strict conformance and interchange, don't set this manually.
81.It Fl s Ar size 84.It Fl s Ar size
82Ignored for now. 85For image files, set the file size to the humanized size
 86.Ar size .
83.It Fl t Ar gmtoff 87.It Fl t Ar gmtoff
84Use the specified 88Use the specified
85.Ar gmtoff 89.Ar gmtoff
86as gmt time offset for recording times on the disc. 90as gmt time offset for recording times on the disc.
87.It Fl V Ar max_udf 91.It Fl V Ar max_udf
88Select 92Select
89.Ar max_udf 93.Ar max_udf
90as the maximum UDF version to be supported. 94as the maximum UDF version to be supported.
91For UDF version 2.50, use 95For UDF version 2.50, use
92.Dq 0x250 96.Dq 0x250
93or 97or
94.Dq 2.50 . 98.Dq 2.50 .
95.It Fl v Ar min_udf 99.It Fl v Ar min_udf
@@ -113,45 +117,65 @@ or @@ -113,45 +117,65 @@ or
113.Pa /dev/rcd0c . 117.Pa /dev/rcd0c .
114.Pp 118.Pp
115Some rewritable optical media needs to be formatted first before it can be 119Some rewritable optical media needs to be formatted first before it can be
116used by UDF. 120used by UDF.
117This can be done using 121This can be done using
118.Xr mmcformat 8 . 122.Xr mmcformat 8 .
119.Pp 123.Pp
120The default UDF version is version 2.01. 124The default UDF version is version 2.01.
121.Sh EXAMPLES 125.Sh EXAMPLES
122Create a file system, using the specified names on the device 126Create a file system, using the specified names on the device
123.Pa /dev/rcd0d 127.Pa /dev/rcd0d
124with the default UDF version : 128with the default UDF version :
125.Bd -literal -offset indent 129.Bd -literal -offset indent
126newfs_udf -S "Encyclopedia" -L "volume 2" -P "copy-nr-1" /dev/rcd0d 130newfs_udf -P "Encyclopedia:copy-nr-1" -L "volume 2" /dev/rcd0d
127.Ed 131.Ed
128.Pp 132.Pp
129Create a 4.8 GiB sparse file and configure it using 133Create a 4.8 GiB sparse file and configure it using
130.Xr vnconfig 8 134.Xr vnconfig 8
131to be a 2048 sector size disc and create a new UDF file system on 135to be a 2048 sector size disc and create a new UDF file system on
132.Pa /dev/rvnd0d 136.Pa /dev/rvnd0d
133: 137:
134.Bd -literal -offset indent 138.Bd -literal -offset indent
135dd if=/dev/zero of=bigdisk.2048.udf seek=9999999 count=1 139dd if=/dev/zero of=bigdisk.2048.udf seek=9999999 count=1
136vnconfig -c vnd0 bigdisk.2048.udf 2048/1/1/1 140vnconfig -c vnd0 bigdisk.2048.udf 2048/1/1/1
137newfs_udf -L bigdisk /dev/rvnd0d 141newfs_udf -L bigdisk /dev/rvnd0d
138.Ed 142.Ed
139.Pp 143.Pp
 144Create a 2 GiB file and create a new UDF file system on it using the default
 145512 byte sector size :
 146.Bd -literal -offset indent
 147newfs_udf -L bigdisk2 -F -s 2G bigdisk2.iso
 148.Ed
 149.Pp
 150Create a 200 MiB file and create a new UDF file system on it using a sector size
 151of 2048 :
 152.Bd -literal -offset indent
 153newfs_udf -L bigdisk2 -F -s 200M -S 2048 bigdisk3.iso
 154.Ed
 155.Pp
140Create a new UDF file system on the inserted USB stick using its 156Create a new UDF file system on the inserted USB stick using its
141.Dq native 157native sectorsize of 512 :
142sectorsize of 512 : 
143.Bd -literal -offset indent 158.Bd -literal -offset indent
144newfs_udf -L "My USB stick" /dev/rsd0d 159newfs_udf -L "My USB stick" /dev/rsd0d
145.Ed 160.Ed
 161.Sh BUGS
 162The
 163.Ar P
 164and the
 165.Ar S
 166arguments have changed meaning. The meaning of
 167.Ar S
 168has been merged into
 169.Ar P since NetBSD 6.1.
146.Sh SEE ALSO 170.Sh SEE ALSO
147.Xr disktab 5 , 171.Xr disktab 5 ,
148.Xr disklabel 8 , 172.Xr disklabel 8 ,
149.Xr mmcformat 8 , 173.Xr mmcformat 8 ,
150.Xr newfs 8 174.Xr newfs 8
151.Sh HISTORY 175.Sh HISTORY
152The 176The
153.Nm 177.Nm
154command first appeared in 178command first appeared in
155.Nx 5.0 . 179.Nx 5.0 .
156.Sh AUTHORS 180.Sh AUTHORS
157.An Reinoud Zandijk Aq reinoud@NetBSD.org 181.An Reinoud Zandijk Aq reinoud@NetBSD.org

cvs diff -r1.12 -r1.13 src/sbin/newfs_udf/newfs_udf.c (expand / switch to unified diff)

--- src/sbin/newfs_udf/newfs_udf.c 2011/05/26 07:59:08 1.12
+++ src/sbin/newfs_udf/newfs_udf.c 2013/07/02 14:59:01 1.13
@@ -1,17 +1,17 @@ @@ -1,17 +1,17 @@
1/* $NetBSD: newfs_udf.c,v 1.12 2011/05/26 07:59:08 reinoud Exp $ */ 1/* $NetBSD: newfs_udf.c,v 1.13 2013/07/02 14:59:01 reinoud Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2006, 2008 Reinoud Zandijk 4 * Copyright (c) 2006, 2008, 2013 Reinoud Zandijk
5 * All rights reserved. 5 * All rights reserved.
6 *  6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
15 *  15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
@@ -85,26 +85,27 @@ int udf_do_newfs(void); @@ -85,26 +85,27 @@ int udf_do_newfs(void);
85#define APP_VERSION_SUB 3 85#define APP_VERSION_SUB 3
86#define IMPL_NAME "*NetBSD userland UDF" 86#define IMPL_NAME "*NetBSD userland UDF"
87 87
88 88
89/* global variables describing disc and format requests */ 89/* global variables describing disc and format requests */
90int fd; /* device: file descriptor */ 90int fd; /* device: file descriptor */
91char *dev; /* device: name */ 91char *dev; /* device: name */
92struct mmc_discinfo mmc_discinfo; /* device: disc info */ 92struct mmc_discinfo mmc_discinfo; /* device: disc info */
93 93
94char *format_str; /* format: string representation */ 94char *format_str; /* format: string representation */
95int format_flags; /* format: attribute flags */ 95int format_flags; /* format: attribute flags */
96int media_accesstype; /* derived from current mmc cap */ 96int media_accesstype; /* derived from current mmc cap */
97int check_surface; /* for rewritables */ 97int check_surface; /* for rewritables */
 98int imagefile_secsize; /* for files */
98 99
99int wrtrack_skew; 100int wrtrack_skew;
100int meta_perc = UDF_META_PERC; 101int meta_perc = UDF_META_PERC;
101float meta_fract = (float) UDF_META_PERC / 100.0; 102float meta_fract = (float) UDF_META_PERC / 100.0;
102 103
103 104
104/* shared structure between udf_create.c users */ 105/* shared structure between udf_create.c users */
105struct udf_create_context context; 106struct udf_create_context context;
106struct udf_disclayout layout; 107struct udf_disclayout layout;
107 108
108 109
109/* queue for temporary storage of sectors to be written out */ 110/* queue for temporary storage of sectors to be written out */
110struct wrsect { 111struct wrsect {
@@ -273,73 +274,88 @@ udf_dump_discinfo(struct mmc_discinfo *d @@ -273,73 +274,88 @@ udf_dump_discinfo(struct mmc_discinfo *d
273 printf("\n"); 274 printf("\n");
274 printf("\tlast_possible_lba %d\n", di->last_possible_lba); 275 printf("\tlast_possible_lba %d\n", di->last_possible_lba);
275 printf("\n"); 276 printf("\n");
276} 277}
277#else 278#else
278#define udf_dump_discinfo(a); 279#define udf_dump_discinfo(a);
279#endif 280#endif
280 281
281/* --------------------------------------------------------------------- */ 282/* --------------------------------------------------------------------- */
282 283
283static int 284static int
284udf_update_discinfo(struct mmc_discinfo *di) 285udf_update_discinfo(struct mmc_discinfo *di)
285{ 286{
 287 struct stat st;
286 struct disklabel disklab; 288 struct disklabel disklab;
287 struct partition *dp; 289 struct partition *dp;
288 struct stat st; 290 off_t size, sectors, secsize;
289 int partnr, error; 291 int partnr, error;
290 292
291 memset(di, 0, sizeof(struct mmc_discinfo)); 293 memset(di, 0, sizeof(struct mmc_discinfo));
292 294
293 /* check if we're on a MMC capable device, i.e. CD/DVD */ 295 /* check if we're on a MMC capable device, i.e. CD/DVD */
294 error = ioctl(fd, MMCGETDISCINFO, di); 296 error = ioctl(fd, MMCGETDISCINFO, di);
295 if (error == 0) 297 if (error == 0)
296 return 0; 298 return 0;
297 299
298 /* 300 /* (re)fstat the file */
299 * disc partition support; note we can't use DIOCGPART in userland so 
300 * get disc label and use the stat info to get the partition number. 
301 */ 
302 if (ioctl(fd, DIOCGDINFO, &disklab) == -1) { 
303 /* failed to get disclabel! */ 
304 perror("disklabel"); 
305 return errno; 
306 } 
307 
308 /* get disk partition it refers to */ 
309 fstat(fd, &st); 301 fstat(fd, &st);
310 partnr = DISKPART(st.st_rdev); 302
311 dp = &disklab.d_partitions[partnr]; 303 if (S_ISREG(st.st_mode)) {
 304 /* file support; we pick the minimum sector size allowed */
 305 size = st.st_size;
 306 secsize = imagefile_secsize;
 307 sectors = size / secsize;
 308 } else {
 309 /*
 310 * disc partition support; note we can't use DIOCGPART in userland so
 311 * get disc label and use the stat info to get the partition number.
 312 */
 313 if (ioctl(fd, DIOCGDINFO, &disklab) == -1) {
 314 /* failed to get disclabel! */
 315 perror("disklabel");
 316 return errno;
 317 }
 318
 319 /* get disk partition it refers to */
 320 fstat(fd, &st);
 321 partnr = DISKPART(st.st_rdev);
 322 dp = &disklab.d_partitions[partnr];
 323
 324 /* TODO problem with last_possible_lba on resizable VND; request */
 325 if (dp->p_size == 0) {
 326 perror("faulty disklabel partition returned, check label\n");
 327 return EIO;
 328 }
 329
 330 sectors = dp->p_size;
 331 secsize = disklab.d_secsize;
 332 }
312 333
313 /* set up a disc info profile for partitions */ 334 /* set up a disc info profile for partitions */
314 di->mmc_profile = 0x01; /* disc type */ 335 di->mmc_profile = 0x01; /* disc type */
315 di->mmc_class = MMC_CLASS_DISC; 336 di->mmc_class = MMC_CLASS_DISC;
316 di->disc_state = MMC_STATE_CLOSED; 337 di->disc_state = MMC_STATE_CLOSED;
317 di->last_session_state = MMC_STATE_CLOSED; 338 di->last_session_state = MMC_STATE_CLOSED;
318 di->bg_format_state = MMC_BGFSTATE_COMPLETED; 339 di->bg_format_state = MMC_BGFSTATE_COMPLETED;
319 di->link_block_penalty = 0; 340 di->link_block_penalty = 0;
320 341
321 di->mmc_cur = MMC_CAP_RECORDABLE | MMC_CAP_REWRITABLE | 342 di->mmc_cur = MMC_CAP_RECORDABLE | MMC_CAP_REWRITABLE |
322 MMC_CAP_ZEROLINKBLK | MMC_CAP_HW_DEFECTFREE; 343 MMC_CAP_ZEROLINKBLK | MMC_CAP_HW_DEFECTFREE;
323 di->mmc_cap = di->mmc_cur; 344 di->mmc_cap = di->mmc_cur;
324 di->disc_flags = MMC_DFLAGS_UNRESTRICTED; 345 di->disc_flags = MMC_DFLAGS_UNRESTRICTED;
325 346
326 /* TODO problem with last_possible_lba on resizable VND; request */ 347 di->last_possible_lba = sectors - 1;
327 if (dp->p_size == 0) { 348 di->sector_size = secsize;
328 perror("faulty disklabel partition returned, check label\n"); 
329 return EIO; 
330 } 
331 di->last_possible_lba = dp->p_size - 1; 
332 di->sector_size = disklab.d_secsize; 
333 349
334 di->num_sessions = 1; 350 di->num_sessions = 1;
335 di->num_tracks = 1; 351 di->num_tracks = 1;
336 352
337 di->first_track = 1; 353 di->first_track = 1;
338 di->first_track_last_session = di->last_track_last_session = 1; 354 di->first_track_last_session = di->last_track_last_session = 1;
339 355
340 return 0; 356 return 0;
341} 357}
342 358
343 359
344static int 360static int
345udf_update_trackinfo(struct mmc_discinfo *di, struct mmc_trackinfo *ti) 361udf_update_trackinfo(struct mmc_discinfo *di, struct mmc_trackinfo *ti)
@@ -1427,50 +1443,53 @@ a_udf_version(const char *s, const char  @@ -1427,50 +1443,53 @@ a_udf_version(const char *s, const char
1427 uint32_t version; 1443 uint32_t version;
1428 1444
1429 if (parse_udfversion(s, &version)) 1445 if (parse_udfversion(s, &version))
1430 errx(1, "unknown %s id %s; specify as hex or float", id_type, s); 1446 errx(1, "unknown %s id %s; specify as hex or float", id_type, s);
1431 return version; 1447 return version;
1432} 1448}
1433 1449
1434/* --------------------------------------------------------------------- */ 1450/* --------------------------------------------------------------------- */
1435 1451
1436static void 1452static void
1437usage(void) 1453usage(void)
1438{ 1454{
1439 (void)fprintf(stderr, "Usage: %s [-cFM] [-L loglabel] " 1455 (void)fprintf(stderr, "Usage: %s [-cFM] [-L loglabel] "
1440 "[-P discid] [-S setlabel] [-s size] [-p perc] " 1456 "[-P discid] [-S sectorsize] [-s size] [-p perc] "
1441 "[-t gmtoff] [-v min_udf] [-V max_udf] special\n", getprogname()); 1457 "[-t gmtoff] [-v min_udf] [-V max_udf] special\n", getprogname());
1442 exit(EXIT_FAILURE); 1458 exit(EXIT_FAILURE);
1443} 1459}
1444 1460
1445 1461
1446int 1462int
1447main(int argc, char **argv) 1463main(int argc, char **argv)
1448{ 1464{
1449 struct tm *tm; 1465 struct tm *tm;
1450 struct stat st; 1466 struct stat st;
1451 time_t now; 1467 time_t now;
1452 char scrap[255]; 1468 off_t setsize;
 1469 char scrap[255], *colon;
1453 int ch, req_enable, req_disable, force; 1470 int ch, req_enable, req_disable, force;
1454 int error; 1471 int error;
1455 1472
1456 setprogname(argv[0]); 1473 setprogname(argv[0]);
1457 1474
1458 /* initialise */ 1475 /* initialise */
1459 format_str = strdup(""); 1476 format_str = strdup("");
1460 req_enable = req_disable = 0; 1477 req_enable = req_disable = 0;
1461 format_flags = FORMAT_INVALID; 1478 format_flags = FORMAT_INVALID;
1462 force = 0; 1479 force = 0;
1463 check_surface = 0; 1480 check_surface = 0;
 1481 setsize = 0;
 1482 imagefile_secsize = 512; /* minimum allowed sector size */
1464 1483
1465 srandom((unsigned long) time(NULL)); 1484 srandom((unsigned long) time(NULL));
1466 udf_init_create_context(); 1485 udf_init_create_context();
1467 context.app_name = APP_NAME; 1486 context.app_name = APP_NAME;
1468 context.impl_name = IMPL_NAME; 1487 context.impl_name = IMPL_NAME;
1469 context.app_version_main = APP_VERSION_MAIN; 1488 context.app_version_main = APP_VERSION_MAIN;
1470 context.app_version_sub = APP_VERSION_SUB; 1489 context.app_version_sub = APP_VERSION_SUB;
1471 1490
1472 /* minimum and maximum UDF versions we advise */ 1491 /* minimum and maximum UDF versions we advise */
1473 context.min_udf = 0x201; 1492 context.min_udf = 0x201;
1474 context.max_udf = 0x201; 1493 context.max_udf = 0x201;
1475 1494
1476 /* use user's time zone as default */ 1495 /* use user's time zone as default */
@@ -1502,75 +1521,126 @@ main(int argc, char **argv) @@ -1502,75 +1521,126 @@ main(int argc, char **argv)
1502 meta_fract = (float) meta_perc/100.0; 1521 meta_fract = (float) meta_perc/100.0;
1503 break; 1522 break;
1504 case 'v' : 1523 case 'v' :
1505 context.min_udf = a_udf_version(optarg, "min_udf"); 1524 context.min_udf = a_udf_version(optarg, "min_udf");
1506 if (context.min_udf > context.max_udf) 1525 if (context.min_udf > context.max_udf)
1507 context.max_udf = context.min_udf; 1526 context.max_udf = context.min_udf;
1508 break; 1527 break;
1509 case 'V' : 1528 case 'V' :
1510 context.max_udf = a_udf_version(optarg, "max_udf"); 1529 context.max_udf = a_udf_version(optarg, "max_udf");
1511 if (context.min_udf > context.max_udf) 1530 if (context.min_udf > context.max_udf)
1512 context.min_udf = context.max_udf; 1531 context.min_udf = context.max_udf;
1513 break; 1532 break;
1514 case 'P' : 1533 case 'P' :
 1534 /* check if there is a ':' in the name */
 1535 if ((colon = strstr(optarg, ":"))) {
 1536 if (context.volset_name)
 1537 free(context.volset_name);
 1538 *colon = 0;
 1539 context.volset_name = strdup(optarg);
 1540 optarg = colon+1;
 1541 }
 1542 if (context.primary_name)
 1543 free(context.primary_name);
 1544 if ((strstr(optarg, ":"))) {
 1545 perror("primary name can't have ':' in its name");
 1546 return EXIT_FAILURE;
 1547 }
1515 context.primary_name = strdup(optarg); 1548 context.primary_name = strdup(optarg);
1516 break; 1549 break;
1517 case 's' : 1550 case 's' :
1518 /* TODO size argument; recordable emulation */ 1551 /* support for files, set file size */
 1552 /* XXX support for formatting recordables on vnd/file? */
 1553 if (dehumanize_number(optarg, &setsize) < 0) {
 1554 perror("can't parse size argument");
 1555 return EXIT_FAILURE;
 1556 }
 1557 setsize = MAX(0, setsize);
1519 break; 1558 break;
1520 case 'S' : 1559 case 'S' :
1521 if (context.volset_name) free(context.volset_name); 1560 imagefile_secsize = a_num(optarg, "secsize");
1522 context.volset_name = strdup(optarg); 1561 imagefile_secsize = MAX(512, imagefile_secsize);
1523 break; 1562 break;
1524 case 't' : 1563 case 't' :
1525 /* time zone overide */ 1564 /* time zone overide */
1526 context.gmtoff = a_num(optarg, "gmtoff"); 1565 context.gmtoff = a_num(optarg, "gmtoff");
1527 break; 1566 break;
1528 default : 1567 default :
1529 usage(); 1568 usage();
1530 /* NOTREACHED */ 1569 /* NOTREACHED */
1531 } 1570 }
1532 } 1571 }
1533 1572
1534 if (optind + 1 != argc) 1573 if (optind + 1 != argc)
1535 usage(); 1574 usage();
1536 1575
1537 /* get device and directory specifier */ 1576 /* get device and directory specifier */
1538 dev = argv[optind]; 1577 dev = argv[optind];
1539 1578
1540 /* open device */ 1579 /* open device */
1541 if ((fd = open(dev, O_RDWR, 0)) == -1) { 1580 if ((fd = open(dev, O_RDWR, 0)) == -1) {
1542 perror("can't open device"); 1581 /* check if we need to create a file */
1543 return EXIT_FAILURE; 1582 fd = open(dev, O_RDONLY, 0);
 1583 if (fd > 0) {
 1584 perror("device is there but can't be opened for read/write");
 1585 return EXIT_FAILURE;
 1586 }
 1587 if (!force) {
 1588 perror("can't open device");
 1589 return EXIT_FAILURE;
 1590 }
 1591 if (setsize == 0) {
 1592 perror("need to create image file but no size specified");
 1593 return EXIT_FAILURE;
 1594 }
 1595 /* need to create a file */
 1596 fd = open(dev, O_RDWR | O_CREAT | O_TRUNC, 0777);
 1597 if (fd == -1) {
 1598 perror("can't create image file");
 1599 return EXIT_FAILURE;
 1600 }
1544 } 1601 }
1545 1602
1546 /* stat the device */ 1603 /* stat the device */
1547 if (fstat(fd, &st) != 0) { 1604 if (fstat(fd, &st) != 0) {
1548 perror("can't stat the device"); 1605 perror("can't stat the device");
1549 close(fd); 1606 close(fd);
1550 return EXIT_FAILURE; 1607 return EXIT_FAILURE;
1551 } 1608 }
1552 1609
 1610 if (S_ISREG(st.st_mode)) {
 1611 if (setsize == 0)
 1612 setsize = st.st_size;
 1613 /* sanitise arguments */
 1614 imagefile_secsize &= ~511;
 1615 setsize &= ~(imagefile_secsize-1);
 1616
 1617 if (ftruncate(fd, setsize)) {
 1618 perror("can't resize file");
 1619 return EXIT_FAILURE;
 1620 }
 1621 }
 1622
1553 /* formatting can only be done on raw devices */ 1623 /* formatting can only be done on raw devices */
1554 if (!S_ISCHR(st.st_mode)) { 1624 if (!S_ISREG(st.st_mode) && !S_ISCHR(st.st_mode)) {
1555 printf("%s is not a raw device\n", dev); 1625 printf("%s is not a raw device\n", dev);
1556 close(fd); 1626 close(fd);
1557 return EXIT_FAILURE; 1627 return EXIT_FAILURE;
1558 } 1628 }
1559 1629
1560 /* just in case something went wrong, synchronise the drive's cache */ 1630 /* just in case something went wrong, synchronise the drive's cache */
1561 udf_synchronise_caches(); 1631 udf_synchronise_caches();
1562 1632
1563 /* get disc information */ 1633 /* get 'disc' information */
1564 error = udf_update_discinfo(&mmc_discinfo); 1634 error = udf_update_discinfo(&mmc_discinfo);
1565 if (error) { 1635 if (error) {
1566 perror("can't retrieve discinfo"); 1636 perror("can't retrieve discinfo");
1567 close(fd); 1637 close(fd);
1568 return EXIT_FAILURE; 1638 return EXIT_FAILURE;
1569 } 1639 }
1570 1640
1571 /* derive disc identifiers when not specified and check given */ 1641 /* derive disc identifiers when not specified and check given */
1572 error = udf_proces_names(); 1642 error = udf_proces_names();
1573 if (error) { 1643 if (error) {
1574 /* error message has been printed */ 1644 /* error message has been printed */
1575 close(fd); 1645 close(fd);
1576 return EXIT_FAILURE; 1646 return EXIT_FAILURE;