Пример #1
0
int main(int argc, char **argv)
{
	hashmap_t * map;

	if (argc != 2) {
		fprintf(stderr, "Usage: %s string\n",argv[0]);
		exit(EXIT_FAILURE);
	}

	map = (hashmap_t *)malloc(sizeof(hashmap_t));

	hashmap_init(map);

	decode(argv[1], map);

	hashmap_iterate(map,print_hashmap);

	hashmap_delete_all(map);

	hashmap_free(map);
	free(map);

	exit(0);
}
Пример #2
0
int free_patch_ids(struct patch_ids *ids)
{
	hashmap_free(&ids->patches, 1);
	return 0;
}
Пример #3
0
static void manager_free(Manager *m) {
        Session *session;
        User *u;
        Device *d;
        Seat *s;
        Inhibitor *i;
        Button *b;

        assert(m);

        while ((session = hashmap_first(m->sessions)))
                session_free(session);

        while ((u = hashmap_first(m->users)))
                user_free(u);

        while ((d = hashmap_first(m->devices)))
                device_free(d);

        while ((s = hashmap_first(m->seats)))
                seat_free(s);

        while ((i = hashmap_first(m->inhibitors)))
                inhibitor_free(i);

        while ((b = hashmap_first(m->buttons)))
                button_free(b);

        hashmap_free(m->devices);
        hashmap_free(m->seats);
        hashmap_free(m->sessions);
        hashmap_free(m->users);
        hashmap_free(m->inhibitors);
        hashmap_free(m->buttons);

        hashmap_free(m->user_units);
        hashmap_free(m->session_units);

        sd_event_source_unref(m->idle_action_event_source);
        sd_event_source_unref(m->inhibit_timeout_source);
        sd_event_source_unref(m->scheduled_shutdown_timeout_source);
        sd_event_source_unref(m->nologin_timeout_source);
        sd_event_source_unref(m->wall_message_timeout_source);

        sd_event_source_unref(m->console_active_event_source);
        sd_event_source_unref(m->udev_seat_event_source);
        sd_event_source_unref(m->udev_device_event_source);
        sd_event_source_unref(m->udev_vcsa_event_source);
        sd_event_source_unref(m->udev_button_event_source);
        sd_event_source_unref(m->lid_switch_ignore_event_source);

        safe_close(m->console_active_fd);

        udev_monitor_unref(m->udev_seat_monitor);
        udev_monitor_unref(m->udev_device_monitor);
        udev_monitor_unref(m->udev_vcsa_monitor);
        udev_monitor_unref(m->udev_button_monitor);

        udev_unref(m->udev);

        if (m->unlink_nologin)
                (void) unlink("/run/nologin");

        bus_verify_polkit_async_registry_free(m->polkit_registry);

        sd_bus_unref(m->bus);
        sd_event_unref(m->event);

        safe_close(m->reserve_vt_fd);

        strv_free(m->kill_only_users);
        strv_free(m->kill_exclude_users);

        free(m->scheduled_shutdown_type);
        free(m->scheduled_shutdown_tty);
        free(m->wall_message);
        free(m->action_job);
        free(m);
}
Пример #4
0
static void free_hashmap(void * h) {
	hashmap_free(h);
	free(h);
}
Пример #5
0
bool buxton_cache_smack_rules(void)
{
	smack_check();

	FILE *load_file = NULL;
	char *rule_pair = NULL;
	int ret = true;
	bool have_rules = false;
	struct stat buf;

	if (_smackrules) {
		hashmap_free(_smackrules);
	}

	_smackrules = hashmap_new(string_hash_func, string_compare_func);

	if (!_smackrules) {
		abort();
	}

	//FIXME: should check for a proper mount point instead
	if ((stat(SMACK_MOUNT_DIR, &buf) == -1) || !S_ISDIR(buf.st_mode)) {
		buxton_log("Smack filesystem not detected; disabling Smack checks\n");
		have_smack = false;
		goto end;
	}

	load_file = fopen(buxton_smack_load_file(), "r");

	if (!load_file) {
		switch (errno) {
		case ENOENT:
			buxton_log("Smackfs load2 file not found; disabling Smack checks\n");
			have_smack = false;
			goto end;
		default:
			buxton_log("fopen(): %m\n");
			ret = false;
			goto end;
		}
	}

	do {
		int r;
		int chars;
		BuxtonKeyAccessType *accesstype;

		char subject[SMACK_LABEL_LEN+1] = { 0, };
		char object[SMACK_LABEL_LEN+1] = { 0, };
		char access[ACC_LEN] = { 0, };

		/* read contents from load2 */
		chars = fscanf(load_file, "%s %s %s\n", subject, object, access);

		if (ferror(load_file)) {
			buxton_log("fscanf(): %m\n");
			ret = false;
			goto end;
		}

		if (!have_rules && chars == EOF && feof(load_file)) {
			buxton_debug("No loaded Smack rules found\n");
			goto end;
		}

		if (chars != 3) {
			buxton_log("Corrupt load file detected\n");
			ret = false;
			goto end;
		}

		have_rules = true;

		r = asprintf(&rule_pair, "%s %s", subject, object);
		if (r == -1) {
			abort();
		}

		accesstype = malloc0(sizeof(BuxtonKeyAccessType));
		if (!accesstype) {
			abort();
		}

		*accesstype = ACCESS_NONE;

		if (strchr(access, 'r')) {
			*accesstype |= ACCESS_READ;
		}

		if (strchr(access, 'w')) {
			*accesstype |= ACCESS_WRITE;
		}

		hashmap_put(_smackrules, rule_pair, accesstype);

	} while (!feof(load_file));

end:
	if (load_file) {
		fclose(load_file);
	}

	return ret;
}
Пример #6
0
void fuser_userdict_destroy(hashmap *users)
{
    hashmap_map(users, &user_delete, NULL);
    hashmap_free(users);
}
Пример #7
0
int renderman_tear_down () {
  hashmap_free ( mapSceneData );
  hashmap_free ( staticShaders );
  hashmap_free ( staticPrograms );
  return 0;
}
Пример #8
0
void set_free(Set* s) {
        hashmap_free(MAKE_HASHMAP(s));
}
Пример #9
0
int main(char* argv, int argc)
{
    int index;
    int error;
    map_t mymap;
    char key_string[KEY_MAX_LENGTH];
    data_struct_t* value;

    fprintf(stderr, "start...\n");
    mymap = hashmap_new();

    /* First, populate the hash map with ascending values */
    for (index=0; index<KEY_COUNT; index+=1)
    {
        /* Store the key string along side the numerical value so we can free it later */
        value = malloc(sizeof(data_struct_t));
        //snprintf(value->key_string, KEY_MAX_LENGTH, "%s%d", KEY_PREFIX, index);
        snprintf(value->key_string, KEY_MAX_LENGTH, "%s", strings[index]);
        value->number = index;
        //fprintf(stderr, "value->key_string=%s, value->number=%d\n",
        //        value->key_string, value->number);

        error = hashmap_put(mymap, value->key_string, value);
        assert(error==MAP_OK);
    }

    /* Now, check all of the expected values are there */
    for (index=0; index<KEY_COUNT; index+=1)
    {
        //snprintf(key_string, KEY_MAX_LENGTH, "%s%d", KEY_PREFIX, index);
        snprintf(key_string, KEY_MAX_LENGTH, "%s", strings[index]);

        error = hashmap_get(mymap, key_string, (void**)(&value));
        //fprintf(stderr, "error=%d, value->number=%d, index=(%d)\n", error, value->number, index);

        /* Make sure the value was both found and the correct number */
        assert(error==MAP_OK);
        assert(value->number==index);
    }

    /* Make sure that a value that wasn't in the map can't be found */
    snprintf(key_string, KEY_MAX_LENGTH, "%s%d", KEY_PREFIX, KEY_COUNT);
    //snprintf(key_string, KEY_MAX_LENGTH, "%s", KEY_COUNT);

    error = hashmap_get(mymap, key_string, (void**)(&value));
    fprintf(stderr, "error=%d\n", error);

    /* Make sure the value was not found */
    assert(error==MAP_MISSING);

    /* Free all of the values we allocated and remove them from the map */
    for (index=0; index<KEY_COUNT; index+=1)
    {
        //snprintf(key_string, KEY_MAX_LENGTH, "%s%d", KEY_PREFIX, index);
        snprintf(key_string, KEY_MAX_LENGTH, "%s", strings[index]);

        error = hashmap_get(mymap, key_string, (void**)(&value));
        assert(error==MAP_OK);

        error = hashmap_remove(mymap, key_string);
        assert(error==MAP_OK);

        free(value);
    }

    /* Now, destroy the map */
    hashmap_free(mymap);

    return 1;
}
Пример #10
0
void oidmap_free(struct oidmap *map, int free_entries)
{
	if (!map)
		return;
	hashmap_free(&map->map, free_entries);
}
Пример #11
0
/*
 * Read stdin line by line and print result of commands to stdout:
 *
 * hash key -> strhash(key) memhash(key) strihash(key) memihash(key)
 * put key value -> NULL / old value
 * get key -> NULL / value
 * remove key -> NULL / old value
 * iterate -> key1 value1\nkey2 value2\n...
 * size -> tablesize numentries
 *
 * perfhashmap method rounds -> test hashmap.[ch] performance
 */
int main(int argc, char *argv[])
{
	char line[1024];
	struct hashmap map;
	int icase;

	/* init hash map */
	icase = argc > 1 && !strcmp("ignorecase", argv[1]);
	hashmap_init(&map, (hashmap_cmp_fn) (icase ? test_entry_cmp_icase
			: test_entry_cmp), 0);

	/* process commands from stdin */
	while (fgets(line, sizeof(line), stdin)) {
		char *cmd, *p1 = NULL, *p2 = NULL;
		int l1 = 0, l2 = 0, hash = 0;
		struct test_entry *entry;

		/* break line into command and up to two parameters */
		cmd = strtok(line, DELIM);
		/* ignore empty lines */
		if (!cmd || *cmd == '#')
			continue;

		p1 = strtok(NULL, DELIM);
		if (p1) {
			l1 = strlen(p1);
			hash = icase ? strihash(p1) : strhash(p1);
			p2 = strtok(NULL, DELIM);
			if (p2)
				l2 = strlen(p2);
		}

		if (!strcmp("hash", cmd) && l1) {

			/* print results of different hash functions */
			printf("%u %u %u %u\n", strhash(p1), memhash(p1, l1),
					strihash(p1), memihash(p1, l1));

		} else if (!strcmp("add", cmd) && l1 && l2) {

			/* create entry with key = p1, value = p2 */
			entry = alloc_test_entry(hash, p1, l1, p2, l2);

			/* add to hashmap */
			hashmap_add(&map, entry);

		} else if (!strcmp("put", cmd) && l1 && l2) {

			/* create entry with key = p1, value = p2 */
			entry = alloc_test_entry(hash, p1, l1, p2, l2);

			/* add / replace entry */
			entry = hashmap_put(&map, entry);

			/* print and free replaced entry, if any */
			puts(entry ? get_value(entry) : "NULL");
			free(entry);

		} else if (!strcmp("get", cmd) && l1) {

			/* lookup entry in hashmap */
			entry = hashmap_get_from_hash(&map, hash, p1);

			/* print result */
			if (!entry)
				puts("NULL");
			while (entry) {
				puts(get_value(entry));
				entry = hashmap_get_next(&map, entry);
			}

		} else if (!strcmp("remove", cmd) && l1) {

			/* setup static key */
			struct hashmap_entry key;
			hashmap_entry_init(&key, hash);

			/* remove entry from hashmap */
			entry = hashmap_remove(&map, &key, p1);

			/* print result and free entry*/
			puts(entry ? get_value(entry) : "NULL");
			free(entry);

		} else if (!strcmp("iterate", cmd)) {

			struct hashmap_iter iter;
			hashmap_iter_init(&map, &iter);
			while ((entry = hashmap_iter_next(&iter)))
				printf("%s %s\n", entry->key, get_value(entry));

		} else if (!strcmp("size", cmd)) {

			/* print table sizes */
			printf("%u %u\n", map.tablesize, map.size);

		} else if (!strcmp("intern", cmd) && l1) {

			/* test that strintern works */
			const char *i1 = strintern(p1);
			const char *i2 = strintern(p1);
			if (strcmp(i1, p1))
				printf("strintern(%s) returns %s\n", p1, i1);
			else if (i1 == p1)
				printf("strintern(%s) returns input pointer\n", p1);
			else if (i1 != i2)
				printf("strintern(%s) != strintern(%s)", i1, i2);
			else
				printf("%s\n", i1);

		} else if (!strcmp("perfhashmap", cmd) && l1 && l2) {

			perf_hashmap(atoi(p1), atoi(p2));

		} else {

			printf("Unknown command %s\n", cmd);

		}
	}

	hashmap_free(&map, 1);
	return 0;
}
Пример #12
0
void LXIntegerMapDestroy(LXIntegerMapPtr r)
{
    if ( !r) return;
    hashmap_free((map_t)r);
}
Пример #13
0
void manager_free(Manager *m) {
        Session *session;
        User *u;
        Device *d;
        Seat *s;
        Inhibitor *i;
        Button *b;

        assert(m);

        while ((session = hashmap_first(m->sessions)))
                session_free(session);

        while ((u = hashmap_first(m->users)))
                user_free(u);

        while ((d = hashmap_first(m->devices)))
                device_free(d);

        while ((s = hashmap_first(m->seats)))
                seat_free(s);

        while ((i = hashmap_first(m->inhibitors)))
                inhibitor_free(i);

        while ((b = hashmap_first(m->buttons)))
                button_free(b);

        hashmap_free(m->devices);
        hashmap_free(m->seats);
        hashmap_free(m->sessions);
        hashmap_free(m->users);
        hashmap_free(m->inhibitors);
        hashmap_free(m->buttons);

        hashmap_free(m->user_units);
        hashmap_free(m->session_units);

        set_free_free(m->busnames);

        sd_event_source_unref(m->idle_action_event_source);

        sd_event_source_unref(m->console_active_event_source);
        sd_event_source_unref(m->udev_seat_event_source);
        sd_event_source_unref(m->udev_device_event_source);
        sd_event_source_unref(m->udev_vcsa_event_source);
        sd_event_source_unref(m->udev_button_event_source);
        sd_event_source_unref(m->lid_switch_ignore_event_source);

        safe_close(m->console_active_fd);

        if (m->udev_seat_monitor)
                udev_monitor_unref(m->udev_seat_monitor);
        if (m->udev_device_monitor)
                udev_monitor_unref(m->udev_device_monitor);
        if (m->udev_vcsa_monitor)
                udev_monitor_unref(m->udev_vcsa_monitor);
        if (m->udev_button_monitor)
                udev_monitor_unref(m->udev_button_monitor);

        if (m->udev)
                udev_unref(m->udev);

        bus_verify_polkit_async_registry_free(m->bus, m->polkit_registry);

        sd_bus_unref(m->bus);
        sd_event_unref(m->event);

        safe_close(m->reserve_vt_fd);

        strv_free(m->kill_only_users);
        strv_free(m->kill_exclude_users);

        free(m->action_job);
        free(m);
}
Пример #14
0
void procedures_at_exit(void) {

  struct source_file_name *f, *fn;
  struct object_file *o;
  struct reference *r;
  struct section *s;
  struct stack *sta;
  struct label *l;

  /* free all the dynamically allocated data structures */
  while (obj_first != NULL) {
    f = obj_first->source_file_names_list;
    while (f != NULL) {
      if (f->name != NULL)
	free(f->name);
      fn = f->next;
      free(f);
      f = fn;
    }
    if (obj_first->data != NULL)
      free(obj_first->data);
    if (obj_first->name != NULL)
      free(obj_first->name);
    o = obj_first;
    obj_first = obj_first->next;
    free(o);
  }

  if (global_unique_label_map != NULL)
    hashmap_free(global_unique_label_map);

  if (namespace_map != NULL) {
    hashmap_free_all_elements(namespace_map);
    hashmap_free(namespace_map);
  }

  while (labels_first != NULL) {
    l = labels_first;
    labels_first = labels_first->next;
    free(l);
  }

  while (reference_first != NULL) {
    r = reference_first;
    reference_first = reference_first->next;
    free(r);
  }

  while (stacks_first != NULL) {
    sta = stacks_first->next;
    free(stacks_first->stack);
    free(stacks_first);
    stacks_first = sta;
  }

  while (sec_first != NULL) {
    s = sec_first->next;
    if (sec_first->listfile_cmds != NULL)
      free(sec_first->listfile_cmds);
    if (sec_first->listfile_ints != NULL)
      free(sec_first->listfile_ints);
    hashmap_free(sec_first->label_map);
    free(sec_first);
    sec_first = s;
  }

  while (sec_hd_first != NULL) {
    s = sec_hd_first->next;
    free(sec_hd_first);
    sec_hd_first = s;
  }

  if (banksizes != NULL)
    free(banksizes);
  if (bankaddress != NULL)
    free(bankaddress);
}
Пример #15
0
/*
 * Clears the cache.
 */
