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