Beispiel #1
0
/*
 * Asks the paxos master for the metric value
 * name: find_replicated
 * @param name metric name
 * @param hostname 
 * @param timestamp
 * @return value
 */
char * find_replicated(char *hostname, char *name, time_t *timestamp) {
    FILE *stream;
    char *value, * tstp, *resp, * cookie;
    char *host, *ret;

    if (_PAXOS_DEBUG) pax_log(LOG_DEBUG, "Find replicated\n");
    net_proto(NPROTO_AUTO);
    host = get_host(&node); /*Find the master*/
    if (host == NULL) return NULL;
    stream = cache_connect_net(host, PBS_CACHE_PORT);
    free(host);
    if (stream != NULL) {
        resp = cache_get(stream, hostname, name);
        if ((tstp = strtok_r(resp, "\t", &cookie)) == NULL) {
            pax_log(LOG_ERR, "Incomplete metric message\n");
            cache_close(stream);
            return NULL;
        }

        if ((value = strtok_r(cookie, "\n", &cookie)) == NULL) {
            pax_log(LOG_ERR, "Incomplete metric message\n");
            cache_close(stream);
            return NULL;
        }
        *timestamp = atol(tstp);
        cache_close(stream);
    } else {
        pax_log(LOG_ERR, "cache_connect failed\n");
        return NULL;
    }
    ret = strdup(value);
    free(resp);
    return ret;
}
Beispiel #2
0
__private_extern__
void
do_close(int argc, char **argv)
{
	if (notifyRls != NULL) {
		if (doDispatch) {
			(void) SCDynamicStoreSetDispatchQueue(store, NULL);
		} else {
			CFRunLoopSourceInvalidate(notifyRls);
			CFRelease(notifyRls);
		}
		notifyRls = NULL;
	}

	if (notifyRl != NULL) {
		CFRunLoopStop(notifyRl);
		notifyRl  = NULL;
	}

	if (store != NULL) {
		CFRelease(store);
		store = NULL;
		CFRelease(watchedKeys);
		watchedKeys = NULL;
		CFRelease(watchedPatterns);
		watchedPatterns = NULL;
	}

	cache_close();

	return;
}
Beispiel #3
0
void cmus_exit(void)
{
	worker_remove_jobs(JOB_TYPE_ANY);
	worker_exit();
	if (cache_close())
		d_print("error: %s\n", strerror(errno));
}
Beispiel #4
0
void cache_free(struct cache *c)
{
	cache_close(c);
	cpair_htable_free(c->table);
	cpair_list_free(c->clock);
	xfree(c);
}
Beispiel #5
0
void
quh_exit (void)
{
  if (quh.pid)
    {
      if (quh.filter_chain)
        {
          filter_quit (quh.filter_chain, &quh.nfo);
          filter_free_chain (quh.filter_chain);
        }
    
      while (quh.files--)
        free (quh.fname[quh.files]);
    
      cache_close (quh.o);
    
      remove (quh.tmp_file);
    
      set_property_int (quh.configfile, "settings", quh.soundcard.vol, NULL);
 
      fputc ('\n', stdout);
    
      fflush (stdout);
    }
}
static void
eventCallback(CFSocketRef s, CFSocketCallBackType type, CFDataRef address, const void *data, void *info)
{
	int			so		= CFSocketGetNative(s);
	int			status;
	char			buf[1024];
	struct kern_event_msg	*ev_msg		= (struct kern_event_msg *)&buf[0];
	int			offset		= 0;

	status = recv(so, &buf, sizeof(buf), 0);
	if (status == -1) {
		SCLog(TRUE, LOG_ERR, CFSTR("recv() failed: %s"), strerror(errno));
		goto error;
	}

	cache_open();

	while (offset < status) {
		if ((offset + ev_msg->total_size) > status) {
			SCLog(TRUE, LOG_NOTICE, CFSTR("missed SYSPROTO_EVENT event, buffer not big enough"));
			break;
		}

		switch (ev_msg->vendor_code) {
			case KEV_VENDOR_APPLE :
				switch (ev_msg->kev_class) {
					case KEV_NETWORK_CLASS :
						processEvent_Apple_Network(ev_msg);
						break;
					case KEV_IOKIT_CLASS :
						processEvent_Apple_IOKit(ev_msg);
						break;
					default :
						/* unrecognized (Apple) event class */
						logEvent(CFSTR("New (Apple) class"), ev_msg);
						break;
				}
				break;
			default :
				/* unrecognized vendor code */
				logEvent(CFSTR("New vendor"), ev_msg);
				break;
		}
		offset += ev_msg->total_size;
		ev_msg = (struct kern_event_msg *)&buf[offset];
	}

	cache_write(store);
	cache_close();

	return;

    error :

	SCLog(TRUE, LOG_ERR, CFSTR("kernel event monitor disabled."));
	CFSocketInvalidate(s);
	return;

}
Beispiel #7
0
static Boolean
eventCallback(int so)
{
	ssize_t			status;
	union {
		char			bytes[1024];
		struct kern_event_msg	ev_msg1;	// first kernel event
	} buf;
	struct kern_event_msg	*ev_msg		= &buf.ev_msg1;
	ssize_t			offset		= 0;

	status = recv(so, &buf, sizeof(buf), 0);
	if (status == -1) {
		SCLog(TRUE, LOG_ERR, CFSTR("recv() failed: %s"), strerror(errno));
		return FALSE;
	}

	cache_open();

	while (offset < status) {
		if ((offset + ev_msg->total_size) > status) {
			SCLog(TRUE, LOG_NOTICE, CFSTR("missed SYSPROTO_EVENT event, buffer not big enough"));
			break;
		}

		switch (ev_msg->vendor_code) {
			case KEV_VENDOR_APPLE :
				switch (ev_msg->kev_class) {
					case KEV_NETWORK_CLASS :
						processEvent_Apple_Network(ev_msg);
						break;
					case KEV_IOKIT_CLASS :
					case KEV_SYSTEM_CLASS :
					case KEV_APPLESHARE_CLASS :
					case KEV_FIREWALL_CLASS :
					case KEV_IEEE80211_CLASS :
						break;
					default :
						/* unrecognized (Apple) event class */
						logEvent(CFSTR("New (Apple) class"), ev_msg);
						break;
				}
				break;
			default :
				/* unrecognized vendor code */
				logEvent(CFSTR("New vendor"), ev_msg);
				break;
		}
		offset += ev_msg->total_size;
		ev_msg = (struct kern_event_msg *)(void *)&buf.bytes[offset];
	}

	cache_write(store);
	cache_close();
	post_network_changed();

	return TRUE;
}
Beispiel #8
0
int rosedb_unload(struct query_module *self)
{
	if (self == NULL) {
		return KNOT_EINVAL;
	}

	cache_close(self->ctx);
	return KNOT_EOK;
}
Beispiel #9
0
static void output_alsa_free_stream(struct output_stream *s)
{
	/* Free cache buffer */
	if(s->cache != NULL)
		cache_close(s->cache);

	/* Close resample module */
	if(s->res != NULL)
		resample_close(s->res);

	/* Free stream */
	free(s);
}
Beispiel #10
0
static void *
cache(void *arg)
{
  int ret;

  ret = cache_create();
  if (ret < 0)
    {
      DPRINTF(E_LOG, L_CACHE, "Error: Cache create failed\n");
      pthread_exit(NULL);
    }

  ret = db_perthread_init();
  if (ret < 0)
    {
      DPRINTF(E_LOG, L_CACHE, "Error: DB init failed\n");
      cache_close();

      pthread_exit(NULL);
    }

  g_initialized = 1;

  event_base_dispatch(evbase_cache);

  if (g_initialized)
    {
      DPRINTF(E_LOG, L_CACHE, "cache event loop terminated ahead of time!\n");
      g_initialized = 0;
    }

  db_perthread_deinit();

  cache_close();

  pthread_exit(NULL);
}
Beispiel #11
0
/*
 * Asks the paxos master for removing the metric
 * name: remove_replicated_request
 */
