Annotation of 43BSD/contrib/courier/doc/courier.tbl.me, revision 1.1.1.1

1.1       root        1: .fo ''%''
                      2: .(l C
                      3: .ps +4
                      4: .b
                      5: Writing Distributed Programs with Courier
                      6: .ps -4
                      7: .sp 2
                      8: .i
                      9: Eric C. Cooper
                     10: .sp 2
                     11: .r
                     12: Computer Science Division \(em EECS
                     13: University of California
                     14: Berkeley, CA  94720
                     15: .sp 2
                     16: March, 1982
                     17: .)l
                     18: .sh 1 "Introduction"
                     19: .pp
                     20: This paper describes the implementation and use
                     21: of the Courier remote procedure call protocol for Berkeley UNIX
                     22: (version 4.2).
                     23: Courier is both a protocol and a specification language.
                     24: The protocol specifies how remote procedures are invoked and
                     25: how parameters and results of various data types are transmitted.
                     26: The specification language, somewhat reminiscent of Mesa,
                     27: provides a simple way of defining the remote interfaces of distributed
                     28: programs.
                     29: This document assumes familiarity with the Courier language,
                     30: details of which may be found in
                     31: the Courier protocol definition.\**
                     32: .r
                     33: .(f
                     34: \**
                     35: ``Courier: The Remote Procedure Call Protocol.''
                     36: Xerox System Integration Standard 038112,
                     37: December 1981.
                     38: .)f
                     39: However, for reference purposes, a grammar for the Courier language
                     40: may be found in the appendix to this document.
                     41: .pp
                     42: The simplest form of distributed program using Courier
                     43: consists of three parts.
                     44: The first is the specification,
                     45: written in the Courier language.
                     46: The specification must declare all procedures of
                     47: the program that will be called remotely (the
                     48: .i "server procedures" ).
                     49: The next part is the implementation, in C, of the server procedures.
                     50: Finally, there is the client portion of the program, also in C, which calls
                     51: the server procedures.
                     52: .sh 1 "The mapping between C and Courier"
                     53: .pp
                     54: The Courier specification language includes
                     55: facilities for declaring new types and constants of given
                     56: types.
                     57: Certain of these types presuppose a programming language
                     58: environment capable of supporting them:
                     59: for example, there are error types that procedures may
                     60: report in lieu of returning a result,
                     61: and procedures may return multiple results.
                     62: Because of the lack of support for these features in the UNIX C
                     63: environment, they are not supported in this implementation.
                     64: .sh 2 "Predefined types"
                     65: .pp
                     66: The following typedefs correspond to predefined Courier types:
                     67: .(b
                     68: .TS
                     69: c c
                     70: l l.
                     71: C typedef      Courier type
                     72: 
                     73: Boolean        BOOLEAN
                     74: Cardinal       CARDINAL
                     75: LongCardinal   LONG CARDINAL
                     76: Integer        INTEGER
                     77: LongInteger    LONG INTEGER
                     78: String STRING
                     79: Unspecified    UNSPECIFIED
                     80: LongUnspecified        LONG UNSPECIFIED
                     81: .TE
                     82: .)b
                     83: .sh 2 "Constructed types"
                     84: .pp
                     85: The Courier enumeration, array, and record types
                     86: correspond to C enumerations, arrays, and structures.
                     87: .pp
                     88: Procedures correspond to C functions,
                     89: except that error reports and multiple results are not supported.
                     90: Error types are not supported.
                     91: .pp
                     92: The Courier sequence and choice types
                     93: pose some problems when they are mapped into C.
                     94: This is because an object of one of these types
                     95: must contain run-time information (the length of the sequence
                     96: or which choice is present)
                     97: that is implicit in Courier, but must be made explicit
                     98: in C.
                     99: Furthermore, the C programmer must bear the responsibility of keeping
                    100: this information consistent.
                    101: .pp
                    102: A sequence type is mapped into a structure consisting
                    103: of a Cardinal called
                    104: .i "length" ,
                    105: and a pointer to the sequence elements called
                    106: .i "sequence" .
                    107: The consistency requirement is that
                    108: .i "length"
                    109: indicate the number of elements in the array pointed to
                    110: by
                    111: .i "sequence" .
                    112: .pp
                    113: A choice type is mapped into a structure consisting
                    114: of an enumeration element called
                    115: .i "designator" ,
                    116: and a union of all the possible choices.
                    117: The designator is of the enumeration type defined
                    118: (implicitly or explicitly)
                    119: in the declaration of the choice type.
                    120: If this enumeration consists of elements
                    121: .i A ,
                    122: .i B ,
                    123: and
                    124: .i C ,
                    125: then the choices are accessible as
                    126: .i A_case ,
                    127: .i B_case ,
                    128: and
                    129: .i C_case .
                    130: The consistency requirement is that
                    131: .i "designator"
                    132: contain the enumeration value corresponding to
                    133: which choice currently occupies the union.
                    134: .sh 2 "Constants"
                    135: .pp
                    136: Although the Courier language allows constants of
                    137: any type to be declared,
                    138: it is difficult to define constants of constructed types
                    139: in C programs.
                    140: Consequently, this implementation restricts constants
                    141: to be numeric.
                    142: .sh 1 "How to build a Courier program"
                    143: .pp
                    144: The specification file is expected to have the extension
                    145: .i ".cr" .
                    146: Consider the following skeletal Courier program definition:
                    147: .sp
                    148:        Example : PROGRAM = BEGIN ... END.
                    149: .sp
                    150: The name of this Courier program is
                    151: .i "Example" ;
                    152: by convention, this specification would stored in the file
                    153: .i "Example.cr" .
                    154: .pp
                    155: The first step is to use the Courier compiler on the specification,
                    156: by doing either
                    157: .sp
                    158:        courier Example.cr
                    159: .sp
                    160: or
                    161: .sp
                    162:        courier -x Example.cr
                    163: .sp
                    164: (The
                    165: .i "-x"
                    166: option is explained below.)
                    167: Assuming there are no errors in compilation,
                    168: the following files will have been produced:
                    169: .(b
                    170: .TS
                    171: c c
                    172: l l.
                    173: File   Contents
                    174: 
                    175: Example.h      definitions and typedefs
                    176: Example_stubs.c        routines to map between C and Courier
                    177: Example_server.c       server routines
                    178: Example_client.c       client routines
                    179: .TE
                    180: .)b
                    181: .pp
                    182: The header file
                    183: .i "Example.h"
                    184: should be included via
                    185: .sp
                    186:        #include ``Example.h''
                    187: .sp
                    188: in all user-written parts of the Courier program
                    189: (i.e., the implementations of the client program and server procedures.)
                    190: It is intended to be readable, so that
                    191: the user can refer to it directly rather than
                    192: memorize the correspondence between Courier types
                    193: and C types discussed above.
                    194: .sh 2 "Calling remote procedures"
                    195: .pp
                    196: The current implementation of Courier supports two styles of
                    197: .i binding
                    198: remote program interfaces to the user program:
                    199: a per-session mechanism (the default) and a per-call mechanism,
                    200: which is requested by giving the Courier compiler the
                    201: .i "-x"
                    202: option (for
                    203: .i explicit
                    204: binding.)
                    205: .pp
                    206: If the per-session mechanism is used, only one instance of each remote interface
                    207: may be active at a time
                    208: (although several different remote programs may be used
                    209: simultaneously.)
                    210: The remote interface for the ``Example'' program above
                    211: is activated by the call
                    212: .sp
                    213:        BindExampleToMachine(machine_name);
                    214: .sp
                    215: (Note that the name of the function to be called depends on the Courier
                    216: program name; it is generated automatically by the Courier compiler.)
                    217: Subsequent calls will deactivate any existing interface for the program before
                    218: activating a new one.
                    219: Once an interface is activated, the remote procedures in it may be called
                    220: exactly as if they were local C functions.
                    221: (The compiler produces stubs
                    222: which invoke the corresponding procedures on the remote machine.)
                    223: .pp
                    224: To use the explicit, or per-call, binding mechanism, the
                    225: .i "-x"
                    226: option must be given to the compiler, as mentioned above.
                    227: No binding call need be given in the user program;
                    228: instead,
                    229: each remote procedure to be called must be passed
                    230: .i "an additional parameter" .
                    231: This parameter, a string, is the machine name 
                    232: on which the procedure should be executed;
                    233: it precedes any other parameters declared in the Courier specification.
                    234: (Again, the compiler produces the appropriate stubs,
                    235: this time with the additional parameter,
                    236: which invoke the corresponding procedures on the specified remote machine.)
                    237: .pp
                    238: This style of binding allows any number of instances of the same 
                    239: remote interface to be used.
                    240: For instance, one could (inefficiently) implement a third-party file transfer
                    241: by reading from one file server and writing to a second file server.
                    242: Since both the read and write procedures would presumably be defined in
                    243: the same Courier specification, per-session binding could not be used.\**
                    244: .(f
                    245: \**
                    246: I am indebted to Jeff Mogul for this example.
                    247: .)f
                    248: .pp
                    249: The client program should be loaded with Example_client.o
                    250: and -lcr (the Courier library) to produce an executable program.
                    251: The server procedures should be loaded with Example_server.o
                    252: and -lcr to produce the server process that will be invoked whenever
                    253: an activation request arrives.
                    254: .sh 1 "The Courier Daemon"
                    255: .pp
                    256: The Courier protocol specifies a standard for communicating
                    257: parameters and results which has been adhered to in this
                    258: implementation.
                    259: It also specifies an initial connection protocol
                    260: and a format for messages, both of which have been somewhat simplified
                    261: for the UNIX environment.
                    262: .pp
                    263: There is a single Courier Daemon per machine whose function
                    264: is to listen on a well-known port for Courier interface activation
                    265: requests.
                    266: A request contains the name of the Courier program
                    267: whose server is to be activated.
                    268: The executable file for this program must reside in a special directory
                    269: (/usr/lib/courier) and have the same name as the Courier program it contains.
                    270: The daemon
                    271: either spawns this executable file
                    272: or replies with an error message.
                    273: .pp
                    274: The format for messages has been simplified somewhat
                    275: because reject and abort messages are not used.
                    276: .sh 1 "An example"
                    277: .pp
                    278: This section contains a Courier program
                    279: which implements remote lookup in
                    280: .i "/etc/passwd"
                    281: (the UNIX database of user names, passwords, home directories, and so on.)
                    282: .bp
                    283: .sh 2 "The specification (PasswordLookup.cr)"
                    284: .sp 2
                    285: .nf
                    286:     PasswordLookup : PROGRAM =
                    287: 
                    288:     BEGIN
                    289: 
                    290:        -- This is a translation of the passwd structure in <pwd.h>
                    291: 
                    292:        Passwd : TYPE = RECORD [
                    293:            pw_name, pw_passwd : STRING,
                    294:            pw_uid, pw_gid, pw_quota : LONG CARDINAL,
                    295:            pw_comment, pw_gecos, pw_dir, pw_shell : STRING
                    296:        ];
                    297: 
                    298:        -- Remote entry points.
                    299: 
                    300:        -- Given a user name, return a Passwd record.
                    301: 
                    302:        LookupUser : PROCEDURE [user : STRING] RETURNS [passwd : Passwd]
                    303:                        = 0;
                    304: 
                    305:        -- Given a user id, return a Passwd record.
                    306: 
                    307:        LookupUid : PROCEDURE [uid : CARDINAL] RETURNS [passwd : Passwd]
                    308:                        = 1;
                    309:     END.
                    310: .fi
                    311: .bp
                    312: .sh 2 "The server procedures (PasswordLookup.c)"
                    313: .sp 2
                    314: .nf
                    315: #include <stdio.h>
                    316: #include "PasswordLookup.h"
                    317: 
                    318: extern Passwd *getpwnam(), *getpwuid();
                    319: 
                    320: Passwd empty = { "", "", 0, 0, 0, "", "" };
                    321: 
                    322: Passwd
                    323: LookupUser(user)
                    324:        String user;
                    325: {
                    326:        Passwd *pw;
                    327: 
                    328:        pw = getpwnam(user);
                    329:        if (pw == 0)
                    330:                return (empty);
                    331:        else
                    332:                return (*pw);
                    333: }
                    334: 
                    335: Passwd
                    336: LookupUid(uid)
                    337:        Cardinal uid;
                    338: {
                    339:        Passwd *pw;
                    340: 
                    341:        pw = getpwuid(uid);
                    342:        if (pw == 0)
                    343:                return (empty);
                    344:        else
                    345:                return (*pw);
                    346: }
                    347: .fi
                    348: .bp
                    349: .sh 2 "The user program (lookup.c)"
                    350: .sp 2
                    351: .nf
                    352: /*
                    353:  * Sample program to access remote password lookup.
                    354:  *
                    355:  * Usage: lookup machine username
                    356:  */
                    357: #include <stdio.h>
                    358: #include "PasswordLookup.h"
                    359: 
                    360: main(argc, argv)
                    361:        int argc;
                    362:        char **argv;
                    363: {
                    364:        Passwd passwd;
                    365: 
                    366:        if (argc != 3) {
                    367:                fprintf(stderr, "Usage: %s machine username\en", argv[0]);
                    368:                exit(1);
                    369:        }
                    370:        BindPasswordLookupToMachine(argv[1]);
                    371:        passwd = LookupUser(argv[2]);
                    372:        if (strcmp(passwd.pw_name, argv[2]) != 0)
                    373:                printf("User %s is unknown on %s.\en",
                    374:                        argv[2], argv[1]);
                    375:        else
                    376:                display(&passwd);
                    377: }
                    378: 
                    379: display(p)
                    380:        Passwd *p;
                    381: {
                    382:        printf("%s:%s:%d:%d:%s:%s:%s\en",
                    383:                p->pw_name,
                    384:                p->pw_passwd,
                    385:                p->pw_uid,
                    386:                p->pw_gid,
                    387:                p->pw_gecos,
                    388:                p->pw_dir,
                    389:                p->pw_shell);
                    390: }
                    391: .fi
                    392: .bp
                    393: .sh 2 "Makefile"
                    394: .sp 2
                    395: .nf
                    396: CFLAGS = -O
                    397: USEROBJS = lookup.o PasswordLookup_client.o
                    398: SRVROBJS = PasswordLookup.o PasswordLookup_server.o
                    399: LIBS = -lcr
                    400: DESTDIR = /usr/lib/courier
                    401: 
                    402: all:   lookup PasswordLookup
                    403: 
                    404: lookup:        $(USEROBJS)
                    405:        cc -o lookup $(USEROBJS) $(LIBS)
                    406: 
                    407: PasswordLookup:        $(SRVROBJS)
                    408:        cc -o PasswordLookup $(SRVROBJS) $(LIBS)
                    409: 
                    410: $(USEROBJS) $(SRVROBJS):       PasswordLookup.h
                    411: 
                    412: PasswordLookup.h \e
                    413: PasswordLookup_server.c \e
                    414: PasswordLookup_client.c:       PasswordLookup.cr
                    415:        courier PasswordLookup.cr
                    416: 
                    417: install:       all
                    418:        install -s PasswordLookup $(DESTDIR)
                    419: 
                    420: clean:
                    421:        -rm -f *.o PasswordLookup_*.c PasswordLookup.h
                    422: .fi
                    423: .sh 1 "Final notes"
                    424: .lp
                    425: The program number and version number fields in a Courier program
                    426: specification are ignored, and instead the program name is used
                    427: to activate the remote interface.
                    428: It was felt that this more dynamic form of binding
                    429: was more in keeping with the UNIX environment than centrally administered
                    430: program numbers.
                    431: .lp
                    432: The DEPENDS UPON facility of the Courier language is not
                    433: supported.
                    434: .lp
                    435: An approximation to Courier error reporting has been designed,
                    436: using a combination of UNIX signals and the C non-local return
                    437: mechanism (a stack frame unwinding mechanism),
                    438: but this has not yet been implemented.
                    439: .lp
                    440: The issues of authentication and protection are
                    441: difficult.
                    442: They are only touched upon in this implementation,
                    443: by making the Courier daemon spawn each server process with privileges
                    444: equivalent to the protection of the corresponding executable file in
                    445: /usr/lib/courier.
                    446: Currently, each Courier program must perform any further authentification
                    447: if this is desired.
                    448: .sh 1 "Appendix"
                    449: .pp
                    450: This appendix contains the grammar for the Courier language.
                    451: It is essentially identical to the YACC specification used
                    452: by the Courier compiler.
                    453: .sp
                    454: .ps -2p
                    455: .vs -2p
                    456: .nf
                    457: .TS
                    458: l l l l l.
                    459: %token identifier      number  string  
                    460:        ARRAY   BEGIN   BOOLEAN CARDINAL
                    461:        CHOICE  DEPENDS END     ERROR
                    462:        FALSE   INTEGER LONG    OF
                    463:        PROCEDURE       PROGRAM RECORD  REPORTS
                    464:        RETURNS SEQUENCE        STRING  TRUE
                    465:        TYPE    UNSPECIFIED     UPON    VERSION
                    466: .TE
                    467: %%
                    468: 
                    469: Program :
                    470:                identifier ':' PROGRAM number VERSION number '='
                    471:                BEGIN DependencyList DeclarationList END '.'
                    472:        |
                    473:                identifier ':' PROGRAM '='
                    474:                BEGIN DependencyList DeclarationList END '.'
                    475:        ;
                    476: 
                    477: DependencyList :
                    478:                /* empty */
                    479:        |       DEPENDS UPON ReferencedProgramList ';'
                    480:        ;
                    481: 
                    482: ReferencedProgramList :
                    483:                ReferencedProgram
                    484:        |       ReferencedProgramList ',' ReferencedProgram
                    485:        ;
                    486: 
                    487: ReferencedProgram :
                    488:                identifier '(' number ')' VERSION number
                    489:        ;
                    490: 
                    491: DeclarationList :
                    492:                /* empty */
                    493:        |       DeclarationList Declaration
                    494:        ;
                    495: 
                    496: Declaration :
                    497:                identifier ':' TYPE '=' Type ';'
                    498:        |       identifier ':' Type '=' Constant ';'
                    499:        ;
                    500: 
                    501: Type :
                    502:                PredefinedType
                    503:        |       ConstructedType
                    504:        |       ReferencedType
                    505:        ;
                    506: 
                    507: PredefinedType :
                    508:                BOOLEAN
                    509:        |       CARDINAL
                    510:        |       LONG CARDINAL
                    511:        |       INTEGER
                    512:        |       LONG INTEGER
                    513:        |       STRING
                    514:        |       UNSPECIFIED
                    515:        |       LONG UNSPECIFIED
                    516:        ;
                    517: 
                    518: ConstructedType :
                    519:                '{' CorrespondenceList '}'
                    520:        |       ARRAY NumericValue OF Type
                    521:        |       SEQUENCE MaximumNumber OF Type
                    522:        |       RECORD '[' FieldList ']'
                    523:        |       RECORD '[' ']'
                    524:        |       CHOICE DesignatorType OF '{' CandidateList '}'
                    525:        |       PROCEDURE ArgumentList ResultList ErrorList
                    526:        |       ERROR ArgumentList
                    527:        ;
                    528: 
                    529: ReferencedType :
                    530:                identifier
                    531:        |       identifier '.' identifier
                    532:        ;
                    533: 
                    534: CorrespondenceList :
                    535:                Correspondence
                    536:        |       CorrespondenceList ',' Correspondence
                    537:        ;
                    538: 
                    539: Correspondence :
                    540:                identifier '(' NumericValue ')'
                    541:        ;
                    542: 
                    543: MaximumNumber :
                    544:                NumericValue
                    545:        |       /* empty */
                    546:        ;
                    547: 
                    548: NumericValue :
                    549:                number
                    550:        |       ReferencedConstant
                    551:        ;
                    552: 
                    553: DesignatorType :
                    554:                /* empty */
                    555:        |       ReferencedType
                    556:        ;
                    557: 
                    558: CandidateList :
                    559:                Candidate
                    560:        |       CandidateList ',' Candidate
                    561:        ;
                    562: 
                    563: Candidate :
                    564:                DesignatorList '=''>' Type
                    565:        ;
                    566: 
                    567: DesignatorList :
                    568:                Designator
                    569:        |       DesignatorList ',' Designator
                    570:        ;
                    571: 
                    572: Designator :
                    573:                identifier
                    574:        |       Correspondence
                    575:        ;
                    576: 
                    577: ArgumentList :
                    578:                /* empty */
                    579:        |       '[' FieldList ']'
                    580:        ;
                    581: 
                    582: ResultList :
                    583:                /* empty */
                    584:        |       RETURNS '[' FieldList ']'
                    585:        ;
                    586: 
                    587: ErrorList :
                    588:                /* empty */
                    589:        |       REPORTS '[' NameList ']'
                    590:        ;
                    591: 
                    592: FieldList :
                    593:                Field
                    594:        |       FieldList ',' Field
                    595:        ;
                    596: 
                    597: Field :
                    598:                NameList ':' Type
                    599:        ;
                    600: 
                    601: Constant :
                    602:                PredefinedConstant
                    603:        |       ConstructedConstant
                    604:        |       ReferencedConstant
                    605:        ;
                    606: 
                    607: PredefinedConstant :
                    608:                TRUE
                    609:        |       FALSE
                    610:        |       number
                    611:        |       '-' number
                    612:        |       '"' string '"'
                    613:        ;
                    614: 
                    615: ConstructedConstant :
                    616:                identifier
                    617:        |       '[' ElementList ']'
                    618:        |       '[' ComponentList ']'
                    619:        |       '['']'
                    620:        |       identifier Constant
                    621:        |       number
                    622:        ;
                    623: 
                    624: ReferencedConstant :
                    625:                identifier
                    626:        |       identifier '.' identifier
                    627:        ;
                    628: 
                    629: ElementList :
                    630:                Constant
                    631:        |       ElementList ',' Constant
                    632:        ;
                    633: 
                    634: ComponentList :
                    635:                Component
                    636:        |       ComponentList ',' Component
                    637:        ;
                    638: 
                    639: Component :
                    640:                NameList ':' Constant
                    641:        ;
                    642: 
                    643: NameList :
                    644:                identifier
                    645:        |       NameList ',' identifier
                    646:        ;
                    647: .fi
                    648: .vs
                    649: .ps

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.