





























#include <stdio.h>
#include <pwd.h>
#include <errno.h>
#include <ctype.h>
#include <rpc/types.h>
#include <rpc/xdr.h>
#include <sys/param.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/file.h>
#include "except.h"
#include "proc.h"
#include "debug.h"
#include "expr.h"
#include "sched.h"

#ifdef NDBM
#include <ndbm.h>
#else NDBM
#include "ndbm_fake.h"
#endif NDBM

static char *_FileName_ = __FILE__;		/* Used by EXCEPT (see except.h)     */

#define STAR	-1

DBM		*Q, *OpenJobQueue();

char	*param();
char	*MyName;
char	*Spool;
XDR		*xdr_Init();

PROC_ID	List[2000];
int		N_Elem;
char	*UserName;
int		All;
int		TroubleReported;

usage()
{
	fprintf( stderr, "Usage: %s [ user ] [ -a ] [ cluster[.proc] ... ]\n",
																	MyName );
	exit( 1 );
}


main( argc, argv)
int		argc;
char	*argv[];
{
	char	queue_name[MAXPATHLEN];
	char	*arg;
	int		gather_all(), gather_user();
	int		i;

	MyName = argv[0];

	config( MyName, (CONTEXT *)0 );
	init_params();

	if( argc < 2 ) {
		usage();
	}
	for( argv++; arg = *argv; argv++ ) {
		if( arg[0] == '-' && arg[1] == 'a' ) {
			All = 1;
		} else if( isdigit(arg[0]) ) {
			add_to_list( arg );
		} else {
			UserName = arg;
		}
	}

		/* Open job queue */
	(void)sprintf( queue_name, "%s/job_queue", Spool );
	if( (Q=OpenJobQueue(queue_name,O_RDWR,0)) == NULL ) {
		EXCEPT( "OpenJobQueue(%s)", queue_name );
	}

	LockJobQueue( Q, WRITER );

	if( All ) {
		ScanJobQueue( Q, gather_all );
	}

	if( UserName ) {
		ScanJobQueue( Q, gather_user );
	}

	for( i=0; i<N_Elem; i++ ) {
		if( check_permission(Q,List[i].cluster) == FALSE ) {
			continue;
		}

		if( List[i].proc == STAR ) {
			TerminateCluster( Q, List[i].cluster, REMOVED );
			notify_schedd( List[i].cluster, STAR );
		} else {
			(void)TerminateProc( Q, &List[i], REMOVED );
			notify_schedd( List[i].cluster, List[i].proc );
		}
	}

	exit( 0 );
}

SetSyscalls( foo )
int		foo;
{
	return foo;
}



add_to_list( arg )
char	*arg;
{
	char	*p, *index();
	int		cluster, proc;

	if( p=index(arg,'.') ) {
		cluster = atoi( arg );
		proc = atoi( ++p );
	} else {
		cluster = atoi( arg );
		proc = STAR;
	}

	if( cluster < 1 || proc < STAR )
		usage();

	List[N_Elem].cluster = cluster;
	List[N_Elem].proc = proc;
	N_Elem += 1;
}

gather_all( proc )
PROC	*proc;
{
	List[N_Elem].cluster = proc->id.cluster;
	List[N_Elem].proc = proc->id.proc;
	N_Elem += 1;
}

gather_user( proc )
PROC	*proc;
{
	if( strcmp(proc->owner,UserName) == MATCH ) {
		List[N_Elem].cluster = proc->id.cluster;
		List[N_Elem].proc = proc->id.proc;
		N_Elem += 1;
	}
}

check_permission( Q, cluster )
DBM		*Q;
int		cluster;
{
	PROC	proc;
	struct passwd	*pwd, *getpwuid();
	int		uid;

	proc.id.cluster = cluster;
	proc.id.proc = 0;

	if( FetchProc(Q,&proc) != 0 ) {
		printf( "Cluster %d: Doesn't Exist\n", cluster );
		return FALSE;
	}

	uid = getuid();

	if( uid == 0 )
		return TRUE;

	if( (pwd=getpwuid(uid)) == NULL ) {
		EXCEPT( "Can't find password entry for user %d\n", uid );
	}

	if( strcmp(pwd->pw_name,proc.owner) == MATCH ) {
		return TRUE;
	} else {
		printf( "Cluster %d: Permission Denied\n", cluster );
		return FALSE;
	}
}

init_params()
{
	Spool = param("SPOOL");
	if( Spool == NULL ) {
		EXCEPT( "SPOOL not specified in config file\n" );
	}
}

notify_schedd( cluster, proc )
int		cluster;
int		proc;
{
	int			sock = -1;
	int			cmd;
	XDR			xdr, *xdrs = NULL;
	char		hostname[512];
	PROC_ID		job_id;

	job_id.cluster = cluster;
	job_id.proc = proc;

	if( gethostname(hostname,sizeof(hostname)) < 0 ) {
		EXCEPT( "gethostname failed" );
	}

		/* Connect to the schedd */
	if( (sock = do_connect(hostname, "condor_schedd", SCHED_PORT)) < 0 ) {
		if( !TroubleReported ) {
			dprintf( D_ALWAYS, "Warning: can't connect to condor scheduler\n" );
			TroubleReported = 1;
		}
		return;
	}
	xdrs = xdr_Init( &sock, &xdr );
	xdrs->x_op = XDR_ENCODE;

	cmd = KILL_FRGN_JOB;
	if( !xdr_int(xdrs, &cmd) ) {
		dprintf( D_ALWAYS,
			"Warning: can't send KILL_JOB command to condor scheduler\n" );
		xdr_destroy( xdrs );
		(void)close( sock );
		return;
	}

	if( !xdr_proc_id(xdrs, &job_id) ) {
		dprintf( D_ALWAYS,
			"Warning: can't send proc_id to condor scheduler\n" );
		xdr_destroy( xdrs );
		(void)close( sock );
		return;
	}

	if( !xdrrec_endofrecord(xdrs,TRUE) ) {
		dprintf( D_ALWAYS,
			"Warning: can't send endofrecord to condor scheduler\n" );
		xdr_destroy( xdrs );
		(void)close( sock );
		return;
	}

	dprintf( D_FULLDEBUG, "Sent KILL_FRGN_JOB command to condor scheduler\n" );
	xdr_destroy( xdrs );
	(void)close( sock );
}
