2.9BSD/usr/contrib/notes/resp.c
static char *sccsid = "@(#)resp.c 1.2 2/2/83";
#include "parms.h"
#include "structs.h"
#ifdef BSD4.1c
#include <sys/file.h>
#else
#define L_SET 0
#define L_INCR 1
#define L_XTND 2
#endif BSD4.1c
/*
* putresp (io, text, status, noteno, anon)
*
* writes out a response to noteno in the last position.
* returns 0 to indicate note has been deleted,
* otherwise it returns the response number it inserted.
*
*
* delresp(io, noteno, resprec, resphys)
*
* Deletes PHYSICAL response located at resprec (record id)
* resphys (internal subscript), updates note's response count
*
*
* getfrsp(io) gets the next free response index -- simple free list chained
* off first two bytes of file, currently.
*
*/
long lseek (); /* declare for type checking */
putresp (io, where, status, noteno, adate, auth, note, lockit, theid, addid, fromsys,
addtime, rcvdtime)
/* all input params */
struct io_f *io;
struct daddr_f *where;
struct note_f *note;
struct when_f *adate;
struct auth_f *auth;
struct id_f *theid;
char *fromsys;
/* addtime - whether to modify time stamps - useed for compression */
struct when_f *rcvdtime; /* time to mark as written */
{
int i,
phys, /* physical subscript number */
lastin; /* address of resp record in memory */
struct resp_f resp;
if (lockit) {
lock(io, 'n'); /* entirely critical */
}
getdscr(io, &io->descr);
if (io->descr.d_stat & NFINVALID) {
closenf (io);
opennf (io, io->nf);
getdscr (io, &io->descr); /* and updated descriptor */
if (lockit) {
unlock(io, 'n'); /* entirely critical */
}
return(0);
}
getnrec(io, noteno, note);
if ((note->n_stat & DELETED) != 0) { /* is this note deleted? */
/* see, it could be deleted by someone else in the intermediary */
if (lockit) {
unlock(io, 'n'); /* entirely critical */
}
return(0); /* putresp failed */
}
if (note->n_rindx < 0) { /* is there an attached response record ? */
lastin = note->n_rindx = getfrsp(io); /* no, make one */
for (i = 0; i < RESPSZ; i++) {
resp.r_stat[i] = 0; /* mark all as undeleted at start */
}
} else {
getrrec(io, lastin = note->n_rindx, &resp); /* get 1st resp record */
}
i = phys = 0; /* logical/phys records start here */
while (i < note->n_nresp) { /* until we get to end */
if (phys >= RESPSZ) { /* off end? -- need next recd */
phys = 0; /* beginning of next one */
getrrec(io, lastin = resp.r_next, &resp); /* next recd */
}
if ((resp.r_stat[phys] & DELETED) == 0) {
i++; /* count this entry if undeleted */
}
phys++; /* always count these */
}
/* could have gone off end with last phys++ */
if (phys >= RESPSZ) {
phys = 0;
resp.r_next = getfrsp(io);
putrrec (io, lastin, &resp); /* out w/modified link */
lastin = resp.r_next;
resp.r_next = -1; /* helps debugging */
for (i = 0; i < RESPSZ; i++) {
resp.r_stat[i] = 0; /* mark all as undeleted */
}
}
note->n_nresp++; /* one more response! */
resp.r_addr[phys].addr = where->addr;
if (addtime) {
gettime(&resp.r_rcvd[phys]);
} else {
copydate(rcvdtime, &resp.r_rcvd[phys]); /* use supplied */
}
copydate(adate, &resp.r_when[phys]); /* copy date over */
copyauth(auth, &resp.r_auth[phys]); /* and author */
strmove(fromsys, resp.r_from[phys]); /* who gave it to us */
if (addid) { /* generate unique id */
strmove(io->descr.d_id.sys, resp.r_id[phys].sys);
resp.r_id[phys].uniqid = ++(io->descr.d_id.uniqid);
#ifdef UNIQPLEX
resp.r_id[phys].uniqid += UNIQPLEX * io->descr.d_nfnum;
/* mpx in the nf number */
#endif
} else { /* use the supplied unique id */
strmove(theid->sys, resp.r_id[phys].sys);
resp.r_id[phys].uniqid = theid->uniqid;
}
resp.r_stat[phys] = status;
if (addtime) { /* timestamp ? */
gettime(¬e->n_lmod); /* last modified entire note */
gettime(&io->descr.d_lastm); /* last modified entire file */
}
putrrec(io, lastin, &resp);
putnrec(io, noteno, note);
putdscr(io, &io->descr); /* order of these three keeps disk consistent */
if (lockit) {
unlock(io, 'n'); /* entirely critical */
}
io->nrspwrit++; /* add count of writes */
return(note->n_nresp); /* success */
}
getfrsp (io)
struct io_f *io;
{
int i; /* will contain the free pointer */
x (lseek(io->fidrdx, 0L, L_SET) < 0, "getfrsp: seek I");
x (read(io->fidrdx, &i, sizeof(i)) < sizeof(i), "getfrsp: read");
i++; /* next free */
x (lseek(io->fidrdx, 0L, L_SET) < 0, "getfrsp: seek II");
x (write(io->fidrdx, &i, sizeof(i)) < sizeof(i), "getfrsp: write");
return(i-1);
}
delresp (io, noteno, resprec, resphys, lockit)
struct io_f *io;
int noteno;
int resprec;
int resphys;
int lockit;
{
struct resp_f resp;
struct note_f note;
if (lockit) {
lock(io, 'n'); /* entirely critical */
}
getrrec(io, resprec, &resp);
if ((resp.r_stat[resphys] & DELETED) == 0) {
/* makes sure that someone hasn't zapped at same time */
resp.r_stat[resphys] |= DELETED; /* deleted */
putrrec(io, resprec, &resp);
getnrec(io, noteno, ¬e);
--note.n_nresp;
putnrec(io, noteno, ¬e);
}
if (lockit) {
unlock(io, 'n'); /* entirely critical */
}
return;
}