summaryrefslogtreecommitdiffstats
path: root/clients
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2004-01-08 21:22:53 +0000
committerLennart Poettering <lennart@poettering.net>2004-01-08 21:22:53 +0000
commit5565b244c983bfbfd8b88077eda690fd630e3f1f (patch)
tree273049996c7e3b1bc855730fea9b993a9d79c2f7 /clients
parent9f14b1b80e6b09e6b2dc067704fff2034dc0ad23 (diff)
renaming client -> clients
git-svn-id: file:///home/lennart/svn/public/ivam2/trunk@19 dbf6933d-3bce-0310-9bcc-ed052ba35b35
Diffstat (limited to 'clients')
-rwxr-xr-xclients/ivam-autobox59
-rwxr-xr-xclients/ivam-createvb6
-rwxr-xr-xclients/ivam-echo3
-rwxr-xr-xclients/ivam-play3
-rwxr-xr-xclients/ivam-voicebox55
-rw-r--r--clients/ivamApi.py49
-rw-r--r--clients/ivamCore.py18
-rw-r--r--clients/ivamDefs.py3
-rw-r--r--clients/ivamPipeConnector.py247
-rw-r--r--clients/ivamShbufConnector.py26
-rw-r--r--clients/ivamUtil.py36
-rw-r--r--clients/ivamVoiceBox.py291
12 files changed, 796 insertions, 0 deletions
diff --git a/clients/ivam-autobox b/clients/ivam-autobox
new file mode 100755
index 0000000..bb7fcfc
--- /dev/null
+++ b/clients/ivam-autobox
@@ -0,0 +1,59 @@
+#!/usr/bin/python
+
+import sys, os, getopt
+
+from ivamCore import log
+import ivamCore, ivamVoiceBox
+
+def usage():
+ log("%s [--record-time=SECS] [--pin=PIN] [--pin-file=PINFILE] [--debug] [DIRECTORY]" % sys.argv[0])
+
+def parseArgs(vb, argv):
+
+ try:
+ opts, args = getopt.getopt(argv[1:], "ht:p:P:de:", ["help", "record-time=", "pin=", "pin-file=", "debug", "message-program"])
+ except getopt.GetoptError:
+ usage()
+ sys.exit(1)
+
+ recordTime = 60
+ pin = "-"
+
+ for o, a in opts:
+ if o in ("-d", "--debug"):
+ ivamCore.DEBUG = True
+
+ elif o in ("-h", "--help"):
+ usage()
+ sys.exit()
+
+ elif o in ("-t", "--record-time"):
+ recordTime = int(a)
+
+ elif o in ("-p", "--pin"):
+ pin = a
+
+ elif o in ("-P", "--pin-file"):
+ pin = getContents(a)
+
+ dname = "msn-" + os.getenv("RINGMSN")
+
+ if len(args):
+ dname = args[0] + "/" + dname
+
+ try:
+ ivamVoiceBox.setupVoiceBox(dname, pin, recordTime)
+ except OSError:
+ pass
+
+ vb.setDirectory(dname)
+
+def main():
+ vb = ivamVoiceBox.VoiceBox()
+ parseArgs(vb, sys.argv)
+ ivamCore.newConnector(vb).run()
+ sys.exit()
+
+if __name__ == "__main__":
+ main()
+
diff --git a/clients/ivam-createvb b/clients/ivam-createvb
new file mode 100755
index 0000000..7365db6
--- /dev/null
+++ b/clients/ivam-createvb
@@ -0,0 +1,6 @@
+#!/usr/bin/python
+
+import ivamVoiceBox
+
+ivamVoiceBox.setupVoiceBox("lennart")
+
diff --git a/clients/ivam-echo b/clients/ivam-echo
new file mode 100755
index 0000000..b0f3e40
--- /dev/null
+++ b/clients/ivam-echo
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+exec cat
diff --git a/clients/ivam-play b/clients/ivam-play
new file mode 100755
index 0000000..043ffbe
--- /dev/null
+++ b/clients/ivam-play
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+exec zcat -f "$1"
diff --git a/clients/ivam-voicebox b/clients/ivam-voicebox
new file mode 100755
index 0000000..fbf6afa
--- /dev/null
+++ b/clients/ivam-voicebox
@@ -0,0 +1,55 @@
+#!/usr/bin/python
+
+import sys, os, getopt
+
+from ivamCore import log
+import ivamCore, ivamVoiceBox
+
+def usage():
+ log("%s [--record-time=SECS] [--pin=PIN] [--pin-file=PINFILE] [--message-program=BINARY] [--debug] DIRECTORY" % sys.argv[0])
+
+def parseArgs(vb, argv):
+
+ try:
+ opts, args = getopt.getopt(argv[1:], "ht:p:P:de:", ["help", "record-time=", "pin=", "pin-file=", "debug", "message-program"])
+ except getopt.GetoptError:
+ usage()
+ sys.exit(1)
+
+ try:
+ dname = args[0]
+ except IndexError:
+ usage()
+ sys.exit(1)
+
+ vb.setDirectory(dname)
+
+ for o, a in opts:
+ if o in ("-d", "--debug"):
+ ivamCore.DEBUG = True
+
+ elif o in ("-h", "--help"):
+ usage()
+ sys.exit()
+
+ elif o in ("-t", "--record-time"):
+ vb.recordTime = int(a)
+
+ elif o in ("-p", "--pin"):
+ vb.setPin(a)
+
+ elif o in ("-P", "--pin-file"):
+ vb.setPin(getContents(a))
+
+ elif o in ("-e", "--message-program"):
+ vb.messageProgram = a
+
+
+def main():
+ vb = ivamVoiceBox.VoiceBox()
+ parseArgs(vb, sys.argv)
+ ivamCore.newConnector(vb).run()
+ sys.exit()
+
+if __name__ == "__main__":
+ main()
diff --git a/clients/ivamApi.py b/clients/ivamApi.py
new file mode 100644
index 0000000..8cab6f9
--- /dev/null
+++ b/clients/ivamApi.py
@@ -0,0 +1,49 @@
+
+class Processor:
+
+ def onConnect(self, c, callerNumber, ringNumber):
+ pass
+
+ def onHangup(self, c):
+ pass
+
+ def onDtmfEvent(self, c, event):
+ pass
+
+ def onClipFinish(self, c, fname):
+ pass
+
+ def onTimeout(self, c):
+ pass
+
+ def onRecordFinish(self, c, fname):
+ pass
+
+class Connector:
+
+ def run(self):
+ pass
+
+ def playClip(self, fname):
+ pass
+
+ def stopPlayback(self):
+ pass
+
+ def stopPlayback2(self): # Same as previous but call onClipFinish
+ pass
+
+ def recordClip(self, fname, gzip = False):
+ pass
+
+ def stopRecording(self):
+ pass
+
+ def setTimeout(self, t):
+ pass
+
+ def hangup(self, t):
+ pass
+
+ def flushOutput(self):
+ pass
diff --git a/clients/ivamCore.py b/clients/ivamCore.py
new file mode 100644
index 0000000..972c156
--- /dev/null
+++ b/clients/ivamCore.py
@@ -0,0 +1,18 @@
+
+import sys, os
+
+import ivamPipeConnector
+
+DEBUG = False
+
+def newConnector(p):
+
+ if os.getenv("SHBUF") is None:
+ return ivamPipeConnector.PipeConnector(p)
+ else:
+ return None
+# return ShbufConnector(c)
+
+def log(s):
+ sys.stderr.write("%s\n" % s)
+
diff --git a/clients/ivamDefs.py b/clients/ivamDefs.py
new file mode 100644
index 0000000..0804e45
--- /dev/null
+++ b/clients/ivamDefs.py
@@ -0,0 +1,3 @@
+
+spoolDirectory = "/home/lennart/tmp/ivam-spool"
+shareDirectory = "/home/lennart/projects/ivam-reloaded/ulaw"
diff --git a/clients/ivamPipeConnector.py b/clients/ivamPipeConnector.py
new file mode 100644
index 0000000..af302b8
--- /dev/null
+++ b/clients/ivamPipeConnector.py
@@ -0,0 +1,247 @@
+
+import os, sys, time, select, signal, gzip
+
+import ivamCore, ivamApi, ivamUtil
+
+pc = None
+
+def sigterm(*args):
+ pc.quit = 1
+
+class PipeConnector(ivamApi.Connector):
+
+ BUFSIZE = 128
+
+ stdin = sys.stdin
+ stdout = sys.stdout
+
+ playing = False
+ recording = False
+
+ timeout = 0
+ quit = False
+
+ def __init__(self, processor):
+
+ if ivamCore.DEBUG:
+ ivamCore.log("PipeConnector()")
+
+ global pc
+ pc = self
+ signal.signal(signal.SIGTERM, sigterm)
+
+ self.callerNumber = os.getenv("CALLERMSN")
+ self.ringNumber = os.getenv("RINGMSN")
+ self.processor = processor
+
+ try:
+ s = os.fstat(128)
+ self.pipeHack = True
+ ivamCore.log("Found and enabled pipe hack.")
+ except OSError:
+ self.pipeHack = False
+ ivamCore.log("Pipe hack not detected.")
+
+ def openDtmf(self):
+
+ try:
+ fn = os.environ["DTMFFIFO"]
+ except KeyError:
+ self.dtmfFifo = None
+ return
+
+ self.dtmfFifo = file(fn, "rb")
+
+ def playClip(self, fname):
+
+ self.stopPlayback()
+
+ if ivamCore.DEBUG:
+ ivamCore.log("playClip('%s')" % fname)
+
+ self.playFile = ivamUtil.magicFile(fname, "rb")
+ self.playName = fname
+ self.playing = True
+ self.playBuffer = None
+
+ def stopPlayback(self):
+
+ if ivamCore.DEBUG:
+ ivamCore.log("stopPlayback()")
+
+ if self.playing:
+ self.playFile.close()
+ self.playing = False
+
+ def stopPlayback2(self):
+
+ self.stopPlayback()
+ self.processor.onClipFinish(self, self.playName)
+
+ def recordClip(self, fname, z = False):
+
+ self.stopRecording()
+
+ if ivamCore.DEBUG:
+ ivamCore.log("recordClip('%s')" % fname)
+
+ if z:
+ self.recordFile = gzip.open(fname, "w+b")
+ else:
+ self.recordFile = open(fname, "w+b")
+
+ self.recordName = fname
+ self.recording = True
+
+ def stopRecording(self):
+
+ if ivamCore.DEBUG:
+ ivamCore.log("stopRecording()")
+
+ if self.recording:
+ self.recordFile.close()
+ self.recording = False
+
+ self.processor.onRecordFinish(self, self.recordName)
+
+ def setTimeout(self, t):
+
+ if ivamCore.DEBUG:
+ ivamCore.log("timeout(%u)" % t)
+
+ if t:
+ self.timeout = time.time()+t
+ else:
+ self.timeout = 0
+
+
+ def run(self):
+
+ if ivamCore.DEBUG:
+ ivamCore.log("run()")
+
+ self.openDtmf()
+ self.processor.onConnect(self, self.callerNumber, self.ringNumber)
+ self.loop()
+ self.stopPlayback()
+ self.stopRecording()
+ self.processor.onHangup(self)
+
+ if not self.dtmfFifo is None:
+ self.dtmfFifo.close()
+
+ if ivamCore.DEBUG:
+ ivamCore.log("run() finished")
+
+ def hangup(self):
+
+ if ivamCore.DEBUG:
+ ivamCore.log("hangup()")
+
+ self.quit = True
+
+ def loop(self):
+
+ while not self.quit:
+
+ t = None
+ now = time.time()
+
+ if self.timeout:
+ t = self.timeout - now
+
+ if t < 0:
+ t = 0
+
+ o = []
+ i = [self.stdin]
+
+ if not self.dtmfFifo is None:
+ i += [self.dtmfFifo]
+
+ if self.playing:
+ o += [self.stdout]
+
+ if t is None:
+ i, o, x = select.select(i, o, [])
+ else:
+ i, o, x = select.select(i, o, [], t)
+
+ now = time.time()
+
+ if self.timeout and self.timeout < now:
+ self.processor.onTimeout(self)
+ self.timeout = 0
+ if self.quit: break
+
+ # Check DTMF fifo
+ if not self.dtmfFifo is None and self.dtmfFifo in i:
+ self.handleDtmf()
+ if self.quit: break
+
+ # Check STDOUT
+ if self.stdout in o:
+ self.writeStdout()
+ if self.quit: break
+
+ # Check STDIN
+ if self.stdin in i:
+ self.readStdin()
+ if self.quit: break
+
+
+ def readStdin(self):
+
+ buf = os.read(self.stdin.fileno(), self.BUFSIZE)
+
+ if buf == "":
+ self.quit = 1
+ elif self.recording:
+ self.recordFile.write(buf)
+
+
+ def writeStdout(self):
+
+ if not self.playing:
+ return
+
+ if self.playBuffer is None:
+
+ self.playBuffer = self.playFile.read(self.BUFSIZE)
+
+ # EOF?
+ if len(self.playBuffer) == 0:
+ self.stopPlayback2()
+ return
+
+ c = os.write(self.stdout.fileno(), self.playBuffer)
+ self.playBuffer = self.playBuffer[c:]
+
+ if len(self.playBuffer) == 0:
+ self.playBuffer = None
+
+ def handleDtmf(self):
+
+ if not self.dtmfFifo is None:
+
+ d = self.dtmfFifo.read(1)
+
+ if d == "":
+ self.dtmfFifo.close()
+ self.dtmfFifo = None
+ else:
+ self.processor.onDtmfEvent(self, d)
+
+ def flushOutput(self):
+
+ if not self.pipeHack:
+ return
+
+ try:
+ b = os.read(128, 4096)
+ if ivamCore.DEBUG:
+ ivamCore.log("Pipe hack succeeded")
+ except OSError:
+
+ if ivamCore.DEBUG:
+ ivamCore.log("Pipe hack failed")
diff --git a/clients/ivamShbufConnector.py b/clients/ivamShbufConnector.py
new file mode 100644
index 0000000..feef521
--- /dev/null
+++ b/clients/ivamShbufConnector.py
@@ -0,0 +1,26 @@
+
+from ivamApi import ivamConnector
+
+class ivamShbufConnector(ivamAnsweringMachine):
+
+ def run(self):
+ pass
+
+ def playClip(self):
+ pass
+
+ def stopPlayback(self):
+ pass
+
+ def softStopPlayback(self):
+ pass
+
+ def recordClip(self):
+ pass
+
+ def stopRecording(self):
+ pass
+
+ def timeout(self):
+ pass
+
diff --git a/clients/ivamUtil.py b/clients/ivamUtil.py
new file mode 100644
index 0000000..053638e
--- /dev/null
+++ b/clients/ivamUtil.py
@@ -0,0 +1,36 @@
+
+import gzip
+
+def getContents(fn):
+ f = file(fn, "r")
+ r = f.readline().strip(" \t\r\n")
+ f.close()
+ return r
+
+
+def setContents(fn, s):
+ f = file(fn, "w")
+ f.write("%s\n" % s)
+ f.close()
+
+def magicFile(fn, mode):
+
+ f = None
+
+ try:
+ f = gzip.open(fn, mode)
+ f.read(1)
+ f.seek(0)
+ return f
+
+ except IOError:
+
+ if not f is None:
+ f.close()
+
+ return open(fn, mode)
+
+
+
+
+
diff --git a/clients/ivamVoiceBox.py b/clients/ivamVoiceBox.py
new file mode 100644
index 0000000..252ce98
--- /dev/null
+++ b/clients/ivamVoiceBox.py
@@ -0,0 +1,291 @@
+
+import getopt, sys, os, time, re
+import ivamApi, ivamCore, ivamDefs
+
+from ivamUtil import getContents, setContents
+
+class VoiceBox(ivamApi.Processor):
+
+ # Constants
+ STATE_INVALID, STATE_WELCOME, STATE_WELCOME_BEEP, STATE_RECORD, STATE_PRE_FINISH, STATE_FINISH, STATE_AUTH, STATE_MESSAGE, STATE_AUTH_OK, STATE_NO_MORE_MESSAGES, STATE_MESSAGE_BEEP, STATE_REMOVED, STATE_EMPTY = range(13)
+ AUTH_TIMEOUT = 20
+
+ # State
+ currentState = STATE_INVALID
+ fileSuffix = ".ulaw.gz"
+
+ def getClip(self, s):
+ return "%s/%s%s" % (self.directory, s, self.fileSuffix)
+
+ def onConnect(self, c, callerNumber, ringNumber):
+
+ if ivamCore.DEBUG:
+ ivamCore.log("onConnect()")
+
+ self.callerNumber = callerNumber
+ self.ringNumber = ringNumber
+
+ self.currentState = self.STATE_WELCOME
+ c.playClip(self.getClip("welcome"))
+
+ def loginComplete(self, c):
+ self.messages = self.getMessageNames()
+ self.currentMessage = 0
+
+ ivamCore.log("Successful login from %s for MSN %s." % (self.callerNumber, self.ringNumber))
+
+ if len(self.messages) == 0:
+ self.currentState = self.STATE_EMPTY
+ c.playClip(self.getClip("empty"))
+ else:
+ self.currentState = self.STATE_MESSAGE_BEEP
+ c.playClip(self.getClip("beep"))
+
+ def onClipFinish(self, c, fname):
+
+ if ivamCore.DEBUG:
+ ivamCore.log("onClipFinish('%s')" % fname)
+
+ if self.currentState == self.STATE_WELCOME:
+ self.currentState = self.STATE_WELCOME_BEEP;
+ c.playClip(self.getClip("beep"))
+
+ elif self.currentState == self.STATE_WELCOME_BEEP:
+ self.currentState = self.STATE_RECORD
+ c.recordClip(self.nextMessageName(), True)
+ c.setTimeout(self.recordTime)
+
+ elif self.currentState == self.STATE_PRE_FINISH:
+ self.currentState = self.STATE_FINISH
+ c.hangup()
+
+ elif self.currentState == self.STATE_AUTH:
+
+ # Silence ...
+ pass
+
+ elif self.currentState == self.STATE_AUTH_OK:
+
+ self.loginComplete(c)
+
+ elif self.currentState == self.STATE_MESSAGE_BEEP:
+
+ while True:
+
+ if self.currentMessage >= len(self.messages):
+ self.currentState = self.STATE_NO_MORE_MESSAGES
+ c.playClip(self.getClip("nomoremessages"))
+ else:
+ self.currentState = self.STATE_MESSAGE
+
+ try:
+ c.playClip(self.messages[self.currentMessage])
+ except IOError, e:
+ del(self.messages[self.currentMessage])
+
+ if len(self.messages) > 0:
+ continue
+
+ self.currentState = self.STATE_EMPTY
+ c.playClip(self.getClip("empty"))
+
+ break
+
+ elif self.currentState == self.STATE_MESSAGE:
+
+ self.currentMessage +=1
+ self.currentState = self.STATE_MESSAGE_BEEP
+ c.playClip(self.getClip("beep"))
+
+ elif self.currentState == self.STATE_REMOVED:
+
+ if len(self.messages) == 0:
+ self.currentState = self.STATE_EMPTY
+ c.playClip(self.getClip("empty"))
+ else:
+ self.currentState = self.STATE_MESSAGE_BEEP
+ c.playClip(self.getClip("beep"))
+
+ elif self.currentState == self.STATE_NO_MORE_MESSAGES:
+
+ # Silence ...
+ pass
+
+ elif self.currentState == self.STATE_EMPTY:
+
+ # Silence ...
+ pass
+
+ def onDtmfEvent(self, c, event):
+
+ if ivamCore.DEBUG:
+ ivamCore.log("onDtmfEvent(%c)" % event)
+
+ if ((self.currentState == self.STATE_WELCOME) or (self.currentState == self.STATE_WELCOME_BEEP)) and (event == '0'):
+
+ if self.pin == "":
+ self.loginComplete(c)
+
+ elif self.pin == "-":
+ self.currentState = self.STATE_FINISH
+ c.hangup()
+
+ else:
+ self.currentState = self.STATE_AUTH
+ self.inputPin = ""
+ c.stopPlayback()
+ c.playClip(self.getClip("auth"))
+ c.setTimeout(self.AUTH_TIMEOUT)
+
+ elif self.currentState == self.STATE_AUTH:
+ c.stopPlayback()
+ self.inputPin += event
+
+ if len(self.inputPin) >= len(self.pin):
+ c.setTimeout(0)
+
+ if self.inputPin == self.pin:
+ self.currentState = self.STATE_AUTH_OK
+ c.playClip(self.getClip("authok"))
+ else:
+ self.currentState = self.STATE_FINISH
+ c.hangup()
+
+ elif self.currentState in [self.STATE_MESSAGE, self.STATE_MESSAGE_BEEP, self.STATE_NO_MORE_MESSAGES] :
+
+ if event == '0':
+
+ if self.currentMessage >= len(self.messages):
+ self.currentMessage = len(self.messages)-1
+
+ os.remove(self.messages[self.currentMessage])
+ ivamCore.log("Sucessfully removed message '%s' on behalf of %s for MSN %s." % (self.messages[self.currentMessage], self.callerNumber, self.ringNumber))
+ del(self.messages[self.currentMessage])
+
+
+ self.currentState = self.STATE_REMOVED
+ c.playClip(self.getClip("removed"))
+
+ else:
+ changed = False
+
+ if event in ['4', '2']:
+ self.currentMessage -= 1
+ changed = True
+
+ if event in ['6', '8']:
+ self.currentMessage += 1
+ changed = True
+
+ if event == '5':
+ changed = True
+
+ if event == '1':
+ self.currentMessage = 0
+ changed = True
+
+ if event == '7':
+ self.currentMessage = len(self.messages)-1
+ changed = True
+
+ if self.currentMessage < 0:
+ self.currentMessage = 0
+
+ if self.currentMessage >= len(self.messages):
+ self.currentMessage = len(self.messages)-1
+
+ if changed:
+ self.currentState = self.STATE_MESSAGE_BEEP
+ c.playClip(self.getClip("beep"))
+
+ else:
+ c.flushOutput()
+ c.stopPlayback2()
+
+ def onTimeout(self, c):
+
+ if ivamCore.DEBUG:
+ ivamCore.log("onTimeout()")
+
+ if self.currentState == self.STATE_RECORD:
+ self.currentState = self.STATE_PRE_FINISH
+ c.stopRecording()
+ c.playClip(self.getClip("beep"))
+
+ elif self.currentState == self.STATE_AUTH:
+ self.currentState = self.STATE_FINISH
+ c.hangup()
+
+ def onRecordFinish(self, c, fname):
+
+ if ivamCore.DEBUG:
+ ivamCore.log("onRecordFinish(%s)" % fname)
+
+ ivamCore.log("Sucessfully recorded new message '%s' from %s for MSN %s." % (fname, self.callerNumber, self.ringNumber))
+
+ os.environ["SPOOLDIR"] = self.directory
+ ivamCore.log("Starting new message notification program.")
+ r=os.spawnvp(os.P_WAIT, self.messageProgram, (self.messageProgram, fname))
+ ivamCore.log("Program finished (return value is %i)." % r)
+
+ def getMessageNames(self):
+
+ f = os.listdir(self.messageDirectory)
+ f = map(lambda e: "%s/%s" % (self.messageDirectory, e), f)
+ f.sort()
+ f.reverse()
+ return f
+
+ def nextMessageName(self):
+
+ return "%s/%010u:%s:%s%s" % (self.messageDirectory, time.time(), self.ringNumber, self.callerNumber, self.fileSuffix)
+
+ def setPin(self, pin):
+
+ if ivamCore.DEBUG:
+ ivamCore.log("setPin('%s')" % pin)
+
+ if re.match('^([0-9#*]*|-)$', pin).end() is None:
+ ivamCore.log("Invalid PIN. PIN has to consist of 0-9#*. Use '-' for always denying access.")
+ raise Exception, "Invalid PIN"
+
+ self.pin = pin
+
+ def setDirectory(self, dname):
+ if dname.find("/") == -1:
+ dname = "%s/%s" % (ivamDefs.spoolDirectory, dname)
+
+ self.directory = dname
+ self.messageDirectory = dname + "/messages"
+
+
+ try:
+ self.setPin(getContents("%s/PIN" % dname))
+ except Exception:
+ self.pin = "-"
+
+ try:
+ self.recordTime = int(getContents("%s/RECORD_TIME" % dname))
+ except Exception:
+ self.recordTime = 60
+
+ self.messageProgram = "%s/newmessage" % dname
+
+
+
+def setupVoiceBox(dname, pin = "-", recordTime = 60, email = "root"):
+ if dname.find("/") == -1:
+ dname = "%s/%s" % (ivamDefs.spoolDirectory, dname)
+
+ os.mkdir(dname, 0770)
+ os.mkdir("%s/messages" % dname, 0770)
+
+ setContents("%s/PIN" % dname, pin)
+ setContents("%s/RECORD_TIME" % dname, `recordTime`)
+ setContents("%s/EMAIL" % dname, email)
+
+ ulaw = map(lambda e: e+".ulaw.gz", ('welcome', 'beep', 'empty', 'nomoremessages', 'auth', 'authok', 'removed'))
+
+ for f in ulaw + ['newmessage', 'README']:
+ os.symlink("%s/%s" % (ivamDefs.shareDirectory, f), "%s/%s" % (dname, f))
+