2 * Copyright (c) 2010 Alistair Crooks <agc@NetBSD.org>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 #include <sys/types.h>
26 #include <sys/param.h>
27 #include <sys/socket.h>
29 #include <netinet/in.h>
43 /* get a socket and connect it to the server */
45 hkpc_connect(const char *hostname
, const int port
, const int fam
)
47 struct addrinfo hints
;
53 (void) memset(&hints
, 0, sizeof(hints
));
54 hints
.ai_family
= (fam
== 4) ? PF_INET
: PF_INET6
;
55 hints
.ai_socktype
= SOCK_STREAM
;
56 (void) snprintf(portstr
, sizeof(portstr
), "%d", port
);
57 if ((rc
= getaddrinfo(hostname
, portstr
, &hints
, &res
)) != 0) {
59 if ((rc
= getaddrinfo(hostname
, "hkp", &hints
, &res
)) != 0) {
60 (void) fprintf(stderr
, "getaddrinfo: %s",
65 if ((sock
= socket((fam
== 4) ? AF_INET
: AF_INET6
, SOCK_STREAM
, 0)) < 0) {
66 (void) fprintf(stderr
, "socket failed %d\n", errno
);
70 if ((rc
= connect(sock
, res
->ai_addr
, res
->ai_addrlen
)) < 0) {
71 (void) fprintf(stderr
, "connect failed %d\n", errno
);
77 (void) fprintf(stderr
, "connect() to %s:%d failed (rc %d)\n",
83 #define MB(x) ((x) * 1024 * 1024)
85 /* get required info from the server */
87 hkpc_get(char **info
, const char *server
, const int port
, const int family
, const char *type
, const char *userid
)
94 if ((sock
= hkpc_connect(server
, port
, family
)) < 0) {
95 (void) fprintf(stderr
, "hkpc_get: can't connect to server '%s'\n", server
);
98 cc
= snprintf(buf
, sizeof(buf
), "GET /pks/lookup?op=%s&search=%s&options=json", type
, userid
);
99 if (write(sock
, buf
, cc
) != cc
) {
100 (void) fprintf(stderr
, "hkpc_get: short write\n");
103 for (cc
= 0 ; (rc
= read(sock
, &buf
[cc
], sizeof(buf
) - cc
)) > 0 ; cc
+= rc
) {
105 *info
= calloc(1, cc
+ 1);
106 (void) memcpy(*info
, buf
, cc
);
112 /* jump over http header, then pass the json to the key-formatting function */
114 hkpc_print_key(FILE *fp
, const char *op
, const char *res
)
118 regmatch_t matches
[10];
123 (void) regcomp(&text
, "\r\n\r\n", REG_EXTENDED
);
125 if (regexec(&text
, res
, 10, matches
, 0) != 0) {
128 if (strcmp(op
, "index") == 0 || strcmp(op
, "vindex") == 0) {
129 ret
= netpgp_format_json(fp
, &res
[(int)matches
[0].rm_eo
], 1);
131 (void) fprintf(fp
, "%s\n", &res
[(int)matches
[0].rm_eo
]);