1 /*
2     pmacct (Promiscuous mode IP Accounting package)
3     pmacct is Copyright (C) 2003-2020 by Paolo Lucente
4 */
5 
6 /*
7     This program is free software; you can redistribute it and/or modify
8     it under the terms of the GNU General Public License as published by
9     the Free Software Foundation; either version 2 of the License, or
10     (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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */
21 
22 #include "pmacct.h"
23 #include "sql_common.h"
24 
AddToLRUTail(struct db_cache * Cursor)25 void AddToLRUTail(struct db_cache *Cursor)
26 {
27   if (Cursor == lru_tail) return;
28 
29   if (Cursor->lru_prev) {
30     if (Cursor->lru_next) {
31       Cursor->lru_prev->lru_next = Cursor->lru_next;
32       Cursor->lru_next->lru_prev = Cursor->lru_prev;
33     }
34     else Cursor->lru_prev->lru_next = NULL;
35   }
36   else {
37     if (Cursor->lru_next) Cursor->lru_next->lru_prev = NULL;
38   }
39 
40   Cursor->lru_prev = lru_tail;
41   Cursor->lru_prev->lru_next = Cursor;
42   Cursor->lru_next = NULL;
43   lru_tail = Cursor;
44 }
45 
RetireElem(struct db_cache * Cursor)46 void RetireElem(struct db_cache *Cursor)
47 {
48   assert(Cursor->prev);
49   assert(Cursor->lru_prev);
50 
51   if (Cursor->lru_next) {
52     Cursor->lru_prev->lru_next = Cursor->lru_next;
53     Cursor->lru_next->lru_prev = Cursor->lru_prev;
54   }
55   else {
56     /* no lru_next: we are tail! */
57     assert(Cursor == lru_tail);
58 
59     Cursor->lru_prev->lru_next = NULL;
60     lru_tail = Cursor->lru_prev;
61   }
62 
63   if (Cursor->next) {
64     Cursor->prev->next = Cursor->next;
65     Cursor->next->prev = Cursor->prev;
66   }
67   else Cursor->prev->next = NULL;
68 
69   if (Cursor->pbgp) free(Cursor->pbgp);
70   if (Cursor->pnat) free(Cursor->pnat);
71   if (Cursor->pmpls) free(Cursor->pmpls);
72   if (Cursor->ptun) free(Cursor->ptun);
73   if (Cursor->pcust) free(Cursor->pcust);
74   if (Cursor->pvlen) free(Cursor->pvlen);
75   if (Cursor->stitch) free(Cursor->stitch);
76 
77   free(Cursor);
78 }
79 
BuildChain(struct db_cache * Cursor,struct db_cache * newElem)80 void BuildChain(struct db_cache *Cursor, struct db_cache *newElem)
81 {
82   Cursor->next = newElem;
83   newElem->prev = Cursor;
84   newElem->chained = TRUE;
85 }
86 
ReBuildChain(struct db_cache * Cursor,struct db_cache * newElem)87 void ReBuildChain(struct db_cache *Cursor, struct db_cache *newElem)
88 {
89   assert(Cursor != newElem);
90 
91   if (newElem->next) {
92     newElem->prev->next = newElem->next;
93     newElem->next->prev = newElem->prev;
94   }
95   else newElem->prev->next = NULL;
96 
97   Cursor->next = newElem;
98   newElem->prev = Cursor;
99   newElem->next = NULL;
100 }
101 
SwapChainedElems(struct db_cache * Cursor,struct db_cache * staleElem)102 void SwapChainedElems(struct db_cache *Cursor, struct db_cache *staleElem)
103 {
104   struct db_cache *auxPtr;
105 
106   assert(Cursor != staleElem);
107   assert(Cursor->prev);
108   assert(staleElem->prev);
109 
110   /* Specific cases first */
111   if (Cursor == staleElem->prev) {
112     staleElem->prev = Cursor->prev;
113     Cursor->next = staleElem->next;
114     staleElem->next = Cursor;
115     Cursor->prev = staleElem;
116     staleElem->prev->next = staleElem;
117     if (Cursor->next) Cursor->next->prev = Cursor;
118   }
119   else if (staleElem == Cursor->prev) {
120     Cursor->prev = staleElem->prev;
121     staleElem->next = Cursor->next;
122     Cursor->next = staleElem;
123     staleElem->prev = Cursor;
124     Cursor->prev->next = Cursor;
125     if (staleElem->next) staleElem->next->prev = staleElem;
126   }
127   /* General case */
128   else {
129     auxPtr = Cursor->prev;
130     Cursor->prev = staleElem->prev;
131     Cursor->prev->next = Cursor;
132     staleElem->prev = auxPtr;
133     staleElem->prev->next = staleElem;
134 
135     auxPtr = Cursor->next;
136     Cursor->next = staleElem->next;
137     if (Cursor->next) Cursor->next->prev = Cursor;
138     staleElem->next = auxPtr;
139     if (staleElem->next) staleElem->next->prev = staleElem;
140   }
141 }
142 
SQL_SetENV()143 void SQL_SetENV()
144 {
145   char *ptrs[16];
146   int count = 0, i;
147 
148   INIT_BUF(envbuf);
149   memset(ptrs, 0, sizeof(ptrs));
150 
151   if (config.sql_db) {
152     strncat(envbuf.ptr, "SQL_DB=", (envbuf.end-envbuf.ptr - 1));
153     strncat(envbuf.ptr, config.sql_db, envbuf.end-envbuf.ptr);
154     ptrs[count] = envbuf.ptr;
155     envbuf.ptr += strlen(envbuf.ptr)+1;
156     count++;
157   }
158 
159   if (config.sql_table) {
160     strncat(envbuf.ptr, "SQL_TABLE=", envbuf.end-envbuf.ptr);
161     strncat(envbuf.ptr, config.sql_table, envbuf.end-envbuf.ptr);
162     ptrs[count] = envbuf.ptr;
163     envbuf.ptr += strlen(envbuf.ptr)+1;
164     count++;
165   }
166 
167   if (config.sql_host) {
168     strncat(envbuf.ptr, "SQL_HOST=", envbuf.end-envbuf.ptr);
169     strncat(envbuf.ptr, config.sql_host, envbuf.end-envbuf.ptr);
170     ptrs[count] = envbuf.ptr;
171     envbuf.ptr += strlen(envbuf.ptr)+1;
172     count++;
173   }
174 
175   if (config.sql_user) {
176     strncat(envbuf.ptr, "SQL_USER=", envbuf.end-envbuf.ptr);
177     strncat(envbuf.ptr, config.sql_user, envbuf.end-envbuf.ptr);
178     ptrs[count] = envbuf.ptr;
179     envbuf.ptr += strlen(envbuf.ptr)+1;
180     count++;
181   }
182 
183   {
184     char *tmpptr;
185 
186     strncat(envbuf.ptr, "SQL_REFRESH_TIME=", envbuf.end-envbuf.ptr);
187     tmpptr = envbuf.ptr + strlen(envbuf.ptr);
188     snprintf(tmpptr, envbuf.end-tmpptr, "%d", config.sql_refresh_time);
189     ptrs[count] = envbuf.ptr;
190     envbuf.ptr += strlen(envbuf.ptr)+1;
191     count++;
192   }
193 
194   if (config.sampling_rate >= 1 || config.ext_sampling_rate >= 1) {
195     char *tmpptr;
196 
197     strncat(envbuf.ptr, "SAMPLING_RATE=", envbuf.end-envbuf.ptr);
198     tmpptr = envbuf.ptr + strlen(envbuf.ptr);
199     snprintf(tmpptr, envbuf.end-tmpptr, "%d", config.sampling_rate ? config.sampling_rate : config.ext_sampling_rate);
200     ptrs[count] = envbuf.ptr;
201     envbuf.ptr += strlen(envbuf.ptr)+1;
202     count++;
203   }
204 
205   if (config.sql_backup_host) {
206     strncat(envbuf.ptr, "SQL_RECOVERY_BACKUP_HOST=", envbuf.end-envbuf.ptr);
207     strncat(envbuf.ptr, config.sql_backup_host, envbuf.end-envbuf.ptr);
208     ptrs[count] = envbuf.ptr;
209     envbuf.ptr += strlen(envbuf.ptr)+1;
210     count++;
211   }
212 
213   {
214     char *tmpptr;
215 
216     strncat(envbuf.ptr, "SQL_MAX_WRITERS=", envbuf.end-envbuf.ptr);
217     tmpptr = envbuf.ptr + strlen(envbuf.ptr);
218     snprintf(tmpptr, envbuf.end-tmpptr, "%d", dump_writers_get_max());
219     ptrs[count] = envbuf.ptr;
220     envbuf.ptr += strlen(envbuf.ptr)+1;
221     count++;
222   }
223 
224   for (i = 0; i < count; i++)
225     putenv(ptrs[i]);
226 }
227 
SQL_SetENV_child(const struct insert_data * idata)228 void SQL_SetENV_child(const struct insert_data *idata)
229 {
230   char *ptrs[N_FUNCS];
231   int count = 0, i;
232 
233   memset(ptrs, 0, sizeof(ptrs));
234 
235   {
236     char *tmpptr;
237 
238     strncat(envbuf.ptr, "INSERT_QUERIES_NUMBER=", envbuf.end-envbuf.ptr);
239     tmpptr = envbuf.ptr + strlen(envbuf.ptr);
240     snprintf(tmpptr, envbuf.end-tmpptr, "%d", idata->iqn);
241     ptrs[count] = envbuf.ptr;
242     envbuf.ptr += strlen(envbuf.ptr)+1;
243     count++;
244   }
245 
246   {
247     char *tmpptr;
248 
249     strncat(envbuf.ptr, "UPDATE_QUERIES_NUMBER=", envbuf.end-envbuf.ptr);
250     tmpptr = envbuf.ptr + strlen(envbuf.ptr);
251     snprintf(tmpptr, envbuf.end-tmpptr, "%d", idata->uqn);
252     ptrs[count] = envbuf.ptr;
253     envbuf.ptr += strlen(envbuf.ptr)+1;
254     count++;
255   }
256 
257   {
258     char *tmpptr;
259 
260     strncat(envbuf.ptr, "ELAPSED_TIME=", envbuf.end-envbuf.ptr);
261     tmpptr = envbuf.ptr + strlen(envbuf.ptr);
262     snprintf(tmpptr, envbuf.end-tmpptr, "%lu", idata->elap_time);
263     ptrs[count] = envbuf.ptr;
264     envbuf.ptr += strlen(envbuf.ptr)+1;
265     count++;
266   }
267 
268   {
269     char *tmpptr;
270 
271     strncat(envbuf.ptr, "TOTAL_ELEM_NUMBER=", envbuf.end-envbuf.ptr);
272     tmpptr = envbuf.ptr + strlen(envbuf.ptr);
273     snprintf(tmpptr, envbuf.end-tmpptr, "%d", idata->ten);
274     ptrs[count] = envbuf.ptr;
275     envbuf.ptr += strlen(envbuf.ptr)+1;
276     count++;
277   }
278 
279   {
280     char *tmpptr;
281 
282     strncat(envbuf.ptr, "EFFECTIVE_ELEM_NUMBER=", envbuf.end-envbuf.ptr);
283     tmpptr = envbuf.ptr + strlen(envbuf.ptr);
284     snprintf(tmpptr, envbuf.end-tmpptr, "%u", idata->een);
285     ptrs[count] = envbuf.ptr;
286     envbuf.ptr += strlen(envbuf.ptr)+1;
287     count++;
288   }
289 
290   if (idata->basetime) {
291     char *tmpptr;
292 
293     strncat(envbuf.ptr, "SQL_HISTORY_BASETIME=", envbuf.end-envbuf.ptr);
294     tmpptr = envbuf.ptr + strlen(envbuf.ptr);
295     snprintf(tmpptr, envbuf.end-tmpptr, "%lu", idata->basetime);
296     ptrs[count] = envbuf.ptr;
297     envbuf.ptr += strlen(envbuf.ptr)+1;
298     count++;
299   }
300 
301   if (idata->timeslot) {
302     char *tmpptr;
303 
304     strncat(envbuf.ptr, "SQL_HISTORY_TIMESLOT=", envbuf.end-envbuf.ptr);
305     tmpptr = envbuf.ptr + strlen(envbuf.ptr);
306     snprintf(tmpptr, envbuf.end-tmpptr, "%lu", idata->timeslot);
307     ptrs[count] = envbuf.ptr;
308     envbuf.ptr += strlen(envbuf.ptr)+1;
309     count++;
310   }
311 
312   if (idata->dyn_table) {
313     char *tmpptr;
314 
315     strncat(envbuf.ptr, "EFFECTIVE_SQL_TABLE=", envbuf.end-envbuf.ptr);
316     tmpptr = envbuf.ptr + strlen(envbuf.ptr);
317     pm_strftime(tmpptr, envbuf.end-tmpptr, config.sql_table, &idata->basetime, config.timestamps_utc);
318     ptrs[count] = envbuf.ptr;
319     envbuf.ptr += strlen(envbuf.ptr)+1;
320     count++;
321   }
322 
323   {
324     char *tmpptr;
325 
326     strncat(envbuf.ptr, "SQL_ACTIVE_WRITERS=", envbuf.end-envbuf.ptr);
327     tmpptr = envbuf.ptr + strlen(envbuf.ptr);
328     snprintf(tmpptr, envbuf.end-tmpptr, "%d", dump_writers_get_active());
329     ptrs[count] = envbuf.ptr;
330     envbuf.ptr += strlen(envbuf.ptr)+1;
331     count++;
332   }
333 
334   for (i = 0; i < count; i++)
335     putenv(ptrs[i]);
336 }
337 
338