[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Bug-sysutils] Updated patch for chage.c
From: |
Barry deFreese |
Subject: |
[Bug-sysutils] Updated patch for chage.c |
Date: |
Fri, 21 May 2004 20:29:04 -0700 |
User-agent: |
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.6) Gecko/20040413 Debian/1.6-5 |
Hello AGAIN.. :-)
OK, I have revised my code for chage.c I can now build it without any
errors but I get "Illegal Operation (core dumped)" running chage.. :-(
I'll look into that but if someone gets a chance to review these changes
I would appreciate it.
I promise once I get a better understanding of all of this I won't ask
for so much input. :-(
Thanks as always,
--
Barry deFreese
Debian 3.0r1 "Woody"
GNU/Hurd
Registered Linux "Newbie" #302256 - Hurd H4XX0r wannabe
"Programming today is a race between software engineers striving
to build bigger and better idiot-proof programs, and the Universe
trying to produce bigger and better idiots. So far, the Universe is
winning." Rich Cook.
? build
? chage_argp_20040520.diff
? config.rpath
? sysutils_bdd_20040521.diff
? sysutils_svpo_20040521.diff
? etc/Makefile.in
? etc/pam.d/Makefile.in
? m4/intmax.m4
? m4/longdouble.m4
? m4/longlong.m4
? m4/nls.m4
? m4/po.m4
? m4/printf-posix.m4
? m4/signed.m4
? m4/size_max.m4
? m4/wchar_t.m4
? m4/wint_t.m4
? m4/xsize.m4
? man/Makefile.in
? man/sv/Makefile.in
? po/Makevars.template
? po/sysutils.pot
? src/chage.orgc
? src/getopt.c
? src/getopt1.c
Index: po/sv.po
===================================================================
RCS file: /cvsroot/sysutils/sysutils/po/sv.po,v
retrieving revision 1.2
diff -u -p -r1.2 sv.po
--- po/sv.po 20 May 2004 10:13:05 -0000 1.2
+++ po/sv.po 22 May 2004 04:16:05 -0000
@@ -1505,7 +1505,7 @@ msgstr ""
#: src/remove-shell.c:123
msgid "remove a shell from the list of valid shells\n"
-msgstr "ta bort ett skal från listan med giltiga inloggningsskal"
+msgstr "ta bort ett skal från listan med giltiga inloggningsskal\n"
#: src/remove-shell.c:156
#, c-format
Index: src/chage.c
===================================================================
RCS file: /cvsroot/sysutils/sysutils/src/chage.c,v
retrieving revision 1.2
diff -u -p -r1.2 chage.c
--- src/chage.c 20 May 2004 10:16:30 -0000 1.2
+++ src/chage.c 22 May 2004 04:16:05 -0000
@@ -26,60 +26,121 @@
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
+#include <argp.h>
#include "misc.h"
#include "sysutils.h"
#define PRG_NAME "chage"
+/* Static program flags for argp */
+const char *argp_program_version = "chage (sysutils) 0.1.2";
+const char *argp_program_bug_address = "<address@hidden>";
+static char doc[] = "Change password aging information for the specified
users\n\n"
+ "USERS should be a list of users, seperated by a space "
+ "or the word ALL to change expiry-information for all "
+ "users.\n";
+static char args_doc[] = " USERS";
+
extern int optind;
extern char *optarg;
extern const char *progname;
-/**
- * Show usage information
- */
-static void usage(void)
+/* Program options struct for argp parser */
+static struct argp_option options[] =
{
- fprintf(stdout,
- _("Usage: %s [OPTION]... USERS\n"
- "Change password aging information for the specified "
- "users.\n"
- "\n"
- "USERS should be a comma-separated list of users,\n"
- "or the word ALL to change expiry-information for all "
- "users.\n"
- "\n"
- " -d, --lstchg the date of when the password "
- "was last changed\n"
- " (YYYY-MM-DD); empty == now\n"
- " -m, --min the minimum number of days "
- "before the password\n"
- " can be changed\n"
- " -M, --max the maximum number of days before "
- "the password\n"
- " must be changed\n"
- " -W, --warn the number of days of before "
- "password expiry to warn\n"
- " -I, --inact the max number of days of "
- "inactivity after password\n"
- " expiry before the account is "
- "locked\n"
- " -E, --expire the date of expiration for the "
- "account\n"
- " (YYYY-MM-DD); empty == never\n"
- " --verbose warn if the specified users "
- "does not exist\n"),
- progname);
- usage_help();
+ {"lstchg", 'd', "DATE", 0, "the date of when the password was last
changed "
+ "(YYYY-MM-DD); empty == now", 0},
+ {"min", 'm', "DAYS", 0, "the minimum number of days before the password
"
+ "can be changed", 1},
+ {"max", 'M', "DAYS", 0, "the maximum number of days before the password
"
+ "must be changed", 2},
+ {"warn", 'W', "DAYS", 0, "the number of days to warn before the password
expires", 3},
+ {"inact", 'I', "DAYS", 0, "the max number of days of inactivity after
password "
+ "expiry before the account is locked", 4},
+ {"expire", 'E', "DATE", 0, "the date of expiration for the account "
+ "(YYYY-MM-DD); empty == never", 5},
+ {"verbose", 'v', 0, 0, "Verbose", 6},
+ {0, 0, 0, 0, 0, 0}
+};
+
+/* Available arguments */
+struct arguments
+{
+ char *args;
+ long lstchg_date;
+ long min_val;
+ long max_val;
+ long warn_val;
+ long inact_val;
+ long expire_date;
+ long verbose;
+ int usercount;
+ char **users;
+};
+
+char *lstchg = NULL;
+char *min = NULL;
+char *max = NULL;
+char *warn = NULL;
+char *inact = NULL;
+char *expire = NULL;
+
+/* parse a single option */
+static error_t
+parse_opt (int key, char *arg, struct argp_state *state)
+{
+ struct arguments *arguments = state->input;
+
+ switch (key)
+ {
+ case 'd':
+ arguments->lstchg_date = atol(arg);
+ break;
+ case 'm':
+ arguments->min_val = atol(arg);
+ break;
+ case 'M':
+ arguments->max_val = atol(arg);
+ break;
+ case 'W':
+ arguments->warn_val = atol(arg);
+ break;
+ case 'I':
+ arguments->inact_val = atol(arg);
+ break;
+ case 'E':
+ arguments->expire_date = atol(arg);
+ break;
+ case 'v':
+ arguments->verbose = 1;
+ break;
+ case ARGP_KEY_INIT:
+ memset(&arguments, -2, sizeof(arguments));
+ arguments->users = (char**) malloc(sizeof(char **));
+ break;
+ case ARGP_KEY_NO_ARGS:
+ argp_usage (state);
+ case ARGP_KEY_ARG:
+ arguments->usercount++;
+ arguments->users = (char **)realloc(arguments->users,
arguments->usercount * sizeof(char *));
+ arguments->users[state->arg_num] = arg;
+ break;
+ default:
+ return ARGP_ERR_UNKNOWN;
+ }
+ return 0;
}
+/* argp parser */
+static struct argp argp = { options, parse_opt, args_doc, doc, NULL, NULL,
NULL };
+
/**
* The program's main-function
*
* @param argc The number of arguments
* @param argv The arguments
- * @return 0 on success, errno on failure
+ * @return 0 on success, errno on failure
*/
int main(int argc, char *argv[])
{
@@ -89,213 +150,23 @@ int main(int argc, char *argv[])
int empty = 1;
int changed = 0;
- int verbose = 0;
-
- int optc;
- int opt_index;
-
- int status = 0;
char *spwname = NULL;
char *spbname = NULL;
char *username = NULL;
+ int status = 0;
+
char **usrarray = NULL;
- struct expirydata expiry = {
- .lstchg = -2,
- .min = -2,
- .max = -2,
- .warn = -2,
- .inact = -2,
- .expire = -2,
- };
-
- char *lstchg = NULL;
- char *min = NULL;
- char *max = NULL;
- char *warn = NULL;
- char *inact = NULL;
- char *expire = NULL;
-
- struct option const options[] = {
- { AS_LSTCHG, optional_argument, 0, 'd' },
- { AS_MIN, required_argument, 0, 'm' },
- { AS_MAX, required_argument, 0, 'M' },
- { AS_WARN, required_argument, 0, 'W' },
- { AS_INACT, required_argument, 0, 'I' },
- { AS_EXPIRE, optional_argument, 0, 'E' },
- { "verbose", no_argument, 0, 'v' },
- { "help", no_argument, 0, 'h' },
- { "version", no_argument, 0, 'V' },
- { 0, 0, 0, 0 }
- };
+ struct arguments arguments;
- errno = 0;
+ argp_parse (&argp, argc, argv, 0, 0, &arguments);
- /* Initialise support for locales, and set the program-name */
+ /* Initialize support for locales, and set the program-name */
if ((status = init_locales(PRG_NAME)))
goto EXIT;
- /* Parse the command-line options */
- while ((optc = getopt_long(argc, argv, "d::m:M:W:I:E::",
- options, &opt_index)) != -1) {
- switch (optc) {
- case 'm':
- if ((status = is_long(optarg))) {
- fprintf(stderr,
- _("%s: invalid value supplied to "
- "`%s'\n"),
- progname, "-m | --min");
- goto EXIT;
- }
-
- if ((status = string_to_long(optarg,
- (void **)&expiry.min))) {
- fprintf(stderr,
- _("%s: `%s' failed; %s\n"),
- progname, "string_to_long",
- strerror(errno));
- goto EXIT;
- }
-
- break;
-
- case 'M':
- if ((status = is_long(optarg))) {
- fprintf(stderr,
- _("%s: invalid value supplied to "
- "`%s'\n"),
- progname, "-M | --max");
- goto EXIT;
- }
-
- if ((status = string_to_long(optarg,
- (void **)&expiry.max))) {
- fprintf(stderr,
- _("%s: `%s' failed; %s\n"),
- progname, "string_to_long",
- strerror(errno));
- goto EXIT;
- }
-
- break;
-
- case 'd':
- if ((status = is_valid_date(optarg))) {
- fprintf(stderr,
- _("%s: invalid value supplied to "
- "`%s'\n"),
- progname, "-d | --lstchg");
- goto EXIT;
- }
-
- if ((status = string_to_date(optarg,
- (void **)&expiry.lstchg)))
{
- fprintf(stderr,
- _("%s: `%s' failed; %s\n"),
- progname, "string_to_date",
- strerror(errno));
- goto EXIT;
- } else if (expiry.lstchg == -2) {
- if ((expiry.lstchg = get_current_date()) == -1)
{
- status = errno;
- goto EXIT;
- }
- }
-
- if (!expiry.lstchg)
- expiry.lstchg = -1;
-
- break;
-
- case 'I':
- if ((status = is_long(optarg))) {
- fprintf(stderr,
- _("%s: invalid value supplied to "
- "`%s'\n"),
- progname, "-I | --inact");
- goto EXIT;
- }
-
- if ((status = string_to_long(optarg,
- (void **)&expiry.inact))) {
- fprintf(stderr,
- _("%s: `%s' failed; %s\n"),
- progname, "string_to_long",
- strerror(errno));
- goto EXIT;
- }
-
- break;
-
- case 'E':
- if ((status = is_valid_date(optarg))) {
- fprintf(stderr,
- _("%s: invalid value supplied to "
- "`%s'\n"),
- progname, "-E | --expire");
- goto EXIT;
- }
-
- if ((status = string_to_date(optarg,
- (void **)&expiry.expire)))
{
- fprintf(stderr,
- _("%s: `%s' failed; %s\n"),
- progname, "string_to_date",
- strerror(errno));
- goto EXIT;
- } else if (expiry.expire == -2) {
- if ((expiry.expire = get_current_date()) == -1)
{
- status = errno;
- goto EXIT;
- }
- }
-
- if (!expiry.expire)
- expiry.expire = -1;
-
- break;
-
- case 'W':
- if ((status = is_long(optarg))) {
- fprintf(stderr,
- _("%s: invalid value supplied to "
- "`%s'\n"),
- progname, "-W | --warn");
- goto EXIT;
- }
-
- if ((status = string_to_long(optarg,
- (void **)&expiry.warn))) {
- fprintf(stderr,
- _("%s: `%s' failed; %s\n"),
- progname, "string_to_long",
- strerror(errno));
- goto EXIT;
- }
-
- break;
-
- case 'v':
- verbose = 1;
- break;
-
- case 'h':
- usage();
- goto EXIT;
-
- case 'V':
- version();
- goto EXIT;
-
- default:
- usage();
- status = EINVAL;
- goto EXIT;
- }
- }
-
/* Make sure the caller has root privileges */
if ((status = is_useradmin())) {
if (status == EPERM) {
@@ -313,15 +184,6 @@ int main(int argc, char *argv[])
goto EXIT;
}
- /* Make sure we get the correct number of arguments */
- if ((argc - optind) > 1) {
- fprintf(stderr,
- _("%s: too many arguments\n"
- "Try `%s --help' for more information.\n"),
- progname, progname);
- status = EINVAL;
- goto EXIT;
- }
/* There are two alternatives here, neither of which are really
* pretty; either to read the entire passwd file once to get
@@ -330,7 +192,7 @@ int main(int argc, char *argv[])
* user-entries. Since the latter is probably the most common,
* the latter has been chosen.
*/
- if (!strcmp(argv[argc - 1], "ALL")) {
+ if (!strcmp(arguments.users[0], "ALL")) {
char *tmp = NULL;
if (!(tmp = get_all_users())) {
@@ -341,49 +203,44 @@ int main(int argc, char *argv[])
"might be corrupt\n"),
progname, _("users"), _("user database"));
status = ENOENT;
- } else if (!(usrarray = strsplit(tmp, ",", 0))) {
- fprintf(stderr,
- _("%s: `%s' failed; %s\n"),
- progname, "strsplit", strerror(errno));
- status = errno;
}
free(tmp);
if (status)
goto EXIT;
- } else {
+ } else {
char *tmp = NULL;
uid_t i = 0; /* We're scanning <= LASTUID, hence uid_t */
- if ((status = is_valid_namelist(argv[argc - 1]))) {
- if (status == EINVAL) {
- fprintf(stderr,
- _("%s: the specified list of %s "
- "contains invalid characters\n"),
- progname, _("users"));
- } else {
- fprintf(stderr,
- _("%s: `%s' failed; %s\n"),
- progname, "is_valid_namelist",
- strerror(errno));
- }
-
- goto EXIT;
- }
+ /* FIXME?? There is probably a better way to handle since the userlist
+ * is now in an argp struct but I didn't want to hack the code
+ * up too bad. bdd
+ */
+ int u;
+ for (u = 0; u < arguments.usercount; u++)
+ {
+ if ((status = is_valid_namelist(arguments.users[u]))) {
+ if (status == EINVAL) {
+ fprintf(stderr,
+ _("%s: the specified list of %s
"
+ "contains invalid
characters\n"),
+ progname, _("users"));
+ } else {
+ fprintf(stderr,
+ _("%s: `%s' failed; %s\n"),
+ progname, "is_valid_namelist",
+ strerror(errno));
+ }
- if (!(usrarray = strsplit(argv[argc - 1], ",", 0))) {
- fprintf(stderr,
- _("%s: `%s' failed; %s\n"),
- progname, "strsplit", strerror(errno));
- status = errno;
- goto EXIT;
+ goto EXIT;
+ }
}
/* If verbose mode has been requested,
* warn about all non-existing users
*/
- while (verbose && (tmp = usrarray[i++])) {
+ while (arguments.verbose && (tmp = arguments.users[i++])) {
if (!getpwnam(tmp)) {
if (errno) {
fprintf(stderr,
@@ -403,11 +260,11 @@ int main(int argc, char *argv[])
}
}
- if (optind == 1) {
+ if (argc == 1 && arguments.usercount >1) {
/* If we get multiple usernames, but no options have been
* specified (interactive mode requested) we abort
*/
- if (usrarray[1]) {
+ if (arguments.usercount > 1) {
fprintf(stderr,
_("%s: multiple users can only be processed "
"in batch-mode\n"),
@@ -417,7 +274,7 @@ int main(int argc, char *argv[])
}
/* Get the current expiry-information */
- if (!(sp = getspnam(usrarray[0])) && errno) {
+ if (!(sp = getspnam(arguments.users[0])) && errno) {
fprintf(stderr,
_("%s: `%s' failed; %s\n"),
progname, "getspnam()", strerror(errno));
@@ -425,12 +282,12 @@ int main(int argc, char *argv[])
goto EXIT;
}
- expiry.lstchg = sp->sp_lstchg;
- expiry.min = sp->sp_min;
- expiry.max = sp->sp_max;
- expiry.warn = sp->sp_warn;
- expiry.inact = sp->sp_inact;
- expiry.expire = sp->sp_expire;
+ arguments.lstchg_date = sp->sp_lstchg;
+ arguments.min_val = sp->sp_min;
+ arguments.max_val = sp->sp_max;
+ arguments.warn_val = sp->sp_warn;
+ arguments.inact_val = sp->sp_inact;
+ arguments.expire_date = sp->sp_expire;
/* Note: from this point on we know that username is valid,
* since it existed in the user database, hence we can
@@ -448,7 +305,7 @@ int main(int argc, char *argv[])
while (1) {
fprintf(stdout,
_("\tMinimum Password Age [%ld]: "),
- expiry.min);
+ arguments.min_val);
(void)fflush(stdout);
if (!(min = input_string(1))) {
@@ -471,7 +328,7 @@ int main(int argc, char *argv[])
}
if ((status = string_to_long(min,
- (void **)&expiry.min))) {
+ (void
**)&arguments.min_val))) {
fprintf(stderr,
_("%s: `%s' failed; %s\n"),
progname, "string_to_long",
@@ -487,7 +344,7 @@ int main(int argc, char *argv[])
while (1) {
fprintf(stdout,
_("\tMaximum Password Age [%ld]: "),
- expiry.max);
+ arguments.max_val);
(void)fflush(stdout);
if (!(max = input_string(1))) {
@@ -510,7 +367,7 @@ int main(int argc, char *argv[])
}
if ((status = string_to_long(max,
- (void **)&expiry.max))) {
+ (void
**)&arguments.max_val))) {
fprintf(stderr,
_("%s: `%s' failed; %s\n"),
progname, "string_to_long",
@@ -526,7 +383,7 @@ int main(int argc, char *argv[])
while (1) {
fprintf(stdout,
_("\tLast Password Change (YYYY-MM-DD) [%s]: "),
- date_to_string(expiry.lstchg));
+ date_to_string(arguments.lstchg_date));
(void)fflush(stdout);
if (!(lstchg = input_string(1))) {
@@ -549,7 +406,7 @@ int main(int argc, char *argv[])
}
if ((status = string_to_date(lstchg,
- (void **)&expiry.lstchg)))
{
+ (void
**)&arguments.lstchg_date))) {
fprintf(stderr,
_("%s: `%s' failed; %s\n"),
progname, "string_to_date",
@@ -565,7 +422,7 @@ int main(int argc, char *argv[])
while (1) {
fprintf(stdout,
_("\tPassword Expiration Warning [%ld]: "),
- expiry.warn);
+ arguments.warn_val);
(void)fflush(stdout);
if (!(warn = input_string(1))) {
@@ -588,7 +445,7 @@ int main(int argc, char *argv[])
}
if ((status = string_to_long(warn,
- (void **)&expiry.warn))) {
+ (void
**)&arguments.warn_val))) {
fprintf(stderr,
_("%s: `%s' failed; %s\n"),
progname, "string_to_long",
@@ -604,7 +461,7 @@ int main(int argc, char *argv[])
while (1) {
fprintf(stdout,
_("\tPassword Inactive [%ld]: "),
- expiry.inact);
+ arguments.inact_val);
(void)fflush(stdout);
if (!(inact = input_string(1))) {
@@ -627,7 +484,7 @@ int main(int argc, char *argv[])
}
if ((status = string_to_long(inact,
- (void **)&expiry.inact))) {
+ (void
**)&arguments.inact_val))) {
fprintf(stderr,
_("%s: `%s' failed; %s\n"),
progname, "string_to_long",
@@ -643,7 +500,7 @@ int main(int argc, char *argv[])
while (1) {
fprintf(stdout,
_("\tAccount Expiration Date (YYYY-MM-DD) [%s]:
"),
- date_to_string(expiry.expire));
+ date_to_string(arguments.expire_date));
(void)fflush(stdout);
if (!(expire = input_string(1))) {
@@ -666,7 +523,7 @@ int main(int argc, char *argv[])
}
if ((status = string_to_date(expire,
- (void **)&expiry.expire))) {
+ (void
**)&arguments.expire_date))) {
fprintf(stderr,
_("%s: `%s' failed; %s\n"),
progname, "string_to_date",
@@ -731,18 +588,18 @@ int main(int argc, char *argv[])
/* If the entry is part of the array of users to edit,
* perform changes; if not, copy the old values
*/
- if (is_in_array(usrarray, sp->sp_namp)) {
- sp2.sp_lstchg = (expiry.lstchg != -2) ? expiry.lstchg :
+ if (is_in_array(arguments.users, sp->sp_namp)) {
+ sp2.sp_lstchg = (arguments.lstchg_date != -2) ?
arguments.lstchg_date :
sp->sp_lstchg;
- sp2.sp_min = (expiry.min != -2) ? expiry.min :
+ sp2.sp_min = (arguments.min_val != -2) ?
arguments.min_val :
sp->sp_min;
- sp2.sp_max = (expiry.max != -2) ? expiry.max :
+ sp2.sp_max = (arguments.max_val != -2) ?
arguments.max_val :
sp->sp_max;
- sp2.sp_warn = (expiry.warn != -2) ? expiry.warn :
+ sp2.sp_warn = (arguments.warn_val != -2) ?
arguments.warn_val :
sp->sp_warn;
- sp2.sp_inact = (expiry.inact != -2) ? expiry.inact :
+ sp2.sp_inact = (arguments.inact_val != -2) ?
arguments.inact_val :
sp->sp_inact;
- sp2.sp_expire = (expiry.expire != -2) ? expiry.expire :
+ sp2.sp_expire = (arguments.expire_date != -2) ?
arguments.expire_date :
sp->sp_expire;
changed = 1;
}
- [Bug-sysutils] Updated patch for chage.c,
Barry deFreese <=