00001 #include "jsoc_main.h"
00002 #include "drms_types.h"
00003 #include "drms_storageunit.h"
00004 #include "exputil.h"
00005 #include "fitsexport.h"
00006
00007 #include "defs.h"
00008 REGISTERSTRINGSPREFIX
00009 #include "data/export.defs"
00010 REGISTERSTRINGSSUFFIX
00011
00158 char *module_name = "export";
00159
00160 typedef enum
00161 {
00162 kMymodErr_Success = 0,
00163 kMymodErr_CantRegisterDefs,
00164 kMymodErr_MissingArg,
00165 kMymodErr_BadRequestID,
00166 kMymodErr_BadRecSetQuery,
00167 kMymodErr_BadFilenameFmt,
00168 kMymodErr_ExportFailed,
00169 kMymodErr_CantOpenPackfile,
00170 kMymodErr_PackfileFailure,
00171 kMymodErr_UnsupportedPLRecType,
00172 kMymodErr_DRMS,
00173 kMymodErr_MissingSegFile
00174 } MymodError_t;
00175
00176 typedef enum
00177 {
00178 kPL_metadata,
00179 kPL_content
00180 } PLRecType_t;
00181
00182 #define kNotSpecified "NOT SPECIFIED"
00183 #define kArg_reqid "reqid"
00184 #define kArg_version "expversion"
00185 #define kArg_method "method"
00186 #define kArg_protocol "protocol"
00187 #define kArg_rsquery "rsquery"
00188 #define kArg_n "n"
00189 #define kArg_expSeries "expseries"
00190 #define kArg_ffmt "ffmt"
00191 #define kArg_path "path"
00192 #define kArg_clname "kmclass"
00193 #define kArg_kmfile "kmfile"
00194 #define kArg_cparms "cparms"
00195
00196
00197 #define kDef_expSeries "jsoc.export"
00198
00199 #define kPWD "PWD"
00200
00201 #define kNoCompression "**NONE**"
00202
00203 #define kMB (1048576)
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218 ModuleArgs_t module_args[] =
00219 {
00220 {ARG_STRING, kArg_version, kNotSpecified, "jsoc export version."},
00221 {ARG_STRING, kArg_reqid, kNotSpecified,
00222 "Export series primary key value that identifies the output record."},
00223 {ARG_STRING, kArg_method, kNotSpecified, "jsoc export method (eg, url or ftp)."},
00224 {ARG_STRING, kArg_protocol, kNotSpecified, "file conversion method (eg, convert to fits)."},
00225 {ARG_STRING, kArg_rsquery, kNotSpecified,
00226 "Record-set query that specifies data to be exported."},
00227 {ARG_STRING, kArg_expSeries, kDef_expSeries, "Series to which exported data are saved."},
00228 {ARG_STRING, kArg_ffmt, kNotSpecified, "Export filename template."},
00229 {ARG_STRING, kArg_path, kNotSpecified, "Path to which fits files are output."},
00230 {ARG_STRING, kArg_clname, kNotSpecified, "Export key map class."},
00231 {ARG_STRING, kArg_kmfile, kNotSpecified, "Export key map file."},
00232 {ARG_STRING, kArg_cparms, kNotSpecified, "FITS-stanford compression string used to compress exported image."},
00233 {ARG_INT, kArg_n, "0", "Record count limit."},
00234 {ARG_END}
00235 };
00236
00237 char gDefBuf[PATH_MAX] = {0};
00238
00239 static void JEAFPrintLocalTime(FILE *stm, const char *msg)
00240 {
00241 char tbuf[64];
00242 time_t sounnecessarilycomplicated;
00243 struct tm *ltime = NULL;
00244
00245 time(&sounnecessarilycomplicated);
00246 ltime = localtime(&sounnecessarilycomplicated);
00247
00248 *tbuf = '\0';
00249 if (ltime)
00250 {
00251 snprintf(tbuf, sizeof(tbuf), "%s", asctime(ltime));
00252 fprintf(stm, "%s - %s\n", tbuf, msg);
00253 }
00254 }
00255
00256
00257 static long long ToMB(long long nbytes)
00258 {
00259 if (nbytes <= kMB && nbytes > 0)
00260 {
00261 return 1;
00262 }
00263
00264 return (long long)((nbytes + 0.5 * kMB) / kMB);
00265 }
00266
00267 MymodError_t WritePListRecord(PLRecType_t rectype, FILE *pkfile, const char *f1, const char *f2)
00268 {
00269 MymodError_t err = kMymodErr_Success;
00270
00271 switch (rectype)
00272 {
00273 case kPL_metadata:
00274 fprintf(pkfile, "%s=%s\n", f1, f2);
00275 break;
00276 case kPL_content:
00277 fprintf(pkfile, "%s\t%s\n", f1, f2);
00278 break;
00279 default:
00280 fprintf(stderr, "Unsupported packing-list record type '%d'.\n", (int)rectype);
00281 err = kMymodErr_UnsupportedPLRecType;
00282 }
00283
00284 return err;
00285 }
00286
00287
00288
00289 static unsigned long long MapexportRecordToDir(DRMS_Record_t *recin,
00290 const char *ffmt,
00291 const char *outpath,
00292 FILE *pklist,
00293 const char *classname,
00294 const char *mapfile,
00295 int *tcount,
00296 const char **cparms,
00297 MymodError_t *status,
00298 char **errmsg)
00299 {
00300 int drmsstat = DRMS_SUCCESS;
00301 MymodError_t modstat = kMymodErr_Success;
00302 DRMS_Segment_t *segin = NULL;
00303 DRMS_Segment_t *tgtseg = NULL;
00304 unsigned long long tsize = 0;
00305 unsigned long long expsize = 0;
00306 char *actualfname = NULL;
00307 char dir[DRMS_MAXPATHLEN];
00308 char fmtname[DRMS_MAXPATHLEN];
00309 char fullfname[DRMS_MAXPATHLEN];
00310 char query[DRMS_MAXQUERYLEN];
00311 HIterator_t *last = NULL;
00312 int iseg;
00313 int lastcparms;
00314 int count;
00315 char buf[256];
00316 ExpUtlStat_t expfn = kExpUtlStat_Success;
00317
00318
00319 drms_record_directory(recin, dir, 1);
00320
00321
00322
00323 drms_sprint_rec_query(query, recin);
00324
00325
00326
00327
00328 iseg = 0;
00329 lastcparms = 0;
00330 count = 0;
00331
00332 while ((segin = drms_record_nextseg(recin, &last, 0)) != NULL)
00333 {
00334 if (segin->info->islink)
00335 {
00336 if ((tgtseg = drms_segment_lookup(recin, segin->info->name)) == NULL)
00337 {
00338 fprintf(stderr, "Unable to locate target segment %s.\n", segin->info->name);
00339 iseg++;
00340 continue;
00341 }
00342 }
00343 else
00344 {
00345 tgtseg = segin;
00346 }
00347
00348 if ((expfn = exputl_mk_expfilename(segin, tgtseg, ffmt, fmtname)) == kExpUtlStat_Success)
00349 {
00350 snprintf(fullfname, sizeof(fullfname), "%s/%s", outpath, fmtname);
00351 }
00352 else
00353 {
00354 if (expfn == kExpUtlStat_InvalidFmt)
00355 {
00356 fprintf(stderr, "Invalid file-name format template '%s'.\n", ffmt);
00357 }
00358 else if (expfn == kExpUtlStat_UnknownKey)
00359 {
00360 fprintf(stderr, "One or more keywords in the file-name format template '%s' do not exist in series '%s'.\n", ffmt, recin->seriesinfo->seriesname);
00361 }
00362
00363 modstat = kMymodErr_BadFilenameFmt;
00364 break;
00365 }
00366
00367 if (!cparms || !cparms[iseg])
00368 {
00369 lastcparms = 1;
00370 }
00371
00372
00373
00374
00375 drmsstat = fitsexport_mapexport_tofile(segin,
00376 !lastcparms ? cparms[iseg] : NULL,
00377 classname,
00378 mapfile,
00379 fullfname,
00380 &actualfname,
00381 &expsize);
00382
00383 if (drmsstat == DRMS_ERROR_INVALIDFILE)
00384 {
00385
00386 fprintf(stderr, "Requested input file %s is missing or invalid.\n", segin->filename);
00387 }
00388 else if (drmsstat != DRMS_SUCCESS)
00389 {
00390
00391 modstat = kMymodErr_ExportFailed;
00392 fprintf(stderr, "Failure exporting segment '%s'.\n", segin->info->name);
00393
00394 if (errmsg)
00395 {
00396 if (drmsstat == DRMS_ERROR_CANTCOMPRESSFLOAT)
00397 {
00398 *errmsg = strdup("Cannot export Rice-compressed floating-point images.\n");
00399 }
00400 }
00401 break;
00402 }
00403 else
00404 {
00405 count++;
00406 tsize += expsize;
00407 WritePListRecord(kPL_content, pklist, query, actualfname);
00408 }
00409
00410 iseg++;
00411 }
00412
00413
00414
00415 if (count == 0)
00416 {
00417 modstat = kMymodErr_ExportFailed;
00418 }
00419
00420 if (tcount)
00421 {
00422 *tcount = count;
00423 }
00424
00425 if (last)
00426 {
00427 hiter_destroy(&last);
00428 }
00429
00430 if (actualfname)
00431 {
00432 free(actualfname);
00433 }
00434
00435 if (status)
00436 {
00437 *status = modstat;
00438 }
00439
00440 return tsize;
00441 }
00442
00443 static unsigned long long MapexportToDir(DRMS_Env_t *env,
00444 const char *rsinquery,
00445 const char *ffmt,
00446 const char *outpath,
00447 FILE *pklist,
00448 const char *classname,
00449 const char *mapfile,
00450 int *tcount,
00451 TIME *exptime,
00452 const char **cparms,
00453 MymodError_t *status)
00454 {
00455 int stat = DRMS_SUCCESS;
00456 MymodError_t modstat = kMymodErr_Success;
00457 DRMS_RecordSet_t *rsin = NULL;
00458 DRMS_Record_t *recin = NULL;
00459 int iRec = 0;
00460 int nSets = 0;
00461 int iSet = 0;
00462 int nRecs = 0;
00463 int RecordLimit = *tcount;
00464 unsigned long long tsize = 0;
00465 int errorCount = 0;
00466 int okayCount = 0;
00467 int count;
00468 int itcount;
00469
00470
00471 itcount = 0;
00472
00473
00474 if (RecordLimit == 0)
00475
00476
00477
00478 rsin = drms_open_records(env, rsinquery, &stat);
00479 else
00480 rsin = drms_open_nrecords(env, rsinquery, RecordLimit, &stat);
00481
00482
00483 if (rsin)
00484 {
00485
00486 drms_stage_records(rsin, 1, 0);
00487 nSets = rsin->ss_n;
00488
00489 for (iSet = 0; iSet < nSets; iSet++)
00490 {
00491 nRecs = drms_recordset_getssnrecs(rsin, iSet, &stat);
00492
00493 if (stat != DRMS_SUCCESS)
00494 {
00495 fprintf(stderr, "Failure calling drms_recordset_getssnrecs(), skipping subset '%d'.\n", iSet);
00496 }
00497 else
00498 {
00499 for (iRec = 0; iRec < nRecs; iRec++)
00500 {
00501 recin = drms_recordset_fetchnext(env, rsin, &stat, NULL, NULL);
00502
00503 if (!recin)
00504 {
00505
00506 break;
00507 }
00508
00509 count = 0;
00510 tsize += MapexportRecordToDir(recin,
00511 ffmt,
00512 outpath,
00513 pklist,
00514 classname,
00515 mapfile,
00516 &count,
00517 cparms,
00518 &modstat,
00519 NULL);
00520 if (modstat == kMymodErr_Success)
00521 {
00522 okayCount++;
00523 itcount += count;
00524 }
00525 else
00526 {
00527 errorCount++;
00528 }
00529 }
00530 }
00531 }
00532
00533 modstat = kMymodErr_Success;
00534
00535
00536 if (errorCount > 0)
00537 {
00538 fprintf(stderr,"Export failed for %d segments of %d attempted.\n", errorCount, errorCount + okayCount);
00539 }
00540
00541 if (exptime)
00542 {
00543 *exptime = CURRENT_SYSTEM_TIME;
00544 }
00545 if (tcount)
00546 {
00547 *tcount = itcount;
00548 }
00549 }
00550 else
00551 {
00552 fprintf(stderr, "Record-set query '%s' is not valid.\n", rsinquery);
00553 modstat = kMymodErr_BadRecSetQuery;
00554 }
00555
00556 if (rsin)
00557 {
00558 drms_close_records(rsin, DRMS_FREE_RECORD);
00559 }
00560
00561 if (status)
00562 {
00563 *status = modstat;
00564 }
00565
00566 return tsize;
00567 }
00568
00569 static MymodError_t CallExportToFile(DRMS_Segment_t *segout,
00570 DRMS_Segment_t *segin,
00571 DRMS_Segment_t *tgtseg,
00572 const char *clname,
00573 const char *mapfile,
00574 const char *ffmt,
00575 unsigned long long *szout,
00576 char *filewritten,
00577 const char *cparms,
00578 char **errmsg)
00579 {
00580 int status = DRMS_SUCCESS;
00581 MymodError_t err = kMymodErr_Success;
00582 char fileout[DRMS_MAXPATHLEN];
00583 char filein[DRMS_MAXPATHLEN];
00584 char basename[DRMS_MAXPATHLEN];
00585 unsigned long long size = 0;
00586 unsigned long long expsize = 0;
00587 char *actualfname = NULL;
00588 struct stat filestat;
00589
00590 if (segout)
00591 {
00592 if (segin->info->islink)
00593 {
00594 drms_segment_filename(tgtseg, filein);
00595 }
00596 else
00597 {
00598 drms_segment_filename(segin, filein);
00599 }
00600
00601 if (!stat(filein, &filestat))
00602 {
00603 ExpUtlStat_t expfn = kExpUtlStat_Success;
00604 size = filestat.st_size;
00605
00606 if ((expfn = exputl_mk_expfilename(segin, tgtseg, ffmt, basename)) == kExpUtlStat_Success)
00607 {
00608 CHECKSNPRINTF(snprintf(segout->filename, DRMS_MAXSEGFILENAME, "%s", basename), DRMS_MAXSEGFILENAME);
00609 drms_segment_filename(segout, fileout);
00610
00611 status = fitsexport_mapexport_tofile(segin, cparms, clname, mapfile, fileout, &actualfname, &expsize);
00612 if (status == DRMS_ERROR_INVALIDFILE)
00613 {
00614
00615 err = kMymodErr_MissingSegFile;
00616 }
00617 else if (status != DRMS_SUCCESS)
00618 {
00619 err = kMymodErr_ExportFailed;
00620 fprintf(stderr, "Failed to export segment '%s' to '%s'.\n", segin->info->name, fileout);
00621 if (errmsg)
00622 {
00623 if (status == DRMS_ERROR_CANTCOMPRESSFLOAT)
00624 {
00625 *errmsg = strdup("Cannot export Rice-compressed floating-point images.\n");
00626 }
00627 }
00628 }
00629 }
00630 else
00631 {
00632 if (expfn == kExpUtlStat_InvalidFmt)
00633 {
00634 fprintf(stderr, "Invalid file-name format template '%s'.\n", ffmt);
00635 }
00636 else if (expfn == kExpUtlStat_UnknownKey)
00637 {
00638 fprintf(stderr, "One or more keywords in the file-name format template '%s' do not exist in series '%s'.\n", ffmt, segin->record->seriesinfo->seriesname);
00639 }
00640
00641 err = kMymodErr_BadFilenameFmt;
00642 }
00643 }
00644 else
00645 {
00646 fprintf(stderr, "Unable to open source file '%s'.\n", filein);
00647 err = kMymodErr_ExportFailed;
00648 }
00649 }
00650
00651 *szout = 0;
00652 if (err == kMymodErr_Success)
00653 {
00654 *szout = size;
00655 snprintf(filewritten, DRMS_MAXPATHLEN, "%s", basename);
00656 }
00657
00658 if (actualfname)
00659 {
00660 free(actualfname);
00661 }
00662
00663 return err;
00664 }
00665
00666
00667 static int MapexportRecord(DRMS_Record_t *recout,
00668 DRMS_Record_t *recin,
00669 const char *classname,
00670 const char *mapfile,
00671 const char *pklfilename,
00672 int *tcount,
00673 const char *ffmt,
00674 char **outpath,
00675 FILE **pklist,
00676 const char **cparms,
00677 MymodError_t *status)
00678 {
00679 MymodError_t err = kMymodErr_Success;
00680 HIterator_t *last = NULL;
00681 DRMS_Segment_t *segout = NULL;
00682 DRMS_Segment_t *segin = NULL;
00683 DRMS_Segment_t *tgtseg = NULL;
00684 unsigned long long size = 0;
00685 unsigned long long tsize = 0;
00686 char dir[DRMS_MAXPATHLEN];
00687 int iseg;
00688 int lastcparms;
00689 int gotone;
00690
00691 segout = drms_segment_lookupnum(recout, 0);
00692
00693 drms_record_directory(recin, dir, 1);
00694
00695 if (segout)
00696 {
00697 char glom[128];
00698 snprintf(glom, sizeof(glom), "%%s/%s", DRMS_SLOTDIR_FORMAT);
00699 char path[DRMS_MAXPATHLEN];
00700 snprintf(path, sizeof(path), glom, segout->record->su->sudir, segout->record->slotnum);
00701
00702 if (outpath)
00703 {
00704 *outpath = strdup(path);
00705 }
00706
00707 if (pklist)
00708 {
00709 char pkpath[DRMS_MAXPATHLEN];
00710 snprintf(pkpath, sizeof(pkpath), "%s/%s", path, pklfilename);
00711 *pklist = fopen(pkpath, "w+");
00712 }
00713
00714 char fname[DRMS_MAXPATHLEN];
00715 char query[DRMS_MAXQUERYLEN];
00716
00717
00718 char buf[1028];
00719 int nkeys = recin->seriesinfo->dbidx_num;
00720 int snext = 0;
00721 int ikey = 0;
00722
00723 snprintf(query, sizeof(query), "%s", recin->seriesinfo->seriesname);
00724 snext = strlen(query);
00725
00726 for (ikey = 0; ikey < nkeys; ikey++)
00727 {
00728 drms_keyword_snprintfval(recin->seriesinfo->dbidx_keywords[ikey], buf, sizeof(buf));
00729 snprintf(query + snext, sizeof(query) - snext, "[%s]", buf);
00730 snext += strlen(buf) + 2;
00731 }
00732
00733
00734
00735 iseg = 0;
00736 lastcparms = 0;
00737 gotone = 0;
00738
00739 while ((segin = drms_record_nextseg(recin, &last, 0)) != NULL)
00740 {
00741 if (segin->info->islink)
00742 {
00743 if ((tgtseg = drms_segment_lookup(recin, segin->info->name)) == NULL)
00744 {
00745 fprintf(stderr, "Unable to locate target segment %s.\n", segin->info->name);
00746 iseg++;
00747 continue;
00748 }
00749 }
00750 else
00751 {
00752 tgtseg = segin;
00753 }
00754
00755 size = 0;
00756
00757 if (!cparms || !cparms[iseg])
00758 {
00759 lastcparms = 1;
00760 }
00761
00762 err = CallExportToFile(segout,
00763 segin,
00764 tgtseg,
00765 classname,
00766 mapfile,
00767 ffmt,
00768 &size,
00769 fname,
00770 !lastcparms ? cparms[iseg] : NULL,
00771 NULL);
00772
00773 if (err == kMymodErr_MissingSegFile)
00774 {
00775
00776 }
00777 else if (err != kMymodErr_Success)
00778 {
00779 fprintf(stderr, "Failure exporting segment '%s'.\n", segin->info->name);
00780 break;
00781 }
00782 else
00783 {
00784 gotone = 1;
00785
00786 if (tcount)
00787 {
00788 ++*tcount;
00789 }
00790
00791 tsize += size;
00792 if (pklist && *pklist)
00793 {
00794 WritePListRecord(kPL_content, *pklist, query, fname);
00795 }
00796 }
00797
00798 iseg++;
00799 }
00800
00801
00802
00803 if (!gotone)
00804 {
00805 err = kMymodErr_ExportFailed;
00806 fprintf(stderr, "Failure exporting record number %lld.\n", recin->recnum);
00807 }
00808
00809 if (last)
00810 {
00811 hiter_destroy(&last);
00812 }
00813 }
00814 else
00815 {
00816 fprintf(stderr, "Export series contains no segment!\n");
00817 err = kMymodErr_ExportFailed;
00818 }
00819
00820 if (status)
00821 {
00822 *status = err;
00823 }
00824
00825 return tsize;
00826 }
00827
00828
00829
00830
00831 static int Mapexport(DRMS_Env_t *env,
00832 const char *reqid,
00833 const char *classname,
00834 const char *mapfile,
00835 const char *expseries,
00836 const char *pklfilename,
00837 int *tcount,
00838 char **outpath,
00839 TIME *exptime,
00840 FILE **pklist,
00841 const char **cparms,
00842 MymodError_t *status)
00843 {
00844 int stat;
00845 MymodError_t err = kMymodErr_Success;
00846 int nSets = 0;
00847 int iSet = 0;
00848 int nRecs = 0;
00849 int iRec = 0;
00850 unsigned long long tsize = 0;
00851 DRMS_Record_t *recout = NULL;
00852 DRMS_Record_t *recin = NULL;
00853 DRMS_RecordSet_t *rs = NULL;
00854 DRMS_RecordSet_t *rsout = NULL;
00855 DRMS_RecordSet_t *rsin = NULL;
00856 char rsoutquery[DRMS_MAXQUERYLEN];
00857 char *rsinquery = NULL;
00858
00859 snprintf(rsoutquery, sizeof(rsoutquery), "%s[%s]", expseries, reqid);
00860
00861 rs = drms_open_records(env, rsoutquery, &stat);
00862
00863 if (rs)
00864 {
00865
00866 rsout = drms_clone_records(rs, DRMS_PERMANENT, DRMS_COPY_SEGMENTS, &stat);
00867 drms_close_records(rs, DRMS_FREE_RECORD);
00868 }
00869
00870 if (rsout && rsout->n == 1)
00871 {
00872
00873 char *ffmt = NULL;
00874 char *kval = NULL;
00875
00876 recout = rsout->records[0];
00877 rsinquery = drms_getkey_string(recout, drms_defs_getval("kExportKW_Request"), &stat);
00878
00879 kval = drms_getkey_string(recout, drms_defs_getval("kExportKW_FileNameFormat"), &stat);
00880 if (kval)
00881 {
00882 if (*kval == '\0')
00883 {
00884 ffmt = NULL;
00885 }
00886 else
00887 {
00888 ffmt = strdup(kval);
00889 }
00890
00891 free(kval);
00892 }
00893
00894
00895
00896
00897 if (rsinquery && (rsin = drms_open_records(env, rsinquery, &stat)))
00898 {
00899
00900 drms_stage_records(rsin, 1, 0);
00901 nSets = rsin->ss_n;
00902
00903 for (iSet = 0;
00904 stat == DRMS_SUCCESS && err == kMymodErr_Success && iSet < nSets;
00905 iSet++)
00906 {
00907
00908
00909
00910 nRecs = drms_recordset_getssnrecs(rsin, iSet, &stat);
00911
00912 for (iRec = 0;
00913 stat == DRMS_SUCCESS && err == kMymodErr_Success &&iRec < nRecs;
00914 iRec++)
00915 {
00916 recin = drms_recordset_fetchnext(env, rsin, &stat, NULL, NULL);
00917
00918 if (!recin)
00919 {
00920
00921 break;
00922 }
00923
00924 tsize += MapexportRecord(recout,
00925 recin,
00926 classname,
00927 mapfile,
00928 pklfilename,
00929 tcount,
00930 ffmt,
00931 outpath,
00932 pklist,
00933 cparms,
00934 &err);
00935 }
00936 }
00937
00938 if (stat != DRMS_SUCCESS || err != kMymodErr_Success)
00939 {
00940 fprintf(stderr, "Export halted due to DRMS failure.\n");
00941 }
00942 else if (exptime)
00943 {
00944 *exptime = CURRENT_SYSTEM_TIME;
00945 }
00946 }
00947 else
00948 {
00949 fprintf(stderr,
00950 "Export series keyword '%s' did not contain a valid recordset query.\n",
00951 drms_defs_getval("kExportKW_Request"));
00952 err = kMymodErr_BadRecSetQuery;
00953 }
00954
00955 if (ffmt)
00956 {
00957 free(ffmt);
00958 }
00959 }
00960 else
00961 {
00962 fprintf(stderr, "Could not open export destination record set with request id '%s'.\n", reqid);
00963 err = kMymodErr_BadRequestID;
00964 }
00965
00966
00967 if (err == kMymodErr_Success)
00968 {
00969 drms_setkey_time(recout, drms_defs_getval("kExportKW_ExpTime"), CURRENT_SYSTEM_TIME);
00970 drms_setkey_int(recout, drms_defs_getval("kExportKW_DataSize"), (int)ToMB(tsize));
00971 }
00972
00973 if (rsout)
00974 {
00975 drms_close_records(rsout, DRMS_INSERT_RECORD);
00976 }
00977
00978 if (rsinquery)
00979 {
00980 free(rsinquery);
00981 }
00982
00983 if (status)
00984 {
00985 *status = err;
00986 }
00987
00988 return tsize;
00989 }
00990
00991 static char *GenErrMsg(const char *fmt, ...)
00992 {
00993 char *msgout = NULL;
00994 char errmsg[4096];
00995
00996 va_list ap;
00997 va_start(ap, fmt);
00998 vsnprintf(errmsg, sizeof(errmsg), fmt, ap);
00999
01000 msgout = strdup(errmsg);
01001 fprintf(stderr, errmsg);
01002
01003 va_end (ap);
01004
01005 return msgout;
01006 }
01007
01008 static MymodError_t AppendContent(FILE *dst, FILE *src)
01009 {
01010 MymodError_t err = kMymodErr_Success;
01011 char buf[32768];
01012 int nread = 0;
01013 int dstfd;
01014 int srcfd;
01015
01016 if (dst && src)
01017 {
01018 dstfd = fileno(dst);
01019 srcfd = fileno(src);
01020
01021 while(1)
01022 {
01023 nread = read(srcfd, buf, sizeof(buf));
01024 if (nread > 0)
01025 {
01026 if (write(dstfd, buf, nread) == -1)
01027 {
01028 err = kMymodErr_PackfileFailure;
01029 fprintf(stderr, "Failure writing packing-list file.\n");
01030 break;
01031 }
01032 }
01033 else
01034 {
01035 if (nread == -1)
01036 {
01037 err = kMymodErr_PackfileFailure;
01038 fprintf(stderr, "Failure reading packing-list file.\n");
01039 }
01040
01041 break;
01042 }
01043 }
01044 }
01045
01046 return err;
01047 }
01048
01049
01050
01051
01052
01053
01054 int DoIt(void)
01055 {
01056 MymodError_t err = kMymodErr_Success;
01057 int drmsstat = DRMS_SUCCESS;
01058 long long tsize = 0;
01059 long long tsizeMB = 0;
01060 int tcount = 0;
01061 TIME exptime = DRMS_MISSING_TIME;
01062 FILE *pklist = NULL;
01063 FILE *pklistTMP = NULL;
01064 char pklistfname[PATH_MAX];
01065 char pklistfnameTMP[PATH_MAX];
01066 char pklistpath[PATH_MAX];
01067 char pklistpathTMP[PATH_MAX];
01068
01069 const char *version = NULL;
01070 const char *reqid = NULL;
01071 const char *method = NULL;
01072 const char *protocol = NULL;
01073 const char *rsquery = NULL;
01074 const char *clname = NULL;
01075 const char *mapfile = NULL;
01076 const char *cparmsarg = NULL;
01077 const char **cparms = NULL;
01078 int RecordLimit = 0;
01079
01080
01081 char *md_version = NULL;
01082 char *md_reqid = NULL;
01083 char *md_method = NULL;
01084 char *md_protocol = NULL;
01085 char *md_count = NULL;
01086 char *md_size = NULL;
01087 char *md_exptime = NULL;
01088 char *md_dir = NULL;
01089
01090 char *md_status = NULL;
01091 char *md_error = NULL;
01092
01093 RecordLimit = cmdparams_get_int(&cmdparams, kArg_n, &drmsstat);
01094
01095
01096 defs_init();
01097
01098 snprintf(pklistfname, sizeof(pklistfname), "%s", drms_defs_getval("kPackListFileName"));
01099 snprintf(pklistfnameTMP, sizeof(pklistfnameTMP), "%s.tmp", pklistfname);
01100
01101 version = cmdparams_get_str(&cmdparams, kArg_version, &drmsstat);
01102 reqid = cmdparams_get_str(&cmdparams, kArg_reqid, &drmsstat);
01103 method = cmdparams_get_str(&cmdparams, kArg_method, &drmsstat);
01104 protocol = cmdparams_get_str(&cmdparams, kArg_protocol, &drmsstat);
01105
01106 rsquery = cmdparams_get_str(&cmdparams, kArg_rsquery, &drmsstat);
01107
01108
01109 clname = cmdparams_get_str(&cmdparams, kArg_clname, &drmsstat);
01110 if (drmsstat != DRMS_SUCCESS || !strcmp(clname, kNotSpecified))
01111 {
01112 clname = NULL;
01113 }
01114
01115 mapfile = cmdparams_get_str(&cmdparams, kArg_kmfile, &drmsstat);
01116 if (drmsstat != DRMS_SUCCESS || !strcmp(mapfile, kNotSpecified))
01117 {
01118 mapfile = NULL;
01119 }
01120
01121 cparmsarg = cmdparams_get_str(&cmdparams, kArg_cparms, &drmsstat);
01122 if (strcmp(cparmsarg, kNotSpecified))
01123 {
01124 char *dup = strdup(cparmsarg);
01125 char *pc = NULL;
01126 char *pend = NULL;
01127 int nstr;
01128 int istr;
01129
01130
01131 pc = dup;
01132 nstr = 1;
01133 while ((pc = strchr(pc, ',')) != NULL)
01134 {
01135 pc++;
01136 ++nstr;
01137 }
01138
01139 cparms = (const char **)malloc((nstr + 1) * sizeof(char *));
01140
01141 pc = dup;
01142 for (istr = 0; istr < nstr; istr++)
01143 {
01144 pend = strchr(pc, ',');
01145 if (pend)
01146 {
01147 *pend = '\0';
01148 }
01149 cparms[istr] = (strcmp(pc, kNoCompression) == 0) ? strdup("") : strdup(pc);
01150 if (pend)
01151 {
01152 pc = pend + 1;
01153 }
01154 }
01155
01156
01157 cparms[nstr] = NULL;
01158
01159 if (dup)
01160 {
01161 free(dup);
01162 }
01163 }
01164
01165 md_version = strdup(version);
01166 md_reqid = strdup(reqid);
01167 md_method = strdup(method);
01168 md_protocol = strdup(protocol);
01169
01170 if (strcmp(rsquery, kNotSpecified) == 0)
01171 {
01172
01173
01174
01175
01176
01177
01178
01179 char *outpath = NULL;
01180
01181
01182 const char *expseries = NULL;
01183
01184 if (strcmp(reqid, kNotSpecified) == 0)
01185 {
01186
01187 md_error = GenErrMsg("Invalid arguments - missing reqid.\n");
01188 err = kMymodErr_MissingArg;
01189 }
01190 else
01191 {
01192
01193 expseries = cmdparams_get_str(&cmdparams, kArg_expSeries, &drmsstat);
01194
01195
01196 tsize = Mapexport(drms_env,
01197 reqid,
01198 clname,
01199 mapfile,
01200 expseries,
01201 pklistfnameTMP,
01202 &tcount,
01203 &outpath,
01204 &exptime,
01205 &pklistTMP,
01206 cparms,
01207 &err);
01208
01209 if (err != kMymodErr_Success)
01210 {
01211 md_error = GenErrMsg("Failure occurred while processing export Request ID '%s'.\n", reqid);
01212 err = kMymodErr_ExportFailed;
01213 }
01214 else
01215 {
01216 snprintf(pklistpathTMP, sizeof(pklistpathTMP), "%s/%s", outpath, pklistfnameTMP);
01217
01218
01219 md_dir = strdup(outpath);
01220 }
01221
01222 if (outpath)
01223 {
01224 free(outpath);
01225 }
01226 }
01227 }
01228 else
01229 {
01230
01231
01232
01233
01234 const char *outpath = NULL;
01235
01236
01237 const char *ffmt = NULL;
01238
01239 outpath = cmdparams_get_str(&cmdparams, kArg_path, &drmsstat);
01240 if (strcmp(outpath, kNotSpecified) == 0)
01241 {
01242
01243 outpath = getenv(kPWD);
01244 }
01245
01246 ffmt = cmdparams_get_str(&cmdparams, kArg_ffmt, &drmsstat);
01247 if (strcmp(ffmt, kNotSpecified) == 0 || *ffmt == '\0')
01248 {
01249
01250 ffmt = NULL;
01251 }
01252
01253
01254 snprintf(pklistpathTMP, sizeof(pklistpathTMP), "%s/%s", outpath, pklistfnameTMP);
01255
01256 pklistTMP = fopen(pklistpathTMP, "w+");
01257 if (pklistTMP)
01258 {
01259
01260 tcount = RecordLimit;
01261 tsize = MapexportToDir(drms_env,
01262 rsquery,
01263 ffmt,
01264 outpath,
01265 pklistTMP,
01266 clname,
01267 mapfile,
01268 &tcount,
01269 &exptime,
01270 cparms,
01271 &err);
01272
01273 }
01274 else
01275 {
01276 err = kMymodErr_CantOpenPackfile;
01277 md_error = GenErrMsg("Couldn't open temporary packing-list file '%s'.\n", pklistpathTMP);
01278 }
01279
01280 if (err != kMymodErr_Success)
01281 {
01282 md_error = GenErrMsg("Failure occurred while processing export Request ID '%s'.\n", reqid);
01283 err = kMymodErr_ExportFailed;
01284 }
01285 else
01286 {
01287
01288 md_dir = strdup(outpath);
01289 }
01290 }
01291
01292 tsizeMB = ToMB(tsize);
01293
01294 if (err == kMymodErr_Success)
01295 {
01296 char tstr[64];
01297 int strsize = 0;
01298 sprint_time(tstr, exptime, "UT", 0);
01299
01300
01301 strsize = 64;
01302 md_size = malloc(strsize);
01303 snprintf(md_size, strsize, "%lld", tsizeMB);
01304 md_count = malloc(strsize);
01305 snprintf(md_count, strsize, "%d", tcount);
01306 md_exptime = strdup(tstr);
01307 }
01308
01309 fprintf(stdout, "%lld megabytes exported.\n", tsizeMB);
01310
01311
01312 if (strcmp(reqid, kNotSpecified) != 0)
01313 {
01314 if (md_dir)
01315 {
01316 snprintf(pklistpath, sizeof(pklistpath), "%s/%s", md_dir, pklistfname);
01317 pklist = fopen(pklistpath, "w+");
01318
01319 if (pklist)
01320 {
01321 if (fseek(pklistTMP, 0, SEEK_SET))
01322 {
01323 md_error = GenErrMsg("Failure accessing packing-list file '%s'.\n", pklistfnameTMP);
01324 err = kMymodErr_PackfileFailure;
01325 }
01326 }
01327 else
01328 {
01329 md_error = GenErrMsg("Failure opening packing-list file '%s'.\n", pklistfname);
01330 err = kMymodErr_PackfileFailure;
01331 }
01332 }
01333
01334
01335 if (err == kMymodErr_Success)
01336 {
01337 md_status = strdup(drms_defs_getval("kMDStatus_Good"));
01338 }
01339 else
01340 {
01341 md_status = strdup(drms_defs_getval("kMDStatus_Bad"));
01342 }
01343
01344 if (pklist)
01345 {
01346 char procSteps[PATH_MAX];
01347 FILE *fpProcSteps = NULL;
01348 struct stat stBuf;
01349 char *lineBuf = NULL;
01350 size_t lineLen = 0;
01351 ssize_t nRead = 0;
01352
01353
01354 fprintf(pklist, "# JSOC \n");
01355 WritePListRecord(kPL_metadata, pklist, drms_defs_getval("kMD_Version"), md_version);
01356 WritePListRecord(kPL_metadata, pklist, drms_defs_getval("kMD_RequestID"), md_reqid);
01357 WritePListRecord(kPL_metadata, pklist, drms_defs_getval("kMD_Method"), md_method);
01358 WritePListRecord(kPL_metadata, pklist, drms_defs_getval("kMD_Protocol"), md_protocol);
01359 WritePListRecord(kPL_metadata, pklist, drms_defs_getval("kMD_Count"), md_count ? md_count : "-1");
01360 WritePListRecord(kPL_metadata, pklist, drms_defs_getval("kMD_Size"), md_size ? md_size : "-1");
01361 WritePListRecord(kPL_metadata, pklist, drms_defs_getval("kMD_ExpTime"), md_exptime ? md_exptime : "");
01362 WritePListRecord(kPL_metadata, pklist, drms_defs_getval("kMD_Dir"), md_dir ? md_dir : "");
01363 WritePListRecord(kPL_metadata, pklist, drms_defs_getval("kMD_Status"), md_status);
01364
01365
01366 snprintf(procSteps, sizeof(procSteps), "%s/proc-steps.txt", md_dir);
01367 if (stat(procSteps, &stBuf) == 0)
01368 {
01369 fprintf(pklist, "# PROCESSING \n");
01370
01371 fpProcSteps = fopen(procSteps, "r");
01372 if (fpProcSteps)
01373 {
01374 while ((nRead = getline(&lineBuf, &lineLen, fpProcSteps)) != -1)
01375 {
01376
01377 fprintf(pklist, lineBuf);
01378 }
01379
01380 if (lineBuf)
01381 {
01382 free(lineBuf);
01383 }
01384 }
01385 }
01386
01387 fflush(pklist);
01388
01389 if (err == kMymodErr_Success)
01390 {
01391
01392 fprintf(pklist, "# DATA \n");
01393 fflush(pklist);
01394 if (tsizeMB > 0)
01395 {
01396 err = AppendContent(pklist, pklistTMP);
01397 }
01398 else
01399 {
01400 WritePListRecord(kPL_metadata, pklist, drms_defs_getval("kMD_Warning"), "No FITS files were exported. The requested FITS files no longer exist.");
01401 }
01402 }
01403
01404 if (err != kMymodErr_Success)
01405 {
01406 fflush(pklist);
01407
01408
01409 WritePListRecord(kPL_metadata, pklist, drms_defs_getval("kMD_Error"), md_error ? md_error : "");
01410 }
01411 }
01412 }
01413
01414 if (pklistTMP)
01415 {
01416
01417 fclose(pklistTMP);
01418 pklistTMP = NULL;
01419
01420
01421 unlink(pklistpathTMP);
01422 }
01423
01424 if (pklist)
01425 {
01426
01427 fclose(pklist);
01428 pklist = NULL;
01429 }
01430
01431 if (md_version)
01432 {
01433 free(md_version);
01434 }
01435 if (md_reqid)
01436 {
01437 free(md_reqid);
01438 }
01439 if (md_method)
01440 {
01441 free(md_method);
01442 }
01443 if (md_protocol)
01444 {
01445 free(md_protocol);
01446 }
01447 if (md_count)
01448 {
01449 free(md_count);
01450 }
01451 if (md_size)
01452 {
01453 free(md_size);
01454 }
01455 if (md_exptime)
01456 {
01457 free(md_exptime);
01458 }
01459 if (md_dir)
01460 {
01461 free(md_dir);
01462 }
01463 if (md_status)
01464 {
01465 free(md_status);
01466 }
01467 if (md_error)
01468 {
01469 free(md_error);
01470 }
01471
01472 if (cparms)
01473 {
01474 int iseg = 0;
01475 while (cparms[iseg])
01476 {
01477 free((void *)cparms[iseg]);
01478 iseg++;
01479 }
01480
01481 free(cparms);
01482 }
01483
01484 return err;
01485 }