dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / lib / libadm / common / getvol.c
blobdf826fcaccb54083ada9b432ebffbd3407b0fff0
1 /*
2 * CDDL HEADER START
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
7 * with the License.
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]
20 * CDDL HEADER END
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.
31 /*LINTLIBRARY*/
33 #include <stdio.h>
34 #include <string.h>
35 #include <sys/types.h>
36 #include <devmgmt.h>
37 #include "libadm.h"
38 #include <stdlib.h>
40 #define LABELSIZ 6
41 #define BELL "\007"
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];
70 * Return:
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
82 #ifdef RT
83 #define IFTAPE(s) ((strncmp(s, "/dev/mt", 7) == 0) || \
84 (strncmp(s, "mt", 2) == 0))
85 #define TAPENAMES "'/dev/mt'"
86 #else
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'"
91 #endif
93 int
94 getvol(char *device, char *label, int options, char *prompt)
96 return (_getvol(device, label, options, prompt, NULL));
99 int
100 _getvol(char *device, char *label, int options, char *prompt, char *norewind)
102 FILE *tmp;
103 char *advice, *pt;
104 int n, override;
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");
114 if (pname == NULL) {
115 pname = devattr(device, "alias");
116 if (!pname)
117 pname = device;
120 volume = devattr(device, "volume");
122 if (label) {
123 (void) strncpy(origfsname, label, LABELSIZ);
124 origfsname[LABELSIZ] = '\0';
125 if (pt = strchr(origfsname, ',')) {
126 *pt = '\0';
128 if (pt = strchr(label, ',')) {
129 (void) strncpy(origvolname, pt+1, LABELSIZ);
130 origvolname[LABELSIZ] = '\0';
131 } else
132 origvolname[0] = '\0';
135 override = 0;
136 for (;;) {
137 if (!(options & DM_BATCH) && volume) {
138 n = insert(device, label, options, prompt);
139 if (n < 0)
140 override++;
141 else if (n)
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)
148 return (1);
149 (void) fprintf(stderr, ERR_ACCESS, pname, cdevice);
150 if ((options & DM_BATCH) || (volume == NULL))
151 return (1);
152 /* display advice on how to ready device */
153 if (advice = devattr(device, "advice"))
154 (void) puttext(stderr, advice, 0, 0);
155 continue;
157 (void) fclose(tmp);
159 /* check label on device */
160 if (label) {
161 if (options & DM_ELABEL)
162 elabel();
163 else {
164 /* check internal label using /etc/labelit */
165 if (ckilabel(label, override)) {
166 if ((options & DM_BATCH) ||
167 volume == NULL)
168 return (4);
169 continue;
173 break;
175 return (0);
178 static int
179 ckilabel(char *label, int flag)
181 FILE *pp;
182 char *pt, *look, buffer[512];
183 char fsname[LABELSIZ+1], volname[LABELSIZ+1];
184 char *pvolname, *pfsname;
185 int n, c;
187 (void) strncpy(fsname, label, LABELSIZ);
188 fsname[LABELSIZ] = '\0';
189 if (pt = strchr(fsname, ',')) {
190 *pt = '\0';
192 if (pt = strchr(label, ',')) {
193 (void) strncpy(volname, pt+1, LABELSIZ);
194 volname[LABELSIZ] = '\0';
195 } else
196 volname[0] = '\0';
198 (void) snprintf(buffer, sizeof (buffer), "/etc/labelit %s", cdevice);
199 pp = popen(buffer, "r");
200 pt = buffer;
201 while ((c = getc(pp)) != EOF)
202 *pt++ = (char)c;
203 *pt = '\0';
204 (void) pclose(pp);
206 pt = buffer;
207 pfsname = pvolname = NULL;
208 look = "Current fsname: ";
209 n = (int)strlen(look);
210 while (*pt) {
211 if (strncmp(pt, look, n) == 0) {
212 *pt = '\0';
213 pt += strlen(look);
214 if (pfsname == NULL) {
215 pfsname = pt;
216 look = ", Current volname: ";
217 n = (int)strlen(look);
218 } else if (pvolname == NULL) {
219 pvolname = pt;
220 look = ", Blocks: ";
221 n = (int)strlen(look);
222 } else
223 break;
224 } else
225 pt++;
228 if (strcmp(fsname, pfsname) || strcmp(volname, pvolname)) {
229 /* mismatched label */
230 if (flag) {
231 /* LINTED E_SEC_SPRINTF_UNBOUNDED_COPY */
232 (void) sprintf(label, "%s,%s", pfsname, pvolname);
233 } else {
234 labelerr(pfsname, pvolname);
235 return (1);
238 return (0);
241 static int
242 wilabel(char *label)
244 char buffer[512];
245 char fsname[LABELSIZ+1];
246 char volname[LABELSIZ+1];
247 int n;
249 if (!label || !strlen(origfsname)) {
250 if (n = ckstr(fsname, NULL, LABELSIZ, NULL, NULL, NULL,
251 "Enter text for fsname label:"))
252 return (n);
253 } else
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:"))
258 return (n);
259 } else
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);
266 } else {
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);
273 return (1);
275 if (label)
276 /* LINTED E_SEC_SPRINTF_UNBOUNDED_COPY */
277 (void) sprintf(label, "%s,%s", fsname, volname);
278 return (0);
281 static void
282 elabel(void)
286 static int
287 insert(char *device, char *label, int options, char *prompt)
289 int n;
290 char strval[16], prmpt[BUFSIZ];
291 char *pt, *keyword[10];
292 char *fmtcmd;
293 char *mkfscmd;
294 char *voltxt;
295 char *removecmd;
296 char *dev_type;
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");
305 if (prompt) {
306 (void) strlcpy(prmpt, prompt, sizeof (prmpt));
307 for (pt = prmpt; *prompt; ) {
308 if ((*prompt == '\\') && (prompt[1] == '%'))
309 prompt++;
310 else if (*prompt == '%') {
311 switch (prompt[1]) {
312 case 'v':
313 (void) strcpy(pt, voltxt);
314 break;
316 case 'p':
317 (void) strcpy(pt, pname);
318 break;
320 default:
321 *pt = '\0';
322 break;
324 pt = pt + strlen(pt);
325 prompt += 2;
326 continue;
328 *pt++ = *prompt++;
330 *pt = '\0';
331 } else {
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",
339 voltxt, label);
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:",
345 voltxt);
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);
354 n = 0;
355 pt += sprintf(pt, "\\nType [go] when ready");
356 keyword[n++] = "go";
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);
362 keyword[n++] = "f";
363 } else if (fmtcmd && *fmtcmd) {
364 /* LINTED E_SEC_SPRINTF_UNBOUNDED_COPY */
365 pt += sprintf(pt, FORMAT_MSG, voltxt);
366 keyword[n++] = "f";
368 if (mkfscmd && *mkfscmd) {
369 /* LINTED E_SEC_SPRINTF_UNBOUNDED_COPY */
370 pt += sprintf(pt, MAKEFS_MSG, voltxt);
371 keyword[n++] = "m";
373 } else if (options & DM_FORMAT) {
374 if (fmtcmd && *fmtcmd) {
375 /* LINTED E_SEC_SPRINTF_UNBOUNDED_COPY */
376 pt += sprintf(pt, FORMAT_MSG, voltxt);
377 keyword[n++] = "f";
380 if (options & DM_WLABEL) {
381 /* LINTED E_SEC_SPRINTF_UNBOUNDED_COPY */
382 pt += sprintf(pt, WLABEL_MSG, voltxt);
383 keyword[n++] = "w";
385 if (options & DM_OLABEL) {
386 pt += sprintf(pt, OLABEL_MSG);
387 keyword[n++] = "o";
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);
393 keyword[n++] = "e";
394 } else {
395 /* LINTED E_SEC_SPRINTF_UNBOUNDED_COPY */
396 pt += sprintf(pt, UNLOAD_MSG, voltxt);
397 keyword[n++] = "u";
400 keyword[n] = NULL;
401 if (ckquit)
402 pt += sprintf(pt, QUIT_MSG);
403 *pt++ = ':';
404 *pt = '\0';
406 pt = prmpt;
407 (void) fprintf(stderr, BELL);
408 for (;;) {
409 if (n = ckkeywd(strval, keyword, NULL, NULL, NULL, pt))
410 return (n);
412 pt = prompt; /* next prompt is only partial */
413 if (*strval == 'f') {
414 if (options & DM_FORMFS)
415 doformat(voltxt, fmtcmd, mkfscmd);
416 else
417 doformat(voltxt, fmtcmd, NULL);
418 continue;
419 } else if (*strval == 'm') {
420 doformat(voltxt, NULL, mkfscmd);
421 continue;
422 } else if (*strval == 'e' || *strval == 'u') {
423 (void) doremovecmd(device, 1);
424 continue;
425 } else if (*strval == 'w') {
426 (void) wilabel(label);
427 continue;
428 } else if (*strval == 'o')
429 return (-1);
430 break;
432 return (0);
435 static void
436 doformat(char *voltxt, char *fmtcmd, char *mkfscmd)
438 char buffer[512];
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);
445 return;
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);
453 return;
458 void
459 doremovecmd(char *device, int echo)
461 char *removecmd;
462 char buffer[512];
464 if (device && *device) {
465 removecmd = devattr(device, "removecmd");
466 if (removecmd && *removecmd) {
467 if (echo)
468 (void) fprintf(stderr, "\t[%s]\n", removecmd);
469 (void) snprintf(buffer, sizeof (buffer),
470 "(%s) 1>&2", removecmd);
471 if (system(buffer)) {
472 if (echo)
473 (void) fprintf(stderr, ERR_REMOVE,
474 removecmd);
475 return;
481 static void
482 labelerr(char *fsname, char *volname)
484 (void) fprintf(stderr, "\nLabel incorrect.\n");
485 if (volume)
486 (void) fprintf(stderr,
487 "The internal label on the inserted %s is\n", volume);
488 else
489 (void) fprintf(stderr, "The internal label for %s is", pname);
490 (void) fprintf(stderr, "\t%s,%s\n", fsname, volname);