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); }
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; }
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; }
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); }
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; }
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); }
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; }
void ni_prop_free( ni_property *prop ) { ni_name_free(&prop->nip_name); ni_namelist_free(&prop->nip_val); }
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); }
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; }
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); }
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; }
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); }