Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #/usr/bin/python
- # terminal based chat server
- #
- #
- #
- #
- # import needed modules:
- from socket import * # get sockets, for well, sockets
- import string # string functions
- import time # for sleep(1) function
- import random
- # new for select()
- from select import *
- # for printing unknown exceptions
- import sys
- import traceback
- # new
- import chatcmds
- import chatglobals
- # define global variables
- HOST = '' # Symbolic name meaning the local host
- PORT = 2749 # Arbitrary non-privileged server
- endl = "\r\n" # standard terminal line ending
- PASS = "foo"
- # set to 1 to allow only this domain to login
- checkdomain = 0
- DOMAIN = 'truehelix.com'
- done = 0 # set to 1 to shut this down
- kAskName = 0 # some constants used to flag
- kWaitName = 1 # the state of each user
- kOK = 2
- # class to store info about connected users
- class User:
- def __init__(self):
- self.name = ""
- self.addr = ""
- self.userinfo = ""
- self.id = ""
- self.conn = None
- self.step = kAskName
- self.away = ""
- self.awaymsg = "Away..."
- self.packetbuf = ""
- self.timeOfLastCmd = time.time()
- def Idle(self):
- if self.step == kAskName:
- self.AskName()
- def AskName(self):
- self.conn.send('''\nThis chat room will let you connect and talk to other people on the server.
- to connect you can either telnet to port 2749 or use a prior made client\n''')
- # self.conn.send("Enter your name: \r\n")
- self.conn.send("Enter handle: ")
- self.step = kWaitName
- def HandleMsg(self, msg):
- # print "Handling message: ["+msg+"]"
- self.timeOfLastCmd = time.time()
- # global chatglobals.userlist
- # if waiting for name, record it
- if self.step == kWaitName:
- # try to trap garb initiall sent by some telnets:
- msg = string.replace(msg, ' ', '')
- if len(msg) < 2 or msg=="#":
- self.conn.send('''\r
- Sorry, that name is invalid, try again.\r
- \r
- If you have further difficulties, please contact the chat\r
- room administrator for assistance.\r
- \r
- \r
- In the chat room, anything you say will be preceeded by the\r
- name you choose for yourself. Please choose the name you\r
- wish to be known by on the chat room.\r
- \r
- ''')
- self.conn.send("Enter Handle: ")
- return
- if chatcmds.finduser(msg):
- self.conn.send('''\r
- That name is already in use, please try again.\r
- \r
- If you have further difficulties, please contact the chat\r
- room administrator for assistance.\r
- \r
- \r
- In the chat room, anything you say will be preceeded by the\r
- name you choose for yourself. Please choose the name you\r
- wish to be known by on the chat room.\r
- \r
- ''')
- self.conn.send("Enter Handle: ")
- return
- print "Setting name to: ["+msg+"]"#Shows who is being named what
- self.name = msg
- self.step = kOK
- self.conn.send('''\r
- \r
- \r
- \r
- Welcome... \r
- \r
- For information on available commands, type /HELP\r
- \r
- \r
- ''')
- # new
- chatcmds.who(self)
- #self.conn.send("Hello, "+self.name+endl)
- chatcmds.broadcastAllbutOne("+=+ " + self.name + " [" + self.id
- + self.hostname + "] entered the chat room at: "
- + time.strftime('%I:%M %p, %a, %b %d, %Y',
- time.localtime(time.time())) + " +=+", self)
- chatcmds.broadcastAllbutOne("+=+ " + self.name + " [" + self.id
- + self.hostname + "] entered this channel at: " +
- time.strftime('%I:%M %p, %a, %b %d, %Y',
- time.localtime(time.time())) + " +=+" + endl, self)
- chatglobals.recentlist.append(self.name + " [" + self.id
- + self.hostname + "] - " +
- time.strftime('%I:%M %p, %a, %b %d, %Y',
- time.localtime(time.time())))
- if len(chatglobals.recentlist) > 20:
- del chatglobals.recentlist[0]
- return
- # check for commands
- # new
- chatcmds.parsecmd(self, msg)
- # polled to check for incoming connections
- def pollNewConn():
- try:
- conn, addr = s.accept()
- except:
- return None
- print "Connection from", addr
- conn.setblocking(0)
- # telnet protocol
- IAC = chr(255)
- DO = chr(253)
- DONT = chr(254)
- WILL = chr(251)
- WONT = chr(252)
- ECHO = chr(1)
- LINEMODE = chr(34)
- SB = chr(250)
- SE = chr(240)
- EDIT = chr(1)
- MODE = chr(1)
- user = User();
- user.conn = conn
- user.addr = addr
- try:
- hostinfo = gethostbyaddr(addr[0])
- user.hostname = hostinfo[0]
- except error, details:
- print 'pollnewconn()', details
- data = getid(addr[0], addr[1], PORT)
- print data
- if data:
- data = string.split(data, ':')
- if len(data) == 4:
- user.id = string.strip(data[3]) + "@"
- chatcmds.broadcast(endl + "Connection from " + user.id + user.hostname + endl)
- # source domain check
- if checkdomain == 1:
- if string.find(user.hostname, DOMAIN) == -1:
- chatcmds.broadcast(endl + user.hostname + " connection rejected." + endl)
- user.conn.send(endl + user.hostname + " connection rejected." + endl)
- user.conn.close()
- return None
- return user
- # ident client
- def getid(remotehost, remoteport, localport):
- host = remotehost
- port = 113
- s = socket(AF_INET, SOCK_STREAM)
- try:
- s.connect(host, port)
- s.send(`remoteport` + ", " + `localport` + "\r\n")
- data = s.recv(1024)
- except:
- data = ''
- s.close()
- return data
- def myfilter(x):
- # 32-122 123 { |124 | |125 } |126 ~ |127 DEL|
- truth = x>=' ' and x<=chr(127)
- # if not truth or x == chr(34) or x == chr(8) or x == chr(127):
- # print "<" + `ord(x)` + ">"
- if x == chr(8): # backspace
- return 1
- return truth
- # MAIN PROGRAM
- # set up the server
- s = socket(AF_INET, SOCK_STREAM)
- try:
- s.bind((HOST, PORT)) # python 2
- except:
- # traceback.print_exc()
- print `sys.exc_info()[:2]`
- print " Re-trying again in 60 sec..."
- time.sleep(60)
- s.bind( (HOST, PORT) ) # python 2
- s.setblocking(0)
- s.listen(1)
- print "Waiting for connection(s)..."
- # loop until done, handling connections and incoming messages
- # new for select()
- S_DEL = 0
- while not done:
- time.sleep(.5) # sleep to reduce processor usage
- u = pollNewConn() # check for incoming connections
- if u:
- chatglobals.userlist.append(u)
- print len(chatglobals.userlist),"connection(s)"
- for u in chatglobals.userlist: # check all connected users
- u.Idle()
- # new for select()
- # print 'select'
- # not more efficient yet
- ino,uto,ero = select([u.conn],[],[u.conn],S_DEL)
- if ero:
- print "Exception:",ero
- continue
- if u.conn in ino:
- # end new for select()
- try:
- data = u.conn.recv(1024)
- if not data: # user disconnected
- chatcmds.disconnect(u)
- # data = filter(myfilter, data)
- # data = string.strip(data)
- if data:
- # print "From",u.name,': ['+data+']'
- # new
- u.packetbuf = u.packetbuf + data
- while 1:
- nlindex = string.find(u.packetbuf, '\n')
- if nlindex < 0:
- nlindex = string.find(u.packetbuf,'\r')
- if nlindex < 0:
- break
- donebuf = u.packetbuf[:nlindex]
- try:
- restbuf = u.packetbuf[nlindex + 1:]
- except IndexError:
- restbuf = ''
- u.packetbuf = restbuf
- donebuf = filter(myfilter, donebuf)
- donebuf = string.strip(donebuf)
- if donebuf:
- # new
- if donebuf == "\\reload " + PASS:
- reload(chatcmds)
- chatcmds.broadcast(endl +
- "Reloading cmds..." + endl)
- else:
- # end new
- u.HandleMsg(donebuf)
- # u.HandleMsg(data)
- # if data == "/shutdown": done=1
- if donebuf == "\\shutdown " + PASS:
- done=1
- # for select(), indent more
- except error:
- chatcmds.disconnect(u)
- chatcmds.broadcast(endl + `sys.exc_info()[:2]` + endl)
- traceback.print_exc()
- # temp off
- except:
- chatcmds.broadcast(endl + `sys.exc_info()[:2]` + endl)
- traceback.print_exc()
- for u in chatglobals.userlist:
- u.conn.close()
- s.close()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement