opennebula-augeas 0.6.6.pre
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/COPYING +502 -0
- data/NEWS +52 -0
- data/README.rdoc +94 -0
- data/Rakefile +93 -0
- data/ext/augeas/_augeas.c +546 -0
- data/ext/augeas/_augeas.h +48 -0
- data/ext/augeas/extconf.rb +48 -0
- data/lib/augeas.rb +393 -0
- data/tests/root/etc/group +26 -0
- data/tests/root/etc/hosts +6 -0
- data/tests/root/etc/inittab +53 -0
- data/tests/root/etc/ssh/sshd_config +2 -0
- data/tests/tc_augeas.rb +551 -0
- metadata +93 -0
data/Rakefile
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
# Rakefile: build ruby augeas bindings
|
3
|
+
#
|
4
|
+
# See AUTHORS for the list of authors
|
5
|
+
#
|
6
|
+
# Distributed under the GNU Lesser General Public License v2.1 or later.
|
7
|
+
# See COPYING for details
|
8
|
+
|
9
|
+
require 'rake/clean'
|
10
|
+
require 'rdoc/task'
|
11
|
+
require 'rake/testtask'
|
12
|
+
require 'rubygems/package_task'
|
13
|
+
|
14
|
+
GEM_NAME = 'opennebula-augeas'
|
15
|
+
GEM_VERSION = '0.6.6.pre'
|
16
|
+
EXT_CONF = 'ext/augeas/extconf.rb'
|
17
|
+
MAKEFILE = 'ext/augeas/Makefile'
|
18
|
+
AUGEAS_MODULE = 'ext/augeas/_augeas.so'
|
19
|
+
SPEC_FILE = 'opennebula-augeas.spec'
|
20
|
+
AUGEAS_SRC = AUGEAS_MODULE.gsub(/\.so$/, '.c')
|
21
|
+
|
22
|
+
# Clean - remove all intermediate files / temporary files, do not touch final product.
|
23
|
+
CLEAN.include '**/*~',
|
24
|
+
'ext/**/*.o',
|
25
|
+
MAKEFILE,
|
26
|
+
'ext/**/depend',
|
27
|
+
'ext/**/mkmf.log'
|
28
|
+
|
29
|
+
# Clobber - return to original state.
|
30
|
+
CLOBBER.include AUGEAS_MODULE
|
31
|
+
|
32
|
+
file MAKEFILE => EXT_CONF do |t|
|
33
|
+
Dir::chdir(File::dirname(EXT_CONF)) do
|
34
|
+
unless sh 'ruby', File::basename(EXT_CONF)
|
35
|
+
fail 'Failed to run extconf'
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
file AUGEAS_MODULE => [ MAKEFILE, AUGEAS_SRC ] do |t|
|
41
|
+
Dir::chdir(File::dirname(EXT_CONF)) do
|
42
|
+
unless sh "make"
|
43
|
+
fail 'make failed'
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
desc 'Build the native library'
|
49
|
+
task :build => AUGEAS_MODULE
|
50
|
+
|
51
|
+
Rake::TestTask.new(:test) do |t|
|
52
|
+
t.test_files = FileList['tests/tc_*.rb']
|
53
|
+
t.libs = ['lib', 'ext/augeas']
|
54
|
+
end
|
55
|
+
task :test => :build
|
56
|
+
|
57
|
+
|
58
|
+
RDoc::Task.new do |rd|
|
59
|
+
rd.main = "README.rdoc"
|
60
|
+
rd.rdoc_dir = "doc/site/api"
|
61
|
+
rd.rdoc_files.include("README.rdoc", "ext/**/*.[ch]","lib/**/*.rb")
|
62
|
+
end
|
63
|
+
|
64
|
+
PKG_FILES = FileList[
|
65
|
+
"Rakefile", "COPYING","README.rdoc", "NEWS",
|
66
|
+
"ext/**/*.[ch]", "lib/**/*.rb", "ext/**/MANIFEST", "ext/**/extconf.rb",
|
67
|
+
"tests/**/*",
|
68
|
+
"spec/**/*"
|
69
|
+
]
|
70
|
+
|
71
|
+
SPEC = Gem::Specification.new do |s|
|
72
|
+
s.name = GEM_NAME
|
73
|
+
s.version = GEM_VERSION
|
74
|
+
s.email = "info@opennebula.io"
|
75
|
+
s.homepage = "http://opennebula.io/"
|
76
|
+
s.summary = "Ruby bindings for augeas"
|
77
|
+
s.authors = File.read('AUTHORS').lines.grep(/^ /).map { |a| a[/[^<]+/].strip }.uniq
|
78
|
+
s.files = PKG_FILES
|
79
|
+
s.metadata = { "source_code_uri" => "https://github.com/OpenNebula/ruby-augeas" }
|
80
|
+
s.licenses = ['LGPL-2.1+']
|
81
|
+
s.required_ruby_version = '>= 1.8.7'
|
82
|
+
s.extensions = "ext/augeas/extconf.rb"
|
83
|
+
s.description = "A fork of ruby-augeas (bindings for augeas) with exceptions support."
|
84
|
+
s.add_development_dependency "rake"
|
85
|
+
s.add_development_dependency "rdoc"
|
86
|
+
end
|
87
|
+
|
88
|
+
Gem::PackageTask.new(SPEC) do |pkg|
|
89
|
+
pkg.need_tar = true
|
90
|
+
pkg.need_zip = true
|
91
|
+
end
|
92
|
+
|
93
|
+
task :default => [:build, :test]
|
@@ -0,0 +1,546 @@
|
|
1
|
+
/*
|
2
|
+
* augeas.c: Ruby bindings for augeas
|
3
|
+
*
|
4
|
+
* Copyright (C) 2008-2011 Red Hat Inc.
|
5
|
+
* Copyright (C) 2011 SUSE LINUX Products GmbH, Nuernberg, Germany.
|
6
|
+
*
|
7
|
+
* This library is free software; you can redistribute it and/or
|
8
|
+
* modify it under the terms of the GNU Lesser General Public
|
9
|
+
* License as published by the Free Software Foundation; either
|
10
|
+
* version 2.1 of the License, or (at your option) any later version.
|
11
|
+
*
|
12
|
+
* This library is distributed in the hope that it will be useful,
|
13
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
15
|
+
* Lesser General Public License for more details.
|
16
|
+
*
|
17
|
+
* You should have received a copy of the GNU Lesser General Public
|
18
|
+
* License along with this library; if not, write to the Free Software
|
19
|
+
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
20
|
+
*
|
21
|
+
* Authors: Bryan Kearney <bkearney@redhat.com>
|
22
|
+
* Ionuț Arțăriși <iartarisi@suse.cz>
|
23
|
+
*/
|
24
|
+
#include "_augeas.h"
|
25
|
+
|
26
|
+
#include <ruby.h>
|
27
|
+
#include <augeas.h>
|
28
|
+
#include <errno.h>
|
29
|
+
|
30
|
+
static VALUE c_augeas;
|
31
|
+
|
32
|
+
static augeas *aug_handle(VALUE s) {
|
33
|
+
augeas *aug;
|
34
|
+
|
35
|
+
Data_Get_Struct(s, struct augeas, aug);
|
36
|
+
if (aug == NULL) {
|
37
|
+
rb_raise(rb_eSystemCallError, "Failed to retrieve connection");
|
38
|
+
}
|
39
|
+
return aug;
|
40
|
+
}
|
41
|
+
|
42
|
+
static void augeas_free(augeas *aug) {
|
43
|
+
if (aug != NULL)
|
44
|
+
aug_close(aug);
|
45
|
+
}
|
46
|
+
|
47
|
+
/*
|
48
|
+
* call-seq:
|
49
|
+
* get(PATH) -> String
|
50
|
+
*
|
51
|
+
* Lookup the value associated with PATH
|
52
|
+
*/
|
53
|
+
VALUE augeas_get(VALUE s, VALUE path) {
|
54
|
+
augeas *aug = aug_handle(s);
|
55
|
+
const char *cpath = StringValueCStr(path);
|
56
|
+
const char *value = NULL;
|
57
|
+
|
58
|
+
int retval = aug_get(aug, cpath, &value);
|
59
|
+
|
60
|
+
if (retval == 1 && value != NULL) {
|
61
|
+
return rb_str_new(value, strlen(value));
|
62
|
+
} else {
|
63
|
+
return Qnil;
|
64
|
+
}
|
65
|
+
}
|
66
|
+
|
67
|
+
/*
|
68
|
+
* call-seq:
|
69
|
+
* exists(PATH) -> boolean
|
70
|
+
*
|
71
|
+
* Return true if there is an entry for this path, false otherwise
|
72
|
+
*/
|
73
|
+
VALUE augeas_exists(VALUE s, VALUE path) {
|
74
|
+
augeas *aug = aug_handle(s);
|
75
|
+
const char *cpath = StringValueCStr(path);
|
76
|
+
int ret = aug_get(aug, cpath, NULL);
|
77
|
+
|
78
|
+
return (ret == 1) ? Qtrue : Qfalse;
|
79
|
+
}
|
80
|
+
|
81
|
+
/*
|
82
|
+
* call-seq:
|
83
|
+
* set(PATH, VALUE) -> int
|
84
|
+
*
|
85
|
+
* Set the value associated with PATH to VALUE. VALUE is copied into the
|
86
|
+
* internal data structure. Intermediate entries are created if they don't
|
87
|
+
* exist.
|
88
|
+
*/
|
89
|
+
VALUE augeas_set(VALUE s, VALUE path, VALUE value) {
|
90
|
+
augeas *aug = aug_handle(s);
|
91
|
+
const char *cpath = StringValueCStr(path) ;
|
92
|
+
const char *cvalue = StringValueCStrOrNull(value) ;
|
93
|
+
|
94
|
+
int callValue = aug_set(aug, cpath, cvalue) ;
|
95
|
+
return INT2FIX(callValue);
|
96
|
+
}
|
97
|
+
|
98
|
+
/*
|
99
|
+
* call-seq:
|
100
|
+
* setm(BASE, SUB, VALUE) -> boolean
|
101
|
+
*
|
102
|
+
* Set multiple nodes in one operation. Find or create a node matching
|
103
|
+
* SUB by interpreting SUB as a path expression relative to each node
|
104
|
+
* matching BASE. SUB may be NULL, in which case all the nodes matching
|
105
|
+
* BASE will be modified.
|
106
|
+
*/
|
107
|
+
VALUE augeas_setm(VALUE s, VALUE base, VALUE sub, VALUE value) {
|
108
|
+
augeas *aug = aug_handle(s);
|
109
|
+
const char *cbase = StringValueCStr(base) ;
|
110
|
+
const char *csub = StringValueCStrOrNull(sub) ;
|
111
|
+
const char *cvalue = StringValueCStrOrNull(value) ;
|
112
|
+
|
113
|
+
int callValue = aug_setm(aug, cbase, csub, cvalue) ;
|
114
|
+
return INT2FIX(callValue);
|
115
|
+
}
|
116
|
+
|
117
|
+
/*
|
118
|
+
* call-seq:
|
119
|
+
* insert(PATH, LABEL, BEFORE) -> int
|
120
|
+
*
|
121
|
+
* Make LABEL a sibling of PATH by inserting it directly before or after PATH.
|
122
|
+
* The boolean BEFORE determines if LABEL is inserted before or after PATH.
|
123
|
+
*/
|
124
|
+
VALUE augeas_insert(VALUE s, VALUE path, VALUE label, VALUE before) {
|
125
|
+
augeas *aug = aug_handle(s);
|
126
|
+
const char *cpath = StringValueCStr(path) ;
|
127
|
+
const char *clabel = StringValueCStr(label) ;
|
128
|
+
|
129
|
+
int callValue = aug_insert(aug, cpath, clabel, RTEST(before));
|
130
|
+
return INT2FIX(callValue) ;
|
131
|
+
}
|
132
|
+
|
133
|
+
/*
|
134
|
+
* call-seq:
|
135
|
+
* mv(SRC, DST) -> int
|
136
|
+
*
|
137
|
+
* Move the node SRC to DST. SRC must match exactly one node in the
|
138
|
+
* tree. DST must either match exactly one node in the tree, or may not
|
139
|
+
* exist yet. If DST exists already, it and all its descendants are
|
140
|
+
* deleted. If DST does not exist yet, it and all its missing ancestors are
|
141
|
+
* created.
|
142
|
+
*/
|
143
|
+
VALUE augeas_mv(VALUE s, VALUE src, VALUE dst) {
|
144
|
+
augeas *aug = aug_handle(s);
|
145
|
+
const char *csrc = StringValueCStr(src);
|
146
|
+
const char *cdst = StringValueCStr(dst);
|
147
|
+
int r = aug_mv(aug, csrc, cdst);
|
148
|
+
|
149
|
+
return INT2FIX(r);
|
150
|
+
}
|
151
|
+
|
152
|
+
/*
|
153
|
+
* call-seq:
|
154
|
+
* rm(PATH) -> int
|
155
|
+
*
|
156
|
+
* Remove path and all its children. Returns the number of entries removed
|
157
|
+
*/
|
158
|
+
VALUE augeas_rm(VALUE s, VALUE path, VALUE sibling) {
|
159
|
+
augeas *aug = aug_handle(s);
|
160
|
+
const char *cpath = StringValueCStr(path) ;
|
161
|
+
|
162
|
+
int callValue = aug_rm(aug, cpath) ;
|
163
|
+
return INT2FIX(callValue) ;
|
164
|
+
}
|
165
|
+
|
166
|
+
/*
|
167
|
+
* call-seq:
|
168
|
+
* match(PATH) -> an_array
|
169
|
+
*
|
170
|
+
* Return all the paths that match the path expression PATH as an aray of
|
171
|
+
* strings.
|
172
|
+
* Returns an empty array if no paths were found.
|
173
|
+
*/
|
174
|
+
VALUE augeas_match(VALUE s, VALUE p) {
|
175
|
+
augeas *aug = aug_handle(s);
|
176
|
+
const char *path = StringValueCStr(p);
|
177
|
+
char **matches = NULL;
|
178
|
+
int cnt, i;
|
179
|
+
|
180
|
+
cnt = aug_match(aug, path, &matches) ;
|
181
|
+
if (cnt < 0)
|
182
|
+
return -1;
|
183
|
+
|
184
|
+
VALUE result = rb_ary_new();
|
185
|
+
for (i = 0; i < cnt; i++) {
|
186
|
+
rb_ary_push(result, rb_str_new(matches[i], strlen(matches[i])));
|
187
|
+
free(matches[i]) ;
|
188
|
+
}
|
189
|
+
free (matches) ;
|
190
|
+
|
191
|
+
return result ;
|
192
|
+
}
|
193
|
+
|
194
|
+
/*
|
195
|
+
* call-seq:
|
196
|
+
* save() -> int
|
197
|
+
*
|
198
|
+
* Write all pending changes to disk
|
199
|
+
*/
|
200
|
+
VALUE augeas_save(VALUE s) {
|
201
|
+
augeas *aug = aug_handle(s);
|
202
|
+
int callValue = aug_save(aug);
|
203
|
+
return INT2FIX(callValue);
|
204
|
+
}
|
205
|
+
|
206
|
+
/*
|
207
|
+
* call-seq:
|
208
|
+
* load() -> int
|
209
|
+
*
|
210
|
+
* Load files from disk according to the transforms under +/augeas/load+
|
211
|
+
*/
|
212
|
+
VALUE augeas_load(VALUE s) {
|
213
|
+
augeas *aug = aug_handle(s);
|
214
|
+
int callValue = aug_load(aug);
|
215
|
+
return INT2FIX(callValue);
|
216
|
+
}
|
217
|
+
|
218
|
+
/*
|
219
|
+
* call-seq:
|
220
|
+
* defvar(NAME, EXPR) -> boolean
|
221
|
+
*
|
222
|
+
* Define a variable NAME whose value is the result of evaluating EXPR. If
|
223
|
+
* a variable NAME already exists, its name will be replaced with the
|
224
|
+
* result of evaluating EXPR.
|
225
|
+
*
|
226
|
+
* If EXPR is NULL, the variable NAME will be removed if it is defined.
|
227
|
+
*
|
228
|
+
*/
|
229
|
+
VALUE augeas_defvar(VALUE s, VALUE name, VALUE expr) {
|
230
|
+
augeas *aug = aug_handle(s);
|
231
|
+
const char *cname = StringValueCStr(name);
|
232
|
+
const char *cexpr = StringValueCStrOrNull(expr);
|
233
|
+
|
234
|
+
int r = aug_defvar(aug, cname, cexpr);
|
235
|
+
|
236
|
+
return (r < 0) ? Qfalse : Qtrue;
|
237
|
+
}
|
238
|
+
|
239
|
+
/*
|
240
|
+
* call-seq:
|
241
|
+
* defnode(NAME, EXPR, VALUE) -> boolean
|
242
|
+
*
|
243
|
+
* Define a variable NAME whose value is the result of evaluating EXPR,
|
244
|
+
* which must be non-NULL and evaluate to a nodeset. If a variable NAME
|
245
|
+
* already exists, its name will be replaced with the result of evaluating
|
246
|
+
* EXPR.
|
247
|
+
*
|
248
|
+
* If EXPR evaluates to an empty nodeset, a node is created, equivalent to
|
249
|
+
* calling AUG_SET(AUG, EXPR, VALUE) and NAME will be the nodeset containing
|
250
|
+
* that single node.
|
251
|
+
*
|
252
|
+
* Returns +false+ if +aug_defnode+ fails, and the number of nodes in the
|
253
|
+
* nodeset on success.
|
254
|
+
*/
|
255
|
+
VALUE augeas_defnode(VALUE s, VALUE name, VALUE expr, VALUE value) {
|
256
|
+
augeas *aug = aug_handle(s);
|
257
|
+
const char *cname = StringValueCStr(name);
|
258
|
+
const char *cexpr = StringValueCStrOrNull(expr);
|
259
|
+
const char *cvalue = StringValueCStrOrNull(value);
|
260
|
+
|
261
|
+
/* FIXME: Figure out a way to return created, maybe accept a block
|
262
|
+
that gets run when created == 1 ? */
|
263
|
+
int r = aug_defnode(aug, cname, cexpr, cvalue, NULL);
|
264
|
+
|
265
|
+
return (r < 0) ? Qfalse : INT2NUM(r);
|
266
|
+
}
|
267
|
+
|
268
|
+
VALUE augeas_init(VALUE m, VALUE r, VALUE l, VALUE f) {
|
269
|
+
unsigned int flags = NUM2UINT(f);
|
270
|
+
const char *root = StringValueCStrOrNull(r);
|
271
|
+
const char *loadpath = StringValueCStrOrNull(l);
|
272
|
+
augeas *aug = NULL;
|
273
|
+
|
274
|
+
aug = aug_init(root, loadpath, flags);
|
275
|
+
if (aug == NULL) {
|
276
|
+
rb_raise(rb_eSystemCallError, "Failed to initialize Augeas (%d)", errno);
|
277
|
+
}
|
278
|
+
return Data_Wrap_Struct(c_augeas, NULL, augeas_free, aug);
|
279
|
+
}
|
280
|
+
|
281
|
+
VALUE augeas_close (VALUE s) {
|
282
|
+
augeas *aug = aug_handle(s);
|
283
|
+
|
284
|
+
aug_close(aug);
|
285
|
+
DATA_PTR(s) = NULL;
|
286
|
+
|
287
|
+
return Qnil;
|
288
|
+
}
|
289
|
+
|
290
|
+
static void hash_set(VALUE hash, const char *sym, VALUE v) {
|
291
|
+
rb_hash_aset(hash, ID2SYM(rb_intern(sym)), v);
|
292
|
+
}
|
293
|
+
|
294
|
+
/*
|
295
|
+
* call-seq:
|
296
|
+
* error -> HASH
|
297
|
+
*
|
298
|
+
* Retrieve details about the last error encountered and return those
|
299
|
+
* details in a HASH with the following entries:
|
300
|
+
* - :code error code from +aug_error+
|
301
|
+
* - :message error message from +aug_error_message+
|
302
|
+
* - :minor minor error message from +aug_minor_error_message+
|
303
|
+
* - :details error details from +aug_error_details+
|
304
|
+
*/
|
305
|
+
VALUE augeas_error(VALUE s) {
|
306
|
+
augeas *aug = aug_handle(s);
|
307
|
+
int code;
|
308
|
+
const char *msg = NULL;
|
309
|
+
VALUE result;
|
310
|
+
|
311
|
+
result = rb_hash_new();
|
312
|
+
|
313
|
+
code = aug_error(aug);
|
314
|
+
hash_set(result, "code", INT2NUM(code));
|
315
|
+
|
316
|
+
msg = aug_error_message(aug);
|
317
|
+
if (msg != NULL)
|
318
|
+
hash_set(result, "message", rb_str_new2(msg));
|
319
|
+
|
320
|
+
msg = aug_error_minor_message(aug);
|
321
|
+
if (msg != NULL)
|
322
|
+
hash_set(result, "minor", rb_str_new2(msg));
|
323
|
+
|
324
|
+
msg = aug_error_details(aug);
|
325
|
+
if (msg != NULL)
|
326
|
+
hash_set(result, "details", rb_str_new2(msg));
|
327
|
+
|
328
|
+
return result;
|
329
|
+
}
|
330
|
+
|
331
|
+
static void hash_set_range(VALUE hash, const char *sym,
|
332
|
+
unsigned int start, unsigned int end) {
|
333
|
+
VALUE r;
|
334
|
+
|
335
|
+
r = rb_range_new(INT2NUM(start), INT2NUM(end), 0);
|
336
|
+
hash_set(hash, sym, r);
|
337
|
+
}
|
338
|
+
|
339
|
+
VALUE augeas_span(VALUE s, VALUE path) {
|
340
|
+
augeas *aug = aug_handle(s);
|
341
|
+
char *cpath = StringValueCStr(path);
|
342
|
+
char *filename = NULL;
|
343
|
+
unsigned int label_start, label_end, value_start, value_end,
|
344
|
+
span_start, span_end;
|
345
|
+
int r;
|
346
|
+
VALUE result;
|
347
|
+
|
348
|
+
r = aug_span(aug, cpath,
|
349
|
+
&filename,
|
350
|
+
&label_start, &label_end,
|
351
|
+
&value_start, &value_end,
|
352
|
+
&span_start, &span_end);
|
353
|
+
|
354
|
+
result = rb_hash_new();
|
355
|
+
|
356
|
+
if (r == 0) {
|
357
|
+
hash_set(result, "filename", rb_str_new2(filename));
|
358
|
+
hash_set_range(result, "label", label_start, label_end);
|
359
|
+
hash_set_range(result, "value", value_start, value_end);
|
360
|
+
hash_set_range(result, "span", span_start, span_end);
|
361
|
+
}
|
362
|
+
|
363
|
+
free(filename);
|
364
|
+
|
365
|
+
return result;
|
366
|
+
}
|
367
|
+
|
368
|
+
/*
|
369
|
+
* call-seq:
|
370
|
+
* srun(COMMANDS) -> [int, String]
|
371
|
+
*
|
372
|
+
* Run one or more newline-separated commands, returning their output.
|
373
|
+
*
|
374
|
+
* Returns:
|
375
|
+
* an array where the first element is the number of executed commands on
|
376
|
+
* success, -1 on failure, and -2 if a 'quit' command was encountered.
|
377
|
+
* The second element is a string of the output from all commands.
|
378
|
+
*/
|
379
|
+
VALUE augeas_srun(VALUE s, VALUE text) {
|
380
|
+
augeas *aug = aug_handle(s);
|
381
|
+
const char *ctext = StringValueCStr(text);
|
382
|
+
|
383
|
+
struct memstream ms;
|
384
|
+
__aug_init_memstream(&ms);
|
385
|
+
|
386
|
+
int r = aug_srun(aug, ms.stream, ctext);
|
387
|
+
__aug_close_memstream(&ms);
|
388
|
+
|
389
|
+
VALUE result = rb_ary_new();
|
390
|
+
rb_ary_push(result, INT2NUM(r));
|
391
|
+
rb_ary_push(result, rb_str_new2(ms.buf));
|
392
|
+
|
393
|
+
free(ms.buf);
|
394
|
+
return result;
|
395
|
+
}
|
396
|
+
|
397
|
+
/*
|
398
|
+
* call-seq:
|
399
|
+
* label(PATH) -> String
|
400
|
+
*
|
401
|
+
* Lookup the label associated with PATH
|
402
|
+
*/
|
403
|
+
VALUE augeas_label(VALUE s, VALUE path) {
|
404
|
+
augeas *aug = aug_handle(s);
|
405
|
+
const char *cpath = StringValueCStr(path);
|
406
|
+
const char *label = NULL;
|
407
|
+
|
408
|
+
aug_label(aug, cpath, &label);
|
409
|
+
if (label != NULL) {
|
410
|
+
return rb_str_new(label, strlen(label)) ;
|
411
|
+
} else {
|
412
|
+
return Qnil;
|
413
|
+
}
|
414
|
+
}
|
415
|
+
|
416
|
+
/*
|
417
|
+
* call-seq:
|
418
|
+
* rename(SRC, LABEL) -> int
|
419
|
+
*
|
420
|
+
* Rename the label of all nodes matching SRC to LABEL.
|
421
|
+
*
|
422
|
+
* Returns +false+ if +aug_rename+ fails, and the number of nodes renamed
|
423
|
+
* on success.
|
424
|
+
*/
|
425
|
+
VALUE augeas_rename(VALUE s, VALUE src, VALUE label) {
|
426
|
+
augeas *aug = aug_handle(s);
|
427
|
+
const char *csrc = StringValueCStr(src);
|
428
|
+
const char *clabel = StringValueCStr(label);
|
429
|
+
int r = aug_rename(aug, csrc, clabel);
|
430
|
+
|
431
|
+
return (r < 0) ? Qfalse : INT2NUM(r);
|
432
|
+
}
|
433
|
+
|
434
|
+
/*
|
435
|
+
* call-seq:
|
436
|
+
* text_store(LENS, NODE, PATH) -> boolean
|
437
|
+
*
|
438
|
+
* Use the value of node NODE as a string and transform it into a tree
|
439
|
+
* using the lens LENS and store it in the tree at PATH, which will be
|
440
|
+
* overwritten. PATH and NODE are path expressions.
|
441
|
+
*/
|
442
|
+
VALUE augeas_text_store(VALUE s, VALUE lens, VALUE node, VALUE path) {
|
443
|
+
augeas *aug = aug_handle(s);
|
444
|
+
const char *clens = StringValueCStr(lens);
|
445
|
+
const char *cnode = StringValueCStr(node);
|
446
|
+
const char *cpath = StringValueCStr(path);
|
447
|
+
int r = aug_text_store(aug, clens, cnode, cpath);
|
448
|
+
|
449
|
+
return (r < 0) ? Qfalse : Qtrue;
|
450
|
+
}
|
451
|
+
|
452
|
+
/*
|
453
|
+
* call-seq:
|
454
|
+
* text_retrieve(LENS, NODE_IN, PATH, NODE_OUT) -> boolean
|
455
|
+
*
|
456
|
+
* Transform the tree at PATH into a string using lens LENS and store it in
|
457
|
+
* the node NODE_OUT, assuming the tree was initially generated using the
|
458
|
+
* value of node NODE_IN. PATH, NODE_IN, and NODE_OUT are path expressions.
|
459
|
+
*/
|
460
|
+
VALUE augeas_text_retrieve(VALUE s, VALUE lens, VALUE node_in, VALUE path, VALUE node_out) {
|
461
|
+
augeas *aug = aug_handle(s);
|
462
|
+
const char *clens = StringValueCStr(lens);
|
463
|
+
const char *cnode_in = StringValueCStr(node_in);
|
464
|
+
const char *cpath = StringValueCStr(path);
|
465
|
+
const char *cnode_out = StringValueCStr(node_out);
|
466
|
+
int r = aug_text_retrieve(aug, clens, cnode_in, cpath, cnode_out);
|
467
|
+
|
468
|
+
return (r < 0) ? Qfalse : Qtrue;
|
469
|
+
}
|
470
|
+
|
471
|
+
void Init__augeas() {
|
472
|
+
/* Define the NEW ruby class
|
473
|
+
*
|
474
|
+
* This class is basically the same as the old one, but uses a
|
475
|
+
* different naming scheme for methods (prefixing everything with
|
476
|
+
* "augeas_"). Also some methods point to different C functions.
|
477
|
+
*/
|
478
|
+
c_augeas = rb_define_class("Augeas", rb_cObject) ;
|
479
|
+
|
480
|
+
/* Constants for enum aug_flags */
|
481
|
+
#define DEF_AUG_FLAG(name) \
|
482
|
+
rb_define_const(c_augeas, #name, INT2NUM(AUG_##name))
|
483
|
+
DEF_AUG_FLAG(NONE);
|
484
|
+
DEF_AUG_FLAG(SAVE_BACKUP);
|
485
|
+
DEF_AUG_FLAG(SAVE_NEWFILE);
|
486
|
+
DEF_AUG_FLAG(TYPE_CHECK);
|
487
|
+
DEF_AUG_FLAG(NO_STDINC);
|
488
|
+
DEF_AUG_FLAG(SAVE_NOOP);
|
489
|
+
DEF_AUG_FLAG(NO_LOAD);
|
490
|
+
DEF_AUG_FLAG(NO_MODL_AUTOLOAD);
|
491
|
+
DEF_AUG_FLAG(ENABLE_SPAN);
|
492
|
+
DEF_AUG_FLAG(NO_ERR_CLOSE);
|
493
|
+
#undef DEF_AUG_FLAG
|
494
|
+
|
495
|
+
/* Constants for enum aug_errcode_t */
|
496
|
+
#define DEF_AUG_ERR(name) \
|
497
|
+
rb_define_const(c_augeas, #name, INT2NUM(AUG_##name))
|
498
|
+
DEF_AUG_ERR(NOERROR);
|
499
|
+
DEF_AUG_ERR(ENOMEM);
|
500
|
+
DEF_AUG_ERR(EINTERNAL);
|
501
|
+
DEF_AUG_ERR(EPATHX);
|
502
|
+
DEF_AUG_ERR(ENOMATCH);
|
503
|
+
DEF_AUG_ERR(EMMATCH);
|
504
|
+
DEF_AUG_ERR(ESYNTAX);
|
505
|
+
DEF_AUG_ERR(ENOLENS);
|
506
|
+
DEF_AUG_ERR(EMXFM);
|
507
|
+
DEF_AUG_ERR(ENOSPAN);
|
508
|
+
DEF_AUG_ERR(EMVDESC);
|
509
|
+
DEF_AUG_ERR(ECMDRUN);
|
510
|
+
DEF_AUG_ERR(EBADARG);
|
511
|
+
DEF_AUG_ERR(ELABEL);
|
512
|
+
#undef DEF_AUG_ERR
|
513
|
+
|
514
|
+
/* Define the methods */
|
515
|
+
rb_define_singleton_method(c_augeas, "open3", augeas_init, 3);
|
516
|
+
rb_define_method(c_augeas, "augeas_defvar", augeas_defvar, 2);
|
517
|
+
rb_define_method(c_augeas, "augeas_defnode", augeas_defnode, 3);
|
518
|
+
rb_define_method(c_augeas, "augeas_get", augeas_get, 1);
|
519
|
+
rb_define_method(c_augeas, "augeas_exists", augeas_exists, 1);
|
520
|
+
rb_define_method(c_augeas, "augeas_insert", augeas_insert, 3);
|
521
|
+
rb_define_method(c_augeas, "augeas_mv", augeas_mv, 2);
|
522
|
+
rb_define_method(c_augeas, "augeas_rm", augeas_rm, 1);
|
523
|
+
rb_define_method(c_augeas, "augeas_match", augeas_match, 1);
|
524
|
+
rb_define_method(c_augeas, "augeas_save", augeas_save, 0);
|
525
|
+
rb_define_method(c_augeas, "augeas_load", augeas_load, 0);
|
526
|
+
rb_define_method(c_augeas, "augeas_set", augeas_set, 2);
|
527
|
+
rb_define_method(c_augeas, "augeas_setm", augeas_setm, 3);
|
528
|
+
/* The `close` and `error` methods as used unchanged in the ruby bindings */
|
529
|
+
rb_define_method(c_augeas, "close", augeas_close, 0);
|
530
|
+
rb_define_method(c_augeas, "error", augeas_error, 0);
|
531
|
+
rb_define_method(c_augeas, "augeas_span", augeas_span, 1);
|
532
|
+
rb_define_method(c_augeas, "augeas_srun", augeas_srun, 1);
|
533
|
+
rb_define_method(c_augeas, "augeas_label", augeas_label, 1);
|
534
|
+
rb_define_method(c_augeas, "augeas_rename", augeas_rename, 2);
|
535
|
+
rb_define_method(c_augeas, "augeas_text_store", augeas_text_store, 3);
|
536
|
+
rb_define_method(c_augeas, "augeas_text_retrieve", augeas_text_retrieve, 4);
|
537
|
+
}
|
538
|
+
|
539
|
+
/*
|
540
|
+
* Local variables:
|
541
|
+
* indent-tabs-mode: nil
|
542
|
+
* c-indent-level: 4
|
543
|
+
* c-basic-offset: 4
|
544
|
+
* tab-width: 4
|
545
|
+
* End:
|
546
|
+
*/
|
@@ -0,0 +1,48 @@
|
|
1
|
+
/*
|
2
|
+
* augeas.h: internal headers for Augeas Ruby bindings
|
3
|
+
*
|
4
|
+
* Copyright (C) 2008-2011 Red Hat Inc.
|
5
|
+
*
|
6
|
+
* This library is free software; you can redistribute it and/or
|
7
|
+
* modify it under the terms of the GNU Lesser General Public
|
8
|
+
* License as published by the Free Software Foundation; either
|
9
|
+
* version 2.1 of the License, or (at your option) any later version.
|
10
|
+
*
|
11
|
+
* This library is distributed in the hope that it will be useful,
|
12
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
14
|
+
* Lesser General Public License for more details.
|
15
|
+
*
|
16
|
+
* You should have received a copy of the GNU Lesser General Public
|
17
|
+
* License along with this library; if not, write to the Free Software
|
18
|
+
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
19
|
+
*/
|
20
|
+
|
21
|
+
#include <ruby.h>
|
22
|
+
|
23
|
+
#ifndef _AUGEAS_H_
|
24
|
+
#define _AUGEAS_H_
|
25
|
+
|
26
|
+
#define StringValueCStrOrNull(v) \
|
27
|
+
NIL_P(v) ? NULL : StringValueCStr(v)
|
28
|
+
|
29
|
+
/* memstream support from Augeas internal.h */
|
30
|
+
struct memstream {
|
31
|
+
FILE *stream;
|
32
|
+
char *buf;
|
33
|
+
size_t size;
|
34
|
+
};
|
35
|
+
|
36
|
+
int __aug_init_memstream(struct memstream *ms);
|
37
|
+
int __aug_close_memstream(struct memstream *ms);
|
38
|
+
|
39
|
+
#endif
|
40
|
+
|
41
|
+
/*
|
42
|
+
* Local variables:
|
43
|
+
* indent-tabs-mode: nil
|
44
|
+
* c-indent-level: 4
|
45
|
+
* c-basic-offset: 4
|
46
|
+
* tab-width: 4
|
47
|
+
* End:
|
48
|
+
*/
|