RFC 477

Remote Job Service at UCSB

πŸ“… published May 1973, from ietf

RFC 477: Remote Job Service at UCSB ✨

Part 1 of 4 πŸŽ€

Okay bestie, let's get into it. This is RFC 477 πŸ’–, written by M. Krilanovich from UCSB on 23 May 1973, and it's tagged as NIC 14922. The header lists RFCs 354, 407, and NIC 16306 as references. It doesn't say what category or status the document has, and it doesn't list anything it obsoletes or updates πŸ™ˆ. Oh, and it's the follow-up to RFC #436, which gave a quick overview of UCSB's RJS πŸ¦‹.

Introduction

Okay so this doc goes deeper into UCSB's RJS. It restates the essence of the official RJE protocol (RFC #407) and then explains in detail how UCSB actually built it 🧚.

The program lives on socket 5 at UCSB, and it supports a subset of the official protocol πŸ’…. Here's what's missing: no checks are made for RJE control cards in the input file, jobs can't be batched in the input file, only the output file dispositions of discard and transmit-and-discard exist, no restart markers get sent on output in FTP blocked mode, and several commands just aren't implemented 😭. There are also other ways RJS is known to be less than ideal. For example, if any error shows up while processing a job (like the output's destination host being dead), the job gets abandoned and any further output is deleted πŸ’€. A rewrite of RJS is scheduled for the near future (in about six months), and a lot of these problems should get fixed then πŸ”₯. Suggestions are more than welcome! You can send them through the Journal to MCK, mail the author at the UCSB Computer Center, or call (8O5) 961-3454 🫢.

Also, in addition to the protocol deviations above, UCSB made some modifications for user convenience ✨. The INACCT, OUTACCT, and ACCT commands were added for TENEX and other systems that need an account number. OUTPATH is a synonym for OUT, INUSER is a synonym for INID, and the BYE command does not cause an ABORT 🌸. The official protocol is super biased toward programs, which makes it pretty clunky for humans, so there's an alternate, optional command syntax called 'local syntax' πŸ’œ. It's designed to feel as "natural" as possible to a human, and it also has some features the standard syntax doesn't have πŸ‘‘.

Service Provided

The UCSB Computer Center runs an IBM 360/75 with OS MVT release 21.0 and HASP πŸ–₯️. All batch jobs at UCSB enter the system through HASP, so RJS acts as the middleman between the user and HASP πŸ§ƒ. RJS gives each user a HASP virtual RJE terminal, made up of a card reader, card punch, line printer, and operator's console. It manages the first three for the user based on the commands they send πŸ’….

RJS keeps track of which user owns which HASP RJE terminal, so a user can change the status of their own submitted jobs through that terminal πŸ¦‹. This works even if the user logged out and back in again, possibly from a different site 🌈.

Here's how using RJS goes, step by step πŸŽ€. First, the user logs in with a user name, password, and account number. That accounting info does two things: it decides how later RJS use gets billed, and it identifies who owns a particular RJE terminal πŸ’–. The link between a user name and a HASP virtual RJE terminal is unique, so only one person can be logged in under a given user name at a time πŸ™…β€β™€οΈ.

Billing isn't implemented in RJS yet, so the login account number is totally arbitrary, and the user name and password are kinda arbitrary too πŸ€·β€β™€οΈ. The first time a user name gets used, you can pick any password. After that, as long as RJS still knows the user name, you have to use the same password πŸ”. RJS remembers a user name while that person is logged in. When they're logged out, it still remembers them as long as they own at least one job that RJS knows about (the doc says "PJS" here). Otherwise, the user name gets thrown out πŸ—‘οΈ.

After logging in, the user specifies their input and output file information and asks for input retrieval to start ✨. After that, they can log out or stay logged in, whatever they want. Staying logged in during source file retrieval isn't required 🌸. A job can finish abnormally at any stage of processing, or finish normally after its last output gets stored 🏁. Either way, the final disposition of the job is shown to the user right away if they're logged in, saved for a while after completion, and available on request the next time they log in πŸ’œ. This status info sticks around for at least a fixed period (currently two days), and it stays longer as long as there's enough storage space πŸ‘‘.

RJS Commands - General Information

To make job parameters easier to specify, RJS keeps a set of accumulators for them 🧚. Every accumulator starts out empty, and various commands can set or reference them πŸ’…. Each user has these parameter accumulators: login accounting parameter (set either by the LOGIN command or by the USER, PASS, and ACCT commands), source pathname, print pathname, punch pathname, source accounting parameter, print accounting parameter, and punch accounting parameter. The user name, password, and account together are called the accounting parameters πŸŽ€. Each job also has its own parameters: source, print, and punch pathname, plus source, print, and punch accounting parameters ✨.

When a TELNET connection first opens, RJS sends a herald message in this form:

300 UCSB RJS (VER.  <date>) TTY <integer>.

The <date> tells you which version of RJS you're on, and <integer> is your terminal number, since every TELNET connection gets its own unique TTY number πŸ¦‹.

While a job is running, RJS might show you some spontaneous job status messages πŸ”₯. Here they are:

  • 240 INPUT RETRIEVAL FOR JOB <jobid> HAS BEGUN. shows up once the input connection(s) are established 🌈.
  • 261 JOB <jobid> HAS COMPLETED EXECUTION. shows up when the first of the job's printed output has come in from HASP πŸ’–.
  • 466 PRINTED [or PUNCHED] OUTPUT FROM UNKNOWN JOB (HASP JOB NUMBER <integer>) IS BEING DISCARDED. shows up if printed or punched output comes in from HASP over your line for a job RJS doesn't know about πŸ™ˆ.
  • Messages explaining errors such as ICP/RFC failure, invalid job card, null source deck, missing pathname, and data transfer network errors. The doc says to check Appendix B for a list of possible reply ids 🧾.

Also, while you're in local syntax, you might get messages from HASP over your virtual operator's console πŸ’œ. Some are replies to HASP commands you sent, and others are spontaneous πŸ’…. But all of them are asynchronous to the entering of other RJS commands ⏳.

Some general rules hold for both syntaxes. Here they are πŸ’–:

  1. The character pair CR-LF is used as command accept to end commands. Other occurrences of these two characters are ignored, and you can use them however you like for local carriage control πŸŽ€.
  2. Any number of blanks is allowed before or after any syntactic unit (including the first and last) ✨.
  3. Upper and lower case letters are treated the same everywhere except in <filename> 🌸.
  4. Whenever you switch to the syntax that isn't currently in effect, the current TELNET modes (full or halfduplex, character or line at a time) are saved, and get reinstated when the current syntax is entered again πŸ”„.

Here's the notation used in the syntactic descriptions below πŸ“:

'text'             denotes literal text (quotes not part of text)

<unit>             denotes name of syntactic unit

<a>_<b>            denotes choice of syntactic units <a> or <b>

[<a>]              denotes optional syntactic unit

(<a><b><c>)        denotes group of syntactic units treated as a
                   whole

=                  syntactic unit at left defined by statement on
                   right

And these are the general syntactic definitions 🧚:

<CA>                = command accept

<user name >        = a string of 1 to 8 alphameric characters

<password>          = a string of 1 to 8 alphameric characters

<account>           = a string of 1 to 6 alphameric characters

<jobid>             = a string of 1 to 8 alphameric characters,
                      the first of which is alphabetic.

to be continued in part 2… stay tuned bestie πŸ’…πŸŒˆ

Description of RJS Commands, Standard Syntax ✨

okay bestie, this part is the full list of every command the standard syntax supports πŸ’… unless it says otherwise, the reply is 200 OK πŸŽ€ and for commands that need you to be logged in, you get 504 LOGIN PLEASE. if you're not πŸ™ˆ

USER

'USER' ['='] <user name> <CA>

so USER tells RJS your user name for accounting, starts your login, and sets the source, print, and punch user name accumulators to <user name> 🧚 to actually finish logging in, you need a successful PASS right after. the only other command you can send before you're logged in is BYE 🫢 and a syntactically valid USER always gets 330 ENTER PASSWORD back, no cap πŸ’–

PASS

'PASS' ['='] (password> <CA>

PASS is where you give your password to get into your account πŸ” it completes the login that USER started and sets the password accumulators (source, print, and punch) to <password>. a successful PASS replies 230 USER <user name> OWNS REMOTE TERMINAL <integer>., where <integer> is the number of the HASP virtual RJE terminal you own πŸ¦‹

the error replies are giving chaos πŸ’€

  • 431 NEW USERS ARE NOT BEING ACCEPTED AT THIS TIME. if there's no free HASP terminal to give you (there's a max of 10), or if there aren't enough other resources to support another user
  • 431 INCORRECT PASSWORD. if <password> isn't the one tied to the <user name> you already gave
  • 431 ANOTHER USER IS LOGGED IN AS <user name>. only one user can be logged in with a given <user name> at a time, so no sharing the account πŸ™…β€β™€οΈ

ACCT

'ACCT' ['='] <account> <CA>

ACCT is for the UCSB Computer Center account number that your RJS use gets billed to πŸ’Έ it sets the source, print, and punch account accumulators to <account>. a syntactically correct ACCT gets 200 OK back.

RJS billing isn't implemented yet, so ACCT is optional for now 🌸

heads up bestie: billing will eventually be required πŸ‘€ and when that happens, PASS will return a reply id of 330, and ACCT will have the replies listed above under PASS. users and people writing user processes, please plan ahead!

BYE

'BYE' <CA>

BYE logs you out and closes your TELNET connections 🌈 it does this even if file transfers are in progress, and if there are any, they just keep going unaltered πŸš€ the reply is always 231 LOGOUT C0MPLETED; TRANSFERS (IF ANY) CONTINUE., followed by a continuation line of TTY <integer> IS DISCONNECTED.

STATUS (users)

'STATUS' <CA>

this one lists the user names of everyone RJS currently knows about πŸ‘―β€β™€οΈ the reply is either 100 NO USERS ARE KNOWN TO RJS or 10O THE FOLLOWING USERS ARE KNOWN TO RJS:. after that comes one or more lines, each starting with a continuation reply id of four blanks, showing a remote terminal number, the user name of whoever owns that terminal, and the name of the site they last logged in from πŸ—ΊοΈ

SYNTAX

'SYNTAX' <CA>

SYNTAX switches the current command syntax over to local syntax ✨ the TELNET modes (full or half duplex, character or line at a time) that were most recently in effect in local syntax become effective again. RJS responds with the local syntax prompt character, which is currently the number sign, # πŸŽ€

The remaining commands require the user to be logged in πŸ”‘

REINIT

'REINIT' <CA>

REINIT resets everything to empty 🧹 that's the source, print, and punch accounting parameter, the source, print, and punch pathname, and the login accounting parameter accumulators. the reply is always 204 OK. clean slate, iconic πŸ’…

INUSER

('INUSER' _ 'INID') ['='] <user name> <CA>

INUSER sets the source user name accumulator to (user name> 🫧

INPASS

'INPASS'  ['='] <password> <CA>

INPASS sets the source password accumulator to <password> πŸ—οΈ

INACCT

'INACCT'  ['='] <account> <CA>

INACCT sets the source account accumulator to <account> πŸ’³

OUTUSER

'OUTUSER' ['='] <user name> <CA>

OUTUSER sets the print and punch user name accumulators to <user name> πŸ“€

OUTPASS

'OUTPASS' ['='] <password> <CA>

OUTPASS sets the print and punch password accumulators to <password> πŸ”

OUTACCT

'OUTACCT' <account> <CA>

OUTACCT sets the print and punch account accumulators to <account> 🧾

INPATH

'INPATH' ['='] <pathname> <CA>
<pathname> = <file> _ <socket>
<socket> = [<host addr> ','] <socket number> <attributes>
<file> = <host addr> <attributes> '/' <filename>
<host addr> = <integer>
<socket number> = <integer>
<integer> = <decimal integer> _ ('D' <decimal integer>) _
('H' <hexadecimal integer>) _ ('X' <hexadecimal integer>) _
('O' <octal integer>)
<attributes> = ':T' _ ':A' _ ':N' _ ':' _ <null> _ ':E' _
':TE' _ ':AE' _ ':NE'
<filename> = 1 to 16 ASCII characters, excluding CR and LF
(codes 0 through 127, excluding 10 and 13)

INPATH sets the source pathname accumulator to <pathname> πŸ›£οΈ the <pathname> is how you specify a file's source or destination, and here's how it works, babe:

  1. giving a <socket> means RJS will set up a simplex connection to that socket (RJS issues the CONNECT, and you issue a LISTEN) πŸ”Œ the data then moves over that connection, and CLOSE marks the end of file.
  2. if the <host addr> in <socket> is left out, the host with the TELNET user gets assumed 🏠
  3. giving a <file> means RJS contacts the standard FTP server socket (currently socket 3) on the stated host and transfers the data using the File Transfer Protocol πŸ“ the <file name> here is what the FTP specification document, RFC #354, calls <pathname>.
  4. the carriage control and data code are decided by <attributes> 🎨 here's the lineup:
':T'        ASCII code, TELNET carriage control
':A'        ASCII code, ASA carriage control
':N'        ASCII code, no carriage control
':'         identical to ':N' for input, ':A' for output
<null>      identical to ':N' for input, ':A' for output
':E'        identical to ':NE' for input, ':AE' for output
':TE'       EBCDIC code, TELNET carriage control
':AE'       EBCDIC code, ASA carriage control
':NE'       EBCDIC code, no carriage control

Detailed descriptions of the transfer modes are below under 'RJS File Transfer.' πŸ“–

OUTPATH

('OUTPATH' _ 'OUT') <output file> '=' <disp> <CA>
<output file> = 'A' _ 'B' _ <null>
<disp> = <pathname> _ '(H)' _ ('(S)' (pathname>) _ '(D)'

OUTPATH stores <disp> in the print pathname accumulator if <output file> is either 'A' or <null>, or in the punch pathname accumulator if <output file> is 'B' πŸ–¨οΈ here's what each <disp> option does:

<pathname>            transmit-and-discard - the file is sent and
                      then deleted

'(H)'                 hold only - the file is not sent but rather
                      held for user intervention

'(S)' <pathname>      save - the file is sent and then held for user
                      intervention

'(D)'                 discard - the file is deleted as soon as it is
                      produced

INPUT

'INPUT' <CA>

INPUT is the big one πŸš€ it creates a job, stores the contents of the source, print, and punch accounting parameter and pathname accumulators with it, and puts it in a queue within RJS of jobs owned by the user that are waiting for a source file transfer. when it becomes the first or only job in that queue, retrieving its source file starts πŸ“¬ the job gets a job identifier (jobid), which is assigned and shown to you. the source and print pathname accumulators have to be set by INPATH and OUTPATH before you send INPUT, or it won't work πŸ™ƒ

if it works, you get 260 ASSIGNED JOBID IS <jobid>. where <jobid> is what you use in later RJS commands to find this job 🎟️ if you already own the max number of jobs (that's currently 5), RJS tries to make room by finding your oldest job that's finished processing. if that works, the old job gets deleted, and the reply is 260 JOB <old jobid> IS BEING DISCARDED TO MAKE ROOM FOR THE NEW JOB., followed by a continuation line of ASSIGNED JOB ID IS <new jobid>. 🧹

the error responses are giving drama 🎭

  • 360 SOURCE PATHNAME HAS NOT BEEN SPECIFIED.
  • 505 PRINT PATHNAME HAS NOT BEEN SPECIFIED.
  • 504 NEW JOBS ARE NOT BEING ACCEPTED AT THIS TIME.
  • 504 USER (user name> ALREADY OWNS THE MAXIMUM NUMBER OF JOBS.

CHANGE

'CHANGE' <jobid> <output file> '=' <disp> <CA>

CHANGE stores <disp> as the print pathname of job <jobid> if <output file> is either 'A' or <null>, or as the punch pathname if <output file> is 'B'. this only works if the file transfer hasn't started yet ⏳ the error replies are:

  • 464 JOB <jobid> NOT FOUND.
  • 5O4 JOB <jobid> IS ALREADY BEING, OR HAS BEEN, PRINTED. if <output file> is 'A'
  • 504 JOB <jobid> IS ALREADY BEING OR HAS BEEN, PUNCHED. if <output file> is 'B'
  • 464 USER <user name> DOES NOT OWN JOB <jobid>.

STATUS (job)

'STATUS' <jobid> <CA>

this one shows the status of the job RJS knows as <jobid> πŸ“Š the display includes which stage the job is in ('BEING READ', 'IN EXECUTION', 'BEING PRINTED', 'BEING PUNCHED', or 'HAS COMPLETED'). it also shows the pathname information (accounting parameters, host name, socket number, attributes, disposition, and filename) for each file that's been supplied for the job (source, print, and punch). and if the job failed at any stage of RJS processing, you get an explanation of why πŸ•΅οΈβ€β™€οΈ the possible responses are 464 JOB <jobid> NOT FOUND., and a line with reply code 161, followed by zero or more continuation lines explaining the job's status.

CANCEL

'CANCEL' <jobid> <CA>

CANCEL stops processing of the job RJS knows as <jobid> right away and deletes every record of it πŸ—‘οΈ if FTP data and/or command connections are pending or established, they get closed. if the job is in execution, an OS CANCEL command gets issued to end it. any output from the job is lost, and asking for the status of <jobid> afterward gives you the diagnostic that the job isn't found πŸ‘» the successful responses are 262 JOB <jobid> DELETED. and 262 JOB <jobid> WILL BE DELETED AS SOON AS POSSIBLE. the failure responses are 464 JOB NOT FOUND. and 464 USER <user name> DOES NOT OWN JOB <jobid>.

Commands Not Yet Implemented

the following standard RJS commands aren't implemented yet, so they just get 506 COMMAND NOT IMPLEMENTED. back πŸ™ƒ ABORT, ALTER, BACK, HOLD, OP, RECOVER, RESTART, and SKIP πŸ₯²

RJS Commands - Local Syntax Conventions ✨

okay so on top of the general conventions we already covered, local syntax has its own little rules πŸ’…

  1. Except in certain circumstances (noted below), a period can be used for command accept. πŸ¦‹
  2. The following control characters have the indicated functions: πŸŽ€
SOH (control A)  delete last character
DEL              delete last character
SYN (control V)  delete last word
CAN (control X)  delete entire line
EOT (control D)  display current word
ACK (control F)  display entire line
'?'              display acceptable input forms
ESC              force recognition of current word
blank            force recognition of current word
  1. The TELNET control characters 'you-echo' and 'I-echo' do the job they're supposed to do. 'You-echo' also switches you into character at a time mode, if you aren't in it already. 🧚

Description of RJS Commands, Local Syntax 🌸

Here's the list of commands you can use in local syntax πŸ“ When a command has no success reply listed, RJS just sends back a CR-LF and then the prompt character. If a command says you must be logged in (or must not be), you'll get LOGIN PLEASE. or LOGGED IN., respectively, when you aren't in the right state πŸ™ˆ And when a command points you to a response under a standard syntax command, just know that reply ids aren't displayed in local syntax.

'FULLDUPLEX' <CA>

Sets you to fullduplex and character at a time modes. πŸ”₯

'HALFDUPLEX' <CA>

Sets you to halfduplex mode. πŸ’œ

'LINE<-AT<-A<-TIME' <CA>

Sets you to halfduplex, line at a time modes. The control characters from before still work, but RJS won't send any output over the TELNET connection unless the current command line is empty. 🌈

'LOGIN' <user name> <password> <account> <CA>

This one picks the UCSB Computer Center user name and account that your RJS use gets billed to, logs you in, and sets the source, print, and punch accounting parameter accumulators to <user name>, <password> and <account>. It's only valid when you're not logged in, and it gives the same replies as the standard syntax 'PASS' command. ✨

'DISCONNECT' <CA>

Closes the TELNET connection. If you're logged in, you get logged out first. An unexpected close on the TELNET connection is handled as a DISCONNECT. The response to a DISCONNECT command is 'TTY <integer> IS DISCONNECTED.' πŸ‘‹

The rest of the commands need you to be logged in πŸ”

'LOG0UT' <CA>

Logs you out and stops billing your later activity over the TELNET connection to the previously effective accounting parameters. It also does the effective action of the REINITIALIZE command. LOGOUT doesn't close the TELNET connection, and it doesn't touch any file transfers in progress for jobs you own. 🫢

'REINITIALIZE' <CA>

Resets these accumulators to empty: source, print and punch accounting parameter, source, print and punch pathname, and login accounting parameter. 🧹

'ACCOUNTING' <account parms> <CA>

'ACCOUNTING' <account parms> <CA>
<account parms> = '(' <u> ',' <p> ',' <a> ')'
<u> = <user name> _ <null>
<p> = <password> _ <null>
<a> = <account> _ <null>

This sets the source, print and punch accounting parameters to <account parms>. Putting <null> in for any of <u>, <p>, or <a> means "use whatever is in the matching login accumulator," which is a super handy shortcut πŸ’…

'SOURCE' <account parms> <CA>

Sets the source accounting parameter accumulators to <account parms>. πŸ“₯

'PRINT' <account parms> <CA>

Sets the print accounting parameter accumulators to <account parms>. πŸ–¨οΈ

'PUNCH' <account parms> <CA>

Sets the punch accounting parameter accumulators to <account parms>. πŸƒ

'SOURCE' <jobid> (<account parms> _ <null>) <pathname> <CA>

Sets the source pathname of job <jobid> to <pathname>, and sets the source accounting parameters to <account parms> if you specify them. If you don't, they get the contents of the source accounting parameter accumulators. If job <jobid> already exists and its source pathname hasn't been specified, the new pathname gets stored. If it has been specified, it changes, unless source file retrieval has already begun. If the job doesn't exist yet, a new job gets created and the pathname stored.

Now the rules, bestie, so read these carefully πŸ™ˆ If a job with a given <jobid> has finished processing, it must be DELETE'd before that <jobid> can be used for a new job. You can only alter jobs you own. And you can't own more than a certain fixed number of jobs (currently 5). If you already own the max, RJS tries to delete an old job to make room for the new one, the same way it does for INPUT under standard syntax.

The SOURCE command can give these error responses:

  • 'NEW JOBS ARE NOT BEING ACCEPTED AT THIS TIME.'
  • 'USER <user name> ALREADY OWNS THE MAXIMUM NUMBER OF JOBS.'
  • 'USER <user name> DOES NOT OWN JOB <jobid>.'
  • 'JOB <jobid> HAS ALREADY COMPLETED.'
  • 'JOB <jobid> IS ALREADY BEING, OR HAS BEEN, READ.'

'PRINT <jobid> (<account parms> _ <null>) <disp> <CA>

Sets the print pathname of job <jobid> to <disp>, and the print accounting parameters to <account parms> if specified. If not, they get the contents of the print accounting parameter accumulators. The PRINT command either creates a new job or changes an existing one, just like SOURCE does. It has the same restrictions and error messages as SOURCE, with the obvious swap of 'PRINTED' for 'READ'. PRINT only works before print file transfer begins. πŸ–¨οΈβœ¨

'PUNCH' <jobid> (<account parms> _ <null>) <disp> <CA>

Sets the punch pathname of job <jobid> to <disp>, and the punch accounting parameters to <account parms> if specified. If not, they get the contents of the punch accounting parameter accumulators. Like SOURCE and PRINT, PUNCH either creates a new job or changes an existing one. It has the same restrictions and error messages as the SOURCE command, with 'PUNCHED' swapped in for 'READ'. PUNCH only works before punch file transfer begins. πŸƒ

'DELETE' <jobid> <CA>

Works exactly like the CANCEL command in standard syntax. πŸ—‘οΈ

'INPUT' <jobid> <CA>

Puts the job identified by <jobid> in a queue within RJS for jobs you own that are waiting on source file transfer. When it becomes the first (or only) job in that queue, retrieval of the source file starts. If INPUT works, you'll see 'JOB <jobid> ACCEPTED FOR PROCESSING.' πŸŽ‰ These error messages are possible:

  • 'JOB <jobid> NOT FOUND.'
  • 'USER <user name> DOES NOT OWN JOB <jobid>.'
  • 'JOB <jobid> HAS ALREADY COMPLETED.'
  • 'SOURCE PATHNAME HAS NOT BEEN SPECIFIED.'
  • 'PRINT PATHNAME HAS NOT BEEN SPECIFIED.'

'JOBSTAT' <jobid> <CA>

Works exactly the same, in function and response, as the 'STATUS' <jobid> command in standard syntax. πŸ“Š

'JOBLIST' <CA>

Lists the jobids of the jobs you own. πŸ“‹

$ <text> <CA>

$ <text> <CA>
<text> = a string of any characters including '?' and '.'.

Note that <CA> must be CR-LF, rather than period. πŸ™…β€β™€οΈ

This issues <text> as a HASP operator command over your virtual operator's console. See Appendix A for a description of HASP commands and command responses. 🧚


RJS File Transfer πŸŽ€

The <pathname> we defined earlier is how you tell RJS where your source, print and punch files live, and what they're like. We already talked about how a file's location gets figured out, so this section is all about the controls you have over the data attributes πŸ’–

The parameter <attributes> sets the type of carriage control and the mode of transfer. For transfer over a simplex connection, it means:

  • :T or :TE - TELNET-like carriage control. The data is a stream of characters with embedded carriage control bytes. Page eject gets signaled by form feed, which is ASCII or EBCDIC decimal 12. New line is carriage return followed by line feed, ASCII l3-lO or EBCDIC 13-27. Multiple new lines (the "double spacing" or "triple spacing" vibe) show up as multiple occurrences of CR-LF.
  • :A or :AE - ASA carriage control. The data is a series of fixed-length records, 81 characters on input and 133 on output, with the first character of each record being an ASA carriage control character. The possible carriage control characters are: '+' for no line advance before print (overprint), ' ' for one line advance (single space), '0' for two lines advance (double space), '-' for three lines advance (triple space), and '1' for page eject. Whatever carriage control character shows up on input gets ignored. πŸ“„
  • :N or :NE - no carriage control. The data is a series of fixed length records, 80 characters on input and 132 on output. Any carriage control generated on output gets thrown out before transmission. 🚫

When file transfer happens over FTP, the <attributes> parameter gets interpreted a bit differently. Here's the deal:

  • :T or :TE - TELNET-like carriage control. The data has the same format as for the simplex connection, and it's transferred in stream mode, file structure, and either ASCII ('A') or EBCDIC ('E') type. 🌊
  • :A or :AE - ASA carriage control. Data gets transferred in blocked mode, record structure, and either ASCII print ('P') or EBCDIC print ('F') type. The first character of every record is the ASA carriage control character described above. 🧾
  • :N or :NE - no carriage control. Data gets transferred in blocked mode, record structure, and either ASCII ('A') or EBCDIC ('E') type. Just like with the simplex connection, no carriage control information is present. 🫧

To pull off the FTP file transfer, RJS issues these FTP commands, in this exact order: πŸ”

  1. USER (if access user name has been specified)
  2. PASS (if password specified)
  3. ACCT (if account specified)
  4. BYTE (specifying bytesize of 8)
  5. ALLO (if outputting file)
  6. TYPE
  7. STRU
  8. MODE
  9. SOCK
  10. APPE or RETR

Appendix A: The HASP Spooling System ✨

okay so HASP is a spooling-queuing-scheduling system 🧚 that works with IBM OS/360 to help process batch jobs πŸ’… its main goal is to boost throughput by minimizing I/O wait time, AND it has a priority scheduling scheme where shorter jobs get picked before longer ones. main character energy for the small jobs πŸ‘‘

There are several stages of processing (aka functions) inside HASP. At any instant a job is either in some stage of processing, which makes it active, or it's waiting for some function to process it, which makes it queued for that function 🌸 each function grabs jobs from its queue in order of decreasing priority. a job's priority comes from its estimated CPU time and its volume of output. so smaller jobs get picked over bigger ones and spend less time in the system. it's giving efficiency πŸ¦‹

The HASP remote user gets a virtual operator's console πŸ’» and over it they can type HASP operator commands to display info about the system in general and to control their terminal and jobs. HASP sends messages back to the console in response to commands, and it also lets them know about things happening to them as they come up 🫢 HASP commands look like this:

$ <verb> <operand1>,<operand2>,...,<operandn>
where
 <verb>          = a single character verb which
                    identifies the general function
                    to be performed

 <operand>       = identification of the object to
                    be displayed or acted upon.

Zero or more operands may be present depending on the command, and commas separate operands when there's more than one πŸŽ€ generally, alphabetics can be typed in either upper or lower case, and for text outside paired apostrophes, blanks can go anywhere you want πŸ’– apostrophes meant as text characters must appear in duplicate, so keep that in mind πŸ™ˆ

Every HASP command gets one or more responses 🌈 the response "OK" is used in lots of cases to acknowledge the command and show that the requested action has been taken or started. in the latter case, an information message gets issued once the request is completed ✨

Every HASP console message begins with the text S HH.MM.SS or S*HH.MM.SS, where HH.MM.SS is the time of day in hours, minutes, and seconds on a 24 hour clock ⏰

Lots of commands display job status info as a response πŸ“‹ the standard response looks like this:

jobs queued for processing:
JOB jjj jobname AW EXEC  class PRIO prio HOLD
                   PRINT rem             PURGE
                   PUNCH rem             *DUP*
                   PURGE

jobs being processed:
JOB jjj jobname EXECUTING class PRIO prio HOLD
                ON DEVICE dev             PURGE
                IS PURGING

where
   jjj             = HASP assigned job number
   jobname         = OS jobname
   AW              = 'AWAITING'
   class           = job's job class
   prio            = job's HASP internal priority
   rem             = terminal number of remote terminal
                     where job is queued to print or punch
   dev             = device name
   HOLD            = signifies job is in hold status, or
                     will be at completion of current
                     function
   PURGE           = signifies job will be purged at
                     completion of current function
   *DUP*           = signifies job cannot begin execution
                     until another job with same jobname
                     completes

Here's a brief rundown of the HASP operator commands a remote user is allowed to issue (for the full tea, see NIC #16306) 🍡

SDA                   Display status information on all active jobs

SDF [,rem]            Display number of jobs queued for special forms

SDN [,queue]          Display status information on all queued jobs

SDQ                   Display number of queued jobs
SCJ jjj               Delete job immediately

SKJ jjj               Issue OS CANCEL and delete job
                      immediately

SPJ jjj               Delete job after current function

SDJ jjj               Display job status information

SD'jobname            Display job status information

SB device,pages       Backspace device

SC device             Delete current function on device

SF device,pages       Forward space device

SDP device            Display job number of job on device

SDI                   Display status and classes of initiators
SDLINE rem            Display status of remote terminal

SDRM rem              Display status of remote terminal

SDU                   Display status of local unit record
                      devices

SDM rem,'message'     Display message to remote console

Appendix B: RJS Reply ID's πŸŽ€

okay here's the list of reply id's that RJS generates in response to each command πŸ“ bookmark this one bestie πŸ”–

command             success reply           failure replies

USER                     330                     501

PASS                     230                     501,431,505

ACCT                     200                     501

BYE                      231                     501

REINIT                   2O4                     5O1,5O4

INUSER/INID              200                     501,504

INPASS                   200                     501,504

INACCT                   200                     501,504

OUTUSER                  200                     501,504

OUTPASS                  200                     501,504

OUTACCT                  200                     501,504

INPATH                   200                     501,504

OUTPATH/OUT              200                     501,504

INPUT                    260                     501,360,504,505

CHANGE                   200                     501,464,504

STATUS (no operand)      100                     501

STATUS (with operand)    161                     501,464,504

CANCEL                   262                     501,464,504

Possible spontaneous reply id's are: 300, 440, 441, 442, 461, and 466 🌟 those can pop up without you asking, so keep your eyes open πŸ‘€

[This RFC was put into machine readable form for entry] [into the online RFC archives by Mikan Mirko] πŸ’œ

πŸ“¦ where this page comes from