File: mldonkey_command.ml

package info (click to toggle)
mldonkey 2.8.1-2etch1
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 16,940 kB
  • ctags: 26,220
  • sloc: ml: 138,666; sh: 15,368; cpp: 12,076; ansic: 8,243; asm: 3,858; xml: 3,367; perl: 1,831; makefile: 259; python: 258
file content (172 lines) | stat: -rw-r--r-- 4,276 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
open Unix;;

let quit = "q"

type application_state = {
  mutable port : int;
  mutable host : string;
  mutable user : string;
  mutable password : string option;
  mutable use_stdin : bool;
  mutable quiet : bool;
  mutable verbose : bool;
  }
  
let create_state () = {
  port = 4000;
  host = "localhost";
  user = "admin";
  password = None;
  quiet = false;
  verbose = false;
  use_stdin = false;
  }

let commands_from_stdin =
  let one_command _ = 
    try
      Some (read_line ())
    with _ ->
      None
  in
  Stream.from one_command

type server_state = S_1 | S_2 | S_3 | End

let mldonkey_result (from_server,to_client) =
  let rec process_server state =
    try
      let new_char = input_char from_server
      in
      Buffer.add_char to_client new_char;
      match (new_char, state) with
      ('m',S_1) ->
        process_server S_2
      | ('\n',S_2) ->
        process_server S_3
      | ('>', S_3) ->
        process_server End
      | (' ',End) ->
        ()
      | _ ->
        process_server S_1
    with End_of_file ->
      ()
  in
  process_server S_1;
  Buffer.add_char to_client '\n'
    

let mldonkey_login (from_server,to_server) user password =
  (* Approximate size of the login panel *)
  let to_client = Buffer.create 600
  in
  let auth =
    let real_password = 
      match password with 
      Some(x) -> x
      | None ->
        begin
        prerr_string "Password: ";
        flush_all ();
        read_line ()
        end
    in
    "auth \""^user^"\" \""^real_password^"\"\n"
  in
  mldonkey_result (from_server,to_client);
  output_string to_server auth;
  flush to_server;
  mldonkey_result (from_server,to_client);
  to_client
  
let mldonkey_command (from_server,to_server) strm_commands = 
  (* Arbitrary size *)
  let to_client = Buffer.create 1000
  in
  let one_command cmd  =
    output_string to_server (cmd ^ "\n");
    flush to_server;
    mldonkey_result (from_server,to_client)
  in
  Stream.iter one_command strm_commands;
  to_client

let mldonkey_logout (from_server,to_server) = 
  (* Approximate size of the quit command *)
  let to_client = Buffer.create 30
  in
  output_string to_server "q\n";
  flush to_server;
  mldonkey_result (from_server,to_client);
  to_client

let _ = 
  let commands = ref []
  in
  let state = create_state ()
  in
  let _ = Arg.parse [
    ("-P", Arg.Int ( fun x -> state.port <- x ), "Port of the telnet mldonkey server");
    ("-h", Arg.String ( fun x -> state.host <- x ), "Host of the telnet mldonkey server");
    ("-u", Arg.String ( fun x -> state.user <- x ), "Username to use while connecting");
    ("-p", Arg.String ( fun x -> state.password <- Some x ), "Password to use while connecting");
    ("-q", Arg.Unit ( fun () -> state.quiet <- true ), "Run without displaying command result");
    ("-s", Arg.Unit ( fun () -> state.use_stdin <- true ), "Use stdin to enter command");
    ("-v", Arg.Unit ( fun () -> state.verbose <- true ), "Display login information") ]
    ( fun x -> commands := x :: !commands )
    "Usage mldonkey_command [options] list_of_command \n where options are:"
  in
  let _ = 
    if state.verbose then 
    begin
      print_string "MLDonkey command sender";
      print_newline ();
      Array.iter ( fun x -> print_string (x^" ") ) Sys.argv;
      print_newline ()
    end
    else
      ()
  in
  let hostent = gethostbyname state.host
  in
  let inet_host = Array.get hostent.h_addr_list 0
  in
  let strm_commands =
    if state.use_stdin then
      commands_from_stdin
    else
      Stream.of_list !commands
  in
  let (from_server, to_server) = 
    open_connection (ADDR_INET (inet_host, state.port))
  in
  let result_login = mldonkey_login (from_server,to_server) 
    state.user state.password
  in
  let result_commands = mldonkey_command (from_server,to_server) 
    strm_commands
  in
  let result_logout = mldonkey_logout (from_server,to_server)
  in
  shutdown_connection from_server;
  begin
  if state.verbose then
    Buffer.output_buffer Pervasives.stdout result_login
  else
    ()
  end;
  begin
  if state.quiet then
    ()
  else
    Buffer.output_buffer Pervasives.stdout result_commands
  end;
  begin
  if state.verbose then
    Buffer.output_buffer Pervasives.stdout result_logout
  else
    ()
  end;
  ()