ronin-post_ex 0.1.0.beta1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. checksums.yaml +7 -0
  2. data/.document +6 -0
  3. data/.github/workflows/ruby.yml +31 -0
  4. data/.gitignore +13 -0
  5. data/.rspec +1 -0
  6. data/.ruby-version +1 -0
  7. data/.yardopts +1 -0
  8. data/API_SPEC.md +235 -0
  9. data/COPYING.txt +165 -0
  10. data/ChangeLog.md +23 -0
  11. data/Gemfile +36 -0
  12. data/README.md +245 -0
  13. data/Rakefile +34 -0
  14. data/examples/bind_shell.rb +19 -0
  15. data/gemspec.yml +25 -0
  16. data/lib/ronin/post_ex/cli/shell_shell.rb +66 -0
  17. data/lib/ronin/post_ex/cli/system_shell.rb +811 -0
  18. data/lib/ronin/post_ex/remote_dir.rb +190 -0
  19. data/lib/ronin/post_ex/remote_file/stat.rb +174 -0
  20. data/lib/ronin/post_ex/remote_file.rb +417 -0
  21. data/lib/ronin/post_ex/remote_process.rb +170 -0
  22. data/lib/ronin/post_ex/resource.rb +144 -0
  23. data/lib/ronin/post_ex/sessions/bind_shell.rb +60 -0
  24. data/lib/ronin/post_ex/sessions/remote_shell_session.rb +48 -0
  25. data/lib/ronin/post_ex/sessions/reverse_shell.rb +67 -0
  26. data/lib/ronin/post_ex/sessions/rpc_session.rb +779 -0
  27. data/lib/ronin/post_ex/sessions/session.rb +73 -0
  28. data/lib/ronin/post_ex/sessions/shell_session.rb +618 -0
  29. data/lib/ronin/post_ex/system/fs.rb +650 -0
  30. data/lib/ronin/post_ex/system/process.rb +422 -0
  31. data/lib/ronin/post_ex/system/shell.rb +1037 -0
  32. data/lib/ronin/post_ex/system.rb +191 -0
  33. data/lib/ronin/post_ex/version.rb +26 -0
  34. data/lib/ronin/post_ex.rb +22 -0
  35. data/ronin-post_ex.gemspec +61 -0
  36. data/spec/sessions/bind_shell_spec.rb +31 -0
  37. data/spec/sessions/remote_shell_session_spec.rb +28 -0
  38. data/spec/sessions/reverse_shell_spec.rb +49 -0
  39. data/spec/sessions/rpc_session_spec.rb +500 -0
  40. data/spec/sessions/session_spec.rb +61 -0
  41. data/spec/sessions/shell_session_spec.rb +482 -0
  42. data/spec/spec_helper.rb +9 -0
  43. data/spec/system_spec.rb +66 -0
  44. metadata +155 -0
