diff options
-rw-r--r-- | Makefile.am | 2 | ||||
-rw-r--r-- | README | 2 | ||||
-rw-r--r-- | configure.ac | 3 | ||||
-rw-r--r-- | doc/Makefile.am | 19 | ||||
-rw-r--r-- | doc/eclat-associate-address.1 | 95 | ||||
-rw-r--r-- | doc/eclat.1 | 300 | ||||
-rw-r--r-- | etc/associate-address.fln | 4 | ||||
-rw-r--r-- | etc/default.fln | 6 | ||||
-rw-r--r-- | lib/forlan.c | 26 | ||||
-rw-r--r-- | lib/forlan.h | 2 | ||||
-rw-r--r-- | lib/forlanlex.l | 5 | ||||
-rw-r--r-- | src/asscaddr-cl.opt | 2 | ||||
-rw-r--r-- | src/cmdline.opt | 20 | ||||
-rw-r--r-- | src/eclat.c | 7 | ||||
-rw-r--r-- | tests/Makefile.am | 3 | ||||
-rw-r--r-- | tests/exit.at | 25 | ||||
-rw-r--r-- | tests/testsuite.at | 1 | ||||
-rw-r--r-- | tests/tforlan.c | 7 | ||||
-rw-r--r-- | tests/xml01.at | 2 |
19 files changed, 503 insertions, 28 deletions
diff --git a/Makefile.am b/Makefile.am index d78d1f6..3ec11b8 100644 --- a/Makefile.am +++ b/Makefile.am @@ -16,7 +16,7 @@ ACLOCAL_AMFLAGS = -I grecs/am -SUBDIRS = grecs lib src etc tests +SUBDIRS = grecs lib src etc tests doc .PHONY: ChangeLog ChangeLog: @@ -12,7 +12,7 @@ and has a tiny memory footprint. * Documentation -None so far. But it will be provided as soon as my time would permit. +Several man pages are ready. Most is to be written yet. * Building diff --git a/configure.ac b/configure.ac index 7c744ff..ec0d3f8 100644 --- a/configure.ac +++ b/configure.ac @@ -94,7 +94,8 @@ AM_MISSING_PROG([AUTOM4TE], [autom4te]) AC_CONFIG_FILES([Makefile lib/Makefile src/Makefile - etc/Makefile]) + etc/Makefile + doc/Makefile]) AC_OUTPUT diff --git a/doc/Makefile.am b/doc/Makefile.am new file mode 100644 index 0000000..1a230e0 --- /dev/null +++ b/doc/Makefile.am @@ -0,0 +1,19 @@ +# This file is part of Eclat +# Copyright (C) 2012 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/>. + +dist_man_MANS=\ + eclat.1\ + eclat-associate-address.1
\ No newline at end of file diff --git a/doc/eclat-associate-address.1 b/doc/eclat-associate-address.1 new file mode 100644 index 0000000..866e914 --- /dev/null +++ b/doc/eclat-associate-address.1 @@ -0,0 +1,95 @@ +.\" This file is part of Eclat +.\" Copyright (C) 2012 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 ECLAT 1 "October 1, 2012" "ECLAT" "Eclat User Reference" +.SH NAME +eclat associate-address \- associate an IP address with an instance +.SH SYNOPSIS +eclat associate-address [\fIOPTIONS\fR] \fIINSTANCE\fR \fIIP\fR + +eclat associate-address [\fIOPTIONS\fR] \fIINSTANCE\fR \fIALLOC-ID\fR + +eclat associate-address \-\-help +.SH DESCRIPTION +The +.B associate-address +command associates an Elastic IP address with an non-VPC instance or +associates a VPC Elastic IP address with an instance in your VPC. +.PP +The first argument is always the ID of the instance to operate upon. +The meaning of the second argument depends on the \fB\-\-vpc\fR command +line option. If that option is given, the second argument supplies the +allocation ID that AWS returned when you allocated the Elastic IP +address for use with Amazon VPC. Otherwise, it is the Elastic IP to +assign to the non-VPC instance. +.SH OPTIONS +.TP +\fB\-A\fR, \fB\-\-allow\-reassociation\fR +Allows an already associated address to be re-associated with the +specified instance (VPC only). +.TP +\fB\-i\fR, \fB\-\-interface\fR=\fIIFACE\fR +A network interface ID to associate with the instance (vpc only). +.TP +\fB\-p\fR, \fB\-\-private\-address\fR=\fIADDRESS\fR +Private IP address to associate with the Elastic IP address (vpc +only). +.TP +\fB\-v\fR, \fB\-\-vpc\fR +Assign VPC addresses. +.SH "OUTPUT AND RETURN VALUE" +The default output format does not display anything if the operation +succeeds. Otherwise it prints on the standard error the diagnostic +message returned by the Amazon, and returns code 1 to the shell. +.PP +The code 2 is returned if +.B eclat +is unable to recognize the response. +.SH EXAMPLES +.SS 1. +Assign an Elastic IP to the instance: +.P +.nf +.B eclat associate-address i-2ea64347 192.0.2.1 +.fi +.SS 2. +Associate an IP address with an instance in the VPC: +.P +.nf +.B eclat associate-address --vpc i-4fd2431a eipalloc-5723d13e +.fi +.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 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/doc/eclat.1 b/doc/eclat.1 new file mode 100644 index 0000000..9481e0b --- /dev/null +++ b/doc/eclat.1 @@ -0,0 +1,300 @@ +.\" This file is part of Eclat +.\" Copyright (C) 2012 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 ECLAT 1 "October 1, 2012" "ECLAT" "Eclat User Reference" +.SH NAME +eclat \- EC2 Command Line Administrator Tool +.SH SYNOPSIS +.B eclat +[\fIOPTIONS\fR] +.B command +[\fIARGS\fR] +.SH DESCRIPTION +.B Eclat +is a tool that makes it possible to manage Amazon EC2 services from +the command line. In contrast to the tools provided by Amazon itself, +.B Eclat +does not require tons of resource-consuming libraries (\fBJava +madness\fR), is very fast and efficient. +.PP +All administrative tasks are invoked through the single binary, +.BR eclat . +The task is identified by +.B command +given to it in the command line. Options preceding the command +configure the general behavior of the tool itself. Any options and +arguments following the command alter the behavior of that particular +command. +.PP +Upon invocation +.B eclat +reads its configuration file +.BR eclat.conf . +The default location of this file is determined when compiling the +package. Normally it is +.BR /etc or /usr/local/etc . +This file provides the default configuration settings for the program, +such as the location of Amazon endpoints, default availability region, +etc. See +.BR eclat.conf (5), +for a detailed description of its syntax. By default this file is +preprocessed using +.BR m4 (1). +A set of command line options is provided to control this +feature (see subsection +.BR "Preprocessor control" , +below). +.PP +Once the configuration file is read, the tool processes its command +line options. These options, when present, modify the default +settings read from the configuration file. +.PP +Finally, the program uses its +.B command +argument to identify the action to be performed. It then forms an +Amazon request using the rest arguments supplied to the command, and +sends it to the selected endpoint. +.PP +An \fBendpoint\fR is a URI of the Amazon server which is supposed to +handle the request. It is selected according to availability region, +as set in the configuration file (the \fBdefault-region\fR statement), +or in the command line (the \fB\-\-region\fR option). If neither of +these is set, the endpoint specified by the \fBdefault-endpoint\fR +configuration statement is used. +.PP +Upon completion of the action, Amazon sends back a +.BR response : +an XML document containing details about the result of the operation +performed. This document is displayed using a special format, expressed +in eclat formatting language (\fBforlan\fR for short). A set of +default formats for each request is shipped with the package. +.PP +The format to use for each particular request is selected using the +following algorithm. If the \fB\-\-format-expression\fR option is +given, its argument is treated as a +.B forlan +text to use as a format. Otherwise, if the \fB\-\-format-file\fR +option is supplied, the format to use is read from the file given as +an argument to that option. Otherwise, if the \fB\-\-format\fR option +is used, the format is searched among the user-defined formats, using +the option argument as its name. User-defined formats are declared in +the configuration file using the \fBdefine-format\fR statement. +.PP +If none of these options is given, the request +.B action name +is used to look up the default format to use. A default format is +defined in the configuration file using the \fBformat\fR statement. +.PP +Finally, if the default format is not defined as well, the format is +read from the file specified by the \fBformat-file\fR configuration +file statement. +.PP +If +.B eclat +fails to select appropriate format using this procedure, it dumps the +contents of the response on the standard output using +.BR "path notation" , +where each tag is identified by its name and the names of parent tags, +separated by dots. +.SH AUTHENTICATION +Requests are authenticated using a pair of strings: access-key and +secret-key. Their function is similar to that of username/password in +traditional authentication schemes. Both keys can be specified in the +command line, but such usage is insecure as the arguments can easily +be seen by other users (e.g. in the +.BR ps (1) +output). The preferred way is to store them in a file protected by +appropriate permissions. Each line in such a file (named for short +\fBaccess-file\fR) lists access-key and the corresponding secret-key, +separated by a semicolon. Empty lines are ignored, as well as lines +starting with a \fB#\fR sign, except as immediately followed by a +semicolon. In the latter case, such a line introduces a tag, which +can be used to identify this line. The tag consists of all the +characters following the \fB#:\fR marker up to the first whitespace +character (newline being counted as a white space). +.PP +The access file is set up using the \fBaccess-file\fR configuration +file statement. The argument to this statement is treated as a shell +globbing pattern: all files matching this pattern are attempted in +turn, until a keypair is identified, using the algorithm described +below. If an access file cannot be opened due to insufficient +privileges, no error message is issued (unless the debugging level +\fBmain.1\fR or higher is requested). This allows you to have different +access files for use by different groups of users. +.PP +If the \fB\-\-access\-key\fR option is used, its argument is the +access-key or tag to look for in the access file. Otherwise, +.B eclat +selects the first available key pair. +.SH COMMANDS +To get a help on a particular command, refer to \fBeclat-\fIcommand\fR +(1), where \fIcommand\fR is the command name. Currently the following +commands are implemented: +.BR associate-address , +.BR describe-addresses , +.BR describe-instance-status , +.BR describe-instances , +.BR describe-tags , +.BR describe-volumes , +.BR disassociate-address , +.BR get-console-output , +.BR reboot-instances , +.BR start-instances , +.BR stop-instances . +.PP +Each command understands a \fB\-\-help\fR (\fB\-h\fR) command line +option which outputs a terse summary on using this particular command. +.SH OPTIONS +.SS Selecting program mode +.TP +\fB\-E\fR +Preprocess configuration and exit. +.TP +\fB\-c\fR, \fB\-\-config\-file\fR=\fIFILE\fR +Use \fIFILE\fR instead of the default configuration. +.SS Configuration and Format Selection +.TP +\fB\-t\fR, \fB\-\-lint\fR +Parse configuration file and exit. +.TP +\fB\-F\fR, \fB\-\-format\-file\fR, \fB\-\-formfile\fR=\fIFILE\fR +Use \fIFILE\fR to format the output. +.TP +\fB\-H\fR, \fB\-\-format\fR=\fINAME\fR +Use the user-defined format \fINAME\fR for output. +.TP +\fB\-e\fR, \fB\-\-format\-expression\fR=\fIEXPR\fR +Format expression. +.SS Access credentials +.TP +\fB\-O\fR, \fB\-\-access\-key\fR=\fISTRING\fR +Set access key to use. +.TP +\fB\-W\fR, \fB\-\-secret\-key\fR=\fISTRING\fR +Set secret key to use. +.TP +\fB\-a\fR, \fB\-\-access\-file\fR=\fINAME\fR +Set access file. +.TP +\fB\-\-region\fR=\fINAME\fR +Set AWS region (availability zone). +.SS Modifiers +.TP +\fB\-s\fR, \fB\-\-sort\fR +Sort the returned XML teee prior to outputting it. +.TP +\fB\-\-ssl\fR +Use SSL (HTTPS) connection +.SS Preprocessor control +.TP +\fB\-D\fR, \fB\-\-define\fR=\fISYMBOL\fR[=\fIVALUE\fB] +Define a preprocessor symbol. +.TP +\fB\-I\fR, \fB\-\-include\-directory\fR=\fIDIR\fR +Add include directory. +.TP +\fB\-\-no\-preprocessor\fR +Disable preprocessing. +.TP +\fB\-\-preprocessor\fR=\fICOMMAND\fR +Use \fICOMMAND\fR instead of the default preprocessor. +.SS Debugging +.TP +\fB\-n\fR, \fB\-\-dry\-run\fR +Do nothing, print almost everything. +.TP +\fB\-d\fR, \fB\-\-debug\fR=\fICAT\fR[.\fILEVEL\fR] +Set debugging level. +.TP +\fB\-\-dump\-grammar\-trace\fR +Dump configuration grammar traces. +.TP +\fB\-\-dump\-lex\-trace\fR +Dump lexical analyzer traces. +.SS Help and additional information +.TP +\fB\-\-config\-help +Show configuration file summary. +.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 "EXIT CODES" +The +.B eclat +utility indicates the success or failure of the operation by issuing a +diagnostic message and returning exit code to the shell. The following +exit codes are used: +.TP +.BR 0 " (" EX_OK ")" +Success. +.TP +.BR 70 " (" EX_SOFTWARE ")" +Internal software error occurred. +.TP +.BR 64 " (" EX_USAGE ")" +Command line usage error, e.g. an unrecognized option has been +encountered, the command given does not correspond to any of the +known commands, or the like. +.TP +.BR 69 " (" EX_UNAVAILABLE ")" +Something went wrong. This is a catch-all error code, used when no +other exit code is deemed suitable. +.TP +.BR 72 " (" EX_OSFILE ")" +Cannot open configuration or format file. +.TP +.BR 77 " (" EX_NOPERM ")" +Permission denied. This code usually indicates that the configuration +file cannot be opened because of insufficient permissions. +.TP +.BR 78 " (" EX_CONFIG ")" +Error in the configuration file. +.PP +Another exit code means it has been set as a result of the +.B exit() +call in the format file. +.SH EXAMPLE +.SH "SEE ALSO" +.BR eclat.conf (5), +.BR forlan (5). +For a detailed description of a particular \fIcommand\fR, see +\fBeclat-\fIcommand\fR (1). +.SH AUTHORS +Sergey Poznyakoff +.SH "BUG REPORTS" +Report bugs to <bug-eclat@gnu.org.ua>. +.SH COPYRIGHT +Copyright \(co 2012 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/etc/associate-address.fln b/etc/associate-address.fln index 4c5d5d1..5c20a20 100644 --- a/etc/associate-address.fln +++ b/etc/associate-address.fln @@ -15,6 +15,8 @@ along with Eclat. If not, see <http://www.gnu.org/licenses/>. */ if (.AssociateAddressResponse.return) { - if (!.AssociateAddressResponse.return[true]) + if (!.AssociateAddressResponse.return[true]) { error("Return: ",.AssociateAddressResponse.return,"\n"); + exit(1); + } } diff --git a/etc/default.fln b/etc/default.fln index 2e2f690..9a6f140 100644 --- a/etc/default.fln +++ b/etc/default.fln @@ -14,9 +14,11 @@ You should have received a copy of the GNU General Public License along with Eclat. If not, see <http://www.gnu.org/licenses/>. */ -if (.Response.Errors) +if (.Response.Errors) { error("Error: ",.Response.Errors.Error.Message,"\n"); -else { + exit(1); +} else { error("Unrecognized response:\n"); dump(.); + exit(2); } diff --git a/lib/forlan.c b/lib/forlan.c index f12e00b..74b03a3 100644 --- a/lib/forlan.c +++ b/lib/forlan.c @@ -28,6 +28,7 @@ struct forlan_eval_env { struct grecs_node *top_node; struct forlan_value retval; union forlan_node *instr; + int exit_code; jmp_buf stop_buf; jmp_buf loop_buf; }; @@ -800,7 +801,7 @@ node_ident_cmp(struct grecs_node const *a, struct grecs_node const *b) } /* FIXME */ -void +static void func_sort(forlan_eval_env_t env, struct grecs_list *list) { struct forlan_value *val = list->head->data; @@ -808,7 +809,7 @@ func_sort(forlan_eval_env_t env, struct grecs_list *list) grecs_tree_sort(val->v.node, node_ident_cmp); } -void +static void func_decode(forlan_eval_env_t env, struct grecs_list *list) { struct forlan_value *val = list->head->data; @@ -835,6 +836,23 @@ func_decode(forlan_eval_env_t env, struct grecs_list *list) grecs_txtacc_free(acc); } +static void +func_exit(forlan_eval_env_t env, struct grecs_list *list) +{ + struct forlan_value *val = list->head->data; + unsigned long code; + char *p; + + code = strtoul(val->v.string, &p, 10); + if (*p || code > 255) { + err("invalid exit code \"%s\", assuming 255", + val->v.string); + code = 255; + } + env->exit_code = code; + longjmp(env->stop_buf, 1); +} + static struct forlan_function functab[] = { { "dump", forlan_value_void, "n", 1, 1, func_dump }, { "print", forlan_value_void, "", 1, -1, func_print }, @@ -842,6 +860,7 @@ static struct forlan_function functab[] = { { "parent", forlan_value_node, "n", 1, 1, func_parent }, { "sort", forlan_value_void, "n", 1, 1, func_sort }, { "decode", forlan_value_literal, "s", 1, 1, func_decode }, + { "exit", forlan_value_void, "s", 1, 1, func_exit }, { NULL } }; @@ -864,7 +883,7 @@ forlan_eval(struct forlan_eval_env *env, union forlan_node *p) f_tab[p->type].f_eval(env, p); } -void +int forlan_run(forlan_eval_env_t env, struct grecs_node *tree) { env->last = NULL; @@ -875,6 +894,7 @@ forlan_run(forlan_eval_env_t env, struct grecs_node *tree) if (setjmp(env->stop_buf) == 0) forlan_eval(env, env->parse_tree); free_value(&env->retval); + return env->exit_code; } forlan_eval_env_t diff --git a/lib/forlan.h b/lib/forlan.h index 300ef57..424cea8 100644 --- a/lib/forlan.h +++ b/lib/forlan.h @@ -191,7 +191,7 @@ struct forlan_function { struct forlan_function *forlan_find_function(const char *name); void forlan_eval(struct forlan_eval_env *env, union forlan_node *p); -void forlan_run(forlan_eval_env_t env, struct grecs_node *tree); +int forlan_run(forlan_eval_env_t env, struct grecs_node *tree); forlan_eval_env_t forlan_create_environment(union forlan_node *parse_tree, size_t varcount); void forlan_free_environment(forlan_eval_env_t env); diff --git a/lib/forlanlex.l b/lib/forlanlex.l index c3797dd..8b3d29a 100644 --- a/lib/forlanlex.l +++ b/lib/forlanlex.l @@ -66,6 +66,11 @@ IDC [a-zA-Z_0-9-] <COMMENT>\n grecs_locus_point_advance_line(grecs_current_locus_point); <COMMENT>"*"+"/" BEGIN(INITIAL); "//".* ; + /* Decimal numbers */ +[0-9][0-9]* { grecs_line_begin(); + grecs_line_add(yytext, yyleng); + yylval.string = grecs_line_finish(); + return STRING; } /* Keywords */ if return IF; else return ELSE; diff --git a/src/asscaddr-cl.opt b/src/asscaddr-cl.opt index 298fb1a..553d510 100644 --- a/src/asscaddr-cl.opt +++ b/src/asscaddr-cl.opt @@ -28,7 +28,7 @@ BEGIN END OPTION(interface,i,IFACE, - [<network interface ID to associate with an instance (vpc only)>]) + [<network interface ID to associate with the instance (vpc only)>]) BEGIN iface = optarg; END diff --git a/src/cmdline.opt b/src/cmdline.opt index 03e94dd..7726416 100644 --- a/src/cmdline.opt +++ b/src/cmdline.opt @@ -57,13 +57,7 @@ BEGIN preprocess_only = 1; END -OPTION(dry-run,n,, - [<do nothing, print almost everything>]) -BEGIN - dry_run_mode = 1; - parse_debug_level("main.1"); - parse_debug_level("curl.1"); -END +GROUP(Modifiers) OPTION(config-file,c,FILE, [<use FILE instead of the default configuration>]) @@ -71,10 +65,8 @@ BEGIN conffile = optarg; END -GROUP(Modifiers) - OPTION(region,,NAME, - [<define AWS region>]) + [<set AWS region (availability zone)>]) BEGIN struct replvar *rv = grecs_malloc(sizeof(*rv)); rv->s_ptr = ®ion_name; @@ -184,6 +176,14 @@ END GROUP(Debugging) +OPTION(dry-run,n,, + [<do nothing, print almost everything>]) +BEGIN + dry_run_mode = 1; + parse_debug_level("main.1"); + parse_debug_level("curl.1"); +END + OPTION(dump-grammar-trace,,, [<dump configuration grammar traces>]) BEGIN diff --git a/src/eclat.c b/src/eclat.c index 9464dd2..6af9eb5 100644 --- a/src/eclat.c +++ b/src/eclat.c @@ -577,7 +577,8 @@ main(int argc, char **argv) warn("no configuration file"); run_config_finish_hooks(); } else - die(EX_OSFILE, "cannot access \"%s\": %s", + die(errno == EACCES ? EX_NOPERM : EX_OSFILE, + "cannot access \"%s\": %s", conffile, strerror(errno)); env = read_format(command); @@ -630,6 +631,8 @@ main(int argc, char **argv) curl_easy_setopt(curl, CURLOPT_WRITEDATA, parser); rc = command->handler(curl, argc, argv); + if (rc) + exit(rc); curl_easy_cleanup(curl); XML_Parse(parser, "", 0, 1); if (xml_dump_file) @@ -641,7 +644,7 @@ main(int argc, char **argv) grecs_tree_sort(xmltree, node_ident_cmp); if (env) { - forlan_run(env, xmltree); + rc = forlan_run(env, xmltree); } else { grecs_print_node(xmltree, GRECS_NODE_FLAG_DEFAULT, stdout); fputc('\n', stdout); diff --git a/tests/Makefile.am b/tests/Makefile.am index 181f2f0..56a4b99 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -47,10 +47,11 @@ TESTSUITE_AT = \ describe-instances.at\ describe-tags.at\ describe-volumes.at\ - get-console-output.at\ dump01.at\ dump02.at\ + exit.at\ forlan01.at\ + get-console-output.at\ hmac01.at\ hmac02.at\ hmac03.at\ diff --git a/tests/exit.at b/tests/exit.at new file mode 100644 index 0000000..c8da624 --- /dev/null +++ b/tests/exit.at @@ -0,0 +1,25 @@ +# This file is part of Eclat -*- Autotest -*- +# Copyright (C) 2012 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/>. + +AT_SETUP(the exit function) + +AT_DATA([prog],[ +exit(25); +]) + +AT_CHECK([tforlan prog /dev/null], [25]) + +AT_CLEANUP
\ No newline at end of file diff --git a/tests/testsuite.at b/tests/testsuite.at index 1776e3b..ccb5868 100644 --- a/tests/testsuite.at +++ b/tests/testsuite.at @@ -42,6 +42,7 @@ m4_include([xml01.at]) AT_BANNER([Forlan]) m4_include([forlan01.at]) +m4_include([exit.at]) m4_include([dump01.at]) m4_include([dump02.at]) m4_include([print01.at]) diff --git a/tests/tforlan.c b/tests/tforlan.c index 403438e..64f84e1 100644 --- a/tests/tforlan.c +++ b/tests/tforlan.c @@ -176,13 +176,14 @@ main(int argc, char **argv) if (options & OPT_SORT) grecs_tree_sort(tree, node_ident_cmp); - forlan_run(env, tree); + rc = forlan_run(env, tree); grecs_tree_free(tree); - } + } else + rc = 0; forlan_free_environment(env); - return 0; + return rc; } diff --git a/tests/xml01.at b/tests/xml01.at index 01d7df4..1d650a4 100644 --- a/tests/xml01.at +++ b/tests/xml01.at @@ -25,7 +25,7 @@ AT_DATA([input],[<?xml version="1.0" encoding="UTF-8"?> <resourceId>i-00000000</resourceId> <resourceType>instance</resourceType> <key>foo</key> - <value>bar</value> +mkdir <value>bar</value> </item> <item> <resourceId>i-11111111</resourceId> |