1X2Go::Server::Agent::NXU:s:eOrptCioonntsr(i3b)uted PerlXD2oGcou:m:eSnetravteiro:n:Agent::NX::Options(3)
2
3
4

NAME

6       X2Go::Server::Agent::NX::Options - NX Options modification module
7

SYNOPSIS

9        use X2Go::Server::Agent::NX::Options;
10
11        # Options string, probably read in from somewhere, but
12        # hardcoded here.
13        my $options = 'some=option,another=opt,more=values,some=override,more=data:90';
14
15        # Parse into an intermediate form.
16        my $intermediate = X2Go::Server::Agent::NX::Options::parse_options ($options);
17
18        # Check for errors.
19        die "Unable to parse option string, aborting.\n" unless (defined ($intermediate));
20
21        # (Optionally) compact it, this should make the duplicated "some" and "more"
22        # keys unique.
23        $intermediate = X2Go::Server::Agent::NX::Options::compact_intermediate ($intermediate);
24
25        # Error handling ...
26        die "Unable to compact intermediate array, aborting.\n" unless (defined ($intermediate));
27
28        # Add to options string.
29        my $transform_op = '+new=value';
30
31        # Parse and sanitize transform string.
32        my $interpreted_transform_ref = X2Go::Server::Agent::NX::Options::interpret_transform ($transform_op);
33
34        # Error handling ...
35        die "Invalid transformation passed, aborting.\n" unless (defined ($interpreted_transform_ref));
36
37        # Extract transformation data.
38        my ($transform_mode, $sanitized_transform) = @{$interpreted_transform_ref};
39
40        # Apply transformation.
41        $intermediate = X2Go::Server::Agent::NX::Options::transform_intermediate ($intermediate, $transform_mode, $sanitized_transform);
42
43        # Error handling ...
44        die "Error while transforming intermediate representation, aborting.\n" unless (defined ($intermediate));
45
46        # Try to remove a combination which doesn't exist, this should not modify the
47        # intermediate.
48        # No more comments for things that were already explained.
49        $transform_op = '-another=doesnotexist';
50        $interpreted_transform_ref = X2Go::Server::Agent::NX::Options::interpret_transform ($transform_op);
51        die "Invalid transformation passed, aborting.\n" unless (defined ($interpreted_transform_ref));
52        ($transform_mode, $sanitized_transform) = @{$interpreted_transform_ref};
53        $intermediate = X2Go::Server::Agent::NX::Options::transform_intermediate ($intermediate, $transform_mode, $sanitized_transform);
54        die "Error while transforming intermediate representation, aborting.\n" unless (defined ($intermediate));
55
56        # Remove a key unconditionally, this should change the intermediate.
57        $transform_op = '-some';
58        $interpreted_transform_ref = X2Go::Server::Agent::NX::Options::interpret_transform ($transform_op);
59        die "Invalid transformation passed, aborting.\n" unless (defined ($interpreted_transform_ref));
60        ($transform_mode, $sanitized_transform) = @{$interpreted_transform_ref};
61        $intermediate = X2Go::Server::Agent::NX::Options::transform_intermediate ($intermediate, $transform_mode, $sanitized_transform);
62        die "Error while transforming intermediate representation, aborting.\n" unless (defined ($intermediate));
63
64        # Modify/update a key.
65        $transform_op = '+another=newval';
66        $interpreted_transform_ref = X2Go::Server::Agent::NX::Options::interpret_transform ($transform_op);
67        die "Invalid transformation passed, aborting.\n" unless (defined ($interpreted_transform_ref));
68        ($transform_mode, $sanitized_transform) = @{$interpreted_transform_ref};
69        $intermediate = X2Go::Server::Agent::NX::Options::transform_intermediate ($intermediate, $transform_mode, $sanitized_transform);
70        die "Error while transforming intermediate representation, aborting.\n" unless (defined ($intermediate));
71
72        # Extract the "more" key.
73        my $extract = X2Go::Server::Agent::NX::Options::extract_element ($intermediate, q{more});
74
75        # Error handling ...
76        die "Unable to extract 'more' key from intermediate, aborting.\n" unless defined ($extract);
77
78        # Fetching multiple elements could be fine, for instance when the intermediate is not compact.
79        # Hence, this need not be a general error, but we'll treat it as one here.
80        die "Extract operation returned more than one element, this should not happen with a compacted intermediate, aborting.\n" if (1 < scalar (@{$extract}));
81
82        # Likewise, it would be okay for the result to be empty, but not for us right here.
83        die "Extract operation returned no result, aborting.\n" if (1 > scalar (@{$extract}));
84
85        my $extracted_kv = q{};
86
87        # Now, get the actual data in a presentable form.
88        foreach my $entry (@{$extract}) {
89          foreach my $key (%{$entry}) {
90            $extracted_kv .= $key;
91            my $value = $entry->{$key};
92            if (defined ($value)) {
93              $extracted_kv .= q{=} . $value;
94            }
95            last;
96          }
97          last;
98        }
99
100        # At this point, $extracted_kv should be "more=data".
101
102        # Yet again, but this time extracting a key which does not exist.
103        $extract =  X2Go::Server::Agent::NX::Options::extract_element ($intermediate, q{nosuchey});
104
105        # Error handling ...
106        die "Unable to extract 'nosuchkey' key from intermediate, aborting.\n" unless defined ($extract);
107
108        # Should be empty.
109        die "Extract operation returned a result, aborting.\n" if (0 < scalar (@{$extract}));
110
111        # Transform back into a string.
112        my $out = X2Go::Server::Agent::NX::Options::intermediate_to_string ($intermediate);
113
114        # Error handling ...
115        die "Unable to transform intermediate back into string, aborting.\n" unless (defined ($out));
116
117        # At this point, $out should be 'another=newval,more=data,new=value:90'.
118

