示例#1
0
void user_daemon_t::log(const char *format, ...)
{
	char buf[0x100];
	va_list ap;

	va_start(ap, format);
	vsnprintf(buf, sizeof(buf), format, ap);
	va_end(ap);

	co_terminal_print("%s: %s", get_daemon_name(), buf);
}
示例#2
0
void user_daemon_t::syntax()
{
	co_terminal_print("Cooperative Linux %s\n", get_daemon_title());
	co_terminal_print("Dan Aloni, 2004 (c)\n");
	co_terminal_print("\n");
	co_terminal_print("syntax: \n");
	co_terminal_print("\n");
	co_terminal_print("  %s -i pid -u unit_index %s\n", get_daemon_name(), get_extended_syntax());
	co_terminal_print("\n");
	co_terminal_print("    -i pid          coLinux instance ID to connect to\n");
	co_terminal_print("    -u unit_index   Network device index number (e.g, 0 for eth0, 1 for\n");
	co_terminal_print("                    eth1, etc.)\n");
}
示例#3
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 );
		}
	}
}
示例#4
0
int
main(int argc, char* argv[])
{
  Collectors = NULL;

  HistorySnapshot *historySnapshot;
  SQLQuery queryhor;
  SQLQuery queryver;
  QuillErrCode st;

  void **parameters;
  char *dbconn=NULL;
  bool readfromfile = false,remotequill=false;

  char *dbIpAddr=NULL, *dbName=NULL,*queryPassword=NULL,*quillName=NULL;

  AttrList *ad=0;

  int flag = 1;

  MyString tmp;

  int i;
  parameters = (void **) malloc(NUM_PARAMETERS * sizeof(void *));
  myDistro->Init( argc, argv );

  queryhor.setQuery(HISTORY_ALL_HOR, NULL);
  queryver.setQuery(HISTORY_ALL_VER, NULL);

  longformat=TRUE;   
  for(i=1; i<argc; i++) {
    if(strcmp(argv[i], "-name")==0) {
		i++;
		if (argc <= i) {
			fprintf( stderr,
					 "Error: Argument -name requires the name of a quilld as a parameter\n" );
			exit(1);
		}
		
		if( !(quillName = get_daemon_name(argv[i])) ) {
			fprintf( stderr, "Error: unknown host %s\n",
					 get_host_part(argv[i]) );
			printf("\n");
			print_wrapped_text("Extra Info: The name given with the -name "
							   "should be the name of a condor_quilld process. "
							   "Normally it is either a hostname, or "
							   "\"name@hostname\". "
							   "In either case, the hostname should be the "
							   "Internet host name, but it appears that it "
							   "wasn't.",
							   stderr);
			exit(1);
		}
		tmp.sprintf ("%s == \"%s\"", ATTR_NAME, quillName);      		
		quillQuery.addORConstraint (tmp.Value());

                tmp.sprintf ("%s == \"%s\"", ATTR_SCHEDD_NAME, quillName);
                quillQuery.addORConstraint (tmp.Value());

		remotequill = true;
		readfromfile = false;
    }
    else if (strcmp(argv[i],"-help")==0) {
		Usage(argv[0],0);
    }
  }
  if (i<argc) Usage(argv[0]);
  
  config();
  
	/* This call must happen AFTER config() is called */
  if (checkDBconfig() == true && !readfromfile) {
  	readfromfile = false;
  } else {
		  /* couldn't get DB configuration, so bail out */
    printf("Error: Cannot use DB to get history information\n");
  	exit(1);
  }

  if(readfromfile == false) {
	  if(remotequill) {
		  if (Collectors == NULL) {
			  Collectors = CollectorList::create();
			  if(Collectors == NULL ) {
				  printf("Error: Unable to get list of known collectors\n");
				  exit(1);
			  }
		  }
		  result = Collectors->query ( quillQuery, quillList );
		  if(result != Q_OK) {
			  printf("Fatal Error querying collectors\n");
			  exit(1);
		  }

		  if(quillList.MyLength() == 0) {
			  printf("Error: Unknown quill server %s\n", quillName);
			  exit(1);
		  }
		  
		  quillList.Open();
		  while ((ad = quillList.Next())) {
				  // get the address of the database
			  dbIpAddr = dbName = queryPassword = NULL;
			  if (!ad->LookupString(ATTR_QUILL_DB_IP_ADDR, &dbIpAddr) ||
				  !ad->LookupString(ATTR_QUILL_DB_NAME, &dbName) ||
				  !ad->LookupString(ATTR_QUILL_DB_QUERY_PASSWORD, &queryPassword) || 
				  (ad->LookupBool(ATTR_QUILL_IS_REMOTELY_QUERYABLE,flag) && !flag)) {
				  printf("Error: The quill daemon \"%s\" is not set up "
						 "for database queries\n", 
						 quillName);
				  exit(1);
			  }
		  }
	  }
	  dbconn = getDBConnStr(quillName,dbIpAddr,dbName,queryPassword);
	  historySnapshot = new HistorySnapshot(dbconn);
		  //printf ("\n\n-- Quill: %s : %s : %s\n", quillName, dbIpAddr, dbName);
	  
	  st = historySnapshot->sendQuery(&queryhor, &queryver, longformat, true);
		  //if there's a failure here and if we're not posing a query on a 
		  //remote quill daemon, we should instead query the local file
	  if(st == QUILL_FAILURE) {
		  printf( "-- Database at %s not reachable\n", dbIpAddr);
	  }
		  // query history table
	  if (historySnapshot->isHistoryEmpty()) {
		  printf("No historical jobs in the database\n");
	  }
	  historySnapshot->release();
	  delete(historySnapshot);
  }
  
  
  if(parameters) free(parameters);
  if(dbIpAddr) free(dbIpAddr);
  if(dbName) free(dbName);
  if(queryPassword) free(queryPassword);
  if(quillName) free(quillName);
  if(dbconn) free(dbconn);
  return 0;
}
示例#5
0
文件: rm.cpp 项目: emaste/htcondor
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;
}
示例#6
0
bool
parseCommandLine(StoreCredOptions *opts, int argc, char *argv[]) {

    int i;
    param_functions *p_funcs = NULL;
    opts->mode = 0;
    opts->pw[0] = opts->pw[MAX_PASSWORD_LENGTH] = '\0';
    opts->username[0] = opts->username[MAX_PASSWORD_LENGTH] = '\0';
    opts->daemonname = NULL;
    opts->password_file = NULL;;
    opts->help = false;

    bool err = false;
    for (i=1; i<argc && !err; i++) {
        switch(argv[i][0]) {
        case 'a':
        case 'A':	// Add
            if (strcasecmp(argv[i], ADD_CREDENTIAL) == 0) {
                if (!opts->mode) {
                    opts->mode = ADD_MODE;
                }
                else if (opts->mode != ADD_MODE) {
                    fprintf(stderr,
                            "ERROR: exactly one command must be provided\n");
                    usage();
                    err = true;
                }
            } else {
                err = true;
                badCommand(argv[i]);
            }
            break;
        case 'd':
        case 'D':	// Delete
            if (strcasecmp(argv[i], DELETE_CREDENTIAL) == 0) {
                if (!opts->mode) {
                    opts->mode = DELETE_MODE;
                }
                else if (opts->mode != DELETE_MODE) {
                    fprintf(stderr,
                            "ERROR: exactly one command must be provided\n");
                    usage();
                    err = true;
                }
            } else {
                err = true;
                badCommand(argv[i]);
            }
            break;
        case 'q':
        case 'Q':	// tell me if I have anything stored
            if (strcasecmp(argv[i], QUERY_CREDENTIAL) == 0) {
                if (!opts->mode) {
                    opts->mode = QUERY_MODE;
                }
                else if (opts->mode != QUERY_MODE) {
                    fprintf(stderr,
                            "ERROR: exactly one command must be provided\n");
                    usage();
                    err = true;
                }
            } else {
                err = true;
                badCommand(argv[i]);
            }
            break;
#if defined(WIN32)
        case 'c':
        case 'C':	// Config
            if (strcasecmp(argv[i], CONFIG_CREDENTIAL) == 0) {
                if (!opts->mode) {
                    opts->mode = CONFIG_MODE;
                }
                else {
                    fprintf(stderr, "ERROR: exactly one command must be provided\n");
                    usage();
                    err = true;
                }
            } else {
                err = true;
                badCommand(argv[i]);
            }
            break;
#endif
        case '-':
            // various switches
            switch (argv[i][1]) {
            case 'n':
                if (i+1 < argc) {
                    if (opts->daemonname != NULL) {
                        fprintf(stderr, "ERROR: only one '-n' arg my be provided\n");
                        usage();
                        err = true;
                    }
                    else {
                        opts->daemonname = get_daemon_name(argv[i+1]);
                        if (opts->daemonname == NULL) {
                            fprintf(stderr, "ERROR: %s is not a valid daemon name\n",
                                    argv[i+1]);
                            err = true;
                        }
                        i++;
                    }
                } else {
                    err = true;
                    optionNeedsArg(argv[i]);
                }
                break;
            case 'p':
                if (i+1 < argc) {
                    if (opts->pw[0] != '\0') {
                        fprintf(stderr, "ERROR: only one '-p' args may be provided\n");
                        usage();
                        err = true;
                    }
                    else {
                        strncpy(opts->pw, argv[i+1], MAX_PASSWORD_LENGTH);
                        i++;
                    }
                } else {
                    err = true;
                    optionNeedsArg(argv[i]);
                }
                break;
            case 'c':
                if (opts->username[0] != '\0') {
                    fprintf(stderr, "ERROR: only one '-c' or '-u' arg may be provided\n");
                    usage();
                    err = true;
                }
                else {
                    strcpy(opts->username, POOL_PASSWORD_USERNAME);
                }
                break;
            case 'u':
                if (i+1 < argc) {
                    if (opts->username[0] != '\0') {
                        fprintf(stderr, "ERROR: only one of '-s' or '-u' may be provided\n");
                        usage();
                        err = true;
                    }
                    else {
                        strncpy(opts->username, argv[i+1], MAX_PASSWORD_LENGTH);
                        i++;
                        char* at_ptr = strchr(opts->username, '@');
                        // '@' must be in the string, but not the beginning
                        // or end of the string.
                        if (at_ptr == NULL ||
                                at_ptr == opts->username ||
                                at_ptr == opts->username+strlen(opts->username)-1) {
                            fprintf(stderr, "ERROR: Username '%s' is not of "
                                    "the form: account@domain\n", opts->username);
                            usage();
                        }
                    }
                } else {
                    err = true;
                    optionNeedsArg(argv[i]);
                }
                break;
#if !defined(WIN32)
            case 'f':
                if (i+1 >= argc) {
                    err = true;
                    optionNeedsArg(argv[i]);
                }
                opts->password_file = argv[i+1];
                i++;
                opts->mode = ADD_MODE;
                break;
#endif
            case 'd':
                Termlog = 1;
                p_funcs = get_param_functions();
                dprintf_config ("TOOL", p_funcs);
                break;
            case 'h':
                opts->help = true;
                break;
            default:
                err = true;
                badOption(argv[i]);
            }
            break;	// break for case '-'
        default:
            err = true;
            badCommand(argv[i]);
            break;
        }
    }

    return !err;
}