void parse_param_string(const char *line, MyString &name, MyString &value, bool del_quotes) { MyString one_line; int pos=0; name = ""; value = ""; if( !line || (line[0] == '\0') ) { return; } one_line = line; one_line.chomp(); pos = one_line.FindChar('=', 0); if( pos <= 0 ) { return; } name = one_line.Substr(0, pos -1); if( pos == (one_line.Length() - 1) ) { value = ""; }else { value = one_line.Substr( pos+1, one_line.Length() - 1); } name.trim(); value.trim(); if( del_quotes ) { value = delete_quotation_marks(value.Value()); } return; }
// Remove/replace characters from the string so it can be used as an attribute name // it changes the string that is passed to it. first leading an trailing spaces // are removed, then Characters that are invalid in compatible classads // (basically anthing but [a-zA-Z0-9_]) is replaced with chReplace. // if chReplace is 0, then invalid characters are removed. // if compact is true, then multiple consecutive runs of chReplace // are changed to a single instance. // return value is the length of the resulting string. // int cleanStringForUseAsAttr(MyString &str, char chReplace/*=0*/, bool compact/*=true*/) { // have 0 mean 'remove' since we can't actually use it as a replacement char // we'll actually implement it by replacing invalid chars with spaces, // and then compacting to remove all of the spaces. if (0 == chReplace) { chReplace = ' '; compact = true; } // trim the input and replace invalid chars with chReplace str.trim(); for (int ii = 0; ii < str.Length(); ++ii) { char ch = str[ii]; if (ch == '_' || (ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z')) continue; str.setChar(ii,chReplace); } // if compact, convert runs of chReplace with a single instance, // unless chReplace is ' ', then remove them entirely. if (compact) { if (chReplace == ' ') str.replaceString(" ",""); else { MyString tmp; tmp += chReplace; tmp += chReplace; str.replaceString(tmp.Value(), tmp.Value()+1); } } str.trim(); return str.Length(); }
// Removes leading/tailing single(') or double(") quote MyString delete_quotation_marks(const char *value) { MyString fixedvalue; if( !value || (value[0] == '\0')) { return fixedvalue; } char *tmpvalue = strdup(value); char *ptr = tmpvalue; // Delete leading ones while( ( *ptr == '\"') || (*ptr == '\'' ) ) { *ptr = ' '; ptr++; } ptr = tmpvalue + strlen(tmpvalue) - 1; // Delete tailing ones while( ( ptr > tmpvalue ) && ( ( *ptr == '\"') || (*ptr == '\'' ) )) { *ptr = ' '; ptr--; } fixedvalue = tmpvalue; fixedvalue.trim(); free(tmpvalue); return fixedvalue; }
void HTTPServer::onIncomingConnection ( SOCKET sock ) { //read data from socket char buffer[1024]; int n; bzero ( buffer, sizeof ( buffer ) ); n = read ( sock,buffer,1024 ); if ( n < 0 ) { mLog ( "ERROR reading from socket", LOG_PERROR ); exit ( 1 ); } //mLog((string)"Read from buffer: " + buffer); MyString data ( buffer ); //data now contains incoming data. string firstLine; firstLine = data.substr ( 0, data.find ( "\r\n" ) ); //we should check if header is correct const string prefix ( "GET" ); const string postfix ( "HTTP/1." ); #ifdef FULLDEBUG mLog ( ( "Data received: " + data ).c_str() ); #endif if ( firstLine.find ( prefix ) != 0 // doesn't start with prefix || firstLine.find ( postfix ) != firstLine.length()-1 - postfix.length() // doesn't end with postfix || firstLine.length() < 14 ) { // length is small // header is incorrect mLog ( "Bad request: " + firstLine ); exit ( 1 ); } else { // header is correct MyString req = firstLine.substr ( 4, firstLine.find ( postfix )-4 ); req.trim(); #if defined(FULLDEBUG) mLog ( "request is:" + req ); mLog ( "first line is:" + firstLine ); #endif onUrlRequested ( req, sock ); } close ( sock ); lock(); openConnCount--; unlock(); }
int GLExecPrivSepHelper::run_script(ArgList& args,MyString &error_desc) { if (!proxy_valid_right_now()) { dprintf(D_ALWAYS, "GLExecPrivSepHelper::run_script: not invoking glexec since the proxy is not valid!\n"); error_desc += "The job proxy is not valid."; return INVALID_PROXY_RC; } /* Note that set_user_priv is a no-op if condor is running as non-root (the "usual" mode for invoking glexec) */ priv_state priv_saved = set_user_priv(); FILE* fp = my_popen(args, "r", TRUE); set_priv(priv_saved); if (fp == NULL) { dprintf(D_ALWAYS, "GLExecPrivSepHelper::run_script: " "my_popen failure on %s: errno=%d (%s)\n", args.GetArg(0), errno, strerror(errno)); return -1; } MyString str; while (str.readLine(fp, true)); priv_saved = set_user_priv(); int ret = my_pclose(fp); set_priv(priv_saved); if (ret != 0) { str.trim(); dprintf(D_ALWAYS, "GLExecPrivSepHelper::run_script: %s exited " "with status %d and following output:\n%s\n", args.GetArg(0), ret, str.Value()); error_desc.formatstr_cat("%s exited with status %d and the following output: %s", condor_basename(args.GetArg(0)), ret, str.Value()); error_desc.replaceString("\n","; "); } return ret; }
//------------------------------------------------------------------------- bool GetConfigAndAttrs( /* const */ StringList &dagFiles, bool useDagDir, MyString &configFile, StringList &attrLines, MyString &errMsg ) { bool result = true; // Note: destructor will change back to original directory. TmpDir dagDir; dagFiles.rewind(); char *dagFile; while ( (dagFile = dagFiles.next()) != NULL ) { // // Change to the DAG file's directory if necessary, and // get the filename we need to use for it from that directory. // const char * newDagFile; if ( useDagDir ) { MyString tmpErrMsg; if ( !dagDir.Cd2TmpDirFile( dagFile, tmpErrMsg ) ) { AppendError( errMsg, MyString("Unable to change to DAG directory ") + tmpErrMsg ); return false; } newDagFile = condor_basename( dagFile ); } else { newDagFile = dagFile; } StringList configFiles; // Note: destructor will close file. MultiLogFiles::FileReader reader; errMsg = reader.Open( newDagFile ); if ( errMsg != "" ) { return false; } MyString logicalLine; while ( reader.NextLogicalLine( logicalLine ) ) { if ( logicalLine != "" ) { // Note: StringList constructor removes leading // whitespace from lines. StringList tokens( logicalLine.Value(), " \t" ); tokens.rewind(); const char *firstToken = tokens.next(); if ( !strcasecmp( firstToken, "config" ) ) { // Get the value. const char *newValue = tokens.next(); if ( !newValue || !strcmp( newValue, "" ) ) { AppendError( errMsg, "Improperly-formatted " "file: value missing after keyword " "CONFIG" ); result = false; } else { // Add the value we just found to the config // files list (if it's not already in the // list -- we don't want duplicates). configFiles.rewind(); char *existingValue; bool alreadyInList = false; while ( ( existingValue = configFiles.next() ) ) { if ( !strcmp( existingValue, newValue ) ) { alreadyInList = true; } } if ( !alreadyInList ) { // Note: append copies the string here. configFiles.append( newValue ); } } //some DAG commands are needed for condor_submit_dag, too... } else if ( !strcasecmp( firstToken, "SET_JOB_ATTR" ) ) { // Strip of DAGMan-specific command name; the // rest we pass to the submit file. logicalLine.replaceString( "SET_JOB_ATTR", "" ); logicalLine.trim(); if ( logicalLine == "" ) { AppendError( errMsg, "Improperly-formatted " "file: value missing after keyword " "SET_JOB_ATTR" ); result = false; } else { attrLines.append( logicalLine.Value() ); } } } } reader.Close(); // // Check the specified config file(s) against whatever we // currently have, setting the config file if it hasn't // been set yet, flagging an error if config files conflict. // configFiles.rewind(); char * cfgFile; while ( (cfgFile = configFiles.next()) ) { MyString cfgFileMS = cfgFile; MyString tmpErrMsg; if ( MakePathAbsolute( cfgFileMS, tmpErrMsg ) ) { if ( configFile == "" ) { configFile = cfgFileMS; } else if ( configFile != cfgFileMS ) { AppendError( errMsg, MyString("Conflicting DAGMan ") + "config files specified: " + configFile + " and " + cfgFileMS ); result = false; } } else { AppendError( errMsg, tmpErrMsg ); result = false; } } // // Go back to our original directory. // MyString tmpErrMsg; if ( !dagDir.Cd2MainDir( tmpErrMsg ) ) { AppendError( errMsg, MyString("Unable to change to original directory ") + tmpErrMsg ); result = false; } } return result; }
int run_simple_docker_command(const std::string &command, const std::string &container, int timeout, CondorError &, bool ignore_output) { ArgList args; if ( ! add_docker_arg(args)) return -1; args.AppendArg( command ); args.AppendArg( container.c_str() ); MyString displayString; args.GetArgsStringForLogging( & displayString ); dprintf( D_FULLDEBUG, "Attempting to run: %s\n", displayString.c_str() ); #if 1 MyPopenTimer pgm; if (pgm.start_program( args, true, NULL, false ) < 0) { dprintf( D_ALWAYS | D_FAILURE, "Failed to run '%s'.\n", displayString.c_str() ); return -2; } if ( ! pgm.wait_and_close(timeout) || pgm.output_size() <= 0) { int error = pgm.error_code(); if( error ) { dprintf( D_ALWAYS | D_FAILURE, "Failed to read results from '%s': '%s' (%d)\n", displayString.c_str(), pgm.error_str(), error ); if (pgm.was_timeout()) { dprintf( D_ALWAYS | D_FAILURE, "Declaring a hung docker\n"); return DockerAPI::docker_hung; } } else { dprintf( D_ALWAYS | D_FAILURE, "'%s' returned nothing.\n", displayString.c_str() ); } return -3; } // On a success, Docker writes the containerID back out. MyString line; line.readLine(pgm.output()); line.chomp(); line.trim(); if (!ignore_output && line != container.c_str()) { // Didn't get back the result I expected, report the error and check to see if docker is hung. dprintf( D_ALWAYS | D_FAILURE, "Docker %s failed, printing first few lines of output.\n", command.c_str()); for (int ii = 0; ii < 10; ++ii) { if ( ! line.readLine(pgm.output(), false)) break; dprintf( D_ALWAYS | D_FAILURE, "%s\n", line.c_str() ); } return -4; } #else // Read from Docker's combined output and error streams. FILE * dockerResults = my_popen( args, "r", 1 , 0, false); if( dockerResults == NULL ) { dprintf( D_ALWAYS | D_FAILURE, "Failed to run '%s'.\n", displayString.c_str() ); return -2; } // On a success, Docker writes the containerID back out. char buffer[1024]; if( NULL == fgets( buffer, 1024, dockerResults ) ) { if( errno ) { dprintf( D_ALWAYS | D_FAILURE, "Failed to read results from '%s': '%s' (%d)\n", displayString.c_str(), strerror( errno ), errno ); } else { dprintf( D_ALWAYS | D_FAILURE, "'%s' returned nothing.\n", displayString.c_str() ); } my_pclose( dockerResults ); return -3; } size_t length = strlen( buffer ); if (!ignore_output) { if( length < 1 || strncmp( buffer, container.c_str(), length - 1 ) != 0 ) { dprintf( D_ALWAYS | D_FAILURE, "Docker %s failed, printing first few lines of output.\n", command.c_str() ); dprintf( D_ALWAYS | D_FAILURE, "%s", buffer ); while( NULL != fgets( buffer, 1024, dockerResults ) ) { dprintf( D_ALWAYS | D_FAILURE, "%s", buffer ); } my_pclose( dockerResults ); return -4; } } my_pclose( dockerResults ); #endif return 0; }
int DockerAPI::rm( const std::string & containerID, CondorError & /* err */ ) { ArgList rmArgs; if ( ! add_docker_arg(rmArgs)) return -1; rmArgs.AppendArg( "rm" ); rmArgs.AppendArg( "-f" ); // if for some reason still running, kill first rmArgs.AppendArg( "-v" ); // also remove the volume rmArgs.AppendArg( containerID.c_str() ); MyString displayString; rmArgs.GetArgsStringForLogging( & displayString ); dprintf( D_FULLDEBUG, "Attempting to run: %s\n", displayString.c_str() ); // Read from Docker's combined output and error streams. #if 1 MyPopenTimer pgm; if (pgm.start_program( rmArgs, true, NULL, false ) < 0) { dprintf( D_ALWAYS | D_FAILURE, "Failed to run '%s'.\n", displayString.c_str() ); return -2; } const char * got_output = pgm.wait_and_close(default_timeout); // On a success, Docker writes the containerID back out. MyString line; if ( ! got_output || ! line.readLine(pgm.output(), false)) { int error = pgm.error_code(); if( error ) { dprintf( D_ALWAYS | D_FAILURE, "Failed to read results from '%s': '%s' (%d)\n", displayString.c_str(), pgm.error_str(), error ); if (pgm.was_timeout()) { dprintf( D_ALWAYS | D_FAILURE, "Declaring a hung docker\n"); return docker_hung; } } else { dprintf( D_ALWAYS | D_FAILURE, "'%s' returned nothing.\n", displayString.c_str() ); } return -3; } line.chomp(); line.trim(); if (line != containerID.c_str()) { // Didn't get back the result I expected, report the error and check to see if docker is hung. return check_if_docker_offline(pgm, "Docker remove", -4); } #else FILE * dockerResults = my_popen( rmArgs, "r", 1 , 0, false); if( dockerResults == NULL ) { dprintf( D_ALWAYS | D_FAILURE, "Failed to run '%s'.\n", displayString.c_str() ); return -2; } // On a success, Docker writes the containerID back out. char buffer[1024]; if( NULL == fgets( buffer, 1024, dockerResults ) ) { if( errno ) { dprintf( D_ALWAYS | D_FAILURE, "Failed to read results from '%s': '%s' (%d)\n", displayString.c_str(), strerror( errno ), errno ); } else { dprintf( D_ALWAYS | D_FAILURE, "'%s' returned nothing.\n", displayString.c_str() ); } my_pclose( dockerResults ); return -3; } int length = strlen( buffer ); if( length < 1 || strncmp( buffer, containerID.c_str(), length - 1 ) != 0 ) { dprintf( D_ALWAYS | D_FAILURE, "Docker remove failed, printing first few lines of output.\n" ); dprintf( D_ALWAYS | D_FAILURE, "%s", buffer ); while( NULL != fgets( buffer, 1024, dockerResults ) ) { dprintf( D_ALWAYS | D_FAILURE, "%s", buffer ); } my_pclose( dockerResults ); return -4; } my_pclose( dockerResults ); #endif return 0; }
bool VirshType::parseXenDiskParam(const char *format) { if( !format || (format[0] == '\0') ) { return false; } vmprintf(D_FULLDEBUG, "format = %s\n", format); StringList working_files; find_all_files_in_dir(m_workingpath.Value(), working_files, true); StringList disk_files(format, ","); if( disk_files.isEmpty() ) { return false; } disk_files.rewind(); const char *one_disk = NULL; while( (one_disk = disk_files.next() ) != NULL ) { // found a disk file StringList single_disk_file(one_disk, ":"); int iNumParams = single_disk_file.number(); if( iNumParams < 3 || iNumParams > 4 ) { return false; } single_disk_file.rewind(); // name of a disk file MyString dfile = single_disk_file.next(); if( dfile.IsEmpty() ) { return false; } dfile.trim(); const char* tmp_base_name = condor_basename(dfile.Value()); if( !tmp_base_name ) { return false; } // Every disk file for Virsh must have full path name MyString disk_file; if( filelist_contains_file(dfile.Value(), &working_files, true) ) { // file is transferred disk_file = m_workingpath; disk_file += DIR_DELIM_CHAR; disk_file += tmp_base_name; m_has_transferred_disk_file = true; }else { // file is not transferred. if( fullpath(dfile.Value()) == false) { vmprintf(D_ALWAYS, "File(%s) for xen disk " "should have full path name\n", dfile.Value()); return false; } disk_file = dfile; } // device name MyString disk_device = single_disk_file.next(); disk_device.trim(); disk_device.lower_case(); // disk permission MyString disk_perm = single_disk_file.next(); disk_perm.trim(); if( !strcasecmp(disk_perm.Value(), "w") || !strcasecmp(disk_perm.Value(), "rw")) { // check if this disk file is writable if( check_vm_write_access_file(disk_file.Value(), false) == false ) { vmprintf(D_ALWAYS, "xen disk image file('%s') cannot be modified\n", disk_file.Value()); return false; } }else { // check if this disk file is readable if( check_vm_read_access_file(disk_file.Value(), false) == false ) { vmprintf(D_ALWAYS, "xen disk image file('%s') cannot be read\n", disk_file.Value()); return false; } } XenDisk *newdisk = new XenDisk; ASSERT(newdisk); newdisk->filename = disk_file; newdisk->device = disk_device; newdisk->permission = disk_perm; // only when a format is specified do we check if (iNumParams == 4 ) { newdisk->format = single_disk_file.next(); newdisk->format.trim(); newdisk->format.lower_case(); } m_disk_list.Append(newdisk); } if( m_disk_list.Number() == 0 ) { vmprintf(D_ALWAYS, "No valid Virsh disk\n"); return false; } return true; }