00001
00002
00003
00004 #include "jsoc.h"
00005 #include <string.h>
00006 #include <stdlib.h>
00007 #include <stdio.h>
00008 #include <alloca.h>
00009 #include <unistd.h>
00010 #include <sys/types.h>
00011 #include <sys/stat.h>
00012 #include <fcntl.h>
00013 #include <sys/statvfs.h>
00014 #include <ctype.h>
00015 #include <dirent.h>
00016 #include "util.h"
00017 #include "xassert.h"
00018 #include "xmem.h"
00019 #include "hcontainer.h"
00020
00021 #define ISUPPER(X) (X >= 0x41 && X <= 0x5A)
00022 #define ISLOWER(X) (X >= 0x61 && X <= 0x7A)
00023 #define ISDIGIT(X) (X >= 0x30 && X <= 0x39)
00024 #define DRMS_MAXNAMELEN 32
00025
00026 char *kKEYNAMERESERVED[] =
00027 {
00028 "_index",
00029 "ALL",
00030 "ANALYSE",
00031 "ANALYZE",
00032 "AND",
00033 "ANY",
00034 "ARRAY",
00035 "AS",
00036 "ASC",
00037 "ASYMMETRIC",
00038 "BOTH",
00039 "CASE",
00040 "CAST",
00041 "CHECK",
00042 "COLLATE",
00043 "COLUMN",
00044 "CONSTRAINT",
00045 "CREATE",
00046 "CURRENT_DATE",
00047 "CURRENT_ROLE",
00048 "CURRENT_TIME",
00049 "CURRENT_TIMESTAMP",
00050 "CURRENT_USER",
00051 "DEFAULT",
00052 "DEFERRABLE",
00053 "DESC",
00054 "DISTINCT",
00055 "DO",
00056 "ELSE",
00057 "END",
00058 "EXCEPT",
00059 "FALSE",
00060 "FOR",
00061 "FOREIGN",
00062 "FROM",
00063 "GRANT",
00064 "GROUP",
00065 "HAVING",
00066 "IN",
00067 "INITIALLY",
00068 "INTERSECT",
00069 "INTO",
00070 "LEADING",
00071 "LIMIT",
00072 "LOCALTIME",
00073 "LOCALTIMESTAMP",
00074 "NEW",
00075 "NOT",
00076 "NULL",
00077 "OFF",
00078 "OFFSET",
00079 "OLD",
00080 "ON",
00081 "ONLY",
00082 "OR",
00083 "ORDER",
00084 "PLACING",
00085 "PRIMARY",
00086 "REFERENCES",
00087 "RETURNING",
00088 "SELECT",
00089 "SESSION_USER",
00090 "SOME",
00091 "SYMMETRIC",
00092 "TABLE",
00093 "THEN",
00094 "TO",
00095 "TRAILING",
00096 "TRUE",
00097 "UNION",
00098 "UNIQUE",
00099 "USER",
00100 "USING",
00101 "WHEN",
00102 "WHERE",
00103 "AUTHORIZATION",
00104 "BETWEEN",
00105 "BINARY",
00106 "CROSS",
00107 "FREEZE",
00108 "FULL",
00109 "ILIKE",
00110 "INNER",
00111 "IS",
00112 "ISNULL",
00113 "JOIN",
00114 "LEFT",
00115 "LIKE",
00116 "NATURAL",
00117 "NOTNULL",
00118 "OUTER",
00119 "OVERLAPS",
00120 "RIGHT",
00121 "SIMILAR",
00122 "VERBOSE",
00123 ""
00124 };
00125
00126 HContainer_t *gCleanup = NULL;
00127 HContainer_t *gReservedDRMS = NULL;
00128
00129 typedef enum
00130 {
00131 kKwCharFirst = 0,
00132 kKwCharNew,
00133 kKwCharError
00134 } KwCharState_t;
00135
00136
00137 char *ns(const char *name) {
00138 char *nspace = strdup(name);
00139 char *pc = strrchr(nspace, '.');
00140 if (pc) {
00141 *pc = '\0';
00142 }
00143 return nspace;
00144 }
00145
00146 void copy_string(char **dst, char *src)
00147 {
00148 XASSERT((src!=NULL));
00149 XASSERT(*dst != src);
00150 if (*dst)
00151 free(*dst);
00152 *dst = strdup(src);
00153 }
00154
00155 void strtolower(char *str)
00156 {
00157 int n,i;
00158 n= strlen(str);
00159 for (i=0;i<n;i++)
00160 str[i] = (char)tolower(str[i]);
00161 }
00162
00163 void strtoupper(char *str)
00164 {
00165 int n,i;
00166 n= strlen(str);
00167 for (i=0;i<n;i++)
00168 str[i] = (char)toupper(str[i]);
00169 }
00170
00171
00172 size_t base_strlcat(char *dst, const char *src, size_t size)
00173 {
00174 size_t max = size - strlen(dst) - 1;
00175 size_t start = strlen(dst);
00176
00177 if (max > 0)
00178 {
00179 snprintf(dst + start, max + 1, "%s", src);
00180 }
00181
00182 return start + strlen(src);
00183 }
00184
00185
00186 void *base_strcatalloc(char *dst, const char *src, size_t *sizedst)
00187 {
00188 size_t srclen = strlen(src);
00189 size_t dstlen = strlen(dst);
00190 void *retstr = NULL;
00191 void *tmp = NULL;
00192
00193 while (srclen > *sizedst - dstlen - 1)
00194 {
00195 if (!tmp)
00196 {
00197 tmp = dst;
00198 }
00199
00200 tmp = realloc(tmp, *sizedst * 2);
00201 if (tmp)
00202 {
00203 *sizedst *= 2;
00204 retstr = tmp;
00205 }
00206 else
00207 {
00208 break;
00209 }
00210 }
00211
00212 if (!retstr)
00213 {
00214 retstr = dst;
00215 }
00216
00217 if (retstr)
00218 {
00219 base_strlcat(retstr, src, *sizedst);
00220 }
00221
00222 return retstr;
00223 }
00224
00225
00226
00227 char *base_strreplace(const char *text, const char *orig, const char *repl)
00228 {
00229 char *result;
00230 const char *replacement = NULL;
00231 char *ins;
00232 char *pc;
00233 const char *pcin;
00234 size_t lenorig;
00235 size_t lenrepl;
00236 size_t lenprefix;
00237 int count;
00238
00239 XASSERT(text && orig && strlen(orig) > 0);
00240
00241 if (text && orig && strlen(orig) > 0)
00242 {
00243 lenorig = strlen(orig);
00244 replacement = (repl == NULL ? "" : repl);
00245 lenrepl = strlen(replacement);
00246
00247 for (count = 0, pc = strstr(text, orig), ins = pc; ins && (pc = strstr(ins, orig)); count++)
00248 {
00249 ins = pc + lenorig;
00250 }
00251
00252 if (count > 0)
00253 {
00254 result = malloc(strlen(text) + (lenrepl - lenorig) * count + 1);
00255 pc = result;
00256 pcin = text;
00257
00258 while (count--)
00259 {
00260 ins = strstr(pcin, orig);
00261 lenprefix = ins - pcin;
00262 strncpy(pc, pcin, lenprefix);
00263 pc += lenprefix;
00264 strncpy(pc, replacement, lenrepl);
00265 pc += lenrepl;
00266 pcin += lenprefix + lenorig;
00267 }
00268
00269 strncpy(pc, pcin, strlen(pcin));
00270 *(pc + strlen(pcin)) = '\0';
00271 }
00272 }
00273
00274 return result;
00275 }
00276
00277
00278
00279
00280
00281 char *base_strcasereplace(const char *text, const char *orig, const char *repl)
00282 {
00283 char *result = NULL;
00284 const char *replacement = NULL;
00285 char *ins;
00286 char *pc;
00287 const char *pcin;
00288 size_t lenorig;
00289 size_t lenrepl;
00290 size_t lenprefix;
00291 int count;
00292
00293 XASSERT(text && orig && strlen(orig) > 0);
00294
00295 if (text && orig && strlen(orig) > 0)
00296 {
00297 lenorig = strlen(orig);
00298 replacement = (repl == NULL ? "" : repl);
00299 lenrepl = strlen(replacement);
00300
00301 for (count = 0, pc = strcasestr(text, orig), ins = pc; ins && (pc = strcasestr(ins, orig)); count++)
00302 {
00303 ins = pc + lenorig;
00304 }
00305
00306 if (count > 0)
00307 {
00308 result = malloc(strlen(text) + (lenrepl - lenorig) * count + 1);
00309 pc = result;
00310 pcin = text;
00311
00312 while (count--)
00313 {
00314 ins = strcasestr(pcin, orig);
00315 lenprefix = ins - pcin;
00316 strncpy(pc, pcin, lenprefix);
00317 pc += lenprefix;
00318 strncpy(pc, replacement, lenrepl);
00319 pc += lenrepl;
00320 pcin += lenprefix + lenorig;
00321 }
00322
00323 strncpy(pc, pcin, strlen(pcin));
00324 *(pc + strlen(pcin)) = '\0';
00325 }
00326 }
00327
00328 return result;
00329 }
00330
00331 int convert_int_field(char *field, int len)
00332 {
00333 char *buf;
00334
00335 buf = alloca(len+1);
00336 memcpy(buf,field,len);
00337 return atoi(buf);
00338 }
00339
00340 long convert_long_field(char *field, int len)
00341 {
00342 char *buf;
00343
00344 buf = alloca(len+1);
00345 memcpy(buf,field,len);
00346 return atol(buf);
00347 }
00348
00349 float convert_float_field(char *field, int len)
00350 {
00351 char *buf;
00352
00353 buf = alloca(len+1);
00354 memcpy(buf,field,len);
00355 return (float)atof(buf);
00356 }
00357
00358 double convert_double_field(char *field, int len)
00359 {
00360 char *buf;
00361
00362 buf = alloca(len+1);
00363 memcpy(buf,field,len);
00364 return atof(buf);
00365 }
00366
00367
00368 void convert_string_field(char *field, int len, char *output, int maxlen)
00369 {
00370 int l;
00371
00372 l = (len>maxlen?maxlen:len);
00373 strncpy(output,field,l);
00374 output[l] = '\0';
00375 }
00376
00377
00378 #define BUFSIZE (1<<20)
00379
00380 int copyfile(const char *inputfile, const char *outputfile)
00381 {
00382 int fin, fout;
00383 ssize_t nread;
00384 char *buffer = 0;
00385 char *bufferorig = 0;
00386 int oflags;
00387
00388 #ifdef _GNU_SOURCE
00389 struct statvfs stat;
00390 static unsigned long align=-1;
00391 oflags = O_DIRECT;
00392 #else
00393 oflags = 0;
00394 #endif
00395
00396 if ( (fin = open(inputfile, O_RDONLY|oflags) ) == -1 )
00397 return -1;
00398
00399 if ( (fout = open(outputfile, O_WRONLY|O_CREAT|O_TRUNC|oflags, 0644 ) ) == -1
00400 )
00401 {
00402 close(fin);
00403 return -2;
00404 }
00405
00406 #ifdef _GNU_SOURCE
00407 if (align == -1)
00408 {
00409 fstatvfs(fin, &stat);
00410 align = stat.f_bsize;
00411 fstatvfs(fout, &stat);
00412 align = align > stat.f_bsize ? align : stat.f_bsize;
00413 }
00414
00415 bufferorig = malloc(BUFSIZE+align);
00416 XASSERT(bufferorig);
00417 buffer = bufferorig;
00418 buffer = buffer + (align - ((unsigned long)buffer % align));
00419
00420 #else
00421 buffer = malloc(BUFSIZE);
00422 XASSERT(buffer);
00423 #endif
00424
00425
00426 while ( (nread = read(fin, buffer, BUFSIZE)) > 0 )
00427 {
00428 if ( write(fout, buffer, nread) < nread )
00429 {
00430 close(fin);
00431 close(fout);
00432 unlink(outputfile);
00433
00434 if (bufferorig)
00435 {
00436 free(bufferorig);
00437 }
00438
00439 return -3;
00440 }
00441 }
00442 close(fin);
00443 close(fout);
00444
00445 if (bufferorig)
00446 {
00447 free(bufferorig);
00448 }
00449
00450 if (nread == -1)
00451 return -4;
00452 else
00453 return 0;
00454 }
00455
00456 static void FreeReservedDRMS(void *data)
00457 {
00458 if (gReservedDRMS != (HContainer_t *)data)
00459 {
00460 fprintf(stderr, "Unexpected argument to FreeReservedDRMS(); bailing.\n");
00461 return;
00462 }
00463
00464 hcon_destroy(&gReservedDRMS);
00465 }
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482 static int DRMSKeyNameValidationStatus(const char *drmsName)
00483 {
00484 int error = 0;
00485 KwCharState_t state = kKwCharFirst;
00486 char *nameC = strdup(drmsName);
00487 char *pc = nameC;
00488
00489 if (strlen(drmsName) > DRMS_MAXNAMELEN - 1)
00490 {
00491 error = 1;
00492 }
00493 else
00494 {
00495
00496 if (!gReservedDRMS)
00497 {
00498 char bogusval = 'A';
00499 int i = 0;
00500
00501 gReservedDRMS = hcon_create(1, 128, NULL, NULL, NULL, NULL, 0);
00502 while (*(kKEYNAMERESERVED[i]) != '\0')
00503 {
00504 hcon_insert_lower(gReservedDRMS, kKEYNAMERESERVED[i], &bogusval);
00505 i++;
00506 }
00507
00508
00509 BASE_Cleanup_t cu;
00510 cu.item = gReservedDRMS;
00511 cu.free = FreeReservedDRMS;
00512 base_cleanup_register("reserveddrmskws", &cu);
00513 }
00514
00515 if (gReservedDRMS)
00516 {
00517 char *pch = NULL;
00518 if ((pch = strchr(nameC, '_')) != NULL)
00519 {
00520
00521 if (hcon_lookup_lower(gReservedDRMS, pch))
00522 {
00523 error = 2;
00524 }
00525 }
00526 else if (hcon_lookup_lower(gReservedDRMS, nameC))
00527 {
00528 error = 2;
00529 }
00530 }
00531
00532 while (*pc != 0 && !error)
00533 {
00534 switch (state)
00535 {
00536 case kKwCharError:
00537 error = 1;
00538 break;
00539 case kKwCharFirst:
00540 if (ISUPPER(*pc) ||
00541 ISLOWER(*pc) ||
00542 *pc == '_')
00543 {
00544 state = kKwCharNew;
00545 pc++;
00546 }
00547 else
00548 {
00549 state = kKwCharError;
00550 }
00551 break;
00552 case kKwCharNew:
00553 if (ISUPPER(*pc) ||
00554 ISLOWER(*pc) ||
00555 ISDIGIT(*pc) ||
00556 *pc == '_')
00557 {
00558 state = kKwCharNew;
00559 pc++;
00560 }
00561 else
00562 {
00563 state = kKwCharError;
00564 }
00565 break;
00566 default:
00567 state = kKwCharError;
00568 }
00569 }
00570 }
00571
00572 if (nameC)
00573 {
00574 free(nameC);
00575 }
00576
00577 return error;
00578 }
00579
00580
00581 int GenerateDRMSKeyName(const char *fitsName, char *drmsName, int size)
00582 {
00583 int error = 0;
00584 const char *pcIn = fitsName;
00585 char *pcOut = drmsName;
00586 int fitsinvalid = 0;
00587 char *pch = NULL;
00588
00589 KwCharState_t state = kKwCharFirst;
00590
00591 while (*pcIn != 0 && pcOut < drmsName + size)
00592 {
00593 switch (state)
00594 {
00595 case kKwCharError:
00596 error = 1;
00597 break;
00598
00599 case kKwCharFirst:
00600 if (*pcIn == '-')
00601 {
00602
00603 if (pcOut + 2 <= drmsName + size)
00604 {
00605 *pcOut++ = '_';
00606 *pcOut++ = '_';
00607 state = kKwCharNew;
00608 fitsinvalid = 1;
00609 }
00610 else
00611 {
00612 state = kKwCharError;
00613 }
00614 }
00615 else if (*pcIn >= 0x30 && *pcIn <= 0x39)
00616 {
00617
00618 if (pcOut + 2 <= drmsName + size)
00619 {
00620 *pcOut++ = '_';
00621 *pcOut++ = *pcIn;
00622 state = kKwCharNew;
00623 fitsinvalid = 1;
00624 }
00625 else
00626 {
00627 state = kKwCharError;
00628 }
00629 }
00630 else
00631 {
00632 *pcOut++ = *pcIn;
00633 state = kKwCharNew;
00634 }
00635
00636 break;
00637 case kKwCharNew:
00638 if (*pcIn == '-')
00639 {
00640 if (pcOut + 2 <= drmsName + size)
00641 {
00642 *pcOut++ = '_';
00643 *pcOut++ = '_';
00644 state = kKwCharNew;
00645 fitsinvalid = 1;
00646 }
00647 else
00648 {
00649 state = kKwCharError;
00650 }
00651 }
00652 else
00653 {
00654 *pcOut++ = *pcIn;
00655 state = kKwCharNew;
00656 }
00657 break;
00658
00659 }
00660
00661 if (state != kKwCharError)
00662 {
00663 pcIn++;
00664 }
00665
00666 }
00667
00668 *pcOut = '\0';
00669
00670
00671
00672 if (!error && DRMSKeyNameValidationStatus(drmsName) == 2)
00673 {
00674
00675 char *tmp = strdup(drmsName);
00676 if (tmp && (pch = strchr(tmp, '_')) != NULL && hcon_lookup_lower(gReservedDRMS, pch))
00677 {
00678 *pch = '\0';
00679 snprintf(drmsName, size, "_%s", tmp);
00680 }
00681 else
00682 {
00683 snprintf(drmsName, size, "_%s", tmp);
00684 }
00685
00686 fitsinvalid = 1;
00687 pcOut = drmsName + strlen(drmsName);
00688
00689 if (tmp)
00690 {
00691 free(tmp);
00692 }
00693 }
00694
00695
00696 if (fitsinvalid)
00697 {
00698 if (size - 1 < 9)
00699 {
00700 error = 1;
00701 fprintf(stderr, "Insufficient string buffer size '%d'.\n", size);
00702 }
00703 else
00704 {
00705 while (pcOut - drmsName < 9)
00706 {
00707 *pcOut++ = '_';
00708 }
00709
00710 *pcOut = '\0';
00711 }
00712 }
00713
00714
00715 return !error;
00716 }
00717
00718 #define kMAXRECURSION 128
00719 int RemoveDir(const char *pathname, int maxrec)
00720 {
00721 int status = 0;
00722
00723 char pbuf[PATH_MAX];
00724 struct stat stBuf;
00725
00726 if (maxrec < kMAXRECURSION && maxrec >= 0)
00727 {
00728 if (!stat(pathname, &stBuf) && S_ISDIR(stBuf.st_mode))
00729 {
00730
00731 snprintf(pbuf, sizeof(pbuf), "%s", pathname);
00732
00733 if (pathname[strlen(pathname) - 1] != '/')
00734 {
00735 base_strlcat(pbuf, "/", sizeof(pbuf));
00736 }
00737
00738 struct dirent **fileList = NULL;
00739 int nFiles = -1;
00740
00741
00742 if ((nFiles = scandir(pbuf, &fileList, NULL, NULL)) > 0 &&
00743 fileList != NULL)
00744 {
00745 int fileIndex = 0;
00746
00747 while (fileIndex < nFiles)
00748 {
00749 struct dirent *entry = fileList[fileIndex];
00750 if (entry != NULL)
00751 {
00752 char *oneFile = entry->d_name;
00753 char dirEntry[PATH_MAX] = {0};
00754 snprintf(dirEntry,
00755 sizeof(dirEntry),
00756 "%s%s",
00757 pbuf,
00758 oneFile);
00759 if (*dirEntry != '\0' && !stat(dirEntry, &stBuf) && status == 0)
00760 {
00761 if (S_ISREG(stBuf.st_mode) || S_ISLNK(stBuf.st_mode))
00762 {
00763
00764 status = unlink(dirEntry);
00765 }
00766 else if (S_ISDIR(stBuf.st_mode))
00767 {
00768
00769 if (strcmp(oneFile, ".") != 0 && strcmp(oneFile, "..") != 0)
00770 {
00771 maxrec--;
00772 if (maxrec >= 0)
00773 {
00774 status = RemoveDir(dirEntry, maxrec);
00775 }
00776 }
00777 }
00778 }
00779
00780 free(entry);
00781 }
00782
00783 fileIndex++;
00784 }
00785 }
00786
00787
00788 if (status == 0)
00789 {
00790 status = rmdir(pathname);
00791 }
00792 }
00793 }
00794
00795 return status;
00796 }
00797
00798
00799 size_t CopyFile(const char *src, const char *dst, int *ioerr)
00800 {
00801 struct stat stbuf;
00802 FILE *fptrS = NULL;
00803 FILE *fptrD = NULL;
00804 char buf[2048];
00805 size_t nbytes = 0;
00806 size_t nbytesW = 0;
00807 size_t nbytesTotal = 0;
00808 int err = 0;
00809
00810 if (!stat(src, &stbuf))
00811 {
00812 if (S_ISREG(stbuf.st_mode) || S_ISLNK(stbuf.st_mode))
00813 {
00814 fptrS = fopen(src, "r");
00815
00816 if (!fptrS)
00817 {
00818 err = errno;
00819 }
00820 else
00821 {
00822 fptrD = fopen(dst, "w");
00823
00824 if (!fptrD)
00825 {
00826 err = errno;
00827 }
00828 }
00829
00830 if (fptrS && fptrD)
00831 {
00832 while (1)
00833 {
00834 nbytes = fread(buf, sizeof(char), sizeof(buf), fptrS);
00835
00836 if (ferror(fptrS))
00837 {
00838 fprintf(stderr, "CopyFile(): read-stream error indicator.\n");
00839 break;
00840 }
00841
00842 if (nbytes == 0)
00843 {
00844 break;
00845 }
00846
00847 nbytesW = fwrite(buf, sizeof(char), nbytes, fptrD);
00848
00849 if (ferror(fptrD))
00850 {
00851 fprintf(stderr, "CopyFile(): write-stream error indicator.\n");
00852 break;
00853 }
00854
00855 if (nbytesW != nbytes)
00856 {
00857 fprintf(stderr, "CopyFile(): Failure writing all bytes.\n");
00858 break;
00859 }
00860
00861 nbytesTotal += nbytesW;
00862 }
00863 }
00864
00865 if (fptrS)
00866 {
00867 fclose(fptrS);
00868 }
00869
00870 if (fptrD)
00871 {
00872 fclose(fptrD);
00873 }
00874 }
00875 else if (S_ISDIR(stbuf.st_mode))
00876 {
00877
00878 if (mkdir(dst, 0777))
00879 {
00880 fprintf(stderr, "Could not create output directory '%s'.\n", dst);
00881 err = 1;
00882 }
00883 else
00884 {
00885 int nfiles = 0;
00886 int ifile;
00887 struct dirent **fileList = NULL;
00888 struct dirent *entry = NULL;
00889 char srcFile[PATH_MAX];
00890 char dstFile[PATH_MAX];
00891
00892 nfiles = scandir(src, &fileList, NULL, NULL);
00893
00894 for (ifile = 0 ; ifile < nfiles; ifile++)
00895 {
00896 entry = fileList[ifile];
00897
00898 if (entry != NULL)
00899 {
00900 char *oneFile = entry->d_name;
00901
00902 if (strcmp(oneFile, ".") != 0 && strcmp(oneFile, "..") != 0)
00903 {
00904
00905 snprintf(srcFile, sizeof(srcFile), "%s/%s", src, oneFile);
00906 snprintf(dstFile, sizeof(dstFile), "%s/%s", dst, oneFile);
00907 nbytesW = CopyFile(srcFile, dstFile, ioerr);
00908 nbytesTotal += nbytesW;
00909 }
00910
00911 free(entry);
00912 entry = NULL;
00913 }
00914 }
00915
00916 if (fileList)
00917 {
00918 free(fileList);
00919 fileList = NULL;
00920 }
00921 }
00922 }
00923 }
00924 else
00925 {
00926 err = errno;
00927 }
00928
00929 if (ioerr)
00930 {
00931 *ioerr = err;
00932 }
00933
00934 return nbytesTotal;
00935 }
00936
00937 void base_cleanup_init()
00938 {
00939 gCleanup = hcon_create(sizeof(BASE_Cleanup_t), 128, NULL, NULL, NULL, NULL, 0);
00940 }
00941
00942 int base_cleanup_register(const char *key, BASE_Cleanup_t *cu)
00943 {
00944 int error = 0;
00945
00946 if (!gCleanup)
00947 {
00948 base_cleanup_init();
00949 }
00950
00951 if (gCleanup)
00952 {
00953 if (hcon_lookup(gCleanup, key))
00954 {
00955
00956 fprintf(stderr, "base_cleanup_register(): cannot register '%s' - already exists.\n", key);
00957 error = 1;
00958 }
00959 else
00960 {
00961 hcon_insert(gCleanup, key, cu);
00962 }
00963 }
00964
00965 return error;
00966 }
00967
00968 int base_cleanup_go(const char *explicit)
00969 {
00970 int error = 0;
00971 BASE_Cleanup_t *cu = NULL;
00972
00973 if (gCleanup)
00974 {
00975 if (explicit && *explicit)
00976 {
00977 cu = hcon_lookup(gCleanup, explicit);
00978
00979 if (cu)
00980 {
00981 (*(cu->free))(cu->item);
00982 hcon_remove(gCleanup, explicit);
00983 }
00984 else
00985 {
00986 error = 1;
00987 }
00988 }
00989 else
00990 {
00991
00992 HIterator_t *hiter = hiter_create(gCleanup);
00993 const char *keyname = NULL;
00994 char **toRemove = NULL;
00995 int ielem;
00996 int ntotal;
00997
00998 ntotal = gCleanup->num_total;
00999
01000 if (gCleanup && ntotal > 0)
01001 {
01002 toRemove = calloc(gCleanup->num_total, sizeof(char *));
01003 }
01004
01005 if (toRemove)
01006 {
01007 ielem = 0;
01008 while ((cu = hiter_extgetnext(hiter, &keyname)) != NULL)
01009 {
01010 (*(cu->free))(cu->item);
01011
01012
01013
01014 toRemove[ielem] = strdup(keyname);
01015 if (!toRemove[ielem])
01016 {
01017 fprintf(stderr, "Out of memory in base_cleanup_go().\n");
01018 error = 1;
01019 break;
01020 }
01021
01022 ielem++;
01023 }
01024
01025 for (ielem = 0; ielem < ntotal; ielem++)
01026 {
01027 if (toRemove[ielem])
01028 {
01029 hcon_remove(gCleanup, toRemove[ielem]);
01030 free(toRemove[ielem]);
01031 toRemove[ielem] = NULL;
01032 }
01033 }
01034
01035 free(toRemove);
01036 toRemove = NULL;
01037 }
01038 else
01039 {
01040 fprintf(stderr, "Out of memory in base_cleanup_go().\n");
01041 error = 1;
01042 }
01043
01044 hiter_destroy(&hiter);
01045 }
01046 }
01047
01048 return error;
01049 }
01050
01051 void base_cleanup_term()
01052 {
01053 if (gCleanup)
01054 {
01055 hcon_destroy(&gCleanup);
01056 }
01057 }
01058
01059 void base_term()
01060 {
01061 base_cleanup_go(NULL);
01062 base_cleanup_term();
01063 }
01064
01065 int base_drmskeycheck(const char *drmsName)
01066 {
01067 return DRMSKeyNameValidationStatus(drmsName);
01068 }
01069
01070 int base_isvers(const char *vers, const char *minvers)
01071 {
01072 long long major;
01073 long long minor;
01074 long long minmajor;
01075 long long minminor;
01076
01077 int ok = 1;
01078
01079 if (*vers == '\0')
01080 {
01081 ok = 0;
01082 }
01083 else if (sscanf(vers, "%lld.%lld", &major, &minor) == 2)
01084 {
01085 if (*minvers != '\0')
01086 {
01087
01088 if (sscanf(minvers, "%lld.%lld", &minmajor, &minminor) == 2)
01089 {
01090 if (major < minmajor || (major == minmajor && minor < minminor))
01091 {
01092 ok = 0;
01093 }
01094 }
01095 else
01096 {
01097 fprintf(stderr, "Invalid version string '%s'.\n", minvers);
01098 ok = 0;
01099 }
01100 }
01101 }
01102 else
01103 {
01104 fprintf(stderr, "Invalid version string '%s'.\n", vers);
01105 ok = 0;
01106 }
01107
01108 return ok;
01109 }
01110
01111 int base_floatIsEqual(const float val1, const float val2)
01112 {
01113 union
01114 {
01115 int32_t integer;
01116 float singlePrecFP;
01117 } conv1, conv2;
01118
01119 conv1.singlePrecFP = val1;
01120 conv2.singlePrecFP = val2;
01121
01122 return (conv1.integer == conv2.integer);
01123 }
01124
01125 int base_doubleIsEqual(const double val1, const double val2)
01126 {
01127 union
01128 {
01129 int64_t integer;
01130 float doublePrecFP;
01131 } conv1, conv2;
01132
01133 conv1.doublePrecFP = val1;
01134 conv2.doublePrecFP = val2;
01135
01136 return (conv1.integer == conv2.integer);
01137 }