1 | /* |
---|
2 | * $XConsortium: tocutil.c,v 2.57 91/07/31 01:10:23 keith Exp $ |
---|
3 | * |
---|
4 | * |
---|
5 | * COPYRIGHT 1987, 1989 |
---|
6 | * DIGITAL EQUIPMENT CORPORATION |
---|
7 | * MAYNARD, MASSACHUSETTS |
---|
8 | * ALL RIGHTS RESERVED. |
---|
9 | * |
---|
10 | * THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE AND |
---|
11 | * SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT CORPORATION. |
---|
12 | * DIGITAL MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THIS SOFTWARE FOR |
---|
13 | * ANY PURPOSE. IT IS SUPPLIED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY. |
---|
14 | * |
---|
15 | * IF THE SOFTWARE IS MODIFIED IN A MANNER CREATING DERIVATIVE COPYRIGHT |
---|
16 | * RIGHTS, APPROPRIATE LEGENDS MAY BE PLACED ON THE DERIVATIVE WORK IN |
---|
17 | * ADDITION TO THAT SET FORTH ABOVE. |
---|
18 | * |
---|
19 | * Permission to use, copy, modify, and distribute this software and its |
---|
20 | * documentation for any purpose and without fee is hereby granted, provided |
---|
21 | * that the above copyright notice appear in all copies and that both that |
---|
22 | * copyright notice and this permission notice appear in supporting |
---|
23 | * documentation, and that the name of Digital Equipment Corporation not be |
---|
24 | * used in advertising or publicity pertaining to distribution of the software |
---|
25 | * without specific, written prior permission. |
---|
26 | */ |
---|
27 | |
---|
28 | /* tocutil.c -- internal routines for toc stuff. */ |
---|
29 | |
---|
30 | #include "xmh.h" |
---|
31 | #include "toc.h" |
---|
32 | #include "tocutil.h" |
---|
33 | #include "tocintrnl.h" |
---|
34 | |
---|
35 | #ifdef X_NOT_POSIX |
---|
36 | extern long lseek(); |
---|
37 | #endif |
---|
38 | |
---|
39 | Toc TUMalloc() |
---|
40 | { |
---|
41 | Toc toc; |
---|
42 | toc = XtNew(TocRec); |
---|
43 | bzero((char *)toc, (int) sizeof(TocRec)); |
---|
44 | toc->msgs = (Msg *) NULL; |
---|
45 | toc->seqlist = (Sequence *) NULL; |
---|
46 | toc->validity = unknown; |
---|
47 | return toc; |
---|
48 | } |
---|
49 | |
---|
50 | |
---|
51 | /* Returns TRUE if the scan file for the given toc is out of date. */ |
---|
52 | |
---|
53 | int TUScanFileOutOfDate(toc) |
---|
54 | Toc toc; |
---|
55 | { |
---|
56 | return LastModifyDate(toc->path) > toc->lastreaddate; |
---|
57 | } |
---|
58 | |
---|
59 | |
---|
60 | /* Make sure the sequence menu entries correspond exactly to the sequences |
---|
61 | * for this toc. |
---|
62 | */ |
---|
63 | |
---|
64 | void TUCheckSequenceMenu(toc) |
---|
65 | Toc toc; |
---|
66 | { |
---|
67 | Scrn scrn; |
---|
68 | register int i, n; |
---|
69 | Arg query_args[2]; |
---|
70 | char *name; |
---|
71 | int j, numChildren; |
---|
72 | Widget menu, item; |
---|
73 | Button button; |
---|
74 | WidgetList children; |
---|
75 | |
---|
76 | static XtCallbackRec callbacks[] = { |
---|
77 | { DoSelectSequence, (XtPointer) NULL}, |
---|
78 | { (XtCallbackProc) NULL, (XtPointer) NULL}, |
---|
79 | }; |
---|
80 | static Arg args[] = { |
---|
81 | { XtNcallback, (XtArgVal) callbacks}, |
---|
82 | { XtNleftMargin, (XtArgVal) 18}, |
---|
83 | }; |
---|
84 | |
---|
85 | for (j=0; j < toc->num_scrns; j++) { |
---|
86 | scrn = toc->scrn[j]; |
---|
87 | |
---|
88 | /* Find the sequence menu and the number of entries in it. */ |
---|
89 | |
---|
90 | name = MenuBoxButtons[XMH_SEQUENCE].button_name; |
---|
91 | button = BBoxFindButtonNamed(scrn->mainbuttons, name); |
---|
92 | menu = BBoxMenuOfButton(button); |
---|
93 | XtSetArg(query_args[0], XtNnumChildren, &numChildren); |
---|
94 | XtSetArg(query_args[1], XtNchildren, &children); |
---|
95 | XtGetValues(menu, query_args, (Cardinal) 2); |
---|
96 | n = MenuBoxButtons[XMH_SEQUENCE].num_entries; |
---|
97 | if (strcmp(XtName(children[0]), "menuLabel") == 0) |
---|
98 | n++; |
---|
99 | |
---|
100 | /* Erase the current check mark. */ |
---|
101 | |
---|
102 | for (i=(n-1); i < numChildren; i++) |
---|
103 | ToggleMenuItem(children[i], False); |
---|
104 | |
---|
105 | /* Delete any entries which should be deleted. */ |
---|
106 | |
---|
107 | for (i=n; i < numChildren; i++) |
---|
108 | if (! TocGetSeqNamed(toc, XtName(children[i]))) |
---|
109 | XtDestroyWidget(children[i]); |
---|
110 | |
---|
111 | /* Create any entries which should be created. */ |
---|
112 | |
---|
113 | callbacks[0].closure = (XtPointer) scrn; |
---|
114 | for (i=1; i < toc->numsequences; i++) |
---|
115 | if (! XtNameToWidget(menu, toc->seqlist[i]->name)) |
---|
116 | XtCreateManagedWidget(toc->seqlist[i]->name, smeBSBObjectClass, |
---|
117 | menu, args, XtNumber(args)); |
---|
118 | |
---|
119 | /* Set the check mark. */ |
---|
120 | |
---|
121 | name = toc->viewedseq->name; |
---|
122 | if ((item = XtNameToWidget(menu, name)) != NULL) |
---|
123 | ToggleMenuItem(item, True); |
---|
124 | } |
---|
125 | TocSetSelectedSequence(toc, toc->viewedseq); |
---|
126 | } |
---|
127 | |
---|
128 | |
---|
129 | void TUScanFileForToc(toc) |
---|
130 | Toc toc; |
---|
131 | { |
---|
132 | Scrn scrn; |
---|
133 | char **argv, str[100]; |
---|
134 | if (toc) { |
---|
135 | TUGetFullFolderInfo(toc); |
---|
136 | if (toc->num_scrns) scrn = toc->scrn[0]; |
---|
137 | else scrn = scrnList[0]; |
---|
138 | |
---|
139 | (void) sprintf(str, "Rescanning %s", toc->foldername); |
---|
140 | ChangeLabel(scrn->toclabel, str); |
---|
141 | |
---|
142 | argv = MakeArgv(5); |
---|
143 | argv[0] = "scan"; |
---|
144 | argv[1] = TocMakeFolderName(toc); |
---|
145 | argv[2] = "-width"; |
---|
146 | (void) sprintf(str, "%d", app_resources.toc_width); |
---|
147 | argv[3] = str; |
---|
148 | argv[4] = "-noheader"; |
---|
149 | DoCommand(argv, (char *) NULL, toc->scanfile); |
---|
150 | XtFree(argv[1]); |
---|
151 | XtFree((char *) argv); |
---|
152 | |
---|
153 | toc->needslabelupdate = True; |
---|
154 | toc->validity = valid; |
---|
155 | toc->curmsg = NULL; /* Get cur msg somehow! %%% */ |
---|
156 | } |
---|
157 | } |
---|
158 | |
---|
159 | |
---|
160 | |
---|
161 | int TUGetMsgPosition(toc, msg) |
---|
162 | Toc toc; |
---|
163 | Msg msg; |
---|
164 | { |
---|
165 | int msgid, h, l, m; |
---|
166 | char str[100]; |
---|
167 | static Boolean ordered = True; |
---|
168 | msgid = msg->msgid; |
---|
169 | if (ordered) { |
---|
170 | l = 0; |
---|
171 | h = toc->nummsgs - 1; |
---|
172 | while (l < h - 1) { |
---|
173 | m = (l + h) / 2; |
---|
174 | if (toc->msgs[m]->msgid > msgid) |
---|
175 | h = m; |
---|
176 | else |
---|
177 | l = m; |
---|
178 | } |
---|
179 | if (toc->msgs[l] == msg) return l; |
---|
180 | if (toc->msgs[h] == msg) return h; |
---|
181 | } |
---|
182 | ordered = False; |
---|
183 | for (l = 0; l < toc->nummsgs; l++) { |
---|
184 | if (msgid == toc->msgs[l]->msgid) return l; |
---|
185 | } |
---|
186 | (void) sprintf(str, |
---|
187 | "TUGetMsgPosition search failed! hi=%d, lo=%d, msgid=%d", |
---|
188 | h, l, msgid); |
---|
189 | Punt(str); |
---|
190 | return 0; /* Keep lint happy. */ |
---|
191 | } |
---|
192 | |
---|
193 | |
---|
194 | void TUResetTocLabel(scrn) |
---|
195 | Scrn scrn; |
---|
196 | { |
---|
197 | char str[500]; |
---|
198 | Toc toc; |
---|
199 | if (scrn) { |
---|
200 | toc = scrn->toc; |
---|
201 | if (toc == NULL) |
---|
202 | (void) strcpy(str, " "); |
---|
203 | else { |
---|
204 | if (toc->stopupdate) { |
---|
205 | toc->needslabelupdate = TRUE; |
---|
206 | return; |
---|
207 | } |
---|
208 | (void) sprintf(str, "%s:%s", toc->foldername, |
---|
209 | toc->viewedseq->name); |
---|
210 | toc->needslabelupdate = FALSE; |
---|
211 | } |
---|
212 | ChangeLabel((Widget) scrn->toclabel, str); |
---|
213 | } |
---|
214 | } |
---|
215 | |
---|
216 | |
---|
217 | /* A major toc change has occured; redisplay it. (This also should work even |
---|
218 | if we now have a new source to display stuff from.) */ |
---|
219 | |
---|
220 | void TURedisplayToc(scrn) |
---|
221 | Scrn scrn; |
---|
222 | { |
---|
223 | Toc toc; |
---|
224 | Widget source; |
---|
225 | if (scrn != NULL && scrn->tocwidget != NULL) { |
---|
226 | toc = scrn->toc; |
---|
227 | if (toc) { |
---|
228 | if (toc->stopupdate) { |
---|
229 | toc->needsrepaint = TRUE; |
---|
230 | return; |
---|
231 | } |
---|
232 | XawTextDisableRedisplay(scrn->tocwidget); |
---|
233 | source = XawTextGetSource(scrn->tocwidget); |
---|
234 | if (toc->force_reset || source != toc->source) { |
---|
235 | XawTextSetSource(scrn->tocwidget, toc->source, |
---|
236 | (XawTextPosition) 0); |
---|
237 | toc->force_reset = False; /* %%% temporary */ |
---|
238 | } |
---|
239 | TocSetCurMsg(toc, TocGetCurMsg(toc)); |
---|
240 | XawTextEnableRedisplay(scrn->tocwidget); |
---|
241 | TUCheckSequenceMenu(toc); |
---|
242 | toc->needsrepaint = FALSE; |
---|
243 | } else { |
---|
244 | XawTextSetSource(scrn->tocwidget, PNullSource, (XawTextPosition) 0); |
---|
245 | } |
---|
246 | } |
---|
247 | } |
---|
248 | |
---|
249 | |
---|
250 | void TULoadSeqLists(toc) |
---|
251 | Toc toc; |
---|
252 | { |
---|
253 | Sequence seq; |
---|
254 | FILEPTR fid; |
---|
255 | char str[500], *ptr, *ptr2, viewed[500], selected[500]; |
---|
256 | int i; |
---|
257 | if (toc->viewedseq) (void) strcpy(viewed, toc->viewedseq->name); |
---|
258 | else *viewed = 0; |
---|
259 | if (toc->selectseq) (void) strcpy(selected, toc->selectseq->name); |
---|
260 | else *selected = 0; |
---|
261 | for (i = 0; i < toc->numsequences; i++) { |
---|
262 | seq = toc->seqlist[i]; |
---|
263 | XtFree((char *) seq->name); |
---|
264 | if (seq->mlist) FreeMsgList(seq->mlist); |
---|
265 | XtFree((char *)seq); |
---|
266 | } |
---|
267 | toc->numsequences = 1; |
---|
268 | toc->seqlist = (Sequence *) XtRealloc((char *) toc->seqlist, |
---|
269 | (Cardinal) sizeof(Sequence)); |
---|
270 | seq = toc->seqlist[0] = XtNew(SequenceRec); |
---|
271 | seq->name = XtNewString("all"); |
---|
272 | seq->mlist = NULL; |
---|
273 | toc->viewedseq = seq; |
---|
274 | toc->selectseq = seq; |
---|
275 | (void) sprintf(str, "%s/.mh_sequences", toc->path); |
---|
276 | fid = myfopen(str, "r"); |
---|
277 | if (fid) { |
---|
278 | while (ptr = ReadLine(fid)) { |
---|
279 | ptr2 = index(ptr, ':'); |
---|
280 | if (ptr2) { |
---|
281 | *ptr2 = 0; |
---|
282 | if (strcmp(ptr, "all") != 0 && |
---|
283 | strcmp(ptr, "cur") != 0 && |
---|
284 | strcmp(ptr, "unseen") != 0) { |
---|
285 | toc->numsequences++; |
---|
286 | toc->seqlist = (Sequence *) |
---|
287 | XtRealloc((char *) toc->seqlist, (Cardinal) |
---|
288 | toc->numsequences * sizeof(Sequence)); |
---|
289 | seq = toc->seqlist[toc->numsequences - 1] = |
---|
290 | XtNew(SequenceRec); |
---|
291 | seq->name = XtNewString(ptr); |
---|
292 | seq->mlist = StringToMsgList(toc, ptr2 + 1); |
---|
293 | if (strcmp(seq->name, viewed) == 0) { |
---|
294 | toc->viewedseq = seq; |
---|
295 | *viewed = 0; |
---|
296 | } |
---|
297 | if (strcmp(seq->name, selected) == 0) { |
---|
298 | toc->selectseq = seq; |
---|
299 | *selected = 0; |
---|
300 | } |
---|
301 | } |
---|
302 | } |
---|
303 | } |
---|
304 | (void) myfclose(fid); |
---|
305 | } |
---|
306 | } |
---|
307 | |
---|
308 | |
---|
309 | |
---|
310 | /* Refigure what messages are visible. */ |
---|
311 | |
---|
312 | void TURefigureWhatsVisible(toc) |
---|
313 | Toc toc; |
---|
314 | { |
---|
315 | MsgList mlist; |
---|
316 | Msg msg, oldcurmsg; |
---|
317 | int i, w, changed, newval, msgid; |
---|
318 | Sequence seq = toc->viewedseq; |
---|
319 | mlist = seq->mlist; |
---|
320 | oldcurmsg = toc->curmsg; |
---|
321 | TocSetCurMsg(toc, (Msg)NULL); |
---|
322 | w = 0; |
---|
323 | changed = FALSE; |
---|
324 | |
---|
325 | for (i = 0; i < toc->nummsgs; i++) { |
---|
326 | msg = toc->msgs[i]; |
---|
327 | msgid = msg->msgid; |
---|
328 | while (mlist && mlist->msglist[w] && mlist->msglist[w]->msgid < msgid) |
---|
329 | w++; |
---|
330 | newval = (!mlist |
---|
331 | || (mlist->msglist[w] && mlist->msglist[w]->msgid == msgid)); |
---|
332 | if (newval != msg->visible) { |
---|
333 | changed = TRUE; |
---|
334 | msg->visible = newval; |
---|
335 | } |
---|
336 | } |
---|
337 | if (changed) { |
---|
338 | TURefigureTocPositions(toc); |
---|
339 | if (oldcurmsg) { |
---|
340 | if (!oldcurmsg->visible) { |
---|
341 | toc->curmsg = TocMsgAfter(toc, oldcurmsg); |
---|
342 | if (toc->curmsg == NULL) |
---|
343 | toc->curmsg = TocMsgBefore(toc, oldcurmsg); |
---|
344 | } else toc->curmsg = oldcurmsg; |
---|
345 | } |
---|
346 | for (i=0 ; i<toc->num_scrns ; i++) |
---|
347 | TURedisplayToc(toc->scrn[i]); |
---|
348 | } else TocSetCurMsg(toc, oldcurmsg); |
---|
349 | for (i=0 ; i<toc->num_scrns ; i++) |
---|
350 | TUResetTocLabel(toc->scrn[i]); |
---|
351 | } |
---|
352 | |
---|
353 | |
---|
354 | /* (Re)load the toc from the scanfile. If reloading, this makes efforts to |
---|
355 | keep the fates of msgs, and to keep msgs that are being edited. Note that |
---|
356 | this routine must know of all places that msg ptrs are stored; it expects |
---|
357 | them to be kept only in tocs, in scrns, and in msg sequences. */ |
---|
358 | |
---|
359 | #define SeemsIdentical(msg1, msg2) ((msg1)->msgid == (msg2)->msgid && \ |
---|
360 | ((msg1)->temporary || (msg2)->temporary ||\ |
---|
361 | strcmp((msg1)->buf, (msg2)->buf) == 0)) |
---|
362 | |
---|
363 | void TULoadTocFile(toc) |
---|
364 | Toc toc; |
---|
365 | { |
---|
366 | int maxmsgs, l, orignummsgs, i, j, origcurmsgid; |
---|
367 | FILEPTR fid; |
---|
368 | XawTextPosition position; |
---|
369 | char *ptr; |
---|
370 | Msg msg, curmsg; |
---|
371 | Msg *origmsgs; |
---|
372 | int bufsiz = app_resources.toc_width + 1; |
---|
373 | static char *buf; |
---|
374 | |
---|
375 | if (!buf) |
---|
376 | buf = XtMalloc((Cardinal) bufsiz); |
---|
377 | TocStopUpdate(toc); |
---|
378 | toc->lastreaddate = LastModifyDate(toc->scanfile); |
---|
379 | if (toc->curmsg) { |
---|
380 | origcurmsgid = toc->curmsg->msgid; |
---|
381 | TocSetCurMsg(toc, (Msg)NULL); |
---|
382 | } else origcurmsgid = 0; /* The "default" current msg; 0 means none */ |
---|
383 | fid = FOpenAndCheck(toc->scanfile, "r"); |
---|
384 | maxmsgs = orignummsgs = toc->nummsgs; |
---|
385 | if (maxmsgs == 0) maxmsgs = 100; |
---|
386 | toc->nummsgs = 0; |
---|
387 | origmsgs = toc->msgs; |
---|
388 | toc->msgs = (Msg *) XtMalloc((Cardinal) maxmsgs * sizeof(Msg)); |
---|
389 | position = 0; |
---|
390 | i = 0; |
---|
391 | curmsg = NULL; |
---|
392 | while (ptr = fgets(buf, bufsiz, fid)) { |
---|
393 | toc->msgs[toc->nummsgs++] = msg = XtNew(MsgRec); |
---|
394 | bzero((char *) msg, sizeof(MsgRec)); |
---|
395 | msg->toc = toc; |
---|
396 | msg->position = position; |
---|
397 | msg->length = l = strlen(ptr); |
---|
398 | position += l; |
---|
399 | if (l == app_resources.toc_width && buf[bufsiz-2] != '\n') { |
---|
400 | buf[bufsiz-2] = '\n'; |
---|
401 | msg->buf = strcpy(XtMalloc((Cardinal) ++l), ptr); |
---|
402 | msg->msgid = atoi(ptr); |
---|
403 | do |
---|
404 | ptr = fgets(buf, bufsiz, fid); |
---|
405 | while (ptr && strlen(ptr) == app_resources.toc_width |
---|
406 | && buf[bufsiz-2] != '\n'); |
---|
407 | } else { |
---|
408 | msg->buf = strcpy(XtMalloc((Cardinal) ++l), ptr); |
---|
409 | msg->msgid = atoi(ptr); |
---|
410 | } |
---|
411 | if (msg->msgid == origcurmsgid) |
---|
412 | curmsg = msg; |
---|
413 | msg->buf[MARKPOS] = ' '; |
---|
414 | msg->changed = FALSE; |
---|
415 | msg->fate = Fignore; |
---|
416 | msg->desttoc = NULL; |
---|
417 | msg->visible = TRUE; |
---|
418 | if (toc->nummsgs >= maxmsgs) { |
---|
419 | maxmsgs += 100; |
---|
420 | toc->msgs = (Msg *) XtRealloc((char *) toc->msgs, |
---|
421 | (Cardinal) maxmsgs * sizeof(Msg)); |
---|
422 | } |
---|
423 | while (i < orignummsgs && origmsgs[i]->msgid < msg->msgid) i++; |
---|
424 | if (i < orignummsgs) { |
---|
425 | origmsgs[i]->buf[MARKPOS] = ' '; |
---|
426 | if (SeemsIdentical(origmsgs[i], msg)) |
---|
427 | MsgSetFate(msg, origmsgs[i]->fate, origmsgs[i]->desttoc); |
---|
428 | } |
---|
429 | } |
---|
430 | toc->length = toc->origlength = toc->lastPos = position; |
---|
431 | toc->msgs = (Msg *) XtRealloc((char *) toc->msgs, |
---|
432 | (Cardinal) toc->nummsgs * sizeof(Msg)); |
---|
433 | (void) myfclose(fid); |
---|
434 | if ( (toc->source == NULL) && ( toc->num_scrns > 0 ) ) { |
---|
435 | Arg args[1]; |
---|
436 | |
---|
437 | XtSetArg(args[0], XtNtoc, toc); |
---|
438 | toc->source = XtCreateWidget("tocSource", tocSourceWidgetClass, |
---|
439 | toc->scrn[0]->tocwidget, |
---|
440 | args, (Cardinal) 1); |
---|
441 | } |
---|
442 | for (i=0 ; i<numScrns ; i++) { |
---|
443 | msg = scrnList[i]->msg; |
---|
444 | if (msg && msg->toc == toc) { |
---|
445 | for (j=0 ; j<toc->nummsgs ; j++) { |
---|
446 | if (SeemsIdentical(toc->msgs[j], msg)) { |
---|
447 | msg->position = toc->msgs[j]->position; |
---|
448 | msg->visible = TRUE; |
---|
449 | ptr = toc->msgs[j]->buf; |
---|
450 | l = toc->msgs[j]->length; |
---|
451 | *(toc->msgs[j]) = *msg; |
---|
452 | toc->msgs[j]->buf = ptr; |
---|
453 | toc->msgs[j]->length = l; |
---|
454 | scrnList[i]->msg = toc->msgs[j]; |
---|
455 | break; |
---|
456 | } |
---|
457 | } |
---|
458 | if (j >= toc->nummsgs) { |
---|
459 | msg->temporary = FALSE; /* Don't try to auto-delete msg. */ |
---|
460 | MsgSetScrnForce(msg, (Scrn) NULL); |
---|
461 | } |
---|
462 | } |
---|
463 | } |
---|
464 | for (i=0 ; i<orignummsgs ; i++) |
---|
465 | MsgFree(origmsgs[i]); |
---|
466 | XtFree((char *)origmsgs); |
---|
467 | TocSetCurMsg(toc, curmsg); |
---|
468 | TULoadSeqLists(toc); |
---|
469 | TocStartUpdate(toc); |
---|
470 | } |
---|
471 | |
---|
472 | |
---|
473 | void TUSaveTocFile(toc) |
---|
474 | Toc toc; |
---|
475 | { |
---|
476 | Msg msg; |
---|
477 | int fid; |
---|
478 | int i; |
---|
479 | XawTextPosition position; |
---|
480 | char c; |
---|
481 | if (toc->stopupdate) { |
---|
482 | toc->needscachesave = TRUE; |
---|
483 | return; |
---|
484 | } |
---|
485 | fid = -1; |
---|
486 | position = 0; |
---|
487 | for (i = 0; i < toc->nummsgs; i++) { |
---|
488 | msg = toc->msgs[i]; |
---|
489 | if (fid < 0 && msg->changed) { |
---|
490 | fid = myopen(toc->scanfile, O_RDWR, 0666); |
---|
491 | (void) lseek(fid, (long)position, 0); |
---|
492 | } |
---|
493 | if (fid >= 0) { |
---|
494 | c = msg->buf[MARKPOS]; |
---|
495 | msg->buf[MARKPOS] = ' '; |
---|
496 | (void) write(fid, msg->buf, msg->length); |
---|
497 | msg->buf[MARKPOS] = c; |
---|
498 | } |
---|
499 | position += msg->length; |
---|
500 | } |
---|
501 | if (fid < 0 && toc->length != toc->origlength) |
---|
502 | fid = myopen(toc->scanfile, O_RDWR, 0666); |
---|
503 | if (fid >= 0) { |
---|
504 | #if defined(SYSV) && (defined(SYSV386) || defined(MOTOROLA)) |
---|
505 | (void) ftruncate_emu(fid, toc->length, toc->scanfile); |
---|
506 | #else |
---|
507 | (void) ftruncate(fid, toc->length); |
---|
508 | (void) myclose(fid); |
---|
509 | #endif |
---|
510 | toc->origlength = toc->length; |
---|
511 | } |
---|
512 | toc->needscachesave = FALSE; |
---|
513 | toc->lastreaddate = LastModifyDate(toc->scanfile); |
---|
514 | } |
---|
515 | |
---|
516 | |
---|
517 | void TUEnsureScanIsValidAndOpen(toc) |
---|
518 | Toc toc; |
---|
519 | { |
---|
520 | if (toc) { |
---|
521 | TUGetFullFolderInfo(toc); |
---|
522 | if (TUScanFileOutOfDate(toc)) { |
---|
523 | if (toc->source) { |
---|
524 | XtFree((char *) toc->source); |
---|
525 | toc->source = NULL; |
---|
526 | } |
---|
527 | TUScanFileForToc(toc); |
---|
528 | } |
---|
529 | if (toc->source == NULL) |
---|
530 | TULoadTocFile(toc); |
---|
531 | toc->validity = valid; |
---|
532 | } |
---|
533 | } |
---|
534 | |
---|
535 | |
---|
536 | |
---|
537 | /* Refigure all the positions, based on which lines are visible. */ |
---|
538 | |
---|
539 | void TURefigureTocPositions(toc) |
---|
540 | Toc toc; |
---|
541 | { |
---|
542 | int i; |
---|
543 | Msg msg; |
---|
544 | XawTextPosition position, length; |
---|
545 | position = length = 0; |
---|
546 | for (i=0; i<toc->nummsgs ; i++) { |
---|
547 | msg = toc->msgs[i]; |
---|
548 | msg->position = position; |
---|
549 | if (msg->visible) position += msg->length; |
---|
550 | length += msg->length; |
---|
551 | } |
---|
552 | toc->lastPos = position; |
---|
553 | toc->length = length; |
---|
554 | } |
---|
555 | |
---|
556 | |
---|
557 | |
---|
558 | /* Make sure we've loaded ALL the folder info for this toc, including its |
---|
559 | path and sequence lists. */ |
---|
560 | |
---|
561 | void TUGetFullFolderInfo(toc) |
---|
562 | Toc toc; |
---|
563 | { |
---|
564 | char str[500]; |
---|
565 | if (! toc->scanfile) { |
---|
566 | if (! toc->path) { |
---|
567 | /* usually preset by TocFolderExists */ |
---|
568 | (void) sprintf(str, "%s/%s", app_resources.mail_path, |
---|
569 | toc->foldername); |
---|
570 | toc->path = XtNewString(str); |
---|
571 | } |
---|
572 | (void) sprintf(str, "%s/.xmhcache", toc->path); |
---|
573 | toc->scanfile = XtNewString(str); |
---|
574 | toc->lastreaddate = LastModifyDate(toc->scanfile); |
---|
575 | if (TUScanFileOutOfDate(toc)) |
---|
576 | toc->validity = invalid; |
---|
577 | else { |
---|
578 | toc->validity = valid; |
---|
579 | TULoadTocFile(toc); |
---|
580 | } |
---|
581 | } |
---|
582 | } |
---|
583 | |
---|
584 | /* Append a message to the end of the toc. It has the given scan line. This |
---|
585 | routine will figure out the message number, and change the scan line |
---|
586 | accordingly. */ |
---|
587 | |
---|
588 | Msg TUAppendToc(toc, ptr) |
---|
589 | Toc toc; |
---|
590 | char *ptr; |
---|
591 | { |
---|
592 | Msg msg; |
---|
593 | int msgid, i; |
---|
594 | |
---|
595 | TUGetFullFolderInfo(toc); |
---|
596 | if (toc->validity != valid) |
---|
597 | return NULL; |
---|
598 | |
---|
599 | if (toc->nummsgs > 0) |
---|
600 | msgid = toc->msgs[toc->nummsgs - 1]->msgid + 1; |
---|
601 | else |
---|
602 | msgid = 1; |
---|
603 | (toc->nummsgs)++; |
---|
604 | toc->msgs = (Msg *) XtRealloc((char *) toc->msgs, |
---|
605 | (Cardinal) toc->nummsgs * sizeof(Msg)); |
---|
606 | toc->msgs[toc->nummsgs - 1] = msg = XtNew(MsgRec); |
---|
607 | bzero((char *) msg, (int) sizeof(MsgRec)); |
---|
608 | msg->toc = toc; |
---|
609 | msg->buf = XtNewString(ptr); |
---|
610 | if (msgid >= 10000) |
---|
611 | msgid %= 10000; |
---|
612 | (void)sprintf(msg->buf, "%4d", msgid); |
---|
613 | msg->buf[MARKPOS] = ' '; |
---|
614 | msg->msgid = msgid; |
---|
615 | msg->position = toc->lastPos; |
---|
616 | msg->length = strlen(ptr); |
---|
617 | msg->changed = TRUE; |
---|
618 | msg->fate = Fignore; |
---|
619 | msg->desttoc = NULL; |
---|
620 | if (toc->viewedseq == toc->seqlist[0]) { |
---|
621 | msg->visible = TRUE; |
---|
622 | toc->lastPos += msg->length; |
---|
623 | } |
---|
624 | else |
---|
625 | msg->visible = FALSE; |
---|
626 | toc->length += msg->length; |
---|
627 | if ( (msg->visible) && (toc->source != NULL) ) |
---|
628 | TSourceInvalid(toc, msg->position, msg->length); |
---|
629 | TUSaveTocFile(toc); |
---|
630 | return msg; |
---|
631 | } |
---|