static void AddPrintColumn(const char * heading, int width, int opts, const char * expr) { mask.set_heading(heading); int wid = width ? width : strlen(heading); mask.registerFormat("%v", wid, opts, expr); }
static void ppDisplayHeadings(FILE* file, ClassAd *ad, const char * pszExtra) { if (ad) { // render the first ad to a string so the column widths update std::string tmp; pm.display(tmp, ad, NULL); } if (pm.has_headings()) { pm.display_Headings(file); } else { pm.display_Headings(file, pm_head); } if (pszExtra) printf("%s", pszExtra); }
void printRun (ClassAd *ad, bool first) { if (first) { ppInit(); ppSetColumn(ATTR_NAME, wide_display ? -34 : -15, ! wide_display); if (javaMode) { ppSetColumn(ATTR_JAVA_VENDOR, -11, ! wide_display); ppSetColumn(ATTR_JAVA_VERSION, Lbl("Ver"), -6, ! wide_display); } else if (vmMode) { ppSetColumn(ATTR_VM_TYPE, Lbl("VMType"), -6, ! wide_display); ppSetColumn(ATTR_VM_NETWORKING_TYPES, Lbl("Network"), -11, ! wide_display); } else { ppSetColumn(ATTR_OPSYS, -11, true); ppSetColumn(ATTR_ARCH, -6, true); } ppSetColumn(ATTR_LOAD_AVG, Lbl("LoadAv"), formatLoadAvg, NULL, 6, true); ppSetColumn(ATTR_REMOTE_USER, -20, ! wide_display); ppSetColumn(ATTR_CLIENT_MACHINE, -16, ! wide_display); ppDisplayHeadings(stdout, ad, "\n"); } if (ad) pm.display (stdout, ad); }
int set_status_print_mask_from_stream ( const char * streamid, bool is_filename, const char ** pconstraint) { std::string where_expr; std::string messages; StringList attrs; printmask_aggregation_t aggregation; SimpleInputStream * pstream = NULL; *pconstraint = NULL; FILE *file = NULL; if (MATCH == strcmp("-", streamid)) { pstream = new SimpleFileInputStream(stdin, false); } else if (is_filename) { file = safe_fopen_wrapper_follow(streamid, "r"); if (file == NULL) { fprintf(stderr, "Can't open select file: %s\n", streamid); return -1; } pstream = new SimpleFileInputStream(file, true); } else { pstream = new StringLiteralInputStream(streamid); } ASSERT(pstream); int err = SetAttrListPrintMaskFromStream( *pstream, *getCondorStatusPrintFormats(), pm, pmHeadFoot, aggregation, group_by_keys, where_expr, attrs, messages); delete pstream; pstream = NULL; if ( ! err) { if (aggregation != PR_NO_AGGREGATION) { fprintf(stderr, "print-format aggregation not supported\n"); return -1; } if ( ! where_expr.empty()) { *pconstraint = pm.store(where_expr.c_str()); //if ( ! validate_constraint(*pconstraint)) { // formatstr_cat(messages, "WHERE expression is not valid: %s\n", *pconstraint); //} } // convert projection list into the format that condor status likes. because programmers. attrs.rewind(); const char * attr; while ((attr = attrs.next())) { projList.AppendArg(attr); } } if ( ! messages.empty()) { fprintf(stderr, "%s", messages.c_str()); } return err; }
static void ppSetColumnFormat(const CustomFormatFn & fmt, const char * print, int width, bool truncate, ivfield alt, const char * attr) { int opts = ppWidthOpts(width, truncate) | ppAltOpts(alt); if (width == 11 && fmt.IsNumber() && (fmt.Is(formatElapsedTime) || fmt.Is(formatRealTime))) { opts |= FormatOptionNoPrefix; width = 12; } pm.registerFormat(print, width, opts, fmt, attr); }
void printMasterNormal(ClassAd *ad, bool first) { if (first) { ppInit(); ppSetColumn(ATTR_NAME, -20, false); ppDisplayHeadings(stdout, ad, "\n"); } if (ad) pm.display (stdout, ad); }
void printQuillNormal (ClassAd *ad) { static bool first = true; static AttrListPrintMask alpm; if (ad) { // print header if necessary if (first) { printf ("\n%-20.20s %-10.10s %-16.16s %-18.18s\n\n", ATTR_NAME, ATTR_MACHINE, ATTR_QUILL_SQL_TOTAL, ATTR_QUILL_SQL_LAST_BATCH); alpm.registerFormat("%-20.20s ", ATTR_NAME, "[??????????????????] "); alpm.registerFormat("%-10.10s ", ATTR_MACHINE, "[????????] "); alpm.registerFormat("%16d ",ATTR_QUILL_SQL_TOTAL, "[??????????????] "); alpm.registerFormat("%18d\n",ATTR_QUILL_SQL_LAST_BATCH, "[???????????]\n"); first = false; } alpm.display (stdout, ad); } }
void printStartdNormal (ClassAd *ad, bool first) { if (first) { ppInit(); ppSetColumn(ATTR_NAME, wide_display ? -34 : -18, ! wide_display); if (javaMode) { ppSetColumn(ATTR_JAVA_VENDOR, -10, ! wide_display); ppSetColumn(ATTR_JAVA_VERSION, Lbl("Ver"), -6, ! wide_display); } else if (vmMode) { ppSetColumn(ATTR_VM_TYPE, Lbl("VmType"), -6, true); ppSetColumn(ATTR_VM_NETWORKING_TYPES, Lbl("Network"), -9, true); }else { ppSetColumn(ATTR_OPSYS, -10, true); ppSetColumn(ATTR_ARCH, -6, true); } ppSetColumn(ATTR_STATE, -9, true); ppSetColumn(ATTR_ACTIVITY, -8, true); //ppSetColumn(0, ATTR_LOAD_AVG, "%.3f ", false, invalid_fields_empty ? "" : "[???] "); //pm_head.Append(ATTR_LOAD_AVG); //pm_head.Append(wide_display ? ATTR_LOAD_AVG : "LoadAv"); //pm.registerFormat("%.3f ", wide_display ? 7 : 6, FormatOptionAutoWidth, ATTR_LOAD_AVG, invalid_fields_empty ? "" : "[???] "); ppSetColumn(ATTR_LOAD_AVG, Lbl("LoadAv"), formatLoadAvg, NULL, 6, true); if (vmMode) { ppSetColumn(ATTR_VM_MEMORY, Lbl("VMMem"), "%4d", false); } else { ppSetColumn(ATTR_MEMORY, Lbl("Mem"), "%4d", false); } pm_head.Append(wide_display ? "ActivityTime" : " ActvtyTime"); pm.registerFormat(NULL, 12, FormatOptionAutoWidth | (wide_display ? 0 : FormatOptionNoPrefix) | AltFixMe, formatActivityTime, ATTR_ENTERED_CURRENT_ACTIVITY /* " [Unknown]"*/); ppDisplayHeadings(stdout, ad, "\n"); } if (ad) pm.display (stdout, ad); }
void printNegotiatorNormal(ClassAd *ad, bool first) { if (first) { ppInit(); ppSetColumn(ATTR_NAME, wide_display ? -32 : -20, ! wide_display); ppSetColumn(ATTR_MACHINE, wide_display ? -32 : -20, ! wide_display); ppDisplayHeadings(stdout, ad, "\n"); } if (ad) pm.display (stdout, ad); }
static void printHeader() { // Print header if ( ! longformat) { if ( ! customFormat) { // hack to get backward-compatible formatting if ( ! wide_format && 80 == wide_format_width) short_header(); else { init_default_custom_format(); if ( ! wide_format || 0 != wide_format_width) { int console_width = wide_format_width; if (console_width <= 0) console_width = getConsoleWindowSize()-1; // -1 because we get double spacing if we use the full width. if (console_width < 0) console_width = 1024; mask.SetOverallWidth(console_width); } } } if (customFormat && mask.has_headings()) { mask.display_Headings(stdout); } } }
void printStorageNormal(ClassAd *ad, bool first) { if (first) { ppInit(); ppSetColumn(ATTR_NAME, wide_display ? -34 : -30, ! wide_display); ppSetColumn(ATTR_DISK, Lbl("AvailDisk"), "%9d", true); ppSetColumn(ATTR_SUBNET, "%-11s", !wide_display); ppDisplayHeadings(stdout, ad, "\n"); } if (ad) pm.display (stdout, ad); }
void printAnyNormal(ClassAd *ad, bool first) { if (first) { ppInit(); ppSetColumn(ATTR_MY_TYPE, formatAdType, -18, true, CallInvalidField); ppSetColumn(ATTR_TARGET_TYPE, formatAdType, -18, true, CallInvalidField); ppSetColumn(ATTR_NAME, wide_display ? "%-41s" : "%-41.41s", ! wide_display, ShortInvalidField /*"[???]"*/); ppDisplayHeadings(stdout, ad, "\n"); } if (ad) pm.display (stdout, ad); }
// setup display mask for default output static void init_default_custom_format() { mask.SetAutoSep(NULL, " ", NULL, "\n"); int opts = wide_format ? (FormatOptionNoTruncate | FormatOptionAutoWidth) : 0; AddPrintColumn(" ID", -7, FormatOptionNoTruncate, ATTR_CLUSTER_ID, format_job_id); AddPrintColumn("OWNER", -14, FormatOptionAutoWidth | opts, ATTR_OWNER); AddPrintColumn("SUBMITTED", 11, 0, ATTR_Q_DATE, format_int_date); AddPrintColumn("RUN_TIME", 12, 0, ATTR_CLUSTER_ID, format_hist_runtime); AddPrintColumn("ST", -2, 0, ATTR_JOB_STATUS, format_int_job_status); AddPrintColumn("COMPLETED", 11, 0, ATTR_COMPLETION_DATE, format_int_date); AddPrintColumn("CMD", -15, FormatOptionLeftAlign | FormatOptionNoTruncate, ATTR_JOB_CMD, format_job_cmd_and_args); customFormat = TRUE; }
void printCollectorNormal(ClassAd *ad, bool first) { if (first) { ppInit(); ppSetColumn(ATTR_NAME, wide_display ? -34 : -28, ! wide_display); ppSetColumn(ATTR_MACHINE, wide_display ? -34 : -18, ! wide_display); ppSetColumn(ATTR_RUNNING_JOBS, "%11d", true); ppSetColumn(ATTR_IDLE_JOBS, "%8d", true); ppSetColumn(ATTR_NUM_HOSTS_TOTAL, "%10d", true); ppDisplayHeadings(stdout, ad, "\n"); } if (ad) pm.display (stdout, ad); }
void printScheddSubmittors (ClassAd *ad, bool first) { if (first) { ppInit(); ppSetColumn(ATTR_NAME, wide_display ? -34 : -28, ! wide_display); ppSetColumn(ATTR_MACHINE, wide_display ? -34 : -18, ! wide_display); ppSetColumn(ATTR_RUNNING_JOBS, "%11d", true); ppSetColumn(ATTR_IDLE_JOBS, "%8d", true); ppSetColumn(ATTR_HELD_JOBS, "%8d", true); ppDisplayHeadings(stdout, ad, "\n"); } if (ad) pm.display (stdout, ad); }
void printScheddNormal (ClassAd *ad, bool first) { if (first) { ppInit(); ppSetColumn(ATTR_NAME, wide_display ? -34 : -20, ! wide_display); ppSetColumn(ATTR_MACHINE, wide_display ? -34 : -10, ! wide_display); ppSetColumn(ATTR_TOTAL_RUNNING_JOBS, "%16d", true); ppSetColumn(ATTR_TOTAL_IDLE_JOBS, "%13d", true); ppSetColumn(ATTR_TOTAL_HELD_JOBS, "%14d", true); ppDisplayHeadings(stdout, ad, "\n"); } if (ad) pm.display (stdout, ad); }
void printStartdAbsent (ClassAd *ad, bool first) { if (first) { ppInit(); ppSetColumn(ATTR_NAME, -34, ! wide_display); ppSetColumn(ATTR_OPSYS, -10, true); ppSetColumn(ATTR_ARCH, -8, true); ppSetColumn(ATTR_LAST_HEARD_FROM, Lbl("Went Absent"), formatRealDate, -11, true); ppSetColumn(ATTR_CLASSAD_LIFETIME, Lbl("Will Forget"), formatDueDate, -11, true); ppDisplayHeadings(stdout, ad, "\n"); } if (ad) pm.display (stdout, ad); return; }
void printGridNormal(ClassAd *ad, bool first) { if (first) { ppInit(); ppSetColumn(ATTR_NAME, -34, ! wide_display); ppSetColumn("NumJobs", "%7d", true); ppSetColumn("SubmitsAllowed", Lbl("Allowed"), "%7d", true); ppSetColumn("SubmitsWanted", Lbl(" Wanted"), "%7d", true); ppSetColumn(ATTR_RUNNING_JOBS, "%11d", true); ppSetColumn(ATTR_IDLE_JOBS, "%8d", true); ppDisplayHeadings(stdout, ad, "\n"); } if (ad) pm.display (stdout, ad); }
// print a single job ad // static void printJob(ClassAd & ad) { if (longformat) { if (use_xml) { fPrintAdAsXML(stdout, ad); } else { fPrintAd(stdout, ad); } printf("\n"); } else { if (customFormat) { mask.display(stdout, &ad); } else { displayJobShort(&ad); } } }
void printServer (ClassAd *ad, bool first) { if (first) { ppInit(); ppSetColumn(ATTR_NAME, wide_display ? -34 : -13, ! wide_display); ppSetColumn(ATTR_OPSYS, -11, true); ppSetColumn(ATTR_ARCH, -6, true); ppSetColumn(ATTR_LOAD_AVG, Lbl("LoadAv"), formatLoadAvg, NULL, 6, true); ppSetColumn(ATTR_MEMORY, "%8d", true); ppSetColumn(ATTR_DISK, "%9d", true); ppSetColumn(ATTR_MIPS, "%7d", true); ppSetColumn(ATTR_KFLOPS, "%9d", true); ppDisplayHeadings(stdout, ad, "\n"); } if (ad) pm.display (stdout, ad); }
void printStartdOffline( ClassAd *ad, bool first ) { if( first ) { ppInit(); ppSetColumn( ATTR_NAME, -34, ! wide_display ); // A custom printer for filtering out the ints would be handy. ppSetColumn( "OfflineUniverses", Lbl( "Offline Universes" ), formatOfflineUniverses, -42, ! wide_display ); // How should I print out the offline reasons and timestamps? ppDisplayHeadings(stdout, ad, "\n"); } if( ad ) { pm.display( stdout, ad ); } return; }
void printState (ClassAd *ad, bool first) { if (first) { ppInit(); int timewid = wide_display ? 12 : 11; ppSetColumn(ATTR_NAME, wide_display ? -34 : -12, ! wide_display); ppSetColumn(ATTR_CPUS, Lbl("Cpu"), 3, true); ppSetColumn(ATTR_MEMORY, Lbl(" Mem"), 5, true); //ppSetColumn(ATTR_LOAD_AVG, Lbl("Load "), "%.3f", true); ppSetColumn(ATTR_LOAD_AVG, Lbl("LoadAv"), formatLoadAvg, NULL, 6, true); ppSetColumn(ATTR_KEYBOARD_IDLE, Lbl(" KbdIdle"), formatRealTime, timewid, true); ppSetColumn(ATTR_STATE, -7, true); ppSetColumn(ATTR_ENTERED_CURRENT_STATE, Lbl(" StateTime"), formatElapsedTime, timewid, true); ppSetColumn(ATTR_ACTIVITY, Lbl("Activ"), -5, true); ppSetColumn(ATTR_ENTERED_CURRENT_ACTIVITY, Lbl(" ActvtyTime"), formatElapsedTime, timewid, true); ppDisplayHeadings(stdout, ad, "\n"); } if (ad) pm.display (stdout, ad); }
// Read the history from a single file and print it out. static void readHistoryFromFile(char *JobHistoryFileName, char* constraint, ExprTree *constraintExpr) { int EndFlag = 0; int ErrorFlag = 0; int EmptyFlag = 0; AttrList *ad = NULL; long offset = 0; bool BOF = false; // Beginning Of File MyString buf; FILE* LogFile=safe_fopen_wrapper(JobHistoryFileName,"r"); if (!LogFile) { fprintf(stderr,"History file (%s) not found or empty.\n", JobHistoryFileName); exit(1); } // In case of rotated history files, check if we have already reached the number of // matches specified by the user before reading the next file if (specifiedMatch != 0) { if (matchCount == specifiedMatch) { // Already found n number of matches, cleanup fclose(LogFile); return; } } if (backwards) { offset = findLastDelimiter(LogFile, JobHistoryFileName); } while(!EndFlag) { if (backwards) { // Read history file backwards if (BOF) { // If reached beginning of file break; } offset = findPrevDelimiter(LogFile, JobHistoryFileName, offset); if (offset == -1) { // Unable to match constraint break; } else if (offset != 0) { fseek(LogFile, offset, SEEK_SET); buf.readLine(LogFile); // Read one line to skip delimiter and adjust to actual offset of ad } else { // Offset set to 0 BOF = true; fseek(LogFile, offset, SEEK_SET); } } if( !( ad=new AttrList(LogFile,"***", EndFlag, ErrorFlag, EmptyFlag) ) ){ fprintf( stderr, "Error: Out of memory\n" ); exit( 1 ); } if( ErrorFlag ) { printf( "\t*** Warning: Bad history file; skipping malformed ad(s)\n" ); ErrorFlag=0; if(ad) { delete ad; ad = NULL; } continue; } if( EmptyFlag ) { EmptyFlag=0; if(ad) { delete ad; ad = NULL; } continue; } if (!constraint || EvalBool(ad, constraintExpr)) { if (longformat) { ad->fPrint(stdout); printf("\n"); } else { if (customFormat) { mask.display(stdout, ad); } else { displayJobShort(ad); } } matchCount++; // if control reached here, match has occured if (specifiedMatch != 0) { // User specified a match number if (matchCount == specifiedMatch) { // Found n number of matches, cleanup if (ad) { delete ad; ad = NULL; } fclose(LogFile); return; } } } if(ad) { delete ad; ad = NULL; } } fclose(LogFile); return; }
// Read a stream a line at a time, and parse it to fill out the print mask, // header, group_by, where expression, and projection attributes. // int SetAttrListPrintMaskFromStream ( SimpleInputStream & stream, // in: fetch lines from this stream until nextline() returns NULL const CustomFormatFnTable & FnTable, // in: table of custom output functions for SELECT AttrListPrintMask & mask, // out: columns and headers set in SELECT printmask_headerfooter_t & headfoot, // out: header and footer flags set in SELECT or SUMMARY printmask_aggregation_t & aggregate, // out: aggregation mode in SELECT std::vector<GroupByKeyInfo> & group_by, // out: ordered set of attributes/expressions in GROUP BY std::string & where_expression, // out: classad expression from WHERE StringList & attrs, // out ClassAd attributes referenced in mask or group_by outputs std::string & error_message) // out, if return is non-zero, this will be an error message { ClassAd ad; // so we can GetExprReferences enum section_t { NOWHERE=0, SELECT, SUMMARY, WHERE, GROUP}; enum cust_t { PRINTAS_STRING, PRINTAS_INT, PRINTAS_FLOAT }; bool label_fields = false; const char * labelsep = " = "; const char * prowpre = NULL; const char * pcolpre = " "; const char * pcolsux = NULL; const char * prowsux = "\n"; mask.SetAutoSep(prowpre, pcolpre, pcolsux, prowsux); error_message.clear(); aggregate = PR_NO_AGGREGATION; printmask_headerfooter_t usingHeadFoot = (printmask_headerfooter_t)(HF_CUSTOM | HF_NOSUMMARY); section_t sect = SELECT; tokener toke(""); while (toke.set(stream.nextline())) { if ( ! toke.next()) continue; if (toke.matches("#")) continue; if (toke.matches("SELECT")) { while (toke.next()) { if (toke.matches("FROM")) { if (toke.next()) { if (toke.matches("AUTOCLUSTER")) { aggregate = PR_FROM_AUTOCLUSTER; } else { std::string aa; toke.copy_token(aa); formatstr_cat(error_message, "Warning: Unknown header argument %s for SELECT FROM\n", aa.c_str()); } } } else if (toke.matches("UNIQUE")) { aggregate = PR_COUNT_UNIQUE; } else if (toke.matches("BARE")) { usingHeadFoot = HF_BARE; } else if (toke.matches("NOTITLE")) { usingHeadFoot = (printmask_headerfooter_t)(usingHeadFoot | HF_NOTITLE); } else if (toke.matches("NOHEADER")) { usingHeadFoot = (printmask_headerfooter_t)(usingHeadFoot | HF_NOHEADER); } else if (toke.matches("NOSUMMARY")) { usingHeadFoot = (printmask_headerfooter_t)(usingHeadFoot | HF_NOSUMMARY); } else if (toke.matches("LABEL")) { label_fields = true; } else if (label_fields && toke.matches("SEPARATOR")) { if (toke.next()) { std::string tmp; toke.copy_token(tmp); collapse_escapes(tmp); labelsep = mask.store(tmp.c_str()); } } else if (toke.matches("RECORDPREFIX")) { if (toke.next()) { std::string tmp; toke.copy_token(tmp); collapse_escapes(tmp); prowpre = mask.store(tmp.c_str()); } } else if (toke.matches("RECORDSUFFIX")) { if (toke.next()) { std::string tmp; toke.copy_token(tmp); collapse_escapes(tmp); prowsux = mask.store(tmp.c_str()); } } else if (toke.matches("FIELDPREFIX")) { if (toke.next()) { std::string tmp; toke.copy_token(tmp); collapse_escapes(tmp); pcolpre = mask.store(tmp.c_str()); } } else if (toke.matches("FIELDSUFFIX")) { if (toke.next()) { std::string tmp; toke.copy_token(tmp); collapse_escapes(tmp); pcolsux = mask.store(tmp.c_str()); } } else { std::string aa; toke.copy_token(aa); formatstr_cat(error_message, "Warning: Unknown header argument %s for SELECT\n", aa.c_str()); } } mask.SetAutoSep(prowpre, pcolpre, pcolsux, prowsux); sect = SELECT; continue; } else if (toke.matches("WHERE")) { sect = WHERE; if ( ! toke.next()) continue; } else if (toke.matches("GROUP")) { sect = GROUP; if ( ! toke.next() || (toke.matches("BY") && ! toke.next())) continue; } else if (toke.matches("SUMMARY")) { usingHeadFoot = (printmask_headerfooter_t)(usingHeadFoot & ~HF_NOSUMMARY); while (toke.next()) { if (toke.matches("STANDARD")) { // attrs.insert(ATTR_JOB_STATUS); } else if (toke.matches("NONE")) { usingHeadFoot = (printmask_headerfooter_t)(usingHeadFoot | HF_NOSUMMARY); } else { std::string aa; toke.copy_token(aa); formatstr_cat(error_message, "Unknown argument %s for SELECT\n", aa.c_str()); } } sect = SUMMARY; continue; } switch (sect) { case SELECT: { toke.mark(); std::string attr; std::string name; int opts = FormatOptionAutoWidth | FormatOptionNoTruncate; const char * fmt = "%v"; int wid = 0; CustomFormatFn cust; bool got_attr = false; while (toke.next()) { const Keyword * pkw = SelectKeywords.find_match(toke); if ( ! pkw) continue; // next token is a keyword, if we havent set the attribute yet // it's everything up to the current token. int kw = pkw->value; if ( ! got_attr) { toke.copy_marked(attr); got_attr = true; } switch (kw) { case kw_AS: { if (toke.next()) { toke.copy_token(name); if (toke.is_quoted_string()) { collapse_escapes(name); } } else { expected_token(error_message, "column name after AS", "SELECT", stream, toke); } toke.mark_after(); } break; case kw_PRINTF: { if (toke.next()) { std::string val; toke.copy_token(val); fmt = mask.store(val.c_str()); } else { expected_token(error_message, "format after PRINTF", "SELECT", stream, toke); } } break; case kw_PRINTAS: { if (toke.next()) { const CustomFormatFnTableItem * pcffi = FnTable.find_match(toke); if (pcffi) { cust = pcffi->cust; //cust_type = pcffi->cust; const char * pszz = pcffi->extra_attribs; if (pszz) { size_t cch = strlen(pszz); while (cch > 0) { attrs.insert(pszz); pszz += cch+1; cch = strlen(pszz); } } } else { std::string aa; toke.copy_token(aa); formatstr_cat(error_message, "Unknown argument %s for PRINTAS\n", aa.c_str()); } } else { expected_token(error_message, "function name after PRINTAS", "SELECT", stream, toke); } } break; case kw_NOSUFFIX: { opts |= FormatOptionNoSuffix; } break; case kw_NOPREFIX: { opts |= FormatOptionNoPrefix; } break; case kw_LEFT: { opts |= FormatOptionLeftAlign; } break; case kw_RIGHT: { opts &= ~FormatOptionLeftAlign; } break; case kw_TRUNCATE: { opts &= ~FormatOptionNoTruncate; } break; case kw_WIDTH: { if (toke.next()) { std::string val; toke.copy_token(val); if (toke.matches("AUTO")) { opts |= FormatOptionAutoWidth; } else { wid = atoi(val.c_str()); //if (wid) opts &= ~FormatOptionAutoWidth; //PRAGMA_REMIND("TJ: decide how LEFT & RIGHT interact with pos and neg widths." } } else { expected_token(error_message, "number or AUTO after WIDTH", "SELECT", stream, toke); } } break; default: unexpected_token(error_message, "SELECT", stream, toke); break; } // switch } // while if ( ! got_attr) { attr = toke.content(); } trim(attr); if (attr.empty() || attr[0] == '#') continue; const char * lbl = name.empty() ? attr.c_str() : name.c_str(); if (label_fields) { // build a format string that contains the label std::string label(lbl); if (labelsep) { label += labelsep; } if (fmt) { label += fmt; } else { label += "%"; if (wid) { if (opts & FormatOptionNoTruncate) formatstr_cat(label, "%d", wid); else formatstr_cat(label, "%d.%d", wid, wid < 0 ? -wid : wid); } label += cust ? "s" : "v"; } lbl = mask.store(label.c_str()); fmt = lbl; wid = 0; } else { if ( ! wid) { wid = 0 - (int)strlen(lbl); } mask.set_heading(lbl); lbl = NULL; } if (cust) { mask.registerFormat (lbl, wid, opts, cust, attr.c_str()); } else { mask.registerFormat(fmt, wid, opts, attr.c_str()); } ad.GetExprReferences(attr.c_str(), NULL, &attrs); } break; case WHERE: { toke.copy_to_end(where_expression); trim(where_expression); } break; case SUMMARY: { } break; case GROUP: { toke.mark(); GroupByKeyInfo key; // in case we end up finding no keywords, copy the remainder of the line now as the expression toke.copy_to_end(key.expr); bool got_expr = false; while (toke.next()) { const Keyword * pgw = GroupKeywords.find_match(toke); if ( ! pgw) continue; // got a keyword int gw = pgw->value; if ( ! got_expr) { toke.copy_marked(key.expr); got_expr = true; } switch (gw) { case gw_AS: { if (toke.next()) { toke.copy_token(key.name); } toke.mark_after(); } break; case gw_DECENDING: { key.decending = true; toke.mark_after(); } break; case gw_ASCENDING: { key.decending = false; toke.mark_after(); } break; default: unexpected_token(error_message, "GROUP BY", stream, toke); break; } // switch } // while toke.next trim(key.expr); if (key.expr.empty() || key.expr[0] == '#') continue; if ( ! ad.GetExprReferences(key.expr.c_str(), NULL, &attrs)) { formatstr_cat(error_message, "GROUP BY expression is not valid: %s\n", key.expr.c_str()); } else { group_by.push_back(key); } } break; default: break; } } headfoot = usingHeadFoot; return 0; }
void prettyPrint (ClassAdList &adList, TrackTotals *totals) { ppOption pps = using_print_format ? PP_CUSTOM : ppStyle; ClassAd *ad; int classad_index; int last_classad_index; bool fPrintHeadings = pm.has_headings() || (pm_head.Length() > 0); classad_index = 0; last_classad_index = adList.Length() - 1; adList.Open(); while ((ad = adList.Next())) { if (!wantOnlyTotals) { switch (pps) { case PP_STARTD_NORMAL: if (absentMode) { printStartdAbsent (ad, (classad_index == 0)); } else if( offlineMode ) { printStartdOffline( ad, (classad_index == 0)); } else { printStartdNormal (ad, (classad_index == 0)); } break; case PP_STARTD_SERVER: printServer (ad, (classad_index == 0)); break; case PP_STARTD_RUN: printRun (ad, (classad_index == 0)); break; case PP_STARTD_COD: printCOD (ad); break; case PP_STARTD_STATE: printState(ad, (classad_index == 0)); break; #ifdef HAVE_EXT_POSTGRESQL case PP_QUILL_NORMAL: printQuillNormal (ad); break; #endif /* HAVE_EXT_POSTGRESQL */ case PP_SCHEDD_NORMAL: printScheddNormal (ad, (classad_index == 0)); break; case PP_NEGOTIATOR_NORMAL: printNegotiatorNormal (ad, (classad_index == 0)); break; case PP_SCHEDD_SUBMITTORS: printScheddSubmittors (ad, (classad_index == 0)); break; case PP_VERBOSE: printVerbose (ad); break; case PP_XML: printXML (ad, (classad_index == 0), (classad_index == last_classad_index)); break; case PP_MASTER_NORMAL: printMasterNormal(ad, (classad_index == 0)); break; case PP_COLLECTOR_NORMAL: printCollectorNormal(ad, (classad_index == 0)); break; case PP_CKPT_SRVR_NORMAL: printCkptSrvrNormal(ad, (classad_index == 0)); break; case PP_STORAGE_NORMAL: printStorageNormal(ad, (classad_index == 0)); break; case PP_GRID_NORMAL: printGridNormal(ad, (classad_index == 0)); break; case PP_GENERIC_NORMAL: case PP_GENERIC: case PP_ANY_NORMAL: printAnyNormal(ad, (classad_index == 0)); break; case PP_CUSTOM: // hack: print a single item to a string, then discard the string // this makes sure that the headings line up correctly over the first // line of data. if (fPrintHeadings) { std::string tmp; pm.display(tmp, ad, targetAd); if (pm.has_headings()) { if ( ! (pmHeadFoot & HF_NOHEADER)) pm.display_Headings(stdout); } else { pm.display_Headings(stdout, pm_head); } fPrintHeadings = false; } printCustom (ad); break; case PP_NOTSET: fprintf (stderr, "Error: pretty printing set to PP_NOTSET.\n"); exit (1); default: fprintf (stderr, "Error: Unknown pretty print option.\n"); exit (1); } } classad_index++; totals->update(ad); } adList.Close(); // if there are no ads to print, but the user wanted XML output, // then print out the XML header and footer, so that naive XML // parsers won't get confused. if ( PP_XML == pps && 0 == classad_index ) { printXML (NULL, true, true); } // if totals are required, display totals if (adList.MyLength() > 0 && totals) totals->displayTotals(stdout, 20); }
static void AddPrintColumn(const char * heading, int width, int opts, const char * attr, const CustomFormatFn & fmt) { mask.set_heading(heading); int wid = width ? width : strlen(heading); mask.registerFormat(NULL, wid, opts, fmt, attr); }
int main(int argc, char* argv[]) { Collectors = NULL; #ifdef HAVE_EXT_POSTGRESQL HistorySnapshot *historySnapshot; SQLQuery queryhor; SQLQuery queryver; QuillErrCode st; bool remotequill=false; char *quillName=NULL; AttrList *ad=0; int flag = 1; void **parameters; char *dbconn=NULL; char *completedsince = NULL; char *dbIpAddr=NULL, *dbName=NULL,*queryPassword=NULL; bool remoteread = false; #endif /* HAVE_EXT_POSTGRESQL */ const char *owner=NULL; bool readfromfile = true; bool fileisuserlog = false; char* JobHistoryFileName=NULL; const char * pcolon=NULL; GenericQuery constraint; // used to build a complex constraint. ExprTree *constraintExpr=NULL; std::string tmp; int i; myDistro->Init( argc, argv ); config(); #ifdef HAVE_EXT_POSTGRESQL parameters = (void **) malloc(NUM_PARAMETERS * sizeof(void *)); queryhor.setQuery(HISTORY_ALL_HOR, NULL); queryver.setQuery(HISTORY_ALL_VER, NULL); #endif /* HAVE_EXT_POSTGRESQL */ for(i=1; i<argc; i++) { if (is_dash_arg_prefix(argv[i],"long",1)) { longformat=TRUE; } else if (is_dash_arg_prefix(argv[i],"xml",3)) { use_xml = true; longformat = true; } else if (is_dash_arg_prefix(argv[i],"backwards",1)) { backwards=TRUE; } // must be at least -forw to avoid conflict with -f (for file) and -format else if (is_dash_arg_prefix(argv[i],"nobackwards",3) || is_dash_arg_prefix(argv[i],"forwards",4)) { backwards=FALSE; } else if (is_dash_arg_colon_prefix(argv[i],"wide", &pcolon, 1)) { wide_format=TRUE; if (pcolon) { wide_format_width = atoi(++pcolon); if ( ! mask.IsEmpty()) mask.SetOverallWidth(getDisplayWidth()-1); if (wide_format_width <= 80) wide_format = FALSE; } } else if (is_dash_arg_prefix(argv[i],"match",1) || is_dash_arg_prefix(argv[i],"limit",3)) { i++; if (argc <= i) { fprintf(stderr, "Error: Argument -match requires a number value " " as a parameter.\n"); exit(1); } specifiedMatch = atoi(argv[i]); } #ifdef HAVE_EXT_POSTGRESQL else if(is_dash_arg_prefix(argv[i], "dbname",1)) { i++; if (argc <= i) { fprintf( stderr, "Error: Argument -dbname requires the name of a quilld as a parameter\n" ); exit(1); } /* if( !(quillName = get_daemon_name(argv[i])) ) { fprintf( stderr, "Error: unknown host %s\n", get_host_part(argv[i]) ); printf("\n"); print_wrapped_text("Extra Info: The name given with the -dbname " "should be the name of a condor_quilld process. " "Normally it is either a hostname, or " "\"name@hostname\". " "In either case, the hostname should be the " "Internet host name, but it appears that it " "wasn't.", stderr); exit(1); } sprintf (tmp, "%s == \"%s\"", ATTR_NAME, quillName); quillQuery.addORConstraint (tmp); */ quillName = argv[i]; sprintf (tmp, "%s == \"%s\"", ATTR_SCHEDD_NAME, quillName); quillQuery.addORConstraint (tmp.c_str()); remotequill = false; readfromfile = false; } #endif /* HAVE_EXT_POSTGRESQL */ else if (is_dash_arg_prefix(argv[i],"file",2)) { if (i+1==argc || JobHistoryFileName) break; i++; JobHistoryFileName=argv[i]; readfromfile = true; } else if (is_dash_arg_prefix(argv[i],"userlog",1)) { if (i+1==argc || JobHistoryFileName) break; i++; JobHistoryFileName=argv[i]; readfromfile = true; fileisuserlog = true; } else if (is_dash_arg_prefix(argv[i],"help",1)) { Usage(argv[0],0); } else if (is_dash_arg_prefix(argv[i],"format",1)) { if (argc <= i + 2) { fprintf(stderr, "Error: Argument -format requires a spec and " "classad attribute name as parameters.\n"); fprintf(stderr, "\t\te.g. condor_history -format '%%d' ClusterId\n"); exit(1); } mask.registerFormat(argv[i + 1], argv[i + 2]); customFormat = true; i += 2; } else if (*(argv[i]) == '-' && (is_arg_colon_prefix(argv[i]+1,"af", &pcolon, 2) || is_arg_colon_prefix(argv[i]+1,"autoformat", &pcolon, 5))) { // make sure we have at least one argument to autoformat if (argc <= i+1 || *(argv[i+1]) == '-') { fprintf (stderr, "Error: Argument %s requires at last one attribute parameter\n", argv[i]); fprintf(stderr, "\t\te.g. condor_history %s ClusterId\n", argv[i]); exit(1); } if (pcolon) ++pcolon; // if there are options, skip over the colon to the options. int ixNext = parse_autoformat_args(argc, argv, i+1, pcolon, mask, diagnostic); if (ixNext > i) i = ixNext-1; customFormat = true; } else if (is_dash_arg_colon_prefix(argv[i], "print-format", &pcolon, 2)) { if ( (argc <= i+1) || (*(argv[i+1]) == '-' && (argv[i+1])[1] != 0)) { fprintf( stderr, "Error: Argument -print-format requires a filename argument\n"); exit( 1 ); } // hack allow -pr ! to disable use of user-default print format files. if (MATCH == strcmp(argv[i+1], "!")) { ++i; disable_user_print_files = true; continue; } if ( ! wide_format) mask.SetOverallWidth(getDisplayWidth()-1); customFormat = true; ++i; std::string where_expr; if (set_print_mask_from_stream(mask, where_expr, argv[i], true) < 0) { fprintf(stderr, "Error: cannot execute print-format file %s\n", argv[i]); exit (1); } if ( ! where_expr.empty()) { constraint.addCustomAND(where_expr.c_str()); } } else if (is_dash_arg_prefix(argv[i],"constraint",1)) { // make sure we have at least one more argument if (argc <= i+1) { fprintf( stderr, "Error: Argument %s requires another parameter\n", argv[i]); exit(1); } i++; constraint.addCustomAND(argv[i]); } #ifdef HAVE_EXT_POSTGRESQL else if (is_dash_arg_prefix(argv[i],"completedsince",3)) { i++; if (argc <= i) { fprintf(stderr, "Error: Argument -completedsince requires a date and " "optional timestamp as a parameter.\n"); fprintf(stderr, "\t\te.g. condor_history -completedsince \"2004-10-19 10:23:54\"\n"); exit(1); } if (constraint!="") break; completedsince = strdup(argv[i]); parameters[0] = completedsince; queryhor.setQuery(HISTORY_COMPLETEDSINCE_HOR,parameters); queryver.setQuery(HISTORY_COMPLETEDSINCE_VER,parameters); } #endif /* HAVE_EXT_POSTGRESQL */ else if (sscanf (argv[i], "%d.%d", &cluster, &proc) == 2) { std::string jobconst; formatstr (jobconst, "%s == %d && %s == %d", ATTR_CLUSTER_ID, cluster,ATTR_PROC_ID, proc); constraint.addCustomOR(jobconst.c_str()); #ifdef HAVE_EXT_POSTGRESQL parameters[0] = &cluster; parameters[1] = &proc; queryhor.setQuery(HISTORY_CLUSTER_PROC_HOR, parameters); queryver.setQuery(HISTORY_CLUSTER_PROC_VER, parameters); #endif /* HAVE_EXT_POSTGRESQL */ } else if (sscanf (argv[i], "%d", &cluster) == 1) { std::string jobconst; formatstr (jobconst, "%s == %d", ATTR_CLUSTER_ID, cluster); constraint.addCustomOR(jobconst.c_str()); #ifdef HAVE_EXT_POSTGRESQL parameters[0] = &cluster; queryhor.setQuery(HISTORY_CLUSTER_HOR, parameters); queryver.setQuery(HISTORY_CLUSTER_VER, parameters); #endif /* HAVE_EXT_POSTGRESQL */ } else if (is_dash_arg_prefix(argv[i],"debug",1)) { // dprintf to console dprintf_set_tool_debug("TOOL", 0); } else if (is_dash_arg_prefix(argv[i],"diagnostic",4)) { // dprintf to console diagnostic = true; } else if (is_dash_arg_prefix(argv[i], "name", 1)) { i++; if (argc <= i) { fprintf(stderr, "Error: Argument -name requires name of a remote schedd\n"); fprintf(stderr, "\t\te.g. condor_history -name submit.example.com \n"); exit(1); } g_name = argv[i]; readfromfile = false; #ifdef HAVE_EXT_POSTGRESQL remoteread = true; #endif } else if (is_dash_arg_prefix(argv[i], "pool", 1)) { i++; if (argc <= i) { fprintf(stderr, "Error: Argument -name requires name of a remote schedd\n"); fprintf(stderr, "\t\te.g. condor_history -name submit.example.com \n"); exit(1); } g_pool = argv[i]; readfromfile = false; #ifdef HAVE_EXT_POSTGRESQL remoteread = true; #endif } else { std::string ownerconst; owner = argv[i]; formatstr(ownerconst, "%s == \"%s\"", ATTR_OWNER, owner); constraint.addCustomOR(ownerconst.c_str()); #ifdef HAVE_EXT_POSTGRESQL parameters[0] = owner; queryhor.setQuery(HISTORY_OWNER_HOR, parameters); queryver.setQuery(HISTORY_OWNER_VER, parameters); #endif /* HAVE_EXT_POSTGRESQL */ } } if (i<argc) Usage(argv[0]); MyString my_constraint; constraint.makeQuery(my_constraint); if (diagnostic) { fprintf(stderr, "Using effective constraint: %s\n", my_constraint.c_str()); } if ( ! my_constraint.empty() && ParseClassAdRvalExpr( my_constraint.c_str(), constraintExpr ) ) { fprintf( stderr, "Error: could not parse constraint %s\n", my_constraint.c_str() ); exit( 1 ); } #ifdef HAVE_EXT_POSTGRESQL /* This call must happen AFTER config() is called */ if (checkDBconfig() == true && !readfromfile) { readfromfile = false; } else { readfromfile = true; } #endif /* HAVE_EXT_POSTGRESQL */ #ifdef HAVE_EXT_POSTGRESQL if(!readfromfile && !remoteread) { if(remotequill) { if (Collectors == NULL) { Collectors = CollectorList::create(); if(Collectors == NULL ) { printf("Error: Unable to get list of known collectors\n"); exit(1); } } result = Collectors->query ( quillQuery, quillList ); if(result != Q_OK) { printf("Fatal Error querying collectors\n"); exit(1); } if(quillList.MyLength() == 0) { printf("Error: Unknown quill server %s\n", quillName); exit(1); } quillList.Open(); while ((ad = quillList.Next())) { // get the address of the database dbIpAddr = dbName = queryPassword = NULL; if (!ad->LookupString(ATTR_QUILL_DB_IP_ADDR, &dbIpAddr) || !ad->LookupString(ATTR_QUILL_DB_NAME, &dbName) || !ad->LookupString(ATTR_QUILL_DB_QUERY_PASSWORD, &queryPassword) || (ad->LookupBool(ATTR_QUILL_IS_REMOTELY_QUERYABLE,flag) && !flag)) { printf("Error: The quill daemon \"%s\" is not set up " "for database queries\n", quillName); exit(1); } } } else { // they just typed 'condor_history' on the command line and want // to use quill, so get the schedd ad for the local machine if // we can, figure out the name of the schedd and the // jobqueuebirthdate Daemon schedd( DT_SCHEDD, 0, 0 ); if ( schedd.locate(Daemon::LOCATE_FULL) ) { char *scheddname = quillName; if (scheddname == NULL) { // none set explictly, look it up in the daemon ad scheddname = schedd.name(); ClassAd *daemonAd = schedd.daemonAd(); int scheddbirthdate; if(daemonAd) { if(daemonAd->LookupInteger( ATTR_JOB_QUEUE_BIRTHDATE, scheddbirthdate) ) { queryhor.setJobqueuebirthdate( (time_t)scheddbirthdate); queryver.setJobqueuebirthdate( (time_t)scheddbirthdate); } } } else { queryhor.setJobqueuebirthdate(0); queryver.setJobqueuebirthdate(0); } queryhor.setScheddname(scheddname); queryver.setScheddname(scheddname); } } dbconn = getDBConnStr(quillName,dbIpAddr,dbName,queryPassword); historySnapshot = new HistorySnapshot(dbconn); if (!customFormat) { printf ("\n\n-- Quill: %s : %s : %s\n", quillName, dbIpAddr, dbName); } queryhor.prepareQuery(); // create the query strings before sending off to historySnapshot queryver.prepareQuery(); st = historySnapshot->sendQuery(&queryhor, &queryver, longformat, false, customFormat, &mask, constraint.c_str()); //if there's a failure here and if we're not posing a query on a //remote quill daemon, we should instead query the local file if(st == QUILL_FAILURE) { printf( "-- Database at %s not reachable\n", dbIpAddr); if(!remotequill) { char *tmp_hist = param("HISTORY"); if (!customFormat) { printf( "--Failing over to the history file at %s instead --\n", tmp_hist ? tmp_hist : "(null)" ); } if(!tmp_hist) { free(tmp_hist); } readfromfile = true; } } // query history table if (historySnapshot->isHistoryEmpty()) { printf("No historical jobs in the database match your query\n"); } historySnapshot->release(); delete(historySnapshot); } #endif /* HAVE_EXT_POSTGRESQL */ if(readfromfile == true) { readHistoryFromFiles(fileisuserlog, JobHistoryFileName, my_constraint.c_str(), constraintExpr); } else { readHistoryRemote(constraintExpr); } #ifdef HAVE_EXT_POSTGRESQL if(completedsince) free(completedsince); if(parameters) free(parameters); if(dbIpAddr) free(dbIpAddr); if(dbName) free(dbName); if(queryPassword) free(queryPassword); if(dbconn) free(dbconn); #endif return 0; }
// Read the history from a single file and print it out. static void readHistoryFromFileOld(const char *JobHistoryFileName, const char* constraint, ExprTree *constraintExpr) { int EndFlag = 0; int ErrorFlag = 0; int EmptyFlag = 0; ClassAd *ad = NULL; long offset = 0; bool BOF = false; // Beginning Of File MyString buf; int flags = 0; if( !backwards ) { // Currently, the file position manipulations used in -backwards // do not work with files > 2GB on platforms with 32-bit file // offsets. flags = O_LARGEFILE; } int LogFd = safe_open_wrapper_follow(JobHistoryFileName,flags,0); if (LogFd < 0) { fprintf(stderr,"Error opening history file %s: %s\n", JobHistoryFileName,strerror(errno)); #ifdef EFBIG if( (errno == EFBIG) && backwards ) { fprintf(stderr,"The -backwards option does not support files this large.\n"); } #endif exit(1); } FILE *LogFile = fdopen(LogFd,"r"); if (!LogFile) { fprintf(stderr,"Error opening history file %s: %s\n", JobHistoryFileName,strerror(errno)); exit(1); } // In case of rotated history files, check if we have already reached the number of // matches specified by the user before reading the next file if (specifiedMatch != 0) { if (matchCount == specifiedMatch) { // Already found n number of matches, cleanup fclose(LogFile); return; } } if (backwards) { offset = findLastDelimiter(LogFile, JobHistoryFileName); } if(longformat && use_xml) { std::string out; AddClassAdXMLFileHeader(out); printf("%s\n", out.c_str()); } while(!EndFlag) { if (backwards) { // Read history file backwards if (BOF) { // If reached beginning of file break; } offset = findPrevDelimiter(LogFile, JobHistoryFileName, offset); if (offset == -1) { // Unable to match constraint break; } else if (offset != 0) { fseek(LogFile, offset, SEEK_SET); buf.readLine(LogFile); // Read one line to skip delimiter and adjust to actual offset of ad } else { // Offset set to 0 BOF = true; fseek(LogFile, offset, SEEK_SET); } } if( !( ad=new ClassAd(LogFile,"***", EndFlag, ErrorFlag, EmptyFlag) ) ){ fprintf( stderr, "Error: Out of memory\n" ); exit( 1 ); } if( ErrorFlag ) { printf( "\t*** Warning: Bad history file; skipping malformed ad(s)\n" ); ErrorFlag=0; if(ad) { delete ad; ad = NULL; } continue; } if( EmptyFlag ) { EmptyFlag=0; if(ad) { delete ad; ad = NULL; } continue; } if (!constraint || constraint[0]=='\0' || EvalBool(ad, constraintExpr)) { if (longformat) { if( use_xml ) { fPrintAdAsXML(stdout, *ad); } else { fPrintAd(stdout, *ad); } printf("\n"); } else { if (customFormat) { mask.display(stdout, ad); } else { displayJobShort(ad); } } matchCount++; // if control reached here, match has occured if (specifiedMatch != 0) { // User specified a match number if (matchCount == specifiedMatch) { // Found n number of matches, cleanup if (ad) { delete ad; ad = NULL; } fclose(LogFile); return; } } } if(ad) { delete ad; ad = NULL; } } if(longformat && use_xml) { std::string out; AddClassAdXMLFileFooter(out); printf("%s\n", out.c_str()); } fclose(LogFile); return; }
void secondPass (int argc, char *argv[]) { const char * pcolon = NULL; char *daemonname; for (int i = 1; i < argc; i++) { // omit parameters which qualify switches if( matchPrefix(argv[i],"-pool", 2) || matchPrefix(argv[i],"-direct", 4) ) { i++; continue; } if( matchPrefix(argv[i],"-subsystem", 5) ) { i++; continue; } if (matchPrefix (argv[i], "-format", 2)) { pm.registerFormat (argv[i+1], argv[i+2]); StringList attributes; ClassAd ad; if(!ad.GetExprReferences(argv[i+2],NULL,&attributes)){ fprintf( stderr, "Error: Parse error of: %s\n", argv[i+2]); exit(1); } attributes.rewind(); char const *s; while( (s=attributes.next()) ) { projList.AppendArg(s); } if (diagnose) { printf ("Arg %d --- register format [%s] for [%s]\n", i, argv[i+1], argv[i+2]); } i += 2; continue; } if (*argv[i] == '-' && (is_arg_colon_prefix(argv[i]+1, "autoformat", &pcolon, 5) || is_arg_colon_prefix(argv[i]+1, "af", &pcolon, 2)) ) { // make sure we have at least one more argument if ( !argv[i+1] || *(argv[i+1]) == '-') { fprintf( stderr, "Error: Argument %s requires " "at last one attribute parameter\n", argv[i] ); fprintf( stderr, "Use \"%s -help\" for details\n", myName ); exit( 1 ); } bool flabel = false; bool fCapV = false; bool fRaw = false; bool fheadings = false; const char * prowpre = NULL; const char * pcolpre = " "; const char * pcolsux = NULL; if (pcolon) { ++pcolon; while (*pcolon) { switch (*pcolon) { case ',': pcolsux = ","; break; case 'n': pcolsux = "\n"; break; case 'g': pcolpre = NULL; prowpre = "\n"; break; case 't': pcolpre = "\t"; break; case 'l': flabel = true; break; case 'V': fCapV = true; break; case 'r': case 'o': fRaw = true; break; case 'h': fheadings = true; break; } ++pcolon; } } pm.SetAutoSep(prowpre, pcolpre, pcolsux, "\n"); while (argv[i+1] && *(argv[i+1]) != '-') { ++i; ClassAd ad; StringList attributes; if(!ad.GetExprReferences(argv[i],NULL,&attributes)){ fprintf( stderr, "Error: Parse error of: %s\n", argv[i]); exit(1); } attributes.rewind(); char const *s; while ((s = attributes.next())) { projList.AppendArg(s); } MyString lbl = ""; int wid = 0; int opts = FormatOptionNoTruncate; if (fheadings || pm_head.Length() > 0) { const char * hd = fheadings ? argv[i] : "(expr)"; wid = 0 - (int)strlen(hd); opts = FormatOptionAutoWidth | FormatOptionNoTruncate; pm_head.Append(hd); } else if (flabel) { lbl.formatstr("%s = ", argv[i]); wid = 0; opts = 0; } lbl += fRaw ? "%r" : (fCapV ? "%V" : "%v"); if (diagnose) { printf ("Arg %d --- register format [%s] width=%d, opt=0x%x for [%s]\n", i, lbl.Value(), wid, opts, argv[i]); } pm.registerFormat(lbl.Value(), wid, opts, argv[i]); } // if autoformat list ends in a '-' without any characters after it, just eat the arg and keep going. if (i+1 < argc && '-' == (argv[i+1])[0] && 0 == (argv[i+1])[1]) { ++i; } continue; } if (is_dash_arg_colon_prefix(argv[i], "print-format", &pcolon, 2)) { if ( (i+1 >= argc) || (*(argv[i+1]) == '-' && (argv[i+1])[1] != 0)) { fprintf( stderr, "Error: Argument -print-format requires a filename argument\n"); exit( 1 ); } // hack allow -pr ! to disable use of user-default print format files. if (MATCH == strcmp(argv[i+1], "!")) { ++i; disable_user_print_files = true; continue; } ppTotalStyle = ppStyle; setPPstyle (PP_CUSTOM, i, argv[i]); setPPwidth(); ++i; // skip to the next argument. if (set_status_print_mask_from_stream(argv[i], true, &mode_constraint) < 0) { fprintf(stderr, "Error: invalid select file %s\n", argv[i]); exit (1); } if (mode_constraint) { query->addANDConstraint(mode_constraint); } using_print_format = true; // so we can hack totals. continue; } if (matchPrefix (argv[i], "-target", 5)) { i++; continue; } if (is_dash_arg_prefix(argv[i], "ads", 2)) { ++i; continue; } if( matchPrefix(argv[i], "-sort", 3) ) { i++; if ( ! noSort) { sprintf( buffer, "%s =!= UNDEFINED", argv[i] ); query->addANDConstraint( buffer ); } continue; } if (matchPrefix (argv[i], "-statistics", 6)) { i += 2; sprintf(buffer,"STATISTICS_TO_PUBLISH = \"%s\"", statistics); if (diagnose) { printf ("[%s]\n", buffer); } query->addExtraAttribute(buffer); continue; } if (matchPrefix (argv[i], "-attributes", 3) ) { // parse attributes to be selected and split them along "," StringList more_attrs(argv[i+1],","); char const *s; more_attrs.rewind(); while( (s=more_attrs.next()) ) { projList.AppendArg(s); dashAttributes.append(s); } i++; continue; } // figure out what the other parameters should do if (*argv[i] != '-') { // display extra information for diagnosis if (diagnose) { printf ("Arg %d (%s) --- adding constraint", i, argv[i]); } if( !(daemonname = get_daemon_name(argv[i])) ) { if ( (mode==MODE_SCHEDD_SUBMITTORS) && strchr(argv[i],'@') ) { // For a submittor query, it is possible that the // hostname is really a UID_DOMAIN. And there is // no requirement that UID_DOMAIN actually have // an inverse lookup in DNS... so if get_daemon_name() // fails with a fully qualified submittor lookup, just // use what we are given and do not flag an error. daemonname = strnewp(argv[i]); } else { dprintf_WriteOnErrorBuffer(stderr, true); fprintf( stderr, "%s: unknown host %s\n", argv[0], get_host_part(argv[i]) ); exit(1); } } switch (mode) { case MODE_DEFRAG_NORMAL: case MODE_STARTD_NORMAL: case MODE_STARTD_COD: #ifdef HAVE_EXT_POSTGRESQL case MODE_QUILL_NORMAL: #endif /* HAVE_EXT_POSTGRESQL */ case MODE_SCHEDD_NORMAL: case MODE_SCHEDD_SUBMITTORS: case MODE_MASTER_NORMAL: case MODE_COLLECTOR_NORMAL: case MODE_CKPT_SRVR_NORMAL: case MODE_NEGOTIATOR_NORMAL: case MODE_STORAGE_NORMAL: case MODE_ANY_NORMAL: case MODE_GENERIC_NORMAL: case MODE_STARTD_AVAIL: case MODE_OTHER: case MODE_GRID_NORMAL: case MODE_HAD_NORMAL: sprintf(buffer,"(%s==\"%s\") || (%s==\"%s\")", ATTR_NAME, daemonname, ATTR_MACHINE, daemonname ); if (diagnose) { printf ("[%s]\n", buffer); } query->addORConstraint (buffer); break; case MODE_STARTD_RUN: sprintf (buffer,"%s == \"%s\"",ATTR_REMOTE_USER,argv[i]); if (diagnose) { printf ("[%s]\n", buffer); } query->addORConstraint (buffer); break; default: fprintf(stderr,"Error: Don't know how to process %s\n",argv[i]); } delete [] daemonname; daemonname = NULL; } else if (matchPrefix (argv[i], "-constraint", 4)) { if (diagnose) { printf ("[%s]\n", argv[i+1]); } query->addANDConstraint (argv[i+1]); i++; } } }
void printCustom (ClassAd *ad) { (void) pm.display (stdout, ad, targetAd); }