cmd: add flags argument to create syntax function
[openafs.git] / src / libadmin / cfg / test / cfgtest.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 /* Test driver for configuration functions. */
11
12 #include <afsconfig.h>
13 #include <afs/param.h>
14 #include <afs/stds.h>
15
16 #include <roken.h>
17
18 #include <pthread.h>
19
20 #include <afs/afs_Admin.h>
21 #include <afs/afs_utilAdmin.h>
22 #include <afs/afs_clientAdmin.h>
23 #include <afs/afs_cfgAdmin.h>
24
25 #include <afs/cellconfig.h>
26 #include <afs/cmd.h>
27
28
29 /* define some globals */
30 static char myCellName[MAXCELLCHARS];
31 static void *myTokenHandle;
32 static void *myCellHandle;
33
34
35
36 /* ------------------- Utility functions ---------------------- */
37
38 static const char *
39 GetErrorText(afs_status_t errorCode)
40 {
41     afs_status_t st;
42     const char *errorCodeText;
43     static const char *failedLookupText = "unable to translate error code";
44
45     if (util_AdminErrorCodeTranslate(errorCode, 0, &errorCodeText, &st)) {
46         return errorCodeText;
47     } else {
48         return failedLookupText;
49     }
50 }
51
52
53 /* ------------------- CellServDB functions ------------------------ */
54
55 #define CSDBCallBackId 42
56 static pthread_mutex_t CSDBCallBackMutex;
57 static pthread_cond_t CSDBCallBackCond;
58 static int CSDBCallBackDone;
59
60 static void ADMINAPI
61 CellServDbCallBack(void *callBackId, cfg_cellServDbStatus_t * statusItemP,
62                    afs_status_t st)
63 {
64     if (statusItemP != NULL) {
65         printf("Updated %s with result '%s' (tid = %u)\n",
66                statusItemP->fsDbHost, GetErrorText(statusItemP->status),
67                (unsigned)pthread_self());
68     } else {
69         printf("Update termination (tid = %u)\n", (unsigned)pthread_self());
70
71         (void)pthread_mutex_lock(&CSDBCallBackMutex);
72         CSDBCallBackDone = 1;
73         (void)pthread_mutex_unlock(&CSDBCallBackMutex);
74         (void)pthread_cond_signal(&CSDBCallBackCond);
75     }
76
77     if (callBackId != (void *)CSDBCallBackId) {
78         printf("Update call back ID invalid (tid = %u)\n",
79                (unsigned)pthread_self());
80     }
81 }
82
83
84 static int
85 DoCellServDbAddHost(struct cmd_syndesc *as, void *arock)
86 {
87     afs_status_t st = 0;
88     int maxUpdates;
89     void *hostHandle;
90     char *cfgHost = as->parms[0].items->data;
91     char *sysHost = NULL;
92
93     if (as->parms[1].items) {
94         sysHost = as->parms[1].items->data;
95     }
96
97     if (!cfg_HostOpen(myCellHandle, cfgHost, &hostHandle, &st)) {
98         printf("cfg_HostOpen failed (%s)\n", GetErrorText(st));
99     } else {
100         CSDBCallBackDone = 0;
101
102         if (!cfg_CellServDbAddHost
103             (hostHandle, sysHost, CellServDbCallBack, (void *)CSDBCallBackId,
104              &maxUpdates, &st)) {
105             printf("cfg_CellServDbAddHost failed (%s)\n", GetErrorText(st));
106             CSDBCallBackDone = 1;
107
108         } else {
109             printf("cfg_CellServDbAddHost succeeded (maxUpdates = %d)\n",
110                    maxUpdates);
111         }
112
113         (void)pthread_mutex_lock(&CSDBCallBackMutex);
114
115         while (!CSDBCallBackDone) {
116             (void)pthread_cond_wait(&CSDBCallBackCond, &CSDBCallBackMutex);
117         }
118
119         (void)pthread_mutex_unlock(&CSDBCallBackMutex);
120
121         if (!cfg_HostClose(hostHandle, &st)) {
122             printf("cfg_HostClose failed (%s)\n", GetErrorText(st));
123         }
124     }
125     return (st == 0 ? 0 : 1);
126 }
127
128
129 static int
130 DoCellServDbRemoveHost(struct cmd_syndesc *as, void *arock)
131 {
132     afs_status_t st = 0;
133     int maxUpdates;
134     void *hostHandle;
135     char *cfgHost = as->parms[0].items->data;
136     char *sysHost = NULL;
137
138     if (as->parms[1].items) {
139         sysHost = as->parms[1].items->data;
140     }
141
142     if (!cfg_HostOpen(myCellHandle, cfgHost, &hostHandle, &st)) {
143         printf("cfg_HostOpen failed (%s)\n", GetErrorText(st));
144     } else {
145         CSDBCallBackDone = 0;
146
147         if (!cfg_CellServDbRemoveHost
148             (hostHandle, sysHost, CellServDbCallBack, (void *)CSDBCallBackId,
149              &maxUpdates, &st)) {
150             printf("cfg_CellServDbRemoveHost failed (%s)\n",
151                    GetErrorText(st));
152             CSDBCallBackDone = 1;
153
154         } else {
155             printf("cfg_CellServDbRemoveHost succeeded (maxUpdates = %d)\n",
156                    maxUpdates);
157         }
158
159         (void)pthread_mutex_lock(&CSDBCallBackMutex);
160
161         while (!CSDBCallBackDone) {
162             (void)pthread_cond_wait(&CSDBCallBackCond, &CSDBCallBackMutex);
163         }
164
165         (void)pthread_mutex_unlock(&CSDBCallBackMutex);
166
167         if (!cfg_HostClose(hostHandle, &st)) {
168             printf("cfg_HostClose failed (%s)\n", GetErrorText(st));
169         }
170     }
171     return (st == 0 ? 0 : 1);
172 }
173
174
175 static int
176 DoCellServDbEnumerate(struct cmd_syndesc *as, void *arock)
177 {
178     afs_status_t st = 0;
179     char *fsDbHost = as->parms[0].items->data;
180     char *cellName;
181     char *cellDbHosts;
182
183     if (!cfg_CellServDbEnumerate(fsDbHost, &cellName, &cellDbHosts, &st)) {
184         printf("cfg_CellServDbEnumerate failed (%s)\n", GetErrorText(st));
185     } else {
186         char *mstrp;
187
188         printf("%s is in cell %s\n", fsDbHost, cellName);
189
190         for (mstrp = cellDbHosts; *mstrp != '\0'; mstrp += strlen(mstrp) + 1) {
191             printf("\t%s\n", mstrp);
192         }
193
194         if (!cfg_StringDeallocate(cellName, &st)) {
195             printf("cfg_StringDeallocate failed (%s)\n", GetErrorText(st));
196         }
197
198         if (!cfg_StringDeallocate(cellDbHosts, &st)) {
199             printf("cfg_StringDeallocate failed (%s)\n", GetErrorText(st));
200         }
201     }
202     return (st == 0 ? 0 : 1);
203 }
204
205
206 static void
207 SetupCellServDbCmd(void)
208 {
209     struct cmd_syndesc *ts;
210
211     ts = cmd_CreateSyntax("CellServDbAddHost", DoCellServDbAddHost, NULL, 0,
212                           "add configuration target to server CellServDB");
213     cmd_AddParm(ts, "-cfghost", CMD_SINGLE, CMD_REQUIRED,
214                 "configuration host");
215     cmd_AddParm(ts, "-syshost", CMD_SINGLE, CMD_OPTIONAL,
216                 "system control host");
217
218     ts = cmd_CreateSyntax("CellServDbRemoveHost", DoCellServDbRemoveHost, NULL, 0,
219                           "remove configuration target from server CellServDB");
220     cmd_AddParm(ts, "-cfghost", CMD_SINGLE, CMD_REQUIRED,
221                 "configuration host");
222     cmd_AddParm(ts, "-syshost", CMD_SINGLE, CMD_OPTIONAL,
223                 "system control host");
224
225     ts = cmd_CreateSyntax("CellServDbEnumerate", DoCellServDbEnumerate, NULL, 0,
226                           "enumerate server CellServDB from specified host");
227     cmd_AddParm(ts, "-host", CMD_SINGLE, CMD_REQUIRED, "host name");
228
229
230     (void)pthread_mutex_init(&CSDBCallBackMutex, NULL);
231     (void)pthread_cond_init(&CSDBCallBackCond, NULL);
232 }
233
234
235
236 /* ------------------- Server functions ------------------------ */
237
238
239 static int
240 DoDbServersWaitForQuorum(struct cmd_syndesc *as, void *arock)
241 {
242     afs_status_t st = 0;
243     void *hostHandle;
244     char *cfgHost = as->parms[0].items->data;
245     unsigned int timeout = 180;
246
247     if (as->parms[1].items) {
248         timeout = strtoul(as->parms[1].items->data, NULL, 10);
249     }
250
251     if (!cfg_HostOpen(myCellHandle, cfgHost, &hostHandle, &st)) {
252         printf("cfg_HostOpen failed (%s)\n", GetErrorText(st));
253     } else {
254         if (!cfg_DbServersWaitForQuorum(hostHandle, timeout, &st)) {
255             printf("cfg_DbServersWaitForQuorum failed (%s)\n",
256                    GetErrorText(st));
257         }
258
259         if (!cfg_HostClose(hostHandle, &st)) {
260             printf("cfg_HostClose failed (%s)\n", GetErrorText(st));
261         }
262     }
263     return (st == 0 ? 0 : 1);
264 }
265
266
267 static int
268 DoFileServerStop(struct cmd_syndesc *as, void *arock)
269 {
270     afs_status_t st = 0;
271     void *hostHandle;
272     char *cfgHost = as->parms[0].items->data;
273
274     if (!cfg_HostOpen(myCellHandle, cfgHost, &hostHandle, &st)) {
275         printf("cfg_HostOpen failed (%s)\n", GetErrorText(st));
276     } else {
277         if (!cfg_FileServerStop(hostHandle, &st)) {
278             printf("cfg_FileServerStop failed (%s)\n", GetErrorText(st));
279         }
280
281         if (!cfg_HostClose(hostHandle, &st)) {
282             printf("cfg_HostClose failed (%s)\n", GetErrorText(st));
283         }
284     }
285     return (st == 0 ? 0 : 1);
286 }
287
288 static int
289 DoFileServerStart(struct cmd_syndesc *as, void *arock)
290 {
291     afs_status_t st = 0;
292     void *hostHandle;
293     char *cfgHost = as->parms[0].items->data;
294
295     if (!cfg_HostOpen(myCellHandle, cfgHost, &hostHandle, &st)) {
296         printf("cfg_HostOpen failed (%s)\n", GetErrorText(st));
297     } else {
298         if (!cfg_FileServerStart(hostHandle, &st)) {
299             printf("cfg_FileServerStart failed (%s)\n", GetErrorText(st));
300         }
301
302         if (!cfg_HostClose(hostHandle, &st)) {
303             printf("cfg_HostClose failed (%s)\n", GetErrorText(st));
304         }
305     }
306     return (st == 0 ? 0 : 1);
307 }
308
309
310 static void
311 SetupServerCmd(void)
312 {
313     struct cmd_syndesc *ts;
314
315     ts = cmd_CreateSyntax("DbServersWaitForQuorum", DoDbServersWaitForQuorum,
316                           NULL, 0, "wait for database servers to achieve quorum");
317     cmd_AddParm(ts, "-cfghost", CMD_SINGLE, CMD_REQUIRED,
318                 "configuration host");
319     cmd_AddParm(ts, "-timeout", CMD_SINGLE, CMD_OPTIONAL,
320                 "timeout in seconds");
321
322     ts = cmd_CreateSyntax("FileServerStop", DoFileServerStop, NULL, 0,
323                           "stop and unconfigure fileserver on specified host");
324     cmd_AddParm(ts, "-cfghost", CMD_SINGLE, CMD_REQUIRED,
325                 "configuration host");
326
327     ts = cmd_CreateSyntax("FileServerStart", DoFileServerStart, NULL, 0,
328                           "start the fileserver on specified host");
329     cmd_AddParm(ts, "-cfghost", CMD_SINGLE, CMD_REQUIRED,
330                 "configuration host");
331 }
332
333
334
335 /* ------------------- Host functions ------------------------ */
336
337
338 static int
339 DoHostPartitionTableEnumerate(struct cmd_syndesc *as, void *arock)
340 {
341     afs_status_t st = 0;
342     cfg_partitionEntry_t *vptable;
343     int tableCount, i;
344     void *hostHandle;
345     char *cfgHost = as->parms[0].items->data;
346
347     if (!cfg_HostOpen(myCellHandle, cfgHost, &hostHandle, &st)) {
348         printf("cfg_HostOpen failed (%s)\n", GetErrorText(st));
349     } else {
350         if (!cfg_HostPartitionTableEnumerate
351             (hostHandle, &vptable, &tableCount, &st)) {
352             printf("cfg_HostPartitionTableEnumerate failed (%s)\n",
353                    GetErrorText(st));
354         } else {
355             for (i = 0; i < tableCount; i++) {
356                 printf("Partition: %s     Device: %s\n",
357                        vptable[i].partitionName, vptable[i].deviceName);
358             }
359
360             if (!cfg_PartitionListDeallocate(vptable, &st)) {
361                 printf("cfg_PartitionListDeallocate failed (%s)\n",
362                        GetErrorText(st));
363             }
364         }
365
366         if (!cfg_HostClose(hostHandle, &st)) {
367             printf("cfg_HostClose failed (%s)\n", GetErrorText(st));
368         }
369     }
370     return (st == 0 ? 0 : 1);
371 }
372
373
374 static void
375 SetupHostCmd(void)
376 {
377     struct cmd_syndesc *ts;
378
379     ts = cmd_CreateSyntax("HostPartitionTableEnumerate",
380                           DoHostPartitionTableEnumerate, NULL, 0,
381                           "enumerate vice partition table");
382     cmd_AddParm(ts, "-cfghost", CMD_SINGLE, CMD_REQUIRED,
383                 "configuration host");
384 }
385
386
387
388
389 /* ------------------- Client functions ------------------------ */
390
391
392 static int
393 DoClientCellServDbAdd(struct cmd_syndesc *as, void *arock)
394 {
395     afs_status_t st = 0;
396     void *hostHandle;
397     char *cfgHost = as->parms[0].items->data;
398     char *cellName = as->parms[1].items->data;
399     char *dbHost = as->parms[2].items->data;
400
401     if (!cfg_HostOpen(myCellHandle, cfgHost, &hostHandle, &st)) {
402         printf("cfg_HostOpen failed (%s)\n", GetErrorText(st));
403     } else {
404         if (!cfg_ClientCellServDbAdd(hostHandle, cellName, dbHost, &st)) {
405             printf("cfg_ClientCellServDbAdd failed (%s)\n", GetErrorText(st));
406         }
407
408         if (!cfg_HostClose(hostHandle, &st)) {
409             printf("cfg_HostClose failed (%s)\n", GetErrorText(st));
410         }
411     }
412     return (st == 0 ? 0 : 1);
413 }
414
415
416 static int
417 DoClientCellServDbRemove(struct cmd_syndesc *as, void *arock)
418 {
419     afs_status_t st = 0;
420     void *hostHandle;
421     char *cfgHost = as->parms[0].items->data;
422     char *cellName = as->parms[1].items->data;
423     char *dbHost = as->parms[2].items->data;
424
425     if (!cfg_HostOpen(myCellHandle, cfgHost, &hostHandle, &st)) {
426         printf("cfg_HostOpen failed (%s)\n", GetErrorText(st));
427     } else {
428         if (!cfg_ClientCellServDbRemove(hostHandle, cellName, dbHost, &st)) {
429             printf("cfg_ClientCellServDbRemove failed (%s)\n",
430                    GetErrorText(st));
431         }
432
433         if (!cfg_HostClose(hostHandle, &st)) {
434             printf("cfg_HostClose failed (%s)\n", GetErrorText(st));
435         }
436     }
437     return (st == 0 ? 0 : 1);
438 }
439
440
441 static int
442 DoClientStart(struct cmd_syndesc *as, void *arock)
443 {
444     afs_status_t st = 0;
445     void *hostHandle;
446     char *cfgHost = as->parms[0].items->data;
447     char *timeoutStr = as->parms[1].items->data;
448     unsigned int timeoutVal;
449
450     timeoutVal = strtoul(timeoutStr, NULL, 10);
451
452     if (!cfg_HostOpen(myCellHandle, cfgHost, &hostHandle, &st)) {
453         printf("cfg_HostOpen failed (%s)\n", GetErrorText(st));
454     } else {
455         if (!cfg_ClientStart(hostHandle, timeoutVal, &st)) {
456             printf("cfg_ClientStart failed (%s)\n", GetErrorText(st));
457         }
458
459         if (!cfg_HostClose(hostHandle, &st)) {
460             printf("cfg_HostClose failed (%s)\n", GetErrorText(st));
461         }
462     }
463     return (st == 0 ? 0 : 1);
464 }
465
466
467
468 static int
469 DoClientStop(struct cmd_syndesc *as, void *arock)
470 {
471     afs_status_t st = 0;
472     void *hostHandle;
473     char *cfgHost = as->parms[0].items->data;
474     char *timeoutStr = as->parms[1].items->data;
475     unsigned int timeoutVal;
476
477     timeoutVal = strtoul(timeoutStr, NULL, 10);
478
479     if (!cfg_HostOpen(myCellHandle, cfgHost, &hostHandle, &st)) {
480         printf("cfg_HostOpen failed (%s)\n", GetErrorText(st));
481     } else {
482         if (!cfg_ClientStop(hostHandle, timeoutVal, &st)) {
483             printf("cfg_ClientStop failed (%s)\n", GetErrorText(st));
484         }
485
486         if (!cfg_HostClose(hostHandle, &st)) {
487             printf("cfg_HostClose failed (%s)\n", GetErrorText(st));
488         }
489     }
490     return (st == 0 ? 0 : 1);
491 }
492
493
494
495 static int
496 DoClientSetCell(struct cmd_syndesc *as, void *arock)
497 {
498     afs_status_t st = 0;
499     void *hostHandle;
500     char *cfgHost = as->parms[0].items->data;
501     char *cellName = as->parms[1].items->data;
502     struct cmd_item *citem;
503     char cellDbHosts[1024];
504     char *dbHost = cellDbHosts;
505     void *nullCellHandle;
506
507     /* setup multistring of database hosts */
508     for (citem = as->parms[2].items; citem != NULL; citem = citem->next) {
509         strcpy(dbHost, citem->data);
510         dbHost += strlen(citem->data) + 1;
511     }
512     *dbHost = '\0';
513
514     /* use a null cell handle to avoid "cell mismatch" */
515     if (!afsclient_NullCellOpen(&nullCellHandle, &st)) {
516         printf("afsclient_NullCellOpen failed (%s)\n", GetErrorText(st));
517     } else {
518         if (!cfg_HostOpen(nullCellHandle, cfgHost, &hostHandle, &st)) {
519             printf("cfg_HostOpen failed (%s)\n", GetErrorText(st));
520         } else {
521             if (!cfg_ClientSetCell(hostHandle, cellName, cellDbHosts, &st)) {
522                 printf("cfg_ClientSetCell failed (%s)\n", GetErrorText(st));
523             }
524
525             if (!cfg_HostClose(hostHandle, &st)) {
526                 printf("cfg_HostClose failed (%s)\n", GetErrorText(st));
527             }
528         }
529
530         if (!afsclient_CellClose(nullCellHandle, &st)) {
531             printf("afsclient_CellClose failed (%s)\n", GetErrorText(st));
532         }
533     }
534     return (st == 0 ? 0 : 1);
535 }
536
537
538 static int
539 DoClientQueryStatus(struct cmd_syndesc *as, void *arock)
540 {
541     afs_status_t st = 0;
542     char *cfgHost = as->parms[0].items->data;
543     short cmInstalled;
544     unsigned cmVersion;
545     afs_status_t clientSt;
546     char *clientCell;
547
548     if (!cfg_ClientQueryStatus
549         (cfgHost, &cmInstalled, &cmVersion, &clientSt, &clientCell, &st)) {
550         printf("cfg_ClientQueryStatus failed (%s)\n", GetErrorText(st));
551     } else {
552         if (cmInstalled) {
553             printf("Client (CM) version %u is installed.\n", cmVersion);
554         } else {
555             printf("Client (CM) is not installed.\n");
556         }
557
558         if (clientSt == 0) {
559             printf("Client configuration is valid; default cell is %s.\n",
560                    clientCell);
561         } else {
562             printf("Client configuration is not valid (%s).\n",
563                    GetErrorText(clientSt));
564         }
565     }
566
567     return (st == 0 ? 0 : 1);
568 }
569
570
571
572 static int
573 DoHostQueryStatus(struct cmd_syndesc *as, void *arock)
574 {
575     afs_status_t st = 0;
576     char *cfgHost = as->parms[0].items->data;
577     afs_status_t serverSt;
578     char *serverCell;
579
580     if (!cfg_HostQueryStatus(cfgHost, &serverSt, &serverCell, &st)) {
581         printf("cfg_HostQueryStatus failed (%s)\n", GetErrorText(st));
582     } else {
583         if (serverSt == 0) {
584             printf("Server configuration is valid; cell is %s.\n",
585                    serverCell);
586         } else {
587             printf("Server configuration is not valid (%s).\n",
588                    GetErrorText(serverSt));
589         }
590     }
591
592     return (st == 0 ? 0 : 1);
593 }
594
595
596
597
598
599
600 static void
601 SetupClientCmd(void)
602 {
603     struct cmd_syndesc *ts;
604
605     ts = cmd_CreateSyntax("ClientCellServDbAdd", DoClientCellServDbAdd, NULL, 0,
606                           "add host entry to client CellServDB");
607     cmd_AddParm(ts, "-cfghost", CMD_SINGLE, CMD_REQUIRED,
608                 "configuration host");
609     cmd_AddParm(ts, "-cell", CMD_SINGLE, CMD_REQUIRED, "cell name");
610     cmd_AddParm(ts, "-dbhost", CMD_SINGLE, CMD_REQUIRED, "host to add");
611
612     ts = cmd_CreateSyntax("ClientCellServDbRemove", DoClientCellServDbRemove,
613                           NULL, 0, "remove host entry from client CellServDB");
614     cmd_AddParm(ts, "-cfghost", CMD_SINGLE, CMD_REQUIRED,
615                 "configuration host");
616     cmd_AddParm(ts, "-cell", CMD_SINGLE, CMD_REQUIRED, "cell name");
617     cmd_AddParm(ts, "-dbhost", CMD_SINGLE, CMD_REQUIRED, "host to remove");
618
619     ts = cmd_CreateSyntax("ClientSetCell", DoClientSetCell, NULL, 0,
620                           "set default client cell");
621     cmd_AddParm(ts, "-cfghost", CMD_SINGLE, CMD_REQUIRED,
622                 "configuration host");
623     cmd_AddParm(ts, "-cell", CMD_SINGLE, CMD_REQUIRED, "cell name");
624     cmd_AddParm(ts, "-dbhosts", CMD_LIST, CMD_REQUIRED, "database hosts");
625
626     ts = cmd_CreateSyntax("ClientQueryStatus", DoClientQueryStatus, NULL, 0,
627                           "query status of client on host");
628     cmd_AddParm(ts, "-cfghost", CMD_SINGLE, CMD_REQUIRED,
629                 "configuration host");
630
631     ts = cmd_CreateSyntax("HostQueryStatus", DoHostQueryStatus, NULL, 0,
632                           "query status of server on host");
633     cmd_AddParm(ts, "-cfghost", CMD_SINGLE, CMD_REQUIRED,
634                 "configuration host");
635
636
637     ts = cmd_CreateSyntax("ClientStart", DoClientStart, NULL, 0,
638                           "start the client");
639     cmd_AddParm(ts, "-cfghost", CMD_SINGLE, CMD_REQUIRED,
640                 "configuration host");
641     cmd_AddParm(ts, "-timeout", CMD_SINGLE, CMD_REQUIRED, "wait timeout");
642
643
644     ts = cmd_CreateSyntax("ClientStop", DoClientStop, NULL, 0, "stop the client");
645     cmd_AddParm(ts, "-cfghost", CMD_SINGLE, CMD_REQUIRED,
646                 "configuration host");
647     cmd_AddParm(ts, "-timeout", CMD_SINGLE, CMD_REQUIRED, "wait timeout");
648 }
649
650
651
652
653 int
654 main(int argc, char *argv[])
655 {
656     int code;
657     afs_status_t st;
658     char *whoami = argv[0];
659
660     /* perform client initialization */
661
662     if (!afsclient_Init(&st)) {
663         printf("afsclient_Init failed (%s)\n", GetErrorText(st));
664         exit(1);
665     }
666
667     if (!afsclient_LocalCellGet(myCellName, &st)) {
668         printf("afsclient_LocalCellGet failed (%s)\n", GetErrorText(st));
669         exit(1);
670     } else {
671         printf("%s running in cell %s\n\n", whoami, myCellName);
672     }
673
674     if (!afsclient_TokenGetExisting(myCellName, &myTokenHandle, &st)) {
675         printf("afsclient_TokenGetExisting failed (%s)\n", GetErrorText(st));
676         printf("Test will run unauthenticated\n\n");
677
678         if (!afsclient_TokenGetNew
679             (myCellName, NULL, NULL, &myTokenHandle, &st)) {
680             printf("afsclient_TokenGetNew failed (%s)\n", GetErrorText(st));
681             exit(1);
682         }
683     }
684
685     if (!afsclient_CellOpen(myCellName, myTokenHandle, &myCellHandle, &st)) {
686         printf("afsclient_CellOpen failed (%s)\n", GetErrorText(st));
687         exit(1);
688     }
689
690     /* initialize command syntax and globals */
691
692     SetupCellServDbCmd();
693     SetupServerCmd();
694     SetupHostCmd();
695     SetupClientCmd();
696
697     /* execute command */
698
699     code = cmd_Dispatch(argc, argv);
700
701     /* release handles */
702
703     if (!afsclient_CellClose(myCellHandle, &st)) {
704         printf("afsclient_CellClose failed (%s)\n", GetErrorText(st));
705         exit(1);
706     }
707
708     if (!afsclient_TokenClose(myTokenHandle, &st)) {
709         printf("afsclient_TokenClose failed (%s)\n", GetErrorText(st));
710         exit(1);
711     }
712
713     return (code);
714 }