xref: /netbsd-src/external/bsd/ipf/dist/lib/load_file.c (revision 13885a665959c62f13a82b3caedf986eaa17aa31)
1*13885a66Sdarrenr /*	$NetBSD: load_file.c,v 1.2 2012/07/22 14:27:36 darrenr Exp $	*/
2bc4097aaSchristos 
3bc4097aaSchristos /*
4c9d5dc6cSdarrenr  * Copyright (C) 2012 by Darren Reed.
5bc4097aaSchristos  *
6bc4097aaSchristos  * See the IPFILTER.LICENCE file for details on licencing.
7bc4097aaSchristos  *
8*13885a66Sdarrenr  * Id: load_file.c,v 1.1.1.2 2012/07/22 13:44:39 darrenr Exp $
9bc4097aaSchristos  */
10bc4097aaSchristos 
11bc4097aaSchristos #include "ipf.h"
12bc4097aaSchristos #include <ctype.h>
13bc4097aaSchristos 
14bc4097aaSchristos alist_t *
load_file(char * filename)15bc4097aaSchristos load_file(char *filename)
16bc4097aaSchristos {
17bc4097aaSchristos 	alist_t *a, *rtop, *rbot;
18bc4097aaSchristos 	char *s, line[1024], *t;
19bc4097aaSchristos 	int linenum, not;
20bc4097aaSchristos 	FILE *fp;
21bc4097aaSchristos 
22bc4097aaSchristos 	fp = fopen(filename + 7, "r");
23bc4097aaSchristos 	if (fp == NULL) {
24bc4097aaSchristos 		fprintf(stderr, "load_file cannot open '%s'\n", filename);
25bc4097aaSchristos 		return NULL;
26bc4097aaSchristos 	}
27bc4097aaSchristos 
28bc4097aaSchristos 	a = NULL;
29bc4097aaSchristos 	rtop = NULL;
30bc4097aaSchristos 	rbot = NULL;
31bc4097aaSchristos 	linenum = 0;
32bc4097aaSchristos 
33bc4097aaSchristos 	while (fgets(line, sizeof(line) - 1, fp)) {
34bc4097aaSchristos 		line[sizeof(line) - 1] = '\0';
35bc4097aaSchristos 		linenum++;
36bc4097aaSchristos 		/*
37bc4097aaSchristos 		 * Hunt for CR/LF.  If no LF, stop processing.
38bc4097aaSchristos 		 */
39bc4097aaSchristos 		s = strchr(line, '\n');
40bc4097aaSchristos 		if (s == NULL) {
41bc4097aaSchristos 			fprintf(stderr, "%d:%s: line too long\n",
42bc4097aaSchristos 				linenum, filename);
43bc4097aaSchristos 			fclose(fp);
44bc4097aaSchristos 			alist_free(rtop);
45bc4097aaSchristos 			return NULL;
46bc4097aaSchristos 		}
47bc4097aaSchristos 
48bc4097aaSchristos 		/*
49bc4097aaSchristos 		 * Remove trailing spaces
50bc4097aaSchristos 		 */
51bc4097aaSchristos 		for (; ISSPACE(*s); s--)
52bc4097aaSchristos 			*s = '\0';
53bc4097aaSchristos 
54bc4097aaSchristos 		s = strchr(line, '\r');
55bc4097aaSchristos 		if (s != NULL)
56bc4097aaSchristos 			*s = '\0';
57bc4097aaSchristos 		for (t = line; ISSPACE(*t); t++)
58bc4097aaSchristos 			;
59bc4097aaSchristos 		if (*t == '!') {
60bc4097aaSchristos 			not = 1;
61bc4097aaSchristos 			t++;
62bc4097aaSchristos 		} else
63bc4097aaSchristos 			not = 0;
64bc4097aaSchristos 
65bc4097aaSchristos 		/*
66bc4097aaSchristos 		 * Remove comment markers
67bc4097aaSchristos 		 */
68bc4097aaSchristos 		s = strchr(t, '#');
69bc4097aaSchristos 		if (s != NULL) {
70bc4097aaSchristos 			*s = '\0';
71bc4097aaSchristos 			if (s == t)
72bc4097aaSchristos 				continue;
73bc4097aaSchristos 		}
74bc4097aaSchristos 
75bc4097aaSchristos 		/*
76bc4097aaSchristos 		 * Trim off tailing white spaces
77bc4097aaSchristos 		 */
78bc4097aaSchristos 		s = strlen(t) + t - 1;
79bc4097aaSchristos 		while (ISSPACE(*s))
80bc4097aaSchristos 			*s-- = '\0';
81bc4097aaSchristos 
82bc4097aaSchristos 		a = alist_new(AF_UNSPEC, t);
83bc4097aaSchristos 		if (a != NULL) {
84bc4097aaSchristos 			a->al_not = not;
85bc4097aaSchristos 			if (rbot != NULL)
86bc4097aaSchristos 				rbot->al_next = a;
87bc4097aaSchristos 			else
88bc4097aaSchristos 				rtop = a;
89bc4097aaSchristos 			rbot = a;
90bc4097aaSchristos 		} else {
91bc4097aaSchristos 			fprintf(stderr, "%s:%d unrecognised content :%s\n",
92bc4097aaSchristos 				filename, linenum, t);
93bc4097aaSchristos 		}
94bc4097aaSchristos 	}
95bc4097aaSchristos 	fclose(fp);
96bc4097aaSchristos 
97bc4097aaSchristos 	return rtop;
98bc4097aaSchristos }
99