Print this page
4833 Remove volrmmount
Reviewed by: Dan McDonald <danmcd@omniti.com>
Reviewed by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/rmformat/rmf_misc.c
+++ new/usr/src/cmd/rmformat/rmf_misc.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
↓ open down ↓ |
9 lines elided |
↑ open up ↑ |
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 - */
21 -
22 -/*
20 + *
21 + *
23 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 23 * Use is subject to license terms.
24 + *
25 + * Copyright 2014 Andrew Stormont.
25 26 */
26 27
27 28 /*
28 29 * rmf_misc.c :
29 30 * Miscelleneous routines for rmformat.
30 31 */
31 32
32 33 #include <sys/types.h>
33 34 #include <stdio.h>
34 35 #include <sys/mnttab.h>
35 36 #include <volmgt.h>
36 37 #include <sys/dkio.h>
37 38 #include <sys/fdio.h>
38 39 #include <sys/vtoc.h>
39 40 #include <sys/termios.h>
40 41 #include <sys/mount.h>
41 42 #include <ctype.h>
42 43 #include <signal.h>
43 44 #include <sys/wait.h>
44 45 #include <dirent.h>
45 46 #include <priv_utils.h>
46 47 #include <stdarg.h>
47 48 #include "rmformat.h"
48 49
49 50 /*
50 51 * Definitions.
51 52 */
52 53 #define SENSE_KEY(rqbuf) (rqbuf[2] & 0xf) /* scsi error category */
53 54 #define ASC(rqbuf) (rqbuf[12]) /* additional sense code */
54 55 #define ASCQ(rqbuf) (rqbuf[13]) /* ASC qualifier */
55 56
56 57 #define DEFAULT_SCSI_TIMEOUT 60
57 58 #define INQUIRY_CMD 0x12
58 59 #define RQBUFLEN 32
59 60 #define CD_RW 1 /* CD_RW/CD-R */
60 61 #define WRITE_10_CMD 0x2A
61 62 #define READ_INFO_CMD 0x51
62 63 #define SYNC_CACHE_CMD 0x35
63 64 #define CLOSE_TRACK_CMD 0x5B
64 65 #define MODE_SENSE_10_CMD 0x5A
65 66 #define DEVFS_PREFIX "/devices"
66 67
67 68 int uscsi_error; /* used for debugging failed uscsi */
68 69 char rqbuf[RQBUFLEN];
69 70 static uint_t total_retries;
70 71 static struct uscsi_cmd uscmd;
71 72 static char ucdb[16];
72 73 uchar_t uscsi_status, rqstatus, rqresid;
73 74 int total_devices_found = 0;
74 75 int removable_found = 0;
75 76
76 77 extern char *global_intr_msg;
77 78 extern int vol_running;
78 79 extern char *dev_name;
79 80 extern int32_t m_flag;
↓ open down ↓ |
45 lines elided |
↑ open up ↑ |
80 81
81 82 /*
82 83 * ON-private functions from libvolmgt
83 84 */
84 85 int _dev_mounted(char *path);
85 86
86 87 /*
87 88 * Function prototypes.
88 89 */
89 90 static int my_umount(char *mountp);
90 -static int my_volrmmount(char *real_name);
91 91 static int vol_name_to_dev_node(char *vname, char *found);
92 92 static int vol_lookup(char *supplied, char *found);
93 93 static device_t *get_device(char *user_supplied, char *node);
94 94 static char *get_physical_name(char *path);
95 95 static int lookup_device(char *supplied, char *found);
96 96 static void fini_device(device_t *dev);
97 97 static int is_cd(char *node);
98 98 void *my_zalloc(size_t size);
99 99 void err_msg(char *fmt, ...);
100 100 int inquiry(int fd, uchar_t *inq);
101 101 struct uscsi_cmd *get_uscsi_cmd(void);
102 102 int uscsi(int fd, struct uscsi_cmd *scmd);
103 103 int get_mode_page(int fd, int page_no, int pc, int buf_len,
104 104 uchar_t *buffer);
105 105 int mode_sense(int fd, uchar_t pc, int dbd, int page_len,
106 106 uchar_t *buffer);
107 107 uint16_t read_scsi16(void *addr);
108 108 int check_device(device_t *dev, int cond);
109 109 static void get_media_info(device_t *t_dev, char *sdev,
110 110 char *pname, char *sn);
111 111
112 112 extern void process_p_flag(smedia_handle_t handle, int32_t fd);
113 113
114 114 void
115 115 my_perror(char *err_string)
116 116 {
117 117
118 118 int error_no;
119 119 if (errno == 0)
120 120 return;
121 121
122 122 error_no = errno;
123 123 (void) fprintf(stderr, "%s", err_string);
124 124 (void) fprintf(stderr, gettext(" : "));
125 125 errno = error_no;
126 126 perror("");
127 127 }
128 128
129 129 int32_t
130 130 get_confirmation()
131 131 {
132 132 char c;
133 133
134 134 (void) fprintf(stderr, gettext("Do you want to continue? (y/n)"));
135 135 c = getchar();
136 136 if (c == 'y' || c == 'Y')
137 137 return (1);
138 138 else if (c == 'n' || c == 'N')
139 139 return (0);
140 140 else {
141 141 (void) fprintf(stderr, gettext("Invalid choice\n"));
142 142 return (0);
143 143 }
144 144 }
145 145
146 146
147 147 void
148 148 get_passwd(struct smwp_state *wp, int32_t confirm)
149 149 {
150 150 char passwd[256], re_passwd[256];
151 151 int32_t len;
152 152 struct termios tio;
153 153 int32_t echo_off = 0;
154 154 FILE *in, *out;
155 155 char *buf;
156 156
157 157
158 158 in = fopen("/dev/tty", "r+");
159 159 if (in == NULL) {
160 160 in = stdin;
161 161 out = stderr;
162 162 } else {
163 163 out = in;
164 164 }
165 165
166 166 /* Turn echoing off if it is on now. */
167 167
168 168 if (tcgetattr(fileno(in), &tio) < 0) {
169 169 PERROR("Echo off ioctl failed");
170 170 exit(1);
171 171 }
172 172 if (tio.c_lflag & ECHO) {
173 173 tio.c_lflag &= ~ECHO;
174 174 /* echo_off = tcsetattr(fileno(in), TCSAFLUSH, &tio) == 0; */
175 175 echo_off = tcsetattr(fileno(in), TCSAFLUSH, &tio) == 0;
176 176 tio.c_lflag |= ECHO;
177 177 }
178 178
179 179 /* CONSTCOND */
180 180 while (1) {
181 181 (void) fputs(
182 182 gettext("Please enter password (32 chars maximum):"),
183 183 out);
184 184 (void) fflush(out);
185 185 buf = fgets(passwd, (size_t)256, in);
186 186 rewind(in);
187 187 if (buf == NULL) {
188 188 PERROR("Error reading password");
189 189 continue;
190 190 }
191 191 len = strlen(passwd);
192 192 (void) fputc('\n', out);
193 193 len--; /* To offset the \n */
194 194 if ((len <= 0) || (len > 32)) {
195 195 (void) fprintf(stderr,
196 196 gettext("Invalid length of password \n"));
197 197 (void) fputs("Try again\n", out);
198 198 continue;
199 199 }
200 200
201 201 if (!confirm)
202 202 break;
203 203
204 204 (void) fputs("Please reenter password:", out);
205 205 (void) fflush(out);
206 206 buf = fgets(re_passwd, (size_t)256, in);
207 207 rewind(in);
208 208 (void) fputc('\n', out);
209 209 if ((buf == NULL) || strcmp(passwd, re_passwd)) {
210 210 (void) fputs("passwords did not match\n", out);
211 211 (void) fputs("Try again\n", out);
212 212 } else {
213 213 break;
214 214 }
215 215 }
↓ open down ↓ |
115 lines elided |
↑ open up ↑ |
216 216 wp->sm_passwd_len = len;
217 217 (void) strncpy(wp->sm_passwd, passwd, wp->sm_passwd_len);
218 218 wp->sm_version = SMWP_STATE_V_1;
219 219
220 220 /* Restore echoing. */
221 221 if (echo_off)
222 222 (void) tcsetattr(fileno(in), TCSAFLUSH, &tio);
223 223
224 224 }
225 225
226 -int32_t
227 -check_and_unmount_vold(char *device_name, int32_t flag)
228 -{
229 - char *real_name;
230 - char *nm;
231 - char tmp_path_name[PATH_MAX];
232 - struct stat stat_buf;
233 - int32_t ret_val = 0;
234 - struct mnttab *mntp;
235 - FILE *fp;
236 - int nl;
237 -
238 - DPRINTF1("Device name %s\n", device_name);
239 -
240 - if (volmgt_running() == 0) {
241 - DPRINTF("Vold not running\n");
242 - return (0);
243 - }
244 - if ((nm = volmgt_symname(device_name)) == NULL) {
245 - DPRINTF("path not managed\n");
246 - real_name = media_findname(device_name);
247 - } else {
248 - DPRINTF1("path managed as %s\n", nm);
249 - real_name = media_findname(nm);
250 - DPRINTF1("real name %s\n", real_name);
251 - }
252 -
253 - if (real_name == NULL)
254 - return (-1);
255 -
256 - /*
257 - * To find out whether the device has been mounted by
258 - * volume manager...
259 - *
260 - * Convert the real name to a block device address.
261 - * Do a partial match with the mnttab entries.
262 - * Make sure the match is in the beginning to avoid if
263 - * anybody puts a label similiar to volume manager path names.
264 - * Then use "volrmmount -e <dev_name>" if -U flag is set.
265 - */
266 -
267 - nl = strlen("/vol/dev/");
268 -
269 - if (strncmp(real_name, "/vol/dev/", nl) != 0)
270 - return (0);
271 - if (real_name[nl] == 'r') {
272 - (void) snprintf(tmp_path_name, PATH_MAX, "%s%s", "/vol/dev/",
273 - &real_name[nl + 1]);
274 - } else {
275 - (void) snprintf(tmp_path_name, PATH_MAX, "%s", real_name);
276 - }
277 - DPRINTF1("%s \n", tmp_path_name);
278 - ret_val = stat(tmp_path_name, &stat_buf);
279 - if (ret_val < 0) {
280 - PERROR("Could not stat");
281 - return (-1);
282 - }
283 -
284 - fp = fopen("/etc/mnttab", "r");
285 -
286 - if (fp == NULL) {
287 - PERROR("Could not open /etc/mnttab");
288 - return (-1);
289 - }
290 -
291 - mntp = (struct mnttab *)malloc(sizeof (struct mnttab));
292 - if (mntp == NULL) {
293 - PERROR("malloc failed");
294 - (void) fclose(fp);
295 - return (-1);
296 - }
297 - errno = 0;
298 - while (getmntent(fp, mntp) == 0) {
299 - if (errno != 0) {
300 - PERROR("Error with mnttab");
301 - (void) fclose(fp);
302 - return (-1);
303 - }
304 - /* Is it a probable entry? */
305 - DPRINTF1(" %s \n", mntp->mnt_special);
306 - if (strstr(mntp->mnt_special, tmp_path_name) !=
307 - mntp->mnt_special) {
308 - /* Skip to next entry */
309 - continue;
310 - } else {
311 - DPRINTF1("Found!! %s\n", mntp->mnt_special);
312 - ret_val = 1;
313 - break;
314 - }
315 - }
316 -
317 - if (ret_val == 1) {
318 - if (flag) {
319 - if (my_volrmmount(real_name) < 0) {
320 - ret_val = -1;
321 - }
322 - } else {
323 - ret_val = -1;
324 - }
325 - }
326 - (void) fclose(fp);
327 - free(mntp);
328 - return (ret_val);
329 -}
330 -
331 226 /*
332 227 * This routine checks if a device has mounted partitions. The
333 228 * device name is assumed to be /dev/rdsk/cNtNdNsN. So, this can
334 229 * be used for SCSI and PCMCIA cards.
335 230 * Returns
336 231 * 0 : if not mounted
337 232 * 1 : if successfully unmounted
338 233 * -1 : Any error or umount failed
339 234 */
340 235
341 236 int32_t
342 237 check_and_unmount_scsi(char *device_name, int32_t flag)
343 238 {
344 239
345 240 struct mnttab *mntrefp;
346 241 struct mnttab *mntp;
347 242 FILE *fp;
348 243 char block_dev_name[PATH_MAX];
349 244 char tmp_name[PATH_MAX];
350 245 int32_t i, j;
351 246 int32_t unmounted = 0;
352 247
353 248 /*
354 249 * If the device name is not a character special, anyway we
355 250 * can not progress further
356 251 */
357 252
358 253 if (strncmp(device_name, "/dev/rdsk/c", strlen("/dev/rdsk/c")) != 0)
359 254 return (0);
360 255
361 256 (void) snprintf(block_dev_name, PATH_MAX, "/dev/%s",
362 257 &device_name[strlen("/dev/r")]);
363 258 fp = fopen("/etc/mnttab", "r");
364 259
365 260 if (fp == NULL) {
366 261 PERROR("Could not open /etc/mnttab");
367 262 return (-1);
368 263 }
369 264
370 265 mntrefp = (struct mnttab *)malloc(sizeof (struct mnttab));
371 266 if (mntrefp == NULL) {
372 267 PERROR("malloc failed");
373 268 (void) fclose(fp);
374 269 return (-1);
375 270 }
376 271
377 272 mntp = (struct mnttab *)malloc(sizeof (struct mnttab));
378 273 if (mntp == NULL) {
379 274 PERROR("malloc failed");
380 275 (void) fclose(fp);
381 276 free(mntrefp);
382 277 return (-1);
383 278 }
384 279
385 280 /* Try all the partitions */
386 281
387 282 (void) snprintf(tmp_name, PATH_MAX, "/dev/%s",
388 283 &device_name[strlen("/dev/r")]);
389 284
390 285 tmp_name[strlen("/dev/dsk/c0t0d0s")] = '\0';
391 286
392 287 errno = 0;
393 288 while (getmntent(fp, mntp) == 0) {
394 289 if (errno != 0) {
395 290 PERROR("Error with mnttab");
396 291 (void) fclose(fp);
397 292 return (-1);
398 293 }
399 294 /* Is it a probable entry? */
400 295 if (strncmp(mntp->mnt_special, tmp_name, strlen(tmp_name))) {
401 296 /* Skip to next entry */
402 297 continue;
403 298 }
404 299 for (i = 0; i < NDKMAP; i++) {
405 300 /* Check for ufs style mount devices */
406 301 (void) snprintf(block_dev_name, PATH_MAX,
407 302 "%s%d", tmp_name, i);
408 303
409 304 if (strcmp(mntp->mnt_special, block_dev_name) == 0) {
410 305 if (flag) {
411 306 if (my_umount(mntp->mnt_mountp) < 0) {
412 307 (void) fclose(fp);
413 308 return (-1);
414 309 }
415 310 unmounted = 1;
416 311 } else {
417 312 (void) fclose(fp);
418 313 return (-1);
419 314 }
420 315 /* Skip to next entry */
421 316 continue;
422 317 }
423 318
424 319 /* Try for :1 -> :24 for pcfs */
425 320
426 321 for (j = 1; j < 24; j++) {
427 322 (void) snprintf(block_dev_name, PATH_MAX,
428 323 "%s%d:%d", tmp_name, i, j);
429 324
430 325 if (strcmp(mntp->mnt_special,
431 326 block_dev_name) == 0) {
432 327 if (flag) {
433 328 if (my_umount(mntp->mnt_mountp)
434 329 < 0) {
435 330 (void) fclose(fp);
436 331 return (-1);
437 332 }
438 333 unmounted = 1;
439 334 } else {
440 335 (void) fclose(fp);
441 336 return (-1);
442 337 }
443 338 /* Skip to next entry */
444 339 continue;
445 340 }
446 341 (void) snprintf(block_dev_name, PATH_MAX,
447 342 "%s%d:%c", tmp_name, i, 'b' + j);
448 343
449 344 if (strcmp(mntp->mnt_special,
450 345 block_dev_name) == 0) {
451 346 if (flag) {
452 347 if (my_umount(mntp->mnt_mountp)
453 348 < 0) {
454 349 (void) fclose(fp);
455 350 return (-1);
456 351 }
457 352 unmounted = 1;
458 353 } else {
459 354 (void) fclose(fp);
460 355 return (-1);
461 356 }
462 357 /* Skip to next entry */
463 358 continue;
464 359 }
465 360 }
466 361 }
467 362
468 363 }
469 364
470 365 if (unmounted)
471 366 return (1);
472 367 return (0);
473 368 }
474 369
475 370 /*
476 371 * This routine checks if a device has mounted partitions. The
477 372 * device name is assumed to be /dev/rdiskette. So, this can
478 373 * be used for Floppy controllers
479 374 * Returns
480 375 * 0 : if not mounted
481 376 * 1 : if successfully unmounted
482 377 * -1 : Any error or unmount failed
483 378 */
484 379
485 380 int32_t
486 381 check_and_unmount_floppy(int32_t fd, int32_t flag)
487 382 {
488 383 FILE *fp = NULL;
489 384 int32_t mfd;
490 385 struct dk_cinfo dkinfo, dkinfo_tmp;
491 386 struct mnttab mnt_record;
492 387 struct mnttab *mp = &mnt_record;
493 388 struct stat stbuf;
494 389 char raw_device[PATH_MAX];
495 390 int32_t found = 0;
496 391
497 392
498 393 if (ioctl(fd, DKIOCINFO, &dkinfo) < 0) {
499 394 return (-1);
500 395 }
501 396
502 397 if ((fp = fopen(MNTTAB, "r")) == NULL) {
503 398 PERROR("Could not open /etc/mnttab");
504 399 (void) close(fd);
505 400 exit(3);
506 401 }
507 402
508 403 while (getmntent(fp, mp) == 0) {
509 404 if (strstr(mp->mnt_special, "/dev/fd") == NULL &&
510 405 strstr(mp->mnt_special, "/dev/disket") == NULL &&
511 406 strstr(mp->mnt_special, "/dev/c") == NULL) {
512 407 continue;
513 408 }
514 409
515 410 (void) strcpy(raw_device, "/dev/r");
516 411 (void) strcat(raw_device, mp->mnt_special + strlen("/dev/"));
517 412
518 413
519 414 /*
520 415 * Attempt to open the device. If it fails, skip it.
521 416 */
522 417
523 418 /* Turn on the privileges. */
524 419 (void) __priv_bracket(PRIV_ON);
525 420
526 421 mfd = open(raw_device, O_RDWR | O_NDELAY);
527 422
528 423 /* Turn off the privileges. */
529 424 (void) __priv_bracket(PRIV_OFF);
530 425
531 426 if (mfd < 0) {
532 427 continue;
533 428 }
534 429
535 430 /*
536 431 * Must be a character device
537 432 */
538 433 if (fstat(mfd, &stbuf) < 0 || !S_ISCHR(stbuf.st_mode)) {
539 434 (void) close(mfd);
540 435 continue;
541 436 }
542 437 /*
543 438 * Attempt to read the configuration info on the disk.
544 439 */
545 440 if (ioctl(mfd, DKIOCINFO, &dkinfo_tmp) < 0) {
546 441 (void) close(mfd);
547 442 continue;
548 443 }
549 444 /*
550 445 * Finished with the opened device
551 446 */
552 447 (void) close(mfd);
553 448
554 449 /*
555 450 * If it's not the disk we're interested in, it doesn't apply.
556 451 */
557 452 if (dkinfo.dki_ctype != dkinfo_tmp.dki_ctype ||
558 453 dkinfo.dki_cnum != dkinfo_tmp.dki_cnum ||
559 454 dkinfo.dki_unit != dkinfo_tmp.dki_unit) {
560 455 continue;
561 456 }
562 457 /*
563 458 * It's a mount on the disk we're checking. If we are
564 459 * checking whole disk, then we found trouble. We can
565 460 * quit searching.
566 461 */
567 462
568 463 if (flag) {
569 464 if (my_umount(mp->mnt_mountp) < 0) {
570 465 return (-1);
571 466 }
572 467 found = 1;
573 468 } else {
574 469 return (-1);
575 470 }
576 471 }
577 472 return (found);
578 473 }
579 474
580 475
581 476 int32_t
582 477 my_open(char *device_name, int32_t flags)
583 478 {
584 479 char *real_name;
585 480 char *nm;
586 481 char tmp_path_name[PATH_MAX];
587 482 struct stat stat_buf;
588 483 int32_t ret_val;
589 484 int32_t fd;
590 485 int32_t have_read_priv = 0;
591 486 DIR *dirp;
592 487 struct dirent *dp;
593 488
594 489 DPRINTF1("Device name %s\n", device_name);
595 490
596 491 if ((nm = volmgt_symname(device_name)) == NULL) {
597 492 DPRINTF("path not managed\n");
598 493 real_name = media_findname(device_name);
599 494 } else {
600 495 DPRINTF1("path managed as %s\n", nm);
601 496 real_name = media_findname(nm);
602 497 DPRINTF1("real name %s\n", real_name);
603 498 }
604 499
605 500 if (real_name == NULL)
606 501 return (-1);
607 502
608 503 (void) strcpy(tmp_path_name, real_name);
609 504 ret_val = stat(tmp_path_name, &stat_buf);
610 505 if (ret_val < 0) {
611 506 PERROR("Could not stat");
612 507 return (-1);
613 508 }
614 509 if (S_ISDIR(stat_buf.st_mode)) {
615 510
616 511 /*
617 512 * Open the directory and look for the
618 513 * first non '.' entry.
619 514 * Since raw_read and raw_writes are used, we don't
620 515 * need to access the backup slice.
621 516 * For PCMCIA Memory cards, raw_read and raw_writes are
622 517 * not supported, but that is not a problem as, only slice2
623 518 * is allowed on PCMCIA memory cards.
624 519 */
625 520
626 521 /*
627 522 * First make sure we are operating with a /vol/....
628 523 * Otherwise it can dangerous,
629 524 * e.g. rmformat -s /dev/rdsk
630 525 * We should not look into the directory contents here.
631 526 */
632 527 if (strncmp(tmp_path_name, "/vol/dev/", strlen("/vol/dev/"))
633 528 != 0) {
634 529 (void) fprintf(stderr, gettext("The specified device \
635 530 is not a raw device.\n"));
636 531 exit(1);
637 532 }
638 533
639 534 /* Turn on the privileges. */
640 535 (void) __priv_bracket(PRIV_ON);
641 536
642 537 dirp = opendir(tmp_path_name);
643 538
644 539 /* Turn off the privileges. */
645 540 (void) __priv_bracket(PRIV_OFF);
646 541
647 542 if (dirp == NULL) {
648 543 return (-1);
649 544 }
650 545
651 546 /* Turn on the privileges. */
652 547 (void) __priv_bracket(PRIV_ON);
653 548 have_read_priv = 1;
654 549
655 550 while ((dp = readdir(dirp)) != NULL) {
656 551
657 552 /* Turn off the privileges. */
658 553 (void) __priv_bracket(PRIV_OFF);
659 554 have_read_priv = 0;
660 555
661 556 DPRINTF1("Found %s\n", dp->d_name);
662 557 if ((strcmp(dp->d_name, ".") != 0) &&
663 558 (strcmp(dp->d_name, "..") != 0)) {
664 559 (void) snprintf(tmp_path_name, PATH_MAX,
665 560 "%s/%s", tmp_path_name, dp->d_name);
666 561
667 562 DPRINTF1("tmp_pathname is %s\n", tmp_path_name);
668 563 break;
669 564 }
670 565
671 566 /* Turn on the privileges. */
672 567 (void) __priv_bracket(PRIV_ON);
673 568 have_read_priv = 1;
674 569 }
675 570
676 571 if (have_read_priv) {
677 572 /* drop the file_dac_read privilege */
678 573 (void) __priv_bracket(PRIV_OFF);
679 574 have_read_priv = 0;
680 575 }
681 576
682 577 (void) closedir(dirp);
683 578 }
684 579
685 580
686 581 if (volmgt_running() == 0) {
687 582 /* Turn on privileges. */
688 583 (void) __priv_bracket(PRIV_ON);
689 584 have_read_priv = 1;
690 585 }
691 586
692 587 fd = open(tmp_path_name, flags);
693 588
694 589 if (have_read_priv) {
695 590 /* Turn off privileges. */
696 591 (void) __priv_bracket(PRIV_OFF);
697 592 have_read_priv = 0;
698 593 }
699 594
700 595 DPRINTF1("path opened %s\n", tmp_path_name);
701 596
702 597 return (fd);
703 598 }
704 599
705 600 uint64_t
706 601 my_atoll(char *ptr)
707 602 {
708 603 char *tmp_ptr = ptr;
709 604 int32_t base = 10;
710 605 uint64_t ret_val;
711 606
712 607 while (*tmp_ptr) {
713 608 if (isdigit(*tmp_ptr))
714 609 tmp_ptr++;
715 610 else {
716 611 base = 16;
717 612 break;
718 613 }
719 614 }
720 615 tmp_ptr = ptr;
721 616 if (base == 16) {
722 617 if (strlen(tmp_ptr) < 3) {
723 618 return (-1);
724 619 }
725 620 if (*tmp_ptr++ != '0' || (*tmp_ptr != 'x' && *tmp_ptr != 'X')) {
726 621 return (-1);
727 622 }
728 623 tmp_ptr++;
729 624 while (*tmp_ptr) {
730 625 if (isxdigit(*tmp_ptr))
731 626 tmp_ptr++;
732 627 else {
733 628 return (-1);
734 629 }
735 630 }
736 631 }
737 632 ret_val = (uint64_t)strtoull(ptr, (char **)NULL, 0);
738 633 return (ret_val);
739 634 }
740 635
741 636 int32_t
742 637 write_sunos_label(int32_t fd, int32_t media_type)
743 638 {
744 639
745 640 struct extvtoc v_toc;
746 641 int32_t ret;
747 642
748 643 (void) memset(&v_toc, 0, sizeof (struct extvtoc));
749 644
750 645 /* Initialize the vtoc information */
751 646
752 647 if (media_type == SM_FLOPPY) {
753 648 struct fd_char fdchar;
754 649 int32_t mult_factor;
755 650
756 651 if (ioctl(fd, FDIOGCHAR, &fdchar) < 0) {
757 652 PERROR("FDIOGCHAR failed");
758 653 return (-1);
759 654 }
760 655
761 656 /* SPARC and x86 fd drivers use fdc_medium differently */
762 657 #if defined(__sparc)
763 658 mult_factor = (fdchar.fdc_medium) ? 2 : 1;
764 659 #elif defined(__x86)
765 660 mult_factor = (fdchar.fdc_medium == 5) ? 2 : 1;
766 661 #else
767 662 #error No Platform defined
768 663 #endif /* defined(__sparc) */
769 664
770 665 /* initialize the vtoc structure */
771 666 v_toc.v_nparts = 3;
772 667
773 668 v_toc.v_part[0].p_start = 0;
774 669 v_toc.v_part[0].p_size = (fdchar.fdc_ncyl - 1) * 2 *
775 670 fdchar.fdc_secptrack * mult_factor;
776 671 v_toc.v_part[1].p_start = (fdchar.fdc_ncyl - 1) * 2 *
777 672 fdchar.fdc_secptrack * mult_factor;
778 673 v_toc.v_part[1].p_size = 2 * fdchar.fdc_secptrack * mult_factor;
779 674
780 675 v_toc.v_part[2].p_start = 0;
781 676 v_toc.v_part[2].p_size = fdchar.fdc_ncyl * 2 *
782 677 fdchar.fdc_secptrack * mult_factor;
783 678
784 679 } else if (media_type == SM_SCSI_FLOPPY) {
785 680
786 681 smedia_handle_t handle;
787 682 smmedium_prop_t med_info;
788 683 struct dk_geom dkgeom;
789 684
790 685
791 686 /*
792 687 * call smedia_get_medium_property to get the
793 688 * correct media information, since DKIOCGMEDIAINFO
794 689 * may fail for unformatted media.
795 690 */
796 691
797 692 handle = smedia_get_handle(fd);
798 693 if (handle == NULL) {
799 694 (void) fprintf(stderr,
800 695 gettext("Failed to get libsmedia handle.\n"));
801 696
802 697 (void) close(fd);
803 698 return (-1);
804 699 }
805 700
806 701
807 702 if (smedia_get_medium_property(handle, &med_info) < 0) {
808 703 (void) fprintf(stderr,
809 704 gettext("Get medium property failed \n"));
810 705
811 706 (void) smedia_release_handle(handle);
812 707 (void) close(fd);
813 708 return (-1);
814 709 }
815 710
816 711 /* Fill in our own geometry information */
817 712
818 713 dkgeom.dkg_pcyl = med_info.sm_pcyl;
819 714 dkgeom.dkg_ncyl = med_info.sm_pcyl;
820 715 dkgeom.dkg_nhead = med_info.sm_nhead;
821 716 dkgeom.dkg_nsect = med_info.sm_nsect;
822 717 dkgeom.dkg_acyl = 0;
823 718 dkgeom.dkg_bcyl = 0;
824 719 dkgeom.dkg_intrlv = 0;
825 720 dkgeom.dkg_apc = 0;
826 721
827 722 /*
828 723 * Try to set vtoc, if not successful we will
829 724 * continue to use the faked geometry information.
830 725 */
831 726
832 727 (void) ioctl(fd, DKIOCSGEOM, &dkgeom);
833 728
834 729 (void) smedia_release_handle(handle);
835 730
836 731 /* we want the same partitioning as used for normal floppies */
837 732
838 733 v_toc.v_part[0].p_start = 0;
839 734 v_toc.v_part[0].p_size = (diskaddr_t)(dkgeom.dkg_ncyl - 1) *
840 735 dkgeom.dkg_nhead * dkgeom.dkg_nsect;
841 736
842 737 v_toc.v_part[1].p_start = (diskaddr_t)(dkgeom.dkg_ncyl - 1) *
843 738 dkgeom.dkg_nhead * dkgeom.dkg_nsect;
844 739 v_toc.v_part[1].p_size = dkgeom.dkg_nhead * dkgeom.dkg_nsect;
845 740
846 741 v_toc.v_part[2].p_start = 0;
847 742 v_toc.v_part[2].p_size = (diskaddr_t)dkgeom.dkg_ncyl *
848 743 dkgeom.dkg_nhead * dkgeom.dkg_nsect;
849 744
850 745 /* both write_vtoc and DKIOCSVTOC require V_NUMPAR partitions */
851 746 v_toc.v_nparts = V_NUMPAR;
852 747
853 748 } else {
854 749
855 750 return (0);
856 751 }
857 752
858 753 v_toc.v_sanity = VTOC_SANE;
859 754 v_toc.v_version = V_VERSION;
860 755
861 756 /*
862 757 * The label structure is set up for DEV_BSIZE(512 byte) blocks,
863 758 * even though a medium density diskette has 1024 byte blocks
864 759 * See dklabel.h for more details.
865 760 */
866 761 v_toc.v_sectorsz = DEV_BSIZE;
867 762
868 763 /* let the fd driver finish constructing the label and writing it. */
869 764
870 765
871 766 /* Turn on the privileges. */
872 767 (void) __priv_bracket(PRIV_ON);
873 768
874 769 ret = write_extvtoc(fd, &v_toc);
875 770
876 771 /* Turn off the privileges. */
877 772 (void) __priv_bracket(PRIV_OFF);
878 773
879 774 if (ret < 0) {
880 775 PERROR("Write vtoc");
881 776 DPRINTF1("Write vtoc failed errno:%d\n", errno);
882 777 return (-1);
883 778 }
884 779
885 780 return (0);
886 781 }
887 782
888 783 static void
889 784 intr_sig_handler()
890 785 {
891 786 char c;
892 787
893 788 (void) fprintf(stderr, gettext(global_intr_msg));
894 789 (void) fprintf(stderr,
895 790 gettext("\nDo you want to stop formatting?(y/n)"));
896 791 (void) fflush(stdout);
897 792 rewind(stdin);
898 793 while ((c = getchar()) == -1)
899 794 ;
900 795 if (c == 'y' || c == 'Y') {
901 796 (void) fprintf(stderr, gettext("Format interrupted\n"));
902 797 exit(1);
903 798 } else if (c == 'n' || c == 'N')
904 799 return;
905 800 else {
906 801 (void) fprintf(stderr, gettext("Did not interrupt\n"));
907 802 return;
908 803 }
909 804 }
910 805
911 806 static struct sigaction act, oact;
912 807 void
913 808 trap_SIGINT()
914 809 {
915 810
916 811 act.sa_handler = intr_sig_handler;
917 812 (void) memset(&act.sa_mask, 0, sizeof (sigset_t));
918 813 act.sa_flags = SA_RESTART; /* | SA_NODEFER; */
919 814 if (sigaction(SIGINT, &act, &oact) < 0) {
920 815 DPRINTF("sigset failed\n");
921 816 return;
922 817 }
923 818 }
924 819
925 820 void
926 821 release_SIGINT()
927 822 {
928 823 if (sigaction(SIGINT, &oact, (struct sigaction *)NULL) < 0) {
929 824 DPRINTF("sigunset failed\n");
930 825 return;
931 826 }
932 827 }
933 828
934 829 int32_t
935 830 verify(smedia_handle_t handle, int32_t fd, diskaddr_t start_sector,
936 831 uint32_t nblocks, char *buf,
937 832 int32_t flag, int32_t blocksize, int32_t no_raw_rw)
938 833 {
939 834 uint64_t ret;
940 835
941 836 DPRINTF("ANALYSE MEDIA \n");
942 837
943 838
944 839 if ((flag == VERIFY_READ) && (!no_raw_rw)) {
945 840
946 841 /* Turn on the privileges. */
947 842 (void) __priv_bracket(PRIV_ON);
948 843
949 844 ret = smedia_raw_read(handle, start_sector, buf, nblocks *
950 845 blocksize);
951 846
952 847 /* Turn off the privileges. */
953 848 (void) __priv_bracket(PRIV_OFF);
954 849
955 850 if (ret != (nblocks * blocksize))
956 851 return (-1);
957 852 return (0);
958 853
959 854 } else if ((flag == VERIFY_WRITE) && (!no_raw_rw)) {
960 855
961 856 /* Turn on privileges. */
962 857 (void) __priv_bracket(PRIV_ON);
963 858
964 859 ret = smedia_raw_write(handle, start_sector, buf, nblocks *
965 860 blocksize);
966 861
967 862 /* Turn off the privileges. */
968 863 (void) __priv_bracket(PRIV_OFF);
969 864
970 865 if (ret != (blocksize * nblocks))
971 866 return (-1);
972 867 return (0);
973 868
974 869 } else if ((flag == VERIFY_READ) && (no_raw_rw)) {
975 870 ret = llseek(fd, start_sector * blocksize, SEEK_SET);
976 871 if (ret != start_sector * blocksize) {
977 872 (void) fprintf(stderr, gettext("Seek failed\n"));
978 873 return (-2);
979 874 }
980 875
981 876 /* Turn on the privileges. */
982 877 (void) __priv_bracket(PRIV_ON);
983 878
984 879 ret = read(fd, buf, nblocks * blocksize);
985 880
986 881 /* Turn off the privileges. */
987 882 (void) __priv_bracket(PRIV_OFF);
988 883
989 884 if (ret != nblocks * blocksize) {
990 885 return (-1);
991 886 }
992 887 return (0);
993 888 } else if ((flag == VERIFY_WRITE) && (no_raw_rw)) {
994 889 ret = llseek(fd, start_sector * blocksize, SEEK_SET);
995 890 if (ret != start_sector * blocksize) {
996 891 (void) fprintf(stderr, gettext("Seek failed\n"));
997 892 return (-2);
998 893 }
999 894
1000 895 /* Turn on the privileges. */
1001 896 (void) __priv_bracket(PRIV_ON);
1002 897
1003 898 ret = write(fd, buf, nblocks * blocksize);
1004 899
1005 900 /* Turn off the privileges. */
1006 901 (void) __priv_bracket(PRIV_OFF);
1007 902
1008 903 if (ret != nblocks * blocksize) {
1009 904 return (-1);
1010 905 }
1011 906 return (0);
1012 907 } else {
1013 908 DPRINTF("Illegal parameter to verify_analysis!\n");
1014 909 return (-1);
1015 910 }
1016 911 }
1017 912
1018 913 static int
1019 914 my_umount(char *mountp)
1020 915 {
1021 916 pid_t pid; /* forked proc's pid */
1022 917 int rval; /* proc's return value */
1023 918
1024 919
1025 920 /* create a child to unmount the path */
1026 921
1027 922 /* Turn on the privileges */
1028 923 (void) __priv_bracket(PRIV_ON);
1029 924
1030 925 pid = fork();
1031 926
1032 927 /* Turn off the privileges. */
1033 928 (void) __priv_bracket(PRIV_OFF);
1034 929
1035 930 if (pid < 0) {
1036 931 PERROR("fork failed");
1037 932 exit(0);
1038 933 }
1039 934
1040 935 if (pid == 0) {
1041 936 /* the child */
1042 937 /* get rid of those nasty err messages */
1043 938 DPRINTF1("call_unmount_prog: calling %s \n", mountp);
1044 939
1045 940 /* Turn on the priviliges. */
1046 941 (void) __priv_bracket(PRIV_ON);
1047 942
1048 943 if (execl("/usr/sbin/umount", "/usr/sbin/umount", mountp,
1049 944 NULL) < 0) {
1050 945 perror("exec failed");
1051 946 /* Turn off the privileges */
1052 947 (void) __priv_bracket(PRIV_OFF);
1053 948 exit(-1);
1054 949 }
1055 950 }
1056 951
1057 952 /* wait for the umount command to exit */
1058 953 rval = 0;
1059 954 if (waitpid(pid, &rval, 0) == pid) {
↓ open down ↓ |
719 lines elided |
↑ open up ↑ |
1060 955 if (WIFEXITED(rval)) {
1061 956 if (WEXITSTATUS(rval) == 0) {
1062 957 DPRINTF("umount : Success\n");
1063 958 return (1);
1064 959 }
1065 960 }
1066 961 }
1067 962 return (-1);
1068 963 }
1069 964
1070 -static int
1071 -my_volrmmount(char *real_name)
1072 -{
1073 - int pid, rval;
1074 -
1075 - /* Turn on the privileges. */
1076 - (void) __priv_bracket(PRIV_ON);
1077 -
1078 - pid = fork();
1079 -
1080 - /* Turn off the privileges. */
1081 - (void) __priv_bracket(PRIV_OFF);
1082 -
1083 - /* create a child to unmount the path */
1084 - if (pid < 0) {
1085 - PERROR("fork failed");
1086 - exit(0);
1087 - }
1088 -
1089 - if (pid == 0) {
1090 - /* the child */
1091 - /* get rid of those nasty err messages */
1092 - DPRINTF1("call_unmount_prog: calling %s \n",
1093 - "/usr/bin/volrmmount");
1094 -
1095 - /* Turn on the privileges. */
1096 - (void) __priv_bracket(PRIV_ON);
1097 - if (execl("/usr/bin/volrmmount", "/usr/bin/volrmmount", "-e",
1098 - real_name, NULL) < 0) {
1099 - PERROR("volrmmount exec failed");
1100 - /* Turn off the privileges */
1101 - (void) __priv_bracket(PRIV_OFF);
1102 - exit(-1);
1103 - }
1104 - } else if (waitpid(pid, &rval, 0) == pid) {
1105 - if (WIFEXITED(rval)) {
1106 - if (WEXITSTATUS(rval) == 0) {
1107 - DPRINTF("volrmmount: Success\n");
1108 - return (1);
1109 - }
1110 - }
1111 - }
1112 - return (-1);
1113 -}
1114 -
1115 965 int
1116 966 find_device(int defer, char *tmpstr)
1117 967 {
1118 968 DIR *dir;
1119 969 struct dirent *dirent;
1120 970 char sdev[PATH_MAX], dev[PATH_MAX], *pname;
1121 971 device_t *t_dev;
1122 972 int removable = 0;
1123 973 int device_type = 0;
1124 974 int hotpluggable = 0;
1125 975 struct dk_minfo mediainfo;
1126 976 static int found = 0;
1127 977
1128 978 dir = opendir("/dev/rdsk");
1129 979 if (dir == NULL)
1130 980 return (-1);
1131 981
1132 982 total_devices_found = 0;
1133 983 while ((dirent = readdir(dir)) != NULL) {
1134 984 if (dirent->d_name[0] == '.') {
1135 985 continue;
1136 986 }
1137 987 (void) snprintf(sdev, PATH_MAX, "/dev/rdsk/%s",
1138 988 dirent->d_name);
1139 989 #ifdef sparc
1140 990 if (!strstr(sdev, "s2")) {
1141 991 continue;
1142 992 }
1143 993 #else /* x86 */
1144 994 if (vol_running) {
1145 995 if (!(strstr(sdev, "s2") || strstr(sdev, "p0"))) {
1146 996 continue;
1147 997 }
1148 998 } else {
1149 999 if (!strstr(sdev, "p0")) {
1150 1000 continue;
1151 1001 }
1152 1002 }
↓ open down ↓ |
28 lines elided |
↑ open up ↑ |
1153 1003 #endif
1154 1004 if (!lookup_device(sdev, dev)) {
1155 1005 continue;
1156 1006 }
1157 1007 if ((t_dev = get_device(NULL, dev)) == NULL) {
1158 1008 continue;
1159 1009 }
1160 1010 total_devices_found++;
1161 1011
1162 1012 if ((!defer) && !found) {
1163 - char *sn, *tmpbuf;
1013 + char *sn, *tmpbuf = NULL;
1164 1014 /*
1165 1015 * dev_name is an optional command line input.
1166 1016 */
1167 1017 if (dev_name) {
1168 1018 if (strstr(dirent->d_name, tmpstr)) {
1169 1019 found = 1;
1170 1020 } else if (!vol_running) {
1171 1021 continue;
1172 1022 }
1173 1023 }
1174 1024 /*
1175 1025 * volmgt_symname() returns NULL if the device
1176 1026 * is not managed by volmgt.
1177 1027 */
1178 1028 sn = volmgt_symname(sdev);
1179 1029
1180 1030 if (vol_running && (sn != NULL)) {
1181 1031 if (strstr(sn, "dev") == NULL) {
1182 1032 tmpbuf = (char *)my_zalloc(PATH_MAX);
1183 1033 (void) strcpy(tmpbuf,
1184 1034 "/vol/dev/aliases/");
1185 1035 (void) strcat(tmpbuf, sn);
1186 1036 free(sn);
1187 1037 sn = tmpbuf;
1188 1038 }
1189 1039 if (dev_name && !found) {
1190 1040 if (!strstr(tmpbuf, tmpstr)) {
1191 1041 continue;
1192 1042 } else {
1193 1043 found = 1;
1194 1044 }
1195 1045 }
1196 1046 }
1197 1047
1198 1048 /*
1199 1049 * Get device type information for CD/DVD devices.
1200 1050 */
1201 1051 if (is_cd(dev)) {
1202 1052 if (check_device(t_dev,
1203 1053 CHECK_DEVICE_IS_DVD_WRITABLE)) {
1204 1054 device_type = DK_DVDR;
1205 1055 } else if (check_device(t_dev,
1206 1056 CHECK_DEVICE_IS_DVD_READABLE)) {
1207 1057 device_type = DK_DVDROM;
1208 1058 } else if (check_device(t_dev,
1209 1059 CHECK_DEVICE_IS_CD_WRITABLE)) {
1210 1060 device_type = DK_CDR;
1211 1061 } else {
1212 1062 device_type = DK_CDROM;
1213 1063 }
1214 1064 } else {
1215 1065 device_type = ioctl(t_dev->d_fd,
1216 1066 DKIOCGMEDIAINFO, &mediainfo);
1217 1067 if (device_type < 0)
1218 1068 device_type = 0;
1219 1069 else
1220 1070 device_type = mediainfo.dki_media_type;
1221 1071 }
1222 1072
1223 1073 if (!ioctl(t_dev->d_fd, DKIOCREMOVABLE, &removable) &&
1224 1074 !ioctl(t_dev->d_fd, DKIOCHOTPLUGGABLE,
1225 1075 &hotpluggable)) {
1226 1076 if (removable || hotpluggable) {
1227 1077 removable_found++;
1228 1078 pname = get_physical_name(sdev);
1229 1079 if (sn) {
1230 1080 (void) printf(" %4d. "
1231 1081 "Volmgt Node: %s\n",
1232 1082 removable_found, sn);
1233 1083 (void) printf(" "
1234 1084 "Logical Node: %s\n", sdev);
1235 1085 (void) printf(" "
1236 1086 "Physical Node: %s\n",
1237 1087 pname);
1238 1088 } else {
1239 1089 (void) printf(" %4d. "
1240 1090 "Logical Node: %s\n",
1241 1091 removable_found, sdev);
1242 1092 (void) printf(" "
1243 1093 "Physical Node: %s\n",
1244 1094 pname);
1245 1095 }
1246 1096 (void) printf(" Connected "
1247 1097 "Device: %-8.8s %-16.16s "
1248 1098 "%-4.4s\n",
1249 1099 &t_dev->d_inq[8],
1250 1100 &t_dev->d_inq[16],
1251 1101 &t_dev->d_inq[32]);
1252 1102 (void) printf(" Device "
1253 1103 "Type: ");
1254 1104 } else
1255 1105 continue;
1256 1106 } else
1257 1107 continue;
1258 1108
1259 1109 switch (device_type) {
1260 1110 case DK_CDROM:
1261 1111 (void) printf("CD Reader\n");
1262 1112 break;
1263 1113 case DK_CDR:
1264 1114 case DK_CDRW:
1265 1115 (void) printf("CD Reader/Writer\n");
1266 1116 break;
1267 1117 case DK_DVDROM:
1268 1118 (void) printf("DVD Reader\n");
1269 1119 break;
1270 1120 case DK_DVDR:
1271 1121 case DK_DVDRAM:
1272 1122 (void) printf("DVD Reader/Writer\n");
1273 1123 break;
1274 1124 case DK_FIXED_DISK:
1275 1125 if (strstr((const char *)
1276 1126 &t_dev->d_inq[16], "FD") ||
1277 1127 strstr((const char *)
1278 1128 &t_dev->d_inq[16], "LS-120"))
1279 1129 (void) printf("Floppy "
1280 1130 "drive\n");
1281 1131 else
1282 1132 (void) printf("Removable\n");
1283 1133 break;
1284 1134 case DK_FLOPPY:
1285 1135 (void) printf("Floppy drive\n");
1286 1136 break;
1287 1137 case DK_ZIP:
1288 1138 (void) printf("Zip drive\n");
1289 1139 break;
1290 1140 case DK_JAZ:
1291 1141 (void) printf("Jaz drive\n");
1292 1142 break;
1293 1143 default:
1294 1144 (void) printf("<Unknown>\n");
1295 1145 DPRINTF1("\t %d\n", device_type);
1296 1146 break;
1297 1147 }
1298 1148 get_media_info(t_dev, sdev, pname, sn);
1299 1149 }
1300 1150 fini_device(t_dev);
1301 1151 }
1302 1152
1303 1153 (void) closedir(dir);
1304 1154 return (removable_found);
1305 1155 }
1306 1156
1307 1157 /*
1308 1158 * Returns a device_t handle for a node returned by lookup_device()
1309 1159 * and takes the user supplied name and stores it inside the node.
1310 1160 */
1311 1161 static device_t *
1312 1162 get_device(char *user_supplied, char *node)
1313 1163 {
1314 1164 device_t *dev;
1315 1165 int fd;
1316 1166 char devnode[PATH_MAX];
1317 1167 int size;
1318 1168
1319 1169 /*
1320 1170 * we need to resolve any link paths to avoid fake files
1321 1171 * such as /dev/rdsk/../../export/file.
1322 1172 */
1323 1173 size = resolvepath(node, devnode, PATH_MAX);
1324 1174 if ((size <= 0) || (size >= (PATH_MAX - 1)))
1325 1175 return (NULL);
1326 1176
1327 1177 /* resolvepath may not return a null terminated string */
1328 1178 devnode[size] = '\0';
1329 1179
1330 1180
1331 1181 /* the device node must be in /devices/ or /vol/dev/rdsk */
1332 1182
1333 1183 if ((strncmp(devnode, "/devices/", 9) != 0) &&
1334 1184 (strncmp(devnode, "/vol/dev/rdsk", 13) != 0))
1335 1185 return (NULL);
1336 1186
1337 1187 /* Turn on the privileges. */
1338 1188 (void) __priv_bracket(PRIV_ON);
1339 1189
1340 1190 /*
1341 1191 * Since we are currently running with the user euid it is
1342 1192 * safe to try to open the file without checking access.
1343 1193 */
1344 1194
1345 1195 fd = open(devnode, O_RDONLY|O_NDELAY);
1346 1196
1347 1197 /* Turn off the privileges. */
1348 1198 (void) __priv_bracket(PRIV_OFF);
1349 1199
1350 1200 if (fd < 0) {
1351 1201 return (NULL);
1352 1202 }
1353 1203
1354 1204 dev = (device_t *)my_zalloc(sizeof (device_t));
1355 1205
1356 1206 dev->d_node = (char *)my_zalloc(strlen(devnode) + 1);
1357 1207 (void) strcpy(dev->d_node, devnode);
1358 1208
1359 1209 dev->d_fd = fd;
1360 1210
1361 1211 dev->d_inq = (uchar_t *)my_zalloc(INQUIRY_DATA_LENGTH);
1362 1212
1363 1213 /* Turn on privileges. */
1364 1214 (void) __priv_bracket(PRIV_ON);
1365 1215 if (!inquiry(fd, dev->d_inq)) {
1366 1216 DPRINTF1("USCSI ioctl failed %d\n",
1367 1217 uscsi_error);
1368 1218 free(dev->d_inq);
1369 1219 free(dev->d_node);
1370 1220 (void) close(dev->d_fd);
1371 1221 free(dev);
1372 1222 /* Turn off privileges. */
1373 1223 (void) __priv_bracket(PRIV_OFF);
1374 1224 return (NULL);
1375 1225 }
1376 1226 /* Turn off privileges. */
1377 1227 (void) __priv_bracket(PRIV_OFF);
1378 1228
1379 1229 if (user_supplied) {
1380 1230 dev->d_name = (char *)my_zalloc(strlen(user_supplied) + 1);
1381 1231 (void) strcpy(dev->d_name, user_supplied);
1382 1232 }
1383 1233 return (dev);
1384 1234 }
1385 1235
1386 1236 /*
1387 1237 * Check for device specific characteristics.
1388 1238 */
1389 1239 int
1390 1240 check_device(device_t *dev, int cond)
1391 1241 {
1392 1242 uchar_t page_code[4];
1393 1243
1394 1244 /* Look at the capabilities page for this information */
1395 1245 if (cond & CHECK_DEVICE_IS_CD_WRITABLE) {
1396 1246 if (get_mode_page(dev->d_fd, 0x2a, 0, 4, page_code) &&
1397 1247 (page_code[3] & 1)) {
1398 1248 return (1);
1399 1249 }
1400 1250 }
1401 1251
1402 1252 if (cond & CHECK_DEVICE_IS_DVD_WRITABLE) {
1403 1253 if (get_mode_page(dev->d_fd, 0x2a, 0, 4, page_code) &&
1404 1254 (page_code[3] & 0x10)) {
1405 1255 return (1);
1406 1256 }
1407 1257 }
1408 1258
1409 1259 if (cond & CHECK_DEVICE_IS_DVD_READABLE) {
1410 1260 if (get_mode_page(dev->d_fd, 0x2a, 0, 4, page_code) &&
1411 1261 (page_code[2] & 0x8)) {
1412 1262 return (1);
1413 1263 }
1414 1264 }
1415 1265
1416 1266 return (0);
1417 1267 }
1418 1268
1419 1269 /*
1420 1270 * Builds an open()able device path from a user supplied node which can be
1421 1271 * of the * form of /dev/[r]dsk/cxtxdx[sx] or cxtxdx[sx] or volmgt-name like
1422 1272 * cdrom[n].
1423 1273 * Returns the path found in 'found' and returns 1. Otherwise returns 0.
1424 1274 */
1425 1275 int
1426 1276 lookup_device(char *supplied, char *found)
1427 1277 {
1428 1278 struct stat statbuf;
1429 1279 int fd;
1430 1280 char tmpstr[PATH_MAX];
1431 1281
1432 1282 /* Turn on privileges */
1433 1283 (void) __priv_bracket(PRIV_ON);
1434 1284
1435 1285 /* If everything is fine and proper, no need to analyze */
1436 1286 if ((stat(supplied, &statbuf) == 0) && S_ISCHR(statbuf.st_mode) &&
1437 1287 ((fd = open(supplied, O_RDONLY|O_NDELAY)) >= 0)) {
1438 1288 (void) close(fd);
1439 1289 (void) strlcpy(found, supplied, PATH_MAX);
1440 1290 /* Turn off privilege */
1441 1291 (void) __priv_bracket(PRIV_OFF);
1442 1292 return (1);
1443 1293 }
1444 1294
1445 1295 /* Turn off privileges. */
1446 1296 (void) __priv_bracket(PRIV_OFF);
1447 1297
1448 1298 if (strncmp(supplied, "/dev/rdsk/", 10) == 0)
1449 1299 return (vol_lookup(supplied, found));
1450 1300 if (strncmp(supplied, "/dev/dsk/", 9) == 0) {
1451 1301 (void) snprintf(tmpstr, PATH_MAX, "/dev/rdsk/%s",
1452 1302 (char *)strrchr(supplied, '/'));
1453 1303
1454 1304 if ((fd = open(tmpstr, O_RDONLY|O_NDELAY)) >= 0) {
1455 1305 (void) close(fd);
1456 1306 (void) strlcpy(found, supplied, PATH_MAX);
1457 1307 return (1);
1458 1308 }
1459 1309 if ((access(tmpstr, F_OK) == 0) && vol_running)
1460 1310 return (vol_lookup(tmpstr, found));
1461 1311 else
1462 1312 return (0);
1463 1313 }
1464 1314 if ((strncmp(supplied, "cdrom", 5) != 0) &&
1465 1315 (strlen(supplied) < 32)) {
1466 1316 (void) snprintf(tmpstr, sizeof (tmpstr), "/dev/rdsk/%s",
1467 1317 supplied);
1468 1318 if (access(tmpstr, F_OK) < 0) {
1469 1319 (void) strcat(tmpstr, "s2");
1470 1320 }
1471 1321 if ((fd = open(tmpstr, O_RDONLY|O_NDELAY)) >= 0) {
1472 1322 (void) close(fd);
1473 1323 (void) strlcpy(found, tmpstr, PATH_MAX);
1474 1324 return (1);
1475 1325 }
1476 1326 if ((access(tmpstr, F_OK) == 0) && vol_running)
1477 1327 return (vol_lookup(tmpstr, found));
1478 1328 }
1479 1329 return (vol_name_to_dev_node(supplied, found));
1480 1330 }
1481 1331
1482 1332 int
1483 1333 is_cd(char *node)
1484 1334 {
1485 1335 int fd;
1486 1336 struct dk_cinfo cinfo;
1487 1337
1488 1338 fd = open(node, O_RDONLY|O_NDELAY);
1489 1339 if (fd < 0)
1490 1340 return (0);
1491 1341 if (ioctl(fd, DKIOCINFO, &cinfo) < 0) {
1492 1342 (void) close(fd);
1493 1343 return (0);
1494 1344 }
1495 1345 if (cinfo.dki_ctype != DKC_CDROM)
1496 1346 return (0);
1497 1347 return (1);
1498 1348 }
1499 1349
1500 1350 void
1501 1351 print_header(void)
1502 1352 {
1503 1353 /* l10n_NOTE : Column spacing should be kept same */
1504 1354 (void) printf(gettext(" Node "
1505 1355 "Connected Device"));
1506 1356 /* l10n_NOTE : Column spacing should be kept same */
1507 1357 (void) printf(gettext(" Device type\n"));
1508 1358 (void) printf(
1509 1359 "---------------------------+---------------------------");
1510 1360 (void) printf("-----+----------------\n");
1511 1361 }
1512 1362
1513 1363 void
1514 1364 print_divider(void)
1515 1365 {
1516 1366 (void) printf(
1517 1367 "---------------------------+---------------------------");
1518 1368 (void) printf("-----+----------------\n");
1519 1369 }
1520 1370
1521 1371 static void
1522 1372 fini_device(device_t *dev)
1523 1373 {
1524 1374 free(dev->d_inq);
1525 1375 free(dev->d_node);
1526 1376 (void) close(dev->d_fd);
1527 1377 if (dev->d_name)
1528 1378 free(dev->d_name);
1529 1379 free(dev);
1530 1380 }
1531 1381
1532 1382 void *
1533 1383 my_zalloc(size_t size)
1534 1384 {
1535 1385 void *ret;
1536 1386
1537 1387 ret = malloc(size);
1538 1388 if (ret == NULL) {
1539 1389
1540 1390 /* Lets wait a sec. and try again */
1541 1391 if (errno == EAGAIN) {
1542 1392 (void) sleep(1);
1543 1393 ret = malloc(size);
1544 1394 }
1545 1395
1546 1396 if (ret == NULL) {
1547 1397 (void) err_msg("%s\n", gettext(strerror(errno)));
1548 1398 (void) err_msg(gettext(
1549 1399 "Memory allocation failure, Exiting...\n"));
1550 1400 exit(1);
1551 1401 }
1552 1402 }
1553 1403 (void) memset(ret, 0, size);
1554 1404 return (ret);
1555 1405 }
1556 1406
1557 1407 static int
1558 1408 vol_name_to_dev_node(char *vname, char *found)
1559 1409 {
1560 1410 struct stat statbuf;
1561 1411 char *p1;
1562 1412 int i;
1563 1413
1564 1414 if (vname == NULL)
1565 1415 return (0);
1566 1416 if (vol_running)
1567 1417 (void) volmgt_check(vname);
1568 1418 p1 = media_findname(vname);
1569 1419 if (p1 == NULL)
1570 1420 return (0);
1571 1421 if (stat(p1, &statbuf) < 0) {
1572 1422 free(p1);
1573 1423 return (0);
1574 1424 }
1575 1425 if (S_ISDIR(statbuf.st_mode)) {
1576 1426 for (i = 0; i < 16; i++) {
1577 1427 (void) snprintf(found, PATH_MAX, "%s/s%d", p1, i);
1578 1428 if (access(found, F_OK) >= 0)
1579 1429 break;
1580 1430 }
1581 1431 if (i == 16) {
1582 1432 free(p1);
1583 1433 return (0);
1584 1434 }
1585 1435 } else {
1586 1436 (void) strlcpy(found, p1, PATH_MAX);
1587 1437 }
1588 1438 free(p1);
1589 1439 return (1);
1590 1440 }
1591 1441
1592 1442 /*
1593 1443 * Searches for volume manager's equivalent char device for the
1594 1444 * supplied pathname which is of the form of /dev/rdsk/cxtxdxsx
1595 1445 */
1596 1446 static int
1597 1447 vol_lookup(char *supplied, char *found)
1598 1448 {
1599 1449 char tmpstr[PATH_MAX], tmpstr1[PATH_MAX], *p;
1600 1450 int i, ret;
1601 1451
1602 1452 (void) strlcpy(tmpstr, supplied, PATH_MAX);
1603 1453 if ((p = volmgt_symname(tmpstr)) == NULL) {
1604 1454 if (strstr(tmpstr, "s2") != NULL) {
1605 1455 *((char *)(strrchr(tmpstr, 's') + 1)) = 0;
1606 1456 for (i = 0; i < 16; i++) {
1607 1457 (void) snprintf(tmpstr1, PATH_MAX, "%s%d",
1608 1458 tmpstr, i);
1609 1459 if ((p = volmgt_symname(tmpstr1)) != NULL)
1610 1460 break;
1611 1461 }
1612 1462 } else if (strstr(tmpstr, "p0") != NULL) {
1613 1463 *((char *)(strrchr(tmpstr, 'p') + 1)) = 0;
1614 1464 for (i = 0; i < 5; i++) {
1615 1465 (void) snprintf(tmpstr1, PATH_MAX, "%s%d",
1616 1466 tmpstr, i);
1617 1467 if ((p = volmgt_symname(tmpstr1)) != NULL)
1618 1468 break;
1619 1469 }
1620 1470 } else
1621 1471 return (0);
1622 1472 if (p == NULL)
1623 1473 return (0);
1624 1474 }
1625 1475
1626 1476 ret = vol_name_to_dev_node(p, found);
1627 1477 free(p);
1628 1478 return (ret);
1629 1479 }
1630 1480
1631 1481 /*PRINTFLIKE1*/
1632 1482 void
1633 1483 err_msg(char *fmt, ...)
1634 1484 {
1635 1485 va_list ap;
1636 1486
1637 1487 va_start(ap, fmt);
1638 1488 (void) vfprintf(stderr, fmt, ap);
1639 1489 va_end(ap);
1640 1490 }
1641 1491
1642 1492 int
1643 1493 inquiry(int fd, uchar_t *inq)
1644 1494 {
1645 1495 struct uscsi_cmd *scmd;
1646 1496
1647 1497 scmd = get_uscsi_cmd();
1648 1498 scmd->uscsi_flags = USCSI_READ|USCSI_SILENT;
1649 1499 scmd->uscsi_timeout = DEFAULT_SCSI_TIMEOUT;
1650 1500 scmd->uscsi_cdb[0] = INQUIRY_CMD;
1651 1501 scmd->uscsi_cdb[4] = INQUIRY_DATA_LENGTH;
1652 1502 scmd->uscsi_cdblen = 6;
1653 1503 scmd->uscsi_bufaddr = (char *)inq;
1654 1504 scmd->uscsi_buflen = INQUIRY_DATA_LENGTH;
1655 1505 if ((uscsi_error = uscsi(fd, scmd)) < 0)
1656 1506 return (0);
1657 1507 return (1);
1658 1508 }
1659 1509
1660 1510 struct uscsi_cmd *
1661 1511 get_uscsi_cmd(void)
1662 1512 {
1663 1513 (void) memset(&uscmd, 0, sizeof (uscmd));
1664 1514 (void) memset(ucdb, 0, 16);
1665 1515 uscmd.uscsi_cdb = ucdb;
1666 1516 return (&uscmd);
1667 1517 }
1668 1518
1669 1519 int
1670 1520 uscsi(int fd, struct uscsi_cmd *scmd)
1671 1521 {
1672 1522 int ret, global_rqsense;
1673 1523 int retries, max_retries = 5;
1674 1524 int i;
1675 1525
1676 1526 /* set up for request sense extensions */
1677 1527 if (!(scmd->uscsi_flags & USCSI_RQENABLE)) {
1678 1528 scmd->uscsi_flags |= USCSI_RQENABLE;
1679 1529 scmd->uscsi_rqlen = RQBUFLEN;
1680 1530 scmd->uscsi_rqbuf = rqbuf;
1681 1531 global_rqsense = 1;
1682 1532 } else {
1683 1533 global_rqsense = 0;
1684 1534 }
1685 1535
1686 1536 /*
1687 1537 * The device may be busy or slow and fail with a not ready status.
1688 1538 * we'll allow a limited number of retries to give the drive time
1689 1539 * to recover.
1690 1540 */
1691 1541 for (retries = 0; retries < max_retries; retries++) {
1692 1542
1693 1543 scmd->uscsi_status = 0;
1694 1544
1695 1545 if (global_rqsense)
1696 1546 (void) memset(rqbuf, 0, RQBUFLEN);
1697 1547
1698 1548 DPRINTF("cmd:[");
1699 1549 for (i = 0; i < scmd->uscsi_cdblen; i++)
1700 1550 DPRINTF1("0x%02x ",
1701 1551 (uchar_t)scmd->uscsi_cdb[i]);
1702 1552 DPRINTF("]\n");
1703 1553
1704 1554 /*
1705 1555 * We need to have root privledges in order to use
1706 1556 * uscsi commands on the device.
1707 1557 */
1708 1558
1709 1559 ret = ioctl(fd, USCSICMD, scmd);
1710 1560
1711 1561 /* maintain consistency in case of sgen */
1712 1562 if ((ret == 0) && (scmd->uscsi_status == 2)) {
1713 1563 ret = -1;
1714 1564 errno = EIO;
1715 1565 }
1716 1566
1717 1567 /* if error and extended request sense, retrieve errors */
1718 1568 if (global_rqsense && (ret < 0) && (scmd->uscsi_status == 2)) {
1719 1569 /*
1720 1570 * The drive is not ready to recieve commands but
1721 1571 * may be in the process of becoming ready.
1722 1572 * sleep for a short time then retry command.
1723 1573 * SENSE/ASC = 2/4 : not ready
1724 1574 * ASCQ = 0 Not Reportable.
1725 1575 * ASCQ = 1 Becoming ready.
1726 1576 */
1727 1577 if ((SENSE_KEY(rqbuf) == 2) && (ASC(rqbuf) == 4) &&
1728 1578 ((ASCQ(rqbuf) == 0) || (ASCQ(rqbuf) == 1))) {
1729 1579 total_retries++;
1730 1580 (void) sleep(3);
1731 1581 continue;
1732 1582 }
1733 1583
1734 1584 /*
1735 1585 * Device is not ready to transmit or a device reset
1736 1586 * has occurred. wait for a short period of time then
1737 1587 * retry the command.
1738 1588 */
1739 1589 if ((SENSE_KEY(rqbuf) == 6) && ((ASC(rqbuf) == 0x28) ||
1740 1590 (ASC(rqbuf) == 0x29))) {
1741 1591 (void) sleep(3);
1742 1592 total_retries++;
1743 1593 continue;
1744 1594 }
1745 1595
1746 1596 DPRINTF3("cmd: 0x%02x ret:%i status:%02x ",
1747 1597 (uchar_t)scmd->uscsi_cdb[0], ret,
1748 1598 scmd->uscsi_status);
1749 1599 DPRINTF3(" sense: %02x ASC: %02x ASCQ:%02x\n",
1750 1600 (uchar_t)SENSE_KEY(rqbuf),
1751 1601 (uchar_t)ASC(rqbuf), (uchar_t)ASCQ(rqbuf));
1752 1602 }
1753 1603
1754 1604 /* no errors we'll return */
1755 1605 break;
1756 1606 }
1757 1607
1758 1608 /* store the error status for later debug printing */
1759 1609 if ((ret < 0) && (global_rqsense)) {
1760 1610 uscsi_status = scmd->uscsi_status;
1761 1611 rqstatus = scmd->uscsi_rqstatus;
1762 1612 rqresid = scmd->uscsi_rqresid;
1763 1613
1764 1614 }
1765 1615
1766 1616 DPRINTF1("total retries: %d\n", total_retries);
1767 1617
1768 1618 return (ret);
1769 1619 }
1770 1620
1771 1621 /*
1772 1622 * will get the mode page only i.e. will strip off the header.
1773 1623 */
1774 1624 int
1775 1625 get_mode_page(int fd, int page_no, int pc, int buf_len, uchar_t *buffer)
1776 1626 {
1777 1627 int ret;
1778 1628 uchar_t byte2, *buf;
1779 1629 uint_t header_len, page_len, copy_cnt;
1780 1630
1781 1631 byte2 = (uchar_t)(((pc << 6) & 0xC0) | (page_no & 0x3f));
1782 1632 buf = (uchar_t *)my_zalloc(256);
1783 1633
1784 1634 /* Ask 254 bytes only to make our IDE driver happy */
1785 1635 ret = mode_sense(fd, byte2, 1, 254, buf);
1786 1636 if (ret == 0) {
1787 1637 free(buf);
1788 1638 return (0);
1789 1639 }
1790 1640
1791 1641 header_len = 8 + read_scsi16(&buf[6]);
1792 1642 page_len = buf[header_len + 1] + 2;
1793 1643
1794 1644 copy_cnt = (page_len > buf_len) ? buf_len : page_len;
1795 1645 (void) memcpy(buffer, &buf[header_len], copy_cnt);
1796 1646 free(buf);
1797 1647
1798 1648 return (1);
1799 1649 }
1800 1650
1801 1651 int
1802 1652 mode_sense(int fd, uchar_t pc, int dbd, int page_len, uchar_t *buffer)
1803 1653 {
1804 1654 struct uscsi_cmd *scmd;
1805 1655
1806 1656 scmd = get_uscsi_cmd();
1807 1657 scmd->uscsi_flags = USCSI_READ|USCSI_SILENT;
1808 1658 scmd->uscsi_buflen = page_len;
1809 1659 scmd->uscsi_bufaddr = (char *)buffer;
1810 1660 scmd->uscsi_timeout = DEFAULT_SCSI_TIMEOUT;
1811 1661 scmd->uscsi_cdblen = 0xa;
1812 1662 scmd->uscsi_cdb[0] = MODE_SENSE_10_CMD;
1813 1663 if (dbd) {
1814 1664 /* don't return any block descriptors */
1815 1665 scmd->uscsi_cdb[1] = 0x8;
1816 1666 }
1817 1667 /* the page code we want */
1818 1668 scmd->uscsi_cdb[2] = pc;
1819 1669 /* allocation length */
1820 1670 scmd->uscsi_cdb[7] = (page_len >> 8) & 0xff;
1821 1671 scmd->uscsi_cdb[8] = page_len & 0xff;
1822 1672
1823 1673 if ((uscsi_error = uscsi(fd, scmd)) < 0)
1824 1674 return (0);
1825 1675 return (1);
1826 1676 }
1827 1677
1828 1678 uint16_t
1829 1679 read_scsi16(void *addr)
1830 1680 {
1831 1681 uchar_t *ad = (uchar_t *)addr;
1832 1682 uint16_t ret;
1833 1683
1834 1684 ret = ((((uint16_t)ad[0]) << 8) | ad[1]);
1835 1685 return (ret);
1836 1686 }
1837 1687
1838 1688 /*
1839 1689 * Allocate space for and return a pointer to a string
1840 1690 * on the stack. If the string is null, create
1841 1691 * an empty string.
1842 1692 * Use destroy_data() to free when no longer used.
1843 1693 */
1844 1694 char *
1845 1695 alloc_string(s)
1846 1696 char *s;
1847 1697 {
1848 1698 char *ns;
1849 1699
1850 1700 if (s == (char *)NULL) {
1851 1701 ns = (char *)my_zalloc(1);
1852 1702 } else {
1853 1703 ns = (char *)my_zalloc(strlen(s) + 1);
1854 1704 (void) strcpy(ns, s);
1855 1705 }
1856 1706 return (ns);
1857 1707 }
1858 1708
1859 1709 /*
1860 1710 * Follow symbolic links from the logical device name to
1861 1711 * the /devfs physical device name. To be complete, we
1862 1712 * handle the case of multiple links. This function
1863 1713 * either returns NULL (no links, or some other error),
1864 1714 * or the physical device name, alloc'ed on the heap.
1865 1715 *
1866 1716 * Note that the standard /devices prefix is stripped from
1867 1717 * the final pathname, if present. The trailing options
1868 1718 * are also removed (":c, raw").
1869 1719 */
1870 1720 static char *
1871 1721 get_physical_name(char *path)
1872 1722 {
1873 1723 struct stat stbuf;
1874 1724 int i;
1875 1725 int level;
1876 1726 char *p;
1877 1727 char s[MAXPATHLEN];
1878 1728 char buf[MAXPATHLEN];
1879 1729 char dir[MAXPATHLEN];
1880 1730 char savedir[MAXPATHLEN];
1881 1731 char *result = NULL;
1882 1732
1883 1733 if (getcwd(savedir, sizeof (savedir)) == NULL) {
1884 1734 DPRINTF1("getcwd() failed - %s\n", strerror(errno));
1885 1735 return (NULL);
1886 1736 }
1887 1737
1888 1738 (void) strcpy(s, path);
1889 1739 if ((p = strrchr(s, '/')) != NULL) {
1890 1740 *p = 0;
1891 1741 }
1892 1742 if (s[0] == 0) {
1893 1743 (void) strcpy(s, "/");
1894 1744 }
1895 1745 if (chdir(s) == -1) {
1896 1746 DPRINTF2("cannot chdir() to %s - %s\n",
1897 1747 s, strerror(errno));
1898 1748 goto exit;
1899 1749 }
1900 1750
1901 1751 level = 0;
1902 1752 (void) strcpy(s, path);
1903 1753 for (;;) {
1904 1754 /*
1905 1755 * See if there's a real file out there. If not,
1906 1756 * we have a dangling link and we ignore it.
1907 1757 */
1908 1758 if (stat(s, &stbuf) == -1) {
1909 1759 goto exit;
1910 1760 }
1911 1761 if (lstat(s, &stbuf) == -1) {
1912 1762 DPRINTF2("%s: lstat() failed - %s\n",
1913 1763 s, strerror(errno));
1914 1764 goto exit;
1915 1765 }
1916 1766 /*
1917 1767 * If the file is not a link, we're done one
1918 1768 * way or the other. If there were links,
1919 1769 * return the full pathname of the resulting
1920 1770 * file.
1921 1771 */
1922 1772 if (!S_ISLNK(stbuf.st_mode)) {
1923 1773 if (level > 0) {
1924 1774 /*
1925 1775 * Strip trailing options from the
1926 1776 * physical device name
1927 1777 */
1928 1778 if ((p = strrchr(s, ':')) != NULL) {
1929 1779 *p = 0;
1930 1780 }
1931 1781 /*
1932 1782 * Get the current directory, and
1933 1783 * glue the pieces together.
1934 1784 */
1935 1785 if (getcwd(dir, sizeof (dir)) == NULL) {
1936 1786 DPRINTF1("getcwd() failed - %s\n",
1937 1787 strerror(errno));
1938 1788 goto exit;
1939 1789 }
1940 1790 (void) strcat(dir, "/");
1941 1791 (void) strcat(dir, s);
1942 1792 /*
1943 1793 * If we have the standard fixed
1944 1794 * /devices prefix, remove it.
1945 1795 */
1946 1796 p = (strstr(dir, DEVFS_PREFIX) == dir) ?
1947 1797 dir+strlen(DEVFS_PREFIX) : dir;
1948 1798 result = alloc_string(p);
1949 1799 }
1950 1800 goto exit;
1951 1801 }
1952 1802 i = readlink(s, buf, sizeof (buf));
1953 1803 if (i == -1) {
1954 1804 DPRINTF2("%s: readlink() failed - %s\n",
1955 1805 s, strerror(errno));
1956 1806 goto exit;
1957 1807 }
1958 1808 level++;
1959 1809 buf[i] = 0;
1960 1810
1961 1811 /*
1962 1812 * Break up the pathname into the directory
1963 1813 * reference, if applicable and simple filename.
1964 1814 * chdir()'ing to the directory allows us to
1965 1815 * handle links with relative pathnames correctly.
1966 1816 */
1967 1817 (void) strcpy(dir, buf);
1968 1818 if ((p = strrchr(dir, '/')) != NULL) {
1969 1819 *p = 0;
1970 1820 if (chdir(dir) == -1) {
1971 1821 DPRINTF2("cannot chdir() to %s - %s\n",
1972 1822 dir, strerror(errno));
1973 1823 goto exit;
1974 1824 }
1975 1825 (void) strcpy(s, p+1);
1976 1826 } else {
1977 1827 (void) strcpy(s, buf);
1978 1828 }
1979 1829 }
1980 1830
1981 1831 exit:
1982 1832 if (chdir(savedir) == -1) {
1983 1833 (void) printf("cannot chdir() to %s - %s\n",
1984 1834 savedir, strerror(errno));
1985 1835 }
1986 1836
1987 1837 return (result);
1988 1838 }
1989 1839
1990 1840 static void
1991 1841 get_media_info(device_t *t_dev, char *sdev, char *pname, char *sn)
1992 1842 {
1993 1843 struct dk_cinfo cinfo;
1994 1844 struct extvtoc vtocinfo;
1995 1845 float size;
1996 1846 int32_t fd;
1997 1847 smedia_handle_t handle;
1998 1848 struct dk_minfo mediainfo;
1999 1849 int device_type;
2000 1850
2001 1851 device_type = ioctl(t_dev->d_fd, DKIOCGMEDIAINFO, &mediainfo);
2002 1852
2003 1853 /*
2004 1854 * Determine bus type.
2005 1855 */
2006 1856 if (!ioctl(t_dev->d_fd, DKIOCINFO, &cinfo)) {
2007 1857 if (strstr(cinfo.dki_cname, "usb") || strstr(pname, "usb")) {
2008 1858 (void) printf("\tBus: USB\n");
2009 1859 } else if (strstr(cinfo.dki_cname, "firewire") ||
2010 1860 strstr(pname, "firewire")) {
2011 1861 (void) printf("\tBus: Firewire\n");
2012 1862 } else if (strstr(cinfo.dki_cname, "ide") ||
2013 1863 strstr(pname, "ide")) {
2014 1864 (void) printf("\tBus: IDE\n");
2015 1865 } else if (strstr(cinfo.dki_cname, "scsi") ||
2016 1866 strstr(pname, "scsi")) {
2017 1867 (void) printf("\tBus: SCSI\n");
2018 1868 } else {
2019 1869 (void) printf("\tBus: <Unknown>\n");
2020 1870 }
2021 1871 } else {
2022 1872 (void) printf("\tBus: <Unknown>\n");
2023 1873 }
2024 1874
2025 1875 /*
2026 1876 * Calculate size of media.
2027 1877 */
2028 1878 if (!device_type &&
2029 1879 (!ioctl(t_dev->d_fd, DKIOCGMEDIAINFO, &mediainfo))) {
2030 1880 size = (mediainfo.dki_lbsize*
2031 1881 mediainfo.dki_capacity)/(1024.0*1024.0);
2032 1882 if (size < 1000) {
2033 1883 (void) printf("\tSize: %.1f MB\n", size);
2034 1884 } else {
2035 1885 size = size/1000;
2036 1886 (void) printf("\tSize: %.1f GB\n", size);
2037 1887 }
2038 1888 } else {
2039 1889 (void) printf("\tSize: <Unknown>\n");
2040 1890 }
2041 1891
2042 1892 /*
2043 1893 * Print label.
2044 1894 */
2045 1895 if (!device_type && (read_extvtoc(t_dev->d_fd, &vtocinfo) >= 0)) {
2046 1896 if (*vtocinfo.v_volume) {
2047 1897 (void) printf("\tLabel: %s\n", vtocinfo.v_volume);
2048 1898 } else {
2049 1899 (void) printf("\tLabel: <None>\n");
2050 1900 }
2051 1901 } else {
2052 1902 (void) printf("\tLabel: <Unknown>\n");
2053 1903 }
2054 1904
2055 1905 /*
2056 1906 * Acess permissions.
2057 1907 */
2058 1908 if (device_type) {
2059 1909 (void) printf("\tAccess permissions: <Unknown>\n");
2060 1910 return;
2061 1911 }
2062 1912
2063 1913 (void) fprintf(stdout, gettext("\tAccess permissions: "));
2064 1914 if (sn) {
2065 1915 /*
2066 1916 * Set dev_name for process_p_flag().
2067 1917 */
2068 1918 dev_name = sn;
2069 1919 fd = my_open(sn, O_RDONLY|O_NDELAY);
2070 1920 } else {
2071 1921 dev_name = sdev;
2072 1922 fd = my_open(sdev, O_RDONLY|O_NDELAY);
2073 1923 }
2074 1924 if (fd < 0) {
2075 1925 (void) printf("<Unknown>\n");
2076 1926 DPRINTF("Could not open device.\n");
2077 1927 (void) close(fd);
2078 1928 } else {
2079 1929 /* register the fd with the libsmedia */
2080 1930 handle = smedia_get_handle(fd);
2081 1931 if (handle == NULL) {
2082 1932 (void) printf("<Unknown>\n");
2083 1933 DPRINTF("Failed to get libsmedia handle.\n");
2084 1934 (void) close(fd);
2085 1935 } else {
2086 1936 process_p_flag(handle, fd);
2087 1937 }
2088 1938 }
2089 1939 /* Clear dev_name */
2090 1940 dev_name = NULL;
2091 1941 }
↓ open down ↓ |
918 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX