]> Pileus Git - ~andy/fetchmail/commitdiff
Allow C-style escapes in strings.
authorEric S. Raymond <esr@thyrsus.com>
Thu, 17 Oct 1996 16:42:58 +0000 (16:42 -0000)
committerEric S. Raymond <esr@thyrsus.com>
Thu, 17 Oct 1996 16:42:58 +0000 (16:42 -0000)
svn path=/trunk/; revision=344

NEWS
fetchmail.c
fetchmail.h
fetchmail.man
rcfile_l.l

diff --git a/NEWS b/NEWS
index b2ea04b49178c2fc35698f368d6a687260c730fb..965714b7c8e22c19c63a4e09639f5c53bcc20ce3 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -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
index 2c204a9eb06c418f0c3204e4b7a74ee790534abf..08ca78f9d964dc2268e57a9c4396e6806229cb22 100644 (file)
@@ -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);
+}
index 392417dd395548ebaf0b3b306821a65702fb2955..c5ef2496588ac028e6f1c3953123f998709dd8e1 100644 (file)
@@ -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(); 
index 835cd20ad6546fb8f2d9454107aede1df1083a04..15df5fb8d78c567f2a0636ebc48aaa9e4bdf9096 100644 (file)
@@ -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
index 000b10d96a9fd134644a7858935f995a47af283c..99558152d8b208e9b62d08b167c9792ec25d5381 100644 (file)
@@ -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 */