options->identity_files[options->num_identity_files++] = xstrdup(cp);
charptr = (opcode == oIdentityFile) ? &options->identity_files[*intptr] : &options->identity_files2[*intptr]; *charptr = xstrdup(cp); *intptr = *intptr + 1;
process_config_line(Options *options, const char *host,		    char *line, const char *filename, int linenum,		    int *activep){	char buf[256], *cp, *string, **charptr, *cp2;	int opcode, *intptr, value;	u_short fwd_port, fwd_host_port;	/* Skip leading whitespace. */	cp = line + strspn(line, WHITESPACE);	if (!*cp || *cp == '\n' || *cp == '#')		return 0;	/* Get the keyword. (Each line is supposed to begin with a keyword). */	cp = strtok(cp, WHITESPACE);	opcode = parse_token(cp, filename, linenum);	switch (opcode) {	case oBadOption:		/* don't panic, but count bad options */		return -1;		/* NOTREACHED */	case oForwardAgent:		intptr = &options->forward_agent;parse_flag:		cp = strtok(NULL, WHITESPACE);		if (!cp)			fatal("%.200s line %d: Missing yes/no argument.", filename, linenum);		value = 0;	/* To avoid compiler warning... */		if (strcmp(cp, "yes") == 0 || strcmp(cp, "true") == 0)			value = 1;		else if (strcmp(cp, "no") == 0 || strcmp(cp, "false") == 0)			value = 0;		else			fatal("%.200s line %d: Bad yes/no argument.", filename, linenum);		if (*activep && *intptr == -1)			*intptr = value;		break;	case oForwardX11:		intptr = &options->forward_x11;		goto parse_flag;	case oGatewayPorts:		intptr = &options->gateway_ports;		goto parse_flag;	case oUsePrivilegedPort:		intptr = &options->use_privileged_port;		goto parse_flag;	case oRhostsAuthentication:		intptr = &options->rhosts_authentication;		goto parse_flag;	case oPasswordAuthentication:		intptr = &options->password_authentication;		goto parse_flag;	case oRSAAuthentication:		intptr = &options->rsa_authentication;		goto parse_flag;	case oRhostsRSAAuthentication:		intptr = &options->rhosts_rsa_authentication;		goto parse_flag;	case oTISAuthentication:		/* fallthrough, there is no difference on the client side */	case oSkeyAuthentication:		intptr = &options->skey_authentication;		goto parse_flag;#ifdef KRB4	case oKerberosAuthentication:		intptr = &options->kerberos_authentication;		goto parse_flag;#endif /* KRB4 */#ifdef AFS	case oKerberosTgtPassing:		intptr = &options->kerberos_tgt_passing;		goto parse_flag;	case oAFSTokenPassing:		intptr = &options->afs_token_passing;		goto parse_flag;#endif	case oFallBackToRsh:		intptr = &options->fallback_to_rsh;		goto parse_flag;	case oUseRsh:		intptr = &options->use_rsh;		goto parse_flag;	case oBatchMode:		intptr = &options->batch_mode;		goto parse_flag;	case oCheckHostIP:		intptr = &options->check_host_ip;		goto parse_flag;	case oStrictHostKeyChecking:		intptr = &options->strict_host_key_checking;		cp = strtok(NULL, WHITESPACE);		if (!cp)			fatal("%.200s line %d: Missing yes/no argument.",			      filename, linenum);		value = 0;	/* To avoid compiler warning... */		if (strcmp(cp, "yes") == 0 || strcmp(cp, "true") == 0)			value = 1;		else if (strcmp(cp, "no") == 0 || strcmp(cp, "false") == 0)			value = 0;		else if (strcmp(cp, "ask") == 0)			value = 2;		else			fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum);		if (*activep && *intptr == -1)			*intptr = value;		break;	case oCompression:		intptr = &options->compression;		goto parse_flag;	case oKeepAlives:		intptr = &options->keepalives;		goto parse_flag;	case oNumberOfPasswordPrompts:		intptr = &options->number_of_password_prompts;		goto parse_int;	case oCompressionLevel:		intptr = &options->compression_level;		goto parse_int;	case oIdentityFile:		cp = strtok(NULL, WHITESPACE);		if (!cp)			fatal("%.200s line %d: Missing argument.", filename, linenum);		if (*activep) {			if (options->num_identity_files >= SSH_MAX_IDENTITY_FILES)				fatal("%.200s line %d: Too many identity files specified (max %d).",				      filename, linenum, SSH_MAX_IDENTITY_FILES);			options->identity_files[options->num_identity_files++] = xstrdup(cp);		}		break;	case oUser:		charptr = &options->user;parse_string:		cp = strtok(NULL, WHITESPACE);		if (!cp)			fatal("%.200s line %d: Missing argument.", filename, linenum);		if (*activep && *charptr == NULL)			*charptr = xstrdup(cp);		break;	case oGlobalKnownHostsFile:		charptr = &options->system_hostfile;		goto parse_string;	case oUserKnownHostsFile:		charptr = &options->user_hostfile;		goto parse_string;	case oHostName:		charptr = &options->hostname;		goto parse_string;	case oProxyCommand:		charptr = &options->proxy_command;		string = xstrdup("");		while ((cp = strtok(NULL, WHITESPACE)) != NULL) {			string = xrealloc(string, strlen(string) + strlen(cp) + 2);			strcat(string, " ");			strcat(string, cp);		}		if (*activep && *charptr == NULL)			*charptr = string;		else			xfree(string);		return 0;	case oPort:		intptr = &options->port;parse_int:		cp = strtok(NULL, WHITESPACE);		if (!cp)			fatal("%.200s line %d: Missing argument.", filename, linenum);		if (cp[0] < '0' || cp[0] > '9')			fatal("%.200s line %d: Bad number.", filename, linenum);		/* Octal, decimal, or hex format? */		value = strtol(cp, &cp2, 0);		if (cp == cp2)			fatal("%.200s line %d: Bad number.", filename, linenum);		if (*activep && *intptr == -1)			*intptr = value;		break;	case oConnectionAttempts:		intptr = &options->connection_attempts;		goto parse_int;	case oCipher:		intptr = &options->cipher;		cp = strtok(NULL, WHITESPACE);		value = cipher_number(cp);		if (value == -1)			fatal("%.200s line %d: Bad cipher '%s'.",			      filename, linenum, cp ? cp : "<NONE>");		if (*activep && *intptr == -1)			*intptr = value;		break;	case oCiphers:		cp = strtok(NULL, WHITESPACE);		if (!ciphers_valid(cp))			fatal("%.200s line %d: Bad cipher spec '%s'.",			      filename, linenum, cp ? cp : "<NONE>");		if (*activep && options->ciphers == NULL)			options->ciphers = xstrdup(cp);		break;	case oProtocol:		intptr = &options->protocol;		cp = strtok(NULL, WHITESPACE);		value = proto_spec(cp);		if (value == SSH_PROTO_UNKNOWN)			fatal("%.200s line %d: Bad protocol spec '%s'.",			      filename, linenum, cp ? cp : "<NONE>");		if (*activep && *intptr == SSH_PROTO_UNKNOWN)			*intptr = value;		break;	case oLogLevel:		intptr = (int *) &options->log_level;		cp = strtok(NULL, WHITESPACE);		value = log_level_number(cp);		if (value == (LogLevel) - 1)			fatal("%.200s line %d: unsupported log level '%s'\n",			      filename, linenum, cp ? cp : "<NONE>");		if (*activep && (LogLevel) * intptr == -1)			*intptr = (LogLevel) value;		break;	case oRemoteForward:		cp = strtok(NULL, WHITESPACE);		if (!cp)			fatal("%.200s line %d: Missing argument.", filename, linenum);		if (cp[0] < '0' || cp[0] > '9')			fatal("%.200s line %d: Badly formatted port number.",			      filename, linenum);		fwd_port = atoi(cp);		cp = strtok(NULL, WHITESPACE);		if (!cp)			fatal("%.200s line %d: Missing second argument.",			      filename, linenum);		if (sscanf(cp, "%255[^:]:%hu", buf, &fwd_host_port) != 2)			fatal("%.200s line %d: Badly formatted host:port.",			      filename, linenum);		if (*activep)			add_remote_forward(options, fwd_port, buf, fwd_host_port);		break;	case oLocalForward:		cp = strtok(NULL, WHITESPACE);		if (!cp)			fatal("%.200s line %d: Missing argument.", filename, linenum);		if (cp[0] < '0' || cp[0] > '9')			fatal("%.200s line %d: Badly formatted port number.",			      filename, linenum);		fwd_port = atoi(cp);		cp = strtok(NULL, WHITESPACE);		if (!cp)			fatal("%.200s line %d: Missing second argument.",			      filename, linenum);		if (sscanf(cp, "%255[^:]:%hu", buf, &fwd_host_port) != 2)			fatal("%.200s line %d: Badly formatted host:port.",			      filename, linenum);		if (*activep)			add_local_forward(options, fwd_port, buf, fwd_host_port);		break;	case oHost:		*activep = 0;		while ((cp = strtok(NULL, WHITESPACE)) != NULL)			if (match_pattern(host, cp)) {				debug("Applying options for %.100s", cp);				*activep = 1;				break;			}		/* Avoid garbage check below, as strtok already returned NULL. */		return 0;	case oEscapeChar:		intptr = &options->escape_char;		cp = strtok(NULL, WHITESPACE);		if (!cp)			fatal("%.200s line %d: Missing argument.", filename, linenum);		if (cp[0] == '^' && cp[2] == 0 &&		    (unsigned char) cp[1] >= 64 && (unsigned char) cp[1] < 128)			value = (unsigned char) cp[1] & 31;		else if (strlen(cp) == 1)			value = (unsigned char) cp[0];		else if (strcmp(cp, "none") == 0)			value = -2;		else {			fatal("%.200s line %d: Bad escape character.",			      filename, linenum);			/* NOTREACHED */			value = 0;	/* Avoid compiler warning. */		}		if (*activep && *intptr == -1)			*intptr = value;		break;	default:		fatal("process_config_line: Unimplemented opcode %d", opcode);	}	/* Check that there is no garbage at end of line. */	if (strtok(NULL, WHITESPACE) != NULL)		fatal("%.200s line %d: garbage at end of line.",		      filename, linenum);	return 0;}