1 | /***************************************
2 | $Revision: 1.6 $
3 |
4 | Status: NOT REVUED, NOT TESTED
5 |
6 | Author(s): Andrei Robachevsky
7 |
8 | ******************/ /******************
9 | Modification History:
10 | andrei (10/04/2000) Created.
11 | ******************/ /******************
12 | Copyright (c) 2000 RIPE NCC
13 |
14 | All Rights Reserved
15 |
16 | Permission to use, copy, modify, and distribute this software and its
17 | documentation for any purpose and without fee is hereby granted,
18 | provided that the above copyright notice appear in all copies and that
19 | both that copyright notice and this permission notice appear in
20 | supporting documentation, and that the name of the author not be
21 | used in advertising or publicity pertaining to distribution of the
22 | software without specific, written prior permission.
23 |
24 | THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
25 | ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
26 | AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
27 | DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
28 | AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
29 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
30 | ***************************************/
31 | #include <glib.h>
32 | #include <stdio.h>
33 | #include <strings.h>
34 | #include <glib.h>
35 | #include <stdlib.h>
36 | #include <ctype.h>
37 | #include <unistd.h>
38 |
39 | #include "nh.h"
40 | #include <stubs.h>
41 |
42 | /*+ String sizes +*/
43 | #define STR_S 63
44 | #define STR_M 255
45 | #define STR_L 1023
46 | #define STR_XL 4095
47 | #define STR_XXL 16383
48 | #define STR_XXXL 65535
49 |
50 | /*
51 | CREATE TABLE nic_hdl (
52 | thread_id(11) DEFAULT '0' NOT NULL,
53 | range_id int(10) unsigned DEFAULT '0' NOT NULL auto_increment,
54 | range_start int(10) DEFAULT '0' NOT NULL,
55 | range_end int(10) DEFAULT '0' NOT NULL,
56 | space char(4) DEFAULT '' NOT NULL,
57 | source char(10) DEFAULT '' NOT NULL,
58 | PRIMARY KEY (range_id, range_start, range_end)
59 | );
60 |
61 | */
62 |
63 | #define get_min_range(prange, sql_connection) get_range(MIN_NIC_ID, prange, sql_connection)
64 | static long get_range(long nic_id, range_t *prange, SQ_connection_t *sql_connection);
65 | static long update_range(long range_id, range_t *p_newrange, SQ_connection_t *sql_connection, int commit_now);
66 | static long create_range(range_t *p_range, SQ_connection_t *sql_connection, int commit_now);
67 |
68 | /************************************************************
69 | * int NH_convert() *
70 | * *
71 | * Converts space & nic_id into a database nic-handle *
72 | * *
73 | * *
74 | * Returns: *
75 | * The size of the nic_handle in characters *
76 | * *
77 | ************************************************************/
78 | int NH_convert(char *nic, nic_handle_t *nh_ptr)
79 | {
80 | /* Check for special cases */
81 | /* Is is and AUTO nic-handle ? */
82 | if(nh_ptr->nic_id == AUTO_NIC_ID) return(-1);
83 | if(nh_ptr->space) nic+=sprintf(nic, "%s", nh_ptr->space);
84 | /* No nic-id ? */
85 | if(nh_ptr->nic_id != NULL_NIC_ID) nic+=sprintf(nic, "%ld", nh_ptr->nic_id);
86 | /* No source ? */
87 | if (nh_ptr->source) sprintf(nic, "%s", nh_ptr->source);
88 | return(1);
89 | }
90 |
91 | /************************************************************
92 | * int NH_parse() *
93 | * *
94 | * Parse a nic handle as supplied by DBupdate *
95 | * The format is: <space>[<nic_id>|*][SOURCE] *
96 | * Also extracts nic_id and space for regular nic-handles *
97 | * *
98 | * Acceptable format is: *
99 | * [A-Z][A-Z]*[1-9][0-9]*(-[A-Z][A-Z]*)? *
100 | * *
101 | * Returns: *
102 | * >0 - success *
103 | * 0 - AUTO NIC *
104 | * -1 - error (not defined and processed yet) *
105 | * *
106 | ************************************************************/
107 | int NH_parse(char *nic, nic_handle_t **nh_ptr_ptr)
108 | {
109 | char *ptr;
110 | int res = 1;
111 | nic_handle_t *nh_ptr;
112 |
113 | if(!(nh_ptr=calloc(1, sizeof(nic_handle_t)))) die;
114 |
115 | ptr=nic;
116 |
117 | /* extract space */
118 | while(isalpha((int)*ptr))ptr++;
119 | if(!(nh_ptr->space=malloc(ptr-nic+1))) die;
120 | strncpy(nh_ptr->space, nic, ptr-nic); *(nh_ptr->space+(ptr-nic))='\0';
121 |
122 | /* If there are no digits, then this is no nic-hdl */
123 | /* We reserve NULL_NIC_ID for such pretty identifiers */
124 | if(*ptr == '\0') {
125 | nh_ptr->nic_id=NULL_NIC_ID;
126 | nh_ptr->source=NULL;
127 | }
128 | else {
129 | /* Check if it is and AUTO nic */
130 | if (*ptr == '*') {
131 | /* For AUTO nic_id we reserve AUTO_NIC_ID */
132 | nh_ptr->nic_id=AUTO_NIC_ID;
133 | res=0;
134 | ptr++;
135 | } else {
136 | nic=ptr;
137 | /* convert digits (if any) and store first invalid characted in ptr */
138 | nh_ptr->nic_id=(int)strtol(nic, &ptr, 10);
139 | /* Check if there were any digits at all */
140 | if(ptr == nic) nh_ptr->nic_id=NULL_NIC_ID;
141 | }
142 | /* check if there is any suffix */
143 | if (*ptr == '\0') nh_ptr->source=NULL;
144 | /* Copy suffix into source */
145 | else {
146 | if(!(nh_ptr->source=malloc(strlen(ptr)+1))) die;
147 | strcpy(nh_ptr->source, ptr);
148 | }
149 | }
150 | *nh_ptr_ptr=nh_ptr;
151 | return(res);
152 | }
153 |
154 |
155 |
156 | /************************************************************
157 | * int NH_check() *
158 | * *
159 | * Check a NIC handle in the repository *
160 | * *
161 | * *
162 | * Returns: *
163 | * 1 - success *
164 | * 0 - error(nic_id exists or space is fully occupied) *
165 | * -1 - error (f.e. more than one object with the same PK) *
166 | * *
167 | ************************************************************/
168 | int NH_check(nic_handle_t *nh_ptr, SQ_connection_t *sql_connection)
169 | {
170 | range_t range;
171 | long range_id;
172 | long nic_id=nh_ptr->nic_id;
173 |
174 |
175 | range.space=nh_ptr->space;
176 | if(nh_ptr->source)range.source=nh_ptr->source; else range.source="";
177 |
178 | if (nic_id == AUTO_NIC_ID) {
179 | /* NIC handle is an AUTO one */
180 | /* get first range (with min range_end) for a given space */
181 | range_id = get_min_range(&range, sql_connection);
182 | if(range_id<0) return(-1); /* in case of an error */
183 |
184 | if ( range_id==0 ) {
185 | /* Nothing found */
186 | /* Allocate a hic-hdl in a new space with the first range {0-1} in it*/
187 | nic_id=1;
188 | } else {
189 | if ( range.end == MAX_NIC_ID ) return(0); /* space is fully occupied */
190 | /* attach to range and may be join with next */
191 | nic_id = range.end+1;
192 | }
193 | }
194 | /* if not AUTO */
195 | else {
196 | range_id = get_range(nic_id, &range, sql_connection);
197 | if(range_id <0) return(-1); /* in case of an error */
198 | if(range_id!=0) return(0); /* this nic_id already exists */
199 | }
200 | nh_ptr->nic_id=nic_id;
201 | return(1);
202 | }
203 |
204 | /************************************************************
205 | * long NH_free() *
206 | * *
207 | * Delete a NIC handle from the repository *
208 | * *
209 | * To finalize changes make commit/rollback *
210 | * *
211 | * Returns: *
212 | * 1 - success *
213 | * 0 - error (range is not founnd) *
214 | * -1 - error (f.e. more than one object with the same PK) *
215 | * *
216 | ************************************************************/
217 | int NH_free(nic_handle_t *nh_ptr, SQ_connection_t *sql_connection, int commit_now)
218 | {
219 | range_t range;
220 | long range_id;
221 | int old_start;
222 | long nic_id=nh_ptr->nic_id;
223 |
224 |
225 | range.space=nh_ptr->space;
226 | if(nh_ptr->source)range.source=nh_ptr->source; else range.source="";
227 |
228 | /* Search for the range containing the nic-handle */
229 | range_id = get_range(nic_id, &range, sql_connection);
230 | /* If range is not found or an error occcured - return */
231 | if(range_id==0) { return(0); }
232 | if(range_id<0) { return(-1); }
233 |
234 | if(nic_id == range.start) {
235 | /* update range start and may be detele range and space */
236 | range.start+=1;
237 | range_id=update_range(range_id, &range, sql_connection, commit_now);
238 | if(range_id<=0) { return(-1); }
239 | }
240 | else if(nic_id == range.end) {
241 | /* update range end and may be detele range and space */
242 | range.end-=1;
243 | range_id=update_range(range_id, &range, sql_connection, commit_now);
244 | if(range_id<=0) { return(-1); }
245 | }
246 | else {
247 | /* split the range into two */
248 | /* shrink the old one */
249 | old_start=range.start;
250 | range.start=nic_id+1;
251 | range_id=update_range(range_id, &range, sql_connection, commit_now);
252 | if(range_id<=0) { return(-1); }
253 | /* create a new one */
254 | range.start=old_start;
255 | range.end=nic_id-1;
256 | range_id=create_range(&range, sql_connection, commit_now);
257 | if(range_id<=0) { return(-1); }
258 | }
259 |
260 | return(1);
261 | }
262 |
263 |
264 | /************************************************************
265 | * int NH_register() *
266 | * *
267 | * Get a NIC handle from the repository *
268 | * *
269 | * *
270 | * Returns: *
271 | * 1 - success *
272 | * 0 - nic_id already exists or space is fully occupied *
273 | * -1 - error (f.e. more than one object with the same PK) *
274 | * *
275 | ************************************************************/
276 | int NH_register(nic_handle_t *nh_ptr, SQ_connection_t *sql_connection, int commit_now)
277 | {
278 | range_t range;
279 | long range_id;
280 | long nic_id=nh_ptr->nic_id;
281 |
282 |
283 |
284 |
285 | /* Yiu should check for nh first for AUTO nic-handles */
286 | if (nic_id == AUTO_NIC_ID) { return(0); };
287 |
288 | range.space=nh_ptr->space;
289 | if(nh_ptr->source)range.source=nh_ptr->source; else range.source="";
290 |
291 | range_id = get_range(nic_id, &range, sql_connection);
292 | if(range_id <0) { return(-1); } /* in case of an error */
293 | if(range_id!=0) { return(0); } /* this nic_id already exists */
294 |
295 | /* check if we can attach to existing next range */
296 | range_id = get_range(nic_id+1, &range, sql_connection);
297 | if(range_id <0) { return(-1); } /* in case of an error */
298 |
299 | if( range_id>0 ) {
300 | /* attach to range and may be join with previous */
301 | range.start-=1;
302 | range_id=update_range(range_id, &range, sql_connection, commit_now);
303 | if(range_id<=0) { return(-1); }
304 | }
305 | else {
306 | /* check if we can attach to existing previous range */
307 | if(nic_id>0) range_id = get_range(nic_id-1, &range, sql_connection);
308 | else range_id=0; /* there is no previous range in this case (nic_id==0) */
309 | if(range_id <0) { return(-1); } /* in case of an error */
310 | if( range_id>0 ) {
311 | /* attach to range and may be join with next */
312 | range.end+=1;
313 | range_id=update_range(range_id, &range, sql_connection, commit_now);
314 | if(range_id<=0) { return(-1); }
315 | }
316 | else {
317 | /* If we cannot attach to any existing range - create new {nic_id-nic_id} */
318 | range.end=range.start=nic_id;
319 | range_id=create_range(&range, sql_connection, commit_now);
320 | if(range_id <=0) { return(-1); } /* in case of an error */
321 | }
322 | }
323 | return(1);
324 | }
325 |
326 | /*
327 | Free nic_handle_t structure
328 | */
329 | void free_nh(nic_handle_t *nh_ptr)
330 | {
331 | if(nh_ptr){
332 | if(nh_ptr->space)free(nh_ptr->space);
333 | if(nh_ptr->source)free(nh_ptr->source);
334 | free(nh_ptr);
335 | }
336 | }
337 |
338 |
339 | /************************************************************
340 | * long get_range() *
341 | * *
342 | * Searches for the range of the space containing *
343 | * the specified nic_id *
344 | * *
345 | * To request to search for the firt (min) range, nic_id *
346 | * should be set to MIN_NIC_ID *
347 | * *
348 | * Returns: *
349 | * >0 - range exists, returns range_id *
350 | * 0 - range does not exist *
351 | * -1 - DB error (f.e. more than one object with the same PK)*
352 | * *
353 | * **********************************************************/
354 | static long get_range(long nic_id, range_t *prange, SQ_connection_t *sql_connection)
355 | {
356 | SQ_result_set_t *sql_result;
357 | SQ_row_t *sql_row;
358 | char *sql_str;
359 | GString *query;
360 | long range_id=0;
361 | int sql_err;
362 |
363 | if ((query = g_string_sized_new(STR_L)) == NULL){
364 | fprintf(stderr, "E: cannot allocate gstring\n");
365 | return(-1);
366 | }
367 |
368 | /* Define row numbers in the result of the query */
369 | #define RANGE_ID 0
370 | #define RANGE_START 1
371 | #define RANGE_END 2
372 |
373 | if (nic_id==MIN_NIC_ID) {
374 | /* requesting the first (min) range */
375 | g_string_sprintf(query, "SELECT range_id, range_start, range_end "
376 | "FROM nic_hdl "
377 | "WHERE space='%s' "
378 | "AND source='%s' "
379 | "AND (range_start=0 "
380 | "OR range_start=1) ",
381 | prange->space, prange->source);
382 | } else {
383 |
384 | g_string_sprintf(query, "SELECT range_id, range_start, range_end "
385 | "FROM nic_hdl "
386 | "WHERE space='%s' "
387 | "AND source='%s' "
388 | "AND range_start<=%ld "
389 | "AND range_end>=%ld ",
390 | prange->space, prange->source, nic_id, nic_id);
391 | }
392 |
393 | /* execute query */
394 | /* fprintf(stderr, "get_range[%s]\n", query->str); */
395 | sql_err=SQ_execute_query(sql_connection, query->str, &sql_result);
396 | g_string_free(query, TRUE);
397 |
398 | if(sql_err) {
399 | fprintf(stderr,"ERROR: %s\n", SQ_error(sql_connection));
400 | return(-1);
401 | }
402 |
403 | if ((sql_row = SQ_row_next(sql_result)) != NULL) {
404 | /* Object exists */
405 | sql_str = SQ_get_column_string(sql_result, sql_row, RANGE_ID);
406 | if (sql_str != NULL) {
407 | range_id = atol(sql_str);
408 | free(sql_str);
409 | }
410 | sql_str = SQ_get_column_string(sql_result, sql_row, RANGE_START);
411 | if (sql_str != NULL) {
412 | prange->start = atoi(sql_str);
413 | free(sql_str);
414 | }
415 | sql_str = SQ_get_column_string(sql_result, sql_row, RANGE_END);
416 | if (sql_str != NULL) {
417 | prange->end = atoi(sql_str);
418 | free(sql_str);
419 | }
420 |
421 | /* We must process all the rows of the result */
422 | /* otherwise we'll have them as part of the next qry */
423 | while ( (sql_row = SQ_row_next(sql_result)) != NULL) range_id=-1;
424 | } else
425 | range_id=0; // object does not exist
426 |
427 | if(sql_result)SQ_free_result(sql_result);
428 | return(range_id);
429 | }
430 |
431 |
432 |
433 |
434 | /************************************************************
435 | * long update_range() *
436 | * *
437 | * Updates the range by changing the boundaries *
438 | * Deletes the range if nothing left *
439 | * Merges with neighbor ranges if there is no gap between *
440 | * *
441 | * We never update range. We create a new one with specified *
442 | * limits and mark old one(s) for deletion, so that we can *
443 | * make commit/rollback properly. This is possible as the *
444 | * primary keys are (range_id, range_start, range_end) *
445 | * *
446 | * To finalize changes make commit/rollback *
447 | * *
448 | * Returns: *
449 | * >0 - returns range_id on success *
450 | * -1 - error (f.e. more than one object with the same PK) *
451 | * *
452 | ************************************************************/
453 |
454 | static long update_range(long range_id, range_t *p_newrange, SQ_connection_t *sql_connection, int commit_now)
455 | {
456 | GString *query;
457 | range_t range;
458 | long prev_range_id, next_range_id;
459 | int num;
460 | int sql_err;
461 |
462 | /* Allocate memory */
463 | if ((query = g_string_sized_new(STR_L)) == NULL){
464 | fprintf(stderr, "E: cannot allocate gstring\n");
465 | return(-1);
466 | }
467 |
468 | /* Do range check */
469 | if (( p_newrange->end > MAX_RANGE ) || ( p_newrange->start < MIN_RANGE )) return(-1);
470 |
471 | /* Check if the range collapses */
472 | if ( p_newrange->end < p_newrange->start ) {
473 | /* then delete the range */
474 | /* Do this by marking the range for deletion for further commit/rollback */
475 | if(commit_now)
476 | g_string_sprintf(query, "DELETE FROM nic_hdl "
477 | "WHERE range_id=%ld ",
478 | range_id);
479 | else
480 | g_string_sprintf(query, "UPDATE nic_hdl SET thread_id=%d "
481 | "WHERE range_id=%ld ",
482 | NH_DELETE, range_id);
483 |
484 | /* fprintf(stderr, "update_range[%s]\n", query->str); */
485 | sql_err=SQ_execute_query(sql_connection, query->str, (SQ_result_set_t **)NULL);
486 | if(sql_err) {
487 | /* An error occured */
488 | g_string_free(query, TRUE);
489 | return(-1);
490 | }
491 | num = mysql_affected_rows(sql_connection);
492 | /* this should not happen */
493 | if(num==0) die;
494 |
495 | }
496 | else {
497 | /* update the range for the same space/source */
498 | range.space=p_newrange->space;
499 | range.source=p_newrange->source;
500 | /* Check if we can join with previous range of the same space */
501 | prev_range_id=get_range(p_newrange->start-1, &range, sql_connection);
502 | /* Check if such range exists and it is not ours (this happens when we are shrinking */
503 | if((prev_range_id>0) && (prev_range_id!=range_id)) {
504 | /* acquire the previous range */
505 | /* mark it for deletion for commit/rollback */
506 | if(commit_now)
507 | g_string_sprintf(query, "DELETE FROM nic_hdl "
508 | "WHERE range_id=%ld ",
509 | prev_range_id);
510 | else
511 | g_string_sprintf(query, "UPDATE nic_hdl SET thread_id=%d "
512 | "WHERE range_id=%ld ",
513 | NH_DELETE, prev_range_id);
514 |
515 |
516 |
517 | /* fprintf(stderr, "update_range[%s]\n", query->str); */
518 | sql_err=SQ_execute_query(sql_connection, query->str, (SQ_result_set_t **)NULL);
519 | if(sql_err) {
520 | /* An error occured */
521 | g_string_free(query, TRUE);
522 | return(-1);
523 | }
524 | num = mysql_affected_rows(sql_connection);
525 | /* this should not happen */
526 | if(num==0) die;
527 |
528 | /* expand the boundaries */
529 | p_newrange->start=range.start;
530 | }
531 |
532 | /* Check if we can join with next range of the same space */
533 | next_range_id=get_range(p_newrange->end+1, &range, sql_connection);
534 | /* Check if such range exists and it is not ours (this happens when we are shrinking) */
535 | if((next_range_id>0) && (next_range_id!=range_id)) {
536 | /* acquire the next range */
537 | /* mark it for deletion for commit/rollback */
538 | if(commit_now)
539 | g_string_sprintf(query, "DELETE FROM nic_hdl "
540 | "WHERE range_id=%ld ",
541 | next_range_id);
542 | else
543 | g_string_sprintf(query, "UPDATE nic_hdl SET thread_id=%d "
544 | "WHERE range_id=%ld ",
545 | NH_DELETE, next_range_id);
546 |
547 |
548 |
549 | /* fprintf(stderr, "update_range[%s]\n", query->str); */
550 | sql_err=SQ_execute_query(sql_connection, query->str, (SQ_result_set_t **)NULL);
551 | if(sql_err) {
552 | /* An error occured */
553 | g_string_free(query, TRUE);
554 | return(-1);
555 | }
556 | num = mysql_affected_rows(sql_connection);
557 | /* this should not happen */
558 | if(num==0) die;
559 |
560 | /* expand the boundaries */
561 | p_newrange->end=range.end;
562 | }
563 |
564 | /* Now make a larger range. Mark current for deletion and new for commit/rollback */
565 | if(commit_now)
566 | g_string_sprintf(query, "UPDATE nic_hdl "
567 | "SET range_start=%ld, range_end=%ld "
568 | "WHERE range_id=%ld",
569 | p_newrange->start, p_newrange->end, range_id);
570 | else {
571 |
572 | g_string_sprintf(query, "UPDATE nic_hdl SET thread_id=%d "
573 | "WHERE range_id=%ld ",
574 | NH_DELETE, range_id);
575 | /* fprintf(stderr, "update_range[%s]\n", query->str); */
576 | sql_err=SQ_execute_query(sql_connection, query->str, (SQ_result_set_t **)NULL);
577 | if(sql_err) {
578 | /* An error occured */
579 | g_string_free(query, TRUE);
580 | return(-1);
581 | }
582 | num = mysql_affected_rows(sql_connection);
583 | /* this should not happen */
584 | if(num==0) die;
585 |
586 | g_string_sprintf(query, "INSERT nic_hdl "
587 | "SET thread_id=%d, range_id=%ld, space='%s', source='%s', range_start=%ld, range_end=%ld ",
588 | NH_INSERT, range_id, p_newrange->space, p_newrange->source, p_newrange->start, p_newrange->end);
589 | }
590 |
591 | /* fprintf(stderr, "update_range[%s]\n", query->str); */
592 | sql_err=SQ_execute_query(sql_connection, query->str, (SQ_result_set_t **)NULL);
593 | if(sql_err) {
594 | /* An error occured */
595 | g_string_free(query, TRUE);
596 | return(-1);
597 | }
598 | num = mysql_affected_rows(sql_connection);
599 | /* this should not happen */
600 | if(num==0) die;
601 | } /* update the range */
602 |
603 | g_string_free(query, TRUE);
604 | return (range_id);
605 | }
606 |
607 | /************************************************************
608 | * long create_range() *
609 | * *
610 | * Creates a new range in a given name space *
611 | * *
612 | * To finalize changes make commit/rollback *
613 | * *
614 | * Returns: *
615 | * >0 - returns range_id on success *
616 | * -1 - error (f.e. more than one object with the same PK) *
617 | * *
618 | ************************************************************/
619 |
620 | static long create_range(range_t *p_range, SQ_connection_t *sql_connection, int commit_now)
621 | {
622 | GString *query;
623 | int sql_err, num;
624 |
625 | /* Allocate memory */
626 | if ((query = g_string_sized_new(STR_L)) == NULL){
627 | fprintf(stderr, "E: cannot allocate gstring\n");
628 | return(-1);
629 | }
630 |
631 | if(commit_now)
632 | g_string_sprintf(query, "INSERT nic_hdl "
633 | "SET thread_id=0, space='%s', source='%s', range_start=%ld, range_end=%ld ",
634 | p_range->space, p_range->source, p_range->start, p_range->end);
635 | else
636 | g_string_sprintf(query, "INSERT nic_hdl "
637 | "SET thread_id=%d, space='%s', source='%s', range_start=%ld, range_end=%ld ",
638 | NH_INSERT, p_range->space, p_range->source, p_range->start, p_range->end);
639 |
640 | /* fprintf(stderr, "create_range[%s]\n", query->str); */
641 | sql_err=SQ_execute_query(sql_connection, query->str, (SQ_result_set_t **)NULL);
642 | g_string_free(query, TRUE);
643 |
644 | if(sql_err) {
645 | /* An error occured */
646 | return(-1);
647 | }
648 | num = mysql_affected_rows(sql_connection);
649 | /* this should not happen */
650 | if(num==0) die;
651 | return(mysql_insert_id(sql_connection));
652 | }
653 |
654 |
655 | /************************************************************
656 | * int NH_comrol() *
657 | * *
658 | * Commits or rolls back changes to NHR *
659 | * *
660 | * *
661 | * Returns: *
662 | * >0 - success *
663 | * -1 - SQL error *
664 | * *
665 | ************************************************************/
666 |
667 | int NH_comrol(SQ_connection_t *sql_connection, int thread_ins, int thread_del)
668 | {
669 | GString *query;
670 | int sql_err;
671 |
672 | /* Allocate memory */
673 | if ((query = g_string_sized_new(STR_L)) == NULL){
674 | fprintf(stderr, "E: cannot allocate gstring\n");
675 | return(-1);
676 | }
677 |
678 | g_string_sprintf(query, "DELETE FROM nic_hdl "
679 | "WHERE thread_id=%d ",
680 | thread_del);
681 |
682 | /* fprintf(stderr, "create_range[%s]\n", query->str); */
683 | sql_err=SQ_execute_query(sql_connection, query->str, (SQ_result_set_t **)NULL);
684 | if(sql_err) {
685 | /* An error occured */
686 | g_string_free(query, TRUE);
687 | fprintf(stderr,"ERROR: %s\n", SQ_error(sql_connection));
688 | die;
689 | }
690 |
691 | g_string_sprintf(query, "UPDATE nic_hdl "
692 | "SET thread_id=0 "
693 | "WHERE thread_id=%d ",
694 | thread_ins);
695 |
696 | /* fprintf(stderr, "create_range[%s]\n", query->str); */
697 | sql_err=SQ_execute_query(sql_connection, query->str, (SQ_result_set_t **)NULL);
698 | g_string_free(query, TRUE);
699 |
700 | if(sql_err) {
701 | /* An error occured */
702 | fprintf(stderr,"ERROR: %s\n", SQ_error(sql_connection));
703 | die;
704 | }
705 |
706 | return(1);
707 |
708 | }
709 |
710 |