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