int remove_replicated_request(char *hostname, char *name) {
    int ret = 0;
    FILE *stream;
    char * host;

    net_proto(NPROTO_AUTO);
    host = get_host(&node);
    if (host == NULL) return -1;
    stream = cache_connect_net(host, PBS_CACHE_PORT);
    free(host);
    if (stream != NULL) {
        ret = cache_remove(stream, hostname, name);
        cache_close(stream);
    } else {
        pax_log(LOG_ERR, "cache_connect failed\n");
        return -1;
    }
    return ret;
}
Beispiel #12
0
__private_extern__
void
do_open(int argc, char **argv)
{
	if (store) {
		CFRelease(store);
		CFRelease(watchedKeys);
		CFRelease(watchedPatterns);
	}

	if (argc < 1) {
		store = SCDynamicStoreCreate(NULL, CFSTR("scutil"), storeCallback, NULL);
	} else {
		CFMutableDictionaryRef	options;

		options = CFDictionaryCreateMutable(NULL,
						    0,
						    &kCFTypeDictionaryKeyCallBacks,
						    &kCFTypeDictionaryValueCallBacks);
		CFDictionarySetValue(options, kSCDynamicStoreUseSessionKeys, kCFBooleanTrue);
		store = SCDynamicStoreCreateWithOptions(NULL,
							CFSTR("scutil"),
							options,
							storeCallback,
							NULL);
		CFRelease(options);
	}
	if (store == NULL) {
		SCPrint(TRUE, stdout, CFSTR("  %s\n"), SCErrorString(SCError()));
		return;
	}

	(void) SCDynamicStoreSetDisconnectCallBack(store, reconnected);

	watchedKeys     = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
	watchedPatterns = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);

	cache_close();

	return;
}
Beispiel #13
0
/*
 * Asks the paxos master for change the value of the metric
 * name: update_replicated_request
 */
int update_replicated_request(char *hostname, char *name, char *value) {
    int ret = 0;
    FILE *stream;
    char * host;

    net_proto(NPROTO_AUTO);
    if (_PAXOS_DEBUG > 1) pax_log(LOG_DEBUG, "Proxiing to master %s, %s, %s\n", hostname, name, value);
    host = get_host(&node);
    if (host == NULL) return -1;
    stream = cache_connect_net(host, PBS_CACHE_PORT);
    free(host);
    if (stream != NULL) {
        ret = cache_store(stream, hostname, name, value);
        cache_close(stream);
    } else {
        pax_log(LOG_ERR, "cache_connect failed\n");
        return -1;
    }
    if (_PAXOS_DEBUG > 2) pax_log(LOG_DEBUG, "Proxy done %s, %s, %s\n", hostname, name, value);
    return ret;
}
Beispiel #14
0
void cmus_exit(void)
{
	job_exit();
	if (cache_close())
		d_print("error: %s\n", strerror(errno));
}
Beispiel #15
0
int main(int argc, char *argv[])
{
	if (argc < 3) {
		return help();
	}

	/* Get mandatory parameters. */
	int ret = EXIT_SUCCESS;
	char *dbdir  = argv[1];
	char *action = argv[2];
	argv += 3;
	argc -= 3;

	g_scanner = zs_scanner_create(".", KNOT_CLASS_IN, 0, NULL, parse_err, NULL);
	if (g_scanner == NULL) {
		return EXIT_FAILURE;
	}

	/* Open cache for operations. */
	struct cache *cache = cache_open(dbdir, 0, NULL);
	if (cache == NULL) {
		fprintf(stderr, "failed to open db '%s'\n", dbdir);
		zs_scanner_free(g_scanner);
		return EXIT_FAILURE;
	}

	/* Execute action. */
	bool found = false;
	for (unsigned i = 0; i < TOOL_ACTION_COUNT; ++i) {
		struct tool_action *ta = &TOOL_ACTION[i];
		if (strcmp(ta->name, action) == 0) {

			/* Check param count. */
			if (argc < ta->min_args) {
				break;
			}

			/* Now set as found. */
			found = true;

			MDB_txn *txn = NULL;
			int ret = mdb_txn_begin(cache->env, NULL, 0, &txn);
			if (ret != MDB_SUCCESS) {
				fprintf(stderr, "failed to open transaction, aborting\n");
				break;
			}

			/* Execute operation handler. */
			ret = ta->func(cache, txn, argc, argv);
			if (ret != 0) {
				fprintf(stderr, "'%s' failed, aborting transaction\n", action);
				mdb_txn_abort(txn);
			} else {
				mdb_txn_commit(txn);
			}

			break;
		}
	}

	cache_close(cache);
	zs_scanner_free(g_scanner);

	if (!found) {
		return help();
	}

	return ret;
}
Beispiel #16
0
int main(int argc, char* argv[])
{
	int debugging = 0, broken_only = 0;
#ifdef WITH_DB42
	int id_only = 0;
#endif
	char *output_file = NULL;
	FILE *fp;
	int rv;
	DBC *cur;
	char *dn;
	CacheEntry entry;

	univention_debug_init("stderr", 1, 1);

	/* parse arguments */
	for (;;) {
		int c;

#ifdef WITH_DB42
		c = getopt(argc, argv, "d:c:O:ri");
#else
		c = getopt(argc, argv, "d:c:O:r");
#endif
		if (c < 0)
			break;
		switch (c) {
		case 'd':
			debugging=atoi(optarg);
			break;
		case 'c':
			cache_dir=strdup(optarg);
			break;
		case 'O':
			if (strcmp(optarg, "-") != 0)
				output_file=strdup(optarg);
			break;
		case 'r':
			broken_only=1;
			break;
#ifdef WITH_DB42
		case 'i':
			id_only=1;
			break;
#endif
		default:
			usage();
			exit(1);
		}
	}

	if (debugging > 1) {
		univention_debug_set_level(UV_DEBUG_LISTENER, UV_DEBUG_ALL);
		univention_debug_set_level(UV_DEBUG_LDAP, UV_DEBUG_ALL);
		univention_debug_set_level(UV_DEBUG_KERBEROS, UV_DEBUG_ALL);
	} else if ( debugging > 0 ) {
		univention_debug_set_level(UV_DEBUG_LISTENER, UV_DEBUG_INFO);
		univention_debug_set_level(UV_DEBUG_LDAP, UV_DEBUG_INFO);
		univention_debug_set_level(UV_DEBUG_KERBEROS, UV_DEBUG_INFO);
	} else {
		univention_debug_set_level(UV_DEBUG_LISTENER, UV_DEBUG_ERROR);
		univention_debug_set_level(UV_DEBUG_LDAP, UV_DEBUG_ERROR);
		univention_debug_set_level(UV_DEBUG_KERBEROS, UV_DEBUG_ERROR);
	}

	if (output_file) {
		fp = fopen(output_file, "w");
	} else {
		fp = stdout;
	}
	if (fp == NULL) {
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR,
			"Couldn't open dump file");
		exit(1);
	}
	if (cache_init() != 0)
		exit(1);

