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
11 * (3) add new pts commands:
13 * Interactive - allow the pts command
14 * to be run interactively.
15 * Quit - quit interactive mode.
16 * Source - allow input to come from a file(s).
17 * Sleep - pause for a specified number
22 #include <afsconfig.h>
23 #include <afs/param.h>
34 #include <sys/types.h>
39 #include <WINNT/afsevent.h>
41 #include <netinet/in.h>
43 #include <afs/cellconfig.h>
48 #include <afs/afsutil.h>
55 #if defined(SUPERGROUPS)
58 * Add new pts commands:
60 * Interactive - allow the pts command to be run interactively.
61 * Quit - quit interactive mode.
62 * Source - allow input to come from a file(s).
63 * Sleep - pause for a specified number of seconds.
68 extern struct ubik_client *pruclient;
71 struct sourcestack *s_next;
77 register struct cmd_syndesc *as;
85 register struct cmd_syndesc *as;
93 register struct cmd_syndesc *as;
96 struct sourcestack *sp;
99 if (!as->parms[0].items) {
100 /* can this happen? */
103 fd = fopen(as->parms[0].items->data, "r");
105 perror(as->parms[0].items->data);
108 sp = (struct sourcestack *)malloc(sizeof *sp);
110 return errno ? errno : ENOMEM;
122 register struct cmd_syndesc *as;
125 if (!as->parms[0].items) {
126 /* can this happen? */
129 delay = atoi(as->parms[0].items->data);
136 register struct sourcestack *sp;
147 #endif /* SUPERGROUPS */
152 /* OK, this REALLY sucks bigtime, but I can't tell who is calling
153 * afsconf_CheckAuth easily, and only *SERVERS* should be calling osi_audit
154 * anyway. It's gonna give somebody fits to debug, I know, I know.
161 register struct cmd_syndesc *as;
163 register afs_int32 code;
169 if (!strcmp(as->name, "help"))
171 if (as->parms[16].items)
172 cell = as->parms[16].items->data;
175 if (as->parms[17].items)
178 if (as->parms[18].items) { /* testing? */
179 code = pr_Initialize(sec, AFSDIR_SERVER_ETC_DIRPATH, cell);
181 code = pr_Initialize(sec, AFSDIR_CLIENT_ETC_DIRPATH, cell);
184 com_err(whoami, code, "while initializing");
187 if (as->parms[19].items)
194 register struct cmd_syndesc *as;
196 #if defined(SUPERGROUPS)
197 if (as && !strcmp(as->name, "help"))
200 /* Need to shutdown the ubik_client & other connections */
205 if (!strcmp(as->name, "help"))
207 /* Need to shutdown the ubik_client & other connections */
210 #endif /* SUPERGROUPS */
216 register struct cmd_syndesc *as;
218 register afs_int32 code;
221 struct cmd_item *namei;
222 struct cmd_item *idi;
224 namei = as->parms[0].items;
225 idi = as->parms[2].items;
226 if (as->parms[1].items)
227 owner = as->parms[1].items->data;
233 code = util_GetInt32(idi->data, &id);
235 com_err(whoami, code, "because group id was: '%s'",
241 com_err(whoami, code, "because group id %d was not negative",
245 #if defined(SUPERGROUPS)
247 printf("0 isn't a valid user id; aborting\n");
255 code = pr_CreateGroup(namei->data, owner, &id);
258 com_err(whoami, code,
259 "; unable to create group %s with id %d%s%s%s%s",
260 namei->data, id, owner ? " owned by '" : "",
261 owner ? owner : "", owner ? "'" : "",
262 (force ? " (ignored)" : ""));
264 com_err(whoami, code, "; unable to create group %s %s",
265 namei->data, (force ? "(ignored)" : ""));
269 printf("group %s has id %d\n", namei->data, id);
276 register struct cmd_syndesc *as;
278 register afs_int32 code;
280 struct cmd_item *namei;
281 struct cmd_item *idi;
283 namei = as->parms[0].items;
284 idi = as->parms[1].items;
288 code = util_GetInt32(idi->data, &id);
290 com_err(whoami, code, "because id was: '%s'", idi->data);
294 printf("0 isn't a valid user id; aborting\n");
301 code = pr_CreateUser(namei->data, &id);
304 com_err(whoami, code,
305 "; unable to create user %s with id %d %s",
306 namei->data, id, (force ? "(ignored)" : ""));
308 com_err(whoami, code, "; unable to create user %s %s",
309 namei->data, (force ? "(ignored)" : ""));
313 printf("User %s has id %d\n", namei->data, id);
322 GetNameOrId(as, lids, lnames)
323 register struct cmd_syndesc *as;
325 struct namelist *lnames;
327 register afs_int32 code = 0;
332 if (!(as->parms[0].items || as->parms[1].items)) {
333 com_err(whoami, 0, "must specify either a name or an id.");
336 if (as->parms[0].items && as->parms[1].items) {
337 com_err(whoami, 0, "can't specify both a name and id.");
342 lids->idlist_len = 0;
343 lids->idlist_val = 0;
345 if (as->parms[0].items) { /* name */
346 struct namelist names; /* local copy, if not ret. names */
349 names.namelist_val = 0; /* so it gets freed later if needed */
355 n = 0; /* count names */
356 for (i = as->parms[0].items; i; i = i->next)
358 nl->namelist_val = (prname *) malloc(n * PR_MAXNAMELEN);
359 nl->namelist_len = n;
361 for (i = as->parms[0].items; i; i = i->next)
362 strncpy(nl->namelist_val[n++], i->data, PR_MAXNAMELEN);
364 code = pr_NameToId(nl, lids);
366 com_err(whoami, code, "so couldn't look up names");
368 for (n = 0; n < lids->idlist_len; n++) {
369 if ((lids->idlist_val[n] == ANONYMOUSID)) {
370 com_err(whoami, PRNOENT, "so couldn't look up id for %s",
371 nl->namelist_val[n]);
375 /* treat things as working if any of the lookups worked */
380 if (names.namelist_val)
381 free(names.namelist_val);
382 } else if (as->parms[1].items) { /* id */
384 for (i = as->parms[1].items; i; i = i->next)
386 lids->idlist_val = (afs_int32 *) malloc(n * sizeof(afs_int32));
387 lids->idlist_len = n;
389 for (i = as->parms[1].items; i; i = i->next) {
390 code = util_GetInt32(i->data, &lids->idlist_val[n]);
392 com_err(whoami, code =
393 PRNOENT, "because a bogus id '%s' was specified",
397 if (!code && lnames) {
398 lnames->namelist_val = 0;
399 lnames->namelist_len = 0;
400 code = pr_IdToName(lids, lnames);
402 com_err(whoami, code, "translating ids");
406 if (lids->idlist_val)
407 free(lids->idlist_val);
416 GetNameOrId(as, lids, lnames)
417 register struct cmd_syndesc *as;
419 struct namelist *lnames;
421 register afs_int32 code = 0;
422 int n = 0, nd = 0, nm = 0, id, x;
424 struct namelist names, tnames; /* local copy, if not ret. names */
425 struct idlist ids, tids; /* local copy, if not ret. ids */
428 for (i = as->parms[0].items; i; i = i->next)
430 lids->idlist_val = (afs_int32 *) malloc(n * sizeof(afs_int32));
431 lids->idlist_len = n;
432 ids.idlist_val = (afs_int32 *) malloc(n * sizeof(afs_int32));
434 names.namelist_val = (prname *) malloc(n * PR_MAXNAMELEN);
435 names.namelist_len = n;
437 lnames->namelist_val = (prname *) malloc(n * PR_MAXNAMELEN);
438 lnames->namelist_len = 0;
440 for (i = as->parms[0].items; i; i = i->next) {
441 tnames.namelist_val = (prname *) malloc(PR_MAXNAMELEN);
442 strncpy(tnames.namelist_val[0], i->data, PR_MAXNAMELEN);
443 tnames.namelist_len = 1;
446 code = pr_NameToId(&tnames, &tids);
447 if ((!code && (tids.idlist_val[0] != 32766))
448 || (code = util_GetInt32(i->data, &id))) {
449 /* Assume it's a name instead */
450 strncpy(names.namelist_val[nm++], i->data, PR_MAXNAMELEN);
452 ids.idlist_val[nd++] = id;
454 free(tnames.namelist_val);
456 names.namelist_len = nm;
458 tids.idlist_len = nd = nm = 0;
460 code = pr_NameToId(&names, &tids);
462 com_err(whoami, code, "so couldn't look up names");
464 for (n = 0; n < tids.idlist_len; n++) {
465 if ((tids.idlist_val[n] == ANONYMOUSID)) {
466 com_err(whoami, PRNOENT, "so couldn't look up id for %s",
467 names.namelist_val[n]);
470 lids->idlist_val[nd] = tids.idlist_val[n];
472 strcpy(lnames->namelist_val[nd], names.namelist_val[n]);
476 for (x = 0; x < ids.idlist_len; x++) {
477 lids->idlist_val[nd + x] = ids.idlist_val[x];
479 lids->idlist_len = nd + x;
480 if (!code && lnames) {
481 tnames.namelist_val = 0;
482 tnames.namelist_len = 0;
483 code = pr_IdToName(&ids, &tnames);
485 com_err(whoami, code, "translating ids");
489 for (x = 0; x < ids.idlist_len; x++)
490 strcpy(lnames->namelist_val[nd + x], tnames.namelist_val[x]);
491 lnames->namelist_len = nd + x;
494 /* treat things as working if any of the lookups worked */
498 if (lids->idlist_val)
499 free(lids->idlist_val);
507 register struct cmd_syndesc *as;
509 register afs_int32 code;
510 struct cmd_item *u, *g;
512 for (u = as->parms[0].items; u; u = u->next) {
513 for (g = as->parms[1].items; g; g = g->next) {
514 code = pr_AddToGroup(u->data, g->data);
516 com_err(whoami, code,
517 "; unable to add user %s to group %s %s", u->data,
518 g->data, (force ? "(ignored)" : ""));
528 register struct cmd_syndesc *as;
530 register afs_int32 code;
531 struct cmd_item *u, *g;
533 for (u = as->parms[0].items; u; u = u->next) {
534 for (g = as->parms[1].items; g; g = g->next) {
535 code = pr_RemoveUserFromGroup(u->data, g->data);
537 com_err(whoami, code,
538 "; unable to remove user %s from group %s %s",
539 u->data, g->data, (force ? "(ignored)" : ""));
549 register struct cmd_syndesc *as;
551 register afs_int32 code;
558 if (GetNameOrId(as, &ids, &names))
561 for (i = 0; i < ids.idlist_len; i++) {
562 afs_int32 id = ids.idlist_val[i];
563 char *name = names.namelist_val[i];
565 if (id == ANONYMOUSID)
566 continue; /* bad entry */
568 list.namelist_val = 0;
569 list.namelist_len = 0;
570 code = pr_IDListMembers(ids.idlist_val[i], &list);
572 com_err(whoami, code, "; unable to get membership of %s (id: %d)",
577 printf("Members of %s (id: %d) are:\n", name, id);
579 printf("Groups %s (id: %d) is a member of:\n", name, id);
581 for (j = 0; j < list.namelist_len; j++)
582 printf(" %s\n", list.namelist_val[j]);
583 if (list.namelist_val)
584 free(list.namelist_val);
587 free(ids.idlist_val);
588 if (names.namelist_val)
589 free(names.namelist_val);
594 register struct cmd_syndesc *as;
596 register afs_int32 code;
601 if (GetNameOrId(as, &ids, &names))
604 for (i = 0; i < ids.idlist_len; i++) {
605 afs_int32 id = ids.idlist_val[i];
606 char *name = names.namelist_val[i];
608 if (id == ANONYMOUSID)
611 code = pr_DeleteByID(id);
613 com_err(whoami, code, "deleting %s (id: %d) %s", name, id,
614 (force ? "(ignored)" : ""));
620 free(ids.idlist_val);
621 if (names.namelist_val)
622 free(names.namelist_val);
626 /* access bit translation info */
628 char *flags_upcase = "SOMA "; /* legal all access values */
629 char *flags_dncase = "s mar"; /* legal member acces values */
630 int flags_shift[5] = { 2, 1, 2, 2, 1 }; /* bits for each */
633 register struct cmd_syndesc *as;
635 register afs_int32 code;
637 int i, flag = 0, admin = 0;
638 namelist lnames, names;
641 struct prcheckentry aentry;
643 if (GetNameOrId(as, &ids, &names))
647 lids.idlist_val = (afs_int32 *) malloc(sizeof(afs_int32) * 2);
648 lnames.namelist_len = 0;
649 lnames.namelist_val = 0;
651 for (i = 0; i < ids.idlist_len; i++) {
652 afs_int32 id = ids.idlist_val[i];
654 if (id == ANONYMOUSID)
658 code = pr_ListEntry(id, &aentry);
661 com_err(whoami, code, "; unable to find entry for (id: %d)", id);
665 lids.idlist_val[0] = aentry.owner;
666 lids.idlist_val[1] = aentry.creator;
667 code = pr_IdToName(&lids, &lnames);
670 com_err(whoami, code,
671 "translating owner (%d) and creator (%d) ids",
672 aentry.owner, aentry.creator);
675 printf("Name: %s, id: %d, owner: %s, creator: %s,\n", aentry.name,
676 aentry.id, lnames.namelist_val[0], lnames.namelist_val[1]);
677 printf(" membership: %d", aentry.count);
680 afs_int32 flags = aentry.flags;
683 access[5] = 0; /* null-terminate the string */
684 for (j = 4; j >= 0; j--) {
703 printf(", flags: %s", access);
705 if (aentry.id == SYSADMINID)
707 else if (!pr_IsAMemberOf(aentry.name, "system:administrators", &flag)) {
712 printf(", group quota: unlimited");
714 printf(", group quota: %d", aentry.ngroups);
716 printf(", foreign user quota=%d", aentry.nusers);
721 if (lnames.namelist_val)
722 free(lnames.namelist_val);
724 free(lids.idlist_val);
726 free(ids.idlist_val);
732 struct cmd_syndesc *as;
735 afs_int32 flag, startindex, nentries, nextstartindex;
736 struct prlistentries *entriesp = 0, *e;
740 if (as->parms[1].items)
742 if (as->parms[0].items)
745 printf("Name ID Owner Creator\n");
746 for (startindex = 0; startindex != -1; startindex = nextstartindex) {
748 pr_ListEntries(flag, startindex, &nentries, &entriesp,
751 com_err(whoami, code, "; unable to list entries\n");
757 /* Now display each of the entries we read */
758 for (i = 0, e = entriesp; i < nentries; i++, e++) {
759 printf("%-25s %6d %6d %7d \n", e->name, e->id, e->owner,
769 register struct cmd_syndesc *as;
771 register afs_int32 code;
775 name = as->parms[0].items->data;
776 owner = as->parms[1].items->data;
777 code = pr_ChangeEntry(name, "", 0, owner);
779 com_err(whoami, code, "; unable to change owner of %s to %s", name,
785 register struct cmd_syndesc *as;
787 register afs_int32 code;
791 oldname = as->parms[0].items->data;
792 newname = as->parms[1].items->data;
793 code = pr_ChangeEntry(oldname, newname, 0, "");
795 com_err(whoami, code, "; unable to change name of %s to %s", oldname,
801 register struct cmd_syndesc *as;
803 register afs_int32 code;
804 afs_int32 maxUser, maxGroup;
806 code = pr_ListMaxUserId(&maxUser);
808 com_err(whoami, code, "getting maximum user id");
810 code = pr_ListMaxGroupId(&maxGroup);
812 com_err(whoami, code, "getting maximum group id");
814 printf("Max user id is %d and max group id is %d.\n", maxUser,
822 register struct cmd_syndesc *as;
824 register afs_int32 code;
828 if (as->parms[1].items) {
830 code = util_GetInt32(as->parms[1].items->data, &maxid);
832 com_err(whoami, code, "because id was: '%s'",
833 as->parms[1].items->data);
835 code = pr_SetMaxUserId(maxid);
837 com_err(whoami, code, "so couldn't set Max User Id to %d",
841 if (as->parms[0].items) {
843 code = util_GetInt32(as->parms[0].items->data, &maxid);
845 com_err(whoami, code, "because id was: '%s'",
846 as->parms[0].items->data);
848 code = pr_SetMaxGroupId(maxid);
850 com_err(whoami, code, "so couldn't set Max Group Id to %d",
854 if (!as->parms[0].items && !as->parms[1].items) {
856 printf("Must specify at least one of group or user.\n");
862 register struct cmd_syndesc *as;
864 register afs_int32 code;
868 afs_int32 mask, flags, ngroups, nusers;
870 if (GetNameOrId(as, &ids, &names))
877 if (as->parms[1].items) { /* privacy bits */
878 char *access = as->parms[1].items->data;
881 if (strpbrk(access, "76543210") != 0) { /* all octal digits */
882 sscanf(access, "%lo", &flags);
883 } else { /* interpret flag bit names */
884 if (strlen(access) != 5) {
886 printf("Access bits must be of the form 'somar', not %s\n",
890 if (strpbrk(access, "somar-") == 0)
893 for (i = 0; i < 5; i++) {
894 if (access[i] == flags_upcase[i])
896 else if (access[i] == flags_dncase[i])
898 else if (access[i] == '-')
902 ("Access bits out of order or illegal:\n must be a combination of letters from '%s' or '%s' or hyphen, not %s\n",
903 flags_upcase, flags_dncase, access);
906 flags <<= flags_shift[i];
907 if (flags_shift[i] == 1) {
914 mask |= PR_SF_ALLBITS;
916 if (as->parms[2].items) { /* limitgroups */
917 code = util_GetInt32(as->parms[2].items->data, &ngroups);
919 com_err(whoami, code, "because ngroups was: '%s'",
920 as->parms[2].items->data);
923 mask |= PR_SF_NGROUPS;
926 if (as->parms[3].items) { /* limitgroups */
927 code = util_GetInt32(as->parms[3].items->data, &nusers);
929 com_err(whoami, code, "because nusers was: '%s'",
930 as->parms[3].items->data);
933 mask |= PR_SF_NUSERS;
937 for (i = 0; i < ids.idlist_len; i++) {
938 afs_int32 id = ids.idlist_val[i];
939 char *name = names.namelist_val[i];
940 if (id == ANONYMOUSID)
942 code = pr_SetFieldsEntry(id, mask, flags, ngroups, nusers);
944 com_err(whoami, code, "; unable to set fields for %s (id: %d)",
950 free(ids.idlist_val);
951 if (names.namelist_val)
952 free(names.namelist_val);
957 register struct cmd_syndesc *as;
959 register afs_int32 code;
966 if (GetNameOrId(as, &ids, &names))
969 for (i = 0; i < ids.idlist_len; i++) {
970 afs_int32 oid = ids.idlist_val[i];
971 char *name = names.namelist_val[i];
973 if (oid == ANONYMOUSID)
977 printf("Groups owned by %s (id: %d) are:\n", name, oid);
979 printf("Orphaned groups are:\n");
982 list.namelist_val = 0;
983 list.namelist_len = 0;
984 code = pr_ListOwned(oid, &list, &more);
986 com_err(whoami, code,
987 "; unable to get owner list for %s (id: %d)", name,
992 for (j = 0; j < list.namelist_len; j++)
993 printf(" %s\n", list.namelist_val[j]);
994 if (list.namelist_val)
995 free(list.namelist_val);
1000 free(ids.idlist_val);
1001 if (names.namelist_val)
1002 free(names.namelist_val);
1008 register struct cmd_syndesc *ts;
1010 char test_help[AFSDIR_PATH_MAX];
1012 sprintf(test_help, "use config file in %s", AFSDIR_SERVER_ETC_DIRPATH);
1015 cmd_AddParm(ts, "-cell", CMD_SINGLE, CMD_OPTIONAL, "cell name");
1016 cmd_AddParm(ts, "-noauth", CMD_FLAG, CMD_OPTIONAL, "run unauthenticated");
1017 cmd_AddParm(ts, "-test", CMD_FLAG, CMD_OPTIONAL | CMD_HIDE, test_help);
1018 cmd_AddParm(ts, "-force", CMD_FLAG, CMD_OPTIONAL,
1019 "Continue oper despite reasonable errors");
1023 static void add_NameOrId_args (ts)
1024 register struct cmd_syndesc *ts;
1026 cmd_AddParm(ts,"-name",CMD_LIST,CMD_OPTIONAL,"user or group name");
1027 cmd_AddParm(ts,"-id",CMD_LIST,CMD_OPTIONAL,"user or group id");
1031 #include "AFS_component_version_number.c"
1038 register afs_int32 code;
1039 register struct cmd_syndesc *ts;
1040 #if defined(SUPERGROUPS)
1044 char *parsev[CMD_MAXPARMS];
1052 WSAStartup(0x0101, &WSAjunk);
1055 #ifdef AFS_AIX32_ENV
1057 * The following signal action for AIX is necessary so that in case of a
1058 * crash (i.e. core is generated) we can include the user's data section
1059 * in the core dump. Unfortunately, by default, only a partial core is
1060 * generated which, in many cases, isn't too useful.
1062 struct sigaction nsa;
1064 sigemptyset(&nsa.sa_mask);
1065 nsa.sa_handler = SIG_DFL;
1066 nsa.sa_flags = SA_FULLDUMP;
1067 sigaction(SIGSEGV, &nsa, NULL);
1070 ts = cmd_CreateSyntax("creategroup", CreateGroup, 0,
1071 "create a new group");
1072 cmd_AddParm(ts, "-name", CMD_LIST, 0, "group name");
1073 cmd_AddParm(ts, "-owner", CMD_SINGLE, CMD_OPTIONAL, "owner of the group");
1074 cmd_AddParm(ts, "-id", CMD_LIST, CMD_OPTIONAL,
1075 "id (negated) for the group");
1077 cmd_CreateAlias(ts, "cg");
1079 ts = cmd_CreateSyntax("createuser", CreateUser, 0, "create a new user");
1080 cmd_AddParm(ts, "-name", CMD_LIST, 0, "user name");
1081 cmd_AddParm(ts, "-id", CMD_LIST, CMD_OPTIONAL, "user id");
1083 cmd_CreateAlias(ts, "cu");
1085 ts = cmd_CreateSyntax("adduser", AddToGroup, 0, "add a user to a group");
1086 cmd_AddParm(ts, "-user", CMD_LIST, 0, "user name");
1087 cmd_AddParm(ts, "-group", CMD_LIST, 0, "group name");
1090 ts = cmd_CreateSyntax("removeuser", RemoveFromGroup, 0,
1091 "remove a user from a group");
1092 cmd_AddParm(ts, "-user", CMD_LIST, 0, "user name");
1093 cmd_AddParm(ts, "-group", CMD_LIST, 0, "group name");
1096 ts = cmd_CreateSyntax("membership", ListMembership, 0,
1097 "list membership of a user or group");
1098 cmd_AddParm(ts, "-nameorid", CMD_LIST, 0, "user or group name or id");
1100 cmd_CreateAlias(ts, "groups");
1102 ts = cmd_CreateSyntax("delete", Delete, 0,
1103 "delete a user or group from database");
1104 cmd_AddParm(ts, "-nameorid", CMD_LIST, 0, "user or group name or id");
1107 ts = cmd_CreateSyntax("examine", CheckEntry, 0, "examine an entry");
1108 cmd_AddParm(ts, "-nameorid", CMD_LIST, 0, "user or group name or id");
1110 cmd_CreateAlias(ts, "check");
1112 ts = cmd_CreateSyntax("chown", ChownGroup, 0,
1113 "change ownership of a group");
1114 cmd_AddParm(ts, "-name", CMD_SINGLE, 0, "group name");
1115 cmd_AddParm(ts, "-owner", CMD_SINGLE, 0, "new owner");
1118 ts = cmd_CreateSyntax("rename", ChangeName, 0, "rename user or group");
1119 cmd_AddParm(ts, "-oldname", CMD_SINGLE, 0, "old name");
1120 cmd_AddParm(ts, "-newname", CMD_SINGLE, 0, "new name");
1122 cmd_CreateAlias(ts, "chname");
1124 ts = cmd_CreateSyntax("listmax", ListMax, 0, "list max id");
1127 ts = cmd_CreateSyntax("setmax", SetMax, 0, "set max id");
1128 cmd_AddParm(ts, "-group", CMD_SINGLE, CMD_OPTIONAL, "group max");
1129 cmd_AddParm(ts, "-user", CMD_SINGLE, CMD_OPTIONAL, "user max");
1132 ts = cmd_CreateSyntax("setfields", SetFields, 0,
1133 "set fields for an entry");
1134 cmd_AddParm(ts, "-nameorid", CMD_LIST, 0, "user or group name or id");
1135 cmd_AddParm(ts, "-access", CMD_SINGLE, CMD_OPTIONAL, "set privacy flags");
1136 cmd_AddParm(ts, "-groupquota", CMD_SINGLE, CMD_OPTIONAL,
1137 "set limit on group creation");
1139 cmd_AddParm(ts, "-userquota", CMD_SINGLE, CMD_OPTIONAL,
1140 "set limit on foreign user creation");
1144 ts = cmd_CreateSyntax("listowned", ListOwned, 0,
1145 "list groups owned by an entry or zero id gets orphaned groups");
1146 cmd_AddParm(ts, "-nameorid", CMD_LIST, 0, "user or group name or id");
1149 ts = cmd_CreateSyntax("listentries", ListEntries, 0,
1150 "list users/groups in the protection database");
1151 cmd_AddParm(ts, "-users", CMD_FLAG, CMD_OPTIONAL, "list user entries");
1152 cmd_AddParm(ts, "-groups", CMD_FLAG, CMD_OPTIONAL, "list group entries");
1155 #if defined(SUPERGROUPS)
1157 ts = cmd_CreateSyntax("interactive", Interactive, 0,
1158 "enter interactive mode");
1160 cmd_CreateAlias(ts, "in");
1162 ts = cmd_CreateSyntax("quit", Quit, 0, "exit program");
1165 ts = cmd_CreateSyntax("source", Source, 0, "read commands from file");
1166 cmd_AddParm(ts, "-file", CMD_SINGLE, 0, "filename");
1169 ts = cmd_CreateSyntax("sleep", Sleep, 0, "pause for a bit");
1170 cmd_AddParm(ts, "-delay", CMD_SINGLE, 0, "seconds");
1173 #endif /* SUPERGROUPS */
1175 cmd_SetBeforeProc(GetGlobals, 0);
1177 #if defined(SUPERGROUPS)
1179 if (code = cmd_Dispatch(argc, argv)) {
1185 if (isatty(fileno(source)))
1186 fprintf(stderr, "pts> ");
1187 if (!fgets(line, sizeof line, source)) {
1193 for (cp = line; *cp; ++cp)
1203 cmd_ParseLine(line, parsev, &parsec,
1204 sizeof(parsev) / sizeof(*parsev));
1206 com_err(whoami, code, "parsing line: <%s>", line);
1210 parsev[0] = argv[0];
1211 code = cmd_Dispatch(parsec, parsev);
1213 cmd_FreeArgv(parsev);
1218 #else /* SUPERGROUPS */
1220 cmd_SetAfterProc(CleanUp, 0);
1221 code = cmd_Dispatch(argc, argv);
1223 #endif /* SUPERGROUPS */