X-Git-Url: https://git.ucc.asn.au/?p=uccvend-vendserver.git;a=blobdiff_plain;f=sql-edition%2Fservers%2FVendServer.py;h=22591088161469d89ef46de72066037c6632a7ab;hp=6b24f80ab0754c16ba9b6619840c7dc7aa71d6ad;hb=9e15e5dbeacc5e038d19a42dcb07d5978bcfd925;hpb=15bf186b639b1ee317eb780c7a85fd2a1de50efe diff --git a/sql-edition/servers/VendServer.py b/sql-edition/servers/VendServer.py index 6b24f80..2259108 100755 --- a/sql-edition/servers/VendServer.py +++ b/sql-edition/servers/VendServer.py @@ -18,7 +18,7 @@ from MessageKeeper import MessageKeeper from HorizScroll import HorizScroll from random import random, seed from Idler import GreetingIdler,TrainIdler,GrayIdler,StringIdler,ClockIdler,FortuneIdler,FileIdler,PipeIdler -from SnackConfig import get_snacks, get_snack +from SnackConfig import get_snack#, get_snacks import socket from posix import geteuid from LDAPConnector import get_uid, set_card_id @@ -108,13 +108,18 @@ def scroll_options(username, mk, welcome = False): else: msg = [] choices = ' '*10+'CHOICES: ' - try: - coke_machine = file('/home/other/coke/coke_contents') - cokes = coke_machine.readlines() - coke_machine.close() - except: - cokes = [] - pass + + # Get coke contents + cokes = [] + for i in range(0, 7): + cmd = 'dispense iteminfo coke:%i' % i + raw = os.popen(cmd) + info = raw.read() + raw.close() + m = re.match("\s*[a-z]+:\d+\s+(\d+)\.(\d\d)\s+([^\n]+)", info) + cents = int(m.group(1))*100 + int(m.group(2)) + cokes.append('%i %i %s' % (i, cents, m.group(3))); + for c in cokes: c = c.strip() (slot_num, price, slot_name) = c.split(' ', 2) @@ -138,48 +143,30 @@ def scroll_options(username, mk, welcome = False): msg.append((choices, False, None)) mk.set_messages(msg) -def get_pin(uid): +def get_acct_state(uid): try: info = pwd.getpwuid(uid) except KeyError: logging.info('getting pin for uid %d: user not in password file'%uid) - return None - if info.pw_dir == None: return False - pinfile = os.path.join(info.pw_dir, '.pin') - try: - s = os.stat(pinfile) - except OSError: - logging.info('getting pin for uid %d: .pin not found in home directory'%uid) - return None - if s.st_mode & 077: - logging.info('getting pin for uid %d: .pin has wrong permissions. Fixing.'%uid) - os.chmod(pinfile, 0600) - try: - f = file(pinfile) - except IOError: - logging.info('getting pin for uid %d: I cannot read pin file'%uid) - return None - pinstr = f.readline() - f.close() - if not re.search('^'+'[0-9]'*PIN_LENGTH+'$', pinstr): - logging.info('getting pin for uid %d: %s not a good pin'%(uid,repr(pinstr))) - return None - return int(pinstr) + return 'invalid' + ret = os.system('dispense acct %s' % (info.pw_name)) + if ret != 0: + return 'invalid' + + # TODO: Disabled account check (done in server pin check now) -def has_good_pin(uid): - return get_pin(uid) != None + return 'good' def verify_user_pin(uid, pin, skip_pin_check=False): - if skip_pin_check or get_pin(uid) == pin: - info = pwd.getpwuid(uid) - if skip_pin_check: - logging.info('accepted mifare for uid %d (%s)'%(uid,info.pw_name)) - else: - logging.info('accepted pin for uid %d (%s)'%(uid,info.pw_name)) - return info.pw_name - else: + info = pwd.getpwuid(uid) + if skip_pin_check: + logging.info('accepted mifare for uid %d (%s)'%(uid,info.pw_name)) + elif os.system('dispense pincheck %04i %s' % (pin, info.pw_name)) != 0: logging.info('refused pin for uid %d'%(uid)) return None + else: + logging.info('accepted pin for uid %d (%s)'%(uid,info.pw_name)) + return info.pw_name def cookie(v): @@ -410,7 +397,8 @@ def make_selection(v, vstatus): vstatus.mk.set_message('OPENSESAME') logging.info('dispensing a door for %s'%vstatus.username) if geteuid() == 0: - ret = os.system('su - "%s" -c "dispense door"'%vstatus.username) + #ret = os.system('su - "%s" -c "dispense door"'%vstatus.username) + ret = os.system('dispense -u "%s" door'%vstatus.username) else: ret = os.system('dispense door') if ret == 0: @@ -428,10 +416,11 @@ def make_selection(v, vstatus): return elif vstatus.cur_selection[1] == '8': v.display('GOT DRINK?') - if ((os.system('su - "%s" -c "dispense %s"'%(vstatus.username, vstatus.cur_selection[0])) >> 8) != 0): + if ((os.system('dispense -u "%s" coke:%s'%(vstatus.username, vstatus.cur_selection[0])) >> 8) != 0): v.display('SEEMS NOT') else: v.display('GOT DRINK!') + #v.display('SEE FRIDGE') else: # first see if it's a named slot try: @@ -440,15 +429,23 @@ def make_selection(v, vstatus): price, shortname, name = get_snack( '--' ) dollarprice = "$%.2f" % ( price / 100.0 ) v.display(vstatus.cur_selection+' - %s'%dollarprice) - exitcode = os.system('su - "%s" -c "dispense give \>snacksales %d \'%s\'"'%(vstatus.username, price, name)) >> 8 +# exitcode = os.system('dispense -u "%s" give \>sales\:snack %d "%s"'%(vstatus.username, price, name)) >> 8 + # For some reason, this causes the machine and this code to desync + exitcode = os.system('dispense -u "%s" snack:%s'%(vstatus.username, vstatus.cur_selection)) >> 8 if (exitcode == 0): # magic dispense syslog service syslog.syslog(syslog.LOG_INFO | syslog.LOG_LOCAL4, "vended %s (slot %s) for %s" % (name, vstatus.cur_selection, vstatus.username)) v.vend(vstatus.cur_selection) v.display('THANK YOU') + elif (exitcode == 5): # RV_BALANCE + v.display('NO MONEY?') + elif (exitcode == 4): # RV_ARGUMENTS (zero give causes arguments) + v.display('EMPTY SLOT') + elif (exitcode == 1): # RV_BADITEM (Dead slot) + v.display('EMPTY SLOT') else: syslog.syslog(syslog.LOG_INFO | syslog.LOG_LOCAL4, "failed vending %s (slot %s) for %s (code %d)" % (name, vstatus.cur_selection, vstatus.username, exitcode)) - v.display('NO MONEY?') + v.display('UNK ERROR') sleep(1) @@ -572,23 +569,40 @@ Wouldn't you prefer a nice game of chess? return - if not has_good_pin(uid): - logging.info('user '+vstatus.cur_user+' has a bad PIN') + acct_state = get_acct_state(uid) + if acct_state == 'invalid': + logging.info('user '+vstatus.cur_user+' is not in the database') + vstatus.mk.set_messages( + [(' '*10+'INVALID PIN SETUP'+' '*11, False, 3)]) + vstatus.cur_user = '' + vstatus.cur_pin = '' + + reset_idler(v, vstatus, 3) + return + elif acct_state == 'locked': + logging.info('user '+vstatus.cur_user+' is locked') + vstatus.mk.set_messages( + [(' '*10+'INVALID PIN SETUP'+' '*11, False, 3)]) + vstatus.cur_user = '' + vstatus.cur_pin = '' + + reset_idler(v, vstatus, 3) + return + elif acct_state == 'good': + vstatus.cur_pin = '' + vstatus.mk.set_message('PIN: ') + logging.info('need pin for user %s'%vstatus.cur_user) + vstatus.change_state(STATE_GETTING_PIN) + return + else: + logging.error('user '+vstatus.cur_user+' has an unknown account state'+acct_state) vstatus.mk.set_messages( [(' '*10+'INVALID PIN SETUP'+' '*11, False, 3)]) vstatus.cur_user = '' vstatus.cur_pin = '' reset_idler(v, vstatus, 3) - return - - - vstatus.cur_pin = '' - vstatus.mk.set_message('PIN: ') - logging.info('need pin for user %s'%vstatus.cur_user) - vstatus.change_state(STATE_GETTING_PIN) - return def handle_idle_key(state, event, params, v, vstatus): @@ -773,6 +787,7 @@ def handle_mifare_event(state, event, params, v, vstatus): vstatus.username = verify_user_pin(int(vstatus.cur_user), None, True) except ValueError: vstatus.username = None + if vstatus.username: v.beep(0, False) vstatus.cur_selection = '' @@ -1072,6 +1087,8 @@ def do_vend_server(options, config_opts): sleep(5) continue +# run_forever(rfh, wfh, options, config_opts) + try: run_forever(rfh, wfh, options, config_opts) except VendingException: