Protocol description in human readable format:
/*
* Find out about remote users
*/
const MAXUSERS = 100;
const MAXUTLEN = 256;
struct utmp {
string ut_line;
string ut_name;
string ut_host;
int ut_time;
};
struct utmpidle {
utmp ui_utmp;
unsigned int ui_idle;
};
typedef utmp utmparr;
typedef utmpidle utmpidlearr;
program RUSERSPROG {
/*
* Includes idle information
*/
version RUSERSVERS_IDLE {
int
RUSERSPROC_NUM(void) = 1;
utmpidlearr
RUSERSPROC_NAMES(void) = 2;
utmpidlearr
RUSERSPROC_ALLNAMES(void) = 3;
} = 1;
/*
* Old version does not include idle information
*/
version RUSERSVERS_ORIG {
int
RUSERSPROC_NUM(void) = 1;
utmparr
RUSERSPROC_NAMES(void) = 2;
utmparr
RUSERSPROC_ALLNAMES(void) = 3;
} = 2;
} = 100002;
Tape converted:
Address Contents Comments
(word)
100 32 (program)
101 100002 program number
102 1 version 1 starts at ...
103 107
104 2 version 2 starts at ...
105 115
106 0 a "nop"
107 33 (version)
108 3 there are 3 procedures
109 1 procedure 1 starts at ...
110 123
111 2
112 127
113 3
114 131
115 33 (version)
116 3 there are 3 procedures
117 1
118 134
119 2
120 p2
121 3
122 p3
123 34 (procedure)
124 2 two "arguments" - the first argument is the result
125 1 integer
126 0 void
127 34 (procedure)
128 2 1 input argument and 1 output argument
129 147 utmpidlearr location of description of utmpidlearr
130 0 argument is void
131 34 (procedure)
132 2
133 147 utmpidlearr
134 0
135 34 (procedure)
136 2
137 1
138 0
139 34
140 2
141 150 utmparr location of utmparr
142 0
143 34
144 2
145 150 utmparr
146 0
147 21 utmpidlearr
148 100 MAXUSERS value of MAXUSERS is given as 100
149 153 utmpidle
150 21 utmparr
151 100 MAXUSERS constant value
152 157 utmp
153 22 struct utmpidle
154 2 there are two fields in the structure
155 157 utmp
156 2
157 22 struct utmp
158 4 four fields in utmp
159 19 string ut_line
160 256 string length is MAXUTLEN (256)
161 19 ut_name
162 256
163 19 ut_host
164 256
165 1 int ut_time
The entire description of the protocol takes 65 tokens (little over 256 bytes)
Another example (from the yellow pages service).
const YPMAXRECORD = 1024;
const YPMAXDOMAIN = 64;const YPMAXRECORD = 1024;
const YPMAXDOMAIN = 64;
const YPMAXMAP = 64;
const YPMAXPEER = 64;
enum ypstat {
YP_TRUE = 1,
YP_NOMORE = 2,
YP_FALSE = 0,
YP_NOMAP = -1,
YP_NODOM = -2,
YP_NOKEY = -3,
YP_BADOP = -4,
YP_BADDB = -5,
YP_YPERR = -6,
YP_BADARGS = -7,
YP_VERS = -8
};
enum ypxfrstat {
YPXFR_SUCC = 1,
YPXFR_AGE = 2,
YPXFR_NOMAP = -1,
YPXFR_NODOM = -2,
YPXFR_RSRC = -3,
YPXFR_RPC = -4,
YPXFR_MADDR = -5,
YPXFR_YPERR = -6,
YPXFR_BADARGS = -7,
YPXFR_DBM = -8,
YPXFR_FILE = -9,
YPXFR_SKEW = -10,
YPXFR_CLEAR = -11,
YPXFR_FORCE = -12,
YPXFR_XFRERR = -13,
YPXFR_REFUSED = -14
};
typedef string domainname;
typedef string mapname;
typedef string peername;
typedef opaque keydat;
typedef opaque valdat;
struct ypmap_parms {
domainname domain;
mapname map;
unsigned int ordernum;
peername peer;
};
const YPMAXRECORD = 1024;
const YPMAXDOMAIN = 64;
const YPMAXMAP = 64;
const YPMAXPEER = 64;
enum ypstat {
YP_TRUE = 1,
YP_NOMORE = 2,
YP_FALSE = 0,
YP_NOMAP = -1,
YP_NODOM = -2,
YP_NOKEY = -3,
YP_BADOP = -4,
YP_BADDB = -5,
YP_YPERR = -6,
YP_BADARGS = -7,
YP_VERS = -8
};
enum ypxfrstat {
YPXFR_SUCC = 1,
YPXFR_AGE = 2,
YPXFR_NOMAP = -1,
YPXFR_NODOM = -2,
YPXFR_RSRC = -3,
YPXFR_RPC = -4,
YPXFR_MADDR = -5,
YPXFR_YPERR = -6,
YPXFR_BADARGS = -7,
YPXFR_DBM = -8,
YPXFR_FILE = -9,
YPXFR_SKEW = -10,
YPXFR_CLEAR = -11,
YPXFR_FORCE = -12,
YPXFR_XFRERR = -13,
YPXFR_REFUSED = -14
};
typedef string domainname;
typedef string mapname;
typedef string peername;
typedef opaque keydat;
typedef opaque valdat;
struct ypmap_parms {
domainname domain;
mapname map;
unsigned int ordernum;
peername peer;
};
struct ypreq_key {
domainname domain;
mapname map;
keydat key;
};
struct ypreq_nokey {
domainname domain;
mapname map;
};
struct ypreq_xfr {
ypmap_parms map_parms;
unsigned int transid;
unsigned int prog;
unsigned int port;
};
struct ypresp_val {
ypstat stat;
valdat val;
};
struct ypresp_key_val {
ypstat stat;
keydat key;
valdat val;
};
struct ypresp_master {
ypstat stat;
peername peer;
};
struct ypresp_order {
ypstat stat;
unsigned int ordernum;
};
union ypresp_all switch (bool more) {
case TRUE:
ypresp_key_val val;
case FALSE:
void;
};
struct ypresp_xfr {
unsigned int transid;
ypxfrstat xfrstat;
};
struct ypmaplist {
mapname map;
ypmaplist *next;
};
struct ypresp_maplist {
ypstat stat;
ypmaplist *maps;
};
struct ypreq_key {
domainname domain;
mapname map;
keydat key;
};
struct ypreq_nokey {
domainname domain;
mapname map;
};
struct ypreq_xfr {
ypmap_parms map_parms;
unsigned int transid;
unsigned int prog;
unsigned int port;
};
struct ypresp_val {
ypstat stat;
valdat val;
};
struct ypresp_key_val {
ypstat stat;
keydat key;
valdat val;
};
struct ypresp_master {
ypstat stat;
peername peer;
};
struct ypresp_order {
ypstat stat;
unsigned int ordernum;
};
union ypresp_all switch (bool more) {
case TRUE:
ypresp_key_val val;
case FALSE:
void;
};
struct ypresp_xfr {
unsigned int transid;
ypxfrstat xfrstat;
};
struct ypmaplist {
mapname map;
ypmaplist *next;
};
struct ypresp_maplist {
ypstat stat;
ypmaplist *maps;
};
const YPMAXMAP = 64;
const YPMAXPEER = 64;
enum ypstat {
YP_TRUE = 1,
YP_NOMORE = 2,
YP_FALSE = 0,
YP_NOMAP = -1,
YP_NODOM = -2,
YP_NOKEY = -3,
YP_BADOP = -4,
YP_BADDB = -5,
YP_YPERR = -6,
YP_BADARGS = -7,
YP_VERS = -8
};
enum ypxfrstat {
YPXFR_SUCC = 1,
YPXFR_AGE = 2,
YPXFR_NOMAP = -1,
YPXFR_NODOM = -2,
YPXFR_RSRC = -3,
YPXFR_RPC = -4,
YPXFR_MADDR = -5,
YPXFR_YPERR = -6,
YPXFR_BADARGS = -7,
YPXFR_DBM = -8,
YPXFR_FILE = -9,
YPXFR_SKEW = -10,
YPXFR_CLEAR = -11,
YPXFR_FORCE = -12,
YPXFR_XFRERR = -13,
YPXFR_REFUSED = -14
};
typedef string domainname;
typedef string mapname;
typedef string peername;
typedef opaque keydat;
typedef opaque valdat;
struct ypmap_parms {
domainname domain;
mapname map;
unsigned int ordernum;
peername peer;
};
struct ypreq_key {
domainname domain;
mapname map;
keydat key;
};
struct ypreq_nokey {
domainname domain;
mapname map;
};
struct ypreq_xfr {
ypmap_parms map_parms;
unsigned int transid;
unsigned int prog;
unsigned int port;
};
struct ypresp_val {
ypstat stat;
valdat val;
};
struct ypresp_key_val {
ypstat stat;
keydat key;
valdat val;
};
struct ypresp_master {
ypstat stat;
peername peer;
};
struct ypresp_order {
ypstat stat;
unsigned int ordernum;
};
union ypresp_all switch (bool more) {
case TRUE:
ypresp_key_val val;
case FALSE:
void;
};
struct ypresp_xfr {
unsigned int transid;
ypxfrstat xfrstat;
};
struct ypmaplist {
mapname map;
ypmaplist *next;
};
struct ypresp_maplist {
ypstat stat;
ypmaplist *maps;
};
Tape for the above (this time alocating addresses from
the top):
200 16 enumeration ypstat
201 11 number of values
202 1
203 2
204 0
205 -1
206 -2
207 -3
208 -4
209 -5
210 -6
211 -7
212 -8
213 16 enum ypxfrstat
214 16 16 values
215 1
216 2
217 -1
218 -2
...
228 -12
229 -13
230 -14
231 19 string domainname
232 64
233 19 mapname
234 64
235 19 peername
236 64
237 17 keydat
238 1024
239 17 valdat
240 1024
241 22 structure ypmap_parms
242 4 4 fields
243 231
244 233
245 2
246 235
247 22 structure ypreq_key
248 3
249 231
250 233
251 237
251 22 structure ypreq_nokey
252 2
253 231
254 233
255 22 structure ypreq_xfr
256 4
257 241
258 2 unsigned int transid
259 2
260 2
261 22 struct ypresp_val
262 2
263 200 location of ypstat description
264 239 location of valdat
265 22 struct ypresp_key_val
266 3
267 200
268 237
269 239
270 22 struct ypresp_master
271 2
272 200
273 235
274 22 struct ypresp_order
275 2
276 200
277 2
278 23 union ypresp_all
279 2 two values (no default)
280 1 TRUE
281 265
282 0 FALSE
283 0
284 22 struct ypresp_xfr
285 2
286 2
287 213
288 22 struct ypmaplist
289 2
290 233
291 25 pointer to ...
292 288 ... ypmaplist
293 22 struct ypresp_maplist
294 2
295 200
296 25
297 288 ypmaplist*