Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
emulab
emulab-devel
Commits
606a3a81
Commit
606a3a81
authored
Mar 12, 2010
by
U-CASSANDRA\duerig
Browse files
Merge branch 'master' of git-public.flux.utah.edu:/flux/git/emulab-devel into mapflashbranch
parents
d6d335d4
d883d8c5
Changes
41
Hide whitespace changes
Inline
Side-by-side
account/tbacct.in
View file @
606a3a81
...
...
@@ -2,7 +2,7 @@
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-200
9
University of Utah and the Flux Group.
# Copyright (c) 2000-20
1
0 University of Utah and the Flux Group.
# All rights reserved.
#
use
English
;
...
...
@@ -50,6 +50,7 @@ my $CHATSUPPORT = @CHATSUPPORT@;
my
$MAILMANSUPPORT
=
@MAILMANSUPPORT@
;
my
$THISHOMEBASE
=
"
@THISHOMEBASE
@
";
my
$PROTOUSER
=
'
elabman
';
my
$ELABINELAB
=
@ELABINELAB@
;
my
$SAMBANODE
=
"
fs
";
# DNS makes this do the right thing in E-in-E.
my
$SMBPASSWD
=
"
/usr/local/bin/smbpasswd
";
...
...
@@ -349,6 +350,13 @@ sub AddUser()
if
(
$webonly
)
{
return
0
;
}
#
# Allow for users to be initialized to frozen in an inner Emulab.
#
if
(
$ELABINELAB
&&
$status
eq
USERSTATUS_FROZEN
)
{
print
STDERR
"
Ignoring frozen user in elabinelab
\n
";
return
0
;
}
if
(
$wikionly
)
{
$EUID
=
$UID
;
...
...
@@ -395,14 +403,18 @@ sub AddUser()
}
}
# shell escape.
$pswd
=~
s/\$/\\\$/g
;
$pswd
=~
s/\*/\\\*/g
;
print
"
Initializing user
$user
password on
$CONTROL
.
\n
";
if
(
system
("
$SSH
-host
$CONTROL
$CHPASS
-p '
$pswd
'
$user
"))
{
fatal
("
Could not initialize password for user
$user
on
$CONTROL
!
");
#
# Leave the password "starred" on elabinelab; safer.
#
if
(
!
$ELABINELAB
)
{
# shell escape.
$pswd
=~
s/\$/\\\$/g
;
$pswd
=~
s/\*/\\\*/g
;
print
"
Initializing user
$user
password on
$CONTROL
.
\n
";
if
(
system
("
$SSH
-host
$CONTROL
$CHPASS
-p '
$pswd
'
$user
"))
{
fatal
("
Could not initialize password for
$user
on
$CONTROL
!
");
}
}
#
...
...
@@ -620,8 +632,9 @@ sub UpdatePassword()
#
# Change on ops only if there is a real account there.
# For ELABINELAB, safer to leave the password "starred".
#
if
(
!
$wikionly
)
{
if
(
!
$wikionly
&&
!
$ELABINELAB
)
{
#
# Grab from the DB to avoid taint checking sillyness.
#
...
...
@@ -927,6 +940,14 @@ sub ThawUser()
}
$sfsupdate
=
1
;
#
# This lets users start off as frozen in an ELABINELAB, and then
# get created later. Saves a lot of time.
#
if
(
$ELABINELAB
&&
system
("
egrep -q -s '^
${user}
:' /etc/passwd
"))
{
return
AddUser
();
}
return
UpdateUser
(
0
);
}
...
...
assign/parse_advertisement_rspec.cc
View file @
606a3a81
...
...
@@ -27,9 +27,9 @@ static const char rcsid[] = "$Id: parse_advertisement_rspec.cc,v 1.7 2009-10-21
#define ISSWITCH(n) (n->types.find("switch") != n->types.end())
#ifdef TBROOT
#define SCHEMA_LOCATION TBROOT"/lib/assign/
rspec-
ad.xsd"
#define SCHEMA_LOCATION TBROOT"/lib/assign/ad.xsd"
#else
#define SCHEMA_LOCATION "
rspec-
ad.xsd"
#define SCHEMA_LOCATION "ad.xsd"
#endif
/*
...
...
assign/parse_request_rspec.cc
View file @
606a3a81
...
...
@@ -27,9 +27,9 @@ static const char rcsid[] = "$Id: parse_request_rspec.cc,v 1.16 2009-10-21 20:49
#define ISSWITCH(n) (n->types.find("switch") != n->types.end())
#ifdef TBROOT
#define SCHEMA_LOCATION TBROOT"/lib/assign/
rspec-
request.xsd"
#define SCHEMA_LOCATION TBROOT"/lib/assign/request.xsd"
#else
#define SCHEMA_LOCATION "
rspec-
request.xsd"
#define SCHEMA_LOCATION "request.xsd"
#endif
/*
* XXX: Do I have to release lists when done with them?
...
...
@@ -601,9 +601,16 @@ bool populate_link (DOMElement* elt, tb_vgraph &vg, map< pair<string,string>, pa
tb_vnode
*
src_vnode
=
get
(
vvertex_pmap
,
v_src_vertex
);
tb_vnode
*
dst_vnode
=
get
(
vvertex_pmap
,
v_dst_vertex
);
bool
emulated
=
false
;
if
(
str_virtualization_type
.
compare
(
"raw"
)
==
0
||
str_virtualization_type
.
compare
(
""
)
==
0
)
emulated
=
true
;
// If the virtualization type on the string is missing or "raw", then
// we leave the emulated flag off - we want the whole physical
// interface. If anything else, we assume that it's some kind of
// virtualized link and the emulated flag should be set.
bool
emulated
=
true
;
if
(
str_virtualization_type
.
compare
(
"raw"
)
==
0
||
str_virtualization_type
.
compare
(
""
)
==
0
)
{
emulated
=
false
;
cerr
<<
"Set emulated=false"
<<
endl
;
}
// bool allow_delayed = !hasChildTag (elt, "nodelay");
...
...
assign/score.cc
View file @
606a3a81
...
...
@@ -60,7 +60,7 @@ extern tb_sgraph SG; // switch fabric
void
score_link
(
pedge
pe
,
vedge
ve
,
tb_pnode
*
src_pnode
,
tb_pnode
*
dst_pnode
);
void
unscore_link
(
pedge
pe
,
vedge
ve
,
tb_pnode
*
src_pnode
,
tb_pnode
*
dst_pnode
);
bool
find_best_link
(
pvertex
pv
,
pvertex
switch_pv
,
tb_vlink
*
vlink
,
pedge
&
out_edge
,
bool
check_src_iface
,
pedge
&
out_edge
,
bool
flipped
,
bool
check_src_iface
,
bool
check_dst_iface
);
int
find_interswitch_path
(
pvertex
src_pv
,
pvertex
dest_pv
,
int
bandwidth
,
pedge_path
&
out_path
,
...
...
@@ -240,7 +240,7 @@ float find_link_resolutions(resolution_vector &resolutions, pvertex pv,
pedge
pe
;
// Direct link (have to check both interfaces if they are fixed)
if
(
find_best_link
(
dest_pv
,
pv
,
vlink
,
pe
,
true
,
true
))
{
if
(
find_best_link
(
dest_pv
,
pv
,
vlink
,
pe
,
flipped
,
true
,
true
))
{
tb_link_info
info
(
tb_link_info
::
LINK_DIRECT
);
info
.
plinks
.
push_back
(
pe
);
resolutions
.
push_back
(
info
);
...
...
@@ -279,9 +279,10 @@ float find_link_resolutions(resolution_vector &resolutions, pvertex pv,
}
if
(
first_link
)
{
SDEBUG
(
cerr
<<
" intraswitch: finding first link"
<<
endl
;)
// Check only whether the source interface is fixed - this is the
// first link in a multi-hop path
if
(
!
find_best_link
(
pv
,
*
switch_it
,
vlink
,
first
,
true
,
false
))
{
if
(
!
find_best_link
(
pv
,
*
switch_it
,
vlink
,
first
,
flipped
,
true
,
false
))
{
SDEBUG
(
cerr
<<
" intraswitch failed - no link first"
<<
endl
;)
// No link to this switch
...
...
@@ -292,7 +293,9 @@ float find_link_resolutions(resolution_vector &resolutions, pvertex pv,
if
(
second_link
)
{
// Check only whether the dest interface is fixed - this is the
// last link in a multi-hop path
if
(
!
find_best_link
(
dest_pv
,
*
switch_it
,
vlink
,
second
,
false
,
true
))
{
SDEBUG
(
cerr
<<
" intraswitch: finding second link ("
<<
")"
<<
endl
;)
if
(
!
find_best_link
(
dest_pv
,
*
switch_it
,
vlink
,
second
,
flipped
,
false
,
true
))
{
// No link to this switch
SDEBUG
(
cerr
<<
" intraswitch failed - no link second"
<<
endl
;)
...
...
@@ -359,7 +362,8 @@ float find_link_resolutions(resolution_vector &resolutions, pvertex pv,
if
(
first_link
)
{
// Check only whether the source interface is fixed - this is the
// first link in a multi-hop path
if
(
!
find_best_link
(
pv
,
*
source_switch_it
,
vlink
,
first
,
true
,
false
))
{
if
(
!
find_best_link
(
pv
,
*
source_switch_it
,
vlink
,
first
,
flipped
,
true
,
false
))
{
// No link to this switch
SDEBUG
(
cerr
<<
" interswitch failed - no first link"
<<
endl
;)
...
...
@@ -370,7 +374,8 @@ float find_link_resolutions(resolution_vector &resolutions, pvertex pv,
if
(
second_link
)
{
// Check only whether the dest interface is fixed - this is the
// last link in a multi-hop path
if
(
!
find_best_link
(
dest_pv
,
*
dest_switch_it
,
vlink
,
second
,
false
,
true
))
{
if
(
!
find_best_link
(
dest_pv
,
*
dest_switch_it
,
vlink
,
second
,
flipped
,
false
,
true
))
{
// No link to tshis switch
SDEBUG
(
cerr
<<
" interswitch failed - no second link"
<<
endl
;)
continue
;
...
...
@@ -510,6 +515,7 @@ void resolve_link(vvertex vv, pvertex pv, tb_vnode *vnode, tb_pnode *pnode,
*/
bool
flipped
=
false
;
if
(
vlink
->
src
!=
vv
)
{
SDEBUG
(
cerr
<<
" vlink is flipped"
<<
endl
);
flipped
=
true
;
}
...
...
@@ -1461,7 +1467,7 @@ int add_node(vvertex vv,pvertex pv, bool deterministic, bool is_fixed, bool skip
}
bool
find_best_link
(
pvertex
pv
,
pvertex
switch_pv
,
tb_vlink
*
vlink
,
pedge
&
out_edge
,
bool
check_src_iface
,
pedge
&
out_edge
,
bool
flipped
,
bool
check_src_iface
,
bool
check_dst_iface
)
{
pvertex
dest_pv
;
...
...
@@ -1486,15 +1492,20 @@ bool find_best_link(pvertex pv,pvertex switch_pv,tb_vlink *vlink,
// If the vlink has a fixed source interface, and it doesn't match
// this plink, skip it
// XXX: Is this gonna break interswtich?
if
(
vlink
->
fix_src_iface
&&
check_src_iface
)
{
if
(
plink
->
srciface
!=
vlink
->
src_iface
)
{
SDEBUG
(
cerr
<<
"find_best_link: Fix source: "
<<
plink
->
srciface
<<
" != "
<<
vlink
->
src_iface
<<
endl
);
// Whether we check the 'source' or 'destination' on the vlink against
// the phyisical link's source interface depends on whether we're
// traversing the link if forward or reverse (flipped) order
fstring
compare_iface
=
(
flipped
?
vlink
->
dst_iface
:
vlink
->
src_iface
);
if
(
plink
->
srciface
!=
compare_iface
)
{
SDEBUG
(
cerr
<<
" find_best_link ("
<<
vlink
->
name
<<
"): Fix source: "
<<
plink
->
srciface
<<
" != "
<<
compare_iface
<<
endl
);
continue
;
}
else
{
SDEBUG
(
cerr
<<
"find_best_link: Fix source: "
<<
plink
->
srciface
<<
" == "
<<
vlink
->
src_iface
<<
endl
);
SDEBUG
(
cerr
<<
" find_best_link ("
<<
vlink
->
name
<<
"): Fix source: "
<<
plink
->
srciface
<<
" == "
<<
compare_iface
<<
endl
);
}
}
...
...
@@ -1503,13 +1514,16 @@ bool find_best_link(pvertex pv,pvertex switch_pv,tb_vlink *vlink,
// XXX: This only works because we always have the node as the 'source'
// of a plink! Shouldn't depend on this!
if
(
vlink
->
fix_dst_iface
&&
check_dst_iface
)
{
if
(
plink
->
srciface
!=
vlink
->
dst_iface
)
{
SDEBUG
(
cerr
<<
"find_best_link: Fix dst: "
<<
plink
->
srciface
<<
" != "
<<
vlink
->
dst_iface
<<
endl
);
fstring
compare_iface
=
(
flipped
?
vlink
->
src_iface
:
vlink
->
dst_iface
);
if
(
plink
->
srciface
!=
compare_iface
)
{
SDEBUG
(
cerr
<<
" find_best_link ("
<<
vlink
->
name
<<
"): Fix dst: "
<<
plink
->
srciface
<<
" != "
<<
compare_iface
<<
endl
);
continue
;
}
else
{
SDEBUG
(
cerr
<<
"find_best_link: Fix dst: "
<<
plink
->
srciface
<<
" == "
<<
vlink
->
dst_iface
<<
endl
);
SDEBUG
(
cerr
<<
" find_best_link ("
<<
vlink
->
name
<<
"): Fix dst: "
<<
plink
->
srciface
<<
" == "
<<
compare_iface
<<
endl
);
}
}
...
...
@@ -1562,18 +1576,25 @@ bool find_best_link(pvertex pv,pvertex switch_pv,tb_vlink *vlink,
best_distance
=
distance
;
found_best
=
true
;
best_users
=
plink
->
emulated
+
plink
->
nonemulated
;
SDEBUG
(
cerr
<<
" find_best_link: picked "
<<
plink
->
name
<<
" with "
<<
best_users
<<
" users"
<<
endl
;)
}
}
}
}
if
((
!
vlink
->
emulated
)
&&
found_best
&&
(
best_users
>
0
))
{
SDEBUG
(
cerr
<<
" find_best_link failing (first case) ("
<<
vlink
->
emulated
<<
","
<<
found_best
<<
","
<<
best_users
<<
")"
<<
endl
;)
return
false
;
}
if
(
found_best
)
{
out_edge
=
best_pedge
;
SDEBUG
(
cerr
<<
" find_best_link succeeding"
<<
endl
;)
return
true
;
}
else
{
SDEBUG
(
cerr
<<
" find_best_link failing (second case)"
<<
endl
;)
return
false
;
}
}
...
...
collab/jabber/GNUmakefile.in
View file @
606a3a81
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-200
6
University of Utah and the Flux Group.
# Copyright (c) 2000-20
1
0 University of Utah and the Flux Group.
# All rights reserved.
#
...
...
@@ -13,7 +13,7 @@ include $(OBJDIR)/Makeconf
SBIN_SCRIPTS = jabbersetup addjabberuser deljabberuser \
modjabberbuddies addjabberchat deljabberchat \
setchatmembers
chatsup.py
setchatmembers
LIBEXEC_SCRIPTS =
CTRL_LIBEXEC_SCRIPTS =
CTRL_LIB_FILES =
...
...
collab/jabber/chatsup.py.in
deleted
100644 → 0
View file @
d6d335d4
#! /usr/bin/env python
#
# EMULAB-COPYRIGHT
# Copyright (c) 2005, 2006 University of Utah and the Flux Group.
# All rights reserved.
#
# Permission to use, copy, modify and distribute this software is hereby
# granted provided that (1) source code retains these copyright, permission,
# and disclaimer notices, and (2) redistributions including binaries
# reproduce the notices in supporting documentation.
#
# THE UNIVERSITY OF UTAH ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
# CONDITION. THE UNIVERSITY OF UTAH DISCLAIMS ANY LIABILITY OF ANY KIND
# FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
#
import
sys
import
getopt
import
os
,
os
.
path
TBROOT
=
"@prefix@"
DOMAIN
=
"@OURDOMAIN@"
TBPATH
=
os
.
path
.
join
(
TBROOT
,
"lib"
)
if
TBPATH
not
in
sys
.
path
:
sys
.
path
.
append
(
TBPATH
)
pass
# We get this from the testbed library directory.
import
xmpp
# Debugging output.
debug
=
False
verbose
=
False
# Error condition.
server_error
=
0
exitval
=
0
# The default admin user to connect as is tbops.
admin_user
=
"testbed-ops"
admin_password
=
"WeLovChat"
admin_resource
=
"TestbedOps"
admin_jid
=
""
# Default server to jabber server
jabber_server
=
"jabber."
+
DOMAIN
muc_server
=
"conference."
+
DOMAIN
# The room we are operating on.
chatroom
=
False
chatroom_jid
=
""
;
# Current ID we are looking for, and the one we have.
current_id
=
False
;
desired_id
=
False
;
# Stuff to hand to the muc server.
chatroom_fields
=
{
"muc#owner_roomname"
:
""
,
"muc#owner_roomdesc"
:
""
,
"muc#owner_publicroom"
:
"0"
,
"muc#owner_persistentroom"
:
"1"
,
"privacy"
:
"1"
,
"muc#owner_maxusers"
:
"50"
,
"muc#owner_moderatedroom"
:
"0"
,
"defaulttype"
:
"0"
,
"privmsg"
:
"0"
,
"muc#owner_inviteonly"
:
"1"
,
"muc#owner_allowinvites"
:
"1"
,
"legacy"
:
"0"
,
"muc#owner_passwordprotectedroom"
:
"1"
,
"muc#owner_roomsecret"
:
"foobar"
,
"muc#owner_enablelogging"
:
"0"
,
"muc#owner_whois"
:
"anyone"
}
##
# Print the usage statement to stdout.
#
def
usage
():
print
(
"Usage: "
+
sys
.
argv
[
0
]
+
" [-d] [-s server] <room> <op> [params]"
)
sys
.
exit
(
-
1
)
#
# Process program arguments.
#
try
:
# Parse the options,
opts
,
req_args
=
getopt
.
getopt
(
sys
.
argv
[
1
:],
"dhs:"
,
[
"help"
,
"server="
])
# ... act on them appropriately, and
for
opt
,
val
in
opts
:
if
opt
in
(
"-h"
,
"--help"
):
usage
()
pass
elif
opt
in
(
"-s"
,
"--server"
):
jabber_server
=
val
pass
elif
opt
in
(
"-d"
,
"--debug"
):
debug
=
True
pass
pass
pass
except
getopt
.
error
,
e
:
print
e
.
args
[
0
]
usage
()
sys
.
exit
(
2
)
pass
if
len
(
req_args
)
<
2
:
usage
()
sys
.
exit
(
2
)
pass
# First argument is the room jid.
chatroom
=
req_args
[
0
]
req_args
=
req_args
[
1
:];
# We need these a lot.
chatroom_jid
=
chatroom
+
"@"
+
muc_server
+
"/"
+
admin_resource
;
admin_jid
=
admin_user
+
"@"
+
jabber_server
+
"/"
+
admin_resource
#
# These handlers are required by the xmpp library.
#
def
HandlePresence
(
session
,
presence
):
global
current_id
,
server_error
if
verbose
:
print
str
(
presence
)
pass
current_id
=
presence
.
getID
()
if
presence
.
getType
()
==
'error'
:
errmsg
=
presence
.
getError
()
server_error
=
presence
.
getErrorCode
()
raise
xmpp
.
protocol
.
NodeProcessed
pass
# This is for doing the RoomExists test below.
def
HandleMessage
(
session
,
message
):
global
current_id
,
server_error
if
verbose
:
print
str
(
message
)
pass
current_id
=
message
.
getID
()
if
message
.
getType
()
==
'error'
:
errmsg
=
message
.
getError
()
server_error
=
message
.
getErrorCode
()
raise
xmpp
.
protocol
.
NodeProcessed
pass
def
HandleIQ
(
conn
,
iq_node
):
global
current_id
,
desired_id
if
verbose
:
print
str
(
iq_node
)
pass
current_id
=
iq_node
.
getID
()
if
current_id
==
desired_id
:
raise
xmpp
.
protocol
.
NodeProcessed
pass
def
HandleIQ_Error
(
conn
,
iq_node
):
global
current_id
,
server_error
if
verbose
:
print
str
(
iq_node
)
pass
errmsg
=
iq_node
.
getError
()
current_id
=
iq_node
.
getID
()
server_error
=
1
raise
xmpp
.
protocol
.
NodeProcessed
pass
#
# Try and connect.
#
def
Connect
():
jid
=
xmpp
.
protocol
.
JID
(
admin_jid
)
dbg
=
[]
if
debug
:
dbg
=
[
'always'
,]
pass
cl
=
xmpp
.
Client
(
jid
.
getDomain
(),
debug
=
dbg
)
cl
.
connect
()
cl
.
auth
(
jid
.
getNode
(),
admin_password
,
resource
=
admin_resource
)
cl
.
sendInitPresence
(
requestRoster
=
0
)
cl
.
Process
(
timeout
=
2
)
cl
.
RegisterHandler
(
'presence'
,
HandlePresence
)
cl
.
RegisterHandler
(
'message'
,
HandleMessage
)
cl
.
RegisterHandler
(
'iq'
,
HandleIQ
,
'result'
)
cl
.
RegisterHandler
(
'iq'
,
HandleIQ_Error
,
'error'
)
return
cl
#
# Wait for response. Generic 10 second timeout, or if error.
#
def
SendAndWait
(
client
,
x
):
global
current_id
,
desired_id
,
server_error
server_error
=
0
current_id
=
False
desired_id
=
x
.
getID
()
# Send it and wait.
client
.
send
(
x
)
waitcount
=
10
while
(
waitcount
>=
0
):
client
.
Process
(
timeout
=
1
)
if
current_id
==
desired_id
:
if
server_error
!=
0
:
return
-
1
return
0
waitcount
=
waitcount
-
1
pass
if
waitcount
<
0
:
print
"Timed out talking to server"
;
sys
.
exit
(
1
);
pass
pass
#
# See if a room already exists.
#
def
RoomExists
(
client
):
global
server_error
#
# Send a message to the room. If the room does not exist, we get
# back an error 400. If the room does exists, we get back an error
# 405 since we are not in the room, and thus are not allowed to send
# messages to the room. Reverse engineering ...
#
p
=
xmpp
.
Message
(
to
=
chatroom
+
"@"
+
muc_server
);
# Add an id, to look for.
p
.
setID
(
"exists"
)
# Wait for response
SendAndWait
(
client
,
p
);
# We should always get an error back
if
server_error
==
0
:
print
"RoomExists: Protocol error; no error returned."
;
sys
.
exit
(
1
);
pass
if
server_error
==
"400"
:
return
False
elif
server_error
==
"405"
:
return
True
print
"RoomExists: Protocol error; error "
+
server_error
+
" returned."
;
sys
.
exit
(
1
);
pass
#
# Create/Delete a romm
#
def
DoChatRoom
(
client
,
args
):
global
chatroom
,
admin_jid
op
=
args
[
0
]
exists
=
RoomExists
(
client
);
#
# Destroy the room.
#
if
(
op
==
"destroy"
):
if
exists
==
False
:
print
"Presence: Chatroom "
+
chatroom
+
" does not exist."
return
0
# Must enter the room to destroy it. How dumb is that!
p
=
xmpp
.
Presence
(
to
=
chatroom_jid
);
p
.
setTag
(
xmpp
.
NS_MUC
+
' x'
)
p
.
setID
(
"enter"
);
if
SendAndWait
(
client
,
p
)
<
0
:
print
"Presence: Chatroom "
+
chatroom
+
" could not be entered"
return
-
1
client
.
Process
(
timeout
=
2
)
# Now send the magic destroy message.
iq
=
xmpp
.
Iq
(
typ
=
'set'
,
queryNS
=
xmpp
.
protocol
.
NS_MUC_OWNER
,
frm
=
admin_jid
,
to
=
chatroom
+
"@"
+
muc_server
)
# Add a destroy element to the query element. It is empty.
item
=
iq
.
getTag
(
'query'
).
setTag
(
'destroy'
)
# Add an id, to look for.
iq
.
setID
(
"begone"
)
# Send it and wait. Server either did it or failed.
return
SendAndWait
(
client
,
iq
)
if
exists
==
True
:
print
"Presence: Chatroom "
+
chatroom
+
" already exists."
return
0
#
# Otherwise creating a room. Must have a password.
#
if
len
(
args
)
!=
3
:
usage
()
sys
.
exit
(
2
)
pass
password
=
args
[
1
]
leader
=
args
[
2
]
# Announce presence, which creates room.
p
=
xmpp
.
Presence
(
to
=
chatroom_jid
)
p
.
setTag
(
xmpp
.
NS_MUC
+
' x'
)
p
.
setID
(
"create"
);