1 /* @(#)mountcd.c	1.14 21/08/20 Copyright 2005-2021 J. Schilling */
2 #include <schily/mconfig.h>
3 #ifndef lint
4 static	UConst char sccsid[] =
5 	"@(#)mountcd.c	1.14 21/08/20 Copyright 2005-2021 J. Schilling";
6 #endif
7 /*
8  *	Mount the "right" CD medium from a list of devices,
9  *	use ISO-9660 volume ID to identify the correct device.
10  *
11  *	Copyright (c) 2005-2021 J. Schilling
12  */
13 /*
14  * The contents of this file are subject to the terms of the
15  * Common Development and Distribution License, Version 1.0 only
16  * (the "License").  You may not use this file except in compliance
17  * with the License.
18  *
19  * See the file CDDL.Schily.txt in this distribution for details.
20  * A copy of the CDDL is also available via the Internet at
21  * http://www.opensource.org/licenses/cddl1.txt
22  *
23  * When distributing Covered Code, include this CDDL HEADER in each
24  * file and include the License file CDDL.Schily.txt from this distribution.
25  */
26 
27 #include <schily/stdio.h>
28 #include <schily/standard.h>
29 #include <schily/unistd.h>
30 #include <schily/stdlib.h>
31 #include <schily/fcntl.h>
32 #include <schily/dirent.h>
33 #include <schily/string.h>
34 #include <schily/stat.h>
35 #define	GT_COMERR		/* #define comerr gtcomerr */
36 #define	GT_ERROR		/* #define error gterror   */
37 #include <schily/schily.h>
38 #include <schily/errno.h>
39 #include <schily/nlsdefs.h>
40 
41 BOOL	debug = FALSE;
42 
43 LOCAL	void	usage		__PR((int excode));
44 EXPORT	int	main		__PR((int ac, char *av[]));
45 LOCAL	int	trymount	__PR((char *name, char *volid));
46 
47 LOCAL void
usage(excode)48 usage(excode)
49 	int	excode;
50 {
51 	error("Usage:	mountcd [options] [device path ...]\n");
52 	error("Options:\n");
53 	error("	-help		Print this help.\n");
54 	error("	-version	Print version info and exit.\n");
55 	error("	-debug		Print additional debug info.\n");
56 	error("	V=volid		Only mount a CD that matches the Volume ID 'volid'.\n");
57 	exit(excode);
58 }
59 
60 
61 EXPORT int
main(ac,av)62 main(ac, av)
63 	int	ac;
64 	char	*av[];
65 {
66 	int	cac = ac;
67 	char	* const *cav = av;
68 	char	*options = "help,version,debug,V*";
69 	BOOL	help = FALSE;
70 	BOOL	pversion = FALSE;
71 	char	*volid = NULL;
72 	DIR	*dp;
73 	struct dirent *de;
74 	char	*p;
75 	int	i;
76 
77 	save_args(ac, av);
78 
79 	(void) setlocale(LC_ALL, "");
80 
81 #ifdef  USE_NLS
82 #if !defined(TEXT_DOMAIN)	/* Should be defined by cc -D */
83 #define	TEXT_DOMAIN "mountcd"	/* Use this only if it weren't */
84 #endif
85 	{ char	*dir;
86 	dir = searchfileinpath("share/locale", F_OK,
87 					SIP_ANY_FILE|SIP_NO_PATH, NULL);
88 	if (dir)
89 		(void) bindtextdomain(TEXT_DOMAIN, dir);
90 	else
91 #if defined(PROTOTYPES) && defined(INS_BASE)
92 	(void) bindtextdomain(TEXT_DOMAIN, INS_BASE "/share/locale");
93 #else
94 	(void) bindtextdomain(TEXT_DOMAIN, "/usr/share/locale");
95 #endif
96 	(void) textdomain(TEXT_DOMAIN);
97 	}
98 #endif 	/* USE_NLS */
99 
100 	cac--; cav++;
101 	if (getallargs(&cac, &cav, options, &help, &pversion, &debug, &volid) < 0) {
102 		errmsgno(EX_BAD, "Bad flag: %s.\n", cav[0]);
103 		usage(EX_BAD);
104 	}
105 	if (help)
106 		usage(0);
107 	if (pversion) {
108 		printf("Mountcd release %s (%s-%s-%s) Copyright (C) 2005-2021 %s\n",
109 				"1.14", HOST_CPU, HOST_VENDOR, HOST_OS,
110 				_("J�rg Schilling"));
111 		exit(0);
112 	}
113 	if (debug) {
114 		error ("Looking for CD Volume ID '%s'.\n",
115 			volid ? volid:"<NO-Volid specified>");
116 	}
117 	cac = ac;
118 	cav = av;
119 	cac--; cav++;
120 	for (i = 0; getfiles(&cac, &cav, options); cac--, cav++, i++) {
121 		trymount(cav[0], volid);
122 	}
123 
124 	if (i == 0) {
125 		dp = opendir("/dev/dsk");
126 		if (dp == NULL)
127 			exit(EX_BAD);
128 		while ((de = readdir(dp)) != NULL) {
129 #ifdef	__sparc
130 			if ((p = strstr(de->d_name, "s2")) != NULL && p[2] == '\0') {
131 #else
132 			if ((p = strstr(de->d_name, "p0")) != NULL && p[2] == '\0') {
133 #endif
134 				char	pname[225];
135 
136 				snprintf(pname, sizeof (pname), "/dev/dsk/%s", de->d_name);
137 
138 				if (debug)
139 					error("-->name %s\n", pname);
140 				trymount(pname, volid);
141 			}
142 		}
143 	}
144 
145 	return (0);
146 }
147 
148 #include <schily/types.h>
149 #ifdef	HAVE_SYS_MOUNT_H
150 #include <sys/mount.h>
151 #endif
152 #ifdef	HAVE_SYS_MNTTAB_H
153 #include <sys/mnttab.h>
154 #endif
155 #ifdef	HAVE_SYS_MNTENT_H
156 #include <sys/mntent.h>
157 #endif
158 
159 LOCAL int
trymount(name,volid)160 trymount(name, volid)
161 	char	*name;
162 	char	*volid;
163 {
164 	char	buf[2048];
165 	int	len = 0;
166 	int	f;
167 	struct stat sb;
168 
169 	f = open(name, O_RDONLY);
170 	if (f < 0) {
171 		if (debug)
172 			errmsg("Cannot open '%s'.\n", name);
173 		return (-1);
174 	}
175 	if (volid != NULL)
176 		len = strlen(volid);
177 
178 	lseek(f, 16 * sizeof (buf), SEEK_SET);
179 	fillbytes(buf, sizeof (buf), '\0');
180 	if (read(f, buf, sizeof (buf)) < 0) {
181 		if (debug)
182 			errmsg("Cannot read '%s'.\n", name);
183 		close(f);
184 		return (-1);
185 	}
186 	if (strncmp(&buf[1], "CD001", 5) == 0) {
187 		if (debug) {
188 			error("At '%s':\n", name);
189 			error("found CD Volume ID: '%.32s'.\n", &buf[40]);
190 		}
191 		if (volid != NULL && strncmp(&buf[40], volid, len) != 0) {
192 			close(f);
193 			return (0);
194 		}
195 		if (debug)
196 			error("String begin match for CD Volume ID for '%s'.\n", name);
197 		if (buf[40+len] != ' ' && buf[40+len] != '\0') {
198 			close(f);
199 			return (0);
200 		}
201 		if (debug)
202 			error("Full match for CD Volume ID, trying to mount '%s'.\n", name);
203 
204 		if (stat("/.cdrom", &sb) == -1 || !S_ISDIR(sb.st_mode)) {
205 			unlink("/.cdrom");
206 			if (mkdir("/.cdrom", 0755) < 0) {
207 				errmsg("Cannot make directory '%s'.\n", "/.cdrom");
208 				close(f);
209 				return (-1);
210 			}
211 		}
212 		strcpy(buf, "ro");
213 #ifdef	MS_OPTIONSTR
214 		if (mount(name, "/.cdrom", MS_RDONLY|MS_OPTIONSTR, "hsfs", NULL, 0, buf, 64) < 0) {
215 			errmsg("Cannot mount '%s' on '%s'.\n", name, "/.cdrom");
216 			exit(geterrno());
217 		}
218 #else
219 		comerrno(EX_BAD, "mountcd not implemented on this platform.\n");
220 #endif
221 		exit(0);
222 	}
223 	close(f);
224 	return (0);
225 }
226