private function create() { global $Now, $Opt; if (!($tmpdir = $this->tmpdir())) { return set_error_html("Could not create temporary directory."); } // maybe cache zipfile in docstore $zip_filename = "{$tmpdir}/_hotcrp.zip"; if (count($this->filestore) > 0 && get($Opt, "docstore") && get($Opt, "docstoreAccelRedirect")) { // calculate sha1 for zipfile contents usort($this->filestore, function ($a, $b) { return strcmp($a->filename, $b->filename); }); $sha1_input = count($this->filestore) . "\n"; foreach ($this->filestore as $f) { $sha1_input .= $f->filename . "\n" . $f->sha1 . "\n"; } if (count($this->warnings)) { $sha1_input .= "README-warnings.txt\n" . join("\n", $this->warnings) . "\n"; } $zipfile_sha1 = sha1($sha1_input, false); // look for zipfile $zfn = $Opt["docstore"] . "/tmp/" . $zipfile_sha1 . ".zip"; if (Filer::prepare_filestore($Opt["docstore"], $zfn)) { if (file_exists($zfn)) { if (($mtime = @filemtime($zfn)) < $Now - 21600) { @touch($zfn); } return $zfn; } $zip_filename = $zfn; } } // actually run zip if (!($zipcmd = get($Opt, "zipCommand", "zip"))) { return set_error_html("<code>zip</code> is not supported on this installation."); } $this->_add_filestore(); if (count($this->warnings)) { $this->add(join("\n", $this->warnings) . "\n", "README-warnings.txt"); } $opts = $this->recurse ? "-rq" : "-q"; set_time_limit(60); $out = system("cd {$tmpdir}; {$zipcmd} {$opts} '{$zip_filename}' '" . join("' '", array_keys($this->files)) . "' 2>&1", $status); if ($status != 0) { return set_error_html("<code>zip</code> returned an error. Its output: <pre>" . htmlspecialchars($out) . "</pre>"); } if (!file_exists($zip_filename)) { return set_error_html("<code>zip</code> output unreadable or empty. Its output: <pre>" . htmlspecialchars($out) . "</pre>"); } return $zip_filename; }