printf("hitting cache for `%s'\n", str);
cvsroot_parse(const char *str){	u_int i;	char *cp, *sp, *pp;	void *tmp;	struct cvsroot *root;	for (i = 0; i < cvs_rcsz; i++) {		if (strcmp(str, cvs_rcache[i]->cr_str) == 0) {			printf("hitting cache for `%s'\n", str);			cvs_rcache[i]->cr_ref++;			return (cvs_rcache[i]);		}	}	root = (struct cvsroot *)malloc(sizeof(*root));	if (root == NULL) {		cvs_log(LP_ERRNO, "failed to allocate CVS root data");		return (NULL);	}	memset(root, 0, sizeof(*root));	root->cr_ref = 2;	root->cr_method = CVS_METHOD_NONE;	root->cr_str = strdup(str);	if (root->cr_str == NULL) {		free(root);		return (NULL);	}	root->cr_buf = strdup(str);	if (root->cr_buf == NULL) {		cvs_log(LP_ERRNO, "failed to copy CVS root");		cvsroot_free(root);		return (NULL);	}	sp = root->cr_buf;	cp = root->cr_buf;	if (*sp == ':') {		sp++;		cp = strchr(sp, ':');		if (cp == NULL) {			cvs_log(LP_ERR, "failed to parse CVSROOT: "			    "unterminated method");			cvsroot_free(root);			return (NULL);		}		*(cp++) = '\0';		for (i = 0; i < CVS_NBMETHODS; i++) {			if (strcmp(sp, cvs_methods[i]) == 0) {				root->cr_method = i;				break;			}		}	}	/* find the start of the actual path */	sp = strchr(cp, '/');	if (sp == NULL) {		cvs_log(LP_ERR, "no path specification in CVSROOT");		cvsroot_free(root);		return (NULL);	}	root->cr_dir = sp;	if (sp == cp) {		if (root->cr_method == CVS_METHOD_NONE)			root->cr_method = CVS_METHOD_LOCAL;		/* stop here, it's just a path */		return (root);	}	if (*(sp - 1) != ':') {		cvs_log(LP_ERR, "missing host/path delimiter in CVS root");		cvsroot_free(root);		return (NULL);	}	*(sp - 1) = '\0';	/*	 * looks like we have more than just a directory path, so	 * attempt to split it into user and host parts	 */	sp = strchr(cp, '@');	if (sp != NULL) {		*(sp++) = '\0';		/* password ? */		pp = strchr(cp, ':');		if (pp != NULL) {			*(pp++) = '\0';			root->cr_pass = pp;		}		root->cr_user = cp;	}	pp = strchr(sp, ':');	if (pp != NULL) {		*(pp++) = '\0';		root->cr_port = (u_int)strtol(pp, &cp, 10);		if (*cp != '\0' || root->cr_port > 65535) {			cvs_log(LP_ERR,			    "invalid port specification in CVSROOT");			cvsroot_free(root);			return (NULL);		}	}	root->cr_host = sp;	if (root->cr_method == CVS_METHOD_NONE) {		/* no method found from start of CVSROOT, guess */		if (root->cr_host != NULL)			root->cr_method = CVS_METHOD_SERVER;		else			root->cr_method = CVS_METHOD_LOCAL;	}	/* add to the cache */	tmp = realloc(cvs_rcache, (cvs_rcsz + 1) * sizeof(struct cvsroot *));	if (tmp == NULL) {		/* just forget about the cache and return anyways */		root->cr_ref--;	}	else {		cvs_rcache = (struct cvsroot **)tmp;		cvs_rcache[cvs_rcsz++] = root;	}	return (root);}