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

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