--- /dev/null
+#! /usr/bin/tclsh8.5
+### -*-tcl-*-
+###
+### Insert a certificate request into the database.
+###
+### (c) 2011 Mark Wooding
+###
+
+###----- Licensing notice ---------------------------------------------------
+###
+### This program is free software; you can redistribute it and/or modify
+### it under the terms of the GNU General Public License as published by
+### the Free Software Foundation; either version 2 of the License, or
+### (at your option) any later version.
+###
+### This program is distributed in the hope that it will be useful,
+### but WITHOUT ANY WARRANTY; without even the implied warranty of
+### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+### GNU General Public License for more details.
+###
+### You should have received a copy of the GNU General Public License
+### along with this program; if not, write to the Free Software Foundation,
+### Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+## Find the common utilities.
+source [file join [file dirname $argv0] "../lib/func.tcl"]
+
+## Parse the command line.
+set O(replace) false
+set usage "usage: $argv0 \[-replace\] PROFILE TAG FILE"
+for {set i 0} {$i < [llength $argv]} {incr i} {
+ switch -glob -- [lindex $argv $i] {
+ "-replace" {
+ set O(replace) true
+ }
+ "--" {
+ incr i
+ break
+ }
+ "-*" {
+ puts stderr $usage
+ exit 1
+ }
+ default {
+ break
+ }
+ }
+}
+set args [lrange $argv $i end]
+if {[llength $args] != 3} {
+ puts stderr $usage
+ exit 1
+}
+lassign $args profile tag file
+
+## Open the database.
+sqlite3 db "$CERTROOT/state/ca.db"
+
+## Do most of the work in a transaction.
+db transaction {
+ with-cleanup {
+
+ ## Check whether this tag is already taken.
+ if {!$O(replace) && [db exists {
+ SELECT 1 FROM request
+ WHERE tag = $tag AND st = 'active';
+ }]} {
+ error "request `$tag' already active"
+ }
+
+ ## Check whether the profile exists.
+ if {![db exists {
+ SELECT 1 FROM profile WHERE label = $profile;
+ }]} {
+ error "unknown profile `$profile'"
+ }
+
+ ## Copy the file away.
+ fresh-temp "$CERTROOT/tmp" tmp {
+ file copy $file $tmp
+ }
+ cleanup { file delete $tmp }
+
+ ## Get lots of information about the request.
+ set dn [req-dn $tmp]
+ set hash [req-key-hash $tmp]
+
+ ## Get an id number for the new request.
+ db eval {
+ UPDATE meta
+ SET request_seq = request_seq + 1;
+ }
+ set id [db eval {
+ SELECT request_seq FROM meta;
+ }]
+
+ ## Insert the new record into the request table.
+ db eval {
+ UPDATE request SET st = 'withdrawn' WHERE tag = $tag AND st = 'active';
+ INSERT INTO request(id, tag, dn, hash, st, profile)
+ VALUES ($id, $tag, $dn, @hash, 'active', $profile);
+ }
+
+ ## Link the file into the right place.
+ file link -hard "$CERTROOT/req/by-id/$id" $tmp
+ exec ln -sf "../by-id/$id" "$CERTROOT/req/active/$tag"
+ }
+
+ ## Issue a shiny new certificate.
+ issue-cert $id [now]
+}