mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-10-26 04:30:27 +01:00
21498: Add zsh/newuser module
This commit is contained in:
parent
eb86b42f30
commit
e3c5dd2dd9
10 changed files with 266 additions and 43 deletions
|
|
@ -1,3 +1,10 @@
|
|||
2005-07-20 Peter Stephenson <pws@csr.com>
|
||||
|
||||
* 21498: configure.ac, Configs/defs.mk.in, Doc/Makefile.in,
|
||||
Doc/Zsh/mod_newuser.yo, Src/init.c, Src/module.c, Src/zsh.mdd,
|
||||
Src/Modules/newuser.c, Src/Modules/newuser.mdd: Add zsh/newuser
|
||||
module, currently with no associated shell code.
|
||||
|
||||
2005-07-20 Doug Kearns <djkea2@gus.gscit.monash.edu.au>
|
||||
|
||||
* unposted: Completion/Unix/Command/_rake: add -s option to _arguments
|
||||
|
|
|
|||
|
|
@ -43,6 +43,8 @@ mandir = @mandir@
|
|||
datadir = @datadir@
|
||||
fndir = @fndir@
|
||||
sitefndir = @sitefndir@
|
||||
scriptdir = @scriptdir@
|
||||
sitescriptdir = @sitescriptdir@
|
||||
htmldir = $(datadir)/$(tzsh)/htmldoc
|
||||
|
||||
# compilation
|
||||
|
|
|
|||
|
|
@ -59,7 +59,8 @@ Zsh/mod_compctl.yo Zsh/mod_complete.yo Zsh/mod_complist.yo \
|
|||
Zsh/mod_computil.yo \
|
||||
Zsh/mod_datetime.yo Zsh/mod_deltochar.yo \
|
||||
Zsh/mod_example.yo Zsh/mod_files.yo \
|
||||
Zsh/mod_mapfile.yo Zsh/mod_mathfunc.yo Zsh/mod_parameter.yo Zsh/mod_pcre.yo \
|
||||
Zsh/mod_mapfile.yo Zsh/mod_mathfunc.yo Zsh/mod_newuser.yo \
|
||||
Zsh/mod_parameter.yo Zsh/mod_pcre.yo \
|
||||
Zsh/mod_sched.yo Zsh/mod_socket.yo \
|
||||
Zsh/mod_stat.yo Zsh/mod_system.yo Zsh/mod_tcp.yo \
|
||||
Zsh/mod_termcap.yo Zsh/mod_terminfo.yo \
|
||||
|
|
|
|||
37
Doc/Zsh/mod_newuser.yo
Normal file
37
Doc/Zsh/mod_newuser.yo
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
COMMENT(!MOD!zsh/newuser
|
||||
Arrange for files for new users to be installed.
|
||||
!MOD!)
|
||||
The tt(zsh/newuser) module is loaded at boot if it is
|
||||
available, the tt(RCS) option is set, and the tt(PRIVILEGED) option is not
|
||||
set (all three are true by default). This takes
|
||||
place immediately after commands in the global tt(zshenv) file (typically
|
||||
tt(/etc/zshenv)), if any, have been executed. If the module is not
|
||||
available it is silently ignored by the shell; the module may safely be
|
||||
removed from tt($MODULE_PATH) by the administrator if it is not required.
|
||||
|
||||
On loading, the module tests if any of the start-up files tt(.zshenv),
|
||||
tt(.zprofile), tt(.zshrc) or tt(.zlogin) exist in the directory given by
|
||||
the environment variable tt(ZDOTDIR), or the user's home directory if that
|
||||
is not set.
|
||||
|
||||
If none of the start-up files were found, the module then looks for the
|
||||
file tt(newuser) first in a sitewide directory, usually the parent
|
||||
directory of the tt(site-functions) directory, and if that is not found the
|
||||
module searches in a version-specific directory, usually the parent of the
|
||||
tt(functions) directory containing version-specific functions. (These
|
||||
directories can be configured when zsh is built using the
|
||||
tt(--enable-site-scriptdir=)var(dir) and tt(--enable-scriptdir=)var(dir)
|
||||
flags to tt(configure), respectively; the defaults are
|
||||
var(prefix)tt(/share/zsh) and var(prefix)tt(/share/zsh/$ZSH_VERSION) where
|
||||
the default var(prefix) is tt(/usr/local).)
|
||||
|
||||
If the file tt(newuser) is found, it is then sourced in the same manner as
|
||||
a start-up file. The file is expected to contain code to install start-up
|
||||
files for the user, however any valid shell code will be executed.
|
||||
|
||||
The tt(zsh/newuser) module is then unconditionally unloaded.
|
||||
|
||||
Note that it is possible to achieve exactly the same effect as the
|
||||
tt(zsh/newuser) module by adding code to tt(/etc/zshenv). The module
|
||||
exists simply to allow the shell to make arrangements for new users without
|
||||
the need for invervention by package maintainers and system administrators.
|
||||
99
Src/Modules/newuser.c
Normal file
99
Src/Modules/newuser.c
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
* newuser.c - handler for easy setup for new zsh users
|
||||
*
|
||||
* This file is part of zsh, the Z shell.
|
||||
*
|
||||
* Copyright (c) 2005 Peter Stephenson
|
||||
* All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, without written agreement and without
|
||||
* license or royalty fees, to use, copy, modify, and distribute this
|
||||
* software and to distribute modified versions of this software for any
|
||||
* purpose, provided that the above copyright notice and the following
|
||||
* two paragraphs appear in all copies of this software.
|
||||
*
|
||||
* In no event shall Peter Stephenson or the Zsh Development Group be liable
|
||||
* to any party for direct, indirect, special, incidental, or consequential
|
||||
* damages arising out of the use of this software and its documentation,
|
||||
* even if Peter Stephenson and the Zsh Development Group have been advised of
|
||||
* the possibility of such damage.
|
||||
*
|
||||
* Peter Stephenson and the Zsh Development Group specifically disclaim any
|
||||
* warranties, including, but not limited to, the implied warranties of
|
||||
* merchantability and fitness for a particular purpose. The software
|
||||
* provided hereunder is on an "as is" basis, and Peter Stephenson and the
|
||||
* Zsh Development Group have no obligation to provide maintenance,
|
||||
* support, updates, enhancements, or modifications.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "newuser.mdh"
|
||||
#include "newuser.pro"
|
||||
|
||||
#include "../zshpaths.h"
|
||||
|
||||
/**/
|
||||
int
|
||||
setup_(UNUSED(Module m))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
static int
|
||||
check_dotfile(const char *dotdir, const char *fname)
|
||||
{
|
||||
VARARR(char, buf, strlen(dotdir) + strlen(fname) + 2);
|
||||
sprintf(buf, "%s/%s", dotdir, fname);
|
||||
|
||||
return access(buf, F_OK);
|
||||
}
|
||||
|
||||
/**/
|
||||
int
|
||||
boot_(UNUSED(Module m))
|
||||
{
|
||||
const char *dotdir = getsparam("ZDOTDIR");
|
||||
const char *spaths[] = {
|
||||
#ifdef SITESCRIPT_DIR
|
||||
SITESCRIPT_DIR,
|
||||
#endif
|
||||
#ifdef SCRIPT_DIR
|
||||
SCRIPT_DIR,
|
||||
#endif
|
||||
0 };
|
||||
const char **sp;
|
||||
|
||||
if (!dotdir)
|
||||
dotdir = home;
|
||||
|
||||
if (check_dotfile(dotdir, ".zshenv") == 0 ||
|
||||
check_dotfile(dotdir, ".zprofile") == 0 ||
|
||||
check_dotfile(dotdir, ".zshrc") == 0 ||
|
||||
check_dotfile(dotdir, ".zlogin") == 0)
|
||||
return 0;
|
||||
|
||||
for (sp = spaths; *sp; sp++) {
|
||||
VARARR(char, buf, strlen(*sp) + 9);
|
||||
sprintf(buf, "%s/newuser", *sp);
|
||||
|
||||
if (!source(buf))
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
int
|
||||
cleanup_(UNUSED(Module m))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
int
|
||||
finish_(UNUSED(Module m))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
12
Src/Modules/newuser.mdd
Normal file
12
Src/Modules/newuser.mdd
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
name=zsh/newuser
|
||||
link=dynamic
|
||||
# We will always try to load newuser, but there is
|
||||
# no error if it fails.
|
||||
load=no
|
||||
|
||||
objects="newuser.o"
|
||||
|
||||
:<<\Make
|
||||
newuser.o: ../zshpaths.h
|
||||
|
||||
Make
|
||||
12
Src/init.c
12
Src/init.c
|
|
@ -948,8 +948,20 @@ run_init_scripts(void)
|
|||
#ifdef GLOBAL_ZSHENV
|
||||
source(GLOBAL_ZSHENV);
|
||||
#endif
|
||||
|
||||
if (isset(RCS) && unset(PRIVILEGED))
|
||||
{
|
||||
/*
|
||||
* Always attempt to load the newuser module to perform
|
||||
* checks for new zsh users. Don't care if we can't load it.
|
||||
*/
|
||||
if (load_module_silence("zsh/newuser", 1)) {
|
||||
/* Unload it immediately. */
|
||||
unload_named_module("zsh/newuser", "zsh", 1);
|
||||
}
|
||||
|
||||
sourcehome(".zshenv");
|
||||
}
|
||||
if (islogin) {
|
||||
#ifdef GLOBAL_ZPROFILE
|
||||
if (isset(RCS) && isset(GLOBALRCS))
|
||||
|
|
|
|||
107
Src/module.c
107
Src/module.c
|
|
@ -434,12 +434,12 @@ try_load_module(char const *name)
|
|||
|
||||
/**/
|
||||
static void *
|
||||
do_load_module(char const *name)
|
||||
do_load_module(char const *name, int silent)
|
||||
{
|
||||
void *ret;
|
||||
|
||||
ret = try_load_module(name);
|
||||
if (!ret) {
|
||||
if (!ret && !silent) {
|
||||
int waserr = errflag;
|
||||
zerr("failed to load module: %s", name, 0);
|
||||
errflag = waserr;
|
||||
|
|
@ -452,11 +452,12 @@ do_load_module(char const *name)
|
|||
|
||||
/**/
|
||||
static void *
|
||||
do_load_module(char const *name)
|
||||
do_load_module(char const *name, int silent)
|
||||
{
|
||||
int waserr = errflag;
|
||||
|
||||
zerr("failed to load module: %s", name, 0);
|
||||
if (!silent)
|
||||
zerr("failed to load module: %s", name, 0);
|
||||
errflag = waserr;
|
||||
|
||||
return NULL;
|
||||
|
|
@ -747,6 +748,13 @@ modname_ok(char const *p)
|
|||
/**/
|
||||
mod_export int
|
||||
load_module(char const *name)
|
||||
{
|
||||
return load_module_silence(name, 0);
|
||||
}
|
||||
|
||||
/**/
|
||||
mod_export int
|
||||
load_module_silence(char const *name, int silent)
|
||||
{
|
||||
Module m;
|
||||
void *handle = NULL;
|
||||
|
|
@ -755,7 +763,8 @@ load_module(char const *name)
|
|||
int set;
|
||||
|
||||
if (!modname_ok(name)) {
|
||||
zerr("invalid module name `%s'", name, 0);
|
||||
if (!silent)
|
||||
zerr("invalid module name `%s'", name, 0);
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
|
|
@ -766,7 +775,7 @@ load_module(char const *name)
|
|||
queue_signals();
|
||||
if (!(node = find_module(name, 1, &name))) {
|
||||
if (!(linked = module_linked(name)) &&
|
||||
!(handle = do_load_module(name))) {
|
||||
!(handle = do_load_module(name, silent))) {
|
||||
unqueue_signals();
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -811,7 +820,7 @@ load_module(char const *name)
|
|||
m->flags |= MOD_BUSY;
|
||||
if (m->deps)
|
||||
for (n = firstnode(m->deps); n; incnode(n))
|
||||
if (!load_module((char *) getdata(n))) {
|
||||
if (!load_module_silence((char *) getdata(n), silent)) {
|
||||
m->flags &= ~MOD_BUSY;
|
||||
unqueue_signals();
|
||||
return 0;
|
||||
|
|
@ -820,7 +829,7 @@ load_module(char const *name)
|
|||
if (!m->u.handle) {
|
||||
handle = NULL;
|
||||
if (!(linked = module_linked(name)) &&
|
||||
!(handle = do_load_module(name))) {
|
||||
!(handle = do_load_module(name, silent))) {
|
||||
unqueue_signals();
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -886,7 +895,7 @@ require_module(char *nam, const char *module, UNUSED(int res), int test)
|
|||
return 0;
|
||||
}
|
||||
} else
|
||||
ret = load_module(module);
|
||||
ret = load_module_silence(module, 0);
|
||||
unqueue_signals();
|
||||
|
||||
return ret;
|
||||
|
|
@ -1549,6 +1558,50 @@ unload_module(Module m, LinkNode node)
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**/
|
||||
int
|
||||
unload_named_module(char *modname, char *nam, int silent)
|
||||
{
|
||||
const char *mname;
|
||||
LinkNode node;
|
||||
Module m;
|
||||
int ret = 0;
|
||||
|
||||
node = find_module(modname, 1, &mname);
|
||||
if (node) {
|
||||
LinkNode mn, dn;
|
||||
int del = 0;
|
||||
|
||||
for (mn = firstnode(modules); mn; incnode(mn)) {
|
||||
m = (Module) getdata(mn);
|
||||
if (m->deps && m->u.handle)
|
||||
for (dn = firstnode(m->deps); dn; incnode(dn))
|
||||
if (!strcmp((char *) getdata(dn), mname)) {
|
||||
if (m->flags & MOD_UNLOAD)
|
||||
del = 1;
|
||||
else {
|
||||
zwarnnam(nam, "module %s is in use by another module and cannot be unloaded", mname, 0);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
m = (Module) getdata(node);
|
||||
if (del)
|
||||
m->wrapper++;
|
||||
if (unload_module(m, node))
|
||||
ret = 1;
|
||||
if (del)
|
||||
m->wrapper--;
|
||||
} else if (!silent) {
|
||||
zwarnnam(nam, "no such module %s", modname, 0);
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**/
|
||||
static int
|
||||
bin_zmodload_load(char *nam, char **args, Options ops)
|
||||
|
|
@ -1558,39 +1611,9 @@ bin_zmodload_load(char *nam, char **args, Options ops)
|
|||
int ret = 0;
|
||||
if(OPT_ISSET(ops,'u')) {
|
||||
/* unload modules */
|
||||
const char *mname = *args;
|
||||
for(; *args; args++) {
|
||||
node = find_module(*args, 1, &mname);
|
||||
if (node) {
|
||||
LinkNode mn, dn;
|
||||
int del = 0;
|
||||
|
||||
for (mn = firstnode(modules); mn; incnode(mn)) {
|
||||
m = (Module) getdata(mn);
|
||||
if (m->deps && m->u.handle)
|
||||
for (dn = firstnode(m->deps); dn; incnode(dn))
|
||||
if (!strcmp((char *) getdata(dn), mname)) {
|
||||
if (m->flags & MOD_UNLOAD)
|
||||
del = 1;
|
||||
else {
|
||||
zwarnnam(nam, "module %s is in use by another module and cannot be unloaded", mname, 0);
|
||||
ret = 1;
|
||||
goto cont;
|
||||
}
|
||||
}
|
||||
}
|
||||
m = (Module) getdata(node);
|
||||
if (del)
|
||||
m->wrapper++;
|
||||
if (unload_module(m, node))
|
||||
ret = 1;
|
||||
if (del)
|
||||
m->wrapper--;
|
||||
} else if (!OPT_ISSET(ops,'i')) {
|
||||
zwarnnam(nam, "no such module %s", *args, 0);
|
||||
if (unload_named_module(*args, nam, OPT_ISSET(ops,'i')))
|
||||
ret = 1;
|
||||
}
|
||||
cont: ;
|
||||
}
|
||||
return ret;
|
||||
} else if(!*args) {
|
||||
|
|
@ -1645,7 +1668,7 @@ getconddef(int inf, char *name, int autol)
|
|||
/* This is a definition for an autoloaded condition, load the *
|
||||
* module if we haven't tried that already. */
|
||||
if (f) {
|
||||
load_module(p->module);
|
||||
load_module_silence(p->module, 0);
|
||||
f = 0;
|
||||
p = NULL;
|
||||
} else {
|
||||
|
|
@ -2086,7 +2109,7 @@ getmathfunc(char *name, int autol)
|
|||
|
||||
removemathfunc(q, p);
|
||||
|
||||
load_module(n);
|
||||
load_module_silence(n, 0);
|
||||
|
||||
return getmathfunc(name, 0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,6 +38,12 @@ version.h: $(sdir_top)/Config/version.mk
|
|||
|
||||
zshpaths.h: Makemod $(CONFIG_INCS)
|
||||
@echo '#define MODULE_DIR "'$(MODDIR)'"' > zshpaths.h.tmp
|
||||
@if test x$(sitescriptdir) != xno; then \
|
||||
echo '#define SITESCRIPT_DIR "'$(sitescriptdir)'"' >> zshpaths.h.tmp; \
|
||||
fi
|
||||
@if test x$(scriptdir) != xno; then \
|
||||
echo '#define SCRIPT_DIR "'$(scriptdir)'"' >> zshpaths.h.tmp; \
|
||||
fi
|
||||
@if test x$(sitefndir) != xno; then \
|
||||
echo '#define SITEFPATH_DIR "'$(sitefndir)'"' >> zshpaths.h.tmp; \
|
||||
fi
|
||||
|
|
|
|||
24
configure.ac
24
configure.ac
|
|
@ -286,6 +286,30 @@ AC_SUBST(fndir)dnl
|
|||
AC_SUBST(sitefndir)dnl
|
||||
AC_SUBST(FUNCTIONS_SUBDIRS)dnl
|
||||
|
||||
dnl Directories for scripts such as newuser.
|
||||
|
||||
ifdef([scriptdir],[undefine([scriptdir])])dnl
|
||||
AC_ARG_ENABLE(scriptdir,
|
||||
[ --enable-scriptdir=DIR the directory in which to install scripts],
|
||||
dnl ${VERSION} to be determined at compile time.
|
||||
[if test $enableval = yes; then
|
||||
scriptdir=${datadir}/${tzsh_name}/'${VERSION}'
|
||||
else
|
||||
scriptdir="$enableval"
|
||||
fi], [scriptdir=${datadir}/${tzsh_name}/'${VERSION}'])
|
||||
|
||||
ifdef([sitescriptdir],[undefine([sitescriptdir])])dnl
|
||||
AC_ARG_ENABLE(site-scriptdir,
|
||||
[ --enable-site-scriptdir=DIR same for site scripts (not version specific)],
|
||||
[if test $enableval = yes; then
|
||||
sitescriptdir=${datadir}/${tzsh_name}
|
||||
else
|
||||
sitescriptdir="$enableval"
|
||||
fi], [sitescriptdir=${datadir}/${tzsh_name}])
|
||||
|
||||
AC_SUBST(scriptdir)dnl
|
||||
AC_SUBST(sitescriptdir)dnl
|
||||
|
||||
dnl Do you want maildir support?
|
||||
ifdef([maildir_support],[undefine([maildir_support])])dnl
|
||||
AH_TEMPLATE([MAILDIR_SUPPORT],
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue