add ebtablesu scheme, along with general cleanup
diff --git a/communication.c b/communication.c
index af00fa2..81fca22 100644
--- a/communication.c
+++ b/communication.c
@@ -31,15 +31,19 @@
 
 int sockfd = -1;
 
-static void get_sockfd()
+static int get_sockfd()
 {
+	int ret = 0;
 	if (sockfd == -1) {
 		sockfd = socket(AF_INET, SOCK_RAW, PF_INET);
-		if (sockfd < 0)
+		if (sockfd < 0) {
 			ebt_print_error("Problem getting a socket, "
 					"you probably don't have the right "
 					"permissions");
+			ret = -1;
+		}
 	}
+	return ret;
 }
 
 static struct ebt_replace * translate_user2kernel(struct ebt_u_replace *u_repl)
@@ -62,7 +66,7 @@
 	new->nentries = u_repl->nentries;
 	new->num_counters = u_repl->num_counters;
 	new->counters = sparc_cast u_repl->counters;
-	/* determine nr of udc */
+	/* Determine nr of udc */
 	i = 0;
 	cl = u_repl->udc;
 	while (cl) {
@@ -71,7 +75,7 @@
 	}
 	i += NF_BR_NUMHOOKS;
 	chain_offsets = (unsigned int *)malloc(i * sizeof(unsigned int));
-	/* determine size */
+	/* Determine size */
 	i = 0;
 	cl = u_repl->udc;
 	while (1) {
@@ -109,7 +113,7 @@
 			   sizeof(struct ebt_entry_target);
 			e = e->next;
 		}
-		/* a little sanity check */
+		/* A little sanity check */
 		if (j != entries->nentries)
 			ebt_print_bug("Wrong nentries: %d != %d, hook = %s", j,
 			   entries->nentries, entries->name);
@@ -123,7 +127,7 @@
 	if (!p)
 		ebt_print_memory();
 
-	/* put everything in one block */
+	/* Put everything in one block */
 	new->entries = sparc_cast p;
 	i = 0;
 	cl = u_repl->udc;
@@ -147,7 +151,7 @@
 		hlp->policy = entries->policy;
 		strcpy(hlp->name, entries->name);
 		hlp->counter_offset = entries->counter_offset;
-		hlp->distinguisher = 0; /* make the kernel see the light */
+		hlp->distinguisher = 0; /* Make the kernel see the light */
 		p += sizeof(struct ebt_entries);
 		e = entries->entries;
 		while (e) {
@@ -192,7 +196,7 @@
 			if (!strcmp(e->t->u.name, EBT_STANDARD_TARGET)) {
 				struct ebt_standard_target *st =
 				   (struct ebt_standard_target *)p;
-				/* translate the jump to a udc */
+				/* Translate the jump to a udc */
 				if (st->verdict >= 0)
 					st->verdict = chain_offsets
 					   [st->verdict + NF_BR_NUMHOOKS];
@@ -207,7 +211,7 @@
 		i++;
 	}
 
-	/* sanity check */
+	/* Sanity check */
 	if (p - (char *)new->entries != new->entries_size)
 		ebt_print_bug("Entries_size bug");
 	free(chain_offsets);
@@ -220,19 +224,22 @@
 	int size;
 	FILE *file;
 
-	/* start from an empty file with right priviliges */
+	/* Start from an empty file with right priviliges */
 	command = (char *)malloc(strlen(filename) + 15);
 	if (!command)
 		ebt_print_memory();
 	strcpy(command, "cat /dev/null>");
 	strcpy(command + 14, filename);
-	if (system(command))
+	if (system(command)) {
 		ebt_print_error("Couldn't create file %s", filename);
+		goto free_command;
+	}
 	strcpy(command, "chmod 600 ");
 	strcpy(command + 10, filename);
-	if (system(command))
+	if (system(command)) {
 		ebt_print_error("Couldn't chmod file %s", filename);
-	free(command);
+		goto free_command;
+	}
 
 	size = sizeof(struct ebt_replace) + repl->entries_size +
 	   repl->nentries * sizeof(struct ebt_counter);
@@ -242,18 +249,20 @@
 	memcpy(data, repl, sizeof(struct ebt_replace));
 	memcpy(data + sizeof(struct ebt_replace), (char *)repl->entries,
 	   repl->entries_size);
-	/* initialize counters to zero, deliver_counters() can update them */
+	/* Initialize counters to zero, deliver_counters() can update them */
 	memset(data + sizeof(struct ebt_replace) + repl->entries_size,
 	   0, repl->nentries * sizeof(struct ebt_counter));
-	if (!(file = fopen(filename, "wb")))
+	if (!(file = fopen(filename, "wb"))) {
 		ebt_print_error("Couldn't open file %s", filename);
-	if (fwrite(data, sizeof(char), size, file) != size) {
-		fclose(file);
+		goto free_data;
+	} else if (fwrite(data, sizeof(char), size, file) != size)
 		ebt_print_error("Couldn't write everything to file %s",
 				filename);
-	}
 	fclose(file);
+free_data:
 	free(data);
+free_command:
+	free(command);
 }
 
 void ebt_deliver_table(struct ebt_u_replace *u_repl)
@@ -261,19 +270,20 @@
 	socklen_t optlen;
 	struct ebt_replace *repl;
 
-	/* translate the struct ebt_u_replace to a struct ebt_replace */
+	/* Translate the struct ebt_u_replace to a struct ebt_replace */
 	repl = translate_user2kernel(u_repl);
 	if (u_repl->filename != NULL) {
 		store_table_in_file(u_repl->filename, repl);
 		return;
 	}
-	/* give the data to the kernel */
+	/* Give the data to the kernel */
 	optlen = sizeof(struct ebt_replace) + repl->entries_size;
-	get_sockfd();
+	if (get_sockfd())
+		return;
 	if (!setsockopt(sockfd, IPPROTO_IP, EBT_SO_SET_ENTRIES, repl, optlen))
 		return;
-	if (u_repl->command == 8) { /* the ebtables module may not
-	                            * yet be loaded with --atomic-commit */
+	if (u_repl->command == 8) { /* The ebtables module may not
+	                             * yet be loaded with --atomic-commit */
 		ebtables_insmod("ebtables");
 		if (!setsockopt(sockfd, IPPROTO_IP, EBT_SO_SET_ENTRIES,
 		    repl, optlen))
@@ -285,41 +295,46 @@
 		    " the extension");
 }
 
-static void store_counters_in_file(char *filename, struct ebt_u_replace *repl)
+static int store_counters_in_file(char *filename, struct ebt_u_replace *repl)
 {
-	int size = repl->nentries * sizeof(struct ebt_counter);
+	int size = repl->nentries * sizeof(struct ebt_counter), ret = 0;
 	unsigned int entries_size;
 	struct ebt_replace hlp;
 	FILE *file;
 
-	if (!(file = fopen(filename, "r+b")))
+	if (!(file = fopen(filename, "r+b"))) {
 		ebt_print_error("Could not open file %s", filename);
-	/* 
-	 * find out entries_size and then set the file pointer to the
-	 * counters
-	 */
+		return -1;
+	}
+	/* Find out entries_size and then set the file pointer to the
+	 * counters */
 	if (fseek(file, (char *)(&hlp.entries_size) - (char *)(&hlp), SEEK_SET)
 	   || fread(&entries_size, sizeof(char), sizeof(unsigned int), file) !=
 	   sizeof(unsigned int) ||
 	   fseek(file, entries_size + sizeof(struct ebt_replace), SEEK_SET)) {
-		fclose(file);
 		ebt_print_error("File %s is corrupt", filename);
+		ret = -1;
+		goto close_file;
 	}
 	if (fwrite(repl->counters, sizeof(char), size, file) != size) {
-		fclose(file);
 		ebt_print_error("Could not write everything to file %s",
 				filename);
+		ret = -1;
 	}
+close_file:
 	fclose(file);
+	return 0;
 }
 
