1: #ifdef RCSIDENT 2: static char rcsid[] = "$Header: recsio.c,v 1.7 85/01/18 15:38:05 notes Rel $"; 3: #endif RCSIDENT 4: 5: /* 6: * init(io,p), finish(io) struct io_f *io, char *p 7: * initopens the three i/o files and initializes session stats 8: * 9: * finish(io) closes all those files. 10: * 11: * getnrec, putnrec, getrrec, putrrec 12: * getdscr, putdscr, gettrec, puttrec 13: * each gets or puts physical records inside its appropriate file. 14: * 15: */ 16: 17: #include "parms.h" 18: #include "structs.h" 19: #include <sys/types.h> 20: #include <sys/stat.h> 21: 22: long lseek (); /* for sake of lint */ 23: 24: init (io, p) struct io_f *io; 25: char *p; 26: { 27: int i; /* counter */ 28: struct auth_f me; /* identify self */ 29: 30: if ((i = opennf (io, p)) < 0) /* try to open */ 31: { 32: return (i); /* bad luck opening */ 33: } 34: 35: getdscr (io, &io -> descr); 36: if (io -> descr.d_format != DBVERSION) /* bad version */ 37: { 38: printf ("%s: wrong database format (is %ld, want %ld)\n", 39: io -> fullname, io -> descr.d_format, (long) DBVERSION); 40: closenf (io); /* close files */ 41: return (QUITBAD); 42: } 43: getname (&me, 0); /* grab identity for permissions */ 44: getperms (io, 0, me.aname); /* go establish access rights */ 45: 46: io -> nrspwrit = io -> nnotwrit = 0; /* set up stats */ 47: io -> nrspread = io -> nnotread = 0; 48: io -> nnotxmit = io -> nrspxmit = 0; 49: io -> nnotrcvd = io -> nrsprcvd = 0; 50: io -> nnotdrop = io -> nrspdrop = 0; 51: io -> norphans = io -> adopted = 0; 52: io -> xstring[0] = io -> xauthor[0] = '\0'; /* clear search strings */ 53: 54: time (&io -> entered); /* get entry time */ 55: 56: return (0); /* all set */ 57: } 58: 59: /* 60: * Open a notesfile. 61: * 62: * given a name, pick the appropriate notesfile. This includes 63: * searching along "search paths" once we get that implemented. 64: * Absolute path names are permitted. 65: */ 66: 67: opennf (io, p) 68: struct io_f *io; 69: char *p; 70: { 71: char fn[WDLEN]; 72: char *q, 73: *r, 74: *s; 75: char *endname; 76: int i; 77: struct stat statbuf; 78: 79: if (p != (char *) NULL) 80: { /* newly-opened */ 81: if (*p == '/') /* explicit path */ 82: { 83: q = rindex (p, '/'); /* find last '/' */ 84: for (r = p, s = io -> basedir; r < q;) /* copy directory */ 85: *s++ = *r++; 86: *s++ = '\0'; /* terminate */ 87: endname = ++q; 88: } 89: else 90: { 91: /* 92: * This is where we should start looking for the 93: * notesfile along a search path. 94: */ 95: strcpy (io -> basedir, Mstdir); /* default dir */ 96: endname = p; /* for errors */ 97: } 98: 99: if (chkpath (endname)) 100: { 101: printf ("Invalid notefile name: '%s'\n", p); 102: return (QUITBAD); 103: } 104: q = endname; 105: r = io -> nf; 106: i = NNLEN; 107: while ((*r++ = *q++) && --i); /* notesfile name */ 108: 109: sprintf (fn, "%s/%s", io -> basedir, endname); /* open the directory */ 110: if (stat (fn, &statbuf) != 0) /* see if directory */ 111: { 112: printf ("No such notesfile: '%s'\n", p); 113: return (QUITNEX); 114: } 115: } 116: 117: sprintf (io -> fullname, "%s/%s", io -> basedir, io -> nf); 118: 119: sprintf (fn, "%s/%s", io -> fullname, TEXT); 120: if ((io -> fidtxt = open (fn, 2)) < 0) 121: { 122: return (QUITBAD); /* bad nf */ 123: } 124: 125: sprintf (fn, "%s/%s", io -> fullname, INDEXN); 126: if ((io -> fidndx = open (fn, 2)) < 0) 127: { 128: close (io -> fidtxt); 129: return (QUITBAD); 130: } 131: 132: sprintf (fn, "%s/%s", io -> fullname, INDEXR); 133: if ((io -> fidrdx = open (fn, 2)) < 0) 134: { 135: close (io -> fidtxt); 136: close (io -> fidndx); 137: return (QUITBAD); /* bad nf */ 138: } 139: 140: return 0; /* all's well */ 141: } 142: 143: 144: finish (io) 145: struct io_f *io; 146: { 147: long left; 148: struct when_f lvtime; /* for days used */ 149: 150: #ifdef STATS /* if keeping statistics */ 151: locknf (io, DSCRLOCK); /* update statistics */ 152: getdscr (io, &io -> descr); 153: io -> descr.d_notwrit += io -> nnotwrit; 154: io -> descr.d_rspwrit += io -> nrspwrit; 155: io -> descr.d_notread += io -> nnotread; 156: io -> descr.d_rspread += io -> nrspread; 157: io -> descr.d_notxmit += io -> nnotxmit; 158: io -> descr.d_rspxmit += io -> nrspxmit; 159: io -> descr.d_notrcvd += io -> nnotrcvd; 160: io -> descr.d_rsprcvd += io -> nrsprcvd; 161: io -> descr.d_notdrop += io -> nnotdrop; 162: io -> descr.d_rspdrop += io -> nrspdrop; 163: io -> descr.d_orphans += io -> norphans; 164: io -> descr.d_adopted += io -> adopted; 165: io -> descr.entries++; /* count of entries */ 166: time (&left); 167: io -> descr.walltime += left - io -> entered; /* time spent in nf */ 168: gettime (&lvtime); 169: if ((lvtime.w_day != io -> descr.d_lastuse.w_day) || 170: (lvtime.w_month != io -> descr.d_lastuse.w_month) || 171: (lvtime.w_year != io -> descr.d_lastuse.w_year)) 172: { 173: io -> descr.d_daysused++; 174: copydate (&lvtime, &io -> descr.d_lastuse); 175: } 176: putdscr (io, &io -> descr); /* update the block */ 177: unlocknf (io, DSCRLOCK); 178: #endif STATS /* end of stats gathering */ 179: 180: closenf (io); 181: } 182: 183: closenf (io) 184: struct io_f *io; 185: { 186: 187: x (close (io -> fidtxt) < 0, "finish: text fail"); 188: x (close (io -> fidndx) < 0, "finish: nindx fail"); 189: x (close (io -> fidrdx) < 0, "finish: rindx fail"); 190: } 191: 192: 193: 194: getnrec (io, n, note) struct note_f *note; /* n is the number of the note to get. 0 is policy note */ 195: struct io_f *io; 196: { 197: long where; /* going to seek here eventually */ 198: struct descr_f *descr; /* for sizeof below */ 199: 200: x (n < 0, "getnrec: negative recnum"); 201: where = sizeof (*descr) + n * sizeof (*note); 202: x (lseek (io -> fidndx, where, 0) < 0, "getnrec: seek"); 203: x (read (io -> fidndx, note, sizeof *note) < sizeof *note, "getnrec: read"); 204: } 205: 206: putnrec (io, n, note) struct note_f *note; /* n is the number of the note to put. 0 is policy note */ 207: struct io_f *io; 208: { 209: long where; /* going to seek here eventually */ 210: struct descr_f *descr; /* for sizeof below */ 211: 212: x (n < 0, "putnrec: negative recnum"); 213: where = sizeof (*descr) + n * sizeof (*note); 214: x (lseek (io -> fidndx, where, 0) < 0, "putnrec: seek"); 215: x (write (io -> fidndx, note, sizeof *note) < sizeof *note, "putnrec: write "); 216: } 217: 218: getdscr (io, descr) struct descr_f *descr; 219: struct io_f *io; 220: { 221: 222: x (lseek (io -> fidndx, 0L, 0) < 0, "getdscr: seek"); 223: x (read (io -> fidndx, descr, sizeof *descr) < sizeof *descr, "getdscr: read"); 224: } 225: 226: putdscr (io, descr) struct descr_f *descr; 227: struct io_f *io; 228: { 229: 230: x (lseek (io -> fidndx, 0L, 0) < 0, "putdscr: seek"); 231: x (write (io -> fidndx, descr, sizeof *descr) < sizeof *descr, "putdscr: write"); 232: } 233: 234: getrrec (io, n, resp) struct resp_f *resp; /* n is the number of the resp to get */ 235: struct io_f *io; 236: { 237: long where; /* going to seek here eventually */ 238: int a; /* size of free link */ 239: x (n < 0, "getrrec: negative recnum"); 240: 241: where = sizeof a + n * sizeof (*resp); 242: x (lseek (io -> fidrdx, where, 0) < 0, "getrrec: seek"); 243: x (read (io -> fidrdx, resp, sizeof *resp) < sizeof *resp, "getrrec: read"); 244: } 245: 246: putrrec (io, n, resp) struct resp_f *resp; /* n is the number of the resp to put */ 247: struct io_f *io; 248: { 249: long where; /* going to seek here eventually */ 250: int a; /* size of free link */ 251: x (n < 0, "putrrec: negative recnum"); 252: 253: where = sizeof a + n * sizeof (*resp); 254: x (lseek (io -> fidrdx, where, 0) < 0, "putrrec: seek"); 255: x (write (io -> fidrdx, resp, sizeof *resp) < sizeof *resp, "putrrec: write"); 256: } 257: 258: /* 259: * puttrec(i&io_f, &FILE, &daddr_f, long) 260: * 261: * reads cound characters from the input stream specified ad 262: * puts them into the text file. The address is returned... 263: * 264: * Almost identical to the code in "pagein.c" and should 265: * probably be the same code with the third parameter being 266: * the count and meaning "until EOF" if -1 or something.. 267: * 268: * Ray Essick May 8, 1982 269: */ 270: long puttrec (io, zfile, where, count) 271: struct io_f *io; 272: FILE * zfile; 273: struct daddr_f *where; 274: long count; 275: { 276: 277: int i; 278: long nchars; 279: long ignored; 280: int ignoring; 281: struct daddr_f nwhere; 282: struct txtbuf_f buf; /* hold bunches of text */ 283: 284: if (count == 0) /* empty text */ 285: { 286: where -> addr = 0; 287: where -> textlen = 0; /* standard empty */ 288: return ((long) 0); 289: } 290: 291: locknf (io, TXTLOCK); /* grab access to the file */ 292: x (lseek (io -> fidtxt, 0L, 0) < 0, "puttrec: bad seek 0"); 293: x (read (io -> fidtxt, where, sizeof nwhere) < 0, "puttrec: read 0"); 294: x (lseek (io -> fidtxt, where -> addr, 0) < 0, "puttrec:badseek"); 295: 296: nchars = 0; 297: ignored = 0; 298: ignoring = 0; 299: i = 0; 300: while ((nchars + ignored) != count) /* grab input */ 301: { 302: if (!ignoring) 303: { 304: if (i == BUFSIZE) /* flush full buffer */ 305: { 306: x (write (io -> fidtxt, buf.txtbuf, BUFSIZE) != BUFSIZE, 307: "puttrec: bad text"); 308: i = 0; /* reset buffer */ 309: } 310: buf.txtbuf[i++] = getc (zfile); 311: if (++nchars >= io -> descr.d_longnote) /* gotta truncate */ 312: ignoring++; /* start now */ 313: } 314: else 315: { 316: (void) getc (zfile); /* punt */ 317: ignored++; 318: } 319: } 320: if (i) /* write partial buf */ 321: x (write (io -> fidtxt, buf.txtbuf, i) != i, "puttrec: bad text"); 322: if (ignored) /* write warning */ 323: { 324: sprintf (buf.txtbuf, "\n\n%s ignored %ld excess bytes\n", 325: System, ignored); 326: i = strlen (buf.txtbuf); /* get length */ 327: x (write (io -> fidtxt, buf.txtbuf, i) != i, "puttrec: bad text"); 328: nchars += i; /* count extras */ 329: } 330: /* 331: * fix count of characters sucked in daddr_f structure 332: */ 333: where -> textlen = nchars; /* fill header */ 334: /* 335: * now fix the free pointer 336: */ 337: x (lseek (io -> fidtxt, 0L, 0) < 0, "puttrec:bad reseek"); 338: nwhere.addr = where -> addr + nchars; 339: if (nwhere.addr & 1) /* odd ? */ 340: nwhere.addr++; /* round to word boundary */ 341: x (write (io -> fidtxt, &nwhere, sizeof nwhere) != sizeof nwhere, "puttrec: badupdate"); 342: 343: unlocknf (io, TXTLOCK); 344: return ((long) nchars); 345: }