home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_disks / 200-299 / ff290.lzh / IPC / Sources / SimpleServer.c < prev   
C/C++ Source or Header  |  1989-12-11  |  7KB  |  244 lines

  1. /************************************************************
  2.  *                                                          *
  3.  *         Trivial Server demo for IPC                      *
  4.  *                                                          *
  5.  *                Pete Goodeve 89:4:01                      *
  6.  *                                                          *
  7.  *  [This module has only been compiled under Lattice;      *
  8.  *   it will need some modification for Manx/Aztec;         *
  9.  *   ... I'd be very grateful if someone would do the       *
  10.  *   conversion...]                                         *
  11.  *                                                          *
  12.  *                                                          *
  13.  *  This is just a "working skeleton" Server [shades of     *
  14.  *  Harryhausen...?] that simply opens a port, looks for    *
  15.  *  any LINE, TEXT, or STRG items it can print out in any   *
  16.  *  messages sent to it, and replies the message..          *                          *
  17.  *                                                          *
  18.  *  (Note that it expects all messages to have a replyport  *
  19.  *  -- any that don't will be discarded without reclaiming  *
  20.  *  memory.  Other servers can be set up to delete messages *
  21.  *  properly if they follow the rules.)                     *
  22.  *                                                          *
  23.  *                                                          *
  24.  *  The only special message ID recognized by this server   *
  25.  *  is QUIT, which always causes an immediate exit (after   *
  26.  *  replying to any remaining messages).                    *
  27.  *  It will also quit if it is sent a cntrl-C break.        *
  28.  *                                                          *
  29.  *                                                          *
  30.  ************************************************************/
  31.  
  32. /*** This code has been written to be compiled under Lattice 4 or 5
  33. *   -- if you are using another compiler, you will have to adjust
  34. *   these includes (and maybe other parts of the code) to make it work.
  35. ***/
  36.  
  37. #ifdef LATTICE
  38. #if LATTICE_40 | LATTICE_50
  39. #include "IPC_proto.h"
  40. /* ...else (not recent Lattice) will need library linkage stubs (IPC.o) */
  41. #include <proto/exec.h>
  42. #endif
  43. #endif
  44.  
  45. /*** if proto/exec.h is not included, you should declare the following:
  46. APTR OpenLibrary(char *, int);
  47. void CloseLibrary(APTR);
  48. struct Message * Getmsg(struct MsgPort *);
  49. ***/
  50. /** (or without parameters if your compiler doesn't accept them) **/
  51.  
  52.  
  53. #include "IPC.h"
  54.  
  55. #include "stdio.h"
  56.  
  57. #include "exec/memory.h"
  58. #include "libraries/dos.h"
  59.  
  60. /************************************************************/
  61.  
  62. /*
  63.  *  Define the ID codes recognized by server
  64.  *
  65.  *  (MAKE_ID is defined in IPC.h)
  66.  */
  67.  
  68. /* Message IDs: */
  69. #define QUIT  MAKE_ID('Q','U','I','T')
  70.  
  71. #define LINE  MAKE_ID('L','I','N','E')
  72.     /* indicates a complete line of text -- omitting newline */
  73.  
  74. #define TEXT  MAKE_ID('T','E','X','T')
  75.     /* Text block -- may include newlines */
  76.  
  77. #define STRG  MAKE_ID('S','T','R','G')
  78.     /* general non-specific ASCII STRinG (normally less than a line) */
  79.  
  80.  
  81.  
  82. /************************************************************/
  83.  
  84.     /*** Global Variables: ***/
  85.  
  86.  
  87. struct Library * IPCBase = NULL; /* Base pointer for the IPC Library */
  88.  
  89.  
  90. struct IPCPort *import=NULL; /* this is the port we serve */
  91.  
  92. struct IPCMessage *imsg=NULL; /* we only handle one message at a time,
  93.                                  so a global pointer is useful */
  94.  
  95.  
  96. void procitem(); /* (just using old-style forward ref...)*/
  97. void Cleanup();
  98.  
  99. int active = TRUE; /* when this goes FALSE, it's time to quit */
  100.  
  101. ULONG importsig = 0; /* signal mask for port */
  102.  
  103. /************************************************************/
  104.  
  105.  
  106.  
  107.     /***************************
  108.      *
  109.      *  Main program entry point:
  110.      *
  111.      ***************************/
  112.  
  113. void main()
  114. {
  115.     ULONG sigset;  /* set to signals that woke up Wait() */
  116.  
  117.  
  118.     /* Before anything else, we need the IPC Library: */
  119.     IPCBase = OpenLibrary("ppipc.library",0);
  120.     if (!IPCBase) {
  121.         puts(
  122.         "Couldn't find ppipc.library!\nHave you installed it in LIBS: ?\n");
  123.         exit(20);
  124.     }
  125.  
  126.     setnbf(stdout); /* so we can see output! (unbuffered) */
  127.  
  128.     import = ServeIPCPort("Demo");
  129.     if (!import) {
  130.         puts("Print Server already exists ... exiting");
  131.         Cleanup();
  132.         return;
  133.     }
  134.  
  135.     /* Get the signal bit for the port for later convenience: */
  136.     /* (Note that, because we did not include IPCPorts.h, IPCPorts
  137.         are identical to MsgPorts as far as the user is concerned;
  138.         if we DID need IPCPorts.h, this statement would have to
  139.         be changed appropriately.) */
  140.     importsig = 1<<import->mp_SigBit;
  141.  
  142.  
  143.     /*
  144.      ***  The main loop: ***
  145.      *  -- first we process any outstanding messages, looping until
  146.      *  no more are found
  147.      *  -- then we go to sleep until woken up by another message (or
  148.      *  a cntrl-C).
  149.      */
  150.     do {
  151.         while ( procimsg()) ;  /* loop to satisfy messages */
  152.  
  153.         /*
  154.          *  Now wait for further messages, unless 'active' is FALSE
  155.          */
  156.         if (active) {
  157.             /* Note that Wait() must be used rather than WaitPort()
  158.                if we want to wake up on IPP_NOTIFY as well as messages */
  159.             sigset = Wait(importsig | SIGBREAKF_CTRL_C);
  160.             if (sigset & SIGBREAKF_CTRL_C) {
  161.                 active = FALSE;
  162.                 ShutIPCPort(import); /* note: multiple calls don't hurt! */
  163.                 continue; /* so we clear out any messages that sneak in */
  164.             }
  165.         }
  166.     } while (active);
  167.     /*** end of main loop ***/
  168.  
  169.     puts("Server terminating...\n");
  170.  
  171.     Cleanup();
  172. }
  173. /*** end of _main ***/
  174.  
  175.  
  176. void Cleanup()
  177. {
  178.     if (import) LeaveIPCPort(import);
  179.     CloseLibrary(IPCBase);
  180. }
  181.  
  182.  
  183. /************************************************************/
  184.  
  185.  
  186.  
  187. /*
  188.  *  Process incoming messages
  189.  *  -- returns FALSE if there are none, otherwise TRUE.
  190.  *  (In a functional server this procedure would recognize the message ID
  191.  *  and invoke the appropriate handling procedures.)
  192.  */
  193.  
  194. procimsg() {
  195.     struct IPCItem *item;
  196.     int count, i;
  197.     if (!(imsg = (struct IPCMessage *) GetMsg(import))) return FALSE;
  198.     switch (imsg->ipc_Id) {
  199.  
  200.        case QUIT:
  201.                active = FALSE;
  202.                ShutIPCPort(import);
  203.                puts("server got QUIT message...");
  204.                break;
  205.  
  206.        default:
  207.                item = imsg->ipc_Items;
  208.                count = imsg->ipc_ItemCount;
  209.                for (i=0; i<count; i++)
  210.                    procitem(&item[i]);
  211.                break;
  212.     }
  213.  
  214.     if (imsg->ipc_Msg.mn_ReplyPort)
  215.         ReplyMsg(imsg);
  216.     else
  217.         puts("received message with no reply port -- MEMORY WILL BE LOST!!");
  218.  
  219.     return TRUE;
  220. }
  221.  
  222. void procitem(item) struct IPCItem *item;
  223. {
  224.     switch (item->ii_Id) {
  225.        case LINE:
  226.                 puts(item->ii_Ptr); /* this appends a newline */
  227.                 break;
  228.        case TEXT:
  229.                 fputs(item->ii_Ptr, stdout); /* this doesn't */
  230.                 break;
  231.        case STRG:
  232.                 fputs(item->ii_Ptr, stdout);
  233.                 fputc('|', stdout); /* supply a separator */
  234.                 break;
  235.        default:
  236.                 item->ii_Flags |= IPC_NOTKNOWN;
  237.                 imsg->ipc_Flags |= IPC_CHECKITEM;
  238.                 break;
  239.     }
  240. }
  241.  
  242. /************************************************************/
  243.  
  244.