home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
rtsi.com
/
2014.01.www.rtsi.com.tar
/
www.rtsi.com
/
OS9
/
TOP
/
USR
/
SRC
/
vcron.t.Z
/
vcron.t
/
VCRON
/
do_command.c
< prev
next >
Wrap
Text File
|
1988-11-15
|
6KB
|
234 lines
/* $Source: /usr/src/local/vix/cron/do_new.c,v $
* $Revision: 1.5 $
* $Log: do_new.c,v $
* Revision 1.5 88/04/20 21:02:00 ram
* OSK-Version. 100% rewrite
*
* Revision 1.4 87/05/02 17:33:35 paul
* baseline for mod.sources release
*
* Revision 1.3 87/04/09 00:03:58 paul
* improved data hiding, locality of declaration/references
* fixed a rs@mirror bug by redesigning the mailto stuff completely
*
* Revision 1.2 87/03/19 12:46:24 paul
* implemented suggestions from rs@mirror (Rich $alz):
* MAILTO="" means no mail should be sent
* various fixes of bugs or lint complaints
* put a To: line in the mail message
*
* Revision 1.1 87/01/26 23:47:00 paul
* Initial revision
*/
/* Copyright 1988 by ram
* All rights reserved
*
* Distribute freely, except: don't sell it, don't remove my name from the
* source or documentation (don't take credit for my work), mark your changes
* (don't get me blamed for your possible bugs), don't alter or remove this
* notice. Commercial redistribution is negotiable; contact me for details.
*
* Send bug reports, bug fixes, enhancements, requests, flames, etc., and
* I'll try to keep a version up to date. I can be reached as follows:
* Paul Vixie, Vixie Enterprises, 329 Noe Street, San Francisco, CA, 94114,
* (415) 864-7013, {ucbvax!dual,ames,ucsfmis,lll-crg,sun}!ptsfa!vixie!paul.
*/
#include "cron.h"
#include <signal.h>
# include <modes.h>
# include <types.h>
# include <time.h>
# include <info.h>
extern int os9forkc(),os9exec();
extern char **environ,*getenv(),*index();
void
do_command(cmd, u)
char *cmd;
user *u;
{
REG int child;
char *ag[2];
extern char *env_get();
#if DEBUGGING
Debug(DPROC, "do_command(%s, (%s,%d,%d))\n",
cmd, env_get(USERENV, u->envp), u->uid, u->gid);
#endif
setuid ((u->gid << 16) | u->uid);
/*
* set uid of user and fork first vcron with enviroment of user.
* wait for first vcron to terminate.
*/
ag[0] = "*"; /* first child ...*/
ag[1] = cmd; /* the command ...*/
ag[2] = NULL;
child = os9exec(os9forkc, PROGNAME, ag, u->envp, 0, 0, 0);
#if DEBUGGING
Debug(DPROC, "[%d] child process forked\n", child);
#endif
wait(0);
set_cron_uid(); /* finish, get back to work */
#if DEBUGGING
Debug(DPROC, "[%d] main process returning to work\n", getpid());
#endif
}
void
do_1th_child(argc,argv)
int argc;
char **argv;
{
argv[0][0] = '?'; /* 2nd child ...... */
os9exec(os9forkc, PROGNAME, argv, environ, 0, 0, 0);
/* no wait cause the 2.nd fork should run independly from
* master cron ! i.e. create a artificial zombie.
* return as fast as you can ...
*/
}
void
do_2nd_child(argc,argv)
int argc;
char **argv;
{
REG int mailit;
REG char *input;
int need_newline = FALSE,escaped = FALSE;
char *ag[2];
char *shell = getenv("SHELL");
REG char *x = shell;
unsigned int status;
int child;
time_t zeit;
char mailpath[MAX_FNAME]; /* place for exec-path to mail */
while (*x && (!isspace (*x))) ++x;
*x = '\0';
chdir(getenv("HOME"));
chxdir(getenv("XDIR"));
if( argv[1][0] == '-') { /* oops we got a mail request */
mailit = TRUE;
argv[1]++;
} else mailit = FALSE;
creat("/nil", S_IREAD | S_IWRITE);
dup(0); dup(0);
if(mailit) {
/*
* we have to mail, so open an input-pipe for the mailer,
* and mail to USER. if MAILTO is defined send mail to that
* name, if fork failes, ignore mail-request.
*/
close(0);
creat("/pipe", S_IREAD | S_IWRITE);
setbuf(stdin, NULL);
ag[0] = "/h0/etc/cmds/smail"; /* default mailer */
if( info_str("smail", mailpath, MAX_FNAME)) ag[0] = mailpath;
if( !((x = getenv("MAILTO")) && *x)) x = getenv("USER");
ag[1] = x;
ag[2] = NULL;
mailit = os9exec(os9forkc, ag[0], ag, environ, 0, 0, 3);
if( mailit < 0) {
close(0); dup(1);
mailit = FALSE;
} else {
close(1); dup(0); /* this is for the benefit */
close(0); dup(2); /* of the next os9forkc() */
close(2); dup(1); /* 0 -->1,2 & 1,2 --> 0 */
}
puts("From VCron-DAEMON");
puts(MAILSUBJ);
puts("---");
}
if (input = index(argv[1], '%')) {
/* % found. replace with a null (remember, we're a forked
* process and the string won't be reused), and increment
* input to point at the following character.
*/
*input++ = '\0';
}
if( input) {
/*
* we are creating path 0 since we were forked with no
* open pathes. open a unnamed pipe with a sufficient
* size for holding the entire input string !
* then write the input-string out and do the %-->CR
* translation.
* NOTICE: this path must be closed after (!!) forking the
* command to signal EOF !
*/
close(0);
create("/pipe", S_ISIZE | S_IREAD | S_IWRITE, S_IREAD |
S_IWRITE, strlen(input)+1);
while (*input)
{
if (!escaped && *input == '%')
{
need_newline = FALSE;
write( 0, "\n", 1);
}
else
{
need_newline = TRUE;
write( 0, input, 1);
escaped = (*input == '\\');
}
input++;
}
if (need_newline)
write( 0, "\n", 1);
}
ag[0] = shell;
ag[1] = argv[1]; /* do even shell-scripts */
ag[2] = NULL;
child = os9exec(os9forkc, shell, ag, environ,0,0,3);
close(0); /* remember: we have to close it, to signal EOF */
time(&zeit);
x = (char *) ctime(&zeit);
x[ strlen(x) - 1] = '\0';
/*
* we have several cases:
* - child couldn't be forked, notifiy it to the mailer and
* close the pipes to signal him a EOF and wait for mailer
* to die.
* - mailer dies first (OOPS). so close the output-pipes to
* allow child to die and wait for it.
* - child dies first. notify starting-ending time and return
* status of child to mailer. that should be normal.
*/
if(mailit) {
if( wait(&status) != child) {
close(1); close(2);
wait(&status);
}
time(&zeit);
if( child >0) {
printf("\n---\ncommand[%d]: '%s'\nrunning between %s ",child,
argv[1], x);
printf("and %sfinished with status %d.\n", ctime( &zeit), (unsigned short) status);
} else
printf("\n---\ncommand '%s'\ncouldn't be forked at %s",argv[1],x);
}
fflush(stdout); /* flush buffers, we are finished */
close(1); close(2);
}