gdp / apps / gcl-clone.c @ master
History | View | Annotate | Download (5.15 KB)
1 | e41ced34 | Eric Allman | /* vim: set ai sw=4 sts=4 ts=4 : */
|
---|---|---|---|
2 | |||
3 | /*
|
||
4 | ** LOG-CLONE --- clone a log --- essentially the same as doing
|
||
5 | ** a gcl-create with the same metadata but on a different
|
||
6 | ** server. We can't actually do that because the meta
|
||
7 | ** differs (notably creation time).
|
||
8 | **
|
||
9 | ** Note: it does NOT copy any data. This program is only
|
||
10 | ** intended for research purposes.
|
||
11 | **
|
||
12 | ** This is a temporary interface. Ultimately we need a log
|
||
13 | ** creation service that does reasonable log placement rather
|
||
14 | ** than having to name a specific log server.
|
||
15 | **
|
||
16 | ** ----- BEGIN LICENSE BLOCK -----
|
||
17 | ** Applications for the Global Data Plane
|
||
18 | ** From the Ubiquitous Swarm Lab, 490 Cory Hall, U.C. Berkeley.
|
||
19 | **
|
||
20 | c87dd166 | Eric Allman | ** Copyright (c) 2015-2019, Regents of the University of California.
|
21 | e41ced34 | Eric Allman | ** All rights reserved.
|
22 | **
|
||
23 | ** Permission is hereby granted, without written agreement and without
|
||
24 | ** license or royalty fees, to use, copy, modify, and distribute this
|
||
25 | ** software and its documentation for any purpose, provided that the above
|
||
26 | ** copyright notice and the following two paragraphs appear in all copies
|
||
27 | ** of this software.
|
||
28 | **
|
||
29 | ** IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
|
||
30 | ** SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST
|
||
31 | ** PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION,
|
||
32 | ** EVEN IF REGENTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||
33 | **
|
||
34 | ** REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
|
||
35 | ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||
36 | ** FOR A PARTICULAR PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION,
|
||
37 | ** IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO
|
||
38 | ** OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
|
||
39 | ** OR MODIFICATIONS.
|
||
40 | ** ----- END LICENSE BLOCK -----
|
||
41 | */
|
||
42 | |||
43 | #include <ep/ep.h> |
||
44 | #include <ep/ep_app.h> |
||
45 | #include <ep/ep_crypto.h> |
||
46 | #include <ep/ep_dbg.h> |
||
47 | #include <ep/ep_string.h> |
||
48 | #include <gdp/gdp.h> |
||
49 | |||
50 | #include <openssl/rsa.h> |
||
51 | #include <openssl/engine.h> |
||
52 | #include <openssl/pem.h> |
||
53 | |||
54 | #include <unistd.h> |
||
55 | #include <fcntl.h> |
||
56 | #include <getopt.h> |
||
57 | #include <netdb.h> |
||
58 | #include <pwd.h> |
||
59 | #include <string.h> |
||
60 | #include <sysexits.h> |
||
61 | #include <unistd.h> |
||
62 | #include <sys/stat.h> |
||
63 | |||
64 | |||
65 | // minimum secure key length
|
||
66 | #ifndef GDP_MIN_KEY_LEN
|
||
67 | # define GDP_MIN_KEY_LEN 1024 |
||
68 | #endif // GDP_MIN_KEY_LEN |
||
69 | |||
70 | static EP_DBG Dbg = EP_DBG_INIT("gdp.gcl-clone", "Clone log app"); |
||
71 | |||
72 | void
|
||
73 | usage(void)
|
||
74 | { |
||
75 | fprintf(stderr, "Usage: %s [-D dbgspec] [-G gdpd_addr]\n"
|
||
76 | "\tgcl_name logd_name ...\n"
|
||
77 | " -D set debugging flags\n"
|
||
78 | " -G IP host to contact for GDP router\n"
|
||
79 | " gcl_name is the name of the GCL to be cloned\n"
|
||
80 | " logd_name is the name of the log server(s) to host this log\n",
|
||
81 | ep_app_getprogname()); |
||
82 | exit(EX_USAGE); |
||
83 | } |
||
84 | |||
85 | |||
86 | int
|
||
87 | main(int argc, char **argv) |
||
88 | { |
||
89 | gdp_name_t gcliname; // internal name of GCL
|
||
90 | const char *gclxname = NULL; // external name of GCL |
||
91 | gdp_gcl_t *gcl = NULL;
|
||
92 | eae1d3ec | Eric Allman | gdp_gob_md_t *gmd = NULL;
|
93 | e41ced34 | Eric Allman | int opt;
|
94 | EP_STAT estat; |
||
95 | char *gdpd_addr = NULL; |
||
96 | char ebuf[100]; |
||
97 | bool show_usage = false; |
||
98 | bool quiet = false; |
||
99 | |||
100 | // collect command-line arguments
|
||
101 | while ((opt = getopt(argc, argv, "D:G:")) > 0) |
||
102 | { |
||
103 | switch (opt)
|
||
104 | { |
||
105 | case 'D': |
||
106 | ep_dbg_set(optarg); |
||
107 | break;
|
||
108 | |||
109 | case 'G': |
||
110 | gdpd_addr = optarg; |
||
111 | break;
|
||
112 | |||
113 | default:
|
||
114 | show_usage = true;
|
||
115 | break;
|
||
116 | } |
||
117 | } |
||
118 | argc -= optind; |
||
119 | argv += optind; |
||
120 | |||
121 | if (show_usage || argc-- < 2) |
||
122 | usage(); |
||
123 | |||
124 | gclxname = *argv++; |
||
125 | |||
126 | // initialize the GDP library
|
||
127 | estat = gdp_init(gdpd_addr); |
||
128 | if (!EP_STAT_ISOK(estat))
|
||
129 | { |
||
130 | ep_app_error("GDP Initialization failed");
|
||
131 | goto fail0;
|
||
132 | } |
||
133 | |||
134 | // allow thread to settle to avoid interspersed debug output
|
||
135 | ep_time_nanosleep(INT64_C(100000000));
|
||
136 | |||
137 | // open the existing log to get the metadata
|
||
138 | estat = gdp_parse_name(gclxname, gcliname); |
||
139 | 22f2276a | Eric Allman | if (EP_STAT_ISFAIL(estat))
|
140 | e41ced34 | Eric Allman | { |
141 | ep_app_error("Cannot parse source name %s: %s", gclxname,
|
||
142 | ep_stat_tostr(estat, ebuf, sizeof ebuf));
|
||
143 | exit(EX_NOINPUT); |
||
144 | } |
||
145 | |||
146 | estat = gdp_gcl_open(gcliname, GDP_MODE_RO, NULL, &gcl);
|
||
147 | if (!EP_STAT_ISOK(estat))
|
||
148 | { |
||
149 | ep_app_error("Cannot find source log %s: %s", gclxname,
|
||
150 | ep_stat_tostr(estat, ebuf, sizeof ebuf));
|
||
151 | exit(EX_NOINPUT); |
||
152 | } |
||
153 | |||
154 | // get the metadata from the source log
|
||
155 | estat = gdp_gcl_getmetadata(gcl, &gmd); |
||
156 | if (!EP_STAT_ISOK(estat))
|
||
157 | { |
||
158 | ep_app_error("Cannot fetch metadata for log %s: %s", gclxname,
|
||
159 | ep_stat_tostr(estat, ebuf, sizeof ebuf));
|
||
160 | exit(EX_NOINPUT); |
||
161 | } |
||
162 | |||
163 | // we no longer need the source log
|
||
164 | gdp_gcl_close(gcl); |
||
165 | |||
166 | for (; argc-- > 0; ++argv) |
||
167 | { |
||
168 | gdp_name_t logdiname; |
||
169 | estat = gdp_parse_name(*argv, logdiname); |
||
170 | 22f2276a | Eric Allman | if (EP_STAT_ISFAIL(estat))
|
171 | e41ced34 | Eric Allman | { |
172 | ep_app_error("Cannot parse log name %s: %s", *argv++,
|
||
173 | ep_stat_tostr(estat, ebuf, sizeof ebuf));
|
||
174 | continue;
|
||
175 | } |
||
176 | |||
177 | // do the actual create
|
||
178 | estat = gdp_gcl_create(gcliname, logdiname, gmd, &gcl); |
||
179 | if (!EP_STAT_ISOK(estat))
|
||
180 | { |
||
181 | ep_app_error("Cannot create clone on %s: %s", *argv++,
|
||
182 | ep_stat_tostr(estat, ebuf, sizeof ebuf));
|
||
183 | continue;
|
||
184 | } |
||
185 | |||
186 | // we can now close the new log as well
|
||
187 | gdp_gcl_close(gcl); |
||
188 | } |
||
189 | |||
190 | // free metadata, if set
|
||
191 | if (gmd != NULL) |
||
192 | eae1d3ec | Eric Allman | gdp_gob_md_free(gmd); |
193 | e41ced34 | Eric Allman | |
194 | fail0:
|
||
195 | // OK status can have values; hide that from the user
|
||
196 | int xstat = 0; |
||
197 | if (EP_STAT_ISOK(estat))
|
||
198 | estat = EP_STAT_OK; |
||
199 | else
|
||
200 | xstat = EX_CANTCREAT; |
||
201 | if (!quiet)
|
||
202 | 9829d4ae | Eric Allman | ep_app_message(estat, exiting with status");
|
203 | e41ced34 | Eric Allman | exit(xstat); |
204 | } |