-/* gets executed after ebt_deliver_table */
-void ebt_deliver_counters(struct ebt_u_replace *u_repl)
+/* Gets executed after ebt_deliver_table. Delivers the counters to the kernel
+ * and resets the counterchanges to CNT_NORM */
+void ebt_deliver_counters(struct ebt_u_replace *u_repl, int exec_style)
 {
 	struct ebt_counter *old, *new, *newcounters;
 	socklen_t optlen;
 	struct ebt_replace repl;
-	struct ebt_cntchanges *cc = u_repl->counterchanges;
+	struct ebt_cntchanges *cc = u_repl->counterchanges, *cc2, **cc3;
+	int i;
 
 	if (u_repl->nentries == 0)
 		return;
@@ -333,24 +348,22 @@
 	new = newcounters;
 	while (cc) {
 		if (cc->type == CNT_NORM) {
-			/*
-			 *'normal' rule, meaning we didn't do anything to it
-			 * So, we just copy
-			 */
+			/* 'Normal' rule, meaning we didn't do anything to it
+			 * So, we just copy */
 			new->pcnt = old->pcnt;
 			new->bcnt = old->bcnt;
-			/* we've used an old counter */
+			/* We've used an old counter */
 			old++;
-			/* we've set a new counter */
+			/* We've set a new counter */
 			new++;
 		} else if (cc->type == CNT_DEL) {
-			/* don't use this old counter */
+			/* Don't use this old counter */
 			old++;
 		} else if (cc->type == CNT_ADD) {
-			/* new counter, let it stay 0 */
+			/* New counter, let it stay 0 */
 			new++;
 		} else {
-			/* zero it (let it stay 0) */
+			/* Zero it (let it stay 0) */
 			old++;
 			new++;
 		}
@@ -366,20 +379,38 @@
 	}
 	optlen = u_repl->nentries * sizeof(struct ebt_counter) +
 	   sizeof(struct ebt_replace);
-	/* now put the stuff in the kernel's struct ebt_replace */
+	/* Now put the stuff in the kernel's struct ebt_replace */
 	repl.counters = sparc_cast u_repl->counters;
 	repl.num_counters = u_repl->num_counters;
 	memcpy(repl.name, u_repl->name, sizeof(repl.name));
 
-	get_sockfd();
+	if (get_sockfd())
+		return;
 	if (setsockopt(sockfd, IPPROTO_IP, EBT_SO_SET_COUNTERS, &repl, optlen))
 		ebt_print_bug("Couldn't update kernel counters");
+
+	if (exec_style != EXEC_STYLE_DAEMON)
+		return;
+	/* Reset the counterchanges to CNT_NORM */
+	cc = u_repl->counterchanges;
+	for (i = 0; i < u_repl->nentries; i++) {
+		cc->type = CNT_NORM;
+		cc3 = &cc->next;
+		cc = cc->next;
+	}
+	*cc3 = NULL;
+	while (cc) {
+		cc2 = cc->next;
+		free(cc);
+		cc = cc2;
+	}
 }
 
 static int
 ebt_translate_match(struct ebt_entry_match *m, struct ebt_u_match_list ***l)
 {
 	struct ebt_u_match_list *new;
+	int ret = 0;
 
 	new = (struct ebt_u_match_list *)
 	   malloc(sizeof(struct ebt_u_match_list));
@@ -393,10 +424,12 @@
 	new->next = NULL;
 	**l = new;
 	*l = &new->next;
-	if (ebt_find_match(new->m->u.name) == NULL)
+	if (ebt_find_match(new->m->u.name) == NULL) {
 		ebt_print_error("Kernel match %s unsupported by userspace tool",
 				new->m->u.name);
-	return 0;
+		ret = -1;
+	}
+	return ret;
 }
 
 static int
@@ -404,6 +437,7 @@
    struct ebt_u_watcher_list ***l)
 {
 	struct ebt_u_watcher_list *new;
+	int ret = 0;
 
 	new = (struct ebt_u_watcher_list *)
 	   malloc(sizeof(struct ebt_u_watcher_list));
@@ -417,10 +451,12 @@
 	new->next = NULL;
 	**l = new;
 	*l = &new->next;
-	if (ebt_find_watcher(new->w->u.name) == NULL)
+	if (ebt_find_watcher(new->w->u.name) == NULL) {
 		ebt_print_error("Kernel watcher %s unsupported by userspace "
 				"tool", new->w->u.name);
-	return 0;
+		ret = -1;
+	}
+	return ret;
 }
 
 static int
