fixed typo
[rxpd] / src / rxpd_rule.c
1 /*
2     rxpd_rule.c - regex policy daemon
3
4   Copyright (C)
5     2007,               Christian Thaeter <ct@pipapo.org>
6
7   This program is free software; you can redistribute it and/or
8   modify it under the terms of the GNU General Public License as
9   published by the Free Software Foundation; either version 2 of the
10   License, or (at your option) any later version.
11
12   This program is distributed in the hope that it will be useful,
13   but WITHOUT ANY WARRANTY; without even the implied warranty of
14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   GNU General Public License for more details.
16
17   You should have received a copy of the GNU General Public License
18   along with this program; if not, write to the Free Software
19   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 #include "rxpd.h"
23
24 struct rxpd_rule*
25 rxpd_rule_new (const char* buf, struct rxpd_base* base)
26 {
27   struct rxpd_rule* self = rxpd_malloc (sizeof (struct rxpd_rule));
28
29   llist_init (&self->node);
30   self->atime = (time_t)-1;
31   self->base = base;
32
33   if (*buf != '#')
34     {
35       int err;
36       char* namestart = strchr (buf, ':');
37       char* rxstart = namestart? strchr (namestart+1, ':') : NULL;
38
39       if (!rxstart || *(rxstart-1) == '>')
40           self->string = rxpd_strdup ("#ERROR: Syntax error, line was neither a comment nor a rule");
41       else
42         {
43           if (namestart != buf)
44             {
45               /* atime given */
46               self->atime = atoi (buf);
47               if (!self->atime)
48                 /* atime was zero or not set */
49                 self->atime = time (NULL)-1;
50             }
51
52           err = regcomp (&self->rx, rxstart+1, base->regflags|REG_EXTENDED|REG_NOSUB);
53
54           if (!err)
55             self->string = rxpd_strdup (namestart+1);
56           else
57             {
58               char ebuf[256];
59               size_t len = regerror (err, NULL, ebuf, 256);
60               self->string = rxpd_malloc (len + strlen(namestart+1) + 14);
61               strcpy (self->string, "#ERROR: ");
62               strcat (self->string, ebuf);
63               strcat (self->string, " in '");
64               strcat (self->string, namestart+1);
65               strcat (self->string, "'");
66             }
67         }
68     }
69   else
70     self->string = rxpd_strdup (buf);
71
72   return self;
73 }
74
75 struct rxpd_rule*
76 rxpd_rule_copy (const struct rxpd_rule* src)
77 {
78   struct rxpd_rule* self = rxpd_malloc (sizeof (struct rxpd_rule));
79
80   llist_init (&self->node);
81   self->string = rxpd_strdup (src->string);
82   self->atime = src->atime;
83
84   if (*self->string != '#')
85     {
86       int err;
87       char* rxstart = strchr (self->string, ':');
88
89       err = regcomp (&self->rx, rxstart+1, src->base->regflags|REG_EXTENDED|REG_NOSUB);
90       if (err)
91         rxpd_die ("unexpected regcomp error\n");
92     }
93
94   return self;
95 }
96
97 struct rxpd_rule*
98 rxpd_rule_activate (struct rxpd_rule* self)
99 {
100   if (self)
101     {
102       char* buf;
103       if (self->string[0] == '#' && (buf = strstr (self->string, ": ")+2) && *buf)
104         {
105           if (*buf != '#')
106             {
107               char* namestart = strchr (buf, ':');
108               char* rxstart = namestart? strchr (namestart+1, ':') : NULL;
109
110               if (!rxstart)
111                 return NULL;
112
113               if (regcomp (&self->rx, rxstart+1, self->base->regflags|REG_EXTENDED|REG_NOSUB))
114                 return NULL;
115
116               free (self->string);
117               self->string = rxpd_strdup (namestart+1);
118
119               if (namestart != buf)
120                 {
121                   /* atime given */
122                   self->atime = atoi (buf);
123                   if (!self->atime)
124                     /* atime was zero or not set */
125                     self->atime = time (NULL)-1;
126                 }
127             }
128           else
129             self->string = rxpd_strdup (buf);
130         }
131       else
132         return NULL;
133     }
134   return self;
135 }
136
137 struct rxpd_rule*
138 rxpd_rule_comment (struct rxpd_rule* self, const char* comment)
139 {
140   if (self)
141     {
142       int len;
143       if (self->atime != -1)
144         len = snprintf (NULL, 0, "#%s: %ld:%s", comment, self->atime, self->string);
145       else if (self->string[0] != '#')
146         len = snprintf (NULL, 0, "#%s: :%s", comment, self->string);
147       else
148         len = snprintf (NULL, 0, "#%s: %s", comment, self->string);
149
150       if (len < 0)
151         return NULL;
152
153       char* dst = rxpd_malloc (len+1);
154
155       if (self->atime != -1)
156         snprintf (dst, len+1, "#%s: %ld:%s", comment, self->atime, self->string);
157       else if (self->string[0] != '#')
158         snprintf (dst, len+1, "#%s: :%s", comment, self->string);
159       else
160         snprintf (dst, len+1, "#%s: %s", comment, self->string);
161
162       if (self->string[0] != '#')
163         regfree (&self->rx);
164
165       self->atime = -1;
166
167       free (self->string);
168       self->string = dst;
169     }
170   return self;
171 }
172
173 void
174 rxpd_rule_delete (struct rxpd_rule* rule)
175 {
176   if (rule)
177     {
178       llist_unlink (&rule->node);
179       if (rule->string[0] != '#')
180         regfree (&rule->rx);
181       free (rule->string);
182       free(rule);
183     }
184 }
185
186