home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume3 / pcmail / part05 / switcher.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-02-03  |  3.9 KB  |  144 lines

  1. /*++
  2. /* NAME
  3. /*      switcher 3
  4. /* SUMMARY
  5. /*      master/slave protocol control switcher
  6. /* PROJECT
  7. /*      pc-mail
  8. /* PACKAGE
  9. /*      cico
  10. /* SYNOPSIS
  11. /*      int switcher(role)
  12. /*      int role;
  13. /* DESCRIPTION
  14. /*      switcher() takes care of the high-level protocol on top of
  15. /*      the packet protocol. 
  16. /*
  17. /*    The system is in one of two roles: MASTER or SLAVE. In MASTER
  18. /*    mode (initial mode of the caller) a system scans its local
  19. /*    spool directory for work until no more is found, and then
  20. /*    sends a H (hangup) request. The slave will respond with HY
  21. /*    if it has no work, otherwise it will respond with HN and
  22. /*    the two systems switch roles.
  23. /*
  24. /*    Work can be of the form of S (send) requests or R (receive)
  25. /*    requests. The slave responds with SY (RY) or SN (RN), depending on
  26. /*    whether it is willing to process the request. The recipient
  27. /*    of a message sends a CY or CN message, depending on whether
  28. /*    transmission was successfull.
  29. /*
  30. /*      Only H(angup) and S(end) requests are implemented here. This is
  31. /*      for security reasons. Thus, the only way to exchange data is
  32. /*      through electronic mail.
  33. /* FUNCTIONS AND MACROS
  34. /*      isok, talk(), hear(), trap(), scanwork(), sendwork()
  35. /*      rmtwork(), getwork()
  36. /* DIAGNOSTICS
  37. /*      Various nonzero status codes are returned in case of problems.
  38. /* AUTHOR(S)
  39. /*      W.Z. Venema
  40. /*      Eindhoven University of Technology
  41. /*      Department of Mathematics and Computer Science
  42. /*      Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  43. /* CREATION DATE
  44. /*      Fri Mar 27 21:49:16 GMT+1:00 1987
  45. /* LAST MODIFICATION
  46. /*    Wed Apr  6 00:23:14 MET 1988
  47. /* VERSION/RELEASE
  48. /*    1.4
  49. /*--*/
  50.  
  51. #include <setjmp.h>
  52. #include "defs.h"
  53. #include "work.h"
  54. #include "params.h"
  55. #include "comm.h"
  56. #include "logs.h"
  57. #include "status.h"
  58.  
  59. /* switcher - handles master/slave role swicthing until all work is done */
  60.  
  61. public switcher(role)
  62. register int role;
  63. {
  64.     int *savetrap = systrap;
  65.     jmp_buf mytrap;
  66.     int status;
  67.  
  68.     if (status = setjmp(systrap = mytrap)) {
  69.     systrap = savetrap;             /* get here on fatal errors */
  70.     return(status);
  71.     }
  72.  
  73.     /* switch roles until both ends out of work */
  74.  
  75.     while (role != DONE) {
  76.     switch (role) {
  77.     case MASTER:
  78.         role = master();
  79.         break;
  80.     case SLAVE:
  81.         role = slave();
  82.         break;
  83.     default:
  84.         trap(E_CONFUSED,"INTERNAL ERROR (unexpected role: %d)",role);
  85.     }
  86.     }
  87.     systrap = savetrap;                 /* get here if no fatal errors */
  88.     return(0);
  89. }
  90.  
  91. /* master - process local work; when done, switch roles or finish */
  92.  
  93. hidden int master()
  94. {
  95.     register work *wrk;
  96.     register char *resp;
  97.  
  98.     while (wrk = scanwork()) {                /* scan for work */
  99.     log("REQUEST (%s)",wrk->rqst);
  100.     if (wrk->fp == 0) {                /* check file exists */
  101.         log("CAN'T READ DATA (%s)",sys_errlist[errno]);
  102.     } else if (isok(wrk->rqst) == NO) {        /* check xfer allowed */
  103.         log("PERMISSION (DENIED)");
  104.     } else {                    /* adapt + send data */
  105.         sendwork(wrk);
  106.         log("REQUESTED (%s)",resp = hear());
  107.         if (strcmp(resp,"CY"))            /* check sucessfull */
  108.         trap(E_REJECT,"FAILED");        /* completion */
  109.         chmod(wrk->path,0666);            /* delete workfile */
  110.         unlink(wrk->path);                /* only if all well */
  111.     }
  112.     }
  113.  
  114.     /* switch roles or finish if slave has no work */
  115.  
  116.     return(isok("H") == YES ? (talk("HY"),DONE) : SLAVE);
  117. }
  118.  
  119. /* slave - process remote work; accept H and S requests only */
  120.  
  121. hidden int slave()
  122. {
  123.     register char *cmnd;
  124.     register work *wrk;
  125.  
  126.     for (;;) {
  127.     switch ((cmnd = hear())[0]) {
  128.     case 'S':                /* master wants to send */
  129.         log("REQUESTED (%s)",cmnd);        /* log the request */
  130.         wrk = rmtwork(cmnd);        /* parse the request */
  131.         talk("SY");                /* say ok */
  132.         getwork(wrk);            /* receive work */
  133.         talk("CY");                /* we never copy */
  134.         log("COPY (SUCCEEDED)");
  135.         break;
  136.     case 'H':                /* master is out of work */
  137.         return(scanwork() ? (talk("HN"),MASTER) : (talk("HY"),DONE));
  138.     default:
  139.         talk(strcons("%cN",cmnd[0]));    /* refuse other type of work */
  140.         break;
  141.     }
  142.     }
  143. }
  144.