home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD v1.2 / amidev_cd_12.iso / reference / amiga_mail_vol2 / ii-31 / messagenotification.c < prev    next >
C/C++ Source or Header  |  1996-01-30  |  9KB  |  221 lines

  1. ;/* MessageNotification.c - Compiled with SAS/C 6.56:
  2. sc NMINC STRMERGE NOSTKCHK NODEBUG DATA=FAR IGNORE=73 MessageNotification.c
  3. slink from MessageNotification.o to MessageNotification lib lib:amiga.lib
  4. quit
  5.  
  6. Copyright (c) 1991 Commodore-Amiga, Inc.
  7.  
  8. This example is provided in electronic form by Commodore-Amiga,
  9. Inc. for use with the Amiga Mail Volume II technical publication.
  10. Amiga Mail Volume II contains additional information on the correct
  11. usage of the techniques and operating system functions presented in
  12. these examples.  The source and executable code of these examples may
  13. only be distributed in free electronic form, via bulletin board or
  14. as part of a fully non-commercial and freely redistributable
  15. diskette.  Both the source and executable code (including comments)
  16. must be included, without modification, in any copy.  This example
  17. may not be published in printed form or distributed with any
  18. commercial product. However, the programming techniques and support
  19. routines set forth in these examples may be used in the development
  20. of original executable software products for Commodore Amiga
  21. computers.
  22.  
  23. All other rights reserved.
  24.  
  25. This example is provided "as-is" and is subject to change; no
  26. warranties are made.  All use is at your own risk. No liability or
  27. responsibility is assumed.
  28. */
  29.  
  30. #include <exec/types.h>
  31. #include <exec/memory.h>
  32. #include <exec/lists.h>
  33. #include <exec/nodes.h>
  34. #include <dos/dos.h>
  35. #include <dos/dosasl.h>
  36. #include <dos/notify.h>
  37. #include <dos/rdargs.h>
  38.  
  39. #include <clib/alib_protos.h>
  40. #include <clib/exec_protos.h>
  41. #include <clib/dos_protos.h>
  42.  
  43. /* Use pragmas if you've got them */
  44.  
  45. static UBYTE   *VersTag = "\0$VER: MessageNotification 37.1 (09.07.91)";
  46. struct Library *DOSBase;
  47. struct ExecBase *SysBase;
  48.  
  49. /* I'll keep track of the NotifyRequests in an Exec list */
  50. struct NotifyNode
  51. {
  52.     struct Node     nn_Node;
  53.     struct NotifyRequest nn_NotifyRequest;
  54.     /* and whatever is useful. Maybe a FileInfoBlock structure... */
  55. };
  56.  
  57. VOID            main(VOID);
  58.  
  59. VOID
  60. main(VOID)
  61. {
  62.  
  63.     struct RDArgs  *readargs;
  64.     LONG            rargs[2];
  65.     struct NotifyRequest *notifyrequest;
  66.     struct NotifyMessage *notifymsg;
  67.     struct List    *notifylist;
  68.     struct MsgPort *notifyport;
  69.     struct NotifyNode *nnode, *nextnode;
  70.     UBYTE         **filenames;
  71.     ULONG           signal, notifysignal;
  72.  
  73.     /* To appease amiga.lib */
  74.     SysBase = (*((struct Library **) 4));
  75.  
  76.     /* Fail silently if < 37 */
  77.     if (DOSBase = OpenLibrary("dos.library", 37))
  78.     {
  79.  
  80.         /* See the DOS Autodocs for more information about ReadArgs() */
  81.         if (readargs = ReadArgs("Filename/A/M", rargs, NULL))
  82.         {
  83.             /* Pointer to array of filenames */
  84.             filenames = (UBYTE **) (rargs[0]);
  85.  
  86.             if (notifyport = CreateMsgPort())
  87.             {
  88.                 if (notifylist = AllocMem(sizeof(struct List), MEMF_CLEAR))
  89.                 {
  90.                     /* initialize list */
  91.                     NewList(notifylist);
  92.  
  93.                     /* The list of filenames is terminated with a NULL */
  94.                     while (*filenames)
  95.                     {
  96.                         /* Get a NotifyNode */
  97.                         if (nnode = AllocMem(sizeof(struct NotifyNode), MEMF_CLEAR))
  98.                         {
  99.                             /*
  100.                              * Use ln_Name to store qualified filename to
  101.                              * monitor. Note that I keep using that pointer to
  102.                              * the command argument line here. In a real life
  103.                              * application you're better off copying the
  104.                              * string.
  105.                              */
  106.                             nnode->nn_Node.ln_Name = (UBYTE *) * filenames++;
  107.                             notifyrequest = &(nnode->nn_NotifyRequest);
  108.  
  109.                             /* Initialize notifcation request */
  110.                             notifyrequest->nr_Name = nnode->nn_Node.ln_Name;
  111.                             notifyrequest->nr_Flags = NRF_SEND_MESSAGE | NRF_WAIT_REPLY;
  112.                             notifyrequest->nr_stuff.nr_Msg.nr_Port = notifyport;
  113.                             /*
  114.                              * I'm storing the address of the NotifyNode in
  115.                              * nr_UserData. Not going to do anything with it
  116.                              * here, but it would enable me to use the node
  117.                              * immediately when I receive a NotifyMessage.
  118.                              */
  119.                             notifyrequest->nr_UserData = (ULONG) nnode;
  120.                             /*
  121.                              * only add the node to the list if notification is
  122.                              * supported
  123.                              */
  124.                             if ((StartNotify(notifyrequest)) == DOSTRUE)
  125.                             {
  126.                                 AddTail(notifylist, (struct Node *) nnode);
  127.                                 Printf("Notification on %s\n",
  128.                                        (LONG) nnode->nn_Node.ln_Name);
  129.                             }
  130.                             else
  131.                             {
  132.                                 Printf("Notification failed on %s\n",
  133.                                        (LONG) nnode->nn_Node.ln_Name);
  134.                                 FreeMem(nnode, sizeof(struct NotifyNode));
  135.                             }
  136.                         }
  137.                         else
  138.                         {
  139.                             PrintFault(ERROR_NO_FREE_STORE, NULL);
  140.                             break;
  141.                         }
  142.                     }
  143.  
  144.                     /*
  145.                      * Is list empty? If so get out of here. (Macro defined in
  146.                      * <exec/lists.h>)
  147.                      */
  148.                     if (!(IsListEmpty(notifylist)))
  149.                     {
  150.                         /*
  151.                          * No empty, so we've got outstanding NotifyRequests.
  152.                          * Loop until Ctrl-C.
  153.                          */
  154.                         notifysignal = 1L << notifyport->mp_SigBit;
  155.                         for (;;)
  156.                         {
  157.                             /* Wait for message port signals and break */
  158.                             signal = Wait(notifysignal | SIGBREAKF_CTRL_C);
  159.  
  160.                             if (signal & notifysignal)
  161.                             {
  162.                                 while (notifymsg =
  163.                                         (struct NotifyMessage *) GetMsg(notifyport))
  164.                                 {
  165.                                     /*
  166.                                      * Here is that node again, stuffed in
  167.                                      * nr_UserData. Can immediately reference
  168.                                      * its data, like comparing filesize with
  169.                                      * stored filesize in node, or remove it
  170.                                      * (after an EndNotify() ofcourse).
  171.                                      */
  172.                                     Printf("Notification message for %s, Node at 0x%lx\n",
  173.                                            (LONG) notifymsg->nm_NReq->nr_Name,
  174.                                       (LONG) notifymsg->nm_NReq->nr_UserData);
  175.                                     ReplyMsg((struct Message *) notifymsg);
  176.                                 }
  177.                             }
  178.  
  179.                             if (signal & SIGBREAKF_CTRL_C)
  180.                             {
  181.                                 /*
  182.                                  * Walk down the list, remove all
  183.                                  * NotifyRequests, free all nodes.
  184.                                  */
  185.                                 nnode = (struct NotifyNode *) notifylist->lh_Head;
  186.                                 while (nextnode =
  187.                                         (struct NotifyNode *) nnode->nn_Node.ln_Succ)
  188.                                 {
  189.                                     notifyrequest = &(nnode->nn_NotifyRequest);
  190.                                     Printf("Removing notifcation for %s\n",
  191.                                            (LONG) notifyrequest->nr_Name);
  192.                                     /*
  193.                                      * remove this request. EndNotify() will
  194.                                      * also remove any messages on the message
  195.                                      * port.
  196.                                      */
  197.                                     EndNotify(notifyrequest);
  198.                                     /*
  199.                                      * Not really needed to Remove() the node,
  200.                                      * never going to use this list again
  201.                                      */
  202.                                     Remove((struct Node *) nnode);
  203.                                     FreeMem(nnode, sizeof(struct NotifyNode));
  204.                                     nnode = nextnode;
  205.                                 }
  206.                                 break;
  207.                             }
  208.                         }
  209.                     }
  210.                     FreeMem(notifylist, sizeof(struct List));
  211.                 }
  212.                 DeleteMsgPort(notifyport);
  213.             }
  214.             FreeArgs(readargs);
  215.         }
  216.         else
  217.             PrintFault(IoErr(), NULL);
  218.         CloseLibrary(DOSBase);
  219.     }
  220. }
  221.