vold_config.c revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (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 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms..
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <rpc/auth_unix.h>
#include <rpcsvc/nfs_prot.h>
#include <locale.h>
#include "vold.h"
/*
* the "present" field below is set to true (if not already true)
* when a particular command is seen
*
* when all config file commands are seen then the list of all commands
* is scanned, and any with the "present" flag *not* set will cause
* vold to die (hopefull) a clean death (using "quit()")
*/
static struct cmds {
char *name; /* config file "command" string */
char *emsg_fmt; /* error msg if not TRUE when done */
} cmd_list[] = {
"Need at least one matching \"%s\" directive in config file \"%s\"\n" },
"Need at least one \"%s\" directive in config file \"%s\"\n" },
"Need one \"%s\" directive in config file \"%s\"\n" },
{ 0, 0}
};
/*
* The "flags" are really quite easy to use. To add a new one, just
* create a new entry in base_flags for your flag, add a FLAG_XXX tag
* name so you can access it with getflag, and you're off.
*/
/* Tags to allow access to flags through getflag */
#define FLAG_UID 1
#define FLAG_GID 2
#define FLAG_TEMP 3
#define FLAG_MODE 4
#define FLAG_MAPTTY 5
#define FLAG_FORCE 6
/* different types of flags */
#define FLAGTYPE_INT 0
#define FLAGTYPE_STRING 1
#define FLAGTYPE_BOOL 2
typedef union valu_t {
char *s;
bool_t b;
} valu_t;
static struct flags {
char *fl_name; /* name of the flag */
} base_flags[] = {
{"user", 0, (void *)"nobody", /* user id */
{"group", 0, (void *)"nobody", /* group id */
{"mode", 0, (void *)"0666", /* access modes */
{ "", 0, 0, 0, 0, 0},
};
static void parseflagvalue(struct flags *, char *);
static void cleanupflags(struct flags *);
/*
* read the config file
*/
config_read(void)
{
extern void unsafe_flush(void);
extern void action_flush(void);
extern void dev_configstart(void);
extern void makeargv(int *, char **, char *);
extern void dev_configend(void);
int ac;
"config_read: can't open config file \"%s\"; %m\n"),
return (FALSE);
}
unsafe_flush(); /* clear the way for new unsafe things */
action_flush(); /* clear the way for new actions */
/*
* If we are rereading the config file, the drivers will get
* called again. It is up to them to deal with any changes.
* If they were configured in, and they aren't in the
* config file now, the code in vold_dev will call dev_close
* on them. dev_configstart(), and dev_configend() allow
* dev_use to do the right thing.
*/
lineno++;
/* skip comment lines (starting with #) and blanks */
continue;
}
continue;
} else {
len -= 2;
continue;
}
} else {
/* just a one liner */
} else {
}
}
/* make a nice argc, argv thing for the commands */
}
}
}
if (!found) {
/* no match for this directive! */
"config_read: unknown directive \"%s\", line %d\n"),
}
}
linelen = 0;
}
return (TRUE);
}
/*
* argv[0] = "use"
* argv[1] = devices: "mo", "cdrom", "floppy", "tape", "worm", "test",
* "pcmem", ...
* argv[2] = type: "drive", "test"
* argv[5] = symbolic name (e.g. "floppy%d")
* argv[...] = flags
*
* flags we may care about:
* uid=UID use UID as default user id
* gid=GID use GID as default group id
* mode=MODE use MODE as default node mode
* force=BOOL work even if not present
*/
static bool_t
{
/* ensure enough args */
if (argc < 6) {
"config file (%s) line %d: insufficient arguments\n"),
vold_config, ln);
return (FALSE);
}
/* at least one database must be configured */
if (db_configured_cnt() == 0) {
"Need at least one database configured in %s\n"),
}
/* load the shared library */
return (FALSE);
}
/* get all of the "flag=value" flags */
/* register this device class */
if (flagp)
return (rval);
}
/*
* argv[0] = "unsafe"
* argv[1..N] = <fstype>
*/
static bool_t
{
extern bool_t add_to_unsafe_list(char *);
int i;
/* ensure we have enough args */
if (argc < 2) {
"config file (%s) line %d: insufficient arguments\n"),
vold_config, ln);
return (FALSE);
}
/* put our unsafe fs'es in the list */
for (i = 1; i < argc; i++) {
if (!add_to_unsafe_list(argv[i])) {
"config file (%s) line %d: unsafe max (%d) exceeded\n"),
return (FALSE);
}
}
return (TRUE);
}
/*
* argv[0] = "db"
* argv[1] = <filename>
* argv[n] = <filename>
*/
static bool_t
{
int i;
if (argc < 2) {
"config file (%s) line %d: insufficient arguments\n"),
vold_config, ln);
return (FALSE);
}
for (i = 1; i < argc; i++) {
"config file (%s) line %d: error loading %s\n"),
/* if there's another one */
if (i+1 < argc) {
gettext("Switching to alternate database %s\n"),
argv[i+1]);
}
} else {
}
}
return (gotone);
}
/*
* handle "label ..." line from vold.conf
*
* argv[0]: "label"
* argv[1]: label_type (e.g. "dos", "cdrom", "sun")
* argv[3...]: media_type (e.g. "floppy", "cdrom", "pcmem")
*/
static bool_t
{
int i;
int n;
if (argc < 2) {
"config file (%s) line %d: insufficient arguments\n"),
vold_config, ln);
return (FALSE);
}
/*
* Load the dso into memory.
*/
return (FALSE);
}
/*
* This is a bit ugly, but what we do here is get the lsw
* for the most recently loaded label code.
*/
lsw = label_getlast();
/*
* Build the list of devices that this label may reside on.
*/
if (argc > 3) {
/* does a list already exist ?? */
/* list already exists -- free it */
}
}
for (i = 3, n = 0; i < argc; i++, n++) {
}
}
return (TRUE);
}
/*
* argv[0]: action ("insert", "eject", "notify")
* argv[2...]: command to execute with execv, and optional args
*
* NOTE: options (e.g. "user=root") have already been stripped
*/
static bool_t
{
extern uid_t network_uid(char *);
extern uid_t network_gid(char *);
char *pname;
if (argc < 3) {
"config file (%s) line %d: insufficient arguments\n"),
vold_config, ln);
return (FALSE);
}
act = ACT_NOTIFY;
act = ACT_INSERT;
act = ACT_REMOUNT;
} else {
"config file (%s) line %d: unknown action %s\n"),
return (FALSE);
}
/* probably ENOENT */
return (FALSE);
}
"config file (%s) line %d: %s not a regular file\n"),
return (FALSE);
}
/*
* XXX: Now check the modes. This is pretty crude... I need to
* XXX: be more complete. I should really check the execute
* XXX: bit for the user and group that's going to execute the
* XXX: file. For now, I assume that if the owner of the
* XXX: file can execute it, so can we. A fair bet in most
* XXX: cases.
*/
"config file (%s) line %d: %s not executable\n"),
return (FALSE);
}
if (*shre != '/') {
char *shre2;
/* relatvie path name -- prepend vol root */
"can't allocate memory for config file scanning\n"));
return (FALSE);
}
} else {
}
"config file (%s) line %d: bad regular expr\n"),
vold_config, ln);
return (FALSE);
}
/*
* We handed the pointer to ap off, but we can still make changes.
* This makes error recovery easier.
*/
/* add 3 for read only on mount if media is read only */
for (i = 0; i < nargs; i++) {
}
if (flagp)
return (TRUE);
}
/*
* search the flag list "flagp" for the tag "tag", returning the string
* value found, or NULL if an error is found
*/
static char *
{
}
return (fp->fl_default.s);
}
}
return (NULL);
}
/*
* search the flag list "flagp" for the tag "tag", returning the bool
* value found, or FALSE if an error is found
*/
static bool_t
{
}
return (fp->fl_default.b);
}
}
return (FALSE);
}
/*
* search the flag list "flagp" for the tag "tag", returning the u_int
* value found, or 0 if an error is found
*/
static uint_t
{
}
}
}
return (0);
}
/*
* flags take the **required** form "flag=value" (no spaces!!). Returns how
* many "argc's" we've eaten.
*/
static uint_t
{
int i, n;
char *p = NULL;
*p++ = NULLC;
}
parseflagvalue(fp, p);
n++;
break;
}
}
if (p != NULL) {
*(p-1) = '=';
}
}
return (n);
}
static void
{
case FLAGTYPE_INT:
}
break;
case FLAGTYPE_STRING:
}
break;
case FLAGTYPE_BOOL:
} else {
}
break;
default:
break;
}
}
static void
{
}
}