static void fscache_clear(void)
{
	hashmap_free(&map, 1);
	hashmap_init(&map, (hashmap_cmp_fn)fsentry_cmp, NULL, 0);
}
Пример #16
0
int main(void) {
	entry *en;
	char *key, *value;
	int res;

	hashmap *hm = hashmap_empty(20, string_hash_function, entry_free_func);
	if (hm == NULL) {
		return EXIT_FAILURE;
	}
	printf("Inserting test entries...\n");
	en = create_entry("cat", "goes meow");
	res = hashmap_put(en, hm);
	if (res) {
		fprintf(stderr, "FAIL: OOM (Insert1)\n");
		return EXIT_FAILURE;
	}
	en = create_entry("dog", "goes woof");
	res = hashmap_put(en, hm);
	if (res) {
		fprintf(stderr, "FAIL: OOM (Insert2)\n");
		return EXIT_FAILURE;
	}
	en = create_entry("bird", "goes tweet");
	res = hashmap_put(en, hm);
	if (res) {
		fprintf(stderr, "FAIL: OOM (Insert3)\n");
		return EXIT_FAILURE;
	}
	en = create_entry("mouse", "goes sqeak");
	res = hashmap_put(en, hm);
	if (res) {
		fprintf(stderr, "FAIL: OOM (Insert4)\n");
		return EXIT_FAILURE;
	}
	if (hm->nr_entries == 4) {
		printf("Success: 4 test entries inserted\n");
	} else {
		fprintf(stderr, "FAIL: Wrong number of entries! (insert5)\n");
		return EXIT_FAILURE;
	}

	printf("\nTest Get...\n");
	key = "dog";
	value = (char *) hashmap_get(key, strlen(key) + 1, hm);
	if (value) {
		printf("Success: %s %s\n", key, value);
	} else {
		fprintf(stderr, "FAIL: No entry found! (Get1)\n");
		return EXIT_FAILURE;
	}
	value = (char *) hashmap_get(key, strlen(key), hm);
	if (value) {
		fprintf(stderr, "FAIL: Entry found! (Get2)\n");
		return EXIT_FAILURE;
	} else {
		printf("Success: No entry found for erroneous key length\n");
	}

	printf("\nTest Remove...\n");
	res = hashmap_remove(key, strlen(key) + 1, hm);
	if (res) {
		printf("Success: Entry removed\n");
	} else {
		fprintf(stderr, "FAIL: Entry not removed! (Remove1)\n");
		return EXIT_FAILURE;
	}
	value = (char *) hashmap_get(key, strlen(key), hm);
	if (value) {
		fprintf(stderr, "FAIL: Entry found! (Remove2)\n");
		return EXIT_FAILURE;
	} else {
		printf("Success: No entry found after removal\n");
	}

	hashmap_free(hm);
	return EXIT_SUCCESS;
}
Пример #17
0
void i18n_cleanup(void)
{
	hashmap_free(&map, 1);
}
Пример #18
0
/*
 * shm_network_stopall - Shared Memory Manager destructor
 */
static void shm_network_stopall() {
	hashmap_free(shm_network);
	free(shm_network);
	syscall_shm_release(shm_cmd);
}
Пример #19
0
static void group_hashmap_free(Hashmap *h) {
        group_hashmap_clear(h);
        hashmap_free(h);
}
Пример #20
0
void free_eml_domains(map_t domains){
    hashmap_iterate_keys(domains,&free_eml_domain_key,NULL);
    hashmap_free(domains);
}
Пример #21
0
static void free_scene_data (Scene* scene) {

  char sdkey[KEYSIZE];
  snprintf (sdkey, KEYSIZE, "%p", scene);
  
  SceneData* sceneData = hashmap_find (sdkey, mapSceneData);

  if (sceneData) {    
      
    GLuint handle;
    
    int k;
    for (k = 0; k < list_size(sceneData->listBuffers); k++) {

      handle = (GLuint)list_get(k, sceneData->listBuffers);
      glDeleteBuffers (1, &handle);
    }

    for ( k = 0; k < list_size(sceneData->listPrograms); k++) {
      
      handle = (GLuint)list_get(k, sceneData->listPrograms);
      glDeleteProgram ( handle );
    }

    for ( k = 0; k < list_size(sceneData->listVShaders); k++) {
      
      handle = (GLuint)list_get(k, sceneData->listVShaders);
      glDeleteShader ( handle );
    }

    for ( k = 0; k < list_size(sceneData->listFShaders); k++) {
      
      handle = (GLuint)list_get(k, sceneData->listFShaders);
      glDeleteShader ( handle );
    }

    for ( k = 0; k < list_size(sceneData->listTextures); k++) {
      
      handle = (GLuint)list_get(k, sceneData->listTextures);
      glDeleteTextures ( 1, &handle );
    }

    list_free (sceneData->listPrograms);
    list_free (sceneData->listVShaders);
    list_free (sceneData->listFShaders);
    list_free (sceneData->listBuffers);
    list_free (sceneData->listTextures);

    hashmap_free (sceneData->mapVShader2Handle);
    hashmap_free (sceneData->mapFShader2Handle);
    hashmap_free (sceneData->mapShaderShader2Handle);
    hashmap_free (sceneData->mapBuffer2Handle);
    hashmap_free (sceneData->mapTexture2Handle);

    hashmap_free (sceneData->countBufferUsers);
    hashmap_free (sceneData->countVShaderUsers);
    hashmap_free (sceneData->countFShaderUsers);
    hashmap_free (sceneData->countProgramUsers);
    hashmap_free (sceneData->countTextureUsers);

    hashmap_free (sceneData->mapSo2SoData);

    list_free (sceneData->stageGbuffer);
    list_free (sceneData->stageLight);
    list_free (sceneData->stageGeometry);
    list_free (sceneData->stageParticle);
    list_free (sceneData->stageOverlay);
    
    hashmap_delete (sdkey, mapSceneData);
  }
}
Пример #22
0
/**
 * Entry point into bt-daemon
 * @param argc Number of arguments passed
 * @param argv An array of string arguments
 * @returns EXIT_SUCCESS if the operation succeeded, otherwise EXIT_FAILURE
 */
