xref: /freebsd/sbin/ipf/libipf/save_file.c (revision 4d846d26)
1 #include "ipf.h"
2 #include "ipmon.h"
3 
4 static void *file_parse(char **);
5 static void file_destroy(void *);
6 static int file_send(void *, ipmon_msg_t *);
7 static void file_print(void *);
8 static int file_match(void *, void *);
9 static void *file_dup(void *);
10 
11 typedef struct file_opts_s {
12 	FILE	*fp;
13 	int	raw;
14 	char	*path;
15 	int	ref;
16 } file_opts_t;
17 
18 ipmon_saver_t filesaver = {
19 	"file",
20 	file_destroy,
21 	file_dup,
22 	file_match,
23 	file_parse,
24 	file_print,
25 	file_send
26 };
27 
28 
29 static void *
30 file_parse(char **strings)
31 {
32 	file_opts_t *ctx;
33 
34 	ctx = calloc(1, sizeof(*ctx));
35 	if (ctx == NULL)
36 		return (NULL);
37 
38 	if (strings[0] != NULL && strings[0][0] != '\0') {
39 		ctx->ref = 1;
40 		if (!strncmp(strings[0], "raw://", 6)) {
41 			ctx->raw = 1;
42 			ctx->path = strdup(strings[0] + 6);
43 			ctx->fp = fopen(ctx->path, "ab");
44 		} else if (!strncmp(strings[0], "file://", 7)) {
45 			ctx->path = strdup(strings[0] + 7);
46 			ctx->fp = fopen(ctx->path, "a");
47 		} else {
48 			free(ctx);
49 			ctx = NULL;
50 		}
51 	} else {
52 		free(ctx);
53 		ctx = NULL;
54 	}
55 
56 	return (ctx);
57 }
58 
59 
60 static int
61 file_match(void *ctx1, void *ctx2)
62 {
63 	file_opts_t *f1 = ctx1, *f2 = ctx2;
64 
65 	if (f1->raw != f2->raw)
66 		return (1);
67 	if (strcmp(f1->path, f2->path))
68 		return (1);
69 	return (0);
70 }
71 
72 
73 static void *
74 file_dup(void *ctx)
75 {
76 	file_opts_t *f = ctx;
77 
78 	f->ref++;
79 	return (f);
80 }
81 
82 
83 static void
84 file_print(void *ctx)
85 {
86 	file_opts_t *file = ctx;
87 
88 	if (file->raw)
89 		printf("raw://");
90 	else
91 		printf("file://");
92 	printf("%s", file->path);
93 }
94 
95 
96 static void
97 file_destroy(void *ctx)
98 {
99 	file_opts_t *file = ctx;
100 
101 	file->ref--;
102 	if (file->ref > 0)
103 		return;
104 
105 	if (file->path != NULL)
106 		free(file->path);
107 	free(file);
108 }
109 
110 
111 static int
112 file_send(void *ctx, ipmon_msg_t *msg)
113 {
114 	file_opts_t *file = ctx;
115 
116 	if (file->raw) {
117 		fwrite(msg->imm_data, msg->imm_dsize, 1, file->fp);
118 	} else {
119 		fprintf(file->fp, "%s", msg->imm_msg);
120 	}
121 	return (0);
122 }
123 
124