source: trunk/athena/bin/xdsc/cache.c @ 7204

Revision 7204, 12.6 KB checked in by miki, 31 years ago (diff)
include sys/fcntl.h for SOLARIS
Line 
1/*
2Copyright 1991 by the Massachusetts Institute of Technology
3
4Permission to use, copy, modify, and distribute this
5software and its documentation for any purpose and without
6fee is hereby granted, provided that the above copyright
7notice appear in all copies and that both that copyright
8notice and this permission notice appear in supporting
9documentation, and that the name of M.I.T. not be used in
10advertising or publicity pertaining to distribution of the
11software without specific, written prior permission.
12M.I.T. makes no representations about the suitability of
13this software for any purpose.  It is provided "as is"
14without express or implied warranty.
15*/
16
17/*
18**  cache.c:  manage the files in /tmp
19**
20**  Ensure we have the ones we need, and get rid of the ones no
21/*
22**  cache.c:  manage the files in /tmp
23**
24**  Ensure we have the ones we need, and get rid of the ones no
25**  longer in use.
26**
27*/
28
29#include        <stdio.h>
30#include        <X11/Intrinsic.h>
31#include        <X11/StringDefs.h>
32#include        <X11/IntrinsicP.h>
33#include        <X11/CoreP.h>
34#include        <X11/Xaw/Command.h>
35#include        <X11/Xaw/AsciiText.h>
36#include        <X11/Xaw/TextP.h>
37#ifdef SOLARIS
38#include        <sys/fcntl.h>
39#endif
40#include        "xdsc.h"
41
42#define         NUM_CACHED_FILES        5
43#define         CACHE_DIR_NEXT          1
44#define         CACHE_DIR_PREV          2
45#define         CACHE_DIR_NREF          3
46#define         CACHE_DIR_PREF          4
47
48
49static char rcsid[] = "";
50
51extern char     *RunCommand();
52extern EntryRec         toplevelbuttons[2][MAX_BUTTONS];
53extern TextWidget       bottextW, toptextW;
54extern Boolean  debug;
55extern char     filebase[];
56extern int      topscreen;
57extern int      edscversion;
58extern Widget   topW;
59extern void     TopSelect();
60extern Boolean  nocache;
61extern char     axis[];
62
63int     next=0, prev=0;
64static int      nref = 0, pref=0, fref=0, lref=0;
65static int      first=0, last=0;
66static int      highestseen;
67static int      current;
68
69static int      cache[NUM_CACHED_FILES] = {-1,-1,-1,-1,-1};
70static char     currentmtglong[LONGNAMELEN] = "";
71static char     currentmtgshort[SHORTNAMELEN] = "";
72
73char    *GetTransactionFile();
74
75char *
76CurrentMtg(which)
77int     which;
78{
79        if (which == 0)
80                return (currentmtglong);
81        else
82                return (currentmtgshort);
83}
84
85int
86SaveMeetingNames(newlong, newshort)
87char    *newlong;
88char    *newshort;
89{
90        char    oldlong[LONGNAMELEN];
91        char    oldshort[SHORTNAMELEN];
92        if (*currentmtglong) {
93                MarkLastRead();
94                DeleteOldTransactions();
95        }
96
97        if (*newlong) {
98                strcpy (oldlong, currentmtglong);
99                strcpy (currentmtglong, newlong);
100                strcpy (oldshort, currentmtgshort);
101                strcpy (currentmtgshort, newshort);
102                if (SetUpTransactionNumbers() == -1) {
103                        strcpy (currentmtglong, oldlong);
104                        strcpy (currentmtgshort, oldshort);
105                        return (-1);
106                }
107        }
108
109        else {
110                *currentmtglong = '\0';
111                *currentmtgshort = '\0';
112        }
113        return (0);
114}
115
116/*
117**  GoToTransaction updates the data structures and cache so that
118**  we are in a particular transaction.
119**
120**  if 'update' is True (it usually is) we put the contents of the
121**  transaction into the lower text widget.
122*/
123
124GoToTransaction (num, update)
125int     num;
126Boolean update;
127{
128        static char     command[LONGNAMELEN + 25];
129        char            *filename;
130        char            *returndata;
131        int             transactionnum;
132
133        if (!num) return;
134
135        if (num < 0)
136                transactionnum = TransactionNum(num);
137        else
138                transactionnum = num;
139
140        if (update && topscreen == LISTTRNS);
141                UpdateHighlightedTransaction(transactionnum);
142
143        sprintf (command, "Reading %s [%d-%d], #%d...",
144                                currentmtglong, first, last, transactionnum);
145        PutUpStatusMessage(command);
146
147        if ((filename = GetTransactionFile(num)) == (char *) -1)
148                return (-1);
149
150        if (update)
151                FileIntoWidget(filename, bottextW);
152
153        sprintf (command, "(gti %d %s)\n", transactionnum, currentmtglong);
154        returndata = RunCommand (command, NULL, NULL, True);
155
156        if ((int) returndata <= 0) goto DONE;
157
158        sscanf (        returndata,
159                        "%*c%d%d%d%d%d%d%d%*s",
160                        &current, &prev, &next, &pref,
161                        &nref, &fref, &lref);
162
163        myfree(returndata);
164        CheckButtonSensitivity(BUTTONS_UPDATE);
165
166        if (!nocache)
167                CacheSurroundingTransactions();
168
169        if ( current >  highestseen)
170                highestseen = current;
171
172        if ( next > last || current > last) {
173                MarkLastRead();
174                (void) SetUpTransactionNumbers();
175        }
176
177        if (highestseen == last && topscreen == MAIN)
178                RemoveLetterC();
179DONE:
180        sprintf (command, "Reading %s [%d-%d], #%d",
181                                currentmtglong, first, last, transactionnum);
182        PutUpStatusMessage(command);
183}
184
185DeleteOldTransactions()
186{
187        char            filename[80];
188        unsigned int    fd;
189
190        DeleteTransactionFile(current);
191        DeleteTransactionFile(prev);
192        DeleteTransactionFile(next);
193        DeleteTransactionFile(pref);
194        DeleteTransactionFile(nref);
195
196        sprintf (filename, "%s-list", filebase);
197        if ((fd = open(filename, O_RDONLY)) != -1) {
198                close (fd);
199                unlink (filename);
200        }
201
202        next=0, prev=0, nref=0;
203        pref=0, fref=0, lref=0;
204        first=0, last=0, current=0;
205}
206
207/*
208** Read in the transactions immedidately before and after the
209** current one.
210*/
211
212CacheSurroundingTransactions()
213{
214
215        int             i;
216
217/*
218** Remove unnecessary files
219*/
220
221        for (i = 0; i < NUM_CACHED_FILES; i++) {
222                if (    cache[i] != next && cache[i] != prev &&
223                        cache[i] != nref && cache[i] != pref &&
224                        cache[i] != current && cache[i] != -1) {
225
226                        DeleteTransactionFile(cache[i]);
227                }
228        }
229
230/*
231** Get the files we need
232*/
233        (void) GetTransactionFile (next);
234        (void) GetTransactionFile (prev);
235        (void) GetTransactionFile (nref);
236        (void) GetTransactionFile (pref);
237        (void) GetTransactionFile (current);
238
239}
240
241/*
242** Remove the file from /tmp and the cache.
243*/
244
245DeleteTransactionFile(num)
246int     num;
247{
248        char    filename[50];
249        int     i;
250
251        sprintf (filename, "%s-%d", filebase, num);
252        unlink (filename);
253
254        for (i = 0; i < NUM_CACHED_FILES; i++)
255                if (cache[i] == num)
256                        cache[i] = -1;
257}
258
259/*
260**  This function behaves differently depending on the version of
261**  edsc we're talking to. 
262**
263**  If edsc is doing the caching, just ask for the transaction and
264**  return the filename.
265**
266**  If we're doing the caching, ask if the file is already in the cache,
267**  and return the filename if it is.  Otherwise, run the
268**  edsc command to fetch it, note it as cached, and return the filename.
269**
270*/
271
272char *
273GetTransactionFile(num)
274int     num;
275{
276        static char     filename[50];
277        char            command[LONGNAMELEN + 25];
278        int             i;
279        char            *retval;
280        int             transactionnum;
281        int             direction;
282
283        if (num == 0)
284                return((char *)-1);
285
286/*
287** have we been passed a symbol instead of a number?
288*/
289
290        if (num < 0)
291                transactionnum = TransactionNum(num);
292        else
293                transactionnum = num;
294
295        if (!nocache)
296                sprintf (filename, "%s-%d", filebase, transactionnum);
297/*
298** See if the file is in our cache.  If so, return its filename;.
299*/
300        if (!nocache) {
301                for (i = 0; i < NUM_CACHED_FILES; i++) {
302                        if (cache[i] == num) {
303                                return (filename);
304                        }
305                }
306        }
307
308/*
309** If file doesn't exist, go get it.
310*/
311        if (nocache) {
312                switch (num) {
313                case NEXT:     
314                        direction = CACHE_DIR_NEXT;
315                        break;
316                case PREV:     
317                        direction = CACHE_DIR_PREV;
318                        break;
319                case NREF:     
320                        direction = CACHE_DIR_NREF;
321                        break;
322                case PREF:     
323                        direction = CACHE_DIR_PREF;
324                        break;
325                default:
326                        direction = 0;
327                        break;
328                }
329
330                sprintf (       command, "(gtfc %d %d %s)\n",
331                                direction, transactionnum, currentmtglong);
332
333                retval = RunCommand (command, NULL, NULL, True);
334                if ((int) retval <= 0)
335                        return((char *)-1);
336                sscanf (retval, "(\"%[^\"]", filename);
337        }
338
339        else {
340                sprintf (       command, "(gtf %s %d %s)\n",
341                                filename, transactionnum, currentmtglong);
342                retval = RunCommand (command, NULL, NULL, True);
343                if ((int) retval <= 0)
344                        return((char *)-1);
345
346                for (i = 0; i < NUM_CACHED_FILES; i++) {
347                        if (cache[i] == -1) {
348                                cache[i] = num;
349                                break;
350                        }
351                }
352        }
353
354        myfree (retval);
355        return (filename);
356}
357
358/*
359** Return the highestseen from mtg.  Also set first, last, and highestseen.
360** Set current to highestseen if it's not already set (ie, we've just
361** entered the meeting)
362**
363** Return -1 if something went wrong.
364*/
365
366int
367SetUpTransactionNumbers()
368{
369
370        char    command[LONGNAMELEN + 25];
371        char    *retval;
372        static int      oldhighestseen = 0;
373
374        sprintf (command, "(gmi %s)\n", currentmtglong);
375
376        retval = RunCommand (command, NULL, NULL, True);
377        if ((int) retval <= 0) return (-1);
378
379        sscanf (retval, "(\"%*[^\"]\" \"%*[^\"]\" \"%*[^\"]\" %d %d %*d %*d \"%*[^\"]\" \"%*[^\"]\" %*d \"%[^\"]\" %d",
380                &first, &last, axis, &highestseen);
381
382        oldhighestseen = highestseen;
383                       
384        if (last == 0 && first == 0) {
385                fprintf (stderr,"xdsc:  Reply out of sync with request!\n");
386                fprintf (stderr,"xdsc:  requested '%s', got '%s'\n",command, retval);
387                PutUpWarning(   "INTERNAL ERROR DETECTED",
388                                "I suggest you quit immediately to avoid\npossible corruption of your .meetings file.", True);
389                myfree(retval);
390                return (-1);
391        }
392        myfree(retval);
393
394        if (highestseen > last) {
395                PutUpWarning(   "WARNING",
396                                "The highest-read transaction in this\nmeeting no longer exists.\nGoing to end of the meeting.", True);
397                highestseen = last;
398        }
399
400        if (debug) {
401                fprintf (stderr, "highestseen message of %s is %d\n",
402                                currentmtglong, highestseen);
403
404                fprintf (stderr, "first is %d, last is %d\n",first, last);
405        }
406
407        GoToTransaction (highestseen, False);
408
409        return (highestseen);
410}
411
412MarkLastRead()
413{
414        static char     command[LONGNAMELEN + 25];
415
416        if (*currentmtglong)  {
417                sprintf (       command,
418                                "(ss %d %s)\n",
419                                highestseen,
420                                currentmtglong);
421                if (edscversion >= 24)
422                        (void) RunCommand (command, NULL, NULL, True);
423                else
424                        (void) RunCommand (command, NULL, NULL, False);
425        }
426
427}
428
429TransactionNum(arg)
430int     arg;
431{
432        switch (arg) {
433                case NEXT:
434                        return(next);
435                case PREV:
436                        return(prev);
437                case NREF:
438                        return(nref);
439                case PREF:
440                        return(pref);
441                case LREF:
442                        return(lref);
443                case FREF:
444                        return(fref);
445                case FIRST:
446                        return(first);
447                case LAST:
448                        return(last);
449                case CURRENT:
450                        return(current);
451                case HIGHESTSEEN:
452                        return(highestseen);
453                default:
454                        fprintf (stderr, "Unknown arg to TransactionNum: %d\n", arg);
455                        return(0);
456        }
457}
458
459MoveToMeeting(which)
460int     which;
461{
462        Arg     args[2];
463        Boolean transactionflag = False;
464/*
465** If we're currently showing transactions, we have to restore the top-level
466** list of meetings.
467*/
468        if (topscreen == LISTTRNS) {
469                XawTextDisableRedisplay(toptextW);
470                TopSelect (NULL, 4 + (1 << 4));
471                transactionflag = True;
472        }
473
474/*
475** HighlightNewItem will eventually call SaveMeetingNames and
476** SetUpTransactionNumbers to get the next, prev, etc. vars set.
477*/
478        if (HighlightNewItem(toptextW, which, True) == 0) {
479
480/*
481** Need to restore transaction list?
482*/
483                if (transactionflag == True) {
484                        TopSelect (NULL, 4 + (0 << 4));
485                        XawTextEnableRedisplay(toptextW);
486                }
487
488/*
489** Clear out bottom text window.
490*/
491                XtSetArg (args[0], XtNstring, "");
492                XtSetArg (args[1], XtNlength, 0);
493                XtSetValues (bottextW, args, 1);
494
495/*
496** If we're at the end of the meeting, make it so the "next" button
497** will show us the last transaction.
498*/
499                if (next == 0)
500                        next = last;
501
502                CheckButtonSensitivity(BUTTONS_ON);
503                return (0);
504        }
505
506        else {
507                return (-1);
508        }
509}
510
511/*
512** Make sure bottom buttons are set appropriately, according to context
513** and mode.
514**
515** Mode = BUTTONS_UPDATE: turn on appropriate buttons, if sensitive = True.
516** Mode = BUTTONS_OFF:  Turn off all buttons.  Set sensitive = False.
517** Mode = BUTTONS_ON:  Turn on appropriate buttons.  Set sensitive = True.
518**
519*/
520CheckButtonSensitivity(mode)
521int mode;
522{
523        static Boolean  sensitive = True;
524        Arg             args[2];
525
526        if (mode == BUTTONS_ON) sensitive = True;
527        if (mode == BUTTONS_OFF) sensitive = False;
528
529        if (next && sensitive) {
530                XtSetArg(args[0], XtNsensitive, True);
531                XtSetArg(args[1], XtNborderWidth, 1);
532        }
533        else {
534                XtSetArg(args[0], XtNsensitive, False);
535                XtSetArg(args[1], XtNborderWidth, 4);
536        }
537        XtSetValues ((toplevelbuttons[1][0]).button, args, 2);
538
539        if (prev && sensitive)
540                XtSetArg(args[0], XtNsensitive, True);
541        else
542                XtSetArg(args[0], XtNsensitive, False);
543        XtSetValues ((toplevelbuttons[1][1]).button, args, 1);
544
545        if (nref && sensitive)
546                XtSetArg(args[0], XtNsensitive, True);
547        else
548                XtSetArg(args[0], XtNsensitive, False);
549        XtSetValues ((toplevelbuttons[1][2]).button, args, 1);
550
551        if (pref && sensitive)
552                XtSetArg(args[0], XtNsensitive, True);
553        else
554                XtSetArg(args[0], XtNsensitive, False);
555        XtSetValues ((toplevelbuttons[1][3]).button, args, 1);
556
557        if (topscreen == LISTTRNS && sensitive)
558                XtSetArg(args[0], XtNsensitive, True);
559        else
560                XtSetArg(args[0], XtNsensitive, False);
561        XtSetValues ((toplevelbuttons[0][5]).button, args, 1);
562
563        if (axis[0] == ' ' && axis[6] == ' ')
564                XtSetArg(args[0], XtNsensitive, False);
565        else
566                XtSetArg(args[0], XtNsensitive, True);
567        XtSetValues ((toplevelbuttons[1][5]).button, args, 1);
568
569        if (axis[0] == ' ')
570                XtSetArg(args[0], XtNsensitive, False);
571        else
572                XtSetArg(args[0], XtNsensitive, True);
573        XtSetValues ((toplevelbuttons[1][5]).nextrec->button, args, 1);
574
575        if (axis[6] == ' ')
576                XtSetArg(args[0], XtNsensitive, False);
577        else
578                XtSetArg(args[0], XtNsensitive, True);
579        XtSetValues ((toplevelbuttons[1][5]).nextrec->nextrec->button, args, 1);
580
581        XtSetArg(args[0], XtNsensitive, False);
582        XtSetValues ((toplevelbuttons[1][6]).nextrec->nextrec->button, args, 1);
583}
Note: See TracBrowser for help on using the repository browser.