libadmin: appease clang -Wsometimes-uninitialized
[openafs.git] / src / libadmin / test / bos.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  */
9
10 /*
11  * This file implements the bos related funtions for afscp
12  */
13
14 #include <afsconfig.h>
15 #include <afs/param.h>
16
17 #include <roken.h>
18
19 #include <ctype.h>
20
21 #include "bos.h"
22
23 /*
24  * Utility functions
25  */
26
27 /*
28  * Generic fuction for converting input string to an integer.  Pass
29  * the error_msg you want displayed if there is an error converting
30  * the string.
31  */
32
33 static int
34 GetIntFromString(const char *int_str, const char *error_msg)
35 {
36     int i;
37     char *bad_char = NULL;
38
39     i = strtoul(int_str, &bad_char, 10);
40     if ((bad_char == NULL) || (*bad_char == 0)) {
41         return i;
42     }
43
44     ERR_EXT(error_msg);
45 }
46
47 /*
48  * Functions for reading and displaying bos restart times.  These are copied
49  * from util/ktime.c and changed to handle the bos types.
50  */
51
52 struct token {
53     struct token *next;
54     char *key;
55 };
56
57 static char *day[] = {
58     "sun",
59     "mon",
60     "tue",
61     "wed",
62     "thu",
63     "fri",
64     "sat"
65 };
66
67 static int
68 LocalFreeTokens(struct token *alist)
69 {
70     struct token *nlist;
71     for (; alist; alist = nlist) {
72         nlist = alist->next;
73         free(alist->key);
74         free(alist);
75     }
76     return 0;
77 }
78
79 static int
80 space(int x)
81 {
82     if (x == 0 || x == ' ' || x == '\t' || x == '\n')
83         return 1;
84     else
85         return 0;
86 }
87
88 static int
89 LocalParseLine(char *aline, struct token **alist)
90 {
91     char tbuffer[256];
92     char *tptr = NULL;
93     int inToken;
94     struct token *first, *last;
95     struct token *ttok;
96     int tc;
97
98     inToken = 0;                /* not copying token chars at start */
99     first = NULL;
100     last = NULL;
101     while (1) {
102         tc = *aline++;
103         if (tc == 0 || space(tc)) {
104             if (inToken) {
105                 inToken = 0;    /* end of this token */
106                 *tptr++ = 0;
107                 ttok = malloc(sizeof(struct token));
108                 ttok->next = NULL;
109                 ttok->key = strdup(tbuffer);
110                 if (last) {
111                     last->next = ttok;
112                     last = ttok;
113                 } else
114                     last = ttok;
115                 if (!first)
116                     first = ttok;
117             }
118         } else {
119             /* an alpha character */
120             if (!inToken) {
121                 tptr = tbuffer;
122                 inToken = 1;
123             }
124             if (tptr - tbuffer >= sizeof(tbuffer))
125                 return -1;
126             *tptr++ = tc;
127         }
128         if (tc == 0) {
129             /* last token flushed 'cause space(0) --> true */
130             if (last)
131                 last->next = NULL;
132             *alist = first;
133             return 0;
134         }
135     }
136 }
137
138 /* keyword database for periodic date parsing */
139 static struct ptemp {
140     char *key;
141     afs_int32 value;
142 } ptkeys[] = {
143         {"sun", 0x10000}, {"mon", 0x10001}, {"tue", 0x10002},
144         {"wed", 0x10003}, {"thu", 0x10004}, {"fri", 0x10005},
145         {"sat", 0x10006},
146         {"sunday", 0x10000}, {"monday", 0x10001},
147         {"tuesday", 0x10002}, {"wednesday", 0x10003},
148         {"thursday", 0x10004}, {"thur", 0x10004},
149         {"friday", 0x10005}, {"saturday", 0x10006},
150         {"am", 0x20000}, {"pm", 0x20001},
151         {"a.m.", 0x20000}, {"p.m.", 0x20001}, {0, 0}};
152
153 static int
154 ParseTime(bos_RestartTime_p ak, char *astr)
155 {
156     int field;
157     short temp;
158     char *tp;
159     int tc;
160
161     field = 0;                  /* 0=hour, 1=min, 2=sec */
162     temp = 0;
163
164     ak->mask |=
165         (BOS_RESTART_TIME_HOUR | BOS_RESTART_TIME_MINUTE |
166          BOS_RESTART_TIME_SECOND);
167     for (tp = astr;;) {
168         tc = *tp++;
169         if (tc == 0 || tc == ':') {
170             if (field == 0)
171                 ak->hour = temp;
172             else if (field == 1)
173                 ak->min = temp;
174             else if (field == 2)
175                 ak->sec = temp;
176             temp = 0;
177             field++;
178             if (tc == 0)
179                 break;
180             continue;
181         } else if (!isdigit(tc))
182             return -1;          /* syntax error */
183         else {
184             /* digit */
185             temp *= 10;
186             temp += tc - '0';
187         }
188     }
189     if (ak->hour >= 24 || ak->min >= 60 || ak->sec >= 60)
190         return -1;
191     return 0;
192 }
193
194 int
195 ktime_ParsePeriodic(char *adate, bos_RestartTime_p ak)
196 {
197     struct token *tt;
198     afs_int32 code;
199     struct ptemp *tp;
200
201     memset(ak, 0, sizeof(*ak));
202     code = LocalParseLine(adate, &tt);
203     if (code)
204         return -1;
205     for (; tt; tt = tt->next) {
206         /* look at each token */
207         if (strcmp(tt->key, "now") == 0) {
208             ak->mask |= BOS_RESTART_TIME_NOW;
209             LocalFreeTokens(tt);
210             return 0;
211         }
212         if (strcmp(tt->key, "never") == 0) {
213             ak->mask |= BOS_RESTART_TIME_NEVER;
214             LocalFreeTokens(tt);
215             return 0;
216         }
217         if (strcmp(tt->key, "at") == 0)
218             continue;
219         if (strcmp(tt->key, "every") == 0)
220             continue;
221         if (isdigit(tt->key[0])) {
222             /* parse a time */
223             code = ParseTime(ak, tt->key);
224             if (code) {
225                 LocalFreeTokens(tt);
226                 return -1;
227             }
228             continue;
229         }
230         /* otherwise use keyword table */
231         for (tp = ptkeys;; tp++) {
232             if (tp->key == NULL) {
233                 LocalFreeTokens(tt);
234                 return -1;
235             }
236             if (strcmp(tp->key, tt->key) == 0)
237                 break;
238         }
239         /* now look at tp->value to see what we've got */
240         if ((tp->value >> 16) == 1) {
241             /* a day */
242             ak->mask |= BOS_RESTART_TIME_DAY;
243             ak->day = tp->value & 0xff;
244         }
245         if ((tp->value >> 16) == 2) {
246             /* am or pm token */
247             if ((tp->value & 0xff) == 1) {
248                 /* pm */
249                 if (!(ak->mask & BOS_RESTART_TIME_HOUR))
250                     return -1;
251                 if (ak->hour < 12)
252                     ak->hour += 12;
253                 /* 12 is 12 PM */
254                 else if (ak->hour != 12) {
255                     LocalFreeTokens(tt);
256                     return -1;
257                 }
258             } else {
259                 /* am is almost a noop, except that we map 12:01 am to 0:01 */
260                 if (ak->hour > 12) {
261                     LocalFreeTokens(tt);
262                     return -1;
263                 }
264                 if (ak->hour == 12)
265                     ak->hour = 0;
266             }
267         }
268     }
269     LocalFreeTokens(tt);
270     return 0;
271 }
272
273 int
274 DoBosProcessCreate(struct cmd_syndesc *as, void *arock)
275 {
276     enum { SERVER, PROCESS, BINARY, CRON, CRONTIME,
277         NOTIFIER
278     };
279     afs_status_t st = 0;
280     void *bos_server = NULL;
281     const char *process = NULL;
282     bos_ProcessType_t process_type = BOS_PROCESS_SIMPLE;
283     const char *binary = NULL;
284     int is_cron = 0;
285     const char *cron_time = NULL;
286     int has_cron_time = 0;
287     const char *notifier = NULL;
288
289     if (as->parms[SERVER].items) {
290         if (!bos_ServerOpen
291             (cellHandle, as->parms[SERVER].items->data, &bos_server, &st)) {
292             ERR_ST_EXT("bos_ServerOpen", st);
293         }
294     }
295
296     if (as->parms[PROCESS].items) {
297         process = as->parms[PROCESS].items->data;
298     }
299
300     if (as->parms[BINARY].items) {
301         binary = as->parms[BINARY].items->data;
302     }
303
304     if (as->parms[CRON].items) {
305         is_cron = 1;
306         process_type = BOS_PROCESS_CRON;
307     }
308
309     if (as->parms[CRONTIME].items) {
310         cron_time = as->parms[CRONTIME].items->data;
311         has_cron_time = 1;
312     }
313
314     if (is_cron) {
315         if (!has_cron_time) {
316             ERR_EXT("must specify cron time when creating a cron process");
317         }
318     } else {
319         if (has_cron_time) {
320             ERR_EXT("cron time is meaningless for non cron process");
321         }
322     }
323
324     if (as->parms[NOTIFIER].items) {
325         notifier = as->parms[NOTIFIER].items->data;
326     }
327
328     if (!bos_ProcessCreate
329         (bos_server, (char *)process, process_type, (char *)binary, (char *)cron_time, (char *)notifier,
330          &st)) {
331         ERR_ST_EXT("bos_ProcessCreate", st);
332     }
333
334     bos_ServerClose(bos_server, 0);
335
336     return 0;
337 }
338
339 int
340 DoBosFSProcessCreate(struct cmd_syndesc *as, void *arock)
341 {
342     enum { SERVER, PROCESS, FILESERVER, VOLSERVER, SALVAGER,
343         NOTIFIER
344     };
345     afs_status_t st = 0;
346     void *bos_server = NULL;
347     const char *process = NULL;
348     const char *fileserver = NULL;
349     const char *volserver = NULL;
350     const char *salvager = NULL;
351     const char *notifier = NULL;
352
353     if (as->parms[SERVER].items) {
354         if (!bos_ServerOpen
355             (cellHandle, as->parms[SERVER].items->data, &bos_server, &st)) {
356             ERR_ST_EXT("bos_ServerOpen", st);
357         }
358     }
359
360     if (as->parms[PROCESS].items) {
361         process = as->parms[PROCESS].items->data;
362     }
363
364     if (as->parms[FILESERVER].items) {
365         fileserver = as->parms[FILESERVER].items->data;
366     }
367
368     if (as->parms[VOLSERVER].items) {
369         volserver = as->parms[VOLSERVER].items->data;
370     }
371
372     if (as->parms[SALVAGER].items) {
373         salvager = as->parms[SALVAGER].items->data;
374     }
375
376     if (as->parms[NOTIFIER].items) {
377         notifier = as->parms[NOTIFIER].items->data;
378     }
379
380     if (!bos_FSProcessCreate
381         (bos_server, (char *)process, (char *)fileserver, (char *)volserver, (char *)salvager, (char *)notifier,
382          &st)) {
383         ERR_ST_EXT("bos_FSProcessCreate", st);
384     }
385
386     bos_ServerClose(bos_server, 0);
387
388     return 0;
389 }
390
391 int
392 DoBosProcessDelete(struct cmd_syndesc *as, void *arock)
393 {
394     enum { SERVER, PROCESS };
395     afs_status_t st = 0;
396     void *bos_server = NULL;
397     const char *process = NULL;
398
399     if (as->parms[SERVER].items) {
400         if (!bos_ServerOpen
401             (cellHandle, as->parms[SERVER].items->data, &bos_server, &st)) {
402             ERR_ST_EXT("bos_ServerOpen", st);
403         }
404     }
405
406     if (as->parms[PROCESS].items) {
407         process = as->parms[PROCESS].items->data;
408     }
409
410     if (!bos_ProcessDelete(bos_server, (char *)process, &st)) {
411         ERR_ST_EXT("bos_ProcessDelete", st);
412     }
413
414     bos_ServerClose(bos_server, 0);
415
416     return 0;
417 }
418
419 static void
420 Print_bos_ProcessExecutionState_p(bos_ProcessExecutionState_p state,
421                                   const char *prefix)
422 {
423     printf("%sThe process executation state is: ", prefix);
424     switch (*state) {
425     case BOS_PROCESS_STOPPED:
426         printf("stopped\n");
427         break;
428     case BOS_PROCESS_RUNNING:
429         printf("running\n");
430         break;
431     case BOS_PROCESS_STOPPING:
432         printf("stopping\n");
433         break;
434     case BOS_PROCESS_STARTING:
435         printf("starting\n");
436         break;
437     }
438 }
439
440 int
441 DoBosProcessExecutionStateGet(struct cmd_syndesc *as, void *arock)
442 {
443     enum { SERVER, PROCESS };
444     afs_status_t st = 0;
445     void *bos_server = NULL;
446     const char *process = NULL;
447     bos_ProcessExecutionState_t state;
448     char aux_status[BOS_MAX_NAME_LEN];
449
450     if (as->parms[SERVER].items) {
451         if (!bos_ServerOpen
452             (cellHandle, as->parms[SERVER].items->data, &bos_server, &st)) {
453             ERR_ST_EXT("bos_ServerOpen", st);
454         }
455     }
456
457     if (as->parms[PROCESS].items) {
458         process = as->parms[PROCESS].items->data;
459     }
460
461     if (!bos_ProcessExecutionStateGet
462         (bos_server, (char *)process, &state, aux_status, &st)) {
463         ERR_ST_EXT("bos_ProcessExecutionStateGet", st);
464     }
465
466     Print_bos_ProcessExecutionState_p(&state, "");
467     if (aux_status[0] != 0) {
468         printf("Aux process status: %s\n", aux_status);
469     }
470
471     bos_ServerClose(bos_server, 0);
472
473     return 0;
474 }
475
476 int
477 DoBosProcessExecutionStateSet(struct cmd_syndesc *as, void *arock)
478 {
479     enum { SERVER, PROCESS, STOPPED,
480         RUNNING
481     };
482     afs_status_t st = 0;
483     void *bos_server = NULL;
484     const char *process = NULL;
485     int stop = 0;
486     int run = 0;
487     bos_ProcessExecutionState_t state = 0;
488
489     if (as->parms[SERVER].items) {
490         if (!bos_ServerOpen
491             (cellHandle, as->parms[SERVER].items->data, &bos_server, &st)) {
492             ERR_ST_EXT("bos_ServerOpen", st);
493         }
494     }
495
496     if (as->parms[PROCESS].items) {
497         process = as->parms[PROCESS].items->data;
498     }
499
500     if (as->parms[STOPPED].items) {
501         stop = 1;
502         state = BOS_PROCESS_STOPPED;
503     }
504
505     if (as->parms[RUNNING].items) {
506         run = 1;
507         state = BOS_PROCESS_RUNNING;
508     }
509
510     if ((stop == 1) && (run == 1)) {
511         ERR_EXT("you must specify either running or stopped, but not both");
512     }
513
514     if ((stop == 0) && (run == 0)) {
515         ERR_EXT("you must specify either running or stopped");
516     }
517
518     if (!bos_ProcessExecutionStateSet(bos_server, process, state, &st)) {
519         ERR_ST_EXT("bos_ProcessExecutionStateSet", st);
520     }
521
522     bos_ServerClose(bos_server, 0);
523
524     return 0;
525 }
526
527 int
528 DoBosProcessExecutionStateSetTemporary(struct cmd_syndesc *as, void *arock)
529 {
530     enum { SERVER, PROCESS, STOPPED,
531         RUNNING
532     };
533     afs_status_t st = 0;
534     void *bos_server = NULL;
535     const char *process = NULL;
536     int stop = 0;
537     int run = 0;
538     bos_ProcessExecutionState_t state = 0;
539
540     if (as->parms[SERVER].items) {
541         if (!bos_ServerOpen
542             (cellHandle, as->parms[SERVER].items->data, &bos_server, &st)) {
543             ERR_ST_EXT("bos_ServerOpen", st);
544         }
545     }
546
547     if (as->parms[PROCESS].items) {
548         process = as->parms[PROCESS].items->data;
549     }
550
551     if (as->parms[STOPPED].items) {
552         stop = 1;
553         state = BOS_PROCESS_STOPPED;
554     }
555
556     if (as->parms[RUNNING].items) {
557         run = 1;
558         state = BOS_PROCESS_RUNNING;
559     }
560
561     if ((stop == 1) && (run == 1)) {
562         ERR_EXT("you must specify either running or stopped, but not both");
563     }
564
565     if ((stop == 0) && (run == 0)) {
566         ERR_EXT("you must specify either running or stopped");
567     }
568
569     if (!bos_ProcessExecutionStateSetTemporary
570         (bos_server, (char *)process, state, &st)) {
571         ERR_ST_EXT("bos_ProcessExecutionStateSetTemporary", st);
572     }
573
574     bos_ServerClose(bos_server, 0);
575
576     return 0;
577 }
578
579 int
580 DoBosProcessNameList(struct cmd_syndesc *as, void *arock)
581 {
582     enum { SERVER };
583     afs_status_t st = 0;
584     void *bos_server = NULL;
585     void *iter = NULL;
586     char process[BOS_MAX_NAME_LEN];
587
588     if (as->parms[SERVER].items) {
589         if (!bos_ServerOpen
590             (cellHandle, as->parms[SERVER].items->data, &bos_server, &st)) {
591             ERR_ST_EXT("bos_ServerOpen", st);
592         }
593     }
594
595     if (!bos_ProcessNameGetBegin(bos_server, &iter, &st)) {
596         ERR_ST_EXT("bos_ProcessNameGetBegin", st);
597     }
598
599     printf("Listing processes at server %s:\n",
600            as->parms[SERVER].items->data);
601
602     while (bos_ProcessNameGetNext(iter, process, &st)) {
603         printf("\t%s\n", process);
604     }
605
606     if (st != ADMITERATORDONE) {
607         ERR_ST_EXT("bos_ProcessNameGetNext", st);
608     }
609
610     if (!bos_ProcessNameGetDone(iter, &st)) {
611         ERR_ST_EXT("bos_ProcessNameGetDone", st);
612     }
613
614     return 0;
615 }
616
617 static void
618 Print_bos_ProcessType_p(bos_ProcessType_p type, const char *prefix)
619 {
620     printf("%sProcess type: \n", prefix);
621     switch (*type) {
622     case BOS_PROCESS_SIMPLE:
623         printf("simple\n");
624         break;
625     case BOS_PROCESS_FS:
626         printf("fs\n");
627         break;
628     case BOS_PROCESS_CRON:
629         printf("cron\n");
630         break;
631     }
632 }
633
634 static void
635 Print_bos_ProcessState_p(bos_ProcessState_p state, const char *prefix)
636 {
637     printf("%sProcess state:\n", prefix);
638     /* FIXME: BOS_PROCESS_OK is 0, so this test is not right */
639     if (*state & BOS_PROCESS_OK) {
640         printf("%s\tBOS_PROCESS_OK:\n", prefix);
641     }
642     if (*state & BOS_PROCESS_CORE_DUMPED) {
643         printf("%s\tBOS_PROCESS_CORE_DUMPED:\n", prefix);
644     }
645     if (*state & BOS_PROCESS_TOO_MANY_ERRORS) {
646         printf("%s\tBOS_PROCESS_TOO_MANY_ERRORS:\n", prefix);
647     }
648     if (*state & BOS_PROCESS_BAD_FILE_ACCESS) {
649         printf("%s\tBOS_PROCESS_BAD_FILE_ACCESS:\n", prefix);
650     }
651 }
652
653 static void
654 Print_bos_ProcessInfo_p(bos_ProcessInfo_p info, const char *prefix)
655 {
656     Print_bos_ProcessExecutionState_p(&info->processGoal, prefix);
657     printf("%sStart time %lu\n", prefix, info->processStartTime);
658     printf("%sNumber of process starts %lu \n", prefix,
659            info->numberProcessStarts);
660     printf("%sProcess exit time %lu\n", prefix, info->processExitTime);
661     printf("%sProcess exit error time %lu\n", prefix,
662            info->processExitErrorTime);
663     printf("%sProcess error code %lu\n", prefix, info->processErrorCode);
664     printf("%sProcess error signal %lu\n", prefix, info->processErrorSignal);
665     Print_bos_ProcessState_p(&info->state, prefix);
666 }
667
668 int
669 DoBosProcessInfoGet(struct cmd_syndesc *as, void *arock)
670 {
671     enum { SERVER, PROCESS };
672     afs_status_t st = 0;
673     void *bos_server = NULL;
674     const char *process = NULL;
675     bos_ProcessType_t type;
676     bos_ProcessInfo_t info;
677
678     if (as->parms[SERVER].items) {
679         if (!bos_ServerOpen
680             (cellHandle, as->parms[SERVER].items->data, &bos_server, &st)) {
681             ERR_ST_EXT("bos_ServerOpen", st);
682         }
683     }
684
685     if (as->parms[PROCESS].items) {
686         process = as->parms[PROCESS].items->data;
687     }
688
689     if (!bos_ProcessInfoGet(bos_server, (char *)process, &type, &info, &st)) {
690         ERR_ST_EXT("bos_ProcessInfoGet", st);
691     }
692
693     Print_bos_ProcessType_p(&type, "");
694     Print_bos_ProcessInfo_p(&info, "");
695
696     return 0;
697 }
698
699 int
700 DoBosProcessParameterList(struct cmd_syndesc *as, void *arock)
701 {
702     enum { SERVER, PROCESS };
703     afs_status_t st = 0;
704     void *bos_server = NULL;
705     char *process = NULL;
706     void *iter = NULL;
707     char parameter[BOS_MAX_NAME_LEN];
708
709     if (as->parms[SERVER].items) {
710         if (!bos_ServerOpen
711             (cellHandle, as->parms[SERVER].items->data, &bos_server, &st)) {
712             ERR_ST_EXT("bos_ServerOpen", st);
713         }
714     }
715
716     if (as->parms[PROCESS].items) {
717         process = as->parms[PROCESS].items->data;
718     }
719
720     if (!bos_ProcessParameterGetBegin(bos_server, process, &iter, &st)) {
721         ERR_ST_EXT("bos_ProcessParameterGetBegin", st);
722     }
723
724     printf("Getting parameters for %s\n", process);
725
726     while (bos_ProcessParameterGetNext(iter, parameter, &st)) {
727         printf("\t%s\n", parameter);
728     }
729
730     if (st != ADMITERATORDONE) {
731         ERR_ST_EXT("bos_ProcessParameterGetNext", st);
732     }
733
734     if (!bos_ProcessParameterGetDone(iter, &st)) {
735         ERR_ST_EXT("bos_ProcessParameterGetDone", st);
736     }
737
738     bos_ServerClose(bos_server, 0);
739
740     return 0;
741 }
742
743 int
744 DoBosProcessNotifierGet(struct cmd_syndesc *as, void *arock)
745 {
746     enum { SERVER, PROCESS };
747     afs_status_t st = 0;
748     void *bos_server = NULL;
749     const char *process = NULL;
750     char notifier[BOS_MAX_NAME_LEN];
751
752     if (as->parms[SERVER].items) {
753         if (!bos_ServerOpen
754             (cellHandle, as->parms[SERVER].items->data, &bos_server, &st)) {
755             ERR_ST_EXT("bos_ServerOpen", st);
756         }
757     }
758
759     if (as->parms[PROCESS].items) {
760         process = as->parms[PROCESS].items->data;
761     }
762
763     if (!bos_ProcessNotifierGet(bos_server, process, notifier, &st)) {
764         ERR_ST_EXT("bos_ProcessNotifierGet", st);
765     }
766
767     if (notifier[0] == 0) {
768         printf("%s does not have a notifier.\n", process);
769     } else {
770         printf("The notifier for %s is %s\n", process, notifier);
771     }
772
773     bos_ServerClose(bos_server, 0);
774
775     return 0;
776 }
777
778 int
779 DoBosProcessRestart(struct cmd_syndesc *as, void *arock)
780 {
781     enum { SERVER, PROCESS };
782     afs_status_t st = 0;
783     void *bos_server = NULL;
784     const char *process = NULL;
785
786     if (as->parms[SERVER].items) {
787         if (!bos_ServerOpen
788             (cellHandle, as->parms[SERVER].items->data, &bos_server, &st)) {
789             ERR_ST_EXT("bos_ServerOpen", st);
790         }
791     }
792
793     if (as->parms[PROCESS].items) {
794         process = as->parms[PROCESS].items->data;
795     }
796
797     if (!bos_ProcessRestart(bos_server, process, &st)) {
798         ERR_ST_EXT("bos_ProcessRestart", st);
799     }
800
801     bos_ServerClose(bos_server, 0);
802
803     return 0;
804 }
805
806 int
807 DoBosProcessAllStop(struct cmd_syndesc *as, void *arock)
808 {
809     enum { SERVER };
810     afs_status_t st = 0;
811     void *bos_server = NULL;
812
813     if (as->parms[SERVER].items) {
814         if (!bos_ServerOpen
815             (cellHandle, as->parms[SERVER].items->data, &bos_server, &st)) {
816             ERR_ST_EXT("bos_ServerOpen", st);
817         }
818     }
819
820     if (!bos_ProcessAllStop(bos_server, &st)) {
821         ERR_ST_EXT("bos_ProcessAllStop", st);
822     }
823
824     bos_ServerClose(bos_server, 0);
825
826     return 0;
827 }
828
829 int
830 DoBosProcessAllStart(struct cmd_syndesc *as, void *arock)
831 {
832     enum { SERVER };
833     afs_status_t st = 0;
834     void *bos_server = NULL;
835
836     if (as->parms[SERVER].items) {
837         if (!bos_ServerOpen
838             (cellHandle, as->parms[SERVER].items->data, &bos_server, &st)) {
839             ERR_ST_EXT("bos_ServerOpen", st);
840         }
841     }
842
843     if (!bos_ProcessAllStart(bos_server, &st)) {
844         ERR_ST_EXT("bos_ProcessAllStart", st);
845     }
846
847     bos_ServerClose(bos_server, 0);
848
849     return 0;
850 }
851
852 int
853 DoBosProcessAllWaitStop(struct cmd_syndesc *as, void *arock)
854 {
855     enum { SERVER };
856     afs_status_t st = 0;
857     void *bos_server = NULL;
858
859     if (as->parms[SERVER].items) {
860         if (!bos_ServerOpen
861             (cellHandle, as->parms[SERVER].items->data, &bos_server, &st)) {
862             ERR_ST_EXT("bos_ServerOpen", st);
863         }
864     }
865
866     if (!bos_ProcessAllWaitStop(bos_server, &st)) {
867         ERR_ST_EXT("bos_ProcessAllWaitStop", st);
868     }
869
870     bos_ServerClose(bos_server, 0);
871
872     return 0;
873 }
874
875 int
876 DoBosProcessAllWaitTransition(struct cmd_syndesc *as, void *arock)
877 {
878     enum { SERVER };
879     afs_status_t st = 0;
880     void *bos_server = NULL;
881
882     if (as->parms[SERVER].items) {
883         if (!bos_ServerOpen
884             (cellHandle, as->parms[SERVER].items->data, &bos_server, &st)) {
885             ERR_ST_EXT("bos_ServerOpen", st);
886         }
887     }
888
889     if (!bos_ProcessAllWaitTransition(bos_server, &st)) {
890         ERR_ST_EXT("bos_ProcessAllWaitTransition", st);
891     }
892
893     bos_ServerClose(bos_server, 0);
894
895     return 0;
896 }
897
898 int
899 DoBosProcessAllStopAndRestart(struct cmd_syndesc *as, void *arock)
900 {
901     enum { SERVER, INCLUDEBOS };
902     afs_status_t st = 0;
903     void *bos_server = NULL;
904     bos_RestartBosServer_t restart = BOS_DONT_RESTART_BOS_SERVER;
905
906     if (as->parms[SERVER].items) {
907         if (!bos_ServerOpen
908             (cellHandle, as->parms[SERVER].items->data, &bos_server, &st)) {
909             ERR_ST_EXT("bos_ServerOpen", st);
910         }
911     }
912
913     if (as->parms[INCLUDEBOS].items) {
914         restart = BOS_RESTART_BOS_SERVER;
915     }
916
917     if (!bos_ProcessAllStopAndRestart(bos_server, restart, &st)) {
918         ERR_ST_EXT("bos_ProcessAllStopAndRestart", st);
919     }
920
921     bos_ServerClose(bos_server, 0);
922
923     return 0;
924 }
925
926 int
927 DoBosAdminCreate(struct cmd_syndesc *as, void *arock)
928 {
929     enum { SERVER, ADMIN };
930     afs_status_t st = 0;
931     void *bos_server = NULL;
932     const char *admin = NULL;
933
934     if (as->parms[SERVER].items) {
935         if (!bos_ServerOpen
936             (cellHandle, as->parms[SERVER].items->data, &bos_server, &st)) {
937             ERR_ST_EXT("bos_ServerOpen", st);
938         }
939     }
940
941     if (as->parms[ADMIN].items) {
942         admin = as->parms[ADMIN].items->data;
943     }
944
945     if (!bos_AdminCreate(bos_server, admin, &st)) {
946         ERR_ST_EXT("bos_AdminCreate", st);
947     }
948
949     bos_ServerClose(bos_server, 0);
950
951     return 0;
952 }
953
954 int
955 DoBosAdminDelete(struct cmd_syndesc *as, void *arock)
956 {
957     enum { SERVER, ADMIN };
958     afs_status_t st = 0;
959     void *bos_server = NULL;
960     const char *admin = NULL;
961
962     if (as->parms[SERVER].items) {
963         if (!bos_ServerOpen
964             (cellHandle, as->parms[SERVER].items->data, &bos_server, &st)) {
965             ERR_ST_EXT("bos_ServerOpen", st);
966         }
967     }
968
969     if (as->parms[ADMIN].items) {
970         admin = as->parms[ADMIN].items->data;
971     }
972
973     if (!bos_AdminDelete(bos_server, admin, &st)) {
974         ERR_ST_EXT("bos_AdminDelete", st);
975     }
976
977     bos_ServerClose(bos_server, 0);
978
979     return 0;
980 }
981
982 int
983 DoBosAdminList(struct cmd_syndesc *as, void *arock)
984 {
985     enum { SERVER };
986     afs_status_t st = 0;
987     void *bos_server = NULL;
988     void *iter = NULL;
989     char admin[BOS_MAX_NAME_LEN];
990
991     if (as->parms[SERVER].items) {
992         if (!bos_ServerOpen
993             (cellHandle, as->parms[SERVER].items->data, &bos_server, &st)) {
994             ERR_ST_EXT("bos_ServerOpen", st);
995         }
996     }
997
998     if (!bos_AdminGetBegin(bos_server, &iter, &st)) {
999         ERR_ST_EXT("bos_AdminGetBegin", st);
1000     }
1001
1002     printf("Administrators at %s\n", as->parms[SERVER].items->data);
1003
1004     while (bos_AdminGetNext(iter, admin, &st)) {
1005         printf("%s\n", admin);
1006     }
1007
1008     if (st != ADMITERATORDONE) {
1009         ERR_ST_EXT("bos_AdminGetNext", st);
1010     }
1011
1012     if (!bos_AdminGetDone(iter, &st)) {
1013         ERR_ST_EXT("bos_AdminGetDone", st);
1014     }
1015
1016     bos_ServerClose(bos_server, 0);
1017
1018     return 0;
1019 }
1020
1021 int
1022 DoBosKeyCreate(struct cmd_syndesc *as, void *arock)
1023 {
1024     enum { SERVER, VERSIONNUMBER, KEY };
1025     afs_status_t st = 0;
1026     void *bos_server = NULL;
1027     int version_number = 0;
1028     kas_encryptionKey_t key = { {0, 0, 0, 0, 0, 0, 0, 0} };
1029     const char *cell;
1030
1031     if (as->parms[SERVER].items) {
1032         if (!bos_ServerOpen
1033             (cellHandle, as->parms[SERVER].items->data, &bos_server, &st)) {
1034             ERR_ST_EXT("bos_ServerOpen", st);
1035         }
1036     }
1037
1038     if (as->parms[VERSIONNUMBER].items) {
1039         version_number =
1040             GetIntFromString(as->parms[VERSIONNUMBER].items->data,
1041                              "invalid version number");
1042     }
1043
1044     if (as->parms[KEY].items) {
1045         const char *str = as->parms[KEY].items->data;
1046         if (!afsclient_CellNameGet(cellHandle, &cell, &st)) {
1047             ERR_ST_EXT("afsclient_CellNameGet", st);
1048         }
1049         if (!kas_StringToKey(cell, str, &key, &st)) {
1050             ERR_ST_EXT("kas_StringToKey", st);
1051         }
1052     }
1053
1054     if (!bos_KeyCreate(bos_server, version_number, &key, &st)) {
1055         ERR_ST_EXT("bos_KeyCreate", st);
1056     }
1057
1058     bos_ServerClose(bos_server, 0);
1059
1060     return 0;
1061 }
1062
1063 int
1064 DoBosKeyDelete(struct cmd_syndesc *as, void *arock)
1065 {
1066     enum { SERVER, VERSIONNUMBER };
1067     afs_status_t st = 0;
1068     void *bos_server = NULL;
1069     int version_number = 0;
1070
1071     if (as->parms[SERVER].items) {
1072         if (!bos_ServerOpen
1073             (cellHandle, as->parms[SERVER].items->data, &bos_server, &st)) {
1074             ERR_ST_EXT("bos_ServerOpen", st);
1075         }
1076     }
1077
1078     if (as->parms[VERSIONNUMBER].items) {
1079         version_number =
1080             GetIntFromString(as->parms[VERSIONNUMBER].items->data,
1081                              "invalid version number");
1082     }
1083
1084     if (!bos_KeyDelete(bos_server, version_number, &st)) {
1085         ERR_ST_EXT("bos_KeyDelete", st);
1086     }
1087
1088     bos_ServerClose(bos_server, 0);
1089
1090     return 0;
1091 }
1092
1093 static void
1094 Print_bos_KeyInfo_p(bos_KeyInfo_p key, const char *prefix)
1095 {
1096     int i;
1097     printf("%sVersion number: %d\n", prefix, key->keyVersionNumber);
1098     printf("%sLast modification date %d\n", prefix,
1099            key->keyStatus.lastModificationDate);
1100     printf("%sLast modification micro seconds %d\n", prefix,
1101            key->keyStatus.lastModificationMicroSeconds);
1102     printf("%sChecksum %u\n", prefix, key->keyStatus.checkSum);
1103
1104     printf("%sKey: \n", prefix);
1105     for (i = 0; i < KAS_ENCRYPTION_KEY_LEN; i++) {
1106         printf("%s\t%d ", prefix, key->key.key[i]);
1107     }
1108     printf("\n");
1109 }
1110
1111 int
1112 DoBosKeyList(struct cmd_syndesc *as, void *arock)
1113 {
1114     enum { SERVER };
1115     afs_status_t st = 0;
1116     void *bos_server = NULL;
1117     void *iter = NULL;
1118     bos_KeyInfo_t key;
1119
1120     if (as->parms[SERVER].items) {
1121         if (!bos_ServerOpen
1122             (cellHandle, as->parms[SERVER].items->data, &bos_server, &st)) {
1123             ERR_ST_EXT("bos_ServerOpen", st);
1124         }
1125     }
1126
1127     if (!bos_KeyGetBegin(bos_server, &iter, &st)) {
1128         ERR_ST_EXT("bos_KeyGetBegin", st);
1129     }
1130
1131     printf("Listing keys at server %s:\n", as->parms[SERVER].items->data);
1132
1133     while (bos_KeyGetNext(iter, &key, &st)) {
1134         Print_bos_KeyInfo_p(&key, "");
1135     }
1136
1137     if (st != ADMITERATORDONE) {
1138         ERR_ST_EXT("bos_KeyGetNext", st);
1139     }
1140
1141     if (!bos_KeyGetDone(iter, &st)) {
1142         ERR_ST_EXT("bos_KeyGetDone", st);
1143     }
1144
1145     bos_ServerClose(bos_server, 0);
1146
1147     return 0;
1148 }
1149
1150 int
1151 DoBosCellSet(struct cmd_syndesc *as, void *arock)
1152 {
1153     enum { SERVER, CELL };
1154     afs_status_t st = 0;
1155     void *bos_server = NULL;
1156     const char *cell = NULL;
1157
1158     if (as->parms[SERVER].items) {
1159         if (!bos_ServerOpen
1160             (cellHandle, as->parms[SERVER].items->data, &bos_server, &st)) {
1161             ERR_ST_EXT("bos_ServerOpen", st);
1162         }
1163     }
1164
1165     if (as->parms[SERVER].items) {
1166         cell = as->parms[SERVER].items->data;
1167     }
1168
1169     if (!bos_CellSet(bos_server, cell, &st)) {
1170         ERR_ST_EXT("bos_CellSet", st);
1171     }
1172
1173     bos_ServerClose(bos_server, 0);
1174
1175     return 0;
1176 }
1177
1178 int
1179 DoBosCellGet(struct cmd_syndesc *as, void *arock)
1180 {
1181     enum { SERVER };
1182     afs_status_t st = 0;
1183     void *bos_server = NULL;
1184     char cell[BOS_MAX_NAME_LEN];
1185
1186     if (as->parms[SERVER].items) {
1187         if (!bos_ServerOpen
1188             (cellHandle, as->parms[SERVER].items->data, &bos_server, &st)) {
1189             ERR_ST_EXT("bos_ServerOpen", st);
1190         }
1191     }
1192
1193     if (!bos_CellGet(bos_server, cell, &st)) {
1194         ERR_ST_EXT("bos_CellGet", st);
1195     }
1196
1197     printf("The cell name is %s\n", cell);
1198
1199     bos_ServerClose(bos_server, 0);
1200
1201     return 0;
1202 }
1203
1204 int
1205 DoBosHostCreate(struct cmd_syndesc *as, void *arock)
1206 {
1207     enum { SERVER, HOST };
1208     afs_status_t st = 0;
1209     void *bos_server = NULL;
1210     const char *host = NULL;
1211
1212     if (as->parms[SERVER].items) {
1213         if (!bos_ServerOpen
1214             (cellHandle, as->parms[SERVER].items->data, &bos_server, &st)) {
1215             ERR_ST_EXT("bos_ServerOpen", st);
1216         }
1217     }
1218
1219     if (as->parms[HOST].items) {
1220         host = as->parms[HOST].items->data;
1221     }
1222
1223     if (!bos_HostCreate(bos_server, host, &st)) {
1224         ERR_ST_EXT("bos_HostCreate", st);
1225     }
1226
1227     bos_ServerClose(bos_server, 0);
1228
1229     return 0;
1230 }
1231
1232 int
1233 DoBosHostDelete(struct cmd_syndesc *as, void *arock)
1234 {
1235     enum { SERVER, HOST };
1236     afs_status_t st = 0;
1237     void *bos_server = NULL;
1238     const char *host = NULL;
1239
1240     if (as->parms[SERVER].items) {
1241         if (!bos_ServerOpen
1242             (cellHandle, as->parms[SERVER].items->data, &bos_server, &st)) {
1243             ERR_ST_EXT("bos_ServerOpen", st);
1244         }
1245     }
1246
1247     if (as->parms[HOST].items) {
1248         host = as->parms[HOST].items->data;
1249     }
1250
1251     if (!bos_HostDelete(bos_server, host, &st)) {
1252         ERR_ST_EXT("bos_HostDelete", st);
1253     }
1254
1255     bos_ServerClose(bos_server, 0);
1256
1257     return 0;
1258 }
1259
1260 int
1261 DoBosHostList(struct cmd_syndesc *as, void *arock)
1262 {
1263     enum { SERVER };
1264     afs_status_t st = 0;
1265     void *bos_server = NULL;
1266     void *iter = NULL;
1267     char host[BOS_MAX_NAME_LEN];
1268
1269     if (as->parms[SERVER].items) {
1270         if (!bos_ServerOpen
1271             (cellHandle, as->parms[SERVER].items->data, &bos_server, &st)) {
1272             ERR_ST_EXT("bos_ServerOpen", st);
1273         }
1274
1275         printf("Listing hosts at server %s\n", as->parms[SERVER].items->data);
1276     }
1277
1278     if (!bos_HostGetBegin(bos_server, &iter, &st)) {
1279         ERR_ST_EXT("bos_HostGetBegin", st);
1280     }
1281
1282
1283     while (bos_HostGetNext(iter, host, &st)) {
1284         printf("\t%s\n", host);
1285     }
1286
1287     if (st != ADMITERATORDONE) {
1288         ERR_ST_EXT("bos_HostGetNext", st);
1289     }
1290
1291     if (!bos_HostGetDone(iter, &st)) {
1292         ERR_ST_EXT("bos_HostGetDone", st);
1293     }
1294
1295     bos_ServerClose(bos_server, 0);
1296
1297     return 0;
1298 }
1299
1300 int
1301 DoBosExecutableCreate(struct cmd_syndesc *as, void *arock)
1302 {
1303     enum { SERVER, BINARY, DEST };
1304     afs_status_t st = 0;
1305     void *bos_server = NULL;
1306     const char *binary = NULL;
1307     const char *dest = NULL;
1308
1309     if (as->parms[SERVER].items) {
1310         if (!bos_ServerOpen
1311             (cellHandle, as->parms[SERVER].items->data, &bos_server, &st)) {
1312             ERR_ST_EXT("bos_ServerOpen", st);
1313         }
1314     }
1315
1316     if (as->parms[BINARY].items) {
1317         binary = as->parms[BINARY].items->data;
1318     }
1319
1320     if (as->parms[DEST].items) {
1321         dest = as->parms[DEST].items->data;
1322     }
1323
1324     if (!bos_ExecutableCreate(bos_server, binary, dest, &st)) {
1325         ERR_ST_EXT("bos_ExecutableCreate", st);
1326     }
1327
1328     bos_ServerClose(bos_server, 0);
1329
1330     return 0;
1331 }
1332
1333 int
1334 DoBosExecutableRevert(struct cmd_syndesc *as, void *arock)
1335 {
1336     enum { SERVER, EXECUTABLE };
1337     afs_status_t st = 0;
1338     void *bos_server = NULL;
1339     const char *executable = NULL;
1340
1341     if (as->parms[SERVER].items) {
1342         if (!bos_ServerOpen
1343             (cellHandle, as->parms[SERVER].items->data, &bos_server, &st)) {
1344             ERR_ST_EXT("bos_ServerOpen", st);
1345         }
1346     }
1347
1348     if (as->parms[EXECUTABLE].items) {
1349         executable = as->parms[EXECUTABLE].items->data;
1350     }
1351
1352     if (!bos_ExecutableRevert(bos_server, executable, &st)) {
1353         ERR_ST_EXT("bos_ExecutableRevert", st);
1354     }
1355
1356     bos_ServerClose(bos_server, 0);
1357
1358     return 0;
1359 }
1360
1361 int
1362 DoBosExecutableTimestampGet(struct cmd_syndesc *as, void *arock)
1363 {
1364     enum { SERVER, EXECUTABLE };
1365     afs_status_t st = 0;
1366     void *bos_server = NULL;
1367     const char *executable = NULL;
1368     afs_int32 new_time = 0;
1369     afs_int32 old_time = 0;
1370     afs_int32 bak_time = 0;
1371
1372     if (as->parms[SERVER].items) {
1373         if (!bos_ServerOpen
1374             (cellHandle, as->parms[SERVER].items->data, &bos_server, &st)) {
1375             ERR_ST_EXT("bos_ServerOpen", st);
1376         }
1377     }
1378
1379     if (as->parms[EXECUTABLE].items) {
1380         executable = as->parms[EXECUTABLE].items->data;
1381     }
1382
1383     if (!bos_ExecutableTimestampGet
1384         (bos_server, executable, &new_time, &old_time, &bak_time, &st)) {
1385         ERR_ST_EXT("bos_ExecutableTimestampGet", st);
1386     }
1387
1388     bos_ServerClose(bos_server, 0);
1389
1390     return 0;
1391 }
1392
1393 int
1394 DoBosExecutablePrune(struct cmd_syndesc *as, void *arock)
1395 {
1396     enum { SERVER, OLDFILES, BAKFILES,
1397         COREFILES
1398     };
1399     afs_status_t st = 0;
1400     void *bos_server = NULL;
1401     bos_Prune_t old_files = BOS_DONT_PRUNE;
1402     bos_Prune_t bak_files = BOS_DONT_PRUNE;
1403     bos_Prune_t core_files = BOS_DONT_PRUNE;
1404
1405     if (as->parms[SERVER].items) {
1406         if (!bos_ServerOpen
1407             (cellHandle, as->parms[SERVER].items->data, &bos_server, &st)) {
1408             ERR_ST_EXT("bos_ServerOpen", st);
1409         }
1410     }
1411
1412     if (as->parms[OLDFILES].items) {
1413         old_files = BOS_PRUNE;
1414     }
1415
1416     if (as->parms[BAKFILES].items) {
1417         bak_files = BOS_PRUNE;
1418     }
1419
1420     if (as->parms[COREFILES].items) {
1421         core_files = BOS_PRUNE;
1422     }
1423
1424     if (!bos_ExecutablePrune
1425         (bos_server, old_files, bak_files, core_files, &st)) {
1426         ERR_ST_EXT("bos_ExecutablePrune", st);
1427     }
1428
1429     bos_ServerClose(bos_server, 0);
1430
1431     return 0;
1432 }
1433
1434 int
1435 DoBosExecutableRestartTimeSet(struct cmd_syndesc *as, void *arock)
1436 {
1437     enum { SERVER, DAILY, WEEKLY,
1438         TIME
1439     };
1440     afs_status_t st = 0;
1441     void *bos_server = NULL;
1442     bos_Restart_t type = 0;
1443     int have_daily = 0;
1444     int have_weekly = 0;
1445     bos_RestartTime_t time;
1446
1447     if (as->parms[SERVER].items) {
1448         if (!bos_ServerOpen
1449             (cellHandle, as->parms[SERVER].items->data, &bos_server, &st)) {
1450             ERR_ST_EXT("bos_ServerOpen", st);
1451         }
1452     }
1453
1454     if (as->parms[DAILY].items) {
1455         type = BOS_RESTART_DAILY;
1456         have_daily = 1;
1457     }
1458
1459     if (as->parms[WEEKLY].items) {
1460         type = BOS_RESTART_WEEKLY;
1461         have_weekly = 1;
1462     }
1463
1464     if ((have_daily == 0) && (have_weekly == 0)) {
1465         ERR_EXT("must specify either daily or weekly");
1466     }
1467
1468     if ((have_daily == 1) && (have_weekly == 1)) {
1469         ERR_EXT("must specify either daily or weekly, not both");
1470     }
1471
1472     if (as->parms[TIME].items) {
1473         if (ktime_ParsePeriodic(as->parms[TIME].items->data, &time) == -1) {
1474             ERR_EXT("error parsing time");
1475         }
1476     } else {
1477         ERR_EXT("Mandatory time argument not supplied");
1478     }
1479
1480     if (!bos_ExecutableRestartTimeSet(bos_server, type, time, &st)) {
1481         ERR_ST_EXT("bos_ExecutableRestartTimeSet", st);
1482     }
1483
1484     bos_ServerClose(bos_server, 0);
1485
1486     return 0;
1487 }
1488
1489 static void
1490 Print_bos_RestartTime_p(bos_RestartTime_p restart, const char *prefix)
1491 {
1492     char tempString[50];
1493     char astring[50];
1494
1495     astring[0] = 0;
1496     tempString[0] = 0;
1497
1498     if (restart->mask & BOS_RESTART_TIME_NEVER) {
1499         printf("%snever\n", prefix);
1500     } else if (restart->mask & BOS_RESTART_TIME_NOW) {
1501         printf("%snow\n", prefix);
1502     } else {
1503         strcpy(astring, "at");
1504         if (restart->mask & BOS_RESTART_TIME_DAY) {
1505             strcat(astring, " ");
1506             strcat(astring, day[restart->day]);
1507         }
1508         if (restart->mask & BOS_RESTART_TIME_HOUR) {
1509             if (restart->hour > 12)
1510                 sprintf(tempString, " %d", restart->hour - 12);
1511             else if (restart->hour == 0)
1512                 strcpy(tempString, " 12");
1513             else
1514                 sprintf(tempString, " %d", restart->hour);
1515             strcat(astring, tempString);
1516         }
1517         if (restart->mask & BOS_RESTART_TIME_MINUTE) {
1518             sprintf(tempString, ":%02d", restart->min);
1519             strcat(astring, tempString);
1520         }
1521         if ((restart->mask & BOS_RESTART_TIME_SECOND) && restart->sec != 0) {
1522             sprintf(tempString, ":%02d", restart->sec);
1523             strcat(astring, tempString);
1524         }
1525         if (restart->mask & BOS_RESTART_TIME_HOUR) {
1526             if (restart->hour >= 12)
1527                 strcat(astring, " pm");
1528             else
1529                 strcat(astring, " am");
1530         }
1531         printf("%s%s\n", prefix, astring);
1532     }
1533 }
1534
1535 int
1536 DoBosExecutableRestartTimeGet(struct cmd_syndesc *as, void *arock)
1537 {
1538     enum { SERVER, DAILY,
1539         WEEKLY
1540     };
1541     afs_status_t st = 0;
1542     void *bos_server = NULL;
1543     bos_Restart_t type = 0;
1544     int have_daily = 0;
1545     int have_weekly = 0;
1546     bos_RestartTime_t restart_time;
1547
1548     if (as->parms[SERVER].items) {
1549         if (!bos_ServerOpen
1550             (cellHandle, as->parms[SERVER].items->data, &bos_server, &st)) {
1551             ERR_ST_EXT("bos_ServerOpen", st);
1552         }
1553     }
1554
1555     if (as->parms[DAILY].items) {
1556         type = BOS_RESTART_DAILY;
1557         have_daily = 1;
1558     }
1559
1560     if (as->parms[WEEKLY].items) {
1561         type = BOS_RESTART_WEEKLY;
1562         have_weekly = 1;
1563     }
1564
1565     if ((have_daily == 0) && (have_weekly == 0)) {
1566         ERR_EXT("must specify either daily or weekly");
1567     }
1568
1569     if ((have_daily == 1) && (have_weekly == 1)) {
1570         ERR_EXT("must specify either daily or weekly, not both");
1571     }
1572
1573     if (!bos_ExecutableRestartTimeGet(bos_server, type, &restart_time, &st)) {
1574         ERR_ST_EXT("bos_ExecutableRestartTimeGet", st);
1575     }
1576
1577     Print_bos_RestartTime_p(&restart_time, "");
1578
1579     bos_ServerClose(bos_server, 0);
1580
1581     return 0;
1582 }
1583
1584 #define INITIAL_BUF_SIZE 4096
1585
1586 int
1587 DoBosLogGet(struct cmd_syndesc *as, void *arock)
1588 {
1589     enum { SERVER, LOGFILE };
1590     afs_status_t st = 0;
1591     void *bos_server = NULL;
1592     const char *log_file = NULL;
1593     unsigned long buf_size = INITIAL_BUF_SIZE;
1594     char *buf = NULL;
1595
1596     if (as->parms[SERVER].items) {
1597         if (!bos_ServerOpen
1598             (cellHandle, as->parms[SERVER].items->data, &bos_server, &st)) {
1599             ERR_ST_EXT("bos_ServerOpen", st);
1600         }
1601     }
1602
1603     if (as->parms[LOGFILE].items) {
1604         log_file = as->parms[LOGFILE].items->data;
1605     }
1606
1607     st = ADMMOREDATA;
1608     while (st == ADMMOREDATA) {
1609         buf = realloc(buf, buf_size);
1610         if (buf == NULL) {
1611             ERR_EXT("cannot dynamically allocate memory");
1612         }
1613         bos_LogGet(bos_server, log_file, &buf_size, buf, &st);
1614         if (st == ADMMOREDATA) {
1615             buf_size = buf_size + (unsigned long)(0.2 * buf_size);
1616         }
1617     }
1618
1619     if (st != 0) {
1620         ERR_ST_EXT("bos_LogGet", st);
1621     } else {
1622         printf("Log file:\n%s", buf);
1623     }
1624
1625     if (buf != NULL) {
1626         free(buf);
1627     }
1628
1629     bos_ServerClose(bos_server, 0);
1630
1631     return 0;
1632 }
1633
1634 int
1635 DoBosAuthSet(struct cmd_syndesc *as, void *arock)
1636 {
1637     enum { SERVER, REQUIREAUTH, DISABLEAUTH };
1638     afs_status_t st = 0;
1639     void *bos_server = NULL;
1640     bos_Auth_t auth = 0;
1641     int have_req = 0;
1642     int have_dis = 0;
1643
1644     if (as->parms[SERVER].items) {
1645         if (!bos_ServerOpen
1646             (cellHandle, as->parms[SERVER].items->data, &bos_server, &st)) {
1647             ERR_ST_EXT("bos_ServerOpen", st);
1648         }
1649     }
1650
1651     if (as->parms[REQUIREAUTH].items) {
1652         auth = BOS_AUTH_REQUIRED;
1653         have_req = 1;
1654     }
1655
1656     if (as->parms[DISABLEAUTH].items) {
1657         auth = BOS_NO_AUTH;
1658         have_dis = 1;
1659     }
1660
1661     if ((have_req == 0) && (have_dis == 0)) {
1662         ERR_EXT("must specify either requireauth or disableauth");
1663     }
1664
1665     if ((have_req == 1) && (have_dis == 1)) {
1666         ERR_EXT("must specify either requireauth or disableauth, not both");
1667     }
1668
1669     if (!bos_AuthSet(bos_server, auth, &st)) {
1670         ERR_ST_EXT("bos_AuthSet", st);
1671     }
1672
1673     bos_ServerClose(bos_server, 0);
1674
1675     return 0;
1676 }
1677
1678 int
1679 DoBosCommandExecute(struct cmd_syndesc *as, void *arock)
1680 {
1681     enum { SERVER, COMMAND };
1682     afs_status_t st = 0;
1683     void *bos_server = NULL;
1684     const char *command = NULL;
1685
1686     if (as->parms[SERVER].items) {
1687         if (!bos_ServerOpen
1688             (cellHandle, as->parms[SERVER].items->data, &bos_server, &st)) {
1689             ERR_ST_EXT("bos_ServerOpen", st);
1690         }
1691     }
1692
1693     if (as->parms[COMMAND].items) {
1694         command = as->parms[COMMAND].items->data;
1695     }
1696
1697     if (!bos_CommandExecute(bos_server, command, &st)) {
1698         ERR_ST_EXT("bos_CommandExecute", st);
1699     }
1700
1701     bos_ServerClose(bos_server, 0);
1702
1703     return 0;
1704 }
1705
1706 int
1707 DoBosSalvage(struct cmd_syndesc *as, void *arock)
1708 {
1709     enum { SERVER, PARTITION, VOLUME, NUMSALVAGERS, TMPDIR, LOGFILE,
1710         FORCE, NOWRITE, INODES, ROOTINODES, SALVAGEDIRS, BLOCKREADS
1711     };
1712     afs_status_t st = 0;
1713     void *bos_server = NULL;
1714     const char *partition = NULL;
1715     const char *volume = NULL;
1716     int num_salvagers = 1;
1717     const char *tmp_dir = NULL;
1718     const char *log_file = NULL;
1719     vos_force_t force = VOS_NORMAL;
1720     bos_SalvageDamagedVolumes_t no_write = BOS_SALVAGE_DAMAGED_VOLUMES;
1721     bos_WriteInodes_t inodes = BOS_SALVAGE_WRITE_INODES;
1722     bos_WriteRootInodes_t root_inodes = BOS_SALVAGE_WRITE_ROOT_INODES;
1723     bos_ForceDirectory_t salvage_dirs = BOS_SALVAGE_DONT_FORCE_DIRECTORIES;
1724     bos_ForceBlockRead_t block_reads = BOS_SALVAGE_DONT_FORCE_BLOCK_READS;
1725
1726
1727     if (as->parms[SERVER].items) {
1728         if (!bos_ServerOpen
1729             (cellHandle, as->parms[SERVER].items->data, &bos_server, &st)) {
1730             ERR_ST_EXT("bos_ServerOpen", st);
1731         }
1732     }
1733
1734     if (as->parms[PARTITION].items) {
1735         partition = as->parms[PARTITION].items->data;
1736     }
1737
1738     if (as->parms[VOLUME].items) {
1739         volume = as->parms[VOLUME].items->data;
1740     }
1741
1742     if (as->parms[NUMSALVAGERS].items) {
1743         num_salvagers =
1744             GetIntFromString(as->parms[NUMSALVAGERS].items->data,
1745                              "invalid number of salvagers");
1746     }
1747
1748     if (as->parms[TMPDIR].items) {
1749         tmp_dir = as->parms[TMPDIR].items->data;
1750     }
1751
1752     if (as->parms[LOGFILE].items) {
1753         log_file = as->parms[LOGFILE].items->data;
1754     }
1755
1756     if (as->parms[FORCE].items) {
1757         force = VOS_FORCE;
1758     }
1759
1760     if (as->parms[NOWRITE].items) {
1761         no_write = BOS_DONT_SALVAGE_DAMAGED_VOLUMES;
1762     }
1763
1764     if (as->parms[INODES].items) {
1765         inodes = BOS_SALVAGE_DONT_WRITE_INODES;
1766     }
1767
1768     if (as->parms[ROOTINODES].items) {
1769         root_inodes = BOS_SALVAGE_DONT_WRITE_ROOT_INODES;
1770     }
1771
1772     if (as->parms[SALVAGEDIRS].items) {
1773         salvage_dirs = BOS_SALVAGE_FORCE_DIRECTORIES;
1774     }
1775
1776     if (as->parms[BLOCKREADS].items) {
1777         block_reads = BOS_SALVAGE_FORCE_BLOCK_READS;
1778     }
1779
1780     if (!bos_Salvage
1781         (cellHandle, bos_server, partition, volume, num_salvagers, tmp_dir,
1782          log_file, force, no_write, inodes, root_inodes, salvage_dirs,
1783          block_reads, &st)) {
1784         ERR_ST_EXT("bos_Salvage", st);
1785     }
1786
1787     bos_ServerClose(bos_server, 0);
1788
1789     return 0;
1790 }
1791
1792 #if 0
1793 static void
1794 Print_afs_RPCStatsState_p(afs_RPCStatsState_p state, const char *prefix)
1795 {
1796     printf("%sThe rpc stats state is: ", prefix);
1797     switch (*state) {
1798     case AFS_RPC_STATS_DISABLED:
1799         printf("disabled\n");
1800         break;
1801     case AFS_RPC_STATS_ENABLED:
1802         printf("enabled\n");
1803         break;
1804     }
1805 }
1806 #endif
1807
1808 void
1809 SetupBosAdminCmd(void)
1810 {
1811     struct cmd_syndesc *ts;
1812
1813     ts = cmd_CreateSyntax("BosProcessCreate", DoBosProcessCreate, NULL, 0,
1814                           "create a new bos process");
1815     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED,
1816                 "server where process will be created");
1817     cmd_AddParm(ts, "-name", CMD_SINGLE, CMD_REQUIRED,
1818                 "the name of the process");
1819     cmd_AddParm(ts, "-binary", CMD_SINGLE, CMD_REQUIRED,
1820                 "path to the process binary");
1821     cmd_AddParm(ts, "-cron", CMD_FLAG, CMD_OPTIONAL,
1822                 "this is a cron process");
1823     cmd_AddParm(ts, "-crontime", CMD_SINGLE, CMD_OPTIONAL,
1824                 "the time when the process will be run");
1825     cmd_AddParm(ts, "-notifier", CMD_SINGLE, CMD_OPTIONAL,
1826                 "path to notifier binary that is run when process terminates");
1827     SetupCommonCmdArgs(ts);
1828
1829     ts = cmd_CreateSyntax("BosFSProcessCreate", DoBosFSProcessCreate, NULL, 0,
1830                           "create a fs bos process");
1831     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED,
1832                 "server where process will be created");
1833     cmd_AddParm(ts, "-name", CMD_SINGLE, CMD_REQUIRED,
1834                 "the name of the process");
1835     cmd_AddParm(ts, "-fileserver", CMD_SINGLE, CMD_REQUIRED,
1836                 "path to the fileserver binary");
1837     cmd_AddParm(ts, "-volserver", CMD_SINGLE, CMD_REQUIRED,
1838                 "path to the volserver binary");
1839     cmd_AddParm(ts, "-salvager", CMD_SINGLE, CMD_REQUIRED,
1840                 "path to the salvager binary");
1841     cmd_AddParm(ts, "-notifier", CMD_SINGLE, CMD_OPTIONAL,
1842                 "path to notifier binary that is run when process terminates");
1843     SetupCommonCmdArgs(ts);
1844
1845     ts = cmd_CreateSyntax("BosProcessDelete", DoBosProcessDelete, NULL, 0,
1846                           "delete a bos process");
1847     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED,
1848                 "server where process will be deleted");
1849     cmd_AddParm(ts, "-name", CMD_SINGLE, CMD_REQUIRED,
1850                 "the name of the process");
1851     SetupCommonCmdArgs(ts);
1852
1853     ts = cmd_CreateSyntax("BosProcessExecutionStateGet",
1854                           DoBosProcessExecutionStateGet, NULL, 0,
1855                           "get the process execution state of a process");
1856     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED,
1857                 "server where process exists");
1858     cmd_AddParm(ts, "-name", CMD_SINGLE, CMD_REQUIRED,
1859                 "the name of the process");
1860     SetupCommonCmdArgs(ts);
1861
1862     ts = cmd_CreateSyntax("BosProcessExecutionStateSet",
1863                           DoBosProcessExecutionStateSet, NULL, 0,
1864                           "set the process execution state of a process");
1865     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED,
1866                 "server where process exists");
1867     cmd_AddParm(ts, "-name", CMD_SINGLE, CMD_REQUIRED,
1868                 "the name of the process");
1869     cmd_AddParm(ts, "-stopped", CMD_FLAG, CMD_OPTIONAL,
1870                 "set the process state to stopped");
1871     cmd_AddParm(ts, "-running", CMD_FLAG, CMD_OPTIONAL,
1872                 "set the process state to running");
1873     SetupCommonCmdArgs(ts);
1874
1875     ts = cmd_CreateSyntax("BosProcessExecutionStateSetTemporary",
1876                           DoBosProcessExecutionStateSetTemporary, NULL, 0,
1877                           "set the process execution state "
1878                           "of a process temporarily");
1879     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED,
1880                 "server where process exists");
1881     cmd_AddParm(ts, "-name", CMD_SINGLE, CMD_REQUIRED,
1882                 "the name of the process");
1883     cmd_AddParm(ts, "-stopped", CMD_FLAG, CMD_OPTIONAL,
1884                 "set the process state to stopped");
1885     cmd_AddParm(ts, "-running", CMD_FLAG, CMD_OPTIONAL,
1886                 "set the process state to running");
1887     SetupCommonCmdArgs(ts);
1888
1889     ts = cmd_CreateSyntax("BosProcessNameList", DoBosProcessNameList, NULL, 0,
1890                           "list the names of all processes at a bos server");
1891     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED, "server to query");
1892     SetupCommonCmdArgs(ts);
1893
1894     ts = cmd_CreateSyntax("BosProcessInfoGet", DoBosProcessInfoGet, NULL, 0,
1895                           "get information about a process");
1896     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED,
1897                 "server where process exists");
1898     cmd_AddParm(ts, "-name", CMD_SINGLE, CMD_REQUIRED,
1899                 "the name of the process");
1900     SetupCommonCmdArgs(ts);
1901
1902     ts = cmd_CreateSyntax("BosProcessParameterList",
1903                           DoBosProcessParameterList, NULL, 0,
1904                           "list the parameters of a process");
1905     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED,
1906                 "server where process exists");
1907     cmd_AddParm(ts, "-name", CMD_SINGLE, CMD_REQUIRED,
1908                 "the name of the process");
1909     SetupCommonCmdArgs(ts);
1910
1911     ts = cmd_CreateSyntax("BosProcessNotifierGet", DoBosProcessNotifierGet, NULL, 0,
1912                           "get the notifier for a process");
1913     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED,
1914                 "server where process exists");
1915     cmd_AddParm(ts, "-name", CMD_SINGLE, CMD_REQUIRED,
1916                 "the name of the process");
1917     SetupCommonCmdArgs(ts);
1918
1919     ts = cmd_CreateSyntax("BosProcessRestart", DoBosProcessRestart, NULL, 0,
1920                           "restart a process");
1921     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED,
1922                 "server where process exists");
1923     cmd_AddParm(ts, "-name", CMD_SINGLE, CMD_REQUIRED,
1924                 "the name of the process");
1925     SetupCommonCmdArgs(ts);
1926
1927     ts = cmd_CreateSyntax("BosProcessAllStop", DoBosProcessAllStop, NULL, 0,
1928                           "stop all processes at a bos server");
1929     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED,
1930                 "server where processes exists");
1931     SetupCommonCmdArgs(ts);
1932
1933     ts = cmd_CreateSyntax("BosProcessAllWaitStop", DoBosProcessAllWaitStop, NULL, 0,
1934                           "stop all processes at a bos server and block "
1935                           "until they all exit");
1936     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED,
1937                 "server where processes exists");
1938     SetupCommonCmdArgs(ts);
1939
1940     ts = cmd_CreateSyntax("BosProcessAllWaitTransition",
1941                           DoBosProcessAllWaitTransition, NULL, 0,
1942                           "wait until all processes have transitioned to "
1943                           "their desired state");
1944     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED,
1945                 "server where processes exists");
1946     SetupCommonCmdArgs(ts);
1947
1948     ts = cmd_CreateSyntax("BosProcessAllStopAndRestart",
1949                           DoBosProcessAllStopAndRestart, NULL, 0,
1950                           "stop all processes at a bos server and "
1951                           "then restart them");
1952     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED,
1953                 "server where processes exists");
1954     cmd_AddParm(ts, "-includebos", CMD_FLAG, CMD_OPTIONAL,
1955                 "include the bos server in the processes to be restarted");
1956     SetupCommonCmdArgs(ts);
1957
1958     ts = cmd_CreateSyntax("BosAdminCreate", DoBosAdminCreate, NULL, 0,
1959                           "create an admin user at a bos server");
1960     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED,
1961                 "server where admin will be created");
1962     cmd_AddParm(ts, "-admin", CMD_SINGLE, CMD_REQUIRED,
1963                 "the name of the administrator to add");
1964     SetupCommonCmdArgs(ts);
1965
1966     ts = cmd_CreateSyntax("BosAdminDelete", DoBosAdminDelete, NULL, 0,
1967                           "delete an admin user at a bos server");
1968     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED,
1969                 "server where admin will be deleted");
1970     cmd_AddParm(ts, "-admin", CMD_SINGLE, CMD_REQUIRED,
1971                 "the name of the administrator to delete");
1972     SetupCommonCmdArgs(ts);
1973
1974     ts = cmd_CreateSyntax("BosAdminList", DoBosAdminList, NULL, 0,
1975                           "list all admin users at a bos server");
1976     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED,
1977                 "server where admins will be listed");
1978     SetupCommonCmdArgs(ts);
1979
1980     ts = cmd_CreateSyntax("BosKeyCreate", DoBosKeyCreate, NULL, 0,
1981                           "create a key at a bos server");
1982     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED,
1983                 "server where key will be created");
1984     cmd_AddParm(ts, "-versionnumber", CMD_SINGLE, CMD_REQUIRED,
1985                 "version number of new key");
1986     cmd_AddParm(ts, "-key", CMD_SINGLE, CMD_REQUIRED, "new encryption key");
1987     SetupCommonCmdArgs(ts);
1988
1989     ts = cmd_CreateSyntax("BosKeyDelete", DoBosKeyDelete, NULL, 0,
1990                           "delete a key at a bos server");
1991     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED,
1992                 "server where key will be deleted");
1993     cmd_AddParm(ts, "-versionnumber", CMD_SINGLE, CMD_REQUIRED,
1994                 "version number of the key");
1995     SetupCommonCmdArgs(ts);
1996
1997     ts = cmd_CreateSyntax("BosKeyList", DoBosKeyList, NULL, 0,
1998                           "list keys at a bos server");
1999     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED,
2000                 "server where keys exist");
2001     SetupCommonCmdArgs(ts);
2002
2003     ts = cmd_CreateSyntax("BosCellSet", DoBosCellSet, NULL, 0,
2004                           "set the cell at a bos server");
2005     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED, "server to modify");
2006     cmd_AddParm(ts, "-cell", CMD_SINGLE, CMD_REQUIRED, "new cell");
2007     SetupCommonCmdArgs(ts);
2008
2009     ts = cmd_CreateSyntax("BosCellGet", DoBosCellGet, NULL, 0,
2010                           "get the cell at a bos server");
2011     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED, "server to query");
2012     SetupCommonCmdArgs(ts);
2013
2014     ts = cmd_CreateSyntax("BosHostCreate", DoBosHostCreate, NULL, 0,
2015                           "add a host entry to the server CellServDB");
2016     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED, "server to modify");
2017     cmd_AddParm(ts, "-host", CMD_SINGLE, CMD_REQUIRED, "host to add");
2018     SetupCommonCmdArgs(ts);
2019
2020     ts = cmd_CreateSyntax("BosHostDelete", DoBosHostDelete, NULL, 0,
2021                           "delete a host entry from the server CellServDB");
2022     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED, "server to modify");
2023     cmd_AddParm(ts, "-host", CMD_SINGLE, CMD_REQUIRED, "host to delete");
2024     SetupCommonCmdArgs(ts);
2025
2026     ts = cmd_CreateSyntax("BosHostList", DoBosHostList, NULL, 0,
2027                           "list all host entries from the server CellServDB");
2028     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED, "server to query");
2029     SetupCommonCmdArgs(ts);
2030
2031     ts = cmd_CreateSyntax("BosExecutableCreate", DoBosExecutableCreate, NULL, 0,
2032                           "create a new binary at a bos server");
2033     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED, "server to modify");
2034     cmd_AddParm(ts, "-binary", CMD_SINGLE, CMD_REQUIRED,
2035                 "path to the binary to create");
2036     cmd_AddParm(ts, "-dest", CMD_SINGLE, CMD_REQUIRED,
2037                 "path where the binary will be stored");
2038     SetupCommonCmdArgs(ts);
2039
2040     ts = cmd_CreateSyntax("BosExecutableRevert", DoBosExecutableRevert, NULL, 0,
2041                           "revert a binary at a bos server");
2042     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED, "server to modify");
2043     cmd_AddParm(ts, "-executable", CMD_SINGLE, CMD_REQUIRED,
2044                 "path to the binary to revert");
2045     SetupCommonCmdArgs(ts);
2046
2047     ts = cmd_CreateSyntax("BosExecutableTimestampGet",
2048                           DoBosExecutableTimestampGet, NULL, 0,
2049                           "get the timestamps for a binary at bos server");
2050     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED, "server to query");
2051     cmd_AddParm(ts, "-executable", CMD_SINGLE, CMD_REQUIRED,
2052                 "path to the binary to revert");
2053     SetupCommonCmdArgs(ts);
2054
2055     ts = cmd_CreateSyntax("BosExecutablePrune", DoBosExecutablePrune, NULL, 0,
2056                           "prune various files at bos server");
2057     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED, "server to modify");
2058     cmd_AddParm(ts, "-oldfiles", CMD_FLAG, CMD_OPTIONAL, "prune .old files");
2059     cmd_AddParm(ts, "-bakfiles", CMD_FLAG, CMD_OPTIONAL, "prune .bak files");
2060     cmd_AddParm(ts, "-corefiles", CMD_FLAG, CMD_OPTIONAL, "prune core files");
2061     SetupCommonCmdArgs(ts);
2062
2063     ts = cmd_CreateSyntax("BosExecutableRestartTimeSet",
2064                           DoBosExecutableRestartTimeSet, NULL, 0,
2065                           "set the restart times at a bos server");
2066     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED, "server to modify");
2067     cmd_AddParm(ts, "-daily", CMD_FLAG, CMD_OPTIONAL,
2068                 "set daily restart time");
2069     cmd_AddParm(ts, "-weekly", CMD_FLAG, CMD_OPTIONAL,
2070                 "set weekly restart time");
2071     cmd_AddParm(ts, "-time", CMD_SINGLE, CMD_REQUIRED,
2072                 "the new restart time");
2073     SetupCommonCmdArgs(ts);
2074
2075     ts = cmd_CreateSyntax("BosExecutableRestartTimeGet",
2076                           DoBosExecutableRestartTimeGet, NULL, 0,
2077                           "get the restart times at a bos server");
2078     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED, "server to query");
2079     cmd_AddParm(ts, "-daily", CMD_FLAG, CMD_OPTIONAL,
2080                 "get daily restart time");
2081     cmd_AddParm(ts, "-weekly", CMD_FLAG, CMD_OPTIONAL,
2082                 "get weekly restart time");
2083     SetupCommonCmdArgs(ts);
2084
2085     ts = cmd_CreateSyntax("BosLogGet", DoBosLogGet, NULL, 0,
2086                           "get a log file from the bos server");
2087     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED, "server to query");
2088     cmd_AddParm(ts, "-logfile", CMD_SINGLE, CMD_REQUIRED,
2089                 "path to the log file to retrieve");
2090     SetupCommonCmdArgs(ts);
2091
2092     ts = cmd_CreateSyntax("BosAuthSet", DoBosAuthSet, NULL, 0,
2093                           "set the authorization level at a bos server");
2094     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED, "server to modify");
2095     cmd_AddParm(ts, "-requireauth", CMD_FLAG, CMD_OPTIONAL,
2096                 "require authorization");
2097     cmd_AddParm(ts, "-disableauth", CMD_FLAG, CMD_OPTIONAL,
2098                 "don't require authorization");
2099     SetupCommonCmdArgs(ts);
2100
2101     ts = cmd_CreateSyntax("BosCommandExecute", DoBosCommandExecute, 0, 0,
2102                           "execute a command at a bos server");
2103     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED,
2104                 "server where command will execute");
2105     cmd_AddParm(ts, "-command", CMD_SINGLE, CMD_REQUIRED,
2106                 "command to execute");
2107     SetupCommonCmdArgs(ts);
2108
2109     ts = cmd_CreateSyntax("BosSalvage", DoBosSalvage, NULL, 0,
2110                           "execute a salvage command at a bos server");
2111     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED,
2112                 "server where salvager will execute");
2113     cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL,
2114                 "partition to salvage");
2115     cmd_AddParm(ts, "-volume", CMD_SINGLE, CMD_OPTIONAL, "volume to salvage");
2116     cmd_AddParm(ts, "-numsalvagers", CMD_SINGLE, CMD_REQUIRED,
2117                 "number of salvagers to run in parallel");
2118     cmd_AddParm(ts, "-tmpdir", CMD_SINGLE, CMD_OPTIONAL,
2119                 "directory to place temporary files");
2120     cmd_AddParm(ts, "-logfile", CMD_SINGLE, CMD_OPTIONAL,
2121                 "file where salvager log will be written");
2122     cmd_AddParm(ts, "-force", CMD_FLAG, CMD_OPTIONAL, "run salvager -force");
2123     cmd_AddParm(ts, "-nowrite", CMD_FLAG, CMD_OPTIONAL,
2124                 "run salvager -nowrite");
2125     cmd_AddParm(ts, "-inodes", CMD_FLAG, CMD_OPTIONAL,
2126                 "run salvager -inodes");
2127     cmd_AddParm(ts, "-rootinodes", CMD_FLAG, CMD_OPTIONAL,
2128                 "run salvager -rootinodes");
2129     cmd_AddParm(ts, "-salvagedirs", CMD_FLAG, CMD_OPTIONAL,
2130                 "run salvager -salvagedirs");
2131     cmd_AddParm(ts, "-blockreads", CMD_FLAG, CMD_OPTIONAL,
2132                 "run salvager -blockreads");
2133     SetupCommonCmdArgs(ts);
2134 }