/** Function to deal with the external tool mechanism */ function put_submit_file() { include "models/buildfile.php"; // We expect GET to contain the following values: $vars = array('buildid', 'type'); foreach ($vars as $var) { if (!isset($_GET[$var]) || empty($_GET[$var])) { $response_array['status'] = 1; $response_array['description'] = 'Variable \'' . $var . '\' not set but required.'; echo json_encode($response_array); return; } } // Verify buildid. if (!is_numeric($_GET['buildid'])) { $response_array['status'] = 1; $response_array['description'] = 'Variable \'buildid\' is not numeric.'; echo json_encode($response_array); return; } // Abort early if we already have this file. $buildfile = new BuildFile(); $buildfile->BuildId = $_GET['buildid']; $buildfile->Type = htmlspecialchars(pdo_real_escape_string($_GET['type'])); $buildfile->md5 = htmlspecialchars(pdo_real_escape_string($_GET['md5'])); $buildfile->Filename = htmlspecialchars(pdo_real_escape_string($_GET['filename'])); if (!$buildfile->Insert()) { $response_array['status'] = 1; $response_array['description'] = 'Cannot insert buildfile into database. The file might already exist.'; echo json_encode($response_array); return; } // Get the ID of the project associated with this build. $row = pdo_single_row_query("SELECT projectid FROM build WHERE id = {$buildfile->BuildId}"); if (empty($row)) { $response_array['status'] = 1; $response_array['description'] = "Cannot find projectid for build #{$buildfile->BuildId}"; echo json_encode($response_array); return; } $projectid = $row[0]; // Begin writing this file to the backup directory. global $CDASH_BACKUP_DIRECTORY; $uploadDir = $CDASH_BACKUP_DIRECTORY; $ext = pathinfo($buildfile->Filename, PATHINFO_EXTENSION); $filename = $uploadDir . "/" . $buildfile->BuildId . "_" . $buildfile->md5 . ".{$ext}"; if (!($handle = fopen($filename, 'w'))) { $response_array['status'] = 1; $response_array['description'] = "Cannot open file ({$filename})"; echo json_encode($response_array); return; } // Read the data 1 KB at a time and write to the file. $putdata = fopen("php://input", "r"); while ($data = fread($putdata, 1024)) { fwrite($handle, $data); } // Close the streams. fclose($handle); fclose($putdata); // Check that the md5sum of the file matches what we were expecting. $md5sum = md5_file($filename); if ($md5sum != $buildfile->md5) { $response_array['status'] = 1; $response_array['description'] = "md5 mismatch. expected: {$buildfile->md5}, received: {$md5sum}"; unlink($filename); $buildfile->Delete(); echo json_encode($response_array); return; } global $CDASH_ASYNCHRONOUS_SUBMISSION; if ($CDASH_ASYNCHRONOUS_SUBMISSION) { // Create a new entry in the submission table for this file. $bytes = filesize($filename); $now_utc = gmdate(FMT_DATETIMESTD); pdo_query("INSERT INTO submission (filename,projectid,status,attempts,filesize,filemd5sum,created) " . "VALUES ('{$filename}','{$projectid}','0','0','{$bytes}','{$buildfile->md5}','{$now_utc}')"); // Trigger the processing loop in case it's not already running. trigger_process_submissions($projectid); } else { // synchronous processing. $handle = fopen($filename, 'r'); do_submit($handle, $projectid, $buildfile->md5, false); // The file is given a more appropriate name during do_submit, so we can // delete the old file now. unlink($filename); } // Returns the OK submission $response_array['status'] = 0; echo json_encode($response_array); }
/** Function to handle new style submissions via HTTP PUT */ function parse_put_submission($filehandler, $projectid, $expected_md5) { if (!$expected_md5) { return false; } $buildfile_row = pdo_single_row_query("SELECT * FROM buildfile WHERE md5='{$expected_md5}' LIMIT 1"); if (empty($buildfile_row)) { return false; } // Save a backup file for this submission. $row = pdo_single_row_query("SELECT name FROM project WHERE id={$projectid}"); $projectname = $row['name']; $buildid = $buildfile_row['buildid']; $row = pdo_single_row_query("SELECT name, stamp FROM build WHERE id={$buildid}"); $buildname = $row['name']; $stamp = $row['stamp']; $row = pdo_single_row_query("SELECT name FROM site WHERE id=\n (SELECT siteid FROM build WHERE id={$buildid})"); $sitename = $row['name']; global $CDASH_BACKUP_TIMEFRAME; if ($CDASH_BACKUP_TIMEFRAME == '0') { $meta_data = stream_get_meta_data($filehandler); $filename = $meta_data['uri']; } else { $filename = writeBackupFile($filehandler, '', $projectname, $buildname, $sitename, $stamp, $buildfile_row['filename']); } // Instantiate a buildfile object so we can delete it from the database // once we're done parsing it. require_once 'models/buildfile.php'; $buildfile = new BuildFile(); $buildfile->BuildId = $buildid; $buildfile->md5 = $expected_md5; // Include the handler file for this type of submission. $type = $buildfile_row['type']; $include_file = 'xml_handlers/' . $type . '_handler.php'; if (stream_resolve_include_path($include_file) === false) { add_log("No handler include file for {$type} (tried {$include_file})", 'parse_put_submission', LOG_ERR, $projectid); check_for_immediate_deletion($filename); $buildfile->Delete(); return true; } require_once $include_file; // Instantiate the handler. $className = $type . 'Handler'; if (!class_exists($className)) { add_log("No handler class for {$type}", 'parse_put_submission', LOG_ERR, $projectid); check_for_immediate_deletion($filename); $buildfile->Delete(); return true; } $handler = new $className($buildid); // Parse the file. $handler->Parse($filename); check_for_immediate_deletion($filename); $buildfile->Delete(); return true; }