Advertisement
Guest User

Untitled

a guest
May 27th, 2017
65
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 8.28 KB | None | 0 0
  1. #/usr/bin/python
  2.  
  3. # terminal based chat server
  4. #
  5. #
  6. #
  7. #
  8.  
  9. # import needed modules:
  10.  
  11. from socket import *        # get sockets, for well, sockets
  12. import string               # string functions
  13. import time                 # for sleep(1) function
  14. import random
  15.  
  16. # new for select()
  17. from select import *
  18.  
  19. # for printing unknown exceptions
  20. import sys
  21.  
  22. import traceback
  23.  
  24. # new
  25. import chatcmds
  26. import chatglobals
  27.  
  28. # define global variables
  29.  
  30.  
  31.  
  32. HOST = ''               # Symbolic name meaning the local host
  33. PORT = 2749             # Arbitrary non-privileged server
  34. endl = "\r\n"                   # standard terminal line ending
  35.  
  36. PASS = "foo"
  37.  
  38. # set to 1 to allow only this domain to login
  39. checkdomain = 0
  40. DOMAIN = 'truehelix.com'
  41.  
  42. done = 0                # set to 1 to shut this down
  43.  
  44. kAskName = 0            # some constants used to flag
  45. kWaitName = 1           #   the state of each user
  46. kOK = 2
  47.  
  48.  
  49.  
  50. # class to store info about connected users
  51.  
  52. class User:
  53.     def __init__(self):
  54.         self.name = ""
  55.         self.addr = ""
  56.         self.userinfo = ""
  57.         self.id = ""
  58.         self.conn = None
  59.         self.step = kAskName
  60.         self.away = ""
  61.         self.awaymsg = "Away..."
  62.         self.packetbuf = ""
  63.         self.timeOfLastCmd = time.time()
  64.        
  65.     def Idle(self):
  66.         if self.step == kAskName:
  67.                         self.AskName()
  68.  
  69.     def AskName(self):
  70.         self.conn.send('''\nThis chat room will let you connect and talk to other people on the server.
  71. to connect you can either telnet to port 2749 or use a prior made client\n''')
  72. #       self.conn.send("Enter your name: \r\n")
  73.         self.conn.send("Enter handle: ")
  74.         self.step = kWaitName
  75.  
  76.     def HandleMsg(self, msg):
  77. #       print "Handling message: ["+msg+"]"
  78.  
  79.                 self.timeOfLastCmd = time.time()
  80.  
  81.         # global chatglobals.userlist
  82.        
  83.         # if waiting for name, record it
  84.         if self.step == kWaitName:
  85.             # try to trap garb initiall sent by some telnets:
  86.             msg = string.replace(msg, ' ', '')
  87.             if len(msg) < 2 or msg=="#":
  88.                 self.conn.send('''\r
  89. Sorry, that name is invalid, try again.\r
  90. \r
  91. If you have further difficulties, please contact the chat\r
  92. room administrator for assistance.\r
  93. \r
  94. \r
  95. In the chat room, anything you say will be preceeded by the\r
  96. name you choose for yourself. Please choose the name you\r
  97. wish to be known by on the chat room.\r
  98. \r
  99. ''')
  100.                 self.conn.send("Enter Handle: ")
  101.                 return
  102.             if chatcmds.finduser(msg):
  103.                 self.conn.send('''\r
  104. That name is already in use, please try again.\r
  105. \r
  106. If you have further difficulties, please contact the chat\r
  107. room administrator for assistance.\r
  108. \r
  109. \r
  110. In the chat room, anything you say will be preceeded by the\r
  111. name you choose for yourself. Please choose the name you\r
  112. wish to be known by on the chat room.\r
  113. \r
  114. ''')
  115.                 self.conn.send("Enter Handle: ")
  116.                 return
  117.             print "Setting name to: ["+msg+"]"#Shows who is being named what
  118.             self.name = msg
  119.             self.step = kOK
  120.             self.conn.send('''\r
  121. \r
  122. \r
  123. \r
  124. Welcome... \r
  125. \r
  126. For information on available commands, type /HELP\r
  127. \r
  128. \r
  129. ''')
  130.                         # new
  131.             chatcmds.who(self)
  132.                        
  133.             #self.conn.send("Hello, "+self.name+endl)
  134.             chatcmds.broadcastAllbutOne("+=+ " + self.name + " [" + self.id
  135.                 + self.hostname + "] entered the chat room at: "
  136.                 + time.strftime('%I:%M %p, %a, %b %d, %Y',
  137.                 time.localtime(time.time())) + " +=+", self)
  138.             chatcmds.broadcastAllbutOne("+=+ " + self.name + " [" + self.id
  139.                 + self.hostname + "] entered this channel at: " +
  140.                 time.strftime('%I:%M %p, %a, %b %d, %Y',
  141.                 time.localtime(time.time())) + " +=+" + endl, self)
  142.  
  143.  
  144.             chatglobals.recentlist.append(self.name + " [" + self.id
  145.                 + self.hostname + "] - " +
  146.                 time.strftime('%I:%M %p, %a, %b %d, %Y',
  147.                       time.localtime(time.time())))
  148.             if len(chatglobals.recentlist) > 20:
  149.                 del chatglobals.recentlist[0]
  150.            
  151.             return
  152.  
  153.         # check for commands
  154.  
  155.                 # new
  156.                 chatcmds.parsecmd(self, msg)
  157.  
  158.  
  159.        
  160. # polled to check for incoming connections
  161. def pollNewConn():
  162.     try:
  163.         conn, addr = s.accept()
  164.     except:
  165.         return None
  166.     print "Connection from", addr
  167.     conn.setblocking(0)
  168.  
  169.     # telnet protocol
  170.     IAC = chr(255)
  171.     DO = chr(253)
  172.     DONT = chr(254)
  173.     WILL = chr(251)
  174.     WONT = chr(252)
  175.     ECHO = chr(1)
  176.     LINEMODE = chr(34)
  177.     SB = chr(250)
  178.     SE = chr(240)
  179.     EDIT = chr(1)
  180.     MODE = chr(1)
  181.  
  182.     user = User();
  183.     user.conn = conn
  184.     user.addr = addr
  185.     try:
  186.         hostinfo = gethostbyaddr(addr[0])
  187.         user.hostname = hostinfo[0]
  188.     except error, details:
  189.         print 'pollnewconn()', details
  190.  
  191.     data = getid(addr[0], addr[1], PORT)
  192.     print data
  193.     if data:
  194.         data = string.split(data, ':')
  195.         if len(data) == 4:
  196.         user.id = string.strip(data[3]) + "@"
  197.     chatcmds.broadcast(endl + "Connection from " + user.id + user.hostname + endl)
  198.  
  199.     # source domain check
  200.     if checkdomain == 1:
  201.         if string.find(user.hostname, DOMAIN) == -1:
  202.         chatcmds.broadcast(endl + user.hostname + " connection rejected." + endl)  
  203.         user.conn.send(endl + user.hostname + " connection rejected." + endl)  
  204.         user.conn.close()
  205.         return None
  206.    
  207.     return user
  208.  
  209. # ident client
  210. def getid(remotehost, remoteport, localport):
  211.     host = remotehost
  212.     port = 113
  213.     s = socket(AF_INET, SOCK_STREAM)
  214.     try:
  215.     s.connect(host, port)
  216.     s.send(`remoteport` + ", " + `localport` + "\r\n")
  217.     data = s.recv(1024)
  218.     except:
  219.     data = ''
  220.     s.close()
  221.     return data
  222.  
  223.                    
  224.  
  225. def myfilter(x):
  226. # 32-122    123  { |124  | |125  } |126  ~ |127 DEL|
  227.     truth = x>=' ' and x<=chr(127)
  228. #    if not truth or x == chr(34) or x == chr(8) or x == chr(127):
  229. #   print "<" + `ord(x)` + ">"
  230.     if x == chr(8): # backspace
  231.     return 1
  232.     return truth
  233.  
  234.  
  235. # MAIN PROGRAM
  236.  
  237. # set up the server
  238.  
  239. s = socket(AF_INET, SOCK_STREAM)
  240. try:
  241.     s.bind((HOST, PORT)) # python 2
  242. except:
  243.     # traceback.print_exc()
  244.     print `sys.exc_info()[:2]`
  245.     print " Re-trying again in 60 sec..."
  246.     time.sleep(60)
  247.     s.bind( (HOST, PORT) ) # python 2
  248.        
  249. s.setblocking(0)
  250. s.listen(1)
  251. print "Waiting for connection(s)..."
  252.  
  253. # loop until done, handling connections and incoming messages
  254.  
  255. # new for select()
  256. S_DEL = 0
  257.  
  258. while not done:
  259.     time.sleep(.5)      # sleep to reduce processor usage
  260.     u = pollNewConn()   # check for incoming connections
  261.     if u:
  262.         chatglobals.userlist.append(u)
  263.         print len(chatglobals.userlist),"connection(s)"
  264.  
  265.     for u in chatglobals.userlist# check all connected users
  266.         u.Idle()
  267.                 # new for select()
  268.         # print 'select'
  269.         # not more efficient yet
  270.         ino,uto,ero = select([u.conn],[],[u.conn],S_DEL)
  271.         if ero:
  272.             print "Exception:",ero
  273.             continue
  274.         if u.conn in ino:
  275.         # end new for select()
  276.             try:
  277.             data = u.conn.recv(1024)
  278.             if not data:         # user disconnected
  279.                 chatcmds.disconnect(u)
  280. #           data = filter(myfilter, data)
  281. #           data = string.strip(data)
  282.             if data:
  283.                 # print "From",u.name,': ['+data+']'
  284.                 # new
  285.                 u.packetbuf = u.packetbuf + data
  286.                 while 1:
  287.                     nlindex = string.find(u.packetbuf, '\n')
  288.                     if nlindex < 0:
  289.                         nlindex = string.find(u.packetbuf,'\r')
  290.                         if nlindex < 0:
  291.                            break
  292.                     donebuf = u.packetbuf[:nlindex]
  293.                     try:
  294.                     restbuf = u.packetbuf[nlindex + 1:]
  295.                     except IndexError:
  296.                     restbuf = ''
  297.                     u.packetbuf = restbuf
  298.                     donebuf = filter(myfilter, donebuf)
  299.                     donebuf = string.strip(donebuf)
  300.                     if donebuf:
  301.                                         # new
  302.                                         if donebuf == "\\reload " + PASS:
  303.                                             reload(chatcmds)
  304.                                             chatcmds.broadcast(endl +
  305.                                                 "Reloading cmds..." + endl)
  306.                                         else:
  307.                                         # end new
  308.                         u.HandleMsg(donebuf)
  309.                
  310. #               u.HandleMsg(data)
  311.                
  312.                 # if data == "/shutdown": done=1
  313.                 if donebuf == "\\shutdown " + PASS:
  314.                                         done=1
  315.             # for select(), indent more
  316.             except error:
  317.             chatcmds.disconnect(u)
  318.             chatcmds.broadcast(endl + `sys.exc_info()[:2]` + endl)
  319.                         traceback.print_exc()
  320.  
  321.                     # temp off
  322.             except:
  323.                 chatcmds.broadcast(endl + `sys.exc_info()[:2]` + endl)
  324.                 traceback.print_exc()
  325.                            
  326. for u in chatglobals.userlist:
  327.     u.conn.close()
  328.  
  329. s.close()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement