1d6f907dcSJoerg Wunsch /*- 24d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause 31de7b4b8SPedro F. Giffuni * 4ad7cf975SJoerg Wunsch * Copyright (C) 1996 5ad7cf975SJoerg Wunsch * David L. Nugent. All rights reserved. 6d6f907dcSJoerg Wunsch * 7d6f907dcSJoerg Wunsch * Redistribution and use in source and binary forms, with or without 8d6f907dcSJoerg Wunsch * modification, are permitted provided that the following conditions 9d6f907dcSJoerg Wunsch * are met: 10d6f907dcSJoerg Wunsch * 1. Redistributions of source code must retain the above copyright 11ad7cf975SJoerg Wunsch * notice, this list of conditions and the following disclaimer. 12d6f907dcSJoerg Wunsch * 2. Redistributions in binary form must reproduce the above copyright 13d6f907dcSJoerg Wunsch * notice, this list of conditions and the following disclaimer in the 14d6f907dcSJoerg Wunsch * documentation and/or other materials provided with the distribution. 15d6f907dcSJoerg Wunsch * 16ad7cf975SJoerg Wunsch * THIS SOFTWARE IS PROVIDED BY DAVID L. NUGENT AND CONTRIBUTORS ``AS IS'' AND 17d6f907dcSJoerg Wunsch * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18d6f907dcSJoerg Wunsch * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19ad7cf975SJoerg Wunsch * ARE DISCLAIMED. IN NO EVENT SHALL DAVID L. NUGENT OR CONTRIBUTORS BE LIABLE 20d6f907dcSJoerg Wunsch * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21d6f907dcSJoerg Wunsch * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22d6f907dcSJoerg Wunsch * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23d6f907dcSJoerg Wunsch * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24d6f907dcSJoerg Wunsch * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25d6f907dcSJoerg Wunsch * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26d6f907dcSJoerg Wunsch * SUCH DAMAGE. 27d6f907dcSJoerg Wunsch */ 28d6f907dcSJoerg Wunsch 291dcc6ec7SPhilippe Charnier #include <err.h> 305e91a8acSNate Williams #include <fcntl.h> 31e7161f36SAndrey A. Chernov #include <locale.h> 32bcbdb01eSBaptiste Daroussin #include <string.h> 33bcbdb01eSBaptiste Daroussin #include <sysexits.h> 34bcbdb01eSBaptiste Daroussin #include <unistd.h> 35bcbdb01eSBaptiste Daroussin 365f12594aSDavid Nugent #include "pw.h" 37d6f907dcSJoerg Wunsch 382399cd14SDavid Nugent const char *Modes[] = { 392399cd14SDavid Nugent "add", "del", "mod", "show", "next", 402399cd14SDavid Nugent NULL}; 41d6f907dcSJoerg Wunsch const char *Which[] = {"user", "group", NULL}; 4248aee7f3SJoerg Wunsch static const char *Combo1[] = { 4348aee7f3SJoerg Wunsch "useradd", "userdel", "usermod", "usershow", "usernext", 442399cd14SDavid Nugent "lock", "unlock", 4548aee7f3SJoerg Wunsch "groupadd", "groupdel", "groupmod", "groupshow", "groupnext", 46d6f907dcSJoerg Wunsch NULL}; 4748aee7f3SJoerg Wunsch static const char *Combo2[] = { 4848aee7f3SJoerg Wunsch "adduser", "deluser", "moduser", "showuser", "nextuser", 492399cd14SDavid Nugent "lock", "unlock", 5048aee7f3SJoerg Wunsch "addgroup", "delgroup", "modgroup", "showgroup", "nextgroup", 51d6f907dcSJoerg Wunsch NULL}; 52d6f907dcSJoerg Wunsch 535f12594aSDavid Nugent struct pwf PWF = 545f12594aSDavid Nugent { 55ac72be28SBaptiste Daroussin PWF_REGULAR, 565f12594aSDavid Nugent setpwent, 575f12594aSDavid Nugent endpwent, 585f12594aSDavid Nugent getpwent, 595f12594aSDavid Nugent getpwuid, 605f12594aSDavid Nugent getpwnam, 615f12594aSDavid Nugent setgrent, 625f12594aSDavid Nugent endgrent, 635f12594aSDavid Nugent getgrent, 645f12594aSDavid Nugent getgrgid, 655f12594aSDavid Nugent getgrnam, 665f12594aSDavid Nugent 675f12594aSDavid Nugent }; 685f12594aSDavid Nugent struct pwf VPWF = 695f12594aSDavid Nugent { 70ac72be28SBaptiste Daroussin PWF_ALT, 715f12594aSDavid Nugent vsetpwent, 725f12594aSDavid Nugent vendpwent, 735f12594aSDavid Nugent vgetpwent, 745f12594aSDavid Nugent vgetpwuid, 755f12594aSDavid Nugent vgetpwnam, 765f12594aSDavid Nugent vsetgrent, 775f12594aSDavid Nugent vendgrent, 785f12594aSDavid Nugent vgetgrent, 795f12594aSDavid Nugent vgetgrgid, 805f12594aSDavid Nugent vgetgrnam, 815f12594aSDavid Nugent }; 825f12594aSDavid Nugent 83d2d022b9SBaptiste Daroussin static int (*cmdfunc[W_NUM][M_NUM])(int argc, char **argv, char *_name) = { 84d2d022b9SBaptiste Daroussin { /* user */ 85d2d022b9SBaptiste Daroussin pw_user_add, 86d2d022b9SBaptiste Daroussin pw_user_del, 87d2d022b9SBaptiste Daroussin pw_user_mod, 88d2d022b9SBaptiste Daroussin pw_user_show, 89d2d022b9SBaptiste Daroussin pw_user_next, 90d2d022b9SBaptiste Daroussin pw_user_lock, 91d2d022b9SBaptiste Daroussin pw_user_unlock, 92d2d022b9SBaptiste Daroussin }, 93d2d022b9SBaptiste Daroussin { /* group */ 94d2d022b9SBaptiste Daroussin pw_group_add, 95d2d022b9SBaptiste Daroussin pw_group_del, 96d2d022b9SBaptiste Daroussin pw_group_mod, 97d2d022b9SBaptiste Daroussin pw_group_show, 98d2d022b9SBaptiste Daroussin pw_group_next, 99d2d022b9SBaptiste Daroussin } 100d2d022b9SBaptiste Daroussin }; 1012cc63cd1SBaptiste Daroussin 102d2d022b9SBaptiste Daroussin struct pwconf conf; 103d6f907dcSJoerg Wunsch 104*c8611932SDag-Erling Smørgrav static int mode = -1; 105*c8611932SDag-Erling Smørgrav static int which = -1; 106*c8611932SDag-Erling Smørgrav 107d6f907dcSJoerg Wunsch static int getindex(const char *words[], const char *word); 108d6f907dcSJoerg Wunsch static void cmdhelp(int mode, int which); 109d6f907dcSJoerg Wunsch 110d6f907dcSJoerg Wunsch int 111d6f907dcSJoerg Wunsch main(int argc, char *argv[]) 112d6f907dcSJoerg Wunsch { 113*c8611932SDag-Erling Smørgrav int tmp; 11490edef4fSBaptiste Daroussin struct stat st; 115d2d022b9SBaptiste Daroussin char arg, *arg1; 11682a3c75aSBaptiste Daroussin bool relocated, nis; 117d6f907dcSJoerg Wunsch 118d2d022b9SBaptiste Daroussin arg1 = NULL; 11982a3c75aSBaptiste Daroussin relocated = nis = false; 120bbe09b2eSBaptiste Daroussin memset(&conf, 0, sizeof(conf)); 12165730d93SBaptiste Daroussin strlcpy(conf.rootdir, "/", sizeof(conf.rootdir)); 1222cc63cd1SBaptiste Daroussin strlcpy(conf.etcpath, _PATH_PWD, sizeof(conf.etcpath)); 12311621f96SBaptiste Daroussin conf.fd = -1; 124a70fbf7eSBaptiste Daroussin conf.checkduplicate = true; 1252cc63cd1SBaptiste Daroussin 126d2d022b9SBaptiste Daroussin setlocale(LC_ALL, ""); 127e7161f36SAndrey A. Chernov 128d6f907dcSJoerg Wunsch /* 129d6f907dcSJoerg Wunsch * Break off the first couple of words to determine what exactly 130d6f907dcSJoerg Wunsch * we're being asked to do 131d6f907dcSJoerg Wunsch */ 1325f12594aSDavid Nugent while (argc > 1) { 1335f12594aSDavid Nugent if (*argv[1] == '-') { 1345f12594aSDavid Nugent /* 1355f12594aSDavid Nugent * Special case, allow pw -V<dir> <operation> [args] for scripts etc. 1365f12594aSDavid Nugent */ 137ac72be28SBaptiste Daroussin arg = argv[1][1]; 138ac72be28SBaptiste Daroussin if (arg == 'V' || arg == 'R') { 1392cc63cd1SBaptiste Daroussin if (relocated) 1402cc63cd1SBaptiste Daroussin errx(EXIT_FAILURE, "Both '-R' and '-V' " 1412cc63cd1SBaptiste Daroussin "specified, only one accepted"); 1422cc63cd1SBaptiste Daroussin relocated = true; 1435f12594aSDavid Nugent optarg = &argv[1][2]; 1445f12594aSDavid Nugent if (*optarg == '\0') { 14590edef4fSBaptiste Daroussin if (stat(argv[2], &st) != 0) 14690edef4fSBaptiste Daroussin errx(EX_OSFILE, \ 14790edef4fSBaptiste Daroussin "no such directory `%s'", 14890edef4fSBaptiste Daroussin argv[2]); 14990edef4fSBaptiste Daroussin if (!S_ISDIR(st.st_mode)) 15090edef4fSBaptiste Daroussin errx(EX_OSFILE, "`%s' not a " 15190edef4fSBaptiste Daroussin "directory", argv[2]); 1525f12594aSDavid Nugent optarg = argv[2]; 1535f12594aSDavid Nugent ++argv; 1545f12594aSDavid Nugent --argc; 1555f12594aSDavid Nugent } 1562cc63cd1SBaptiste Daroussin memcpy(&PWF, &VPWF, sizeof PWF); 1572cc63cd1SBaptiste Daroussin if (arg == 'R') { 1582cc63cd1SBaptiste Daroussin strlcpy(conf.rootdir, optarg, 1592cc63cd1SBaptiste Daroussin sizeof(conf.rootdir)); 1602cc63cd1SBaptiste Daroussin PWF._altdir = PWF_ROOTDIR; 1612cc63cd1SBaptiste Daroussin } 1622cc63cd1SBaptiste Daroussin snprintf(conf.etcpath, sizeof(conf.etcpath), 1634835c3b1SYuri Pankov "%s%s", optarg, arg == 'R' ? 1644835c3b1SYuri Pankov _PATH_PWD : ""); 165e3921b27SDavid Nugent } else 1665f12594aSDavid Nugent break; 1675f12594aSDavid Nugent } 168c4e667b9SDavid Nugent else if (mode == -1 && (tmp = getindex(Modes, argv[1])) != -1) 169d6f907dcSJoerg Wunsch mode = tmp; 170c4e667b9SDavid Nugent else if (which == -1 && (tmp = getindex(Which, argv[1])) != -1) 171d6f907dcSJoerg Wunsch which = tmp; 172c4e667b9SDavid Nugent else if ((mode == -1 && which == -1) && 173c4e667b9SDavid Nugent ((tmp = getindex(Combo1, argv[1])) != -1 || 174c4e667b9SDavid Nugent (tmp = getindex(Combo2, argv[1])) != -1)) { 175d6f907dcSJoerg Wunsch which = tmp / M_NUM; 176d6f907dcSJoerg Wunsch mode = tmp % M_NUM; 177c4e667b9SDavid Nugent } else if (strcmp(argv[1], "help") == 0 && argv[2] == NULL) 178d6f907dcSJoerg Wunsch cmdhelp(mode, which); 179d2d022b9SBaptiste Daroussin else if (which != -1 && mode != -1) 180d2d022b9SBaptiste Daroussin arg1 = argv[1]; 181d2d022b9SBaptiste Daroussin else 1821dcc6ec7SPhilippe Charnier errx(EX_USAGE, "unknown keyword `%s'", argv[1]); 183d6f907dcSJoerg Wunsch ++argv; 184d6f907dcSJoerg Wunsch --argc; 185d6f907dcSJoerg Wunsch } 186d6f907dcSJoerg Wunsch 187d6f907dcSJoerg Wunsch /* 188d6f907dcSJoerg Wunsch * Bail out unless the user is specific! 189d6f907dcSJoerg Wunsch */ 190d6f907dcSJoerg Wunsch if (mode == -1 || which == -1) 191d6f907dcSJoerg Wunsch cmdhelp(mode, which); 192d6f907dcSJoerg Wunsch 19365730d93SBaptiste Daroussin conf.rootfd = open(conf.rootdir, O_DIRECTORY|O_CLOEXEC); 19465730d93SBaptiste Daroussin if (conf.rootfd == -1) 19565730d93SBaptiste Daroussin errx(EXIT_FAILURE, "Unable to open '%s'", conf.rootdir); 196d6f907dcSJoerg Wunsch 197d2d022b9SBaptiste Daroussin return (cmdfunc[which][mode](argc, argv, arg1)); 198d6f907dcSJoerg Wunsch } 199d6f907dcSJoerg Wunsch 2005e91a8acSNate Williams 201d6f907dcSJoerg Wunsch static int 202d6f907dcSJoerg Wunsch getindex(const char *words[], const char *word) 203d6f907dcSJoerg Wunsch { 204d6f907dcSJoerg Wunsch int i = 0; 205d6f907dcSJoerg Wunsch 206d6f907dcSJoerg Wunsch while (words[i]) { 207d6f907dcSJoerg Wunsch if (strcmp(words[i], word) == 0) 208d2d022b9SBaptiste Daroussin return (i); 209d6f907dcSJoerg Wunsch i++; 210d6f907dcSJoerg Wunsch } 211d2d022b9SBaptiste Daroussin return (-1); 212d6f907dcSJoerg Wunsch } 213d6f907dcSJoerg Wunsch 214d6f907dcSJoerg Wunsch 215d6f907dcSJoerg Wunsch /* 216d6f907dcSJoerg Wunsch * This is probably an overkill for a cmdline help system, but it reflects 217d6f907dcSJoerg Wunsch * the complexity of the command line. 218d6f907dcSJoerg Wunsch */ 219d6f907dcSJoerg Wunsch 220d6f907dcSJoerg Wunsch static void 221d6f907dcSJoerg Wunsch cmdhelp(int mode, int which) 222d6f907dcSJoerg Wunsch { 223d6f907dcSJoerg Wunsch if (which == -1) 2242399cd14SDavid Nugent fprintf(stderr, "usage:\n pw [user|group|lock|unlock] [add|del|mod|show|next] [help|switches/values]\n"); 225d6f907dcSJoerg Wunsch else if (mode == -1) 2262399cd14SDavid Nugent fprintf(stderr, "usage:\n pw %s [add|del|mod|show|next] [help|switches/values]\n", Which[which]); 227d6f907dcSJoerg Wunsch else { 228d6f907dcSJoerg Wunsch 229d6f907dcSJoerg Wunsch /* 230d6f907dcSJoerg Wunsch * We need to give mode specific help 231d6f907dcSJoerg Wunsch */ 232d6f907dcSJoerg Wunsch static const char *help[W_NUM][M_NUM] = 233d6f907dcSJoerg Wunsch { 234d6f907dcSJoerg Wunsch { 2351dcc6ec7SPhilippe Charnier "usage: pw useradd [name] [switches]\n" 2365f12594aSDavid Nugent "\t-V etcdir alternate /etc location\n" 2376a3133efSWarren Block "\t-R rootdir alternate root directory\n" 238d6f907dcSJoerg Wunsch "\t-C config configuration file\n" 239d6f907dcSJoerg Wunsch "\t-q quiet operation\n" 240d6f907dcSJoerg Wunsch " Adding users:\n" 241d6f907dcSJoerg Wunsch "\t-n name login name\n" 242d6f907dcSJoerg Wunsch "\t-u uid user id\n" 243d6f907dcSJoerg Wunsch "\t-c comment user name/comment\n" 244d6f907dcSJoerg Wunsch "\t-d directory home directory\n" 245d6f907dcSJoerg Wunsch "\t-e date account expiry date\n" 246d6f907dcSJoerg Wunsch "\t-p date password expiry date\n" 247d6f907dcSJoerg Wunsch "\t-g grp initial group\n" 248d6f907dcSJoerg Wunsch "\t-G grp1,grp2 additional groups\n" 249d6f907dcSJoerg Wunsch "\t-m [ -k dir ] create and set up home\n" 2501dd634b0SLukas Ertl "\t-M mode home directory permissions\n" 251d6f907dcSJoerg Wunsch "\t-s shell name of login shell\n" 252d6f907dcSJoerg Wunsch "\t-o duplicate uid ok\n" 253d6f907dcSJoerg Wunsch "\t-L class user class\n" 254d6f907dcSJoerg Wunsch "\t-h fd read password on fd\n" 25587d6b5caSIan Dowse "\t-H fd read encrypted password on fd\n" 256f1d684faSDavid Nugent "\t-Y update NIS maps\n" 25748aee7f3SJoerg Wunsch "\t-N no update\n" 258d6f907dcSJoerg Wunsch " Setting defaults:\n" 2595f12594aSDavid Nugent "\t-V etcdir alternate /etc location\n" 2606a3133efSWarren Block "\t-R rootdir alternate root directory\n" 261d6f907dcSJoerg Wunsch "\t-D set user defaults\n" 262d6f907dcSJoerg Wunsch "\t-b dir default home root dir\n" 263d6f907dcSJoerg Wunsch "\t-e period default expiry period\n" 264d6f907dcSJoerg Wunsch "\t-p period default password change period\n" 265d6f907dcSJoerg Wunsch "\t-g group default group\n" 266d6f907dcSJoerg Wunsch "\t-G grp1,grp2 additional groups\n" 267d6f907dcSJoerg Wunsch "\t-L class default user class\n" 268d6f907dcSJoerg Wunsch "\t-k dir default home skeleton\n" 26985204142SLukas Ertl "\t-M mode home directory permissions\n" 270d6f907dcSJoerg Wunsch "\t-u min,max set min,max uids\n" 271d6f907dcSJoerg Wunsch "\t-i min,max set min,max gids\n" 272d6f907dcSJoerg Wunsch "\t-w method set default password method\n" 273f1d684faSDavid Nugent "\t-s shell default shell\n" 274f1d684faSDavid Nugent "\t-y path set NIS passwd file path\n", 2751dcc6ec7SPhilippe Charnier "usage: pw userdel [uid|name] [switches]\n" 2765f12594aSDavid Nugent "\t-V etcdir alternate /etc location\n" 2776a3133efSWarren Block "\t-R rootdir alternate root directory\n" 278d6f907dcSJoerg Wunsch "\t-n name login name\n" 279d6f907dcSJoerg Wunsch "\t-u uid user id\n" 280f1d684faSDavid Nugent "\t-Y update NIS maps\n" 281d2d022b9SBaptiste Daroussin "\t-y path set NIS passwd file path\n" 282d6f907dcSJoerg Wunsch "\t-r remove home & contents\n", 2831dcc6ec7SPhilippe Charnier "usage: pw usermod [uid|name] [switches]\n" 2845f12594aSDavid Nugent "\t-V etcdir alternate /etc location\n" 2856a3133efSWarren Block "\t-R rootdir alternate root directory\n" 286d6f907dcSJoerg Wunsch "\t-C config configuration file\n" 287d6f907dcSJoerg Wunsch "\t-q quiet operation\n" 288d6f907dcSJoerg Wunsch "\t-F force add if no user\n" 289d6f907dcSJoerg Wunsch "\t-n name login name\n" 290d6f907dcSJoerg Wunsch "\t-u uid user id\n" 291d6f907dcSJoerg Wunsch "\t-c comment user name/comment\n" 292d6f907dcSJoerg Wunsch "\t-d directory home directory\n" 293d6f907dcSJoerg Wunsch "\t-e date account expiry date\n" 294d6f907dcSJoerg Wunsch "\t-p date password expiry date\n" 295d6f907dcSJoerg Wunsch "\t-g grp initial group\n" 296d6f907dcSJoerg Wunsch "\t-G grp1,grp2 additional groups\n" 297d6f907dcSJoerg Wunsch "\t-l name new login name\n" 298d6f907dcSJoerg Wunsch "\t-L class user class\n" 299d6f907dcSJoerg Wunsch "\t-m [ -k dir ] create and set up home\n" 3001dd634b0SLukas Ertl "\t-M mode home directory permissions\n" 301d6f907dcSJoerg Wunsch "\t-s shell name of login shell\n" 30248aee7f3SJoerg Wunsch "\t-w method set new password using method\n" 30348aee7f3SJoerg Wunsch "\t-h fd read password on fd\n" 30487d6b5caSIan Dowse "\t-H fd read encrypted password on fd\n" 305f1d684faSDavid Nugent "\t-Y update NIS maps\n" 306d2d022b9SBaptiste Daroussin "\t-y path set NIS passwd file path\n" 30748aee7f3SJoerg Wunsch "\t-N no update\n", 3081dcc6ec7SPhilippe Charnier "usage: pw usershow [uid|name] [switches]\n" 3095f12594aSDavid Nugent "\t-V etcdir alternate /etc location\n" 3106a3133efSWarren Block "\t-R rootdir alternate root directory\n" 311d6f907dcSJoerg Wunsch "\t-n name login name\n" 312d6f907dcSJoerg Wunsch "\t-u uid user id\n" 313d6f907dcSJoerg Wunsch "\t-F force print\n" 31448aee7f3SJoerg Wunsch "\t-P prettier format\n" 315f3522722SDavid Nugent "\t-a print all users\n" 316f3522722SDavid Nugent "\t-7 print in v7 format\n", 3171dcc6ec7SPhilippe Charnier "usage: pw usernext [switches]\n" 3185f12594aSDavid Nugent "\t-V etcdir alternate /etc location\n" 3196a3133efSWarren Block "\t-R rootdir alternate root directory\n" 3203bfc59e8SBaptiste Daroussin "\t-C config configuration file\n" 3213bfc59e8SBaptiste Daroussin "\t-q quiet operation\n", 322ed6fd55aSDima Dorfman "usage pw: lock [switches]\n" 323ed6fd55aSDima Dorfman "\t-V etcdir alternate /etc locations\n" 324ed6fd55aSDima Dorfman "\t-C config configuration file\n" 325ed6fd55aSDima Dorfman "\t-q quiet operation\n", 326ed6fd55aSDima Dorfman "usage pw: unlock [switches]\n" 327ed6fd55aSDima Dorfman "\t-V etcdir alternate /etc locations\n" 328ed6fd55aSDima Dorfman "\t-C config configuration file\n" 329ed6fd55aSDima Dorfman "\t-q quiet operation\n" 330d6f907dcSJoerg Wunsch }, 331d6f907dcSJoerg Wunsch { 3321dcc6ec7SPhilippe Charnier "usage: pw groupadd [group|gid] [switches]\n" 3335f12594aSDavid Nugent "\t-V etcdir alternate /etc location\n" 3346a3133efSWarren Block "\t-R rootdir alternate root directory\n" 335d6f907dcSJoerg Wunsch "\t-C config configuration file\n" 336d6f907dcSJoerg Wunsch "\t-q quiet operation\n" 337d6f907dcSJoerg Wunsch "\t-n group group name\n" 338d6f907dcSJoerg Wunsch "\t-g gid group id\n" 33948aee7f3SJoerg Wunsch "\t-M usr1,usr2 add users as group members\n" 34048aee7f3SJoerg Wunsch "\t-o duplicate gid ok\n" 341f1d684faSDavid Nugent "\t-Y update NIS maps\n" 34248aee7f3SJoerg Wunsch "\t-N no update\n", 3431dcc6ec7SPhilippe Charnier "usage: pw groupdel [group|gid] [switches]\n" 3445f12594aSDavid Nugent "\t-V etcdir alternate /etc location\n" 3456a3133efSWarren Block "\t-R rootdir alternate root directory\n" 346d6f907dcSJoerg Wunsch "\t-n name group name\n" 347f1d684faSDavid Nugent "\t-g gid group id\n" 348f1d684faSDavid Nugent "\t-Y update NIS maps\n", 3491dcc6ec7SPhilippe Charnier "usage: pw groupmod [group|gid] [switches]\n" 3505f12594aSDavid Nugent "\t-V etcdir alternate /etc location\n" 3516a3133efSWarren Block "\t-R rootdir alternate root directory\n" 352d6f907dcSJoerg Wunsch "\t-C config configuration file\n" 353d6f907dcSJoerg Wunsch "\t-q quiet operation\n" 354d6f907dcSJoerg Wunsch "\t-F force add if not exists\n" 355d6f907dcSJoerg Wunsch "\t-n name group name\n" 356d6f907dcSJoerg Wunsch "\t-g gid group id\n" 35748aee7f3SJoerg Wunsch "\t-M usr1,usr2 replaces users as group members\n" 35848aee7f3SJoerg Wunsch "\t-m usr1,usr2 add users as group members\n" 359bc991a6dSSean Farley "\t-d usr1,usr2 delete users as group members\n" 36048aee7f3SJoerg Wunsch "\t-l name new group name\n" 361f1d684faSDavid Nugent "\t-Y update NIS maps\n" 36248aee7f3SJoerg Wunsch "\t-N no update\n", 3631dcc6ec7SPhilippe Charnier "usage: pw groupshow [group|gid] [switches]\n" 3645f12594aSDavid Nugent "\t-V etcdir alternate /etc location\n" 3656a3133efSWarren Block "\t-R rootdir alternate root directory\n" 366d6f907dcSJoerg Wunsch "\t-n name group name\n" 367d6f907dcSJoerg Wunsch "\t-g gid group id\n" 368d6f907dcSJoerg Wunsch "\t-F force print\n" 36948aee7f3SJoerg Wunsch "\t-P prettier format\n" 37048aee7f3SJoerg Wunsch "\t-a print all accounting groups\n", 3711dcc6ec7SPhilippe Charnier "usage: pw groupnext [switches]\n" 3725f12594aSDavid Nugent "\t-V etcdir alternate /etc location\n" 3736a3133efSWarren Block "\t-R rootdir alternate root directory\n" 37448aee7f3SJoerg Wunsch "\t-C config configuration file\n" 3753bfc59e8SBaptiste Daroussin "\t-q quiet operation\n" 376d6f907dcSJoerg Wunsch } 377d6f907dcSJoerg Wunsch }; 378d6f907dcSJoerg Wunsch 379cab0fb4eSKris Kennaway fprintf(stderr, "%s", help[which][mode]); 380d6f907dcSJoerg Wunsch } 381*c8611932SDag-Erling Smørgrav exit(EX_USAGE); 382*c8611932SDag-Erling Smørgrav } 383*c8611932SDag-Erling Smørgrav 384*c8611932SDag-Erling Smørgrav void 385*c8611932SDag-Erling Smørgrav usage(void) 386*c8611932SDag-Erling Smørgrav { 387*c8611932SDag-Erling Smørgrav cmdhelp(mode, which); 388d6f907dcSJoerg Wunsch } 389