4.3BSD-UWisc/src/usr.etc/ypserv/ypserv_domain.c

Compare this file to the similar file:
Show the results in this format:

#ifndef lint
/* @(#)ypserv_domain.c	2.1 86/04/16 NFSSRC */
static	char sccsid[] = "@(#)ypserv_domain.c 1.1 86/02/05 Copyr 1984 Sun Micro";
#endif

/*
 * This contains all yellow pages server code which knows about and manipulates
 * the server's domain data bases.
 */

#include "ypsym.h"

struct domain_list_item *ypdomains_known = NULL;


/*
 * Loads the runtime list of domains served. The elements on the list of 
 * known domains pointed to by global cell ypdomains_known will be have the
 * dom_supported field set TRUE for each supported domain.
 */
void
ypget_supported_domains()
{
	DIR *dirp;
	struct direct *dp;
	char path[MAXNAMLEN + 1];
	struct stat filestat;
	bool found;
	struct domain_list_item *pdom;

	if ( (dirp = opendir(ypdbpath) ) == NULL) {
		fprintf(stderr, "ypserv:  ypget_supported_domains can't open yp data base directory.\n");
		return;
	}

	/*
	 * For each directory entry, stat the associated file.  If the file is a
	 * directory, check the list of known domains, and, if found, mark the
	 * domain as supported.  Directories "." and ".." will be filtered out,
	 * therefore aren't valid domain names.  Directories which are not on
	 * the list of known domains will be skipped.  Domains which are already
	 * supported will be skipped in this pass.  Domains which contain at
	 * least the map of maps in this domain (ypmaps at the time of this
	 * writing) will be marked as supported.  In addition, a check for the
	 * map of peer servers (ypservers) and the mapping of host names to
	 * IP addresses (hosts.byname) will be made.  Map list entries will be
	 * made for each of the required/desired maps.
	 */

	for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp) ) {
		strcpy(path, ypdbpath);
		strcat(path, "/");
		strcat(path, dp->d_name);

		if (stat(path, &filestat) != -1) {

			if ( (filestat.st_mode & S_IFDIR) &&
			    (strcmp(dp->d_name, ".") ) &&
			    (strcmp(dp->d_name, "..") ) ) {

				if (pdom = yppoint_at_domain(dp->d_name) ) {

					if (pdom->dom_supported) {
						continue;
					}

					/*
					 * Provisionally say the domain's
					 * supported, then check to see if the
					 * required maps did get supported and
					 * decide on a real status for the
					 * domain.
					 */

					pdom->dom_supported = TRUE;
					(void) ypadd_named_map(YPMAPS, pdom);
					(void) ypadd_named_map(YPSERVERS, pdom);
					(void) ypadd_named_map(YPHOSTS_BYNAME, pdom);

					if (!ypcheck_map(YPMAPS, pdom->dom_name) ) {
						pdom->dom_supported = FALSE;
					}
				}
			}

		} else {
			fprintf(stderr, "ypserv:  ypget_supported_domains can't stat domain file %s.\n",
			     dp->d_name);
		}
	}
	closedir(dirp);
}

/*
 * This returns a pointer to the domain_list_item associated with a named
 * domain, or NULL.
 */
struct domain_list_item *
yppoint_at_domain(pname)
	char *pname;
{
	int len;
	struct domain_list_item *plist;

	if ( (pname == (char *) NULL) || ( (len = strlen(pname) ) == 0) ||
	    (len > YPMAXDOMAIN) ) {
		return( (struct domain_list_item *) NULL);
	}

	for  (plist= ypdomains_known; plist != NULL; plist= plist->dom_pnext) {

		if (strcmp(plist->dom_name, pname) == 0) {
			return(plist);
		}
	}

	return( (struct domain_list_item *) NULL);

}

/*
 * This checks to see if a domain is supported.  
 */
struct domain_list_item *
ypcheck_domain(pname)
	char *pname;
{
	int len;
	struct domain_list_item *pdom;

	if (!pname || ((len = strlen(pname)) == 0) || (len > YPMAXDOMAIN) ) {
		return( (struct domain_list_item *) NULL);
	}

	if ( ( (pdom = yppoint_at_domain(pname) ) !=
	    (struct domain_list_item *) NULL) &&
	    (pdom->dom_supported == TRUE) ) {
		return(pdom);
	} else {
		return( (struct domain_list_item *) NULL);
	}

}

