! Utility routines to obtain the information in the $UserData file. This ! file is assumed to be sorted by username, so that a binary search can be ! used for speed. For now we don't use the standard Imp RTL. %include "GDMR_H:IO_F.Inc" %systemroutinespec phex(%integer x) %owninteger token1 = 0, token2 = 0, size = 0, flags = 0 %recordformat buffer fm(%bytearray x(0 : 511)) %ownrecord(buffer fm) buffer %owninteger pos = -1, buffer start = 0, buffer end = -1 %predicate open database %string(255) textual response %integer status %true %if token1 # 0; ! Already open {} printstring("Open $UserData"); newline ! Database isn't open yet status = F open file(nil, "$UserData", read file mode, read file mode, 0, token1, token2, size, flags, textual response) %if status # 0 %start printstring("Open $UserData fails: "); printstring(textual response) newline %false %finish {} printstring("Opened: "); phex(token1); space {} phex(token2); newline buffer start = 0; buffer end = -1 pos = 0 %true %end %integerfn next sym %string(255) textual response %integer status, start, bytes, x %unless buffer start <= pos <= buffer end %start ! Wrong block, so we'll have to fetch it {} printstring("Fetch: "); write(pos, 0); space {} write(buffer start, 0); space; write(buffer end, 0) {} space; write(size, 0); newline %signal 9, 9, pos %if pos >= size; ! EOF start = pos & (\ 511); ! Lose offset status = F read block(nil, token1, token2, start, bytes, buffer, textual response) %if status # 0 %start printstring("Read $UserData at "); write(start, 0) printstring(" fails: "); printstring(textual response); newline %signal 9, 9, pos %finish buffer start = start buffer end = start + bytes - 1 %finish x = buffer_x(pos - buffer start) {} write(pos, 0); space; print symbol(x); newline pos = pos + 1 %result = x %end %routine close database %string(255) textual response %integer status %return %if token1 = 0; ! Not open {} printstring("Close $UserData"); newline status = F close file(nil, token1, token2, 0, textual response) %if status # 0 %start printstring("Close $UserData fails: "); printstring(textual response) newline %finish token1 = 0; token2 = 0 %end %routine get user data(%string(15) user, %string(*)%name home, full name) ! Eventually we'll use a binary search here.... %string(255) current user %bytename x %integer sym, i, quoted = 0 %on 9 %start close database %return %finish {} printstring("Get for "); printstring(user); newline home = ""; full name = "" %return %if user = "" %return %unless open database %for i = 1, 1, length(user) %cycle x == charno(user, i) x = x - 'a' + 'A' %if 'a' <= x <= 'z' %repeat %cycle current user = "" sym = next sym %until sym > ' '; ! Blank lines, leading white space %while sym = '!' %cycle ! Skip comments: first the rest of this line sym = next sym %while sym # NL ! Then the white space at the start of the next sym = next sym %until sym > ' ' %repeat %while sym > ' ' %cycle sym = sym - 'a' + 'A' %if 'a' <= sym <= 'z' current user = current user . to string(sym) sym = next sym %repeat {} printstring("Current user: "); printstring(current user); newline %if current user = user %start sym = next sym %while sym <= ' ' %while sym > ' ' %cycle home = home . to string(sym) sym = next sym %repeat {} printstring("Home: "); printstring(home); newline sym = next sym %while sym # '"' sym = next sym %while sym # '"' %cycle full name = full name . to string(sym) sym = next sym %repeat close database %return %else ! Not this one, so skip the rest of the line sym = next sym %while sym # NL %finish %repeat %end %begin %string(255) user, home, name %on 9 %start; %stop; %finish %cycle read(user) get user data(user, home, name) printstring(home); space; printstring(name); newline %repeat %end %end %of %file