]> sourceware.org Git - systemtap.git/blame - session.cxx
Long options rework.
[systemtap.git] / session.cxx
CommitLineData
e2012a7a 1// session functions
73f52eb4 2// Copyright (C) 2010-2012 Red Hat Inc.
e2012a7a
DB
3//
4// This file is part of systemtap, and is free software. You can
5// redistribute it and/or modify it under the terms of the GNU General
6// Public License (GPL); either version 2, or (at your option) any
7// later version.
8
9#include "config.h"
10#include "session.h"
11#include "cache.h"
12#include "elaborate.h"
aa4d21c0
DB
13#include "translate.h"
14#include "buildrun.h"
15#include "coveragedb.h"
e2012a7a
DB
16#include "hash.h"
17#include "task_finder.h"
aa4d21c0
DB
18#include "csclient.h"
19#include "rpm_finder.h"
e2012a7a 20#include "util.h"
73f52eb4 21#include "cmdline.h"
e2012a7a
DB
22#include "git_version.h"
23
85007c04
DB
24#include <cerrno>
25#include <cstdlib>
26
e2012a7a 27extern "C" {
e2012a7a
DB
28#include <getopt.h>
29#include <limits.h>
a83cc46b 30#include <grp.h>
2dce8c42 31#include <sys/stat.h>
e2012a7a
DB
32#include <sys/utsname.h>
33#include <elfutils/libdwfl.h>
47caa991 34#include <unistd.h>
e2012a7a
DB
35}
36
b0e5fa85
DB
37#if HAVE_NSS
38extern "C" {
39#include <nspr.h>
40}
41#endif
42
e2012a7a
DB
43#include <string>
44
45using namespace std;
46
47/* getopt variables */
48extern int optind;
49
50#define PATH_TBD string("__TBD__")
51
48e74294 52#if HAVE_NSS
44edbcd6 53bool systemtap_session::NSPR_Initialized = false;
48e74294 54#endif
44edbcd6 55
e2012a7a
DB
56systemtap_session::systemtap_session ():
57 // NB: pointer members must be manually initialized!
abc15290 58 // NB: don't forget the copy constructor too!
e2012a7a
DB
59 base_hash(0),
60 pattern_root(new match_node),
61 user_file (0),
62 be_derived_probes(0),
63 dwarf_derived_probes(0),
64 kprobe_derived_probes(0),
65 hwbkpt_derived_probes(0),
66 perf_derived_probes(0),
67 uprobe_derived_probes(0),
68 utrace_derived_probes(0),
69 itrace_derived_probes(0),
70 task_finder_derived_probes(0),
71 timer_derived_probes(0),
72 profile_derived_probes(0),
73 mark_derived_probes(0),
74 tracepoint_derived_probes(0),
75 hrtimer_derived_probes(0),
76 procfs_derived_probes(0),
77 op (0), up (0),
78 sym_kprobes_text_start (0),
79 sym_kprobes_text_end (0),
80 sym_stext (0),
81 module_cache (0),
82 last_token (0)
e2012a7a
DB
83{
84 struct utsname buf;
85 (void) uname (& buf);
86 kernel_release = string (buf.release);
87 release = kernel_release;
88 kernel_build_tree = "/lib/modules/" + kernel_release + "/build";
daa75206 89 architecture = machine = normalize_machine(buf.machine);
e2012a7a
DB
90
91 for (unsigned i=0; i<5; i++) perpass_verbose[i]=0;
2dce8c42 92 verbose = 0;
e2012a7a
DB
93
94 have_script = false;
2fad97fd
DB
95 runtime_specified = false;
96 include_arg_start = -1;
e2012a7a
DB
97 timing = false;
98 guru_mode = false;
99 bulk_mode = false;
100 unoptimized = false;
101 suppress_warnings = false;
102 panic_warnings = false;
103 listing_mode = false;
104 listing_mode_vars = false;
b82d77b4 105 dump_probe_types = false;
e2012a7a
DB
106
107#ifdef ENABLE_PROLOGUES
108 prologue_searching = true;
109#else
110 prologue_searching = false;
111#endif
112
113 buffer_size = 0;
114 last_pass = 5;
115 module_name = "stap_" + lex_cast(getpid());
116 stapconf_name = "stapconf_" + lex_cast(getpid()) + ".h";
117 output_file = ""; // -o FILE
305fac7d 118 tmpdir_opt_set = false;
e2012a7a 119 save_module = false;
5c854d7c 120 modname_given = false;
e2012a7a
DB
121 keep_tmpdir = false;
122 cmd = "";
123 target_pid = 0;
e2012a7a
DB
124 use_cache = true;
125 use_script_cache = true;
126 poison_cache = false;
127 tapset_compile_coverage = false;
128 need_uprobes = false;
08badca8 129 need_unwind = false;
8af41ec2 130 need_symbols = false;
474d17ad 131 uprobes_path = "";
e2012a7a
DB
132 consult_symtab = false;
133 ignore_vmlinux = false;
134 ignore_dwarf = false;
135 load_only = false;
136 skip_badvars = false;
42e38653 137 privilege = pr_stapdev;
73f52eb4 138 privilege_set = false;
e2012a7a
DB
139 omit_werror = false;
140 compatible = VERSION; // XXX: perhaps also process GIT_SHAID if available?
141 unwindsym_ldd = false;
142 client_options = false;
eff14db3 143 server_cache = NULL;
a46f9abe 144 automatic_server_mode = false;
3e1ec884 145 use_server_on_error = false;
44edbcd6 146 try_server_status = try_server_unset;
756cfd49 147 use_remote_prefix = false;
a07a2c28 148 systemtap_v_check = false;
ea60076d 149 download_dbinfo = 0;
7baf48e9 150 suppress_handler_errors = false;
50f2545f 151 native_build = true; // presumed
e2012a7a 152
6ac63adf 153 /* adding in the XDG_DATA_DIRS variable path,
2dce8c42
DB
154 * this searches in conjunction with SYSTEMTAP_TAPSET
155 * to locate stap scripts, either can be disabled if
156 * needed using env $PATH=/dev/null where $PATH is the
157 * path you want disabled
158 */
6ac63adf
LB
159 const char* s_p1 = getenv ("XDG_DATA_DIRS");
160 if ( s_p1 != NULL )
161 {
162 vector<string> dirs;
163 tokenize(s_p1, dirs, ":");
164 for(vector<string>::iterator i = dirs.begin(); i != dirs.end(); ++i)
165 {
166 include_path.push_back(*i + "/systemtap/tapset");
167 }
168 }
e2012a7a
DB
169
170 const char* s_p = getenv ("SYSTEMTAP_TAPSET");
171 if (s_p != NULL)
172 {
173 include_path.push_back (s_p);
174 }
175 else
176 {
177 include_path.push_back (string(PKGDATADIR) + "/tapset");
178 }
179
180 const char* s_r = getenv ("SYSTEMTAP_RUNTIME");
181 if (s_r != NULL)
182 runtime_path = s_r;
183 else
184 runtime_path = string(PKGDATADIR) + "/runtime";
185
186 const char* s_d = getenv ("SYSTEMTAP_DIR");
187 if (s_d != NULL)
188 data_path = s_d;
189 else
190 data_path = get_home_directory() + string("/.systemtap");
191 if (create_dir(data_path.c_str()) == 1)
192 {
193 const char* e = strerror (errno);
2713ea24 194 print_warning("failed to create systemtap data directory \"" + data_path + "\" " + e + ", disabling cache support.");
e2012a7a
DB
195 use_cache = use_script_cache = false;
196 }
197
198 if (use_cache)
199 {
200 cache_path = data_path + "/cache";
201 if (create_dir(cache_path.c_str()) == 1)
202 {
203 const char* e = strerror (errno);
2713ea24 204 print_warning("failed to create cache directory (\" " + cache_path + " \") " + e + ", disabling cache support.");
e2012a7a
DB
205 use_cache = use_script_cache = false;
206 }
207 }
208
e2012a7a
DB
209 const char* s_tc = getenv ("SYSTEMTAP_COVERAGE");
210 if (s_tc != NULL)
211 tapset_compile_coverage = true;
212
213 const char* s_kr = getenv ("SYSTEMTAP_RELEASE");
214 if (s_kr != NULL) {
215 setup_kernel_release(s_kr);
216 }
217}
218
abc15290
JS
219systemtap_session::systemtap_session (const systemtap_session& other,
220 const string& arch,
221 const string& kern):
222 // NB: pointer members must be manually initialized!
223 // NB: this needs to consider everything that the base ctor does,
224 // plus copying any wanted implicit fields (strings, vectors, etc.)
225 base_hash(0),
226 pattern_root(new match_node),
227 user_file (other.user_file),
228 be_derived_probes(0),
229 dwarf_derived_probes(0),
230 kprobe_derived_probes(0),
231 hwbkpt_derived_probes(0),
232 perf_derived_probes(0),
233 uprobe_derived_probes(0),
234 utrace_derived_probes(0),
235 itrace_derived_probes(0),
236 task_finder_derived_probes(0),
237 timer_derived_probes(0),
238 profile_derived_probes(0),
239 mark_derived_probes(0),
240 tracepoint_derived_probes(0),
241 hrtimer_derived_probes(0),
242 procfs_derived_probes(0),
243 op (0), up (0),
244 sym_kprobes_text_start (0),
245 sym_kprobes_text_end (0),
246 sym_stext (0),
247 module_cache (0),
248 last_token (0)
249{
250 release = kernel_release = kern;
251 kernel_build_tree = "/lib/modules/" + kernel_release + "/build";
252 architecture = machine = normalize_machine(arch);
253 setup_kernel_release(kern.c_str());
50f2545f 254 native_build = false; // assumed; XXX: could be computed as in check_options()
abc15290
JS
255
256 // These are all copied in the same order as the default ctor did above.
257
258 copy(other.perpass_verbose, other.perpass_verbose + 5, perpass_verbose);
259 verbose = other.verbose;
260
261 have_script = other.have_script;
262 runtime_specified = other.runtime_specified;
263 include_arg_start = other.include_arg_start;
264 timing = other.timing;
265 guru_mode = other.guru_mode;
266 bulk_mode = other.bulk_mode;
267 unoptimized = other.unoptimized;
268 suppress_warnings = other.suppress_warnings;
269 panic_warnings = other.panic_warnings;
270 listing_mode = other.listing_mode;
271 listing_mode_vars = other.listing_mode_vars;
b82d77b4 272 dump_probe_types = other.dump_probe_types;
abc15290
JS
273
274 prologue_searching = other.prologue_searching;
275
276 buffer_size = other.buffer_size;
277 last_pass = other.last_pass;
278 module_name = other.module_name;
279 stapconf_name = other.stapconf_name;
280 output_file = other.output_file; // XXX how should multiple remotes work?
305fac7d 281 tmpdir_opt_set = false;
abc15290 282 save_module = other.save_module;
5c854d7c 283 modname_given = other.modname_given;
abc15290
JS
284 keep_tmpdir = other.keep_tmpdir;
285 cmd = other.cmd;
286 target_pid = other.target_pid; // XXX almost surely nonsense for multiremote
287 use_cache = other.use_cache;
288 use_script_cache = other.use_script_cache;
289 poison_cache = other.poison_cache;
290 tapset_compile_coverage = other.tapset_compile_coverage;
291 need_uprobes = false;
08badca8 292 need_unwind = false;
8af41ec2 293 need_symbols = false;
abc15290
JS
294 uprobes_path = "";
295 consult_symtab = other.consult_symtab;
296 ignore_vmlinux = other.ignore_vmlinux;
297 ignore_dwarf = other.ignore_dwarf;
298 load_only = other.load_only;
299 skip_badvars = other.skip_badvars;
42e38653 300 privilege = other.privilege;
73f52eb4 301 privilege_set = other.privilege_set;
abc15290
JS
302 omit_werror = other.omit_werror;
303 compatible = other.compatible;
304 unwindsym_ldd = other.unwindsym_ldd;
305 client_options = other.client_options;
eff14db3 306 server_cache = NULL;
abc15290
JS
307 use_server_on_error = other.use_server_on_error;
308 try_server_status = other.try_server_status;
756cfd49 309 use_remote_prefix = other.use_remote_prefix;
abc15290 310 systemtap_v_check = other.systemtap_v_check;
ea60076d 311 download_dbinfo = other.download_dbinfo;
7baf48e9 312 suppress_handler_errors = other.suppress_handler_errors;
abc15290
JS
313
314 include_path = other.include_path;
315 runtime_path = other.runtime_path;
316
317 // NB: assuming that "other" created these already
318 data_path = other.data_path;
319 cache_path = other.cache_path;
320
321 tapset_compile_coverage = other.tapset_compile_coverage;
322
323
324 // These are fields that were left to their default ctor, but now we want to
325 // copy them from "other". In the same order as declared...
326 script_file = other.script_file;
327 cmdline_script = other.cmdline_script;
328 macros = other.macros;
329 args = other.args;
330 kbuildflags = other.kbuildflags;
331 globalopts = other.globalopts;
633e5ca7 332 modinfos = other.modinfos;
abc15290 333
372c6458 334 client_options_disallowed_for_unprivileged = other.client_options_disallowed_for_unprivileged;
abc15290
JS
335 server_status_strings = other.server_status_strings;
336 specified_servers = other.specified_servers;
337 server_trust_spec = other.server_trust_spec;
338 server_args = other.server_args;
339
340 unwindsym_modules = other.unwindsym_modules;
74fe61bc 341 automatic_server_mode = other.automatic_server_mode;
abc15290
JS
342}
343
b0e5fa85
DB
344systemtap_session::~systemtap_session ()
345{
ebff2ed0 346 delete_map(subsessions);
08b61232 347 delete pattern_root;
b0e5fa85
DB
348}
349
48e74294 350#if HAVE_NSS
b0e5fa85
DB
351void
352systemtap_session::NSPR_init ()
353{
354 if (! NSPR_Initialized)
355 {
356 PR_Init (PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);
357 NSPR_Initialized = true;
358 }
3d9dfde6 359}
48e74294 360#endif // HAVE_NSS
e2012a7a 361
ebff2ed0
JS
362systemtap_session*
363systemtap_session::clone(const string& arch, const string& release)
364{
ba0bd1be
JS
365 const string norm_arch = normalize_machine(arch);
366 if (this->architecture == norm_arch && this->kernel_release == release)
ebff2ed0
JS
367 return this;
368
ba0bd1be 369 systemtap_session*& s = subsessions[make_pair(norm_arch, release)];
ebff2ed0 370 if (!s)
ba0bd1be 371 s = new systemtap_session(*this, norm_arch, release);
ebff2ed0
JS
372 return s;
373}
374
e2012a7a
DB
375void
376systemtap_session::version ()
377{
d3c40c65 378 clog << _F("Systemtap translator/driver (version %s/%s %s)\n"
e64c7f38 379 "Copyright (C) 2005-2012 Red Hat, Inc. and others\n"
ce0f6648
LB
380 "This is free software; see the source for copying conditions.",
381 VERSION, dwfl_version(NULL), GIT_MESSAGE) << endl;
79bc39ab 382 clog << _("enabled features:")
1ef0423a
FCE
383#ifdef HAVE_AVAHI
384 << " AVAHI"
385#endif
386#ifdef HAVE_LIBRPM
387 << " LIBRPM"
388#endif
389#ifdef HAVE_LIBSQLITE3
390 << " LIBSQLITE3"
391#endif
392#ifdef HAVE_NSS
393 << " NSS"
394#endif
395#ifdef HAVE_BOOST_SHARED_PTR_HPP
396 << " BOOST_SHARED_PTR"
397#endif
398#ifdef HAVE_TR1_UNORDERED_MAP
399 << " TR1_UNORDERED_MAP"
400#endif
401#ifdef ENABLE_PROLOGUES
402 << " PROLOGUES"
f8e53f3a
FCE
403#endif
404#ifdef ENABLE_NLS
405 << " NLS"
1ef0423a
FCE
406#endif
407 << endl;
e2012a7a
DB
408}
409
0d70f9d8
JS
410void
411systemtap_session::usage (int exitcode)
412{
413 version ();
414 clog
415 << endl
6073c3fc
LB
416 << _F("Usage: stap [options] FILE Run script in file.\n"
417 " or: stap [options] - Run script on stdin.\n"
418 " or: stap [options] -e SCRIPT Run given script.\n"
419 " or: stap [options] -l PROBE List matching probes.\n"
420 " or: stap [options] -L PROBE List matching probes and local variables.\n\n"
222e16ed 421 "Options (in %s/rc and on command line):\n"
6073c3fc
LB
422 " -- end of translator options, script options follow\n"
423 " -h --help show help\n"
424 " -V --version show version\n"
425 " -p NUM stop after pass NUM 1-5, instead of %d\n"
426 " (parse, elaborate, translate, compile, run)\n"
427 " -v add verbosity to all passes\n"
222e16ed 428 " --vp {N}+ add per-pass verbosity [", data_path.c_str(), last_pass);
0d70f9d8
JS
429 for (unsigned i=0; i<5; i++)
430 clog << (perpass_verbose[i] <= 9 ? perpass_verbose[i] : 9);
431 clog
6073c3fc
LB
432 << "]" << endl;
433 clog << _F(" -k keep temporary directory\n"
434 " -u unoptimized translation %s\n"
435 " -w suppress warnings %s\n"
436 " -W turn warnings into errors %s\n"
437 " -g guru mode %s\n"
438 " -P prologue-searching for function probes %s\n"
439 " -b bulk (percpu file) mode %s\n"
440 " -s NUM buffer size in megabytes, instead of %d\n"
441 " -I DIR look in DIR for additional .stp script files", (unoptimized ? _(" [set]") : ""),
442 (suppress_warnings ? _(" [set]") : ""), (panic_warnings ? _(" [set]") : ""),
443 (guru_mode ? _(" [set]") : ""), (prologue_searching ? _(" [set]") : ""),
444 (bulk_mode ? _(" [set]") : ""), buffer_size);
0d70f9d8
JS
445 if (include_path.size() == 0)
446 clog << endl;
447 else
448 clog << _(", in addition to") << endl;
449 for (unsigned i=0; i<include_path.size(); i++)
ce0f6648 450 clog << " " << include_path[i].c_str() << endl;
0d70f9d8 451 clog
6073c3fc
LB
452 << _F(" -D NM=VAL emit macro definition into generated C code\n"
453 " -B NM=VAL pass option to kbuild make\n"
633e5ca7
FCE
454 " --modinfo NM=VAL\n"
455 " include a MODULE_INFO(NM,VAL) in the generated C code\n"
6073c3fc 456 " -G VAR=VAL set global variable to value\n"
ce0f6648 457 //TRANSLATORS: translating 'runtime' is not advised
6073c3fc
LB
458 " -R DIR look in DIR for runtime, instead of\n"
459 " %s\n"
460 " -r DIR cross-compile to kernel with given build tree; or else\n"
461 " -r RELEASE cross-compile to kernel /lib/modules/RELEASE/build, instead of\n"
462 " %s\n"
463 " -a ARCH cross-compile to given architecture, instead of %s\n"
464 " -m MODULE set probe module name, instead of \n"
465 " %s\n"
466 " -o FILE send script output to file, instead of stdout. This supports\n"
467 " strftime(3) formats for FILE\n"
468 " -c CMD start the probes, run CMD, and exit when it finishes\n"
469 " -x PID sets target() to PID\n"
470 " -F run as on-file flight recorder with -o.\n"
471 " run as on-memory flight recorder without -o.\n"
472 " -S size[,n] set maximum of the size and the number of files.\n"
473 " -d OBJECT add unwind/symbol data for OBJECT file", runtime_path.c_str(), kernel_build_tree.c_str(), architecture.c_str(), module_name.c_str());
0d70f9d8
JS
474 if (unwindsym_modules.size() == 0)
475 clog << endl;
476 else
477 clog << _(", in addition to") << endl;
e2012a7a 478 {
0d70f9d8
JS
479 vector<string> syms (unwindsym_modules.begin(), unwindsym_modules.end());
480 for (unsigned i=0; i<syms.size(); i++)
ce0f6648 481 clog << " " << syms[i].c_str() << endl;
0d70f9d8
JS
482 }
483 clog
6073c3fc
LB
484 << _F(" --ldd add unwind/symbol data for all referenced object files.\n"
485 " --all-modules\n"
486 " add unwind/symbol data for all loaded kernel objects.\n"
487 " -t collect probe timing information\n"
0d70f9d8 488#ifdef HAVE_LIBSQLITE3
6073c3fc 489 " -q generate information on tapset coverage\n"
0d70f9d8 490#endif /* HAVE_LIBSQLITE3 */
f66bb29a
DB
491 " --privilege=PRIVILEGE_LEVEL\n"
492 " check the script for constructs not allowed at the given privilege level\n"
6073c3fc 493 " --unprivileged\n"
42e38653 494 " equivalent to --privilege=stapusr\n"
0d70f9d8 495#if 0 /* PR6864: disable temporarily; should merge with -d somehow */
6073c3fc
LB
496 " --kelf make do with symbol table from vmlinux\n"
497 " --kmap[=FILE]\n"
498 " make do with symbol table from nm listing\n"
0d70f9d8
JS
499#endif
500 // Formerly present --ignore-{vmlinux,dwarf} options are for testsuite use
501 // only, and don't belong in the eyesight of a plain user.
6073c3fc
LB
502 " --compatible=VERSION\n"
503 " suppress incompatible language/tapset changes beyond VERSION,\n"
504 " instead of %s\n"
505 " --check-version\n"
506 " displays warnings where a syntax element may be \n"
507 " version dependent\n"
508 " --skip-badvars\n"
509 " substitute zero for bad context $variables\n"
7baf48e9
FCE
510 " --suppress-handler-errors\n"
511 " catch all runtime errors, quietly skip probe handlers\n"
6073c3fc
LB
512 " --use-server[=SERVER-SPEC]\n"
513 " specify systemtap compile-servers\n"
514 " --list-servers[=PROPERTIES]\n"
4830b335
FCE
515 " report on the status of the specified compile-servers:\n"
516 " all,specified,online,trusted,signer,compatible\n"
0d70f9d8 517#if HAVE_NSS
6073c3fc 518 " --trust-servers[=TRUST-SPEC]\n"
4830b335
FCE
519 " add/revoke trust of specified compile-servers:\n"
520 " ssl,signer,all-users,revoke,no-prompt\n"
6073c3fc
LB
521 " --use-server-on-error[=yes/no]\n"
522 " retry compilation using a compile server upon compilation error\n"
0d70f9d8 523#endif
6073c3fc
LB
524 " --remote=HOSTNAME\n"
525 " run pass 5 on the specified ssh host.\n"
756cfd49
JS
526 " may be repeated for targeting multiple hosts.\n"
527 " --remote-prefix\n"
715c8369 528 " prefix each line of remote output with a host index.\n"
305fac7d 529 " --tmpdir=NAME\n"
d1242dfa 530 " specify name of temporary directory to be used.\n"
ea60076d 531 " --download-debuginfo[=OPTION]\n"
d1242dfa 532 " automatically download debuginfo using ABRT.\n"
ea60076d 533 " yes,no,ask,<timeout value>\n"
b82d77b4
DB
534 " --dump-probe-types\n"
535 " show a list of available probe types.\n"
756cfd49 536 , compatible.c_str()) << endl
0d70f9d8 537 ;
e2012a7a
DB
538
539 time_t now;
540 time (& now);
541 struct tm* t = localtime (& now);
542 if (t && t->tm_mon*3 + t->tm_mday*173 == 0xb6)
543 clog << morehelp << endl;
544
545 exit (exitcode);
546}
547
548int
549systemtap_session::parse_cmdline (int argc, char * const argv [])
550{
372c6458 551 client_options_disallowed_for_unprivileged = "";
e2012a7a
DB
552 while (true)
553 {
e2012a7a 554 char * num_endptr;
73f52eb4 555 int grc = getopt_long (argc, argv, STAP_SHORT_OPTIONS, stap_long_options, NULL);
e2012a7a
DB
556
557 // NB: when adding new options, consider very carefully whether they
17874af3 558 // should be restricted from stap clients (after --client-options)!
e2012a7a
DB
559
560 if (grc < 0)
561 break;
562 switch (grc)
563 {
564 case 'V':
565 version ();
566 exit (0);
567
568 case 'v':
372c6458 569 server_args.push_back (string ("-") + (char)grc);
e2012a7a
DB
570 for (unsigned i=0; i<5; i++)
571 perpass_verbose[i] ++;
2dce8c42 572 verbose ++;
e2012a7a
DB
573 break;
574
2b7d9d84
RH
575 case 'G':
576 // Make sure the global option is only composed of the
577 // following chars: [_=a-zA-Z0-9]
7a583298 578 assert_regexp_match("-G parameter", optarg, "^[a-z_][a-z0-9_]*=[a-z0-9_-]+$");
2b7d9d84 579 globalopts.push_back (string(optarg));
bb25d08f
RH
580 break;
581
e2012a7a 582 case 't':
372c6458 583 server_args.push_back (string ("-") + (char)grc);
e2012a7a
DB
584 timing = true;
585 break;
586
587 case 'w':
372c6458 588 server_args.push_back (string ("-") + (char)grc);
e2012a7a
DB
589 suppress_warnings = true;
590 break;
591
592 case 'W':
372c6458 593 server_args.push_back (string ("-") + (char)grc);
e2012a7a
DB
594 panic_warnings = true;
595 break;
596
597 case 'p':
598 last_pass = (int)strtoul(optarg, &num_endptr, 10);
599 if (*num_endptr != '\0' || last_pass < 1 || last_pass > 5)
600 {
79bc39ab 601 cerr << _("Invalid pass number (should be 1-5).") << endl;
e2012a7a
DB
602 return 1;
603 }
604 if (listing_mode && last_pass != 2)
605 {
79bc39ab 606 cerr << _("Listing (-l) mode implies pass 2.") << endl;
e2012a7a
DB
607 return 1;
608 }
372c6458 609 server_args.push_back (string ("-") + (char)grc + optarg);
e2012a7a
DB
610 break;
611
612 case 'I':
613 if (client_options)
372c6458 614 client_options_disallowed_for_unprivileged += client_options_disallowed_for_unprivileged.empty () ? "-I" : ", -I";
2fad97fd
DB
615 if (include_arg_start == -1)
616 include_arg_start = include_path.size ();
e2012a7a
DB
617 include_path.push_back (string (optarg));
618 break;
619
620 case 'd':
372c6458 621 server_args.push_back (string ("-") + (char)grc + optarg);
e2012a7a
DB
622 {
623 // At runtime user module names are resolved through their
624 // canonical (absolute) path.
625 const char *mpath = canonicalize_file_name (optarg);
626 if (mpath == NULL) // Must be a kernel module name
627 mpath = optarg;
628 unwindsym_modules.insert (string (mpath));
a057c85c
MW
629 // PR10228: trigger vma tracker logic early if -d /USER-MODULE/
630 // given. XXX This is actually too early. Having a user module
631 // is a good indicator that something will need vma tracking.
632 // But it is not 100%, this really should only trigger through
633 // a user mode tapset /* pragma:vma */ or a probe doing a
634 // variable lookup through a dynamic module.
e2012a7a 635 if (mpath[0] == '/')
a057c85c 636 enable_vma_tracker (*this);
e2012a7a
DB
637 break;
638 }
639
640 case 'e':
641 if (have_script)
642 {
79bc39ab 643 cerr << _("Only one script can be given on the command line.")
e2012a7a
DB
644 << endl;
645 return 1;
646 }
372c6458 647 server_args.push_back (string ("-") + (char)grc + optarg);
e2012a7a
DB
648 cmdline_script = string (optarg);
649 have_script = true;
650 break;
651
652 case 'o':
653 // NB: client_options not a problem, since pass 1-4 does not use output_file.
372c6458 654 server_args.push_back (string ("-") + (char)grc + optarg);
e2012a7a
DB
655 output_file = string (optarg);
656 break;
657
658 case 'R':
ce0f6648 659 if (client_options) { cerr << _F("ERROR: %s invalid with %s", "-R", "--client-options") << endl; return 1; }
2fad97fd 660 runtime_specified = true;
e2012a7a
DB
661 runtime_path = string (optarg);
662 break;
663
664 case 'm':
665 if (client_options)
372c6458 666 client_options_disallowed_for_unprivileged += client_options_disallowed_for_unprivileged.empty () ? "-m" : ", -m";
e2012a7a
DB
667 module_name = string (optarg);
668 save_module = true;
5c854d7c 669 modname_given = true;
e2012a7a
DB
670 {
671 // If the module name ends with '.ko', chop it off since
672 // modutils doesn't like modules named 'foo.ko.ko'.
673 if (endswith(module_name, ".ko"))
674 {
675 module_name.erase(module_name.size() - 3);
46a1a151 676 cerr << _F("Truncating module name to '%s'", module_name.c_str()) << endl;
e2012a7a
DB
677 }
678
679 // Make sure an empty module name wasn't specified (-m "")
680 if (module_name.empty())
681 {
79bc39ab 682 cerr << _("Module name cannot be empty.") << endl;
e2012a7a
DB
683 return 1;
684 }
685
686 // Make sure the module name is only composed of the
2b7d9d84
RH
687 // following chars: [a-z0-9_]
688 assert_regexp_match("-m parameter", module_name, "^[a-z0-9_]+$");
e2012a7a
DB
689
690 // Make sure module name isn't too long.
691 if (module_name.size() >= (MODULE_NAME_LEN - 1))
692 {
693 module_name.resize(MODULE_NAME_LEN - 1);
46a1a151 694 cerr << _F("Truncating module name to '%s'", module_name.c_str()) << endl;
e2012a7a
DB
695 }
696 }
697
372c6458 698 server_args.push_back (string ("-") + (char)grc + optarg);
e2012a7a
DB
699 use_script_cache = false;
700 break;
701
702 case 'r':
703 if (client_options) // NB: no paths!
704 assert_regexp_match("-r parameter from client", optarg, "^[a-z0-9_.-]+$");
372c6458 705 server_args.push_back (string ("-") + (char)grc + optarg);
e2012a7a
DB
706 setup_kernel_release(optarg);
707 break;
708
709 case 'a':
710 assert_regexp_match("-a parameter", optarg, "^[a-z0-9_-]+$");
372c6458 711 server_args.push_back (string ("-") + (char)grc + optarg);
e2012a7a
DB
712 architecture = string(optarg);
713 break;
714
715 case 'k':
71a522b5 716 if (client_options) { cerr << _F("ERROR: %s invalid with %s", "-k", "--client-options") << endl; return 1; }
e2012a7a
DB
717 keep_tmpdir = true;
718 use_script_cache = false; /* User wants to keep a usable build tree. */
719 break;
720
721 case 'g':
372c6458 722 server_args.push_back (string ("-") + (char)grc);
e2012a7a
DB
723 guru_mode = true;
724 break;
725
726 case 'P':
372c6458 727 server_args.push_back (string ("-") + (char)grc);
e2012a7a
DB
728 prologue_searching = true;
729 break;
730
731 case 'b':
372c6458 732 server_args.push_back (string ("-") + (char)grc);
e2012a7a
DB
733 bulk_mode = true;
734 break;
735
736 case 'u':
372c6458 737 server_args.push_back (string ("-") + (char)grc);
e2012a7a
DB
738 unoptimized = true;
739 break;
740
741 case 's':
742 buffer_size = (int) strtoul (optarg, &num_endptr, 10);
743 if (*num_endptr != '\0' || buffer_size < 1 || buffer_size > 4095)
744 {
79bc39ab 745 cerr << _("Invalid buffer size (should be 1-4095).") << endl;
e2012a7a
DB
746 return 1;
747 }
372c6458 748 server_args.push_back (string ("-") + (char)grc + optarg);
e2012a7a
DB
749 break;
750
751 case 'c':
752 cmd = string (optarg);
2d363b75
FCE
753 if (cmd == "")
754 {
755 // This would mess with later code deciding to pass -c
756 // through to staprun
79bc39ab 757 cerr << _("Empty CMD string invalid.") << endl;
2d363b75
FCE
758 return 1;
759 }
372c6458 760 server_args.push_back (string ("-") + (char)grc + optarg);
e2012a7a
DB
761 break;
762
763 case 'x':
764 target_pid = (int) strtoul(optarg, &num_endptr, 10);
765 if (*num_endptr != '\0')
766 {
79bc39ab 767 cerr << _("Invalid target process ID number.") << endl;
e2012a7a
DB
768 return 1;
769 }
372c6458 770 server_args.push_back (string ("-") + (char)grc + optarg);
e2012a7a
DB
771 break;
772
773 case 'D':
774 assert_regexp_match ("-D parameter", optarg, "^[a-z_][a-z_0-9]*(=-?[a-z_0-9]+)?$");
775 if (client_options)
372c6458
DB
776 client_options_disallowed_for_unprivileged += client_options_disallowed_for_unprivileged.empty () ? "-D" : ", -D";
777 server_args.push_back (string ("-") + (char)grc + optarg);
e2012a7a
DB
778 macros.push_back (string (optarg));
779 break;
780
781 case 'S':
782 assert_regexp_match ("-S parameter", optarg, "^[0-9]+(,[0-9]+)?$");
372c6458 783 server_args.push_back (string ("-") + (char)grc + optarg);
e2012a7a
DB
784 size_option = string (optarg);
785 break;
786
787 case 'q':
ce0f6648 788 if (client_options) { cerr << _F("ERROR: %s invalid with %s", "-q", "--client-options") << endl; return 1; }
372c6458 789 server_args.push_back (string ("-") + (char)grc);
e2012a7a
DB
790 tapset_compile_coverage = true;
791 break;
792
793 case 'h':
794 usage (0);
795 break;
796
797 case 'L':
798 listing_mode_vars = true;
799 unoptimized = true; // This causes retention of variables for listing_mode
68ac5d0e 800 // fallthrough
e2012a7a
DB
801 case 'l':
802 suppress_warnings = true;
803 listing_mode = true;
804 last_pass = 2;
805 if (have_script)
806 {
79bc39ab 807 cerr << _("Only one script can be given on the command line.")
e2012a7a
DB
808 << endl;
809 return 1;
810 }
372c6458 811 server_args.push_back (string ("-") + (char)grc + optarg);
e2012a7a
DB
812 cmdline_script = string("probe ") + string(optarg) + " {}";
813 have_script = true;
814 break;
815
816 case 'F':
372c6458 817 server_args.push_back (string ("-") + (char)grc);
e2012a7a
DB
818 load_only = true;
819 break;
820
821 case 'B':
ce0f6648 822 if (client_options) { cerr << _F("ERROR: %s invalid with %s", "-B", "--client-options") << endl; return 1; }
372c6458 823 server_args.push_back (string ("-") + (char)grc + optarg);
e2012a7a
DB
824 kbuildflags.push_back (string (optarg));
825 break;
826
372c6458
DB
827 case LONG_OPT_VERSION:
828 version ();
829 exit (0);
830 break;
831
832 case LONG_OPT_KELF:
833 server_args.push_back ("--kelf");
834 consult_symtab = true;
835 break;
836
837 case LONG_OPT_KMAP:
838 // Leave consult_symtab unset for now, to ease error checking.
839 if (!kernel_symtab_path.empty())
840 {
841 cerr << _("You can't specify multiple --kmap options.") << endl;
842 return 1;
843 }
844 if (optarg) {
845 kernel_symtab_path = optarg;
846 server_args.push_back ("--kmap=" + string(optarg));
847 }
848 else {
849 kernel_symtab_path = PATH_TBD;
850 server_args.push_back ("--kmap");
851 }
852 break;
853
854 case LONG_OPT_IGNORE_VMLINUX:
855 server_args.push_back ("--ignore-vmlinux");
856 ignore_vmlinux = true;
857 break;
858
859 case LONG_OPT_IGNORE_DWARF:
860 server_args.push_back ("--ignore-dwarf");
861 ignore_dwarf = true;
862 break;
863
864 case LONG_OPT_VERBOSE_PASS:
865 {
866 bool ok = true;
867 if (strlen(optarg) < 1 || strlen(optarg) > 5)
868 ok = false;
869 if (ok)
870 for (unsigned i=0; i<strlen(optarg); i++)
871 if (isdigit (optarg[i]))
872 perpass_verbose[i] += optarg[i]-'0';
873 else
874 ok = false;
e2012a7a 875
372c6458 876 if (! ok)
73f52eb4 877 {
372c6458
DB
878 cerr << _("Invalid --vp argument: it takes 1 to 5 digits.") << endl;
879 return 1;
73f52eb4 880 }
372c6458
DB
881 // NB: we don't do this: last_pass = strlen(optarg);
882 server_args.push_back ("--vp=" + string(optarg));
883 break;
884 }
885
886 case LONG_OPT_SKIP_BADVARS:
887 server_args.push_back ("--skip-badvars");
888 skip_badvars = true;
889 break;
890
891 case LONG_OPT_PRIVILEGE:
892 {
893 // We allow only multiple privilege-setting options if they all specify the same
894 // privilege level. The server also expects and depends on this behaviour when
895 // examining the client-side options passed to it.
896 privilege_t newPrivilege;
897 if (strcmp (optarg, "stapdev") == 0)
898 newPrivilege = pr_stapdev;
899 else if (strcmp (optarg, "stapsys") == 0)
900 newPrivilege = pr_stapsys;
901 else if (strcmp (optarg, "stapusr") == 0)
902 newPrivilege = pr_stapusr;
903 else
904 {
905 cerr << _F("Invalid argument '%s' for --privilege.", optarg) << endl;
906 return 1;
907 }
908 if (privilege_set && newPrivilege != privilege)
909 {
910 cerr << _("Privilege level may be set only once.") << endl;
911 return 1;
912 }
913 privilege = newPrivilege;
914 privilege_set = true;
915 server_args.push_back ("--privilege=" + string(optarg));
916 }
917 /* NB: for server security, it is essential that once this flag is
918 set, no future flag be able to unset it. */
919 break;
920
921 case LONG_OPT_UNPRIVILEGED:
922 // We allow only multiple privilege-setting options if they all specify the same
923 // privilege level. The server also expects and depends on this behaviour when
924 // examining the client-side options passed to it.
925 if (privilege_set && pr_unprivileged != privilege)
926 {
927 cerr << _("Privilege level may be set only once.") << endl;
928 return 1;
929 }
930 privilege = pr_unprivileged;
931 privilege_set = true;
932 server_args.push_back ("--unprivileged");
933 /* NB: for server security, it is essential that once this flag is
934 set, no future flag be able to unset it. */
935 break;
936
937 case LONG_OPT_OMIT_WERROR:
938 server_args.push_back (OMIT_WERROR_NAME);
939 omit_werror = true;
940 break;
941
942 case LONG_OPT_CLIENT_OPTIONS:
943 client_options = true;
944 break;
945
946 case LONG_OPT_TMPDIR:
947 if (client_options) {
948 cerr << _F("ERROR: %s is invalid with %s", "--tmpdir", "--client-options") << endl;
949 return 1;
950 }
951 tmpdir_opt_set = true;
952 tmpdir = optarg;
953 break;
954
955 case LONG_OPT_DOWNLOAD_DEBUGINFO:
956 if(optarg)
957 {
958 if(strcmp(optarg, "no") == 0)
959 download_dbinfo = 0; //Disable feature
960 else if (strcmp(optarg, "yes") == 0)
961 download_dbinfo = INT_MAX; //Enable, No Timeout
962 /* NOTE: Timeout and Asking for Confirmation features below are not supported yet by abrt
963 * in version abrt-2.0.3-1.fc15.x86_64, Bugzilla: BZ730107 (timeout), BZ726192 ('-y') */
964 else if(atoi(optarg) > 0)
965 download_dbinfo = atoi(optarg); //Enable, Set timeout to optarg
966 else if (strcmp(optarg, "ask") == 0)
967 download_dbinfo = -1; //Enable, Ask for confirmation
2dce8c42 968 else
44edbcd6 969 {
372c6458
DB
970 cerr << _F("ERROR: %s is not a valid value. Use 'yes', 'no', 'ask' or a timeout value.", optarg) << endl;
971 return 1;
44edbcd6 972 }
372c6458
DB
973 }
974 else
975 download_dbinfo = INT_MAX; //Enable, No Timeout
976 break;
977
978 case LONG_OPT_USE_SERVER:
979 if (client_options) {
980 cerr << _F("ERROR: %s is invalid with %s", "--use-server", "--client-options") << endl;
981 return 1;
982 }
983 if (optarg)
984 specified_servers.push_back (optarg);
985 else
986 specified_servers.push_back ("");
987 break;
988
989 case LONG_OPT_USE_SERVER_ON_ERROR:
990 if (client_options) {
991 cerr << _F("ERROR: %s is invalid with %s", "--use-server-on-error", "--client-options") << endl;
992 return 1;
993 }
994 if (optarg)
995 {
996 string arg = optarg;
997 for (unsigned i = 0; i < arg.size (); ++i)
998 arg[i] = tolower (arg[i]);
999 if (arg == "yes" || arg == "ye" || arg == "y")
44edbcd6 1000 use_server_on_error = true;
372c6458
DB
1001 else if (arg == "no" || arg == "n")
1002 use_server_on_error = false;
2dce8c42 1003 else
372c6458
DB
1004 cerr << _F("Invalid argument '%s' for --use-server-on-error.", optarg) << endl;
1005 }
1006 else
1007 use_server_on_error = true;
1008 break;
1009
1010 case LONG_OPT_LIST_SERVERS:
1011 if (client_options) {
1012 cerr << _F("ERROR: %s is invalid with %s", "--list-servers", "--client-options") << endl;
1013 return 1;
1014 }
1015 if (optarg)
1016 server_status_strings.push_back (optarg);
1017 else
1018 server_status_strings.push_back ("");
1019 break;
1020
1021 case LONG_OPT_TRUST_SERVERS:
1022 if (client_options) {
1023 cerr << _F("ERROR: %s is invalid with %s", "--trust-servers", "--client-options") << endl;
1024 return 1;
1025 }
1026 if (optarg)
1027 server_trust_spec = optarg;
1028 else
1029 server_trust_spec = "ssl";
1030 break;
1031
1032 case LONG_OPT_HELP:
1033 usage (0);
1034 break;
1035
1036 // The caching options should not be available to server clients
1037 case LONG_OPT_DISABLE_CACHE:
1038 if (client_options) {
1039 cerr << _F("ERROR: %s is invalid with %s", "--disable-cache", "--client-options") << endl;
1040 return 1;
1041 }
1042 use_cache = use_script_cache = false;
1043 break;
1044
1045 case LONG_OPT_POISON_CACHE:
1046 if (client_options) {
1047 cerr << _F("ERROR: %s is invalid with %s", "--poison-cache", "--client-options") << endl;
1048 return 1;
1049 }
1050 poison_cache = true;
1051 break;
1052
1053 case LONG_OPT_CLEAN_CACHE:
1054 if (client_options) {
1055 cerr << _F("ERROR: %s is invalid with %s", "--clean-cache", "--client-options") << endl;
1056 return 1;
1057 }
1058 clean_cache(*this);
1059 exit(0);
1060
1061 case LONG_OPT_COMPATIBLE:
1062 server_args.push_back ("--compatible=" + string(optarg));
1063 compatible = optarg;
1064 break;
1065
1066 case LONG_OPT_LDD:
1067 if (client_options) {
1068 cerr << _F("ERROR: %s is invalid with %s", "--ldd", "--client-options") << endl;
1069 return 1;
1070 }
1071 unwindsym_ldd = true;
1072 break;
1073
1074 case LONG_OPT_ALL_MODULES:
1075 if (client_options) {
1076 cerr << _F("ERROR: %s is invalid with %s", "--all-modules", "--client-options") << endl;
1077 return 1;
1078 }
1079 insert_loaded_modules();
1080 break;
1081
1082 case LONG_OPT_REMOTE:
1083 if (client_options) {
1084 cerr << _F("ERROR: %s is invalid with %s", "--remote", "--client-options") << endl;
1085 return 1;
1086 }
1087
1088 remote_uris.push_back(optarg);
1089 break;
1090
1091 case LONG_OPT_REMOTE_PREFIX:
1092 if (client_options) {
1093 cerr << _F("ERROR: %s is invalid with %s", "--remote-prefix", "--client-options") << endl;
1094 return 1;
1095 }
1096
1097 use_remote_prefix = true;
1098 break;
1099
1100 case LONG_OPT_CHECK_VERSION:
1101 server_args.push_back ("--check-version");
1102 systemtap_v_check = true;
1103 break;
1104
1105 case LONG_OPT_DUMP_PROBE_TYPES:
1106 server_args.push_back ("--dump-probe-types");
1107 dump_probe_types = true;
1108 break;
1109
1110 case LONG_OPT_SUPPRESS_HANDLER_ERRORS:
1111 suppress_handler_errors = true;
1112 break;
1113
1114 case LONG_OPT_MODINFO:
1115 // Make sure the global option is only composed of the
1116 // following chars: [_=a-zA-Z0-9]
1117 if (client_options) {
1118 cerr << _F("ERROR: %s is invalid with %s", "--modinfo", "--client-options") << endl;
1119 return 1;
1120 }
1121 assert_regexp_match("--modinfo parameter", optarg, "^[a-z_][a-z0-9_]*=.+$");
1122 modinfos.push_back (string(optarg));
1123 break;
e2012a7a 1124
36222574
MW
1125 case '?':
1126 // Invalid/unrecognized option given or argument required, but
1127 // not given. In both cases getopt_long() will have printed the
1128 // appropriate error message to stderr already.
1129 return 1;
1130 break;
1131
e2012a7a 1132 default:
372c6458 1133 // NOTREACHED unless one added a getopt option but not a corresponding case:
46a1a151 1134 cerr << _F("Unhandled argument code %d", (char)grc) << endl;
e2012a7a
DB
1135 return 1;
1136 break;
1137 }
1138 }
1139
1140 return 0;
1141}
1142
1143void
1144systemtap_session::check_options (int argc, char * const argv [])
1145{
a83cc46b
DB
1146 for (int i = optind; i < argc; i++)
1147 {
1148 if (! have_script)
1149 {
1150 script_file = string (argv[i]);
1151 have_script = true;
1152 }
1153 else
1154 args.push_back (string (argv[i]));
1155 }
1156
1157 // need a user file
1158 // NB: this is also triggered if stap is invoked with no arguments at all
1159 if (! have_script)
1160 {
b82d77b4
DB
1161 // We don't need a script if --list-servers, --trust-servers or --dump-probe-types was
1162 // specified.
1163 if (server_status_strings.empty () && server_trust_spec.empty () && ! dump_probe_types)
a83cc46b 1164 {
79bc39ab 1165 cerr << _("A script must be specified.") << endl;
a83cc46b
DB
1166 usage(1);
1167 }
1168 }
1169
2dce8c42
DB
1170#if ! HAVE_NSS
1171 if (client_options)
2713ea24 1172 print_warning("--client-options is not supported by this version of systemtap");
2dce8c42 1173
c77af0d0
DB
1174 if (! server_trust_spec.empty ())
1175 {
2713ea24 1176 print_warning("--trust-servers is not supported by this version of systemtap");
c77af0d0
DB
1177 server_trust_spec.clear ();
1178 }
1179#endif
2dce8c42 1180
2fad97fd
DB
1181 if (runtime_specified && ! specified_servers.empty ())
1182 {
2713ea24 1183 print_warning("Ignoring --use-server due to the use of -R");
2fad97fd
DB
1184 specified_servers.clear ();
1185 }
1186
e2012a7a
DB
1187 if (client_options && last_pass > 4)
1188 {
1189 last_pass = 4; /* Quietly downgrade. Server passed through -p5 naively. */
1190 }
f6be7c06
DB
1191
1192 // If phase 5 has been requested, automatically adjust the --privilege setting to match the
1193 // user's actual privilege level and add --use-server, if necessary.
73f52eb4 1194 // Do this only if we have a script and we are not the server.
dbf065b9 1195 // XXX Eventually we could check remote hosts, but disable that case for now.
73f52eb4 1196 if (last_pass > 4 && have_script && ! client_options && remote_uris.empty())
a83cc46b 1197 {
f6be7c06
DB
1198 // What is the user's privilege level?
1199 privilege_t credentials = get_privilege_credentials ();
73f52eb4
DB
1200 // Don't alter specifically-requested privilege levels
1201 if (! privilege_set && ! pr_contains (credentials, privilege))
a83cc46b 1202 {
73f52eb4 1203 // We do not have the default privilege credentials (stapdev). Lower
bb4470ca
DB
1204 // the privilege level to match our credentials.
1205 if (pr_contains (credentials, pr_stapsys))
a83cc46b 1206 {
bb4470ca
DB
1207 if (perpass_verbose[0] > 1)
1208 cerr << _("Using --privilege=stapsys for member of the group stapsys") << endl;
1209 privilege = pr_stapsys;
1210 server_args.push_back ("--privilege=stapsys");
a83cc46b 1211 }
bb4470ca
DB
1212 else if (pr_contains (credentials, pr_stapusr))
1213 {
1214 if (perpass_verbose[0] > 1)
1215 cerr << _("Using --privilege=stapusr for member of the group stapusr") << endl;
1216 privilege = pr_stapusr;
1217 server_args.push_back ("--privilege=stapusr");
1218 }
1219 else
1220 {
1221 // Completely unprivileged user.
1222 cerr << _("You are trying to run systemtap as a normal user.\n"
1223 "You should either be root, or be part of "
1224 "the group \"stapusr\" and possibly one of the groups \"stapsys\" or \"stapdev\".\n");
1225 usage (1); // does not return.
1226 }
1227 }
bb4470ca
DB
1228 // Add --use-server if not already specified and the user's (lack of) credentials require
1229 // it for pass 5.
1230 if (! pr_contains (credentials, pr_stapdev))
1231 {
f6be7c06
DB
1232 if (specified_servers.empty ())
1233 {
1234 if (perpass_verbose[0] > 1)
1235 cerr << _F("Using --use-server for user with privilege level %s",
1236 pr_name (privilege))
1237 << endl;
1238 specified_servers.push_back ("");
1239 }
a83cc46b
DB
1240 }
1241 }
1242
372c6458 1243 if (client_options && ! pr_contains (privilege, pr_stapdev) && ! client_options_disallowed_for_unprivileged.empty ())
e2012a7a 1244 {
f66bb29a 1245 cerr << _F("You can't specify %s when --privilege=%s is specified.",
372c6458 1246 client_options_disallowed_for_unprivileged.c_str(),
f66bb29a
DB
1247 pr_name (privilege))
1248 << endl;
e2012a7a
DB
1249 usage (1);
1250 }
1251 if ((cmd != "") && (target_pid))
1252 {
ce0f6648 1253 cerr << _F("You can't specify %s and %s together.", "-c", "-x") << endl;
e2012a7a
DB
1254 usage (1);
1255 }
f66bb29a 1256 if (! pr_contains (privilege, pr_stapdev) && guru_mode)
e2012a7a 1257 {
f66bb29a
DB
1258 cerr << _F("You can't specify %s and --privilege=%s together.", "-g", pr_name (privilege))
1259 << endl;
e2012a7a
DB
1260 usage (1);
1261 }
1262 if (!kernel_symtab_path.empty())
1263 {
1264 if (consult_symtab)
1265 {
ce0f6648 1266 cerr << _F("You can't specify %s and %s together.", "--kelf", "--kmap") << endl;
e2012a7a
DB
1267 usage (1);
1268 }
1269 consult_symtab = true;
1270 if (kernel_symtab_path == PATH_TBD)
1271 kernel_symtab_path = string("/boot/System.map-") + kernel_release;
1272 }
305fac7d
CM
1273 // Can't use --remote and --tmpdir together because with --remote,
1274 // there may be more than one tmpdir needed.
1275 if (!remote_uris.empty() && tmpdir_opt_set)
1276 {
1277 cerr << _F("You can't specify %s and %s together.", "--remote", "--tmpdir") << endl;
1278 usage(1);
1279 }
e2012a7a 1280 // Warn in case the target kernel release doesn't match the running one.
50f2545f
FCE
1281 native_build = (release == kernel_release &&
1282 machine == architecture); // NB: squashed ARCH by PR4186 logic
1283
19da0351
JS
1284 // Non-native builds can't be loaded locally, but may still work on remotes
1285 if (last_pass > 4 && !native_build && remote_uris.empty())
50f2545f 1286 {
2713ea24 1287 print_warning("kernel release/architecture mismatch with host forces last-pass 4.");
50f2545f
FCE
1288 last_pass = 4;
1289 }
0ba354fe
CM
1290 if(download_dbinfo != 0 && access ("/usr/bin/abrt-action-install-debuginfo-to-abrt-cache", X_OK) < 0
1291 && access ("/usr/libexec/abrt-action-install-debuginfo-to-abrt-cache", X_OK) < 0)
ea60076d 1292 {
0ba354fe 1293 print_warning("abrt-action-install-debuginfo-to-abrt-cache is not installed. Continuing without downloading debuginfo.");
ea60076d
CM
1294 download_dbinfo = 0;
1295 }
e2012a7a 1296
e2012a7a
DB
1297 // translate path of runtime to absolute path
1298 if (runtime_path[0] != '/')
1299 {
1300 char cwd[PATH_MAX];
1301 if (getcwd(cwd, sizeof(cwd)))
1302 {
1303 runtime_path = string(cwd) + "/" + runtime_path;
1304 }
1305 }
44edbcd6
JS
1306
1307 // Abnormal characters in our temp path can break us, including parts out
1308 // of our control like Kbuild. Let's enforce nice, safe characters only.
1309 const char *tmpdir = getenv("TMPDIR");
fc4cb088 1310 if (tmpdir != NULL)
44edbcd6 1311 assert_regexp_match("TMPDIR", tmpdir, "^[-/._0-9a-z]+$");
ce286ff0
DB
1312}
1313
44edbcd6
JS
1314
1315void
1316systemtap_session::init_try_server ()
1317{
1318#if HAVE_NSS
1319 // If the option is disabled or we are a server or we are already using a
1320 // server, then never retry compilation using a server.
1321 if (! use_server_on_error || client_options || ! specified_servers.empty ())
1322 try_server_status = dont_try_server;
1323 else
1324 try_server_status = try_server_unset;
1325#else
1326 // No client, so don't bother.
1327 try_server_status = dont_try_server;
1328#endif
1329}
1330
1331void
1332systemtap_session::set_try_server (int t)
1333{
1334 if (try_server_status != dont_try_server)
1335 try_server_status = t;
1336}
1337
1338
c1743705
AK
1339void systemtap_session::insert_loaded_modules()
1340{
1341 char line[1024];
1342 ifstream procmods ("/proc/modules");
1343 while (procmods.good()) {
1344 procmods.getline (line, sizeof(line));
1345 strtok(line, " \t");
1346 if (line[0] == '\0')
1347 break; // maybe print a warning?
1348 unwindsym_modules.insert (string (line));
1349 }
1350 procmods.close();
eebd081d 1351 unwindsym_modules.insert ("kernel");
c1743705
AK
1352}
1353
e2012a7a
DB
1354void
1355systemtap_session::setup_kernel_release (const char* kstr)
1356{
4f747a64
JS
1357 // Sometimes we may get dupes here... e.g. a server may have a full
1358 // -r /path/to/kernel followed by a client's -r kernel.
1359 if (kernel_release == kstr)
1360 return; // nothing new here...
1361
504d2b61 1362 kernel_release = kernel_build_tree = kernel_source_tree = "";
e2012a7a
DB
1363 if (kstr[0] == '/') // fully specified path
1364 {
1365 kernel_build_tree = kstr;
aeb9cc10 1366 kernel_release = kernel_release_from_build_tree (kernel_build_tree, verbose);
61f1a63b
FCE
1367
1368 // PR10745
1369 // Maybe it's a full kernel source tree, for purposes of PR10745.
1370 // In case CONFIG_DEBUG_INFO was set, we'd find it anyway with the
1371 // normal search in tapsets.cxx. Without CONFIG_DEBUG_INFO, we'd
1372 // need heuristics such as this one:
1373
1374 string some_random_source_only_file = kernel_build_tree + "/COPYING";
1375 ifstream epic (some_random_source_only_file.c_str());
1376 if (! epic.fail())
1377 {
1378 kernel_source_tree = kernel_build_tree;
1379 if (verbose > 2)
46a1a151 1380 clog << _F("Located kernel source tree (COPYING) at '%s'", kernel_source_tree.c_str()) << endl;
61f1a63b 1381 }
e2012a7a
DB
1382 }
1383 else
1384 {
1385 kernel_release = string (kstr);
504d2b61
JS
1386 if (!kernel_release.empty())
1387 kernel_build_tree = "/lib/modules/" + kernel_release + "/build";
61f1a63b
FCE
1388
1389 // PR10745
1390 // Let's not look for the kernel_source_tree; it's definitely
1391 // not THERE. tapsets.cxx might try to find it later if tracepoints
1392 // need it.
e2012a7a
DB
1393 }
1394}
1395
1396
1397// Register all the aliases we've seen in library files, and the user
1398// file, as patterns.
1399void
1400systemtap_session::register_library_aliases()
1401{
1402 vector<stapfile*> files(library_files);
1403 files.push_back(user_file);
1404
1405 for (unsigned f = 0; f < files.size(); ++f)
1406 {
1407 stapfile * file = files[f];
1408 for (unsigned a = 0; a < file->aliases.size(); ++a)
1409 {
1410 probe_alias * alias = file->aliases[a];
1411 try
1412 {
1413 for (unsigned n = 0; n < alias->alias_names.size(); ++n)
1414 {
1415 probe_point * name = alias->alias_names[n];
6f58d8ae 1416 match_node * mn = pattern_root;
e2012a7a
DB
1417 for (unsigned c = 0; c < name->components.size(); ++c)
1418 {
1419 probe_point::component * comp = name->components[c];
1420 // XXX: alias parameters
1421 if (comp->arg)
46a1a151
JS
1422 throw semantic_error(_F("alias component %s contains illegal parameter",
1423 comp->functor.c_str()));
6f58d8ae 1424 mn = mn->bind(comp->functor);
e2012a7a 1425 }
f66bb29a 1426 // PR 12916: All probe aliases are OK for all users. The actual
373027ba 1427 // referenced probe points will be checked when the alias is resolved.
f66bb29a 1428 mn->bind_privilege (pr_all);
6f58d8ae 1429 mn->bind(new alias_expansion_builder(alias));
e2012a7a
DB
1430 }
1431 }
1432 catch (const semantic_error& e)
1433 {
1434 semantic_error* er = new semantic_error (e); // copy it
1435 stringstream msg;
1436 msg << e.msg2;
79bc39ab 1437 msg << _(" while registering probe alias ");
e2012a7a
DB
1438 alias->printsig(msg);
1439 er->msg2 = msg.str();
1440 print_error (* er);
1441 delete er;
1442 }
1443 }
1444 }
1445}
1446
1447
1448// Print this given token, but abbreviate it if the last one had the
1449// same file name.
1450void
1451systemtap_session::print_token (ostream& o, const token* tok)
1452{
1453 assert (tok);
1454
1455 if (last_token && last_token->location.file == tok->location.file)
1456 {
1457 stringstream tmpo;
1458 tmpo << *tok;
1459 string ts = tmpo.str();
1460 // search & replace the file name with nothing
1461 size_t idx = ts.find (tok->location.file->name);
1462 if (idx != string::npos)
1463 ts.replace (idx, tok->location.file->name.size(), "");
1464
1465 o << ts;
1466 }
1467 else
1468 o << *tok;
1469
1470 last_token = tok;
1471}
1472
1473
1474
1475void
1476systemtap_session::print_error (const semantic_error& e)
1477{
1478 string message_str[2];
1479 string align_semantic_error (" ");
1480
1481 // We generate two messages. The second one ([1]) is printed
1482 // without token compression, for purposes of duplicate elimination.
1483 // This way, the same message that may be generated once with a
1484 // compressed and once with an uncompressed token still only gets
1485 // printed once.
1486 for (int i=0; i<2; i++)
1487 {
1488 stringstream message;
1489
46a1a151 1490 message << _F("semantic error: %s", e.what ());
e2012a7a
DB
1491 if (e.tok1 || e.tok2)
1492 message << ": ";
1493 if (e.tok1)
1494 {
1495 if (i == 0) print_token (message, e.tok1);
1496 else message << *e.tok1;
1497 }
1498 message << e.msg2;
1499 if (e.tok2)
1500 {
1501 if (i == 0) print_token (message, e.tok2);
1502 else message << *e.tok2;
1503 }
1504 message << endl;
1505 message_str[i] = message.str();
1506 }
1507
1508 // Duplicate elimination
1509 if (seen_errors.find (message_str[1]) == seen_errors.end())
1510 {
1511 seen_errors.insert (message_str[1]);
1512 cerr << message_str[0];
1513
1514 if (e.tok1)
1515 print_error_source (cerr, align_semantic_error, e.tok1);
1516
1517 if (e.tok2)
1518 print_error_source (cerr, align_semantic_error, e.tok2);
1519 }
1520
1521 if (e.chain)
1522 print_error (* e.chain);
1523}
1524
1525void
1526systemtap_session::print_error_source (std::ostream& message,
1527 std::string& align, const token* tok)
1528{
1529 unsigned i = 0;
1530
1531 assert (tok);
1532 if (!tok->location.file)
1533 //No source to print, silently exit
1534 return;
1535
1536 unsigned line = tok->location.line;
1537 unsigned col = tok->location.column;
1538 const string &file_contents = tok->location.file->file_contents;
1539
1540 size_t start_pos = 0, end_pos = 0;
1541 //Navigate to the appropriate line
1542 while (i != line && end_pos != std::string::npos)
1543 {
1544 start_pos = end_pos;
1545 end_pos = file_contents.find ('\n', start_pos) + 1;
1546 i++;
1547 }
efee9a98
LB
1548 //TRANSLATORS: Here were are printing the source string of the error
1549 message << align << _("source: ") << file_contents.substr (start_pos, end_pos-start_pos-1) << endl;
e2012a7a
DB
1550 message << align << " ";
1551 //Navigate to the appropriate column
1552 for (i=start_pos; i<start_pos+col-1; i++)
1553 {
1554 if(isspace(file_contents[i]))
1555 message << file_contents[i];
1556 else
1557 message << ' ';
1558 }
1559 message << "^" << endl;
1560}
1561
1562void
1563systemtap_session::print_warning (const string& message_str, const token* tok)
1564{
2713ea24
CM
1565 if(suppress_warnings)
1566 return;
1567
e2012a7a
DB
1568 // Duplicate elimination
1569 string align_warning (" ");
1570 if (seen_warnings.find (message_str) == seen_warnings.end())
1571 {
1572 seen_warnings.insert (message_str);
79bc39ab 1573 clog << _("WARNING: ") << message_str;
e2012a7a
DB
1574 if (tok) { clog << ": "; print_token (clog, tok); }
1575 clog << endl;
1576 if (tok) { print_error_source (clog, align_warning, tok); }
1577 }
1578}
1579
a4b9c3b3
FCE
1580
1581translator_output* systemtap_session::op_create_auxiliary()
1582{
1583 static int counter = 0;
1584 string tmpname = this->tmpdir + "/" + this->module_name + "_aux_" + lex_cast(counter++) + ".c";
1585 translator_output* n = new translator_output (tmpname);
1586 auxiliary_outputs.push_back (n);
1587 return n;
1588}
1589
1590
1591
2dce8c42
DB
1592// --------------------------------------------------------------------------
1593
e2012a7a
DB
1594/*
1595Perngrq sebz fzvyrlgnc.fit, rkcbegrq gb n 1484k1110 fzvyrlgnc.cat,
1596gurapr catgbcnz | cazfpnyr -jvqgu 160 |
1597cczqvgure -qvz 4 -erq 2 -terra 2 -oyhr 2 | cczgbnafv -2k4 | bq -i -j19 -g k1 |
1598phg -s2- -q' ' | frq -r 'f,^,\\k,' -r 'f, ,\\k,t' -r 'f,^,",' -r 'f,$,",'
1599*/
1600const char*
1601systemtap_session::morehelp =
1602"\x1b\x5b\x30\x6d\x1b\x5b\x33\x37\x6d\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1603"\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1604"\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1605"\x20\x20\x20\x60\x20\x20\x2e\x60\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1606"\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20"
1607"\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1608"\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1609"\x20\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x1b\x5b"
1610"\x33\x33\x6d\x20\x1b\x5b\x33\x37\x6d\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1611"\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1612"\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1613"\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x1b\x5b\x33\x33\x6d\x20\x60"
1614"\x2e\x60\x1b\x5b\x33\x37\x6d\x20\x3a\x2c\x3a\x2e\x60\x20\x60\x20\x60\x20\x60"
1615"\x2c\x3b\x2c\x3a\x20\x1b\x5b\x33\x33\x6d\x60\x2e\x60\x20\x1b\x5b\x33\x37\x6d"
1616"\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20"
1617"\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1618"\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x1b\x5b\x33"
1619"\x33\x6d\x20\x60\x20\x60\x20\x3a\x27\x60\x1b\x5b\x33\x37\x6d\x20\x60\x60\x60"
1620"\x20\x20\x20\x60\x20\x60\x60\x60\x20\x1b\x5b\x33\x33\x6d\x60\x3a\x60\x20\x60"
1621"\x20\x60\x20\x1b\x5b\x33\x37\x6d\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1622"\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1623"\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1624"\x20\x2e\x1b\x5b\x33\x33\x6d\x60\x2e\x60\x20\x60\x20\x60\x20\x20\x1b\x5b\x33"
1625"\x37\x6d\x20\x3a\x20\x20\x20\x60\x20\x20\x20\x60\x20\x20\x2e\x1b\x5b\x33\x33"
1626"\x6d\x60\x20\x60\x2e\x60\x20\x60\x2e\x60\x20\x1b\x5b\x33\x37\x6d\x20\x20\x20"
1627"\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x2e\x3a\x20\x20"
1628"\x20\x20\x20\x20\x20\x20\x2e\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1629"\x20\x20\x2e\x76\x53\x1b\x5b\x33\x34\x6d\x53\x1b\x5b\x33\x37\x6d\x53\x1b\x5b"
1630"\x33\x31\x6d\x2b\x1b\x5b\x33\x33\x6d\x60\x20\x60\x20\x60\x20\x20\x20\x20\x1b"
1631"\x5b\x33\x31\x6d\x3f\x1b\x5b\x33\x30\x6d\x53\x1b\x5b\x33\x33\x6d\x2b\x1b\x5b"
1632"\x33\x37\x6d\x20\x20\x20\x20\x20\x20\x20\x2e\x1b\x5b\x33\x30\x6d\x24\x1b\x5b"
1633"\x33\x37\x6d\x3b\x1b\x5b\x33\x31\x6d\x7c\x1b\x5b\x33\x33\x6d\x20\x60\x20\x60"
1634"\x20\x60\x20\x60\x1b\x5b\x33\x31\x6d\x2c\x1b\x5b\x33\x32\x6d\x53\x1b\x5b\x33"
1635"\x37\x6d\x53\x53\x3e\x2c\x2e\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x2e"
1636"\x3b\x27\x20\x20\x20\x20\x20\x20\x20\x20\x20\x60\x3c\x20\x20\x20\x20\x20\x20"
1637"\x20\x20\x20\x2e\x2e\x3a\x1b\x5b\x33\x30\x6d\x26\x46\x46\x46\x48\x46\x1b\x5b"
1638"\x33\x33\x6d\x60\x2e\x60\x20\x60\x20\x60\x20\x60\x1b\x5b\x33\x30\x6d\x4d\x4d"
1639"\x46\x1b\x5b\x33\x33\x6d\x20\x20\x1b\x5b\x33\x37\x6d\x20\x20\x20\x20\x1b\x5b"
1640"\x33\x33\x6d\x20\x3a\x1b\x5b\x33\x30\x6d\x4d\x4d\x46\x1b\x5b\x33\x33\x6d\x20"
1641"\x20\x20\x60\x20\x60\x2e\x60\x1b\x5b\x33\x31\x6d\x3c\x1b\x5b\x33\x30\x6d\x46"
1642"\x46\x46\x24\x53\x46\x1b\x5b\x33\x37\x6d\x20\x20\x20\x20\x20\x0a\x20\x20\x20"
1643"\x20\x2e\x3c\x3a\x60\x20\x20\x20\x20\x2e\x3a\x2e\x3a\x2e\x2e\x3b\x27\x20\x20"
1644"\x20\x20\x20\x20\x2e\x60\x2e\x3a\x60\x60\x3c\x27\x1b\x5b\x33\x31\x6d\x3c\x27"
1645"\x1b\x5b\x33\x33\x6d\x20\x60\x20\x60\x20\x60\x20\x20\x20\x60\x3c\x1b\x5b\x33"
1646"\x30\x6d\x26\x1b\x5b\x33\x31\x6d\x3f\x1b\x5b\x33\x33\x6d\x20\x1b\x5b\x33\x37"
1647"\x6d\x20\x1b\x5b\x33\x33\x6d\x20\x20\x20\x20\x20\x1b\x5b\x33\x37\x6d\x60\x1b"
1648"\x5b\x33\x30\x6d\x2a\x46\x1b\x5b\x33\x37\x6d\x27\x1b\x5b\x33\x33\x6d\x20\x60"
1649"\x20\x60\x20\x60\x20\x60\x20\x1b\x5b\x33\x31\x6d\x60\x3a\x1b\x5b\x33\x37\x6d"
1650"\x27\x3c\x1b\x5b\x33\x30\x6d\x23\x1b\x5b\x33\x37\x6d\x3c\x60\x3a\x20\x20\x20"
1651"\x0a\x20\x20\x20\x20\x3a\x60\x3a\x60\x20\x20\x20\x60\x3a\x2e\x2e\x2e\x2e\x3c"
1652"\x3c\x20\x20\x20\x20\x20\x20\x3a\x2e\x60\x3a\x60\x20\x20\x20\x60\x1b\x5b\x33"
1653"\x33\x6d\x3a\x1b\x5b\x33\x31\x6d\x60\x1b\x5b\x33\x33\x6d\x20\x60\x2e\x60\x20"
1654"\x60\x20\x60\x20\x60\x20\x60\x1b\x5b\x33\x37\x6d\x20\x20\x1b\x5b\x33\x33\x6d"
1655"\x20\x60\x20\x20\x20\x60\x1b\x5b\x33\x37\x6d\x20\x60\x20\x60\x1b\x5b\x33\x33"
1656"\x6d\x20\x60\x2e\x60\x20\x60\x2e\x60\x20\x60\x3a\x1b\x5b\x33\x37\x6d\x20\x20"
1657"\x20\x60\x3a\x2e\x60\x2e\x20\x0a\x20\x20\x20\x60\x3a\x60\x3a\x60\x20\x20\x20"
1658"\x20\x20\x60\x60\x60\x60\x20\x3a\x2d\x20\x20\x20\x20\x20\x60\x20\x60\x20\x20"
1659"\x20\x20\x20\x60\x1b\x5b\x33\x33\x6d\x3a\x60\x2e\x60\x20\x60\x20\x60\x20\x60"
1660"\x20\x60\x20\x20\x2e\x3b\x1b\x5b\x33\x31\x6d\x76\x1b\x5b\x33\x30\x6d\x24\x24"
1661"\x24\x1b\x5b\x33\x31\x6d\x2b\x53\x1b\x5b\x33\x33\x6d\x2c\x60\x20\x60\x20\x60"
1662"\x20\x60\x20\x60\x20\x60\x2e\x1b\x5b\x33\x31\x6d\x60\x1b\x5b\x33\x33\x6d\x3a"
1663"\x1b\x5b\x33\x37\x6d\x20\x20\x20\x20\x60\x2e\x60\x20\x20\x0a\x20\x20\x20\x60"
1664"\x3a\x3a\x3a\x3a\x20\x20\x20\x20\x3a\x60\x60\x60\x60\x3a\x53\x20\x20\x20\x20"
1665"\x20\x20\x3a\x2e\x60\x2e\x20\x20\x20\x20\x20\x1b\x5b\x33\x33\x6d\x3a\x1b\x5b"
1666"\x33\x31\x6d\x3a\x1b\x5b\x33\x33\x6d\x2e\x60\x2e\x60\x20\x60\x2e\x60\x20\x60"
1667"\x20\x3a\x1b\x5b\x33\x30\x6d\x24\x46\x46\x48\x46\x46\x46\x46\x46\x1b\x5b\x33"
1668"\x31\x6d\x53\x1b\x5b\x33\x33\x6d\x2e\x60\x20\x60\x2e\x60\x20\x60\x2e\x60\x2e"
1669"\x1b\x5b\x33\x31\x6d\x3a\x1b\x5b\x33\x33\x6d\x3a\x1b\x5b\x33\x37\x6d\x20\x20"
1670"\x20\x2e\x60\x2e\x3a\x20\x20\x0a\x20\x20\x20\x60\x3a\x3a\x3a\x60\x20\x20\x20"
1671"\x60\x3a\x20\x2e\x20\x3b\x27\x3a\x20\x20\x20\x20\x20\x20\x3a\x2e\x60\x3a\x20"
1672"\x20\x20\x20\x20\x3a\x1b\x5b\x33\x33\x6d\x3c\x3a\x1b\x5b\x33\x31\x6d\x60\x1b"
1673"\x5b\x33\x33\x6d\x2e\x60\x20\x60\x20\x60\x20\x60\x2e\x1b\x5b\x33\x30\x6d\x53"
1674"\x46\x46\x46\x53\x46\x46\x46\x53\x46\x46\x1b\x5b\x33\x33\x6d\x20\x60\x20\x60"
1675"\x20\x60\x2e\x60\x2e\x60\x3a\x1b\x5b\x33\x31\x6d\x3c\x1b\x5b\x33\x37\x6d\x20"
1676"\x20\x20\x20\x3a\x60\x3a\x60\x20\x20\x0a\x20\x20\x20\x20\x60\x3c\x3b\x3c\x20"
1677"\x20\x20\x20\x20\x60\x60\x60\x20\x3a\x3a\x20\x20\x20\x20\x20\x20\x20\x3a\x3a"
1678"\x2e\x60\x20\x20\x20\x20\x20\x3a\x1b\x5b\x33\x33\x6d\x3b\x1b\x5b\x33\x31\x6d"
1679"\x3c\x3a\x60\x1b\x5b\x33\x33\x6d\x2e\x60\x2e\x60\x20\x60\x3a\x1b\x5b\x33\x30"
1680"\x6d\x53\x46\x53\x46\x46\x46\x53\x46\x46\x46\x53\x1b\x5b\x33\x33\x6d\x2e\x60"
1681"\x20\x60\x2e\x60\x2e\x60\x3a\x1b\x5b\x33\x31\x6d\x3c\x1b\x5b\x33\x33\x6d\x3b"
1682"\x1b\x5b\x33\x37\x6d\x27\x20\x20\x20\x60\x3a\x3a\x60\x20\x20\x20\x0a\x20\x20"
1683"\x20\x20\x20\x60\x3b\x3c\x20\x20\x20\x20\x20\x20\x20\x3a\x3b\x60\x20\x20\x20"
1684"\x20\x20\x20\x20\x20\x20\x60\x3a\x60\x2e\x20\x20\x20\x20\x20\x3a\x1b\x5b\x33"
1685"\x33\x6d\x3c\x3b\x1b\x5b\x33\x31\x6d\x3c\x1b\x5b\x33\x33\x6d\x3a\x1b\x5b\x33"
1686"\x31\x6d\x3a\x1b\x5b\x33\x33\x6d\x2e\x60\x2e\x60\x20\x1b\x5b\x33\x31\x6d\x3a"
1687"\x1b\x5b\x33\x30\x6d\x46\x53\x46\x53\x46\x53\x46\x53\x46\x1b\x5b\x33\x31\x6d"
1688"\x3f\x1b\x5b\x33\x33\x6d\x20\x60\x2e\x60\x2e\x3a\x3a\x1b\x5b\x33\x31\x6d\x3c"
1689"\x1b\x5b\x33\x33\x6d\x3b\x1b\x5b\x33\x31\x6d\x3c\x1b\x5b\x33\x37\x6d\x60\x20"
1690"\x20\x20\x3a\x3a\x3a\x60\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x53\x3c"
1691"\x20\x20\x20\x20\x20\x20\x3a\x53\x3a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1692"\x20\x60\x3a\x3a\x60\x2e\x20\x20\x20\x20\x60\x3a\x1b\x5b\x33\x31\x6d\x3c\x1b"
1693"\x5b\x33\x33\x6d\x3b\x1b\x5b\x33\x31\x6d\x3c\x3b\x3c\x1b\x5b\x33\x33\x6d\x3a"
1694"\x60\x2e\x60\x3c\x1b\x5b\x33\x30\x6d\x53\x46\x53\x24\x53\x46\x53\x24\x1b\x5b"
1695"\x33\x33\x6d\x60\x3a\x1b\x5b\x33\x31\x6d\x3a\x1b\x5b\x33\x33\x6d\x3a\x1b\x5b"
1696"\x33\x31\x6d\x3a\x3b\x3c\x1b\x5b\x33\x33\x6d\x3b\x1b\x5b\x33\x31\x6d\x3c\x1b"
1697"\x5b\x33\x33\x6d\x3a\x1b\x5b\x33\x37\x6d\x60\x20\x20\x2e\x60\x3a\x3a\x60\x20"
1698"\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x3b\x3c\x2e\x2e\x2c\x2e\x2e\x20"
1699"\x3a\x3c\x3b\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x60\x3a\x3a\x3a"
1700"\x60\x20\x20\x20\x20\x20\x60\x3a\x1b\x5b\x33\x33\x6d\x3c\x3b\x1b\x5b\x33\x31"
1701"\x6d\x3c\x3b\x3c\x1b\x5b\x33\x33\x6d\x3b\x1b\x5b\x33\x31\x6d\x3c\x1b\x5b\x33"
1702"\x33\x6d\x3b\x1b\x5b\x33\x31\x6d\x3c\x3c\x1b\x5b\x33\x30\x6d\x53\x24\x53\x1b"
1703"\x5b\x33\x31\x6d\x53\x1b\x5b\x33\x37\x6d\x27\x1b\x5b\x33\x33\x6d\x2e\x3a\x3b"
1704"\x1b\x5b\x33\x31\x6d\x3c\x3b\x3c\x1b\x5b\x33\x33\x6d\x3a\x1b\x5b\x33\x31\x6d"
1705"\x3c\x1b\x5b\x33\x33\x6d\x3a\x1b\x5b\x33\x37\x6d\x60\x20\x20\x20\x60\x2e\x3a"
1706"\x3a\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x2e\x3a\x3a\x3c\x53\x3c\x3a\x60"
1707"\x3a\x3a\x3a\x3a\x53\x1b\x5b\x33\x32\x6d\x53\x1b\x5b\x33\x37\x6d\x3b\x27\x3a"
1708"\x3c\x2c\x2e\x20\x20\x20\x20\x20\x20\x20\x20\x20\x60\x3a\x3a\x3a\x3a\x2e\x60"
1709"\x2e\x60\x2e\x60\x3a\x1b\x5b\x33\x33\x6d\x3c\x3a\x1b\x5b\x33\x31\x6d\x3c\x1b"
1710"\x5b\x33\x33\x6d\x53\x1b\x5b\x33\x31\x6d\x3c\x1b\x5b\x33\x33\x6d\x3b\x1b\x5b"
1711"\x33\x31\x6d\x3c\x2c\x1b\x5b\x33\x33\x6d\x3c\x3b\x3a\x1b\x5b\x33\x31\x6d\x2c"
1712"\x1b\x5b\x33\x33\x6d\x3c\x3b\x1b\x5b\x33\x31\x6d\x3c\x1b\x5b\x33\x33\x6d\x53"
1713"\x1b\x5b\x33\x31\x6d\x3c\x1b\x5b\x33\x33\x6d\x3b\x3c\x1b\x5b\x33\x37\x6d\x3a"
1714"\x60\x2e\x60\x2e\x3b\x1b\x5b\x33\x34\x6d\x53\x1b\x5b\x33\x37\x6d\x53\x3f\x27"
1715"\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x2e\x60\x3a\x60\x3a\x3c\x53\x53\x3b\x3c"
1716"\x3a\x60\x3a\x3a\x53\x53\x53\x3c\x3a\x60\x3a\x1b\x5b\x33\x30\x6d\x53\x1b\x5b"
1717"\x33\x37\x6d\x2b\x20\x20\x20\x20\x20\x20\x60\x20\x20\x20\x3a\x1b\x5b\x33\x34"
1718"\x6d\x53\x1b\x5b\x33\x30\x6d\x53\x46\x24\x1b\x5b\x33\x37\x6d\x2c\x60\x3a\x3a"
1719"\x3a\x3c\x3a\x3c\x1b\x5b\x33\x33\x6d\x53\x1b\x5b\x33\x37\x6d\x3c\x1b\x5b\x33"
1720"\x33\x6d\x53\x1b\x5b\x33\x31\x6d\x53\x1b\x5b\x33\x33\x6d\x3b\x1b\x5b\x33\x31"
1721"\x6d\x53\x3b\x53\x1b\x5b\x33\x33\x6d\x3b\x1b\x5b\x33\x31\x6d\x53\x1b\x5b\x33"
1722"\x33\x6d\x53\x1b\x5b\x33\x37\x6d\x3c\x1b\x5b\x33\x33\x6d\x53\x1b\x5b\x33\x37"
1723"\x6d\x3c\x53\x3c\x3a\x3a\x3a\x3a\x3f\x1b\x5b\x33\x30\x6d\x53\x24\x48\x1b\x5b"
1724"\x33\x37\x6d\x27\x60\x20\x60\x20\x20\x20\x20\x20\x20\x0a\x2e\x60\x3a\x60\x2e"
1725"\x60\x3a\x60\x2e\x60\x3a\x60\x2e\x60\x3a\x60\x2e\x60\x3a\x60\x2e\x1b\x5b\x33"
1726"\x30\x6d\x53\x46\x1b\x5b\x33\x37\x6d\x20\x20\x20\x20\x60\x20\x20\x20\x60\x20"
1727"\x60\x3a\x1b\x5b\x33\x30\x6d\x3c\x46\x46\x46\x1b\x5b\x33\x37\x6d\x3f\x2e\x60"
1728"\x3a\x60\x3a\x60\x3a\x60\x3a\x60\x3a\x3c\x3a\x60\x3a\x27\x3a\x60\x3a\x60\x3a"
1729"\x60\x3a\x60\x3b\x1b\x5b\x33\x30\x6d\x53\x46\x48\x46\x1b\x5b\x33\x37\x6d\x27"
1730"\x20\x60\x20\x60\x20\x60\x20\x20\x20\x20\x0a\x20\x3c\x3b\x3a\x2e\x60\x20\x60"
1731"\x2e\x60\x20\x60\x2e\x60\x20\x60\x2e\x60\x2c\x53\x1b\x5b\x33\x32\x6d\x53\x1b"
1732"\x5b\x33\x30\x6d\x53\x1b\x5b\x33\x37\x6d\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1733"\x20\x20\x60\x20\x60\x3c\x1b\x5b\x33\x30\x6d\x46\x46\x46\x1b\x5b\x33\x34\x6d"
1734"\x2b\x1b\x5b\x33\x37\x6d\x3a\x20\x60\x20\x60\x20\x60\x2e\x60\x20\x60\x2e\x60"
1735"\x20\x60\x2e\x60\x20\x60\x20\x60\x2c\x1b\x5b\x33\x30\x6d\x24\x46\x48\x46\x1b"
1736"\x5b\x33\x37\x6d\x27\x20\x60\x20\x20\x20\x60\x20\x20\x20\x20\x20\x20\x0a\x20"
1737"\x60\x3a\x1b\x5b\x33\x30\x6d\x53\x24\x1b\x5b\x33\x37\x6d\x53\x53\x53\x3b\x3c"
1738"\x2c\x60\x2c\x3b\x3b\x53\x3f\x53\x1b\x5b\x33\x30\x6d\x24\x46\x3c\x1b\x5b\x33"
1739"\x37\x6d\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x60\x20\x60"
1740"\x3c\x1b\x5b\x33\x30\x6d\x48\x46\x46\x46\x1b\x5b\x33\x37\x6d\x3f\x2e\x60\x20"
1741"\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x3b\x76\x1b\x5b\x33\x30\x6d"
1742"\x48\x46\x48\x46\x1b\x5b\x33\x37\x6d\x27\x20\x60\x20\x20\x20\x60\x20\x20\x20"
1743"\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x60\x3c\x1b\x5b\x33\x30\x6d\x46\x24\x1b"
1744"\x5b\x33\x37\x6d\x53\x53\x53\x53\x53\x53\x1b\x5b\x33\x30\x6d\x53\x24\x53\x46"
1745"\x46\x46\x1b\x5b\x33\x37\x6d\x27\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1746"\x20\x20\x20\x20\x20\x20\x20\x20\x60\x3c\x1b\x5b\x33\x30\x6d\x23\x46\x46\x46"
1747"\x24\x1b\x5b\x33\x37\x6d\x76\x2c\x2c\x20\x2e\x20\x2e\x20\x2c\x2c\x76\x1b\x5b"
1748"\x33\x30\x6d\x26\x24\x46\x46\x48\x3c\x1b\x5b\x33\x37\x6d\x27\x20\x20\x20\x20"
1749"\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x60"
1750"\x3c\x1b\x5b\x33\x30\x6d\x53\x46\x46\x24\x46\x24\x46\x46\x48\x46\x53\x1b\x5b"
1751"\x33\x37\x6d\x20\x20\x20\x20\x20\x20\x20\x20\x2e\x60\x20\x60\x2e\x60\x2e\x60"
1752"\x2e\x60\x2e\x60\x3a\x3a\x3a\x3a\x3a\x1b\x5b\x33\x30\x6d\x2a\x46\x46\x46\x48"
1753"\x46\x48\x46\x48\x46\x46\x46\x48\x46\x48\x46\x48\x1b\x5b\x33\x37\x6d\x3c\x22"
1754"\x2e\x60\x2e\x60\x2e\x60\x2e\x60\x2e\x60\x20\x20\x20\x20\x20\x20\x20\x20\x0a"
1755"\x20\x20\x20\x20\x20\x20\x20\x60\x3a\x1b\x5b\x33\x30\x6d\x48\x46\x46\x46\x48"
1756"\x46\x46\x46\x1b\x5b\x33\x37\x6d\x27\x20\x20\x20\x60\x20\x60\x2e\x60\x20\x60"
1757"\x2e\x60\x2e\x60\x3a\x60\x3a\x60\x3a\x60\x3a\x60\x3a\x3a\x3a\x60\x3a\x3c\x3c"
1758"\x1b\x5b\x33\x30\x6d\x3c\x46\x48\x46\x46\x46\x48\x46\x46\x46\x1b\x5b\x33\x37"
1759"\x6d\x27\x3a\x60\x3a\x60\x3a\x60\x3a\x60\x2e\x60\x2e\x60\x20\x60\x2e\x60\x20"
1760"\x60\x20\x60\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x60\x22\x1b\x5b"
1761"\x33\x30\x6d\x2a\x46\x48\x46\x1b\x5b\x33\x37\x6d\x3f\x20\x20\x20\x60\x20\x60"
1762"\x2e\x60\x20\x60\x2e\x60\x2e\x60\x3a\x60\x2e\x60\x3a\x60\x3a\x60\x3a\x60\x3a"
1763"\x60\x3a\x60\x3a\x60\x3a\x60\x3a\x1b\x5b\x33\x30\x6d\x46\x46\x48\x46\x48\x46"
1764"\x1b\x5b\x33\x37\x6d\x27\x3a\x60\x3a\x60\x3a\x60\x3a\x60\x2e\x60\x3a\x60\x2e"
1765"\x60\x2e\x60\x20\x60\x2e\x60\x20\x60\x20\x60\x0a\x20\x20\x20\x20\x20\x20\x20"
1766"\x20\x20\x20\x20\x60\x3c\x1b\x5b\x33\x30\x6d\x48\x46\x46\x1b\x5b\x33\x37\x6d"
1767"\x2b\x60\x20\x20\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x2e\x60\x20"
1768"\x60\x2e\x60\x20\x60\x2e\x60\x20\x60\x3a\x60\x2e\x60\x3b\x1b\x5b\x33\x30\x6d"
1769"\x48\x46\x46\x46\x1b\x5b\x33\x37\x6d\x27\x2e\x60\x2e\x60\x20\x60\x2e\x60\x20"
1770"\x60\x2e\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x20\x20\x60\x20\x20\x0a\x20"
1771"\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x22\x1b\x5b\x33\x30\x6d\x3c"
1772"\x48\x46\x53\x1b\x5b\x33\x37\x6d\x2b\x3a\x20\x20\x20\x60\x20\x60\x20\x60\x20"
1773"\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x2c\x1b"
1774"\x5b\x33\x30\x6d\x24\x46\x48\x46\x1b\x5b\x33\x37\x6d\x3f\x20\x60\x20\x60\x20"
1775"\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x20\x20\x60"
1776"\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1777"\x60\x22\x3c\x1b\x5b\x33\x30\x6d\x48\x24\x46\x46\x1b\x5b\x33\x37\x6d\x3e\x2c"
1778"\x2e\x2e\x20\x20\x20\x20\x20\x20\x20\x20\x60\x20\x20\x20\x60\x20\x20\x20\x3b"
1779"\x2c\x2c\x1b\x5b\x33\x30\x6d\x24\x53\x46\x46\x46\x1b\x5b\x33\x37\x6d\x27\x22"
1780"\x20\x20\x60\x20\x20\x20\x60\x20\x20\x20\x60\x20\x20\x20\x20\x20\x20\x20\x20"
1781"\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20"
1782"\x20\x20\x20\x20\x20\x20\x20\x20\x20\x60\x22\x1b\x5b\x33\x30\x6d\x2a\x3c\x48"
1783"\x46\x46\x24\x53\x24\x1b\x5b\x33\x37\x6d\x53\x53\x53\x3e\x3e\x3e\x3e\x3e\x53"
1784"\x3e\x53\x1b\x5b\x33\x30\x6d\x24\x53\x24\x46\x24\x48\x46\x23\x1b\x5b\x33\x37"
1785"\x6d\x27\x22\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1786"\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20"
1787"\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1788"\x60\x60\x22\x3c\x1b\x5b\x33\x30\x6d\x2a\x3c\x3c\x3c\x48\x46\x46\x46\x48\x46"
1789"\x46\x46\x23\x3c\x1b\x5b\x33\x36\x6d\x3c\x1b\x5b\x33\x37\x6d\x3c\x27\x22\x22"
1790"\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1791"\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x1b"
1792 "\x5b\x30\x6d";
ebff2ed0
JS
1793
1794/* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */
This page took 0.271505 seconds and 5 git commands to generate.