Commit 0f7330e4 0f7330e4cc079e59c3d8ea69f55a2dde1238cd95 by Sergey Poznyakoff

Parse arguments using mu_argp instead of getopt_long.

1 parent 301bef05
......@@ -17,28 +17,8 @@
#include "pop3d.h"
static char short_options[] = "acdf:hlmo:p:u:v";
static struct option long_options[] =
{
{ "add", no_argument, 0, 'a' },
{ "create", no_argument, 0, 'c' },
{ "modify", no_argument, 0, 'm' },
{ "delete", no_argument, 0, 'd' },
{ "file", required_argument, 0, 'f' },
{ "help", no_argument, 0, 'h' },
{ "list", no_argument, 0, 'l' },
{ "output", required_argument, 0, 'o' },
{ "password", required_argument, 0, 'p' },
{ "user", required_argument, 0, 'u' },
{ "version", no_argument, 0, 'v', },
{ 0, 0, 0, 0 }
};
int db_list (char *input_name, char *output_name);
int db_make (char *input_name, char *output_name);
static void help (void);
static void version (void);
#define ACT_CREATE 0
#define ACT_ADD 1
......@@ -47,6 +27,7 @@ static void version (void);
#define ACT_CHPASS 4
struct action_data {
int action;
char *input_name;
char *output_name;
char *username;
......@@ -68,84 +49,124 @@ int (*ftab[]) __P((struct action_data *)) = {
action_chpass
};
int
main(int argc, char **argv)
{
int c;
int action = -1;
struct action_data adata;
const char *argp_program_version = "popauth (" PACKAGE_STRING ")";
static char doc[] = "GNU popauth -- manage pop3 authentcation database";
static error_t popauth_parse_opt __P((int key, char *arg,
struct argp_state *astate));
memset (&adata, 0, sizeof adata);
void popauth_version __P((FILE *stream, struct argp_state *state));
void (*argp_program_version_hook) __P((FILE *stream,
struct argp_state *state)) =
popauth_version;
while ((c = getopt_long (argc, argv, short_options, long_options, NULL))
!= -1)
{
switch (c)
{
case 'a':
check_action (action);
action = ACT_ADD;
break;
static struct argp_option options[] =
{
{ NULL, 0, NULL, 0, "Actions are:", 1 },
{ "add", 'a', 0, 0, "Add user", 1 },
{ "modify", 'm', 0, 0, "Modify user's record (change password)", 1 },
{ "delete", 'd', 0, 0, "Delete user's record", 1 },
{ "list", 'l', 0, 0, "List the contents of DBM file", 1 },
{ NULL, 0, NULL, 0,
"Default action is:\n"
" For the file owner: --list\n"
" For a user: --modify --username <username>\n", 2 },
{ NULL, 0, NULL, 0, "Options are:", 3 },
{ "file", 'f', "FILE", 0, "Read input from FILE (default stdin)", 3 },
{ "output", 'o', "FILE", 0, "Direct output to file", 3 },
{ "password", 'p', "STRING", 0, "Specify user's password", 3 },
{ "user", 'u', "USERNAME", 0, "Specify user name", 3 },
{ NULL, }
};
case 'c':
check_action (action);
action = ACT_CREATE;
break;
case 'l':
check_action (action);
action = ACT_LIST;
break;
case 'd':
check_action (action);
action = ACT_DELETE;
break;
case 'p':
adata.passwd = optarg;
break;
static struct argp argp = {
options,
popauth_parse_opt,
NULL,
doc,
NULL,
NULL, NULL
};
case 'm':
check_action (action);
action = ACT_CHPASS;
break;
case 'f':
adata.input_name = optarg;
break;
case 'h':
help ();
break;
case 'o':
adata.output_name = optarg;
break;
static const char *popauth_argp_capa[] = {
"common",
"license",
NULL
};
case 'u':
adata.username = optarg;
break;
static error_t
popauth_parse_opt (int key, char *arg, struct argp_state *astate)
{
struct action_data *ap = astate->input;
switch (key)
{
case ARGP_KEY_INIT:
memset (ap, 0, sizeof(*ap));
ap->action = -1;
break;
case 'a':
check_action (ap->action);
ap->action = ACT_ADD;
break;
case 'l':
check_action (ap->action);
ap->action = ACT_LIST;
break;
case 'd':
check_action (ap->action);
ap->action = ACT_DELETE;
break;
case 'v':
version ();
break;
case 'p':
ap->passwd = optarg;
break;
case 'm':
check_action (ap->action);
ap->action = ACT_CHPASS;
break;
case 'f':
ap->input_name = optarg;
break;
default:
break;
case 'o':
ap->output_name = optarg;
break;
case 'u':
ap->username = optarg;
break;
case ARGP_KEY_FINI:
if (ap->action == -1)
{
/* Deduce the default action */
if (getuid () == 0)
ap->action = ACT_LIST;
else
ap->action = ACT_CHPASS;
}
default:
return ARGP_ERR_UNKNOWN;
}
return 0;
}
if (action == -1)
{
/* Deduce the default action */
if (getuid () == 0)
action = ACT_LIST;
else
action = ACT_CHPASS;
}
int
main(int argc, char **argv)
{
struct action_data adata;
mu_argp_parse (&argp, &argc, &argv, 0,
popauth_argp_capa, NULL, &adata);
return (*ftab[action]) (&adata);
return (*ftab[adata.action]) (&adata);
}
void
......@@ -170,8 +191,23 @@ check_user_perm (int action, struct action_data *ap)
if (mu_dbm_stat (ap->input_name, &sb))
{
mu_error ("can't stat %s: %s", ap->input_name, strerror (errno));
exit (1);
if (ap->action == ACT_ADD)
{
DBM_FILE db;
if (mu_dbm_open (ap->input_name, &db, MU_STREAM_CREAT, 0600))
{
mu_error ("can't create %s: %s",
ap->input_name, strerror (errno));
exit (1);
}
mu_dbm_close (db);
mu_dbm_stat (ap->input_name, &sb);
}
else
{
mu_error ("can't stat %s: %s", ap->input_name, strerror (errno));
exit (1);
}
}
uid = getuid ();
......@@ -499,32 +535,8 @@ action_chpass (struct action_data *ap)
return rc;
}
static void
help ()
{
printf ("Usage: popauth [OPTIONS] [ACTION]\n");
printf ("Manipulates pop3d authentication database.\n\n");
printf ("Options are:\n");
printf (" -f, --file=FILE Read input from FILE (default stdin)\n");
printf (" -o, --output=FILE Direct output to FILE\n");
printf (" -h, --help Display this help and exit\n");
printf (" -u, --user=USERNAME Specify the user name\n");
printf (" -p, --password=PASS Specify user's password\n");
printf (" -v, --version Display program version\n");
printf ("Actions are:\n");
printf (" -a, --add Add user\n");
printf (" -l, --list List the contents of DBM file\n");
printf (" -d, --delete Delete the given user\n");
printf (" -m, --modify Modify user's record (change password)\n");
printf ("\nDefault action is:\n");
printf (" For the file owner: --list\n");
printf (" For a user: --modify --username <username>\n");
printf ("\nReport bugs to bug-mailutils@gnu.org\n");
exit (EXIT_SUCCESS);
}
static void
version ()
void
popauth_version (FILE *stream, struct argp_state *state)
{
#if defined(WITH_GDBM)
# define FORMAT "GDBM"
......@@ -535,7 +547,7 @@ version ()
#elif defined(WITH_OLD_DBM)
# define FORMAT "Old DBM"
#endif
printf ("popauth: %s (%s)\n", PACKAGE, VERSION);
printf ("%s\n", argp_program_version);
printf ("Database format: %s\n", FORMAT);
printf ("Database location: %s\n", APOP_PASSFILE);
exit (EXIT_SUCCESS);
......
......@@ -18,30 +18,96 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <mailutils/argp.h>
#include "readmsg.h"
#define WEEDLIST_SEPARATOR " :,"
static void usage __P ((int, const char *));
static void print_header __P ((message_t, int no_header, int all_header, const char *weedlst));
static void print_body __P ((message_t));
static int string_starts_with __P ((const char * s1, const char *s2));
const char *short_options = "adnhpf:w:";
static struct option long_options[] =
const char *argp_program_version = "readmsg (" PACKAGE_STRING ")";
static char doc[] = "GNU readmsg -- print messages";
static error_t readmsg_parse_opt __P((int key, char *arg,
struct argp_state *astate));
static struct argp_option options[] =
{
{"debug", no_argument, 0, 'd'},
{"header", no_argument, 0, 'h'},
{"weedlist", required_argument, 0, 'w'},
{"folder", no_argument, 0, 'f'},
{"no-header", no_argument, 0, 'n'},
{"form-feeds", no_argument, 0, 'p'},
{"show-all-match", required_argument, 0, 'a'},
{"help", no_argument, 0, '&'},
{"version", no_argument, 0, 'v'},
{ "debug", 'd', 0, 0, "Display debugging information", 1 },
{ "header", 'h', 0, 0, "Display entire header", 1 },
{ "weedlist", 'w', "LIST", 0, "List of header names separated by whitespace or commas", 1 },
{ "folder", 'f', "FOLDER", 0, "Folder to use", 1 },
{ "no-header", 'n', 0, 0, "Exclude all headers", 1 },
{ "form-feeds", 'p', 0, 0, "Output formfeeds between messages", 1 },
{ "show-all-match", 'a', "PATTERN", 0,
"Print all messages matching PATTERN", 1 },
{0, 0, 0, 0}
};
static struct argp argp = {
options,
readmsg_parse_opt,
NULL,
doc,
NULL,
NULL, NULL
};
static const char *readmsg_argp_capa[] = {
"common",
"mailbox",
NULL
};
int dbug = 0;
const char *mailbox_name = NULL;
const char *weedlist = NULL;
int no_header = 0;
int all_header = 0;
int form_feed = 0;
int show_all = 0;
static error_t
readmsg_parse_opt (int key, char *arg, struct argp_state *astate)
{
switch (key)
{
case 'd':
dbug++;
break;
case 'h':
all_header = 1;
break;
case 'f':
mailbox_name = optarg;
break;
case 'w':
weedlist = optarg;
break;
case 'n':
no_header = 1;
break;
case 'p':
form_feed = 1;
break;
case 'a':
show_all = 1;
break;
default:
return ARGP_ERR_UNKNOWN;
}
return 0;
}
static int
string_starts_with (const char * s1, const char *s2)
{
......@@ -62,7 +128,8 @@ string_starts_with (const char * s1, const char *s2)
}
static void
print_header (message_t message, int no_header, int all_headers, const char *weedlist)
print_header (message_t message, int no_header, int all_headers,
const char *weedlist)
{
header_t header = NULL;
......@@ -79,7 +146,8 @@ print_header (message_t message, int no_header, int all_headers, const char *wee
char buf[128];
header_get_stream (header, &stream);
while (stream_read (stream, buf, sizeof (buf) - 1, offset, &len) == 0 && len != 0)
while (stream_read (stream, buf, sizeof (buf) - 1, offset, &len) == 0
&& len != 0)
{
buf[len] ='\0';
printf ("%s", buf);
......@@ -130,7 +198,9 @@ print_body (message_t message)
size_t len = 0;
message_get_body (message, &body);
body_get_stream (body, &stream);
while (stream_read (stream, buf, sizeof (buf) - 1, offset, &len) == 0 && len != 0)
while (stream_read (stream, buf, sizeof (buf) - 1, offset, &len) == 0
&& len != 0)
{
buf[len] ='\0';
printf ("%s", buf);
......@@ -138,32 +208,6 @@ print_body (message_t message)
}
}
static void
usage (int status, const char *prognam)
{
if (status == 0)
{
printf ("GNU Mailutils.\n");
printf ("Usage: %s [OPTIONS]\n\n", prognam);
printf (" -d, --debug display debuging information\n");
printf (" -h, --header display the entire header\n");
printf (" -f, --folder=FILE folder to use\n");
printf (" -w, --weelist=LIST list of header names separated by whitespace or commas\n");
printf (" -n, --no-header exclude all headers\n");
printf (" -p, --form-feeds put form-feeds between messages instead of newline\n");
printf (" -a, --show-all-match print all message matching PATTERN\n");
printf (" --help display this help and exit\n");
printf (" -v, --version display version information and exit\n");
printf ("\nReport bugs to bug-mailutils@gnu.org\n");
}
else
{
printf ("Try: %s --help\n", prognam);
}
exit (status);
}
/* This is still work in progress */
/* FIXME: Parse options: See readmsg(1) part of elm:
readmsg 1 3 0
......@@ -176,64 +220,10 @@ main (int argc, char **argv)
int *set = NULL;
int n = 0;
int i;
int c;
int dbug = 0;
const char *mailbox_name = NULL;
const char *weedlist = NULL;
int no_header = 0;
int all_header = 0;
int form_feed = 0;
int show_all = 0;
int index;
mailbox_t mbox = NULL;
while ((c = getopt_long (argc, argv, short_options, long_options, NULL))
!= -1)
{
switch (c)
{
case 'd':
dbug++;
break;
case 'h':
all_header = 1;
break;
case 'f':
mailbox_name = optarg;
break;
case 'w':
weedlist = optarg;
break;
case 'n':
no_header = 1;
break;
case 'p':
form_feed = 1;
break;
case 'a':
show_all = 1;
break;
case '&':
usage (0, argv[0]);
break;
case 'v':
printf ("Mailutils 0.0.0: readmsg\n");
exit (0);
break;
default:
usage (1, argv[0]);
break;
}
}
mu_argp_parse (&argp, &argc, &argv, 0, readmsg_argp_capa, &index, NULL);
/* Registration. */
{
......@@ -273,7 +263,7 @@ main (int argc, char **argv)
/* Build an array containing the message number. */
argc -= optind;
if (argc > 0)
msglist (mbox, show_all, argc, &argv[optind], &set, &n);
msglist (mbox, show_all, argc, &argv[index], &set, &n);
for (i = 0; i < n; ++i)
{
......@@ -282,7 +272,8 @@ main (int argc, char **argv)
status = mailbox_get_message (mbox, set[i], &msg);
if (status != 0)
{
fprintf (stderr, "mailbox_get_message - %s\n", mu_errstring (status));
fprintf (stderr, "mailbox_get_message - %s\n",
mu_errstring (status));
exit (2);
}
......