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