int main( int argc, char *argv[] ) { const char *filename=0; char *pool=0; int command=-1; int i; bool use_tcp = false; bool with_ack = false; bool allow_multiple = false; param_functions *p_funcs = NULL; myDistro->Init( argc, argv ); config(); p_funcs = get_param_functions(); for( i=1; i<argc; i++ ) { if(!strcmp(argv[i],"-help")) { usage(argv[0]); exit(0); } else if(!strcmp(argv[i],"-pool")) { i++; if(!argv[i]) { fprintf(stderr,"-pool requires an argument.\n\n"); usage(argv[0]); exit(1); } pool = argv[i]; } else if(!strncmp(argv[i],"-tcp",strlen(argv[i]))) { use_tcp = true; } else if(!strncmp(argv[i],"-multiple",strlen(argv[i]))) { // We don't set allow_multiple=true by default, because // existing users (e.g. glideinWMS) have stray blank lines // in the input file. allow_multiple = true; } else if(!strcmp(argv[i],"-version")) { version(); exit(0); } else if(!strcmp(argv[i],"-debug")) { // dprintf to console Termlog = 1; p_funcs = get_param_functions(); dprintf_config ("TOOL", p_funcs); } else if(argv[i][0]!='-' || !strcmp(argv[i],"-")) { if(command==-1) { command = getCollectorCommandNum(argv[i]); if(command==-1) { fprintf(stderr,"Unknown command name %s\n\n",argv[i]); usage(argv[0]); exit(1); } } else if(!filename) { filename = argv[i]; } else { fprintf(stderr,"Extra argument: %s\n\n",argv[i]); usage(argv[0]); exit(1); } } else { fprintf(stderr,"Unknown argument: %s\n\n",argv[i]); usage(argv[0]); exit(1); } } FILE *file; ClassAdList ads; Daemon *collector; Sock *sock; switch( command ) { case UPDATE_STARTD_AD_WITH_ACK: with_ack = true; break; } if( with_ack ) { use_tcp = true; } if(!filename || !strcmp(filename,"-")) { file = stdin; filename = "(stdin)"; } else { file = safe_fopen_wrapper_follow(filename,"r"); } if(!file) { fprintf(stderr,"couldn't open %s: %s\n",filename,strerror(errno)); return 1; } while(!feof(file)) { int eof=0,error=0,empty=0; char const *delim = "\n"; if( !allow_multiple ) { delim = "***"; } ClassAd *ad = new ClassAd(file,const_cast<char *>(delim),eof,error,empty); if(error) { fprintf(stderr,"couldn't parse ClassAd in %s\n",filename); delete ad; return 1; } if( empty ) { delete ad; break; } if( !allow_multiple && ads.Length() > 0 ) { fprintf(stderr,"ERROR: failed to parse '%s' as a ClassAd attribute\n",delim); delete ad; return 1; } ads.Insert(ad); } if(ads.Length() == 0) { fprintf(stderr,"%s is empty\n",filename); return 1; } CollectorList * collectors; if ( pool ) { collector = new Daemon( DT_COLLECTOR, pool, 0 ); collectors = new CollectorList(); collectors->append (collector); } else { collectors = CollectorList::create(); } bool had_error = false; collectors->rewind(); while (collectors->next(collector)) { dprintf(D_FULLDEBUG,"locating collector %s...\n", collector->name()); if(!collector->locate()) { fprintf(stderr,"couldn't locate collector: %s\n",collector->error()); had_error = true; continue; } dprintf(D_FULLDEBUG,"collector is %s located at %s\n", collector->hostname(),collector->addr()); sock = NULL; ClassAd *ad; int success_count = 0; int failure_count = 0; ads.Rewind(); while( (ad=ads.Next()) ) { // If there's no "MyAddress", generate one.. if( !ad->Lookup( ATTR_MY_ADDRESS ) ) { MyString tmp; tmp.formatstr( "<%s:0>", my_ip_string() ); ad->Assign( ATTR_MY_ADDRESS, tmp.Value() ); } if ( use_tcp ) { if( !sock ) { sock = collector->startCommand(command,Stream::reli_sock,20); } else { // Use existing connection. sock->encode(); sock->put(command); } } else { // We must open a new UDP socket each time. delete sock; sock = collector->startCommand(command,Stream::safe_sock,20); } int result = 0; if ( sock ) { result += ad->put( *sock ); result += sock->end_of_message(); } if ( result != 2 ) { fprintf(stderr,"failed to send classad to %s\n",collector->addr()); had_error = true; failure_count++; delete sock; sock = NULL; continue; } if( with_ack ) { sock->decode(); int ok = 0; if( !sock->get(ok) || !sock->end_of_message() ) { fprintf(stderr,"failed to get ack from %s\n",collector->addr()); had_error = true; failure_count++; delete sock; sock = NULL; continue; } // ack protocol does not allow for multiple updates, // so close the socket now delete sock; sock = NULL; } success_count++; } if( sock ) { CondorVersionInfo const *ver = sock->get_peer_version(); if( !ver || ver->built_since_version(7,7,3) ) { // graceful hangup so the collector knows we are done sock->encode(); command = DC_NOP; sock->put(command); sock->end_of_message(); } delete sock; sock = NULL; } printf("Sent %d of %d ad%s to %s.\n", success_count, success_count + failure_count, success_count+failure_count == 1 ? "" : "s", collector->name()); } delete collectors; return (had_error)?1: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); }