Software /
code /
prosody
Comparison
prosodyctl @ 1087:5e9475bec571
prosodyctl, util.prosodyctl: New prosodyctl utility for managing Prosody servers
author | Matthew Wild <mwild1@gmail.com> |
---|---|
date | Sat, 02 May 2009 17:03:19 +0100 |
child | 1089:a817cbaa0f46 |
comparison
equal
deleted
inserted
replaced
1086:0b895e1ac713 | 1087:5e9475bec571 |
---|---|
1 #!/usr/bin/env lua | |
2 -- Prosody IM v0.4 | |
3 -- Copyright (C) 2008-2009 Matthew Wild | |
4 -- Copyright (C) 2008-2009 Waqas Hussain | |
5 -- | |
6 -- This project is MIT/X11 licensed. Please see the | |
7 -- COPYING file in the source package for more information. | |
8 -- | |
9 | |
10 -- prosodyctl - command-line controller for Prosody XMPP server | |
11 | |
12 -- Will be modified by configure script if run -- | |
13 | |
14 CFG_SOURCEDIR=nil; | |
15 CFG_CONFIGDIR=os.getenv("PROSODY_CFGDIR"); | |
16 CFG_PLUGINDIR=nil; | |
17 CFG_DATADIR=os.getenv("PROSODY_DATADIR"); | |
18 | |
19 -- -- -- -- -- -- -- ---- -- -- -- -- -- -- -- -- | |
20 | |
21 if CFG_SOURCEDIR then | |
22 package.path = CFG_SOURCEDIR.."/?.lua;"..package.path | |
23 package.cpath = CFG_SOURCEDIR.."/?.so;"..package.cpath | |
24 end | |
25 | |
26 if CFG_DATADIR then | |
27 if os.getenv("HOME") then | |
28 CFG_DATADIR = CFG_DATADIR:gsub("^~", os.getenv("HOME")); | |
29 end | |
30 end | |
31 | |
32 -- Required to be able to find packages installed with luarocks | |
33 pcall(require, "luarocks.require") | |
34 | |
35 | |
36 config = require "core.configmanager" | |
37 | |
38 do | |
39 -- TODO: Check for other formats when we add support for them | |
40 -- Use lfs? Make a new conf/ dir? | |
41 local ok, level, err = config.load((CFG_CONFIGDIR or ".").."/prosody.cfg.lua"); | |
42 if not ok then | |
43 print("\n"); | |
44 print("**************************"); | |
45 if level == "parser" then | |
46 print("A problem occured while reading the config file "..(CFG_CONFIGDIR or ".").."/prosody.cfg.lua"); | |
47 local err_line, err_message = tostring(err):match("%[string .-%]:(%d*): (.*)"); | |
48 print("Error"..(err_line and (" on line "..err_line) or "")..": "..(err_message or tostring(err))); | |
49 print(""); | |
50 elseif level == "file" then | |
51 print("Prosody was unable to find the configuration file."); | |
52 print("We looked for: "..(CFG_CONFIGDIR or ".").."/prosody.cfg.lua"); | |
53 print("A sample config file is included in the Prosody download called prosody.cfg.lua.dist"); | |
54 print("Copy or rename it to prosody.cfg.lua and edit as necessary."); | |
55 end | |
56 print("More help on configuring Prosody can be found at http://prosody.im/doc/configure"); | |
57 print("Good luck!"); | |
58 print("**************************"); | |
59 print(""); | |
60 os.exit(1); | |
61 end | |
62 end | |
63 | |
64 local error_messages = setmetatable({ | |
65 ["invalid-username"] = "The given username is invalid in a Jabber ID"; | |
66 ["invalid-hostname"] = "The given hostname is invalid"; | |
67 ["no-password"] = "No password was supplied"; | |
68 ["no-such-user"] = "The given user does not exist on the server"; | |
69 }, { __index = function (t,k) return "Error: "..(tostring(k):gsub("%-", " "):gsub("^.", string.upper)); end }); | |
70 | |
71 hosts = {}; | |
72 | |
73 require "core.hostmanager" | |
74 require "core.eventmanager".fire_event("server-starting"); | |
75 | |
76 require "util.prosodyctl" | |
77 ----------------------- | |
78 | |
79 function show_message(msg, ...) | |
80 print(msg:format(...)); | |
81 end | |
82 | |
83 function show_warning(msg, ...) | |
84 print(msg:format(...)); | |
85 end | |
86 | |
87 function show_usage(usage, desc) | |
88 print("Usage: "..arg[0].." "..usage); | |
89 if desc then | |
90 print(" "..desc); | |
91 end | |
92 end | |
93 | |
94 local function getchar(n) | |
95 os.execute("stty raw -echo"); | |
96 local char = io.read(n or 1); | |
97 os.execute("stty sane"); | |
98 return char; | |
99 end | |
100 | |
101 local function getpass() | |
102 os.execute("stty -echo"); | |
103 local pass = io.read("*l"); | |
104 os.execute("stty sane"); | |
105 io.write("\n"); | |
106 return pass; | |
107 end | |
108 | |
109 function show_yesno(prompt) | |
110 io.write(prompt, " "); | |
111 local choice = getchar():lower(); | |
112 io.write("\n"); | |
113 if not choice:match("%a") then | |
114 choice = prompt:match("%[.-(%U).-%]$"); | |
115 if not choice then return nil; end | |
116 end | |
117 return (choice == "y"); | |
118 end | |
119 | |
120 local function read_password() | |
121 local password; | |
122 while true do | |
123 io.write("Enter new password: "); | |
124 password = getpass(); | |
125 io.write("Retype new password: "); | |
126 if getpass() ~= password then | |
127 if not show_yesno [=[Passwords did not match, try again? [Y/n]]=] then | |
128 return; | |
129 end | |
130 else | |
131 break; | |
132 end | |
133 end | |
134 return password; | |
135 end | |
136 ----------------------- | |
137 local commands = {}; | |
138 local command = arg[1]; | |
139 | |
140 function commands.adduser(arg) | |
141 if not arg[1] or arg[1] == "--help" then | |
142 show_usage([[adduser JID]], [[Create the specified user account in Prosody]]); | |
143 return 1; | |
144 end | |
145 local user, host = arg[1]:match("([^@]+)@(.+)"); | |
146 if not user and host then | |
147 show_message [[Failed to understand JID, please supply the JID you want to create]] | |
148 show_usage [[adduser user@host]] | |
149 return 1; | |
150 end | |
151 | |
152 if not host then | |
153 show_message [[Please specify a JID, including a host. e.g. alice@example.com]]; | |
154 return 1; | |
155 end | |
156 | |
157 if prosodyctl.user_exists{ user = user, host = host } then | |
158 show_message [[That user already exists]]; | |
159 return 1; | |
160 end | |
161 | |
162 if not hosts[host] then | |
163 show_warning("The host '%s' is not listed in the configuration file (or is not enabled).", host) | |
164 show_warning("The user will not be able to log in until this is changed."); | |
165 end | |
166 | |
167 local password = read_password(); | |
168 if not password then return 1; end | |
169 | |
170 local ok, msg = prosodyctl.adduser { user = user, host = host, password = password }; | |
171 | |
172 if ok then return 0; end | |
173 | |
174 show_message(error_messages[msg]) | |
175 return 1; | |
176 end | |
177 | |
178 function commands.passwd(arg) | |
179 if not arg[1] or arg[1] == "--help" then | |
180 show_usage([[passwd JID]], [[Set the password for the specified user account in Prosody]]); | |
181 return 1; | |
182 end | |
183 local user, host = arg[1]:match("([^@]+)@(.+)"); | |
184 if not user and host then | |
185 show_message [[Failed to understand JID, please supply the JID you want to set the password for]] | |
186 show_usage [[passwd user@host]] | |
187 return 1; | |
188 end | |
189 | |
190 if not host then | |
191 show_message [[Please specify a JID, including a host. e.g. alice@example.com]]; | |
192 return 1; | |
193 end | |
194 | |
195 if not prosodyctl.user_exists { user = user, host = host } then | |
196 show_message [[That user does not exist, use prosodyctl adduser to create a new user]] | |
197 return 1; | |
198 end | |
199 | |
200 local password = read_password(); | |
201 if not password then return 1; end | |
202 | |
203 local ok, msg = prosodyctl.passwd { user = user, host = host, password = password }; | |
204 | |
205 if ok then return 0; end | |
206 | |
207 show_message(error_messages[msg]) | |
208 return 1; | |
209 end | |
210 | |
211 function commands.deluser(arg) | |
212 if not arg[1] or arg[1] == "--help" then | |
213 show_usage([[deluser JID]], [[Permanently remove the specified user account from Prosody]]); | |
214 return 1; | |
215 end | |
216 local user, host = arg[1]:match("([^@]+)@(.+)"); | |
217 if not user and host then | |
218 show_message [[Failed to understand JID, please supply the JID you want to set the password for]] | |
219 show_usage [[passwd user@host]] | |
220 return 1; | |
221 end | |
222 | |
223 if not host then | |
224 show_message [[Please specify a JID, including a host. e.g. alice@example.com]]; | |
225 return 1; | |
226 end | |
227 | |
228 if not prosodyctl.user_exists { user = user, host = host } then | |
229 show_message [[That user does not exist on this server]] | |
230 return 1; | |
231 end | |
232 | |
233 local ok, msg = prosodyctl.passwd { user = user, host = host }; | |
234 | |
235 if ok then return 0; end | |
236 | |
237 show_message(error_messages[msg]) | |
238 return 1; | |
239 end | |
240 | |
241 function commands.start() | |
242 local ok, ret = prosodyctl.isrunning(); | |
243 if not ok then | |
244 show_message(error_messages[ret]); | |
245 return 1; | |
246 end | |
247 | |
248 if ret then | |
249 local ok, ret = prosodyctl.getpid(); | |
250 if not ok then | |
251 show_message("Couldn't get running Prosody's PID"); | |
252 show_message(error_messages[ret]); | |
253 return 1; | |
254 end | |
255 show_message("Prosody is already running with PID %s", ret or "(unknown)"); | |
256 return 1; | |
257 end | |
258 | |
259 local ok, ret = prosodyctl.start(); | |
260 if ok then return 0; end | |
261 | |
262 show_message("Failed to start Prosody"); | |
263 show_message(error_messages[ret]) | |
264 return 1; | |
265 end | |
266 | |
267 function commands.status() | |
268 local ok, ret = prosodyctl.isrunning(); | |
269 if not ok then | |
270 show_message(error_messages[ret]); | |
271 return 1; | |
272 end | |
273 | |
274 if ret then | |
275 local ok, ret = prosodyctl.getpid(); | |
276 if not ok then | |
277 show_message("Couldn't get running Prosody's PID"); | |
278 show_message(error_messages[ret]); | |
279 return 1; | |
280 end | |
281 show_message("Prosody is running with PID %s", ret or "(unknown)"); | |
282 return 0; | |
283 end | |
284 return 1; | |
285 end | |
286 | |
287 function commands.stop() | |
288 if not prosodyctl.isrunning() then | |
289 show_message("Prosody is not running"); | |
290 return 1; | |
291 end | |
292 | |
293 local ok, ret = prosodyctl.stop(); | |
294 if ok then return 0; end | |
295 | |
296 show_message(error_messages[ret]) | |
297 return 1; | |
298 end | |
299 | |
300 -- ejabberdctl compatibility | |
301 | |
302 function commands.register(arg) | |
303 local user, host, password = unpack(arg); | |
304 if (not (user and host)) or arg[1] == "--help" then | |
305 if not user and user ~= "--help" then | |
306 show_message [[No username specified]] | |
307 elseif not host then | |
308 show_message [[Please specify which host you want to register the user on]]; | |
309 end | |
310 show_usage("register USER HOST [PASSWORD]", "Register a user on the server, with the given password"); | |
311 return 1; | |
312 end | |
313 if not password then | |
314 password = read_password(); | |
315 if not password then | |
316 show_message [[Unable to register user with no password]]; | |
317 return 1; | |
318 end | |
319 end | |
320 | |
321 local ok, msg = prosodyctl.adduser { user = user, host = host, password = password }; | |
322 | |
323 if ok then return 0; end | |
324 | |
325 show_message(error_messages[msg]) | |
326 return 1; | |
327 end | |
328 | |
329 function commands.unregister(arg) | |
330 local user, host = unpack(arg); | |
331 if (not (user and host)) or arg[1] == "--help" then | |
332 if not user then | |
333 show_message [[No username specified]] | |
334 elseif not host then | |
335 show_message [[Please specify which host you want to unregister the user from]]; | |
336 end | |
337 show_usage("register USER HOST [PASSWORD]", "Permanently remove a user account from the server"); | |
338 return 1; | |
339 end | |
340 | |
341 local ok, msg = prosodyctl.deluser { user = user, host = host }; | |
342 | |
343 if ok then return 0; end | |
344 | |
345 show_message(error_messages[msg]) | |
346 return 1; | |
347 end | |
348 | |
349 | |
350 --------------------- | |
351 | |
352 if not commands[command] then -- Show help for all commands | |
353 function show_usage(usage, desc) | |
354 print(" "..usage); | |
355 print(" "..desc); | |
356 end | |
357 | |
358 print("prosodyctl - Manage a Prosody server"); | |
359 print(""); | |
360 print("Usage: "..arg[0].." COMMAND [OPTIONS]"); | |
361 print(""); | |
362 print("Where COMMAND may be one of:\n"); | |
363 | |
364 local commands_order = { "adduser", "passwd", "deluser" }; | |
365 | |
366 local done = {}; | |
367 | |
368 for _, command_name in ipairs(commands_order) do | |
369 local command = commands[command_name]; | |
370 if command then | |
371 command{ "--help" }; | |
372 print"" | |
373 done[command_name] = true; | |
374 end | |
375 end | |
376 | |
377 for command_name, command in pairs(commands) do | |
378 if not done[command_name] then | |
379 command{ "--help" }; | |
380 print"" | |
381 done[command_name] = true; | |
382 end | |
383 end | |
384 | |
385 | |
386 os.exit(0); | |
387 end | |
388 | |
389 os.exit(commands[command]({ select(2, unpack(arg)) })); |