#ifdef WITH_DB42
	if (id_only) {
		CacheMasterEntry master_entry;
		cache_get_master_entry(&master_entry);

		printf("%ld %ld\n", master_entry.id, master_entry.schema_id);

	} else {
		exit(0);
#endif

	for (rv=cache_first_entry(&cur, &dn, &entry); rv != DB_NOTFOUND;
			rv=cache_next_entry(&cur, &dn, &entry)) {
		if ((rv == 0 && !broken_only) || (rv == -1 && broken_only)) {
			cache_dump_entry(dn, &entry, fp);
			cache_free_entry(&dn, &entry);
			fprintf(fp, "\n");
		}
		if (rv < -1) break;
	}
	cache_free_cursor(cur);

#ifdef WITH_DB42
	}
#endif

	cache_close();

	return 0;
}
Beispiel #17
0
/*
 * Read the database file and draw the world.
 */
static void
load(char *fn)
{
	register DBPOINT	*pp;
	DBPOINT		*pend;
	FLOAT		x, y, LonPrv, LatPrv;
	long		oldlong = 0L;
	GR_COORD	xnew, ynew;
	GR_COORD	xold = 0, yold = 0;
	GR_BOOL		is_out;
	GR_BOOL		was_out;
	GR_BOOL		newseg = GR_FALSE;
	GR_COLOR	oldcolor;
	GR_COLOR	newcolor;
	int		n;
	int		fh;
	DBPOINT		p[PCount];

	LonPrv = ITOF(0);
	LatPrv = ITOF(0);
	oldcolor = -1;
	is_out = GR_FALSE;
	was_out = GR_FALSE;

#if USE_CACHE
	fh = cache_open(fn);
#else
	fh = syscall_file_open(fn,O_RDONLY|O_BINARY);
#endif
	if (fh < 0) {
		GrClose();
		printf("Cannot open %s\n", fn);
		exit(1);
	}

//printf("open %s\n", fn);
//GrClose();
//exit(1);

	for(;;) {
#if USE_CACHE
		n = cache_read(fh, p, PCount * POINTSize);
#else
		n = syscall_file_read(fh, p, PCount * POINTSize);
#endif
		if(n <= 0)
			break;

		for (pp = p,pend = p + n/POINTSize; pp < pend; pp++)
		{
			DBPOINT_CONVERT(pp);
			/* do displacement */
			x = ITOF(pp->Lon) - Longitude;
			y = ITOF(pp->Lat) - Latitude;

			/* wrap around for East-West */
			if (x < -HSPAN)
				x += WSPAN;
			if (x > HSPAN)
				x -= WSPAN;

			if (pp->Code > 5) {
				newcolor = code_colors[pp->Code / 1000];
				if (newcolor != oldcolor) {
					oldcolor = newcolor;
					GrSetGCForeground(mapgc, oldcolor);
				}
				newseg = GR_TRUE;
			}

			if (oldcolor == BLACK)
				goto go_on;

			/* ignore points outside magnified area */
			if ((x < -longradius || x > longradius ||
				y < -latradius || y > latradius))
			{
				is_out = 1;
				if (was_out) {		/* out to out */
					LonPrv = x;
					LatPrv = y;
					goto go_on;
				}

				/* in to out */
				xold = mapxorig + FTOI(FFMUL(LonPrv, X_Scale)) / 60;
				yold = mapyorig - FTOI(FFMUL(LatPrv, Y_Scale)) / 60;
			} else {			/* out to in */
				is_out = 0;
				if (was_out) {
					xold = mapxorig +
						FTOI(FFMUL(LonPrv, X_Scale)) / 60;
					yold = mapyorig -
						FTOI(FFMUL(LatPrv, Y_Scale)) / 60;
				}
				/* in to in */
			}
			LonPrv = x;
			LatPrv = y;

			/* scale points w/in area to interlace screen */
			xnew = mapxorig + FTOI(FFMUL(x, X_Scale)) / 60;
			ynew = mapyorig - FTOI(FFMUL(y, Y_Scale)) / 60;

			/* if new segment, move to place */
			if (newseg || ABS(oldlong - pp->Lon) > 180*60) {
				xold = xnew;
				yold = ynew;
			}
			oldlong = pp->Lon;

			GrLine(mapwid, mapgc, xold, yold, xnew, ynew);
			xold = xnew;
			yold = ynew;
go_on:
			was_out = is_out;
			newseg = GR_FALSE;
		}
	}
	//if(n<0)
	//	printf("Read Error %d\n", n);
#if USE_CACHE
	cache_close(fh);
#else
	syscall_file_close(fh);
#endif
}
Beispiel #18
0
static void
prime(void)
{
	struct ifaddrs	*ifap	= NULL;
	struct ifaddrs	*scan;
	int		sock	= -1;

	SCLog(_verbose, LOG_DEBUG, CFSTR("prime() called"));

	cache_open();

	sock = dgram_socket(AF_INET);
	if (sock == -1) {
		SCLog(TRUE, LOG_ERR, CFSTR("could not get interface list, socket() failed: %s"), strerror(errno));
		goto done;
	}

	if (getifaddrs(&ifap) == -1) {
		SCLog(TRUE,
		      LOG_ERR,
		      CFSTR("could not get interface info, getifaddrs() failed: %s"),
		      strerror(errno));
		goto done;
	}

	/* update list of interfaces & link status */
	for (scan = ifap; scan != NULL; scan = scan->ifa_next) {
		if (scan->ifa_addr == NULL
		    || scan->ifa_addr->sa_family != AF_LINK) {
			continue;
		}
		/* get the per-interface link/media information */
		link_add(scan->ifa_name);
	}

	/*
	 * update IPv4 network addresses already assigned to
	 * the interfaces.
	 */
	ipv4_interface_update(ifap, NULL);

	/*
	 * update IPv6 network addresses already assigned to
	 * the interfaces.
	 */
	interface_update_ipv6(ifap, NULL);

	freeifaddrs(ifap);

 done:
	if (sock != -1)
		close(sock);

	cache_write(store);
	cache_close();

	network_changed = TRUE;
	post_network_changed();

	/* start handling kernel events */
	dispatch_resume(S_kev_source);

	return;
}
Beispiel #19
0
/**
 * Htags catch signal even if the parent ignore it.
 */
void
clean(void)
{
	unload_gpath();
	cache_close();
}
Beispiel #20
0
static int output_alsa_mix_streams(struct output *h, unsigned char *in_buffer,
				   unsigned char *out_buffer, size_t len)
{
	struct output_stream *s;
	struct a_format fmt = A_FORMAT_INIT;
#ifdef USE_FLOAT
	float *p_in = (float*) in_buffer;
	float *p_out = (float*) out_buffer;
	float sample;
#else
	int32_t *p_in = (int32_t*) in_buffer;
	int32_t *p_out = (int32_t*) out_buffer;
	int32_t sample;
#endif
	int out_size = 0;
	int first = 1;
	int in_size;
	int i;

	pthread_mutex_lock(&h->mutex);
	for(s = h->streams; s != NULL; s = s->next)
	{
		if(!s->is_playing || s->end_of_stream)
			continue;

		/* Get input data */
		in_size = cache_read(s->cache, in_buffer, len, &fmt);
		if(in_size <= 0)
		{
			if(in_size < 0)
			{
				s->end_of_stream = 1;

				/* Close cache filter */
				if(s->cache != NULL)
					cache_close(s->cache);
				s->cache = NULL;

				/* Close resample filter */
				if(s->res != NULL)
					resample_close(s->res);
				s->res = NULL;
			}
			continue;
		}

		/* Update played value (in ms) */
		s->played += in_size;

		/* Add it to output buffer */
		if(first)
		{
			first = 0;
			for(i = 0; i < in_size; i++)
			{
				sample = output_alsa_vol(p_in[i], s->volume);
				p_out[i] = sample;
			}
		}
		else
		{
			/* Add it to output buffer */
			for(i = 0; i < in_size; i++)
			{
				sample = output_alsa_vol(p_in[i], s->volume);
				p_out[i] = output_alsa_add(p_out[i], sample);
			}
		}

		/* Update out_size */
		if(out_size < in_size);
			out_size = in_size;
	}
	pthread_mutex_unlock(&h->mutex);

	return out_size;
}
Beispiel #21
0
void CPU_Core_Dynrec_Cache_Close(void) {
	cache_close();
}
void
prime()
{
	struct ifaddrs	*ifap	= NULL;
	struct ifaddrs	*scan;
	int		sock	= -1;

	SCLog(_verbose, LOG_DEBUG, CFSTR("prime() called"));

	cache_open();

	sock = dgram_socket(AF_INET);
	if (sock == -1) {
		SCLog(TRUE, LOG_ERR, CFSTR("could not get interface list, socket() failed: %s"), strerror(errno));
		goto done;
	}

	if (getifaddrs(&ifap) < 0) {
		SCLog(TRUE,
		      LOG_ERR,
		      CFSTR("could not get interface info, getifaddrs() failed: %s"),
		      strerror(errno));
		goto done;
	}

	/* update list of interfaces & link status */
	for (scan = ifap; scan != NULL; scan = scan->ifa_next) {
		if (scan->ifa_addr == NULL
		    || scan->ifa_addr->sa_family != AF_LINK) {
			continue;
		}
		/* get the per-interface link/media information */
		link_add(scan->ifa_name);
	}

	/*
	 * update IPv4 network addresses already assigned to
	 * the interfaces.
	 */
	interface_update_ipv4(ifap, NULL);

	/*
	 * update IPv6 network addresses already assigned to
	 * the interfaces.
	 */
	interface_update_ipv6(ifap, NULL);

	/*
	 * update AppleTalk network addresses already assigned
	 * to the interfaces.
	 */
	interface_update_appletalk(ifap, NULL);

	freeifaddrs(ifap);

 done:
	if (sock >= 0)
		close(sock);

	cache_write(store);
	cache_close();

	return;
}
Beispiel #23
0
int main(int argc, char *argv[])
{
	static const struct option options[] = {
		{ "version", no_argument, 0, 'V' },
		{ "help",    no_argument, 0, 'h' },
		{ NULL }
	};

	int opt = 0;
	int index = 0;
	while ((opt = getopt_long(argc, argv, "Vh", options, &index)) != -1) {
		switch (opt) {
		case 'V':
			printf("rosedb_tool (Knot DNS), version %s\n", PACKAGE_VERSION);
			return EXIT_SUCCESS;
		case 'h':
			help(stdout);
			return EXIT_SUCCESS;
		default:
			help(stderr);
			return EXIT_FAILURE;
		}
	}

	if (argc < 3) {
		help(stderr);
		return EXIT_FAILURE;
	}

	/* Get mandatory parameters. */
	int ret = EXIT_SUCCESS;
	char *dbdir  = argv[1];
	char *action = argv[2];
	argv += 3;
	argc -= 3;

	g_scanner = malloc(sizeof(zs_scanner_t));
	if (g_scanner == NULL) {
		return EXIT_FAILURE;
	}

	if (zs_init(g_scanner, ".", KNOT_CLASS_IN, 0) != 0 ||
	    zs_set_processing(g_scanner, NULL, parse_err, NULL) != 0) {
		zs_deinit(g_scanner);
		free(g_scanner);
		return EXIT_FAILURE;
	}

	/* Open cache for operations. */
	struct cache *cache = cache_open(dbdir, 0, NULL);
	if (cache == NULL) {
		fprintf(stderr, "failed to open db '%s'\n", dbdir);
		zs_deinit(g_scanner);
		free(g_scanner);
		return EXIT_FAILURE;
	}

	/* Execute action. */
	bool found = false;
	for (unsigned i = 0; i < TOOL_ACTION_COUNT; ++i) {
		struct tool_action *ta = &TOOL_ACTION[i];
		if (strcmp(ta->name, action) == 0) {

			/* Check param count. */
			if (argc < ta->min_args) {
				break;
			}

			/* Now set as found. */
			found = true;

			MDB_txn *txn = NULL;
			int ret = mdb_txn_begin(cache->env, NULL, 0, &txn);
			if (ret != MDB_SUCCESS) {
				fprintf(stderr, "failed to open transaction, aborting\n");
				break;
			}

			/* Execute operation handler. */
			ret = ta->func(cache, txn, argc, argv);
			if (ret != 0) {
				fprintf(stderr, "'%s' failed, aborting transaction\n", action);
				mdb_txn_abort(txn);
			} else {
				mdb_txn_commit(txn);
			}

			break;
		}
	}

	cache_close(cache);
	zs_deinit(g_scanner);
	free(g_scanner);

	if (!found) {
		help(stderr);
		return EXIT_FAILURE;
	}

	return ret;
}
Beispiel #24
0
static boolean_t
updateConfiguration(int *newState)
{
	boolean_t		changed			= FALSE;
	CFStringRef		computerName;
	CFStringEncoding	computerNameEncoding;
	CFArrayRef		configuredServices	= NULL;
	CFDictionaryRef		dict;
	CFIndex			i;
	CFIndex			ifCount			= 0;
	CFMutableArrayRef	info			= NULL;
	CFArrayRef		interfaces		= NULL;
	CFStringRef		key;
	CFArrayRef		keys;
	CFIndex			n;
	CFMutableArrayRef	newConfigFile;
	CFMutableDictionaryRef	newDefaults;
	CFMutableDictionaryRef	newDict;
	CFMutableDictionaryRef	newGlobals;
	CFMutableDictionaryRef	newGlobalsX;			/* newGlobals without ServiceID */
	CFMutableDictionaryRef	newStartup;
	CFMutableDictionaryRef	newZones;
	CFNumberRef		num;
	CFMutableDictionaryRef	curGlobalsX;			/* curGlobals without ServiceID */
	CFStringRef		pattern;
	boolean_t		postGlobals		= FALSE;
	CFStringRef		primaryPort		= NULL;	/* primary interface */
	CFStringRef		primaryZone		= NULL;
	CFArrayRef		serviceOrder		= NULL;
	CFDictionaryRef		setGlobals		= NULL;

	cache_open();

	/*
	 * establish the "new" AppleTalk configuration
	 */
	*newState     = curState;
	newConfigFile = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
	newGlobals    = CFDictionaryCreateMutable(NULL,
						  0,
						  &kCFTypeDictionaryKeyCallBacks,
						  &kCFTypeDictionaryValueCallBacks);
	newDefaults   = CFDictionaryCreateMutable(NULL,
						  0,
						  &kCFTypeDictionaryKeyCallBacks,
						  &kCFTypeDictionaryValueCallBacks);
	newStartup    = CFDictionaryCreateMutable(NULL,
						  0,
						  &kCFTypeDictionaryKeyCallBacks,
						  &kCFTypeDictionaryValueCallBacks);
	newZones      = CFDictionaryCreateMutable(NULL,
						  0,
						  &kCFTypeDictionaryKeyCallBacks,
						  &kCFTypeDictionaryValueCallBacks);

	/* initialize overall state */
	CFDictionarySetValue(newStartup, CFSTR("APPLETALK"), CFSTR("-NO-"));

	/*
	 * get the global settings (ServiceOrder, ComputerName, ...)
	 */
	key = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL,
							 kSCDynamicStoreDomainSetup,
							 kSCEntNetAppleTalk);
	setGlobals = cache_SCDynamicStoreCopyValue(store, key);
	CFRelease(key);
	if (setGlobals) {
		if (isA_CFDictionary(setGlobals)) {
			/* get service order */
			serviceOrder = CFDictionaryGetValue(setGlobals,
							    kSCPropNetServiceOrder);
			serviceOrder = isA_CFArray(serviceOrder);
			if (serviceOrder) {
				CFRetain(serviceOrder);
			}
		} else {
			CFRelease(setGlobals);
			setGlobals = NULL;
		}
	}

	/*
	 * if we don't have an AppleTalk ServiceOrder, use IPv4's (if defined)
	 */
	if (!serviceOrder) {
		key = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL,
								 kSCDynamicStoreDomainSetup,
								 kSCEntNetIPv4);
		dict = cache_SCDynamicStoreCopyValue(store, key);
		CFRelease(key);
		if (dict) {
			if (isA_CFDictionary(dict)) {
				serviceOrder = CFDictionaryGetValue(dict,
								    kSCPropNetServiceOrder);
				serviceOrder = isA_CFArray(serviceOrder);
				if (serviceOrder) {
					CFRetain(serviceOrder);
				}
			}
			CFRelease(dict);
		}
	}

	/*
	 * get the list of ALL configured services
	 */
	configuredServices = entity_all(store, kSCEntNetAppleTalk, serviceOrder);
	if (configuredServices) {
		ifCount = CFArrayGetCount(configuredServices);
	}

	if (serviceOrder)	CFRelease(serviceOrder);

	/*
	 * get the list of ALL active interfaces
	 */
	key  = SCDynamicStoreKeyCreateNetworkInterface(NULL, kSCDynamicStoreDomainState);
	dict = cache_SCDynamicStoreCopyValue(store, key);
	CFRelease(key);
	if (dict) {
		if (isA_CFDictionary(dict)) {
			interfaces = CFDictionaryGetValue(dict,
							  kSCDynamicStorePropNetInterfaces);
			interfaces = isA_CFArray(interfaces);
			if (interfaces) {
				CFRetain(interfaces);
			}
		}
		CFRelease(dict);
	}

	/*
	 * get the list of previously configured services
	 */
	pattern = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
							      kSCDynamicStoreDomainState,
							      kSCCompAnyRegex,
							      kSCEntNetAppleTalk);
	keys = SCDynamicStoreCopyKeyList(store, pattern);
	CFRelease(pattern);
	if (keys) {
		info = CFArrayCreateMutableCopy(NULL, 0, keys);
		CFRelease(keys);
	}

	/*
	 * iterate over each configured service to establish the new
	 * configuration.
	 */
	for (i = 0; i < ifCount; i++) {
		CFDictionaryRef		service;
		CFStringRef		ifName;
		CFStringRef		configMethod;
		CFMutableStringRef	portConfig	= NULL;
		CFArrayRef		networkRange;	/* for seed ports, CFArray[2] of CFNumber (lo, hi) */
		int			sNetwork;
		int			eNetwork;
		CFArrayRef		zoneList;	/* for seed ports, CFArray[] of CFString (zones names) */
		CFIndex			zCount;
		CFIndex			j;
		CFMutableDictionaryRef	ifDefaults	= NULL;
		CFNumberRef		defaultNetwork;
		CFNumberRef		defaultNode;
		CFStringRef		defaultZone;

		/* get AppleTalk service dictionary */
		service = CFArrayGetValueAtIndex(configuredServices, i);

		/* get interface name */
		ifName  = CFDictionaryGetValue(service, kSCPropNetInterfaceDeviceName);

		/* check inteface availability */
		if (!interfaces ||
		    !CFArrayContainsValue(interfaces, CFRangeMake(0, CFArrayGetCount(interfaces)), ifName)) {
			/* if interface not available */
			goto nextIF;
		}

		/* check interface link status */
		key = SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL,
								    kSCDynamicStoreDomainState,
								    ifName,
								    kSCEntNetLink);
		dict = cache_SCDynamicStoreCopyValue(store, key);
		CFRelease(key);
		if (dict) {
			Boolean	linkStatus	= TRUE;  /* assume the link is "up" */
			Boolean	ifDetaching	= FALSE; /* assume link is not detaching */

			/* the link key for this interface is available */
			if (isA_CFDictionary(dict)) {
				CFBooleanRef	bVal;

				bVal = CFDictionaryGetValue(dict, kSCPropNetLinkActive);
				if (isA_CFBoolean(bVal)) {
					linkStatus = CFBooleanGetValue(bVal);
				}

				/* check if interface is detaching - value
				   doesn't really matter, only that it exists */
				ifDetaching = CFDictionaryContainsKey(dict, kSCPropNetLinkDetaching);
			}
			CFRelease(dict);

			if (!linkStatus || ifDetaching) {
				/* if link status down or the interface is detaching */
				goto nextIF;
			}
		}

		/*
		 * Determine configuration method for this service
		 */
		configMethod = CFDictionaryGetValue(service, kSCPropNetAppleTalkConfigMethod);
		if (!isA_CFString(configMethod)) {
			/* if no ConfigMethod */
			goto nextIF;
		}

		if (!CFEqual(configMethod, kSCValNetAppleTalkConfigMethodNode      ) &&
		    !CFEqual(configMethod, kSCValNetAppleTalkConfigMethodRouter    ) &&
		    !CFEqual(configMethod, kSCValNetAppleTalkConfigMethodSeedRouter)) {
			/* if not one of the expected values, disable */
			SCLog(TRUE, LOG_NOTICE,
			      CFSTR("Unexpected AppleTalk ConfigMethod: %@"),
			      configMethod);
			goto nextIF;
		}

		/*
		 * the first service to be defined will always be "primary"
		 */
		if (CFArrayGetCount(newConfigFile) == 0) {
			CFDictionaryRef	active;

			CFDictionarySetValue(newGlobals,
					     kSCDynamicStorePropNetPrimaryService,
					     CFDictionaryGetValue(service, CFSTR("ServiceID")));
			CFDictionarySetValue(newGlobals,
					     kSCDynamicStorePropNetPrimaryInterface,
					     ifName);

			/* and check if AT newtorking is active on the primary interface */
			key = SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL,
									    kSCDynamicStoreDomainState,
									    ifName,
									    kSCEntNetAppleTalk);
			active = cache_SCDynamicStoreCopyValue(store, key);
			CFRelease(key);
			if (active) {
				if (isA_CFDictionary(active)) {
					postGlobals = TRUE;
				}
				CFRelease(active);
			}
		}

		/*
		 * define the port
		 */
		portConfig = CFStringCreateMutable(NULL, 0);
		CFStringAppendFormat(portConfig, NULL, CFSTR("%@:"), ifName);

		if (CFEqual(configMethod, kSCValNetAppleTalkConfigMethodSeedRouter)) {
			CFNumberRef	num;

			/*
			 * we have been asked to configure this interface as a
			 * seed port. Ensure that we have been provided at least
			 * one network number, have been provided with at least
			 * one zonename, ...
			 */

			networkRange = CFDictionaryGetValue(service,
							    kSCPropNetAppleTalkSeedNetworkRange);
			if (!isA_CFArray(networkRange) || (CFArrayGetCount(networkRange) == 0)) {
				SCLog(TRUE, LOG_NOTICE,
				      CFSTR("AppleTalk configuration error (%@)"),
				      kSCPropNetAppleTalkSeedNetworkRange);
				goto nextIF;
			}

			/*
			 * establish the starting and ending network numbers
			 */
			num = CFArrayGetValueAtIndex(networkRange, 0);
			if (!isA_CFNumber(num)) {
				SCLog(TRUE, LOG_NOTICE,
				      CFSTR("AppleTalk configuration error (%@)"),
				      kSCPropNetAppleTalkSeedNetworkRange);
				goto nextIF;
			}
			CFNumberGetValue(num, kCFNumberIntType, &sNetwork);
			eNetwork = sNetwork;

			if (CFArrayGetCount(networkRange) > 1) {
				num = CFArrayGetValueAtIndex(networkRange, 1);
				if (!isA_CFNumber(num)) {
					SCLog(TRUE, LOG_NOTICE,
					      CFSTR("AppleTalk configuration error (%@)"),
					      kSCPropNetAppleTalkSeedNetworkRange);
					goto nextIF;
				}
				CFNumberGetValue(num, kCFNumberIntType, &eNetwork);
			}
			CFStringAppendFormat(portConfig, NULL, CFSTR("%d:%d:"), sNetwork, eNetwork);

			/*
			 * establish the zones associated with this port
			 */
			zoneList = CFDictionaryGetValue(service,
							kSCPropNetAppleTalkSeedZones);
			if (!isA_CFArray(zoneList)) {
				SCLog(TRUE, LOG_NOTICE,
				      CFSTR("AppleTalk configuration error (%@)"),
				      kSCPropNetAppleTalkSeedZones);
				goto nextIF;
			}

			zCount = CFArrayGetCount(zoneList);
			for (j = 0; j < zCount; j++) {
				CFStringRef		zone;
				CFArrayRef		ifList;
				CFMutableArrayRef	newIFList;

				zone = CFArrayGetValueAtIndex(zoneList, j);
				if (!isA_CFString(zone)) {
					continue;
				}

				if (CFDictionaryGetValueIfPresent(newZones, zone, (const void **)&ifList)) {
					/* known zone */
					newIFList = CFArrayCreateMutableCopy(NULL, 0, ifList);
				} else {
					/* new zone */
					newIFList = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
				}
				CFArrayAppendValue(newIFList, ifName);
				CFArraySortValues(newIFList,
						  CFRangeMake(0, CFArrayGetCount(newIFList)),
						  (CFComparatorFunction)CFStringCompare,
						  NULL);
				CFDictionarySetValue(newZones, zone, newIFList);
				CFRelease(newIFList);

				/*
				 * flag the default zone
				 */
				if (!primaryZone) {
					primaryZone = CFRetain(zone);
				}
			}
			if (!primaryZone) {
				SCLog(TRUE, LOG_NOTICE,
				      CFSTR("AppleTalk configuration error (%@)"),
				      kSCPropNetAppleTalkSeedZones);
				goto nextIF;
			}
		}

		/* get the (per-interface) "Computer Name" */
		computerName = CFDictionaryGetValue(service,
						    kSCPropNetAppleTalkComputerName);
		if (CFDictionaryGetValueIfPresent(service,
						  kSCPropNetAppleTalkComputerNameEncoding,
						  (const void **)&num) &&
		    isA_CFNumber(num)) {
			CFNumberGetValue(num, kCFNumberIntType, &computerNameEncoding);
		} else {
			computerNameEncoding = CFStringGetSystemEncoding();
		}
		encodeName(computerName, computerNameEncoding, newStartup, newGlobals);

		/*
		 * declare the first configured AppleTalk service / interface
		 * as the "home port".
		 */
		if (CFArrayGetCount(newConfigFile) == 0) {
			CFStringAppend(portConfig, CFSTR("*"));
			primaryPort = CFRetain(ifName);
		}
		CFArrayAppendValue(newConfigFile, portConfig);

		/*
		 * get the per-interface defaults
		 */
		ifDefaults = CFDictionaryCreateMutable(NULL,
						       0,
						       &kCFTypeDictionaryKeyCallBacks,
						       &kCFTypeDictionaryValueCallBacks);

		defaultNetwork = CFDictionaryGetValue(service, kSCPropNetAppleTalkNetworkID);
		defaultNode    = CFDictionaryGetValue(service, kSCPropNetAppleTalkNodeID);
		if (isA_CFNumber(defaultNetwork) && isA_CFNumber(defaultNode)) {
			/*
			 * set the default node and network
			 */
			CFDictionarySetValue(ifDefaults,
					     kSCPropNetAppleTalkNetworkID,
					     defaultNetwork);
			CFDictionarySetValue(ifDefaults,
					     kSCPropNetAppleTalkNodeID,
					     defaultNode);
		}

		if ((CFDictionaryGetValueIfPresent(service,
						   kSCPropNetAppleTalkDefaultZone,
						   (const void **)&defaultZone) == TRUE)) {
			/*
			 * set the default zone for this interface
			 */
			CFDictionarySetValue(ifDefaults,
					     kSCPropNetAppleTalkDefaultZone,
					     defaultZone);
		}

		CFDictionarySetValue(newDefaults, ifName, ifDefaults);
		CFRelease(ifDefaults);

		switch (CFArrayGetCount(newConfigFile)) {
			case 1:
				/*
				 * first AppleTalk interface
				 */
				CFDictionarySetValue(newStartup, CFSTR("APPLETALK"), ifName);
				break;
			case 2:
				/* second AppleTalk interface */
				if (!CFEqual(CFDictionaryGetValue(newStartup, CFSTR("APPLETALK")),
					     CFSTR("-ROUTER-"))) {
					/*
					 * if not routing (yet), configure as multi-home
					 */
					CFDictionarySetValue(newStartup, CFSTR("APPLETALK"), CFSTR("-MULTIHOME-"));
				}
				break;
		}

		if (CFEqual(configMethod, kSCValNetAppleTalkConfigMethodRouter) ||
		    CFEqual(configMethod, kSCValNetAppleTalkConfigMethodSeedRouter)) {
			/* if not a simple node, enable routing */
			CFDictionarySetValue(newStartup, CFSTR("APPLETALK"), CFSTR("-ROUTER-"));
		}

		/*
		 * establish the State:/Network/Service/nnn/AppleTalk key info
		 */
		key = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
								  kSCDynamicStoreDomainState,
								  CFDictionaryGetValue(service, CFSTR("ServiceID")),
								  kSCEntNetAppleTalk);
		newDict = CFDictionaryCreateMutable(NULL,
						    0,
						    &kCFTypeDictionaryKeyCallBacks,
						    &kCFTypeDictionaryValueCallBacks);
		CFDictionaryAddValue(newDict, kSCPropInterfaceName, ifName);
		cache_SCDynamicStoreSetValue(store, key, newDict);
		CFRelease(newDict);
		if (info) {
			j = CFArrayGetFirstIndexOfValue(info,
							CFRangeMake(0, CFArrayGetCount(info)),
							key);
			if (j != kCFNotFound) {
				CFArrayRemoveValueAtIndex(info, j);
			}
		}
		CFRelease(key);

	    nextIF :

		if (portConfig)	CFRelease(portConfig);
	}

	if (primaryZone) {
		CFArrayRef		ifList;
		CFMutableArrayRef	newIFList;

		ifList = CFDictionaryGetValue(newZones, primaryZone);
		if (CFArrayContainsValue(ifList,
					 CFRangeMake(0, CFArrayGetCount(ifList)),
					 primaryPort)) {
			newIFList = CFArrayCreateMutableCopy(NULL, 0, ifList);
			CFArrayAppendValue(newIFList, CFSTR("*"));
			CFDictionarySetValue(newZones, primaryZone, newIFList);
			CFRelease(newIFList);
		}
		CFRelease(primaryZone);
	}
	if (primaryPort) {
		CFRelease(primaryPort);
	}

	/* sort the ports */
	i = CFArrayGetCount(newConfigFile);
	CFArraySortValues(newConfigFile,
			  CFRangeMake(0, i),
			  (CFComparatorFunction)CFStringCompare,
			  NULL);

	/* add the zones to the configuration */
	CFDictionaryApplyFunction(newZones, addZoneToPorts, newConfigFile);
	CFRelease(newZones);

	/* sort the zones */
	CFArraySortValues(newConfigFile,
			  CFRangeMake(i, CFArrayGetCount(newConfigFile)-i),
			  (CFComparatorFunction)CFStringCompare,
			  NULL);

	/* ensure that the last line of the configuration file is terminated */
	CFArrayAppendValue(newConfigFile, CFSTR(""));

	/*
	 * Check if we have a "ComputerName" and look elsewhere if we don't have
	 * one yet.
	 */
	if (!CFDictionaryContainsKey(newStartup, CFSTR("APPLETALK_HOSTNAME")) &&
	    (setGlobals != NULL)) {
		computerName = CFDictionaryGetValue(setGlobals,
						    kSCPropNetAppleTalkComputerName);
		if (CFDictionaryGetValueIfPresent(setGlobals,
						  kSCPropNetAppleTalkComputerNameEncoding,
						  (const void **)&num) &&
		    isA_CFNumber(num)) {
			CFNumberGetValue(num, kCFNumberIntType, &computerNameEncoding);
		} else {
			computerNameEncoding = CFStringGetSystemEncoding();
		}
		encodeName(computerName, computerNameEncoding, newStartup, newGlobals);
	}
	if (!CFDictionaryContainsKey(newStartup, CFSTR("APPLETALK_HOSTNAME"))) {
		computerName = SCDynamicStoreCopyComputerName(store, &computerNameEncoding);
		if (computerName) {
			encodeName(computerName, computerNameEncoding, newStartup, newGlobals);
			CFRelease(computerName);
		}
	}
	if (!CFDictionaryContainsKey(newStartup, CFSTR("APPLETALK_HOSTNAME"))) {
		struct utsname	name;

		if (uname(&name) == 0) {
			computerName = CFStringCreateWithCString(NULL, name.nodename, kCFStringEncodingASCII);
			if (computerName) {
				encodeName(computerName, kCFStringEncodingASCII, NULL, newGlobals);
				CFRelease(computerName);
			}
		}
	}

	/* compare the previous and current configurations */

	curGlobalsX = CFDictionaryCreateMutableCopy(NULL, 0, curGlobals);
	CFDictionaryRemoveValue(curGlobalsX, kSCDynamicStorePropNetPrimaryService);

	newGlobalsX = CFDictionaryCreateMutableCopy(NULL, 0, newGlobals);
	CFDictionaryRemoveValue(newGlobalsX, kSCDynamicStorePropNetPrimaryService);

	key = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL,
							 kSCDynamicStoreDomainState,
							 kSCEntNetAppleTalk);

	if (CFEqual(curGlobalsX   , newGlobalsX   ) &&
	    CFEqual(curConfigFile , newConfigFile) &&
	    CFEqual(curDefaults   , newDefaults  ) &&
	    CFEqual(curStartup    , newStartup   )
	    ) {
		/*
		 * the configuration has not changed.
		 */

		if (postGlobals) {
			/*
			 * the requested configuration hasn't changed but we
			 * now need to tell everyone that AppleTalk is active.
			 */
			if (!SCDynamicStoreSetValue(store, key, newGlobals)) {
				SCLog(TRUE,
				      LOG_ERR,
				      CFSTR("SCDynamicStoreSetValue() failed: %s"),
				      SCErrorString(SCError()));
			}
		}

		CFRelease(newGlobals);
		CFRelease(newConfigFile);
		CFRelease(newDefaults);
		CFRelease(newStartup);
	} else if (CFArrayGetCount(newConfigFile) <= 1) {
		/*
		 * the configuration has changed but there are no
		 * longer any interfaces configured for AppleTalk
		 * networking.
		 */

		/*
		 * remove the global (State:/Network/Global/AppleTalk) key.
		 *
		 * Note: it will be restored later after AT networking has
		 *       been activated.
		 */

		/* remove the (/etc/appletalk.cfg) configuration file */
		(void)unlink(AT_CFG_FILE);

		/*
		 * update the per-service (and global) state
		 */
		cache_SCDynamicStoreRemoveValue(store, key);	// remove State:/Network/Global/AppleTalk
		n = CFArrayGetCount(info);
		for (i = 0; i < n; i++) {
			CFStringRef	xKey	= CFArrayGetValueAtIndex(info, i);

			cache_SCDynamicStoreRemoveValue(store, xKey);
		}
		cache_write(store);

		/* flag this as a new configuration */
		*newState = -(abs(curState) + 1);
		changed = TRUE;
	} else {
		/*
		 * the configuration has changed.
		 */

		/* update the (/etc/appletalk.cfg) configuration file */
		configWrite(AT_CFG_FILE, newConfigFile);

		/*
		 * update the per-service (and global) state
		 *
		 * Note: if present, we remove any existing global state key and allow it
		 *       to be restored after the stack has been re-started.
		 */
		CFDictionaryApplyFunction(newDefaults, updateDefaults, NULL);
		cache_SCDynamicStoreRemoveValue(store, key);	// remove State:/Network/Global/AppleTalk
		n = CFArrayGetCount(info);
		for (i = 0; i < n; i++) {
			CFStringRef	xKey	= CFArrayGetValueAtIndex(info, i);

			cache_SCDynamicStoreRemoveValue(store, xKey);
		}
		cache_write(store);

		/* flag this as a new configuration */
		*newState = abs(curState) + 1;
		changed = TRUE;
	}

	CFRelease(curGlobalsX);
	CFRelease(newGlobalsX);
	CFRelease(key);

	if (changed) {
		CFRelease(curGlobals);
		curGlobals    = newGlobals;
		CFRelease(curConfigFile);
		curConfigFile = newConfigFile;
		CFRelease(curDefaults);
		curDefaults   = newDefaults;
		CFRelease(curStartup);
		curStartup    = newStartup;
	}

	if (info)		CFRelease(info);
	if (interfaces)		CFRelease(interfaces);
	if (configuredServices)	CFRelease(configuredServices);
	if (setGlobals)		CFRelease(setGlobals);

	cache_close();

	return changed;
}