Changeset 6873 for trunk/psModules/src/config/pmConfig.c
- Timestamp:
- Apr 17, 2006, 8:10:08 AM (20 years ago)
- File:
-
- 1 edited
-
trunk/psModules/src/config/pmConfig.c (modified) (22 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psModules/src/config/pmConfig.c
r6418 r6873 3 3 * @author PAP, IfA 4 4 * 5 * @version $Revision: 1. 9$ $Name: not supported by cvs2svn $6 * @date $Date: 2006-0 2-10 02:43:19$5 * @version $Revision: 1.10 $ $Name: not supported by cvs2svn $ 6 * @date $Date: 2006-04-17 18:10:08 $ 7 7 * 8 8 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 11 11 #include <stdio.h> 12 12 #include <string.h> 13 #include <unistd.h> 14 #include <assert.h> 15 #include <sys/types.h> 16 #include <sys/stat.h> 17 #include <glob.h> 13 18 #include "pslib.h" 14 19 #include "pmConfig.h" 15 20 16 #define PS_SITE "PS_SITE" // Name of the environment variable containing the site config file 17 #define PS_DEFAULT_SITE "ipprc.config" // Default site config file 21 #define PS_SITE "PS_SITE" // Name of the environment variable containing the site config file 22 #define PS_DEFAULT_SITE ".ipprc" // Default site config file 23 24 static psArray *configPath = NULL; 25 26 static void configFree(pmConfig *config) 27 { 28 psFree(config->site); 29 psFree(config->files); 30 psFree(config->camera); 31 psFree(config->recipes); 32 psFree(config->arguments); 33 psFree(config->database); 34 } 35 36 pmConfig *pmConfigAlloc(void) 37 { 38 pmConfig *config = psAlloc(sizeof(pmConfig)); 39 (void)psMemSetDeallocator(config, (psFreeFunc)configFree); 40 41 // Initialise 42 config->site = NULL; 43 config->camera = NULL; 44 config->recipes = NULL; 45 config->arguments = NULL; 46 config->database = NULL; 47 48 // the file structure is used to carry pmFPAfiles 49 config->files = psMetadataAlloc (); 50 return config; 51 } 52 53 void pmConfigDone(void) 54 { 55 psFree(configPath); 56 } 57 18 58 19 59 /** readConfig … … 23 63 * 24 64 */ 25 staticbool readConfig(65 bool readConfig( 26 66 psMetadata **config, // Config to output 27 67 const char *name, // Name of file 28 68 const char *description) // Description of file 29 69 { 70 char *realName = NULL; 30 71 unsigned int numBadLines = 0; 72 struct stat filestat; 31 73 32 74 psLogMsg(__func__, PS_LOG_INFO, "Loading %s configuration from file %s\n", 33 75 description, name); 34 *config = psMetadataConfigParse(NULL, &numBadLines, name, true); 76 77 uid_t uid = getuid(); 78 gid_t gid = getgid(); 79 80 // we try: name, path[0]/name, path[1]/name, ... 81 // find the first existing entry in the path (starting with the bare name) 82 realName = psStringCopy (name); 83 psTrace (__func__, 5, "trying %s\n", realName); 84 85 int status = stat (realName, &filestat); 86 if (status == 0) { 87 if ((uid == filestat.st_uid) && (filestat.st_mode & S_IRUSR)) 88 goto found; 89 if ((gid == filestat.st_gid) && (filestat.st_mode & S_IRGRP)) 90 goto found; 91 if (filestat.st_mode & S_IROTH) 92 goto found; 93 } 94 psFree (realName); 95 96 if (configPath == NULL) { 97 psError(PS_ERR_IO, false, "Cannot find %s configuration file in path\n", description); 98 return false; 99 } 100 101 for (int i = 0; i < configPath->n; i++) { 102 realName = psStringCopy (configPath->data[i]); 103 psStringAppend (&realName, "/%s", name); 104 psTrace (__func__, 5, "trying %s\n", realName); 105 106 status = stat (realName, &filestat); 107 if (status == 0) { 108 if ((uid == filestat.st_uid) && (filestat.st_mode & S_IRUSR)) 109 goto found; 110 if ((gid == filestat.st_gid) && (filestat.st_mode & S_IRGRP)) 111 goto found; 112 if (filestat.st_mode & S_IROTH) 113 goto found; 114 } 115 psFree (realName); 116 } 117 118 psError(PS_ERR_IO, false, "Cannot find %s configuration file in path\n", description); 119 return false; 120 121 found: 122 *config = psMetadataConfigParse(NULL, &numBadLines, realName, true); 35 123 if (numBadLines > 0) { 36 124 psLogMsg(__func__, PS_LOG_WARN, "%d bad lines in %s configuration file (%s)\n", 37 description, name);125 description, realName); 38 126 } 39 127 if (!*config) { 40 128 psError(PS_ERR_IO, false, "Unable to read %s configuration from %s\n", 41 description, name); 129 description, realName); 130 psFree (realName); 42 131 return false; 43 132 } 44 133 134 psFree (realName); 45 135 return true; 46 136 } … … 57 147 line. 58 148 *****************************************************************************/ 59 bool pmConfigRead( 60 psMetadata **site, 61 psMetadata **camera, 62 psMetadata **recipe, 149 pmConfig *pmConfigRead( 63 150 int *argc, 64 char **argv, 65 const char *recipeName) 66 { 67 /* XXX: We need clarification on what is to be done if these arguments are 68 NULL. 69 PS_ASSERT_PTR_NON_NULL(site, false); 70 PS_ASSERT_PTR_NON_NULL(*site, false); 71 PS_ASSERT_PTR_NON_NULL(camera, false); 72 PS_ASSERT_PTR_NON_NULL(*camera, false); 73 PS_ASSERT_PTR_NON_NULL(recipe, false); 74 PS_ASSERT_PTR_NON_NULL(*recipe, false); 75 PS_ASSERT_INT_POSITIVE(*argc, false); 76 PS_ASSERT_PTR_NON_NULL(argv, false); 77 */ 151 char **argv) 152 { 153 PS_ASSERT_INT_POSITIVE(*argc, false); 154 PS_ASSERT_PTR_NON_NULL(argv, false); 155 156 pmConfig *config = pmConfigAlloc(); // The configuration, containing site, camera and recipes 157 78 158 // 79 159 // The following section of code attempts to determine which file is … … 97 177 "-site command-line switch provided without the required filename --- ignored.\n"); 98 178 } else { 99 siteName = argv[argNum];179 siteName = psStringCopy(argv[argNum]); 100 180 psArgumentRemove(argNum, argc, argv); 101 181 } … … 106 186 if (!siteName) { 107 187 siteName = getenv(PS_SITE); 188 if (siteName) { 189 siteName = psStringCopy (siteName); 190 } 108 191 } 109 192 … … 111 194 // Last chance is ~/.ipprc 112 195 // 113 bool cleanupSiteName = false; // Do I have to psFree siteName?114 196 if (!siteName) { 115 siteName = psStringCopy(PS_DEFAULT_SITE); 116 cleanupSiteName = true; 117 } 118 119 // 120 // We have the connfiguration filename; now we read and parse the config 197 char *home = getenv("HOME"); 198 siteName = psStringCopy(home); 199 psStringAppend(&siteName, "/%s", PS_DEFAULT_SITE); 200 } 201 202 203 // We have the configuration filename; now we read and parse the config 121 204 // file and store in psMetadata struct site. 122 205 // 123 206 124 if (!readConfig(site, siteName, "site")) { 125 return false; 126 } 127 if (cleanupSiteName) { 128 psFree(siteName); 129 } 130 131 132 // 133 // Next, we do a similar thing for the recipe configuration file. The 134 // file is read and parsed into psMetadata struct "recipe". 135 // 136 // 137 argNum = psArgumentGet(*argc, argv, "-recipe"); 138 if (argNum > 0) { 139 psArgumentRemove(argNum, argc, argv); 140 if (argNum >= *argc) { 141 psLogMsg(__func__, PS_LOG_WARN, 142 "-recipe command-line switch provided without the required filename --- ignored.\n"); 143 } else { 144 psArgumentRemove(argNum, argc, argv); 145 readConfig(recipe, argv[argNum], "recipe"); 146 } 147 } 148 // Or, load the recipe from the camera file, if appropriate 149 if (! *recipe && *camera && recipeName) { 150 *recipe = pmConfigRecipeFromCamera(*camera, recipeName); 151 } 152 153 154 // 207 if (!readConfig(&config->site, siteName, "site")) { 208 psFree(config); 209 return NULL; 210 } 211 psFree(siteName); 212 213 // define the config-file search path (configPath) 214 if (configPath) { 215 psFree(configPath); 216 configPath = NULL; 217 } 218 char *path = psMetadataLookupStr(NULL, config->site, "PATH"); 219 if (path) { 220 psList *list = psStringSplit(path, ":"); 221 configPath = psListToArray(list); 222 psFree(list); 223 } 224 155 225 // Next, we do a similar thing for the camera configuration file. The 156 226 // file is read and parsed into psMetadata struct "camera". … … 164 234 } else { 165 235 psArgumentRemove(argNum, argc, argv); 166 readConfig(camera, argv[argNum], "camera"); 167 } 168 } else { 169 // XXX: Not sure is this is correct. 170 *camera = NULL; 236 readConfig(&config->camera, argv[argNum], "camera"); 237 } 238 } 239 240 // Load the recipes from the camera file, if appropriate 241 if (! config->recipes && config->camera) { 242 pmConfigReadRecipes(config); 171 243 } 172 244 … … 183 255 // with a call to psTimeInitialize. 184 256 // 185 psString timeName = psMetadataLookupStr(&mdok, *site, "TIME");257 psString timeName = psMetadataLookupStr(&mdok, config->site, "TIME"); 186 258 if (mdok && timeName) { 187 259 psTrace(__func__, 7, "Initialising psTime with file %s\n", timeName); … … 195 267 // with a call to psLogSetLevel(). 196 268 // 197 int logLevel = psMetadataLookupS32(&mdok, *site, "LOGLEVEL");269 int logLevel = psMetadataLookupS32(&mdok, config->site, "LOGLEVEL"); 198 270 if (mdok && logLevel >= 0) { 199 271 psTrace(__func__, 7, "Setting log level to %d\n", logLevel); … … 206 278 // with a call to psLogSetFormat(). 207 279 // 208 psString logFormat = psMetadataLookupStr(&mdok, *site, "LOGFORMAT");280 psString logFormat = psMetadataLookupStr(&mdok, config->site, "LOGFORMAT"); 209 281 if (mdok && logFormat) { 210 282 psTrace(__func__, 7, "Setting log format to %s\n", logFormat); … … 218 290 // XXX: This is not spec'ed in the SDRS. 219 291 // 220 psString logDest = psMetadataLookupStr(&mdok, *site, "LOGDEST");292 psString logDest = psMetadataLookupStr(&mdok, config->site, "LOGDEST"); 221 293 if (mdok && logDest) { 222 // XXX: Only stdout isprovided for now; this section should be294 // XXX: Only stdout and stderr are provided for now; this section should be 223 295 // expanded in the future to do files, and perhaps even sockets. 224 if (strcasecmp(logDest, "STDOUT") != 0) { 225 psLogMsg(__func__, PS_LOG_WARN, "Only STDOUT is currently supported as a log destination.\n"); 296 int logFD = STDIN_FILENO; // a known invalid value 297 if (!strcasecmp(logDest, "STDOUT")) { 298 logFD = STDOUT_FILENO; 299 } 300 if (!strcasecmp(logDest, "STDERR")) { 301 logFD = STDERR_FILENO; 302 } 303 if (logFD == STDIN_FILENO) { 304 psLogMsg(__func__, PS_LOG_WARN, "Only STDERR and STDOUT currently supported as a log destination.\n"); 305 logFD = STDERR_FILENO; 226 306 } 227 307 psTrace(__func__, 7, "Setting log destination to STDOUT.\n"); 228 // XXX: Use something other than "1" 229 psLogSetDestination(1); 230 } 231 308 psLogSetDestination(logFD); 309 } 232 310 233 311 // … … 236 314 // XXX: This is not spec'ed in the SDRS. 237 315 // 238 psMetadata *trace = psMetadataLookupMD(&mdok, *site, "TRACE");316 psMetadata *trace = psMetadataLookupMD(&mdok, config->site, "TRACE"); 239 317 if (mdok && trace) { 240 318 psMetadataIterator *traceIter = psMetadataIteratorAlloc(trace, PS_LIST_HEAD, NULL); // Iterator … … 264 342 psLogSetLevel(saveLogLevel); 265 343 } 266 return(true); 267 } 268 269 bool pmConfigValidateCamera( 270 const psMetadata *camera, 344 345 return config; 346 } 347 348 349 bool pmConfigValidateCameraFormat( 350 const psMetadata *cameraFormat, 271 351 const psMetadata *header) 272 352 { 273 // Read the rule for that camera 353 // Read the rule for that camera format 274 354 bool mdStatus = true; 275 psMetadata *rule = psMetadataLookupMD(&mdStatus, camera , "RULE");355 psMetadata *rule = psMetadataLookupMD(&mdStatus, cameraFormat, "RULE"); 276 356 if (! mdStatus || ! rule) { 277 357 psLogMsg(__func__, PS_LOG_WARN, "Unable to read rule for camera.\n"); … … 282 362 psMetadataIterator *ruleIter = psMetadataIteratorAlloc(rule, PS_LIST_HEAD, NULL); // Rule iterator 283 363 psMetadataItem *ruleItem = NULL; // Item from the metadata 284 bool match = true; // Does it match? 285 while ((ruleItem = psMetadataGetAndIncrement(ruleIter)) && match) { 364 while ((ruleItem = psMetadataGetAndIncrement(ruleIter))) { 286 365 // Check for the existence of the rule 287 366 psMetadataItem *headerItem = psMetadataLookup((psMetadata*)header, ruleItem->name); 288 367 if (! headerItem || headerItem->type != ruleItem->type) { 289 match = false; 368 psFree(ruleIter); 369 return false; 290 370 } 291 371 … … 297 377 if (strncmp(ruleItem->data.V, headerItem->data.V, 298 378 strlen(ruleItem->data.V)) != 0) { 299 match = false; 379 psFree(ruleIter); 380 return false; 300 381 } 301 382 break; … … 305 386 ruleItem->data.S32, headerItem->data.S32); 306 387 if (ruleItem->data.S32 != headerItem->data.S32) { 307 match = false; 388 psFree(ruleIter); 389 return false; 308 390 } 309 391 break; … … 312 394 ruleItem->data.F32, headerItem->data.F32); 313 395 if (ruleItem->data.F32 != headerItem->data.F32) { 314 match = false; 396 psFree(ruleIter); 397 return false; 315 398 } 316 399 break; … … 319 402 ruleItem->data.F64, headerItem->data.F64); 320 403 if (ruleItem->data.F64 != headerItem->data.F64) { 321 match = false; 404 psFree(ruleIter); 405 return false; 322 406 } 323 407 break; … … 329 413 330 414 psFree(ruleIter); 331 332 return match; 333 } 334 335 336 337 // Work out what camera we have, based on the FITS header and a set of 338 // rules specified in the IPP configuration; return the camera configuration 339 psMetadata *pmConfigCameraFromHeader( 340 const psMetadata *ipprc, // The IPP configuration 341 const psMetadata *header) // The FITS header 342 { 343 bool mdStatus = false; // Metadata lookup status 344 psMetadata *cameras = psMetadataLookupMD(&mdStatus, ipprc, "CAMERAS"); 345 if (! mdStatus) { 346 psError(PS_ERR_IO, false, "Unable to find CAMERAS in the configuration.\n"); 347 return NULL; 348 } 349 psMetadata *winner = NULL; // The camera configuration whose rule first matches 350 // the supplied header 351 // Iterate over the cameras 352 psMetadataIterator *iterator = psMetadataIteratorAlloc(cameras, PS_LIST_HEAD, NULL); 353 psMetadataItem *cameraItem = NULL; // Item from the metadata 354 355 while ((cameraItem = psMetadataGetAndIncrement(iterator))) { 356 // Open the camera information 357 psTrace(__func__, 3, "Inspecting camera %s (%s)\n", cameraItem->name, 358 cameraItem->comment); 359 psMetadata *camera = NULL; // The camera metadata 360 if (cameraItem->type == PS_DATA_METADATA) { 361 camera = psMemIncrRefCounter(cameraItem->data.md); 362 } else if (cameraItem->type == PS_DATA_STRING) { 363 psTrace(__func__, 5, "Reading camera configuration for %s...\n", cameraItem->name); 364 unsigned int badLines = 0; // Number of bad lines in reading camera configuration 365 camera = psMetadataConfigParse(NULL, &badLines, cameraItem->data.V, true); 415 return true; 416 } 417 418 419 static bool formatFromHeader(psMetadata **format, // Format to return 420 psMetadata *camera, // Camera configuration 421 const psMetadata *header, // FITS header 422 const char *cameraName // Name of camera 423 ) 424 { 425 psMetadata *testFormat; 426 427 assert(format); 428 assert(camera); 429 assert(header); 430 431 bool result = false; // Did we find the first match? 432 433 // Read the list of formats 434 bool mdok = true; // Status of MD lookup 435 psMetadata *formats = psMetadataLookupMD(&mdok, camera, "FORMATS"); // List of formats 436 if (!mdok || !formats) { 437 psLogMsg(__func__, PS_LOG_WARN, "Unable to find list of FORMATS in camera %s --- ignored\n", 438 cameraName); 439 return false; 440 } 441 // Iterate over the formats 442 psMetadataIterator *formatsIter = psMetadataIteratorAlloc(formats, PS_LIST_HEAD, NULL); 443 psMetadataItem *formatsItem = NULL; // Item from formats 444 while ((formatsItem = psMetadataGetAndIncrement(formatsIter))) { 445 if (formatsItem->type != PS_DATA_STRING) { 446 psLogMsg(__func__, PS_LOG_WARN, "In camera %s, camera format %s is not of type STR --- " 447 "ignored.\n", cameraName, formatsItem->name); 448 continue; 449 } 450 psTrace(__func__, 5, "Reading camera format for %s...\n", formatsItem->name); 451 // unsigned int badLines = 0; // Number of bad lines in reading camera configuration 452 // Format to test against what we've got 453 454 if (!readConfig(&testFormat, formatsItem->data.V, formatsItem->name)) { 455 psLogMsg(__func__, PS_LOG_WARN, "trouble reading reading camera format %s\n", formatsItem->name); 456 psFree(testFormat); 457 continue; 458 } 459 460 # if (0) 461 psMetadata *testFormat = psMetadataConfigParse(NULL, &badLines, formatsItem->data.V, true); 462 if (badLines > 0) { 463 psLogMsg(__func__, PS_LOG_WARN, "%d bad lines encountered while reading camera" 464 "format %s\n", badLines, formatsItem->name); 465 } 466 # endif 467 468 if (pmConfigValidateCameraFormat(testFormat, header)) { 469 if (!*format) { 470 psLogMsg(__func__, PS_LOG_INFO, "Camera %s, format %s matches header.\n", cameraName, 471 formatsItem->name); 472 *format = psMemIncrRefCounter(testFormat); 473 result = true; 474 } else { 475 psLogMsg(__func__, PS_LOG_WARN, "Camera %s, format %s also matches header --- ignored.\n", 476 cameraName, formatsItem->name); 477 } 478 } 479 psFree(testFormat); 480 } 481 psFree(formatsIter); 482 483 return result; 484 } 485 486 // Work out what camera we have, based on the FITS header and a set of rules specified in the IPP 487 // configuration; return the camera configuration and format 488 psMetadata *pmConfigCameraFormatFromHeader( 489 pmConfig *config, // The configuration 490 const psMetadata *header // The FITS header 491 ) 492 { 493 psMetadata *format = NULL; // The winning format 494 bool mdok = false; // Metadata lookup status 495 psMetadata *testCamera = NULL; 496 497 // If we don't know what sort of camera we have, we try all that we know 498 if (! config->camera) { 499 psMetadata *cameras = psMetadataLookupMD(&mdok, config->site, "CAMERAS"); 500 if (! mdok) { 501 psError(PS_ERR_IO, false, "Unable to find CAMERAS in the configuration.\n"); 502 return false; 503 } 504 505 // Iterate over the cameras 506 psMetadataIterator *camerasIter = psMetadataIteratorAlloc(cameras, PS_LIST_HEAD, NULL); 507 psMetadataItem *camerasItem = NULL; // Item from the metadata 508 while ((camerasItem = psMetadataGetAndIncrement(camerasIter))) { 509 // Open the camera information 510 psTrace(__func__, 3, "Inspecting camera %s (%s)\n", camerasItem->name, camerasItem->comment); 511 if (camerasItem->type != PS_DATA_STRING) { 512 psLogMsg(__func__, PS_LOG_WARN, "Camera configuration for %s in CAMERAS is not of type STR " 513 "--- ignored.\n", camerasItem->name); 514 continue; 515 } 516 517 psTrace(__func__, 5, "Reading camera configuration for %s...\n", camerasItem->name); 518 // unsigned int badLines = 0; // Number of bad lines in reading camera configuration 519 // Camera to test against what we've got: 520 521 if (!readConfig(&testCamera, camerasItem->data.V, camerasItem->name)) { 522 psLogMsg(__func__, PS_LOG_WARN, "trouble reading reading camera configuration %s\n", camerasItem->name); 523 psFree(testCamera); 524 continue; 525 } 526 527 # if (0) 528 psMetadata *testCamera = psMetadataConfigParse(NULL, &badLines, camerasItem->data.V, true); 366 529 if (badLines > 0) { 367 530 psLogMsg(__func__, PS_LOG_WARN, "%d bad lines encountered while reading camera" 368 "configuration %s\n", badLines, cameraItem->name); 369 } 370 } 371 372 if (! camera) { 373 psLogMsg(__func__, PS_LOG_WARN, "Unable to interpret camera configuration for %s (%s)\n", 374 cameraItem->name, cameraItem->comment); 375 continue; 376 } 377 378 if (pmConfigValidateCamera(camera, header)) { 379 if (! winner) { 380 // This is the first match 381 winner = psMemIncrRefCounter(camera); 382 psLogMsg(__func__, PS_LOG_INFO, "FITS header matches camera %s\n", 383 cameraItem->name); 384 } else { 385 // We have a duplicate match 386 psLogMsg(__func__, PS_LOG_WARN, "Additional camera found that matches the rules: %s\n", 387 cameraItem->name); 388 } 389 } // Done inspecting the camera 390 391 psFree(camera); 392 393 } // Done looking at all cameras 394 if (! winner) { 395 psError(PS_ERR_IO, true, "Unable to find an camera that matches input FITS header!\n"); 396 } 397 398 psFree(iterator); 399 return winner; 400 } 401 402 psMetadata *pmConfigRecipeFromCamera( 403 const psMetadata *camera, 404 const char *recipeName) 405 { 406 PS_ASSERT_PTR_NON_NULL(camera, false); 407 PS_ASSERT_PTR_NON_NULL(recipeName, false); 408 409 psMetadata *recipe = NULL; // Recipe to read 531 "configuration %s\n", badLines, camerasItem->name); 532 } 533 # endif 534 535 if (! testCamera) { 536 psLogMsg(__func__, PS_LOG_WARN, "Unable to interpret camera configuration for %s (%s) --- " 537 "ignored\n", camerasItem->name, camerasItem->comment); 538 continue; 539 } 540 541 if (formatFromHeader(&format, testCamera, header, camerasItem->name)) { 542 config->camera = psMemIncrRefCounter(testCamera); 543 } 544 psFree(testCamera); 545 } // Done looking at all cameras 546 psFree(camerasIter); 547 548 if (! config->camera) { 549 psError(PS_ERR_IO, true, "Unable to find a camera that matches input FITS header!\n"); 550 return NULL; 551 } 552 553 // Now we have the camera, we can read the recipes 554 if (!config->recipes) { 555 pmConfigReadRecipes(config); 556 } 557 558 return format; 559 } 560 561 // Otherwise, try the specific camera 562 if (! formatFromHeader(&format, config->camera, header, "specified camera")) { 563 psError(PS_ERR_IO, true, "Unable to find a format with the specified camera that matches the " 564 "given header.\n"); 565 return NULL; 566 } 567 return format; 568 } 569 570 bool pmConfigReadRecipes( 571 pmConfig *config 572 ) 573 { 574 PS_ASSERT_PTR_NON_NULL(config, false); 575 PS_ASSERT_PTR_NON_NULL(config->camera, false); 576 577 if (!config->recipes) { 578 config->recipes = psMetadataAlloc(); 579 } 580 410 581 bool mdok = true; // Status of MD lookup 411 psMetadata *recipes = psMetadataLookupMD(&mdok, c amera, "RECIPES"); // The list of recipes582 psMetadata *recipes = psMetadataLookupMD(&mdok, config->camera, "RECIPES"); // The list of recipes 412 583 if (! mdok || ! recipes) { 413 584 psLogMsg(__func__, PS_LOG_WARN, "RECIPES in the camera configuration file is not of type METADATA\n"); 414 } else { 415 psString recipeFileName = psMetadataLookupStr(&mdok, recipes, recipeName); 416 (void)readConfig(&recipe, recipeFileName, "recipe"); 417 } 418 419 return recipe; 585 return false; 586 } 587 // Go through the recipes and load each one 588 psMetadataIterator *recipesIter = psMetadataIteratorAlloc(recipes, PS_LIST_HEAD, NULL); // Iterator 589 psMetadataItem *recipesItem = NULL; // Item from iteration 590 while ((recipesItem = psMetadataGetAndIncrement(recipesIter))) { 591 if (recipesItem->type != PS_DATA_STRING) { 592 psLogMsg(__func__, PS_LOG_WARN, "Filename for recipe %s isn't of type STR --- ignored.\n", 593 recipesItem->name); 594 continue; 595 } 596 597 psMetadata *recipe = NULL; // Recipe from file 598 if (readConfig(&recipe, recipesItem->data.V, "recipe")) { 599 psMetadataAdd(config->recipes, PS_LIST_TAIL, recipesItem->name, 600 PS_DATA_METADATA | PS_META_REPLACE, recipesItem->comment, recipe); 601 } 602 psFree(recipe); // Drop reference 603 } 604 psFree(recipesIter); 605 606 return true; 420 607 } 421 608 … … 423 610 pmConfigDB(*site) 424 611 612 XXX: this should allow the option of having NO database server, if chosen by config 425 613 XXX: What should we use for the Database namespace in the call to psDBInit()? 426 614 This is currently NULL. 427 615 *****************************************************************************/ 428 616 429 #ifdef OMIT_PSDB430 psDB *pmConfigDB(psMetadata *site)431 {432 psError(PS_ERR_UNKNOWN, true, "pslib was built without psDB support");433 return NULL;434 }435 #else436 617 psDB *pmConfigDB( 437 618 psMetadata *site) … … 442 623 psBool mdStatus03 = false; 443 624 625 // XXX leaky strings 444 626 psString dbServer = psMetadataLookupStr(&mdStatus01, site, "DBSERVER"); 445 627 psString dbUsername = psMetadataLookupStr(&mdStatus02, site, "DBUSER"); 446 628 psString dbPassword = psMetadataLookupStr(&mdStatus03, site, "DBPASSWORD"); 447 629 psString dbName = psMetadataLookupStr(&mdStatus01, site, "DBNAME"); 448 449 630 if (!(mdStatus01 & mdStatus02 & mdStatus03)) { 450 631 psLogMsg(__func__, PS_LOG_WARN, "Could not determine database server name, userID, and password from site metadata.\n"); 451 return NULL; 452 } 453 454 455 456 psDB *dbh = psDBInit(dbServer, dbUsername, dbPassword, dbName); 457 psFree(dbServer); 458 psFree(dbUsername); 459 psFree(dbPassword); 460 psFree(dbName); 461 462 if (!dbh) { 463 psError(PS_ERR_UNKNOWN, false, "database connection failed"); 464 } 465 466 return dbh; 467 } 468 #endif 632 return(NULL); 633 } 634 635 return(psDBInit(dbServer, dbUsername, dbPassword, dbName)); 636 } 637 638 639 bool pmConfigConformHeader(psMetadata *header, // Header to conform 640 const psMetadata *format // Camera format 641 ) 642 { 643 bool mdok = true; // Status of MD lookup 644 psMetadata *rules = psMetadataLookupMD(&mdok, format, "RULE"); // How to identify this format 645 if (!mdok || !rules) { 646 psError(PS_ERR_IO, false, "Unable to find RULE in camer format.\n"); 647 return false; 648 } 649 650 psMetadataIterator *rulesIter = psMetadataIteratorAlloc(rules, PS_LIST_HEAD, NULL); // Iterator for rules 651 psMetadataItem *rulesItem = NULL; // Item from iteration 652 while ((rulesItem = psMetadataGetAndIncrement(rulesIter))) { 653 psMetadataItem *newItem = psMetadataItemCopy(rulesItem); // Copy of item 654 psMetadataAddItem(header, newItem, PS_LIST_TAIL, PS_META_REPLACE); 655 psFree(newItem); // Drop reference 656 } 657 psFree(rulesIter); 658 659 return true; 660 } 661 662 // given the 'file' and 'list' words, find the arguments associated with these words 663 // and interpret them as lists of files. return an array of the resulting filenames. 664 psArray *pmConfigFileSets (int *argc, char **argv, char *file, char *list) 665 { 666 667 int Narg; 668 669 // we load all input files onto a psArray, to be parsed later 670 psArray *input = psArrayAlloc (16); 671 input->n = 0; 672 673 // load the list of filenames the supplied file (may be a glob: "file*.fits") 674 if ((Narg = psArgumentGet (*argc, argv, file))) { 675 glob_t globList; 676 psArgumentRemove (Narg, argc, argv); 677 globList.gl_offs = 0; 678 glob (argv[Narg], 0, NULL, &globList); 679 for (int i = 0; i < globList.gl_pathc; i++) { 680 char *filename = psStringCopy (globList.gl_pathv[i]); 681 psArrayAdd (input, 16, filename); 682 psFree (filename); 683 } 684 psArgumentRemove (Narg, argc, argv); 685 } 686 687 // load the list from the supplied text file 688 if ((Narg = psArgumentGet (*argc, argv, list))) { 689 int nItems; 690 char line[1024]; // XXX limits the list lines to 1024 chars 691 char word[1024]; 692 char *filename; 693 694 psArgumentRemove (Narg, argc, argv); 695 FILE *f = fopen (argv[Narg], "r"); 696 if (f == NULL) { 697 psAbort ("psphot", "unable to open specified list file"); 698 } 699 while (fgets (line, 1024, f) != NULL) { 700 nItems = sscanf (line, "%s", word); 701 switch (nItems) { 702 case 0: 703 break; 704 case 1: 705 filename = psStringCopy (word); 706 psArrayAdd (input, 16, filename); 707 psFree (filename); 708 break; 709 default: 710 // rigid format, no comments allowed? 711 psAbort ("pmConfig", "error parsing input list file"); 712 break; 713 } 714 } 715 psArgumentRemove (Narg, argc, argv); 716 } 717 718 return input; 719 } 720 721 bool pmConfigFileSetsMD (psMetadata *metadata, int *argc, char **argv, char *name, char *file, char *list) 722 { 723 724 psArray *files = pmConfigFileSets (argc, argv, file, list); 725 if (files->n == 0) { 726 psFree (files); 727 return false; 728 } 729 730 psMetadataAddPtr (metadata, PS_LIST_TAIL, name, PS_DATA_ARRAY, "", files); 731 psFree (files); 732 return true; 733 }
Note:
See TracChangeset
for help on using the changeset viewer.
