home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / dos / communic / pcmail / main / switcher.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-06-05  |  4.5 KB  |  293 lines

  1. /*++
  2.  
  3. /* NAME
  4.  
  5. /*      switcher 3
  6.  
  7. /* SUMMARY
  8.  
  9. /*      master/slave protocol control switcher
  10.  
  11. /* PROJECT
  12.  
  13. /*      pc-mail
  14.  
  15. /* PACKAGE
  16.  
  17. /*      cico
  18.  
  19. /* SYNOPSIS
  20.  
  21. /*      int switcher(role)
  22.  
  23. /*      int role;
  24.  
  25. /* DESCRIPTION
  26.  
  27. /*      switcher() takes care of the high-level protocol on top of
  28.  
  29. /*      the packet protocol. 
  30.  
  31. /*
  32.  
  33. /*    The system is in one of two roles: MASTER or SLAVE. In MASTER
  34.  
  35. /*    mode (initial mode of the caller) a system scans its local
  36.  
  37. /*    spool directory for work until no more is found, and then
  38.  
  39. /*    sends a H (hangup) request. The slave will respond with HY
  40.  
  41. /*    if it has no work, otherwise it will respond with HN and
  42.  
  43. /*    the two systems switch roles.
  44.  
  45. /*
  46.  
  47. /*    Work can be of the form of S (send) requests or R (receive)
  48.  
  49. /*    requests. The slave responds with SY (RY) or SN (RN), depending on
  50.  
  51. /*    whether it is willing to process the request. The recipient
  52.  
  53. /*    of a message sends a CY or CN message, depending on whether
  54.  
  55. /*    transmission was successfull.
  56.  
  57. /*
  58.  
  59. /*      Only H(angup) and S(end) requests are implemented here. This is
  60.  
  61. /*      for security reasons. Thus, the only way to exchange data is
  62.  
  63. /*      through electronic mail.
  64.  
  65. /* FUNCTIONS AND MACROS
  66.  
  67. /*      isok, talk(), hear(), trap(), scanwork(), sendwork()
  68.  
  69. /*      rmtwork(), getwork()
  70.  
  71. /* DIAGNOSTICS
  72.  
  73. /*      Various nonzero status codes are returned in case of problems.
  74.  
  75. /* AUTHOR(S)
  76.  
  77. /*      W.Z. Venema
  78.  
  79. /*      Eindhoven University of Technology
  80.  
  81. /*      Department of Mathematics and Computer Science
  82.  
  83. /*      Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  84.  
  85. /* CREATION DATE
  86.  
  87. /*      Fri Mar 27 21:49:16 GMT+1:00 1987
  88.  
  89. /* LAST MODIFICATION
  90.  
  91. /*    90/01/22 13:02:45
  92.  
  93. /* VERSION/RELEASE
  94.  
  95. /*    2.1
  96.  
  97. /*--*/
  98.  
  99.  
  100.  
  101. #include <stdio.h>
  102.  
  103. #include <setjmp.h>
  104.  
  105.  
  106.  
  107. #include "defs.h"
  108.  
  109. #include "work.h"
  110.  
  111. #include "params.h"
  112.  
  113. #include "comm.h"
  114.  
  115. #include "logs.h"
  116.  
  117. #include "status.h"
  118.  
  119.  
  120.  
  121. /* switcher - handles master/slave role swicthing until all work is done */
  122.  
  123.  
  124.  
  125. public  switcher(role)
  126.  
  127. register int role;
  128.  
  129. {
  130.  
  131.     int    *savetrap = systrap;
  132.  
  133.     jmp_buf mytrap;
  134.  
  135.     int     status;
  136.  
  137.  
  138.  
  139.     if (status = setjmp(systrap = mytrap)) {
  140.  
  141.     systrap = savetrap;            /* get here on fatal errors */
  142.  
  143.     return (status);
  144.  
  145.     }
  146.  
  147.     /* switch roles until both ends out of work */
  148.  
  149.  
  150.  
  151.     while (role != DONE) {
  152.  
  153.     switch (role) {
  154.  
  155.     case MASTER:
  156.  
  157.         role = master();
  158.  
  159.         break;
  160.  
  161.     case SLAVE:
  162.  
  163.         role = slave();
  164.  
  165.         break;
  166.  
  167.     default:
  168.  
  169.         trap(E_CONFUSED, "INTERNAL ERROR (unexpected role: %d)", role);
  170.  
  171.     }
  172.  
  173.     }
  174.  
  175.     systrap = savetrap;                /* no fatal errors */
  176.  
  177.     return (0);
  178.  
  179. }
  180.  
  181.  
  182.  
  183. /* master - process local work; when done, switch roles or finish */
  184.  
  185.  
  186.  
  187. hidden int master()
  188.  
  189. {
  190.  
  191.     register work *wrk;
  192.  
  193.     register char *resp;
  194.  
  195.  
  196.  
  197.     while (wrk = scanwork()) {            /* scan for work */
  198.  
  199.     log("REQUEST (%s)", wrk->rqst);
  200.  
  201.     if (wrk->fp == 0) {            /* check file exists */
  202.  
  203.         log("CAN'T READ DATA (%s)", sys_errlist[errno]);
  204.  
  205.         trap(E_SYSFAIL, "FAILED");        /* don\'t loop forever */
  206.  
  207.     } else if (isok(wrk->rqst) == NO) {    /* check xfer allowed */
  208.  
  209.         log("PERMISSION (DENIED)");
  210.  
  211.         trap(E_REJECT, "FAILED");        /* don\'t loop forever */
  212.  
  213.     } else {
  214.  
  215.         sendwork(wrk);            /* adapt and send data */
  216.  
  217.         log("REQUESTED (%s)", resp = hear());/* get remote status */
  218.  
  219.         if (strcmp(resp, "CY"))        /* check for sucessful */
  220.  
  221.         trap(E_REJECT, "FAILED");    /* completion */
  222.  
  223.         unlink(wrk->sent);            /* just in case */
  224.  
  225.         rename(wrk->path, wrk->sent);    /* change status to "sent" */
  226.  
  227.     }
  228.  
  229.     }
  230.  
  231.  
  232.  
  233.     /* switch roles or finish if slave has no work */
  234.  
  235.  
  236.  
  237.     return (isok("H") == YES ? (talk("HY"), DONE) : SLAVE);
  238.  
  239. }
  240.  
  241.  
  242.  
  243. /* slave - process remote work; accept H and S requests only */
  244.  
  245.  
  246.  
  247. hidden int slave()
  248.  
  249. {
  250.  
  251.     register char *cmnd;
  252.  
  253.     register work *wrk;
  254.  
  255.  
  256.  
  257.     for (;;) {
  258.  
  259.     switch ((cmnd = hear())[0]) {
  260.  
  261.     case 'S':                /* master wants to send */
  262.  
  263.         log("REQUESTED (%s)", cmnd);    /* log the request */
  264.  
  265.         wrk = rmtwork(cmnd);        /* parse the request */
  266.  
  267.         talk("SY");                /* say ok */
  268.  
  269.         getwork(wrk);            /* receive work */
  270.  
  271.         talk("CY");                /* we never copy */
  272.  
  273.         log("COPY (SUCCEEDED)");
  274.  
  275.         break;
  276.  
  277.     case 'H':                /* master is out of work */
  278.  
  279.         return (scanwork() ? (talk("HN"), MASTER) : (talk("HY"), DONE));
  280.  
  281.     default:
  282.  
  283.         talk(strcons("%cN", cmnd[0]));    /* refuse other type of work */
  284.  
  285.         break;
  286.  
  287.     }
  288.  
  289.     }
  290.  
  291. }
  292.  
  293.