opennebula-augeas 0.6.6.pre
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
*/
|