/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* scan /dev directory for mountable objects and construct device_allocate
* file for allocate....
*
* devices are:
* tape (cartridge)
* audio
* floppy
* CD
*
*/
#include <errno.h>
#include <fcntl.h>
#include <dirent.h> /* for readdir(3), etc. */
#include <unistd.h> /* for readlink(2) */
#include <stropts.h>
#include <string.h> /* for strcpy(3), etc. */
#include <strings.h> /* for bcopy(3C), etc. */
#include <stdio.h> /* for perror(3) */
#include <stdlib.h> /* for atoi(3) */
#include <locale.h>
#include <libintl.h>
#include <libdevinfo.h>
#include <secdb.h>
#include <deflt.h>
#include <auth_attr.h>
#include <auth_list.h>
#include <bsm/devalloc.h>
#ifndef TEXT_DOMAIN
#endif
struct tape {
char *name;
char *device;
int number;
} *tape;
struct audio {
char *name;
char *device;
int number;
} *audio;
struct cd {
char *name;
char *device;
int id;
int controller;
int number;
} *cd;
struct rmdisk {
char *name;
char *device;
int id;
int controller;
int number;
struct fp {
char *name;
char *device;
int number;
} *fp;
static void dotape();
static void doaudio();
static void dofloppy();
static int docd();
static void dormdisk(int);
static void initmem();
static int expandmem(int, void **, int);
static void no_memory(void);
int system_labeled = 0;
int do_devalloc = 0;
int do_devmaps = 0;
int do_files = 0;
int
{
int cd_count = 0;
char *progname;
(void) textdomain(TEXT_DOMAIN);
else
progname++;
do_devalloc = 1;
do_devmaps = 1;
else
exit(1);
if (!system_labeled) {
/*
* is_system_labeled() will return false in case we are
* starting before the first reboot after Trusted Extensions
* TX is enabled (even if not yet booted).
*/
system_labeled = 1;
/* close defaults file */
}
}
#ifdef DEBUG
/* test hook: see also devfsadm.c and allocate.c */
if (!system_labeled) {
if (system_labeled) {
"forcing system label on for testing...\n");
}
}
#endif
/*
* write device entries to device_allocate and device_maps.
* default is to print them on stdout.
*/
do_files = 1;
}
initmem(); /* initialize memory */
dotape();
doaudio();
dofloppy();
if (system_labeled)
return (0);
}
static void
dotape()
{
int i, j;
int tape_count;
int first = 0;
ntape = DFLT_NTAPE;
/*
* look for rst* and nrst*
*/
exit(1);
}
i = 0;
/* ignore if neither rst* nor nrst* */
continue;
/* if array full, then expand it */
if (i == ntape) {
/* will exit(1) if insufficient memory */
sizeof (struct tape));
}
/* save name (/dev + / + d_name + \0) */
no_memory();
/* ignore if not symbolic link (note i not incremented) */
perror("stat(2) failed ");
exit(1);
}
continue;
/* get name from symbolic link */
sizeof (linkvalue))) < 0)
continue;
no_memory();
/* get device number */
cp++; /* advance to device # */
i++;
}
/*
*/
exit(1);
}
/* skip . .. etc... */
continue;
/* if array full, then expand it */
if (i == ntape) {
/* will exit(1) if insufficient memory */
sizeof (struct tape));
}
no_memory();
/* save device name (rmt/ + d_name + \0) */
no_memory();
i++;
}
tape_count = i;
/* remove duplicate entries */
for (i = 0; i < tape_count - 1; i++) {
for (j = i + 1; j < tape_count; j++) {
continue;
}
}
if (system_labeled) {
} else {
dname = "st";
dtype = "st";
dclean = TAPE_CLEAN;
}
for (i = 0; i < 8; i++) {
for (j = 0; j < tape_count; j++) {
continue;
if (do_files) {
DA_TAPE);
} else if (do_devalloc) {
/* print device_allocate for tape devices */
if (system_labeled) {
(void) printf("%s%d%s\\\n",
dname, i, KV_DELIMITER);
(void) printf("\t%s%s\\\n",
(void) printf("\t%s%s\\\n",
(void) printf("\t%s%s\\\n",
(void) printf("\t%s%s\\\n",
} else {
(void) printf(
"st%d;st;reserved;reserved;%s;",
"/st_clean");
}
break;
} else if (do_devmaps) {
/* print device_maps for tape devices */
if (first) {
(void) printf(" ");
} else {
if (system_labeled) {
(void) printf("%s%d%s\\\n",
dname, i, KV_TOKEN_DELIMIT);
(void) printf("\t%s%s\\\n",
(void) printf("\t");
} else {
(void) printf("st%d:\\\n", i);
(void) printf("\trmt:\\\n");
(void) printf("\t");
}
first++;
}
}
}
if (do_devmaps && first) {
(void) printf("\n\n");
first = 0;
}
}
if (do_files && tape_count) {
(void) da_update_device(&dargs);
}
}
}
static void
doaudio()
{
int i, j;
int audio_count = 0;
int first = 0;
char *dclean;
exit(1);
}
i = 0;
continue;
/* if array full, then expand it */
if (i == naudio) {
/* will exit(1) if insufficient memory */
sizeof (struct audio));
}
/* save name (/dev + 1 + d_name + \0) */
no_memory();
/* ignore if not symbolic link (note i not incremented) */
exit(1);
}
continue;
/* get name from symbolic link */
sizeof (linkvalue))) < 0)
continue;
no_memory();
cp++; /* advance to device # */
i++;
}
goto skip;
}
/* skip . .. etc... */
continue;
/* if array full, then expand it */
if (i == naudio) {
/* will exit(1) if insufficient memory */
sizeof (struct audio));
}
no_memory();
no_memory();
i++;
}
skip:
audio_count = i;
/* remove duplicate entries */
for (i = 0; i < audio_count - 1; i++) {
for (j = i + 1; j < audio_count; j++) {
continue;
}
}
/* print out device_allocate entries for audio devices */
for (i = 0; i < 8; i++) {
for (j = 0; j < audio_count; j++) {
continue;
if (system_labeled)
if (do_files) {
i, DA_AUDIO);
} else if (do_devalloc) {
/* print device_allocate for audio devices */
if (system_labeled) {
(void) printf("%s%s\\\n",
(void) printf("\t%s%s\\\n",
(void) printf("\t%s%s\\\n",
(void) printf("\t%s%s\\\n",
(void) printf("\t%s%s\\\n",
} else {
(void) printf("audio;audio;");
(void) printf("reserved;reserved;%s;",
"/audio_clean");
}
break;
} else if (do_devmaps) {
/* print device_maps for audio devices */
if (first) {
(void) printf(" ");
} else {
if (system_labeled) {
(void) printf("%s%s\\\n",
(void) printf("\t%s%s\\\n",
(void) printf("\t");
} else {
(void) printf("audio:\\\n");
(void) printf("\taudio:\\\n");
(void) printf("\t");
}
first++;
}
}
}
if (do_devmaps && first) {
(void) printf("\n\n");
first = 0;
}
}
if (do_files && audio_count) {
(void) da_update_device(&dargs);
}
}
}
static void
dofloppy()
{
int i, j;
int floppy_count = 0;
int first = 0;
/*
* look for fd* and rfd*
*/
exit(1);
}
i = 0;
/* ignore if neither rst* nor nrst* */
continue;
/* if array full, then expand it */
if (i == nfp) {
/* will exit(1) if insufficient memory */
}
/* save name (/dev + 1 + d_name + \0) */
no_memory();
/* ignore if not symbolic link (note i not incremented) */
exit(1);
}
continue;
/* get name from symbolic link */
sizeof (linkvalue))) < 0)
continue;
no_memory();
/* get device number */
cp++; /* advance to device # */
cp++; /* advance to device # */
i++;
}
floppy_count = i;
/* print out device_allocate entries for floppy devices */
if (system_labeled) {
} else {
dname = "fd";
}
for (i = 0; i < 8; i++) {
for (j = 0; j < floppy_count; j++) {
continue;
if (do_files) {
} else if (do_devalloc) {
/* print device_allocate for floppy devices */
if (system_labeled) {
(void) printf("%s%d%s\\\n",
dname, i, KV_DELIMITER);
(void) printf("\t%s%s\\\n",
(void) printf("\t%s%s\\\n",
(void) printf("\t%s%s\\\n",
(void) printf("\t%s%s\\\n",
} else {
(void) printf(
"fd%d;fd;reserved;reserved;%s;",
"/fd_clean");
}
break;
} else if (do_devmaps) {
/* print device_maps for floppy devices */
if (first) {
(void) printf(" ");
} else {
if (system_labeled) {
(void) printf("%s%d%s\\\n",
dname, i, KV_TOKEN_DELIMIT);
(void) printf("\t%s%s\\\n",
(void) printf("\t");
} else {
(void) printf("fd%d:\\\n", i);
(void) printf("\tfd:\\\n");
(void) printf("\t");
}
if (i == 0) {
(void) printf(
}
first++;
}
}
}
if (do_devmaps && first) {
(void) printf("\n\n");
first = 0;
}
}
if (do_files && floppy_count) {
(void) da_update_device(&dargs);
}
}
}
static int
docd()
{
int i, j;
int cd_count = 0;
int first = 0;
/*
* look for sr* and rsr*
*/
exit(1);
}
i = 0;
/* ignore if neither sr* nor rsr* */
continue;
/* if array full, then expand it */
if (i == ncd) {
/* will exit(1) if insufficient memory */
}
/* save name (/dev + / + d_name + \0) */
no_memory();
/* ignore if not symbolic link (note i not incremented) */
exit(1);
}
continue;
/* get name from symbolic link */
0)
continue;
no_memory();
cp++; /* advance to device # */
i++;
}
cd_count = i;
/*
*/
exit(1);
}
/* skip . .. etc... */
continue;
/* get device # (disk #) */
continue;
/* see if this is one of the cd special devices */
for (j = 0; j < cd_count; j++) {
goto found;
}
continue;
/* if array full, then expand it */
if (i == ncd) {
/* will exit(1) if insufficient memory */
}
no_memory();
i++;
}
/*
*/
exit(1);
}
/* skip . .. etc... */
continue;
/* get device # (disk #) */
continue;
/* see if this is one of the cd special devices */
for (j = 0; j < cd_count; j++) {
goto found1;
}
continue;
/* if array full, then expand it */
if (i == ncd) {
/* will exit(1) if insufficient memory */
}
no_memory();
i++;
}
cd_count = i;
if (system_labeled) {
dname = DA_CD_NAME;
} else {
dname = "sr";
}
for (i = 0; i < 8; i++) {
for (j = 0; j < cd_count; j++) {
continue;
if (do_files) {
DA_CD);
} else if (do_devalloc) {
/* print device_allocate for cd devices */
if (system_labeled) {
(void) printf("%s%d%s\\\n",
dname, i, KV_DELIMITER);
(void) printf("\t%s%s\\\n",
(void) printf("\t%s%s\\\n",
(void) printf("\t%s%s\\\n",
(void) printf("\t%s%s\\\n",
} else {
(void) printf(
"sr%d;sr;reserved;reserved;%s;",
"/sr_clean");
}
break;
} else if (do_devmaps) {
/* print device_maps for cd devices */
if (first) {
(void) printf(" ");
} else {
if (system_labeled) {
(void) printf("%s%d%s\\\n",
dname, i, KV_TOKEN_DELIMIT);
(void) printf("\t%s%s\\\n",
(void) printf("\t");
} else {
(void) printf("sr%d:\\\n", i);
(void) printf("\tsr:\\\n");
(void) printf("\t");
}
first++;
}
}
}
if (do_devmaps && first) {
(void) printf("\n\n");
first = 0;
}
}
(void) da_update_device(&dargs);
}
}
return (cd_count);
}
static void
{
int i, j;
int rmdisk_count;
int first = 0;
int is_cd;
int checked;
int removable;
i = rmdisk_count = 0;
/*
*/
exit(1);
}
is_cd = 0;
checked = 0;
removable = 0;
/* skip . .. etc... */
continue;
/* get device # (disk #) */
continue;
/* see if we've already examined this device */
for (j = 0; j < i; j++) {
checked = 1;
break;
}
/*
* c2t0d0s0 is a different rmdisk than c3t0d0s0.
*/
}
if (checked)
continue;
/* ignore if this is a cd */
for (j = 0; j < cd_count; j++) {
is_cd = 1;
break;
}
}
if (is_cd)
continue;
/* see if device is removable */
continue;
if (removable == 0)
continue;
/*
* if array full, then expand it
*/
if (i == nrmdisk) {
/* will exit(1) if insufficient memory */
sizeof (struct rmdisk));
/* When we expand rmdisk, need to expand rmdisk_r */
sizeof (struct rmdisk));
}
no_memory();
i++;
}
rmdisk_count = i;
for (i = 0, j = rmdisk_count; i < rmdisk_count; i++, j++) {
if (j == nrmdisk) {
/* will exit(1) if insufficient memory */
sizeof (struct rmdisk));
}
}
rmdisk_count = j;
for (i = 0; i < 8; i++) {
for (j = 0; j < rmdisk_count; j++) {
continue;
if (do_files) {
} else if (do_devalloc) {
/* print device_allocate for rmdisk devices */
(void) printf("%s%d%s\\\n",
DA_RMDISK_NAME, i, KV_DELIMITER);
(void) printf("\t%s%s\\\n",
(void) printf("\t%s%s\\\n",
(void) printf("\t%s%s\\\n",
(void) printf("\t%s%s\\\n",
break;
} else if (do_devmaps) {
/* print device_maps for rmdisk devices */
if (first) {
(void) printf(" ");
} else {
(void) printf("%s%d%s\\\n",
DA_RMDISK_NAME, i,
(void) printf("\t%s%s\\\n",
(void) printf("\t");
first++;
}
}
}
if (do_devmaps && first) {
(void) printf("\n\n");
first = 0;
}
}
if (do_files && rmdisk_count) {
(void) da_update_device(&dargs);
}
}
}
/* set default array sizes */
static void
initmem()
{
if (system_labeled) {
sizeof (struct rmdisk));
no_memory();
sizeof (struct rmdisk));
no_memory();
}
no_memory();
}
/* note n will be # elments in array (and could be 0) */
static int
{
void *new;
/* get new array space (n + DELTA) */
perror("memory allocation failed");
exit(1);
}
/* copy old array into new space */
/* now release old arrary */
return (n + DELTA);
}
static void
no_memory(void)
{
gettext("out of memory"));
exit(1);
/* NOT REACHED */
}