+-+-+-+ Beginning of part 2 +-+-+-+ X`009! node$`009`009DECnet node we are fingering (unpadded) & X`009! nodreq%`009Flag for node name required in mail match & X`009! nonwld%`009Number of non-wild characters in the name requested & X`009! o.retcnt%`009Retry count for network write operations & X`009! opsys$`009Operating system and version information & X`009! pattern$`009Pattern we are matching against for wildcards & X`009! persname$`009Personal name from ISAM file & X`009! ppn$`009`009Project-Programmer Number from ISAM file & X`009! recurs%`009Recursion level for alias resolution & X`009! qual$`009`009Qualifier we are looking for to set flags%() & X`009! r0%, r1$, r2%, & X`009! r3%, r4%, r5%, & X`009! r6%, r7%, r8%, & X`009! r9%`009`009VAX emulation registers (honestly) & X`009! reason%`009Reason code for connect error & X`009! reqd%`009`009Number of required match characters in qualifier & X`009! reqd$`009`009Portion of qualifier required for match & X`009! router$`009Node to send request to if host not known locally & X`009! stat%`009`009Status code for connect error & X`009! t0`009`009Work variable for uptime computation & X`009! ttabl$`009String of valid terminal type codes & X`009! tttype$`009Type of terminal this job is using & X`009! u.name$`009Personal name of user$ & X`009! u.ppn$`009PPN expressed in system format & X`009! u.prog%`009Programmer number component of PPN & X`009! u.proj%`009Project number component of PPN & X`009! user$`009`009User name we are fingering & X`009! username$`009Username from ISAM file & X`009! version$`009Version number and release date of this program & X`009! where$`009Node name of person issuing finger command & X`009! who$`009`009User name of person issuing finger command & X`009! wild%`009`009Flag for wildcard in username search & X`009! year%`009`009Work variable for date computation & X`009! yf%`009`009Work variable for date computation & X`009! yf2%`009`009Work variable for date computation & X`009! zdate%`009Work variable for date computation & X`009! ztime%`009Work variable for date computation & X`009& X`009& X X40`009! & X`009& X`009& X`009!`009I / O C H A N N E L U S A G E & X`009& X`009& X`009! CHANNEL`009USAGE & X`009! #9%`009`009Configuration file, read on startup, or & X`009!`009`009terminal or mail file, read during processing & X`009! #10%`009`009Username file (FINGER$:FINGER.DAT) & X`009! #11%`009`009Inbound finger links (we are a server) & X`009! #12%`009`009Outbound finger links (we are a requestor) & X`009& X`009& X X50`009! & X`009& X`009& X`009!`009F U N C T I O N U S A G E & X`009& X`009& X`009! FUNCTION`009USAGE & X`009! fnactive%`009Determine if a job is active on the system & X`009! fndatim$`009Convert internal date/time to printable data & X`009! fngetjob%`009Build a line of information about a job & X`009! fnheader%`009Display job information header & X`009! fnmaildate$`009Convert mail date/time to printable data & X`009! fnppntoname$`009Convert PPN to username & X`009! fnstate$`009Compute job state & X`009! fnwild%`009Wildcard matching & X`009& X`009& X X60`009! & X`009& X`009& X`009!`009M A J O R P R O G R A M S E C T I O N S & X`009& X`009& X`009! SECTION`009USAGE & X`009! 1000- 1999`009Declarations, RUN trap & X`009! 2000- 2999`009Finger, no arguments & X`009! 3000- 3999 Finger a specific user & X`009! 4000- 4999`009Finger a wildcarded user & X`009! 25000-25999 Function definition & X`009! 26000-26999`009Parse command qualifiers & X`009! 27000-27999`009Return a line of output to fingerer & X`009! 28000-28999`009DECnet communication to finger a remote node & X`009! 29000-29999`009DECnet communication to respond to remote fingers & X`009! 30000-30999`009CCL entry point & X`009! 31000-31999`009Initial setup and initialization code & X`009! 32000-32599`009Error handling & X`009! 32600-32767`009Exit processing & X`009& X`009& X`012 X X1000`009! Entry point if "RUN" & X`009& X`009dim flags%(3%) & X`009\ dim day.week$(7%), month.year$(12%) & X`009\ map (indexf) string ppn$=2%, username$=12%, persname$=31%, & X`009 forward$=64%, alias$=1%, filler$=18% & X`009\ print "?FINGER - Please use the DCL FINGER command." & X`009\ goto 32767 & X`009! This is not a directly executable program & X`012 X X2000`009! Entry point for local FINGER command & X`009& X`009gosub 26000 & X`009\ msg$=chr$(13%)+chr$(10%) & X`009\ gosub 27000 if accmod%=3% & X`009\ msg$=version$+chr$(13%)+chr$(10%) & X`009\ gosub 27000 if flags%(1%) and 32% & X`009\ goto 2050 if (flags%(1%) and 16%) <> 16% & X`009\ goto 2010 if accmod%=3% & X`009\ msg$="?FINGER - Please use the DCL HELP command for help."+ & X`009 chr$(13%)+chr$(10%) & X`009\ gosub 27000 & X`009\ goto 32600 & X`009! Print the version information if requested. If the user didn't ask & X`009! for help, proceed. If user asked for help and access was local, tell & X`009! him to use DCL HELP instead. & X X2010`009open "FINGER$:FINGER.HLP" for input as file #9%, mode 6144%, access & X`009 read, allow modify & X`009\ goto 2030 & X`009! Open the help file, if present. & X V2020`009msg$="?FINGER - Cannot open help file FINGER$:FINGER.HLP"+chr$(13%)+ X & X`009 chr$(10%) & X`009\ gosub 27000 & X`009\ goto 32600 & X`009! Print an appropriate error message and exit. & X X2030`009input line #9%,msg$ & X`009\ gosub 27000 & X`009\ goto 2030 & X`009! Read help lines until we are done. & X X2040`009close #9% & X`009\ goto 32600 & X`009! Then close the file and bail out. & X X2050`009recurs%=10% & X`009\ open "FINGER$:FINGER.DAT" for input as file #10%, & X`009 organization indexed, & X`009 recordsize 128%, & X`009 map indexf, & X`009 primary key ppn$, & X`009 alternate key username$, & X`009 mode 4352%, & X`009 access read, & X`009 allow modify & X`009\ i%=instr(1%,command$," ") & X`009\ goto 3000 if i% & X`009! Allow up to 10 recursions in alias resolution & X`009! Open the mail control file & X`009! See if a person is being fingered, skip to personal finger if so & X X2060`009msg$=l.org$+chr$(13%)+chr$(10%) & X`009\ gosub 27000 & X`009\ msg$=l.host$+", "+opsys$+", "+fndatim$(0%,0%)+", "+ & X`009 num1$(jobact%)+" Jobs, "+num1$(jobmax%)+" Max."+ & X`009 chr$(13%)+chr$(10%) & X`009\ gosub 27000 & X`009\ msg$="Uptime " & X`009\ i%=peek(36%)/1000%+2% & X`009\ j%=(peek(512%)/1000% <> peek(36%)/1000%) & X`009\ j%=635%+((i%/4%*4%)=i%) if j% & X`009\ t=(peek(512%)-peek(36%)-j%)*1440.+(peek(38%)-peek(514%)) & X`009\ t0=int(t/1440.) & X`009\ t=(t-(t0*1440.))*60.+60.-(peek(516%) and 255%) & X`009\ t=86400. if t0<0. & X`009\ goto 2070 if t0<0. & X`009\ msg$=msg$+num1$(t0)+" " if t0<>0. & X`009! Print the simple stuff in the header. Compute the uptime. & X X2070`009if t<0. or t>=86400. then msg$=msg$+"?? ??:??:??" & X`009else k%=t/3600. & X`009\ msg$=msg$+right(num1$(k%+100%),2%)+":" & X`009\ t=t-(k%*3600.) & X`009\ k%=t/60. & X`009\ msg$=msg$+right(num1$(k%+100%),2%)+":" & X`009\ t=t-(k%*60.) & X`009\ msg$=msg$+right(num1$(int(t+100%)),2%) & X`009! More uptime stuff. & X V2080`009msg$=msg$+", since "+fndatim$(peek(36%),peek(38%))+chr$(13%)+chr$(10% X) & X`009\ gosub 27000 & X`009\ msg$=chr$(13%)+chr$(10%) & X`009\ gosub 27000 & X`009\ goto 2120 if (flags%(1%) and 128%) <> 128% & X`009\ goto 2120 if l.msg$="" & X`009\ goto 2090 if left(l.msg$,1%)="@" & X`009\ msg$=l.msg$+chr$(13%)+chr$(10%)+chr$(10%) & X`009\ gosub 27000 & X`009\ goto 2120 & X`009! Print the rest of the uptime stuff. See if we want to do anything & X`009! with the local message field. & X X2090`009l.msg$=right(l.msg$,2%) & X`009\ open l.msg$ for input as file #9%, mode 6144%, access read, allow & X`009 modify & X`009! Open the local message file. & X X2100`009input line #9,msg$ & X`009\ gosub 27000 & X`009\ goto 2100 & X`009! Read lines from the message file until EOF. & X X2110`009close #9% & X`009\ msg$=chr$(13%)+chr$(10%) & X`009\ gosub 27000 & X`009! Print the trailing blank line. & X X2120`009open "FINGER$:FINGER.TRM" for input as file #9%, recordsize 512%, & X`009 mode 6144%, access read, allow modify & X`009\ field #9%, 512% as buff9$ & X`009\ for j%=1% to jobmax% & X`009\ goto 2130 if fnactive%(0%,0%,j%)<>1% & X`009\ i%=fngetjob%(j%) & X`009\ l%=(flags%(1%) and 15%) and i% & X`009\ gosub 27000 if len(msg$)>3% and l%<>0% & X`009! Get the job information, display it if it's a job we want to see. & X X2130`009next j% & X`009\ close #9% & X`009\ close #10% & X`009\ goto 32600 & X`012 X X3000`009! The command was to finger a particular user (if we have an exact & X`009! match on the username), or to look up a user (if we don't have an & X`009! exact match) & X`009& X`009user$=cvt$$(right(command$,i%+1%),128%) & X`009\ u.ppn$=cvt%$(peek(peek(peek(520%)+8%)+24%)) & X`009\ who$=fnppntoname$(u.ppn$) & X`009\ where$="" & X`009\ i%=instr(1%,iam$,"`126") X`009\ who$=left(iam$,i%-1%) if (accmod%=3% and iam$<>"") & X`009\ where$=mid(iam$,i%+1%,len(iam$)) if (accmod%=3% and iam$<>"") & X`009\ user$=who$ if user$="." & X`009\ i%=instr(1%,user$," ") & X`009\ goto 3010 if i%=0% & X`009\ msg$="?FINGER - Too many parameters - re-enter command with fewer"+ & X`009 " parameters."+chr$(13%)+chr$(10%) & X`009\ gosub 27000 & X`009\ goto 32600 & X`009! Pick out username portion. If more than one, give error message and & X`009! exit. & X X3010`009wild%=(instr(1%,user$,"*") or instr(1%,user$,"?") or & X`009 instr(1%,user$,"%")) & X`009\ i%=instr(1%,l.host$," ") & X`009\ msg$=l.host$ if i%=0% & X`009\ msg$=left(l.host$,i%-1%) if i%<>0% & X`009\ msg$=msg$+" RSTS/E, "+fndatim$(0%,0%)+chr$(13%)+chr$(10%) & X`009\ gosub 27000 & X`009\ msg$=chr$(13%)+chr$(10%) & X`009\ gosub 27000 & X`009\ goto 4000 if wild% & X`009\ i%=0% & X`009! See if wildcard in username. Print header info. Don't bother looking & X`009! in usernames if we had a wildcard. & X X3020`009get #10%, key #1% eq user$ & X`009\ goto 4000 if alias$="S" & X`009\ goto 3023 if alias$<>"Y" & X`009\ i%=1% & X`009\ recurs%=recurs%-1% & X`009\ msg$="?FINGER - excessive recursion resolving alias."+chr$(13%)+ & X`009 chr$(10%) & X`009\ gosub 27000 if recurs%=0% & X`009\ goto 4040 if recurs%=0% & X`009\ msg$=user$+" is an alias for "+cvt$$(persname$,160%)+chr$(13%)+ & X`009 chr$(10%) & X`009\ gosub 27000 & X`009\ goto 4040 if instr(1%,persname$,"::") & X`009\ goto 4040 if instr(1%,persname$,"@") & X`009\ user$=cvt$$(persname$,160%) & X`009\ goto 3020 & X`009! If a system distribution list, treat as wildcard. If not an alias, & X`009! process normally. Otherwise resolve alias until it either leaves & X`009! this node or recurses more than 10 times. & X X3023`009msg$=chr$(13%)+chr$(10%) & X`009\ gosub 27000 if i% & X`009! Print a blank line after alias information (if there was any, that & X`009! is). & X`009\ goto 4000 if user$<>cvt$$(username$,128%) & X`009\ u.proj%=ascii(left(ppn$,1%)) & X`009\ u.prog%=ascii(mid(ppn$,2%,1%)) & X`009\ jobcnt%=0% & X`009\ u.name$=cvt$$(persname$,128%) & X`009\ msg$=user$+" ["+num1$(u.proj%)+","+num1$(u.prog%)+"] ("+u.name$+ & X`009 ") is not logged in."+chr$(13%)+chr$(10%) & X`009\ open "FINGER$:FINGER.TRM" for input as file #9%, recordsize 512%, & X`009 mode 6144%, access read, allow modify & X`009\ field #9%, 512% as buff9$ & X`009\ for j%=1% to jobmax% & X`009\ k%=fnactive%(u.proj%,u.prog%,j%) & X`009\ goto 3025 if k%=0% & X`009\ jobcnt%=jobcnt%+1%& X`009\ i%=fngetjob%(j%) & X`009\ gosub 27000 if len(msg$)>3% & X`009! We have a match. Compute the PPN and personal name for this user. & X`009! Display the status of any active jobs. If none were found, give & X`009! the "not logged in" message. & X X3025`009next j% & X`009\ close #9% & X`009\ gosub 27000 if jobcnt%=0% & X X3030`009msg$=chr$(13%)+chr$(10%) & X`009\ gosub 27000 & X`009\ msg$=" Default directory: _SY0:["+num1$(u.proj%)+","+ & X`009 num1$(u.prog%)+"]"+chr$(13%)+chr$(10%) & X`009\ gosub 27000 if flags%(3%) and 8% & X`009\ a$=sys(chr$(6%)+chr$(-25%)+chr$(-1%)+chr$(4%)+chr$(u.prog%)+ & X`009 chr$(u.proj%)) & X`009\ i%=ascii(mid(a$,8%,1%)) & X`009\ j%=swap%(cvt$%(mid(a$,9%,2%))) & X`009\ msg$=" Last login: " & X`009\ msg$=" Logged in since: " if jobcnt%<>0% & X`009\ msg$=msg$+fndatim$(j%,swap%(cvt$%(mid(a$,11%,2%))) and 2047%)+" " & X`009\ msg$=msg$+"(detached)" if (i%=255% and jobcnt%=0%) & X`009\ msg$=msg$+"from KB"+num1$(i%)+":" if (i%<>255% and jobcnt%=0%) & X`009\ msg$=" Last login: (none)" if j%=0% & X`009\ msg$=msg$+chr$(13%)+chr$(10%) & X`009\ gosub 27000 & X`009\ goto 3110 if (flags%(3%) and 4%) <> 4% & X`009\ goto 3110 if ljkflg%>=2% & X`009! Compute the user's default directory and display if desired. Get & X`009! and format date/time/KB of last login. See if mail info wanted. & X X3040`009a$="SY:["+num1$(u.proj%)+","+num1$(u.prog%)+"]MAIL.MAI" & X`009\ i%=0% & X`009\ open a$ for input as file #9%, mode 12544%, access read, allow & X`009 modify & X`009\ field #9%, 6% as fill1$, & X`009`009 2% as mbox.version$, & X`009`009 2% as mbox.type$, & X`009`009 2% as mbox.total$, & X`009`009 4% as fill2$, & X`009`009 6% as mbox.id$, & X`009`009 2% as fill3$, & X`009`009 2% as mbox.new$ & X`009\ get #9%, record 1% & X`009\ i%=swap%(cvt$%(mbox.new$)) if (mbox.id$="FOLDER") and & X`009 (mbox.type$=cvt%$(swap%(5%))) and (mbox.version$= & X`009 cvt%$(swap%(1%+swap%(3%)))) & X`009! Open the user's mail file. Read the new mail count. & X X3050`009goto 3055 if cvt$$(forward$,160%)="" & X`009\ msg$=" Mail is forwarded to: "+cvt$$(forward$,160%)+chr$(13%)+ & X`009 chr$(10%) & X`009\ gosub 27000 & X`009\ goto 3100 & X`009! Check for any forwarding in effect. If so, display address and & X`009! exit, otherwise do the whole thing. & X`009 X3055`009msg$=" Mail: " & X`009\ msg$=msg$+"(no new mail)" if i%=0% & X`009\ msg$=msg$+num1$(i%) if i%<>0% & X`009\ msg$=msg$+" new message" if i%<>0% & X`009\ msg$=msg$+"s" if i%>1% & X`009\ msg$=msg$+"." if i%<>0% & X`009\ msg$=msg$+chr$(13%)+chr$(10%) & X`009\ gosub 27000 & X`009\ goto 3100 if ljkflg%>=1% & X`009\ goto 3100 if i%=0% & X`009\ j%=swap%(cvt$%(mbox.total$)) & X`009\ j%=(j%-i%)+1% & X`009\ goto 3100 if j%<=0% & X`009\ k%=j%/20% & X`009\ m%=(((j%-(k%*20%))-1%)*24%)+33% & X`009\ field #9%, 512% as buff9$ & X`009\ i%=2% & X`009\ m.count%=0% & X`009! Display the new message count. If 0, just bail out. Otherwise com- & X`009! pute the index block and offset for the first new message. Preset & X`009! the counter of messages from us to zero. & X X3060`009get #9%, record i% & X`009\ j%=i% & X`009\ i%=swap%(cvt$%(mid(buff9$,3%,2%))) & X`009\ k%=k%-1% & X`009\ goto 3060 if k%<>-1% & X`009\ i%=j% & X`009! Chase the index blocks until we have the one we want. & X X3070`009get #9%, record i% & X`009\ b$=buff9$+"" & X`009\ i%=swap%(cvt$%(mid(b$,3%,2%))) & X`009\ for j%=m% to 489% step 24% & X`009\ k%=swap%(cvt$%(mid(b$,j%+2%,2%))) & X`009\ goto 3100 if k%=0% & X`009\ get #9%, record k% & X`009\ m.from$="" & X`009\ m.subj$="" & X`009\ k%=23% & X`009! Get the first index record of the mailfile which contains new mail. & X`009! Save pointer to forward link. Step through the mail entries, start- & X`009! ing at the offset of the first new message. Form first part of info & X`009! line. & X -+-+-+-+-+ End of part 2 +-+-+-+-+-