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 |