DESCRIPTION

120       Use this module to modify or extract data from X2Go/NX Agent options
121       strings.  Refer to "OPTIONS STRINGS" for an in-depth description of
122       options strings.
123
124       First, transform the input options string into an intermediate
125       representation via "parse_options".  The options string must end with a
126       display specification (i.e., it must end in ":displaynumber").  Parsing
127       errors are indicated by it returning "undef".  The returned value is
128       actually a reference to an array of hash references, but you should
129       make no assumptions to the layout or even its actual format.  Treat it
130       like a black box.  Crucially, whenever an intermediate is expected,
131       such a reference should be passed.
132
133       To remove redundant or empty entries within an options string, pass the
134       intermediate to "compact_intermediate".  This is entirely optional and
135       can be done at any step, as long as an intermediate is available.  If
136       you intend to extract data, it is recommended, but not necessary, to
137       compact the intermediate first.
138
139       In order to extract key-value pairs, supply the intermediate and a key-
140       value pair to extract to "extract_element".  Its result will be either
141       undefined on error, or a reference to an array consisting of references
142       to hashes.  Each hash contains exactly one key-value pair.
143
144       The same approach using "extract_element" can be used to check for the
145       existence of either keys or full key-value pairs.  If the returned
146       array is empty, no such element exists.
147
148       For compacted intermediates, each extraction operation returns an array
149       with at most one hash reference entry.  Non-compacted intermediates can
150       contain a key multiple times, so no guarantee regarding the result's
151       magnitude can be given.
152
153       To parse transformations, pass each one to "interpret_transform".
154       Refer to "TRANSFORMATIONS" for documentation on transformation formats.
155       This will either return "undef" on error, or an array of two scalars -
156       the transformation mode (an internal number) and the sanitized
157       transformation string (i.e., the original transformation string with
158       any preceding operator removed).
159
160       Pass the intermediate, the transformation mode and the sanitized
161       transformation string to "transform_intermediate" to modify the
162       intermediate value.
163
164       Repeat this until the intermediate is modified to your liking.
165
166       Finally, pass the intermediate to "intermediate_to_string" in order to
167       parse it back into a normal string.  This operation is essentially the
168       opposite of "parse_options".  As usual, "undef" is returned on error.
169
170       Generally, parsing an options string to an intermediate via
171       "parse_options" and then immediately parsing it back into a string via
172       "intermediate_to_string" should always produce an options string that
173       is identical to the original options string (assuming no errors
174       occurred).
175
176       If this is not the case, please report a bug.
177
178       Any subroutines and constants not marked as exportable are explicitly
179       not documented and should be regarded as internal and not be used.
180       There is no guarantee regarding their behavior or existence.
181

OPTIONS STRINGS