/*
 * This points at the first domain_list_item in the list of known domains, or
 * NULL if there are none.  If parameter supportedis TRUE, return the first
 * supported domain; else the first whether or not it is supported.
 */
struct domain_list_item *
yppoint_at_first_domain(supported)
	bool supported;
{
	struct domain_list_item *pdom;

	pdom = ypdomains_known;

	if (! supported) {
		return(pdom);
	}

	while ( (pdom != (struct domain_list_item *) NULL) &&
	    (pdom->dom_supported == FALSE) ) {
		pdom = pdom->dom_pnext;
	}

	return(pdom);
}

/*
 * This points at the next domain_list_item in the list of known domains, or
 * NULL if there are none.
 */
struct domain_list_item *
yppoint_at_next_domain(pcurr, supported)
	struct domain_list_item *pcurr;
	bool supported;
{
	struct domain_list_item *pdom;

	if (!pcurr) {
		return( (struct domain_list_item *) NULL);
	}

	pdom = pcurr->dom_pnext;

	if (! supported) {
		return(pdom);
	}

	while ( (pdom != (struct domain_list_item *) NULL) &&
	    (pdom->dom_supported == FALSE) ) {
		pdom = pdom->dom_pnext;
	}

	return(pdom);
}

/*
 * This returns a ptr to the list of the maps in a supported domain, or NULL if
 * there are none.
 * 
 * Note:  This will return NULL if there are no maps on the list, or if the
 * domain name is bogus, or if the domain name is real but the domain is
 * unsupported.
 */
struct map_list_item *
yppoint_at_maplist(pdom)
	struct domain_list_item *pdom;
{
	if (pdom) {
		return(pdom->dom_pmaplist);
	} else {
		return( (struct map_list_item *) NULL);
	}
}

/*
 * This returns a ptr to the list of the peers in a supported domain, or NULL
 * if there are none.
 *
 * Note:  This will return NULL if there are no peers on the list, or if the
 * domain name is bogus, or if the domain name is real but the domain is
 * unsupported.
 */
struct peer_list_item *
yppoint_at_peerlist(pdom)
	struct domain_list_item *pdom;
{
	if (pdom) {
		return(pdom->dom_ppeerlist);
	} else {
		return( (struct peer_list_item *) NULL);
	}
}

/*
 * This returns a ptr to the domain name string from aninput domain_list_item
 * pointer.
 */
char *
yppoint_at_domname(pdom)
	struct domain_list_item *pdom;

{
	if (pdom) {
		return(pdom->dom_name);
	} else {
		return( (char *) NULL);
	}
}

/*
 * This builds a list of all known domains, using the map ypdomains in the
 * yp_private domain.
 *
 * Note:  This may be called to	reprocess ypdomains after startup:  new domains
 * will get picked up, existing domains will get marked "in the new map".
 */
bool
ypget_all_domains()
{
	char mapname[YPDBPATH_LENGTH + YPMAXDOMAIN + YPMAXMAP + 3];
	datum key;

	/*
	 * This function MAY NOT use ypset_current_map, which checks to see
	 * if a domain is supported.  Since this function is used in initially
	 * setting up domains, that won't work.
	 */

	ypmkfilename(ypprivate_domain_name, ypdomains, mapname);

	if (ypcheck_map_existence(mapname) ) {

		if (current_map[0] != '\0') {
			dbmclose(current_map);
			current_map[0] = '\0';
		}

		if (dbminit(mapname) >= 0) {

			strcpy(current_map, mapname);

			for (key = firstkey(); key.dptr != (char *) NULL;
			    key = nextkey(key) ) {

				/*
				 * Knock out key-value pairs from the
				 * map file which are yp private symbols.
				 */

				if (key.dsize >= YPSYMBOL_PREFIX_LENGTH &&
				    (!bcmp(key.dptr, YPSYMBOL_PREFIX,
				    YPSYMBOL_PREFIX_LENGTH) ) ) {
					continue;
				}
					
				ypadd_one_domain(&key);
			}
			
		} else {
			fprintf(stderr, "ypserv:  can't dbminit yp domain map.\n");
			return(FALSE);
		}

	} else {
		fprintf(stderr, "ypserv:  yp domain map not present.\n");
		return(FALSE);
	}

	return(TRUE);
}

