xref: /freebsd/sbin/mount_udf/mount_udf.c (revision d3250014)
151a7b740SScott Long /*
251a7b740SScott Long  * Copyright (c) 1992, 1993, 1994
351a7b740SScott Long  *      The Regents of the University of California.  All rights reserved.
451a7b740SScott Long  * Copyright (c) 2002 Scott Long
551a7b740SScott Long  *
651a7b740SScott Long  * This code is derived from software contributed to Berkeley
751a7b740SScott Long  * by Pace Willisson (pace@blitz.com).  The Rock Ridge Extension
851a7b740SScott Long  * Support code is derived from software contributed to Berkeley
951a7b740SScott Long  * by Atsushi Murai (amurai@spec.co.jp).
1051a7b740SScott Long  *
1151a7b740SScott Long  * Redistribution and use in source and binary forms, with or without
1251a7b740SScott Long  * modification, are permitted provided that the following conditions
1351a7b740SScott Long  * are met:
1451a7b740SScott Long  * 1. Redistributions of source code must retain the above copyright
1551a7b740SScott Long  *    notice, this list of conditions and the following disclaimer.
1651a7b740SScott Long  * 2. Redistributions in binary form must reproduce the above copyright
1751a7b740SScott Long  *    notice, this list of conditions and the following disclaimer in the
1851a7b740SScott Long  *    documentation and/or other materials provided with the distribution.
1951a7b740SScott Long  * 4. Neither the name of the University nor the names of its contributors
2051a7b740SScott Long  *    may be used to endorse or promote products derived from this software
2151a7b740SScott Long  *    without specific prior written permission.
2251a7b740SScott Long  *
2351a7b740SScott Long  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2451a7b740SScott Long  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2551a7b740SScott Long  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2651a7b740SScott Long  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2751a7b740SScott Long  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2851a7b740SScott Long  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2951a7b740SScott Long  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3051a7b740SScott Long  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3151a7b740SScott Long  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3251a7b740SScott Long  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3351a7b740SScott Long  * SUCH DAMAGE.
3451a7b740SScott Long  *
3551a7b740SScott Long  * $FreeBSD$
3651a7b740SScott Long  */
3751a7b740SScott Long 
3851a7b740SScott Long /*
3951a7b740SScott Long  * This is just a rip-off of mount_iso9660.c.  It's been vastly simplified
4051a7b740SScott Long  * because UDF doesn't take any options at this time.
4151a7b740SScott Long  */
4251a7b740SScott Long 
4351a7b740SScott Long #include <sys/cdio.h>
4451a7b740SScott Long #include <sys/file.h>
45cc2c948fSScott Long #include <sys/iconv.h>
4651a7b740SScott Long #include <sys/param.h>
47cc2c948fSScott Long #include <sys/linker.h>
48cc2c948fSScott Long #include <sys/module.h>
4951a7b740SScott Long #include <sys/mount.h>
50eddb9a0dSMaxime Henrion #include <sys/uio.h>
5151a7b740SScott Long 
52cc2c948fSScott Long #include <fs/udf/udf_mount.h>
53cc2c948fSScott Long 
5451a7b740SScott Long #include <err.h>
5551a7b740SScott Long #include <errno.h>
5651a7b740SScott Long #include <stdlib.h>
5751a7b740SScott Long #include <stdio.h>
5851a7b740SScott Long #include <string.h>
5951a7b740SScott Long #include <sysexits.h>
6051a7b740SScott Long #include <unistd.h>
6151a7b740SScott Long 
6251a7b740SScott Long #include "mntopts.h"
6351a7b740SScott Long 
641efe3c6bSEd Schouten static struct mntopt mopts[] = {
6551a7b740SScott Long 	MOPT_STDOPTS,
6651a7b740SScott Long 	MOPT_UPDATE,
6746b7a14bSXin LI 	MOPT_END
6851a7b740SScott Long };
6951a7b740SScott Long 
70cc2c948fSScott Long int	set_charset(char **, char **, const char *);
7151a7b740SScott Long void	usage(void);
7251a7b740SScott Long 
7351a7b740SScott Long int
7451a7b740SScott Long main(int argc, char **argv)
7551a7b740SScott Long {
76cc2c948fSScott Long 	struct iovec iov[12];
77cc2c948fSScott Long 	int ch, i, mntflags, opts, udf_flags;
7851a7b740SScott Long 	char *dev, *dir, mntpath[MAXPATHLEN];
79cc2c948fSScott Long 	char *cs_disk, *cs_local;
80526ba6d3SMaxime Henrion 	int verbose;
8151a7b740SScott Long 
82cc2c948fSScott Long 	i = mntflags = opts = udf_flags = verbose = 0;
83cc2c948fSScott Long 	cs_disk = cs_local = NULL;
84cc2c948fSScott Long 	while ((ch = getopt(argc, argv, "o:vC:")) != -1)
8551a7b740SScott Long 		switch (ch) {
8651a7b740SScott Long 		case 'o':
8751a7b740SScott Long 			getmntopts(optarg, mopts, &mntflags, &opts);
8851a7b740SScott Long 			break;
8951a7b740SScott Long 		case 'v':
9051a7b740SScott Long 			verbose++;
9151a7b740SScott Long 			break;
92cc2c948fSScott Long 		case 'C':
93cc2c948fSScott Long 			if (set_charset(&cs_disk, &cs_local, optarg) == -1)
94cc2c948fSScott Long 				err(EX_OSERR, "udf_iconv");
95cc2c948fSScott Long 			udf_flags |= UDFMNT_KICONV;
96cc2c948fSScott Long 			break;
9751a7b740SScott Long 		case '?':
9851a7b740SScott Long 		default:
9951a7b740SScott Long 			usage();
10051a7b740SScott Long 		}
10151a7b740SScott Long 	argc -= optind;
10251a7b740SScott Long 	argv += optind;
10351a7b740SScott Long 
10451a7b740SScott Long 	if (argc != 2)
10551a7b740SScott Long 		usage();
10651a7b740SScott Long 
10751a7b740SScott Long 	dev = argv[0];
10851a7b740SScott Long 	dir = argv[1];
10951a7b740SScott Long 
11051a7b740SScott Long 	/*
11151a7b740SScott Long 	 * Resolve the mountpoint with realpath(3) and remove unnecessary
11251a7b740SScott Long 	 * slashes from the devicename if there are any.
11351a7b740SScott Long 	 */
114d3250014SJaakko Heinonen 	if (checkpath(dir, mntpath) != 0)
115d3250014SJaakko Heinonen 		err(EX_USAGE, "%s", mntpath);
11651a7b740SScott Long 	(void)rmslashes(dev, dev);
11751a7b740SScott Long 
11851a7b740SScott Long 	/*
11951a7b740SScott Long 	 * UDF file systems are not writeable.
12051a7b740SScott Long 	 */
12151a7b740SScott Long 	mntflags |= MNT_RDONLY;
12251a7b740SScott Long 
123cc2c948fSScott Long 	iov[i].iov_base = "fstype";
124cc2c948fSScott Long 	iov[i++].iov_len = sizeof("fstype");
125cc2c948fSScott Long 	iov[i].iov_base = "udf";
126cc2c948fSScott Long 	iov[i].iov_len = strlen(iov[i].iov_base) + 1;
127cc2c948fSScott Long 	i++;
128cc2c948fSScott Long 	iov[i].iov_base = "fspath";
129cc2c948fSScott Long 	iov[i++].iov_len = sizeof("fspath");
130cc2c948fSScott Long 	iov[i].iov_base = mntpath;
131cc2c948fSScott Long 	iov[i++].iov_len = strlen(mntpath) + 1;
132cc2c948fSScott Long 	iov[i].iov_base = "from";
133cc2c948fSScott Long 	iov[i++].iov_len = sizeof("from");
134cc2c948fSScott Long 	iov[i].iov_base = dev;
135cc2c948fSScott Long 	iov[i++].iov_len = strlen(dev) + 1;
136cc2c948fSScott Long 	iov[i].iov_base = "flags";
137cc2c948fSScott Long 	iov[i++].iov_len = sizeof("flags");
138cc2c948fSScott Long 	iov[i].iov_base = &udf_flags;
139cc2c948fSScott Long 	iov[i++].iov_len = sizeof(udf_flags);
140cc2c948fSScott Long 	if (udf_flags & UDFMNT_KICONV) {
141cc2c948fSScott Long 		iov[i].iov_base = "cs_disk";
142cc639d55SAlexander Kabaev 		iov[i++].iov_len = sizeof("cs_disk");
143cc2c948fSScott Long 		iov[i].iov_base = cs_disk;
144cc2c948fSScott Long 		iov[i++].iov_len = strlen(cs_disk) + 1;
145cc2c948fSScott Long 		iov[i].iov_base = "cs_local";
146cc639d55SAlexander Kabaev 		iov[i++].iov_len = sizeof("cs_local");
147cc2c948fSScott Long 		iov[i].iov_base = cs_local;
148cc2c948fSScott Long 		iov[i++].iov_len = strlen(cs_local) + 1;
149cc2c948fSScott Long 	}
150cc2c948fSScott Long 	if (nmount(iov, i, mntflags) < 0)
151c3210a83SMaxime Henrion 		err(1, "%s", dev);
15251a7b740SScott Long 	exit(0);
15351a7b740SScott Long }
15451a7b740SScott Long 
155cc2c948fSScott Long int
156cc2c948fSScott Long set_charset(char **cs_disk, char **cs_local, const char *localcs)
157cc2c948fSScott Long {
158cc2c948fSScott Long 	int error;
159cc2c948fSScott Long 
160cc2c948fSScott Long 	if (modfind("udf_iconv") < 0)
161cc2c948fSScott Long 		if (kldload("udf_iconv") < 0 || modfind("udf_iconv") < 0) {
162cc2c948fSScott Long 			warnx( "cannot find or load \"udf_iconv\" kernel module");
163cc2c948fSScott Long 			return (-1);
164cc2c948fSScott Long 		}
165cc2c948fSScott Long 
166cc2c948fSScott Long 	if ((*cs_disk = malloc(ICONV_CSNMAXLEN)) == NULL)
167cc2c948fSScott Long 		return (-1);
168cc2c948fSScott Long 	if ((*cs_local = malloc(ICONV_CSNMAXLEN)) == NULL)
169cc2c948fSScott Long 		return (-1);
170cc2c948fSScott Long 	strncpy(*cs_disk, ENCODING_UNICODE, ICONV_CSNMAXLEN);
171cc2c948fSScott Long 	strncpy(*cs_local, localcs, ICONV_CSNMAXLEN);
1720f4e4130SMax Khon 	error = kiconv_add_xlat16_cspairs(*cs_disk, *cs_local);
173cc2c948fSScott Long 	if (error)
174cc2c948fSScott Long 		return (-1);
175cc2c948fSScott Long 
176cc2c948fSScott Long 	return (0);
177cc2c948fSScott Long }
178cc2c948fSScott Long 
17951a7b740SScott Long void
18051a7b740SScott Long usage(void)
18151a7b740SScott Long {
18251a7b740SScott Long 	(void)fprintf(stderr,
183cc2c948fSScott Long 		"usage: mount_udf [-v] [-o options] [-C charset] special node\n");
18451a7b740SScott Long 	exit(EX_USAGE);
18551a7b740SScott Long }
186