00001
00002 #define DEBUG 0
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "jsoc_main.h"
00012 #include "drms.h"
00013 #include "drms_names.h"
00014 #include <sys/types.h>
00015 #include <sys/stat.h>
00016 #include <unistd.h>
00017 #include "exputil.h"
00018
00019 #define kMaxSegs 1000
00020
00021 ModuleArgs_t module_args[] =
00022 {
00023 {ARG_STRING, "op", "Not Specified", "<Operation>"},
00024 {ARG_STRING, "ds", "Not Specified", "<record_set query>"},
00025 {ARG_INT, "n", "0", "record_set count limit"},
00026 {ARG_STRING, "seg", "**ALL**", "<comma delimited segment list>"},
00027 {ARG_STRING, "requestid", "Not Specified", "RequestID string for export management"},
00028 {ARG_STRING, "method", "url", "Export method"},
00029 {ARG_STRING, "protocol", "as-is", "export file protocol"},
00030 {ARG_STRING, "format", "json", "export communication protocol"},
00031 {ARG_STRING, "filenamefmt", "Not Specified", "export filename format rule"},
00032 {ARG_FLAG, "h", "0", "help - show usage"},
00033 {ARG_FLAG, "z", "0", "emit JSON output"},
00034 {ARG_STRING, "QUERY_STRING", "Not Specified", "AJAX query from the web"},
00035 {ARG_END}
00036 };
00037
00038 char *module_name = "jsoc_export_as_is";
00039 int nice_intro ()
00040 {
00041 int usage = cmdparams_get_int (&cmdparams, "h", NULL);
00042 if (usage)
00043 {
00044 printf ("Usage:\njsoc_export_as_is {-h} "
00045 "op=<command> ds=<recordset query> {n=0} {key=<keylist>} {seg=<segment_list>}\n"
00046 " details are:\n"
00047 "op=<command> tell which ajax function to execute\n"
00048 "ds=<recordset query> as <series>{[record specifier]} - required\n"
00049 "n=<recordset count limit> optional\n"
00050 "seg=<comma delimited segment list, default is **ALL**>\n"
00051 "requestid= RequestID string for export management\n"
00052 "method = Export method, default to url\n"
00053 "protocol = export file protocol, default to as-is\n"
00054 "format = export communication protocol, default to json\n"
00055 "filenamefmt = export filename format rule\n"
00056 );
00057 return(1);
00058 }
00059 return (0);
00060 }
00061
00062 #define DIE(msg) \
00063 { \
00064 fprintf(index_txt,"status=1\n"); \
00065 fprintf(index_txt, "error='%s'\n", msg); \
00066 fclose(index_txt); \
00067 return(1); \
00068 }
00069
00070 static int GetSegList(const char *seglistin, DRMS_Record_t *rec, char **segs, int size)
00071 {
00072 int nsegs = 0;
00073 char *thisseg = NULL;
00074 char *restrict seglist = strdup(seglistin);
00075
00076 if (seglist)
00077 {
00078 thisseg=strtok(seglist, ",");
00079
00080 if (strcmp(thisseg,"**NONE**")==0)
00081 {
00082 nsegs = 0;
00083 }
00084 else if (strcmp(thisseg, "**ALL**")==0)
00085 {
00086 DRMS_Segment_t *seg;
00087 HIterator_t *hit = NULL;
00088
00089 while ((seg = drms_record_nextseg(rec, &hit, 1)) != NULL)
00090 {
00091 if (nsegs >= size)
00092 {
00093 fprintf(stderr, "Segment list truncated - too many segments.\n");
00094 break;
00095 }
00096
00097 segs[nsegs++] = strdup(seg->info->name);
00098 }
00099
00100 hiter_destroy(&hit);
00101 }
00102 else
00103 {
00104 for (; thisseg; thisseg=strtok(NULL,","))
00105 {
00106 if (nsegs >= size)
00107 {
00108 fprintf(stderr, "Segment list truncated - too many segments.\n");
00109 break;
00110 }
00111
00112 segs[nsegs++] = strdup(thisseg);
00113 }
00114 }
00115 }
00116
00117 return nsegs;
00118 }
00119
00120
00121 int DoIt(void)
00122 {
00123 char *in;
00124 char *requestid;
00125 char *method;
00126 char *protocol;
00127 char *format;
00128 char *filenamefmt;
00129 char *seglist;
00130 int segs_listed;
00131
00132 DRMS_RecordSet_t *recordset;
00133 DRMS_Record_t *rec;
00134 char *segs[kMaxSegs];
00135 int iseg, nsegs = 0;
00136 int count;
00137 int RecordLimit = 0;
00138 int status=0;
00139 int irec, nrecs;
00140 long long size;
00141 FILE *index_txt, *index_data;
00142 char buf[2*DRMS_MAXPATHLEN];
00143 char *cwd;
00144
00145 in = (char *)cmdparams_get_str (&cmdparams, "ds", NULL);
00146 requestid = (char *)cmdparams_get_str (&cmdparams, "requestid", NULL);
00147 format = (char *)cmdparams_get_str (&cmdparams, "format", NULL);
00148 filenamefmt = (char *)cmdparams_get_str (&cmdparams, "filenamefmt", NULL);
00149 method = (char *)cmdparams_get_str (&cmdparams, "method", NULL);
00150 protocol = (char *)cmdparams_get_str (&cmdparams, "protocol", NULL);
00151 seglist = (char *)strdup (cmdparams_get_str (&cmdparams, "seg", NULL));
00152 RecordLimit = cmdparams_get_int (&cmdparams, "n", NULL);
00153 segs_listed = strcmp (seglist, "Not Specified");
00154
00155 index_txt = fopen("index.txt", "w");
00156 fprintf(index_txt, "# JSOC Export File List\n");
00157 fprintf(index_txt, "version=1\n");
00158 fprintf(index_txt, "requestid=%s\n", requestid);
00159 fprintf(index_txt, "method=%s\n", method);
00160 fprintf(index_txt, "protocol=%s\n", protocol);
00161 fprintf(index_txt, "wait=0\n");
00162
00163
00164 if (RecordLimit == 0)
00165
00166
00167
00168 recordset = drms_open_records(drms_env, in, &status);
00169 else
00170 recordset = drms_open_nrecords (drms_env, in, RecordLimit, &status);
00171 if (!recordset)
00172 DIE(" jsoc_export_as_is: series not found.");
00173
00174
00175
00176 if (drms_stage_records(recordset, 1, 0))
00177 {
00178 DIE(" jsoc_export_as_is: Unable to stage records.");
00179 }
00180
00181 nrecs = recordset->n;
00182 if (nrecs == 0)
00183 {
00184 fprintf(index_txt, "count=0\n");
00185 fprintf(index_txt, "size=0\n");
00186 fprintf(index_txt, "status=0\n");
00187 fclose(index_txt);
00188 return(0);
00189 }
00190
00191 index_data = fopen("index.data", "w+");
00192
00193
00194 count = 0;
00195 size = 0;
00196 for (irec = 0; irec < nrecs; irec++)
00197 {
00198 char recquery[DRMS_MAXQUERYLEN];
00199 char recpath[DRMS_MAXPATHLEN];
00200
00201 rec = drms_recordset_fetchnext(drms_env, recordset, &status, NULL, NULL);
00202
00203 if (!rec)
00204 {
00205
00206 break;
00207 }
00208
00209 if (irec == 0 && segs_listed)
00210 {
00211
00212 nsegs = GetSegList(seglist, rec, segs, kMaxSegs);
00213 }
00214
00215 drms_sprint_rec_query(recquery,rec);
00216 if (drms_record_directory (rec, recpath, 1))
00217 continue;
00218 if (strlen(recpath) < 10)
00219 continue;
00220
00221
00222
00223 DRMS_Segment_t *tgtseg = NULL;
00224 for (iseg=0; iseg<nsegs; iseg++)
00225 {
00226 DRMS_Segment_t *rec_seg_iseg = drms_segment_lookup (rec, segs[iseg]);
00227 char path[DRMS_MAXPATHLEN];
00228 char query[DRMS_MAXQUERYLEN];
00229 char filename[DRMS_MAXPATHLEN];
00230 struct stat filestat;
00231
00232 if (!rec_seg_iseg)
00233 {
00234 DIE("jsoc_export_as_is: attempt to lookup unidentified segment");
00235 }
00236
00237
00238 strncpy(query, recquery, DRMS_MAXQUERYLEN);
00239 strncat(query, "{", DRMS_MAXQUERYLEN);
00240 strncat(query, segs[iseg], DRMS_MAXQUERYLEN);
00241 strncat(query, "}", DRMS_MAXQUERYLEN);
00242
00243 if (*rec_seg_iseg->filename != '\0')
00244 {
00245
00246
00247 strncpy(path, recpath, DRMS_MAXPATHLEN);
00248 strncat(path, "/", DRMS_MAXPATHLEN);
00249 strncat(path, rec_seg_iseg->filename, DRMS_MAXPATHLEN);
00250 }
00251 else
00252 {
00253
00254
00255 strncpy(path, recpath, DRMS_MAXPATHLEN);
00256 strncat(path, "/", DRMS_MAXPATHLEN);
00257 strncat(path, rec_seg_iseg->info->name, DRMS_MAXPATHLEN);
00258 }
00259
00260 if (stat(path, &filestat) == 0)
00261 {
00262 if (S_ISDIR(filestat.st_mode))
00263 {
00264 char cmd[DRMS_MAXPATHLEN+100];
00265 FILE *du;
00266 long long dirsize;
00267 sprintf(cmd,"/usr/bin/du -s -b %s", path);
00268 du = popen(cmd, "r");
00269 if (du)
00270 {
00271 if (fscanf(du,"%lld",&dirsize) == 1)
00272 size += dirsize;
00273 pclose(du);
00274 }
00275 }
00276 else
00277 size += filestat.st_size;
00278
00279
00280 if (rec_seg_iseg->info->islink)
00281 {
00282 if ((tgtseg = drms_segment_lookup(rec, rec_seg_iseg->info->name)) == NULL)
00283 {
00284 DIE("Unable to locate target segment.\n");
00285 }
00286 }
00287
00288 exputl_mk_expfilename(rec_seg_iseg, tgtseg, strcmp(filenamefmt,"Not Specified") ? filenamefmt : NULL, filename);
00289 if (strcmp(method,"ftp")==0)
00290 {
00291 char tmp[DRMS_MAXPATHLEN];
00292 sprintf(tmp,"/export%s", path);
00293 symlink(tmp,filename);
00294 }
00295 else
00296 symlink(path,filename);
00297
00298
00299
00300 fprintf(index_data, "%s\t%s\n",query,filename);
00301 count += 1;
00302 }
00303 else
00304 fprintf(index_data, "%s\tNoDataFile\n",query);
00305 }
00306 }
00307
00308 if (seglist)
00309 {
00310 free(seglist);
00311 seglist = NULL;
00312 }
00313
00314 if (size > 0 && size < 1024*1024) size = 1024*1024;
00315 size /= 1024*1024;
00316
00317
00318
00319 fprintf(index_txt, "count=%d\n",count);
00320 fprintf(index_txt, "size=%lld\n",size);
00321 fprintf(index_txt, "status=0\n");
00322 cwd = getcwd(NULL, 0);
00323 fprintf(index_txt,"dir=%s\n", ((strncmp("/auto", cwd,5) == 0) ? cwd+5 : cwd));
00324 fprintf(index_txt, "# DATA\n");
00325 rewind(index_data);
00326 while (fgets(buf, DRMS_MAXPATHLEN*2, index_data))
00327 fputs(buf, index_txt);
00328 fclose(index_txt);
00329 fclose(index_data);
00330 unlink("index.data");
00331
00332 drms_close_records(recordset, DRMS_FREE_RECORD);
00333 return(0);
00334 }