pull-prototypes-to-head-20020821
[openafs.git] / src / afsmonitor / afsmon-win.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  */
9
10 /*
11  * Afsmon-win: Curses interface for the Afsmonitor using the gtx library.
12  *
13  *-------------------------------------------------------------------------*/
14
15 #include <afsconfig.h>
16 #include <afs/param.h>
17
18 RCSID("$Header$");
19
20 #include <stdio.h>
21 #include <signal.h>
22 #include <math.h>
23 #include <cmd.h>
24 #ifdef HAVE_STRING_H
25 #include <string.h>
26 #endif
27 #undef IN
28 #include <time.h>
29
30 #include <gtxwindows.h>         /*Generic window package*/
31 #include <gtxobjects.h>         /*Object definitions*/
32 #if 0
33 #include <gtxtextcb.h>          /*Text object circular buffer interface*/
34 #include <gtxtextobj.h>         /*Text object interface*/
35 #endif
36 #include <gtxlightobj.h>        /*Light object interface*/
37 #include <gtxcurseswin.h>       /*Curses window package*/
38 #include <gtxdumbwin.h>         /*Dumb terminal window package*/
39 #include <gtxX11win.h>          /*X11 window package*/
40 #include <gtxframe.h>           /*Frame package*/
41
42 #include <afs/xstat_fs.h>  
43 #include <afs/xstat_cm.h> 
44
45
46 #include "afsmonitor.h"
47 #include "afsmon-labels.h"
48
49
50 /* afsmonitor version number */
51 static char afsmon_version[] = "1.0";
52
53 /* EXTERNAL VARIABLES (from afsmonitor.c) */
54
55 extern int afsmon_debug;        /* debug info to file ? */
56 extern FILE *debugFD;           /* debugging file descriptor */
57 extern char errMsg[256];        /* buffers used to print error messages after*/ 
58 extern char errMsg1[256];       /* gtx is initialized (stderr/stdout gone !) */ 
59
60 /* number of fileservers and cache managers to monitor */
61 extern int numFS;
62 extern int numCM;
63
64 /* number of FS alerts and number of hosts on FS alerts */
65 extern int num_fs_alerts;
66 extern int numHosts_onfs_alerts;
67
68 /* number of CM alerts and number of hosts on FS alerts */
69 extern int num_cm_alerts;
70 extern int numHosts_oncm_alerts;
71
72 /* ptr to array holding the results of FS probes in ascii format */     
73 extern struct fs_Display_Data *prev_fsData;
74
75 /* ptr to array holding the results of CM probes in ascii format */     
76 extern struct cm_Display_Data *prev_cmData;
77
78 extern int afsmon_fs_curr_probeNum;     /* current fs probe number */
79 extern int afsmon_fs_prev_probeNum;     /* previous fs probe number */
80 extern int afsmon_cm_curr_probeNum;     /* current cm probe number */
81 extern int afsmon_cm_prev_probeNum;     /* previous cm probe number */
82
83 extern int afsmon_probefreq;            /* probe frequency */
84
85 /* map of fs results items we must display. This array contains indices to
86 the fs_varNames[] array corresponding to the stats we want to display. It is
87 initialized while processing the config file */
88
89 extern short fs_Display_map[XSTAT_FS_FULLPERF_RESULTS_LEN];
90 extern int fs_DisplayItems_count;      /* number of items to display */
91
92 extern short cm_Display_map[XSTAT_FS_FULLPERF_RESULTS_LEN];
93 extern int cm_DisplayItems_count;      /* number of items to display */
94
95
96 /* GTX VARIABLES */
97
98 /* minimum window size */
99 #define MINX 80
100 #define MINY 12
101
102 /* justifications */
103 #define RIGHT_JUSTIFY 0
104 #define LEFT_JUSTIFY 1
105 #define CENTER 2
106
107 /* width of overview frame objects */
108 /* field widths include the terminating null character */
109
110 #define PROGNAME_O_WIDTH (maxX/2)       /* program name object */
111 #define OVW_PAGENUM_O_WIDTH     29      /* page number object */
112 #define OVW_PROBENUM_O_WIDTH  39        /* probe number object */
113 #define OVW_CMD_O_WIDTH  (maxX/2)       /* cmd line object */
114 #define OVW_NUMFS_O_WIDTH       40      /* num FSs monitored */
115 #define OVW_NUMCM_O_WIDTH       40      /* num CMs monitored */
116 #define OVW_FSALERTS_O_WIDTH 40         /* num FS alerts */
117 #define OVW_CMALERTS_O_WIDTH 40         /* num CM alerts */
118 #define OVW_HOSTNAME_O_WIDTH (maxX / 2) /* FS & CM host names */
119 #define OVW_HOSTNAME_O_WIDTH_HGL 30     /* cosmetic, atleast this many chars
120                                         will be highlightned */
121
122 /* widths of FS and CM frame objects */
123 #define FC_NUMHOSTS_O_WIDTH  (maxX - 8) /* number of fs monitored. leave 4
124                                         chars on either side for '<<','>>' */
125 #define FC_PAGENUM_O_WIDTH 43
126 #define FC_HOSTNAME_O_WIDTH 11          /* width of FS hostnames column */
127 #define FC_CMD_O_WIDTH    55            /* width of cmd line */
128 #define FC_PROBENUM_O_WIDTH 30          /* width of probe number object */
129 #define FC_ARROWS_O_WIDTH    4          /* width of arrow indicators */
130 #define FC_COLUMN_WIDTH    11           /* width of data columns */
131
132 /* bit definitions for use in resolving command line */
133 /* these bits are set in the xx_pageType variables to indicate what commands
134 are acceptable */
135
136 #define CMD_NEXT  1             /* next page ? */
137 #define CMD_PREV  2             /* previous page ? */
138 #define CMD_LEFT  4             /* left scroll ? */
139 #define CMD_RIGHT 8             /* right scroll ? */
140 #define CMD_FS    16            /* file servers frame exists ? */
141 #define CMD_CM    32            /* cache managers frame exists ? */
142
143
144 #define FC_NUM_FIXED_LINES 10           /* number of fixed lines */
145 #define FC_FIRST_HOST_ROW 8             /* first host entry row number */
146 #define FC_FIRST_LABEL_ROW 4            /* first label row number */
147
148 /* number of fixed lines (that dont change) on the overview screen */
149 #define OVW_NUM_FIXED_LINES 7
150 #define OVW_FIRST_HOST_ROW 5   /* row index of first host entry in ovw frame*/
151
152 #define HIGHLIGHT 1             /* highlight object? */
153
154 static char blankline[256];     /* blank line */
155
156 /* maximum X & Y coordinates of the frames */
157 int maxX;
158 int maxY;
159
160 struct gwin *afsmon_win;        /* afsmonitor window */
161 int gtx_initialized = 0;
162
163 /* Overview screen related definitions */
164
165 struct gtx_frame *ovwFrame;             /* overview screen frame */
166 struct gwin_sizeparams frameDims;       /* frame dimensions. all frames have
167                                         same dimensions */
168
169 /* overview frame object names */
170 struct onode *ovw_progName_o;           /* program name object */
171 struct onode *ovw_pageNum_o;            /* page number onject */
172 struct onode *ovw_cmd_o;                /* command line object */
173 struct onode *ovw_probeNum_o;           /* probe number object */
174 struct onode *ovw_numFS_o;              /* num FS monitored */
175 struct onode *ovw_numCM_o;              /* num CM monitored */
176 struct onode *ovw_FSalerts_o;           /* nunber of FS alerts */
177 struct onode *ovw_CMalerts_o;           /* nunber of CM alerts */
178 struct onode *initMsg_o;                /* initialization message */
179
180 /* number of pages of data for the overview frame */
181 int ovw_numPages = 0;
182 int ovw_currPage = 1;           /* current page number */
183
184 static int ovw_pageType = 0;    /* one of the above types */
185
186 /* number of rows of server names that can be displayed on one overview page*/
187 int ovw_numHosts_perPage;
188
189 /* ptr to a block of ovw_numHosts_perPage number of objects for file servers */
190 struct onode **ovw_fsNames_o;
191 /*ptr to a block of ovw_numHosts_perPage number of objects for cache managers */
192 struct onode **ovw_cmNames_o;
193
194 /* When the ovw_refresh routine is called by the keyboard handlers the
195 following variable is used to determine if fs/cm/fs&cm info must be updated */
196 int ovw_update_info = 0;
197
198 /* Variables needed to display an intialization message on startup */
199 static char *initMsg = "AFSMonitor Collecting Statistics ...";
200 static int initMsg_on = 0;      /* message on ? */
201
202 /* FILE SERVER Screen related definitions */
203
204 struct gtx_frame *fsFrame;              /* File Server screen frame */
205
206 struct onode *fs_pageNum_o;             /* fs page number object */
207 struct onode *fs_cmd_o;                 /* fs command line object */
208 struct onode *fs_probeNum_o;            /* fs probe number object */
209 struct onode *fs_numFS_o;               /* fs number of FSs object */
210 struct onode *fs_leftArrows_o;          /* fs cols on left signal object */
211 struct onode *fs_rightArrows_o;         /* fs cols on right signal object */
212 struct onode **fs_hostNames_o;          /* ptr to host names objects */
213
214 /* bit-map to characterize page type and contents of command prompt */
215 static int fs_pageType = 0;
216
217 /* coordinates for the File Servers screen */
218
219 /* we use page numbers to navigate vertically (ie, across hosts) and column
220 numbers to navigate horizontally */
221
222 int fs_numHosts_perPage;        /* number of file servers per page */
223 int fs_cols_perPage;            /* number of data columns per file server page*/
224 int fs_currPage;                /* current FS page number */
225 int fs_numPages;                /* number of FS pages */
226
227 /* column numbers are index to the mapping structure fs_Display_map. this
228 map contains the indices of datums that should be displayed */
229
230 int fs_numCols;         /* number of columns of FS data (excluding hostname)*/
231                         /* this is the same as fs_DisplayItems_count */
232 /* following column indices run from 1 to (fs_numCols -1) */
233 int fs_curr_LCol = 0;   /* column number of leftmost column on display */
234 int fs_curr_RCol = 0;   /* column number of rightmost column on display */
235 int fs_Data_Available = 0; /* atleast one fs probe cycle completed ? */
236
237
238 /* structure that defines a line of data in the fs/cm frames */
239
240 /* we store each datum value in two objects, one below the other. The reason
241 for doing this is to conserve screen area. most of the datums are just longs
242 and will fit into one object. some of them are timing values and require 13
243 characters to be displayed - such fields may overflow to the second object
244 placed below the first one. */
245
246 struct ServerInfo_line {
247         struct onode *host_o;           /* hostname object */
248         struct onode **data_o[2];       /* ptrs to two arrays of data objects.*/
249                                                 
250 };
251
252 struct ServerInfo_line *fs_lines;       /* ptr to the file server data objects*/
253
254 /* file server label onodes - three rows of them */
255 struct onode **fsLabels_o[3];
256
257 /* CACHE MANAGER Screen related definitions */
258
259 struct gtx_frame *cmFrame;              /* Cache Manager screen frame */
260
261 struct onode *cm_pageNum_o;             /* cm page number object */
262 struct onode *cm_cmd_o;                 /* cm command line object */
263 struct onode *cm_probeNum_o;            /* cm probe number object */
264 struct onode *cm_numCM_o;               /* cm number of FSs object */
265 struct onode *cm_leftArrows_o;          /* fs cols on left signal object */
266 struct onode *cm_rightArrows_o;         /* fs cols on right signal object */
267
268 struct onode **cm_hostNames_o;          /* ptr to host names objects */
269
270 /* bit-map to characterize page type and contents of command prompt */
271 static int cm_pageType = 0;
272
273 /* coordinates for the Cache Managers screen */
274
275 /* we use page numbers to navigate vertically (ie, across hosts) and column
276 numbers to navigate horizontally */
277
278 int cm_numHosts_perPage;        /* number of cache managers per page */
279 int cm_cols_perPage;            /* number of data columns per file server page*/
280 int cm_currPage;                /* current CM page number */
281 int cm_numPages;                /* number of CM pages */
282
283 /* column numbers are index to the mapping structure cm_Display_map. this
284 map contains the indices of datums that should be displayed */
285
286 int cm_numCols;         /* number of columns of FS data (excluding hostname)*/
287                         /* this is the same as cm_DisplayItems_count */
288 /* following column indices run from 1 to (cm_numCols -1) */
289 int cm_curr_LCol = 0;   /* column number of leftmost column on display */
290 int cm_curr_RCol = 0;   /* column number of rightmost column on display */
291 int cm_Data_Available = 0; /* atleast one cm probe cycle completed ? */
292
293
294 /* structure that defines a line of data in the fs/cm frames */
295 struct ServerInfo_line *cm_lines;       /* ptr to the file server data objects*/
296
297 /* file server label onodes - three rows of them */
298 struct onode **cmLabels_o[3];
299
300
301
302 /*------------------------------------------------------------------------
303  * initLightObject
304  *
305  * Description:
306  *      Create and initialize a light onode according to the given
307  *      parameters.
308  *      ( Borrowed from scout.c )
309  *
310  * Arguments:
311  *      char *a_name       : Ptr to the light's string name.
312  *      int a_x            : X offset.
313  *      int a_y            : Y offset.
314  *      int a_width        : Width in chars.
315  *      struct gwin *a_win : Ptr to window structure.
316  *
317  * Returns:
318  *      Ptr to new light onode on success,
319  *      A null pointer otherwise.
320  *
321  * Environment:
322  *      See above.
323  *
324  * Side Effects:
325  *      As advertised.
326  *------------------------------------------------------------------------*/
327
328 static struct onode *
329 initLightObject(a_name, a_x, a_y, a_width, a_win)
330     char *a_name;
331     int a_x;
332     int a_y;
333     int a_width;
334     struct gwin *a_win;
335
336 { /*initLightObject*/
337
338     static char rn[] = "initLightObject";       /*Routine name*/
339     struct onode *newlightp;                    /*Ptr to new light onode*/
340     struct gator_light_crparams light_crparams; /*Light creation params*/
341     char *truncname;                            /*Truncated name, if needed*/
342     int name_len;                               /*True length of name*/
343
344 /* the following debug statement floods the debug file */
345 #ifdef DEBUG_DETAILED
346     if (afsmon_debug) {
347         fprintf(debugFD,"[ %s ] Called, a_name= %s, a_x= %d, a_y= %d, a_width= %d, a_win= %d\n",
348         rn, a_name, a_x, a_y, a_width, a_win);
349         fflush(debugFD);
350     }
351 #endif
352
353     newlightp = NULL;
354
355     /*
356       * Set up the creation parameters according to the information we've
357       * received.
358       */
359     light_crparams.onode_params.cr_type = GATOR_OBJ_LIGHT;
360     name_len = strlen(a_name);
361
362     if (name_len <= a_width)
363       sprintf(light_crparams.onode_params.cr_name, "%s", a_name);
364     else {
365       /*
366         * We need to truncate the given name, leaving a `*' at the end to
367         * show us it's been truncated.
368         */
369       truncname = light_crparams.onode_params.cr_name;
370       strncpy(truncname, a_name, a_width-1);
371       truncname[a_width-1] = '*';
372       truncname[a_width]   = 0;
373     }
374     light_crparams.onode_params.cr_x          = a_x;
375     light_crparams.onode_params.cr_y          = a_y;
376     light_crparams.onode_params.cr_width      = a_width;
377     light_crparams.onode_params.cr_height     = 1;
378     light_crparams.onode_params.cr_window     = a_win;
379     light_crparams.onode_params.cr_home_obj   = NULL;
380     light_crparams.onode_params.cr_prev_obj   = NULL;
381     light_crparams.onode_params.cr_parent_obj = NULL;
382     light_crparams.onode_params.cr_helpstring = NULL;
383
384     light_crparams.appearance = 0;
385     light_crparams.flashfreq  = 0;
386     sprintf(light_crparams.label, "%s", a_name);
387     light_crparams.label_x = 0;
388     light_crparams.label_y = 0;
389
390     newlightp =
391       gator_objects_create((struct onode_createparams *)(&light_crparams));
392
393     /*
394       * Return the news, happy or not.
395       */
396     return(newlightp);
397
398 } /*initLightObject*/
399
400
401
402 /*------------------------------------------------------------------------
403  * justify_light
404  *
405  * Description:
406  *      Place the chars in the source buffer into the target buffer
407  *      with the desired justification, either centered, left-justified
408  *      or right-justified.  Also, support inidication of truncation
409  *      with a star (*), either on the left or right of the string,
410  *      and whether we're justifying a labeled disk quantity.
411  *
412  *      (derived from mini_justify() in scout.c)
413  *
414  * Arguments:
415  *      char *a_srcbuff     : Ptr to source char buffer.
416  *      char *a_dstbuff     : Ptr to dest char buffer.
417  *      int a_dstwidth      : Width of dest buffer in chars.
418  *      int a_justification : Kind of justification.
419  *      int a_rightTrunc    : If non-zero, place the truncation char
420  *                            on the right of the string.  Otherwise,
421  *                            place it on the left.
422  *
423  * Returns:
424  *      0 on success,
425  *      -1 otherwise.
426  *
427  *------------------------------------------------------------------------*/
428
429 int 
430 justify_light(a_srcbuff, a_dstbuff, a_dstwidth, a_justification, a_rightTrunc)
431     char *a_srcbuff;
432     char *a_dstbuff;
433     int a_dstwidth;
434     int a_justification;
435     int a_rightTrunc;
436
437 { /*justify_light*/
438
439     static char rn[] = "justify_light"; /*Routine name*/
440     int leftpad_chars;                  /*# of chars for left-padding*/
441     int num_src_chars;                  /*# of chars in source*/
442     int true_num_src_chars;             /*# src chars before truncation*/
443     int trunc_needed;                   /*Is truncation needed?*/
444
445
446 /* the following debug statement floods the debug file */
447 #ifdef DEBUG_DETAILED
448     if (afsmon_debug) {
449         fprintf(debugFD,"[ %s ] Called, a_srcbuff= %s, a_dstbuff= %d, a_dstwidth= %d, a_justification= %d, a_rightTrunc= %d\n",
450         rn, a_srcbuff, a_dstbuff, a_dstwidth, a_justification, a_rightTrunc);
451         fflush(debugFD);
452     }
453 #endif
454
455
456     /*
457      * If the destination width will overrun the gtx string storage,
458      * we automatically shorten up.
459      */
460     if (a_dstwidth > GATOR_LABEL_CHARS) {
461       /* 
462       if (afsmon_debug) {
463         fprintf(debugFD,
464         "[%s] Dest width (%d) > gtx buflen (%d), shrinking dest width\n",
465                 rn, a_dstwidth, GATOR_LABEL_CHARS);
466         fflush(debugFD);
467       }
468       */
469       a_dstwidth = GATOR_LABEL_CHARS;
470     }
471
472     /*
473      * If our source string is too long, prepare for truncation.
474      */
475     true_num_src_chars = strlen(a_srcbuff);
476     if (true_num_src_chars >= a_dstwidth) {
477         trunc_needed = 1;
478         num_src_chars = a_dstwidth - 1;
479         leftpad_chars = 0;
480         if (!a_rightTrunc)
481             a_srcbuff += (true_num_src_chars - num_src_chars);
482     }
483     else {
484         trunc_needed = 0;
485         num_src_chars = true_num_src_chars;
486         
487         /*
488          * Compute the necessary left-padding.
489          */
490         switch (a_justification) {
491             
492           case RIGHT_JUSTIFY:
493             leftpad_chars = (a_dstwidth - 1) - num_src_chars;
494             break;
495             
496           case LEFT_JUSTIFY:
497             /*
498              * This is the really easy one.
499              */
500             leftpad_chars = 0;
501             break;
502             
503           case CENTER:
504             leftpad_chars = ((a_dstwidth - 1) - num_src_chars) / 2;
505             break;
506             
507           default:
508             if (afsmon_debug) {
509             fprintf(debugFD, "[%s] Illegal justification command: %d",
510                     rn, a_justification);
511             fprintf(debugFD, "[%s] Called with '%s', dest width=%d\n",
512                     rn, a_srcbuff, a_dstwidth);
513             fflush(debugFD);
514             }
515             return(-1);
516         } /*Switch on justification type*/
517     }
518
519     /*
520      * Clear out the dest buffer, then place the source string at the
521      * appropriate padding location.  Remember to place a string
522      * terminator at the end of the dest buffer, plus whatever truncation
523      * may be needed.  If we're left-truncating, we've already shifted
524      * the src buffer appropriately.
525      */
526     strncpy(a_dstbuff, blankline, a_dstwidth);
527     strncpy(a_dstbuff+leftpad_chars, a_srcbuff, num_src_chars);
528     *(a_dstbuff+a_dstwidth-1) = '\0';
529     if (trunc_needed) {
530         if (a_rightTrunc)
531             *(a_dstbuff+a_dstwidth-2) = '*'; /*Truncate on the right*/
532         else {
533                 *a_dstbuff = '*';            /*Truncate on the left, non-disk*/
534         }
535     } /*Handle truncations*/
536
537     /*
538      * Return the good news.
539      */
540     return(0);
541
542 } /*justify_light*/
543
544
545
546 /*-----------------------------------------------------------------------
547  * afsmonExit_gtx()
548  *
549  * Description:
550  *      Call the exit routine. This function is mapped
551  *      to the keys Q and \ 3 in all the frames and is called by the 
552  *      gtx input server.
553  *----------------------------------------------------------------------*/
554
555 int
556 afsmonExit_gtx()
557 {
558     static char rn[] = "afsmonExit_gtx";
559
560     if (afsmon_debug) {
561         fprintf(debugFD,"[ %s ] Called\n",rn);
562         fflush(debugFD);
563     }
564
565         afsmon_Exit(0);
566 }
567
568
569 /*-----------------------------------------------------------------------
570  * ovw_refresh()
571  *
572  * Description:
573  *      Refresh the overview screen with the contents of the specified page.
574  *      There are two parts to the overview screen - the file server column
575  *      and the cache manager column and each of them is independent of the
576  *      other. Hence it takes as an argumnet the "type" of update to be
577  *      performed.
578  *
579  * Returns:
580  *      Success: 0
581  *      Failure: Exits afsmonitor.
582  *----------------------------------------------------------------------*/
583
584 int
585 ovw_refresh(a_pageNum, a_updateType)
586 int a_pageNum;          /* page to refresh overview display */
587 int a_updateType;       /* OVW_UPDATE_FS = update fs column only,
588                            OVW_UPDATE_CM = update cm column only,
589                            OVW_UPDATE_BOTH = update fs & cm columns. Note that 
590                            we do not want to update a column until the 
591                            corresponding probe cycle has completed */
592 {       /* ovw_refresh */
593
594    static char rn[] = "ovw_refresh";    /* routine name */
595    struct onode **tmp_fsNames_o;                /* ptr to fsNames onodes */
596    struct gator_lightobj *tmp_lightobj; /* ptr for object's display data */
597    struct fs_Display_Data *fsDataP;     /* ptr to FS display data array */
598    struct onode **tmp_cmNames_o;                /* ptr to fsNames onodes */
599    struct cm_Display_Data *cmDataP;     /* ptr to CM display data array */
600    int fsIdx;                           /* for counting # of CM hosts */
601    int cmIdx;                           /* for counting # of CM hosts */
602    int next_page = 0;                   /* is there a next ovw page ? */
603    int prev_page = 0;                   /* is there a previous ovw page */
604    char cmdLine[80];                    /* buffer for command line */
605    char printBuf[256];                  /* buffer to print to screen */
606    int i;
607    int code;
608    int len;
609
610    if (afsmon_debug) {
611         fprintf(debugFD,"[ %s ] Called, a_pageNum= %d, a_updateType= %d\n",
612                 rn, a_pageNum, a_updateType);
613         fflush(debugFD);
614    }
615
616    /* if the data is not yet available  ie., not one probe cycle has 
617    completed, do nothing */
618
619    if ( (a_updateType & OVW_UPDATE_FS) && !fs_Data_Available)
620         return(0);
621    if ( (a_updateType & OVW_UPDATE_CM) && !cm_Data_Available)
622         return(0);
623    
624
625    /* validate page number */
626    if (a_pageNum < 1 || a_pageNum > ovw_numPages) {
627         sprintf(errMsg,"[ %s ] called with incorrect page number %d\n",
628                 rn,a_pageNum);
629         afsmon_Exit(235);
630    }
631
632    /* set the current page number */
633    ovw_currPage = a_pageNum;
634
635    /* turn off init message */
636    if (initMsg_on) {
637         initMsg_on = 0;
638         gtxframe_RemoveFromList(ovwFrame, initMsg_o);
639    }
640
641    /* update the labels */
642
643    /* version label */
644    tmp_lightobj=(struct gator_lightobj *) ovw_progName_o->o_data;
645    sprintf(printBuf,"AFSMonitor [Version %s]",afsmon_version);
646    justify_light(printBuf,tmp_lightobj->label,strlen(printBuf)+1, 
647                 LEFT_JUSTIFY,1);
648    gator_light_set(ovw_progName_o,1);
649
650    /* page number label */
651    tmp_lightobj=(struct gator_lightobj *) ovw_pageNum_o->o_data;
652    sprintf(printBuf,"[System Overview, p. %d of %d]",ovw_currPage,ovw_numPages);
653    justify_light(printBuf,tmp_lightobj->label, OVW_PAGENUM_O_WIDTH, 
654                 RIGHT_JUSTIFY,1);
655    gator_light_set(ovw_pageNum_o,1);
656
657    /* file servers monitored label */
658    tmp_lightobj=(struct gator_lightobj *) ovw_numFS_o->o_data;
659    sprintf(printBuf,"    %d File Servers monitored",numFS);
660    justify_light(printBuf,tmp_lightobj->label, strlen(printBuf)+1, 
661                 LEFT_JUSTIFY,1);
662    
663    /* cache managers monitored label */
664    tmp_lightobj=(struct gator_lightobj *) ovw_numCM_o->o_data;
665    sprintf(printBuf,"    %d Cache Managers monitored",numCM);
666    justify_light(printBuf,tmp_lightobj->label, strlen(printBuf)+1, 
667                 LEFT_JUSTIFY,1);
668
669
670    /* no. of fs alerts label */
671    tmp_lightobj=(struct gator_lightobj *) ovw_FSalerts_o->o_data;
672    sprintf(printBuf,"    %d alerts on %d machines",
673                 num_fs_alerts,numHosts_onfs_alerts);
674    justify_light(printBuf,tmp_lightobj->label, strlen(printBuf)+1, 
675                 LEFT_JUSTIFY,1);
676
677    /* no. of cm alerts label */
678    tmp_lightobj=(struct gator_lightobj *) ovw_CMalerts_o->o_data;
679    sprintf(printBuf,"    %d alerts on %d machines",
680                 num_cm_alerts,numHosts_oncm_alerts);
681    justify_light(printBuf,tmp_lightobj->label, strlen(printBuf)+1, 
682                 LEFT_JUSTIFY,1);
683
684    /* command line */
685    /* determine if we have fs/cm, more/previous pages of data to display */
686
687    ovw_pageType = 0;
688    if (numFS && fs_Data_Available) 
689         ovw_pageType |= CMD_FS;         /* we have an fs frame & data avail. */
690    if (numCM && cm_Data_Available) 
691         ovw_pageType |= CMD_CM;         /* we have a cm frame & data avail. */
692    if (ovw_currPage > 1) 
693         ovw_pageType |= CMD_PREV;       /* got a previous page */
694    if (ovw_currPage < ovw_numPages) 
695         ovw_pageType |= CMD_NEXT;       /* got a next page */
696
697    strcpy(cmdLine,"Command [");
698    if ( (ovw_pageType & CMD_FS) && (ovw_pageType & CMD_CM) )
699         strcat(cmdLine,"fs, cm");
700    else if (ovw_pageType & CMD_FS)
701         strcat(cmdLine,"fs");
702    else if (ovw_pageType & CMD_CM)
703         strcat(cmdLine,"cm");
704         
705    if (ovw_pageType & CMD_PREV)
706         strcat(cmdLine,", prev");
707    if (ovw_pageType & CMD_NEXT)
708         strcat(cmdLine,", next");
709
710    strcat(cmdLine,"]? ");
711
712
713
714
715    /* display the command line */
716    tmp_lightobj=(struct gator_lightobj *) ovw_cmd_o->o_data;
717    sprintf(printBuf,"%s", cmdLine);
718    justify_light(printBuf,tmp_lightobj->label, strlen(printBuf)+1, 
719                 LEFT_JUSTIFY,1);
720    gator_light_set(ovw_cmd_o, 1);
721         
722    /* display probe numbers line */
723    tmp_lightobj=(struct gator_lightobj *) ovw_probeNum_o->o_data;
724    sprintf(printBuf,"[probes %d(fs) %d(cm), freq=%d sec]",
725         afsmon_fs_prev_probeNum, afsmon_cm_prev_probeNum,afsmon_probefreq);
726    justify_light(printBuf,tmp_lightobj->label, OVW_PROBENUM_O_WIDTH, 
727                 RIGHT_JUSTIFY,1);
728    gator_light_set(ovw_probeNum_o, 1);
729         
730
731
732    /* update the file server names column if we are asked to */
733
734    if (numFS && (a_updateType & OVW_UPDATE_FS)) {
735
736    /* move to the right spot in the FS display data array */
737    fsDataP = prev_fsData;
738    fsIdx = 0;
739    for(i=0; i < ((a_pageNum-1) * ovw_numHosts_perPage); i++) {
740         fsDataP++;
741         fsIdx++;
742    }
743    
744    /* get the address to the first FS name */
745    tmp_fsNames_o = ovw_fsNames_o;
746
747    for (i=0; i < ovw_numHosts_perPage; i++) {
748         if (fsIdx < numFS) {    /* this could be the last & partial page */
749
750                 if (fsDataP->hostName[0] == '\0') {
751                         sprintf(errMsg,"[ %s ] empty fs display entry \n",rn);
752                         afsmon_Exit(240);
753                 }
754
755                 /* check if the probe succeeded. if it did check for thresholds
756                 overflow. A failed probe is indicated by "PF" */
757
758                 if (! fsDataP->probeOK) {
759                         sprintf(printBuf,"[ PF] %s", fsDataP->hostName);
760                 } else if (fsDataP->ovfCount)   /* thresholds overflow */
761                         sprintf(printBuf,"[%3d] %s",
762                         fsDataP->ovfCount,fsDataP->hostName);
763                 else {
764                         sprintf(printBuf,"      %s",fsDataP->hostName);
765
766                 }
767                 if (afsmon_debug) 
768                 fprintf(debugFD,"[ %s ] to display %s\n",rn,printBuf);
769
770                 tmp_lightobj=(struct gator_lightobj *) (*tmp_fsNames_o)->o_data;
771
772                 if (strlen(printBuf)+1 < OVW_HOSTNAME_O_WIDTH_HGL)
773                         len = OVW_HOSTNAME_O_WIDTH_HGL;
774                 else 
775                         len = strlen(printBuf)+1;
776
777                 code = justify_light(printBuf,tmp_lightobj->label,
778                         len, LEFT_JUSTIFY, 1);
779                 if (code) {
780                         if (afsmon_debug) {
781                         fprintf(debugFD,"[ %s ] justify_code returned %d\n",
782                                 rn,code);
783                 }
784                 }
785                 
786                 /* highlighten if overflowed or probe failed */
787
788                 if (fsDataP->ovfCount || ! fsDataP->probeOK)    
789                         code = gator_light_set(*tmp_fsNames_o,1);
790                 else
791                         code = gator_light_set(*tmp_fsNames_o,0);
792
793
794         } else {        /* no more hosts, blank the rest of the entries */
795                 tmp_lightobj=(struct gator_lightobj *) (*tmp_fsNames_o)->o_data;
796                 sprintf(tmp_lightobj->label,"%s","");
797         }
798
799         tmp_fsNames_o++;        /* next onode */
800         fsDataP++;              /* next host's data */
801         fsIdx++;                /* host index */
802    }
803    }            /* if numFS */
804
805    /* if we have any cache managers, update them if we are asked to */
806    if (numCM && (a_updateType & OVW_UPDATE_CM)){        
807
808    /* move to the right spot in the CM display data array */
809    cmDataP = prev_cmData;
810    cmIdx = 0;
811    for(i=0; i < ((a_pageNum-1) * ovw_numHosts_perPage); i++) {
812         cmDataP++;
813         cmIdx++;
814    }
815    
816    /* get the address to the first CM name */
817    tmp_cmNames_o = ovw_cmNames_o;
818
819    for (i=0; i < ovw_numHosts_perPage; i++) {
820         if (cmIdx < numCM) {    /* this could be the last & partial page */
821
822                 if (cmDataP->hostName[0] == '\0') {
823                         sprintf(errMsg,"[ %s ] empty cm display entry \n",rn);
824                         afsmon_Exit(245);
825                 }
826
827                 /* check if the probe succeeded. if it did check for thresholds
828                 overflow. A failed probe is indicated by "PF" */
829
830                 if (! cmDataP->probeOK) {
831                         sprintf(printBuf,"[ PF] %s", cmDataP->hostName);
832                 } else if (cmDataP->ovfCount) { /* thresholds overflow */
833                         sprintf(printBuf,"[%3d] %s",
834                         cmDataP->ovfCount,cmDataP->hostName);
835                 } else 
836                         sprintf(printBuf,"      %s",cmDataP->hostName);
837                 
838                 if (afsmon_debug)
839                         fprintf(debugFD,"[ %s ] to display %s\n",rn,printBuf);
840
841                 tmp_lightobj=(struct gator_lightobj *) (*tmp_cmNames_o)->o_data;
842
843                 if (strlen(printBuf)+1 < OVW_HOSTNAME_O_WIDTH_HGL)
844                         len = OVW_HOSTNAME_O_WIDTH_HGL;
845                 else 
846                         len = strlen(printBuf)+1;
847
848                 code = justify_light(printBuf,tmp_lightobj->label,
849                         len, LEFT_JUSTIFY, 1);
850                 if (code) {
851                         if (afsmon_debug) {
852                         fprintf(debugFD,"[ %s ] justify_code returned %d\n",
853                                 rn,code);
854                 }
855                 }
856
857                 /* highlighten if overflow or if probe failed */
858                 if (cmDataP->ovfCount || ! cmDataP->probeOK)
859                         code = gator_light_set(*tmp_cmNames_o,1);
860                 else 
861                         code = gator_light_set(*tmp_cmNames_o,0);
862
863
864         } else {        /* no more hosts, blank the rest of the entries */
865                 tmp_lightobj=(struct gator_lightobj *) (*tmp_cmNames_o)->o_data;
866                 sprintf(tmp_lightobj->label,"%s","");
867         }
868
869         tmp_cmNames_o++;        /* next onode */
870         cmDataP++;              /* next host's data */
871         cmIdx++;                /* host index */
872    }
873    }    /* if numCM */
874
875    /* redraw the display if the overview screen is currently displayed */
876    if (afsmon_win->w_frame == ovwFrame)
877         WOP_DISPLAY(afsmon_win);
878
879    return(0);
880
881 }       /* ovw_refresh */
882         
883
884
885 /*-----------------------------------------------------------------------
886  * Switch_ovw_2_fs()
887  *
888  * Description:
889  *              Switch from the overview screen to the FS screen
890  *----------------------------------------------------------------------*/
891 int
892 Switch_ovw_2_fs()
893 {
894    static char rn[] = "Switch_ovw_2_fs";
895
896     if (afsmon_debug) {
897         fprintf(debugFD,"[ %s ] Called\n",rn);
898         fflush(debugFD);
899     }
900
901    /* bind the File Server frame to the window */
902    if (ovw_pageType & CMD_FS)
903         gtxframe_SetFrame(afsmon_win,fsFrame);
904    return(0);
905 }
906
907 /*-----------------------------------------------------------------------
908  * Switch_ovw_2_cm()
909  *
910  * Description:
911  *              Switch from the overview screen to the CM screen
912  *----------------------------------------------------------------------*/
913 int
914 Switch_ovw_2_cm()
915 {
916    static char rn[] = "Switch_ovw_2_cm";
917
918    if (afsmon_debug) {
919         fprintf(debugFD,"[ %s ] Called\n",rn);
920         fflush(debugFD);
921    }
922
923    /* bind the Cache Managers frame to the window */
924    if (ovw_pageType & CMD_CM)
925         gtxframe_SetFrame(afsmon_win,cmFrame);
926    return(0);
927 }
928
929 /*-----------------------------------------------------------------------
930  * Switch_ovw_next()
931  *
932  * Description:
933  *              Switch to the next page in overview screen
934  *----------------------------------------------------------------------*/
935 int
936 Switch_ovw_next()
937 {
938    static char rn[] = "Switch_ovw_next";
939
940    if (afsmon_debug) {
941         fprintf(debugFD,"[ %s ] Called\n",rn);
942         fflush(debugFD);
943    }
944
945    if (ovw_pageType & CMD_NEXT) {
946         /* call refresh with the next page number */
947         ovw_refresh(ovw_currPage + 1,ovw_update_info);
948    }
949
950    return(0);
951 }
952
953 /*-----------------------------------------------------------------------
954  * Switch_ovw_last()
955  *
956  * Description:
957  *              Switch to the last page in the overview screen
958  *----------------------------------------------------------------------*/
959 int
960 Switch_ovw_last()
961 {
962    static char rn[] = "Switch_ovw_last";
963
964     if (afsmon_debug) {
965         fprintf(debugFD,"[ %s ] Called\n",rn);
966         fflush(debugFD);
967     }
968
969    if (ovw_pageType & CMD_NEXT) {
970         /* call refresh with the last page number */
971         ovw_refresh(ovw_numPages, ovw_update_info);
972    }
973
974    return(0);
975 }
976
977 /*-----------------------------------------------------------------------
978  * Switch_ovw_prev()
979  *
980  * Description:
981  *              Switch to the previous page in the overview screen
982  *----------------------------------------------------------------------*/
983 int
984 Switch_ovw_prev()
985 {
986    static char rn[] = "Switch_ovw_prev";
987
988     if (afsmon_debug) {
989         fprintf(debugFD,"[ %s ] Called\n",rn);
990         fflush(debugFD);
991     }
992
993    if (ovw_pageType & CMD_PREV) {
994         /* call refresh with the previous page number */
995         ovw_refresh(ovw_currPage - 1,ovw_update_info);
996    }
997    return(0);
998 }
999
1000 /*-----------------------------------------------------------------------
1001  * Switch_ovw_first()
1002  *
1003  * Description:
1004  *              Switch to the first page in the overview screen
1005  *----------------------------------------------------------------------*/
1006 int
1007 Switch_ovw_first()
1008 {
1009    static char rn[] = "Switch_ovw_first";
1010
1011     if (afsmon_debug) {
1012         fprintf(debugFD,"[ %s ] Called\n",rn);
1013         fflush(debugFD);
1014     }
1015
1016    if (ovw_pageType & CMD_PREV) {
1017         /* refresh with the first page number */
1018         ovw_refresh(1, ovw_update_info);
1019    }
1020    return(0);
1021 }
1022
1023 /*-----------------------------------------------------------------------
1024  * create_ovwFrame_objects()
1025  *
1026  * Description:
1027  *      Create the gtx objects (onodes) for the overview frame and setup
1028  *      the keyboard bindings.
1029  *      Only as many objects as can fit on the display are created. The
1030  *      positions and lengths of all these objects are fixed at creation.
1031  *      These objects are updated with new data at the end of each probe
1032  *      cycle.
1033  *
1034  * Returns:
1035  *      Success: 0
1036  *      Failure: Exits afsmonitor.
1037  *----------------------------------------------------------------------*/
1038
1039 int
1040 create_ovwFrame_objects()
1041 {       /* create_ovwFrame_objects */
1042
1043    static char rn[] = "create_ovwFrame_objects";
1044    int hostLines;       /* number of lines of host names to display */
1045    struct onode **ovw_fsNames_o_Ptr;    /* index to list of fs names onodes */
1046    struct onode **ovw_cmNames_o_Ptr;    /* index to list of cm names onodes */
1047    int code;
1048    int i;
1049
1050     if (afsmon_debug) {
1051         fprintf(debugFD,"[ %s ] Called\n",rn);
1052         fflush(debugFD);
1053     }
1054
1055    /* get frame dimensions, it must be atleast 80x10 for any sensible output*/
1056    WOP_GETDIMENSIONS(ovwFrame->window,&frameDims);
1057    maxX = frameDims.maxx;
1058    maxY = frameDims.maxy;
1059    if (maxX < MINX || maxY < MINY) {
1060         sprintf(errMsg1,"[ %s ] Window size must be atleaset 80x12\n",
1061                 rn);
1062         return(-1);
1063    }
1064    if (afsmon_debug)
1065         fprintf(debugFD,"maxX = %d maxY = %d\n",maxX,maxY);
1066
1067
1068    /* Print an Intial message to the screen. The init message is 36 chars
1069       long */
1070    initMsg_o = initLightObject(initMsg,
1071                 maxX/2 - 18,maxY/3,sizeof(initMsg),afsmon_win);
1072    if (initMsg_o == NULL) {
1073         sprintf(errMsg,"[ %s ] Failed to create initMsg_o onode\n",rn);
1074         afsmon_Exit(250);
1075    }
1076    code = gtxframe_AddToList(ovwFrame,initMsg_o);
1077    code = gator_light_set(initMsg_o,HIGHLIGHT);
1078    initMsg_on = 1;
1079
1080
1081
1082    /* create the command line object */
1083
1084    ovw_cmd_o = initLightObject("",
1085                 0,maxY-1,OVW_CMD_O_WIDTH,afsmon_win);
1086    if (ovw_cmd_o == NULL) {
1087         sprintf(errMsg,"[ %s ] Failed to create command onode\n",rn);
1088         afsmon_Exit(265);
1089    }
1090    code = gtxframe_AddToList(ovwFrame,ovw_cmd_o);
1091    code = gator_light_set(ovw_cmd_o,HIGHLIGHT);
1092
1093    /* create the program name object */
1094
1095    ovw_progName_o = initLightObject("",0,0,
1096                                 PROGNAME_O_WIDTH,afsmon_win);
1097    if (ovw_progName_o == NULL) {
1098         sprintf(errMsg,"[ %s ] Failed to create programName onode\n",rn);
1099         afsmon_Exit(255);
1100    }
1101    code = gtxframe_AddToList(ovwFrame,ovw_progName_o);
1102    code = gator_light_set(ovw_progName_o,HIGHLIGHT);
1103
1104    /* create the page number object */
1105
1106    ovw_pageNum_o = initLightObject("",
1107                 maxX-OVW_PAGENUM_O_WIDTH,0,OVW_PAGENUM_O_WIDTH,afsmon_win);
1108    if (ovw_pageNum_o == NULL) {
1109         sprintf(errMsg,"[ %s ] Failed to create pageNumber onode\n",rn);
1110         afsmon_Exit(260);
1111    }
1112    code = gtxframe_AddToList(ovwFrame,ovw_pageNum_o);
1113    code = gator_light_set(ovw_pageNum_o,HIGHLIGHT);
1114                 
1115    /* create the probe number object */
1116    ovw_probeNum_o = initLightObject("",
1117         maxX-OVW_PROBENUM_O_WIDTH,maxY-1,OVW_PROBENUM_O_WIDTH,afsmon_win);
1118    if (ovw_probeNum_o == NULL) {
1119         sprintf(errMsg,"[ %s ] Failed to create probe number onode\n",rn);
1120         afsmon_Exit(270);
1121    }
1122    code = gtxframe_AddToList(ovwFrame,ovw_probeNum_o);
1123    code = gator_light_set(ovw_probeNum_o,HIGHLIGHT);
1124
1125    /* create the numFS monitored object */
1126    ovw_numFS_o = initLightObject("",
1127                 0,2,FC_NUMHOSTS_O_WIDTH,afsmon_win);
1128    if (ovw_numFS_o == NULL) {
1129         sprintf(errMsg,"[ %s ] Failed to create numFS onode\n",rn);
1130         afsmon_Exit(275);
1131    }
1132    code = gtxframe_AddToList(ovwFrame,ovw_numFS_o);
1133
1134    /* create the numCM monitored object */
1135    ovw_numCM_o = initLightObject("",
1136                 maxX/2,2,OVW_NUMCM_O_WIDTH,afsmon_win);
1137    if (ovw_numCM_o == NULL) {
1138         sprintf(errMsg,"[ %s ] Failed to create numCM_o onode\n",rn);
1139         afsmon_Exit(280);
1140    }
1141    code = gtxframe_AddToList(ovwFrame,ovw_numCM_o);
1142
1143    /* create the number-of-FS-alerts object */
1144    ovw_FSalerts_o = initLightObject("",
1145                 0,3,OVW_FSALERTS_O_WIDTH,afsmon_win);
1146    if (ovw_FSalerts_o == NULL) {
1147         sprintf(errMsg,"[ %s ] Failed to create FSalerts_o onode\n",rn);
1148         afsmon_Exit(285);
1149    }
1150    code = gtxframe_AddToList(ovwFrame,ovw_FSalerts_o);
1151    
1152    /* create the number-of-CM-alerts object */
1153    ovw_CMalerts_o = initLightObject("",
1154                 maxX/2,3,OVW_CMALERTS_O_WIDTH,afsmon_win);
1155    if (ovw_CMalerts_o == NULL) {
1156         sprintf(errMsg,"[ %s ] Failed to create CMalerts_o onode\n",rn);
1157         afsmon_Exit(290);
1158    }
1159    code = gtxframe_AddToList(ovwFrame,ovw_CMalerts_o);
1160
1161    /* create file-server-name and cache-manager-names objects */
1162    ovw_numHosts_perPage = maxY - OVW_NUM_FIXED_LINES;
1163
1164    /* allocate memory for a list of onode pointers for file server names */
1165    ovw_fsNames_o = (struct onode **) malloc(
1166                         sizeof(struct onode *) * ovw_numHosts_perPage); 
1167    if (ovw_fsNames_o == NULL) {
1168         sprintf(errMsg,"[ %s ] Failed to allocate memory for FS onodes\n",rn);
1169         afsmon_Exit(295);
1170    }
1171
1172    /* create file server name objects */
1173    ovw_fsNames_o_Ptr = ovw_fsNames_o;
1174    for (i=0; i< ovw_numHosts_perPage; i++) {
1175         *ovw_fsNames_o_Ptr = initLightObject("",
1176                 0,OVW_FIRST_HOST_ROW+i,OVW_HOSTNAME_O_WIDTH,afsmon_win);
1177         if (*ovw_fsNames_o_Ptr == NULL) {
1178                 sprintf(errMsg,"[ %s ] Failed to create an FS name onode\n",rn);
1179                 afsmon_Exit(300);
1180         }
1181         /*
1182         if (afsmon_debug) {
1183                 fprintf(debugFD,"[ %s ] fsName_o  %d:  %d\n",
1184                         rn,i,*ovw_fsNames_o_Ptr);
1185                 fflush(debugFD);
1186         }
1187         */
1188         code = gtxframe_AddToList(ovwFrame,*ovw_fsNames_o_Ptr);
1189         ovw_fsNames_o_Ptr++;
1190
1191    }
1192         
1193                         
1194    /* allocate memory for a list of onode pointers for cache manager names */
1195    ovw_cmNames_o = (struct onode **) malloc(
1196                         sizeof(struct onode *) * ovw_numHosts_perPage); 
1197    if (ovw_cmNames_o == NULL) {
1198         sprintf(errMsg,"[ %s ] Failed to allocate memory for CM onodes\n",rn);
1199         afsmon_Exit(305);
1200    }
1201
1202    /* create cache manager name objects */
1203    ovw_cmNames_o_Ptr = ovw_cmNames_o;
1204    for (i=0; i< ovw_numHosts_perPage; i++) {
1205         *ovw_cmNames_o_Ptr = initLightObject("",
1206                 maxX/2,OVW_FIRST_HOST_ROW+i,OVW_HOSTNAME_O_WIDTH,afsmon_win);
1207         if (*ovw_cmNames_o_Ptr == NULL) {
1208                 sprintf(errMsg,"[ %s ] Failed to create a CM name onode\n",rn);
1209                 afsmon_Exit(310);
1210         }
1211         code = gtxframe_AddToList(ovwFrame,*ovw_cmNames_o_Ptr);
1212         ovw_cmNames_o_Ptr++;
1213    }
1214
1215
1216    /* Calculate the number of pages of overview data to display */
1217    /* host information starts at the 6th line from top and stops at 3rd
1218    line from bottom of screen */
1219
1220    if (numFS > numCM) hostLines = numFS;
1221         else hostLines = numCM;
1222
1223    ovw_numPages = hostLines / (maxY - OVW_NUM_FIXED_LINES); 
1224    if ( hostLines % (maxY - OVW_NUM_FIXED_LINES) )
1225         ovw_numPages++;
1226    
1227    if (afsmon_debug)
1228         fprintf(debugFD,"[ %s ] number of ovw pages = %d\n",rn,ovw_numPages);
1229
1230    /* When the ovw_refresh() routine is called by the keyboard handlers the
1231    following variable is used to determine if fs/cm/fs&cm info must be
1232    updated */
1233    ovw_update_info = 0;
1234    if (numFS)
1235         ovw_update_info |= OVW_UPDATE_FS;
1236    if (numCM)
1237         ovw_update_info |= OVW_UPDATE_CM;
1238
1239   /* bind the overview frame to a keyboard input handler */
1240
1241    /* bind Q and \ 3 to exit */
1242    keymap_BindToString(ovwFrame->keymap,"Q",afsmonExit_gtx,NULL,NULL);
1243    keymap_BindToString(ovwFrame->keymap,"\ 3",afsmonExit_gtx,NULL,NULL);
1244
1245   /* f -> switch of fs frame */
1246   keymap_BindToString(ovwFrame->keymap,"f",Switch_ovw_2_fs,NULL,NULL);
1247   /* c -> switch of cm frame */
1248   keymap_BindToString(ovwFrame->keymap,"c",Switch_ovw_2_cm,NULL,NULL);
1249   /* n -> switch to next overview page */
1250   keymap_BindToString(ovwFrame->keymap,"n",Switch_ovw_next,NULL,NULL);
1251   /* N -> switch to last overview page */
1252   keymap_BindToString(ovwFrame->keymap,"N",Switch_ovw_last,NULL,NULL);
1253   /* p -> switch to previous overview page */
1254   keymap_BindToString(ovwFrame->keymap,"p",Switch_ovw_prev,NULL,NULL);
1255   /* P -> switch to first overview page */
1256   keymap_BindToString(ovwFrame->keymap,"P",Switch_ovw_first,NULL,NULL);
1257
1258    
1259    return(0);
1260 }       /* create_ovwFrame_objects */
1261
1262
1263 /*-----------------------------------------------------------------------
1264  * resolve_CmdLine()
1265  *
1266  * Description:
1267  *      This function is called to determine the permissible keyboard
1268  *      operations on the FS and CM frames. This information is used
1269  *      to create an appropriate command line prompt. It also generates
1270  *      a bit map of the permissible operations on this page which is
1271  *      used by the keyboard-input handler routines.
1272  *
1273  * Returns:
1274  *      Success: page-type (bit map of permissible operations)
1275  *      Failure: -1
1276  *----------------------------------------------------------------------*/
1277
1278 int
1279 resolve_CmdLine(a_buffer, a_currFrame, a_currPage, a_numPages, 
1280                 a_numCols, a_curr_LCol, a_cols_perPage, a_Data_Available)
1281 char *a_buffer;         /* buffer to copy command line */
1282 int a_currFrame;        /* current frame ovw, fs or cm? */
1283 int a_currPage;         /* current page number */
1284 int a_numPages;         /* number of pages of data */
1285 int a_numCols;          /* number of columns of data to display */
1286 int a_curr_LCol;        /* current number of leftmost column */
1287 int a_cols_perPage;     /* number of columns per page */
1288
1289 {       /* resolve_CmdLine */
1290    static char rn[] = "resolve_CmdLine";
1291    int pageType;
1292
1293     if (afsmon_debug) {
1294         fprintf(debugFD,"[ %s ] Called, a_buffer= %d, a_currFrame= %d, a_currPage= %d, a_numPages= %d, a_numCols= %d, a_curr_LCol= %d, a_cols_perPage= %d\n",
1295         rn, a_buffer, a_currFrame, a_currPage, a_numPages, a_numCols, 
1296         a_curr_LCol, a_cols_perPage);
1297         fflush(debugFD);
1298     }
1299
1300    pageType = 0;
1301
1302    /* determine if we have fs/cm frames. If we do, note that we should not
1303       let the user seen the initial junk we have there until the probe
1304       results are available  */
1305    if (a_currFrame == 1) {              /* in the fs frame */
1306         if (numCM && cm_Data_Available) pageType |= CMD_CM;
1307    } else if (a_currFrame == 2)  {      /* in the cm frame */
1308         if (numFS && fs_Data_Available) pageType |= CMD_FS;
1309    } else {
1310         if (afsmon_debug) {
1311                 fprintf(debugFD,"[ %s ] Wrong frame type %d\n",rn,a_currFrame);
1312                 fflush(debugFD);
1313         }
1314         return(-1);
1315    }
1316
1317    /* do we have next/previous pages */
1318    if ( a_currPage < a_numPages )
1319         pageType |= CMD_NEXT;   /* have a next page */
1320    if ( a_currPage > 1 )
1321         pageType |= CMD_PREV;   /* have a previous page */
1322    
1323    if ( a_numCols > a_cols_perPage ) {
1324         if ( a_curr_LCol > 0 )
1325                 pageType |= CMD_LEFT;   /* have columns on left */
1326         if ( (a_curr_LCol + a_cols_perPage )  < a_numCols )
1327                 pageType |= CMD_RIGHT;  /* have columns on right */
1328    }
1329                 
1330    /* now build the command line */
1331
1332    strcpy(a_buffer,"Command [oview");
1333    if ( pageType & CMD_FS)
1334         strcat(a_buffer,", fs");
1335    if ( pageType & CMD_CM)
1336         strcat(a_buffer,", cm");
1337    if ( pageType & CMD_PREV )
1338         strcat(a_buffer,", prev");      
1339    if ( pageType & CMD_NEXT )
1340         strcat(a_buffer,", next");      
1341    if ( pageType & CMD_LEFT )
1342         strcat(a_buffer,", left");      
1343    if ( pageType & CMD_RIGHT )
1344         strcat(a_buffer,", right");     
1345    strcat(a_buffer,"]? ");
1346
1347    return(pageType);
1348
1349 }       /* resolve_CmdLine */
1350
1351 /*-----------------------------------------------------------------------
1352  * display_Server_datum()
1353  *
1354  * Description:
1355  *      The data in the file server & cache manager frames are displayed
1356  *      in two objects, one below the other. If the data is too long to
1357  *      fit in the first object it will overflow into the next. This is
1358  *      to conserve real estate on the screen. This function copies the 
1359  *      contents of the source buffer adjusted to the two objects if the
1360  *      probe had succeded. Otherwise it enters "--" in the first object 
1361  *      blanks out the second. If the object needs to be highlightned
1362  *      (due to a threshold crossing) it is done.
1363  *
1364  * Returns:
1365  *      0 always
1366  *----------------------------------------------------------------------*/
1367 int
1368 display_Server_datum(a_srcBuf, a_firstObj_o, a_secondObj_o, 
1369                 a_probeOK, a_just, a_highlight)
1370
1371 char *a_srcBuf;                 /* source buffer */
1372 struct onode *a_firstObj_o;             /* first object */
1373 struct onode *a_secondObj_o;            /* second object */
1374 int a_probeOK;                  /* probe OK ? */
1375 int a_just;                     /* justification */
1376 int a_highlight;                /* highlight object  ? */
1377
1378 {       /* display_Server_datum */
1379
1380     static char rn[] = "display_Server_datum";
1381     struct gator_lightobj *tmp_lightobj1;
1382     struct gator_lightobj *tmp_lightobj2;
1383     char part1[FC_COLUMN_WIDTH+2];
1384     char part2[FC_COLUMN_WIDTH+2];
1385     int code;
1386
1387     if (afsmon_debug) {
1388         if (a_highlight)
1389         fprintf(debugFD,"[ %s ] Called, a_srcBuf= %s, a_firstObj_o= %d, a_secondObj_o= %d, a_probeOK= %d, a_just= %d, a_highlight= %d\n", rn, 
1390         a_srcBuf, a_firstObj_o, a_secondObj_o, a_probeOK, a_just, a_highlight);
1391         fflush(debugFD);
1392     }
1393
1394
1395     tmp_lightobj1 = (struct gator_lightobj *) a_firstObj_o->o_data;
1396     tmp_lightobj2 = (struct gator_lightobj *) a_secondObj_o->o_data;
1397
1398     if (a_probeOK) {    /* probe is ok so fill in the data */
1399
1400         /* check if it would fit in one object */
1401         if (strlen(a_srcBuf) < FC_COLUMN_WIDTH) {
1402                 strcpy(part1, a_srcBuf );
1403                 strcpy(part2, "");
1404         } else {
1405                 /* break up the src string into 2 parts */
1406                 /* note that column width includes terminator */
1407                 strncpy(part1, a_srcBuf, FC_COLUMN_WIDTH-1);
1408                 part1[FC_COLUMN_WIDTH-1] = '\0';
1409                 strncpy(part2, a_srcBuf+FC_COLUMN_WIDTH-1, FC_COLUMN_WIDTH-1);
1410
1411         }
1412
1413    } else {     /* probe failed, enter "--"s */
1414         strcpy(part1,"--");
1415         strcpy(part2,"");
1416    }
1417
1418    /* if (afsmon_debug) {
1419         fprintf(debugFD,"[ %s ] %s split to %s & %s\n",rn,a_srcBuf,part1,part2);
1420         fflush(debugFD);
1421    } */
1422
1423    /* initialize both the objects */
1424
1425    code = justify_light(part1, tmp_lightobj1->label,
1426                 FC_COLUMN_WIDTH, a_just, 1);
1427    if (code) {
1428         if (afsmon_debug) {
1429         fprintf(debugFD,"[ %s ] justify_light failed 1 \n",rn);
1430         fflush(debugFD);
1431         }
1432    }
1433
1434    code = justify_light(part2, tmp_lightobj2->label,
1435         FC_COLUMN_WIDTH, a_just, 1);
1436    if (code) {
1437         if (afsmon_debug) {
1438         fprintf(debugFD,"[ %s ] justify_light failed 1 \n",rn);
1439         fflush(debugFD);
1440         }
1441    }
1442
1443    /* highlight them */
1444    if (a_highlight && (part1[0] != '-'))
1445         gator_light_set(a_firstObj_o, 1);
1446    else
1447         gator_light_set(a_firstObj_o, 0);
1448    if (a_highlight && (part2[0] != '\0'))
1449         gator_light_set(a_secondObj_o, 1);
1450    else
1451         gator_light_set(a_secondObj_o, 0);
1452         
1453
1454
1455    return(0);
1456
1457 }       /* display_Server_datum */
1458
1459
1460 /*-----------------------------------------------------------------------
1461  * display_Server_label()
1462  *
1463  * Description:
1464  *      Display the given server label in three objects. The label is
1465  *      partitioned into three parts by '/'s and each part is copied
1466  *      into each label object.
1467  *
1468  * Returns:
1469  *      0 always.
1470  *----------------------------------------------------------------------*/
1471
1472 int
1473 display_Server_label(a_srcBuf, a_firstObj_o, a_secondObj_o, a_thirdObj_o)
1474 char *a_srcBuf;
1475 struct onode *a_firstObj_o;             /* first object */
1476 struct onode *a_secondObj_o;            /* second object */
1477 struct onode *a_thirdObj_o;             /* third object */
1478
1479 {       /* display_Server_label */
1480
1481    static char rn[] = "display_Server_label";
1482    char part[3][20];            /* buffer for three parts of label */
1483    char *strPtr;
1484    struct gator_lightobj *tmp_lightobj;
1485    struct onode *objPtr_o[3];
1486    int code;
1487    int strLen;
1488    int len;
1489    int i;
1490    int j;
1491
1492 /* the following debug statement floods the debug file */
1493 #ifdef DEBUG_DETAILED
1494     if (afsmon_debug) {
1495         fprintf(debugFD,"[ %s ] Called, a_srcBuf= %s, a_firstObj_o= %d, a_secondObj_o= %d, a_thirdObj_o= %d\n",
1496         rn, a_srcBuf, a_firstObj_o, a_secondObj_o, a_thirdObj_o);
1497         fflush(debugFD);
1498     }
1499 #endif
1500
1501
1502    /* break the label string into three parts */
1503
1504    part[0][0] = '\0'; part[1][0] = '\0'; part[2][0] = '\0';
1505    /* now for a dumb precaution */
1506
1507    strLen = strlen(a_srcBuf);
1508    len = 0;
1509    strPtr = a_srcBuf;
1510    for(i=0; i < 3; i++) {
1511         j = 0;
1512         while (*strPtr != '\0' && (len++ <= strLen)) {
1513                 if (*strPtr == '/') {
1514                         strPtr++; 
1515                         break;
1516                 }
1517                 else part[i][j] = *strPtr;
1518                 strPtr++;
1519                 j++;
1520         }
1521         part[i][j] = '\0';
1522    }
1523         
1524    /* 
1525    if (afsmon_debug) {
1526         fprintf(debugFD,"[ %s ] LABELS %s -> %s %s %s\n",
1527                 rn, a_srcBuf, part[0], part[1], part[2]);
1528         fflush(debugFD);
1529    }
1530    */
1531
1532    objPtr_o[0] = a_firstObj_o;
1533    objPtr_o[1] = a_secondObj_o;
1534    objPtr_o[2] = a_thirdObj_o;
1535
1536    /* display each label justified CENTER */
1537
1538    for (i = 0; i < 3; i++) {
1539    tmp_lightobj = (struct gator_lightobj *) objPtr_o[i]->o_data;
1540         code = justify_light(part[i], tmp_lightobj->label,
1541                 FC_COLUMN_WIDTH, CENTER, 1);
1542         if (code) {
1543                 if (afsmon_debug) {
1544                 fprintf(debugFD,"[ %s ] justify_light %d failed \n",rn,i);
1545                 fflush(debugFD);
1546                 }
1547         }
1548    }
1549
1550 }       /* display_Server_label */
1551
1552
1553
1554
1555
1556 /*-----------------------------------------------------------------------
1557  * fs_refresh()
1558  *
1559  * Description:
1560  *      Refresh the File Servers screen with the given page number starting
1561  *      at the given left-column number. The appropriate contents of 
1562  *      prev_fsData are displayed. 
1563  *      First the status labels at the four corners of the screen are
1564  *      updated. Next the column labels are updated and then each row
1565  *      of statistics.
1566  *      
1567  * Returns:
1568  *      Success: 0
1569  *      Failure: Exits afsmoitor on a severe error.
1570  *----------------------------------------------------------------------*/
1571
1572
1573 int
1574 fs_refresh(a_pageNum, a_LcolNum)
1575 int a_pageNum;          /* page to display */
1576 int a_LcolNum;          /* starting (leftmost) column number */
1577
1578 {       /* fs_refresh */
1579
1580    static char rn[] = "fs_refresh";     /* routine name */
1581    struct gator_lightobj *tmp_lightobj; /* ptr for object's display data */
1582    struct fs_Display_Data *fsDataP;     /* ptr to FS display data array */
1583    struct ServerInfo_line *tmp_fs_lines_P;      /* tmp ptr to fs_lines */
1584    struct onode **firstSlot_o_Ptr;      /* ptr to first data slot of a datum */
1585    struct onode **secondSlot_o_Ptr;     /* ptr to second data slot of a datum */
1586    struct onode **fsLabels_o_Ptr1;      /* ptr to label row 0 */
1587    struct onode **fsLabels_o_Ptr2;      /* ptr to label row 1 */
1588    struct onode **fsLabels_o_Ptr3;      /* ptr to label row 2 */
1589    char cmdLine[80];                    /* buffer for command line */
1590    char printBuf[256];                  /* buffer to print to screen */
1591    int i;
1592    int j;
1593    int k;
1594    int code;
1595    int fsIdx;
1596    int labelIdx;
1597    int dataIndex;                       /* index to the data[] field of 
1598                                         struct fs_Display_Data */
1599
1600    if (afsmon_debug) {
1601         fprintf(debugFD,"[ %s ] Called with row %d col %d \n",
1602                 rn, a_pageNum, a_LcolNum);
1603         fflush(debugFD);
1604    }
1605
1606
1607    /* if the data is not yet available, ie., not one probe cycle has 
1608    completed, do nothing */
1609
1610    if (! fs_Data_Available)
1611         return(0);
1612
1613
1614   /* validate the page number & column number */
1615   if (a_pageNum < 1 || a_pageNum > fs_numPages) {
1616         if (afsmon_debug) {
1617         fprintf(debugFD,"[ %s ] Called with wrong page # %d \n",rn, a_pageNum);
1618         fflush(debugFD);
1619         }
1620         afsmon_Exit(315);
1621    }
1622   if (a_LcolNum < 0 || a_LcolNum > fs_numCols) {
1623         if (afsmon_debug) {
1624         fprintf(debugFD,"[ %s ] Called with wrong column #%d\n",rn, a_LcolNum);
1625         fflush(debugFD);
1626         }
1627         afsmon_Exit(320);
1628    }
1629
1630    
1631
1632    /* update the fixed labels */
1633
1634    /* we reuse the ovw version lable and hence do not have to do anything
1635    for it here */
1636
1637    /* page number label */
1638    tmp_lightobj=(struct gator_lightobj *) fs_pageNum_o->o_data;
1639    sprintf(printBuf,"[File Servers, p. %d of %d, c. %d of %d]",
1640                 a_pageNum, fs_numPages, a_LcolNum +1, fs_numCols);      
1641    justify_light(printBuf,tmp_lightobj->label, FC_PAGENUM_O_WIDTH, 
1642                 RIGHT_JUSTIFY,1);
1643    gator_light_set(fs_pageNum_o,1);
1644
1645    /* file servers monitored label */
1646    tmp_lightobj=(struct gator_lightobj *) fs_numFS_o->o_data;
1647    sprintf(printBuf,"%d File Servers monitored, %d alerts on %d machines",
1648                 numFS, num_fs_alerts, numHosts_onfs_alerts);
1649    justify_light(printBuf,tmp_lightobj->label, FC_NUMHOSTS_O_WIDTH, CENTER,1);
1650    
1651
1652    /* command line */
1653
1654    /* figure out what we need to show in the prompt & set the page type */
1655    /* the fs_pageType variable is in turn used by the keyboard handler 
1656    routines to call fs_refresh() with the correct parameters */
1657
1658    fs_pageType = resolve_CmdLine( cmdLine, 1 /* fs frame*/, a_pageNum,
1659                 fs_numPages, fs_numCols, a_LcolNum, fs_cols_perPage);
1660
1661    /* display the command line */
1662    tmp_lightobj=(struct gator_lightobj *) fs_cmd_o->o_data;
1663    sprintf(printBuf,"%s", cmdLine);
1664    justify_light(printBuf,tmp_lightobj->label, strlen(printBuf)+1, 
1665                 LEFT_JUSTIFY,1);
1666    gator_light_set(fs_cmd_o, 1);
1667         
1668    /* update the probe number label */
1669    tmp_lightobj=(struct gator_lightobj *) fs_probeNum_o->o_data;
1670    sprintf(printBuf,"[FS probes %d, freq=%d sec]", 
1671         afsmon_fs_prev_probeNum, afsmon_probefreq);
1672    justify_light(printBuf,tmp_lightobj->label, FC_PROBENUM_O_WIDTH, 
1673                 RIGHT_JUSTIFY,1);
1674    gator_light_set(fs_probeNum_o, 1);
1675         
1676    /* update "columns on left" signal */
1677    tmp_lightobj=(struct gator_lightobj *) fs_leftArrows_o->o_data;
1678    if (fs_pageType & CMD_LEFT)
1679         strcpy(printBuf, "<<<");
1680    else
1681         strcpy(printBuf,"");
1682    justify_light(printBuf,tmp_lightobj->label, FC_ARROWS_O_WIDTH, 
1683                 LEFT_JUSTIFY,1);
1684    gator_light_set(fs_leftArrows_o, 0);
1685         
1686    /* update "columns on right" signal */
1687    tmp_lightobj=(struct gator_lightobj *) fs_rightArrows_o->o_data;
1688    if (fs_pageType & CMD_RIGHT)
1689         strcpy(printBuf, ">>>");
1690    else
1691         strcpy(printBuf,"");
1692    justify_light(printBuf,tmp_lightobj->label, FC_ARROWS_O_WIDTH, 
1693                 RIGHT_JUSTIFY,1);
1694    gator_light_set(fs_rightArrows_o, 0);
1695
1696
1697
1698    /* UPDATE THE COLUMN LABELS */
1699
1700    /* the column index is also used to index the label arrays */
1701    labelIdx = a_LcolNum;
1702
1703    /* get the pointers to the three arrays of label onodes */
1704    fsLabels_o_Ptr1 = fsLabels_o[0];
1705    fsLabels_o_Ptr2 = fsLabels_o[1];
1706    fsLabels_o_Ptr3 = fsLabels_o[2];
1707
1708    for(k=0; k < fs_cols_perPage; k++) {
1709
1710         if (labelIdx < fs_numCols) {
1711                 dataIndex = fs_Display_map[labelIdx];
1712                 code = display_Server_label( fs_labels[dataIndex], 
1713                                 *fsLabels_o_Ptr1,
1714                                 *fsLabels_o_Ptr2,
1715                                 *fsLabels_o_Ptr3);
1716
1717                 labelIdx++;     /* next label */
1718         } else {
1719                 code = display_Server_label( "//", 
1720                                 *fsLabels_o_Ptr1,
1721                                 *fsLabels_o_Ptr2,
1722                                 *fsLabels_o_Ptr3);
1723         }
1724
1725         fsLabels_o_Ptr1++;      /* next onode in label row 1 */
1726         fsLabels_o_Ptr2++;      /* next onode in label row 2 */
1727         fsLabels_o_Ptr3++;      /* next onode in label row 3 */
1728
1729    }    /* labels for each column */
1730
1731
1732     /* UPDATE THE FILE SERVER STATISTICS */
1733
1734    /* move to the right spot in the FS display data array */
1735    fsDataP = prev_fsData;
1736    fsIdx = 0;
1737    for(i=0; i < ((a_pageNum-1) * fs_numHosts_perPage); i++) {
1738         fsDataP++;
1739         fsIdx++;
1740    }
1741    
1742    if (fsIdx >= numFS) {        /* whoops! screwed up */
1743         sprintf(errMsg,"[ %s ] Programming error 1\n", rn);
1744         afsmon_Exit(325);
1745    }
1746
1747    /* get the pointer to the first line of onodes of the file server frame */ 
1748    tmp_fs_lines_P = fs_lines;
1749
1750    for (i=0; i < fs_numHosts_perPage; i++) {
1751
1752
1753         /* if this is the last page we may not have file servers to fill up
1754         the page, so check the index */
1755         if (fsIdx < numFS) {    
1756
1757            if (fsDataP->hostName[0] == '\0') {
1758                 sprintf(errMsg,"[ %s ] empty fs display entry \n",rn);
1759                 afsmon_Exit(330);
1760                 }
1761
1762            /* display the hostname , first names only please! */
1763            
1764            sprintf(printBuf, fsDataP->hostName);
1765            for(j=0; j<strlen(printBuf); j++) {
1766                 if (printBuf[j] == '.') {
1767                         printBuf[j] = '\0';
1768                         break;
1769                 }
1770            }
1771
1772            tmp_lightobj=(struct gator_lightobj *)tmp_fs_lines_P->host_o->o_data;
1773            code = justify_light(printBuf,tmp_lightobj->label,
1774                 FC_HOSTNAME_O_WIDTH, LEFT_JUSTIFY, 1);
1775            if (code) {
1776                 fprintf(debugFD,"[ %s ] justify_code returned %d\n",rn, code);
1777                 fflush(debugFD);
1778            }
1779
1780            /* use the current column value to index into the fs_Display_map
1781            array to obtain the index of the item to display. check if its
1782            overflow flag is set and highlight if so. if the probe had failed
1783            enter "--" is all columns */
1784
1785            /* each host has two rows of slots for datums. get the pointers to 
1786            both the arrays */
1787
1788            firstSlot_o_Ptr = tmp_fs_lines_P->data_o[0];
1789            secondSlot_o_Ptr = tmp_fs_lines_P->data_o[1];
1790            fs_curr_RCol = a_LcolNum;    /* starting column number from which
1791                                 we are asked to display data */
1792
1793            for(j=0; j < fs_cols_perPage; j++) {         /* for each column */
1794
1795              /* if there is another column of data */
1796              if (fs_curr_RCol < fs_numCols) {
1797
1798                 dataIndex = fs_Display_map[fs_curr_RCol];
1799
1800                 code = display_Server_datum( fsDataP->data[dataIndex], 
1801                                 *firstSlot_o_Ptr,
1802                                 *secondSlot_o_Ptr,
1803                                 fsDataP->probeOK,
1804                                 RIGHT_JUSTIFY,
1805                                 fsDataP->threshOvf[dataIndex]);
1806
1807                 fs_curr_RCol++;
1808               } else    {       /* no more data, blank out columns */
1809                 code = display_Server_datum( "", 
1810                                 *firstSlot_o_Ptr,
1811                                 *secondSlot_o_Ptr,
1812                                 1,              /* probe ok */
1813                                 RIGHT_JUSTIFY,
1814                                 0);             /* no overflow */
1815                 }
1816
1817
1818                 firstSlot_o_Ptr++;              /* onode of next column */
1819                 secondSlot_o_Ptr++;             /* onode of next column */
1820
1821            }            /* for each column */
1822
1823            /* the loop could have taken the right-column-index one over,
1824            adjust it now */
1825            if (fs_curr_RCol == fs_numCols)
1826                 fs_curr_RCol--;
1827
1828         
1829         }               /* if fdIdx < numFS */
1830         
1831
1832         /* if fsIdx >= numFS , blank out all succeding rows */
1833
1834         if (fsIdx >= numFS) {
1835            
1836            /* blank out host name object */
1837            tmp_lightobj=(struct gator_lightobj *)tmp_fs_lines_P->host_o->o_data;
1838            code = justify_light("",tmp_lightobj->label,
1839                 FC_HOSTNAME_O_WIDTH, LEFT_JUSTIFY, 1);
1840            if (code) {
1841                 fprintf(debugFD,"[ %s ] justify_code returned %d\n",rn, code);
1842                 fflush(debugFD);
1843            }
1844
1845            firstSlot_o_Ptr = tmp_fs_lines_P->data_o[0];
1846            secondSlot_o_Ptr = tmp_fs_lines_P->data_o[1];
1847
1848            for (k=0; k<fs_cols_perPage; k++) {
1849                 code = display_Server_datum( "", 
1850                                 *firstSlot_o_Ptr,
1851                                 *secondSlot_o_Ptr,
1852                                 1,                      /* probe OK */
1853                                 RIGHT_JUSTIFY,
1854                                 0);                     /* dont highlight*/
1855
1856                 firstSlot_o_Ptr++;
1857                 secondSlot_o_Ptr++;
1858            }
1859
1860         }       /* fsIDx >= numFS */
1861
1862
1863        tmp_fs_lines_P++;        /* pointer to next line in the frame */
1864        fsDataP++;       /* next host's data */
1865        fsIdx++;         /* host index */
1866
1867
1868    }    /* for each row in the File Servers frame */
1869
1870    /* redraw the display if the File Servers screen is currently displayed */
1871    if(afsmon_win->w_frame == fsFrame)
1872         WOP_DISPLAY(afsmon_win);
1873
1874    /* update the global page & column numbers to reflect the changes */
1875    fs_currPage = a_pageNum;
1876    fs_curr_LCol = a_LcolNum;;
1877
1878    return(0);
1879
1880 }       /* fs_refresh */
1881
1882
1883
1884
1885 /*-----------------------------------------------------------------------
1886  * Switch_fs_2_ovw()
1887  *
1888  * Description:
1889  *      Switch from the File Server screen to the Overview Screen
1890  *----------------------------------------------------------------------*/
1891 int
1892 Switch_fs_2_ovw()
1893 {
1894    /* bind the overview frame to the window */
1895    gtxframe_SetFrame(afsmon_win,ovwFrame);
1896    return(0);
1897 }
1898
1899 /*-----------------------------------------------------------------------
1900  * Switch_fs_2_cm()
1901  *
1902  * Description:
1903  *      Switch from the File Server screen to the Cache Managers screen. 
1904  *----------------------------------------------------------------------*/
1905 int
1906 Switch_fs_2_cm()
1907 {
1908    if (fs_pageType & CMD_CM) {
1909         /* bind the overview Cache Managers to the window */
1910         gtxframe_SetFrame(afsmon_win,cmFrame);
1911    }
1912         return(0);
1913 }
1914
1915 /*-----------------------------------------------------------------------
1916  * Switch_fs_next()
1917  *
1918  * Description:
1919  *      Switch to next page of file server screen 
1920  *----------------------------------------------------------------------*/
1921 int
1922 Switch_fs_next()
1923 {
1924    static char rn[] = "Switch_fs_next";
1925
1926    if (fs_pageType & CMD_NEXT) {
1927         /* we have a next page, refresh with next page number */
1928         fs_refresh(fs_currPage+1, fs_curr_LCol);
1929   }
1930
1931   return(0);
1932 }
1933
1934 /*-----------------------------------------------------------------------
1935  * Switch_fs_last()
1936  *
1937  * Description:
1938  *      Switch to last page of file server screen 
1939  *----------------------------------------------------------------------*/
1940 int
1941 Switch_fs_last()
1942 {
1943    static char rn[] = "Switch_fs_last";
1944
1945
1946    if (fs_pageType & CMD_NEXT) {
1947         /* we have a next page, refresh with the last page number */
1948         fs_refresh(fs_numPages, fs_curr_LCol);
1949   }
1950
1951   return(0);
1952 }
1953
1954 /*-----------------------------------------------------------------------
1955  * Switch_fs_prev()
1956  *
1957  * Description:
1958  *      Switch to previous page of file server screen 
1959  *----------------------------------------------------------------------*/
1960 int
1961 Switch_fs_prev()
1962 {
1963    static char rn[] = "Switch_fs_prev";
1964
1965    if (fs_pageType & CMD_PREV) {
1966         /* we have a previous page, refresh with the rpevious page number */
1967         fs_refresh(fs_currPage -1, fs_curr_LCol);
1968   }
1969         return(0);
1970 }
1971
1972 /*-----------------------------------------------------------------------
1973  * Switch_fs_first()
1974  *
1975  * Description:
1976  *      Switch to first page of file server screen 
1977  *----------------------------------------------------------------------*/
1978 int
1979 Switch_fs_first()
1980 {
1981    static char rn[] = "Switch_fs_first";
1982
1983    if (fs_pageType & CMD_PREV) {
1984         /* we have a previous page, got to first page */
1985         fs_refresh(1 , fs_curr_LCol);
1986   }
1987         return(0);
1988 }
1989
1990 /*-----------------------------------------------------------------------
1991  * Switch_fs_left()
1992  *
1993  * Description:
1994  *      Scroll left on the file server screen 
1995  *----------------------------------------------------------------------*/
1996 int
1997 Switch_fs_left()
1998 {
1999    static char rn[] = "Switch_fs_left";
2000
2001    if (fs_pageType & CMD_LEFT) {
2002         /* we have columns on left, refresh with new column number */
2003         fs_refresh(fs_currPage, fs_curr_LCol - fs_cols_perPage);
2004    }
2005    return(0);
2006 }
2007
2008
2009 /*-----------------------------------------------------------------------
2010  * Switch_fs_leftmost()
2011  *
2012  * Description:
2013  *      Scroll to first column on  the file server screen 
2014  *----------------------------------------------------------------------*/
2015 int
2016 Switch_fs_leftmost()
2017 {
2018    static char rn[] = "Switch_fs_leftmost";
2019
2020    if (fs_pageType & CMD_LEFT) {
2021         /* we have columns on left, go to the first */
2022         fs_refresh(fs_currPage, 0);
2023    }
2024    return(0);
2025 }
2026
2027 /*-----------------------------------------------------------------------
2028  * Switch_fs_right()
2029  *
2030  * Description:
2031  *      Scroll right on the file server screen 
2032  *----------------------------------------------------------------------*/
2033 int
2034 Switch_fs_right()
2035 {
2036    static char rn[] = "Switch_fs_right";
2037
2038    if (fs_pageType & CMD_RIGHT) {
2039         /* we have columns on right, refresh with new column number */
2040         fs_refresh(fs_currPage, fs_curr_LCol + fs_cols_perPage);
2041    }
2042         return(0);
2043 }
2044
2045 /*-----------------------------------------------------------------------
2046  * Switch_fs_rightmost()
2047  *
2048  * Description:
2049  *      Scroll to last column on the file server screen 
2050  *----------------------------------------------------------------------*/
2051 int
2052 Switch_fs_rightmost()
2053 {
2054    static char rn[] = "Switch_fs_rightmost";
2055    int curr_LCol;
2056
2057
2058    if (fs_pageType & CMD_RIGHT) {
2059         /* we have columns on right, go to the last column */
2060         if (fs_numCols % fs_cols_perPage)
2061            curr_LCol = (fs_numCols / fs_cols_perPage) * fs_cols_perPage;
2062         else
2063            curr_LCol = ((fs_numCols / fs_cols_perPage)-1) * fs_cols_perPage;
2064
2065         fs_refresh(fs_currPage, curr_LCol);
2066    }
2067         return(0);
2068 }
2069
2070
2071 /*-----------------------------------------------------------------------
2072  * create_FSframe_objects()
2073  *
2074  * Description:
2075  *      Create the gtx objects (onodes) for the Fileservers frame and setup
2076  *      the keyboard bindings.
2077  *      Only as many objects as can fit on the display are created. The
2078  *      positions and lengths of all these objects are fixed at creation.
2079  *      These objects are updated with new data at the end of each probe
2080  *      cycle.
2081  *
2082  * Returns:
2083  *      Success: 0
2084  *      Failure: Exits afsmonitor.
2085  *----------------------------------------------------------------------*/
2086
2087 int
2088 create_FSframe_objects()
2089 {       /* create_FSframe_objects */
2090    static char rn[] = "create_FSframe_objects";
2091    struct ServerInfo_line *fs_lines_Ptr;        
2092    struct onode **fs_data_o_Ptr;        
2093    struct onode **fsLabels_o_Ptr;
2094    int x_pos;
2095    int y_pos;
2096    int code;
2097    int i;
2098    int j;
2099    int numBytes;
2100    int arrIdx;
2101
2102
2103     if (afsmon_debug) {
2104         fprintf(debugFD,"[ %s ] Called\n",rn);
2105         fflush(debugFD);
2106     }
2107
2108    /* create the command line object */
2109    fs_cmd_o = initLightObject("Command [oview, cm, prev, next, left, right] ? ",
2110                 0,maxY-1,FC_CMD_O_WIDTH,afsmon_win);
2111    if (fs_cmd_o == NULL) {
2112         sprintf(errMsg,"[ %s ] Failed to create fs command onode\n",rn);
2113         afsmon_Exit(340);
2114    }
2115    code = gtxframe_AddToList(fsFrame,fs_cmd_o);
2116    code = gator_light_set(fs_cmd_o,HIGHLIGHT);
2117
2118    /* we already have the dimensions for the frame - same as the ovw frame */
2119    /* use the ovw program name object for the fs screen too */
2120
2121    code = gtxframe_AddToList(fsFrame, ovw_progName_o);
2122
2123
2124    /* create the page number object */
2125    fs_pageNum_o = initLightObject("[File Servers, p. X of X, c. Y of Y]",
2126                 maxX-FC_PAGENUM_O_WIDTH,0,FC_PAGENUM_O_WIDTH,afsmon_win);
2127    if (fs_pageNum_o == NULL) {
2128         sprintf(errMsg,"[ %s ] Failed to create pageNumber onode\n",rn);
2129         afsmon_Exit(335);
2130    }
2131    code = gtxframe_AddToList(fsFrame,fs_pageNum_o);
2132    code = gator_light_set(fs_pageNum_o,HIGHLIGHT);
2133    
2134    /* create the probe number object */
2135    fs_probeNum_o = initLightObject("[FS probes 1, freq=30 sec]",
2136         maxX-FC_PROBENUM_O_WIDTH ,maxY-1, FC_PROBENUM_O_WIDTH, afsmon_win);
2137    if (fs_probeNum_o == NULL) {
2138         sprintf(errMsg,"[ %s ] Failed to create fs probeNum onode\n",rn);
2139         afsmon_Exit(345);
2140    }
2141    code = gtxframe_AddToList(fsFrame,fs_probeNum_o);
2142    code = gator_light_set(fs_probeNum_o,HIGHLIGHT);
2143
2144
2145    /* create the numFS monitored object */
2146    fs_numFS_o = initLightObject(
2147                 "       0 File Servers monitored, 0 alerts on 0 machines",
2148                 4,2,FC_NUMHOSTS_O_WIDTH,afsmon_win);
2149    if (fs_numFS_o == NULL) {
2150         sprintf(errMsg,"[ %s ] Failed to create numFS onode for the fs frame\n",
2151                 rn);
2152         afsmon_Exit(350);
2153    }
2154    code = gtxframe_AddToList(fsFrame,fs_numFS_o);
2155
2156    /* create the "more columns to left" indicator */
2157    fs_leftArrows_o = initLightObject("<<<", 0,2,FC_ARROWS_O_WIDTH, afsmon_win);
2158    if (fs_leftArrows_o == NULL) {
2159         sprintf(errMsg,"[ %s ] Failed to create leftArrows onode for the fs frame\n", rn);
2160         afsmon_Exit(355);
2161    }
2162    code = gtxframe_AddToList(fsFrame,fs_leftArrows_o);
2163
2164    /* create the "more columns to right" indicator */
2165    fs_rightArrows_o = initLightObject(">>>", maxX-FC_ARROWS_O_WIDTH, 2,
2166                                 FC_ARROWS_O_WIDTH, afsmon_win);
2167    if (fs_rightArrows_o == NULL) {
2168         sprintf(errMsg,"[ %s ] Failed to create rightArrows onode for the fs frame\n", rn);
2169         afsmon_Exit(360);
2170    }
2171    code = gtxframe_AddToList(fsFrame,fs_rightArrows_o);
2172
2173
2174
2175
2176    /* calculate the maximum number of hosts per page (2 rows per host) */
2177    fs_numHosts_perPage = (maxY - FC_NUM_FIXED_LINES) / 2;       
2178
2179    /* determine the number of data columns that can fit in a page */
2180    fs_cols_perPage = (maxX - FC_HOSTNAME_O_WIDTH ) / (FC_COLUMN_WIDTH);
2181
2182    if (afsmon_debug) {
2183         fprintf(debugFD,"[ %s ] fs_numHosts_perPage=%d fs_cols_perPage=%d\n",
2184                 rn,fs_numHosts_perPage, fs_cols_perPage);
2185         fflush(debugFD);
2186    }
2187
2188    /* the above two variables give us the information needed to create
2189    the objects for displaying the file server information */
2190
2191    /* allocate memory for all the onode pointers required to display
2192    the file server statistics */
2193
2194    numBytes = fs_numHosts_perPage * sizeof(struct ServerInfo_line);
2195    fs_lines = (struct ServerInfo_line *) malloc(numBytes);
2196    if (fs_lines == (struct ServerInfo_line *)0) {
2197         sprintf(errMsg,"[ %s ] Failed to allocate %d bytes for FS data lines\n",
2198                 rn, numBytes);
2199         afsmon_Exit(365);
2200    }
2201
2202    /* for each line of server statistics allocate memory to store two arrays 
2203    of data onodes */
2204
2205    fs_lines_Ptr = fs_lines;
2206    for(i=0; i<fs_numHosts_perPage; i++) {
2207    for(arrIdx=0; arrIdx<2; arrIdx++) {
2208         numBytes = fs_cols_perPage * sizeof(struct onode *);
2209         fs_lines_Ptr->data_o[arrIdx] = (struct onode **) malloc(numBytes);
2210         if (fs_lines_Ptr->data_o[arrIdx] == NULL) {
2211         sprintf(errMsg,"[ %s ] Failed to allocate %d bytes for FS data onodes\n",
2212                 rn, numBytes);
2213         afsmon_Exit(370);
2214         }
2215    }
2216    fs_lines_Ptr++;
2217    }
2218
2219    /* now allocate the onodes itself */
2220
2221    fs_lines_Ptr = fs_lines;
2222    for(i=0; i<fs_numHosts_perPage; i++) {
2223
2224         /* initialize host name onode */
2225         fs_lines_Ptr->host_o = initLightObject("FSHostName",
2226                 0,FC_FIRST_HOST_ROW + 2*i, FC_HOSTNAME_O_WIDTH, afsmon_win);
2227         if (fs_lines_Ptr->host_o == NULL) {
2228                 sprintf(errMsg,"[ %s ] Failed to create an FS name onode\n",rn);
2229                 afsmon_Exit(375);
2230         }
2231         code = gtxframe_AddToList(fsFrame, fs_lines_Ptr->host_o);
2232
2233         /* if (afsmon_debug) {
2234                 fprintf(debugFD,"[ %s ] Addr of host_o = %d for line %d\n",
2235                         rn,fs_lines_Ptr->host_o,i);
2236                 fflush(debugFD);
2237         } */
2238
2239         /* initialize data onodes for this host */
2240
2241         for(arrIdx=0; arrIdx<2; arrIdx++) {     /* for each array index */
2242
2243         fs_data_o_Ptr = fs_lines_Ptr->data_o[arrIdx];
2244         for(j=0; j<fs_cols_perPage; j++) {      /* for each column */
2245
2246                 char tmpBuf[20];
2247
2248                 /* determine x & y coordinate for this data object */
2249                 /* the 1's are for leaving a blank after each column */
2250                 x_pos = FC_HOSTNAME_O_WIDTH + (j * (FC_COLUMN_WIDTH));
2251                 y_pos = FC_FIRST_HOST_ROW + 2*i + arrIdx;
2252
2253                 sprintf(tmpBuf,"-FSData %d-",arrIdx);
2254                 *fs_data_o_Ptr = initLightObject(tmpBuf,
2255                         x_pos, y_pos, FC_COLUMN_WIDTH, afsmon_win);
2256                 if (*fs_data_o_Ptr == NULL) {
2257                 sprintf(errMsg,"[ %s ] Failed to create an FS data onode\n",rn);
2258                 afsmon_Exit(380);
2259                 }
2260                 code = gtxframe_AddToList(fsFrame, *fs_data_o_Ptr);
2261
2262                 fs_data_o_Ptr++;
2263         }       /* for each column */
2264         }       /* for each onode array index */                        
2265
2266         fs_lines_Ptr++; 
2267    }    /* for each host slot */
2268
2269
2270    /* INITIALIZE COLUMN LABELS */
2271
2272
2273    /* allocate memory for two arrays of onode pointers for file server column
2274    labels */
2275    for( arrIdx=0; arrIdx < 3; arrIdx++) {
2276
2277    fsLabels_o[arrIdx] = (struct onode **) malloc(
2278                         sizeof(struct onode *) * fs_cols_perPage); 
2279    if (fsLabels_o[arrIdx] == NULL) {
2280         sprintf(errMsg,"[ %s ] Failed to allocate memory for FS label onodes\n",
2281                 rn);
2282         afsmon_Exit(385);
2283    }
2284
2285    /* create cache manager name objects */
2286    fsLabels_o_Ptr = fsLabels_o[arrIdx];
2287    for (i=0; i< fs_cols_perPage; i++) {
2288         *fsLabels_o_Ptr = initLightObject("",
2289                 FC_HOSTNAME_O_WIDTH + i * FC_COLUMN_WIDTH,
2290                 FC_FIRST_LABEL_ROW + arrIdx, 
2291                 FC_COLUMN_WIDTH,afsmon_win);
2292
2293         if (*fsLabels_o_Ptr == NULL) {
2294                 sprintf(errMsg,"[ %s ] Failed to create a FS label onode\n",rn);
2295                 afsmon_Exit(390);
2296         }
2297         code = gtxframe_AddToList(fsFrame,*fsLabels_o_Ptr);
2298         fsLabels_o_Ptr++;
2299    }
2300
2301    }
2302
2303
2304    /* initialize the column & page counters */
2305
2306    fs_currPage = 1;             
2307    fs_numCols = fs_DisplayItems_count;  
2308    fs_numPages = numFS / fs_numHosts_perPage;
2309    if (numFS % fs_numHosts_perPage)
2310         fs_numPages++;
2311    fs_curr_LCol = 0;    /* leftmost col */
2312    fs_curr_RCol = 0;    /* rightmost col */
2313
2314    /* create keyboard bindings */
2315    /* bind Q and \ 3 to exit */
2316    keymap_BindToString(fsFrame->keymap,"Q",afsmonExit_gtx,NULL,NULL);
2317    keymap_BindToString(fsFrame->keymap,"\ 3",afsmonExit_gtx,NULL,NULL);
2318
2319    /* o = overview, c = cm, n = next, p = prev, l = left, r = right 
2320       N = last page, P = first page, L = leftmost col, R = rightmost col */
2321
2322    keymap_BindToString(fsFrame->keymap,"o",Switch_fs_2_ovw,NULL,NULL);
2323    keymap_BindToString(fsFrame->keymap,"c",Switch_fs_2_cm,NULL,NULL);
2324    keymap_BindToString(fsFrame->keymap,"n",Switch_fs_next,NULL,NULL);
2325    keymap_BindToString(fsFrame->keymap,"N",Switch_fs_last,NULL,NULL);
2326    keymap_BindToString(fsFrame->keymap,"p",Switch_fs_prev,NULL,NULL);
2327    keymap_BindToString(fsFrame->keymap,"P",Switch_fs_first,NULL,NULL);
2328    keymap_BindToString(fsFrame->keymap,"l",Switch_fs_left,NULL,NULL);
2329    keymap_BindToString(fsFrame->keymap,"L",Switch_fs_leftmost,NULL,NULL);
2330    keymap_BindToString(fsFrame->keymap,"r",Switch_fs_right,NULL,NULL);
2331    keymap_BindToString(fsFrame->keymap,"R",Switch_fs_rightmost,NULL,NULL);
2332
2333    return(0);
2334 }       /* create_FSframe_objects */
2335
2336
2337 /*-----------------------------------------------------------------------
2338  * Function:    cm_refresh()
2339  *
2340  * Description:
2341  *      Refresh the Cache Managers screen with the given page number starting
2342  *      at the given left-column number. The appropriate contents of 
2343  *      prev_cmData are displayed. 
2344  *      First the status labels at the four corners of the screen are
2345  *      updated. Next the column labels are updated and then each row
2346  *      of statistics.
2347  *      
2348  * Returns:
2349  *      Success: 0
2350  *      Failure: Exits afsmoitor on a severe error.
2351  *----------------------------------------------------------------------*/
2352
2353 int
2354 cm_refresh(a_pageNum, a_LcolNum)
2355 int a_pageNum;          /* page to display */
2356 int a_LcolNum;          /* starting (leftmost) column number */
2357
2358 {       /* cm_refresh */
2359
2360    static char rn[] = "cm_refresh";     /* routine name */
2361    struct gator_lightobj *tmp_lightobj; /* ptr for object's display data */
2362    struct cm_Display_Data *cmDataP;     /* ptr to CM display data array */
2363    struct ServerInfo_line *tmp_cm_lines_P;      /* tmp ptr to cm_lines */
2364    struct onode **firstSlot_o_Ptr;      /* ptr to first data slot of a datum */
2365    struct onode **secondSlot_o_Ptr;     /* ptr to second data slot of a datum */
2366    struct onode **cmLabels_o_Ptr1;      /* ptr to label row 0 */
2367    struct onode **cmLabels_o_Ptr2;      /* ptr to label row 1 */
2368    struct onode **cmLabels_o_Ptr3;      /* ptr to label row 2 */
2369    char cmdLine[80];                    /* buffer for command line */
2370    char printBuf[256];                  /* buffer to print to screen */
2371    int i;
2372    int j;
2373    int k;
2374    int code;
2375    int cmIdx;
2376    int labelIdx;
2377    int dataIndex;                       /* index to the data[] field of 
2378                                         struct cm_Display_Data */
2379
2380    if (afsmon_debug) {
2381         fprintf(debugFD,"[ %s ] Called, a_pageNum= %d, a_LcolNum= %d \n",
2382                 rn, a_pageNum, a_LcolNum);
2383         fflush(debugFD);
2384    }
2385
2386
2387    /* if the data is not yet available, ie., not one probe cycle has 
2388    completed, do nothing */
2389
2390    if (! cm_Data_Available)
2391         return(0);
2392
2393
2394   /* validate the page number & column number */
2395   if (a_pageNum < 1 || a_pageNum > cm_numPages) {
2396         if (afsmon_debug) {
2397         fprintf(debugFD,"[ %s ] Called with wrong page # %d \n",rn, a_pageNum);
2398         fflush(debugFD);
2399         }
2400         afsmon_Exit(395);
2401    }
2402   if (a_LcolNum < 0 || a_LcolNum > cm_numCols) {
2403         if (afsmon_debug) {
2404         fprintf(debugFD,"[ %s ] Called with wrong column #%d\n",rn, a_LcolNum);
2405         fflush(debugFD);
2406         }
2407         afsmon_Exit(400);
2408    }
2409
2410    
2411
2412    /* update the fixed labels */
2413
2414    /* we reuse the ovw version lable and hence do not have to do anything
2415    for it here */
2416
2417    /* page number label */
2418    tmp_lightobj=(struct gator_lightobj *) cm_pageNum_o->o_data;
2419    sprintf(printBuf,"[Cache Managers, p.%d of %d, c.%d of %d]",
2420                 a_pageNum, cm_numPages, a_LcolNum +1, cm_numCols);      
2421    justify_light(printBuf,tmp_lightobj->label, FC_PAGENUM_O_WIDTH, 
2422                 RIGHT_JUSTIFY,1);
2423    gator_light_set(cm_pageNum_o,1);
2424
2425    /* file servers monitored label */
2426    tmp_lightobj=(struct gator_lightobj *) cm_numCM_o->o_data;
2427    sprintf(printBuf,"%d Cache Managers monitored, %d alerts on %d machines",
2428                 numCM, num_cm_alerts, numHosts_oncm_alerts);
2429    justify_light(printBuf,tmp_lightobj->label, FC_NUMHOSTS_O_WIDTH, CENTER,1);
2430    
2431
2432    /* command line */
2433
2434    /* figure out what we need to show in the prompt & set the page type */
2435    /* the cm_pageType variable is in turn used by the keyboard handler 
2436    routines to call cm_refresh() with the correct parameters */
2437
2438    cm_pageType = resolve_CmdLine( cmdLine, 2 /* cm frame */, a_pageNum,
2439                 cm_numPages, cm_numCols, a_LcolNum, cm_cols_perPage);
2440
2441    /* display the command line */
2442    tmp_lightobj=(struct gator_lightobj *) cm_cmd_o->o_data;
2443    sprintf(printBuf,"%s", cmdLine);
2444    justify_light(printBuf,tmp_lightobj->label, strlen(printBuf)+1, 
2445                 LEFT_JUSTIFY,1);
2446    gator_light_set(cm_cmd_o, 1);
2447         
2448    /* update the probe number label */
2449    tmp_lightobj=(struct gator_lightobj *) cm_probeNum_o->o_data;
2450    sprintf(printBuf,"[CM probes %d, freq=%d sec]", 
2451         afsmon_cm_prev_probeNum, afsmon_probefreq);
2452    justify_light(printBuf,tmp_lightobj->label, FC_PROBENUM_O_WIDTH, 
2453                 RIGHT_JUSTIFY,1);
2454    gator_light_set(cm_cmd_o, 1);
2455         
2456    /* update "columns on left" signal */
2457    tmp_lightobj=(struct gator_lightobj *) cm_leftArrows_o->o_data;
2458    if (cm_pageType & CMD_LEFT)
2459         strcpy(printBuf, "<<<");
2460    else
2461         strcpy(printBuf,"");
2462    justify_light(printBuf,tmp_lightobj->label, FC_ARROWS_O_WIDTH, 
2463                 LEFT_JUSTIFY,1);
2464    gator_light_set(cm_leftArrows_o, 0);
2465         
2466    /* update "columns on right" signal */
2467    tmp_lightobj=(struct gator_lightobj *) cm_rightArrows_o->o_data;
2468    if (cm_pageType & CMD_RIGHT)
2469         strcpy(printBuf, ">>>");
2470    else
2471         strcpy(printBuf,"");
2472    justify_light(printBuf,tmp_lightobj->label, FC_ARROWS_O_WIDTH, 
2473                 RIGHT_JUSTIFY,1);
2474    gator_light_set(cm_rightArrows_o, 0);
2475
2476
2477
2478    /* UPDATE THE COLUMN LABELS */
2479
2480    /* the column index is also used to index the label arrays */
2481    labelIdx = a_LcolNum;
2482
2483    /* get the pointers to the three arrays of label onodes */
2484    cmLabels_o_Ptr1 = cmLabels_o[0];
2485    cmLabels_o_Ptr2 = cmLabels_o[1];
2486    cmLabels_o_Ptr3 = cmLabels_o[2];
2487
2488    for(k=0; k < cm_cols_perPage; k++) {
2489
2490         if (labelIdx < cm_numCols) {
2491                 dataIndex = cm_Display_map[labelIdx];
2492                 code = display_Server_label( cm_labels[dataIndex], 
2493                                 *cmLabels_o_Ptr1,
2494                                 *cmLabels_o_Ptr2,
2495                                 *cmLabels_o_Ptr3);
2496
2497                 labelIdx++;     /* next label */
2498         } else {
2499                 code = display_Server_label( "//", 
2500                                 *cmLabels_o_Ptr1,
2501                                 *cmLabels_o_Ptr2,
2502                                 *cmLabels_o_Ptr3);
2503         }
2504
2505         cmLabels_o_Ptr1++;      /* next onode in label row 1 */
2506         cmLabels_o_Ptr2++;      /* next onode in label row 2 */
2507         cmLabels_o_Ptr3++;      /* next onode in label row 3 */
2508
2509    }    /* labels for each column */
2510
2511
2512     /* UPDATE THE FILE SERVER STATISTICS */
2513
2514    /* move to the right spot in the CM display data array */
2515    cmDataP = prev_cmData;
2516    cmIdx = 0;
2517    for(i=0; i < ((a_pageNum-1) * cm_numHosts_perPage); i++) {
2518         cmDataP++;
2519         cmIdx++;
2520    }
2521    
2522    if (cmIdx >= numCM) {        /* whoops! screwed up */
2523         sprintf(errMsg,"[ %s ] Programming error 1\n", rn);
2524         afsmon_Exit(405);
2525    }
2526
2527    /* get the pointer to the first line of onodes of the file server frame */ 
2528    tmp_cm_lines_P = cm_lines;
2529
2530    for (i=0; i < cm_numHosts_perPage; i++) {
2531
2532
2533         /* if this is the last page we may not have file servers to fill up
2534         the page, so check the index */
2535         if (cmIdx < numCM) {    
2536
2537            if (cmDataP->hostName[0] == '\0') {
2538                 sprintf(errMsg,"[ %s ] empty cm display entry \n",rn);
2539                 afsmon_Exit(410);
2540                 }
2541
2542            /* display the hostname , first names only please! */
2543            
2544            sprintf(printBuf, cmDataP->hostName);
2545            for(j=0; j<strlen(printBuf); j++) {
2546                 if (printBuf[j] == '.') {
2547                         printBuf[j] = '\0';
2548                         break;
2549                 }
2550            }
2551
2552            tmp_lightobj=(struct gator_lightobj *)tmp_cm_lines_P->host_o->o_data;
2553            code = justify_light(printBuf,tmp_lightobj->label,
2554                 FC_HOSTNAME_O_WIDTH, LEFT_JUSTIFY, 1);
2555            if (code) {
2556                 fprintf(debugFD,"[ %s ] justify_code returned %d\n",rn, code);
2557                 fflush(debugFD);
2558            }
2559
2560            /* use the current column value to index into the cm_Display_map
2561            array to obtain the index of the item to display. check if its
2562            overflow flag is set and highlight if so. if the probe had failed
2563            enter "--" is all columns */
2564
2565            /* each host has two rows of slots for datums. get the pointers to 
2566            both the arrays */
2567
2568            firstSlot_o_Ptr = tmp_cm_lines_P->data_o[0];
2569            secondSlot_o_Ptr = tmp_cm_lines_P->data_o[1];
2570            cm_curr_RCol = a_LcolNum;    /* starting column number from which
2571                                 we are asked to display data */
2572
2573            for(j=0; j < cm_cols_perPage; j++) {         /* for each column */
2574
2575              /* if there is another column of data */
2576              if (cm_curr_RCol < cm_numCols) {
2577
2578                 dataIndex = cm_Display_map[cm_curr_RCol];
2579
2580                 code = display_Server_datum( cmDataP->data[dataIndex], 
2581                                 *firstSlot_o_Ptr,
2582                                 *secondSlot_o_Ptr,
2583                                 cmDataP->probeOK,
2584                                 RIGHT_JUSTIFY,
2585                                 cmDataP->threshOvf[dataIndex]);
2586
2587                 cm_curr_RCol++;
2588               } else    {       /* no more data, blank out columns */
2589                 code = display_Server_datum( "", 
2590                                 *firstSlot_o_Ptr,
2591                                 *secondSlot_o_Ptr,
2592                                 1,                      /* probe ok */
2593                                 RIGHT_JUSTIFY,
2594                                 0);                     /* no overflow */
2595                 }
2596
2597
2598                 firstSlot_o_Ptr++;              /* onode of next column */
2599                 secondSlot_o_Ptr++;             /* onode of next column */
2600
2601            }            /* for each column */
2602
2603            /* the loop could have taken the right-column-index one over,
2604            adjust it now */
2605            if (cm_curr_RCol == cm_numCols)
2606                 cm_curr_RCol--;
2607
2608         
2609         }               /* if fdIdx < numCM */
2610         
2611
2612         /* if cmIdx >= numCM , blank out all succeding rows */
2613
2614         if (cmIdx >= numCM) {
2615            
2616            /* blank out host name object */
2617            tmp_lightobj=(struct gator_lightobj *)tmp_cm_lines_P->host_o->o_data;
2618            code = justify_light("",tmp_lightobj->label,
2619                 FC_HOSTNAME_O_WIDTH, LEFT_JUSTIFY, 1);
2620            if (code) {
2621                 fprintf(debugFD,"[ %s ] justify_code returned %d\n",rn, code);
2622                 fflush(debugFD);
2623            }
2624
2625            firstSlot_o_Ptr = tmp_cm_lines_P->data_o[0];
2626            secondSlot_o_Ptr = tmp_cm_lines_P->data_o[1];
2627
2628            for (k=0; k<cm_cols_perPage; k++) {
2629                 code = display_Server_datum( "", 
2630                                 *firstSlot_o_Ptr,
2631                                 *secondSlot_o_Ptr,
2632                                 1,                      /* probe OK */
2633                                 RIGHT_JUSTIFY,
2634                                 0);                     /* dont highlight*/
2635
2636                 firstSlot_o_Ptr++;
2637                 secondSlot_o_Ptr++;
2638            }
2639
2640         }       /* cmIDx >= numCM */
2641
2642
2643        tmp_cm_lines_P++;        /* pointer to next line in the frame */
2644        cmDataP++;       /* next host's data */
2645        cmIdx++;         /* host index */
2646
2647
2648    }    /* for each row in the Cache Manager frame */
2649
2650    /* redraw the display if the Cache Managers screen is currently displayed*/
2651    if(afsmon_win->w_frame == cmFrame)
2652         WOP_DISPLAY(afsmon_win);
2653
2654    /* update the global page & column numbers to reflect the changes */
2655    cm_currPage = a_pageNum;
2656    cm_curr_LCol = a_LcolNum;;
2657
2658    return(0);
2659
2660 }       /* cm_refresh */
2661
2662
2663
2664 /*-----------------------------------------------------------------------
2665  * Switch_cm_2_ovw()
2666  *
2667  * Description:
2668  *      Switch from the Cache Manager screen to the Overview Screen
2669  *----------------------------------------------------------------------*/
2670 int
2671 Switch_cm_2_ovw()
2672 {
2673    /* bind the overview frame to the window */
2674    gtxframe_SetFrame(afsmon_win,ovwFrame);
2675    return(0);
2676 }
2677
2678 /*-----------------------------------------------------------------------
2679  * Switch_cm_2_fs()
2680  *
2681  * Description:
2682  *      Switch from the Cache Manager screen to the File Servers screen 
2683  *----------------------------------------------------------------------*/
2684 int
2685 Switch_cm_2_fs()
2686 {
2687    if (cm_pageType & CMD_FS) {
2688         /* bind the file servers frame to the window */
2689         gtxframe_SetFrame(afsmon_win,fsFrame);
2690    }
2691         return(0);
2692 }
2693
2694 /*-----------------------------------------------------------------------
2695  * Switch_cm_next()
2696  *
2697  * Description:
2698  *      Switch to next page of cache managers screen 
2699  *----------------------------------------------------------------------*/
2700 int
2701 Switch_cm_next()
2702 {
2703    static char rn[] = "Switch_cm_next";
2704
2705    if (cm_pageType & CMD_NEXT) {
2706         /* we have a next page, refresh with next page number */
2707         cm_refresh(cm_currPage+1, cm_curr_LCol);
2708   }
2709
2710   return(0);
2711 }
2712
2713 /*-----------------------------------------------------------------------
2714  * Switch_cm_last()
2715  *
2716  * Description:
2717  *      Switch to last page of file server screen 
2718  *----------------------------------------------------------------------*/
2719 int
2720 Switch_cm_last()
2721 {
2722    static char rn[] = "Switch_cm_last";
2723
2724
2725    if (cm_pageType & CMD_NEXT) {
2726         /* we have a next page, refresh with last page number */
2727         cm_refresh(cm_numPages, cm_curr_LCol);
2728   }
2729
2730   return(0);
2731 }
2732
2733 /*-----------------------------------------------------------------------
2734  * Switch_cm_prev()
2735  *
2736  * Description:
2737  *      Switch to previous page of cache managers screen 
2738  *----------------------------------------------------------------------*/
2739 int
2740 Switch_cm_prev()
2741 {
2742    static char rn[] = "Switch_cm_prev";
2743
2744    if (cm_pageType & CMD_PREV) {
2745         /* we have a previous page, refresh to previous page */
2746         cm_refresh(cm_currPage-1, cm_curr_LCol);
2747   }
2748         return(0);
2749 }
2750
2751 /*-----------------------------------------------------------------------
2752  * Switch_cm_first()
2753  *
2754  * Description:
2755  *      Switch to first page of cache managers screen 
2756  *----------------------------------------------------------------------*/
2757 int
2758 Switch_cm_first()
2759 {
2760    static char rn[] = "Switch_cm_first";
2761
2762    if (cm_pageType & CMD_PREV) {
2763         /* we have a previous page, refresh to first page */
2764         cm_refresh(1, cm_curr_LCol);
2765   }
2766         return(0);
2767 }
2768
2769 /*-----------------------------------------------------------------------
2770  * Switch_cm_left()
2771  *
2772  * Description:
2773  *      Scroll left on the cache managers screen 
2774  *----------------------------------------------------------------------*/
2775 int
2776 Switch_cm_left()
2777 {
2778    static char rn[] = "Switch_cm_left";
2779
2780    if (cm_pageType & CMD_LEFT) {
2781         /* we have columns on left, refresh with new column number */
2782         cm_refresh(cm_currPage, cm_curr_LCol - cm_cols_perPage);
2783    }
2784    return(0);
2785 }
2786
2787
2788 /*-----------------------------------------------------------------------
2789  * Switch_cm_leftmost()
2790  *
2791  * Description:
2792  *      Scroll to first column on  the cache managers screen 
2793  *----------------------------------------------------------------------*/
2794 int
2795 Switch_cm_leftmost()
2796 {
2797    static char rn[] = "Switch_cm_leftmost";
2798
2799    if (cm_pageType & CMD_LEFT) {
2800         /* we have columns on left, go to the first column */
2801         cm_refresh(cm_currPage, 0);
2802    }
2803    return(0);
2804 }
2805
2806 /*-----------------------------------------------------------------------
2807  * Switch_cm_right()
2808  *
2809  * Description:
2810  *      Scroll right on the cache managers screen 
2811  *----------------------------------------------------------------------*/
2812 int
2813 Switch_cm_right()
2814 {
2815    static char rn[] = "Switch_cm_right";
2816
2817    if (cm_pageType & CMD_RIGHT) {
2818         /* we have columns on right, refresh with new column number */
2819         cm_refresh(cm_currPage, cm_curr_LCol + cm_cols_perPage);
2820    }
2821         return(0);
2822 }
2823
2824 /*-----------------------------------------------------------------------
2825  * Switch_cm_rightmost()
2826  *
2827  * Description:
2828  *      Scroll to last column on the cache managers screen 
2829  *----------------------------------------------------------------------*/
2830 int
2831 Switch_cm_rightmost()
2832 {
2833    static char rn[] = "Switch_cm_rightmost";
2834    int curr_LCol;
2835
2836
2837    if (cm_pageType & CMD_RIGHT) {
2838         /* we have columns on right, go to the last column */
2839         if (cm_numCols % cm_cols_perPage) 
2840            curr_LCol = (cm_numCols / cm_cols_perPage) * cm_cols_perPage;
2841         else 
2842         curr_LCol = ((cm_numCols / cm_cols_perPage)-1) * cm_cols_perPage;
2843         cm_refresh(cm_currPage, curr_LCol);
2844    }
2845         return(0);
2846 }
2847
2848
2849 /*-----------------------------------------------------------------------
2850  * create_CMframe_objects()
2851  *
2852  * Description:
2853  *      Create the gtx objects (onodes) for the Cache Managers frame and setup
2854  *      the keyboard bindings.
2855  *      Only as many objects as can fit on the display are created. The
2856  *      positions and lengths of all these objects are fixed at creation.
2857  *      These objects are updated with new data at the end of each probe
2858  *      cycle.
2859  *
2860  * Returns:
2861  *      Success: 0
2862  *      Failure: Exits afsmonitor.
2863  *----------------------------------------------------------------------*/
2864
2865 int
2866 create_CMframe_objects()
2867 {       /* create_CMframe_objects */
2868    static char rn[] = "create_CMframe_objects";
2869    struct ServerInfo_line *cm_lines_Ptr;        
2870    struct onode **cm_data_o_Ptr;        
2871    struct onode **cmLabels_o_Ptr;
2872    int x_pos;
2873    int y_pos;
2874    int code;
2875    int i;
2876    int j;
2877    int numBytes;
2878    int arrIdx;
2879
2880     if (afsmon_debug) {
2881         fprintf(debugFD,"[ %s ] Called\n",rn);
2882         fflush(debugFD);
2883     }
2884
2885
2886
2887    /* create the command line object */
2888    cm_cmd_o = initLightObject("Command [oview, fs, prev, next, left, right] ? ",
2889                 0,maxY-1,FC_CMD_O_WIDTH,afsmon_win);
2890    if (cm_cmd_o == NULL) {
2891         sprintf(errMsg,"[ %s ] Failed to create cm command onode\n",rn);
2892         afsmon_Exit(420);
2893    }
2894    code = gtxframe_AddToList(cmFrame,cm_cmd_o);
2895    code = gator_light_set(cm_cmd_o,HIGHLIGHT);
2896
2897
2898    /* we already have the dimensions for the frame - same as the ovw frame */
2899    /* use the ovw program name object for the cm screen too */
2900
2901    code = gtxframe_AddToList(cmFrame, ovw_progName_o);
2902
2903
2904    /* create the page number object */
2905    cm_pageNum_o = initLightObject("[Cache Managers, p. X of X, c. Y of Y]",
2906                 maxX-FC_PAGENUM_O_WIDTH,0,FC_PAGENUM_O_WIDTH,afsmon_win);
2907    if (cm_pageNum_o == NULL) {
2908         sprintf(errMsg,"[ %s ] Failed to create pageNumber onode\n",rn);
2909         afsmon_Exit(415);
2910    }
2911    code = gtxframe_AddToList(cmFrame,cm_pageNum_o);
2912    code = gator_light_set(cm_pageNum_o,HIGHLIGHT);
2913    
2914    /* create the probe number object */
2915    cm_probeNum_o = initLightObject("[CM probes 1, freq=30 sec]",
2916         maxX-FC_PROBENUM_O_WIDTH ,maxY-1, FC_PROBENUM_O_WIDTH, afsmon_win);
2917    if (cm_probeNum_o == NULL) {
2918         sprintf(errMsg,"[ %s ] Failed to create cm probeNum onode\n",rn);
2919         afsmon_Exit(425);
2920    }
2921    code = gtxframe_AddToList(cmFrame,cm_probeNum_o);
2922    code = gator_light_set(cm_probeNum_o,HIGHLIGHT);
2923
2924
2925    /* create the numCM monitored object */
2926    cm_numCM_o = initLightObject(
2927                 "       0 Cache Mangers monitored, 0 alerts on 0 machines",
2928                 4,2,FC_NUMHOSTS_O_WIDTH,afsmon_win);
2929    if (cm_numCM_o == NULL) {
2930         sprintf(errMsg,"[ %s ] Failed to create numCM onode for the cm frame\n",
2931                 rn);
2932         afsmon_Exit(430);
2933    }
2934    code = gtxframe_AddToList(cmFrame,cm_numCM_o);
2935
2936    /* create the "more columns to left" indicator */
2937    cm_leftArrows_o = initLightObject("<<<", 0,2,FC_ARROWS_O_WIDTH, afsmon_win);
2938    if (cm_leftArrows_o == NULL) {
2939         sprintf(errMsg,"[ %s ] Failed to create leftArrows onode for the cm frame\n", rn);
2940         afsmon_Exit(435);
2941    }
2942    code = gtxframe_AddToList(cmFrame,cm_leftArrows_o);
2943
2944    /* create the "more columns to right" indicator */
2945    cm_rightArrows_o = initLightObject(">>>", maxX-FC_ARROWS_O_WIDTH, 2,
2946                                 FC_ARROWS_O_WIDTH, afsmon_win);
2947    if (cm_rightArrows_o == NULL) {
2948         sprintf(errMsg,"[ %s ] Failed to create rightArrows onode for the cm frame\n", rn);
2949         afsmon_Exit(440);
2950    }
2951    code = gtxframe_AddToList(cmFrame,cm_rightArrows_o);
2952
2953
2954
2955
2956    /* calculate the maximum number of hosts per page (2 rows per host) */
2957    cm_numHosts_perPage = (maxY - FC_NUM_FIXED_LINES) / 2;       
2958
2959    /* determine the number of data columns that can fit in a page */
2960    cm_cols_perPage = (maxX - FC_HOSTNAME_O_WIDTH ) / (FC_COLUMN_WIDTH);
2961
2962    if (afsmon_debug) {
2963         fprintf(debugFD,"[ %s ] cm_numHosts_perPage=%d cm_cols_perPage=%d\n",
2964                 rn,cm_numHosts_perPage, cm_cols_perPage);
2965         fflush(debugFD);
2966    }
2967
2968    /* the above two variables give us the information needed to create
2969    the objects for displaying the file server information */
2970
2971    /* allocate memory for all the onode pointers required to display
2972    the file server statistics */
2973
2974    numBytes = cm_numHosts_perPage * sizeof(struct ServerInfo_line);
2975    cm_lines = (struct ServerInfo_line *) malloc(numBytes);
2976    if (cm_lines == (struct ServerInfo_line *)0) {
2977         sprintf(errMsg,"[ %s ] Failed to allocate %d bytes for CM data lines\n",
2978                 rn, numBytes);
2979         afsmon_Exit(445);
2980    }
2981
2982    /* for each line of server statistics allocate memory to store two arrays 
2983    of data onodes */
2984
2985    cm_lines_Ptr = cm_lines;
2986    for(i=0; i<cm_numHosts_perPage; i++) {
2987    for(arrIdx=0; arrIdx<2; arrIdx++) {
2988         numBytes = cm_cols_perPage * sizeof(struct onode *);
2989         cm_lines_Ptr->data_o[arrIdx] = (struct onode **) malloc(numBytes);
2990         if (cm_lines_Ptr->data_o[arrIdx] == NULL) {
2991         sprintf(errMsg,"[ %s ] Failed to allocate %d bytes for CM data onodes\n",
2992                 rn, numBytes);
2993         afsmon_Exit(450);
2994         }
2995    }
2996    cm_lines_Ptr++;
2997    }
2998
2999    /* now allocate the onodes itself */
3000
3001    cm_lines_Ptr = cm_lines;
3002    for(i=0; i<cm_numHosts_perPage; i++) {
3003
3004         /* initialize host name onode */
3005         cm_lines_Ptr->host_o = initLightObject("CMHostName",
3006                 0,FC_FIRST_HOST_ROW + 2*i, FC_HOSTNAME_O_WIDTH, afsmon_win);
3007         if (cm_lines_Ptr->host_o == NULL) {
3008                 sprintf(errMsg,"[ %s ] Failed to create an CM name onode\n",rn);
3009                 afsmon_Exit(455);
3010         }
3011         code = gtxframe_AddToList(cmFrame, cm_lines_Ptr->host_o);
3012
3013         /* if (afsmon_debug) {
3014                 fprintf(debugFD,"[ %s ] Addr of host_o = %d for line %d\n",
3015                         rn,cm_lines_Ptr->host_o,i);
3016                 fflush(debugFD);
3017         } */
3018
3019         /* initialize data onodes for this host */
3020
3021         for(arrIdx=0; arrIdx<2; arrIdx++) {     /* for each array index */
3022
3023         cm_data_o_Ptr = cm_lines_Ptr->data_o[arrIdx];
3024         for(j=0; j<cm_cols_perPage; j++) {      /* for each column */
3025
3026                 char tmpBuf[20];
3027
3028                 /* determine x & y coordinate for this data object */
3029                 /* the 1's are for leaving a blank after each column */
3030                 x_pos = FC_HOSTNAME_O_WIDTH + (j * (FC_COLUMN_WIDTH));
3031                 y_pos = FC_FIRST_HOST_ROW + 2*i + arrIdx;
3032
3033                 sprintf(tmpBuf,"-CMData %d-",arrIdx);
3034                 *cm_data_o_Ptr = initLightObject(tmpBuf,
3035                         x_pos, y_pos, FC_COLUMN_WIDTH, afsmon_win);
3036                 if (*cm_data_o_Ptr == NULL) {
3037                 sprintf(errMsg,"[ %s ] Failed to create an CM data onode\n",rn);
3038                 afsmon_Exit(460);
3039                 }
3040                 code = gtxframe_AddToList(cmFrame, *cm_data_o_Ptr);
3041
3042                 cm_data_o_Ptr++;
3043         }       /* for each column */
3044         }       /* for each onode array index */                        
3045
3046         cm_lines_Ptr++; 
3047    }    /* for each host slot */
3048
3049
3050    /* INITIALIZE COLUMN LABELS */
3051
3052
3053    /* allocate memory for two arrays of onode pointers for file server column
3054    labels */
3055    for( arrIdx=0; arrIdx < 3; arrIdx++) {
3056
3057    cmLabels_o[arrIdx] = (struct onode **) malloc(
3058                         sizeof(struct onode *) * cm_cols_perPage); 
3059    if (cmLabels_o[arrIdx] == NULL) {
3060         sprintf(errMsg,"[ %s ] Failed to allocate memory for CM label onodes\n",
3061                 rn);
3062         afsmon_Exit(465);
3063    }
3064
3065    /* create cache manager name objects */
3066    cmLabels_o_Ptr = cmLabels_o[arrIdx];
3067    for (i=0; i< cm_cols_perPage; i++) {
3068         *cmLabels_o_Ptr = initLightObject("",
3069                 FC_HOSTNAME_O_WIDTH + i * FC_COLUMN_WIDTH,
3070                 FC_FIRST_LABEL_ROW + arrIdx, 
3071                 FC_COLUMN_WIDTH,afsmon_win);
3072
3073         if (*cmLabels_o_Ptr == NULL) {
3074                 sprintf(errMsg,"[ %s ] Failed to create a CM label onode\n",rn);
3075                 afsmon_Exit(470);
3076         }
3077         code = gtxframe_AddToList(cmFrame,*cmLabels_o_Ptr);
3078         cmLabels_o_Ptr++;
3079    }
3080
3081    }
3082
3083
3084
3085
3086
3087
3088    /* initialize the column & page counters */
3089
3090    cm_currPage = 1;             
3091    cm_numCols = cm_DisplayItems_count;  
3092    cm_numPages = numCM / cm_numHosts_perPage;
3093    if (numCM % cm_numHosts_perPage)
3094         cm_numPages++;
3095    cm_curr_LCol = 0;    /* leftmost col */
3096    cm_curr_RCol = 0;    /* rightmost col */
3097
3098    /* create keyboard bindings */
3099    /* bind Q and \ 3 to exit */
3100    keymap_BindToString(cmFrame->keymap,"Q",afsmonExit_gtx,NULL,NULL);
3101    keymap_BindToString(cmFrame->keymap,"\ 3",afsmonExit_gtx,NULL,NULL);
3102
3103    /* o = overview, c = cm, n = next, p = prev, l = left, r = right 
3104       N = last page, P = first page, L = leftmost col, R = rightmost col */
3105
3106    keymap_BindToString(cmFrame->keymap,"o",Switch_cm_2_ovw,NULL,NULL);
3107    keymap_BindToString(cmFrame->keymap,"f",Switch_cm_2_fs,NULL,NULL);
3108    keymap_BindToString(cmFrame->keymap,"n",Switch_cm_next,NULL,NULL);
3109    keymap_BindToString(cmFrame->keymap,"N",Switch_cm_last,NULL,NULL);
3110    keymap_BindToString(cmFrame->keymap,"p",Switch_cm_prev,NULL,NULL);
3111    keymap_BindToString(cmFrame->keymap,"P",Switch_cm_first,NULL,NULL);
3112    keymap_BindToString(cmFrame->keymap,"l",Switch_cm_left,NULL,NULL);
3113    keymap_BindToString(cmFrame->keymap,"L",Switch_cm_leftmost,NULL,NULL);
3114    keymap_BindToString(cmFrame->keymap,"r",Switch_cm_right,NULL,NULL);
3115    keymap_BindToString(cmFrame->keymap,"R",Switch_cm_rightmost,NULL,NULL);
3116
3117    return(0);
3118 }       /* create_CMframe_objects */
3119
3120
3121
3122 /*-----------------------------------------------------------------------
3123  * gtx_initialize()
3124  *
3125  * Description:
3126  *      Initialize the gtx package and call routines to create the objects
3127  *      for the overview, File Servers & Cache Managers screens.
3128  *----------------------------------------------------------------------*/
3129 int
3130 gtx_initialize() 
3131 {       /* gtx_initialize */
3132    static char rn[] = "gtx_initialize"; /* routine name */
3133    int code;
3134
3135     if (afsmon_debug) {
3136         fprintf(debugFD,"[ %s ] Called\n",rn);
3137         fflush(debugFD);
3138     }
3139
3140    afsmon_win = gtx_Init(0,-1); /* 0 => dont start input server,
3141                                    1 => use curses */
3142    if(afsmon_win == NULL) {
3143         sprintf(errMsg,"[ %s ] gtx initialization failed\n",rn);
3144         afsmon_Exit(475);
3145    }
3146    gtx_initialized = 1;
3147
3148    /* Create the Overview frame */
3149
3150    ovwFrame = gtxframe_Create();
3151    if (ovwFrame == (struct gtx_frame *)0) {
3152         sprintf(errMsg,"[ %s ] Failed to create overview frame\n",rn);
3153         afsmon_Exit(480);
3154    }
3155
3156    /* bind the overview frame to the window */
3157    gtxframe_SetFrame(afsmon_win,ovwFrame);
3158
3159    /* create overview frame objects */
3160    code = create_ovwFrame_objects();
3161    if (code) {
3162         sprintf(errMsg,"[ %s ] Error in creating ovw frame objects\n",rn);
3163         afsmon_Exit(485);
3164    }
3165
3166
3167    /* Create the File Server frame */
3168    fsFrame = gtxframe_Create();
3169    if (fsFrame == (struct gtx_frame *)0) {
3170         sprintf(errMsg,"[ %s ] Failed to create file server frame\n",rn);
3171         afsmon_Exit(490);
3172    }
3173
3174
3175    /* Create File Server frame objects */
3176    code = create_FSframe_objects();
3177    if (code) {
3178         sprintf(errMsg,"[ %s ] Error in creating FS frame objects\n",rn);
3179         afsmon_Exit(495);
3180    }
3181
3182    /* Create the Cache Managers frame */
3183    cmFrame = gtxframe_Create();
3184    if (cmFrame == (struct gtx_frame *)0) {
3185         sprintf(errMsg,"[ %s ] Failed to create Cache Managers frame\n",rn);
3186         afsmon_Exit(500);
3187    }
3188
3189    /* Create Cache Managers frame objects */
3190    code = create_CMframe_objects();
3191    if (code) {
3192         sprintf(errMsg,"[ %s ] Error in creating CM frame objects\n",rn);
3193         afsmon_Exit(505);
3194    }
3195
3196    /* misc initializations */
3197    sprintf(blankline,"%255s"," ");
3198
3199    return (0);  
3200 }       /* gtx_initialize */    
3201