* sufficient, we have to strncmp() anyway.
* sufficient, we have to strncmp() anyway. (We cannot * use strcmp(), because buf is not '\0' terminated.)
static int ssl_cipher_process_rulestr(const char *rule_str,		CIPHER_ORDER *list, CIPHER_ORDER **head_p,		CIPHER_ORDER **tail_p, SSL_CIPHER **ca_list)	{	unsigned long algorithms, mask, algo_strength, mask_strength;	const char *l, *start, *buf;	int j, multi, found, rule, retval, ok, buflen;	char ch;	retval = 1;	l = rule_str;	for (;;)		{		ch = *l;		if (ch == '\0')			break;		/* done */		if (ch == '-')			{ rule = CIPHER_DEL; l++; }		else if (ch == '+')			{ rule = CIPHER_ORD; l++; }		else if (ch == '!')			{ rule = CIPHER_KILL; l++; }		else if (ch == '@')			{ rule = CIPHER_SPECIAL; l++; }		else			{ rule = CIPHER_ADD; }		if (ITEM_SEP(ch))			{			l++;			continue;			}		algorithms = mask = algo_strength = mask_strength = 0;		start=l;		for (;;)			{			ch = *l;			buf = l;			buflen = 0;#ifndef CHARSET_EBCDIC			while (	((ch >= 'A') && (ch <= 'Z')) ||				((ch >= '0') && (ch <= '9')) ||				((ch >= 'a') && (ch <= 'z')) ||				 (ch == '-'))#else			while (	isalnum(ch) || (ch == '-'))#endif				 {				 ch = *(++l);				 buflen++;				 }			if (buflen == 0)				{				/*				 * We hit something we cannot deal with,				 * it is no command or separator nor				 * alphanumeric, so we call this an error.				 */				SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR,				       SSL_R_INVALID_COMMAND);				retval = found = 0;				l++;				break;				}			if (rule == CIPHER_SPECIAL)				{				found = 0; /* unused -- avoid compiler warning */				break;	/* special treatment */				}			/* check for multi-part specification */			if (ch == '+')				{				multi=1;				l++;				}			else				multi=0;			/*			 * Now search for the cipher alias in the ca_list. Be careful			 * with the strncmp, because the "buflen" limitation			 * will make the rule "ADH:SOME" and the cipher			 * "ADH-MY-CIPHER" look like a match for buflen=3.			 * So additionally check whether the cipher name found			 * has the correct length. We can save a strlen() call:			 * just checking for the '\0' at the right place is			 * sufficient, we have to strncmp() anyway.			 */			 j = found = 0;			 while (ca_list[j])				{				if ((ca_list[j]->name[buflen] == '\0') &&				    !strncmp(buf, ca_list[j]->name, buflen))					{					found = 1;					break;					}				else					j++;				}			if (!found)				break;	/* ignore this entry */			algorithms |= ca_list[j]->algorithms;			mask |= ca_list[j]->mask;			algo_strength |= ca_list[j]->algo_strength;			mask_strength |= ca_list[j]->mask_strength;			if (!multi) break;			}		/*		 * Ok, we have the rule, now apply it		 */		if (rule == CIPHER_SPECIAL)			{	/* special command */			ok = 0;			if ((buflen == 8) &&				!strncmp(buf, "STRENGTH", 8))				ok = ssl_cipher_strength_sort(list,					head_p, tail_p);			else				SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR,					SSL_R_INVALID_COMMAND);			if (ok == 0)				retval = 0;			/*			 * We do not support any "multi" options			 * together with "@", so throw away the			 * rest of the command, if any left, until			 * end or ':' is found.			 */			while ((*l != '\0') && ITEM_SEP(*l))				l++;			}		else if (found)			{			ssl_cipher_apply_rule(algorithms, mask,				algo_strength, mask_strength, rule, -1,				list, head_p, tail_p);			}		else			{			while ((*l != '\0') && ITEM_SEP(*l))				l++;			}		if (*l == '\0') break; /* done */		}	return(retval);	}