aboutsummaryrefslogtreecommitdiff
path: root/vendor/voclient/voapps/lib/voDALUtil.c
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/voclient/voapps/lib/voDALUtil.c')
-rw-r--r--vendor/voclient/voapps/lib/voDALUtil.c839
1 files changed, 839 insertions, 0 deletions
diff --git a/vendor/voclient/voapps/lib/voDALUtil.c b/vendor/voclient/voapps/lib/voDALUtil.c
new file mode 100644
index 00000000..f02ffda1
--- /dev/null
+++ b/vendor/voclient/voapps/lib/voDALUtil.c
@@ -0,0 +1,839 @@
+/************************************************************************
+** VODALUTIL.C -- Utility procedures for the DAL interface worker
+** procedures.
+**
+** M. Fitzpatrick, NOAO, July 2007
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/ipc.h>
+#include <sys/sem.h>
+#include <time.h>
+#include <pthread.h>
+#include "VOClient.h"
+#include "voAppsP.h"
+
+
+extern int errno, nservices, nobjects, quiet, format, simple_out, numout;
+extern int debug, verbose, all_named, all_data, save_res, extract;
+extern int meta, dverbose, count, count_only, file_get, use_name;
+extern int kml_max, kml_sample, kml_region, kml_label;
+extern char *output;
+
+extern Service *svcList;
+extern Object *objList;
+
+extern char *vot_getSName (char *root);
+extern char *vot_getOName (char *root);
+
+
+
+int vot_extractResults (char *result, char delim, svcParams *pars);
+int vot_printCount (Query query, svcParams *pars, int *count);
+char vot_svcTypeCode (int type);
+char *vot_getOFName (svcParams *pars, char *extn, int pid);
+char *vot_getOFIndex (svcParams *pars, char *extn, int pid);
+char *vot_openExFile (svcParams *pars, int nrows, char *extn, FILE **ofd);
+char *vot_procTimestamp (void);
+char *vot_getExtn (void);
+void vot_printCountHdr (void);
+void vot_printCountLine (int nrec, svcParams *pars);
+void vot_dalExit (int code, int count);
+void vot_printHdr (int fd, svcParams *pars);
+void vot_concat ();
+
+static void vot_clean (char *extn);
+static int vot_copyFile (char *root, char *extn, char *name,
+ FILE *fd, int hdr, int nrows);
+
+extern char *vot_normalize (char *str);
+extern char *vot_normalizeCoord (char *str);
+
+extern void vot_initKML (FILE *fd, svcParams *pars);
+extern void vot_printKMLPlacemark (FILE *fd, char *id,
+ double ra, double dec, char *line, char *acref,
+ svcParams *pars);
+extern void vot_closeKML (FILE *fd);
+
+extern void vot_initHTML (FILE *fd, svcParams *pars);
+extern void vot_printHTMLRow (FILE *fd, char *line, int isHdr, int rnum);
+extern void vot_closeHTML (FILE *fd);
+
+
+
+
+
+/************************************************************************
+** VOC_EXTRACTRESULTS -- Extract the position and acref information from
+** a DAL query result. We use the first occurance of the POS_EQ_MAIN_<t>
+** UCDs for the position and either ID_MAIN or an artificial ID. Format
+** for the position file is fixed but may be generalized later to allow
+** the order/delimiter to be controlled by the user. The acref file
+** contains the contents of the VOX:Image_AccessReference element.
+*/
+int
+vot_extractResults (char *result, char delim, svcParams *pars)
+{
+ int id=-1, ra=-1, dec=-1, acref=-1, colnum, rownum, nrows, ncols, np, na;
+ char col[SZ_LINE], s_id[SZ_LINE], s_ra[SZ_LINE], s_dec[SZ_LINE];
+ char s_acref[SZ_URL], afname[SZ_LINE], pfname[SZ_LINE];
+ char hfname[SZ_LINE], kfname[SZ_LINE];
+ char *ip = result, *sres, *op, *lp;
+ char hline[SZ_RESULT], line[SZ_RESULT];
+ FILE *pfd = (FILE *)NULL;
+ FILE *afd = (FILE *)NULL;
+ FILE *kfd = (FILE *)NULL;
+ FILE *hfd = (FILE *)NULL;
+
+ static int row_count = 0;
+
+
+ if (!result)
+ vot_dalExit (E_NODATA, 0);
+
+
+ /* Skip leading whitespace
+ */
+ for (ip=result; isspace(*ip) || *ip == '\n'; ip++)
+ ;
+ sres = ip;
+
+ /* Count the number of result records, and skip the header line.
+ */
+ for (nrows=0, ip=sres; *ip; ip++) {
+ if (*ip == '\n')
+ nrows++;
+ }
+ if (nrows > 0)
+ nrows--;
+
+ if (nrows <= 0) {
+ if (debug)
+ fprintf (stderr, "WARNING: No Data found.\n");
+ return (0);
+ }
+
+ /* Return the row count only if we're not extracting anything.
+ */
+ if (!extract)
+ return (nrows);
+
+
+ /* Get the desired column indices.
+ */
+ ip = &result[1];
+ colnum = 0;
+ bzero ((lp = hline), SZ_RESULT);
+ while (1) {
+ bzero (col, SZ_LINE);
+ for (op=col; *ip && *ip != delim && *ip != '\n';)
+ *op++ = *lp++ = *ip++;
+
+ if ((*ip == delim && *(ip+1) == delim) || !col[0]) {/* no UCD */
+ colnum+=2;
+ ip += 2;
+ bzero (col, SZ_LINE);
+ continue;
+ }
+
+
+ if ((strcasecmp ("ID_MAIN", col) == 0) ||
+ (strcasecmp ("meta.id;meta.main", col) == 0))
+ id = colnum;
+ else if ((strcasecmp ("POS_EQ_RA_MAIN", col) == 0) ||
+ (strcasecmp ("pos.eq.ra;meta.main", col) == 0))
+ ra = colnum;
+ else if ((strcasecmp ("POS_EQ_DEC_MAIN", col) == 0) ||
+ (strcasecmp ("pos.eq.dec;meta.main", col) == 0))
+ dec = colnum;
+
+ else if (strcasecmp ("VOX:Image_AccessReference", col) == 0)
+ acref = colnum;
+ else if (strcasecmp ("meta.ref.url", col) == 0)
+ acref = colnum;
+ else if (strcasecmp ("DATA_LINK", col) == 0)
+ acref = colnum;
+
+ while (*ip == delim && *ip != '\n') /* Skip the delimiter. */
+ *lp++ = *ip++;
+
+ if (*ip == '\n') { /* Only process first line here */
+ *lp++ = *ip;
+ break;
+ }
+ colnum++;
+ }
+ ncols = colnum + 1;
+
+ if (debug) {
+ printf ("%s: %c id=%d ra=%d dec=%d acref=%d extract=%d (%d,%d)\n",
+ pars->name, vot_svcTypeCode(pars->type), id, ra, dec,
+ acref, extract, ncols, nrows);
+ }
+
+ /* Begin processing.
+ */
+ for (ip=sres; *ip != '\n'; ip++) ; /* skip header line */
+ ip++;
+
+ bzero (s_id, SZ_LINE);
+ bzero (s_ra, SZ_LINE);
+ bzero (s_dec, SZ_LINE);
+ bzero (s_acref, SZ_URL);
+ bzero (line, SZ_RESULT);
+
+ if (extract & EX_POS && (abs(ra) >= 0 && abs(dec) >= 0)) {
+ bzero (pfname, SZ_LINE);
+ strcpy (pfname, vot_openExFile (pars, nrows, "pos", &pfd) );
+ }
+ if (extract & EX_ACREF && acref >= 0) {
+ bzero (afname, SZ_LINE);
+ strcpy (afname, vot_openExFile (pars, nrows, "urls", &afd) );
+ }
+ if ((extract & EX_KML) && (abs(ra) >= 0 && abs(dec) >= 0)) {
+ bzero (kfname, SZ_LINE);
+ strcpy (kfname, vot_openExFile (pars, nrows, "kml", &kfd) );
+
+ vot_initKML (kfd, pars);
+ }
+ if (extract & EX_HTML) {
+ if (output && output[0] == '-') {
+ hfd = stdout;
+ } else {
+ bzero (hfname, SZ_LINE);
+ strcpy (hfname, vot_openExFile (pars, nrows, "html", &hfd) );
+ }
+
+ vot_initHTML (hfd, pars);
+ vot_printHTMLRow (hfd, hline, TRUE, 0);
+ }
+
+#ifdef FD_DEBUG
+ fprintf (stderr, "%s: pfd=%d afd=%d kfd=%d hfd=%d\n",
+ pars->name, (int)pfd, (int)afd, (int)kfd, (int)hfd);
+#endif
+
+ colnum = 0;
+ rownum = 1;
+ np = 0;
+ na = 0;
+ strcpy (line, hline);
+ lp = line + strlen (line);
+
+ while (*ip) {
+ memset (col, 0, SZ_LINE); /* get value */
+ for (op=col; *ip && *ip != delim && *ip != '\n';)
+ *op++ = *lp++ = *ip++;
+
+ *lp++ = *ip; /* save to line buffer */
+ if (*ip && *ip != '\n') /* skip the delimiter */
+ ip++;
+
+ if (id >= 0 && colnum == id)
+ strcpy (s_id, vot_normalize(col));
+ else if (ra >= 0 && colnum == ra)
+ strcpy (s_ra, vot_normalizeCoord(col));
+ else if (dec >= 0 && colnum == dec)
+ strcpy (s_dec, vot_normalizeCoord(col));
+ else if (acref >= 0 && colnum == acref)
+ strcpy (s_acref, col);
+
+ if (*ip == '\n') {
+ if (pfd) {
+ if (s_id[0])
+ fprintf (pfd, "%s\t%s\t%s\n",
+ vot_normalize(s_id), s_ra, s_dec);
+ else
+ fprintf (pfd, "obj%03d\t%s\t%s\n", rownum, s_ra, s_dec);
+ np++;
+ }
+
+ if (afd && s_acref[0]) {
+ fprintf (afd, "%s\n", s_acref);
+ na++;
+ }
+ if (kfd) {
+ /* See if we're sampling the output. */
+ if (row_count < kml_max) {
+ if (!kml_sample || (row_count % kml_sample) == 0) {
+ vot_printKMLPlacemark (kfd, s_id, atof(s_ra),
+ atof(s_dec), line, s_acref, pars);
+ }
+ }
+ }
+ if (hfd)
+ vot_printHTMLRow (hfd, line, FALSE, row_count);
+
+ if (kfd || hfd) {
+ bzero (line, SZ_RESULT);
+ strcpy (line, hline);
+ lp = line + strlen (line);
+ }
+
+ colnum = 0; /* reinitialize */
+ rownum++;
+ bzero (s_id, SZ_LINE);
+ bzero (s_ra, SZ_LINE);
+ bzero (s_dec, SZ_LINE);
+ bzero (s_acref, SZ_URL);
+ ip++;
+
+ row_count++;
+ } else
+ colnum++;
+ }
+ if (debug) printf ("%s: np = %d na = %d\n", pars->name, np, na);
+
+ if (pfd) {
+ fclose (pfd);
+ if (!np) unlink (pfname);
+ }
+ if (afd) {
+ fclose (afd);
+ if (!na) unlink (afname);
+ }
+ if (hfd) vot_closeHTML (hfd);
+ if (kfd) vot_closeKML (kfd);
+
+
+ return (nrows);
+}
+
+
+/************************************************************************
+** Open an extraction file.
+*/
+char *
+vot_openExFile (svcParams *pars, int nrows, char *extn, FILE **ofd)
+{
+ static char fname[SZ_LINE];
+ FILE *fd = (FILE *) NULL;
+
+ bzero (fname, SZ_LINE);
+ strcpy (fname, (use_name ?
+ vot_getOFName (pars, extn, (int)getpid()) :
+ vot_getOFIndex (pars, extn, (int)getpid())) );
+
+ if ((fd = fopen (fname, "w+")) == (FILE *) NULL) {
+ fprintf (stderr, "exiting ERROR opening position file\n");
+ vot_dalExit (E_NONE, nrows);
+ }
+
+ *ofd = fd;
+ return ( fname );
+}
+
+
+/************************************************************************
+** Construct a standard filename from the service params.
+*/
+char *
+vot_getOFName (svcParams *pars, char *extn, int pid)
+{
+ static char fname[SZ_LINE], *root, spid[16];
+
+
+ bzero (fname, SZ_LINE);
+ bzero (spid, 16);
+ sprintf (spid, "_%d", pid);
+
+
+ /* Create the root part of the name. */
+ if (simple_out) {
+ sprintf (fname, "%s_%s", vot_normalize (pars->name), pars->oname);
+
+ } else if (output) {
+ root = (output[0] == '-' ? "tmp" : output);
+
+ if (numout)
+ sprintf (fname, "%s_%03d_%03d", root,
+ pars->svc_index, pars->obj_index);
+ else if (nservices == 1 && nobjects > 1)
+ sprintf (fname, "%s_%03d", root, pars->index);
+
+ else if (nservices > 1 && nobjects == 1)
+ sprintf (fname, "%s_%s", root, vot_normalize(pars->name));
+
+ else if (nservices > 1 || nobjects > 1)
+ sprintf (fname, "%s_%s_%c_%03d_%s",
+ root,
+ vot_normalize (pars->name),
+ vot_svcTypeCode(pars->type), pars->index, spid);
+ else
+ strcpy (fname, root);
+
+ } else {
+
+ if (nservices==1 && nobjects > 1)
+ sprintf (fname, "%s_%s", vot_normalize (pars->name), pars->oname);
+ else
+ sprintf (fname, "%s_%c_%s",
+ vot_normalize (pars->name),
+ vot_svcTypeCode(pars->type),
+ (pars->oname[0] ? pars->oname : "pos"));
+
+ if (nservices > 1)
+ strcat (fname, spid);
+ }
+
+ if (extn) {
+ strcat (fname, ".");
+ strcat (fname, extn);
+ }
+
+ return (fname);
+}
+
+
+char *
+vot_getOFIndex (svcParams *pars, char *extn, int pid)
+{
+ static char fname[SZ_LINE], *root, spid[16];
+
+ bzero (fname, SZ_LINE);
+ bzero (spid, 16);
+ sprintf (spid, "_%d", pid);
+
+
+ /* Create the root part of the name. */
+ if (output) {
+ root = (output[0] == '-' ? "tmp" : output);
+
+ if (numout)
+ sprintf (fname, "%s_%03d_%03d", root,
+ pars->svc_index, pars->obj_index);
+
+ else if (nservices == 1 && nobjects > 1)
+ sprintf (fname, "%s_%03d", root, pars->index);
+
+ else if (nservices > 1 && nobjects == 1)
+ sprintf (fname, "%s_%s", root, vot_normalize(pars->name));
+
+ else if (nservices > 1 || nobjects > 1)
+ sprintf (fname, "%s_%s_%c_%03d_%s",
+ root,
+ vot_normalize (pars->name),
+ vot_svcTypeCode(pars->type), pars->index, spid);
+ else
+ strcpy (fname, root);
+
+ } else {
+
+ if (nservices==1 && nobjects > 1)
+ sprintf (fname, "%s_%03d", vot_normalize (pars->name), pars->index);
+ else
+ sprintf (fname, "%s_%c_%03d",
+ vot_normalize (pars->name),
+ vot_svcTypeCode(pars->type), pars->index);
+
+ if (nservices > 1)
+ strcat (fname, spid);
+ }
+
+ if (extn) {
+ strcat (fname, ".");
+ strcat (fname, extn);
+ }
+
+ return (fname);
+}
+
+
+/************************************************************************
+** COUNTRESULTS -- Count the number of results in a raw VOTable.
+*/
+int
+vot_countResults (char *result)
+{
+ int nrows = 0;
+ char *tr = (char *) result,
+ *pos = (char *) result;
+
+
+ /* Count the number of <TR> elements in the table. Note we assume
+ ** there is only a single resource, or that the totatl count is what
+ ** we desire. Allow for upper or lower-case tag names.
+ */
+ while (tr) {
+ if ((tr = strstr (pos, "<TR>")) || (tr = strstr (pos, "<tr>")))
+ pos = tr + 4, nrows++;
+ else
+ break;
+ }
+
+ return (nrows);
+}
+
+
+/************************************************************************
+** Exit the process with the given code. Before leaving, we create a
+** semaphore based on the pid and set the value to be the result count.
+** This allows us to pass back the information to the parent thread when
+** setting the status.
+*/
+void
+vot_dalExit (int code, int count)
+{
+ int rc, sem_id, id = getpid();
+ int status = code;
+
+ if ((sem_id = semget ((key_t)id, 1, IPC_CREAT | 0777)) >= 0)
+ rc = semctl (sem_id, 0, SETVAL, count);
+
+/*
+ exit (code);
+*/
+ pthread_exit ((void *) &status);
+}
+
+
+/************************************************************************
+** Print the header for the result table.
+*/
+void
+vot_printHdr (int fd, svcParams *pars)
+{
+ char buf[SZ_LINE];
+
+ bzero (buf, SZ_LINE);
+ sprintf (buf, "# Service: %s\n# Title: %-64.64s\n",
+ pars->name, pars->title);
+ write (fd, buf, strlen (buf));
+
+ bzero (buf, SZ_LINE);
+ sprintf (buf,
+ "# ObjName: %s\n# Position: %f %f\n# Size: %f\n",
+ pars->oname, pars->ra, pars->dec, pars->sr);
+ write (fd, buf, strlen (buf));
+
+ bzero (buf, SZ_LINE);
+ sprintf (buf, "# Query Date: %s\n#\n", vot_procTimestamp());
+ write (fd, buf, strlen (buf));
+}
+
+
+/************************************************************************
+** Print the header for the result count table.
+*/
+void
+vot_printCountHdr ()
+{
+ extern int format, nobjects;
+
+
+ if (quiet)
+ return;
+
+ if (format == F_CSV && count == 0) {
+ if (use_name || all_named)
+ fprintf (stderr, "# %sService,%sNRecs\n",
+ ((nobjects > 1) ? "Rec," : ""),
+ ((nobjects > 1) ? "ObjName," : ""));
+ else
+ fprintf (stderr, "# %sService,%sNRecs\n",
+ ((nobjects > 1) ? "Rec," : ""),
+ ((nobjects > 1) ? "RA,Dec," : ""));
+ } else if (!meta) {
+ extern int inventory;
+
+ if (nobjects == 1 || inventory) {
+ fprintf (stderr, "# %-20s %s %s\n# %-20.20s %s %s\n",
+ "Service", "NRec", "Typ Resource Title",
+ "-------", "----",
+ "--- ---------------------------------------------");
+
+ } else {
+ if (use_name || all_named) {
+ fprintf (stderr, "# %3s %-12.12s\t%-15.15s\t%s\n",
+ "Rec", "Service", "Source Name", "NRecs\n");
+ fprintf (stderr, "# %3s %-12.12s\t%-15.15s\t%s\n",
+ "---", "-------", "-----------", "-----");
+ } else {
+ fprintf (stderr, "# %3s %-12.12s\t %-24.24s\t%s\n",
+ "Rec", "Service", " RA Dec", "NRecs");
+ fprintf (stderr, "# %3s %-12.12s\t %-24.24s\t%s\n",
+ "---", "-------", "-----------------------", "-----");
+ }
+ }
+ }
+}
+
+
+/************************************************************************
+** Print an individual line of the result count table.
+*/
+int
+vot_printCount (Query query, svcParams *pars, int *res_count)
+{
+ QResponse qr = (QResponse) 0; /* Query response */
+ int nrec;
+
+
+ if ((qr = voc_executeQuery (query)) <= 0) {
+ return (E_REQFAIL);
+
+ } else {
+ nrec = voc_getRecordCount(qr);
+ *res_count = nrec;
+
+ if (count_only && nrec <= 0)
+ return (E_NODATA);
+ if (count < 0 && nrec > 0)
+ return (E_NODATA);
+ if (nrec <= 0)
+ return (E_NODATA);
+
+ vot_printCountLine (nrec, pars);
+ return (E_NONE);
+ }
+
+ return (E_NONE);
+}
+
+
+/************************************************************************
+** Print an individual line of the result count table.
+*/
+void
+vot_printCountLine (int nrec, svcParams *pars)
+{
+ int fmt;
+ extern int nobjects;
+ extern void ppMultiLine();
+ extern char *toSexa();
+
+
+ if (nrec == 0 || quiet)
+ return;
+
+ fmt = (count == 1) ? F_ASCII : pars->fmt;
+fmt = F_ASCII;
+
+ switch (fmt) {
+ case F_CSV|F_HTML:
+ case F_CSV|F_KML:
+ case F_TSV:
+ case F_ASCII:
+ if (nobjects == 1) {
+ printf (" %-20.20s %4d %c ",
+ pars->name, nrec,
+ vot_svcTypeCode (pars->type));
+ ppMultiLine (pars->title, 35, 45, 1024);
+ printf ("\n");
+ } else if (use_name || all_named) {
+ printf (" %3d %-12.12s\t%-15.15s\t%6d\n",
+ pars->index, pars->name, pars->oname, nrec);
+ } else {
+ /*
+ printf (" %3d %-12.12s\t%10.6f %10.6f\t%6d",
+ pars->index, pars->name, pars->ra, pars->dec, nrec);
+ */
+ printf (" %3d %-12.12s\t", pars->index, pars->name);
+ printf ("%12.12s ", toSexa (pars->ra/15.0));
+ printf ("%12.12s\t%5d", toSexa(pars->dec), nrec);
+ if (pars->oname[0] && pars->oname && strcmp ("none", pars->oname))
+ printf (" (%s)", pars->oname);
+ printf ("\n");
+ }
+ break;
+ case F_CSV:
+ if (nobjects == 1) {
+ printf ("%s,%d,%s\n", pars->name, nrec, pars->title);
+ } else if (use_name || all_named) {
+ printf ("%d,%s,%s,%d\n",
+ pars->index, pars->name, pars->oname, nrec);
+ } else {
+ /*
+ printf ("%d,%s,%.6f,%.6f,%d\n",
+ pars->index, pars->name, pars->ra, pars->dec, nrec);
+ */
+ printf ("%d,%s,", pars->index, pars->name);
+ printf ("%s,", toSexa (pars->ra/15.0));
+ printf ("%s,%d\n", toSexa (pars->dec), nrec);
+ }
+ break;
+ case F_FITS:
+ fprintf (stderr, "FITS binary table not yet supported\n");
+ break;
+ default:
+ break;
+ }
+}
+
+
+/************************************************************************
+** Return a simple character type code for the specified service type.
+*/
+char
+vot_svcTypeCode (int type)
+{
+ switch (type) {
+ case SVC_CONE: return ('C'); break;
+ case SVC_SIAP: return ('I'); break;
+ case SVC_SSAP: return ('S'); break;
+ case SVC_VIZIER: return ('T'); break;
+ case SVC_OTHER: return ('?'); break;
+ }
+
+ return ('?');
+}
+
+
+/************************************************************************
+** GETEXTN -- Get the filename extension given the current format.
+*/
+char *
+vot_getExtn ()
+{
+ if (format & F_CSV) /* figure out the extension */
+ return ("csv");
+ else if (format & F_ASCII)
+ return ("asv");
+ else if (format & F_TSV)
+ return ("tsv");
+ else if (format & F_RAW)
+ return ("xml");
+ else if (format & F_KML)
+ return ("kml");
+ else if (format & F_XML)
+ return ("xml");
+
+ return ((char *) NULL);
+}
+
+
+/************************************************************************
+** PROCTIMESTAMP -- Return the timestamp with the system newline removed.
+*/
+char *
+vot_procTimestamp ()
+{
+ time_t clock = time (0);
+ char *tstr = ctime (&clock);
+
+ tstr[24] = '\0'; /* kill the newline */
+
+ return (tstr);
+}
+
+
+
+/************************************************************************
+** CONCAT -- Concatenate the files generated by the query into a
+** single document ordered by the service.
+*/
+void
+vot_concat ()
+{
+ FILE *fd = (FILE *) NULL;
+ Service *svc = svcList; /* the service list */
+ Proc *proc; /* process list in each service */
+ char *extn, fname[SZ_FNAME];
+ int nrows = 0;
+
+
+ extn = vot_getExtn (); /* figure out the extension */
+
+ for (svc=svcList; svc; svc=svc->next) {
+
+ if (output && output[0] == '-') {
+ fd = stdout;
+ } else {
+ /* Open a separate file for each service. Since we can't rely
+ ** one services returning the same columns it only makes sense
+ ** to concatenate similar files.
+ */
+ bzero (fname, SZ_FNAME);
+ sprintf (fname, "%s_%d.%s",
+ vot_getSName(svc->proc->root), getpid(), extn);
+
+ if ((fd = fopen (fname, "w+")) == (FILE *) NULL) {
+ fprintf (stderr, "ERROR: Cannot open output file: '%s'\n",
+ fname);
+ continue;
+ }
+ }
+
+ /* Concatenate results for each object.
+ */
+ nrows = 0;
+ for (proc=svc->proc; proc; proc=proc->next)
+ nrows += vot_copyFile (proc->root, extn, vot_getOName(proc->root),
+ fd, (proc == svc->proc), nrows);
+
+ if (fd != stdout) /* close the file descriptor */
+ fclose (fd);
+ }
+
+ /* Clean up the intermediate files if needed.
+ */
+ if (fd == stdout || (extract & EX_COLLECT))
+ vot_clean (extn);
+}
+
+
+/************************************************************************
+** COPYFILE -- Copy a result file to the output XML file.
+*/
+static int
+vot_copyFile (char *root, char *extn, char *name, FILE *fd, int hdr, int nrows)
+{
+ char line[4096], fname[SZ_FNAME];
+ FILE *ifd;
+ int nr = 0;
+
+
+ bzero (fname, SZ_FNAME);
+ sprintf (fname, "%s.%s", root, extn);
+
+ if (access (fname, R_OK) == 0) {
+ if ((ifd = fopen (fname, "r")) == (FILE *) NULL) {
+ fprintf (stderr, "Warning: Cannot open file '%s'\n", fname);
+ return (0);
+ }
+ } else
+ return (0);
+
+ /* (Slow) Copy the file until the end of the Document.
+ */
+ bzero (line, 4096);
+ while (fgets (line, 4096, ifd)) {
+ if (!nrows && hdr && line[0] == '#')
+ /*fprintf (fd, "# %s", &line[1]); */
+ fprintf (fd, "%s", &line[1]);
+ else if (nrows && !hdr && line[0] == '#')
+ ;
+ else {
+ fprintf (fd, "%s", line);
+ nr++;
+ }
+ bzero (line, 4096);
+ }
+ fflush (fd);
+
+ fclose (ifd);
+
+ return (nr);
+}
+
+
+/************************************************************************
+** CLEANXML -- Clean up the intermediate VOTable files when producing
+** the compiled XML doc..
+*/
+static void
+vot_clean (char *extn)
+{
+ Service *svc = svcList; /* the service list */
+ Proc *proc; /* process list in each service */
+ char fname[SZ_FNAME];
+
+ for (svc=svcList; svc; svc=svc->next) {
+ for (proc=svc->proc; proc; proc=proc->next) {
+ bzero (fname, SZ_FNAME);
+ sprintf (fname, "%s.%s", proc->root, extn);
+ unlink (fname);
+ }
+ }
+}