* userv - execserv.c
* daemon code which executes actual service (ie child process)
*
- * Copyright (C)1996-1997 Ian Jackson
+ * Copyright (C)1996-1997,1999 Ian Jackson
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
#include <limits.h>
#include <errno.h>
#include <assert.h>
+#include <string.h>
#include <unistd.h>
#include <stdarg.h>
#include <stdlib.h>
serv_checkstdoutexit();
}
+void bisexec_help(const char *const *argv) {
+ const char *const *pp;
+
+ fputs("recognised builtin services:\n",stdout);
+ for (pp= builtinservicehelpstrings; *pp; pp++) printf(" %s\n",*pp);
+ serv_checkstdoutexit();
+}
+
void bisexec_version(const char *const *argv) {
const unsigned char *p;
int i;
- printf("uservd version " VERSION "; copyright (C)1996-1997 Ian Jackson.\n"
+ printf("uservd version " VERSION VEREXT "; copyright (C)1996-1997 Ian Jackson.\n"
#ifdef DEBUG
"DEBUGGING VERSION"
#else
"production version"
#endif
" - protocol magic number %08lx\n"
- "protocol checksum:",
- BASE_MAGIC);
+ "maximums: fd %-10d general string %d\n"
+ " gids %-10d override length %d\n"
+ " args or variables %-10d error message %d\n"
+ " nested inclusion %-10d errno string reserve %d\n"
+ "protocol checksum: ",
+ BASE_MAGIC,
+ MAX_ALLOW_FD, MAX_GENERAL_STRING,
+ MAX_GIDS, MAX_OVERRIDE_LEN,
+ MAX_ARGSDEFVAR, MAX_ERRMSG_LEN,
+ MAX_INCLUDE_NEST, ERRMSG_RESERVE_ERRNO);
for (i=0, p=protocolchecksumversion; i<sizeof(protocolchecksumversion); i++, p++)
printf("%02x",*p);
printf("\n"
"rendezvous socket: `" RENDEZVOUSPATH "'\n"
"system config dir: `" SYSTEMCONFIGDIR "'\n"
- "pipe filename format: `%s' (max length %d)\n"
- "maximums: fd %-10d general string %d"
- " gids %-10d override length %d\n\n"
- " args or variables %-10d error message %d\n"
- " nested inclusion %-10d errno string reserve %d\n",
- PIPEFORMAT, PIPEMAXLEN,
- MAX_ALLOW_FD, MAX_GENERAL_STRING,
- MAX_GIDS, MAX_OVERRIDE_LEN,
- MAX_ARGSDEFVAR, ERRMSG_RESERVE_ERRNO,
- MAX_INCLUDE_NEST, MAX_ERRMSG_LEN);
+ "pipe filename format: `%s' (max length %d)\n",
+ PIPEFORMAT, PIPEMAXLEN);
serv_checkstdoutexit();
}
static void NONRETURNING dumpconfig(const char *string) {
- int nspaces, c;
+ int nspaces, c, lnl;
- assert(*string);
nspaces= 0;
+ lnl= 1;
while ((c= *string++)) {
switch (c) {
case ' ': nspaces++; break;
- case '\n': nspaces= 0; putchar('\n'); break;
+ case '\n':
+ if (!lnl) putchar('\n');
+ nspaces= 0; lnl= 1;
+ break;
default:
while (nspaces>0) { putchar(' '); nspaces--; }
putchar(c);
+ lnl= 0;
+ break;
}
}
- assert(*--string == '\n');
+ assert(lnl);
serv_checkstdoutexit();
}
serv_checkstdoutexit();
}
+void bisexec_shutdown(const char *const *argv) {
+ /* This is only reached if the serviceuser_uid test in
+ * process.c:servicerequest() fails (we have to handle the
+ * shutdown request there, unfortunately).
+ */
+ fputs("uservd: builtin service shutdown: permission denied\n",stderr);
+ _exit(-1);
+}
+
static void serv_resetsignal(int signo) {
struct sigaction sig;
if (sigaction(signo,&sig,0)) serv_syscallfail("reset signal handler");
}
-static const char *see_logname(void) { return serviceuser; }
+static const char *see_loginname(void) { return serviceuser; }
static const char *see_home(void) { return serviceuser_dir; }
static const char *see_shell(void) { return serviceuser_shell; }
static const char *see_service(void) { return service; }
static const char *see_c_cwd(void) { return cwd; }
-static const char *see_c_logname(void) { return logname; }
+static const char *see_c_loginname(void) { return loginname; }
static const char *see_c_uid(void) {
static char buf[CHAR_BIT*sizeof(uid_t)/3+4];
snyprintf(buf,sizeof(buf),"%lu",(unsigned long)request_mbuf.callinguid);
const char *name;
const char *(*fn)(void);
} serv_envinfos[]= {
- { "USER", see_logname },
- { "LOGNAME", see_logname },
- { "HOME", see_home },
- { "SHELL", see_shell },
- { "PATH", defaultpath },
- { "USERV_SERVICE", see_service },
- { "USERV_CWD", see_c_cwd },
- { "USERV_USER", see_c_logname },
- { "USERV_UID", see_c_uid },
- { "USERV_GROUP", see_c_group },
- { "USERV_GID", see_c_gid },
- { 0 }
+ { "USER", see_loginname },
+ { "LOGNAME", see_loginname },
+ { "HOME", see_home },
+ { "SHELL", see_shell },
+ { "PATH", defaultpath },
+ { "USERV_SERVICE", see_service },
+ { "USERV_CWD", see_c_cwd },
+ { "USERV_USER", see_c_loginname },
+ { "USERV_UID", see_c_uid },
+ { "USERV_GROUP", see_c_group },
+ { "USERV_GID", see_c_gid },
+ { 0 }
};
void execservice(const int synchsocket[], int clientfd) {