File: | scout/scout.c |
Location: | line 1842, column 2 |
Description: | Value stored to 'code' is never read |
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 | */ |
96 | struct 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 | */ |
109 | struct 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 | */ |
138 | struct 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 | |
144 | static char pn[] = "scout"; /*Program name */ |
145 | static int scout_debug = 0; /*Is debugging turned on? */ |
146 | static FILE *scout_debugfd; /*Debugging file descriptor */ |
147 | static int scout_gtx_initialized = 0; /*Has gtx been initialized? */ |
148 | static struct mini_screen scout_screen; /*Mini-screen itself */ |
149 | static int scout_probefreq; /*Probe frequency in seconds */ |
150 | static char scout_basename[64]; /*Base server name */ |
151 | static char scout_hostname[128]; /*Name of machine we're running on */ |
152 | static int scout_showhostname = 0; /*Show name of machine we're on? */ |
153 | static char scout_blankline[256]; /*Blank line */ |
154 | static struct gwin *scout_gwin; /*Window to use */ |
155 | static struct gtx_frame *scout_frame; /*Frame to use */ |
156 | static struct onode *scout_banner0_lp; /*Banner light, line 0 */ |
157 | static struct onode *scout_banner1_lp; /*Banner light, line 1 */ |
158 | static struct onode *scout_banner2_lp; /*Banner light, line 2 */ |
159 | static int scout_DiskLightLeftCol = 0; /*Column for leftmost disk light */ |
160 | static struct gwin_sizeparams scout_frameDims; /*Frame dimensions */ |
161 | |
162 | static 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 | |
177 | static int scout_attn_conn = SCOUT_ATTN_NOTUSED(-1); |
178 | static int scout_attn_fetch = SCOUT_ATTN_NOTUSED(-1); |
179 | static int scout_attn_store = SCOUT_ATTN_NOTUSED(-1); |
180 | static int scout_attn_workstations = SCOUT_ATTN_NOTUSED(-1); |
181 | static int scout_attn_disk_mode = SCOUT_DISKM_PCUSED0; |
182 | static int scout_attn_disk_minfree = 1000; |
183 | static float scout_attn_disk_pcused = 0.95; |
184 | static char scout_attn_disk_pcusedstr[8] = "95"; |
185 | |
186 | /* |
187 | * Some strings we'll be using over and over again. |
188 | */ |
189 | static char scout_Banner[256]; |
190 | static const char *scout_label[] = |
191 | { "Conn", "Fetch", "Store", "Ws", "", "Disk attn" }; |
192 | static 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 | |
219 | static void |
220 | scout_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 *)(>xframe_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 | |
263 | static struct onode * |
264 | mini_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 | |
351 | static int |
352 | scout_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 | |
453 | int |
454 | mini_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 | |
586 | static void |
587 | scout_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 | |
654 | static int |
655 | scout_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 | |
805 | static int |
806 | scout_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 | |
974 | static void |
975 | scout_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 | |
1016 | static int |
1017 | mini_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 | |
1279 | int |
1280 | FS_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 | |
1499 | static int |
1500 | init_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 | |
1625 | static int |
1626 | execute_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 | |
2021 | static 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 | |
2071 | static 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 | */ |
2183 | void |
2184 | scout_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 | |
2229 | static 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 | |
2343 | int |
2344 | main(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 */ |