diff options
author | Eric S. Raymond <esr@thyrsus.com> | 1996-10-17 16:42:58 +0000 |
---|---|---|
committer | Eric S. Raymond <esr@thyrsus.com> | 1996-10-17 16:42:58 +0000 |
commit | 6acb0b4730875ea953f04df5fa6c5680fd98ca09 (patch) | |
tree | e25242b148b18f9356645cb37650dc94acffb468 | |
parent | a9eb6d847ec9c80ad409cfd9ffff6777bc9bb0dd (diff) | |
download | fetchmail-6acb0b4730875ea953f04df5fa6c5680fd98ca09.tar.gz fetchmail-6acb0b4730875ea953f04df5fa6c5680fd98ca09.tar.bz2 fetchmail-6acb0b4730875ea953f04df5fa6c5680fd98ca09.zip |
Allow C-style escapes in strings.
svn path=/trunk/; revision=344
-rw-r--r-- | NEWS | 3 | ||||
-rw-r--r-- | fetchmail.c | 111 | ||||
-rw-r--r-- | fetchmail.h | 2 | ||||
-rw-r--r-- | fetchmail.man | 6 | ||||
-rw-r--r-- | rcfile_l.l | 13 |
5 files changed, 124 insertions, 11 deletions
@@ -19,6 +19,9 @@ features -- * Password is no longer displayed in verbose mode. +* You may use C-like escapes to embed non-printables in passwords and other + strings. Fetchmail -V will display them in a printable form. + bugs -- * Default user name to deliver to is now the calling user, unless diff --git a/fetchmail.c b/fetchmail.c index 2c204a9e..08ca78f9 100644 --- a/fetchmail.c +++ b/fetchmail.c @@ -41,6 +41,7 @@ /* prototypes for internal functions */ static int dump_options (struct hostrec *queryctl); static int query_host(struct hostrec *queryctl); +static char *visbuf(const char *); #endif /* controls the detail level of status/progress messages written to stderr */ @@ -526,18 +527,18 @@ int dump_params (queryctl) struct hostrec *queryctl; { printf("Options for %s retrieving from %s:\n", - hostp->localname, hostp->servername); + hostp->localname, visbuf(hostp->servername)); if (queryctl->skip || outlevel == O_VERBOSE) printf(" This host will%s be queried when no host is specified.\n", queryctl->skip ? " not" : ""); - printf(" Username = '%s'.\n", queryctl->remotename); + printf(" Username = '%s'.\n", visbuf(queryctl->remotename)); if (queryctl->password[0] == '\0') printf(" Password will be prompted for.\n"); else if (outlevel == O_VERBOSE) if (queryctl->protocol == P_APOP) - printf(" APOP secret = '%s'.\n", queryctl->password); + printf(" APOP secret = '%s'.\n", visbuf(queryctl->password)); else - printf(" Password = '%s'.\n", queryctl->password); + printf(" Password = '%s'.\n", visbuf(queryctl->password)); if (queryctl->protocol == P_POP3 && queryctl->port == KPOP_PORT && queryctl->authenticate == A_KERBEROS) @@ -577,14 +578,14 @@ struct hostrec *queryctl; char **cp; printf(" Messages will be delivered with %s, args:", - queryctl->mda_argv[0]); + visbuf(queryctl->mda_argv[0])); for (cp = queryctl->mda_argv+1; *cp; cp++) - printf(" %s", *cp); + printf(" %s", visbuf(*cp)); putchar('\n'); } else printf(" Messages will be SMTP-forwarded to '%s'.\n", - queryctl->smtphost); + visbuf(queryctl->smtphost)); if (queryctl->protocol > P_POP2) if (!queryctl->oldsaved) printf(" No UIDs saved from this host.\n"); @@ -603,7 +604,7 @@ struct hostrec *queryctl; } } -/********************************************************************* + /********************************************************************* function: openmailpipe description: open a one-way pipe to the mail delivery agent. arguments: @@ -694,3 +695,97 @@ int fd; return(err); } + +/* helper functions for string interpretation and display */ + +#define CTRL(x) ((x) & 0x1f) + +void escapes(cp, tp) +/* process standard C-style escape sequences in a string */ +const char *cp; +char *tp; +{ + while (*cp) + { + int cval = 0; + + if (*cp == '\\' && strchr("0123456789xX", cp[1])) + { + char *dp, *hex = "00112233445566778899aAbBcCdDeEfF"; + int dcount = 0; + + if (*++cp == 'x' || *cp == 'X') + for (++cp; (dp = strchr(hex, *cp)) && (dcount++ < 2); cp++) + cval = (cval * 16) + (dp - hex) / 2; + else if (*cp == '0') + while (strchr("01234567",*cp) != (char*)NULL && (dcount++ < 3)) + cval = (cval * 8) + (*cp++ - '0'); + else + while ((strchr("0123456789",*cp)!=(char*)NULL)&&(dcount++ < 3)) + cval = (cval * 10) + (*cp++ - '0'); + } + else if (*cp == '\\') /* C-style character escapes */ + { + switch (*++cp) + { + case '\\': cval = '\\'; break; + case 'n': cval = '\n'; break; + case 't': cval = '\t'; break; + case 'b': cval = '\b'; break; + case 'r': cval = '\r'; break; + default: cval = *cp; + } + cp++; + } + else if (*cp == '^') /* expand control-character syntax */ + { + cval = CTRL(*++cp); + cp++; + } + else + cval = *cp++; + *tp++ = cval; + } + *tp = '\0'; +} + +static char *visbuf(buf) +/* visibilize a given string */ +const char *buf; +{ + static char vbuf[BUFSIZ]; + char *tp = vbuf; + + while (*buf) + { + if (isprint(*buf) || *buf == ' ') + *tp++ = *buf++; + else if (*buf == '\n') + { + *tp++ = '\\'; *tp++ = 'n'; + buf++; + } + else if (*buf == '\r') + { + *tp++ = '\\'; *tp++ = 'r'; + buf++; + } + else if (*buf == '\b') + { + *tp++ = '\\'; *tp++ = 'b'; + buf++; + } + else if (*buf < ' ') + { + *tp++ = '\\'; *tp++ = '^'; *tp++ = '@' + *buf; + buf++; + } + else + { + (void) sprintf(tp, "\\0x%02x", *buf++); + tp += strlen(tp); + } + } + *tp++ = '\0'; + return(vbuf); +} diff --git a/fetchmail.h b/fetchmail.h index 392417dd..c5ef2496 100644 --- a/fetchmail.h +++ b/fetchmail.h @@ -170,6 +170,8 @@ char *MD5Digest (char *); int openmailpipe (struct hostrec *); int daemonize(const char *, void (*)(int)); +void escapes(const char *, char *); + #else struct hostrec *hostinit(); diff --git a/fetchmail.man b/fetchmail.man index 835cd20a..15df5fb8 100644 --- a/fetchmail.man +++ b/fetchmail.man @@ -188,7 +188,9 @@ No POP connection is made. Instead, for each server specified, all option information that would be computed if .I fetchmail. -were connecting to that server is displayed. +were connecting to that server is displayed. Any non-printables in +passwords or other string names are shown as backslashed C-like +escape sequences. .PP Each server name that you specify following the options on the command line will be queried. If you don't specify any servers @@ -365,6 +367,8 @@ Any amount of whitespace separates keywords, tokens, or strings in server entries but is otherwise ignored (but whitespace enclosed in double quotes is treated as part of the string). Keywords and identifiers are case sensitive. +You may use standard C-style escapes (\en, \et, \eb, octal, and hex) +to embed non-printable characters or string delimiters in strings. When there is a conflict between the command-line arguments and the arguments in this file, the command-line arguments take precedence. .PP @@ -71,11 +71,20 @@ options {/* EMPTY */} [0-9]+ { yylval.number = atoi(yytext); return NUMBER; } \"[^\"]*\" { + char buf[POPBUFSIZE]; + yytext[strlen(yytext)-1] = '\0'; - yylval.sval = (char *) strdup(yytext+1); + escapes(yytext+1, buf); + yylval.sval = (char *) strdup(buf); + return STRING; + } +[^;:, \t\r\n]+ { + char buf[POPBUFSIZE]; + + escapes(yytext, buf); + yylval.sval = (char *) strdup(buf); return STRING; } -[^;:, \t\r\n]+ { yylval.sval = (char *) strdup(yytext); return STRING; } [ \t\r]+ ; /* whitespace */ |