2 * Copyright 2000, International Business Machines Corporation and others.
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
10 #include <afsconfig.h>
11 #include <afs/param.h>
22 #include <sys/types.h>
27 #include <WINNT/afsevent.h>
29 #include <netinet/in.h>
31 #include <afs/cellconfig.h>
36 #include <afs/afsutil.h>
37 #include <afs/com_err.h>
46 extern struct ubik_client *pruclient;
49 struct sourcestack *s_next;
54 pts_Interactive(struct cmd_syndesc *as, void *arock)
61 pts_Quit(struct cmd_syndesc *as, void *arock)
68 pts_Source(struct cmd_syndesc *as, void *arock)
71 struct sourcestack *sp;
74 if (!as->parms[0].items) {
75 /* can this happen? */
78 fd = fopen(as->parms[0].items->data, "r");
80 perror(as->parms[0].items->data);
83 sp = (struct sourcestack *)malloc(sizeof *sp);
85 return errno ? errno : ENOMEM;
96 pts_Sleep(struct cmd_syndesc *as, void *arock)
99 if (!as->parms[0].items) {
100 /* can this happen? */
103 delay = atoi(as->parms[0].items->data);
111 register struct sourcestack *sp;
125 /* OK, this REALLY sucks bigtime, but I can't tell who is calling
126 * afsconf_CheckAuth easily, and only *SERVERS* should be calling osi_audit
127 * anyway. It's gonna give somebody fits to debug, I know, I know.
133 GetGlobals(struct cmd_syndesc *as, void *arock)
135 register afs_int32 code;
141 if (!strcmp(as->name, "help"))
143 if (as->parms[16].items)
144 cell = as->parms[16].items->data;
147 if (as->parms[17].items)
150 if (as->parms[18].items) { /* testing? */
151 code = pr_Initialize(sec, AFSDIR_SERVER_ETC_DIRPATH, cell);
153 code = pr_Initialize(sec, AFSDIR_CLIENT_ETC_DIRPATH, cell);
156 afs_com_err(whoami, code, "while initializing");
159 if (as->parms[19].items)
165 CleanUp(struct cmd_syndesc *as, void *arock)
167 if (as && !strcmp(as->name, "help"))
170 /* Need to shutdown the ubik_client & other connections */
178 CreateGroup(struct cmd_syndesc *as, void *arock)
180 register afs_int32 code;
183 struct cmd_item *namei;
184 struct cmd_item *idi;
186 namei = as->parms[0].items;
187 idi = as->parms[2].items;
188 if (as->parms[1].items)
189 owner = as->parms[1].items->data;
195 code = util_GetInt32(idi->data, &id);
197 afs_com_err(whoami, code, "because group id was: '%s'",
203 afs_com_err(whoami, code, "because group id %d was not negative",
209 printf("0 isn't a valid user id; aborting\n");
217 code = pr_CreateGroup(namei->data, owner, &id);
220 afs_com_err(whoami, code,
221 "; unable to create group %s with id %d%s%s%s%s",
222 namei->data, id, owner ? " owned by '" : "",
223 owner ? owner : "", owner ? "'" : "",
224 (force ? " (ignored)" : ""));
226 afs_com_err(whoami, code, "; unable to create group %s %s",
227 namei->data, (force ? "(ignored)" : ""));
231 printf("group %s has id %d\n", namei->data, id);
238 CreateUser(struct cmd_syndesc *as, void *arock)
240 register afs_int32 code;
242 struct cmd_item *namei;
243 struct cmd_item *idi;
245 namei = as->parms[0].items;
246 idi = as->parms[1].items;
250 code = util_GetInt32(idi->data, &id);
252 afs_com_err(whoami, code, "because id was: '%s'", idi->data);
256 printf("0 isn't a valid user id; aborting\n");
263 code = pr_CreateUser(namei->data, &id);
266 afs_com_err(whoami, code,
267 "; unable to create user %s with id %d %s",
268 namei->data, id, (force ? "(ignored)" : ""));
270 afs_com_err(whoami, code, "; unable to create user %s %s",
271 namei->data, (force ? "(ignored)" : ""));
275 printf("User %s has id %d\n", namei->data, id);
284 GetNameOrId(register struct cmd_syndesc *as, struct idlist *lids, struct namelist *lnames)
286 register afs_int32 code = 0;
291 if (!(as->parms[0].items || as->parms[1].items)) {
292 afs_com_err(whoami, 0, "must specify either a name or an id.");
295 if (as->parms[0].items && as->parms[1].items) {
296 afs_com_err(whoami, 0, "can't specify both a name and id.");
301 lids->idlist_len = 0;
302 lids->idlist_val = 0;
304 if (as->parms[0].items) { /* name */
305 struct namelist names; /* local copy, if not ret. names */
308 names.namelist_val = 0; /* so it gets freed later if needed */
314 n = 0; /* count names */
315 for (i = as->parms[0].items; i; i = i->next)
317 nl->namelist_val = (prname *) malloc(n * PR_MAXNAMELEN);
318 nl->namelist_len = n;
320 for (i = as->parms[0].items; i; i = i->next)
321 strncpy(nl->namelist_val[n++], i->data, PR_MAXNAMELEN);
323 code = pr_NameToId(nl, lids);
325 afs_com_err(whoami, code, "so couldn't look up names");
327 for (n = 0; n < lids->idlist_len; n++) {
328 if ((lids->idlist_val[n] == ANONYMOUSID)) {
329 afs_com_err(whoami, PRNOENT, "so couldn't look up id for %s",
330 nl->namelist_val[n]);
334 /* treat things as working if any of the lookups worked */
339 if (names.namelist_val)
340 free(names.namelist_val);
341 } else if (as->parms[1].items) { /* id */
343 for (i = as->parms[1].items; i; i = i->next)
345 lids->idlist_val = (afs_int32 *) malloc(n * sizeof(afs_int32));
346 lids->idlist_len = n;
348 for (i = as->parms[1].items; i; i = i->next) {
349 code = util_GetInt32(i->data, &lids->idlist_val[n]);
351 afs_com_err(whoami, code =
352 PRNOENT, "because a bogus id '%s' was specified",
356 if (!code && lnames) {
357 lnames->namelist_val = 0;
358 lnames->namelist_len = 0;
359 code = pr_IdToName(lids, lnames);
361 afs_com_err(whoami, code, "translating ids");
365 if (lids->idlist_val)
366 free(lids->idlist_val);
375 GetNameOrId(register struct cmd_syndesc *as, struct idlist *lids, struct namelist *lnames)
377 register afs_int32 code = 0;
378 int n = 0, nd = 0, nm = 0, id, x;
380 struct namelist names, tnames; /* local copy, if not ret. names */
381 struct idlist ids, tids; /* local copy, if not ret. ids */
384 for (i = as->parms[0].items; i; i = i->next)
386 lids->idlist_val = (afs_int32 *) malloc(n * sizeof(afs_int32));
387 lids->idlist_len = n;
388 ids.idlist_val = (afs_int32 *) malloc(n * sizeof(afs_int32));
390 names.namelist_val = (prname *) malloc(n * PR_MAXNAMELEN);
391 names.namelist_len = n;
393 lnames->namelist_val = (prname *) malloc(n * PR_MAXNAMELEN);
394 lnames->namelist_len = 0;
396 for (i = as->parms[0].items; i; i = i->next) {
397 tnames.namelist_val = (prname *) malloc(PR_MAXNAMELEN);
398 strncpy(tnames.namelist_val[0], i->data, PR_MAXNAMELEN);
399 tnames.namelist_len = 1;
402 code = pr_NameToId(&tnames, &tids);
403 if ((!code && (tids.idlist_val[0] != 32766))
404 || (code = util_GetInt32(i->data, &id))) {
405 /* Assume it's a name instead */
406 strncpy(names.namelist_val[nm++], i->data, PR_MAXNAMELEN);
408 ids.idlist_val[nd++] = id;
410 free(tnames.namelist_val);
412 names.namelist_len = nm;
414 tids.idlist_len = nd = nm = 0;
416 code = pr_NameToId(&names, &tids);
418 afs_com_err(whoami, code, "so couldn't look up names");
420 for (n = 0; n < tids.idlist_len; n++) {
421 if ((tids.idlist_val[n] == ANONYMOUSID)) {
422 afs_com_err(whoami, PRNOENT, "so couldn't look up id for %s",
423 names.namelist_val[n]);
426 lids->idlist_val[nd] = tids.idlist_val[n];
428 strcpy(lnames->namelist_val[nd], names.namelist_val[n]);
432 for (x = 0; x < ids.idlist_len; x++) {
433 lids->idlist_val[nd + x] = ids.idlist_val[x];
435 lids->idlist_len = nd + x;
436 if (!code && lnames) {
437 tnames.namelist_val = 0;
438 tnames.namelist_len = 0;
439 code = pr_IdToName(&ids, &tnames);
441 afs_com_err(whoami, code, "translating ids");
445 for (x = 0; x < ids.idlist_len; x++)
446 strcpy(lnames->namelist_val[nd + x], tnames.namelist_val[x]);
447 lnames->namelist_len = nd + x;
450 /* treat things as working if any of the lookups worked */
454 if (lids->idlist_val)
455 free(lids->idlist_val);
463 AddToGroup(struct cmd_syndesc *as, void *arock)
465 register afs_int32 code;
466 struct cmd_item *u, *g;
468 for (u = as->parms[0].items; u; u = u->next) {
469 for (g = as->parms[1].items; g; g = g->next) {
470 code = pr_AddToGroup(u->data, g->data);
472 afs_com_err(whoami, code,
473 "; unable to add user %s to group %s %s", u->data,
474 g->data, (force ? "(ignored)" : ""));
484 RemoveFromGroup(struct cmd_syndesc *as, void *arock)
486 register afs_int32 code;
487 struct cmd_item *u, *g;
489 for (u = as->parms[0].items; u; u = u->next) {
490 for (g = as->parms[1].items; g; g = g->next) {
491 code = pr_RemoveUserFromGroup(u->data, g->data);
493 afs_com_err(whoami, code,
494 "; unable to remove user %s from group %s %s",
495 u->data, g->data, (force ? "(ignored)" : ""));
505 ListMembership(struct cmd_syndesc *as, void *arock)
507 register afs_int32 code;
514 if (GetNameOrId(as, &ids, &names))
517 for (i = 0; i < ids.idlist_len; i++) {
518 afs_int32 id = ids.idlist_val[i];
519 char *name = names.namelist_val[i];
521 if (id == ANONYMOUSID)
522 continue; /* bad entry */
524 list.namelist_val = 0;
525 list.namelist_len = 0;
526 code = pr_IDListMembers(ids.idlist_val[i], &list);
528 afs_com_err(whoami, code, "; unable to get membership of %s (id: %d)",
533 printf("Members of %s (id: %d) are:\n", name, id);
535 printf("Groups %s (id: %d) is a member of:\n", name, id);
537 for (j = 0; j < list.namelist_len; j++)
538 printf(" %s\n", list.namelist_val[j]);
539 if (list.namelist_val)
540 free(list.namelist_val);
543 free(ids.idlist_val);
544 if (names.namelist_val)
545 free(names.namelist_val);
550 Delete(struct cmd_syndesc *as, void *arock)
552 register afs_int32 code;
557 if (GetNameOrId(as, &ids, &names))
560 for (i = 0; i < ids.idlist_len; i++) {
561 afs_int32 id = ids.idlist_val[i];
562 char *name = names.namelist_val[i];
564 if (id == ANONYMOUSID)
567 code = pr_DeleteByID(id);
569 afs_com_err(whoami, code, "deleting %s (id: %d) %s", name, id,
570 (force ? "(ignored)" : ""));
576 free(ids.idlist_val);
577 if (names.namelist_val)
578 free(names.namelist_val);
582 /* access bit translation info */
584 char *flags_upcase = "SOMA "; /* legal all access values */
585 char *flags_dncase = "s mar"; /* legal member acces values */
586 int flags_shift[5] = { 2, 1, 2, 2, 1 }; /* bits for each */
589 CheckEntry(struct cmd_syndesc *as, void *arock)
591 register afs_int32 code;
593 int i, flag = 0, admin = 0;
594 namelist lnames, names;
597 struct prcheckentry aentry;
599 if (GetNameOrId(as, &ids, &names))
603 lids.idlist_val = (afs_int32 *) malloc(sizeof(afs_int32) * 2);
604 lnames.namelist_len = 0;
605 lnames.namelist_val = 0;
607 for (i = 0; i < ids.idlist_len; i++) {
608 afs_int32 id = ids.idlist_val[i];
610 if (id == ANONYMOUSID)
614 code = pr_ListEntry(id, &aentry);
617 afs_com_err(whoami, code, "; unable to find entry for (id: %d)", id);
621 lids.idlist_val[0] = aentry.owner;
622 lids.idlist_val[1] = aentry.creator;
623 code = pr_IdToName(&lids, &lnames);
626 afs_com_err(whoami, code,
627 "translating owner (%d) and creator (%d) ids",
628 aentry.owner, aentry.creator);
631 printf("Name: %s, id: %d, owner: %s, creator: %s,\n", aentry.name,
632 aentry.id, lnames.namelist_val[0], lnames.namelist_val[1]);
633 printf(" membership: %d", aentry.count);
636 afs_int32 flags = aentry.flags;
639 access[5] = 0; /* null-terminate the string */
640 for (j = 4; j >= 0; j--) {
659 printf(", flags: %s", access);
661 if (aentry.id == SYSADMINID)
663 else if (!pr_IsAMemberOf(aentry.name, "system:administrators", &flag)) {
668 printf(", group quota: unlimited");
670 printf(", group quota: %d", aentry.ngroups);
672 printf(", foreign user quota=%d", aentry.nusers);
677 if (lnames.namelist_val)
678 free(lnames.namelist_val);
680 free(lids.idlist_val);
682 free(ids.idlist_val);
688 ListEntries(struct cmd_syndesc *as, void *arock)
691 afs_int32 flag, startindex, nentries, nextstartindex;
692 struct prlistentries *entriesp = 0, *e;
696 if (as->parms[1].items)
698 if (as->parms[0].items)
701 printf("Name ID Owner Creator\n");
702 for (startindex = 0; startindex != -1; startindex = nextstartindex) {
704 pr_ListEntries(flag, startindex, &nentries, &entriesp,
707 afs_com_err(whoami, code, "; unable to list entries\n");
713 /* Now display each of the entries we read */
714 for (i = 0, e = entriesp; i < nentries; i++, e++) {
715 printf("%-25s %6d %6d %7d \n", e->name, e->id, e->owner,
725 ChownGroup(struct cmd_syndesc *as, void *arock)
727 register afs_int32 code;
731 name = as->parms[0].items->data;
732 owner = as->parms[1].items->data;
733 code = pr_ChangeEntry(name, "", 0, owner);
735 afs_com_err(whoami, code, "; unable to change owner of %s to %s", name,
741 ChangeName(struct cmd_syndesc *as, void *arock)
743 register afs_int32 code;
747 oldname = as->parms[0].items->data;
748 newname = as->parms[1].items->data;
749 code = pr_ChangeEntry(oldname, newname, 0, "");
751 afs_com_err(whoami, code, "; unable to change name of %s to %s", oldname,
757 ListMax(struct cmd_syndesc *as, void *arock)
759 register afs_int32 code;
760 afs_int32 maxUser, maxGroup;
762 code = pr_ListMaxUserId(&maxUser);
764 afs_com_err(whoami, code, "getting maximum user id");
766 code = pr_ListMaxGroupId(&maxGroup);
768 afs_com_err(whoami, code, "getting maximum group id");
770 printf("Max user id is %d and max group id is %d.\n", maxUser,
778 SetMax(struct cmd_syndesc *as, void *arock)
780 register afs_int32 code;
784 if (as->parms[1].items) {
786 code = util_GetInt32(as->parms[1].items->data, &maxid);
788 afs_com_err(whoami, code, "because id was: '%s'",
789 as->parms[1].items->data);
791 code = pr_SetMaxUserId(maxid);
793 afs_com_err(whoami, code, "so couldn't set Max User Id to %d",
797 if (as->parms[0].items) {
799 code = util_GetInt32(as->parms[0].items->data, &maxid);
801 afs_com_err(whoami, code, "because id was: '%s'",
802 as->parms[0].items->data);
804 code = pr_SetMaxGroupId(maxid);
806 afs_com_err(whoami, code, "so couldn't set Max Group Id to %d",
810 if (!as->parms[0].items && !as->parms[1].items) {
812 printf("Must specify at least one of group or user.\n");
818 SetFields(struct cmd_syndesc *as, void *arock)
820 register afs_int32 code;
824 afs_int32 mask, flags=0, ngroups, nusers;
826 if (GetNameOrId(as, &ids, &names))
833 if (as->parms[1].items) { /* privacy bits */
834 char *access = as->parms[1].items->data;
837 if (strpbrk(access, "76543210") != 0) { /* all octal digits */
838 sscanf(access, "%lo", &flags);
839 } else { /* interpret flag bit names */
840 if (strlen(access) != 5) {
842 printf("Access bits must be of the form 'somar', not %s\n",
846 if (strpbrk(access, "somar-") == 0)
849 for (i = 0; i < 5; i++) {
850 if (access[i] == flags_upcase[i])
852 else if (access[i] == flags_dncase[i])
854 else if (access[i] == '-')
858 ("Access bits out of order or illegal:\n must be a combination of letters from '%s' or '%s' or hyphen, not %s\n",
859 flags_upcase, flags_dncase, access);
862 flags <<= flags_shift[i];
863 if (flags_shift[i] == 1) {
870 mask |= PR_SF_ALLBITS;
872 if (as->parms[2].items) { /* limitgroups */
873 code = util_GetInt32(as->parms[2].items->data, &ngroups);
875 afs_com_err(whoami, code, "because ngroups was: '%s'",
876 as->parms[2].items->data);
879 mask |= PR_SF_NGROUPS;
882 if (as->parms[3].items) { /* limitgroups */
883 code = util_GetInt32(as->parms[3].items->data, &nusers);
885 afs_com_err(whoami, code, "because nusers was: '%s'",
886 as->parms[3].items->data);
889 mask |= PR_SF_NUSERS;
893 for (i = 0; i < ids.idlist_len; i++) {
894 afs_int32 id = ids.idlist_val[i];
895 char *name = names.namelist_val[i];
896 if (id == ANONYMOUSID)
898 code = pr_SetFieldsEntry(id, mask, flags, ngroups, nusers);
900 afs_com_err(whoami, code, "; unable to set fields for %s (id: %d)",
906 free(ids.idlist_val);
907 if (names.namelist_val)
908 free(names.namelist_val);
913 ListOwned(struct cmd_syndesc *as, void *arock)
915 register afs_int32 code;
922 if (GetNameOrId(as, &ids, &names))
925 for (i = 0; i < ids.idlist_len; i++) {
926 afs_int32 oid = ids.idlist_val[i];
927 char *name = names.namelist_val[i];
929 if (oid == ANONYMOUSID)
933 printf("Groups owned by %s (id: %d) are:\n", name, oid);
935 printf("Orphaned groups are:\n");
938 list.namelist_val = 0;
939 list.namelist_len = 0;
940 code = pr_ListOwned(oid, &list, &more);
942 afs_com_err(whoami, code,
943 "; unable to get owner list for %s (id: %d)", name,
948 for (j = 0; j < list.namelist_len; j++)
949 printf(" %s\n", list.namelist_val[j]);
950 if (list.namelist_val)
951 free(list.namelist_val);
956 free(ids.idlist_val);
957 if (names.namelist_val)
958 free(names.namelist_val);
963 add_std_args(register struct cmd_syndesc *ts)
965 char test_help[AFSDIR_PATH_MAX];
967 sprintf(test_help, "use config file in %s", AFSDIR_SERVER_ETC_DIRPATH);
970 cmd_AddParm(ts, "-cell", CMD_SINGLE, CMD_OPTIONAL, "cell name");
971 cmd_AddParm(ts, "-noauth", CMD_FLAG, CMD_OPTIONAL, "run unauthenticated");
972 cmd_AddParm(ts, "-test", CMD_FLAG, CMD_OPTIONAL | CMD_HIDE, test_help);
973 cmd_AddParm(ts, "-force", CMD_FLAG, CMD_OPTIONAL,
974 "Continue oper despite reasonable errors");
978 static void add_NameOrId_args (ts)
979 register struct cmd_syndesc *ts;
981 cmd_AddParm(ts,"-name",CMD_LIST,CMD_OPTIONAL,"user or group name");
982 cmd_AddParm(ts,"-id",CMD_LIST,CMD_OPTIONAL,"user or group id");
986 #include "AFS_component_version_number.c"
989 main(int argc, char **argv)
991 register afs_int32 code;
992 register struct cmd_syndesc *ts;
997 char *parsev[CMD_MAXPARMS];
1005 WSAStartup(0x0101, &WSAjunk);
1008 #ifdef AFS_AIX32_ENV
1010 * The following signal action for AIX is necessary so that in case of a
1011 * crash (i.e. core is generated) we can include the user's data section
1012 * in the core dump. Unfortunately, by default, only a partial core is
1013 * generated which, in many cases, isn't too useful.
1015 struct sigaction nsa;
1017 sigemptyset(&nsa.sa_mask);
1018 nsa.sa_handler = SIG_DFL;
1019 nsa.sa_flags = SA_FULLDUMP;
1020 sigaction(SIGSEGV, &nsa, NULL);
1023 ts = cmd_CreateSyntax("creategroup", CreateGroup, NULL,
1024 "create a new group");
1025 cmd_AddParm(ts, "-name", CMD_LIST, 0, "group name");
1026 cmd_AddParm(ts, "-owner", CMD_SINGLE, CMD_OPTIONAL, "owner of the group");
1027 cmd_AddParm(ts, "-id", CMD_LIST, CMD_OPTIONAL,
1028 "id (negated) for the group");
1030 cmd_CreateAlias(ts, "cg");
1032 ts = cmd_CreateSyntax("createuser", CreateUser, NULL, "create a new user");
1033 cmd_AddParm(ts, "-name", CMD_LIST, 0, "user name");
1034 cmd_AddParm(ts, "-id", CMD_LIST, CMD_OPTIONAL, "user id");
1036 cmd_CreateAlias(ts, "cu");
1038 ts = cmd_CreateSyntax("adduser", AddToGroup, NULL, "add a user to a group");
1039 cmd_AddParm(ts, "-user", CMD_LIST, 0, "user name");
1040 cmd_AddParm(ts, "-group", CMD_LIST, 0, "group name");
1043 ts = cmd_CreateSyntax("removeuser", RemoveFromGroup, NULL,
1044 "remove a user from a group");
1045 cmd_AddParm(ts, "-user", CMD_LIST, 0, "user name");
1046 cmd_AddParm(ts, "-group", CMD_LIST, 0, "group name");
1049 ts = cmd_CreateSyntax("membership", ListMembership, NULL,
1050 "list membership of a user or group");
1051 cmd_AddParm(ts, "-nameorid", CMD_LIST, 0, "user or group name or id");
1053 cmd_CreateAlias(ts, "groups");
1055 ts = cmd_CreateSyntax("delete", Delete, NULL,
1056 "delete a user or group from database");
1057 cmd_AddParm(ts, "-nameorid", CMD_LIST, 0, "user or group name or id");
1060 ts = cmd_CreateSyntax("examine", CheckEntry, NULL, "examine an entry");
1061 cmd_AddParm(ts, "-nameorid", CMD_LIST, 0, "user or group name or id");
1063 cmd_CreateAlias(ts, "check");
1065 ts = cmd_CreateSyntax("chown", ChownGroup, NULL,
1066 "change ownership of a group");
1067 cmd_AddParm(ts, "-name", CMD_SINGLE, 0, "group name");
1068 cmd_AddParm(ts, "-owner", CMD_SINGLE, 0, "new owner");
1071 ts = cmd_CreateSyntax("rename", ChangeName, NULL, "rename user or group");
1072 cmd_AddParm(ts, "-oldname", CMD_SINGLE, 0, "old name");
1073 cmd_AddParm(ts, "-newname", CMD_SINGLE, 0, "new name");
1075 cmd_CreateAlias(ts, "chname");
1077 ts = cmd_CreateSyntax("listmax", ListMax, NULL, "list max id");
1080 ts = cmd_CreateSyntax("setmax", SetMax, NULL, "set max id");
1081 cmd_AddParm(ts, "-group", CMD_SINGLE, CMD_OPTIONAL, "group max");
1082 cmd_AddParm(ts, "-user", CMD_SINGLE, CMD_OPTIONAL, "user max");
1085 ts = cmd_CreateSyntax("setfields", SetFields, NULL,
1086 "set fields for an entry");
1087 cmd_AddParm(ts, "-nameorid", CMD_LIST, 0, "user or group name or id");
1088 cmd_AddParm(ts, "-access", CMD_SINGLE, CMD_OPTIONAL, "set privacy flags");
1089 cmd_AddParm(ts, "-groupquota", CMD_SINGLE, CMD_OPTIONAL,
1090 "set limit on group creation");
1092 cmd_AddParm(ts, "-userquota", CMD_SINGLE, CMD_OPTIONAL,
1093 "set limit on foreign user creation");
1097 ts = cmd_CreateSyntax("listowned", ListOwned, NULL,
1098 "list groups owned by an entry or zero id gets orphaned groups");
1099 cmd_AddParm(ts, "-nameorid", CMD_LIST, 0, "user or group name or id");
1102 ts = cmd_CreateSyntax("listentries", ListEntries, NULL,
1103 "list users/groups in the protection database");
1104 cmd_AddParm(ts, "-users", CMD_FLAG, CMD_OPTIONAL, "list user entries");
1105 cmd_AddParm(ts, "-groups", CMD_FLAG, CMD_OPTIONAL, "list group entries");
1108 ts = cmd_CreateSyntax("interactive", pts_Interactive, NULL,
1109 "enter interactive mode");
1111 cmd_CreateAlias(ts, "in");
1113 ts = cmd_CreateSyntax("quit", pts_Quit, NULL, "exit program");
1116 ts = cmd_CreateSyntax("source", pts_Source, NULL, "read commands from file");
1117 cmd_AddParm(ts, "-file", CMD_SINGLE, 0, "filename");
1120 ts = cmd_CreateSyntax("sleep", pts_Sleep, NULL, "pause for a bit");
1121 cmd_AddParm(ts, "-delay", CMD_SINGLE, 0, "seconds");
1124 cmd_SetBeforeProc(GetGlobals, 0);
1128 if (code = cmd_Dispatch(argc, argv)) {
1129 CleanUp(NULL, NULL);
1133 if (isatty(fileno(source)))
1134 fprintf(stderr, "pts> ");
1135 if (!fgets(line, sizeof line, source)) {
1141 for (cp = line; *cp; ++cp)
1151 cmd_ParseLine(line, parsev, &parsec,
1152 sizeof(parsev) / sizeof(*parsev));
1154 afs_com_err(whoami, code, "parsing line: <%s>", line);
1158 parsev[0] = argv[0];
1159 code = cmd_Dispatch(parsec, parsev);
1161 cmd_FreeArgv(parsev);
1163 CleanUp(NULL, NULL);