aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2015-01-21 11:05:45 +0200
committerSergey Poznyakoff <gray@gnu.org.ua>2015-01-21 11:13:33 +0200
commit5fe918d1f84af9b1f70deb152bf20d0b8a296524 (patch)
treebf97fd6460a92260a1f3563c7583febe6ca863d1
parentf896658fd2c2c2b832536adb8af5ae6789c387a2 (diff)
downloadeclat-5fe918d1f84af9b1f70deb152bf20d0b8a296524.tar.gz
eclat-5fe918d1f84af9b1f70deb152bf20d0b8a296524.tar.bz2
Add ispeek.
* src/ispeek.c: New file. * src/ispeek-cl.opt: New file * src/Makefile.am: Add ispeek * src/io.c (dump, eclat_trace_fun): Moved to the library. (eclat_io_setup): Use eclat_set_curl_trace. * NEWS: Document ispeek. * doc/Makefile.inc: Add ispeek.1 * doc/eclat.1man: Mention ispeek(1) in the "see also" section. * doc/eclat.conf.5: Update. * doc/ispeek.1: New file. * lib/Makefile.am (libeclat_a_SOURCES): Add trace.c * lib/libeclat.h (eclat_trace_fun) (eclat_set_curl_trace): New proto. * lib/trace.c: New file.
-rw-r--r--NEWS6
-rw-r--r--doc/Makefile.inc3
-rw-r--r--doc/eclat.1man7
-rw-r--r--doc/eclat.conf.54
-rw-r--r--doc/ispeek.197
-rw-r--r--lib/Makefile.am1
-rw-r--r--lib/libeclat.h6
-rw-r--r--lib/trace.c121
-rw-r--r--src/Makefile.am8
-rw-r--r--src/io.c95
-rw-r--r--src/ispeek-cl.opt76
-rw-r--r--src/ispeek.c262
12 files changed, 585 insertions, 101 deletions
diff --git a/NEWS b/NEWS
index 3400232..c30d3fb 100644
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,4 @@
-Eclat NEWS -- history of user-visible changes. 2015-01-20
+Eclat NEWS -- history of user-visible changes. 2015-01-21
Copyright (C) 2012-2015 Sergey Poznyakoff
See the end of file for copying conditions.
@@ -55,6 +55,10 @@ If authentication provider is set to "instance-store", its argument
specifies IAM role name. The authentication credentials are then
taken from the instance store.
+* New program: ispeek
+
+Lists content of the instance store.
+
Version 1.0, 2013-12-20
diff --git a/doc/Makefile.inc b/doc/Makefile.inc
index f777f59..8d9ae4c 100644
--- a/doc/Makefile.inc
+++ b/doc/Makefile.inc
@@ -59,7 +59,8 @@ MANPAGES1=\
eclat-setsattr.1\
eclat-sg.1\
eclat-start.1\
- eclat-stop.1
+ eclat-stop.1\
+ ispeek.1
MANPAGES5=\
eclat.conf.5
diff --git a/doc/eclat.1man b/doc/eclat.1man
index 5030d7f..50cc3e2 100644
--- a/doc/eclat.1man
+++ b/doc/eclat.1man
@@ -13,7 +13,7 @@
.\"
.\" You should have received a copy of the GNU General Public License
.\" along with Eclat. If not, see <http://www.gnu.org/licenses/>.
-.TH ECLAT 1 "January 20, 2015" "ECLAT" "Eclat User Reference"
+.TH ECLAT 1 "January 21, 2015" "ECLAT" "Eclat User Reference"
.SH NAME
eclat \- EC2 Command Line Administrator Tool
.SH SYNOPSIS
@@ -530,13 +530,14 @@ These options are processed before the actual command line options.
.SH "SEE ALSO"
.BR eclat.conf (5),
.so xref.man
-.BR forlan (5).
+.BR forlan (5),
+.BR ispeek (1).
.SH AUTHORS
Sergey Poznyakoff
.SH "BUG REPORTS"
Report bugs to <bug\-eclat@gnu.org.ua>.
.SH COPYRIGHT
-Copyright \(co 2012-2014 Sergey Poznyakoff
+Copyright \(co 2012-2015 Sergey Poznyakoff
.br
.na
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
diff --git a/doc/eclat.conf.5 b/doc/eclat.conf.5
index adf3796..dd9489c 100644
--- a/doc/eclat.conf.5
+++ b/doc/eclat.conf.5
@@ -13,7 +13,7 @@
.\"
.\" You should have received a copy of the GNU General Public License
.\" along with Eclat. If not, see <http://www.gnu.org/licenses/>.
-.TH ECLAT.CONF 5 "January 20, 2015" "ECLAT" "Eclat User Reference"
+.TH ECLAT.CONF 5 "January 21, 2015" "ECLAT" "Eclat User Reference"
.SH NAME
eclat.conf \- configuration file for
.BR eclat (1).
@@ -914,7 +914,7 @@ Sergey Poznyakoff
.SH "BUG REPORTS"
Report bugs to <bug\-eclat@gnu.org.ua>.
.SH COPYRIGHT
-Copyright \(co 2012-2014 Sergey Poznyakoff
+Copyright \(co 2012-2015 Sergey Poznyakoff
.br
.na
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
diff --git a/doc/ispeek.1 b/doc/ispeek.1
new file mode 100644
index 0000000..2cfba44
--- /dev/null
+++ b/doc/ispeek.1
@@ -0,0 +1,97 @@
+.\" This file is part of Eclat -*- nroff -*-
+.\" Copyright (C) 2012-2015 Sergey Poznyakoff
+.\"
+.\" Eclat 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 3, or (at your option)
+.\" any later version.
+.\"
+.\" Eclat 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 Eclat. If not, see <http://www.gnu.org/licenses/>.
+.TH INSPEEK 1 "January 21, 2015" "INSPEEK" "Eclat User Reference"
+.SH NAME
+ispeek \- EC2 instance store lister
+.SH SYNOPSIS
+\fBispeek\fR\
+ [\fB\-Ndr\fR]\
+ [\fB\-b\fR \fIURL\fR]\
+ [\fB\-p\fR \fINUMBER\fR]\
+ [\fB\-\-no\-names\fR]\
+ [\fB\-\-base\-url=\fIURL\fR]\
+ [\fB\-\-port=\fINUMBER\fR]\
+ \fIPATH\fR\
+ [\fIKEY\fR...]
+.br
+\fBispeek\fR\
+ [\fB\-Vh\fR]\
+ [\fB\-\-help\fR]\
+ [\fB\-\-usage\fR]\
+ [\fB\-\-version\fR]
+.SH DESCRIPTION
+Lists contents of the EC2 instance store. The \fIPATH\fR argument
+specifies the pathname to list. It is relative to
+.BR http://169.254.169.254/latest .
+If \fIPATH\fR ends with a slash, it is treated as a directory and
+its content is listed. Otherwise, it is treated as a file.
+.PP
+Optional \fIKEY\fR arguments are allowed when listing content of a
+file. If one or more \fIKEY\fRs are given, the file is parsed as
+a JSON object. For each \fIKEY\fR, a corresponding value is looked
+up in the resulting object and printed on a separate line, prefixed
+with \fIKEY\fR and a colon.
+.PP
+The utility must be run from a EC2 instance.
+.SH OPTIONS
+.TP
+\fB\-N\fR, \fB\-\-no\-names
+Don't print key names. This option takes effect only if at least one
+\fIKEY\fR is given.
+.TP
+\fB\-b\fR, \fB\-\-base=\fIURL\fR
+Base URL to use, instead of
+.BR http://169.254.169.254/latest .
+.TP
+\fB\-d\fR, \fB-\-debug\fR
+Increase debugging level.
+.TP
+\fB\-p\fR, \fB\-\-port=\fINUMBER\fR
+Set remote port number, instead of the default \fB80\fR.
+.TP
+\fB\-r\fR, \fB\-\-recursive
+List directories recursively.
+.TP
+\fB\-V\fR, \fB\-\-version\fR
+Print program version.
+.TP
+\fB\-h\fR, \fB\-\-help\fR
+Give a concise help summary.
+.TP
+\fB\-\-usage\fR
+Give a short usage message.
+.SH "SEE ALSO"
+.BR eclat (1).
+.SH AUTHORS
+Sergey Poznyakoff
+.SH "BUG REPORTS"
+Report bugs to <bug\-eclat@gnu.org.ua>.
+.SH COPYRIGHT
+Copyright \(co 2012-2015 Sergey Poznyakoff
+.br
+.na
+License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
+.br
+.ad
+This is free software: you are free to change and redistribute it.
+There is NO WARRANTY, to the extent permitted by law.
+.\" Local variables:
+.\" eval: (add-hook 'write-file-hooks 'time-stamp)
+.\" time-stamp-start: ".TH [A-Z_][A-Z0-9_.-]* [0-9] \""
+.\" time-stamp-format: "%:B %:d, %:y"
+.\" time-stamp-end: "\""
+.\" time-stamp-line-limit: 20
+.\" end:
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 428de49..445d949 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -62,6 +62,7 @@ libeclat_a_SOURCES=\
sha1.h\
sha256.c\
sha256.h\
+ trace.c\
urlencode.c\
xmltree.c\
$(maps)
diff --git a/lib/libeclat.h b/lib/libeclat.h
index 2265a7b..4d6882e 100644
--- a/lib/libeclat.h
+++ b/lib/libeclat.h
@@ -16,6 +16,7 @@
#include <stddef.h>
#include <expat.h>
+#include <curl/curl.h>
#include "grecs.h"
extern const char *program_name;
@@ -50,6 +51,11 @@ void debug_printf(const char *fmt, ...);
int parse_debug_level(const char *arg);
int debug_register(char *name);
+int eclat_trace_fun(CURL *handle, curl_infotype type,
+ char *data, size_t size,
+ void *userp);
+void eclat_set_curl_trace(CURL *curl, int lev);
+
void hmac_sha1(const void *text, size_t textlen,
const void *key, size_t keylen,
diff --git a/lib/trace.c b/lib/trace.c
new file mode 100644
index 0000000..4438822
--- /dev/null
+++ b/lib/trace.c
@@ -0,0 +1,121 @@
+/* This file is part of Eclat.
+ Copyright (C) 2012-2015 Sergey Poznyakoff.
+
+ Eclat 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 3, or (at your option)
+ any later version.
+
+ Eclat 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 Eclat. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "libeclat.h"
+#include <curl/curl.h>
+
+static void
+dump(const char *text, FILE *stream, unsigned char *ptr, size_t size, int hex)
+{
+ size_t i;
+ size_t c;
+ unsigned int width = 0x10;
+
+ if (!hex)
+ /* without the hex output, we can fit more on screen */
+ width = 0x40;
+
+ fprintf(stream, "%s, %zd bytes (0x%zx)\n", text, size, size);
+
+ for (i = 0; i < size; i += width) {
+ fprintf(stream, "%04zx: ", i);
+
+ if (hex) {
+ for (c = 0; c < width; c++)
+ if (i+c < size)
+ fprintf(stream, "%02x ", ptr[i+c]);
+ else
+ fputs(" ", stream);
+ }
+
+ for (c = 0; (c < width) && (i+c < size); c++) {
+ /* check for CRLf; if found, skip past and start a
+ new line of output */
+ if (!hex && (i + c + 1 < size) &&
+ ptr[i+c] == '\r' && ptr[i+c+1] == '\n') {
+ i += (c + 2 -width);
+ break;
+ }
+ fprintf(stream, "%c",
+ isprint(ptr[i+c]) ? ptr[i+c] : '.');
+ /* check again for CRLF, to avoid an extra \n if
+ it's at width */
+ if (!hex && (i + c + 2 < size) &&
+ ptr[i+c+1] == '\r' && ptr[i+c+2] == '\n') {
+ i += (c + 3 - width);
+ break;
+ }
+ }
+ fputc('\n', stream);
+ }
+ fflush(stream);
+}
+
+int
+eclat_trace_fun(CURL *handle, curl_infotype type,
+ char *data, size_t size,
+ void *userp)
+{
+ int hex;
+ const char *text;
+
+ hex = !!userp;
+
+ switch (type) {
+ case CURLINFO_TEXT:
+ fprintf(stderr, "== Info: %s", data);
+ default: /* in case a new one is introduced to shock us */
+ return 0;
+
+ case CURLINFO_HEADER_OUT:
+ text = "=> Send header";
+ break;
+ case CURLINFO_DATA_OUT:
+ text = "=> Send data";
+ break;
+ case CURLINFO_SSL_DATA_OUT:
+ text = "=> Send SSL data";
+ break;
+ case CURLINFO_HEADER_IN:
+ text = "<= Recv header";
+ break;
+ case CURLINFO_DATA_IN:
+ text = "<= Recv data";
+ break;
+ case CURLINFO_SSL_DATA_IN:
+ text = "<= Recv SSL data";
+ break;
+ }
+
+ dump(text, stderr, (unsigned char *)data, size, hex);
+ return 0;
+}
+
+void
+eclat_set_curl_trace(CURL *curl, int lev)
+{
+ if (lev == 0)
+ curl_easy_setopt(curl, CURLOPT_VERBOSE, 0L);
+ else {
+ curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
+ if (lev > 1) {
+ curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION,
+ eclat_trace_fun);
+ if (lev > 2)
+ curl_easy_setopt(curl, CURLOPT_DEBUGDATA, 1L);
+ }
+ }
+}
diff --git a/src/Makefile.am b/src/Makefile.am
index 1c83ec2..0cd910e 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -14,7 +14,7 @@
# You should have received a copy of the GNU General Public License
# along with Eclat. If not, see <http://www.gnu.org/licenses/>.
-bin_PROGRAMS=eclat
+bin_PROGRAMS=eclat ispeek
eclat_SOURCES=\
accfile.c\
@@ -66,6 +66,10 @@ eclat_SOURCES=\
startstop.c\
util.c
+ispeek_SOURCES = \
+ ispeek.c\
+ ispeek-cl.h
+
LDADD=../lib/libeclat.a @LIBOBJS@ ../grecs/src/libgrecs.a $(CURL_LIBS) @MAPLIBS@
AM_CPPFLAGS = \
-I$(top_srcdir)/grecs/src/ -I$(top_srcdir)/lib $(CURL_CFLAGS)\
@@ -103,12 +107,14 @@ eclat_SOURCES += $(OPTFILES:.opt=.h)
BUILT_SOURCES=\
cmdline.h\
+ ispeek-cl.h\
$(OPTFILES:.opt=.h)\
comtab.man\
xref.man
EXTRA_DIST=\
cmdline.opt\
+ ispeek-cl.opt\
$(OPTFILES)\
comtab.man\
xref.man\
diff --git a/src/io.c b/src/io.c
index 366861e..2f40da7 100644
--- a/src/io.c
+++ b/src/io.c
@@ -1,5 +1,5 @@
/* This file is part of Eclat.
- Copyright (C) 2012-2014 Sergey Poznyakoff.
+ Copyright (C) 2012-2015 Sergey Poznyakoff.
Eclat is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -20,92 +20,6 @@ extern FILE *xml_dump_file;
static void
-dump(const char *text, FILE *stream, unsigned char *ptr, size_t size)
-{
- size_t i;
- size_t c;
- unsigned int width = 0x10;
- int hex = debug_level(ECLAT_DEBCAT_CURL) > 2;
-
- if (!hex)
- /* without the hex output, we can fit more on screen */
- width = 0x40;
-
- fprintf(stream, "%s, %zd bytes (0x%zx)\n", text, size, size);
-
- for (i = 0; i < size; i += width) {
- fprintf(stream, "%04zx: ", i);
-
- if (hex) {
- for (c = 0; c < width; c++)
- if (i+c < size)
- fprintf(stream, "%02x ", ptr[i+c]);
- else
- fputs(" ", stream);
- }
-
- for(c = 0; (c < width) && (i+c < size); c++) {
- /* check for CRLf; if found, skip past and start a
- new line of output */
- if (!hex && (i + c + 1 < size) &&
- ptr[i+c] == '\r' && ptr[i+c+1] == '\n') {
- i += (c + 2 -width);
- break;
- }
- fprintf(stream, "%c",
- isprint(ptr[i+c]) ? ptr[i+c] : '.');
- /* check again for CRLF, to avoid an extra \n if
- it's at width */
- if (!hex && (i + c + 2 < size) &&
- ptr[i+c+1] == '\r' && ptr[i+c+2] == '\n') {
- i += (c + 3 - width);
- break;
- }
- }
- fputc('\n', stream); /* newline */
- }
- fflush(stream);
-}
-
-int
-eclat_trace_fun(CURL *handle, curl_infotype type,
- char *data, size_t size,
- void *userp)
-{
-/* struct data *config = (struct data *)userp;*/
- const char *text;
-
- switch (type) {
- case CURLINFO_TEXT:
- fprintf(stderr, "== Info: %s", data);
- default: /* in case a new one is introduced to shock us */
- return 0;
-
- case CURLINFO_HEADER_OUT:
- text = "=> Send header";
- break;
- case CURLINFO_DATA_OUT:
- text = "=> Send data";
- break;
- case CURLINFO_SSL_DATA_OUT:
- text = "=> Send SSL data";
- break;
- case CURLINFO_HEADER_IN:
- text = "<= Recv header";
- break;
- case CURLINFO_DATA_IN:
- text = "<= Recv data";
- break;
- case CURLINFO_SSL_DATA_IN:
- text = "<= Recv SSL data";
- break;
- }
-
- dump(text, stderr, (unsigned char *)data, size);
- return 0;
-}
-
-static void
dumpxml(void *ptr, size_t realsize)
{
static int open_failed = 0;
@@ -163,12 +77,7 @@ eclat_io_setup(struct eclat_io *io, int errfatal)
}
}
- if (debug_level(ECLAT_DEBCAT_CURL)) {
- curl_easy_setopt(io->curl, CURLOPT_VERBOSE, 1L);
- if (debug_level(ECLAT_DEBCAT_CURL) > 1)
- curl_easy_setopt(io->curl, CURLOPT_DEBUGFUNCTION,
- eclat_trace_fun);
- }
+ eclat_set_curl_trace(io->curl, debug_level(ECLAT_DEBCAT_CURL));
/* Create XML parser */
io->parser = XML_ParserCreate("UTF-8");
diff --git a/src/ispeek-cl.opt b/src/ispeek-cl.opt
new file mode 100644
index 0000000..0762f06
--- /dev/null
+++ b/src/ispeek-cl.opt
@@ -0,0 +1,76 @@
+/* This file is part of Eclat.
+ Copyright (C) 2012-2015 Sergey Poznyakoff.
+
+ Eclat 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 3, or (at your option)
+ any later version.
+
+ Eclat 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 Eclat. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_GETOPT_H
+# include <getopt.h>
+#endif
+
+OPTIONS_BEGIN("ispeek",
+ [<EC2 instance store lister>],
+ [<PATH [KEY...]>],
+ [<gnu>],
+ [<copyright_year=2012-2015>],
+ [<copyright_holder=Sergey Poznyakoff>])
+
+OPTION(base,b,URL,
+ [<base URL>])
+BEGIN
+ base_url = optarg;
+END
+
+OPTION(port,p,NUMBER,
+ [<set remote port number>])
+BEGIN
+ char *p;
+
+ errno = 0;
+ port = strtol(optarg, &p, 10);
+ if (port <= 0 || port > USHRT_MAX || errno || *p)
+ die(EX_USAGE, "invalid port number");
+END
+
+OPTION(recursive,r,,
+ [<list recursively>])
+BEGIN
+ recursive = 1;
+END
+
+OPTION(no-names,N,,
+ [<don't print key names>])
+BEGIN
+ print_names = 0;
+END
+
+OPTION(debug,d,,
+ [<increase debugging level>])
+BEGIN
+ debug_category[0].level++;
+END
+
+OPTIONS_END
+
+static void
+parse_options(int *pargc, char **pargv[])
+{
+ int argc = *pargc;
+ char **argv = *pargv;
+ int index;
+
+ GETOPT(argc, argv, index)
+ *pargc -= index;
+ *pargv += index;
+}
+
diff --git a/src/ispeek.c b/src/ispeek.c
new file mode 100644
index 0000000..c2e02ab
--- /dev/null
+++ b/src/ispeek.c
@@ -0,0 +1,262 @@
+/* This file is part of Eclat.
+ Copyright (C) 2012-2015 Sergey Poznyakoff.
+
+ Eclat 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 3, or (at your option)
+ any later version.
+
+ Eclat 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 Eclat. If not, see <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+#include <sysexits.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <curl/curl.h>
+#include "grecs.h"
+#include "grecsopt.h"
+#include "wordsplit.h"
+#include "libeclat.h"
+#include "json.h"
+
+const char *base_url = "http://169.254.169.254/latest";
+int print_names = 1;
+int recursive;
+long port;
+
+static char *
+make_url(const char *url, const char *path)
+{
+ char *p;
+ size_t len = strlen(url);
+
+ while (len > 0 && url[len-1] == '/')
+ --len;
+
+ while (*path == '/')
+ ++path;
+
+ p = grecs_malloc(len + strlen(path) + 2);
+ memcpy(p, url, len);
+ p[len++] = '/';
+ strcpy(p + len, path);
+ return p;
+}
+
+static size_t
+acc_cb(void *ptr, size_t size, size_t nmemb, void *data)
+{
+ size_t realsize = size * nmemb;
+ struct grecs_txtacc *acc = data;
+
+ grecs_txtacc_grow(acc, ptr, realsize);
+
+ return realsize;
+}
+
+static void
+list(const char *path, CURL *curl, struct grecs_txtacc *acc)
+{
+ CURLcode res;
+ long http_resp;
+ char *text;
+ char *url;
+ struct wordsplit ws;
+ size_t i;
+ int isroot = strcmp(path, "/") == 0;
+
+ url = make_url(base_url, path);
+ curl_easy_setopt(curl, CURLOPT_URL, url);
+
+ res = curl_easy_perform(curl);
+ if (res != CURLE_OK)
+ die(EX_UNAVAILABLE, "CURL: %s", curl_easy_strerror(res));
+
+ res = curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_resp);
+ if (res != CURLE_OK)
+ die(EX_UNAVAILABLE, "CURL: %s", curl_easy_strerror(res));
+
+ grecs_txtacc_grow_char(acc, 0);
+ text = grecs_txtacc_finish(acc, 0);
+
+ switch (http_resp) {
+ case 200:
+ break;
+
+ case 404:
+ grecs_txtacc_free_string(acc, text);
+ return;
+
+ default:
+ die(EX_UNAVAILABLE, "CURL: got response %3d, url %s",
+ http_resp, url);
+ }
+ free(url);
+
+ ws.ws_delim = "\r\n";
+ if (wordsplit(text, &ws,
+ WRDSF_NOVAR | WRDSF_NOCMD | WRDSF_SQUEEZE_DELIMS |
+ WRDSF_DELIM | WRDSF_SHOWERR | WRDSF_ENOMEMABRT))
+ exit(EX_UNAVAILABLE);
+
+ for (i = 0; i < ws.ws_wordc; i++) {
+ printf("%s%s\n", path, ws.ws_wordv[i]);
+ if (recursive) {
+ if (isroot) {
+ char *p = make_url(path, ws.ws_wordv[i]);
+ url = make_url(p, "/");
+ free(p);
+ } else if (ws.ws_wordv[i][strlen(ws.ws_wordv[i]) - 1] == '/') {
+ url = make_url(path, ws.ws_wordv[i]);
+ } else
+ continue;
+ list(url, curl, acc);
+ free(url);
+ }
+ }
+ wordsplit_free(&ws);
+ grecs_txtacc_free_string(acc, text);
+}
+
+static void
+cat(const char *path, CURL *curl, struct grecs_txtacc *acc, char **argv)
+{
+ CURLcode res;
+ long http_resp;
+ char *text;
+ char *url;
+
+ url = make_url(base_url, path);
+ curl_easy_setopt(curl, CURLOPT_URL, url);
+
+ res = curl_easy_perform(curl);
+ if (res != CURLE_OK)
+ die(EX_UNAVAILABLE, "CURL: %s", curl_easy_strerror(res));
+
+ res = curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_resp);
+ if (res != CURLE_OK)
+ die(EX_UNAVAILABLE, "CURL: %s", curl_easy_strerror(res));
+
+ grecs_txtacc_grow_char(acc, 0);
+ text = grecs_txtacc_finish(acc, 0);
+
+ switch (http_resp) {
+ case 200:
+ break;
+
+ case 404:
+ grecs_txtacc_free_string(acc, text);
+ return;
+
+ default:
+ die(EX_UNAVAILABLE, "CURL: got response %3d, url %s",
+ http_resp, url);
+ }
+ free(url);
+
+ if (argv[0]) {
+ char *key;
+ struct json_object *obj;
+
+ obj = json_parse_string(text, strlen(text));
+ if (!obj)
+ die(EX_DATAERR,
+ "%s: near %s",
+ json_err_diag,
+ json_err_ptr);
+ while (key = *argv++) {
+ struct json_object *p;
+ char *s;
+
+ if (print_names)
+ printf("%s:", key);
+ p = json_object_lookup(obj, key);
+ if (p) {
+ switch (p->type) {
+ case json_null:
+ printf("null");
+ break;
+ case json_bool:
+ printf("%s",
+ p->v.b ? "true" : "false");
+ break;
+ case json_number:
+ printf("%e", p->v.n);
+ break;
+ case json_string:
+ putchar('"');
+ for (s = p->v.s; *s; s++) {
+ if (*s == '"' || *s == '\\')
+ putchar('\\');
+ putchar(*s);
+ }
+ putchar('"');
+ break;
+ case json_arr:
+ printf("array");
+ break;
+ case json_obj:
+ printf("object");
+ break;
+ default:
+ abort();
+ }
+ }
+ putchar('\n');
+ }
+ } else {
+ printf("%s\n", text);
+ }
+}
+
+static void
+ispeek_do(char **argv)
+{
+ CURLcode res;
+ struct grecs_txtacc *acc;
+ CURL *curl;
+ const char *path = *argv++;
+
+ curl = curl_easy_init();
+ if (!curl)
+ die(EX_UNAVAILABLE, "curl_easy_init failed");
+ if (port)
+ curl_easy_setopt(curl, CURLOPT_PORT, (long) port);
+ eclat_set_curl_trace(curl, debug_level(0));
+
+ acc = grecs_txtacc_create();
+
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, acc_cb);
+ curl_easy_setopt(curl, CURLOPT_WRITEDATA, acc);
+
+ if (path[strlen(path) - 1] == '/')
+ list(path, curl, acc);
+ else
+ cat(path, curl, acc, argv);
+ grecs_txtacc_free(acc);
+ curl_easy_cleanup(curl);
+}
+
+#include "ispeek-cl.h"
+
+int
+main(int argc, char **argv)
+{
+ set_program_name(argv[0]);
+ debug_register("main");
+ parse_options(&argc, &argv);
+ if (argc == 0)
+ die(EX_USAGE, "not enough arguments");
+ ispeek_do(argv);
+ return 0;
+}

Return to:

Send suggestions and report system problems to the System administrator.