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