@@ -0,0 +1,811 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # ronin-post_ex - a Ruby API for Post-Exploitation.
4
+ #
5
+ # Copyright (c) 2007-2022 Hal Brodigan (postmodern.mod3 at gmail.com)
6
+ #
7
+ # ronin-post_ex is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU Lesser General Public License as published
9
+ # by the Free Software Foundation, either version 3 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # ronin-post_ex 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
15
+ # GNU Lesser General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU Lesser General Public License
18
+ # along with ronin-post_ex. If not, see <https://www.gnu.org/licenses/>.
19
+ #
20
+
21
+ require 'ronin/core/cli/command_shell'
22
+ require 'ronin/post_ex/cli/shell_shell'
23
+ require 'ronin/post_ex/remote_file'
24
+
25
+ module Ronin
26
+ module PostEx
27
+ module CLI
28
+ #
29
+ # A shell for {System}.
30
+ #
31
+ class SystemShell < Core::CLI::CommandShell
32
+
33
+ shell_name 'ronin-post_ex'
34
+
35
+ #
36
+ # Initializes the file-system shell.
37
+ #
38
+ # @param [System] system
39
+ # The file-system resource.
40
+ #
41
+ # @param [Hash{Symbol => Object}] kwargs
42
+ # Additional keyword arguments.
43
+ #
44
+ def initialize(system, **kwargs)
45
+ super(**kwargs)
46
+
47
+ @system = system
48
+
49
+ @files = {}
50
+ @next_file_id = 1
51
+ end
52
+
53
+ command 'fs.chdir', method_name: 'fs_chdir',
54
+ usage: 'DIR',
55
+ summary: 'Changes the current working directory'
56
+
57
+ #
58
+ # Changes the working directory.
59
+ #
60
+ # @param [String] path
61
+ # The new working directory.
62
+ #
63
+ # @see System::FS#chdir
64
+ #
65
+ def fs_chdir(path)
66
+ @system.fs.chdir(path)
67
+ puts "Current working directory is now: #{@system.fs.pwd}"
68
+ end
69
+
70
+ command 'fs.pwd', method_name: 'fs_pwd',
71
+ summary: 'Prints the current working directory'
72
+
73
+ #
74
+ # Prints the current working directory.
75
+ #
76
+ # @see System::FS#getcwd
77
+ #
78
+ def fs_pwd
79
+ puts "Current working directory: #{@system.fs.getcwd}"
80
+ end
81
+
82
+ command 'fs.readfile', method_name: 'fs_readfile',
83
+ usage: 'FILE',
84
+ summary: 'Reads the contents of a given FILE'
85
+
86
+ #
87
+ # Reads data from a file.
88
+ #
89
+ # @param [String] path
90
+ # The file to read from.
91
+ #
92
+ # @see System::FS#read
93
+ #
94
+ def fs_readfile(path)
95
+ write(@system.fs.readfile(path))
96
+ end
97
+
98
+ command 'fs.readlink', method_name: 'fs_readlink',
99
+ usage: 'SYMLINK',
100
+ summary: 'Reads the destination path of a symlink'
101
+
102
+ #
103
+ # Reads the destination of a link.
104
+ #
105
+ # @param [String] path
106
+ # The path to the link.
107
+ #
108
+ # @see System::FS#readlink
109
+ #
110
+ def fs_readlink(path)
111
+ puts @system.fs.readlink(path)
112
+ end
113
+
114
+ command 'fs.readdir', method_name: 'fs_readdir',
115
+ usage: 'DIR',
116
+ summary: 'Reads the contents of a given directory'
117
+
118
+ #
119
+ # Reads the entries of a directory.
120
+ #
121
+ # @param [String] path
122
+ # The path to the directory.
123
+ #
124
+ # @see System::FS#readdir
125
+ #
126
+ def fs_readdir(path)
127
+ @system.fs.readdir(path).each do |entry|
128
+ puts entry
129
+ end
130
+ end
131
+
132
+ command 'fs.hexdump', usage: 'FILE',
133
+ summary: 'Hexdumps a given file'
134
+
135
+ #
136
+ # Hexdumps a file.
137
+ #
138
+ # @param [String] path
139
+ # The file to hexdump.
140
+ #
141
+ # @see System::FS#hexdump
142
+ #
143
+ def hexdump(path)
144
+ @system.fs.hexdump(path,self)
145
+ end
146
+
147
+ command 'fs.copy', method_name: 'file_copy',
148
+ usage: 'SRC DEST',
149
+ summary: 'Copies the SRC file to the DEST path'
150
+
151
+ #
152
+ # Copies a file to a destination.
153
+ #
154
+ # @param [String] src
155
+ # The file to copy.
156
+ #
157
+ # @param [String] dest
158
+ # The destination to copy the file to.
159
+ #
160
+ # @see System::FS#copy
161
+ #
162
+ def fs_copy(src,dest)
163
+ @system.fs.copy(src,dest)
164
+
165
+ puts "Copied #{@system.fs.expand_path(src)} -> #{@fs.expand_path(dest)}"
166
+ end
167
+
168
+ command 'fs.unlink', method_name: 'file_unlink',
169
+ usage: 'FILE',
170
+ summary: 'Deletes a given file'
171
+
172
+ #
173
+ # Removes a file.
174
+ #
175
+ # @param [String] path
176
+ # The file to be removed.
177
+ #
178
+ # @see System::FS#unlink
179
+ #
180
+ def file_unlink(path)
181
+ @system.fs.unlink(path)
182
+
183
+ puts "Removed #{@system.fs.expand_path(path)}"
184
+ end
185
+
186
+ command 'fs.rmdir', method_name: 'fs_rmdir',
187
+ usage: 'DIR',
188
+ summary: 'Removes a given directory'
189
+
190
+ #
191
+ # Removes an empty directory.
192
+ #
193
+ # @param [String] path
194
+ # The file to be removed.
195
+ #
196
+ # @see System::FS#rmdir
197
+ #
198
+ def fs_rmdir(path)
199
+ @system.fs.rmdir(path)
200
+
201
+ puts "Removed directory #{@system.fs.expand_path(path)}"
202
+ end
203
+
204
+ command 'fs.mv', method_name: 'fs_mv',
205
+ usage: 'SRC DEST',
206
+ summary: 'Moves or renames a given file or directory'
207
+
208
+ #
209
+ # Moves a file or directory.
210
+ #
211
+ # @param [String] src
212
+ # The file or directory to move.
213
+ #
214
+ # @param [String] dest
215
+ # The destination to move the file or directory to.
216
+ #
217
+ # @see System::FS#move
218
+ #
219
+ def fs_mv(src,dest)
220
+ @system.fs.move(src,dest)
221
+
222
+ puts "Moved #{@system.fs.expand_path(src)} -> #{@fs.expand_path(dest)}"
223
+ end
224
+
225
+ command 'fs.link', method_name: 'fs_link',
226
+ usage: 'SRC DEST',
227
+ summary: 'Creates a link from the source to the destination'
228
+
229
+ #
230
+ # Creates a link to a file or directory.
231
+ #
232
+ # @param [String] src
233
+ # The file or directory to link to.
234
+ #
235
+ # @param [String] dest
236
+ # The path of the new link.
237
+ #
238
+ # @see System::FS#link
239
+ #
240
+ def fs_link(src,dest)
241
+ @system.fs.link(src,dest)
242
+
243
+ puts "Linked #{@system.fs.expand_path(src)} -> #{@fs.expand_path(dest)}"
244
+ end
245
+
246
+ command 'fs.chown', method_name: 'fs_chown',
247
+ usage: 'USER PATH',
248
+ summary: 'Changes the owner of a given file or directory'
249
+
250
+ #
251
+ # Changes ownership of a file or directory.
252
+ #
253
+ # @param [String] user
254
+ # The desired new user.
255
+ #
256
+ # @param [String] path
257
+ # The path of the file or directory.
258
+ #
259
+ # @see System::FS#chown
260
+ #
261
+ def fs_chown(user,path)
262
+ @system.fs.chown(user,path)
263
+
264
+ puts "Changed ownership of #{@system.fs.expand_path(path)} to #{user}"
265
+ end
266
+
267
+ command 'fs.chgrp', method_name: 'fs_chgrp',
268
+ usage: 'GROUP PATH',
269
+ summary: 'Changes the group of a given file or directory'
270
+
271
+ #
272
+ # Changes group ownership of a file or directory.
273
+ #
274
+ # @param [String] group
275
+ # The desired new group.
276
+ #
277
+ # @param [String] path
278
+ # The path of the file or directory.
279
+ #
280
+ # @see System::FS#chgrp
281
+ #
282
+ def fs_chgrp(group,path)
283
+ @system.fs.chgrp(group,path)
284
+
285
+ puts "Changed group ownership of #{@system.fs.expand_path(path)} to #{group}"
286
+ end
287
+
288
+ command 'fs.chmod', method_name: 'fs_chmod',
289
+ usage: 'MODE PATH',
290
+ summary: 'Changes the permission mode of a given file or directory'
291
+
292
+ #
293
+ # Changes the permissions of a file or directory.
294
+ #
295
+ # @param [String] mode
296
+ # The desired new octal permission mode.
297
+ #
298
+ # @param [String] path
299
+ # The path of the file or directory.
300
+ #
301
+ # @see System::FS#chmod
302
+ #
303
+ def fs_chmod(mode,path)
304
+ @system.fs.chmod(mode.to_i(8),path)
305
+
306
+ puts "Changed permissions on #{@system.fs.expand_path(path)} to #{mode}"
307
+ end
308
+
309
+ command 'fs.stat', method_name: 'fs_stat',
310
+ usage: 'PATH',
311
+ summary: 'Prints file system information about a given file or directory'
312
+
313
+ #
314
+ # Stats a file or directory.
315
+ #
316
+ # @param [String] path
317
+ # The file or directory to stat.
318
+ #
319
+ # @see System::FS#stat
320
+ #
321
+ def fs_stat(path)
322
+ stat = @system.fs.stat(path)
323
+ end
324
+
325
+ command 'file.open', method_name: 'file_open',
326
+ usage: 'PATH [MODE]',
327
+ summary: 'Opens a file for reading or writing'
328
+
329
+ #
330
+ # Opens a file.
331
+ #
332
+ # @param [String] path
333
+ # The path to the file.
334
+ #
335
+ # @param [String] mode
336
+ # Optional open mode.
337
+ #
338
+ # @see System::FS#open
339
+ #
340
+ def file_open(path,mode="r")
341
+ file = @system.fs.open(path,mode)
342
+ file_id = @next_file_id
343
+
344
+ @files[file_id] = file
345
+ @next_file_id += 1
346
+
347
+ puts "Opened file ##{file_id} for #{file.path}"
348
+ end
349
+
350
+ command 'files', summary: 'Lists opened files'
351
+
352
+ #
353
+ # Lists opened files.
354
+ #
355
+ def files
356
+ @files.each_with_index do |file,index|
357
+ if file
358
+ id = index + 1
359
+
360
+ puts " [#{id}] #{file.path}"
361
+ end
362
+ end
363
+ end
364
+
365
+ command 'file.seek', method_name: 'file_seek',
366
+ usage: 'FILE_ID POS [SEEK_SET | SEEK_CUR | SEEK_END | SEEK_DATA | SEEK_HOLE]',
367
+ summary: 'Seeks to a position within the file'
368
+
369
+ # Mapping of String whence values to Integer values.
370
+ WHENCE = {
371
+ 'SEEK_SET' => RemoteFile::SEEK_SET,
372
+ 'SEEK_CUR' => RemoteFile::SEEK_CUR,
373
+ 'SEEK_END' => RemoteFile::SEEK_END,
374
+ 'SEEK_DATA' => RemoteFile::SEEK_DATA,
375
+ 'SEEK_HOLE' => RemoteFile::SEEK_HOLE
376
+ }
377
+
378
+ #
379
+ # Seeks to a position within an opened file.
380
+ #
381
+ # @param [String] file_id
382
+ # The file ID number.
383
+ #
384
+ # @param [String] pos
385
+ # The position to seek to.
386
+ #
387
+ # @param [String] whence
388
+ # Where to seek relative from. Acceptable values are:
389
+ # * `"SET"`
390
+ # * `"CUR"`
391
+ # * `"END"`
392
+ # * `"DATA"`
393
+ # * `"HOLE"`
394
+ #
395
+ # @see RemoteFile#seek
396
+ #
397
+ def file_seek(file_id,pos,whence='SEEK_SET')
398
+ unless WHENCE.has_key?(whence)
399
+ print_error "unknown file.seek whence value (#{whence}), must be #{WHENCE.keys.join(', ')}"
400
+ return false
401
+ end
402
+
403
+ file_id = file_id.to_i
404
+ pos = pos.to_i
405
+ whence = WHENCE[whence]
406
+
407
+ if (file = @files[file_id])
408
+ file.seek(pos,whence)
409
+ puts file.pos
410
+ else
411
+ print_error "unknown file id: #{file_id}"
412
+ end
413
+ end
414
+
415
+ command 'file.read', method_name: 'file_read',
416
+ usage: 'FILE_ID LENGTH',
417
+ summary: 'Reads LENGTH of data from an opened file'
418
+
419
+ #
420
+ # Reads data from an opened file.
421
+ #
422
+ # @param [String] file_id
423
+ # The file ID number.
424
+ #
425
+ # @param [String] length
426
+ # The length of data to read.
427
+ #
428
+ # @see RemoteFile#read
429
+ #
430
+ def file_read(file_id,length)
431
+ file_id = file_id.to_i
432
+ length = length.to_i
433
+
434
+ if (file = @files[file_id])
435
+ puts(file.read(length))
436
+ else
437
+ print_error "unknown file id: #{file_id}"
438
+ end
439
+ end
440
+
441
+ command 'file.write', method_name: 'file_write',
442
+ usage: 'FILE_ID DATA',
443
+ summary: 'Writes data to an opened file'
444
+
445
+ #
446
+ # Writes data from to an opened file.
447
+ #
448
+ # @param [String] file_id
449
+ # The file ID number.
450
+ #
451
+ # @param [String] data
452
+ # The data to write.
453
+ #
454
+ # @see RemoteFile#write
455
+ #
456
+ def file_write(file_id,data)
457
+ file_id = file_id.to_i
458
+ length = length.to_i
459
+
460
+ if (file = @files[file_id])
461
+ puts file.write(length)
462
+ else
463
+ print_error "unknown file id: #{file_id}"
464
+ end
465
+ end
466
+
467
+ command 'file.close', method_name: 'file_close',
468
+ usage: 'FILE_ID',
469
+ summary: 'Closes an open file'
470
+
471
+ #
472
+ # Closes an opened file.
473
+ #
474
+ # @param [String] file_id
475
+ # The file ID number.
476
+ #
477
+ # @see RemoteFile#close
478
+ #
479
+ def file_close(file_id)
480
+ file_id = file_id.to_i
481
+ length = length.to_i
482
+
483
+ if (file = @files[file_id])
484
+ file.close
485
+ @files.delete(file_id)
486
+
487
+ puts "Closed file ##{file_id} for #{file.path}"
488
+ else
489
+ print_error "unknown file id: #{file_id}"
490
+ end
491
+ end
492
+
493
+ command 'process.pid', method_name: 'process_pid',
494
+ summary: "Prints the process'es PID"
495
+
496
+ #
497
+ # Prints the process'es PID.
498
+ #
499
+ # @see System::Process#getpid
500
+ #
501
+ def process_pid
502
+ puts @system.process.getpid
503
+ end
504
+
505
+ command 'process.ppid', method_name: 'process_ppid',
506
+ summary: "Prints the process'es PPID"
507
+
508
+ #
509
+ # Prints the process'es PPID.
510
+ #
511
+ # @see System::Process#getppid
512
+ #
513
+ def process_ppid
514
+ puts @system.process.getppid
515
+ end
516
+
517
+ command 'process.uid', method_name: 'process_uid',
518
+ summary: "Prints the process'es UID"
519
+
520
+ #
521
+ # Prints the process'es UID.
522
+ #
523
+ # @see System::Process#getuid
524
+ #
525
+ def process_uid
526
+ puts @system.process.getuid
527
+ end
528
+
529
+ command 'process.setuid', method_name: 'process_setuid',
530
+ usage: 'UID',
531
+ summary: "Sets the process'es UID"
532
+
533
+ #
534
+ # Sets the process'es UID.
535
+ #
536
+ # @param [String] new_uid
537
+ #
538
+ # @see System::Process#setuid
539
+ #
540
+ def process_setuid(new_uid)
541
+ @system.process.setuid(new_uid.to_i)
542
+ end
543
+
544
+ command 'process.euid', method_name: 'process_euid',
545
+ usage: 'EUID',
546
+ summary: "Prints the process'es EUID"
547
+
548
+ #
549
+ # Prints the process'es EUID.
550
+ #
551
+ # @see System::Process#geteuid
552
+ #
553
+ def process_euid
554
+ puts @system.process.geteuid
555
+ end
556
+
557
+ command 'process.seteuid', method_name: 'process_seteuid',
558
+ usage: 'EUID',
559
+ summary: "Sets the process'es EUID"
560
+
561
+ #
562
+ # Sets the process'es EUID.
563
+ #
564
+ # @param [String] new_euid
565
+ #
566
+ # @see System::Process#seteuid
567
+ #
568
+ def process_seteuid(new_euid)
569
+ @system.process.seteuid(new_euid.to_i)
570
+ end
571
+
572
+ command 'process.gid', method_name: 'process_gid',
573
+ usage: 'COMMAND',
574
+ summary: "Prints the process'es GID"
575
+
576
+ #
577
+ # Prints the process'es GID.
578
+ #
579
+ # @see System::Process#getgid
580
+ #
581
+ def process_gid
582
+ puts @system.process.getgid
583
+ end
584
+
585
+ command 'process.setgid', method_name: 'process_setgid',
586
+ usage: 'GID',
587
+ summary: "Sets the process'es GID"
588
+
589
+ #
590
+ # Sets the process'es GID.
591
+ #
592
+ # @param [String] new_gid
593
+ #
594
+ # @see System::Process#setgid
595
+ #
596
+ def process_setgid(new_gid)
597
+ @system.process.setgid(new_gid.to_i)
598
+ end
599
+
600
+ command 'process.egid', method_name: 'process_egid',
601
+ summary: "Prints the process'es EGID"
602
+
603
+ #
604
+ # Prints the process'es EGID.
605
+ #
606
+ # @see System::Process#getegid
607
+ #
608
+ def process_egid
609
+ puts @system.process.getegid
610
+ end
611
+
612
+ command 'process.setegid', method_name: 'process_setegid',
613
+ usage: 'EGID',
614
+ summary: "Sets the process'es EGID"
615
+
616
+ #
617
+ # Sets the process'es EGID.
618
+ #
619
+ # @param [String] new_egid
620
+ #
621
+ # @see System::Process#setegid
622
+ #
623
+ def process_setegid(new_egid)
624
+ @system.process.setegid(new_egid.to_i)
625
+ end
626
+
627
+ command 'process.sid', method_name: 'process_sid',
628
+ summary: "Prints the process'es SID"
629
+
630
+ #
631
+ # Prints the process'es SID.
632
+ #
633
+ # @see System::Process#getsid
634
+ #
635
+ def process_sid
636
+ puts @system.process.getsid
637
+ end
638
+
639
+ command 'process.setsid', method_name: 'process_setsid',
640
+ usage: 'SID',
641
+ summary: "Prints the process'es SID"
642
+
643
+ #
644
+ # Sets the process'es SID.
645
+ #
646
+ # @param [String] new_sid
647
+ #
648
+ # @see System::Process#setsid
649
+ #
650
+ def process_setsid(new_sid)
651
+ @system.process.setsid(new_sid.to_i)
652
+ end
653
+
654
+ command 'process.env', method_name: 'process_env',
655
+ summary: "Prints the process'es environment variables"
656
+
657
+ #
658
+ # Prints the process'es environment variables.
659
+ #
660
+ # @see System::Process#environ
661
+ #
662
+ def process_env
663
+ @system.process.env.each do |name,value|
664
+ puts "#{name}=#{value}"
665
+ end
666
+ end
667
+
668
+ command 'process.getenv', method_name: 'process_getenv',
669
+ usage: 'NAME',
670
+ summary: 'Prints an environment variable from the process'
671
+
672
+ #
673
+ # Prints a specific environment variable from the process.
674
+ #
675
+ # @param [String] name
676
+ # The environment variable name.
677
+ #
678
+ # @see System::Process#getenv
679
+ #
680
+ def process_getenv(name)
681
+ puts @system.process.getenv(name)
682
+ end
683
+
684
+ command 'process.setenv', method_name: 'process_setenv',
685
+ usage: 'NAME=VALUE',
686
+ summary: 'Sets an environment variable for the process'
687
+
688
+ #
689
+ # Sets a specific environment variable from the process.
690
+ #
691
+ # @param [String] name_and_value
692
+ # The environment variable name.
693
+ #
694
+ # @see System::Process#getenv
695
+ #
696
+ def process_setenv(name_and_value)
697
+ name, value = name_and_value.split('=',2)
698
+
699
+ @system.process.setenv(name,value)
700
+ end
701
+
702
+ command 'process.unsetenv', method_name: 'process_getenv',
703
+ usage: 'NAME',
704
+ summary: 'Unsets an environment variable for the process'
705
+
706
+ #
707
+ # Unsets a process environment variable.
708
+ #
709
+ # @param [String] name
710
+ # The environment variable to unset.
711
+ #
712
+ # @see System::Process#unsetenv
713
+ #
714
+ def process_unsetenv(name)
715
+ @system.process.unsetenv(name)
716
+ end
717
+
718
+ command 'process.kill', method_name: 'process_kill',
719
+ usage: 'PID [SIGNAL]',
720
+ summary: 'Kills a process'
721
+
722
+ #
723
+ # Kills a process.
724
+ #
725
+ # @param [String] pid
726
+ # The process PID to kill.
727
+ #
728
+ # @param [String] signal
729
+ # The signal to send the process.
730
+ #
731
+ def process_kill(pid,signal='KILL')
732
+ @system.process.kill(pid.to_i,signal)
733
+ end
734
+
735
+ command 'process.spawn', method_name: 'process_spawn',
736
+ usage: 'PROGRAM [ARGS ...]',
737
+ summary: 'Spawns a new process'
738
+
739
+ #
740
+ # Spawns a new process.
741
+ #
742
+ # @param [String] program
743
+ # The program name.
744
+ #
745
+ # @param [Array<String>] arguments
746
+ # Additional command arguments.
747
+ #
748
+ # @see System::Process#spawn
749
+ #
750
+ def process_spawn(program,*arguments)
751
+ pid = @system.process.spawn(program,*arguments)
752
+
753
+ puts "PID: #{pid}"
754
+ end
755
+
756
+ command 'shell.exec', method_name: 'shell_exec',
757
+ usage: 'COMMAND',
758
+ summary: 'Executes a command in the shell'
759
+
760
+ #
761
+ # Executes a shell command.
762
+ #
763
+ # @param [String] command
764
+ # The command to execute.
765
+ #
766
+ # @see System::Shell#run
767
+ #
768
+ def shell_exec(command)
769
+ puts @system.shell.run(command)
770
+ end
771
+
772
+ command 'shell', method_name: 'shell',
773
+ summary: 'Spawns an interactive command shell'
774
+
775
+ #
776
+ # Spawns an interactive command sub-shell.
777
+ #
778
+ # @see ShellShell
779
+ #
780
+ def shell
781
+ ShellShell.start(@system.shell)
782
+ end
783
+
784
+ command 'sys.time', method_name: 'sys_time',
785
+ summary: "Prints the system's current time"
786
+
787
+ #
788
+ # Prints the system's current time.
789
+ #
790
+ # @see System#time
791
+ #
792
+ def sys_time
793
+ puts @system.time
794
+ end
795
+
796
+ command 'sys.hostname', method_name: 'sys_hostname',
797
+ summary: "Prints the system's hostname"
798
+
799
+ #
800
+ # Prints the system's hostname.
801
+ #
802
+ # @see System#hostname
803
+ #
804
+ def sys_hostname
805
+ puts @system.hostname
806
+ end
807
+
808
+ end
809
+ end
810
+ end
811
+ end