4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
22 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
23 /* All Rights Reserved */
27 * Copyright (c) 1997, by Sun Microsystems, Inc.
28 * All rights reserved.
35 #include <sys/types.h>
43 #define FORMFS_MSG ",\\n\\ \\ or [f] to format %s and place a filesystem on it"
44 #define FORMAT_MSG ",\\n\\ \\ or [f] to format the %s"
45 #define MAKEFS_MSG ",\\n\\ \\ or [m] to place a filesystem on %s"
46 #define EJECT_MSG ",\\n\\ \\ or [e] to eject the %s"
47 #define UNLOAD_MSG ",\\n\\ \\ or [u] to unload/offline the %s"
48 #define WLABEL_MSG ",\\n\\ \\ or [w] to write a new label on the %s"
49 #define OLABEL_MSG ",\\n\\ \\ or [o] to use the current label anyway"
50 #define QUIT_MSG ",\\n\\ \\ or [q] to quit"
52 #define ERR_ACCESS "\n%s (%s) cannot be accessed.\n"
53 #define ERR_FMT "\nAttempt to format %s failed.\n"
54 #define ERR_MKFS "\nAttempt to place filesystem on %s failed.\n"
55 #define ERR_REMOVE "\nExecution of \"removecmd\"[%s] failed.\n"
57 static void elabel(void);
58 static void doformat(char *, char *, char *);
59 static void labelerr(char *, char *);
60 static int ckilabel(char *, int);
61 static int insert(char *, char *, int, char *);
63 static char *cdevice
; /* character device name */
64 static char *pname
; /* device presentation name */
65 static char *volume
; /* volume name */
66 static char origfsname
[LABELSIZ
+1];
67 static char origvolname
[LABELSIZ
+1];
71 * 0 - okay, label matches
72 * 1 - device not accessable
73 * 2 - unknown device (devattr failed)
74 * 3 - user selected quit
75 * 4 - label does not match
79 * macros from labelit to behave correctly for tape
80 * is a kludge, should use devmgmt
83 #define IFTAPE(s) ((strncmp(s, "/dev/mt", 7) == 0) || \
84 (strncmp(s, "mt", 2) == 0))
85 #define TAPENAMES "'/dev/mt'"
87 #define IFTAPE(s) ((strncmp(s, "/dev/rmt", 8) == 0) || \
88 (strncmp(s, "rmt", 3) == 0) || (strncmp(s, "/dev/rtp", 8) == 0) || \
89 (strncmp(s, "rtp", 3) == 0))
90 #define TAPENAMES "'/dev/rmt' or '/dev/rtp'"
94 getvol(char *device
, char *label
, int options
, char *prompt
)
96 return (_getvol(device
, label
, options
, prompt
, NULL
));
100 _getvol(char *device
, char *label
, int options
, char *prompt
, char *norewind
)
106 cdevice
= devattr(device
, "cdevice");
107 if ((cdevice
== NULL
) || !cdevice
[0]) {
108 cdevice
= devattr(device
, "pathname");
109 if ((cdevice
== NULL
) || !cdevice
)
110 return (2); /* bad device */
113 pname
= devattr(device
, "desc");
115 pname
= devattr(device
, "alias");
120 volume
= devattr(device
, "volume");
123 (void) strncpy(origfsname
, label
, LABELSIZ
);
124 origfsname
[LABELSIZ
] = '\0';
125 if (pt
= strchr(origfsname
, ',')) {
128 if (pt
= strchr(label
, ',')) {
129 (void) strncpy(origvolname
, pt
+1, LABELSIZ
);
130 origvolname
[LABELSIZ
] = '\0';
132 origvolname
[0] = '\0';
137 if (!(options
& DM_BATCH
) && volume
) {
138 n
= insert(device
, label
, options
, prompt
);
142 return (n
); /* input function failed */
145 if ((tmp
= fopen(norewind
? norewind
: cdevice
, "r")) == NULL
) {
146 /* device was not accessible */
147 if (options
& DM_BATCH
)
149 (void) fprintf(stderr
, ERR_ACCESS
, pname
, cdevice
);
150 if ((options
& DM_BATCH
) || (volume
== NULL
))
152 /* display advice on how to ready device */
153 if (advice
= devattr(device
, "advice"))
154 (void) puttext(stderr
, advice
, 0, 0);
159 /* check label on device */
161 if (options
& DM_ELABEL
)
164 /* check internal label using /etc/labelit */
165 if (ckilabel(label
, override
)) {
166 if ((options
& DM_BATCH
) ||
179 ckilabel(char *label
, int flag
)
182 char *pt
, *look
, buffer
[512];
183 char fsname
[LABELSIZ
+1], volname
[LABELSIZ
+1];
184 char *pvolname
, *pfsname
;
187 (void) strncpy(fsname
, label
, LABELSIZ
);
188 fsname
[LABELSIZ
] = '\0';
189 if (pt
= strchr(fsname
, ',')) {
192 if (pt
= strchr(label
, ',')) {
193 (void) strncpy(volname
, pt
+1, LABELSIZ
);
194 volname
[LABELSIZ
] = '\0';
198 (void) snprintf(buffer
, sizeof (buffer
), "/etc/labelit %s", cdevice
);
199 pp
= popen(buffer
, "r");
201 while ((c
= getc(pp
)) != EOF
)
207 pfsname
= pvolname
= NULL
;
208 look
= "Current fsname: ";
209 n
= (int)strlen(look
);
211 if (strncmp(pt
, look
, n
) == 0) {
214 if (pfsname
== NULL
) {
216 look
= ", Current volname: ";
217 n
= (int)strlen(look
);
218 } else if (pvolname
== NULL
) {
221 n
= (int)strlen(look
);
228 if (strcmp(fsname
, pfsname
) || strcmp(volname
, pvolname
)) {
229 /* mismatched label */
231 /* LINTED E_SEC_SPRINTF_UNBOUNDED_COPY */
232 (void) sprintf(label
, "%s,%s", pfsname
, pvolname
);
234 labelerr(pfsname
, pvolname
);
245 char fsname
[LABELSIZ
+1];
246 char volname
[LABELSIZ
+1];
249 if (!label
|| !strlen(origfsname
)) {
250 if (n
= ckstr(fsname
, NULL
, LABELSIZ
, NULL
, NULL
, NULL
,
251 "Enter text for fsname label:"))
254 (void) strcpy(fsname
, origfsname
);
255 if (!label
|| !strlen(origvolname
)) {
256 if (n
= ckstr(volname
, NULL
, LABELSIZ
, NULL
, NULL
, NULL
,
257 "Enter text for volume label:"))
260 (void) strcpy(volname
, origvolname
);
262 if (IFTAPE(cdevice
)) {
263 (void) snprintf(buffer
, sizeof (buffer
),
264 "/etc/labelit %s \"%s\" \"%s\" -n 1>&2",
265 cdevice
, fsname
, volname
);
267 (void) snprintf(buffer
, sizeof (buffer
),
268 "/etc/labelit %s \"%s\" \"%s\" 1>&2",
269 cdevice
, fsname
, volname
);
271 if (system(buffer
)) {
272 (void) fprintf(stderr
, "\nWrite of label to %s failed.", pname
);
276 /* LINTED E_SEC_SPRINTF_UNBOUNDED_COPY */
277 (void) sprintf(label
, "%s,%s", fsname
, volname
);
287 insert(char *device
, char *label
, int options
, char *prompt
)
290 char strval
[16], prmpt
[BUFSIZ
];
291 char *pt
, *keyword
[10];
298 voltxt
= (volume
? volume
: "volume");
300 fmtcmd
= devattr(device
, "fmtcmd");
301 mkfscmd
= devattr(device
, "mkfscmd");
302 removecmd
= devattr(device
, "removecmd");
303 dev_type
= devattr(device
, "type");
306 (void) strlcpy(prmpt
, prompt
, sizeof (prmpt
));
307 for (pt
= prmpt
; *prompt
; ) {
308 if ((*prompt
== '\\') && (prompt
[1] == '%'))
310 else if (*prompt
== '%') {
313 (void) strcpy(pt
, voltxt
);
317 (void) strcpy(pt
, pname
);
324 pt
= pt
+ strlen(pt
);
332 /* LINTED E_SEC_SPRINTF_UNBOUNDED_COPY */
333 (void) sprintf(prmpt
, "Insert a %s into %s.", voltxt
, pname
);
334 if (label
&& (options
& DM_ELABEL
)) {
335 (void) strcat(prmpt
, " The following external label ");
336 /* LINTED E_SEC_SPRINTF_UNBOUNDED_COPY */
337 (void) sprintf(prmpt
+strlen(prmpt
),
338 " should appear on the %s:\\n\\t%s",
341 if (label
&& !(options
& DM_ELABEL
)) {
342 /* LINTED E_SEC_SPRINTF_UNBOUNDED_COPY */
343 (void) sprintf(prmpt
+strlen(prmpt
),
344 " The %s should be internally labeled as follows:",
346 /* LINTED E_SEC_SPRINTF_UNBOUNDED_COPY */
347 (void) sprintf(prmpt
+strlen(prmpt
),
348 "\\n\\t%s\\n", label
);
352 pt
= prompt
= prmpt
+ strlen(prmpt
);
355 pt
+= sprintf(pt
, "\\nType [go] when ready");
358 if (options
& DM_FORMFS
) {
359 if (fmtcmd
&& *fmtcmd
&& mkfscmd
&& *mkfscmd
) {
360 /* LINTED E_SEC_SPRINTF_UNBOUNDED_COPY */
361 pt
+= sprintf(pt
, FORMFS_MSG
, voltxt
);
363 } else if (fmtcmd
&& *fmtcmd
) {
364 /* LINTED E_SEC_SPRINTF_UNBOUNDED_COPY */
365 pt
+= sprintf(pt
, FORMAT_MSG
, voltxt
);
368 if (mkfscmd
&& *mkfscmd
) {
369 /* LINTED E_SEC_SPRINTF_UNBOUNDED_COPY */
370 pt
+= sprintf(pt
, MAKEFS_MSG
, voltxt
);
373 } else if (options
& DM_FORMAT
) {
374 if (fmtcmd
&& *fmtcmd
) {
375 /* LINTED E_SEC_SPRINTF_UNBOUNDED_COPY */
376 pt
+= sprintf(pt
, FORMAT_MSG
, voltxt
);
380 if (options
& DM_WLABEL
) {
381 /* LINTED E_SEC_SPRINTF_UNBOUNDED_COPY */
382 pt
+= sprintf(pt
, WLABEL_MSG
, voltxt
);
385 if (options
& DM_OLABEL
) {
386 pt
+= sprintf(pt
, OLABEL_MSG
);
389 if (removecmd
&& *removecmd
&& dev_type
&& *dev_type
) {
390 if (strcmp(dev_type
, "diskette") == 0) {
391 /* LINTED E_SEC_SPRINTF_UNBOUNDED_COPY */
392 pt
+= sprintf(pt
, EJECT_MSG
, voltxt
);
395 /* LINTED E_SEC_SPRINTF_UNBOUNDED_COPY */
396 pt
+= sprintf(pt
, UNLOAD_MSG
, voltxt
);
402 pt
+= sprintf(pt
, QUIT_MSG
);
407 (void) fprintf(stderr
, BELL
);
409 if (n
= ckkeywd(strval
, keyword
, NULL
, NULL
, NULL
, pt
))
412 pt
= prompt
; /* next prompt is only partial */
413 if (*strval
== 'f') {
414 if (options
& DM_FORMFS
)
415 doformat(voltxt
, fmtcmd
, mkfscmd
);
417 doformat(voltxt
, fmtcmd
, NULL
);
419 } else if (*strval
== 'm') {
420 doformat(voltxt
, NULL
, mkfscmd
);
422 } else if (*strval
== 'e' || *strval
== 'u') {
423 (void) doremovecmd(device
, 1);
425 } else if (*strval
== 'w') {
426 (void) wilabel(label
);
428 } else if (*strval
== 'o')
436 doformat(char *voltxt
, char *fmtcmd
, char *mkfscmd
)
440 if (fmtcmd
&& *fmtcmd
) {
441 (void) fprintf(stderr
, "\t[%s]\n", fmtcmd
);
442 (void) snprintf(buffer
, sizeof (buffer
), "(%s) 1>&2", fmtcmd
);
443 if (system(buffer
)) {
444 (void) fprintf(stderr
, ERR_FMT
, voltxt
);
448 if (mkfscmd
&& *mkfscmd
) {
449 (void) fprintf(stderr
, "\t[%s]\n", mkfscmd
);
450 (void) snprintf(buffer
, sizeof (buffer
), "(%s) 1>&2", mkfscmd
);
451 if (system(buffer
)) {
452 (void) fprintf(stderr
, ERR_MKFS
, voltxt
);
459 doremovecmd(char *device
, int echo
)
464 if (device
&& *device
) {
465 removecmd
= devattr(device
, "removecmd");
466 if (removecmd
&& *removecmd
) {
468 (void) fprintf(stderr
, "\t[%s]\n", removecmd
);
469 (void) snprintf(buffer
, sizeof (buffer
),
470 "(%s) 1>&2", removecmd
);
471 if (system(buffer
)) {
473 (void) fprintf(stderr
, ERR_REMOVE
,
482 labelerr(char *fsname
, char *volname
)
484 (void) fprintf(stderr
, "\nLabel incorrect.\n");
486 (void) fprintf(stderr
,
487 "The internal label on the inserted %s is\n", volume
);
489 (void) fprintf(stderr
, "The internal label for %s is", pname
);
490 (void) fprintf(stderr
, "\t%s,%s\n", fsname
, volname
);