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;
76 Interactive(register struct cmd_syndesc *as)
83 Quit(register struct cmd_syndesc *as)
90 Source(register struct cmd_syndesc *as)
93 struct sourcestack *sp;
96 if (!as->parms[0].items) {
97 /* can this happen? */
100 fd = fopen(as->parms[0].items->data, "r");
102 perror(as->parms[0].items->data);
105 sp = (struct sourcestack *)malloc(sizeof *sp);
107 return errno ? errno : ENOMEM;
118 Sleep(register struct cmd_syndesc *as)
121 if (!as->parms[0].items) {
122 /* can this happen? */
125 delay = atoi(as->parms[0].items->data);
132 register struct sourcestack *sp;
143 #endif /* SUPERGROUPS */
148 /* OK, this REALLY sucks bigtime, but I can't tell who is calling
149 * afsconf_CheckAuth easily, and only *SERVERS* should be calling osi_audit
150 * anyway. It's gonna give somebody fits to debug, I know, I know.
156 GetGlobals(register struct cmd_syndesc *as)
158 register afs_int32 code;
164 if (!strcmp(as->name, "help"))
166 if (as->parms[16].items)
167 cell = as->parms[16].items->data;
170 if (as->parms[17].items)
173 if (as->parms[18].items) { /* testing? */
174 code = pr_Initialize(sec, AFSDIR_SERVER_ETC_DIRPATH, cell);
176 code = pr_Initialize(sec, AFSDIR_CLIENT_ETC_DIRPATH, cell);
179 com_err(whoami, code, "while initializing");
182 if (as->parms[19].items)
188 CleanUp(register struct cmd_syndesc *as)
190 #if defined(SUPERGROUPS)
191 if (as && !strcmp(as->name, "help"))
194 /* Need to shutdown the ubik_client & other connections */
199 if (!strcmp(as->name, "help"))
201 /* Need to shutdown the ubik_client & other connections */
204 #endif /* SUPERGROUPS */
210 CreateGroup(register struct cmd_syndesc *as)
212 register afs_int32 code;
215 struct cmd_item *namei;
216 struct cmd_item *idi;
218 namei = as->parms[0].items;
219 idi = as->parms[2].items;
220 if (as->parms[1].items)
221 owner = as->parms[1].items->data;
227 code = util_GetInt32(idi->data, &id);
229 com_err(whoami, code, "because group id was: '%s'",
235 com_err(whoami, code, "because group id %d was not negative",
239 #if defined(SUPERGROUPS)
241 printf("0 isn't a valid user id; aborting\n");
249 code = pr_CreateGroup(namei->data, owner, &id);
252 com_err(whoami, code,
253 "; unable to create group %s with id %d%s%s%s%s",
254 namei->data, id, owner ? " owned by '" : "",
255 owner ? owner : "", owner ? "'" : "",
256 (force ? " (ignored)" : ""));
258 com_err(whoami, code, "; unable to create group %s %s",
259 namei->data, (force ? "(ignored)" : ""));
263 printf("group %s has id %d\n", namei->data, id);
270 CreateUser(register struct cmd_syndesc *as)
272 register afs_int32 code;
274 struct cmd_item *namei;
275 struct cmd_item *idi;
277 namei = as->parms[0].items;
278 idi = as->parms[1].items;
282 code = util_GetInt32(idi->data, &id);
284 com_err(whoami, code, "because id was: '%s'", idi->data);
288 printf("0 isn't a valid user id; aborting\n");
295 code = pr_CreateUser(namei->data, &id);
298 com_err(whoami, code,
299 "; unable to create user %s with id %d %s",
300 namei->data, id, (force ? "(ignored)" : ""));
302 com_err(whoami, code, "; unable to create user %s %s",
303 namei->data, (force ? "(ignored)" : ""));
307 printf("User %s has id %d\n", namei->data, id);
316 GetNameOrId(register struct cmd_syndesc *as, struct idlist *lids, struct namelist *lnames)
318 register afs_int32 code = 0;
323 if (!(as->parms[0].items || as->parms[1].items)) {
324 com_err(whoami, 0, "must specify either a name or an id.");
327 if (as->parms[0].items && as->parms[1].items) {
328 com_err(whoami, 0, "can't specify both a name and id.");
333 lids->idlist_len = 0;
334 lids->idlist_val = 0;
336 if (as->parms[0].items) { /* name */
337 struct namelist names; /* local copy, if not ret. names */
340 names.namelist_val = 0; /* so it gets freed later if needed */
346 n = 0; /* count names */
347 for (i = as->parms[0].items; i; i = i->next)
349 nl->namelist_val = (prname *) malloc(n * PR_MAXNAMELEN);
350 nl->namelist_len = n;
352 for (i = as->parms[0].items; i; i = i->next)
353 strncpy(nl->namelist_val[n++], i->data, PR_MAXNAMELEN);
355 code = pr_NameToId(nl, lids);
357 com_err(whoami, code, "so couldn't look up names");
359 for (n = 0; n < lids->idlist_len; n++) {
360 if ((lids->idlist_val[n] == ANONYMOUSID)) {
361 com_err(whoami, PRNOENT, "so couldn't look up id for %s",
362 nl->namelist_val[n]);
366 /* treat things as working if any of the lookups worked */
371 if (names.namelist_val)
372 free(names.namelist_val);
373 } else if (as->parms[1].items) { /* id */
375 for (i = as->parms[1].items; i; i = i->next)
377 lids->idlist_val = (afs_int32 *) malloc(n * sizeof(afs_int32));
378 lids->idlist_len = n;
380 for (i = as->parms[1].items; i; i = i->next) {
381 code = util_GetInt32(i->data, &lids->idlist_val[n]);
383 com_err(whoami, code =
384 PRNOENT, "because a bogus id '%s' was specified",
388 if (!code && lnames) {
389 lnames->namelist_val = 0;
390 lnames->namelist_len = 0;
391 code = pr_IdToName(lids, lnames);
393 com_err(whoami, code, "translating ids");
397 if (lids->idlist_val)
398 free(lids->idlist_val);
407 GetNameOrId(register struct cmd_syndesc *as, struct idlist *lids, struct namelist *lnames)
409 register afs_int32 code = 0;
410 int n = 0, nd = 0, nm = 0, id, x;
412 struct namelist names, tnames; /* local copy, if not ret. names */
413 struct idlist ids, tids; /* local copy, if not ret. ids */
416 for (i = as->parms[0].items; i; i = i->next)
418 lids->idlist_val = (afs_int32 *) malloc(n * sizeof(afs_int32));
419 lids->idlist_len = n;
420 ids.idlist_val = (afs_int32 *) malloc(n * sizeof(afs_int32));
422 names.namelist_val = (prname *) malloc(n * PR_MAXNAMELEN);
423 names.namelist_len = n;
425 lnames->namelist_val = (prname *) malloc(n * PR_MAXNAMELEN);
426 lnames->namelist_len = 0;
428 for (i = as->parms[0].items; i; i = i->next) {
429 tnames.namelist_val = (prname *) malloc(PR_MAXNAMELEN);
430 strncpy(tnames.namelist_val[0], i->data, PR_MAXNAMELEN);
431 tnames.namelist_len = 1;
434 code = pr_NameToId(&tnames, &tids);
435 if ((!code && (tids.idlist_val[0] != 32766))
436 || (code = util_GetInt32(i->data, &id))) {
437 /* Assume it's a name instead */
438 strncpy(names.namelist_val[nm++], i->data, PR_MAXNAMELEN);
440 ids.idlist_val[nd++] = id;
442 free(tnames.namelist_val);
444 names.namelist_len = nm;
446 tids.idlist_len = nd = nm = 0;
448 code = pr_NameToId(&names, &tids);
450 com_err(whoami, code, "so couldn't look up names");
452 for (n = 0; n < tids.idlist_len; n++) {
453 if ((tids.idlist_val[n] == ANONYMOUSID)) {
454 com_err(whoami, PRNOENT, "so couldn't look up id for %s",
455 names.namelist_val[n]);
458 lids->idlist_val[nd] = tids.idlist_val[n];
460 strcpy(lnames->namelist_val[nd], names.namelist_val[n]);
464 for (x = 0; x < ids.idlist_len; x++) {
465 lids->idlist_val[nd + x] = ids.idlist_val[x];
467 lids->idlist_len = nd + x;
468 if (!code && lnames) {
469 tnames.namelist_val = 0;
470 tnames.namelist_len = 0;
471 code = pr_IdToName(&ids, &tnames);
473 com_err(whoami, code, "translating ids");
477 for (x = 0; x < ids.idlist_len; x++)
478 strcpy(lnames->namelist_val[nd + x], tnames.namelist_val[x]);
479 lnames->namelist_len = nd + x;
482 /* treat things as working if any of the lookups worked */
486 if (lids->idlist_val)
487 free(lids->idlist_val);
495 AddToGroup(register struct cmd_syndesc *as)
497 register afs_int32 code;
498 struct cmd_item *u, *g;
500 for (u = as->parms[0].items; u; u = u->next) {
501 for (g = as->parms[1].items; g; g = g->next) {
502 code = pr_AddToGroup(u->data, g->data);
504 com_err(whoami, code,
505 "; unable to add user %s to group %s %s", u->data,
506 g->data, (force ? "(ignored)" : ""));
516 RemoveFromGroup(register struct cmd_syndesc *as)
518 register afs_int32 code;
519 struct cmd_item *u, *g;
521 for (u = as->parms[0].items; u; u = u->next) {
522 for (g = as->parms[1].items; g; g = g->next) {
523 code = pr_RemoveUserFromGroup(u->data, g->data);
525 com_err(whoami, code,
526 "; unable to remove user %s from group %s %s",
527 u->data, g->data, (force ? "(ignored)" : ""));
537 ListMembership(register struct cmd_syndesc *as)
539 register afs_int32 code;
546 if (GetNameOrId(as, &ids, &names))
549 for (i = 0; i < ids.idlist_len; i++) {
550 afs_int32 id = ids.idlist_val[i];
551 char *name = names.namelist_val[i];
553 if (id == ANONYMOUSID)
554 continue; /* bad entry */
556 list.namelist_val = 0;
557 list.namelist_len = 0;
558 code = pr_IDListMembers(ids.idlist_val[i], &list);
560 com_err(whoami, code, "; unable to get membership of %s (id: %d)",
565 printf("Members of %s (id: %d) are:\n", name, id);
567 printf("Groups %s (id: %d) is a member of:\n", name, id);
569 for (j = 0; j < list.namelist_len; j++)
570 printf(" %s\n", list.namelist_val[j]);
571 if (list.namelist_val)
572 free(list.namelist_val);
575 free(ids.idlist_val);
576 if (names.namelist_val)
577 free(names.namelist_val);
582 Delete(register struct cmd_syndesc *as)
584 register afs_int32 code;
589 if (GetNameOrId(as, &ids, &names))
592 for (i = 0; i < ids.idlist_len; i++) {
593 afs_int32 id = ids.idlist_val[i];
594 char *name = names.namelist_val[i];
596 if (id == ANONYMOUSID)
599 code = pr_DeleteByID(id);
601 com_err(whoami, code, "deleting %s (id: %d) %s", name, id,
602 (force ? "(ignored)" : ""));
608 free(ids.idlist_val);
609 if (names.namelist_val)
610 free(names.namelist_val);
614 /* access bit translation info */
616 char *flags_upcase = "SOMA "; /* legal all access values */
617 char *flags_dncase = "s mar"; /* legal member acces values */
618 int flags_shift[5] = { 2, 1, 2, 2, 1 }; /* bits for each */
621 CheckEntry(register struct cmd_syndesc *as)
623 register afs_int32 code;
625 int i, flag = 0, admin = 0;
626 namelist lnames, names;
629 struct prcheckentry aentry;
631 if (GetNameOrId(as, &ids, &names))
635 lids.idlist_val = (afs_int32 *) malloc(sizeof(afs_int32) * 2);
636 lnames.namelist_len = 0;
637 lnames.namelist_val = 0;
639 for (i = 0; i < ids.idlist_len; i++) {
640 afs_int32 id = ids.idlist_val[i];
642 if (id == ANONYMOUSID)
646 code = pr_ListEntry(id, &aentry);
649 com_err(whoami, code, "; unable to find entry for (id: %d)", id);
653 lids.idlist_val[0] = aentry.owner;
654 lids.idlist_val[1] = aentry.creator;
655 code = pr_IdToName(&lids, &lnames);
658 com_err(whoami, code,
659 "translating owner (%d) and creator (%d) ids",
660 aentry.owner, aentry.creator);
663 printf("Name: %s, id: %d, owner: %s, creator: %s,\n", aentry.name,
664 aentry.id, lnames.namelist_val[0], lnames.namelist_val[1]);
665 printf(" membership: %d", aentry.count);
668 afs_int32 flags = aentry.flags;
671 access[5] = 0; /* null-terminate the string */
672 for (j = 4; j >= 0; j--) {
691 printf(", flags: %s", access);
693 if (aentry.id == SYSADMINID)
695 else if (!pr_IsAMemberOf(aentry.name, "system:administrators", &flag)) {
700 printf(", group quota: unlimited");
702 printf(", group quota: %d", aentry.ngroups);
704 printf(", foreign user quota=%d", aentry.nusers);
709 if (lnames.namelist_val)
710 free(lnames.namelist_val);
712 free(lids.idlist_val);
714 free(ids.idlist_val);
720 ListEntries(struct cmd_syndesc *as)
723 afs_int32 flag, startindex, nentries, nextstartindex;
724 struct prlistentries *entriesp = 0, *e;
728 if (as->parms[1].items)
730 if (as->parms[0].items)
733 printf("Name ID Owner Creator\n");
734 for (startindex = 0; startindex != -1; startindex = nextstartindex) {
736 pr_ListEntries(flag, startindex, &nentries, &entriesp,
739 com_err(whoami, code, "; unable to list entries\n");
745 /* Now display each of the entries we read */
746 for (i = 0, e = entriesp; i < nentries; i++, e++) {
747 printf("%-25s %6d %6d %7d \n", e->name, e->id, e->owner,
757 ChownGroup(register struct cmd_syndesc *as)
759 register afs_int32 code;
763 name = as->parms[0].items->data;
764 owner = as->parms[1].items->data;
765 code = pr_ChangeEntry(name, "", 0, owner);
767 com_err(whoami, code, "; unable to change owner of %s to %s", name,
773 ChangeName(register struct cmd_syndesc *as)
775 register afs_int32 code;
779 oldname = as->parms[0].items->data;
780 newname = as->parms[1].items->data;
781 code = pr_ChangeEntry(oldname, newname, 0, "");
783 com_err(whoami, code, "; unable to change name of %s to %s", oldname,
789 ListMax(register struct cmd_syndesc *as)
791 register afs_int32 code;
792 afs_int32 maxUser, maxGroup;
794 code = pr_ListMaxUserId(&maxUser);
796 com_err(whoami, code, "getting maximum user id");
798 code = pr_ListMaxGroupId(&maxGroup);
800 com_err(whoami, code, "getting maximum group id");
802 printf("Max user id is %d and max group id is %d.\n", maxUser,
810 SetMax(register struct cmd_syndesc *as)
812 register afs_int32 code;
816 if (as->parms[1].items) {
818 code = util_GetInt32(as->parms[1].items->data, &maxid);
820 com_err(whoami, code, "because id was: '%s'",
821 as->parms[1].items->data);
823 code = pr_SetMaxUserId(maxid);
825 com_err(whoami, code, "so couldn't set Max User Id to %d",
829 if (as->parms[0].items) {
831 code = util_GetInt32(as->parms[0].items->data, &maxid);
833 com_err(whoami, code, "because id was: '%s'",
834 as->parms[0].items->data);
836 code = pr_SetMaxGroupId(maxid);
838 com_err(whoami, code, "so couldn't set Max Group Id to %d",
842 if (!as->parms[0].items && !as->parms[1].items) {
844 printf("Must specify at least one of group or user.\n");
850 SetFields(register struct cmd_syndesc *as)
852 register afs_int32 code;
856 afs_int32 mask, flags, ngroups, nusers;
858 if (GetNameOrId(as, &ids, &names))
865 if (as->parms[1].items) { /* privacy bits */
866 char *access = as->parms[1].items->data;
869 if (strpbrk(access, "76543210") != 0) { /* all octal digits */
870 sscanf(access, "%lo", &flags);
871 } else { /* interpret flag bit names */
872 if (strlen(access) != 5) {
874 printf("Access bits must be of the form 'somar', not %s\n",
878 if (strpbrk(access, "somar-") == 0)
881 for (i = 0; i < 5; i++) {
882 if (access[i] == flags_upcase[i])
884 else if (access[i] == flags_dncase[i])
886 else if (access[i] == '-')
890 ("Access bits out of order or illegal:\n must be a combination of letters from '%s' or '%s' or hyphen, not %s\n",
891 flags_upcase, flags_dncase, access);
894 flags <<= flags_shift[i];
895 if (flags_shift[i] == 1) {
902 mask |= PR_SF_ALLBITS;
904 if (as->parms[2].items) { /* limitgroups */
905 code = util_GetInt32(as->parms[2].items->data, &ngroups);
907 com_err(whoami, code, "because ngroups was: '%s'",
908 as->parms[2].items->data);
911 mask |= PR_SF_NGROUPS;
914 if (as->parms[3].items) { /* limitgroups */
915 code = util_GetInt32(as->parms[3].items->data, &nusers);
917 com_err(whoami, code, "because nusers was: '%s'",
918 as->parms[3].items->data);
921 mask |= PR_SF_NUSERS;
925 for (i = 0; i < ids.idlist_len; i++) {
926 afs_int32 id = ids.idlist_val[i];
927 char *name = names.namelist_val[i];
928 if (id == ANONYMOUSID)
930 code = pr_SetFieldsEntry(id, mask, flags, ngroups, nusers);
932 com_err(whoami, code, "; unable to set fields for %s (id: %d)",
938 free(ids.idlist_val);
939 if (names.namelist_val)
940 free(names.namelist_val);
945 ListOwned(register struct cmd_syndesc *as)
947 register afs_int32 code;
954 if (GetNameOrId(as, &ids, &names))
957 for (i = 0; i < ids.idlist_len; i++) {
958 afs_int32 oid = ids.idlist_val[i];
959 char *name = names.namelist_val[i];
961 if (oid == ANONYMOUSID)
965 printf("Groups owned by %s (id: %d) are:\n", name, oid);
967 printf("Orphaned groups are:\n");
970 list.namelist_val = 0;
971 list.namelist_len = 0;
972 code = pr_ListOwned(oid, &list, &more);
974 com_err(whoami, code,
975 "; unable to get owner list for %s (id: %d)", name,
980 for (j = 0; j < list.namelist_len; j++)
981 printf(" %s\n", list.namelist_val[j]);
982 if (list.namelist_val)
983 free(list.namelist_val);
988 free(ids.idlist_val);
989 if (names.namelist_val)
990 free(names.namelist_val);
995 add_std_args(register struct cmd_syndesc *ts)
997 char test_help[AFSDIR_PATH_MAX];
999 sprintf(test_help, "use config file in %s", AFSDIR_SERVER_ETC_DIRPATH);
1002 cmd_AddParm(ts, "-cell", CMD_SINGLE, CMD_OPTIONAL, "cell name");
1003 cmd_AddParm(ts, "-noauth", CMD_FLAG, CMD_OPTIONAL, "run unauthenticated");
1004 cmd_AddParm(ts, "-test", CMD_FLAG, CMD_OPTIONAL | CMD_HIDE, test_help);
1005 cmd_AddParm(ts, "-force", CMD_FLAG, CMD_OPTIONAL,
1006 "Continue oper despite reasonable errors");
1010 static void add_NameOrId_args (ts)
1011 register struct cmd_syndesc *ts;
1013 cmd_AddParm(ts,"-name",CMD_LIST,CMD_OPTIONAL,"user or group name");
1014 cmd_AddParm(ts,"-id",CMD_LIST,CMD_OPTIONAL,"user or group id");
1018 #include "AFS_component_version_number.c"
1021 main(int argc, char **argv)
1023 register afs_int32 code;
1024 register struct cmd_syndesc *ts;
1025 #if defined(SUPERGROUPS)
1029 char *parsev[CMD_MAXPARMS];
1037 WSAStartup(0x0101, &WSAjunk);
1040 #ifdef AFS_AIX32_ENV
1042 * The following signal action for AIX is necessary so that in case of a
1043 * crash (i.e. core is generated) we can include the user's data section
1044 * in the core dump. Unfortunately, by default, only a partial core is
1045 * generated which, in many cases, isn't too useful.
1047 struct sigaction nsa;
1049 sigemptyset(&nsa.sa_mask);
1050 nsa.sa_handler = SIG_DFL;
1051 nsa.sa_flags = SA_FULLDUMP;
1052 sigaction(SIGSEGV, &nsa, NULL);
1055 ts = cmd_CreateSyntax("creategroup", CreateGroup, 0,
1056 "create a new group");
1057 cmd_AddParm(ts, "-name", CMD_LIST, 0, "group name");
1058 cmd_AddParm(ts, "-owner", CMD_SINGLE, CMD_OPTIONAL, "owner of the group");
1059 cmd_AddParm(ts, "-id", CMD_LIST, CMD_OPTIONAL,
1060 "id (negated) for the group");
1062 cmd_CreateAlias(ts, "cg");
1064 ts = cmd_CreateSyntax("createuser", CreateUser, 0, "create a new user");
1065 cmd_AddParm(ts, "-name", CMD_LIST, 0, "user name");
1066 cmd_AddParm(ts, "-id", CMD_LIST, CMD_OPTIONAL, "user id");
1068 cmd_CreateAlias(ts, "cu");
1070 ts = cmd_CreateSyntax("adduser", AddToGroup, 0, "add a user to a group");
1071 cmd_AddParm(ts, "-user", CMD_LIST, 0, "user name");
1072 cmd_AddParm(ts, "-group", CMD_LIST, 0, "group name");
1075 ts = cmd_CreateSyntax("removeuser", RemoveFromGroup, 0,
1076 "remove a user from a group");
1077 cmd_AddParm(ts, "-user", CMD_LIST, 0, "user name");
1078 cmd_AddParm(ts, "-group", CMD_LIST, 0, "group name");
1081 ts = cmd_CreateSyntax("membership", ListMembership, 0,
1082 "list membership of a user or group");
1083 cmd_AddParm(ts, "-nameorid", CMD_LIST, 0, "user or group name or id");
1085 cmd_CreateAlias(ts, "groups");
1087 ts = cmd_CreateSyntax("delete", Delete, 0,
1088 "delete a user or group from database");
1089 cmd_AddParm(ts, "-nameorid", CMD_LIST, 0, "user or group name or id");
1092 ts = cmd_CreateSyntax("examine", CheckEntry, 0, "examine an entry");
1093 cmd_AddParm(ts, "-nameorid", CMD_LIST, 0, "user or group name or id");
1095 cmd_CreateAlias(ts, "check");
1097 ts = cmd_CreateSyntax("chown", ChownGroup, 0,
1098 "change ownership of a group");
1099 cmd_AddParm(ts, "-name", CMD_SINGLE, 0, "group name");
1100 cmd_AddParm(ts, "-owner", CMD_SINGLE, 0, "new owner");
1103 ts = cmd_CreateSyntax("rename", ChangeName, 0, "rename user or group");
1104 cmd_AddParm(ts, "-oldname", CMD_SINGLE, 0, "old name");
1105 cmd_AddParm(ts, "-newname", CMD_SINGLE, 0, "new name");
1107 cmd_CreateAlias(ts, "chname");
1109 ts = cmd_CreateSyntax("listmax", ListMax, 0, "list max id");
1112 ts = cmd_CreateSyntax("setmax", SetMax, 0, "set max id");
1113 cmd_AddParm(ts, "-group", CMD_SINGLE, CMD_OPTIONAL, "group max");
1114 cmd_AddParm(ts, "-user", CMD_SINGLE, CMD_OPTIONAL, "user max");
1117 ts = cmd_CreateSyntax("setfields", SetFields, 0,
1118 "set fields for an entry");
1119 cmd_AddParm(ts, "-nameorid", CMD_LIST, 0, "user or group name or id");
1120 cmd_AddParm(ts, "-access", CMD_SINGLE, CMD_OPTIONAL, "set privacy flags");
1121 cmd_AddParm(ts, "-groupquota", CMD_SINGLE, CMD_OPTIONAL,
1122 "set limit on group creation");
1124 cmd_AddParm(ts, "-userquota", CMD_SINGLE, CMD_OPTIONAL,
1125 "set limit on foreign user creation");
1129 ts = cmd_CreateSyntax("listowned", ListOwned, 0,
1130 "list groups owned by an entry or zero id gets orphaned groups");
1131 cmd_AddParm(ts, "-nameorid", CMD_LIST, 0, "user or group name or id");
1134 ts = cmd_CreateSyntax("listentries", ListEntries, 0,
1135 "list users/groups in the protection database");
1136 cmd_AddParm(ts, "-users", CMD_FLAG, CMD_OPTIONAL, "list user entries");
1137 cmd_AddParm(ts, "-groups", CMD_FLAG, CMD_OPTIONAL, "list group entries");
1140 #if defined(SUPERGROUPS)
1142 ts = cmd_CreateSyntax("interactive", Interactive, 0,
1143 "enter interactive mode");
1145 cmd_CreateAlias(ts, "in");
1147 ts = cmd_CreateSyntax("quit", Quit, 0, "exit program");
1150 ts = cmd_CreateSyntax("source", Source, 0, "read commands from file");
1151 cmd_AddParm(ts, "-file", CMD_SINGLE, 0, "filename");
1154 ts = cmd_CreateSyntax("sleep", Sleep, 0, "pause for a bit");
1155 cmd_AddParm(ts, "-delay", CMD_SINGLE, 0, "seconds");
1158 #endif /* SUPERGROUPS */
1160 cmd_SetBeforeProc(GetGlobals, 0);
1162 #if defined(SUPERGROUPS)
1164 if (code = cmd_Dispatch(argc, argv)) {
1170 if (isatty(fileno(source)))
1171 fprintf(stderr, "pts> ");
1172 if (!fgets(line, sizeof line, source)) {
1178 for (cp = line; *cp; ++cp)
1188 cmd_ParseLine(line, parsev, &parsec,
1189 sizeof(parsev) / sizeof(*parsev));
1191 com_err(whoami, code, "parsing line: <%s>", line);
1195 parsev[0] = argv[0];
1196 code = cmd_Dispatch(parsec, parsev);
1198 cmd_FreeArgv(parsev);
1203 #else /* SUPERGROUPS */
1205 cmd_SetAfterProc(CleanUp, 0);
1206 code = cmd_Dispatch(argc, argv);
1208 #endif /* SUPERGROUPS */