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