/* * bauble: a tiny room-based messaging system * * mbio.c: routines to read/write a circular message queue. * * mbio() do i/o on a messagebase * mbsuper() does something with the superblock for a messagebase * mbopen() opens a named messagebase * mbclose() closes the currently open messagebase * mbputs() writes a message into the current messagebase */ #include #include #include "mb.h" static int mbfile; /* the current messagebase */ struct mbsb __mb; /* its superblock */ /* * mbio() reads or writes a block to the current messagebase */ mbio(op, loc, buf) int (*op)(); char *buf; { register long address = (long)MBBLKSZ * (long)(1+(loc % __mb.size)); register size; if (lseek(mbfile, address, 0) != address) panic("message base seek fault"); if ((*op)(mbfile, buf, MBBLKSZ) != MBBLKSZ) panic("mbio %s fault", (op==write)?"write":"read"); } /* mbio */ /* * mbsuper() reads or writes the superblock for the current messagebase */ mbsuper(op) int (*op)(); { if (lseek(mbfile, 0L, 0) != 0L) panic("message sblock seek fault"); if ((*op)(mbfile, &__mb, sizeof __mb) != sizeof __mb) panic("message sblock i/o fault"); } /* mbsuper */ /* * mbopen() opens a given messagebase */ mbopen(name) char *name; { register size; if ((mbfile = open(name, O_RDWR|O_BINARY)) >= 0) { size = read(mbfile, &__mb, sizeof __mb); if (size == sizeof __mb && __mb.magic == MBMAGIC) return 1; close(mbfile); } return 0; } /* mbopen */ /* * mbclose() closes the current messagebase */ mbclose() { close(mbfile); } /* mbclose */ /* * puttomb() writes text to the messagebase, updating first & last * message #'s */ static puttomb(text, size) register unsigned char *text; register size; { unsigned char bfr[MBBLKSZ]; register i, chunk; while (size > 0) { chunk = MBBLKSZ-__mb.catidx; if (size < chunk) chunk = size; mbread(__mb.catblk, bfr); for (i=0; i= MBBLKSZ) { __mb.catidx = 0; __mb.catblk = (1+__mb.catblk) % __mb.size; } size -= chunk; text += chunk; } } /* puttomb */ /* * needspace() aligns the cat pointers to the start of the next * block if we don't have room to fit a message id in * * MSGIDSZ is shared between needspace() and mbputs() */ #define MSGIDSZ 20 static needspace(size) { char bfr[MSGIDSZ]; if (__mb.catidx+size >= MBBLKSZ) { memset(bfr, 0, MBBLKSZ-__mb.catidx); puttomb(bfr, MBBLKSZ-__mb.catidx); } } /* needspace */ /* * mbputs() writes a complete message into the messagebase */ mbputs(text, size) register unsigned char *text; { char msgid[MSGIDSZ]; register retloc, hsize, j; sprintf(msgid, "\377%d\n", 1+__mb.newest); hsize = strlen(msgid); needspace(hsize); retloc = __mb.catblk; puttomb(msgid, hsize); for (j=0; j