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
-
- /* 90/01/22 13:02:45
-
- /* VERSION/RELEASE
-
- /* 2.1
-
- /*--*/
-
-
-
- #include <stdio.h>
-
- #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; /* 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]);
-
- trap(E_SYSFAIL, "FAILED"); /* don\'t loop forever */
-
- } else if (isok(wrk->rqst) == NO) { /* check xfer allowed */
-
- log("PERMISSION (DENIED)");
-
- trap(E_REJECT, "FAILED"); /* don\'t loop forever */
-
- } else {
-
- sendwork(wrk); /* adapt and send data */
-
- log("REQUESTED (%s)", resp = hear());/* get remote status */
-
- if (strcmp(resp, "CY")) /* check for sucessful */
-
- trap(E_REJECT, "FAILED"); /* completion */
-
- unlink(wrk->sent); /* just in case */
-
- rename(wrk->path, wrk->sent); /* change status to "sent" */
-
- }
-
- }
-
-
-
- /* 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;
-
- }
-
- }
-
- }
-
-