/*
Copyright (C) 2017 Free Software Foundation, Inc.
Written by Miles Bader
This file is part of the GNU Hurd.
The GNU Hurd is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2, or (at
your option) any later version.
The GNU Hurd is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with the GNU Hurd. If not, see <http://www.gnu.org/licenses/>.
*/
/* Fsysopts and command line option parsing */
#include
#include
#include
#include
#include
#include
/* Option parser */
static error_t
parse_opt (int opt, char *arg, struct argp_state *state)
{
error_t err = 0;
struct parse_hook *h = state->hook;
/* Return _ERR from this routine */
#define RETURN(_err) \
do { return _err; } while (0)
/* Print a parsing error message and (if exiting is turned off) return the
error code ERR. */
#define PERR(err, fmt, args...) \
do { argp_error (state, fmt , ##args); RETURN (err); } while (0)
/* Like PERR but for non-parsing errors. */
#define FAIL(rerr, status, perr, fmt, args...) \
do{ argp_failure (state, status, perr, fmt , ##args); RETURN (rerr); } while(0)
if (!arg && state->next < state->argc && (*state->argv[state->next] != '-'))
{
arg = state->argv[state->next];
state->next++;
}
switch (opt)
{
case 'U':
h->perm.uid = atoi (arg);
break;
case 'G':
h->perm.gid = atoi (arg);
break;
case ARGP_KEY_INIT:
/* Initialize our parsing state. */
h = malloc (sizeof (struct parse_hook));
if (!h)
FAIL (ENOMEM, 1, ENOMEM, "option parsing");
h->ncache_len = NODE_CACHE_MAX;
h->perm.uid = 0;
h->perm.gid = 0;
state->hook = h;
break;
case ARGP_KEY_SUCCESS:
/* Set permissions to FS */
fs->perm = h->perm;
/* Set cache len */
fs->node_cache_max = h->ncache_len;
if (fs->root)
{
/*
* FS is already initialized, that means we've been called by fsysopts.
* Update permissions.
*/
/* Don't accept new RPCs during this process */
err = ports_inhibit_all_rpcs ();
if (err)
return err;
err = fs_set_permissions (fs);
/* Accept RPCs again */
ports_resume_all_rpcs ();
}
/* Free the hook */
free (h);
break;
case ARGP_KEY_ERROR:
/* Parsing error occurred, free the permissions. */
free (h);
break;
default:
return ARGP_ERR_UNKNOWN;
}
return err;
}
/*
* Print current permissions. Called by fsysopts.
*/
error_t
netfs_append_args (char **argz, size_t * argz_len)
{
error_t err = 0;
struct acpifs_perm *p;
#define ADD_OPT(fmt, args...) \
do { char buf[100]; \
if (! err) { \
snprintf (buf, sizeof buf, fmt , ##args); \
err = argz_add (argz, argz_len, buf); } } while (0)
p = &fs->perm;
if (p->uid >= 0)
ADD_OPT ("--uid=%u", p->uid);
if (p->gid >= 0)
ADD_OPT ("--gid=%u", p->gid);
#undef ADD_OPT
return err;
}
struct argp acpi_argp = { options, parse_opt, 0, doc };
struct argp *netfs_runtime_argp = &acpi_argp;