Bug Summary

File:scout/scout.c
Location:line 1842, column 2
Description:Value stored to 'code' is never read

Annotated Source Code

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 * Scout: A quick and (semi-)dirty attempt at the old CMU vopcon.
12 *------------------------------------------------------------------------*/
13
14#include <afsconfig.h>
15#include <afs/param.h>
16
17#include <roken.h>
18
19#undef IN
20#include <afs/gtxwindows.h> /*Generic window package */
21#include <afs/gtxobjects.h> /*Object definitions */
22#include <afs/gtxtextobj.h> /*Text object interface */
23#include <afs/gtxlightobj.h> /*Light object interface */
24#include <afs/gtxcurseswin.h> /*Curses window package */
25#include <afs/gtxdumbwin.h> /*Dumb terminal window package */
26#include <afs/gtxX11win.h> /*X11 window package */
27#include <afs/gtxframe.h> /*Frame package */
28#include <afs/gtxinput.h>
29#include <afs/cmd.h> /*Command interpretation library */
30#include <afs/fsprobe.h> /*Interface for fsprobe module */
31#include <afs/afsutil.h>
32
33/*
34 * Command line parameter indicies.
35 */
36#define P_SERVER0 0
37#define P_BASE1 1
38#if 0
39#define P_PACKAGE 2
40#endif /* 0 */
41#define P_FREQ2 2
42#define P_HOST3 3
43#define P_ATTENTION4 4
44#define P_DEBUG5 5
45#define P_WIDTHS6 6
46
47/*
48 * Define the default width in chars for each light object on the mini-line.
49 */
50#define LIGHTOBJ_CONN_WIDTH5 5
51#define LIGHTOBJ_FETCH_WIDTH10 10
52#define LIGHTOBJ_STORE_WIDTH10 10
53#define LIGHTOBJ_WK_WIDTH5 5
54#define LIGHTOBJ_SRVNAME_WIDTH13 13
55#define LIGHTOBJ_DISK_WIDTH12 12
56
57/*
58 * Define column width indices.
59 */
60#define COL_CONN0 0
61#define COL_FETCH1 1
62#define COL_STORE2 2
63#define COL_WK3 3
64#define COL_SRVNAME4 4
65#define COL_DISK5 5
66
67/*
68 * Define the types of justification we can perform.
69 */
70#define SCOUT_RIGHT_JUSTIFY0 0
71#define SCOUT_LEFT_JUSTIFY1 1
72#define SCOUT_CENTER2 2
73
74/*
75 * Define the types of truncation we can perform.
76 */
77#define SCOUT_LEFT_TRUNC0 0
78#define SCOUT_RIGHT_TRUNC1 1
79
80/*
81 * Define whether the value passed is a labeled disk quantity.
82 */
83#define SCOUT_ISNT_LDISK0 0
84#define SCOUT_IS_LDISK1 1
85
86/*
87 * We sometimes use index-base pointers, so we need a distinguished
88 * NIL value.
89 */
90#define SCOUT_NIL(-1) (-1)
91
92/*
93 * Structure describing everything you want to know about a FileServer
94 * disk.
95 */
96struct scout_disk {
97 int prev; /*Index of previous list entry */
98 int next; /*Index of next list entry */
99 int active; /*Is this disk known to exist? */
100 char *name; /*Single-letter disk name */
101 struct onode *disk_lp; /*Ptr to disk light object */
102};
103
104/*
105 * Structure defining all the objects in the Scout line (or lines)
106 * for each server being watched. Note that scout_disk linked list
107 * for used disks is ordered alphabetically.
108 */
109struct mini_line {
110 /*
111 * Information on server location & configuration.
112 */
113 struct sockaddr_in skt; /*Server's socket info */
114 int numDisks; /*Number of disks used */
115 /*
116 * Screen location info.
117 */
118 int base_line; /*Line number on the screen */
119 int num_lines; /*Number of lines of info */
120 /*
121 * Associated light objects.
122 */
123 struct onode *currConns_lp; /*Number of current connections */
124 struct onode *fetches_lp; /*Number of data fetches */
125 struct onode *stores_lp; /*Number of data stores */
126 struct onode *workstations_lp; /*Workstation info */
127 struct onode *srvName_lp; /*Server name */
128 struct scout_disk disks[VOLMAXPARTS255]; /*Info on all the disks */
129 int used_head; /*Index of first used disk struct */
130 int used_tail; /*Index of last used disk struct */
131 int free_head; /*Index of first free disk struct */
132 int free_tail; /*Index of last free disk struct */
133};
134
135/*
136 * Structure defining the contents of the Scout screen.
137 */
138struct mini_screen {
139 int numServers; /*Number of servers being watched */
140 int base_line_num; /*Base mini-line number */
141 struct mini_line *line; /*Array of screen lines */
142};
143
144static char pn[] = "scout"; /*Program name */
145static int scout_debug = 0; /*Is debugging turned on? */
146static FILE *scout_debugfd; /*Debugging file descriptor */
147static int scout_gtx_initialized = 0; /*Has gtx been initialized? */
148static struct mini_screen scout_screen; /*Mini-screen itself */
149static int scout_probefreq; /*Probe frequency in seconds */
150static char scout_basename[64]; /*Base server name */
151static char scout_hostname[128]; /*Name of machine we're running on */
152static int scout_showhostname = 0; /*Show name of machine we're on? */
153static char scout_blankline[256]; /*Blank line */
154static struct gwin *scout_gwin; /*Window to use */
155static struct gtx_frame *scout_frame; /*Frame to use */
156static struct onode *scout_banner0_lp; /*Banner light, line 0 */
157static struct onode *scout_banner1_lp; /*Banner light, line 1 */
158static struct onode *scout_banner2_lp; /*Banner light, line 2 */
159static int scout_DiskLightLeftCol = 0; /*Column for leftmost disk light */
160static struct gwin_sizeparams scout_frameDims; /*Frame dimensions */
161
162static int scout_col_width[] = { LIGHTOBJ_CONN_WIDTH5,
163 LIGHTOBJ_FETCH_WIDTH10,
164 LIGHTOBJ_STORE_WIDTH10,
165 LIGHTOBJ_WK_WIDTH5,
166 LIGHTOBJ_SRVNAME_WIDTH13,
167 LIGHTOBJ_DISK_WIDTH12
168};
169
170/*
171 * Attention thresholds & modes.
172 */
173#define SCOUT_ATTN_NOTUSED(-1) (-1)
174#define SCOUT_DISKM_PCUSED0 0
175#define SCOUT_DISKM_MINFREE1 1
176
177static int scout_attn_conn = SCOUT_ATTN_NOTUSED(-1);
178static int scout_attn_fetch = SCOUT_ATTN_NOTUSED(-1);
179static int scout_attn_store = SCOUT_ATTN_NOTUSED(-1);
180static int scout_attn_workstations = SCOUT_ATTN_NOTUSED(-1);
181static int scout_attn_disk_mode = SCOUT_DISKM_PCUSED0;
182static int scout_attn_disk_minfree = 1000;
183static float scout_attn_disk_pcused = 0.95;
184static char scout_attn_disk_pcusedstr[8] = "95";
185
186/*
187 * Some strings we'll be using over and over again.
188 */
189static char scout_Banner[256];
190static const char *scout_label[] =
191 { "Conn", "Fetch", "Store", "Ws", "", "Disk attn" };
192static const char *scout_underline[] =
193 { "----", "--------", "--------", "-----", "", "----------" };
194
195
196/*------------------------------------------------------------------------
197 * scout_CleanExit
198 *
199 * Description:
200 * Exits cleanly from the Scout. If gtx has not yet been initialized,
201 * then we simply call exit() with the value provided. Otherwise,
202 * we call the appropriate gtx routine to exit cleanly from gtx, which
203 * must reset the terminal or window. We also close the debugging
204 * file descriptor, if one has been opened.
205 *
206 * Arguments:
207 * int a_exitval : Value with which to exit the program.
208 *
209 * Returns:
210 * Void.
211 *
212 * Environment:
213 * Actions depend on scout_gtx_initialized.
214 *
215 * Side Effects:
216 * This routine will always exit Scout.
217 *------------------------------------------------------------------------*/
218
219static void
220scout_CleanExit(int a_exitval)
221{ /*scout_CleanExit */
222
223 static char rn[] = "scout_CleanExit"; /*Routine name */
224
225 if (scout_debugfd != (FILE *) 0) {
226 fprintf(scout_debugfd, "[%s] Closing debugging file\n", rn);
227 fclose(scout_debugfd);
228 }
229
230 if (scout_gtx_initialized) {
231 gtxframe_exitValue = a_exitval;
232 gtxframe_ExitCmd((void *)(&gtxframe_exitValue), NULL((void *)0));
233 } else
234 exit(a_exitval);
235
236} /*scout_CleanExit */
237
238/*------------------------------------------------------------------------
239 * mini_initLightObject
240 *
241 * Description:
242 * Create and initialize a light onode according to the given
243 * parameters.
244 *
245 * Arguments:
246 * char *a_name : Ptr to the light's string name.
247 * int a_x : X offset.
248 * int a_y : Y offset.
249 * int a_width : Width in chars.
250 * struct gwin *a_win : Ptr to window structure.
251 *
252 * Returns:
253 * Ptr to new light onode on success,
254 * A null pointer otherwise.
255 *
256 * Environment:
257 * See above.
258 *
259 * Side Effects:
260 * As advertised.
261 *------------------------------------------------------------------------*/
262
263static struct onode *
264mini_initLightObject(char *a_name, int a_x, int a_y, int a_width, struct gwin *a_win)
265{ /*mini_initLightObject */
266
267 static char rn[] = "mini_initLightObject"; /*Routine name */
268 struct onode *newlightp; /*Ptr to new light onode */
269 /*We only support curses right now */
270 struct gator_light_crparams light_crparams; /*Light creation params */
271 char *truncname; /*Truncated name, if needed */
272 int name_len; /*True length of name */
273
274 if (scout_debug) {
275 fprintf(scout_debugfd,
276 "[%s] Called for name '%s', [%d, %d], %d-char field\n", rn,
277 a_name, a_x, a_y, a_width);
278 fflush(scout_debugfd);
279 }
280 newlightp = NULL((void *)0);
281
282 /*
283 * Set up the creation parameters according to the information we've
284 * received.
285 */
286 light_crparams.onode_params.cr_type = GATOR_OBJ_LIGHT1;
287 name_len = strlen(a_name);
288 if (scout_debug)
289 fprintf(scout_debugfd, "[%s] Name '%s' has %d chars\n", rn, a_name,
290 name_len);
291 if (name_len <= a_width)
292 sprintf(light_crparams.onode_params.cr_name, "%s", a_name);
293 else {
294 /*
295 * We need to truncate the given name, leaving a `*' at the end to
296 * show us it's been truncated.
297 */
298 truncname = light_crparams.onode_params.cr_name;
299 strncpy(truncname, a_name, a_width - 1);
300 truncname[a_width - 1] = '*';
301 truncname[a_width] = 0;
302 }
303 light_crparams.onode_params.cr_x = a_x;
304 light_crparams.onode_params.cr_y = a_y;
305 light_crparams.onode_params.cr_width = a_width;
306 light_crparams.onode_params.cr_height = 1;
307 light_crparams.onode_params.cr_window = a_win;
308 light_crparams.onode_params.cr_home_obj = NULL((void *)0);
309 light_crparams.onode_params.cr_prev_obj = NULL((void *)0);
310 light_crparams.onode_params.cr_parent_obj = NULL((void *)0);
311 light_crparams.onode_params.cr_helpstring = NULL((void *)0);
312
313 light_crparams.appearance = 0;
314 light_crparams.flashfreq = 0;
315 sprintf(light_crparams.label, "%s", a_name);
316 light_crparams.label_x = 0;
317 light_crparams.label_y = 0;
318
319 newlightp =
320 gator_objects_create((struct onode_createparams *)(&light_crparams));
321
322 /*
323 * Return the news, happy or not.
324 */
325 return (newlightp);
326
327} /*mini_initLightObject */
328
329/*------------------------------------------------------------------------
330 * scout_initDiskLightObjects
331 *
332 * Description:
333 * Create and initialize all Scout light objects for a server's
334 * disks.
335 *
336 * Arguments:
337 * struct scout_disk *a_line : Ptr to the server object line.
338 * struct gwin *a_win : Ptr to window structure.
339 *
340 * Returns:
341 * 0 on success,
342 * -1 otherwise.
343 *
344 * Environment:
345 * See above.
346 *
347 * Side Effects:
348 * As advertised.
349 *------------------------------------------------------------------------*/
350
351static int
352scout_initDiskLightObjects(struct mini_line *a_line, struct gwin *a_win)
353{ /*scout_initDiskLightObjects */
354
355 static char rn[] = "scout_initDiskLightObjects"; /*Routine name */
356 struct scout_disk *curr_disk; /*Ptr to current disk being set up */
357 int i; /*Loop variable */
358
359 if (scout_debug) {
360 fprintf(scout_debugfd, "[%s] Called\n", rn);
361 fflush(scout_debugfd);
362 }
363
364 /*
365 * Set up the base linked list fields.
366 */
367 a_line->used_head = SCOUT_NIL(-1);
368 a_line->used_tail = SCOUT_NIL(-1);
369 a_line->free_head = 0;
370 a_line->free_tail = VOLMAXPARTS255 - 1;
371
372 /*
373 * Sweep through the disk structures, creating the light objects and
374 * marking them all as free.
375 */
376 curr_disk = a_line->disks;
377 for (i = 0; i < VOLMAXPARTS255; i++) {
378 /*
379 * Create the disk light object.
380 */
381 if ((curr_disk->disk_lp = mini_initLightObject("Disk", /*Object name */
382 0, /*X value */
383 0, /*Y value */
384 scout_col_width[COL_DISK5], /*Width */
385 a_win)) /*Window */
386 == NULL((void *)0)) {
387 fprintf(stderr__stderrp, "[%s:%s] Can't create disk %d light object\n", pn,
388 rn, i);
389 return (-1);
390 }
391
392 /*
393 * Set the other fields in the disk records; Note that in the
394 * fencepost cases, the prev and next pointers will have to be
395 * fixed.
396 */
397 curr_disk->prev = i - 1;
398 curr_disk->next = i + 1;
399 curr_disk->active = 0;
400 curr_disk->name = '\0';
401
402 /*
403 * Bump up to the next disk structure.
404 */
405 curr_disk++;
406
407 } /*for each disk structure */
408
409 /*
410 * We made it all the way through. Fix the fencepost pointers, set
411 * the overall pointers, then return success.
412 */
413 a_line->disks[0].prev = SCOUT_NIL(-1);
414 a_line->disks[VOLMAXPARTS255 - 1].next = SCOUT_NIL(-1);
415
416 return (0);
417
418} /*scout_initDiskLightObjects */
419
420
421/*------------------------------------------------------------------------
422 * mini_justify
423 *
424 * Description:
425 * Place the chars in the source buffer into the target buffer
426 * with the desired justification, either centered, left-justified
427 * or right-justified. Also, support inidication of truncation
428 * with a star (*), either on the left or right of the string,
429 * and whether we're justifying a labeled disk quantity.
430 *
431 * Arguments:
432 * char *a_srcbuff : Ptr to source char buffer.
433 * char *a_dstbuff : Ptr to dest char buffer.
434 * int a_dstwidth : Width of dest buffer in chars.
435 * int a_justification : Kind of justification.
436 * int a_rightTrunc : If non-zero, place the truncation char
437 * on the right of the string. Otherwise,
438 * place it on the left.
439 * int a_isLabeledDisk : Is this a labeled disk quantity?
440 *
441 * Returns:
442 * 0 on success,
443 * -1 otherwise.
444 *
445 * Environment:
446 * All it needs to know is exported by the fsprobe module, namely
447 * the data structure where the probe results are stored.
448 *
449 * Side Effects:
450 * As advertised.
451 *------------------------------------------------------------------------*/
452
453int
454mini_justify(char *a_srcbuff, char *a_dstbuff, int a_dstwidth,
455 int a_justification, int a_rightTrunc,
456 int a_isLabeledDisk)
457{ /*mini_justify */
458
459 static char rn[] = "mini_justify"; /*Routine name */
460 int leftpad_chars; /*# of chars for left-padding */
461 int num_src_chars; /*# of chars in source */
462 int true_num_src_chars; /*# src chars before truncation */
463 int trunc_needed; /*Is truncation needed? */
464 char diskChar = 0; /*Disk name prefix */
465
466 if (scout_debug) {
467 fprintf(scout_debugfd, "[%s] Called with '%s', dest width=%d\n", rn,
468 a_srcbuff, a_dstwidth);
469 fflush(scout_debugfd);
470 }
471
472 /*
473 * Remember the disk label, if we've been passed such a thing.
474 */
475 if (a_isLabeledDisk)
476 diskChar = *a_srcbuff;
477
478 /*
479 * If the destination width will overrun the gtx string storage,
480 * we automatically shorten up.
481 */
482 if (a_dstwidth > GATOR_LABEL_CHARS128) {
483 if (scout_debug) {
484 fprintf(scout_debugfd,
485 "[%s] Dest width (%d) > gtx buflen (%d), shrinking dest width\n",
486 rn, a_dstwidth, GATOR_LABEL_CHARS128);
487 fflush(scout_debugfd);
488 }
489 a_dstwidth = GATOR_LABEL_CHARS128;
490 }
491
492 /*
493 * If our source string is too long, prepare for truncation.
494 */
495 true_num_src_chars = strlen(a_srcbuff);
496 if (true_num_src_chars >= a_dstwidth) {
497 trunc_needed = 1;
498 num_src_chars = a_dstwidth - 1;
499 leftpad_chars = 0;
500 if (!a_rightTrunc)
501 a_srcbuff += (true_num_src_chars - num_src_chars);
502 } else {
503 trunc_needed = 0;
504 num_src_chars = true_num_src_chars;
505
506 /*
507 * Compute the necessary left-padding.
508 */
509 switch (a_justification) {
510
511 case SCOUT_RIGHT_JUSTIFY0:
512 leftpad_chars = (a_dstwidth - 1) - num_src_chars;
513 break;
514
515 case SCOUT_LEFT_JUSTIFY1:
516 /*
517 * This is the really easy one.
518 */
519 leftpad_chars = 0;
520 break;
521
522 case SCOUT_CENTER2:
523 leftpad_chars = ((a_dstwidth - 1) - num_src_chars) / 2;
524 break;
525
526 default:
527 fprintf(stderr__stderrp, "[%s] Illegal justification command: %d", rn,
528 a_justification);
529 return (-1);
530 } /*Switch on justification type */
531 }
532
533 /*
534 * Clear out the dest buffer, then place the source string at the
535 * appropriate padding location. Remember to place a string
536 * terminator at the end of the dest buffer, plus whatever truncation
537 * may be needed. If we're left-truncating, we've already shifted
538 * the src buffer appropriately.
539 */
540 strncpy(a_dstbuff, scout_blankline, a_dstwidth);
541 strncpy(a_dstbuff + leftpad_chars, a_srcbuff, num_src_chars);
542 *(a_dstbuff + a_dstwidth - 1) = '\0';
543 if (trunc_needed) {
544 if (a_rightTrunc)
545 *(a_dstbuff + a_dstwidth - 2) = '*'; /*Truncate on the right */
546 else {
547 if (a_isLabeledDisk) {
548 *a_dstbuff = diskChar;
549 *(a_dstbuff + 1) = ':';
550 *(a_dstbuff + 2) = '*'; /*Truncate on the left, disk */
551 } else
552 *a_dstbuff = '*'; /*Truncate on the left, non-disk */
553 }
554 }
555
556 /*Handle truncations */
557 /*
558 * Return the good news.
559 */
560 return (0);
561
562} /*mini_justify */
563
564/*------------------------------------------------------------------------
565 * scout_SetNonDiskLightLine
566 *
567 * Description:
568 * Given a mini-line and a line number, place all non-disk lights
569 * on that line.
570 *
571 * Arguments:
572 * struct mini_line *a_srvline : Ptr to server descriptor.
573 * int a_linenum : Line number to move to.
574 *
575 * Returns:
576 * Nothing.
577 *
578 * Environment:
579 * The light's location is stored not only in the onode, but in
580 * the light's rock, so we have to change both sets of value.
581 *
582 * Side Effects:
583 * As described.
584 *------------------------------------------------------------------------*/
585
586static void
587scout_SetNonDiskLightLine(struct mini_line *a_srvline, int a_linenum)
588{ /*scout_SetNonDiskLightLine */
589
590 struct gator_lightobj *nondisk_lightdata; /*Non-disk light data field */
591 struct gwin_strparams *nondisk_strparams; /*Associated string params */
592
593 /*
594 * Do the exact same operation for each non-disk light in the record.
595 */
596 a_srvline->currConns_lp->o_y = a_linenum;
597 nondisk_lightdata =
598 (struct gator_lightobj *)(a_srvline->currConns_lp->o_data);
599 nondisk_strparams = (struct gwin_strparams *)(nondisk_lightdata->llrock);
600 nondisk_strparams->y = a_linenum;
601
602 a_srvline->fetches_lp->o_y = a_linenum;
603 nondisk_lightdata =
604 (struct gator_lightobj *)(a_srvline->fetches_lp->o_data);
605 nondisk_strparams = (struct gwin_strparams *)(nondisk_lightdata->llrock);
606 nondisk_strparams->y = a_linenum;
607
608 a_srvline->stores_lp->o_y = a_linenum;
609 nondisk_lightdata =
610 (struct gator_lightobj *)(a_srvline->stores_lp->o_data);
611 nondisk_strparams = (struct gwin_strparams *)(nondisk_lightdata->llrock);
612 nondisk_strparams->y = a_linenum;
613
614 a_srvline->workstations_lp->o_y = a_linenum;
615 nondisk_lightdata =
616 (struct gator_lightobj *)(a_srvline->workstations_lp->o_data);
617 nondisk_strparams = (struct gwin_strparams *)(nondisk_lightdata->llrock);
618 nondisk_strparams->y = a_linenum;
619
620 a_srvline->srvName_lp->o_y = a_linenum;
621 nondisk_lightdata =
622 (struct gator_lightobj *)(a_srvline->srvName_lp->o_data);
623 nondisk_strparams = (struct gwin_strparams *)(nondisk_lightdata->llrock);
624 nondisk_strparams->y = a_linenum;
625
626} /*scout_SetNonDiskLightLine */
627
628/*------------------------------------------------------------------------
629 * scout_RecomputeLightLocs
630 *
631 * Description:
632 * Given a pointer to a server record, recompute its disk light
633 * locations (and keep proper track of the number of screen lines
634 * required for the server record).
635 *
636 * Arguments:
637 * struct mini_line *a_srvline : Ptr to server descriptor.
638 *
639 * Returns:
640 * 0 if anything went wrong,
641 * else the number of lines used by this server record.
642 *
643 * Environment:
644 * One or more records have joined or left the used light list
645 * for this server. We're not sure which ones, so we recompute
646 * them all. We may also have had a width change in the gtx
647 * frame. The base_line field in the server record is guaranteed
648 * to be correct at this point.
649 *
650 * Side Effects:
651 * As described.
652 *------------------------------------------------------------------------*/
653
654static int
655scout_RecomputeLightLocs(struct mini_line *a_srvline)
656{ /*scout_RecomputeLightLocs */
657
658 static char rn[] = "scout_RecomputeLightLocs"; /*Routine name */
659 int lights_per_line; /*# lights/line */
660 int lights_this_line; /*# lights on cur line */
661 int curr_idx; /*Current disk light idx */
662 struct scout_disk *sc_disk; /*Ptr to disk record array */
663 int lines_for_server; /*Num lines in server record */
664 int curr_line; /*Current line being filled */
665 int curr_x; /*Current x value for light */
666 struct gator_lightobj *disk_lightdata; /*Disk light data field */
667 struct gwin_strparams *disk_strparams; /*String params for disk light */
668
669 if (scout_debug) {
670 fprintf(scout_debugfd, "[%s] Called\n", rn);
671 fflush(scout_debugfd);
672 }
673
674 /*
675 * If we haven't yet computed the column for the leftmost disk light,
676 * do it now.
677 */
678 if (scout_DiskLightLeftCol == 0) {
679 int i;
680 int num_cols = sizeof(scout_col_width) / sizeof(*scout_col_width);
681 scout_DiskLightLeftCol = 0;
682 for (i = 0; i < (num_cols - 1); i++) {
683 scout_DiskLightLeftCol += scout_col_width[i] + 1;
684 }
685 }
686
687 /*
688 * Calculate how many disk light objects can fit in one line.
689 */
690 lights_per_line =
691 (scout_frameDims.maxx -
692 scout_DiskLightLeftCol) / (scout_col_width[COL_DISK5] + 1);
693 if (scout_debug) {
694 fprintf(scout_debugfd, "[%s] %d lights per line\n", rn,
695 lights_per_line);
696 fflush(scout_debugfd);
697 }
698
699 /*
700 * Sweep through the used disk light list, computing the location
701 * for each.
702 */
703 lights_this_line = 0;
704 curr_idx = a_srvline->used_head;
705 lines_for_server = 1;
706 curr_line = a_srvline->base_line;
707 curr_x = scout_DiskLightLeftCol;
708
709 while (curr_idx != SCOUT_NIL(-1)) {
710 /*
711 * Bump the number of lines for the server if we've already
712 * filled up the current line.
713 */
714 if (lights_this_line >= lights_per_line) {
715 lights_this_line = 0;
716 lines_for_server++;
717 curr_line++;
718 curr_x = scout_DiskLightLeftCol;
719 }
720
721 /*Current line filled up */
722 /*
723 * Set the current disk light's location.
724 */
725 sc_disk = a_srvline->disks;
726 sc_disk[curr_idx].disk_lp->o_x = curr_x;
727 sc_disk[curr_idx].disk_lp->o_y = curr_line;
728 disk_lightdata =
729 (struct gator_lightobj *)(sc_disk[curr_idx].disk_lp->o_data);
730 disk_strparams = (struct gwin_strparams *)(disk_lightdata->llrock);
731 disk_strparams->x = curr_x;
732 disk_strparams->y = curr_line;
733 if (scout_debug) {
734 fprintf(scout_debugfd,
735 "[%s] Disk light at index %d located at [%d, %d]\n", rn,
736 curr_idx, curr_x, curr_line);
737 fflush(scout_debugfd);
738 }
739
740 /*
741 * Record the inclusion of the light and move on to the next
742 * light, if any.
743 */
744 lights_this_line++;
745 curr_x += scout_col_width[COL_DISK5] + 1;
746 curr_idx = sc_disk[curr_idx].next;
747
748 } /*Update each used disk light */
749
750 /*
751 * Remember to record the (possibly new) number of lines in the
752 * server record before returning the value of that field.
753 */
754 if (a_srvline->num_lines != lines_for_server) {
755 if (scout_debug) {
756 fprintf(scout_debugfd,
757 "[%s] Server previously had %d screen lines; now changed\n",
758 rn, a_srvline->num_lines);
759 fflush(scout_debugfd);
760 }
761 a_srvline->num_lines = lines_for_server;
762 }
763
764 if (scout_debug) {
765 fprintf(scout_debugfd, "[%s] Server has %d screen lines\n", rn,
766 a_srvline->num_lines);
767 fflush(scout_debugfd);
768 }
769 return (a_srvline->num_lines);
770
771} /*scout_RecomputeLightLocs */
772
773/*------------------------------------------------------------------------
774 * scout_FindUsedDisk
775 *
776 * Description:
777 * Given a single-letter disk name and a pointer to the current server
778 * record, look for a used disk record with that name within the server.
779 * If we can't find one, we create and incorporate one, and return that
780 * fact to our caller.
781 *
782 * Arguments:
783 * char a_diskname : Single-char disk name.
784 * struct mini_line *a_srvline : Ptr to server descriptor.
785 * int *a_record_added : Was a new record added?
786 *
787 * Returns:
788 * Index of matching used disk record,
789 * SCOUT_NIL otherwise.
790 *
791 * Return via parameter:
792 * a_record_added set to 1 iff record was added to the used disk list.
793 *
794 * Environment:
795 * Used disk records are kept in alphabetical order by the single-char
796 * disk name. Should a matching used disk record not be found, one is
797 * pulled from the free pool.
798 *
799 * Side Effects:
800 * An entry may be pulled off the free list and inserted into the
801 * used list. This entry is placed in the update list for the
802 * current gtx frame (at least not by this routine).
803 *------------------------------------------------------------------------*/
804
805static int
806scout_FindUsedDisk(char *a_diskname, struct mini_line *a_srvline, int *a_record_added)
807{ /*scout_FindUsedDisk */
808
809 static char rn[] = "scout_FindUsedDisk"; /*Routine name */
810 int curr_idx; /*Disk record index */
811 int append_idx; /*Index to append after */
812 int new_idx; /*Index of new used record */
813 struct scout_disk *sc_disk; /*Ptr to disk record */
814 int code; /*Function return value */
815
816 if (scout_debug) {
817 fprintf(scout_debugfd, "[%s] Called\n", rn);
818 fflush(scout_debugfd);
819 }
820
821 /*
822 * Sweep through the used disk records, looking for a match.
823 */
824 curr_idx = a_srvline->used_head;
825 append_idx = SCOUT_NIL(-1);
826 sc_disk = a_srvline->disks;
827 if (scout_debug) {
828 fprintf(scout_debugfd,
829 "[%s] Scanning existing used disk entries for disk '%s'\n",
830 rn, a_diskname);
831 fflush(scout_debugfd);
832 }
833 while (curr_idx != SCOUT_NIL(-1)) {
834 if (scout_debug) {
835 fprintf(scout_debugfd, "[%s] Disk %d is named '%s'\n", rn,
836 curr_idx, sc_disk[curr_idx].name);
837 fflush(scout_debugfd);
838 }
839 if (strcmp(sc_disk[curr_idx].name, a_diskname) == 0) {
840 /*
841 * We found it! Bug out.
842 */
843 if (scout_debug) {
844 fprintf(scout_debugfd, "[%s] Match found\n", rn);
845 fflush(scout_debugfd);
846 }
847 return (curr_idx);
848 }
849
850 /*
851 * If we are alphabetically past the given disk name, we
852 * know that we won't find it in the used disk list; we
853 * also have the append index set correctly.
854 */
855 if (strcmp(a_diskname, sc_disk[curr_idx].name) < 0) {
856 if (scout_debug) {
857 fprintf(scout_debugfd, "[%s] Disk '%s' can't be here\n", rn,
858 a_diskname);
859 fflush(scout_debugfd);
860 }
861 break;
862 }
863
864 /*
865 * There's still hope we'll find it. Move on to the next used
866 * disk record, keeping this index as the best candidate so far
867 * for appending a missing entry.
868 */
869 append_idx = curr_idx;
870 curr_idx = sc_disk[curr_idx].next;
871 } /*Look for match */
872
873 /*
874 * We didn't find the record we wanted, which means we'll pull a
875 * record out of the free pool for it. If we didn't find a place
876 * to append it, we then insert it at the beginning of the queue.
877 */
878 if (a_srvline->free_head == SCOUT_NIL(-1))
879 return (SCOUT_NIL(-1));
880 *a_record_added = 1;
881 new_idx = a_srvline->free_head;
882 if (scout_debug) {
883 fprintf(scout_debugfd, "[%s] Choosing free index %d for new entry\n",
884 rn, new_idx);
885 fflush(scout_debugfd);
886 }
887 a_srvline->free_head = sc_disk[new_idx].next;
888 if (a_srvline->free_head == SCOUT_NIL(-1))
889 a_srvline->free_tail = SCOUT_NIL(-1);
890
891 /*
892 * Fill in the new record.
893 */
894 sc_disk[new_idx].active = 0;
895 sc_disk[new_idx].name = a_diskname;
896
897 /*
898 * Insert the new record where it belongs on the used disk list.
899 */
900 if (append_idx == SCOUT_NIL(-1)) {
901 /*
902 * It belongs at the beginning of the list.
903 */
904 if (scout_debug) {
905 fprintf(scout_debugfd, "[%s] Inserted at used disk head\n", rn);
906 fflush(scout_debugfd);
907 }
908 sc_disk[new_idx].next = a_srvline->used_head;
909 sc_disk[new_idx].prev = SCOUT_NIL(-1);
910 a_srvline->used_head = new_idx;
911 if (a_srvline->used_tail == SCOUT_NIL(-1))
912 a_srvline->used_tail = new_idx;
913 } else {
914 if (scout_debug) {
915 fprintf(scout_debugfd, "[%s] Entry appended after index %d\n", rn,
916 append_idx);
917 fflush(scout_debugfd);
918 }
919 sc_disk[new_idx].prev = append_idx;
920 sc_disk[new_idx].next = sc_disk[append_idx].next;
921 sc_disk[append_idx].next = new_idx;
922 if (sc_disk[new_idx].next == SCOUT_NIL(-1))
923 a_srvline->used_tail = new_idx;
924 else
925 sc_disk[sc_disk[new_idx].next].prev = new_idx;
926 };
927
928 /*
929 * Add the new used disk light object to the display list for
930 * the scout frame.
931 */
932 if (scout_debug) {
933 fprintf(scout_debugfd,
934 "[%s] Adding disk light at index %d to display list\n", rn,
935 new_idx);
936 fflush(scout_debugfd);
937 }
938 code = gtxframe_AddToList(scout_frame, sc_disk[new_idx].disk_lp);
939 if (code) {
940 if (scout_debug) {
941 fprintf(scout_debugfd,
942 "[%s] Can't add to display list, code is %d\n", rn, code);
943 fflush(scout_debugfd);
944 }
945 }
946 return (new_idx);
947
948} /*scout_FindUsedDisk */
949
950/*------------------------------------------------------------------------
951 * scout_RemoveInactiveDisk
952 *
953 * Description:
954 * Given a server record and a used disk index, remove the disk
955 * record from the used list, put it on the free list, and remove
956 * it from the gtx frame update list.
957 *
958 * Arguments:
959 * struct mini_line *a_srvline : Ptr to server descriptor.
960 * int a_used_idx : Index of used disk record.
961 *
962 * Returns:
963 * Nothing.
964 *
965 * Environment:
966 * Formerly-used disk records are returned to the free pool.
967 *
968 * Side Effects:
969 * Free and used disk record lists are modified for this server.
970 * The disk record in question is pulled off the gtx update list
971 * for the frame.
972 *------------------------------------------------------------------------*/
973
974static void
975scout_RemoveInactiveDisk(struct mini_line *a_srvline, int a_used_idx)
976{ /*scout_RemoveInactiveDisk */
977
978 static char rn[] = "scout_RemoveInactiveDisk"; /*Routine name */
979
980 if (scout_debug) {
981 fprintf(scout_debugfd, "[%s] Called\n", rn);
982 fflush(scout_debugfd);
983 }
984
985 /*code = gtxframe_RemoveFromList(scout_frame->window, lightobj); */
986
987} /*scout_RemoveInactiveDisk */
988
989/*------------------------------------------------------------------------
990 * mini_PrintDiskStats
991 *
992 * Description:
993 * Given server indexing and light object information, a pointer
994 * to a set of statistics, and whether the probe that produced these
995 * stats succeeded or not, print out the stats in a nice way.
996 *
997 * Arguments:
998 * struct mini_line *a_srvline : Ptr to server descriptor.
999 * struct ProbeViceStatistics *a_stats : Ptr to current stats.
1000 * int a_probeOK : Was the probe OK?
1001 * int a_width_changed : Has the frame width changed?
1002 * int a_fix_line_num : Is the line number wrong?
1003 * int a_delta_line_num : Change in line number.
1004 *
1005 * Returns:
1006 * 0 if something went wrong,
1007 * else the number of lines taken up by this server record.
1008 *
1009 * Environment:
1010 * Nothing interesting.
1011 *
1012 * Side Effects:
1013 * As advertised.
1014 *------------------------------------------------------------------------*/
1015
1016static int
1017mini_PrintDiskStats(struct mini_line *a_srvline,
1018 struct ProbeViceStatistics *a_stats,
1019 int a_probeOK, int a_width_changed,
1020 int a_fix_line_num, int a_delta_line_num)
1021{ /*mini_PrintDiskStats */
1022
1023 static char rn[] = "mini_PrintDiskStats"; /*Routine name */
1024 char s[128]; /*String buffer */
1025 struct onode *curr_disklight; /*Ptr to current disk light */
1026 struct onode *srvname_light; /*Ptr to server name light */
1027 ViceDisk *curr_diskstat; /*Ptr to current disk stat */
1028 int curr_disk; /*Current disk stat number */
1029 int used_disk_idx; /*Used disk index */
1030 int next_used_idx; /*Ditto */
1031 int pastthreshold; /*Was disk past threshold? */
1032 struct gator_lightobj *diskdata; /*Private light data */
1033 struct gwin_strparams *disk_strparams; /*String params for disk light */
1034 char *diskname = 0; /*Name of disk */
1035 int found_idx; /*Idx of matching disk */
1036 char *srv_name; /*Server name */
1037 struct scout_disk *sc_disk; /*Ptr to scout disk desc */
1038 int fix_light_locs; /*Recompute disk light locs? */
1039
1040 if (scout_debug) {
1041 fprintf(scout_debugfd, "[%s] Called\n", rn);
1042 fflush(scout_debugfd);
1043 }
1044
1045 /*
1046 * Remember the current server's print name, don't recompute light
1047 * locations yet.
1048 */
1049 srvname_light = a_srvline->srvName_lp;
1050 srv_name = ((struct gator_lightobj *)(srvname_light->o_data))->label;
1051 fix_light_locs = 0;
1052 if (scout_debug) {
1053 fprintf(scout_debugfd, "[%s] Value of a_delta_line_num is %d\n", rn,
1054 a_delta_line_num);
1055 fflush(scout_debugfd);
1056 }
1057
1058 /*
1059 * If the probe failed, we simply blank out all the used disk
1060 * objects. Note: a NON-ZERO value of a_probeOK implies failure.
1061 */
1062 if (a_probeOK) {
1063 used_disk_idx = a_srvline->used_head;
1064 while (used_disk_idx != SCOUT_NIL(-1)) {
1065 /*
1066 * Point to the current used disk's light, blank out its
1067 * contents, and make sure highlighting is turned off. We
1068 * also take this opportunity to fix the line numbers if
1069 * needed.
1070 */
1071 curr_disklight = a_srvline->disks[used_disk_idx].disk_lp;
1072 diskdata = (struct gator_lightobj *)(curr_disklight->o_data);
1073 if (scout_debug) {
1074 fprintf(scout_debugfd,
1075 "[%s] Prev value of disk light %d: '%s'\n", rn,
1076 used_disk_idx, diskdata->label);
1077 fflush(scout_debugfd);
1078 }
1079 mini_justify(" ", /*Src buffer */
1080 diskdata->label, /*Dest buffer */
1081 scout_col_width[COL_DISK5], /*Dest's width */
1082 SCOUT_RIGHT_JUSTIFY0, /*Right-justify */
1083 SCOUT_LEFT_TRUNC0, /*Left-truncate */
1084 SCOUT_ISNT_LDISK0); /*Not a labeled disk */
1085 gator_light_set(curr_disklight, 0);
1086 if (a_fix_line_num) {
1087 curr_disklight->o_y += a_delta_line_num;
1088 disk_strparams = (struct gwin_strparams *)(diskdata->llrock);
1089 disk_strparams->y += a_delta_line_num;
1090 }
1091
1092 /*
1093 * Advance to next used disk, if any.
1094 */
1095 used_disk_idx = a_srvline->disks[used_disk_idx].next;
1096
1097 } /*Blank out disk name field */
1098
1099 /*
1100 * If the frame width has changed, we have to recompute all disk
1101 * light locations. After that, the number of lines in the server
1102 * record will be accurate, and we return them.
1103 */
1104 if (a_width_changed)
1105 scout_RecomputeLightLocs(a_srvline);
1106
1107 return (a_srvline->num_lines);
1108
1109 }
1110
1111 /*Probe failed for the server */
1112 /*
1113 * Probe was successful. Sweep through the statistics records,
1114 * and put up all values having to do with AFS partitions. First,
1115 * mark all used disk objects for this server as inactive and fix
1116 * their line numbers if needed.
1117 */
1118 sc_disk = a_srvline->disks;
1119 used_disk_idx = a_srvline->used_head;
1120 while (used_disk_idx != SCOUT_NIL(-1)) {
1121 if (scout_debug) {
1122 fprintf(scout_debugfd, "[%s] Marking used disk %d inactive\n", rn,
1123 used_disk_idx);
1124 fflush(scout_debugfd);
1125 }
1126 sc_disk = (a_srvline->disks) + used_disk_idx;
1127 sc_disk->active = 0;
1128 used_disk_idx = sc_disk->next;
1129 if (a_fix_line_num) {
1130 sc_disk->disk_lp->o_y += a_delta_line_num;
1131 diskdata = (struct gator_lightobj *)(sc_disk->disk_lp->o_data);
1132 disk_strparams = (struct gwin_strparams *)(diskdata->llrock);
1133 disk_strparams->y += a_delta_line_num;
1134 }
1135 } /*Mark used disks inactive */
1136
1137 curr_diskstat = (ViceDisk *) a_stats->Disk;
1138 for (curr_disk = 0; curr_disk < VOLMAXPARTS255; curr_disk++) {
1139 /*
1140 * An AFS partition name must be prefixed by `/vicep`.
1141 */
1142 if (scout_debug) {
1143 fprintf(scout_debugfd, "[%s] Disk stats at %p for disk '%s'\n",
1144 rn, curr_diskstat, curr_diskstat->Name);
1145 fflush(scout_debugfd);
1146 }
1147 if (strncmp("/vice", curr_diskstat->Name, 5) == 0) {
1148 /*
1149 * Pull out the single-letter name (actually, abbreviation)
1150 * of the disk and look for such an entry in the used disks.
1151 */
1152 diskname = &curr_diskstat->Name[6];
1153 found_idx = scout_FindUsedDisk(diskname, /*1-char name */
1154 a_srvline, /*Server record */
1155 &fix_light_locs); /*Recompute? */
1156 if (found_idx == SCOUT_NIL(-1)) {
1157 fprintf(stderr__stderrp,
1158 "[%s] Can't display /vicep%s on server '%s'\n", rn,
1159 diskname, srv_name);
1160 } else {
1161 /*
1162 * Found (or created) record for this disk. Fill in the single-
1163 * letter name of the disk followed by the number of free blocks.
1164 * Turn the disk light on if the number of free blocks exceeds
1165 * the threshold the user set, either % used or min free blocks.
1166 */
1167 sprintf(s, "%s:%d", diskname, curr_diskstat->BlocksAvailable);
1168 if (scout_attn_disk_mode == SCOUT_DISKM_PCUSED0) {
1169 if ((float)
1170 (curr_diskstat->TotalBlocks -
1171 curr_diskstat->BlocksAvailable) /
1172 (float)(curr_diskstat->TotalBlocks) >
1173 scout_attn_disk_pcused)
1174 pastthreshold = 1;
1175 else
1176 pastthreshold = 0;
1177 } else
1178 pastthreshold =
1179 (curr_diskstat->BlocksAvailable <
1180 scout_attn_disk_minfree) ? 1 : 0;
1181 sc_disk = (a_srvline->disks) + found_idx;
1182 sc_disk->active = 1;
1183 diskdata =
1184 (struct gator_lightobj *)(sc_disk->disk_lp->o_data);
1185 if (scout_debug) {
1186 fprintf(scout_debugfd,
1187 "[%s] Justifying %s for disk idx %d (prev value: '%s')\n",
1188 rn, s, found_idx, diskdata->label);
1189 fflush(scout_debugfd);
1190 }
1191 mini_justify(s, /*Src buffer */
1192 diskdata->label, /*Dest buffer */
1193 scout_col_width[COL_DISK5], /*Dest's width */
1194 SCOUT_LEFT_JUSTIFY1, /*Left-justify */
1195 SCOUT_LEFT_TRUNC0, /*Left-truncate */
1196 SCOUT_IS_LDISK1); /*Labeled disk */
1197
1198 gator_light_set(sc_disk->disk_lp, pastthreshold);
1199
1200 } /*Found disk record */
1201 }
1202
1203 /*Found AFS disk name */
1204 /*
1205 * Advance to the next disk statistics record.
1206 */
1207 curr_diskstat++;
1208 } /*For each statistics record */
1209
1210 /*
1211 * We've now pulled out all the disk statistics from the probe.
1212 * See if any used disks that were there from the last time are
1213 * now gone. If so, we remove them.
1214 */
1215 if (scout_debug) {
1216 fprintf(scout_debugfd,
1217 "[%s] Scanning used disk records for inactive entries\n", rn);
1218 fflush(scout_debugfd);
1219 }
1220 used_disk_idx = a_srvline->used_head;
1221 while (used_disk_idx != SCOUT_NIL(-1)) {
1222 if (scout_debug) {
1223 fprintf(scout_debugfd, "[%s] Examining entry at index %d\n", rn,
1224 used_disk_idx);
1225 fflush(scout_debugfd);
1226 }
1227 sc_disk = (a_srvline->disks) + used_disk_idx;
1228 next_used_idx = sc_disk->next;
1229 if (!(sc_disk->active)) {
1230 scout_RemoveInactiveDisk(a_srvline, /*Server record */
1231 used_disk_idx); /*Disk index to nuke */
1232 fix_light_locs = 1;
1233 }
1234 used_disk_idx = next_used_idx;
1235
1236 } /*Remove inactive used disks */
1237
1238 /*
1239 * If we've had to add or remove disks to/from the used list,
1240 * or if the frame width has changed, we recompute the light
1241 * locations before returning.
1242 */
1243 if (fix_light_locs || a_width_changed)
1244 scout_RecomputeLightLocs(a_srvline);
1245
1246 /*
1247 * Return the (possibly new) size of the current server record.
1248 */
1249 return (a_srvline->num_lines);
1250
1251} /*mini_PrintDiskStats */
1252
1253/*------------------------------------------------------------------------
1254 * FS_Handler
1255 *
1256 * Description:
1257 * Handler routine passed to the fsprobe module. This handler is
1258 * called immediately after a poll of all the FileServers has taken
1259 * place. Its job is to write out selected data to the scout
1260 * screen.
1261 *
1262 * Arguments:
1263 * None.
1264 *
1265 * Returns:
1266 * 0 on success,
1267 * -1 otherwise.
1268 *
1269 * Environment:
1270 * All it needs to know is exported by the fsprobe module, namely
1271 * the data structure where the probe results are stored.
1272 *
1273 * Side Effects:
1274 * Recomputes disk light locations in response to reshaping the
1275 * scout window or from adding/deleting disk lights to/from
1276 * individual servers.
1277 *------------------------------------------------------------------------*/
1278
1279int
1280FS_Handler(void)
1281{ /*FS_Handler */
1282
1283 static char rn[] = "FS_Handler"; /*Routine name */
1284 int code; /*Return code */
1285 struct ProbeViceStatistics *curr_stats; /*Ptr to current stats */
1286 int *curr_probeOK; /*Ptr to current probeOK field */
1287 int curr_srvidx; /*Current server index */
1288 char s[128]; /*String buffer */
1289 static char sblank[] = " "; /*Blank string buffer */
1290 char *sp; /*Ptr to string buffer */
1291 struct mini_line *curr_line; /*Current mini-line */
1292 int curr_line_num; /*Current line number */
1293 struct gator_lightobj *lightdata; /*Private light data */
1294 int setting; /*Light setting (on or off) */
1295 int old_width; /*Keep the old width value */
1296 int width_changed; /*Has the frame width changed? */
1297 int fix_line_num; /*Line number needs fixing */
1298 int delta_line_num; /*Change in line number */
1299
1300 /*
1301 * See if the size of the scout frame has changed since the last
1302 * time.
1303 */
1304 old_width = scout_frameDims.maxx;
1305 if (scout_debug) {
1306 fprintf(scout_debugfd, "[%s] Calling wop_getdimensions\n", rn);
1307 fflush(scout_debugfd);
1308 }
1309 WOP_GETDIMENSIONS(scout_frame->window, &scout_frameDims)(scout_frame->window)->w_op->gw_getdimensions(scout_frame
->window, &scout_frameDims)
;
1310 width_changed = (old_width == scout_frameDims.maxx) ? 0 : 1;
1311 if (scout_debug) {
1312 fprintf(scout_debugfd,
1313 "[%s] Frame dimensions are %d rows, %d columns\n", rn,
1314 scout_frameDims.maxy, scout_frameDims.maxx);
1315 if (width_changed)
1316 fprintf(scout_debugfd, "[%s] Width has changed from %d columns\n",
1317 rn, old_width);
1318 fflush(scout_debugfd);
1319 }
1320
1321 /*
1322 * Print out the selected fields for each server. We actually change
1323 * the light's label to the new data.
1324 */
1325 curr_line = scout_screen.line;
1326 curr_stats = fsprobe_Results.stats;
1327 curr_probeOK = fsprobe_Results.probeOK;
1328 curr_line_num = curr_line->base_line;
1329
1330 setting = 0;
1331 for (curr_srvidx = 0; curr_srvidx < scout_screen.numServers;
1332 curr_srvidx++) {
1333 /*
1334 * If the current server record is set up on the wrong line, fix
1335 * the non-disk light objects directly, and remember to fix the
1336 * disk light objects later on.
1337 */
1338 if (curr_line->base_line != curr_line_num) {
1339 fix_line_num = 1;
1340 delta_line_num = curr_line_num - curr_line->base_line;
1341 curr_line->base_line = curr_line_num;
1342 scout_SetNonDiskLightLine(curr_line, curr_line_num);
1343 } else {
1344 fix_line_num = 0;
1345 delta_line_num = 0;
1346 }
1347
1348 lightdata =
1349 (struct gator_lightobj *)(curr_line->currConns_lp->o_data);
1350 if (*curr_probeOK == 0) {
1351 sp = s;
1352 sprintf(sp, "%d", curr_stats->CurrentConnections);
1353 } else
1354 sp = sblank;
1355 code = mini_justify(sp, /*Src buffer */
1356 lightdata->label, /*Dest buffer */
1357 scout_col_width[COL_CONN0], /*Dest's width */
1358 SCOUT_RIGHT_JUSTIFY0, /*Right-justify */
1359 SCOUT_LEFT_TRUNC0, /*Left-truncate */
1360 SCOUT_ISNT_LDISK0); /*Not a labeled disk */
1361 if (scout_attn_conn != SCOUT_ATTN_NOTUSED(-1)
1362 && curr_stats->CurrentConnections >= scout_attn_conn)
1363 setting = 1;
1364 else
1365 setting = 0;
1366 code = gator_light_set(curr_line->currConns_lp, setting);
1367
1368 lightdata = (struct gator_lightobj *)(curr_line->fetches_lp->o_data);
1369 if (*curr_probeOK == 0) {
1370 sp = s;
1371 sprintf(sp, "%u", curr_stats->TotalFetchs);
1372 } else
1373 sp = sblank;
1374 code = mini_justify(sp, /*Src buffer */
1375 lightdata->label, /*Dest buffer */
1376 scout_col_width[COL_FETCH1], /*Dest's width */
1377 SCOUT_RIGHT_JUSTIFY0, /*Right-justify */
1378 SCOUT_LEFT_TRUNC0, /*Left-truncate */
1379 SCOUT_ISNT_LDISK0); /*Not a labeled disk */
1380 if (scout_attn_fetch != SCOUT_ATTN_NOTUSED(-1)
1381 && curr_stats->TotalFetchs >= scout_attn_fetch)
1382 setting = 1;
1383 else
1384 setting = 0;
1385 code = gator_light_set(curr_line->fetches_lp, setting);
1386
1387 lightdata = (struct gator_lightobj *)(curr_line->stores_lp->o_data);
1388 if (*curr_probeOK == 0) {
1389 sp = s;
1390 sprintf(sp, "%u", curr_stats->TotalStores);
1391 } else
1392 sp = sblank;
1393 code = mini_justify(sp, /*Src buffer */
1394 lightdata->label, /*Dest buffer */
1395 scout_col_width[COL_STORE2], /*Dest's width */
1396 SCOUT_RIGHT_JUSTIFY0, /*Right-justify */
1397 SCOUT_LEFT_TRUNC0, /*Left-truncate */
1398 SCOUT_ISNT_LDISK0); /*Not a labeled disk */
1399 if (scout_attn_store != SCOUT_ATTN_NOTUSED(-1)
1400 && curr_stats->TotalStores >= scout_attn_store)
1401 setting = 1;
1402 else
1403 setting = 0;
1404 code = gator_light_set(curr_line->stores_lp, setting);
1405
1406 lightdata =
1407 (struct gator_lightobj *)(curr_line->workstations_lp->o_data);
1408 if (*curr_probeOK == 0) {
1409 sp = s;
1410 sprintf(sp, "%d", curr_stats->WorkStations);
1411 } else
1412 sp = sblank;
1413 code = mini_justify(sp, /*Src buffer */
1414 lightdata->label, /*Dest buffer */
1415 scout_col_width[COL_WK3], /*Dest's width */
1416 SCOUT_RIGHT_JUSTIFY0, /*Right-justify */
1417 SCOUT_LEFT_TRUNC0, /*Left-truncate */
1418 SCOUT_ISNT_LDISK0); /*Not a labeled disk */
1419 if (scout_attn_workstations != SCOUT_ATTN_NOTUSED(-1)
1420 && curr_stats->WorkStations >= scout_attn_workstations)
1421 setting = 1;
1422 else
1423 setting = 0;
1424 code = gator_light_set(curr_line->workstations_lp, setting);
1425
1426 /*
1427 * We turn the server light on if there was an error in the
1428 * current probe (e.g., if the curr_probeOK field is non-zero.
1429 * (Don't forget to fix the light's line if it needs it).
1430 */
1431 setting = (*curr_probeOK) ? 1 : 0;
1432 code = gator_light_set(curr_line->srvName_lp, setting);
1433
1434 /*
1435 * Print out the disk statistics. The value returned is the
1436 * number of lines taken up by the server record (or 0 if
1437 * something went wrong).
1438 */
1439 code = mini_PrintDiskStats(curr_line, /*Ptr to server line */
1440 curr_stats, /*Fresh disk stats */
1441 *curr_probeOK, /*Was probe OK? */
1442 width_changed, /*Has the width changed? */
1443 fix_line_num, /*Fix the line number? */
1444 delta_line_num); /*Change in line number */
1445 if (code == 0) {
1446 fprintf(stderr__stderrp, "[%s] Error in printing out disk statistics\n",
1447 rn);
1448 return (-1);
1449 } else
1450 curr_line_num += code;
1451
1452 /*
1453 * Advance the current mini_line, stats source, and probe success
1454 * indication.
1455 */
1456 curr_line++;
1457 curr_stats++;
1458 curr_probeOK++;
1459
1460 } /*for each server probed */
1461
1462 /*
1463 * Display the scout frame.
1464 */
1465 sprintf(s, "Probe %d results", fsprobe_Results.probeNum);
1466 gtxframe_DisplayString(scout_frame, s);
1467 WOP_DISPLAY(scout_gwin)(scout_gwin)->w_op->gw_display(scout_gwin);
1468
1469 /*
1470 * Return the happy news.
1471 */
1472 return (0);
1473
1474} /*FS_Handler */
1475
1476/*------------------------------------------------------------------------
1477 * init_mini_line
1478 *
1479 * Description:
1480 * Initialize each line in the mini_screen.
1481 *
1482 * Arguments:
1483 * struct sockaddr_in *a_skt : Ptr to server socket info.
1484 * int a_lineNum; : Line number being created.
1485 * struct mini_line *a_line : Ptr to mini_line to set up.
1486 * char *a_srvname : Printable server name.
1487 *
1488 * Returns:
1489 * 0 on success,
1490 * Error value otherwise.
1491 *
1492 * Environment:
1493 * Nothing interesting.
1494 *
1495 * Side Effects:
1496 * As advertised.
1497 *------------------------------------------------------------------------*/
1498
1499static int
1500init_mini_line(struct sockaddr_in *a_skt, int a_lineNum,
1501 struct mini_line *a_line, char *a_srvname)
1502{ /*init_mini_line */
1503
1504 static char rn[] = "init_mini_line"; /*Routine name */
1505 int curr_x; /*Current X position */
1506 int curr_y; /*Current Y position */
1507 char s[128]; /*Scratch buffer */
1508 int code; /*Return code */
1509 struct gator_lightobj *lightdata; /*Private light data */
1510
1511 if (scout_debug) {
1512 fprintf(scout_debugfd, "[%s] Called for base line %d\n", rn,
1513 a_lineNum);
1514 fflush(scout_debugfd);
1515 }
1516
1517 /*
1518 * Fill in the top fields (except the disk fields, which will be
1519 * done elsewhere), then create the light onodes.
1520 */
1521 memcpy((char *)&(a_line->skt), (char *)a_skt, sizeof(struct sockaddr_in));
1522 a_line->numDisks = 0;
1523 a_line->base_line = a_lineNum + scout_screen.base_line_num;
1524 a_line->num_lines = 1;
1525
1526 curr_x = 1;
1527 curr_y = a_line->base_line;
1528 if ((a_line->currConns_lp =
1529 mini_initLightObject("Conns", curr_x, curr_y, scout_col_width[COL_CONN0],
1530 scout_gwin))
1531 == NULL((void *)0)) {
1532 fprintf(stderr__stderrp, "[%s:%s] Can't create currConns light object\n", pn,
1533 rn);
1534 return (-1);
1535 }
1536 curr_x += scout_col_width[COL_CONN0] + 1;
1537
1538 if ((a_line->fetches_lp =
1539 mini_initLightObject("Fetches", curr_x, curr_y, scout_col_width[COL_FETCH1],
1540 scout_frame->window))
1541 == NULL((void *)0)) {
1542 fprintf(stderr__stderrp, "[%s:%s] Can't create fetches light object\n", pn,
1543 rn);
1544 return (-1);
1545 }
1546 curr_x += scout_col_width[COL_FETCH1] + 1;
1547
1548 if ((a_line->stores_lp =
1549 mini_initLightObject("Stores", curr_x, curr_y, scout_col_width[COL_STORE2],
1550 scout_frame->window))
1551 == NULL((void *)0)) {
1552 fprintf(stderr__stderrp, "[%s:%s] Can't create stores light object\n", pn, rn);
1553 return (-1);
1554 }
1555 curr_x += scout_col_width[COL_STORE2] + 1;
1556
1557 if ((a_line->workstations_lp =
1558 mini_initLightObject("WrkStn", curr_x, curr_y, scout_col_width[COL_WK3],
1559 scout_frame->window))
1560 == NULL((void *)0)) {
1561 fprintf(stderr__stderrp, "[%s:%s] Can't create workstations light object\n",
1562 pn, rn);
1563 return (-1);
1564 }
1565 curr_x += scout_col_width[COL_WK3] + 1;
1566
1567 if ((a_line->srvName_lp =
1568 mini_initLightObject(a_srvname, curr_x, curr_y,
1569 scout_col_width[COL_SRVNAME4], scout_frame->window))
1570 == NULL((void *)0)) {
1571 fprintf(stderr__stderrp, "[%s:%s] Can't create server name light object\n", pn,
1572 rn);
1573 return (-1);
1574 }
1575 sprintf(s, "%s", a_srvname);
1576 lightdata = (struct gator_lightobj *)(a_line->srvName_lp->o_data);
1577 code = mini_justify(s, /*Src buffer */
1578 lightdata->label, /*Dest buffer */
1579 scout_col_width[COL_SRVNAME4], /*Dest's width */
1580 SCOUT_CENTER2, /*Centered */
1581 SCOUT_RIGHT_TRUNC1, /*Right-truncate */
1582 SCOUT_ISNT_LDISK0); /*Not a labeled disk */
1583 if (code) {
1584 fprintf(stderr__stderrp,
1585 "[%s] Can't center server name inside of light object\n", rn);
1586 return (code);
1587 }
1588 curr_x += scout_col_width[COL_SRVNAME4] + 1;
1589
1590 if (scout_initDiskLightObjects(a_line, scout_frame->window)) {
1591 fprintf(stderr__stderrp, "[%s:%s] Can't create disk light objects\n", pn, rn);
1592 return (-1);
1593 }
1594
1595 /*
1596 * Finally, return the happy news.
1597 */
1598 return (0);
1599
1600} /*init_mini_line */
1601
1602/*------------------------------------------------------------------------
1603 * execute_scout
1604 *
1605 * Description:
1606 * Workhorse routine that starts up the FileServer probe.
1607 *
1608 * Arguments:
1609 * int a_numservers : Length of above list.
1610 * struct cmd_item *a_srvname : List of FileServer machines to
1611 * monitor.
1612 * int a_pkg : Window package to use.
1613 *
1614 * Returns:
1615 * 0 on success,
1616 * Error value otherwise.
1617 *
1618 * Environment:
1619 * Nothing interesting.
1620 *
1621 * Side Effects:
1622 * As advertised.
1623 *------------------------------------------------------------------------*/
1624
1625static int
1626execute_scout(int a_numservers, struct cmd_item *a_srvname, int a_pkg)
1627{ /*execute_scout */
1628
1629 static char rn[] = "execute_scout"; /*Routine name */
1630 static char fullsrvname[128]; /*Full server name */
1631 int code; /*Return code */
1632 struct sockaddr_in *FSSktArray; /*Server socket array */
1633 int sktbytes; /*Num bytes in above */
1634 struct sockaddr_in *curr_skt; /*Ptr to current socket */
1635 struct cmd_item *curr_item; /*Ptr to current cmd item */
1636 struct hostent *he; /*Host entry */
1637 struct mini_line *mini_lines; /*Ptr to all mini-lines */
1638 struct mini_line *curr_line; /*Ptr to current line */
1639 int i; /*Generic loop variable */
1640 int mini_line_bytes; /*Num bytes in mini_lines */
1641 struct timeval tv; /*Time structure */
1642 int linenum; /*Current mini-line number */
1643#if 0
1644 PROCESS pid; /*Main LWP process ID */
1645 PROCESS gxlistener_ID; /*Input Server LWP process ID */
1646#endif /* 0 */
1647 struct gator_lightobj *lightdata; /*Private light data */
1648
1649 if (scout_debug) {
1650 fprintf(scout_debugfd, "[%s] Called\n", rn);
1651 fflush(scout_debugfd);
1652 }
1653
1654 /*
1655 * We have to initialize LWP support before we start up any of
1656 * our packages.
1657 */
1658#if 0
1659 code = LWP_InitializeProcessSupport(LWP_NORMAL_PRIORITY(4 -2), &pid);
1660 if (code) {
1661 fprintf(stderr__stderrp, "[%s:%s] Can't initialize LWP\n", pn, rn);
1662 scout_CleanExit(code);
1663 }
1664#endif /* 0 */
1665
1666 /*
1667 * Initialize the gtx package.
1668 */
1669#if 0
1670 fprintf(stderr__stderrp, "[%s:%s] Starting up gtx package\n", pn, rn);
1671#endif /* 0 */
1672 scout_gwin = gtx_Init(0, /*Don't start up InputServer yet */
1673 -1); /*Type of window package */
1674 if (scout_gwin == NULL((void *)0)) {
1675 fprintf(stderr__stderrp, "[%s:%s] Call to gtx_Init() failed!\n", pn, rn);
1676 return (-1);
1677 }
1678
1679 /*
1680 * Remember we've set up gtx so we can exit cleanly from now on.
1681 */
1682 scout_gtx_initialized = 1;
1683
1684 /*
1685 * Create the frame everything will go into, set it up as our only
1686 * frame for this window.
1687 */
1688 scout_frame = gtxframe_Create();
1689 if (scout_frame == (struct gtx_frame *)0) {
1690 fprintf(stderr__stderrp, "[%s:%s] Call to gtxframe_Create() failed!\n", pn,
1691 rn);
1692 return (-1);
1693 }
1694 gtxframe_SetFrame(scout_gwin, scout_frame);
1695 WOP_GETDIMENSIONS(scout_frame->window, &scout_frameDims)(scout_frame->window)->w_op->gw_getdimensions(scout_frame
->window, &scout_frameDims)
;
1696
1697 /*
1698 * Allocate an array of sockets to describe each FileServer we'll be
1699 * watching.
1700 */
1701 sktbytes = a_numservers * sizeof(struct sockaddr_in);
1702 FSSktArray = (struct sockaddr_in *)malloc(sktbytes);
1703 if (FSSktArray == (struct sockaddr_in *)0) {
1704 fprintf(stderr__stderrp,
1705 "[%s] Can't malloc() %d sockaddrs (%d bytes) for the given servers\n",
1706 rn, a_numservers, sktbytes);
1707 scout_CleanExit(-1);
1708 }
1709 memset(FSSktArray, 0, sktbytes);
1710
1711 /*
1712 * Sweep through the server names provided, filling in the socket
1713 * info for each. Take into account the fact that we may have a
1714 * base name associated for each.
1715 */
1716 curr_item = a_srvname;
1717 curr_skt = FSSktArray;
1718 while (curr_item) {
1719 if (*scout_basename == '\0')
1720 sprintf(fullsrvname, "%s", curr_item->data);
1721 else
1722 sprintf(fullsrvname, "%s.%s", curr_item->data, scout_basename);
1723 he = hostutil_GetHostByName(fullsrvname);
1724 if (he == NULL((void *)0)) {
1725 fprintf(stderr__stderrp, "[%s] Can't get host info for '%s'\n", rn,
1726 fullsrvname);
1727 return (-1);
1728 }
1729 memcpy(&(curr_skt->sin_addr.s_addr), he->h_addrh_addr_list[0], 4);
1730 curr_skt->sin_family = AF_INET2;
1731 curr_skt->sin_port = htons(7000)(__builtin_constant_p(7000) ? (__uint16_t)(((__uint16_t)(7000
)) << 8 | ((__uint16_t)(7000)) >> 8) : __bswap16_var
(7000))
; /* FileServer port */
1732
1733 /*
1734 * Bump our pointers.
1735 */
1736 curr_item = curr_item->next;
1737 curr_skt++;
1738
1739 } /*Build socket entry for each server */
1740
1741 /*
1742 * Create the set of mini-lines, one per server.
1743 */
1744 mini_line_bytes = a_numservers * sizeof(struct mini_line);
1745 mini_lines = (struct mini_line *)malloc(mini_line_bytes);
1746 if (mini_lines == (struct mini_line *)0) {
1747 fprintf(stderr__stderrp, "[%s] Can't malloc() %d bytes for %d screen lines\n",
1748 rn, mini_line_bytes, a_numservers);
1749 return (-1);
1750 }
1751 memset(mini_lines, 0, mini_line_bytes);
1752
1753 /*
1754 * Set up each line in the mini_lines, creating and initializing
1755 * its light objects.
1756 */
1757 scout_screen.base_line_num = 4;
1758 curr_line = mini_lines;
1759 curr_skt = FSSktArray;
1760 linenum = 0;
1761 curr_item = a_srvname;
1762 gtxframe_ClearList(scout_frame);
1763
1764 /*
1765 * Create the light objects that server as banner lines. Remember
1766 * to take into account the server basename, if any, and the name
1767 * of the host that scout if running on, if that's wanted.
1768 */
1769 if (scout_showhostname) {
1770 if (*scout_basename == '\0')
1771 sprintf(scout_Banner, "[%s] %s", scout_hostname, "Scout");
1772 else
1773 sprintf(scout_Banner, "[%s] Scout for %s", scout_hostname,
1774 scout_basename);
1775 } else {
1776 if (*scout_basename == '\0')
1777 sprintf(scout_Banner, "%s", " Scout");
1778 else
1779 sprintf(scout_Banner, " Scout for %s", scout_basename);
1780 }
1781 scout_banner0_lp = mini_initLightObject("Banner 0", /*Light name */
1782 0, /*X*/ 0, /*Y*/ scout_frameDims.maxx, /*Width */
1783 scout_gwin); /*Window */
1784 if (scout_banner0_lp != NULL((void *)0)) {
1785 lightdata = (struct gator_lightobj *)(scout_banner0_lp->o_data);
1786 code =
1787 mini_justify(scout_Banner, lightdata->label, scout_frameDims.maxx,
1788 SCOUT_CENTER2, SCOUT_RIGHT_TRUNC1, SCOUT_ISNT_LDISK0);
1789 code = gator_light_set(scout_banner0_lp, 1);
1790 code = gtxframe_AddToList(scout_frame, scout_banner0_lp);
1791
1792 /*Debugging */
1793 if (scout_debug)
1794 fprintf(scout_debugfd, "[%s] Scout label is '%s', %" AFS_SIZET_FMT"zu" " chars\n", rn,
1795 lightdata->label, strlen(lightdata->label));
1796 }
1797
1798 scout_banner1_lp = mini_initLightObject("Banner 1", /*Light name */
1799 0, /*X*/ 2, /*Y*/ scout_frameDims.maxx, /*Width */
1800 scout_gwin); /*Window */
1801 if (scout_banner1_lp != NULL((void *)0)) {
1802 char attn_label[256];
1803 if (scout_attn_disk_mode == SCOUT_DISKM_PCUSED0) {
1804 snprintf(attn_label, sizeof(attn_label), "%s: > %s%% used",
1805 scout_label[5], scout_attn_disk_pcusedstr);
1806 } else {
1807 snprintf(attn_label, sizeof(attn_label), "%s: < %d blocks free",
1808 scout_label[5], scout_attn_disk_minfree);
1809 }
1810 snprintf(scout_Banner, sizeof(scout_Banner),
1811 "%*s %*s %*s %*s %*s %s",
1812 scout_col_width[0], scout_label[0],
1813 scout_col_width[1], scout_label[1],
1814 scout_col_width[2], scout_label[2],
1815 scout_col_width[3], scout_label[3],
1816 scout_col_width[4], scout_label[4],
1817 attn_label);
1818
1819 lightdata = (struct gator_lightobj *)(scout_banner1_lp->o_data);
1820 code =
1821 mini_justify(scout_Banner, lightdata->label, scout_frameDims.maxx,
1822 SCOUT_LEFT_JUSTIFY1, SCOUT_RIGHT_TRUNC1,
1823 SCOUT_ISNT_LDISK0);
1824
1825 code = gtxframe_AddToList(scout_frame, scout_banner1_lp);
1826 }
1827
1828 scout_banner2_lp = mini_initLightObject("Banner 2", /*Light name */
1829 0, /*X*/ 3, /*Y*/ scout_frameDims.maxx, /*Width */
1830 scout_gwin); /*Window */
1831 if (scout_banner2_lp != NULL((void *)0)) {
1832 snprintf(scout_Banner, sizeof(scout_Banner),
1833 "%*s %*s %*s %*s %*s %s",
1834 scout_col_width[0], scout_underline[0],
1835 scout_col_width[1], scout_underline[1],
1836 scout_col_width[2], scout_underline[2],
1837 scout_col_width[3], scout_underline[3],
1838 scout_col_width[4], scout_underline[4],
1839 scout_underline[5]);
1840
1841 lightdata = (struct gator_lightobj *)(scout_banner2_lp->o_data);
1842 code =
Value stored to 'code' is never read
1843 mini_justify(scout_Banner, lightdata->label,
1844 scout_frameDims.maxx, SCOUT_LEFT_JUSTIFY1,
1845 SCOUT_RIGHT_TRUNC1, SCOUT_ISNT_LDISK0);
1846 code = gtxframe_AddToList(scout_frame, scout_banner2_lp);
1847 }
1848
1849 for (i = 0; i < a_numservers; i++) {
1850 code = init_mini_line(curr_skt, linenum, curr_line, curr_item->data);
1851 if (code) {
1852 fprintf(stderr__stderrp, "[%s] Can't initialize line for server %d\n", rn,
1853 i);
1854 return (-1);
1855 }
1856 curr_skt++;
1857 curr_line++;
1858 linenum++;
1859 curr_item = curr_item->next;
1860 }
1861
1862 /*
1863 * Now that all lines have been set up, we feed in the light items
1864 * created. Note: the disk lights are entered at a later time,
1865 * as they enter the used disk list for each server.
1866 */
1867 curr_line = mini_lines;
1868 for (i = 0; i < a_numservers; i++) {
1869 code = gtxframe_AddToList(scout_frame, curr_line->currConns_lp);
1870 if (code) {
1871 fprintf(stderr__stderrp,
1872 "[%s] Can't add client connections light to display list\n",
1873 rn);
1874 return (code);
1875 }
1876
1877 code = gtxframe_AddToList(scout_frame, curr_line->fetches_lp);
1878 if (code) {
1879 fprintf(stderr__stderrp,
1880 "[%s] Can't add fetches light to frame display list\n",
1881 rn);
1882 return (code);
1883 }
1884
1885 code = gtxframe_AddToList(scout_frame, curr_line->stores_lp);
1886 if (code) {
1887 fprintf(stderr__stderrp,
1888 "[%s] Can't add stores light to frame display list\n",
1889 rn);
1890 return (code);
1891 }
1892
1893 code = gtxframe_AddToList(scout_frame, curr_line->workstations_lp);
1894 if (code) {
1895 fprintf(stderr__stderrp,
1896 "[%s] Can't add workstation light to display list\n", rn);
1897 return (code);
1898 }
1899
1900 code = gtxframe_AddToList(scout_frame, curr_line->srvName_lp);
1901 if (code) {
1902 fprintf(stderr__stderrp,
1903 "[%s] Can't add server name light to display list\n", rn);
1904 return (code);
1905 }
1906
1907 /*
1908 * Move down to the next server record.
1909 */
1910 curr_line++;
1911
1912 } /*Add lights in server records to display list */
1913
1914#if 0
1915 /*
1916 * Set up the minimal keymap.
1917 */
1918 code = keymap_BindToString(scout_frame->keymap, /*Ptr to keymap */
1919 "e", /*Key to bind */
1920 ExitCmd, /*Cmd to execute */
1921 NULL((void *)0), /*Name */
1922 NULL((void *)0)); /*Ptr to rock */
1923 if (code) {
1924 fprintf(stderr__stderrp, "[%s] Can't bind key `e', code is %d\n", rn, code);
1925 return (code);
1926 }
1927#endif /* 0 */
1928
1929 /*
1930 * Finish setting up the overall mini_screen structure.
1931 */
1932 scout_screen.numServers = a_numservers;
1933 scout_screen.line = mini_lines;
1934 WOP_GETDIMENSIONS(scout_frame->window, &scout_frameDims)(scout_frame->window)->w_op->gw_getdimensions(scout_frame
->window, &scout_frameDims)
;
1935
1936 /*
1937 * Start up the fsprobe package, which will gather FileServer
1938 * statistics for us on a regular basis.
1939 */
1940 gtxframe_DisplayString(scout_frame,
1941 "Establishing File Server connection(s)...");
1942 code = fsprobe_Init(a_numservers, /*Num FileServers to probe */
1943 FSSktArray, /*FileServer socket array */
1944 scout_probefreq, /*Probe frequency */
1945 FS_Handler, /*Handler routine */
1946 0); /*Turn debugging output off */
1947#if 0
1948 scout_debug); /*Turn debugging output off */
1949#endif /* 0 */
1950 if (code) {
1951 fprintf(stderr__stderrp, "[%s] Error returned by fsprobe_Init: %d\n", rn,
1952 code);
1953 return (-1);
1954 }
1955
1956
1957 /*
1958 * Start up the input server LWP for our window.
1959 */
1960#if 0
1961 code = LWP_CreateProcess(gtx_InputServer, /*Fcn to start up */
1962 8192, /*Stack size in bytes */
1963 LWP_NORMAL_PRIORITY(4 -2), /*Priority */
1964 (void *)scout_gwin, /*Params: Ptr to window */
1965 "gx-listener", /*Name to use */
1966 &gxlistener_ID); /*Returned LWP process ID */
1967#endif /* 0 */
1968
1969 code = (int)(intptr_t)gtx_InputServer(scout_gwin);
1970 if (code) {
1971 fprintf(stderr__stderrp,
1972 "[%s] Error exit from gtx_InputServer(), error is %d\n", rn,
1973 code);
1974 scout_CleanExit(code);
1975 }
1976
1977 /*
1978 * We fall into a loop, sleeping forever.
1979 */
1980 while (1) {
1981 tv.tv_sec = 60 * 60; /*Sleep for an hour at a time */
1982 tv.tv_usec = 0;
1983 code = select(0, /*Num fds */
1984 0, /*Descriptors ready for reading */
1985 0, /*Descriptors ready for writing */
1986 0, /*Descriptors with exceptional conditions */
1987 &tv); /*Timeout structure */
1988 } /*Sleep forever */
1989
1990#if 0
1991 /*
1992 * How did we get here? Oh, well, clean up our windows and
1993 * return sweetness and light anyway.
1994 */
1995 WOP_CLEANUP(&scout_gwin)((*(gwinbops.gw_cleanup))(&scout_gwin));
1996 return (0);
1997#endif /* 0 */
1998
1999} /*execute_scout */
2000
2001/*------------------------------------------------------------------------
2002 * countServers
2003 *
2004 * Description:
2005 * Given a pointer to the list of servers we'll be polling,
2006 * compute the length of the list.
2007 *
2008 * Arguments:
2009 * struct cmd_item *a_firstItem : Ptr to first item in list.
2010 *
2011 * Returns:
2012 * Length of the above list.
2013 *
2014 * Environment:
2015 * Nothing interesting.
2016 *
2017 * Side Effects:
2018 * As advertised.
2019 *------------------------------------------------------------------------*/
2020
2021static int countServers(struct cmd_item *a_firstItem)
2022{ /*countServers */
2023
2024 int list_len; /*List length */
2025 struct cmd_item *curr_item; /*Ptr to current item */
2026
2027 list_len = 0;
2028 curr_item = a_firstItem;
2029
2030 /*
2031 * Count 'em up.
2032 */
2033 while (curr_item) {
2034 list_len++;
2035 curr_item = curr_item->next;
2036 }
2037
2038 /*
2039 * Return our tally.
2040 */
2041 return (list_len);
2042
2043} /*countServers */
2044
2045/*------------------------------------------------------------------------
2046 * scout_AdoptThresholds
2047 *
2048 * Description:
2049 * Parse and adopt one or more threshold values, as read off the
2050 * command line.
2051 *
2052 * Arguments:
2053 * struct cmd_item *a_thresh_item : Ptr to item on command-line
2054 * threshold list.
2055 *
2056 * Returns:
2057 * Nothing (but may exit the entire program on error!)
2058 *
2059 * Environment:
2060 * Valid keywords are:
2061 * conn, disk, fetch, store, ws
2062 * The disk value, if it has a % sign, signifies that attention
2063 * will be triggered when the disk is more than that percentage
2064 * full; otherwise, it will specify the minimum number of free
2065 * blocks.
2066 *
2067 * Side Effects:
2068 * As specified.
2069 *------------------------------------------------------------------------*/
2070
2071static void scout_AdoptThresholds(struct cmd_item *a_thresh_item)
2072{ /*scout_AdoptThresholds */
2073
2074 static char rn[] = "scout_AdoptThresholds"; /*Routine name */
2075 struct cmd_item *curr_item; /*Current item */
2076 char *curr_name; /*Current name half of pair */
2077 char *curr_value; /*Current value half of pair */
2078 int diskval_len; /*Length of disk attn value */
2079
2080 curr_item = a_thresh_item;
2081 while (curr_item) {
2082 /*
2083 * If there isn't a corresponding value for the current
2084 * attention field, bitch & die.
2085 */
2086 if (curr_item->next == (struct cmd_item *)0) {
2087 printf("[%s] No threshold value given for '%s'\n", rn,
2088 curr_item->data);
2089 scout_CleanExit(-1);
2090 }
2091
2092 curr_name = curr_item->data;
2093 curr_value = curr_item->next->data;
2094
2095 if (strcmp(curr_name, "conn") == 0) {
2096 if (scout_debug) {
2097 fprintf(scout_debugfd,
2098 "[%s] Setting conn attn value to %d (default %d)\n",
2099 rn, atoi(curr_value), scout_attn_conn);
2100 fflush(scout_debugfd);
2101 }
2102 scout_attn_conn = atoi(curr_value);
2103 } else if (strcmp(curr_name, "disk") == 0) {
2104 /*
2105 * If there's a '%' as the last character in the value,
2106 * we use percentage mode.
2107 */
2108 diskval_len = strlen(curr_value);
2109 if (curr_value[diskval_len - 1] == '%') {
2110 curr_value[diskval_len - 1] = '\0';
2111 if (scout_debug) {
2112 fprintf(scout_debugfd,
2113 "[%s] New disk attn value: 0.%s used (default %f)\n",
2114 rn, curr_value, scout_attn_disk_pcused);
2115 fflush(scout_debugfd);
2116 }
2117 sprintf(scout_attn_disk_pcusedstr, "%s", curr_value);
2118 scout_attn_disk_pcused =
2119 ((float)(atoi(curr_value))) / ((float)(100));
2120 } /*Percentage mode */
2121 else {
2122 if (scout_debug) {
2123 fprintf(scout_debugfd,
2124 "[%s] New disk attn value: %s min free (default %f)\n",
2125 rn, curr_value, scout_attn_disk_pcused);
2126 fflush(scout_debugfd);
2127 }
2128 scout_attn_disk_mode = SCOUT_DISKM_MINFREE1;
2129 scout_attn_disk_minfree = atoi(curr_value);
2130 } /*Min free blocks mode */
2131 } else if (strcmp(curr_name, "fetch") == 0) {
2132 if (scout_debug) {
2133 fprintf(scout_debugfd,
2134 "[%s] Setting fetch attn value to %d (default %d)\n",
2135 rn, atoi(curr_value), scout_attn_fetch);
2136 fflush(scout_debugfd);
2137 }
2138 scout_attn_fetch = atoi(curr_value);
2139 } else if (strcmp(curr_name, "store") == 0) {
2140 if (scout_debug) {
2141 fprintf(scout_debugfd,
2142 "[%s] Setting store attn value to %d (default %d)\n",
2143 rn, atoi(curr_value), scout_attn_store);
2144 fflush(scout_debugfd);
2145 }
2146 scout_attn_store = atoi(curr_value);
2147 } else if (strcmp(curr_name, "ws") == 0) {
2148 if (scout_debug) {
2149 fprintf(scout_debugfd,
2150 "[%s] Setting workstation attn value to %d (default %d)\n",
2151 rn, atoi(curr_value), scout_attn_workstations);
2152 fflush(scout_debugfd);
2153 }
2154 scout_attn_workstations = atoi(curr_value);
2155 } else {
2156 printf("[%s] Unknown attention item: '%s'\n", rn,
2157 curr_item->data);
2158 scout_CleanExit(-1);
2159 }
2160
2161 /*
2162 * Advance past the just-processed pair.
2163 */
2164 curr_item = curr_item->next->next;
2165
2166 } /*Interpret each name-value pair */
2167
2168} /*scout_AdoptThresholds */
2169
2170/**
2171 * Setup the user specified column widths.
2172 *
2173 * The column widths specifies the number of digits which
2174 * will be displayed without truncation. The column widths
2175 * are given in the same order in which they are displayed,
2176 * from left to right. Not all columns need to be specified
2177 * on the command line. The default column widths for those
2178 * columns not specified. Column widths can not be set smaller
2179 * than the heading underline.
2180 *
2181 * @param[in] a_width_item command line width item list
2182 */
2183void
2184scout_SetColumnWidths(struct cmd_item *a_width_item)
2185{
2186 int i;
2187 int width;
2188 int num_cols = sizeof(scout_col_width) / sizeof(*scout_col_width);
2189
2190 for (i = 0; a_width_item && i < num_cols; i++) {
2191 width = atoi(a_width_item->data);
2192 if (width > 0) {
2193 int min_width = strlen(scout_underline[i]);
2194 if (min_width) {
2195 width = max(width, min_width)((width) < (min_width) ? (min_width) : (width));
2196 }
2197 scout_col_width[i] = width + 1;
2198 }
2199 a_width_item = a_width_item->next;
2200 }
2201 if (a_width_item) {
2202 fprintf(stderr__stderrp, "Too many values given for -columnwidths\n");
2203 scout_CleanExit(1);
2204 }
2205}
2206
2207/*------------------------------------------------------------------------
2208 * scoutInit
2209 *
2210 * Description:
2211 * Routine called when Scout is invoked, responsible for basic
2212 * initialization, command line parsing, and calling the
2213 * routine that does all the work.
2214 *
2215 * Arguments:
2216 * as : Command syntax descriptor.
2217 * arock : Associated rock (not used here).
2218 *
2219 * Returns:
2220 * Zero (but may exit the entire program on error!)
2221 *
2222 * Environment:
2223 * Nothing interesting.
2224 *
2225 * Side Effects:
2226 * Initializes this program.
2227 *------------------------------------------------------------------------*/
2228
2229static int scoutInit(struct cmd_syndesc *as, void *arock)
2230{ /*scoutInit */
2231
2232 static char rn[] = "scoutInit"; /*Routine name */
2233 int code; /*Return code */
2234 int wpkg_to_use; /*Window package to use */
2235 int server_count; /*Number of servers to watch */
2236 char *debug_filename; /*Name of debugging output file */
2237
2238 if (scout_debug) {
2239 fprintf(scout_debugfd, "[%s] Called\n", rn);
2240 fflush(scout_debugfd);
2241 }
2242
2243 if (as->parms[P_DEBUG5].items != 0) {
2244 scout_debug = 1;
2245 debug_filename = as->parms[P_DEBUG5].items->data;
2246 scout_debugfd = fopen(debug_filename, "w");
2247 if (scout_debugfd == (FILE *) 0) {
2248 printf("[%s] Can't open debugging file '%s'!\n", rn,
2249 debug_filename);
2250 scout_CleanExit(-1);
2251 }
2252 fprintf(scout_debugfd, "[%s] Writing to Scout debugging file '%s'\n",
2253 rn, debug_filename);
2254 }
2255#if 0
2256 wpkg_to_use = atoi(as->parms[P_PACKAGE].items->data);
2257#endif /* 0 */
2258 wpkg_to_use = 2; /*Always use curses for now */
2259#if 0
2260 fprintf(stderr__stderrp, "[%s:%s] Using graphics package %d: ", pn, rn,
2261 wpkg_to_use);
2262 switch (wpkg_to_use) {
2263 case GATOR_WIN_CURSES2:
2264 fprintf(stderr__stderrp, "curses\n");
2265 break;
2266 case GATOR_WIN_DUMB1:
2267 fprintf(stderr__stderrp, "dumb terminal\n");
2268 break;
2269 case GATOR_WIN_X113:
2270 fprintf(stderr__stderrp, "X11\n");
2271 break;
2272 default:
2273 fprintf(stderr__stderrp, "Illegal graphics package: %d\n", wpkg_to_use);
2274 scout_CleanExit(-1);
2275 } /*end switch (wpkg_to_use) */
2276#endif /* 0 */
2277
2278 if (as->parms[P_FREQ2].items != 0)
2279 scout_probefreq = atoi(as->parms[P_FREQ2].items->data);
2280 else
2281 scout_probefreq = 60;
2282
2283 /*
2284 * See if we've been fed a base server name.
2285 */
2286 if (as->parms[P_BASE1].items != 0)
2287 sprintf(scout_basename, "%s", as->parms[P_BASE1].items->data);
2288 else
2289 *scout_basename = '\0';
2290
2291 /*
2292 * Count the number of servers we've been asked to monitor.
2293 */
2294 server_count = countServers(as->parms[P_SERVER0].items);
2295
2296 /*
2297 * Create a line of blanks, a generally-useful thing.
2298 */
2299 sprintf(scout_blankline, "%255s", " ");
2300
2301 /*
2302 * Pull in the name of the host we're executing on if we've been
2303 * asked to. If we can't get the name, we provide a default.
2304 */
2305 if (as->parms[P_HOST3].items != 0) {
2306 scout_showhostname = 1;
2307 *scout_hostname = '\0';
2308 code = gethostname(scout_hostname, 128);
2309 if (code)
2310 sprintf(scout_hostname, "%s", "*No Hostname*");
2311 }
2312
2313 /*
2314 * Pull in any and all attention/highlighting thresholds.
2315 */
2316 if (as->parms[P_ATTENTION4].items != 0)
2317 scout_AdoptThresholds(as->parms[P_ATTENTION4].items);
2318
2319 if (as->parms[P_WIDTHS6].items != 0) {
2320 scout_SetColumnWidths(as->parms[P_WIDTHS6].items);
2321 }
2322
2323 /*
2324 * Now, drive the sucker.
2325 */
2326 code = execute_scout(server_count, /*Num servers */
2327 as->parms[P_SERVER0].items, /*Ptr to srv names */
2328 wpkg_to_use); /*Graphics pkg */
2329 if (code) {
2330 fprintf(stderr__stderrp, "[%s] Error executing scout: %d\n", rn, code);
2331 scout_CleanExit(-1);
2332 }
2333
2334 /*
2335 * We initialized (and ran) correctly, so return the good news.
2336 */
2337 return (0);
2338
2339} /*scoutInit */
2340
2341#include "AFS_component_version_number.c"
2342
2343int
2344main(int argc, char **argv)
2345{ /*main */
2346
2347 afs_int32 code; /*Return code */
2348 struct cmd_syndesc *ts; /*Ptr to cmd line syntax descriptor */
2349
2350#ifdef AFS_AIX32_ENV
2351 /*
2352 * The following signal action for AIX is necessary so that in case of a
2353 * crash (i.e. core is generated) we can include the user's data section
2354 * in the core dump. Unfortunately, by default, only a partial core is
2355 * generated which, in many cases, isn't too useful.
2356 */
2357 struct sigaction nsa;
2358
2359 sigemptyset(&nsa.sa_mask);
2360 nsa.sa_handler__sigaction_u.__sa_handler = SIG_DFL((__sighandler_t *)0);
2361 nsa.sa_flags = SA_FULLDUMP;
2362 sigaction(SIGSEGV11, &nsa, NULL((void *)0));
2363#endif
2364 /*
2365 * Set up the commands we understand.
2366 */
2367 ts = cmd_CreateSyntax("initcmd", scoutInit, NULL((void *)0), "initialize the program");
2368 cmd_AddParm(ts, "-server", CMD_LIST3, CMD_REQUIRED0,
2369 "FileServer name(s) to monitor");
2370 cmd_AddParm(ts, "-basename", CMD_SINGLE2, CMD_OPTIONAL1,
2371 "base server name");
2372#if 0
2373 cmd_AddParm(ts, "-package", CMD_SINGLE2, CMD_REQUIRED0,
2374 "Graphics package to use");
2375#endif /* 0 */
2376 cmd_AddParm(ts, "-frequency", CMD_SINGLE2, CMD_OPTIONAL1,
2377 "poll frequency, in seconds");
2378 cmd_AddParm(ts, "-host", CMD_FLAG1, CMD_OPTIONAL1,
2379 "show name of host you're running on");
2380 cmd_AddParm(ts, "-attention", CMD_LIST3, CMD_OPTIONAL1,
2381 "specify attention (highlighting) level");
2382 cmd_AddParm(ts, "-debug", CMD_SINGLE2, CMD_OPTIONAL1,
2383 "turn debugging output on to the named file");
2384 cmd_AddParm(ts, "-columnwidths", CMD_LIST3, CMD_OPTIONAL1,
2385 "specify column widths");
2386
2387 /*
2388 * Parse command-line switches & execute the test, then get the heck
2389 * out of here.
2390 */
2391 code = cmd_Dispatch(argc, argv);
2392 if (code) {
2393#if 0
2394 fprintf(stderr__stderrp, "[%s:%s] Call to cmd_Dispatch() failed; code is %d\n",
2395 pn, rn, code);
2396#endif /* 0 */
2397 scout_CleanExit(1);
2398 } else
2399 scout_CleanExit(0);
2400
2401 return 0; /* not reachable */
2402} /*main */