fargo 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -6,7 +6,51 @@ This gem is an implementation of the [Direct Connect (DC) protocol](http://en.wi
6
6
 
7
7
  `gem install fargo`
8
8
 
9
- ## Usage
9
+ ## Configuration
10
+
11
+ For a full list of configuration options, see [the source](http://github.com/alexcrichton/fargo/blob/master/lib/fargo/client.rb).
12
+
13
+ Whatever the configuration directory is (by default `~/.fargo`), if there is a file called 'config' located in it, it will be eval'ed when Fargo is started. This way you can call `Fargo.configure` to set a nick, the hub address, share directories, and such.
14
+
15
+ The configuration directory will also be used as a location to store the local file list caches.
16
+
17
+ ## CLI Usage
18
+
19
+ The CLI for Fargo works like an IRB session (it actually is an IRB session!). It's got helper methods and tab completion, however, to make things a lot easier.
20
+
21
+ Here's a synopsis of what the console has for you:
22
+
23
+ * `search 'str'` - search for a string on the hub. You will be notified when results arrive
24
+ * `results 'str'` - see the results for the given search
25
+ * `download 0, str=nil` - download the 0th numbered result from the search for 'str'. By default this uses the last given search
26
+ * `get 0, str=nil` - same as `download`
27
+ * `who 'str'=nil` - show a list of users on the hub when no argument is given. Otherwise print out specific information for the given user. If the user is 'name' or 'size', the users will be sorted based off of that attribute
28
+ * `browse 'nick'` - download nick's file list and begin browsing them. This works like a regular shell where you have a current directory and you 'cd' and 'ls' all the time
29
+ * `cd 'dir'` - change directorires
30
+ * `ls 'dir'` - list a directory
31
+ * `get 'file'` - begin downloading of a file (relative to the current dir)
32
+ * `download 'file'` - same as 'get "file"'
33
+ * `transfers` - see what's being downloaded/uploaded (percentages included)
34
+ * `status` - show some information about what you're sharing
35
+ * `say 'msg'` - say 'msg' on the hub (also `send_chat`)
36
+
37
+ All of the methods are just wrappers around the `client` object available in the IRB session. They just manipulate the return values, provide tab completion, and format results.
38
+
39
+ If you wanna get lower level access, the `client` method returns the client to interact with.
40
+
41
+ ### Multiple Instances
42
+
43
+ By default, the CLI tries to connect to an instance of Fargo over DRb at 'localhost:8082'. If this fails, the CLI spawns a new thread with the EventMachine reactor running inside of it to use.
44
+
45
+ If you would like to have multiple applications using the same instance of Fargo on the same machine, simply have one process start up and call
46
+
47
+ <pre>
48
+ DRb.start_service 'druby://localhost:8082', Fargo::Client.new
49
+ </pre>
50
+
51
+ You can also [configure it](http://github.com/alexcrichton/cohort_radio/blob/master/lib/fargo/daemon.rb) or do whatever in the process as well.
52
+
53
+ ## Programmatic Usage
10
54
 
11
55
  <pre>
12
56
  require 'fargo'
@@ -38,6 +82,10 @@ EventMachine.run {
38
82
 
39
83
  See `lib/fargo/client.rb` for a full list of configuration options
40
84
 
85
+ ## Compatibility
86
+
87
+ Fargo should run on both ruby 1.8 and ruby 1.9. It's been tested on 1.8.7 and 1.9.2
88
+
41
89
  ## MIT License
42
90
 
43
91
  Copyright (c) 2010 Alex Crichton
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'fargo'
4
+
5
+ Fargo::CLI.start
@@ -34,28 +34,3 @@ char* base32_encode(const unsigned char* buffer, int len)
34
34
  }
35
35
  return digest;
36
36
  }
37
-
38
- #if 0
39
- char* base32_decode(const unsigned char* buffer, int len)
40
- {
41
- int i, j = 0;
42
- int bits_remain = 0;
43
- unsigned short value = 0;
44
-
45
- for (i = 0; i < len; i++) {
46
- value |= (buffer[i] << bits_remain);
47
- bits_remain += 8;
48
- while (bits_remain > 5 && j < 1023) {
49
- base32_digest[j++] = (value & 0x1F) < 26 ? 'A'+(value & 0x1F) : '2' + (value & 0x1F);
50
- value >>= 5;
51
- bits_remain -= 5;
52
- }
53
- }
54
- if (bits_remain > 0) {
55
- base32_digest[j++] = (value & 0x1F) < 26 ? 'A'+(value & 0x1F) : '2' + (value & 0x1F);
56
- }
57
- base32_digest[j] = '\0';
58
- return base32_digest;
59
- }
60
-
61
- #endif
@@ -1,16 +1,8 @@
1
1
  #ifndef __BASE32_H
2
2
  #define __BASE32_H
3
3
 
4
- #if defined(__cplusplus)
5
- extern "C" {
6
- #endif
7
-
8
4
  // user must call free() funtion on pointer returned from these functions
9
5
 
10
6
  char* base32_encode(const unsigned char* in, int inlen);
11
7
 
12
- #if defined(__cplusplus)
13
- }
14
- #endif
15
-
16
8
  #endif // ifndef __BASE32_H
@@ -134,30 +134,6 @@ extern word64 table[4*256];
134
134
  feedforward
135
135
  #endif
136
136
 
137
- /*
138
- #define tiger_compress_macro(str, state) \
139
- { \
140
- register word64 a, b, c, tmpa; \
141
- word64 aa, bb, cc; \
142
- register word64 x0, x1, x2, x3, x4, x5, x6, x7; \
143
- register word32 i; \
144
- int pass_no; \
145
- \
146
- a = state[0]; \
147
- b = state[1]; \
148
- c = state[2]; \
149
- \
150
- x0=str[0]; x1=str[1]; x2=str[2]; x3=str[3]; \
151
- x4=str[4]; x5=str[5]; x6=str[6]; x7=str[7]; \
152
- \
153
- compress; \
154
- \
155
- state[0] = a; \
156
- state[1] = b; \
157
- state[2] = c; \
158
- }
159
- */
160
-
161
137
  #define tiger_compress_macro(str, state) \
162
138
  { \
163
139
  register word64 a, b, c, tmpa; \
@@ -28,14 +28,6 @@ typedef u_int16_t word16;
28
28
  typedef unsigned char byte;
29
29
  #endif
30
30
 
31
- #if defined(__cplusplus)
32
- extern "C" {
33
- #endif
34
-
35
31
  void tiger(word64 *str, word64 length, word64 *res);
36
32
 
37
- #if defined(__cplusplus)
38
- }
39
- #endif
40
-
41
33
  #endif
@@ -109,43 +109,7 @@ void tt_digest(TT_CONTEXT *ctx, byte *s)
109
109
  word64 tmp, cnt;
110
110
  tt_final(ctx);
111
111
 
112
- /*
113
- dth_top0 = 0;
114
- cnt = ctx->count;
115
- tmp = cnt;
116
- while(tmp == ((tmp >> 1)<<1)) {
117
- dth_top0++;
118
- tmp >>= 1;
119
- }
120
- cnt -= ((word64)1 << dth_top0);
121
-
122
- TRACE(("ctx->top-TIGERSIZE - ctx->nodes == %d\n", ctx->top-TIGERSIZE - ctx->nodes));
123
- */
124
-
125
112
  while( (ctx->top-TIGERSIZE) > ctx->nodes) {
126
- /*
127
- assert(cnt > 0);
128
-
129
- dth_top1 = 0;
130
- tmp = cnt;
131
- while (tmp == ((tmp >> 1)<<1)) {
132
- dth_top1++;
133
- tmp >>= 1;
134
- }
135
- cnt -= ((word64)1 << dth_top1);
136
-
137
- if ((ctx->depth <= dth_top1) && (ctx->depth >= dth_top0)) {
138
- if ( dth_top1 == ctx->depth) {
139
- TRACE(("depth = %d, dth_top0 == %d, dth_top1 == %d\n", ctx->depth, dth_top0, dth_top1));
140
- memmove(ctx->tthl, ctx->top - 2*TIGERSIZE, 2*TIGERSIZE);
141
- ctx->tthl += 2*TIGERSIZE;
142
- } else {
143
- TRACE(("depth = %d, dth_top0 == %d, dth_top1 == %d\n", ctx->depth, dth_top0, dth_top1));
144
- memmove(ctx->tthl, ctx->top - TIGERSIZE, TIGERSIZE);
145
- ctx->tthl += TIGERSIZE;
146
- }
147
- }
148
- */
149
113
  tt_compose(ctx);
150
114
  dth_top0 = dth_top1 + 1;
151
115
  }
@@ -35,14 +35,8 @@ typedef struct tt_context {
35
35
  unsigned char nodes[STACKSIZE]; /* stack of interim node values */
36
36
  } TT_CONTEXT;
37
37
 
38
- #if defined(__cplusplus)
39
- extern "C" {
40
- #endif
41
38
  void tt_init(TT_CONTEXT *ctx, unsigned char *tthl, unsigned depth);
42
39
  //void tt_update(TT_CONTEXT *ctx, unsigned char *buffer, word32 len);
43
40
  void tt_block(TT_CONTEXT *ctx);
44
41
  void tt_digest(TT_CONTEXT *ctx, unsigned char *hash);
45
42
  void tt_copy(TT_CONTEXT *dest, TT_CONTEXT *src);
46
- #if defined(__cplusplus)
47
- }
48
- #endif
@@ -3,16 +3,8 @@
3
3
 
4
4
  #include "tiger.h"
5
5
 
6
- #if defined(__cplusplus)
7
- extern "C" {
8
- #endif
9
-
10
6
  // user must call free() funtion on pointer returned from these functions
11
7
 
12
8
  char* tth(const char* filename, char **tthl, size_t *tthl_len);
13
9
 
14
- #if defined(__cplusplus)
15
- }
16
- #endif
17
-
18
10
  #endif // ifndef __TTH_H
@@ -0,0 +1,9 @@
1
+ require 'mkmf'
2
+
3
+ if RUBY_VERSION =~ /1\.9/
4
+ $CFLAGS << ' -DRUBY_19'
5
+ end
6
+
7
+ if have_header('readline/readline.h') || have_header('readline.h')
8
+ create_makefile('extra_utils')
9
+ end
@@ -0,0 +1,28 @@
1
+ #include <ruby.h>
2
+ #include "screen.h"
3
+
4
+ VALUE rb_readline_clear_rl(VALUE self) {
5
+ clear_rl();
6
+
7
+ return Qtrue;
8
+ }
9
+
10
+ VALUE rb_readline_restore(VALUE self) {
11
+ restore_rl();
12
+
13
+ return Qtrue;
14
+ }
15
+
16
+ VALUE rb_readline_input(VALUE self) {
17
+ char *input = get_readline_input();
18
+
19
+ return rb_str_new(input, strlen(input));
20
+ }
21
+
22
+ Init_extra_utils() {
23
+ VALUE cReadline = rb_define_module("Readline");
24
+
25
+ rb_define_singleton_method(cReadline, "clear_rl", rb_readline_clear_rl, 0);
26
+ rb_define_singleton_method(cReadline, "restore", rb_readline_restore, 0);
27
+ rb_define_singleton_method(cReadline, "get_input", rb_readline_input, 0);
28
+ }
@@ -0,0 +1,77 @@
1
+ /* screen.c - User interface management (Readline)
2
+ *
3
+ * Copyright (C) 2004, 2005 Oskar Liljeblad
4
+ *
5
+ * This program is free software; you can redistribute it and/or modify
6
+ * it under the terms of the GNU General Public License as published by
7
+ * the Free Software Foundation; either version 2 of the License, or
8
+ * (at your option) any later version.
9
+ *
10
+ * This program is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ * GNU Library General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License along
16
+ * with this program; if not, write to the Free Software Foundation,
17
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18
+ */
19
+ /* This piece of code was snatched from lftp, and modified somewhat by me.
20
+ * I suggest a function called rl_clear() be added to readline. The
21
+ * function clears the prompt and everything the user has written so far on
22
+ * the line. The cursor is positioned at the beginning of the line that
23
+ * contained the prompt. Note: This function doesn't modify the screen_state
24
+ * variable.
25
+ */
26
+
27
+ #include <unistd.h>
28
+ #include <stdio.h>
29
+ #include <stdlib.h>
30
+ #include <signal.h>
31
+
32
+ #if defined(HAVE_READLINE_READLINE_H)
33
+ # include <readline/readline.h>
34
+ #elif defined(HAVE_READLINE_H)
35
+ # include <readline.h>
36
+ #endif
37
+
38
+ #include "screen.h"
39
+
40
+ void clear_rl() {
41
+
42
+ extern char *rl_display_prompt;
43
+ #if HAVE__RL_MARK_MODIFIED_LINES
44
+ extern int _rl_mark_modified_lines;
45
+ int old_mark = _rl_mark_modified_lines;
46
+ #endif
47
+ int old_end = rl_end;
48
+ char *old_prompt = rl_display_prompt;
49
+
50
+ rl_end = 0;
51
+ rl_display_prompt = (char*) "";
52
+ rl_expand_prompt(rl_display_prompt);
53
+ #if HAVE__RL_MARK_MODIFIED_LINES
54
+ _rl_mark_modified_lines = 0;
55
+ #endif
56
+
57
+ rl_redisplay();
58
+
59
+ rl_end = old_end;
60
+ rl_display_prompt = old_prompt;
61
+ #if HAVE__RL_MARK_MODIFIED_LINES
62
+ _rl_mark_modified_lines = old_mark;
63
+ #endif
64
+ if (rl_display_prompt == rl_prompt)
65
+ rl_expand_prompt(rl_prompt);
66
+ }
67
+
68
+ void restore_rl() {
69
+ rl_forced_update_display();
70
+ }
71
+
72
+ char* get_readline_input() {
73
+ struct readline_state state;
74
+ rl_save_state(&state);
75
+
76
+ return state.buffer;
77
+ }
@@ -0,0 +1,3 @@
1
+ void clear_rl();
2
+ void restore_rl();
3
+ char* get_readline_input();
@@ -5,7 +5,6 @@ require 'active_support/core_ext/module/attribute_accessors'
5
5
  require 'active_support/core_ext/module/delegation'
6
6
  require 'active_support/buffered_logger'
7
7
  require 'active_support/concern'
8
- require 'active_support/configurable'
9
8
 
10
9
  module Fargo
11
10
  extend ActiveSupport::Autoload
@@ -15,6 +14,7 @@ module Fargo
15
14
  mattr_accessor :logger
16
15
  self.logger = ActiveSupport::BufferedLogger.new STDOUT
17
16
 
17
+ autoload :CLI
18
18
  autoload :Utils
19
19
  autoload :Parser
20
20
  autoload :Client
@@ -53,3 +53,5 @@ module Fargo
53
53
  delegate :config, :configure, :to => Client
54
54
  end
55
55
  end
56
+
57
+ require 'fargo/ext/struct'
@@ -0,0 +1,84 @@
1
+ require 'fargo/ext/irb'
2
+
3
+ module Fargo
4
+ module CLI
5
+ extend ActiveSupport::Autoload
6
+
7
+ autoload :Completion
8
+ autoload :Downloads
9
+ autoload :Help
10
+ autoload :Info
11
+ autoload :Logging
12
+ autoload :NickBrowser
13
+ autoload :Searches
14
+ autoload :Stats
15
+
16
+ def self.start
17
+ Fargo.logger = ActiveSupport::BufferedLogger.new WrappingLogger.new
18
+ Fargo.logger.level = ActiveSupport::BufferedLogger::INFO
19
+
20
+ console = Console.new
21
+
22
+ EventMachine.error_handler { |e|
23
+ if e.message =~ /no acceptor/
24
+ puts "Couldn't open sockets for listening"
25
+ puts " Ports in question:"
26
+ [console.client.config.active_port, console.client.config.search_port,
27
+ console.client.config.websocket_port].each do |p|
28
+ puts "\t#{p}"
29
+ end
30
+ exit
31
+ else
32
+ Readline.above_prompt {
33
+ puts "ERROR!!!", e.message, e.backtrace.join("\n")
34
+ }
35
+ end
36
+ }
37
+
38
+ begin
39
+ console.client.connected?
40
+ rescue DRb::DRbConnError
41
+ current = Thread.current # Wait for the reactor to start
42
+ Thread.start{ EventMachine.run{
43
+ console.client = Fargo::Client.new
44
+ console.client.connect
45
+ current.wakeup
46
+ } }
47
+ sleep
48
+ end
49
+
50
+ console.log_published_messages
51
+
52
+ if !console.client.connected?
53
+ puts "Client couldn't connect!"
54
+ exit
55
+ end
56
+
57
+ IRB.start_session console.instance_eval{ binding } do
58
+ console.setup_console
59
+ end
60
+
61
+ EventMachine.stop
62
+ end
63
+
64
+ class WrappingLogger
65
+ def write str
66
+ Readline.above_prompt{ puts str }
67
+ end
68
+ end
69
+
70
+ class Console
71
+
72
+ include Completion
73
+ include Logging
74
+ include Searches
75
+ include Info
76
+ include Downloads
77
+ include Stats
78
+ include NickBrowser
79
+ include Help
80
+
81
+ end
82
+
83
+ end
84
+ end