Exemple #1
0
/* This function has a unit test. */
int
string_to_port( const char* addr )
{
	const char* acc = addr;
	const char* tmp;
	int port = 0;

	if( ! (addr && is_valid_sinful(addr)) ) {
		return 0;
	}

	if (*acc != '<')
		return 0;

	acc++;
	if (*acc == '[') {
		tmp = strchr(acc, ']');
		if (!tmp)
			return 0;
		acc = tmp + 1;
	}

	tmp = strchr(acc, ':');
	if (!tmp)
		return 0;

	tmp++;
	port = atoi(tmp);
	return port;
}
JICLocalSchedd::JICLocalSchedd( const char* classad_filename,
								const char* schedd_address, 
								int cluster, int proc, int subproc )
	: JICLocalFile( classad_filename, cluster, proc, subproc )
{
		// initialize this to something reasonable.  we'll change it
		// if anything special happens which needs a different value.
	exit_code = JOB_EXITED;
	if( ! is_valid_sinful(schedd_address) ) {
        EXCEPT("schedd_addr not specified with valid address");
    }
    schedd_addr = strdup( schedd_address );
	dprintf( D_ALWAYS,
			 "Starter running a job under a schedd listening at %s\n",
			 schedd_addr );

	job_updater = NULL;
	m_cleanup_retry_tid = -1;
	m_num_cleanup_retries = 0;
		// NOTE: these config knobs are very similar to
		// SHADOW_MAX_JOB_CLEANUP_RETRIES and
		// SHADOW_JOB_CLEANUP_RETRY_DELAY in the shadow.
	m_max_cleanup_retries = param_integer("LOCAL_UNIVERSE_MAX_JOB_CLEANUP_RETRIES", 5);
	m_cleanup_retry_delay = param_integer("LOCAL_UNIVERSE_JOB_CLEANUP_RETRY_DELAY", 30);
	this->starter_user_policy = NULL;
	m_tried_notify_job_exit = false;
}
static bool test_no_angle_brackets() {
	emit_test("Is the string correctly rejected if there are no angle brackets?");
	char* input = strdup( "209.172.63.167:8080" );
	emit_input_header();
	emit_param("SINFUL", input);
	int result = is_valid_sinful( input );
	free( input );
	emit_output_expected_header();
	emit_retval("%s", tfstr(FALSE));
	emit_output_actual_header();
	emit_retval("%s", tfstr(result));
	if(result != FALSE) {
		FAIL;
	}
	PASS;
}
static bool test_hostname() {
	emit_test("Are hostnames instead of IP addresses rejected like they should be?");
	char* input = strdup( "<balthazar.cs.wisc.edu:47>" );
	emit_input_header();
	emit_param("SINFUL", input);
	int result = is_valid_sinful( input );
	free( input );
	emit_output_expected_header();
	emit_retval("%s", tfstr(FALSE));
	emit_output_actual_header();
	emit_retval("%s", tfstr(result));
	if(result != FALSE) {
		FAIL;
	}
	PASS;
}
static bool test_normal_case() {
	emit_test("Is normal input identified correctly?");
	char* input = strdup( "<208.122.19.56:47>" );
	emit_input_header();
	emit_param("SINFUL", input);
	int result = is_valid_sinful( input );
	free( input );
	emit_output_expected_header();
	emit_retval("%s", tfstr(TRUE));
	emit_output_actual_header();
	emit_retval("%s", tfstr(result));
	if(result != TRUE) {
		FAIL;
	}
	PASS;
}
Exemple #6
0
char*
getAddrFromClaimId( const char* id )
{
	char* tmp;
	char* addr;
	char* copy = strdup( id );
	tmp = strchr( copy, '#' );
	if( tmp ) {
		*tmp = '\0';
		if( is_valid_sinful(copy) ) {
			addr = strdup( copy );
			free( copy );
			return addr;
		}
	}
	free( copy );
	return NULL;
}
Exemple #7
0
bool
DCStarter::initFromClassAd( ClassAd* ad )
{
	char* tmp = NULL;

	if( ! ad ) {
		dprintf( D_ALWAYS, 
				 "ERROR: DCStarter::initFromClassAd() called with NULL ad\n" );
		return false;
	}

	ad->LookupString( ATTR_STARTER_IP_ADDR, &tmp );
	if( ! tmp ) {
			// If that's not defined, try ATTR_MY_ADDRESS
		ad->LookupString( ATTR_MY_ADDRESS, &tmp );
	}
	if( ! tmp ) {
		dprintf( D_FULLDEBUG, "ERROR: DCStarter::initFromClassAd(): "
				 "Can't find starter address in ad\n" );
		return false;
	} else {
		if( is_valid_sinful(tmp) ) {
			New_addr( strnewp(tmp) );
			is_initialized = true;
		} else {
			dprintf( D_FULLDEBUG, 
					 "ERROR: DCStarter::initFromClassAd(): invalid %s in ad (%s)\n", 
					 ATTR_STARTER_IP_ADDR, tmp );
		}
		free( tmp );
		tmp = NULL;
	}

	if( ad->LookupString(ATTR_VERSION, &tmp) ) {
		New_version( strnewp(tmp) );
		free( tmp );
		tmp = NULL;
	}

	return is_initialized;
}
Exemple #8
0
int
main(int argc, char *argv[])
{
	char	*arg;
	int		nArgs = 0;				// number of args 
	int	 i, result;
	char* pool = NULL;
	char* scheddName = NULL;
	char* scheddAddr = NULL;
	MyString method;
	char *tmp;

	myDistro->Init( argc, argv );
	MyName = condor_basename(argv[0]);
	config();

#if !defined(WIN32)
	install_sig_handler(SIGPIPE, SIG_IGN );
#endif

	// dig around in the config file looking for what the config file says
	// about getting files from Condor. This defaults with the global variable
	// initialization.
	tmp = param( "SANDBOX_TRANSFER_METHOD" );
	if ( tmp != NULL ) {
		method = tmp;
		free( tmp );
		string_to_stm( method, st_method );
	}

	char **args = (char **)malloc(sizeof(char *) * argc); // args 
	if ( ! args) exit(2);

	// parse the arguments.
	for( argv++; (arg = *argv); argv++ ) {
		if( arg[0] == '-' ) {
			if( ! arg[1] ) {
				usage();
			}
			switch( arg[1] ) {
			case 'd':
				// dprintf to console
				dprintf_set_tool_debug("TOOL", 0);
				break;
			case 'c':
				args[nArgs] = arg;
				nArgs++;
				argv++;
				if( ! *argv ) {
					fprintf( stderr, 
							 "%s: -constraint requires another argument\n", 
							 MyName);
					exit(1);
				}				
				args[nArgs] = *argv;
				nArgs++;
				break;
			case 'a':
				if( arg[2] && arg[2] == 'd' ) {
					argv++;
					if( ! *argv ) {
						fprintf( stderr, 
								 "%s: -addr requires another argument\n", 
								 MyName);
						exit(1);
					}				
					if( is_valid_sinful(*argv) ) {
						scheddAddr = strdup(*argv);
						if( ! scheddAddr ) {
							fprintf( stderr, "Out of Memory!\n" );
							exit(1);
						}
					} else {
						fprintf( stderr, 
								 "%s: \"%s\" is not a valid address\n",
								 MyName, *argv );
						fprintf( stderr, "Should be of the form "
								 "<ip.address.here:port>\n" );
						fprintf( stderr, 
								 "For example: <123.456.789.123:6789>\n" );
						exit( 1 );
					}
					break;
				}
				All = true;
				break;
			case 'n': 
				// use the given name as the schedd name to connect to
				argv++;
				if( ! *argv ) {
					fprintf( stderr, "%s: -name requires another argument\n", 
							 MyName);
					exit(1);
				}			
				if ( scheddName ) free(scheddName);
				scheddName = strdup(*argv);
				break;
			case 'p':
				// use the given name as the central manager to query
				argv++;
				if( ! *argv ) {
					fprintf( stderr, "%s: -pool requires another argument\n", 
							 MyName);
					exit(1);
				}				
				if( pool ) {
					free( pool );
				}
				pool = strdup( *argv );
				break;
			case 's':
				argv++;
				if( ! *argv ) {
					fprintf( stderr, "%s: -stm requires another argument\n", 
							 MyName);
					exit(1);
				}				
				method = *argv;
				string_to_stm(method, st_method);
				break;
			case 'v':
				version();
				break;
			case 'h':
				usage(0);
				break;
			default:
				fprintf( stderr, "Unrecognized option: %s\n", arg ); 
				usage();
				break;
			}
		} else {
			if( All ) {
					// If -all is set, there should be no other
					// constraint arguments.
				usage();
			}
			args[nArgs] = arg;
			nArgs++;
		}
	}

	// Check to make sure we have a valid sandbox transfer mechanism.
	if (st_method == STM_UNKNOWN) {
		fprintf( stderr,
			"%s: Unknown sandbox transfer method: %s\n", MyName,
			method.Value());
		usage();
		exit(1);
	}

	if( ! (All || nArgs) ) {
			// We got no indication of what to act on


		fprintf( stderr, "You did not specify any jobs\n" ); 
		usage();
	}

		// We're done parsing args, now make sure we know how to
		// contact the schedd. 
	if( ! scheddAddr ) {
			// This will always do the right thing, even if either or
			// both of scheddName or pool are NULL.
		schedd = new DCSchedd( scheddName, pool );
	} else {
		schedd = new DCSchedd( scheddAddr );
	}
	if( ! schedd->locate() ) {
		fprintf( stderr, "%s: %s\n", MyName, schedd->error() ); 
		exit( 1 );
	}

		// Process the args.
	if( All ) {
		handleAll();
	} else {
		for(i = 0; i < nArgs; i++) {
			if( match_prefix( args[i], "-constraint" ) ) {
				i++;
				addConstraint( args[i] );
			} else {
				procArg(args[i]);
			}
		}
	}

		// Sanity check: make certain we now have a constraint
	if ( global_constraint.Length() <= 0 ) {			
		fprintf( stderr, "Unable to create a job constraint!\n");
		exit(1);
	}

	fprintf(stdout,"Fetching data files...\n");

	switch(st_method) {
		case STM_USE_SCHEDD_ONLY:
			{ // start block

			// Get the sandbox directly from the schedd.
			// And now, do the work.
			CondorError errstack;
			result = schedd->receiveJobSandbox(global_constraint.Value(),
				&errstack);
			if ( !result ) {
				fprintf( stderr, "\n%s\n", errstack.getFullText(true).c_str() );
				fprintf( stderr, "ERROR: Failed to spool job files.\n" );
				exit(1);
			}
		
			// All done
			return 0;

			} //end block
			break;

		case STM_USE_TRANSFERD:
			{ // start block

			// NEW METHOD where we ask the schedd for a transferd, then get the
			// files from the transferd

			CondorError errstack;
			ClassAd respad;
			int invalid;
			MyString reason;
			MyString td_sinful;
			MyString td_cap;

			result = schedd->requestSandboxLocation(FTPD_DOWNLOAD, 
				global_constraint, FTP_CFTP, &respad, &errstack);
			if ( !result ) {
				fprintf( stderr, "\n%s\n", errstack.getFullText(true).c_str() );
				fprintf( stderr, "ERROR: Failed to spool job files.\n" );
				exit(1);
			}

			respad.LookupInteger(ATTR_TREQ_INVALID_REQUEST, invalid);
			if (invalid == TRUE) {
				fprintf( stderr, "ERROR: Failed to spool job files.\n" );
				respad.LookupString(ATTR_TREQ_INVALID_REASON, reason);
				fprintf( stderr, "%s\n", reason.Value());
				exit(EXIT_FAILURE);
			}

			respad.LookupString(ATTR_TREQ_TD_SINFUL, td_sinful);
			respad.LookupString(ATTR_TREQ_CAPABILITY, td_cap);

			dprintf(D_ALWAYS, 
				"td: %s, cap: %s\n", td_sinful.Value(), td_cap.Value());

			DCTransferD dctd(td_sinful.Value());

			result = dctd.download_job_files(&respad, &errstack);
			if ( !result ) {
				fprintf( stderr, "\n%s\n", errstack.getFullText(true).c_str() );
				fprintf( stderr, "ERROR: Failed to spool job files.\n" );
				exit(1);
			}

			} // end block
		break;

		default:
			EXCEPT("PROGRAMMER ERROR: st_method must be known.");
			break;
		}

	// All done
	return 0;
}
Exemple #9
0
void
BaseShadow::baseInit( ClassAd *job_ad, const char* schedd_addr, const char *xfer_queue_contact_info )
{
	int pending = FALSE;

	if( ! job_ad ) {
		EXCEPT("baseInit() called with NULL job_ad!");
	}
	jobAd = job_ad;

	if (sendUpdatesToSchedd && ! is_valid_sinful(schedd_addr)) {
		EXCEPT("schedd_addr not specified with valid address");
	}
	scheddAddr = sendUpdatesToSchedd ? strdup( schedd_addr ) : strdup("noschedd");

	m_xfer_queue_contact_info = xfer_queue_contact_info;

	if ( !jobAd->LookupString(ATTR_OWNER, owner)) {
		EXCEPT("Job ad doesn't contain an %s attribute.", ATTR_OWNER);
	}

	if( !jobAd->LookupInteger(ATTR_CLUSTER_ID, cluster)) {
		EXCEPT("Job ad doesn't contain a %s attribute.", ATTR_CLUSTER_ID);
	}

	if( !jobAd->LookupInteger(ATTR_PROC_ID, proc)) {
		EXCEPT("Job ad doesn't contain a %s attribute.", ATTR_PROC_ID);
	}


		// Grab the GlobalJobId if we've got it.
	if( ! jobAd->LookupString(ATTR_GLOBAL_JOB_ID, &gjid) ) {
		gjid = NULL;
	}

	// grab the NT domain if we've got it
	jobAd->LookupString(ATTR_NT_DOMAIN, domain);
	if ( !jobAd->LookupString(ATTR_JOB_IWD, iwd)) {
		EXCEPT("Job ad doesn't contain an %s attribute.", ATTR_JOB_IWD);
	}

	if( !jobAd->LookupFloat(ATTR_BYTES_SENT, prev_run_bytes_sent) ) {
		prev_run_bytes_sent = 0;
	}
	if( !jobAd->LookupFloat(ATTR_BYTES_RECVD, prev_run_bytes_recvd) ) {
		prev_run_bytes_recvd = 0;
	}

		// construct the core file name we'd get if we had one.
	MyString tmp_name = iwd;
	tmp_name += DIR_DELIM_CHAR;
	tmp_name += "core.";
	tmp_name += cluster;
	tmp_name += '.';
	tmp_name += proc;
	core_file_name = strdup( tmp_name.Value() );

        // put the shadow's sinful string into the jobAd.  Helpful for
        // the mpi shadow, at least...and a good idea in general.
	MyString tmp_addr = ATTR_MY_ADDRESS;
	tmp_addr += "=\"";
	tmp_addr += daemonCore->InfoCommandSinfulString();
	tmp_addr += '"';
    if ( !jobAd->Insert( tmp_addr.Value() )) {
        EXCEPT( "Failed to insert %s!", ATTR_MY_ADDRESS );
    }

	DebugId = display_dprintf_header;
	
	config();

		// Make sure we've got enough swap space to run
	checkSwap();

	// handle system calls with Owner's privilege
// XXX this belong here?  We'll see...
	// Calling init_user_ids() while in user priv causes badness.
	// Make sure we're in another priv state.
	set_condor_priv();
	if ( !init_user_ids(owner.Value(), domain.Value())) {
		dprintf(D_ALWAYS, "init_user_ids() failed as user %s\n",owner.Value() );
		// uids.C will EXCEPT when we set_user_priv() now
		// so there's not much we can do at this point
		
#if ! defined(WIN32)
		if ( param_boolean( "SHADOW_RUN_UNKNOWN_USER_JOBS", false ) )
		{
			dprintf(D_ALWAYS, "trying init_user_ids() as user nobody\n" );
			
			owner="nobody";
			domain=NULL;
			if (!init_user_ids(owner.Value(), domain.Value()))
			{
				dprintf(D_ALWAYS, "init_user_ids() failed!\n");
			}
			else
			{
				jobAd->Assign( ATTR_JOB_RUNAS_OWNER, "FALSE" );
				m_RunAsNobody=true;
				dprintf(D_ALWAYS, "init_user_ids() now running as user nobody\n");
			}
		}
#endif

	}
	set_user_priv();
	daemonCore->Register_Priv_State( PRIV_USER );

	dumpClassad( "BaseShadow::baseInit()", this->jobAd, D_JOB );

		// initialize the UserPolicy object
	shadow_user_policy.init( jobAd, this );

		// setup an object to keep our job ad updated to the schedd's
		// permanent job queue.  this clears all the dirty bits on our
		// copy of the classad, so anything we touch after this will
		// be updated to the schedd when appropriate.

		// Unless we got a command line arg asking us not to
	if (sendUpdatesToSchedd) {
		// the usual case
		job_updater = new QmgrJobUpdater( jobAd, scheddAddr, CondorVersion() );
	} else {
		job_updater = new NullQmgrJobUpdater( jobAd, scheddAddr, CondorVersion() );
	}

		// init user log; hold on failure
		// NOTE: job_updater must be initialized _before_ initUserLog(),
		// in order to handle the case of the job going on hold as a
		// result of failure in initUserLog().
	initUserLog();

		// change directory; hold on failure
	if ( cdToIwd() == -1 ) {
		EXCEPT("Could not cd to initial working directory");
	}

		// check to see if this invocation of the shadow is just to write
		// a terminate event and exit since this job had been recorded as
		// pending termination, but somehow the job didn't leave the queue
		// and the schedd is trying to restart it again..
	if( jobAd->LookupInteger(ATTR_TERMINATION_PENDING, pending)) {
		if (pending == TRUE) {
			// If the classad of this job "thinks" that this job should be
			// finished already, let's enact that belief.
			// This function does not return.
			this->terminateJob(US_TERMINATE_PENDING);
		}
	}

		// If we need to claim the startd before activating the claim
	int wantClaiming = 0;
	jobAd->LookupBool(ATTR_CLAIM_STARTD, wantClaiming);
	if (wantClaiming) {
		MyString startdSinful;
		MyString claimid;

			// Pull startd addr and claimid out of the jobad
		jobAd->LookupString(ATTR_STARTD_IP_ADDR, startdSinful);
		jobAd->LookupString(ATTR_CLAIM_ID, claimid);

		dprintf(D_ALWAYS, "%s is true, trying to claim startd %s\n", ATTR_CLAIM_STARTD, startdSinful.Value());

		classy_counted_ptr<DCStartd> startd = new DCStartd("description", NULL, startdSinful.Value(), claimid.Value());
	
		classy_counted_ptr<DCMsgCallback> cb = 
			new DCMsgCallback((DCMsgCallback::CppFunction)&BaseShadow::startdClaimedCB,
			this, jobAd);
																 
			// this can't fail, will always call the callback
		startd->asyncRequestOpportunisticClaim(jobAd, 
											   "description", 
											   daemonCore->InfoCommandSinfulString(), 
											   1200 /*alive interval*/, 
											   20 /* net timeout*/, 
											   100 /*total timeout*/, 
											   cb);
	}
}
Exemple #10
0
void
parseArgv( int  /*argc*/, char* argv[] )
{
	char** tmp = argv;

	for( tmp++; *tmp; tmp++ ) {
		if( (*tmp)[0] != '-' ) {
				// If it doesn't start with '-', skip it
			continue;
		}
		switch( (*tmp)[1] ) {

				// // // // // // // // // // // // // // // //
				// Shared options that make sense to all cmds 
				// // // // // // // // // // // // // // // //

		case 'v':
			if( strncmp("-version", *tmp, strlen(*tmp)) ) {
				invalid( *tmp );
			} 
			version();
			break;

		case 'h':
			if( strncmp("-help", *tmp, strlen(*tmp)) ) {
				invalid( *tmp );
			} 
			usage( my_name, 0);
			break;

		case 'd':
			if( strncmp("-debug", *tmp, strlen(*tmp)) ) {
				invalid( *tmp );
			} 
			dprintf_set_tool_debug("TOOL", 0);
			break;

		case 'a':
			if( cmd != CA_REQUEST_CLAIM ) {
				invalid( *tmp );
			}
			if( strncmp("-address", *tmp, strlen(*tmp)) ) {
				invalid( *tmp );
			} 
			tmp++;
			if( ! (tmp && *tmp) ) {
				another( "-address" );
			}
			if( ! is_valid_sinful(*tmp) ) {
                fprintf( stderr, "%s: '%s' is not a valid address\n",
						 my_name, *tmp );
				exit( 1 );
			}
			if (addr) {
				free(addr);
			}
			addr = strdup( *tmp ); 
			break;

		case 'n':
			if( cmd != CA_REQUEST_CLAIM ) {
				invalid( *tmp );
			}
			if( strncmp("-name", *tmp, strlen(*tmp)) ) {
				invalid( *tmp );
			} 
			tmp++;
			if( ! (tmp && *tmp) ) {
				another( "-name" );
			}
			if (name) {
				free(name);
			}
			name = get_daemon_name( *tmp );
			if( ! name ) {
                fprintf( stderr, "%s: unknown host %s\n", my_name, 
                         get_host_part(*tmp) );
				exit( 1 );
			}
			break;

				// // // // // // // // // // // // // // // //
				// Switches that only make sense to some cmds 
				// // // // // // // // // // // // // // // //

		case 'f':
			if( !((cmd == CA_RELEASE_CLAIM) || 
				  (cmd == CA_DEACTIVATE_CLAIM)) )
			{
				invalid( *tmp );
			}
			if( strncmp("-fast", *tmp, strlen(*tmp)) ) {
				invalid( *tmp );
			} 
			vacate_type = VACATE_FAST;
			break;

		case 'r':
			if( !((cmd == CA_REQUEST_CLAIM) || 
				  (cmd == CA_ACTIVATE_CLAIM)) )
			{
				invalid( *tmp );
			}
			if( strncmp("-requirements", *tmp, strlen(*tmp)) ) {
				invalid( *tmp );
			} 
			tmp++;
			if( ! (tmp && *tmp) ) {
				another( "-requirements" );
			}
			if (requirements) {
				free(requirements);
			}
			requirements = strdup( *tmp );
			break;

		case 'i':
			if( cmd == CA_REQUEST_CLAIM ) {
				invalid( *tmp );
			}
			if( strncmp("-id", *tmp, strlen(*tmp)) ) {
				invalid( *tmp );
			} 
			tmp++;
			if( ! (tmp && *tmp) ) {
				another( "-id" );
			}
			if (claim_id) {
				free(claim_id);
			}
			claim_id = strdup( *tmp );
			break;

		case 'j':
			if( cmd != CA_ACTIVATE_CLAIM ) {
				invalid( *tmp );
			}
			if( strncmp("-jobad", *tmp, strlen(*tmp)) ) {
				invalid( *tmp );
			} 
			tmp++;
			if( ! (tmp && *tmp) ) {
				another( "-jobad" );
			}
			if (jobad_path) {
				free(jobad_path);
			}
			jobad_path = strdup( *tmp );
			break;

		case 'k':
			if( cmd != CA_ACTIVATE_CLAIM ) {
				invalid( *tmp );
			}
			if( strncmp("-keyword", *tmp, strlen(*tmp)) ) {
				invalid( *tmp );
			} 
			tmp++;
			if( ! (tmp && *tmp) ) {
				another( "-keyword" );
			}
			if (job_keyword) {
				free(job_keyword);
			}
			job_keyword = strdup( *tmp );
			break;

				// // // // // // // // // // // // // // // // // // 
				// P and C are complicated, since they are ambiguous
				// in the case of activate, but not others.  so, they
				// have their own methods to make it easier to
				// understand what the hell's going on. :)
				// // // // // // // // // // // // // // // // // //

		case 'l':
			if( strncmp("-lease", *tmp, strlen(*tmp)) == 0 ) {
				if( cmd != CA_REQUEST_CLAIM ) {
					invalid( *tmp );
				}
				tmp++;
				if( ! (tmp && *tmp) ) {
					another( "-lease" );
				}
				lease_time = atoi( *tmp );
			}
			else {
				invalid( *tmp );
			}
			break;

		case 't':
			if( strncmp("-timeout", *tmp, strlen(*tmp)) ) {
				invalid( *tmp );
			} 
			tmp++;
			if( ! (tmp && *tmp) ) {
				another( "-timeout" );
			}
			timeout = atoi( *tmp );
			break;

	    case 'x':
			if( strncmp("-x509proxy", *tmp, strlen(*tmp)) ) {
				invalid( *tmp );
			} 
			tmp++;
			if( ! (tmp && *tmp) ) {
				another( "-x509proxy" );
			}
			proxy_file = *tmp;
			break;

		case 'p':
			parsePOpt( tmp[0], tmp[1] );
			tmp++;
			break;

		case 'c':
			parseCOpt( tmp[0], tmp[1] );
			tmp++;
			break;

		default:
			invalid( *tmp );

		}
	}

		// Now that we're done parsing, make sure it all makes sense

	if( needs_id && ! claim_id ) {
		fprintf( stderr,  "ERROR: You must specify a ClaimID with "
				 "-id for %s\n", my_name );
		usage( my_name );
	}

	if( addr && name ) {
		fprintf( stderr, 
				 "ERROR: You cannot specify both -name and -address\n" );
		usage( my_name );
	}

	if( addr ) {
		target = addr;
	} else if( name ) {
		target = name;
	} else if( claim_id ) {
			// This is the last resort, because claim ids are
			// no longer considered to be the correct place to
			// get the startd's address.
		target = getAddrFromClaimId( claim_id );
	} else { 
			// local startd
		target = NULL;
	}

	if( cmd == CA_ACTIVATE_CLAIM && ! (job_keyword || jobad_path) ) { 
		fprintf( stderr,
				 "ERROR: You must specify -keyword or -jobad for %s\n",
				 my_name );
		usage( my_name );
	}

	if (cmd == DELEGATE_GSI_CRED_STARTD && !proxy_file) {
		proxy_file = get_x509_proxy_filename();
		if (!proxy_file) {
			fprintf( stderr,
					 "\nERROR: can't determine proxy filename to delegate\n" );
			exit(1);
		}
	}

	if( jobad_path ) {
		if( ! strcmp(jobad_path, "-") ) {
			JOBAD_PATH = stdin;
		} else {
			JOBAD_PATH = safe_fopen_wrapper_follow( jobad_path, "r" );
			if( !JOBAD_PATH ) {
				fprintf( stderr,
						 "ERROR: failed to open '%s': errno %d (%s)\n",
						 jobad_path, errno, strerror(errno) );
				exit( 1 );
			}
		}
	}

	if( classad_path ) { 
		CA_PATH = safe_fopen_wrapper_follow( classad_path, "w" );
		if( !CA_PATH ) {
			fprintf( stderr, 
					 "ERROR: failed to open '%s': errno %d (%s)\n",
					 classad_path, errno, strerror(errno) );
			exit( 1 );
		}
	}
}
Exemple #11
0
void
parseArgs( int argc, char *argv[] )
{
    char *opt;

    char** tmp = argv;
    for( tmp++; *tmp; tmp++ ) {
        opt = tmp[0];

        if( sscanf(opt, "%d.%d", &cluster, &proc) == 2 ) {
            if( cluster < 0 || proc < 0 ) {
                dprintf(D_ALWAYS,
                        "ERROR: invalid cluster.proc specified: %s\n", opt);
                usage(argc, argv);
            }
            continue;
        }

        if( opt[0] == '<' ) {
            // might be the schedd's address
            if( is_valid_sinful(opt)) {
                schedd_addr = opt;
                continue;
            } else {
                dprintf(D_ALWAYS,
                        "ERROR: invalid shadow-private schedd_addr specified: %s\n", opt);
                usage(argc, argv);
            }
        }

        if( !strcmp(opt, "--reconnect") || !strcmp(opt, "-reconnect") ) {
            is_reconnect = true;
            continue;
        }

        if (strncmp(opt, "--schedd", 8) == 0) {
            char *ptr = strchr(opt, '<');
            if (ptr && is_valid_sinful(ptr)) {
                public_schedd_addr = ptr;
                continue;
            }
            else {
                dprintf(D_ALWAYS,
                        "ERROR: invalid public schedd_addr specified: %s\n",
                        opt);
                usage(argc, argv);
            }
        }

        if (strncmp(opt, "--xfer-queue=", 13) == 0) {
            xfer_queue_contact_info = opt+13;
            continue;
        }

        if (strcmp(opt, "--no-schedd-updates") == 0) {
            sendUpdatesToSchedd = false;
            continue;
        }

        // the only other argument we understand is the
        // filename we should read our ClassAd from, "-" for
        // STDIN.  There's no further checking we need to do
        if( job_ad_file ) {
            // already were here, bail out
            dprintf( D_ALWAYS, "ERROR: unrecognized option (%s)\n", opt );
            usage(argc, argv);
        }
        job_ad_file = opt;
    }

    // A proper model of arguments should be presented here and
    // used to validate the provided arguments. It would be
    // something like:
    // if no cluster/proc, who cares
    // if no job_ad_file, fail
    // And that might be it.
    // The validation used to count arguments processed, which was
    // easily fooled.
}
Exemple #12
0
int
main( int argc, char *argv[] )
{
	char	*arg;
	char	**args = (char **)malloc(sizeof(char *)*(argc - 1)); // args 
	int					nArgs = 0;				// number of args 
	int					i;
	char*	cmd_str;
	DCCollector* pool = NULL;
	char* scheddName = NULL;
	char* scheddAddr = NULL;

		// Initialize our global variables
	has_constraint = false;

	myDistro->Init( argc, argv );
	MyName = strrchr( argv[0], DIR_DELIM_CHAR );
	if( !MyName ) {
		MyName = argv[0];
	} else {
		MyName++;
	}

	cmd_str = strchr( MyName, '_');

	// we match modes based on characters after the '_'. This means
	// 'condor_hold.exe' or 'condor_hold_wrapped' are all legal argv[0]'s
	// for condor_hold.

	if (cmd_str && strncasecmp( cmd_str, "_hold", strlen("_hold") ) == MATCH) { 

		mode = JA_HOLD_JOBS;

	} else if ( cmd_str && 
			strncasecmp( cmd_str, "_release", strlen("_release") ) == MATCH ) {

		mode = JA_RELEASE_JOBS;

	} else if ( cmd_str && 
			strncasecmp( cmd_str, "_suspend", strlen("_suspend") ) == MATCH ) {

		mode = JA_SUSPEND_JOBS;

	} else if ( cmd_str && 
			strncasecmp( cmd_str, "_continue", strlen("_continue") ) == MATCH ) {

		mode = JA_CONTINUE_JOBS;

	}else if ( cmd_str && 
			strncasecmp( cmd_str, "_rm", strlen("_rm") ) == MATCH ) {

		mode = JA_REMOVE_JOBS;

	} else if( cmd_str && ! strncasecmp(cmd_str, "_vacate_job",
									strlen("_vacate_job")) ) {  

		mode = JA_VACATE_JOBS;

	} else {
		// don't know what mode we're using, so bail.
		fprintf( stderr, "Unrecognized command name, \"%s\"\n", MyName ); 
		usage();
	}

	config();


	if( argc < 2 ) {
			// We got no indication of what to act on
		fprintf( stderr, "You did not specify any jobs\n" ); 
		usage();
	}

#if !defined(WIN32)
	install_sig_handler(SIGPIPE, SIG_IGN );
#endif

	for( argv++; (arg = *argv); argv++ ) {
		if( arg[0] == '-' ) {
            if (match_prefix(arg, "-debug")) {
				// dprintf to console
				dprintf_set_tool_debug("TOOL", 0);
            } else if (match_prefix(arg, "-constraint")) {
				args[nArgs] = arg;
				nArgs++;
				argv++;
				if( ! *argv ) {
					fprintf( stderr, 
							 "%s: -constraint requires another argument\n", 
							 MyName);
					exit(1);
				}				
				args[nArgs] = *argv;
				nArgs++;
				ConstraintArg = true;
            } else if (match_prefix(arg, "-all")) {
                All = true;
            } else if (match_prefix(arg, "-addr")) {
                argv++;
                if( ! *argv ) {
                    fprintf( stderr, 
                             "%s: -addr requires another argument\n", 
                             MyName);
                    exit(1);
                }				
                if( is_valid_sinful(*argv) ) {
                    scheddAddr = strdup(*argv);
                    if( ! scheddAddr ) {
                        fprintf( stderr, "Out of memory!\n" );
                        exit(1);
                    }
                } else {
                    fprintf( stderr, 
                             "%s: \"%s\" is not a valid address\n",
                             MyName, *argv );
                    fprintf( stderr, "Should be of the form "
                             "<ip.address.here:port>\n" );
                    fprintf( stderr, 
                             "For example: <123.456.789.123:6789>\n" );
                    exit( 1 );
                }
			} else if (match_prefix(arg, "-reason")) {
				argv++;
				if( ! *argv ) {
					fprintf( stderr, 
							 "%s: -reason requires another argument\n", 
							 MyName);
					exit(1);
				}		
				actionReason = strdup(*argv);		
				if( ! actionReason ) {
					fprintf( stderr, "Out of memory!\n" );
					exit(1);
				}
			} else if (match_prefix(arg, "-subcode")) {
				argv++;
				if( ! *argv ) {
					fprintf( stderr, 
							 "%s: -subcode requires another argument\n", 
							 MyName);
					exit(1);
				}		
				char *end = NULL;
				long code = strtol(*argv,&end,10);
				if( code == LONG_MIN || !end || *end || end==*argv ) {
					fprintf( stderr, "Invalid -subcode %s!\n", *argv );
					exit(1);
				}
				holdReasonSubCode = strdup(*argv);
				ASSERT( holdReasonSubCode );
            } else if (match_prefix(arg, "-forcex")) {
				if( mode == JA_REMOVE_JOBS ) {
					mode = JA_REMOVE_X_JOBS;
				} else {
                    fprintf( stderr, 
                             "-forcex is only valid with condor_rm\n" );
					usage();
				}
            } else if (match_prefix(arg, "-fast")) {
				if( mode == JA_VACATE_JOBS ) {
					mode = JA_VACATE_FAST_JOBS;
				} else {
                    fprintf( stderr, 
                             "-fast is only valid with condor_vacate_job\n" );
					usage();
				}
            } else if (match_prefix(arg, "-name")) {
				// use the given name as the schedd name to connect to
				argv++;
				if( ! *argv ) {
					fprintf( stderr, "%s: -name requires another argument\n", 
							 MyName);
					exit(1);
				}				
				if( !(scheddName = get_daemon_name(*argv)) ) { 
					fprintf( stderr, "%s: unknown host %s\n", 
							 MyName, get_host_part(*argv) );
					exit(1);
				}
            } else if (match_prefix(arg, "-pool")) {
				// use the given name as the central manager to query
				argv++;
				if( ! *argv ) {
					fprintf( stderr, "%s: -pool requires another argument\n", 
							 MyName);
					exit(1);
				}				
				if( pool ) {
					delete pool;
				}
				pool = new DCCollector( *argv );
				if( ! pool->addr() ) {
					fprintf( stderr, "%s: %s\n", MyName, pool->error() );
					exit(1);
				}
            } else if (match_prefix(arg, "-version")) {
				version();
            } else if (match_prefix(arg, "-help")) {
				usage(0);
            } else {
				fprintf( stderr, "Unrecognized option: %s\n", arg ); 
				usage();
			}
		} else {
			if( All ) {
					// If -all is set, there should be no other
					// constraint arguments.
				usage();
			}
			args[nArgs] = arg;
			nArgs++;
			UserJobIdArg = true;
		}
	}

	if( ! (All || nArgs) ) {
			// We got no indication of what to act on
		fprintf( stderr, "You did not specify any jobs\n" ); 
		usage();
	}

	if ( ConstraintArg && UserJobIdArg ) {
		fprintf( stderr, "You can't use both -constraint and usernames or job ids\n" );
		usage();
	}

		// Pick the default reason if the user didn't specify one
	if( actionReason == NULL ) {
		switch( mode ) {
		case JA_RELEASE_JOBS:
			actionReason = strdup("via condor_release");
			break;
		case JA_REMOVE_X_JOBS:
			actionReason = strdup("via condor_rm -forcex");
			break;
		case JA_REMOVE_JOBS:
			actionReason = strdup("via condor_rm");
			break;
		case JA_HOLD_JOBS:
			actionReason = strdup("via condor_hold");
			break;
		case JA_SUSPEND_JOBS:
			actionReason = strdup("via condor_suspend");
			break;
		case JA_CONTINUE_JOBS:
			actionReason = strdup("via condor_continue");
			break;
		default:
			actionReason = NULL;
		}
	}

		// We're done parsing args, now make sure we know how to
		// contact the schedd. 
	if( ! scheddAddr ) {
			// This will always do the right thing, even if either or
			// both of scheddName or pool are NULL.
		schedd = new DCSchedd( scheddName, pool ? pool->addr() : NULL );
	} else {
		schedd = new DCSchedd( scheddAddr );
	}
	if( ! schedd->locate() ) {
		fprintf( stderr, "%s: %s\n", MyName, schedd->error() ); 
		exit( 1 );
	}

		// Special case for condor_rm -forcex: a configuration
		// setting can disable this functionality.  The real
		// validation is done in the schedd, but we can catch
		// the most common cases here and give a useful error
		// message.
	if(mode == JA_REMOVE_X_JOBS) {
		if( mayUserForceRm() == false) {
			fprintf( stderr, "Remove aborted. condor_rm -forcex has been disabled by the administrator.\n" );
			exit( 1 );
		}
	}

		// Process the args so we do the work.
	if( All ) {
		handleAll();
	} else {
		for(i = 0; i < nArgs; i++) {
			if( match_prefix( args[i], "-constraint" ) ) {
				i++;
				addConstraint( args[i] );
			} else {
				procArg(args[i]);
			}
		}
	}

		// Deal with all the -constraint constraints
	handleConstraints();

		// Finally, do the actual work for all our args which weren't
		// constraints...
	if( job_ids ) {
		CondorError errstack;
		ClassAd* result_ad = doWorkByList( job_ids, &errstack );
		if (had_error) {
			fprintf( stderr, "%s\n", errstack.getFullText(true).c_str() );
		}
		printNewMessages( result_ad, job_ids );
		delete( result_ad );
	}

		// If releasing jobs, and no errors happened, do a 
		// reschedule command now.
	if ( mode == JA_RELEASE_JOBS && had_error == false ) {
		Daemon  my_schedd(DT_SCHEDD, NULL, NULL);
		CondorError errstack;
		if (!my_schedd.sendCommand(RESCHEDULE, Stream::safe_sock, 0, &errstack)) {
			fprintf( stderr, "%s\n", errstack.getFullText(true).c_str() );
		}
	}

	return had_error;
}