#include <locale.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string.h>
#include <unistd.h>
#include <malloc.h>
#include <memory.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/file.h>
#include <fcntl.h>
#include <bsm/devices.h>
#define DMPFILE "/etc/security/device_maps"
#define RETRY_SLEEP 6
#define RETRY_COUNT 10
#define EINVOKE 2
#define EFAIL 1
#if !defined(TEXT_DOMAIN)
#define TEXT_DOMAIN "SUNW_BSM_DMINFO"
#endif
extern off_t lseek();
char *getdmapfield();
char *getdmapdfield();
static void printdmapent();
static void dmapi_err();
static char *prog_name;
static void
printdmapent(dmapp)
devmap_t *dmapp;
{
(void) printf("%s:", dmapp->dmap_devname);
(void) printf("%s:", dmapp->dmap_devtype);
(void) printf("%s", dmapp->dmap_devlist);
(void) printf("\n");
}
static void
dmapi_err(int exit_code, char *err_msg)
{
if (err_msg != NULL) {
(void) fprintf(stderr, "dmapinfo:%s\n", err_msg);
}
if (exit_code == EINVOKE) {
(void) fprintf(stderr,
"Usage: %s [-v] [-a] [-f filename] %s\n",
prog_name,
"[-d device ...]");
(void) fprintf(stderr,
" %s [-v] [-a] [-f filename] %s\n",
prog_name,
"[-n name ...]");
(void) fprintf(stderr,
" %s [-v] [-a] [-f filename] %s\n",
prog_name,
"[-t type ...]");
(void) fprintf(stderr,
" %s [-v] [-a] [-f filename] %s\n",
prog_name,
"[-u Entry]");
}
exit(exit_code);
}
int
main(int argc, char **argv)
{
devmap_t *dmapp;
devmap_t dmap;
char *mptr;
char *tptr;
char *nptr;
char *filename = DMPFILE;
int name = 0;
int device = 0;
int file = 0;
int verbose = 0;
int cntr = 0;
int any = 0;
int update = 0;
int tp = 0;
int des;
int status;
(void) setlocale(LC_ALL, "");
(void) textdomain(TEXT_DOMAIN);
if ((tptr = strrchr(*argv, '/')) != NULL)
prog_name = ++tptr;
else
prog_name = *argv;
argc--;
argv++;
while ((argc >= 1) && (argv[0][0] == '-')) {
switch (argv[0][1]) {
case 'a':
any++;
break;
case 'd':
if ((name) || (device) || (update) || (tp)) {
dmapi_err(EINVOKE,
gettext("option conflict"));
}
device++;
break;
case 'f':
argc--;
argv++;
if (argc <= 0)
dmapi_err(EINVOKE,
gettext("missing file name"));
filename = *argv;
file++;
break;
case 'n':
if ((name) || (device) || (update) || (tp)) {
dmapi_err(EINVOKE,
gettext("option conflict"));
}
name++;
break;
case 't':
if ((name) || (device) || (update) || (tp)) {
dmapi_err(EINVOKE,
gettext("option conflict"));
}
tp++;
break;
case 'u':
if ((name) || (device) || (update) || (tp)) {
dmapi_err(EINVOKE,
gettext("option conflict"));
}
update++;
break;
case 'v':
verbose++;
break;
default:
dmapi_err(EINVOKE,
gettext("bad option"));
break;
}
argc--;
argv++;
}
if (file)
setdmapfile(filename);
if ((device) || (name) || (update) || (tp)) {
if (argc < 1) {
dmapi_err(EINVOKE,
gettext("insufficient args for this option"));
}
}
if (update) {
if (argc != 1) {
dmapi_err(EINVOKE,
gettext("too many args for this option"));
}
if ((dmap.dmap_devname = getdmapfield(*argv)) == NULL) {
dmapi_err(EINVOKE,
gettext("Bad dmap_devname in entry argument"));
}
if ((dmap.dmap_devtype = getdmapfield(NULL)) ==
NULL) {
dmapi_err(EINVOKE,
gettext("Bad dmap_devtype in entry Argument"));
}
if ((dmap.dmap_devlist = getdmapfield(NULL)) ==
NULL) {
dmapi_err(EINVOKE,
gettext("Bad dmap_devlist in entry argument"));
}
cntr = strlen(dmap.dmap_devlist) + 1;
mptr = calloc((unsigned)cntr, sizeof (char));
if (mptr == NULL) {
if (verbose) {
(void) fprintf(stderr,
gettext(
"dmapinfo: Cannot calloc memory\n"));
}
exit(1);
}
(void) strcpy(mptr, dmap.dmap_devlist);
if ((des = open(filename, O_RDWR)) < 0) {
if (verbose) {
(void) fprintf(stderr,
gettext("dmapinfo: Cannot open %s\n"),
filename);
}
exit(1);
}
cntr = 0;
#ifdef CMW
while ((status = flock(des, LOCK_EX | LOCK_NB) == -1) &&
(cntr++ < RETRY_COUNT)) {
(void) sleep(RETRY_SLEEP);
}
#else
while (((status = lockf(des, F_TLOCK, 0)) == -1) &&
(cntr++ < RETRY_COUNT)) {
(void) sleep(RETRY_SLEEP);
}
#endif
if (status == -1) {
if (verbose) {
(void) fprintf(stderr,
gettext("dmapinfo: Cannot lock %s\n"), filename);
}
exit(1);
}
if (verbose) {
(void) fprintf(stderr,
gettext("dmapinfo: Checking %s for name (%s).\n"),
filename, dmap.dmap_devname);
}
if (getdmapnam(dmap.dmap_devname) != NULL) {
if (verbose) {
(void) fprintf(stderr,
gettext("dmapinfo: Device name (%s) found in %s.\n"),
dmap.dmap_devname, filename);
}
exit(1);
}
if (verbose) {
(void) fprintf(stderr,
gettext("dmapinfo: Device name (%s) not found in %s.\n"),
dmap.dmap_devname, filename);
}
nptr = mptr;
nptr = getdmapdfield(nptr);
while (nptr) {
if (verbose) {
(void) fprintf(stderr,
gettext("dmapinfo: "
"Check %s for device (%s).\n"),
filename, nptr);
}
if (getdmapdev(nptr) != NULL) {
if (verbose) {
(void) fprintf(stderr,
gettext("dmapinfo: "
"Device (%s) found in %s.\n"),
nptr, filename);
}
exit(1);
}
if (verbose) {
(void) fprintf(stderr,
gettext("dmapinfo: "
"Device (%s) not found in %s.\n"),
nptr, filename);
}
nptr = getdmapdfield(NULL);
}
if (verbose) {
(void) fprintf(stderr, "dmapinfo: Adding entry to %s\n",
filename);
printdmapent(&dmap);
}
cntr = strlen(dmap.dmap_devname);
cntr += strlen(dmap.dmap_devtype);
cntr += strlen(dmap.dmap_devlist);
cntr += 15;
tptr = calloc((unsigned)cntr, sizeof (char));
if (tptr == NULL) {
exit(1);
}
(void) strcat(tptr, dmap.dmap_devname);
(void) strcat(tptr, ":\\\n\t");
(void) strcat(tptr, dmap.dmap_devtype);
(void) strcat(tptr, ":\\\n\t");
(void) strcat(tptr, dmap.dmap_devlist);
(void) strcat(tptr, ":\\\n\t");
(void) strcat(tptr, "\n");
cntr = strlen(tptr);
#ifdef CMW
if (lseek(des, 0L, L_XTND) == -1L) {
exit(1);
}
#else
if (lseek(des, 0L, SEEK_END) == -1L) {
exit(1);
}
#endif
if (write(des, tptr, cntr) == -1) {
exit(1);
}
if (close(des) == -1) {
exit(1);
}
if (verbose) {
(void) fprintf(stderr, "dmapinfo: Entry added to %s\n",
filename);
}
exit(0);
}
if (device) {
setdmapent();
while (argc >= 1) {
if ((dmapp = getdmapdev(*argv)) != NULL) {
if (verbose) {
printdmapent(dmapp);
}
cntr++;
} else if (any == 0) {
enddmapent();
exit(1);
}
argc--;
argv++;
}
enddmapent();
if (cntr != 0)
exit(0);
exit(1);
}
if (name) {
setdmapent();
while (argc >= 1) {
if ((dmapp = getdmapnam(*argv)) != NULL) {
if (verbose) {
printdmapent(dmapp);
}
cntr++;
} else if (any == 0)
exit(1);
argc--;
argv++;
}
enddmapent();
if (cntr != 0)
exit(0);
exit(1);
}
if (tp) {
cntr = 0;
setdmapent();
while (argc >= 1) {
while ((dmapp = getdmaptype(*argv)) != 0) {
cntr++;
if (verbose) {
printdmapent(dmapp);
}
}
if ((any == 0) && (cntr == 0)) {
enddmapent();
exit(1);
}
argc--;
argv++;
}
enddmapent();
if (cntr == 0)
exit(1);
exit(0);
}
cntr = 0;
setdmapent();
while ((dmapp = getdmapent()) != 0) {
cntr++;
if (verbose) {
printdmapent(dmapp);
}
}
enddmapent();
if (cntr == 0)
exit(1);
return (0);
}