Merge branch 'ah/stripspace-optstring'
[git] / builtin / verify-tag.c
1 /*
2  * Builtin "git verify-tag"
3  *
4  * Copyright (c) 2007 Carlos Rica <jasampler@gmail.com>
5  *
6  * Based on git-verify-tag.sh
7  */
8 #include "cache.h"
9 #include "builtin.h"
10 #include "tag.h"
11 #include "run-command.h"
12 #include <signal.h>
13 #include "parse-options.h"
14 #include "gpg-interface.h"
15
16 static const char * const verify_tag_usage[] = {
17                 N_("git verify-tag [-v | --verbose] <tag>..."),
18                 NULL
19 };
20
21 static int run_gpg_verify(const char *buf, unsigned long size, unsigned flags)
22 {
23         struct signature_check sigc;
24         int len;
25         int ret;
26
27         memset(&sigc, 0, sizeof(sigc));
28
29         len = parse_signature(buf, size);
30
31         if (size == len) {
32                 if (flags & GPG_VERIFY_VERBOSE)
33                         write_in_full(1, buf, len);
34                 return error("no signature found");
35         }
36
37         ret = check_signature(buf, len, buf + len, size - len, &sigc);
38         print_signature_buffer(&sigc, flags);
39
40         signature_check_clear(&sigc);
41         return ret;
42 }
43
44 static int verify_tag(const char *name, unsigned flags)
45 {
46         enum object_type type;
47         unsigned char sha1[20];
48         char *buf;
49         unsigned long size;
50         int ret;
51
52         if (get_sha1(name, sha1))
53                 return error("tag '%s' not found.", name);
54
55         type = sha1_object_info(sha1, NULL);
56         if (type != OBJ_TAG)
57                 return error("%s: cannot verify a non-tag object of type %s.",
58                                 name, typename(type));
59
60         buf = read_sha1_file(sha1, &type, &size);
61         if (!buf)
62                 return error("%s: unable to read file.", name);
63
64         ret = run_gpg_verify(buf, size, flags);
65
66         free(buf);
67         return ret;
68 }
69
70 static int git_verify_tag_config(const char *var, const char *value, void *cb)
71 {
72         int status = git_gpg_config(var, value, cb);
73         if (status)
74                 return status;
75         return git_default_config(var, value, cb);
76 }
77
78 int cmd_verify_tag(int argc, const char **argv, const char *prefix)
79 {
80         int i = 1, verbose = 0, had_error = 0;
81         unsigned flags = 0;
82         const struct option verify_tag_options[] = {
83                 OPT__VERBOSE(&verbose, N_("print tag contents")),
84                 OPT_BIT(0, "raw", &flags, N_("print raw gpg status output"), GPG_VERIFY_RAW),
85                 OPT_END()
86         };
87
88         git_config(git_verify_tag_config, NULL);
89
90         argc = parse_options(argc, argv, prefix, verify_tag_options,
91                              verify_tag_usage, PARSE_OPT_KEEP_ARGV0);
92         if (argc <= i)
93                 usage_with_options(verify_tag_usage, verify_tag_options);
94
95         if (verbose)
96                 flags |= GPG_VERIFY_VERBOSE;
97
98         /* sometimes the program was terminated because this signal
99          * was received in the process of writing the gpg input: */
100         signal(SIGPIPE, SIG_IGN);
101         while (i < argc)
102                 if (verify_tag(argv[i++], flags))
103                         had_error = 1;
104         return had_error;
105 }