|
|
1.1 root 1: #include "parms.h"
2: #include "structs.h"
3:
4: #ifdef RCSIDENT
5: static char rcsid[] = "$Header: resp.c,v 1.7 85/01/18 15:38:30 notes Rel $";
6: #endif RCSIDENT
7:
8: /*
9: * putresp (io, text, status, noteno, anon)
10: *
11: * writes out a response to noteno in the last position.
12: * returns 0 to indicate note has been deleted,
13: * otherwise it returns the response number it inserted.
14: *
15: *
16: * delresp(io, noteno, resprec, resphys)
17: *
18: * Deletes PHYSICAL response located at resprec (record id)
19: * resphys (internal subscript), updates note's response count
20: *
21: *
22: * getfrsp(io) gets the next free response index -- simple free list chained
23: * off first two bytes of file, currently.
24: *
25: */
26:
27: long lseek (); /* declare for type checking */
28:
29: putresp (io, where, status, noteno, adate, auth, note, lockit, theid, addid, fromsys,
30: addtime, rcvdtime)
31: /* all input params */
32: struct io_f *io;
33: struct daddr_f *where;
34: struct note_f *note;
35: struct when_f *adate;
36: struct auth_f *auth;
37: struct id_f *theid;
38: char *fromsys;
39: /* addtime - whether to modify time stamps - useed for compression */
40: struct when_f *rcvdtime; /* time to mark as written */
41: {
42: int i,
43: phys, /* physical subscript number */
44: lastin; /* address of resp record in memory */
45: struct resp_f resp;
46:
47: if (lockit)
48: locknf (io, DSCRLOCK); /* entirely critical */
49: getdscr (io, &io -> descr);
50: if (io -> descr.d_stat & NFINVALID)
51: {
52: closenf (io);
53: opennf (io, 0);
54: getdscr (io, &io -> descr); /* and updated descriptor */
55: if (lockit)
56: unlocknf (io, DSCRLOCK);
57: return 0;
58: }
59: getnrec (io, noteno, note);
60: if ((note -> n_stat & DELETED) != 0) /* is note gone? */
61: {
62: /*
63: * see, it could be deleted by someone else in the
64: * mean time...
65: */
66: if (lockit)
67: unlocknf (io, DSCRLOCK); /* not so critical now */
68: return 0; /* putresp failed */
69: }
70: if (note -> n_rindx < 0) /* is there an attached response record ? */
71: {
72: lastin = note -> n_rindx = getfrsp (io); /* no, make one */
73: resp.r_first = 1;
74: resp.r_last = 0; /* counts */
75: resp.r_previous = (-1); /* no previous */
76: resp.r_next = (-1); /* no next */
77: for (i = 0; i < RESPSZ; i++)
78: resp.r_stat[i] = 0; /* mark all as undeleted at start */
79: }
80: else
81: getrrec (io, lastin = note -> n_rindx, &resp); /* get first resp record */
82: i = phys = 0; /* logical/phys records start here */
83: /*
84: * should update this to take advantage of r_first and r_last
85: * as it would speed up writing responses in long note strings.
86: */
87: while (i < note -> n_nresp) /* until we get to end */
88: {
89: if (phys >= RESPSZ) /* off end? -- need next recd */
90: {
91: phys = 0; /* beginning of next one */
92: getrrec (io, lastin = resp.r_next, &resp); /* next recd */
93: }
94: if ((resp.r_stat[phys] & DELETED) == 0)
95: i++; /* count this entry if undeleted */
96: phys++; /* always count these */
97: }
98: /*
99: * could have gone off end with last phys++
100: */
101: if (phys >= RESPSZ)
102: {
103: phys = 0;
104: resp.r_next = getfrsp (io);
105: putrrec (io, lastin, &resp); /* out w/modified link */
106: resp.r_previous = lastin; /* back ptr */
107: lastin = resp.r_next;
108: resp.r_next = (-1); /* helps debugging */
109: resp.r_first = note -> n_nresp + 1; /* front and */
110: resp.r_last = resp.r_first - 1; /* last. */
111: /*
112: * r_last is bumped just before the putrrec() below.
113: */
114: for (i = 0; i < RESPSZ; i++)
115: {
116: resp.r_stat[i] = 0; /* mark all as undeleted */
117: }
118: }
119: note -> n_nresp++; /* one more response! */
120: resp.r_addr[phys] = *where;
121: if (addtime)
122: gettime (&resp.r_rcvd[phys]);
123: else
124: copydate (rcvdtime, &resp.r_rcvd[phys]); /* use supplied */
125: copydate (adate, &resp.r_when[phys]); /* copy date over */
126: copyauth (auth, &resp.r_auth[phys]); /* and author */
127: strmove (fromsys, resp.r_from[phys]); /* who gave it to us */
128: if (addid) /* generate unique id */
129: {
130: #ifdef SHAREDATA
131: strmove (System, resp.r_id[phys].sys); /* load sys name */
132: #else ! SHAREDATA
133: strmove (io -> descr.d_id.sys, resp.r_id[phys].sys);
134: #endif SHAREDATA
135:
136: resp.r_id[phys].uniqid = ++(io -> descr.d_id.uniqid);
137: #if defined(UNIQPLEX)
138: resp.r_id[phys].uniqid += UNIQPLEX * io -> descr.d_nfnum;
139: /* mpx in the nf number */
140: #endif defined(UNIQPLEX)
141: }
142: else
143: { /* use the supplied unique id */
144: strmove (theid -> sys, resp.r_id[phys].sys);
145: resp.r_id[phys].uniqid = theid -> uniqid;
146: }
147: resp.r_stat[phys] = status;
148: if (addtime) /* timestamp ? */
149: {
150: gettime (¬e -> n_lmod); /* last modified entire note */
151: gettime (&io -> descr.d_lastm); /* last modified entire file */
152: }
153: resp.r_last++; /* 1 more there */
154: putrrec (io, lastin, &resp);
155: putnrec (io, noteno, note);
156: putdscr (io, &io -> descr); /* order of these three keeps disk consistent */
157: if (lockit)
158: unlocknf (io, DSCRLOCK);
159: io -> nrspwrit++; /* add count of writes */
160: return note -> n_nresp; /* success */
161: }
162:
163:
164: /*
165: * getfrsp()
166: *
167: * get the next open response block.
168: */
169: getfrsp (io) struct io_f *io;
170: {
171: int i; /* will contain the free pointer */
172: x (lseek (io -> fidrdx, 0L, 0) < 0, "getfrsp: seek I");
173: x (read (io -> fidrdx, &i, sizeof i) < sizeof i, "getfrsp: read");
174: i++; /* next free */
175: x (lseek (io -> fidrdx, 0L, 0) < 0, "getfrsp: seek II");
176: x (write (io -> fidrdx, &i, sizeof i) < sizeof i, "getfrsp: write");
177: return i - 1;
178: }
179:
180:
181: /*
182: * delresp()
183: *
184: * delete a PHYSICAL response. This takes the actual place
185: * the response lives in rather than the logical response
186: * number.
187: *
188: * Updates r_first and r_last for the rest of the response
189: * chain.
190: */
191: delresp (io, noteno, resprec, resphys, lockit)
192: struct io_f *io;
193: {
194: struct resp_f resp;
195: struct note_f note;
196: register int i; /* follows resp chain */
197:
198: if (lockit)
199: locknf (io, DSCRLOCK); /* all critical */
200: getrrec (io, resprec, &resp);
201: if ((resp.r_stat[resphys] & DELETED) == 0)
202: {
203: /*
204: * makes sure that someone hasn't zapped at same time
205: */
206: resp.r_stat[resphys] |= DELETED; /* deleted */
207: resp.r_last--; /* fix count */
208: /*
209: * if r_first > r_last, we have an empty block.
210: * unfortunate waste of space that is rectified
211: * by compression later.
212: */
213: putrrec (io, resprec, &resp);
214: while ((i = resp.r_next) >= 0) /* for rest of chain */
215: {
216: getrrec (io, i, &resp); /* get it */
217: resp.r_first--;
218: resp.r_last--; /* fix indices */
219: putrrec (io, i, &resp); /* and replace */
220: }
221: getnrec (io, noteno, ¬e); /* update the note */
222: --note.n_nresp;
223: putnrec (io, noteno, ¬e);
224: getdscr (io, &io -> descr); /* count deletes */
225: io -> descr.d_delresp++; /* used by compress */
226: putdscr (io, &io -> descr);
227: }
228: if (lockit)
229: unlocknf (io, DSCRLOCK);
230: return;
231: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.