home *** CD-ROM | disk | FTP | other *** search
- /*++
- /* NAME
- /* switcher 3
- /* SUMMARY
- /* master/slave protocol control switcher
- /* PROJECT
- /* pc-mail
- /* PACKAGE
- /* cico
- /* SYNOPSIS
- /* int switcher(role)
- /* int role;
- /* DESCRIPTION
- /* switcher() takes care of the high-level protocol on top of
- /* the packet protocol.
- /*
- /* The system is in one of two roles: MASTER or SLAVE. In MASTER
- /* mode (initial mode of the caller) a system scans its local
- /* spool directory for work until no more is found, and then
- /* sends a H (hangup) request. The slave will respond with HY
- /* if it has no work, otherwise it will respond with HN and
- /* the two systems switch roles.
- /*
- /* Work can be of the form of S (send) requests or R (receive)
- /* requests. The slave responds with SY (RY) or SN (RN), depending on
- /* whether it is willing to process the request. The recipient
- /* of a message sends a CY or CN message, depending on whether
- /* transmission was successfull.
- /*
- /* Only H(angup) and S(end) requests are implemented here. This is
- /* for security reasons. Thus, the only way to exchange data is
- /* through electronic mail.
- /* FUNCTIONS AND MACROS
- /* isok, talk(), hear(), trap(), scanwork(), sendwork()
- /* rmtwork(), getwork()
- /* DIAGNOSTICS
- /* Various nonzero status codes are returned in case of problems.
- /* AUTHOR(S)
- /* W.Z. Venema
- /* Eindhoven University of Technology
- /* Department of Mathematics and Computer Science
- /* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
- /* CREATION DATE
- /* Fri Mar 27 21:49:16 GMT+1:00 1987
- /* LAST MODIFICATION
- /* Wed Apr 6 00:23:14 MET 1988
- /* VERSION/RELEASE
- /* 1.4
- /*--*/
-
- #include <setjmp.h>
- #include "defs.h"
- #include "work.h"
- #include "params.h"
- #include "comm.h"
- #include "logs.h"
- #include "status.h"
-
- /* switcher - handles master/slave role swicthing until all work is done */
-
- public switcher(role)
- register int role;
- {
- int *savetrap = systrap;
- jmp_buf mytrap;
- int status;
-
- if (status = setjmp(systrap = mytrap)) {
- systrap = savetrap; /* get here on fatal errors */
- return(status);
- }
-
- /* switch roles until both ends out of work */
-
- while (role != DONE) {
- switch (role) {
- case MASTER:
- role = master();
- break;
- case SLAVE:
- role = slave();
- break;
- default:
- trap(E_CONFUSED,"INTERNAL ERROR (unexpected role: %d)",role);
- }
- }
- systrap = savetrap; /* get here if no fatal errors */
- return(0);
- }
-
- /* master - process local work; when done, switch roles or finish */
-
- hidden int master()
- {
- register work *wrk;
- register char *resp;
-
- while (wrk = scanwork()) { /* scan for work */
- log("REQUEST (%s)",wrk->rqst);
- if (wrk->fp == 0) { /* check file exists */
- log("CAN'T READ DATA (%s)",sys_errlist[errno]);
- } else if (isok(wrk->rqst) == NO) { /* check xfer allowed */
- log("PERMISSION (DENIED)");
- } else { /* adapt + send data */
- sendwork(wrk);
- log("REQUESTED (%s)",resp = hear());
- if (strcmp(resp,"CY")) /* check sucessfull */
- trap(E_REJECT,"FAILED"); /* completion */
- chmod(wrk->path,0666); /* delete workfile */
- unlink(wrk->path); /* only if all well */
- }
- }
-
- /* switch roles or finish if slave has no work */
-
- return(isok("H") == YES ? (talk("HY"),DONE) : SLAVE);
- }
-
- /* slave - process remote work; accept H and S requests only */
-
- hidden int slave()
- {
- register char *cmnd;
- register work *wrk;
-
- for (;;) {
- switch ((cmnd = hear())[0]) {
- case 'S': /* master wants to send */
- log("REQUESTED (%s)",cmnd); /* log the request */
- wrk = rmtwork(cmnd); /* parse the request */
- talk("SY"); /* say ok */
- getwork(wrk); /* receive work */
- talk("CY"); /* we never copy */
- log("COPY (SUCCEEDED)");
- break;
- case 'H': /* master is out of work */
- return(scanwork() ? (talk("HN"),MASTER) : (talk("HY"),DONE));
- default:
- talk(strcons("%cN",cmnd[0])); /* refuse other type of work */
- break;
- }
- }
- }
-