@@ -428,7 +464,7 @@
    int *totalcnt, struct ebt_u_entry ***u_e, struct ebt_u_replace *u_repl,
    unsigned int valid_hooks, char *base)
 {
-	/* an entry */
+	/* An entry */
 	if (e->bitmask & EBT_ENTRY_OR_ENTRIES) {
 		struct ebt_u_entry *new;
 		struct ebt_u_match_list **m_l;
@@ -440,7 +476,7 @@
 			ebt_print_memory();
 		new->bitmask = e->bitmask;
 		/*
-		 * plain userspace code doesn't know about
+		 * Plain userspace code doesn't know about
 		 * EBT_ENTRY_OR_ENTRIES
 		 */
 		new->bitmask &= ~EBT_ENTRY_OR_ENTRIES;
@@ -467,12 +503,14 @@
 		   malloc(t->target_size + sizeof(struct ebt_entry_target));
 		if (!new->t)
 			ebt_print_memory();
-		if (ebt_find_target(t->u.name) == NULL)
+		if (ebt_find_target(t->u.name) == NULL) {
 			ebt_print_error("Kernel target %s unsupported by "
 					"userspace tool", t->u.name);
+			return -1;
+		}
 		memcpy(new->t, t, t->target_size +
 		   sizeof(struct ebt_entry_target));
-		/* deal with jumps to udc */
+		/* Deal with jumps to udc */
 		if (!strcmp(t->u.name, EBT_STANDARD_TARGET)) {
 			char *tmp = base;
 			int verdict = ((struct ebt_standard_target *)t)->verdict;
@@ -488,7 +526,7 @@
 					cl = cl->next;
 				}
 				if (!cl)
-					ebt_print_bug("can't find udc for "
+					ebt_print_bug("Can't find udc for "
 						      "jump");
 				((struct ebt_standard_target *)new->t)->verdict = i;
 			}
@@ -500,7 +538,7 @@
 		(*cnt)++;
 		(*totalcnt)++;
 		return 0;
-	} else { /* a new chain */
+	} else { /* A new chain */
 		int i;
 		struct ebt_entries *entries = (struct ebt_entries *)e;
 		struct ebt_u_chain_list *cl;
@@ -513,8 +551,8 @@
 			if (valid_hooks & (1 << i))
 				break;
 		*hook = i;
-		/* makes use of fact that standard chains come before udc */
-		if (i >= NF_BR_NUMHOOKS) { /* udc */
+		/* Makes use of fact that standard chains come before udc */
+		if (i >= NF_BR_NUMHOOKS) { /* Udc */
 			i -= NF_BR_NUMHOOKS;
 			cl = u_repl->udc;
 			while (i-- > 0)
@@ -526,7 +564,7 @@
 	}
 }
 
-/* initialize all chain headers */
+/* Initialize all chain headers */
 static int
 ebt_translate_chains(struct ebt_entry *e, unsigned int *hook,
    struct ebt_u_replace *u_repl, unsigned int valid_hooks)
@@ -540,10 +578,10 @@
 		for (i = *hook + 1; i < NF_BR_NUMHOOKS; i++)
 			if (valid_hooks & (1 << i))
 				break;
-		/* makes use of fact that standard chains come before udc */
-		if (i >= NF_BR_NUMHOOKS) { /* udc */
+		/* Makes use of fact that standard chains come before udc */
+		if (i >= NF_BR_NUMHOOKS) { /* Udc */
 			chain_list = &u_repl->udc;
-			/* add in the back */
+			/* Add in the back */
 			while (*chain_list)
 				chain_list = &((*chain_list)->next);
 			*chain_list = (struct ebt_u_chain_list *)
@@ -556,10 +594,8 @@
 			if (!((*chain_list)->udc))
 				ebt_print_memory();
 			new = (*chain_list)->udc;
-			/*
-			 * ebt_translate_entry depends on this for knowing
-			 * to which chain is being jumped
-			 */
+			/* ebt_translate_entry depends on this for knowing
+			 * to which chain is being jumped */
 			(*chain_list)->kernel_start = (char *)e;
 		} else {
 			*hook = i;
@@ -578,19 +614,19 @@
 	return 0;
 }
 
-static void retrieve_from_file(char *filename, struct ebt_replace *repl,
+static int retrieve_from_file(char *filename, struct ebt_replace *repl,
    char command)
 {
 	FILE *file;
 	char *hlp = NULL, *entries;
 	struct ebt_counter *counters;
-	int size;
+	int size, ret = 0;
 
-	if (!(file = fopen(filename, "r+b")))
+	if (!(file = fopen(filename, "r+b"))) {
 		ebt_print_error("Could not open file %s", filename);
-	/*
-	 * make sure table name is right if command isn't -L or --atomic-commit
-	 */
+		return -1;
+	}
+	/* Make sure table name is right if command isn't -L or --atomic-commit */
 	if (command != 'L' && command != 8) {
 		hlp = (char *)malloc(strlen(repl->name) + 1);
 		if (!hlp)
@@ -598,25 +634,30 @@
 		strcpy(hlp, repl->name);
 	}
 	if (fread(repl, sizeof(char), sizeof(struct ebt_replace), file)
-	   != sizeof(struct ebt_replace))
+	   != sizeof(struct ebt_replace)) {
 		ebt_print_error("File %s is corrupt", filename);
+		ret = -1;
+		goto close_file;
+	}
 	if (command != 'L' && command != 8 && strcmp(hlp, repl->name)) {
-		fclose(file);
 		ebt_print_error("File %s contains wrong table name or is "
 				"corrupt", filename);
-		free(hlp);
+		ret = -1;
+		goto close_file;
 	} else if (!ebt_find_table(repl->name)) {
-		fclose(file);
 		ebt_print_error("File %s contains invalid table name",
 				filename);
+		ret = -1;
+		goto close_file;
 	}
 
 	size = sizeof(struct ebt_replace) +
 	   repl->nentries * sizeof(struct ebt_counter) + repl->entries_size;
 	fseek(file, 0, SEEK_END);
 	if (size != ftell(file)) {
-		fclose(file);
 		ebt_print_error("File %s has wrong size", filename);
+		ret -1;
+		goto close_file;
 	}
 	entries = (char *)malloc(repl->entries_size);
 	if (!entries)
@@ -630,7 +671,7 @@
 			ebt_print_memory();
 	} else
 		repl->counters = sparc_cast NULL;
-	/* copy entries and counters */
+	/* Copy entries and counters */
 	if (fseek(file, sizeof(struct ebt_replace), SEEK_SET) ||
 	   fread((char *)repl->entries, sizeof(char), repl->entries_size, file)
 	   != repl->entries_size ||
@@ -639,10 +680,15 @@
 	   || fread((char *)repl->counters, sizeof(char),
 	   repl->nentries * sizeof(struct ebt_counter), file)
 	   != repl->nentries * sizeof(struct ebt_counter)) {
-		fclose(file);
 		ebt_print_error("File %s is corrupt", filename);
+		free(entries);
+		repl->entries = NULL;
+		ret = -1;
 	}
+close_file:
 	fclose(file);
+	free(hlp);
+	return ret;
 }
 
 static int retrieve_from_kernel(struct ebt_replace *repl, char command,
@@ -653,7 +699,8 @@
 	char *entries;
 
 	optlen = sizeof(struct ebt_replace);
-	get_sockfd();
+	if (get_sockfd())
+		return -1;
 	/* --atomic-init || --init-table */
 	if (init)
 		optname = EBT_SO_GET_INIT_INFO;
@@ -676,7 +723,7 @@
 	else
 		repl->counters = sparc_cast NULL;
 
-	/* we want to receive the counters */
+	/* We want to receive the counters */
 	repl->num_counters = repl->nentries;
 	optlen += repl->entries_size + repl->num_counters *
 	   sizeof(struct ebt_counter);
@@ -685,7 +732,7 @@
 	else
 		optname = EBT_SO_GET_ENTRIES;
 	if (getsockopt(sockfd, IPPROTO_IP, optname, repl, &optlen))
-		ebt_print_bug("hmm, what is wrong??? bug#1");
+		ebt_print_bug("Hmm, what is wrong??? bug#1");
 
 	return 0;
 }
@@ -701,17 +748,16 @@
 	strcpy(repl.name, u_repl->name);
 	if (u_repl->filename != NULL) {
 		if (init)
-			ebt_print_bug("getting initial table data from a "
+			ebt_print_bug("Getting initial table data from a "
 				  "file is impossible");
-		retrieve_from_file(u_repl->filename, &repl, u_repl->command);
-		/*
-		 * -L with a wrong table name should be dealt with silently
-		 */
+		if (retrieve_from_file(u_repl->filename, &repl, u_repl->command))
+			return -1;
+		/* -L with a wrong table name should be dealt with silently */
 		strcpy(u_repl->name, repl.name);
-	} else if (retrieve_from_kernel(&repl, u_repl->command, init) == -1)
+	} else if (retrieve_from_kernel(&repl, u_repl->command, init))
 		return -1;
 
-	/* translate the struct ebt_replace to a struct ebt_u_replace */
+	/* Translate the struct ebt_replace to a struct ebt_u_replace */
 	u_repl->valid_hooks = repl.valid_hooks;
 	u_repl->nentries = repl.nentries;
 	u_repl->num_counters = repl.num_counters;
@@ -729,14 +775,13 @@
 		prev_cc = &(new_cc->next);
 	}
 	hook = -1;
+	/* FIXME: Clean up when an error is encountered */
 	EBT_ENTRY_ITERATE(repl.entries, repl.entries_size, ebt_translate_chains,
 	   &hook, u_repl, u_repl->valid_hooks);
-	i = 0; /* holds the expected nr. of entries for the chain */
-	j = 0; /* holds the up to now counted entries for the chain */
-	/*
-	 * holds the total nr. of entries,
-	 * should equal u_repl->nentries afterwards
-	 */
+	i = 0; /* Holds the expected nr. of entries for the chain */
+	j = 0; /* Holds the up to now counted entries for the chain */
+	/* Holds the total nr. of entries,
+	 * should equal u_repl->nentries afterwards */
 	k = 0;
 	hook = -1;
 	EBT_ENTRY_ITERATE((char *)repl.entries, repl.entries_size,