예제 #1
0
파일: nilib2.c 프로젝트: 9crk/EasyDarwin
ni_status ni2_reapdir(void *domain, char *pathname)
{
    /* destroy a directory if it has nothing but a name */

    ni_status ret;
    ni_id dir;
    ni_namelist nl;

    /* see if the directory exists */
    ret = ni2_pathsearch(domain, &dir, pathname);
    if (ret != NI_OK) return ret;

    /* fetch list of property keys from directory */
    NI_INIT(&nl);
    ret = ni_listprops(domain, &dir, &nl);
    if (ret != NI_OK) {
        return ret;
    }

    /* if more than one property, leave it alone */
    if (nl.ni_namelist_len > 1) {
        ni_namelist_free(&nl);
        return NI_OK;
    }

    /* directory is empty (except for name), delete it */
    ni_namelist_free(&nl);
    return ni2_destroy(domain, pathname);
}
예제 #2
0
파일: nilib2.c 프로젝트: 9crk/EasyDarwin
ni_status ni2_mergedirprop(void *domain, ni_id *dir, const ni_name key, ni_namelist values)
{
    /* mergeprop given a directory rather than a pathname */

    ni_status ret;
    ni_property p;
    ni_namelist nl;
    ni_index where, whereval;
    int i;

    /* need to be talking to the master */
    ni_needwrite(domain, 1);

    /* fetch list of property keys from directory */
    NI_INIT(&nl);
    ret = ni_listprops(domain, dir, &nl);
    if (ret != NI_OK) {
        return ret;
    }

    /* check for existing property with this key */
    where = ni_namelist_match(nl, key);
    ni_namelist_free(&nl);

    /* if property doesn't exist, create it */
    if (where == NI_INDEX_NULL) {
        NI_INIT(&p);
        p.nip_name = ni_name_dup(key);
        p.nip_val = ni_namelist_dup(values);
        ret = ni_createprop(domain, dir, p, NI_INDEX_NULL);
        ni_prop_free(&p);
        return ret;
    }


    /* property exists: replace the existing values */
    /* fetch existing namelist for this property */
    NI_INIT(&nl);
    ret = ni_readprop(domain, dir, where, &nl);
    if (ret != NI_OK) {
        return ret;
    }

    /* merge new values */
    for (i = 0; i < values.ni_namelist_len; i++) {
        whereval = ni_namelist_match(nl, values.ni_namelist_val[i]);
        if (whereval == NI_INDEX_NULL) {
            ni_namelist_insert(&nl, values.ni_namelist_val[i], NI_INDEX_NULL);
        }
    }

    /* write the new list back */
    ret = ni_writeprop(domain, dir, where, nl);
    ni_namelist_free(&nl);
    return ret;
}
예제 #3
0
파일: nilib2.c 프로젝트: 9crk/EasyDarwin
ni_status ni2_destroydirval(void *domain, ni_id *dir, const ni_name key, ni_namelist values)
{
    /* destroyval given a directory rather than a pathname */

    ni_status ret;
    ni_namelist nl;
    ni_index where, whereval;
    int i;

    /* need to be talking to the master */
    ni_needwrite(domain, 1);

    /* fetch list of property keys from directory */
    NI_INIT(&nl);
    ret = ni_listprops(domain, dir, &nl);
    if (ret != NI_OK) {
        return ret;
    }

    /* check for existing property with this key */
    where = ni_namelist_match(nl, key);
    ni_namelist_free(&nl);

    /* if property doesn't exist, nothing to do */
    if (where == NI_INDEX_NULL) {
        return NI_OK;
    }

    /* fetch existing namelist for this property */
    NI_INIT(&nl);
    ret = ni_readprop(domain, dir, where, &nl);
    if (ret != NI_OK) {
        return ret;
    }

    /* delete values */
    for (i = 0; i < values.ni_namelist_len; i++) {
        whereval = ni_namelist_match(nl, values.ni_namelist_val[i]);
        while (whereval != NI_INDEX_NULL) {
            ni_namelist_delete(&nl, whereval);
            whereval = ni_namelist_match(nl, values.ni_namelist_val[i]);
        }
    }

    /* write the new list back */
    ret = ni_writeprop(domain, dir, where, nl);
    ni_namelist_free(&nl);

    return ret;
}
예제 #4
0
int NetInfoPrefsSource::GetValueByIndex(const char* inKey, UInt32 inIndex, char* ioValue)
{
    ni_status status = NI_OK;
    ni_namelist nameList = {};
    void* localDomain = NULL;
    ni_id qtssDir = {}; 
    
    ioValue[0] = '\0';

    status = ni_open(NULL, ".", &localDomain);
    if (status != NI_OK)
        return false;
        
    if (status == NI_OK)
        status = ni_pathsearch(localDomain, &qtssDir, gQTSSPropertiesPath);
        
    if (status == NI_OK)
        status = ni_lookupprop(localDomain, &qtssDir, inKey, &nameList);

    if (status == NI_OK)
    {
        if (nameList.ni_namelist_len > inIndex)
            strcpy(ioValue, nameList.ni_namelist_val[inIndex]);
        else
            status = NI_BADID;
        ni_namelist_free(&nameList);
    }
    
    ni_free(localDomain);
    
    return (status == NI_OK);
}
예제 #5
0
파일: nilib2.c 프로젝트: 9crk/EasyDarwin
ni_status ni2_statpropdir(void *domain, ni_id *dir, const ni_name key, ni_index *where)
{
    /* statprop given a directory rather than a pathname */

    ni_status ret;
    ni_namelist nl;

    /* assume there's no match */
    *where = NI_INDEX_NULL;

    /* fetch list of property keys from directory */
    NI_INIT(&nl);
    ret = ni_listprops(domain, dir, &nl);
    if (ret != NI_OK) {
        return ret;
    }

    /* check for property with this key */
    *where = ni_namelist_match(nl, key);
    ni_namelist_free(&nl);

    /* if property doesn't exist, no match */
    if (*where == NI_INDEX_NULL) {
        return NI_NOPROP;
    }

    return NI_OK;
}
예제 #6
0
파일: nilib2.c 프로젝트: 9crk/EasyDarwin
ni_status ni2_renamedirprop(void *domain, ni_id *dir, const ni_name oldname, const ni_name newname)
{
    /* renameprop given a directory rather than a pathname */

    ni_status ret;
    ni_index where;
    ni_namelist nl;

    /* need to be talking to the master */
    ni_needwrite(domain, 1);

    /* fetch list of property keys from directory */
    NI_INIT(&nl);
    ret = ni_listprops(domain, dir, &nl);
    if (ret != NI_OK) {
        return ret;
    }

    /* look up old name */
    where = ni_namelist_match(nl, oldname);
    ni_namelist_free(&nl);

    /* if it's not there, return an error */
    if (where == NI_INDEX_NULL) {
        return NI_NOPROP;
    }

    return ni_renameprop(domain, dir, where, newname);
}
예제 #7
0
파일: nilib2.c 프로젝트: 9crk/EasyDarwin
ni_status ni2_statvaldir(void *domain, ni_id *dir, const ni_name key, const ni_name value, ni_index *where)
{
    /* statval given a directory rather than a pathname */

    ni_status ret;
    ni_namelist nl;
    ni_index wh;

    /* assume there's no match */
    *where = NI_INDEX_NULL;

    /* fetch list of property keys from directory */
    NI_INIT(&nl);
    ret = ni_listprops(domain, dir, &nl);
    if (ret != NI_OK) {
        return ret;
    }

    /* check for property with this key */
    wh = ni_namelist_match(nl, key);
    ni_namelist_free(&nl);

    /* if property doesn't exist, no match */
    if (wh == NI_INDEX_NULL) {
        return NI_NOPROP;
    }

    /* fetch existing namelist for this property */
    NI_INIT(&nl);
    ret = ni_readprop(domain, dir, wh, &nl);
    if (ret != NI_OK) {
        return ret;
    }

    /* check for this value */
    wh = ni_namelist_match(nl, value);
    ni_namelist_free(&nl);

    /* if value doesn't exist, no match */
    if (wh == NI_INDEX_NULL) {
        return NI_NONAME;
    }

    *where = wh;
    return NI_OK;
}
예제 #8
0
파일: netinfo.c 프로젝트: aosm/bootp
void
ni_prop_free(
	     ni_property *prop
	     )
{
	ni_name_free(&prop->nip_name);
	ni_namelist_free(&prop->nip_val);
}
예제 #9
0
파일: nilib2.c 프로젝트: 9crk/EasyDarwin
ni_status ni2_reappropdir(void *domain, ni_id *dir, const ni_name key)
{
    /* reapprop given a directory rather than a pathname */

    ni_status ret;
    ni_namelist nl;
    ni_index where;

    /* fetch list of property keys from directory */
    NI_INIT(&nl);
    ret = ni_listprops(domain, dir, &nl);
    if (ret != NI_OK) {
        return ret;
    }

    /* check for property with this key */
    where = ni_namelist_match(nl, key);
    ni_namelist_free(&nl);

    /* if property doesn't exist, return */
    if (where == NI_INDEX_NULL) {
        return NI_OK;
    }

    /* fetch existing namelist for this property */
    NI_INIT(&nl);
    ret = ni_readprop(domain, dir, where, &nl);
    if (ret != NI_OK) {
        return ret;
    }

    /* if the property contains any values, leave it alone */
    if (nl.ni_namelist_len > 0) {
        ni_namelist_free(&nl);
        return NI_OK;
    }

    /* property is empty, delete it */
    ni_namelist_free(&nl);
    return ni_destroyprop(domain, dir, where);
}
예제 #10
0
파일: nilib2.c 프로젝트: 9crk/EasyDarwin
ni_status ni2_destroydirprop(void *domain, ni_id *dir, ni_namelist keys)
{
    /* destroyprop given a directory rather than a pathname */

    ni_status ret;
    ni_index where;
    ni_namelist nl;
    int i;

    /* need to be talking to the master */
    ni_needwrite(domain, 1);

    /* fetch list of property keys from directory */
    NI_INIT(&nl);
    ret = ni_listprops(domain, dir, &nl);
    if (ret != NI_OK) {
        return ret;
    }

    /* destroy all occurrences of each key */
    for (i = 0; i < keys.ni_namelist_len; i++) {

        where = ni_namelist_match(nl, keys.ni_namelist_val[i]);

        /* keep looking for all occurrences */
        while (where != NI_INDEX_NULL) {
            ret = ni_destroyprop(domain, dir, where);
            if (ret != NI_OK) {
                ni_namelist_free(&nl);
                return ret;
            }

            /* update the namelist */  
            ni_namelist_delete(&nl, where);
            where = ni_namelist_match(nl, keys.ni_namelist_val[i]);
        }
    }
    ni_namelist_free(&nl);
    return NI_OK;
}
예제 #11
0
void NetInfoPrefsSource::SetValueByIndex(char* inKey, char* inValue, UInt32 inIndex)
{
    void* localDomain = NULL;
    ni_status status = NI_OK;
    ni_namelist nameList = {};

    //ni_namelist_insert(&nameList, (char*)inValue, NI_INDEX_NULL);
    ni_namelist_insert(&nameList, inValue, inIndex);

    status = ni_open(NULL, ".", &localDomain);

    if (status == NI_OK)
    {
        //create the path if it doesn't already exist
        status = ni2_create(localDomain, gQTSSPropertiesPath);

        if (status == NI_OK)
            status = ni2_appendprop(localDomain, gQTSSPropertiesPath, inKey, nameList);
    }
    ni_namelist_free(&nameList);
    ni_free(localDomain);
}
예제 #12
0
파일: nilib2.c 프로젝트: 9crk/EasyDarwin
ni_status ni2_createdirprop(void *domain, ni_id *dir, const ni_name key, ni_namelist values)
{
    /* createprop given a directory rather than a pathname */

    ni_status ret;
    ni_property p;
    ni_namelist nl;
    ni_index where;

    /* need to be talking to the master */
    ni_needwrite(domain, 1);

    /* fetch list of property keys from directory */
    NI_INIT(&nl);
    ret = ni_listprops(domain, dir, &nl);
    if (ret != NI_OK) {
        return ret;
    }

    /* check for existing property with this key */
    where = ni_namelist_match(nl, key);
    ni_namelist_free(&nl);

    /* if property doesn't exist, create it */
    if (where == NI_INDEX_NULL) {
        NI_INIT(&p);
        p.nip_name = ni_name_dup(key);
        p.nip_val = ni_namelist_dup(values);
        ret = ni_createprop(domain, dir, p, NI_INDEX_NULL);
        ni_prop_free(&p);
        return ret;
    }

    /* property exists: replace the existing values */
    ret = ni_writeprop(domain, dir, where, values);
    return ret;
}
예제 #13
0
int
main(int argc, char *argv[])
{
	SVCXPRT *utransp, *ttransp;
	struct sockaddr_in addr;
	DIR *dp;
	struct direct *d;
	ni_name tag = NULL;
	ni_namelist nl;
	ni_index i;
	int pid, localonly, nctoken = -1;
	int log_pri = LOG_NOTICE;
	struct rlimit rlim;
	char *netinfod_argv[16]; /* XXX */
	int netinfod_argc, x;
	union wait wait_stat;
	pid_t child_pid;
	char *pri;
#ifdef _UNIX_BSD_43_
	int ttyfd;
#endif

	localonly = 1;

	netinfod_argc = 0;
	netinfod_argv[netinfod_argc++] = (char *)NETINFO_PROG;

	debug = 0;

	for (i = 1; i < argc; i++)
	{
		if (!strcmp(argv[i], "-n"))
		{
			netinfod_argv[netinfod_argc++] = argv[i];
		}

		if (!strcmp(argv[i], "-d"))
		{
			debug = 1;
			log_pri = LOG_DEBUG;
			if ((argc > (i+1)) && (argv[i+1][0] != '-'))
				debug = atoi(argv[++i]);
		}

		if (!strcmp(argv[i], "-l"))
		{
			if ((argc > (i+1)) && (argv[i+1][0] != '-'))
				log_pri = atoi(argv[++i]);
		}

		if (!strcmp(argv[i], "-D"))
		{
			netinfod_argv[netinfod_argc++] = "-d";

			if ((argc > (i+1)) && (argv[i+1][0] != '-'))
			{
				netinfod_argv[netinfod_argc++] = argv[i];
			}
		}

		if (!strcmp(argv[i], "-L"))
		{
			netinfod_argv[netinfod_argc++] = "-l";

			if ((argc > (i+1)) && (argv[i+1][0] != '-'))
			{
				netinfod_argv[netinfod_argc++] = argv[i];
			}
			else
			{
				pri = malloc(sizeof("999"));
				sprintf(pri, "%d", LOG_DEBUG);
				netinfod_argv[netinfod_argc++] = pri;
			}
		}
	}

	if (debug == 1)
	{
		system_log_open("nibindd", LOG_NDELAY | LOG_PID, LOG_NETINFO, stderr);
		system_log_set_max_priority(log_pri);
		system_log(LOG_DEBUG, "version %s - debug mode\n", _PROJECT_VERSION_);
	}
	else
	{
		closeall();
		system_log_open("nibindd", LOG_NDELAY | LOG_PID, LOG_NETINFO, NULL);
		system_log_set_max_priority(log_pri);
		system_log(LOG_DEBUG, "version %s - starting\n", _PROJECT_VERSION_);

		child_pid = fork();
		if (child_pid == -1)
		{
			system_log(LOG_ALERT, "fork() failed: %m, aborting");
			system_log_close();
			exit(1);
		}
		else if (child_pid > 0)
		{
			signal(SIGTERM, parentexit);
			system_log(LOG_DEBUG, "parent waiting for child to start");
			wait4(child_pid, (_WAIT_TYPE_ *)&wait_stat, 0, 0);

			if (WIFEXITED(wait_stat))
			{
				system_log(LOG_DEBUG,
					"unexpected child exit, status=%d",
					WEXITSTATUS(wait_stat));
			}
			else
			{
				system_log(LOG_DEBUG,
					"unexpected child exit, received signal=%d",
					WTERMSIG(wait_stat));
			}
			system_log_close();
			exit(1);
		}
	}

	restart = 0;

	rlim.rlim_cur = rlim.rlim_max = RLIM_INFINITY;
	setrlimit(RLIMIT_CORE, &rlim);
	signal(SIGCHLD, catchchild);
	signal(SIGTERM, killchildren);
	signal(SIGHUP, catchhup);
	signal(SIGINT, SIG_IGN);

	notify_register_signal(NETWORK_CHANGE_NOTIFICATION, SIGHUP, &nctoken);

	writepid();

	/*
	 * cd to netinfo directory, find out which databases should
	 * be served and lock the directory before registering service.
	 */
	if (chdir(NETINFO_DIR) < 0)
	{
		killparent();
		system_log(LOG_ALERT, "cannot chdir to netinfo directory");
		exit(1);
	}

	dp = opendir(NETINFO_DIR);
	if (dp == NULL)
	{
		killparent();
		system_log(LOG_ALERT, "cannot open netinfo directory");
		exit(1);
	}

	MM_ZERO(&nl);
	while ((d = readdir(dp)))
	{
		if (isnidir(d->d_name, &tag))
		{
			if (ni_namelist_match(nl, tag) == NI_INDEX_NULL)
			{
				system_log(LOG_DEBUG, "found database: %s", tag);
				ni_namelist_insert(&nl, tag, NI_INDEX_NULL);
				if (strcmp(tag, "local")) localonly = 0;
			} 
			ni_name_free(&tag);
		}
	}

#ifdef _NETINFO_FLOCK_
	/*
	 * Do not close the directory: keep it locked so another nibindd
	 * won't run.
	 */
	if (flock(dp->dd_fd, LOCK_EX|LOCK_NB) < 0)
	{
		killparent();
		system_log(LOG_ALERT, "nibindd already running");
		exit(1);
	}
	fcntl(dp->dd_fd, F_SETFD, 1);
#else
	closedir(dp);
#endif

	/*
	 * Register as a SUNRPC service
	 */
	memset(&addr, 0, sizeof(struct sockaddr_in));
	addr.sin_family = AF_INET;
	if (localonly == 1) addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);

	pmap_unset(NIBIND_PROG, NIBIND_VERS);
	utransp = svcudp_bind(RPC_ANYSOCK, addr);
	if (utransp == NULL)
	{
		killparent();
		system_log(LOG_ALERT, "cannot start udp service");
		exit(1);
	}

	if (!svc_register(utransp, NIBIND_PROG, NIBIND_VERS, nibind_prog_1, IPPROTO_UDP))
	{
		killparent();
		system_log(LOG_ALERT, "cannot register udp service");
		exit(1);
	}

	udp_sock = utransp->xp_sock;

	ttransp = svctcp_bind(RPC_ANYSOCK, addr, 0, 0);
	if (ttransp == NULL)
	{
		killparent();
		system_log(LOG_ALERT, "cannot start tcp service");
		exit(1);
	}

	if (!svc_register(ttransp, NIBIND_PROG, NIBIND_VERS, nibind_prog_1, IPPROTO_TCP))
	{
		killparent();
		system_log(LOG_ALERT, "cannot register tcp service");
		exit(1);
	}

	waitreg = 0;
	for (i = 0; i < nl.ninl_len; i++)
	{
		netinfod_argv[netinfod_argc] = nl.ninl_val[i];
		netinfod_argv[netinfod_argc + 1] = NULL;

		system_log(LOG_DEBUG, "starting netinfod %s", nl.ninl_val[i]);
		system_log(LOG_DEBUG, "execv debug 0: %s", NETINFO_PROG);
		for (x = 0; netinfod_argv[x] != NULL; x++)
		{
			system_log(LOG_DEBUG, "execv debug %d: %s", x, netinfod_argv[x]);
		}

		pid = fork();
		if (pid == 0)
		{
			/* child */
			execv(NETINFO_PROG, netinfod_argv);
			exit(-1);
		}

#ifdef DEBUG
		system_log(LOG_DEBUG, "netinfod %s pid = %d", nl.ninl_val[i], pid);
#endif

		if (pid > 0)
		{
			waitreg++;
			storepid(pid, nl.ninl_val[i]);
		}
		else
		{
			system_log(LOG_ERR, "server for tag %s failed to start", nl.ninl_val[i]);
		}
	}

	ni_namelist_free(&nl);
		
	/*
	 * Detach from controlling tty.
	 * Do this AFTER starting netinfod so "type c to continue..." works.
	 */
#ifdef _UNIX_BSD_43_
	ttyfd = open("/dev/tty", O_RDWR, 0);
	if (ttyfd > 0)
	{
		ioctl(ttyfd, TIOCNOTTY, NULL);
		close(ttyfd);
	}

	setpgrp(0, getpid());
#else
	if (setsid() < 0) syslog(LOG_ERR, "nibindd: setsid() failed: %m");
#endif

	system_log(LOG_DEBUG, "starting RPC service");

	nibind_svc_run();
	system_log(LOG_ALERT, "svc_run returned");
	system_log_close();
	exit(1);
}