int main(int argc, char *argv[])
{
	int fd;
	int smackfd = -1;
	socklen_t addr_len;
	struct sockaddr_un remote;
	int descriptors;
	int ret;
	bool manual_start = false;
	struct sigaction sa;

	if (!buxton_cache_smack_rules())
		exit(EXIT_FAILURE);
	smackfd = buxton_watch_smack_rules();
	if (smackfd < 0 && errno)
		exit(EXIT_FAILURE);

	self.nfds_alloc = 0;
	self.accepting_alloc = 0;
	self.nfds = 0;
	self.buxton.client.direct = true;
	self.buxton.client.uid = geteuid();
	if (!buxton_direct_open(&self.buxton))
		exit(EXIT_FAILURE);

	sigemptyset(&sa.sa_mask);
	sa.sa_flags = SA_RESTART;
	sa.sa_handler = my_handler;
	ret = sigaction(SIGINT, &sa, NULL);
	if (ret == -1)
		exit(EXIT_FAILURE);
	ret = sigaction(SIGTERM, &sa, NULL);
	if (ret == -1)
		exit(EXIT_FAILURE);

	/* For client notifications */
	self.notify_mapping = hashmap_new(string_hash_func, string_compare_func);
	/* Store a list of connected clients */
	LIST_HEAD_INIT(client_list_item, self.client_list);

	descriptors = sd_listen_fds(0);
	if (descriptors < 0) {
		buxton_log("sd_listen_fds: %m\n");
		exit(EXIT_FAILURE);
	} else if (descriptors == 0) {
		/* Manual invocation */
		manual_start = true;
		union {
			struct sockaddr sa;
			struct sockaddr_un un;
		} sa;

		fd = socket(AF_UNIX, SOCK_STREAM, 0);
		if (fd < 0) {
			buxton_log("socket(): %m\n");
			exit(EXIT_FAILURE);
		}

		memset(&sa, 0, sizeof(sa));
		sa.un.sun_family = AF_UNIX;
		strncpy(sa.un.sun_path, BUXTON_SOCKET, sizeof(sa.un.sun_path) - 1);
		sa.un.sun_path[sizeof(sa.un.sun_path)-1] = 0;

		ret = unlink(sa.un.sun_path);
		if (ret == -1 && errno != ENOENT) {
			exit(EXIT_FAILURE);
		}

		if (bind(fd, &sa.sa, sizeof(sa)) < 0) {
			buxton_log("bind(): %m\n");
			exit(EXIT_FAILURE);
		}

		chmod(sa.un.sun_path, 0666);

		if (listen(fd, SOMAXCONN) < 0) {
			buxton_log("listen(): %m\n");
			exit(EXIT_FAILURE);
		}
		add_pollfd(&self, fd, POLLIN | POLLPRI, true);
	} else {
		/* systemd socket activation */
		for (fd = SD_LISTEN_FDS_START + 0; fd < SD_LISTEN_FDS_START + descriptors; fd++) {
			if (sd_is_fifo(fd, NULL)) {
				add_pollfd(&self, fd, POLLIN, false);
				buxton_debug("Added fd %d type FIFO\n", fd);
			} else if (sd_is_socket_unix(fd, SOCK_STREAM, -1, BUXTON_SOCKET, 0)) {
				add_pollfd(&self, fd, POLLIN | POLLPRI, true);
				buxton_debug("Added fd %d type UNIX\n", fd);
			} else if (sd_is_socket(fd, AF_UNSPEC, 0, -1)) {
				add_pollfd(&self, fd, POLLIN | POLLPRI, true);
				buxton_debug("Added fd %d type SOCKET\n", fd);
			}
		}
	}

	if (smackfd >= 0) {
		/* add Smack rule fd to pollfds */
		add_pollfd(&self, smackfd, POLLIN | POLLPRI, false);
	}

	buxton_log("%s: Started\n", argv[0]);

	/* Enter loop to accept clients */
	for (;;) {
		ret = poll(self.pollfds, self.nfds, -1);

		if (ret < 0) {
			buxton_log("poll(): %m\n");
			if (errno == EINTR) {
				if (do_shutdown)
					break;
				else
					continue;
			}
			break;
		}
		if (ret == 0)
			continue;

		for (nfds_t i=0; i<self.nfds; i++) {
			client_list_item *cl = NULL;
			char discard[256];

			if (self.pollfds[i].revents == 0)
				continue;

			if (self.pollfds[i].fd == -1) {
				/* TODO: Remove client from list  */
				buxton_debug("Removing / Closing client for fd %d\n", self.pollfds[i].fd);
				del_pollfd(&self, i);
				continue;
			}

			if (smackfd >= 0) {
				if (self.pollfds[i].fd == smackfd) {
					if (!buxton_cache_smack_rules())
						exit(EXIT_FAILURE);
					buxton_log("Reloaded Smack access rules\n");
					/* discard inotify data itself */
					while (read(smackfd, &discard, 256) == 256);
					continue;
				}
			}

			if (self.accepting[i] == true) {
				struct timeval tv;
				int fd;
				int on = 1;

				addr_len = sizeof(remote);

				if ((fd = accept(self.pollfds[i].fd,
				    (struct sockaddr *)&remote, &addr_len)) == -1) {
					buxton_log("accept(): %m\n");
					break;
				}

				buxton_debug("New client fd %d connected through fd %d\n", fd, self.pollfds[i].fd);

				cl = malloc0(sizeof(client_list_item));
				if (!cl)
					exit(EXIT_FAILURE);

				LIST_INIT(client_list_item, item, cl);

				cl->fd = fd;
				cl->cred = (struct ucred) {0, 0, 0};
				LIST_PREPEND(client_list_item, item, self.client_list, cl);

				/* poll for data on this new client as well */
				add_pollfd(&self, cl->fd, POLLIN | POLLPRI, false);

				/* Mark our packets as high prio */
				if (setsockopt(cl->fd, SOL_SOCKET, SO_PRIORITY, &on, sizeof(on)) == -1)
					buxton_log("setsockopt(SO_PRIORITY): %m\n");

				/* Set socket recv timeout */
				tv.tv_sec = SOCKET_TIMEOUT;
				tv.tv_usec = 0;
				if (setsockopt(cl->fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv,
					       sizeof(struct timeval)) == -1)
					buxton_log("setsockopt(SO_RCVTIMEO): %m\n");

				/* check if this is optimal or not */
				break;
			}

			assert(self.accepting[i] == 0);
			if (smackfd >= 0)
				assert(self.pollfds[i].fd != smackfd);

			/* handle data on any connection */
			/* TODO: Replace with hash table lookup */
			LIST_FOREACH(item, cl, self.client_list)
				if (self.pollfds[i].fd == cl->fd)
					break;

			assert(cl);
			handle_client(&self, cl, i);
		}
	}

	buxton_log("%s: Closing all connections\n", argv[0]);

	if (manual_start)
		unlink(BUXTON_SOCKET);
	for (int i = 0; i < self.nfds; i++) {
		close(self.pollfds[i].fd);
	}
	for (client_list_item *i = self.client_list; i;) {
		client_list_item *j = i->item_next;
		free(i);
		i = j;
	}
	hashmap_free(self.notify_mapping);
	buxton_direct_close(&self.buxton);
	return EXIT_SUCCESS;
}