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