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