Improved quoting the fullname.
authormarkus schnalke <meillo@marmaro.de>
Sat, 4 Feb 2012 15:12:22 +0000 (16:12 +0100)
committermarkus schnalke <meillo@marmaro.de>
Sat, 4 Feb 2012 15:12:22 +0000 (16:12 +0100)
sbr/mts.c

index 6b8b3a2..f43b15d 100644 (file)
--- a/sbr/mts.c
+++ b/sbr/mts.c
@@ -132,16 +132,17 @@ getfullname(void)
 static void
 getuserinfo(void)
 {
-       register unsigned char *cp;
-       register char *np;
-       register struct passwd *pw;
-
-       if ((pw = getpwuid(getuid())) == NULL
-               || pw->pw_name == NULL
-               || *pw->pw_name == '\0') {
+       unsigned char *cp;
+       char *np;
+       struct passwd *pw;
+       int needquotes = 0;
+       char tmp[BUFSIZ];
+       char *tp;
+
+       if (!(pw = getpwuid(getuid())) || !pw->pw_name || !*pw->pw_name) {
                strncpy(username, "unknown", sizeof(username));
-               snprintf(fullname, sizeof(fullname), "The Unknown User-ID (%d)",
-                       (int) getuid());
+               snprintf(fullname, sizeof(fullname),
+                               "The Unknown User-ID (%d)", (int)getuid());
                return;
        }
 
@@ -152,7 +153,7 @@ getuserinfo(void)
        ** we hit a ',', which some OSes use to separate other 'finger'
        ** information in the GECOS field, like phone number.
        */
-       for (cp = fullname; *np != '\0' && *np != ',';) {
+       for (cp = tmp; *np != '\0' && *np != ',';) {
 #ifndef BSD42
                *cp++ = *np++;
 #else /* BSD42 */
@@ -185,15 +186,36 @@ getuserinfo(void)
        ** idea of your real name.
        */
        if ((cp = getenv("SIGNATURE")) && *cp)
-               strncpy(fullname, cp, sizeof(fullname));
-
-       if (strchr(fullname, '.')) {  /*  quote any .'s */
-               char tmp[BUFSIZ];
-
-               /* should quote "'s too */
-               snprintf(tmp, sizeof(tmp), "\"%s\"", fullname);
-               strncpy(fullname, tmp, sizeof(fullname));
+               strncpy(tmp, cp, sizeof(tmp));
+
+       /* quote the fullname as needed */
+       needquotes = 0;
+       for (tp=tmp; *tp; tp++) {
+               switch (*tp) {
+               case '(': case ')': case '<': case '>': case '[': case ']':
+               case ':': case ';': case '@': case '\\': case ',': case '.':
+               case '"':  /* cf. RFC 5322 */
+                       break;  /* ... the switch */
+               default:
+                       continue;  /* ... the loop */
+               }
+               /* we've found a special char */
+               needquotes = 1;
+               break;
+       }
+       cp=fullname;
+       if (needquotes) {
+               *cp++ = '"';
        }
+       for (tp=tmp; *tp; *cp++=*tp++) {
+               if (*tp == '"') {
+                       *cp++ = '\\';  /* prepend backslash */
+               }
+       }
+       if (needquotes) {
+               *cp++ = '"';
+       }
+       *cp = '\0';
 
        return;
 }