DOC HOME SITE MAP MAN PAGES GNU INFO SEARCH PRINT BOOK
 
Network services

Sample port monitor code

The following is an example of a null port monitor which does nothing except respond to messages from the Service Access Controller (SAC).

   # include <stdio.h>
   # include <unistd.h>
   # include <fcntl.h>
   # include <signal.h>
   # include <sac.h>
   

char *getenv();

char Scratch[BUFSIZ]; /* scratch buffer */ char Tag[PMTAGSIZE]; /* port monitor's tag */ FILE *Fp; /* file pointer for log file */ FILE *Tfp; /* file pointer for pid file */ char State; /* port monitor's current state */

main(argc, argv) int argc; char *argv[]; { char *istate;

strcpy(Tag, getenv("PMTAG"));

/* * open up a log file in port monitor's private directory */

sprintf(Scratch, "/var/saf/%s/log", Tag); Fp = fopen(Scratch, "a+"); if (Fp == NULL) exit(1); log(Fp, "starting");

/* * retrieve initial state (either "enabled" or "disabled") and set * State accordingly */

istate = getenv("ISTATE"); sprintf(Scratch, "ISTATE is %s", istate); log(Fp, Scratch); if (!strcmp(istate, "enabled")) State = PM_ENABLED; else if (!strcmp(istate, "disabled")) State = PM_DISABLED; else { log(Fp, "invalid initial state"); exit(1); } sprintf(Scratch, "PMTAG is %s", Tag); log(Fp, Scratch);

/* * set up pid file and lock it to indicate that we are active */

Tfp = fopen("_pid", "w"); if (Tfp == NULL) { log(Fp, "couldn't open pid file"); exit(1); } if (lockf(fileno(Tfp), F_TEST, 0) < 0) { log(Fp, "pid file already locked"); exit(1); } fprintf(Tfp, "%d", getpid()); rewind(Tfp); log(Fp, "locking file"); if (lockf(fileno(Tfp), F_LOCK, 0) < 0) { log(Fp, "lock failed"); exit(1); }

/* * handle poll messages from the sac...this function never returns */

handlepoll(); pause(); fclose(Tfp); fclose(Fp); }

handlepoll() { int pfd; /* file descriptor for incoming pipe */ int sfd; /* file descriptor for outgoing pipe */ struct sacmsg sacmsg; /* incoming message */ struct pmmsg pmmsg; /* outgoing message */

/* * open pipe for incoming messages from the sac */

pfd = open("_pmpipe", O_RDWR); if (pfd < 0) { log(Fp, "_pmpipe open failed"); exit(1); }

/* * open pipe for outgoing messages to the sac */

sfd = open("../_sacpipe", O_RDWR); if (sfd < 0) { log(Fp, "_sacpipe open failed"); exit(1); }

/* * start to build a return message; we only support class 1 messages */

strcpy(pmmsg.pm_tag, Tag); pmmsg.pm_size = 0; pmmsg.pm_maxclass = 1;

/* * keep responding to messages from the sac */

for (;;) { if (read(pfd, &sacmsg, sizeof(sacmsg)) != sizeof(sacmsg)) { log(Fp, "_pmpipe read failed"); exit(1); }

/* * determine the message type and respond appropriately */

switch (sacmsg.sc_type) { case SC_STATUS: log(Fp, "Got SC_STATUS message"); pmmsg.pm_type = PM_STATUS; pmmsg.pm_state = State; break; case SC_ENABLE: /* note internal state change below */ log(Fp, "Got SC_ENABLE message"); pmmsg.pm_type = PM_STATUS; State = PM_ENABLED; pmmsg.pm_state = State; break; case SC_DISABLE: /* note internal state change below */ log(Fp, "Got SC_DISABLE message"); pmmsg.pm_type = PM_STATUS; State = PM_DISABLED; pmmsg.pm_state = State; break; case SC_READDB: /* if this were a fully functional port monitor */ /* it would read _pmtab here and take */ /* appropriate action */ log(Fp, "Got SC_READDB message"); pmmsg.pm_type = PM_STATUS; pmmsg.pm_state = State; break; default: sprintf(Scratch, "Got unknown message <%d>", sacmsg.sc_type); log(Fp, Scratch); pmmsg.pm_type = PM_UNKNOWN; pmmsg.pm_state = State; break; }

/* * send back a response to the poll indicating current state */

if (write(sfd, &pmmsg, sizeof(pmmsg)) != sizeof(pmmsg)) { log(Fp, "sanity response failed"); } } }

/* * general logging function */

log(fp, msg) FILE *fp; char *msg; { fprintf(fp, "%d; %s\n", getpid(), msg); fflush(fp); }


© 2004 The SCO Group, Inc. All rights reserved.
UnixWare 7 Release 7.1.4 - 27 April 2004