183       X2Go/NX Agent options strings are fully documented in nxagent's
184       documentation and additional, linked places therein.
185
186       This module is not really concerned with the actual content of an
187       options string, but mostly its format.
188
189       An options string follows the form [[key[=value,]]:displaynumber.
190
191       This has some interesting implications:
192
193       •   Key-value pairs are entirely optional.  For example, an options
194           string like ":42" is well-formed.
195
196       •   Options strings must end with a display number separator, i.e., a
197           colon (":") and a display number.
198
199           No parsing is done on the display number, so any string (even the
200           empty string) is valid as far as this module is concerned.
201
202           The display number, however, can not contain a colon (":"), since
203           that would make it a new display number separator.
204
205           This module will parse the options string from right to left when
206           searching for the display number separator and use the first one it
207           can find.
208
209       •   Key-value pairs are separated via a comma (",").  Hence, this
210           character is not valid in neither keys nor values.  As a
211           workaround, it can be URL-encoded, as, e.g., %2C, and then used as
212           part of either keys or values.
213
214       •   Key-value pairs can be empty.  This is supported and empty key-
215           value pairs will be preserved, but will trigger warnings at parse
216           time.
217
218           An options string such as ",,,:65" is hence valid.
219
220           To remove such empty elements, use "compact_intermediate".  An
221           implicit empty element is added whenever the resulting options
222           string would only contain the display number.  This one can not be
223           removed, but also won't show up anywhere.  Adding any non-empty new
224           key will automatically replace such an empty element, without any
225           need for actual compaction.
226
227       •   In a key-value pair, keys and values are separated from each other
228           via an equal sign ("=").
229
230           Hence, this character is not a valid part of a key.  It can,
231           however, be a valid part of a value.
232
233           To use this character as part of a key, it can be URL-encoded as,
234           e.g., %3D.
235
236           While it is legal as part of a value, it is recommended to also
237           URL-encode it when used as part of a value in order to not confuse
238           other parsers.
239
240           An options string such as "this%3Dis%3Da=key:38" is just as valid
241           as "this=is=a=key:38" or "this=is%3Da%3Dkey:38".
242
243           However, the semantics differ.  While the latter two key-value
244           pairs are logically equivalent to each other, they are very much
245           different from the first one.
246
247           For the first case, the key will be "this%3Dis%3Da" (or, logically,
248           also "this=is=a", which can not be directly represented), while the
249           value will be just "key".
250
251           The latter two will parse into a key "this" with a value of
252           "is=a=key" (or, logically equivalent, "is%3Da%3Dkey").
253
254       •   Quoting with any character is unsupported.  Quotes and other
255           grouping characters (like curly braces ["{}"]) are seen verbatim
256           without any special meaning.
257
258       •   Since options strings are typically parsed by C applications, "NUL"
259           (control) characters are prematurely terminating the string and
260           hence cannot be directly embedded.  Indirectly, they can be
261           embedded by URL-encoding them as %00.
262
263           There is, however, no guarantee that an application unpacking such
264           a string will be able to scan any data after the first embedded
265           "NUL" character.
266
267           It is highly recommended to avoid using embedded "NUL" characters.
268
269           This module will not explicitly scan for them, and, hence, also not
270           issue warnings related to those characters.
271
272       •   There are no provisions (other than the mentioned invalid
273           characters) on the content of keys and values.
274
275           Importantly, this also means that the same key can show up multiple
276           times in the options string.  Semantically, this is redundant,
277           since only the last occurrence of a key (assuming the options
278           string is parsed from left to right) will take any effect.
279           Syntactically, it's completely legal, though.
280
281           It is recommended to avoid duplicate keys in the input options
282           string.
283
284           Note that, due to the nature of the supported transformations, keys
285           can not be duplicated with this module.
286
287           To remove duplicated keys, use "compact_intermediate".  This will
288           preserve the order in a first-seen fashion.
289
290           Additionally, most non-printable control characters can be used
291           verbatim.  This includes, but is not limited to, characters like
292           "LF" ("\n"), "TAB" ("\t") and "VT" ("\v").
293
294           Naturally, it is recommended to avoid such characters.
295
296       •   A key-value pair with an empty key but a non-empty value is
297           allowed.
298
299           Likewise, a key-value pair with a non-empty key, but an empty value
300           is allowed.  In this case, the value will be interpreted as an
301           empty string in order to differentiate it from a non-existent
302           value.
303

TRANSFORMATIONS

305       Transformations follow the form [+]|-key[=value], which means that:
306
307       •   They can be prefixed with a plus character ("+") to indicate either
308           additions or modifications.  A missing prefix character is
309           interpreted like a plus character.
310
311           If the given key already exists in the intermediate, the key-value
312           pair will be updated with the provided value (if any), or a new
313           key-value pair added.
314
315           Insertions always take place at the end of the intermediate.
316
317           The value can be omitted, in which case key will be added without a
318           value on insertions or a potentially existing value removed on
319           updates.
320
321       •   If they are prefixed with a minus character ("-"), deletion mode is
322           activated.
323
324           If the given key is not part of the intermediate, no deletion will
325           occur.
326
327           Otherwise, the optional value determines deletion: if no value has
328           been provided, key will be removed from the intermediate regardless
329           of its value.  If the optional value has been provided, key will
330           only be removed if both values match.
331

AUTHOR

333       This manual has been written by Mihai Moldovan <ionic@ionic.de>
334       <mailto:ionic@ionic.de> for the X2Go project (<https://www.x2go.org>).
335
336
337
338perl v5.38.0                      2023-07-22X2Go::Server::Agent::NX::Options(3)
Impressum