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