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
/
crontab.c
< prev
next >
Wrap
C/C++ Source or Header
|
1988-11-29
|
9KB
|
459 lines
/* $Source: /h0/usr/local/src/crond/crontab.c,v $
* $Revision: 1.6 $
* $Log: crontabnew.c,v $
* Revision 1.6 88/04/20 20:00:00 ram
* OSK-version. use of group-file, added edit_cmd-option, usage of Sysinfo
*
* Revision 1.5 87/05/02 17:33:22 paul
* baseline for mod.sources release
*
* Revision 1.4 87/03/31 13:11:48 paul
* I won't say that rs@mirror gave me this idea
* but crontab uses getopt() now
*
* Revision 1.3 87/03/30 23:43:48 paul
* another suggestion from rs@mirror:
* use getpwuid(getuid)->pw_name instead of getenv("USER")
* this is a boost to security...
*
* Revision 1.2 87/02/11 17:40:12 paul
* changed command syntax to allow append and replace instead of append as
* default and no replace at all.
*
* Revision 1.1 87/01/26 23:49:06 paul
* Initial revision
*/
/* Copyright 1987 by Vixie Enterprises
* 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.
*/
#define MAIN_PROGRAM
#include "cron.h"
#include <pwd.h>
#include <grp.h>
#include <errno.h>
# include <modes.h>
# include <types.h>
# include <info.h>
extern char *strcpy();
static int user_id;
static char n[MAX_FNAME];
static char USER[MAX_UNAME];
static char FILENAME[MAX_FNAME];
static int CHECK_ERROR_COUNT;
static int OPTION;
# define opt_unknown 0
# define opt_list 1
# define opt_delete 2
# define opt_replace 3
# define opt_append 4
# define opt_perm 5
# define opt_edit 6
#if DEBUGGING
static char *OPTIONS[] = {"???", "list", "delete", "replace", "append","show_perm"};
#endif
static void
usage()
{
fprintf(stderr, "usage: %s [-u<=>user] ...\n", PROGNAME);
fprintf(stderr, " ... -l (list user's crontab)\n");
fprintf(stderr, " ... -d (delete user's crontab)\n");
fprintf(stderr, " ... -e (edit user's crontab)\n");
fprintf(stderr, " ... -r<=>file (replace user's crontab)\n");
fprintf(stderr, " ... -a<=>file (append file to user's crontab)\n");
fprintf (stderr," ... -p (which users have the permission to install a crontab)\n");
exit(ERROR_EXIT);
}
void
main(argc, argv)
int argc;
char *argv[];
{
int getuid();
void parse_args(), set_cron_uid(),
list_cmd(), delete_cmd(), replace_cmd(),
show_permission (),edit_cmd();
int append_cmd();
PROGNAME = argv[0];
user_id = getuid();
parse_args(argc, argv);
set_cron_uid();
if(!( info_str("CRONDIR",n, MAX_FNAME))) strcpy(n, SPOOLDIR);
strcat(n, "/");
strcat(n, USER);
switch (OPTION)
{
case opt_list: list_cmd();
break;
case opt_delete: delete_cmd();
break;
case opt_edit: edit_cmd();
unlink(FILENAME);
break;
case opt_replace: replace_cmd();
append_cmd();
break;
case opt_append: append_cmd();
break;
case opt_perm: show_permission ();
break;
}
}
static void
list_cmd()
{
extern errno;
FILE *f;
int ch;
if (!(f = fopen(n, "r")))
{
if (errno == E_PNNF)
fprintf(stderr, "no crontab for %s\n", USER);
else
perror(n);
exit(ERROR_EXIT);
}
/* file it open. copy to stdout, close.
*/
Set_LineNum(1)
while (EOF != (ch = get_char(f)))
putchar(ch);
fclose(f);
}
static void
delete_cmd()
{
extern errno;
int unlink();
void poke_daemon();
if (unlink(n))
{
if (errno == E_PNNF)
fprintf(stderr, "no crontab for %s\n", USER);
else
perror(n);
exit(ERROR_EXIT);
}
poke_daemon();
}
static void
replace_cmd()
{
extern errno;
extern int unlink();
void poke_daemon();
if (unlink(n))
{
if (errno != E_PNNF)
{
perror(n);
exit(ERROR_EXIT);
}
}
}
static void
check_error(msg)
char *msg;
{
CHECK_ERROR_COUNT += 1;
fprintf(stderr, "\"%s\", line %d: %s\n", FILENAME, LINE_NUMBER, msg);
}
static int
append_cmd()
{
entry *load_entry();
int load_env();
void free_entry();
void check_error();
void poke_daemon();
char envstr[MAX_TEMPSTR];
FILE *old, *new;
int ch;
entry *e;
int status;
/* this routine is called for both 'replace' and 'append' commands
*/
/* open the new file being installed.
*/
if (!(new = fopen(FILENAME, "r")))
{
perror(FILENAME);
return(ERROR_EXIT);
}
/* check the syntax of the file being installed.
*/
/* BUG: was reporting errors after the EOF if there were any errors
* in the file proper -- kludged it by stopping after first error.
* vix 31mar87
*/
CHECK_ERROR_COUNT = 0;
while (!CHECK_ERROR_COUNT && ERR != (status = load_env(envstr, new)))
{
if (status == FALSE)
{
if ((e = load_entry(new, check_error)) != NULL)
free((char *) e);
}
}
if (CHECK_ERROR_COUNT != 0)
{
fprintf(stderr, "errors in crontab file, can't install.\n");
fclose(new);
return(ERROR_EXIT);
}
rewind(new);
/* open the old file for append-access. this depends on the file
* being created if it does not exist.
*/
if (!(old = fopen(n, "a")))
{
perror(n);
fclose(new);
return(ERROR_EXIT);
}
/* append the new to the old
*/
Set_LineNum(1)
while (EOF != (ch = get_char(new)))
putc(ch, old);
/* close them and we're done
*/
fclose(old);
fclose(new);
/* set the file to be owned by root
*/
if (ERR == chown(n, ROOT_UID))
{
perror("chown");
return(ERROR_EXIT);
}
poke_daemon();
return(0);
}
void
edit_cmd()
{
extern char **environ;
char *mktemp(),*getenv();
int os9exec(), os9forkc();
int setuid();
void set_cron_uid();
register int i,j;
int ch;
static char *tmp[] = { "me", 0, 0 };
if( getenv("EDITOR")) tmp[0] = getenv("EDITOR");
mktemp(FILENAME);
tmp[1] = FILENAME;
if((i = creat(FILENAME, S_IWRITE | S_IREAD)) < 0) {
perror(FILENAME);
close(i);
exit(ERROR_EXIT);
}
if(( j = open( n, S_IREAD)) < 0)
j = creat( n, S_IREAD | S_IWRITE);
while( read(j, &ch,1) ) write(i, &ch, 1);
close(i); close(j);
if (ERR == chown(FILENAME, user_id))
{
perror("chown");
exit(ERROR_EXIT);
}
again: unlink(n);
setuid(user_id);
os9exec(os9forkc, tmp[0], tmp, environ, 0 ,0 ,3);
wait(0);
set_cron_uid();
while( append_cmd() ) {
perror("retry to edit crontab-file.");
sleep(2);
goto again;
}
}
static void
poke_daemon()
{
if( info_signal(POKECRON) < 0 )
{
perror(POKECRON);
return;
}
}
static void
parse_args(argc, argv)
int argc;
char *argv[];
{
void usage();
struct passwd *getpwnam();
char *x;
int t;
struct passwd *pw;
int argch;
if (!(pw = getpwuid(user_id & 0xffff)))
{
fprintf(stderr, "Your UID isn't in the passwd file.\n");
perror("getpwuid");
}
strcpy(USER, pw->pw_name);
FILENAME[0] = '\0';
OPTION = opt_unknown;
for (t=1;t<argc;++t)
if (*(x = argv[t]) == '-') {
++x;
while (*x) {
switch (*x) {
case 'x':
if (*(x+1) == '=') ++x;
if (*x) ++x;
if (!*x) x = "ext,sch,proc,pars,misc";
if (!set_debug_flags(x))
usage();
else while (*x) ++x;
break;
case 'u':
if ((user_id & 0xff00) != ROOT_UID) {
fprintf(stderr,
"must be privileged to use -u\n"
);
exit(ERROR_EXIT);
}
if (*(x+1) == '=') ++x;
if (*x) ++x;
if (getpwnam(x) == (struct passwd *)NULL) {
fprintf(stderr, "%s: user '%s' unknown\n",
PROGNAME, x);
exit(ERROR_EXIT);
}
(void) strcpy(USER, x);
while (*x) ++x;
break;
case 'l':
if (OPTION != opt_unknown)
usage();
OPTION = opt_list;
break;
case 'p':
if (OPTION != opt_unknown)
usage();
OPTION = opt_perm;
break;
case 'd':
if (OPTION != opt_unknown)
usage();
OPTION = opt_delete;
break;
case 'e':
if (OPTION != opt_unknown)
usage();
OPTION = opt_edit;
(void) strcpy(FILENAME, "/dd/tmp/crXXXXXX");
break;
case 'a':
if (OPTION != opt_unknown)
usage();
OPTION = opt_append;
if (*(x+1) == '=') ++x;
if (*x) ++x;
(void) strcpy(FILENAME, x);
while (*x) ++x;
break;
case 'r':
if (OPTION != opt_unknown)
usage();
OPTION = opt_replace;
if (*(x+1) == '=') ++x;
if (*x) ++x;
(void) strcpy(FILENAME, x);
while (*x) ++x;
break;
default:
usage();
}
if (*x) ++x;
}
}
if (OPTION == opt_unknown)
usage();
endpwent();
#if DEBUGGING
Debug(DMISC, "user=%s, file=%s, option=%s\n",
USER, FILENAME, OPTIONS[(int)OPTION]);
#endif
}
static void
show_permission ()
{
struct group *crongroup;
char **i;
if(!(crongroup = getgrnam(CRON_GRP))) {
perror("no group entry for Cron-group\n");
exit(1);
}
for( i = crongroup->gr_mem; *i ; i++ )
printf("%-10s",*i);
endgrent();
puts("\n\n");
}