00001
00002
00003
00004
00005
00006
00007
00008
00046 #include "jsoc_main.h"
00047 #include "drms.h"
00048 #include "drms_names.h"
00049 #include <unistd.h>
00050 #include <strings.h>
00051 #include <sys/types.h>
00052 #include <regex.h>
00053
00054 char * json_escape (char * text);
00055
00056 static char x2c (char *what) {
00057 char digit;
00058
00059 digit = (what[0] >= 'A' ? ((what[0] & 0xdf) - 'A')+10 : (what[0] - '0'));
00060 digit *= 16;
00061 digit += (what[1] >= 'A' ? ((what[1] & 0xdf) - 'A')+10 : (what[1] - '0'));
00062 return (digit);
00063 }
00064
00065 static void CGI_unescape_url (char *url) {
00066 int x, y;
00067
00068 for (x = 0, y = 0; url[y]; ++x, ++y) {
00069 if ((url[x] = url[y]) == '%') {
00070 url[x] = x2c (&url[y+1]);
00071 y += 2;
00072 }
00073 }
00074 url[x] = '\0';
00075 }
00076
00077
00078 char *drms_getseriesowner(DRMS_Env_t *drms_env, char *series, int *status)
00079 {
00080 char *nspace = NULL;
00081 char *relname = NULL;
00082
00083 DB_Text_Result_t *qres = NULL;
00084 static char owner[256];
00085 owner[0] = '\0';
00086
00087 if (!get_namespace(series, &nspace, &relname))
00088 {
00089 char query[1024];
00090 strtolower(nspace);
00091 strtolower(relname);
00092
00093 snprintf(query, sizeof(query), "SELECT pg_catalog.pg_get_userbyid(T1.relowner) AS owner FROM pg_catalog.pg_class AS T1, (SELECT oid FROM pg_catalog.pg_namespace WHERE nspname = '%s') AS T2 WHERE T1.relnamespace = T2.oid AND T1.relname = '%s'", nspace, relname);
00094
00095 if ((qres = drms_query_txt(drms_env->session, query)) != NULL)
00096 {
00097 if (qres->num_cols == 1 && qres->num_rows == 1)
00098 strcpy(owner, qres->field[0][0]);
00099 db_free_text_result(qres);
00100 }
00101 }
00102 *status = owner[0] != 0;
00103 return(owner);
00104 }
00105
00106
00107
00108
00109
00110
00111
00112 ModuleArgs_t module_args[] = {
00113 {ARG_FLAG, "h", "0", "prints this message and quits."},
00114 {ARG_FLAG, "p", "0", "enables print prime keys and description."},
00115 {ARG_FLAG, "q", NULL, "quiet"},
00116 {ARG_FLAG, "v", "0", "verbose"},
00117 {ARG_FLAG, "z", "0", "JSON"},
00118 {ARG_STRING, "QUERY_STRING", "Not Specified", "AJAX query from the web"},
00119 {ARG_END}
00120 };
00121
00122
00123 char *module_name = "show_series";
00124
00125 int verbose = 0;
00126
00127
00128 int nice_intro() {
00129 int help = cmdparams_get_int (&cmdparams, "h", NULL);
00130 verbose = cmdparams_get_int (&cmdparams, "v", NULL);
00131 if (help) {
00132 printf("show_series gets information about JSOC data series.\n"
00133 "usage: show_series {filter} {-p} {-v}\n"
00134 " filter is regular expression to select series names.\n"
00135 " if the filter begins with the word NOT it will exclude the patterns\n"
00136 " following the 'NOT'\n"
00137 " -h prints this message and quits.\n"
00138 " -p enables print prime keys and description.\n"
00139 " -v verbose \n"
00140 " -z JSON formatted output \n");
00141 return (1);
00142 }
00143 return(0);
00144 }
00145
00146 #define SS_OK 0
00147 #define SS_FORMATERROR 1
00148 #define SS_NODRMS 2
00149
00150 static struct show_Series_errors
00151 {
00152 int errcode;
00153 char errmsg[100];
00154 } SS_ERRORS[] =
00155 {
00156 SS_OK, "SUCCESS",
00157 SS_FORMATERROR, "Series filter format error",
00158 SS_NODRMS, "Cant find DRMS"
00159 };
00160
00161
00162
00163 int DoIt (void)
00164 {
00165 int status = 0;
00166
00167 int iseries, nseries, nused;
00168 char query[DRMS_MAXQUERYLEN];
00169 DB_Text_Result_t *qres;
00170 regex_t seriesfilter;
00171 regmatch_t pmatch[10];
00172 char *filter;
00173 char *filterctx = NULL;
00174 int filterNOT;
00175 int quiet;
00176 char *web_query;
00177 int from_web;
00178 int want_JSON;
00179 int printinfo;
00180 char NameSpace[1024];
00181 int singleNameSpace = 0;
00182 char *index();
00183
00184 if (nice_intro()) return(0);
00185
00186 quiet = cmdparams_isflagset(&cmdparams, "q");
00187 web_query = strdup (cmdparams_get_str (&cmdparams, "QUERY_STRING", NULL));
00188 from_web = strcmp (web_query, "Not Specified") != 0;
00189 want_JSON = from_web || cmdparams_get_int (&cmdparams, "z", NULL) != 0;
00190
00191 printinfo = cmdparams_get_int(&cmdparams, "p", NULL);
00192
00193 if (cmdparams_numargs(&cmdparams)==2)
00194 {
00195 filterctx = strdup(cmdparams_getarg(&cmdparams, 1));
00196 filter = filterctx;
00197 }
00198 else if (from_web && *web_query)
00199 {
00200 filterctx = web_query;
00201 web_query = NULL;
00202 filter = index(filterctx,'=')+1;
00203
00204 CGI_unescape_url(filter);
00205 }
00206 else
00207 filter = NULL;
00208
00209
00210 if (web_query)
00211 {
00212 free(web_query);
00213 web_query = NULL;
00214 }
00215
00216 if (filter)
00217 {
00218 int i;
00219 char *chtmp = NULL;
00220
00221
00222 if (strncmp(filter, "NOT ", 4)==0)
00223 {
00224 filterNOT = 1;
00225 filter += 4;
00226 }
00227 else
00228 {
00229 filterNOT = 0;
00230 for (i=1; filter[i]; i++)
00231 if (filter[i] == '.' && filter[i-1] == '\\')
00232 {
00233 if (singleNameSpace)
00234 {
00235 singleNameSpace = 0;
00236 break;
00237 }
00238 singleNameSpace = 1;
00239 strncpy(NameSpace, filter, i-1);
00240 NameSpace[i-1] = '\0';
00241 }
00242 }
00243 if (regcomp(&seriesfilter, filter, (REG_EXTENDED | REG_ICASE | REG_NOSUB)))
00244 {
00245 status = SS_FORMATERROR;
00246 goto Failure;
00247 }
00248
00249 chtmp = strdup(filter);
00250 filter = chtmp;
00251 chtmp = NULL;
00252
00253 free(filterctx);
00254 filterctx = NULL;
00255 }
00256
00257
00258
00259
00260 if (singleNameSpace)
00261 {
00262 if (printinfo || want_JSON)
00263 sprintf(query, "select seriesname, primary_idx, description from %s.%s order by seriesname", NameSpace, DRMS_MASTER_SERIES_TABLE);
00264 else
00265 sprintf(query, "select seriesname from %s.%s order by seriesname", NameSpace, DRMS_MASTER_SERIES_TABLE);
00266 }
00267 else
00268 {
00269 if (printinfo || want_JSON)
00270 sprintf(query, "select seriesname, primary_idx, description from %s() order by seriesname", DRMS_MASTER_SERIES_TABLE);
00271 else
00272 sprintf(query, "select seriesname from %s() order by seriesname", DRMS_MASTER_SERIES_TABLE);
00273 }
00274
00275 if ((qres = drms_query_txt(drms_env->session, query)) == NULL)
00276 {
00277 status = SS_NODRMS;
00278 goto Failure;
00279 }
00280
00281 nseries = qres->num_rows;
00282
00283
00284
00285
00286
00287
00288 if (want_JSON)
00289 {
00290 if (!quiet)
00291 {
00292 printf("Content-type: application/json\n\n");
00293 }
00294
00295 if (nseries)
00296 {
00297 printf("{\"status\":0,\n");
00298 printf(" \"names\":[\n");
00299 }
00300 }
00301
00302 nused = 0;
00303 for (iseries=0; iseries<nseries; iseries++)
00304 {
00305 char *seriesname = qres->field[iseries][0];
00306 int regex_result;
00307 if (filter)
00308 regex_result = regexec(&seriesfilter, seriesname, 10, pmatch, 0);
00309
00310 if (!filter || (!filterNOT && !regex_result) || (filterNOT && regex_result))
00311 {
00312 if (want_JSON)
00313 printf("%s {\"name\":\"%s\",",(nused ? ",\n" : ""),seriesname);
00314 else
00315 printf(" %s\n",seriesname);
00316
00317 if (printinfo || want_JSON)
00318 {
00319 char *primary_idx = qres->field[iseries][1];
00320 char *description = qres->field[iseries][2];
00321 char *p;
00322 int npk = 0;
00323 if (want_JSON)
00324 printf("\"primekeys\":\"");
00325 else
00326 printf(" Prime Keys are: ");
00327 for (p = strtok(primary_idx, ", "); p; p = strtok(NULL, ", "))
00328 {
00329 char *ind = strstr(p, "_index");
00330 if (ind)
00331 *ind = '\0';
00332 if (npk++)
00333 printf(", ");
00334 printf("%s",p);
00335 }
00336 if (want_JSON)
00337 printf("\",");
00338 if (verbose)
00339 {
00340 int drmsstatus;
00341 DRMS_Record_t *rec = drms_template_record(drms_env, seriesname, &drmsstatus);
00342 if (want_JSON)
00343 {
00344 printf("\"archive\":\"%d\",",rec->seriesinfo->archive);
00345 printf("\"retention\":\"%d\",",rec->seriesinfo->retention);
00346 printf("\"tapegroup\":\"%d\",",rec->seriesinfo->tapegroup);
00347 printf("\"unitsize\":\"%d\",",rec->seriesinfo->unitsize);
00348 printf("\"owner\":\"%s\",",drms_getseriesowner(drms_env, seriesname, &drmsstatus));
00349 }
00350 else
00351 {
00352 printf("\n Archive: %d", rec->seriesinfo->archive);
00353 printf("\n Retention: %d", rec->seriesinfo->retention);
00354 printf("\n Tapegroup: %d", rec->seriesinfo->tapegroup);
00355 printf("\n Unitsize: %d", rec->seriesinfo->unitsize);
00356 printf("\n Owner: %s", drms_getseriesowner(drms_env, seriesname, &drmsstatus));
00357 }
00358 }
00359 if (want_JSON)
00360 {
00361 char *desc_escaped = json_escape(description);
00362 printf("\"note\":\"%s\"}",desc_escaped);
00363 free(desc_escaped);
00364 }
00365 else
00366 {
00367 printf("\n");
00368 printf(" Note: %s", description);
00369 printf("\n");
00370 }
00371 }
00372 nused++;
00373 }
00374 }
00375
00376 if (want_JSON)
00377 {
00378 printf("],\n\"n\":%d}\n", nused);
00379 fflush(stdout);
00380 }
00381 else
00382 {
00383 if (!quiet && filter)
00384 printf("%d series found the matching %s\n", nused, filter);
00385 }
00386
00387 if (filter)
00388 {
00389 regfree(&seriesfilter);
00390 free(filter);
00391 }
00392
00393 db_free_text_result(qres);
00394
00395 return status;
00396
00397 Failure:
00398 if (want_JSON)
00399 printf("{\"status\":1,\"errmsg\":%s}\n", SS_ERRORS[status].errmsg);
00400 else
00401 printf("show_keys error: %s\n",SS_ERRORS[status].errmsg);
00402
00403 return status;
00404 }
00405
00406
00407 char * json_escape (char * text)
00408 {
00409 char *output, *op;
00410 size_t i, length;
00411 char buffer[6];
00412
00413 assert (text != NULL);
00414
00415
00416 length = strlen(text);
00417 op = output = (char *)malloc(length*6*sizeof(char));
00418 if (output == NULL)
00419 return NULL;
00420 for (i = 0; i < length; i++)
00421 {
00422 if (text[i] == '\\')
00423 {
00424 *output++ = '\\';
00425 *output++ = '\\';
00426 }
00427 else if (text[i] == '\"')
00428 {
00429 *output++ = '\\';
00430 *output++ = '"';
00431 }
00432 else if (text[i] == '/')
00433 {
00434 *output++ = '\\';
00435 *output++ = '/';
00436 }
00437 else if (text[i] == '\b')
00438 {
00439 *output++ = '\\';
00440 *output++ = 'b';
00441 }
00442 else if (text[i] == '\f')
00443 {
00444 *output++ = '\\';
00445 *output++ = 'f';
00446 }
00447 else if (text[i] == '\n')
00448 {
00449 *output++ = '\\';
00450 *output++ = 'n';
00451 }
00452 else if (text[i] == '\r')
00453 {
00454 *output++ = '\\';
00455 *output++ = 'r';
00456 }
00457 else if (text[i] == '\t')
00458 {
00459 *output++ = '\\';
00460 *output++ = 't';
00461 }
00462 else if (text[i] < 0)
00463 {
00464 *output++ = text[i];
00465 }
00466 else if (text[i] < 0x20)
00467 {
00468 sprintf(buffer,"\\u%4.4x",text[i]);
00469 strncpy(output,buffer,6);
00470 output += 6;
00471 }
00472 else
00473 {
00474 *output++ = text[i];
00475 }
00476 }
00477 *output = '\0';
00478 return (op);
00479 }
00480