Pass in output function to lbuf_init() instead of writing to stdout.

A side effect is that the usage info can now go to stderr as it should.
This commit is contained in:
Todd C. Miller
2010-03-18 06:42:17 -04:00
parent 038ec569de
commit b4f4afdf69
8 changed files with 50 additions and 23 deletions

View File

@@ -23,15 +23,16 @@
* Line buffer struct. * Line buffer struct.
*/ */
struct lbuf { struct lbuf {
int (*output)(const char *);
char *buf; char *buf;
int continuation; const char *continuation;
int indent; int indent;
int len; int len;
int size; int size;
int cols; int cols;
}; };
void lbuf_init (struct lbuf *, char *, int, int, int); void lbuf_init(struct lbuf *, int (*)(const char *), int, const char *, int);
void lbuf_destroy(struct lbuf *); void lbuf_destroy(struct lbuf *);
void lbuf_append(struct lbuf *, ...); void lbuf_append(struct lbuf *, ...);
void lbuf_append_quoted(struct lbuf *, const char *, ...); void lbuf_append_quoted(struct lbuf *, const char *, ...);

View File

@@ -52,8 +52,6 @@
#include "sudo_auth.h" #include "sudo_auth.h"
#include "insults.h" #include "insults.h"
sudo_conv_t sudo_conv;
sudo_auth auth_switch[] = { sudo_auth auth_switch[] = {
#ifdef AUTH_STANDALONE #ifdef AUTH_STANDALONE
AUTH_STANDALONE AUTH_STANDALONE

View File

@@ -75,8 +75,6 @@ static char *expand_prompt(char *, char *, char *);
static void lecture(int); static void lecture(int);
static void update_timestamp(char *, char *); static void update_timestamp(char *, char *);
extern sudo_conv_t sudo_conv;
/* /*
* This function only returns if the user can successfully * This function only returns if the user can successfully
* verify who he/she is. * verify who he/she is.

View File

@@ -224,10 +224,27 @@ reset_groups(pw)
#endif #endif
} }
static int
output(const char *buf)
{
struct sudo_conv_message msg;
struct sudo_conv_reply repl;
/* Call conversation function */
memset(&msg, 0, sizeof(msg));
msg.msg_type = SUDO_CONV_INFO_MSG;
msg.msg = buf;
memset(&repl, 0, sizeof(repl));
if (sudo_conv(1, &msg, &repl) == -1)
return 0;
return (int)strlen(buf);
}
/* /*
* Print out privileges for the specified user. * Print out privileges for the specified user.
* We only get here if the user is allowed to run something on this host. * We only get here if the user is allowed to run something on this host.
*/ */
/* XXX - conversation function or newlines in lbuf */
void void
display_privs(snl, pw) display_privs(snl, pw)
struct sudo_nss_list *snl; struct sudo_nss_list *snl;
@@ -240,7 +257,7 @@ display_privs(snl, pw)
/* Reset group vector so group matching works correctly. */ /* Reset group vector so group matching works correctly. */
reset_groups(pw); reset_groups(pw);
lbuf_init(&lbuf, NULL, 4, 0, sudo_user.cols); lbuf_init(&lbuf, output, 4, NULL, sudo_user.cols);
/* Display defaults from all sources. */ /* Display defaults from all sources. */
count = 0; count = 0;

View File

@@ -152,6 +152,8 @@ login_cap_t *lc;
char *login_style; char *login_style;
#endif /* HAVE_BSD_AUTH_H */ #endif /* HAVE_BSD_AUTH_H */
sigaction_t saved_sa_int, saved_sa_quit, saved_sa_tstp; sigaction_t saved_sa_int, saved_sa_quit, saved_sa_tstp;
sudo_conv_t sudo_conv;
static char *runas_user; static char *runas_user;
static char *runas_group; static char *runas_group;
static struct sudo_nss_list *snl; static struct sudo_nss_list *snl;

View File

@@ -307,6 +307,7 @@ extern struct passwd *auth_pw, *list_pw;
extern int tgetpass_flags; /* XXX */ extern int tgetpass_flags; /* XXX */
extern int long_list; extern int long_list;
extern uid_t timestamp_uid; extern uid_t timestamp_uid;
extern sudo_conv_t sudo_conv;
#endif #endif
#ifndef errno #ifndef errno
extern int errno; extern int errno;

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2007-2009 Todd C. Miller <Todd.Miller@courtesan.com> * Copyright (c) 2007-2010 Todd C. Miller <Todd.Miller@courtesan.com>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -58,8 +58,10 @@
*/ */
void void
lbuf_init(struct lbuf *lbuf, char *buf, int indent, int continuation, int cols) lbuf_init(struct lbuf *lbuf, int (*output)(const char *),
int indent, const char *continuation, int cols)
{ {
lbuf->output = output;
lbuf->continuation = continuation; lbuf->continuation = continuation;
lbuf->indent = indent; lbuf->indent = indent;
lbuf->cols = cols; lbuf->cols = cols;
@@ -163,10 +165,10 @@ lbuf_append(struct lbuf *lbuf, ...)
void void
lbuf_print(struct lbuf *lbuf) lbuf_print(struct lbuf *lbuf)
{ {
char *cp; char *cp, save;
int i, have, contlen; int i, have, contlen;
contlen = lbuf->continuation ? 2 : 0; contlen = lbuf->continuation ? strlen(lbuf->continuation) : 0;
/* For very small widths just give up... */ /* For very small widths just give up... */
if (lbuf->cols <= lbuf->indent + contlen + 20) { if (lbuf->cols <= lbuf->indent + contlen + 20) {
@@ -198,9 +200,13 @@ lbuf_print(struct lbuf *lbuf)
if (cp != lbuf->buf) { if (cp != lbuf->buf) {
/* indent continued lines */ /* indent continued lines */
for (i = 0; i < lbuf->indent; i++) for (i = 0; i < lbuf->indent; i++)
putchar(' '); lbuf->output(" ");
} }
fwrite(cp, need, 1, stdout); /* NUL-terminate cp for the output function and restore afterwards */
save = cp[need];
cp[need] = '\0';
lbuf->output(cp);
cp[need] = save;
cp = ep; cp = ep;
/* /*
@@ -212,12 +218,10 @@ lbuf_print(struct lbuf *lbuf)
do { do {
cp++; cp++;
} while (isspace((unsigned char)*cp)); } while (isspace((unsigned char)*cp));
if (lbuf->continuation) { if (contlen)
putchar(' '); lbuf->output(lbuf->continuation);
putchar(lbuf->continuation);
} }
} lbuf->output("\n");
putchar('\n');
} }
done: done:

View File

@@ -373,6 +373,12 @@ parse_args(int argc, char **argv, int *nargc, char ***nargv, char ***settingsp,
return(mode | flags); return(mode | flags);
} }
static int
usage_out(const char *buf)
{
return fputs(buf, stderr);
}
/* /*
* Give usage message and exit. * Give usage message and exit.
* The actual usage strings are in sudo_usage.h for configure substitution. * The actual usage strings are in sudo_usage.h for configure substitution.
@@ -404,7 +410,7 @@ usage(int exit_val)
* tty width. * tty width.
*/ */
ulen = (int)strlen(getprogname()) + 8; ulen = (int)strlen(getprogname()) + 8;
lbuf_init(&lbuf, NULL, ulen, 0, user_details.ts_cols); lbuf_init(&lbuf, usage_out, ulen, NULL, user_details.ts_cols);
for (i = 0; uvec[i] != NULL; i++) { for (i = 0; uvec[i] != NULL; i++) {
lbuf_append(&lbuf, "usage: ", getprogname(), uvec[i], NULL); lbuf_append(&lbuf, "usage: ", getprogname(), uvec[i], NULL);
lbuf_print(&lbuf); lbuf_print(&lbuf);