+func q(cmd, id, server string) (err error) {
+ log.Printf("document id: %s, server: %s", id, server)
+ m := map[string]string{
+ "k": "key",
+ "d": "draft",
+ "c": "cert",
+ }
+ k, ok := m[cmd]
+ if !ok {
+ err = fmt.Errorf("unknown query command: %s", cmd)
+ return
+ }
+ d, err := db.Get(k, id)
+ if err != nil {
+ if _, ok := err.(store.NotFoundError); !ok {
+ return
+ }
+ } else {
+ _, err = os.Stdout.Write(d)
+ log.Printf("found %s in local store", id)
+ return
+ }
+ resp, err := http.Get(server+"/"+k+"/"+id)
+ if err != nil {
+ return
+ }
+ d, err = readall(resp.Body)
+ if err != nil {
+ return
+ }
+ err = resp.Body.Close()
+ if err != nil {
+ return
+ }
+ _, err = os.Stdout.Write(d)
+ if resp.StatusCode != 200 {
+ err = fmt.Errorf("request failed: %s", resp.Status)
+ return
+ }
+ if err != nil {
+ return
+ }
+ log.Printf("got %s from the server", id)
+ switch cmd {
+ case "k":
+ e, err1 := key.Parse(d)
+ err = err1
+ if err != nil {
+ return
+ }
+ if id != key.Id(e) {
+ err = fmt.Errorf("id mismatch, expected %s, got %s", id, key.Id(e))
+ return
+ }
+ err = db.Set("key", id, d)
+ case "d":
+ i, s, err1 := document.Parse(d)
+ err = err1
+ if err != nil {
+ return
+ }
+ if id != document.Id(s) {
+ err = fmt.Errorf("id mismatch, expected %s, got %s", id, document.Id(s))
+ return
+ }
+ draft := i.(*document.Draft)
+ b, err1 := db.Get("key", draft.Drawer)
+ err = err1
+ if err != nil {
+ return
+ }
+ e, err1 := key.Parse(b)
+ err = err1
+ if err != nil {
+ return
+ }
+ err = document.Verify(s, openpgp.EntityList{e})
+ if err != nil {
+ return
+ }
+ err = db.Set("draft", id, d)
+ case "c":
+ i, s, err1 := document.Parse(d)
+ err = err1
+ if err != nil {
+ return
+ }
+ if id != document.Id(s) {
+ err = fmt.Errorf("id mismatch, expected %s, got %s", id, document.Id(s))
+ return
+ }
+ cert, err1 := document.ToCert(i)
+ err = err1
+ if err != nil {
+ return
+ }
+ // TODO: check serverkey
+ b, err1 := db.Get("key", cert.AuthorizedBy)
+ err = err1
+ if err != nil {
+ return
+ }
+ e, err1 := key.Parse(b)
+ err = err1
+ if err != nil {
+ return
+ }
+ err = document.Verify(s, openpgp.EntityList{e})
+ if err != nil {
+ return
+ }
+ err = db.Set("cert", id, d)
+ }
+ return
+}
+