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
def scroll_options(username, mk, welcome = False):
if welcome:
- # Balance checking: crap code, [DAA]'s fault
- acct = os.popen('dispense acct %s' % username)
- balance = acct.read()[15:22]
- acct.close()
+ # Balance checking: crap code, [DAA]'s fault
+ # Updated 2011 to handle new dispense [MRD]
+ raw_acct = os.popen('dispense acct %s' % username)
+ acct = raw_acct.read()
+ # this is fucking appalling
+ balance = acct[acct.find("$")+1:acct.find("(")].strip()
+ raw_acct.close()
msg = [(center('WELCOME'), False, TEXT_SPEED),
(center(username), False, TEXT_SPEED),
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)
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):
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:
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:
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 oday %d"'%(vstatus.username, price)) >> 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)
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):
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 = ''
from optparse import OptionParser
op = OptionParser(usage="%prog [OPTION]...")
- op.add_option('-f', '--config-file', default='/etc/dispense/servers.conf', metavar='FILE', dest='config_file', help='use the specified config file instead of /etc/dispense/servers.conf')
+ op.add_option('-f', '--config-file', default='/etc/dispense2/servers.conf', metavar='FILE', dest='config_file', help='use the specified config file instead of /etc/dispense/servers.conf')
op.add_option('--serial', action='store_true', default=True, dest='use_serial', help='use the serial port')
op.add_option('--lat', action='store_true', default=False, dest='use_lat', help='use LAT')
op.add_option('--virtualvend', action='store_false', default=True, dest='use_serial', help='use the virtual vending server instead of LAT')
sleep(5)
continue
+# run_forever(rfh, wfh, options, config_opts)
+
try:
run_forever(rfh, wfh, options, config_opts)
except VendingException: