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