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
00008 #include "fitsio.h"
00009 #include "cfitsio.h"
00010 #include "libtar.h"
00011 #define MAXTARSIZE 2147483648
00012 #define MAXFILETARSIZE 21474836480
00013
00014 #ifndef __export_callback_func_t__
00015 #define __export_callback_func_t__
00016 typedef int (*export_callback_func_t)(char *, ...);
00017 #endif
00018 typedef struct RequestAttr_struct
00019 {
00020 int rscount;
00021 const char **cparms;
00022 const char *outpath;
00023 const char *method;
00024 char scid[512];
00025 const char *stagestatusfile;
00026 char **rsffmt;
00027 char **rsquery;
00028 FILE *fstatus;
00029 TAR *tar;
00030 long reccount;
00031 int arraypointer;
00032 tartype_t tartype;
00033 int terminate;
00034 char *infobuffer;
00035 char *errorbuffer;
00036 int print_header;
00037
00038 } RequestAttr;
00039
00040 #define QUED "QUED"
00041 #define NQUE "NQUE"
00042 #define FAIL "FAIL"
00043 #define DONE "DONE"
00044 #define URL_CGI "url_cgi"
00045 #define STAGE_CGI "stage_cgi"
00046
00047 void ExportHandle(char *callbackState, ...);
00048 void printRequestAttr(RequestAttr *reqattr);
00049 void freeRequestAttr(RequestAttr *reqattr);
00050 int addQueryToReqattr(RequestAttr *reqattr, const char * rsquery, const char * ffmt);
00051 int populatereqattr(RequestAttr *reqattr, const char * rsqueryfile);
00052
00053 int flytar_append_file_header(TAR *t, char * filename, int size);
00054 int flytar_append_file_tail(TAR *t, int size);
00055 int flytar_append_file(TAR *t, FILE *ftar, char * fullname);
00056 int file_set_stats(TAR *t, int size, char * filename);
00057 int block_rest(int block_size, int file_size);
00058 char * flattenstring(char *str1, const char *str2, int n);
00059 int match_query_segments(DRMS_Segment_t *seg);
00060 char ** parse_query_for_segment_names(char * query);
00061 int count_segment_names(char **segments);
00062 int testRecordCount(DRMS_RecordSet_t* rsin, int* stat, int querySegCount);
00063 void CallbackErrorBuffer( RequestAttr *lreqattr, char* filename, char*query, int errorCode);
00064 void CallbackClose(RequestAttr *lreqattr, FILE *ftar);
00065 void CallbackInfo(RequestAttr *lreqattr, char * filename);
00066 void generateStageTarName(const char * stagedir, const char * f_scid, int stagetarcount, char* newname);
00067 int checkdir(const char *dirname);
00068 int checkfile(const char *filename);
00069 FILE * openstatefile(const char *sfile, const char *reqid, int *cstatus);
00070 int stgprintf(FILE *file, const char *format,...);
00071 void setstagestate(const char * path, const char * scid, const char * state);
00072
00073
00074 char sackfile[4000];
00075 char starfile[4000];
00076 char gcgi_request[200];
00077 char **segments = (char **) NULL;
00078
00079
00080
00227 char *module_name = "export";
00228
00229 typedef enum
00230 {
00231 kMymodErr_Success = 0,
00232 kMymodErr_CantRegisterDefs,
00233 kMymodErr_MissingArg,
00234 kMymodErr_BadRequestID,
00235 kMymodErr_BadRecSetQuery,
00236 kMymodErr_BadFilenameFmt,
00237 kMymodErr_ExportFailed,
00238 kMymodErr_CantOpenPackfile,
00239 kMymodErr_PackfileFailure,
00240 kMymodErr_UnsupportedPLRecType,
00241 kMymodErr_DRMS,
00242 kMymodErr_MissingSegFile,
00243 kMymodErr_QuedFileExists,
00244 kMymodErr_MaxURLSizeReached,
00245 kMymodErr_Rename2QuedFail
00246 } MymodError_t;
00247
00248 typedef enum
00249 {
00250 kPL_metadata,
00251 kPL_content
00252 } PLRecType_t;
00253
00254 #define kNotSpecified "NOT SPECIFIED"
00255 #define kArg_reqid "reqid"
00256 #define kArg_version "expversion"
00257 #define kArg_method "method"
00258
00259 #define kArg_ackfile "ackfile"
00260 #define kArg_tarfile "tarfile"
00261 #define kArg_cgi_request "cgi_request"
00262 #define kArg_segments "segments"
00263
00264 #define kArg_protocol "protocol"
00265 #define kArg_rsqueryfile "rsqueryfile"
00266 #define kArg_rsquery "rsquery"
00267 #define kArg_n "n"
00268 #define kArg_expSeries "expseries"
00269 #define kArg_ffmt "ffmt"
00270 #define kArg_path "path"
00271 #define kArg_clname "kmclass"
00272 #define kArg_kmfile "kmfile"
00273 #define kArg_cparms "cparms"
00274 #define kArg_stagestatusfile "stagestatusfile"
00275
00276
00277 #define kDef_expSeries "jsoc.export"
00278
00279 #define kPWD "PWD"
00280
00281 #define kNoCompression "**NONE**"
00282
00283 #define kMB (1048576)
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298 ModuleArgs_t module_args[] =
00299 {
00300 {ARG_STRING, kArg_version, "", "jsoc export version."},
00301 {ARG_STRING, kArg_reqid, "",
00302 "Export series primary key value that identifies the output record."},
00303 {ARG_STRING, kArg_method, "", "jsoc export method (eg, url or ftp)."},
00304
00305 {ARG_STRING, kArg_ackfile, kNotSpecified, "Acknowledgement File"},
00306 {ARG_STRING, kArg_tarfile, kNotSpecified, "Tar File Name"},
00307 {ARG_STRING, kArg_cgi_request, kNotSpecified, "CGI request HEAD,GET,POST"},
00308 {ARG_STRING, kArg_segments, kNotSpecified, "Export segment name."},
00309
00310 {ARG_STRING, kArg_protocol, "", "file conversion method (eg, convert to fits)."},
00311 {ARG_STRING, kArg_rsquery, kNotSpecified,
00312 "Record-set query that specifies data to be exported."},
00313 {ARG_STRING, kArg_rsqueryfile, kNotSpecified,
00314 "Record-set query file list that specifies data to be exported."},
00315 {ARG_STRING, kArg_expSeries, kDef_expSeries, "Series to which exported data are saved."},
00316 {ARG_STRING, kArg_ffmt, kNotSpecified, "Export filename template."},
00317 {ARG_STRING, kArg_path, kNotSpecified, "Path to which fits files are output."},
00318 {ARG_STRING, kArg_clname, kNotSpecified, "Export key map class."},
00319 {ARG_STRING, kArg_kmfile, kNotSpecified, "Export key map file."},
00320 {ARG_STRING, kArg_stagestatusfile, kNotSpecified, "Status file in Stage Status directory."},
00321 {ARG_STRING, kArg_cparms, kNotSpecified, "FITS-stanford compression string used to compress exported image."},
00322 {ARG_INT, kArg_n, "0", "Record count limit."},
00323 {ARG_END}
00324 };
00325
00326 char gDefBuf[PATH_MAX] = {0};
00327
00328
00329 static long long ToMB(long long nbytes)
00330 {
00331 if (nbytes <= kMB)
00332 {
00333 return 1;
00334 }
00335
00336 return nbytes / kMB;
00337 }
00338
00339 MymodError_t WritePListRecord(PLRecType_t rectype, FILE *pkfile, const char *f1, const char *f2)
00340 {
00341 MymodError_t err = kMymodErr_Success;
00342 return err;
00343 #if 0
00344
00345 switch (rectype)
00346 {
00347 case kPL_metadata:
00348 fprintf(pkfile, "%s=%s\n", f1, f2);
00349 break;
00350 case kPL_content:
00351 fprintf(pkfile, "%s\t%s\n", f1, f2);
00352 break;
00353 default:
00354 fprintf(stderr, "Unsupported packing-list record type '%d'.\n", (int)rectype);
00355 err = kMymodErr_UnsupportedPLRecType;
00356 }
00357
00358 return err;
00359 #endif
00360 }
00361
00362
00363
00364 static int MapexportRecordToDir(DRMS_Record_t *recin,
00365 const char *ffmt,
00366 const char *outpath,
00367 FILE *pklist,
00368 const char *classname,
00369 const char *mapfile,
00370 int *tcount,
00371 const char **cparms,
00372 MymodError_t *status,
00373 export_callback_func_t callback)
00374 {
00375 int drmsstat = DRMS_SUCCESS;
00376 MymodError_t modstat = kMymodErr_Success;
00377 DRMS_Segment_t *segin = NULL;
00378 DRMS_Segment_t *tgtseg = NULL;
00379 unsigned long long tsize = 0;
00380 unsigned long long expsize = 0;
00381 char *actualfname = NULL;
00382 char dir[DRMS_MAXPATHLEN];
00383 char fmtname[DRMS_MAXPATHLEN];
00384 char fullfname[DRMS_MAXPATHLEN];
00385 char query[DRMS_MAXQUERYLEN];
00386 struct stat filestat;
00387 HIterator_t *last = NULL;
00388 int iseg;
00389 int lastcparms;
00390 int gotone;
00391
00392 drms_record_directory(recin, dir, 1);
00393
00394
00395 drms_sprint_rec_query(query, recin);
00396
00397
00398
00399
00400 iseg = 0;
00401 lastcparms = 0;
00402 gotone = 0;
00403
00404 while ((segin = drms_record_nextseg(recin, &last, 1)) != NULL)
00405 {
00406 if (segin->info->islink)
00407 {
00408 if ((tgtseg = drms_segment_lookup(recin, segin->info->name)) == NULL)
00409 {
00410 fprintf(stderr, "Unable to locate target segment %s.\n", segin->info->name);
00411 iseg++;
00412 continue;
00413 }
00414 }
00415 else
00416 {
00417 tgtseg = segin;
00418 }
00419
00420 if (exputl_mk_expfilename(segin, tgtseg, ffmt, fmtname) == kExpUtlStat_Success)
00421 {
00422
00423 snprintf(fullfname, sizeof(fullfname), "%s", fmtname);
00424
00425
00426
00427 }
00428 else
00429 {
00430 modstat = kMymodErr_BadFilenameFmt;
00431 break;
00432 }
00433
00434 if (!cparms || !cparms[iseg])
00435 {
00436 lastcparms = 1;
00437 }
00438
00439 drmsstat = fitsexport_mapexport_tofile2( segin,
00440 !lastcparms ? cparms[iseg] : NULL,
00441 classname,
00442 mapfile,
00443 fullfname,
00444 &actualfname,
00445 &expsize,
00446 callback);
00447
00448
00449 if ( drmsstat != DRMS_SUCCESS && callback != NULL) {
00450 fprintf(stderr, "(1) Failure exporting segment '%s'.\n", segin->info->name);
00451 (*callback)("error",query,fullfname);
00452 }
00453 else if (drmsstat == DRMS_ERROR_INVALIDFILE)
00454 {
00455
00456 }
00457 else if ((drmsstat != DRMS_SUCCESS ||
00458 ( stat(fullfname, &filestat) ) && (callback == NULL)) )
00459 {
00460
00461 modstat = kMymodErr_ExportFailed;
00462 fprintf(stderr, "(2) Failure exporting segment '%s'.\n", segin->info->name);
00463 break;
00464 }
00465 else
00466 {
00467
00468 if (callback != NULL) {
00469 (*callback)("info",fullfname);
00470 } else {
00471
00472 gotone = 1;
00473
00474 if (tcount)
00475 {
00476 ++*tcount;
00477 }
00478
00479 tsize += filestat.st_size;
00480 WritePListRecord(kPL_content, pklist, query, fmtname);
00481 }
00482 }
00483
00484 iseg++;
00485 }
00486
00487
00488
00489 if (!gotone && callback == NULL)
00490 {
00491 modstat = kMymodErr_ExportFailed;
00492 }
00493
00494 if (last)
00495 {
00496 hiter_destroy(&last);
00497 }
00498
00499 if (actualfname)
00500 {
00501 free(actualfname);
00502 }
00503
00504 if (status)
00505 {
00506 *status = modstat;
00507 }
00508
00509 return tsize;
00510 }
00511
00512
00513
00514 static long long VSOExportData (DRMS_Env_t *env,
00515 RequestAttr *reqattr,
00516 int *tcount,
00517 const char **cparms,
00518 MymodError_t *status)
00519 {
00520 int stat = DRMS_SUCCESS;
00521 MymodError_t modstat = kMymodErr_Success;
00522 DRMS_RecordSet_t *rsin = NULL;
00523 DRMS_Record_t *recin = NULL;
00524 int iRec = 0;
00525 int nSets = 0;
00526 int iSet = 0;
00527 int nRecs = 0;
00528 unsigned long long tsize = 0;
00529 int errorCount = 0;
00530 int okayCount = 0;
00531
00532 export_callback_func_t callback = (export_callback_func_t) ExportHandle;
00533
00534 int segmentCount=0;
00535
00536
00537
00538 (*callback)("init",reqattr);
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550 for (; reqattr->arraypointer<reqattr->rscount; reqattr->arraypointer++) {
00551
00552 char *rsinquery=reqattr->rsquery[reqattr->arraypointer];
00553 rsin = drms_open_records(env, rsinquery, &stat);
00554
00555 if (rsin)
00556 {
00557 reqattr->reccount+=testRecordCount(rsin,&stat,segmentCount) - 1;
00558 fprintf(stderr,"drms_export_cgi::Record Count [%ld]\n",reqattr->reccount);
00559
00560
00561 drms_stage_records(rsin, 1, 0);
00562 nSets = rsin->ss_n;
00563
00564 for (iSet = 0; iSet < nSets; iSet++)
00565 {
00566 nRecs = drms_recordset_getssnrecs(rsin, iSet, &stat);
00567
00568
00569 if (stat != DRMS_SUCCESS)
00570 {
00571 fprintf(stderr, "Failure calling drms_recordset_getssnrecs(), skipping subset '%d'.\n", iSet);
00572 }
00573 else
00574 {
00575 for (iRec = 0; iRec < nRecs; iRec++)
00576 {
00577 recin = rsin->records[(rsin->ss_starts)[iSet] + iRec];
00578 fprintf(stderr, "nRecs [%d] rsin[%d]\n",nRecs,(rsin->ss_starts)[iSet] + iRec);
00579 MapexportRecordToDir(recin,
00580 reqattr->rsffmt[reqattr->arraypointer],
00581 NULL,
00582 NULL,
00583 NULL,
00584 NULL,
00585 tcount,
00586 cparms,
00587 &modstat,
00588 callback);
00589 fprintf(stderr, "out of MapexportRecordToDir\n");
00590 if (modstat == kMymodErr_Success)
00591 {
00592 okayCount++;
00593 }
00594 else
00595 {
00596 errorCount++;
00597 }
00598
00599 if (reqattr->terminate) {
00600 break;
00601 }
00602 }
00603
00604 if (reqattr->terminate)
00605 break;
00606 }
00607
00608 if (reqattr->terminate)
00609 break;
00610 }
00611
00612
00613 modstat = kMymodErr_Success;
00614
00615
00616 if (errorCount > 0)
00617 {
00618 fprintf(stderr,"Export Failed for %d segments of %d attempted.\n", errorCount, errorCount + okayCount);
00619 if (reqattr->fstatus != NULL)
00620 stgprintf(reqattr->fstatus,"EXPORT_MSG=Export Failed for %d segments of %d attempted.\n", errorCount, errorCount + okayCount);
00621 if (okayCount == 0)
00622 modstat = kMymodErr_ExportFailed;
00623 }
00624
00625
00626 }
00627 else
00628 {
00629 fprintf(stderr, "Record-set query '%s' is not valid.\n", rsinquery);
00630 if (reqattr->fstatus != NULL)
00631 stgprintf(reqattr->fstatus, "EXPORT_MSG=Record-set query '%s' is not valid.\n", rsinquery);
00632 modstat = kMymodErr_BadRecSetQuery;
00633 }
00634
00635 if (rsin)
00636 {
00637 fprintf(stderr, "drms_close_records\n");
00638 drms_close_records(rsin, DRMS_FREE_RECORD);
00639 rsin=NULL;
00640 }
00641
00642 }
00643
00644 fprintf(stderr, "calling callback close in MapexportRecordToDir loop\n");
00645 (*callback)("close");
00646
00647 if (status)
00648 {
00649 *status = modstat;
00650 }
00651
00652 (*callback)("getsize",&tsize);
00653 (*callback)("getcount",tcount);
00654 return tsize;
00655 }
00656
00657 int DoIt(void)
00658 {
00659 MymodError_t err = kMymodErr_Success;
00660 int drmsstat = DRMS_SUCCESS;
00661 long long tsize = 0;
00662 long long tsizeMB = 0;
00663 int tcount = 0;
00664
00665 const char *reqid = NULL;
00666 const char *method = NULL;
00667
00668 const char *ackfile= NULL;
00669 const char *tarfile= NULL;
00670 const char *cgi_request= NULL;
00671
00672 const char *rsquery = NULL;
00673 const char *rsqueryfile = NULL;
00674 const char *stagestatusfile= NULL;
00675 const char *clname = NULL;
00676 const char *mapfile = NULL;
00677 const char *cparmsarg = NULL;
00678 const char **cparms = NULL;
00679 int RecordLimit = 0;
00680
00681
00682 char *md_error = NULL;
00683
00684 RecordLimit = cmdparams_get_int(&cmdparams, kArg_n, &drmsstat);
00685
00686
00687
00688
00689
00690 reqid = cmdparams_get_str(&cmdparams, kArg_reqid, &drmsstat);
00691 method = cmdparams_get_str(&cmdparams, kArg_method, &drmsstat);
00692
00693
00694 ackfile= cmdparams_get_str(&cmdparams, kArg_ackfile, &drmsstat);
00695 if (strcmp(ackfile,kNotSpecified) && access(ackfile, F_OK) == 0 ) {
00696
00697 strcpy(sackfile,ackfile);
00698 }
00699
00700 tarfile=cmdparams_get_str(&cmdparams, kArg_tarfile, &drmsstat);
00701 if (strcmp(tarfile,kNotSpecified)) {
00702
00703 strcpy(starfile,tarfile);
00704 }
00705
00706 cgi_request=cmdparams_get_str(&cmdparams, kArg_cgi_request, &drmsstat);
00707 if (strcmp(cgi_request,kNotSpecified)) {
00708
00709 strcpy(gcgi_request,cgi_request);
00710 }
00711
00712
00713
00714 rsquery = cmdparams_get_str(&cmdparams, kArg_rsquery, &drmsstat);
00715
00716 clname = cmdparams_get_str(&cmdparams, kArg_clname, &drmsstat);
00717 if (drmsstat != DRMS_SUCCESS || !strcmp(clname, kNotSpecified))
00718 {
00719 clname = NULL;
00720 }
00721
00722 mapfile = cmdparams_get_str(&cmdparams, kArg_kmfile, &drmsstat);
00723 if (drmsstat != DRMS_SUCCESS || !strcmp(mapfile, kNotSpecified))
00724 {
00725 mapfile = NULL;
00726 }
00727
00728 cparmsarg = cmdparams_get_str(&cmdparams, kArg_cparms, &drmsstat);
00729 if (strcmp(cparmsarg, kNotSpecified))
00730 {
00731 char *dup = strdup(cparmsarg);
00732 char *pc = NULL;
00733 char *pend = NULL;
00734 int nstr;
00735 int istr;
00736
00737
00738 pc = dup;
00739 nstr = 1;
00740 while ((pc = strchr(pc, ',')) != NULL)
00741 {
00742 pc++;
00743 ++nstr;
00744 }
00745
00746 cparms = (const char **)malloc((nstr + 1) * sizeof(char *));
00747
00748 pc = dup;
00749 for (istr = 0; istr < nstr; istr++)
00750 {
00751 pend = strchr(pc, ',');
00752 if (pend)
00753 {
00754 *pend = '\0';
00755 }
00756 cparms[istr] = (strcmp(pc, kNoCompression) == 0) ? strdup("") : strdup(pc);
00757 if (pend)
00758 {
00759 pc = pend + 1;
00760 }
00761 }
00762
00763
00764 cparms[nstr] = NULL;
00765
00766 if (dup)
00767 {
00768 free(dup);
00769 }
00770 }
00771
00772 rsqueryfile = cmdparams_get_str(&cmdparams, kArg_rsqueryfile, &drmsstat);
00773 if (drmsstat != DRMS_SUCCESS || !strcmp(rsqueryfile, kNotSpecified))
00774 {
00775 rsqueryfile = NULL;
00776 }
00777
00778 stagestatusfile = cmdparams_get_str(&cmdparams, kArg_stagestatusfile, &drmsstat);
00779 if (drmsstat != DRMS_SUCCESS || !strcmp(stagestatusfile, kNotSpecified))
00780 {
00781 stagestatusfile = NULL;
00782 }
00783
00784
00785
00786 const char *outpath = NULL;
00787
00788
00789 const char *ffmt = NULL;
00790
00791 outpath = cmdparams_get_str(&cmdparams, kArg_path, &drmsstat);
00792
00793 if (strcmp(outpath, kNotSpecified) == 0 && (strcmp(method, URL_CGI) || strcmp(method,STAGE_CGI)))
00794 {
00795
00796 outpath = getenv(kPWD);
00797 }
00798
00799 ffmt = cmdparams_get_str(&cmdparams, kArg_ffmt, &drmsstat);
00800 if (strcmp(ffmt, kNotSpecified) == 0 || *ffmt == '\0')
00801 {
00802
00803 ffmt = NULL;
00804 }
00805
00806
00807 tcount = RecordLimit;
00808
00809
00810 RequestAttr reqattr;
00811
00812 memset(&reqattr,'\0',sizeof(RequestAttr));
00813 reqattr.outpath= outpath;
00814 reqattr.method = method;
00815
00816
00817 const char * reqid_ptr = reqid;
00818 flattenstring(reqattr.scid,reqid_ptr,0);
00819
00820
00821 if (!strcmp(method,STAGE_CGI)) {
00822 if (checkdir(outpath) ) {
00823 fprintf(stderr,"Error:: Dir [%s] can't be accessed\n",outpath);
00824 return 1;
00825
00826
00827 } else {
00828 fprintf(stderr, "Stagedatadir [%s]\n",reqattr.outpath);
00829
00830
00831
00832
00833
00834
00835 if(checkfile(stagestatusfile) == 0 ) {
00836 reqattr.stagestatusfile=stagestatusfile;
00837
00838
00839 int cstatus = kMymodErr_Success;
00840 reqattr.fstatus = openstatefile(stagestatusfile,reqattr.scid,&cstatus);
00841 if (cstatus != kMymodErr_Success) {
00842 return cstatus;
00843 }
00844 } else {
00845
00846 reqattr.stagestatusfile=NULL;
00847 reqattr.fstatus = NULL;
00848 }
00849 }
00850 }
00851
00852 if (rsqueryfile!=NULL) {
00853 populatereqattr(&reqattr,rsqueryfile);
00854 } else if (rsquery!=NULL) {
00855 addQueryToReqattr(&reqattr, rsquery, ffmt);
00856 } else {
00857
00858
00859 }
00860
00861
00862
00863
00864 tsize = VSOExportData(drms_env,
00865 &reqattr,
00866 &tcount,
00867 cparms,
00868 &err);
00869
00870 tsizeMB = ToMB(tsize);
00871
00872 stgprintf(reqattr.fstatus, "EXPORT_MB=%lld\n", tsizeMB);
00873 stgprintf(reqattr.fstatus, "EXPORT_FILES=%d\n", tcount);
00874
00875 if (err != kMymodErr_Success) {
00876 stgprintf(reqattr.fstatus,"EXPORT_MSG=Failure occurred while processing export Request ID '%s'.\n", reqattr.scid);
00877 if (reqattr.fstatus != NULL) {
00878 fprintf(reqattr.fstatus,"EXPORT_STATE=FAIL\n");
00879 fclose(reqattr.fstatus);
00880
00881 }
00882 } else {
00883 if (reqattr.fstatus != NULL) {
00884 fprintf(reqattr.fstatus,"EXPORT_STATE=DONE\n");
00885 fclose(reqattr.fstatus);
00886
00887 }
00888 }
00889
00890 if (md_error)
00891 {
00892 free(md_error);
00893 }
00894
00895 if (cparms)
00896 {
00897 int iseg = 0;
00898 while (cparms[iseg])
00899 {
00900 free((void *)cparms[iseg]);
00901 iseg++;
00902 }
00903
00904 free(cparms);
00905 }
00906
00907 return err;
00908 }
00909
00910
00911 int flytar_append_file_header(TAR *t, char * filename, int size) {
00912
00913 memset(&(t->th_buf), 0, sizeof(struct tar_header));
00914 file_set_stats(t, size, filename);
00915 fflush(NULL);
00916 th_write(t);
00917 fflush(NULL);
00918 return 0;
00919 }
00920
00921 int flytar_append_file_tail(TAR *t, int size) {
00922 char block[512];
00923
00924 memset(block, 0, 512);
00925
00926 fflush(NULL);
00927 if (-1==(*((t)->type->writefunc))((t)->fd, block, block_rest(512,size))) {
00928 return -1;
00929 }
00930 fflush(NULL);
00931 return 0;
00932 }
00933
00934 int flytar_append_file(TAR *t, FILE *ftar, char * fullname) {
00935 struct stat s;
00936 int ACK = -1;
00937 int tsize = 0;
00938 if (lstat(fullname,&s) != 0)
00939 return 1;
00940
00941 char *basename = strrchr(fullname, '/');
00942 basename = basename? basename + 1: (char *) fullname;
00943
00944 flytar_append_file_header(t, basename, s.st_size);
00945
00946
00947 if ( (ACK=open(fullname,O_RDONLY))>-1 ) {
00948 char buffer[81];
00949 int rest=0;
00950 while (( rest = read(ACK,buffer, 80)) == 80) {
00951 tsize += 80;
00952 buffer[80]='\0';
00953
00954 fprintf(ftar,"%s",buffer);
00955 }
00956 if (rest > 0 ) {
00957 tsize += rest;
00958 read(ACK,buffer,rest);
00959 buffer[rest]='\0';
00960 }
00961
00962
00963 fprintf(ftar,"%s",buffer);
00964
00965 close(ACK);
00966
00967 } else {
00968 return 1;
00969 }
00970
00971
00972 flytar_append_file_tail(t,s.st_size);
00973
00974 return 0;
00975 }
00976
00977 int block_rest(int block_size, int file_size) {
00978 int mod = 0;
00979 if ( file_size < block_size) {
00980 return block_size - file_size;
00981 } else {
00982 mod = file_size%block_size;
00983 if (mod > 0) {
00984 return 512 - mod;
00985 } else {
00986 return mod;
00987 }
00988 }
00989 }
00990
00991 int file_set_stats(TAR *t, int size, char * filename) {
00992 t->th_buf.typeflag = REGTYPE;
00993
00994
00995 strcpy(t->th_buf.uname, "production");
00996 int_to_oct(670, t->th_buf.uid, 8);
00997
00998
00999 strcpy(t->th_buf.gname, "SUMS");
01000 int_to_oct(669, t->th_buf.gid, 8);
01001
01002
01003 int_to_oct(33204,t->th_buf.mode,8);
01004
01005
01006 int_to_oct(time(NULL),t->th_buf.mtime,12);
01007
01008
01009 int_to_oct(size,t->th_buf.size,12);
01010
01011
01012 th_set_path(t,filename);
01013
01014
01015 return 0;
01016 }
01017
01018
01019
01020 char * flattenstring(char *str1, const char *str2, int n) {
01021 char c = '\0';
01022 char *str1_ptr=str1;
01023 int initn=n;
01024 while ( (c = *str2++)!= '\0' && (0 == initn || n-- >= 1)) {
01025 if ( (c>=48 && c<=57) || (c>=65 && c<= 90) || (c>=97 && c<=122)) {
01026 *str1++=c;
01027 } else {
01028 *str1++='_';
01029 }
01030 }
01031
01032 return str1_ptr;
01033 }
01034
01035
01036 int match_query_segments(DRMS_Segment_t *seg)
01037 {
01038 int j=0;
01039 if (segments!=NULL) {
01040 for (j=0; segments[j][0] !='\0'; j++) {
01041
01042
01043
01044
01045
01046 if (strcmp(segments[j],seg->info->name) == 0) {
01047 return 0;
01048 }
01049 }
01050 return 1;
01051 } else {
01052 return 0;
01053 }
01054 }
01055 int count_segment_names(char **segments)
01056 {
01057 int j=0;
01058 while(segments!=NULL && segments[++j][0]!='\0');
01059 return j;
01060 }
01061
01062 char ** parse_query_for_segment_names(char * query)
01063 {
01064 char **segments = (char **) NULL;
01065
01066 char *cquery = (char *) NULL;
01067
01068 char *ptr1, *ptr2;
01069
01070 cquery=strdup(query);
01071
01072
01073 ptr1 = strchr( cquery, '{');
01074 ptr2 = strrchr(cquery, '}');
01075 if (ptr1 != NULL && ptr2 != NULL) {
01076 *ptr2='\0';
01077 ++ptr1;
01078
01079 char *segstr=ptr1;
01080
01081
01082 int commaCount=0;
01083 while ((ptr2 = strchr( ptr1, ',')) != NULL) {
01084 ptr1=ptr2+1;
01085 commaCount++;
01086 }
01087
01088
01089
01090 int arrCount = commaCount+2;
01091 segments = malloc(arrCount*sizeof(char *));
01092
01093
01094 segments[arrCount-1] = malloc(sizeof(char));
01095 segments[arrCount-1][0]='\0';
01096
01097
01098 ptr1 = segstr;
01099 int i = 0;
01100 int segNameLen = 0;
01101
01102 while((ptr2 = strchr( ptr1, ',')) != NULL) {
01103 segNameLen= ptr2 - ptr1;
01104 segments[i]=malloc(segNameLen*sizeof(char)+1);
01105 strncpy(segments[i],ptr1,segNameLen);
01106 segments[i][segNameLen]='\0';
01107 ptr1=ptr2+1;
01108 i++;
01109 }
01110
01111 segNameLen=strlen(ptr1);
01112 segments[i]=malloc(segNameLen*sizeof(char)+1);
01113 strcpy(segments[i],ptr1);
01114 segments[i][segNameLen]='\0';
01115
01116
01117
01118
01119
01120
01121
01122
01123 free(cquery);
01124 }
01125 return segments;
01126 }
01127
01128 int testRecordCount(DRMS_RecordSet_t* rsin, int* stat, int querySegCount)
01129 {
01130 MymodError_t modstat = kMymodErr_Success;
01131 DRMS_Record_t *recin = NULL;
01132 int iSet =0, nSets = 0, nRecs = 0, recCount = 0, iRec = 0, segNum = 0;
01133
01134 nSets = rsin->ss_n;
01135
01136
01137 for (iSet = 0;
01138 *stat == DRMS_SUCCESS && modstat == kMymodErr_Success && iSet < nSets;
01139 iSet++)
01140 {
01141 nRecs = drms_recordset_getssnrecs(rsin, iSet, stat);
01142
01143 for (iRec = 0; modstat == kMymodErr_Success && iRec < nRecs; iRec++)
01144 {
01145 recin =rsin->records[(rsin->ss_starts)[iSet] + iRec];
01146
01147 if ( querySegCount != 1) {
01148 if ( (segNum = drms_record_numsegments(recin)) > 1) {
01149 recCount=segNum;
01150 }
01151 }
01152 recCount ++;
01153 }
01154 }
01155
01156 return recCount;
01157 }
01158
01159 void CallbackErrorBuffer( RequestAttr *lreqattr, char* filename, char*query, int errorCode) {
01160 char line[4096];
01161 char error[4096];
01162
01163 if ( 2 == errorCode) {
01164 strcpy(error,"###Tar file too big. Please reduced your query range. Max tar file 2GB. Contact igor@noao.edu or oneiros@grace.nascom.nasa.gov if you need help #\n");
01165 } else {
01166 strcpy(error,"###The data requested could not be served. Please retry again in a few minutes. If the problem persists please contact: igor@noao.edu or oneiros@grace.nascom.nasa.gov #\n");
01167 }
01168
01169 snprintf(line, 4095, "%s; Query=[%s]\n",filename,query);
01170
01171 int linelen = strlen(line);
01172 char *ptr = lreqattr->errorbuffer;
01173
01174 if (lreqattr->errorbuffer == (char *) NULL) {
01175
01176 int errorbufferlen = strlen(error) + linelen + 1;
01177
01178
01179 lreqattr->errorbuffer = malloc(sizeof(char)*errorbufferlen);
01180
01181 fprintf(stderr,"Allocating errorbuffer [%p]\n",lreqattr->errorbuffer);
01182
01183 memset(lreqattr->errorbuffer,0,sizeof(char)*errorbufferlen);
01184
01185 sprintf(lreqattr->errorbuffer,"%s%s",error,line);
01186 } else {
01187 int currentbufferlen = strlen(lreqattr->errorbuffer) + 1;
01188
01189
01190 fprintf(stderr,"Reallocating errorbuffer [%p]; current buffer length [%d], adding additional [%d] and [%d]\n",lreqattr->errorbuffer, currentbufferlen,linelen, (int)strlen(error));
01191 lreqattr->errorbuffer = (char *) realloc(lreqattr->errorbuffer, sizeof(char)*(currentbufferlen + linelen + strlen(error)));
01192
01193
01194 ptr= lreqattr->errorbuffer + strlen(lreqattr->errorbuffer)*sizeof(char);
01195
01196
01197 memset(ptr,0,sizeof(char)*(linelen+strlen(error)));
01198 sprintf(ptr,"%s%s",error,line);
01199 }
01200
01201 }
01202
01203 void CallbackClose(RequestAttr *lreqattr, FILE *ftar) {
01204 const char *method = lreqattr->method;
01205 int recCount = lreqattr->reccount;
01206 TAR *tar = lreqattr->tar;
01207 const char *rsquery = lreqattr->rsquery[lreqattr->arraypointer];
01208
01209
01210 if (NULL == ftar)
01211 return;
01212
01213
01214 if (recCount > 1 && tar != (TAR *) NULL) {
01215
01216 if (!lreqattr->print_header && !strcmp(URL_CGI,method)) {
01217 char tarfilename[300];
01218 char starfile[300];
01219 printf("Content-type: application/octet-stream\n");
01220 printf("Content-Disposition: attachment; filename=\"%s.tar\"\n",strlen(starfile)==0?flattenstring(tarfilename,rsquery,300):starfile);
01221 printf("Content-transfer-encoding: binary\n\n");
01222 lreqattr->print_header = 1;
01223 }
01224
01225 fflush(NULL);
01226 if (lreqattr->infobuffer !=NULL) {
01227 if (flytar_append_file_header(tar, "jsoc/file_list.txt", strlen(lreqattr->infobuffer))){
01228 fprintf(stderr, "Error in flytar_append_file\n");
01229 } else {
01230
01231
01232 fprintf(ftar,lreqattr->infobuffer);
01233 if (flytar_append_file_tail(tar, strlen(lreqattr->infobuffer))) {
01234 fprintf(stderr, "Error in flytar_append_tail\n");
01235 }
01236 free(lreqattr->infobuffer);
01237 lreqattr->infobuffer=NULL;
01238 }
01239 }
01240
01241 fflush(NULL);
01242 if ((lreqattr->errorbuffer != (char *) NULL)) {
01243 if (flytar_append_file_header(tar, "jsoc/error_list.txt", strlen(lreqattr->errorbuffer))){
01244 fprintf(stderr, "Error in flytar_append_file\n");
01245 } else {
01246
01247 fprintf(ftar,lreqattr->errorbuffer);
01248 if (flytar_append_file_tail(tar, strlen(lreqattr->errorbuffer))) {
01249 fprintf(stderr, "Error in flytar_append_tail\n");
01250 }
01251 free(lreqattr->errorbuffer);
01252 lreqattr->errorbuffer=NULL;
01253 }
01254 }
01255
01256
01257 fflush(NULL);
01258 flytar_append_file(tar,ftar,sackfile);
01259 fprintf(stderr,"tar closing ... \n");
01260 tar_append_eof(tar);
01261 tar_close(tar);
01262 lreqattr->tar = NULL;
01263
01264 fflush(NULL);
01265 } else {
01266
01267
01268 if (lreqattr->errorbuffer != NULL) {
01269
01270
01271 if (!lreqattr->print_header && !strcmp(URL_CGI,method)) {
01272 printf("Content-type: text/html\n\n");
01273 lreqattr->print_header = 1;
01274 }
01275 printf("<html><base>\n<h1>Retrieval for the below data failed</h1>\n");
01276
01277 printf("<p><i><font color=\"blue\">%s</font></i></p>\n",lreqattr->errorbuffer);
01278 printf("<p>If a retry does not fix the problem, it could be the data is missing. In which case, as there are no data regeneration capabilities at JSOC at the moment, it should be considered as missing data and not retrievable at the present time.</p>\n<p>We are currently working on showing the detailed reason for the export failure.</p>\n");
01279 printf("<p>Thanks for your patience</p>\n<p>Please contact <a href=\"mailto:igor@noao.edu\">igor@noao.edu</a> or <a href=\"mailto:oneiros@grace.nascom.nasa.gov\">oneiros@grace.nascom.nasa.gov</a> for further questions.</p>\n");
01280 printf("</base></html>");
01281 }
01282 }
01283 }
01284
01285 void CallbackInfo(RequestAttr *lreqattr, char * filename) {
01286
01287 char line[400];
01288
01289 sprintf(line,"%s\n",filename);
01290
01291 int linelen = strlen(line);
01292 char *ptr = lreqattr->infobuffer;
01293
01294
01295 if (lreqattr->infobuffer == (char *) NULL) {
01296
01297 char *infohead = "# List of files in Tar file #\n";
01298 int infobufferlen = strlen(infohead) + linelen + 1;
01299
01300 lreqattr->infobuffer = malloc(sizeof(char)*infobufferlen);
01301
01302 memset(lreqattr->infobuffer,0,sizeof(char)*infobufferlen);
01303
01304 sprintf(lreqattr->infobuffer,"%s",infohead);
01305
01306 ptr = lreqattr->infobuffer + strlen(infohead)*(sizeof(char));
01307
01308 } else {
01309 int currentbufferlen = strlen(lreqattr->infobuffer) + 1;
01310
01311 lreqattr->infobuffer = (char *) realloc(lreqattr->infobuffer, sizeof(char)*(currentbufferlen + linelen));
01312
01313
01314 ptr= lreqattr->infobuffer + strlen(lreqattr->infobuffer)*sizeof(char);
01315
01316
01317 memset(ptr,0,sizeof(char)*linelen);
01318 }
01319
01320 strcpy(ptr,line);
01321
01322 }
01323
01324 void generateStageTarName(const char * stagedir, const char * scid, int stagetarcount, char* newname) {
01325 sprintf(newname,"%s/%s_%04d.tar",stagedir, scid,stagetarcount);
01326 }
01327
01328 int addQueryToReqattr(RequestAttr *reqattr,const char * query,const char * ffmt) {
01329 int allocbatch=5;
01330
01331 if (reqattr->rscount > 0 ) {
01332 }
01333
01334 if (reqattr->rsquery == NULL || (reqattr->rscount%allocbatch==0) ) {
01335
01336
01337 int alloccount = (reqattr->rscount/5) + 1;
01338 reqattr->rsquery = (char **) realloc(reqattr->rsquery,sizeof(char *)*allocbatch*alloccount);
01339 reqattr->rsffmt = (char **) realloc(reqattr->rsffmt,sizeof(char *)*allocbatch*alloccount);
01340 }
01341
01342
01343
01344 reqattr->rsffmt[reqattr->rscount] = (char *) calloc(strlen(ffmt)+1,sizeof(char));
01345 reqattr->rsquery[reqattr->rscount] = (char *) calloc(strlen(query)+1,sizeof(char));
01346
01347 strcpy(reqattr->rsffmt[reqattr->rscount],ffmt);
01348 strcpy(reqattr->rsquery[reqattr->rscount],query);
01349 reqattr->rscount++;
01350
01351 return 0;
01352 }
01353 int populatereqattr(RequestAttr *reqattr, const char * rsqueryfile) {
01354 FILE *fqry = NULL;
01355 fqry = fopen(rsqueryfile, "r");
01356
01357 if (fqry != NULL) {
01358 fprintf(stderr,"File [%s] does exist.\n",rsqueryfile);
01359
01360
01361
01362
01363
01364
01365
01366
01367 char c=0;
01368
01369 int allocbatch=5;
01370 int j=0;
01371 int alloccount=1;
01372
01373 while ( (c = (char)getc(fqry) ) != EOF) {
01374 if (c == '#') {
01375 while ( !((c = (char)getc(fqry) ) == '\n' || c == EOF));
01376 } else if (c != '\n') {
01377 int i=0;
01378 char line[4096];
01379 memset(line, 0, 4096);
01380
01381 line[i++]=c;
01382 while ( !((c = (char)getc(fqry) ) == '\n' || c == EOF)) {
01383 line[i++]=c;
01384 }
01385
01386 char *saveptr=NULL;
01387 char *ffmt = NULL;
01388 char *query= NULL;
01389
01390 ffmt = strtok_r(line,"<|!|>",&saveptr);
01391 if (ffmt != NULL) {
01392 query = strtok_r(NULL,"<|!|>",&saveptr);
01393 if (query != NULL) {
01394 fprintf(stderr,"ffmt--> [%s], query--> [%s]\n",ffmt,query);
01395 fprintf(stderr,"line--> [%s]\n",line);
01396 int qrysize=0;
01397 int ffmtsize=0;
01398 qrysize=strlen(query)+1;
01399 ffmtsize=strlen(ffmt)+1;
01400
01401 if (reqattr->rsquery == NULL || (j%allocbatch==0) ) {
01402
01403 fprintf(stderr, "realloc pointers of array [%d]\n", alloccount);
01404 reqattr->rsquery = (char **) realloc(reqattr->rsquery,sizeof(char *)*allocbatch*alloccount);
01405 reqattr->rsffmt = (char **) realloc(reqattr->rsffmt,sizeof(char *)*allocbatch*alloccount);
01406 alloccount++;
01407 }
01408
01409 reqattr->rsffmt[j] = (char *) calloc(ffmtsize,sizeof(char));
01410 reqattr->rsquery[j] = (char *) calloc(qrysize,sizeof(char));
01411
01412 strcpy(reqattr->rsffmt[j],ffmt);
01413 strcpy(reqattr->rsquery[j],query);
01414 j++;
01415 }
01416 }
01417
01418 }
01419 }
01420 fclose(fqry);
01421
01422
01423 reqattr->rscount=j;
01424
01425 return 0;
01426 } else {
01427
01428 return 1;
01429 }
01430 }
01431
01432 void printRequestAttr(RequestAttr *reqattr) {
01433 int i =0;
01434 fprintf(stderr,"Query Count [%d]\n",reqattr->rscount);
01435 fprintf(stderr,"Stage Data Dir [%s]\n",reqattr->outpath);
01436 fprintf(stderr,"Stage Status Dir [%s]\n",reqattr->stagestatusfile);
01437 for (; i<reqattr->rscount; i++) {
01438 fprintf(stderr,"ffmt:[%s]\n",reqattr->rsffmt[i]);
01439 fprintf(stderr,"query:[%s]\n",reqattr->rsquery[i]);
01440 }
01441 }
01442
01443 void freeRequestAttr(RequestAttr *reqattr) {
01444 int i =0;
01445 for (; i<reqattr->rscount; i++) {
01446 free(reqattr->rsquery[i]);
01447 free(reqattr->rsffmt[i]);
01448 }
01449
01450 free(reqattr->rsquery);
01451 free(reqattr->rsffmt);
01452 }
01453
01454 int checkfile(const char *filename) {
01455 struct stat buf;
01456 if (!stat(filename,&buf)) {
01457 if(S_ISREG(buf.st_mode)) {
01458 return access(filename,R_OK|W_OK);
01459 }
01460 }
01461 return 1;
01462 }
01463 int checkdir(const char *dirname) {
01464 struct stat buf;
01465 if (!stat(dirname,&buf)) {
01466 if(S_ISDIR(buf.st_mode)) {
01467 return access(dirname,R_OK|W_OK);
01468 }
01469 }
01470 return 1;
01471 }
01472
01473
01474 static FILE *fTarGlobal = NULL;
01475
01476
01477
01478 int tarURLOpen (const char *path, int flags, ... )
01479 {
01480 fflush(NULL);
01481 fTarGlobal = stdout;
01482 return fileno(fTarGlobal);
01483 }
01484
01485 int tarStageOpen (const char *path, int flags, ... )
01486 {
01487 fTarGlobal = fopen(path, "w");
01488 return fileno(fTarGlobal);
01489 }
01490
01491 void ExportHandle(char *callbackState, ...) {
01492
01493
01494
01495 va_list arguments;
01496 va_start(arguments, callbackState);
01497 static DRMS_Array_t *arrout = NULL;
01498
01499
01500 static long long l_maxtarsize = MAXTARSIZE;
01501 static long long totalsize = 0;
01502 static int totalcount = 0;
01503 static long currentsize = 0;
01504
01505 static int stagetarcount=0;
01506 static char currentfileitem[1024];
01507 static int first = 1;
01508
01509
01510
01511 static RequestAttr *lreqattr=NULL;
01512
01513 if (strcmp(callbackState,"create")==0) {
01514
01515 fitsfile **fptr = (fitsfile **) va_arg(arguments, fitsfile **);
01516 char *filein = (char *) va_arg(arguments, char *);
01517 char *cparms = (char *) va_arg(arguments, char *);
01518 int *cfiostat = (int *) va_arg(arguments, int *);
01519 int *retVal = (int *) va_arg(arguments, int *);
01520
01521 char tempfilein[1024];
01522 char filename[252];
01523
01524 strcpy(tempfilein,"mem://");
01525 totalcount++;
01526
01527
01528 l_maxtarsize = !strcmp(lreqattr->method,URL_CGI)?MAXTARSIZE:MAXFILETARSIZE;
01529
01530
01531 if (first && (1 == lreqattr->reccount) && !strcmp(lreqattr->method,URL_CGI)) {
01532
01533 sprintf(currentfileitem,"%s", filein);
01534 }
01535
01536
01537
01538
01539 else if ((1 < lreqattr->reccount) && !strcmp(lreqattr->method,URL_CGI)) {
01540 char tarfilename[300];
01541 if (first) {
01542 lreqattr->print_header=1;
01543 printf("Content-type: application/octet-stream\n");
01544 printf("Content-Disposition: attachment; filename=\"%s.tar\"\n",strlen(starfile)==0?flattenstring(tarfilename,lreqattr->rsquery[lreqattr->arraypointer],300):starfile);
01545 printf("Content-transfer-encoding: binary\n\n");
01546
01547
01548 fprintf(stderr, "cgi_request(1)=%s, pid=%d; ppid=%d\n",gcgi_request,getpid(),getppid());
01549 if (!strcmp(gcgi_request,"HEAD")) {
01550 fflush(stdout);
01551 lreqattr->terminate=1;
01552 }
01553
01554 lreqattr->tartype.openfunc = &tarURLOpen;
01555
01556
01557 if (tar_open(&lreqattr->tar, "some_generic_name.tar", &lreqattr->tartype,
01558 O_WRONLY | O_CREAT, 0644, TAR_GNU) == -1 ) {
01559 return;
01560 }
01561 first = 0;
01562 }
01563 fflush(NULL);
01564
01565 sprintf(currentfileitem,"%s/%s", "jsoc", filein);
01566 fprintf(stderr, "first, URL_CGI and multiple record\n");
01567 }
01568
01569
01570
01571 else if (first && (1 == lreqattr->reccount) && !strcmp(lreqattr->method,STAGE_CGI)) {
01572 strcpy(tempfilein,"");
01573 sprintf(tempfilein,"%s/%s",lreqattr->outpath,filein);
01574 first = 0;
01575 fprintf(stderr, "first, STAGE_CGI and only one record\n");
01576 }
01577
01578
01579
01580
01581 else if ( (first || currentsize > l_maxtarsize) && (1 < lreqattr->reccount) && !strcmp(lreqattr->method,STAGE_CGI)) {
01582 lreqattr->tartype.openfunc = &tarStageOpen;
01583
01584
01585
01586
01587 if (currentsize > l_maxtarsize) {
01588
01589
01590 ExportHandle("close");
01591
01592 currentsize=0;
01593 stagetarcount++;
01594 } else {
01595 first = 0;
01596 }
01597
01598
01599 char tarfilestagename[1024];
01600 fprintf(stderr,"b4 setting stage file scid [%s], stagetarcount [%04d], stagedir [%s], currentfileitem[%s]\n", lreqattr->scid, stagetarcount, lreqattr->outpath, currentfileitem);
01601 generateStageTarName(lreqattr->outpath, lreqattr->scid, stagetarcount, (char *) &tarfilestagename);
01602 fprintf(stderr,"create new tar file [%s]\n",tarfilestagename);
01603 if (tar_open(&lreqattr->tar, tarfilestagename, &lreqattr->tartype,
01604 O_WRONLY | O_CREAT, 0644, TAR_GNU) == -1 ) {
01605 return;
01606 }
01607 fflush(NULL);
01608 fprintf(stderr, "interation [%d], STAGE_CGI and multiple records\n",stagetarcount);
01609 }
01610
01611
01612 if ((1 < lreqattr->reccount) && !strcmp(lreqattr->method,STAGE_CGI)) {
01613 sprintf(currentfileitem,"%s/%s", "jsoc", filein);
01614 }
01615
01616
01617
01618
01619 if (cparms && *cparms) {
01620 snprintf(filename, sizeof(filename), "%s[%s]", tempfilein, cparms);
01621 } else {
01622
01623 if ( 1 < lreqattr->reccount) {
01624 snprintf(filename, sizeof(filename), "%s[compress Rice]", tempfilein);
01625
01626 }
01627 else {
01628 snprintf(filename, sizeof(filename), "%s", tempfilein);
01629 }
01630 }
01631
01632 fprintf(stderr, "before fits_create_file [%s]\n", filename);
01633 *retVal=fits_create_file(fptr,filename, cfiostat);
01634
01635 }
01636
01637
01638 else if (strcmp(callbackState,"stdout")==0) {
01639 fitsfile *fptr = (fitsfile *) va_arg(arguments, fitsfile *);
01640 int *retVal = (int *) va_arg(arguments, int *);
01641 int mystatus = 0;
01642 int cpstatus=0;
01643
01644 if ((1 == lreqattr->reccount) && !strcmp(lreqattr->method,STAGE_CGI)) {
01645 fits_flush_file(fptr, &cpstatus);
01646 return;
01647
01648 }
01649
01650
01651
01652 fprintf(stderr,"recCount is [%ld]\n", lreqattr->reccount);
01653 if (first && (1 == lreqattr->reccount) && !strcmp(lreqattr->method,URL_CGI)) {
01654
01655
01656
01657 lreqattr->print_header=1;
01658 printf("Content-type: application/octet-stream\n");
01659
01660 printf("Content-Disposition: attachment; filename=\"%s\"\n",currentfileitem);
01661 printf("Content-Length: %lld\n", fptr->Fptr->logfilesize);
01662 printf("Content-transfer-encoding: binary\n\n");
01663
01664 fprintf(stderr, "cgi_request(2)=%s, pid=%d; ppid=%d\n",gcgi_request,getpid(),getppid());
01665 if (!strcmp(gcgi_request,"HEAD")) {
01666 fflush(stdout);
01667 lreqattr->terminate=1;
01668 }
01669
01670 fTarGlobal = stdout;
01671 first=0;
01672 fits_flush_file(fptr, &cpstatus);
01673 }
01674
01675 fprintf(stderr, "\nfile [%s], file size [%lld]\n", currentfileitem, fptr->Fptr->logfilesize);
01676
01677 if (totalsize <= l_maxtarsize|| !strcmp(lreqattr->method,STAGE_CGI)) {
01678
01679 if (lreqattr->reccount > 1) {
01680 fflush(NULL);
01681 totalsize += fptr->Fptr->logfilesize;
01682 currentsize += fptr->Fptr->logfilesize;
01683
01684 if (flytar_append_file_header(lreqattr->tar, currentfileitem, fptr->Fptr->logfilesize)){
01685 *retVal = -1;
01686 }
01687 }
01688
01689
01690 if (arrout->data != NULL) {
01691 free(arrout->data);
01692 arrout->data=NULL;
01693 arrout=NULL;
01694 }
01695
01696 fflush(NULL);
01697
01698
01699 int hdunum=0;
01700 fits_flush_file(fptr, &cpstatus);
01701 fits_get_num_hdus(fptr, &hdunum, &cpstatus);
01702 if (hdunum > 0) {
01703 for (int i=1; i<=hdunum; i++) {
01704
01705 int hdutype=0;
01706 fits_movabs_hdu(fptr, i, &hdutype, &cpstatus);
01707 fits_write_hdu(fptr, fTarGlobal, &cpstatus);
01708 fflush(fTarGlobal);
01709 }
01710 }
01711
01712 fflush(NULL);
01713 if (lreqattr->reccount > 1) {
01714 if (flytar_append_file_tail(lreqattr->tar, fptr->Fptr->logfilesize)) {
01715 stgprintf(lreqattr->fstatus,"EXPORT_MSG=Error in flytar_append_tail\n");
01716 *retVal = -1;
01717 }
01718 }
01719 fits_close_file(fptr, &mystatus);
01720 } else {
01721 lreqattr->terminate =1;
01722 fits_close_file(fptr, &mystatus);
01723 CallbackErrorBuffer( lreqattr, currentfileitem, "Size limitation in tar file.User rice compression or/and make a smaller query", 2);
01724 }
01725 fprintf(stderr,"ExportHandle --stdout is [%d]\n",lreqattr->terminate);
01726 } else if (strcmp(callbackState,"info")==0) {
01727 char *filename = (char *) va_arg(arguments, char *);
01728 fprintf(stderr,"ExportHandle --info is [%d]\n",lreqattr->terminate);
01729 CallbackInfo(lreqattr,filename);
01730
01731 } else if (strcmp(callbackState,"error")==0) {
01732 char *query = (char *) va_arg(arguments, char *);
01733 char *filename = (char *) va_arg(arguments, char *);
01734 fprintf(stderr,"ExportHandle -- error is [%d]\n",lreqattr->terminate);
01735 CallbackErrorBuffer( lreqattr, filename, query, 0);
01736 } else if (strcmp(callbackState,"close")==0) {
01737 fprintf(stderr,"ExportHandle --close is [%d]\n",lreqattr->terminate);
01738 CallbackClose(lreqattr, fTarGlobal);
01739 fTarGlobal = NULL;
01740 lreqattr->tar=NULL;
01741 } else if (strcmp(callbackState,"setarrout")==0) {
01742 fprintf(stderr,"ExportHandle setting arrout [%d]\n", lreqattr->terminate);
01743 arrout = (DRMS_Array_t *) va_arg(arguments, DRMS_Array_t *);
01744 } else if (strcmp(callbackState,"init")==0) {
01745 RequestAttr *_reqattr = (RequestAttr *) va_arg(arguments, RequestAttr *);
01746 fprintf(stderr,"ExportHandle -- init done\n");
01747 lreqattr=_reqattr;
01748 lreqattr->arraypointer=0;
01749
01750
01751
01752 lreqattr->reccount=lreqattr->rscount;
01753
01754 lreqattr->tartype.openfunc = open;
01755 lreqattr->tartype.closefunc = close;
01756 lreqattr->tartype.writefunc = write;
01757 lreqattr->tartype.readfunc = read;
01758
01759 lreqattr->terminate=0;
01760
01761 lreqattr->print_header=0;
01762 } else if (strcmp(callbackState,"getsize")==0) {
01763 int *tsize = (int *) va_arg(arguments, int *);
01764 *tsize=totalsize;
01765 } else if (strcmp(callbackState,"getcount")==0) {
01766 int *tcount = (int *) va_arg(arguments, int *);
01767 *tcount=totalcount;
01768 }
01769
01770
01771 va_end(arguments);
01772 }
01773
01774 FILE * openstatefileold(const char *path, const char *reqid, int *cstatus) {
01775 char oldfilename[512];
01776 char newfilename[512];
01777 const char *oldfilename_ptr=oldfilename;
01778 const char *newfilename_ptr=newfilename;
01779 FILE * fqued=NULL;
01780
01781 pid_t pid = getpid();
01782
01783 sprintf(newfilename,"%s/%s.%s",path,reqid,QUED);
01784 sprintf(oldfilename,"%s/%s.%s",path,reqid,NQUE);
01785
01786 if (!checkfile(newfilename)) {
01787 *cstatus=kMymodErr_QuedFileExists;
01788 return NULL;
01789 }
01790 if (!checkfile(oldfilename)) {
01791 if (rename(oldfilename_ptr,newfilename_ptr)) {
01792 fprintf(stderr, "Error renaming [%s] to [%s] with errno [%d]\n",oldfilename_ptr,newfilename_ptr,errno);
01793 *cstatus=kMymodErr_Rename2QuedFail;
01794 return NULL;
01795 }
01796 }
01797
01798 fqued=fopen(newfilename_ptr,"a");
01799 if (fqued != NULL) {
01800 fprintf(stderr,"Current pid [%d]\n",pid);
01801 }
01802 return fqued;
01803 }
01804
01805 FILE * openstatefile(const char *sfile, const char *reqid, int *cstatus) {
01806 FILE * fstatus=NULL;
01807
01808 fstatus=fopen(sfile,"a");
01809 if (fstatus != NULL) {
01810 pid_t pid = getpid();
01811 fprintf(stderr,"Current pid [%d]\n",pid);
01812 }
01813 return fstatus;
01814 }
01815
01816 int stgprintf(FILE *file, const char * format, ...) {
01817 int ret=0;
01818 va_list args;
01819 va_start(args,format);
01820
01821 if (NULL == file) {
01822 ret=vfprintf(stderr,format,args);
01823 } else {
01824 ret=vfprintf(file,format,args);
01825 }
01826
01827 va_end(args);
01828
01829 return ret;
01830 }
01831
01832 void setstagestate(const char * path, const char * reqid, const char * state) {
01833 char oldfilename[512];
01834 char newfilename[512];
01835 const char *oldfilename_ptr=oldfilename;
01836 const char *newfilename_ptr=newfilename;
01837
01838 sprintf(oldfilename,"%s/%s.%s",path,reqid,QUED);
01839 sprintf(newfilename,"%s/%s.%s",path,reqid,state);
01840
01841 if (!checkfile(oldfilename)) {
01842 rename(oldfilename_ptr,newfilename_ptr);
01843 } else {
01844 fprintf(stderr,"ERROR, could not find [%s]. Touching one.\n",oldfilename);
01845 FILE *file = fopen(newfilename_ptr,"a");
01846 fclose(file);
01847 }
01848 }
01849
01850
01851