/*
 * This builds one domain_list_item containing the domain name in the input
 * datum, marks it "not supported", and links it to the list of known domains
 * as the head entry.  If the domain already exists, dom_in_new_map will be set
 * TRUE, and nothing else will be changed.   Errors are reported here, but no
 * value is returned to the caller.  The domain name in field dom_name will be
 * null terminated, so string functions (such as strcmp, strcpy, etc.) may used
 * on the information.
 */
void
ypadd_one_domain(pdatum)
	datum *pdatum;
{
	struct domain_list_item *pnewdomain;
	char dom_name[YPMAXDOMAIN + 1];

	if (!pdatum || pdatum->dsize == 0 || pdatum->dsize > YPMAXDOMAIN ||
	    (pdatum->dptr == (char *) NULL) ) {
		return;
	}

	bcopy(pdatum->dptr, dom_name, pdatum->dsize);
	dom_name[pdatum->dsize] = '\0';

	if (pnewdomain = yppoint_at_domain(dom_name) ) {
		pnewdomain->dom_in_new_map = TRUE;
		return;
	}

	pnewdomain = (struct domain_list_item *)
	    malloc(sizeof(struct domain_list_item) );

	if (pnewdomain != NULL) {
		strcpy(pnewdomain->dom_name, dom_name);
		pnewdomain->dom_supported = FALSE;
		pnewdomain->dom_in_new_map = TRUE;
		pnewdomain->dom_pmaplist = (struct map_list_item *) NULL;
		pnewdomain->dom_ppeerlist = (struct peer_list_item *) NULL;

		/* Add the domain as the head entry */

		pnewdomain->dom_pnext = ypdomains_known;
		ypdomains_known = pnewdomain;
	} else {
		fprintf(stderr, "ypserv:  Can't get memory for a new domain list entry.\n");
	}

}

/*
 * This finds a domain_list_item associated with a passed domain name on the
 * list of known domains, and removes it from the list.  The list will be
 * well-formed after the call if it was before the call, and the memory
 * associated with the domain_list_item, the domain's map list, and the domain's
 * peer list will be returned to the system.
 */
void
ypdel_one_domain(pdomain)
	char *pdomain;
{
	struct domain_list_item *pdom = ypdomains_known;
	struct domain_list_item *trail;

	if (!pdomain || ypdomains_known == (struct domain_list_item *) NULL) {
	    return;
	}

	pingpeer_curr_domain = (struct domain_list_item *) NULL;
	pingmap_curr_domain = (struct domain_list_item *) NULL;

	if ( strcmp(pdom->dom_name, pdomain) == 0) { /* It's the head entry */
		ypdomains_known = pdom->dom_pnext;
		ypdel_domain_lists(pdom);
		free(pdom);
	} else {				/* Not the head entry */
		trail = pdom;
		pdom = pdom->dom_pnext;
		
		while (pdom != (struct domain_list_item *) NULL) {
			    
			if ( strcmp(pdom->dom_name, pdomain) == 0) {
				trail->dom_pnext  = pdom->dom_pnext;
				ypdel_domain_lists(pdom);
				free(pdom);
				break;
			} else {
				trail = pdom;
				pdom = pdom->dom_pnext;
			}
		}
	}
}

/*
 * This deletes the map list and peer list associated with a domain, returning
 * all memory to the system.
 */
void
ypdel_domain_lists(pdom)
	struct domain_list_item *pdom;
{
	struct map_list_item *pmap;
	struct peer_list_item *ppeer;

	if (!pdom) {
		return;
	}

	for (pmap = yppoint_at_maplist(pdom);
	    pmap != (struct map_list_item *) NULL;
	    pmap = yppoint_at_maplist(pdom) ) {
		    ypdel_one_map(pmap);
	    }
	    
	for (ppeer = yppoint_at_peerlist(pdom);
	    ppeer != (struct peer_list_item *) NULL;
	    ppeer = yppoint_at_peerlist(pdom) ) {
		    ypdel_one_peer(ppeer, pdom);
	    }
	    
}