private function _add($doc, $filename, $check_filename) { // check filename if (!$filename && is_object($doc) && isset($doc->filename)) { $filename = $doc->filename; } if (!$filename || $check_filename && !preg_match(',\\A[^.*/\\s\\000-\\017\\\\\'"][^*/\\000-\\017\\\\\'"]*\\z,', $filename)) { $this->warnings[] = "{$filename}: Bad filename."; return false; } // load document if (is_string($doc)) { $doc = (object) array("content" => $doc); } if (!isset($doc->filestore) && !isset($doc->content)) { if ($doc->docclass && $doc->docclass->load($doc)) { $doc->_content_reset = true; } else { if (!isset($doc->error_text)) { $this->warnings[] = "{$filename}: Couldn’t load document."; } else { if ($doc->error_text) { $this->warnings[] = $doc->error_text; } } return false; } } // add document to filestore list if (is_array($this->filestore) && isset($doc->filestore) && ($sha1 = Filer::binary_sha1($doc)) !== null) { $this->filestore[] = new ZipDocumentFile($filename, $doc->filestore, $sha1); return self::_add_done($doc, true); } // At this point, we will definitely create a new zipfile. // construct temporary directory if (!($tmpdir = $this->tmpdir())) { return self::_add_done($doc, false); } $zip_filename = "{$tmpdir}/"; // populate with contents of filestore list, if any if (!$this->_add_filestore()) { return self::_add_done($doc, false); } // construct subdirectories $fn = $filename; while (($p = strpos($fn, "/")) !== false) { $zip_filename .= substr($fn, 0, $p); if (!is_dir($zip_filename) && (file_exists($zip_filename) || !@mkdir($zip_filename, 0777))) { $this->warnings[] = "{$filename}: Couldn’t save document to this name."; return self::_add_done($doc, false); } $zip_filename .= "/"; $fn = substr($fn, $p + 1); } if ($fn === "") { $this->warnings[] = "{$filename}: Bad filename."; return self::_add_done($doc, false); } $zip_filename .= $fn; // store file in temporary directory if (isset($doc->filestore) && @symlink($doc->filestore, $zip_filename)) { /* OK */ } else { if (isset($doc->content)) { $trylen = file_put_contents($zip_filename, $doc->content); if ($trylen != strlen($doc->content)) { clean_tempdirs(); $trylen = file_put_contents($zip_filename, $doc->content); } if ($trylen != strlen($doc->content)) { $this->warnings[] = "{$filename}: Could not save."; return self::_add_done($doc, false); } } } // track files to pass to `zip` $zip_filename = substr($zip_filename, strlen($tmpdir) + 1); if (($p = strpos($zip_filename, "/")) !== false) { $zip_filename = substr($zip_filename, 0, $p); $this->recurse = true; } $this->files[$zip_filename] = true; // complete if (time() - $this->start_time >= 0) { set_time_limit(30); } return self::_add_done($doc, true); }
public function s3_store($doc, $docinfo, $trust_sha1 = false) { global $Opt; if (!isset($doc->content) && !$this->load_content($doc)) { return false; } if (!$trust_sha1 && Filer::binary_sha1($doc) !== sha1($doc->content, true)) { error_log("S3 upload cancelled: data claims checksum " . Filer::text_sha1($doc) . ", has checksum " . sha1($doc->content)); return false; } $s3 = self::s3_document(); $dtype = isset($doc->documentType) ? $doc->documentType : $this->dtype; $meta = array("conf" => $Opt["dbName"], "pid" => (int) $docinfo->paperId, "dtype" => (int) $dtype); if (get($doc, "filter")) { $meta["filtertype"] = (int) $doc->filter; if (get($doc, "original_sha1")) { $meta["original_sha1"] = $doc->original_sha1; } } $filename = self::s3_filename($doc); $s3->save($filename, $doc->content, $doc->mimetype, array("hotcrp" => json_encode($meta))); if ($s3->status != 200) { error_log("S3 error: POST {$filename}: {$s3->status} {$s3->status_text} " . json_encode($s3->response_headers)); } return $s3->status == 200; }