|
|
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.