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