/* * __nis_path * * Given two path strings, *from and *to, work out the list of names * between them. The length of that path and the pointer to the list * of pointers to the name strings are returned to the caller using * path_length and namesp. As the names list is a pointer to a list of * pointers, the caller must pass the address of the pointer to the * pointer to the list of pointers, hence the unusual "char ***" * type. It is the callers responsibility to free **namesp. */ nis_error __nis_path(char *from, char *to, int *path_length, char ***namesp) { int i; int n; int start; int end; int st, dircmp, lastdircmp; char *tfrom = from; char *tto = to; char **names; dircmp = st = nis_dir_cmp(from, to); if (st == BAD_NAME) return (NIS_BADNAME); /* figure out how long path is */ n = 0; if (st == HIGHER_NAME) { while ((dircmp = nis_dir_cmp(from, to)) == HIGHER_NAME) { n++; to = nis_domain_of(to); } if (dircmp != SAME_NAME) { /* Unrecoverable error */ dircmp = BAD_NAME; } } else if (st == LOWER_NAME) { from = nis_domain_of(from); while ((dircmp = nis_dir_cmp(from, to)) == LOWER_NAME) { n++; from = nis_domain_of(from); } if (dircmp != SAME_NAME) { /* Unrecoverable error */ dircmp = BAD_NAME; } n++; /* include actual target */ } else if (st == NOT_SEQUENTIAL) { /* names are not sequential */ from = nis_domain_of(from); while ((dircmp = nis_dir_cmp(from, to)) == NOT_SEQUENTIAL) { n++; from = nis_domain_of(from); } n++; /* include common parent */ lastdircmp = dircmp; /* Handle HIGHER or LOWER */ while ((dircmp = nis_dir_cmp(from, to)) == lastdircmp) { n++; lastdircmp = dircmp; to = nis_domain_of(to); } if (dircmp != SAME_NAME) { /* Unrecoverable error */ dircmp = BAD_NAME; } } if (dircmp == BAD_NAME) { syslog(LOG_WARNING, "__nis_path: Unable to walk " "from %s to %s", tfrom, tto); return (NIS_BADNAME); } names = malloc(n * sizeof (char *)); if (names == NULL) return (NIS_NOMEMORY); start = 0; end = n; from = tfrom; to = tto; /* * Go through again, this time storing names. * We shouldn't need to check the loops will terminate * on the SAME_NAME condition as we've already checked for * errors in the previous loop. */ if (st == HIGHER_NAME) { while (nis_dir_cmp(from, to) != SAME_NAME) { names[--end] = strdup(to); to = nis_domain_of(to); } } else if (st == LOWER_NAME) { from = nis_domain_of(from); while (nis_dir_cmp(from, to) != SAME_NAME) { names[start++] = strdup(from); from = nis_domain_of(from); } names[start++] = strdup(to); /* include actual target */ } else if (st == NOT_SEQUENTIAL) { /* names are not sequential */ from = nis_domain_of(from); while (nis_dir_cmp(from, to) == NOT_SEQUENTIAL) { names[start++] = strdup(from); from = nis_domain_of(from); } names[start++] = strdup(from); /* include common parent */ while (nis_dir_cmp(from, to) != SAME_NAME) { names[--end] = strdup(to); to = nis_domain_of(to); } } /* make sure all of the allocations were successful */ for (i = 0; i < n; i++) { if (names[i] == NULL) { __nis_path_free(names, n); names = NULL; break; } } /* Set the return values */ *path_length = n; *namesp = names; return (NIS_SUCCESS); }
/* * Convert host to network-name * This routine returns following netnames given the host and domain * arguments defined below: (domainname=y.z) * Arguments * host domain netname * ---- ------ ------- * - - [email protected] (hostname=m) * - a.b [email protected] (hostname=m) * - - [email protected] (hostname=m.w.x) * - a.b [email protected] (hostname=m.w.x) * h - [email protected] * h a.b [email protected] * h.w.x - [email protected] * h.w.x a.b [email protected] */ int host2netname(char netname[MAXNETNAMELEN + 1], const char *host, const char *domain) { char *p; char hostname[MAXHOSTNAMELEN + 1]; char domainname[MAXHOSTNAMELEN + 1]; char *dot_in_host; int i; size_t len; netname[0] = '\0'; /* make null first (no need for memset) */ if (host == NULL) { (void) strncpy(hostname, nis_local_host(), sizeof (hostname)); p = (char *)strchr(hostname, '.'); if (p) { *p++ = '\0'; /* if no domain passed, use tail of nis_local_host() */ if (domain == NULL) { domain = p; } } } else { len = strlen(host); if (len >= sizeof (hostname)) { return (0); } (void) strcpy(hostname, host); } dot_in_host = (char *)strchr(hostname, '.'); if (domain == NULL) { p = dot_in_host; if (p) { p = (char *)nis_domain_of(hostname); len = strlen(p); if (len >= sizeof (domainname)) { return (0); } (void) strcpy(domainname, p); } else { domainname[0] = NULL; if (getdomainname(domainname, MAXHOSTNAMELEN) < 0) return (0); } } else { len = strlen(domain); if (len >= sizeof (domainname)) { return (0); } (void) strcpy(domainname, domain); } i = strlen(domainname); if (i == 0) /* No domainname */ return (0); if (domainname[i - 1] == '.') domainname[i - 1] = 0; if (dot_in_host) { /* strip off rest of name */ *dot_in_host = '\0'; } if ((strlen(domainname) + strlen(hostname) + OPSYS_LEN + 3) > (size_t)MAXNETNAMELEN) { return (0); } (void) snprintf(netname, MAXNETNAMELEN + 1, "%s.%s@%s", OPSYS, hostname, domainname); return (1); }