Thu, 07 Jan 2010 20:59:15 +0000
clix: Allow --debug to be anywhere on the command-line
4
ead275885948
clix.lua: Add shebang for people who don't use squish
Matthew Wild <mwild1@gmail.com>
parents:
2
diff
changeset
|
1 | #!/usr/bin/env lua |
5
7209e1f8e66b
clix.lua, COPYING: Add COPYING file with MIT license, add copyright header to clix.lua
Matthew Wild <mwild1@gmail.com>
parents:
4
diff
changeset
|
2 | -- Clix -- Command-line XMPP |
7209e1f8e66b
clix.lua, COPYING: Add COPYING file with MIT license, add copyright header to clix.lua
Matthew Wild <mwild1@gmail.com>
parents:
4
diff
changeset
|
3 | -- Copyright (C) 2008-2010 Matthew Wild |
7209e1f8e66b
clix.lua, COPYING: Add COPYING file with MIT license, add copyright header to clix.lua
Matthew Wild <mwild1@gmail.com>
parents:
4
diff
changeset
|
4 | -- |
7209e1f8e66b
clix.lua, COPYING: Add COPYING file with MIT license, add copyright header to clix.lua
Matthew Wild <mwild1@gmail.com>
parents:
4
diff
changeset
|
5 | -- This project is MIT/X11 licensed. Please see the |
7209e1f8e66b
clix.lua, COPYING: Add COPYING file with MIT license, add copyright header to clix.lua
Matthew Wild <mwild1@gmail.com>
parents:
4
diff
changeset
|
6 | -- COPYING file in the source package for more information. |
7209e1f8e66b
clix.lua, COPYING: Add COPYING file with MIT license, add copyright header to clix.lua
Matthew Wild <mwild1@gmail.com>
parents:
4
diff
changeset
|
7 | -- |
0 | 8 | require "verse" |
9 | require "verse.client" | |
10 | ||
8
df4cb4a73549
clix: Make short_opts table global, to allow commands to add their own short options
Matthew Wild <mwild1@gmail.com>
parents:
7
diff
changeset
|
11 | -- Global to allow commands to add to it |
17
fa9efbef8a0c
Move presence sending into clix_connect(), and control with -o/--presence
Matthew Wild <mwild1@gmail.com>
parents:
15
diff
changeset
|
12 | short_opts = { v = "verbose", t = "to", f = "from", e = "type", a = "account", p = "password", r = "resource", o = "presence" } |
8
df4cb4a73549
clix: Make short_opts table global, to allow commands to add their own short options
Matthew Wild <mwild1@gmail.com>
parents:
7
diff
changeset
|
13 | |
0 | 14 | local command = arg[1]; |
15 | ||
16 | if not command then | |
17 | print("Command Line XMPP, available commands:"); | |
18 | for module in pairs(package.preload) do | |
19 | if module:match("^clix%.") then | |
20 | local m = require(module); | |
21 | m{ "--short-help" }; | |
22 | end | |
23 | end | |
24 | return 0; | |
25 | end | |
26 | ||
27 | local ok, m = pcall(require, "clix."..command); | |
28 | if not ok then | |
20
80cc61512f10
clix: Allow --debug to be anywhere on the command-line
Matthew Wild <mwild1@gmail.com>
parents:
17
diff
changeset
|
29 | local is_debug; |
80cc61512f10
clix: Allow --debug to be anywhere on the command-line
Matthew Wild <mwild1@gmail.com>
parents:
17
diff
changeset
|
30 | for i=1,#arg do |
80cc61512f10
clix: Allow --debug to be anywhere on the command-line
Matthew Wild <mwild1@gmail.com>
parents:
17
diff
changeset
|
31 | if arg[i] == "--debug" then |
80cc61512f10
clix: Allow --debug to be anywhere on the command-line
Matthew Wild <mwild1@gmail.com>
parents:
17
diff
changeset
|
32 | is_debug = true; break; |
80cc61512f10
clix: Allow --debug to be anywhere on the command-line
Matthew Wild <mwild1@gmail.com>
parents:
17
diff
changeset
|
33 | end |
80cc61512f10
clix: Allow --debug to be anywhere on the command-line
Matthew Wild <mwild1@gmail.com>
parents:
17
diff
changeset
|
34 | end |
80cc61512f10
clix: Allow --debug to be anywhere on the command-line
Matthew Wild <mwild1@gmail.com>
parents:
17
diff
changeset
|
35 | print("Error running command '"..command..(is_debug and "" or "' (run with --debug to see full error)")); |
80cc61512f10
clix: Allow --debug to be anywhere on the command-line
Matthew Wild <mwild1@gmail.com>
parents:
17
diff
changeset
|
36 | if is_debug then |
0 | 37 | print(m); |
38 | end | |
39 | return 1; | |
40 | end | |
41 | ||
42 | if type(m) ~= "function" then | |
43 | print(command.." is not a valid command"); | |
44 | return 1; | |
45 | end | |
46 | ||
47 | local accounts = { default = {} }; | |
48 | local current_account; | |
49 | for line in io.lines(os.getenv("HOME").."/.clix") do | |
50 | line = line:match("^%s*(.-)%s*$"); | |
51 | if line:match("^%[") then | |
52 | current_account = line:match("^%[(.-)%]"); | |
53 | accounts[current_account] = {}; | |
54 | if not current_account then -- This is the first defined account | |
55 | accounts.default = accounts[current_account]; | |
56 | end | |
57 | elseif current_account then | |
58 | local k,v = line:match("^(%w+)%s*[:=]%s*(.+)$"); | |
59 | accounts[current_account or "default"][k] = v; | |
60 | end | |
61 | end | |
62 | ||
63 | function clix_connect(opts, on_connect) | |
64 | local account = accounts[opts.account or "default"]; | |
65 | if not (account and account.jid) then | |
66 | io.stderr:write("The specified account (", opts.account or "default", ") wasn't found in the config file\n"); | |
67 | return nil; | |
68 | end | |
7
6078e8d2b59d
clix: Enable global Verse logger when verbose is enabled
Matthew Wild <mwild1@gmail.com>
parents:
5
diff
changeset
|
69 | verse.set_logger(opts.verbose and print or function () end); |
2
fd77e75c4891
clix: Make more use of Verse's new logging controls
Matthew Wild <mwild1@gmail.com>
parents:
0
diff
changeset
|
70 | local conn = verse.new(verse.logger()); |
fd77e75c4891
clix: Make more use of Verse's new logging controls
Matthew Wild <mwild1@gmail.com>
parents:
0
diff
changeset
|
71 | conn.log.debug = opts.verbose; |
0 | 72 | conn:hook("authentication-failure", function (err) |
2
fd77e75c4891
clix: Make more use of Verse's new logging controls
Matthew Wild <mwild1@gmail.com>
parents:
0
diff
changeset
|
73 | conn:error("Authentication failure ("..(err.condition or "unknown error")..")"..(err.text and (": "..err.text) or "")); |
14
1e927484c6ec
clix: Close connection after fatal error during login
Matthew Wild <mwild1@gmail.com>
parents:
13
diff
changeset
|
74 | conn:close(); |
0 | 75 | end); |
17
fa9efbef8a0c
Move presence sending into clix_connect(), and control with -o/--presence
Matthew Wild <mwild1@gmail.com>
parents:
15
diff
changeset
|
76 | conn:hook("binding-success", function () |
fa9efbef8a0c
Move presence sending into clix_connect(), and control with -o/--presence
Matthew Wild <mwild1@gmail.com>
parents:
15
diff
changeset
|
77 | conn:debug("Connected: "..tostring(conn)); |
fa9efbef8a0c
Move presence sending into clix_connect(), and control with -o/--presence
Matthew Wild <mwild1@gmail.com>
parents:
15
diff
changeset
|
78 | if opts.presence then |
fa9efbef8a0c
Move presence sending into clix_connect(), and control with -o/--presence
Matthew Wild <mwild1@gmail.com>
parents:
15
diff
changeset
|
79 | conn:send(verse.presence()); |
fa9efbef8a0c
Move presence sending into clix_connect(), and control with -o/--presence
Matthew Wild <mwild1@gmail.com>
parents:
15
diff
changeset
|
80 | end |
fa9efbef8a0c
Move presence sending into clix_connect(), and control with -o/--presence
Matthew Wild <mwild1@gmail.com>
parents:
15
diff
changeset
|
81 | return on_connect(conn); |
fa9efbef8a0c
Move presence sending into clix_connect(), and control with -o/--presence
Matthew Wild <mwild1@gmail.com>
parents:
15
diff
changeset
|
82 | end); |
0 | 83 | conn:hook("binding-failure", function (err) |
2
fd77e75c4891
clix: Make more use of Verse's new logging controls
Matthew Wild <mwild1@gmail.com>
parents:
0
diff
changeset
|
84 | conn:error("Resource binding failure ("..(err.condition or "unknown error")..")"..(err.text and (": "..err.text) or "")); |
14
1e927484c6ec
clix: Close connection after fatal error during login
Matthew Wild <mwild1@gmail.com>
parents:
13
diff
changeset
|
85 | conn:close(); |
0 | 86 | end); |
87 | conn:hook("disconnected", function (info) | |
88 | if info.reason then | |
2
fd77e75c4891
clix: Make more use of Verse's new logging controls
Matthew Wild <mwild1@gmail.com>
parents:
0
diff
changeset
|
89 | conn:warn("Disconnecting: %s", tostring(info.reason)); |
0 | 90 | end |
91 | verse.quit(); | |
92 | end); | |
93 | -- Optional config parameters | |
94 | conn.connect_host = account.address; | |
95 | conn.connect_port = account.port; | |
13
751db005032e
clix: Allow specifying the resource with -r/--resource
Matthew Wild <mwild1@gmail.com>
parents:
11
diff
changeset
|
96 | |
0 | 97 | -- Connect! |
15
54314164a2a3
clix: Allow -p/--password to specify the login password
Matthew Wild <mwild1@gmail.com>
parents:
14
diff
changeset
|
98 | conn:connect_client(account.jid, opts.password or account.password); |
11
a502c905527c
clix: Handle errors (including 'interrupted!') in verse.loop()
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
99 | |
13
751db005032e
clix: Allow specifying the resource with -r/--resource
Matthew Wild <mwild1@gmail.com>
parents:
11
diff
changeset
|
100 | if type(opts.resource) == "string" then |
751db005032e
clix: Allow specifying the resource with -r/--resource
Matthew Wild <mwild1@gmail.com>
parents:
11
diff
changeset
|
101 | conn.resource = opts.resource; |
751db005032e
clix: Allow specifying the resource with -r/--resource
Matthew Wild <mwild1@gmail.com>
parents:
11
diff
changeset
|
102 | end |
751db005032e
clix: Allow specifying the resource with -r/--resource
Matthew Wild <mwild1@gmail.com>
parents:
11
diff
changeset
|
103 | |
11
a502c905527c
clix: Handle errors (including 'interrupted!') in verse.loop()
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
104 | local ok, ret = pcall(verse.loop); |
a502c905527c
clix: Handle errors (including 'interrupted!') in verse.loop()
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
105 | if not ok and not ret:match("interrupted!$") then |
a502c905527c
clix: Handle errors (including 'interrupted!') in verse.loop()
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
106 | io.stderr:write("Fatal error: ", ret, "\n"); |
a502c905527c
clix: Handle errors (including 'interrupted!') in verse.loop()
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
107 | return 1; |
a502c905527c
clix: Handle errors (including 'interrupted!') in verse.loop()
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
108 | end |
a502c905527c
clix: Handle errors (including 'interrupted!') in verse.loop()
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
109 | return err or 0; |
0 | 110 | end |
111 | ||
112 | table.remove(arg,1); | |
113 | ||
114 | local opts = {}; | |
115 | ||
116 | local args_handled_up_to; | |
117 | for i, opt in ipairs(arg) do | |
118 | if opt:match("^%-") and opt ~= "--" then | |
119 | local name = opt:match("^%-%-?([^%s=]+)()") | |
120 | name = (short_opts[name] or name):gsub("%-+", "_"); | |
121 | if name:match("^no_") then | |
122 | name = name:sub(4, -1); | |
123 | opts[name] = false; | |
124 | else | |
125 | opts[name] = opt:match("=(.*)$") or true; | |
126 | end | |
127 | else | |
128 | args_handled_up_to = i-1; | |
129 | break; | |
130 | end | |
131 | end | |
132 | ||
133 | -- Remove all the handled args from the arg array | |
134 | for n=(args_handled_up_to or #arg),1,-1 do | |
135 | table.remove(arg, n); | |
136 | end | |
137 | ||
138 | return m(opts, arg) or 0; | |
139 |