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