|
|
1.1 ! root 1: #include "parms.h" ! 2: #include "structs.h" ! 3: ! 4: #ifdef RCSIDENT ! 5: static char rcsid[] = "$Header: compress.c,v 1.7.0.2 85/03/19 13:02:07 notes Rel $"; ! 6: #endif RCSIDENT ! 7: ! 8: /* ! 9: * compress(io) struct io_f ! 10: * compresses the notefile specified. All wasted space ! 11: * reclaimed. The process is a simple one which, like dcheck, ! 12: * does not work so well on active file systems. ! 13: * As a consequence, the director options (which call this) ! 14: * require the notefile to be closed before allowing compression ! 15: * to take place. ! 16: * The code generates 3 scratch files, corresponding with the ! 17: * two index files and the text file. These are made to ! 18: * represent a virgin notefile. The descriptor is copied over ! 19: * with the appropriate fields zapped, and then we go through ! 20: * a cycle of (read note; write note; (read resp; write resp)) ! 21: * until all the notes and responses are moved over. ! 22: * the new files are then copied back into place. ! 23: * ! 24: * Returns: 0 - all successful ! 25: * otherwise will core dump with the notefile ! 26: * in a shambles from the users view point, ! 27: * but still recoverable by a hotshot-pro. ! 28: * ! 29: * Original Coding: Ray Essick January 1981 ! 30: */ ! 31: ! 32: compress (io, lockflag, verbosity, numnotes, numresps) ! 33: struct io_f *io; ! 34: int lockflag; /* to lock or not */ ! 35: int verbosity; ! 36: /* verbosity == 0 silent ! 37: * else print dots as go & do totals ! 38: */ ! 39: int *numnotes, /* remaining notes when done */ ! 40: *numresps; /* ditto for responses */ ! 41: { ! 42: struct io_f tmpio; /* scratch notefile */ ! 43: struct note_f note; /* hold a note record */ ! 44: struct resp_f resp; /* hold the response format */ ! 45: char fn1[WDLEN], ! 46: fn2[WDLEN], ! 47: fn3[WDLEN], ! 48: on1[WDLEN], ! 49: on2[WDLEN], ! 50: on3[WDLEN], ! 51: txtfn[WDLEN]; /* hold text going between files */ ! 52: struct daddr_f where; ! 53: FILE * txtfile; ! 54: int nnotes, ! 55: nresps, ! 56: dint, ! 57: roffset, ! 58: num, ! 59: rblock; ! 60: register int newnum, ! 61: presps, ! 62: rnum; ! 63: struct daddr_f daddr; ! 64: int old_umask; /* save it */ ! 65: ! 66: ! 67: /* ! 68: * build names of files - in notefile directory ! 69: */ ! 70: ! 71: /* new files */ ! 72: sprintf (fn1, "%s/%s/%s%s", io -> basedir, io -> nf, COMPRESS, INDEXN); ! 73: sprintf (fn2, "%s/%s/%s%s", io -> basedir, io -> nf, COMPRESS, INDEXR); ! 74: sprintf (fn3, "%s/%s/%s%s", io -> basedir, io -> nf, COMPRESS, TEXT); ! 75: ! 76: sprintf (on1, "%s/%s/%s", io -> basedir, io -> nf, INDEXN);/* old files */ ! 77: sprintf (on2, "%s/%s/%s", io -> basedir, io -> nf, INDEXR); ! 78: sprintf (on3, "%s/%s/%s", io -> basedir, io -> nf, TEXT); ! 79: ! 80: old_umask = umask (0); /* wide open */ ! 81: x ((tmpio.fidndx = creat (fn1, 0660)) < 0, "compress: create nindex"); ! 82: x ((tmpio.fidrdx = creat (fn2, 0660)) < 0, "compress: create rindex"); ! 83: x ((tmpio.fidtxt = creat (fn3, 0660)) < 0, "compress: create txt"); ! 84: ! 85: dint = 0; /* resp index free pointer */ ! 86: daddr.addr = sizeof daddr; /* and for text file */ ! 87: x (write (tmpio.fidrdx, &dint, sizeof dint) != sizeof dint, "compress: resp ptr"); ! 88: x (write (tmpio.fidtxt, &daddr, sizeof daddr) != sizeof daddr, "Compress: text ptr"); ! 89: ! 90: ! 91: closenf (&tmpio); /* close them up */ ! 92: ! 93: x ((tmpio.fidndx = open (fn1, 2)) < 0, "compress: reopen 1"); ! 94: /* open R/W */ ! 95: x ((tmpio.fidrdx = open (fn2, 2)) < 0, "compress: reopen 2"); ! 96: x ((tmpio.fidtxt = open (fn3, 2)) < 0, "compress: reopen 3"); ! 97: ! 98: strcpy (tmpio.nf, io -> nf); /* notesfile name */ ! 99: strcpy (tmpio.basedir, io -> basedir); /* and directory */ ! 100: nnotes = nresps = 0; ! 101: sprintf (txtfn, "/tmp/nf%d", getpid ()); /* scratch for text */ ! 102: ! 103: if (lockflag) ! 104: locknf (io, DSCRLOCK); /* lock up the notefile */ ! 105: getdscr (io, &tmpio.descr); /* grab descriptor */ ! 106: if (io -> descr.d_stat & NFINVALID) ! 107: { ! 108: printf ("Notesfile compressed behind your back"); ! 109: if (lockflag) ! 110: unlocknf (io, DSCRLOCK); ! 111: closenf (&tmpio); /* clean up mess */ ! 112: x (unlink (fn1) < 0, "compress: unlink tmp1"); ! 113: x (unlink (fn2) < 0, "compress: unlink tmp2"); ! 114: x (unlink (fn3) < 0, "compress: unlink tmp3"); ! 115: umask (old_umask); /* restore */ ! 116: return (-1); ! 117: } ! 118: ! 119: locknf (io, TXTLOCK); /* always */ ! 120: ! 121: tmpio.descr.d_nnote = 0; /* reset note count */ ! 122: tmpio.descr.d_delnote = 0; /* no holes */ ! 123: tmpio.descr.d_delresp = 0; ! 124: putdscr (&tmpio, &tmpio.descr); /* place it into the file */ ! 125: ! 126: if (io -> descr.d_plcy) /* copy the policy note over */ ! 127: { ! 128: getnrec (io, 0, ¬e); /* descriptor */ ! 129: #ifdef notdef ! 130: x ((txtfile = fopen (txtfn, "w")) == NULL, "compress:bad txt"); ! 131: pageout (io, ¬e.n_addr, txtfile); ! 132: fclose (txtfile); ! 133: x ((txtfile = fopen (txtfn, "r")) == NULL, "compress: bad txt read"); ! 134: pagein (&tmpio, txtfile, &where); ! 135: fclose (txtfile); ! 136: #else ! 137: pagemove (io, ¬e.n_addr, &tmpio, &where, NOLOCKIT); ! 138: #endif ! 139: #ifdef FIXTIMES ! 140: fixtime (¬e.n_rcvd); ! 141: fixtime (¬e.n_lmod); ! 142: fixtime (¬e.n_date); ! 143: #endif FIXTIME ! 144: putnote (&tmpio, &where, note.ntitle, note.n_stat, ¬e, ¬e.n_auth, ! 145: POLICY, NOLOCKIT, NOADDID, note.n_from, NOADDTIME); ! 146: } ! 147: for (num = 1; num <= io -> descr.d_nnote; num++) ! 148: { ! 149: if (verbosity) /* if being noisy */ ! 150: { ! 151: putchar ('.'); ! 152: fflush (stdout); /* so he see action */ ! 153: } ! 154: getnrec (io, num, ¬e); ! 155: if (note.n_stat & DELETED) ! 156: continue; /* deleted - we throw away */ ! 157: #ifdef notdef ! 158: x ((txtfile = fopen (txtfn, "w")) == NULL, "compress:bad txt"); ! 159: pageout (io, ¬e.n_addr, txtfile); ! 160: fclose (txtfile); ! 161: x ((txtfile = fopen (txtfn, "r")) == NULL, "compress: bad txt read"); ! 162: pagein (&tmpio, txtfile, &where); ! 163: fclose (txtfile); ! 164: #else ! 165: pagemove (io, ¬e.n_addr, &tmpio, &where, NOLOCKIT); ! 166: #endif ! 167: presps = note.n_nresp; /* save max number of responses */ ! 168: #ifdef FIXTIMES ! 169: fixtime (¬e.n_rcvd); ! 170: fixtime (¬e.n_lmod); ! 171: fixtime (¬e.n_date); ! 172: #endif FIXTIME ! 173: newnum = putnote (&tmpio, &where, note.ntitle, note.n_stat, ¬e, ¬e.n_auth, ! 174: NOPOLICY, NOLOCKIT, NOADDID, note.n_from, NOADDTIME); ! 175: nnotes++; /* add a note */ ! 176: ! 177: for (rnum = 1; rnum <= presps; rnum++) /* process responses */ ! 178: { ! 179: if (lrsp (io, num, rnum, &resp, &roffset, &rblock) != 0) ! 180: break; /* bad response chain - drop rest */ ! 181: #ifdef notdef ! 182: x ((txtfile = fopen (txtfn, "w")) == NULL, "compress:bad txt"); ! 183: pageout (io, &resp.r_addr[roffset], txtfile); ! 184: fclose (txtfile); ! 185: x ((txtfile = fopen (txtfn, "r")) == NULL, "compress: bad txt read"); ! 186: pagein (&tmpio, txtfile, &where); ! 187: fclose (txtfile); ! 188: #else ! 189: pagemove (io, &resp.r_addr[roffset], &tmpio, &where, NOLOCKIT); ! 190: #endif ! 191: #ifdef FIXTIMES ! 192: fixtime (&resp.r_when[roffset]); ! 193: fixtime (&resp.r_rcvd[roffset]); ! 194: #endif FIXTIMES ! 195: putresp (&tmpio, &where, resp.r_stat[roffset], newnum, &resp.r_when[roffset], ! 196: &resp.r_auth[roffset], ¬e, NOLOCKIT, &resp.r_id[roffset], ! 197: NOADDID, resp.r_from[roffset], NOADDTIME, &resp.r_rcvd[roffset]); ! 198: nresps++; /* count responses */ ! 199: } ! 200: } ! 201: ! 202: /* well, we have now copied the entire notefile over, so the time ! 203: * has come to move it back into the correct file names - we will ! 204: * do this by ! 205: */ ! 206: closenf (&tmpio); /* close the new one */ ! 207: ! 208: getdscr (io, &io -> descr); ! 209: io -> descr.d_stat |= NFINVALID; /* mark it bad */ ! 210: putdscr (io, &io -> descr); ! 211: closenf (io); /* close the old one */ ! 212: ! 213: x (unlink (on1) < 0, "compress: remove old 1"); ! 214: x (link (fn1, on1) < 0, "compress: link new 1"); ! 215: x (unlink (fn1) < 0, "compress: remove tmp 1"); ! 216: x (unlink (on2) < 0, "compress: remove old 2"); ! 217: x (link (fn2, on2) < 0, "compress: link new 2"); ! 218: x (unlink (fn2) < 0, "compress: remove tmp 2"); ! 219: x (unlink (on3) < 0, "compress: remove old 3"); ! 220: x (link (fn3, on3) < 0, "compress: link new 3"); ! 221: x (unlink (fn3) < 0, "compress: remove tmp 3"); ! 222: ! 223: opennf (io, (char *) NULL); /* relink to new one */ ! 224: ! 225: getdscr (io, &io -> descr); /* get new descr */ ! 226: ! 227: if (lockflag) ! 228: unlocknf (io, DSCRLOCK); /* release the locks */ ! 229: unlocknf (io, TXTLOCK); /* always text lock */ ! 230: #ifdef notdef ! 231: unlink (txtfn); ! 232: #endif ! 233: *numnotes = nnotes; /* fill in callers values */ ! 234: *numresps = nresps; ! 235: umask (old_umask); /* restore */ ! 236: return 0; /* return ok */ ! 237: } ! 238: ! 239: #ifdef FIXTIMES ! 240: static fixtime (when) ! 241: struct when_f *when; ! 242: { ! 243: struct when_f built; ! 244: ! 245: if (when -> w_gmttime == 0) ! 246: return; /* already ok */ ! 247: if (when -> w_gmttime < 0) ! 248: { ! 249: when -> w_gmttime = 0; ! 250: return; ! 251: } ! 252: maketime (&built, when -> w_gmttime); ! 253: if (built.w_year != when -> w_year || ! 254: built.w_month != when -> w_month || ! 255: built.w_day != when -> w_day || ! 256: built.w_hours != when -> w_hours || ! 257: built.w_mins != when -> w_mins) ! 258: when -> w_gmttime = 0; /* zero it */ ! 259: } ! 260: #endif FIXTIMES
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.