Skip to content

Replace fgetsx() by fgets(3) and fputsx() by fputs(3) #1056

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 8 commits into
base: master
Choose a base branch
from

Conversation

alejandro-colomar
Copy link
Collaborator

@alejandro-colomar alejandro-colomar commented Jul 21, 2024

It seems they never worked correctly. Let's keep it simple and remove
support for escaped newlines.

Closes: #1055
Reported-by: @zeha

(Merge after #1048.)


Revisions:

v1b
  • Rebase
$ git range-diff c76f680fceb4^..gh/fgets string..fgets 
1:  c76f680f = 1:  d0cdc9c8 lib/gshadow.c: endsgent(): Invert logic to reduce indentation
2:  18db7b5a = 2:  4d66df60 lib/, src/: Consistently use NULL with fgets(3)
3:  b38c5eb0 = 3:  941c951c lib/, src/: Remove useless casts in fgets(3)
4:  2c112e69 = 4:  cd64d530 lib/, po/: Remove fgetsx() and fputsx()
v2
  • Use getline(3) instead of its pattern.
$ git range-diff string gh/fgets fgets 
1:  d0cdc9c8 = 1:  d0cdc9c8 lib/gshadow.c: endsgent(): Invert logic to reduce indentation
2:  4d66df60 = 2:  4d66df60 lib/, src/: Consistently use NULL with fgets(3)
3:  941c951c = 3:  941c951c lib/, src/: Remove useless casts in fgets(3)
4:  cd64d530 = 4:  cd64d530 lib/, po/: Remove fgetsx() and fputsx()
-:  -------- > 5:  e8036d0e lib/: Use getline(3) instead of its pattern
v2b
  • Remove unused include and macro
$ git range-diff string gh/fgets fgets 
1:  d0cdc9c8 = 1:  d0cdc9c8 lib/gshadow.c: endsgent(): Invert logic to reduce indentation
2:  4d66df60 = 2:  4d66df60 lib/, src/: Consistently use NULL with fgets(3)
3:  941c951c = 3:  941c951c lib/, src/: Remove useless casts in fgets(3)
4:  cd64d530 = 4:  cd64d530 lib/, po/: Remove fgetsx() and fputsx()
5:  e8036d0e ! 5:  0c59138d lib/: Use getline(3) instead of its pattern
    @@ Commit message
         Signed-off-by: Alejandro Colomar <[email protected]>
     
      ## lib/commonio.c ##
    +@@
    + #include <utime.h>
    + 
    + #include "alloc/malloc.h"
    +-#include "alloc/reallocf.h"
    + #include "atoi/getnum.h"
    + #include "commonio.h"
    + #include "defines.h"
    +@@ lib/commonio.c: static void add_one_entry_nis (struct commonio_db *db,
    + }
    + #endif                            /* KEEP_NIS_AT_END */
    + 
    +-/* Initial buffer size, as well as increment if not sufficient
    +-   (for reading very long lines in group files).  */
    +-#define BUFLEN 4096
    + 
    +-int commonio_open (struct commonio_db *db, int mode)
    ++int
    ++commonio_open(struct commonio_db *db, int mode)
    + {
    +   char *buf;
    +   char *line;
     @@ lib/commonio.c: int commonio_open (struct commonio_db *db, int mode)
                return 0;
        }
    @@ lib/commonio.c: int commonio_open (struct commonio_db *db, int mode)
      
                line = strdup (buf);
                if (NULL == line) {
    +@@ lib/commonio.c: int commonio_open (struct commonio_db *db, int mode)
    +   return 0;
    + }
    + 
    ++
    + /*
    +  * Sort given db according to cmp function (usually compares uids)
    +  */
     
      ## lib/gshadow.c ##
     @@ lib/gshadow.c: void endsgent (void)
v3
  • Cosmetic in function declarator.
  • free(3) memory instead of keeping a static pointer. [@zeha]
$ git range-diff string gh/fgets fgets 
1:  d0cdc9c8 = 1:  d0cdc9c8 lib/gshadow.c: endsgent(): Invert logic to reduce indentation
2:  4d66df60 = 2:  4d66df60 lib/, src/: Consistently use NULL with fgets(3)
3:  941c951c = 3:  941c951c lib/, src/: Remove useless casts in fgets(3)
4:  cd64d530 = 4:  cd64d530 lib/, po/: Remove fgetsx() and fputsx()
5:  0c59138d ! 5:  decf456e lib/: Use getline(3) instead of its pattern
    @@ lib/commonio.c: int commonio_open (struct commonio_db *db, int mode)
     
      ## lib/gshadow.c ##
     @@ lib/gshadow.c: void endsgent (void)
    +   return &sgroup;
    + }
    + 
    ++
    + /*
    +  * fgetsgent - convert next line in stream to (struct sgrp)
    +  *
    +@@ lib/gshadow.c: void endsgent (void)
    +  * converts it to a (struct sgrp).  NULL is returned on EOF.
    +  */
    + 
    +-/*@observer@*//*@null@*/struct sgrp *fgetsgent (/*@null@*/FILE * fp)
    ++/*@observer@*//*@null@*/struct sgrp *
    ++fgetsgent(/*@null@*/FILE *fp)
    + {
        static size_t buflen = 0;
        static char *buf = NULL;
      
    @@ lib/gshadow.c: void endsgent (void)
        return (sgetsgent (buf));
      }
      
    ++
    + /*
    +  * getsgent - get a single shadow group entry
    +  */
-:  -------- > 6:  3e3b3743 lib/gshadow.c: fgetsgent(): Don't use static variables
v3b
  • Remove formatting fix that complicates diff.
$ git range-diff string gh/fgets fgets 
1:  d0cdc9c8 = 1:  d0cdc9c8 lib/gshadow.c: endsgent(): Invert logic to reduce indentation
2:  4d66df60 = 2:  4d66df60 lib/, src/: Consistently use NULL with fgets(3)
3:  941c951c = 3:  941c951c lib/, src/: Remove useless casts in fgets(3)
4:  cd64d530 = 4:  cd64d530 lib/, po/: Remove fgetsx() and fputsx()
5:  decf456e = 5:  decf456e lib/: Use getline(3) instead of its pattern
6:  3e3b3743 ! 6:  0936efac lib/gshadow.c: fgetsgent(): Don't use static variables
    @@ lib/gshadow.c: void endsgent (void)
     +  size_t       buflen = 0;
     +  struct sgrp  *sg;
      
    --  if (NULL == fp) {
    -+  if (NULL == fp)
    -           return NULL;
    --  }
    - 
    -   if (getline(&buf, &buflen, fp) == -1)
    +   if (NULL == fp) {
                return NULL;
    +@@ lib/gshadow.c: fgetsgent(/*@null@*/FILE *fp)
        if (stpsep(buf, "\n") == NULL)
                return NULL;
      
v4
  • Globally make the uses of sizeof() consistent.
  • Provide semantic patches where they can be used to validate the patches, in the corresponding commit message. [@thesamesam ]
  • Move the white-space and brace changes, to commits where it can be hidden with git-diff(1)'s -w and/or --color-words=., so that it doesn't hurt review.
$ git range-diff string gh/fgets fgets 
1:  d0cdc9c8 = 1:  d0cdc9c8 lib/gshadow.c: endsgent(): Invert logic to reduce indentation
-:  -------- > 2:  8f77030f contrib/, lib/, src/: Consistently use sizeof() as if it were a function
3:  941c951c ! 3:  b2b9bbb3 lib/, src/: Remove useless casts in fgets(3)
    @@ Metadata
      ## Commit message ##
         lib/, src/: Remove useless casts in fgets(3)
     
    +    This patch can be replicated with the following semantic patch:
    +
    +            $ cat fgets_cast.sp
    +            @@
    +            expression a, b, c;
    +            @@
    +
    +            - fgets(a, (int) (b), c)
    +            + fgets(a, b, c)
    +
    +            @@
    +            expression a, b, c;
    +            @@
    +
    +            - fgets(a, (int) b, c)
    +            + fgets(a, b, c)
    +
    +            @@
    +            expression a, b, c;
    +            @@
    +
    +            - fgetsx(a, (int) (b), c)
    +            + fgetsx(a, b, c)
    +
    +            @@
    +            expression a, b, c;
    +            @@
    +
    +            - fgetsx(a, (int) b, c)
    +            + fgetsx(a, b, c)
    +
    +            @@
    +            expression a, b, c, p;
    +            @@
    +
    +            - p->fgets(a, (int) (b), c)
    +            + p->fgets(a, b, c)
    +
    +            @@
    +            expression a, b, c, p;
    +            @@
    +
    +            - p->fgets(a, (int) b, c)
    +            + p->fgets(a, b, c)
    +
    +    which is applied as:
    +
    +            $ find lib* src/ -type f \
    +            | xargs spatch --sp-file ~/tmp/spatch/fgets_cast.sp --in-place;
    +
         Signed-off-by: Alejandro Colomar <[email protected]>
     
      ## lib/commonio.c ##
    @@ lib/commonio.c: int commonio_open (struct commonio_db *db, int mode)
     -                  if (db->ops->fgets (buf + len,
     -                                      (int) (buflen - len),
     -                                      db->fp) == NULL) {
    -+                  if (db->ops->fgets(buf + len, buflen - len, db->fp) == NULL)
    ++                  if (db->ops->fgets(buf + len, buflen - len, db->fp) == NULL) {
                                goto cleanup_buf;
    --                  }
    +                   }
                }
    -           stpsep(buf, "\n");
    - 
     
      ## lib/gshadow.c ##
     @@ lib/gshadow.c: void endsgent (void)
                buflen *= 2;
      
                len = strlen (buf);
    --          if (fgetsx(&buf[len], (int) (buflen - len), fp) == NULL)
    -+          if (fgetsx(&buf[len], buflen - len, fp) == NULL)
    +-          if (fgetsx (&buf[len],
    +-                      (int) (buflen - len),
    +-                      fp) != &buf[len]) {
    ++          if (fgetsx(&buf[len], buflen - len, fp) != &buf[len]) {
                        return NULL;
    +           }
        }
    -   stpsep(buf, "\n");
     
      ## lib/setupenv.c ##
     @@ lib/setupenv.c: static void read_env_file (const char *filename)
        if (NULL == fp) {
                return;
        }
    --  while (fgets(buf, (int)(sizeof(buf)), fp) != NULL) {
    -+  while (fgets(buf, sizeof(buf), fp) != NULL) {
    +-  while (fgets(buf, (int) sizeof(buf), fp) == buf) {
    ++  while (fgets(buf, sizeof(buf), fp) == buf) {
                if (stpsep(buf, "\n") == NULL)
                        break;
      
    @@ src/chgpasswd.c: int main (int argc, char **argv)
         * group entry for each group will be looked up in the appropriate
         * file (gshadow or group) and the password changed.
         */
    --  while (fgets (buf, (int) sizeof buf, stdin) != NULL) {
    +-  while (fgets(buf, (int) sizeof(buf), stdin) != NULL) {
     +  while (fgets(buf, sizeof(buf), stdin) != NULL) {
                line++;
                if (stpsep(buf, "\n") == NULL) {
2:  4d66df60 ! 4:  00db7341 lib/, src/: Consistently use NULL with fgets(3)
    @@ Commit message
     
         <stddef.h> is the header that provides NULL; add it where appropriate.
     
    +    The meat of this patch can be approximated with the following semantic
    +    patch:
    +
    +            $ cat ~/tmp/spatch/fgets_null.sp
    +            @@
    +            expression a, b, c;
    +            @@
    +
    +            - fgets(a, b, c) == a
    +            + fgets(a, b, c) != NULL
    +
    +            @@
    +            expression a, b, c;
    +            @@
    +
    +            - fgetsx(a, b, c) == a
    +            + fgetsx(a, b, c) != NULL
    +
    +            @@
    +            expression a, b, c, p;
    +            @@
    +
    +            - p->fgets(a, b, c) == a
    +            + p->fgets(a, b, c) != NULL
    +
    +            @@
    +            expression a, b, c;
    +            @@
    +
    +            - fgets(a, b, c) != a
    +            + fgets(a, b, c) == NULL
    +
    +            @@
    +            expression a, b, c;
    +            @@
    +
    +            - fgetsx(a, b, c) != a
    +            + fgetsx(a, b, c) == NULL
    +
    +            @@
    +            expression a, b, c, p;
    +            @@
    +
    +            - p->fgets(a, b, c) != a
    +            + p->fgets(a, b, c) == NUL
    +
    +    Applied as
    +
    +            $ find contrib/ lib* src/ -type f \
    +            | xargs spatch --sp-file ~/tmp/spatch/fgets_null.sp --in-place;
    +
    +    The differences between the actual patch and the approximation via the
    +    semantic patch from above are includes, whitespace, braces, and a case
    +    where there was an implicit pointer-to-bool comparison which I made
    +    explicit.  When reviewing, it'll be useful to use git-diff(1) with '-w'
    +    and '--color-words=.'.
    +
         Signed-off-by: Alejandro Colomar <[email protected]>
     
      ## lib/commonio.c ##
    @@ lib/gshadow.c: void endsgent (void)
                buflen *= 2;
      
                len = strlen (buf);
    --          if (fgetsx (&buf[len],
    --                      (int) (buflen - len),
    --                      fp) != &buf[len]) {
    -+          if (fgetsx(&buf[len], (int) (buflen - len), fp) == NULL)
    +-          if (fgetsx(&buf[len], buflen - len, fp) != &buf[len]) {
    ++          if (fgetsx(&buf[len], buflen - len, fp) == NULL)
                        return NULL;
     -          }
        }
    @@ lib/hushed.c: bool hushed (const char *username)
        if (NULL == fp) {
                return false;
        }
    --  for (found = false; !found && (fgets (buf, sizeof buf, fp) == buf);) {
    +-  for (found = false; !found && (fgets(buf, sizeof(buf), fp) == buf);) {
     +  for (found = false; !found && (fgets(buf, sizeof(buf), fp) != NULL);) {
                stpsep(buf, "\n");
                found = (strcmp (buf, pw->pw_shell) == 0) ||
    @@ lib/loginprompt.c: login_prompt(char *name, int namesize)
         */
      
        MEMZERO(buf);
    --  if (fgets (buf, sizeof buf, stdin) != buf) {
    +-  if (fgets(buf, sizeof(buf), stdin) != buf) {
     +  if (fgets(buf, sizeof(buf), stdin) == NULL)
                exit (EXIT_FAILURE);
     -  }
    @@ lib/setupenv.c: static void read_env_file (const char *filename)
        if (NULL == fp) {
                return;
        }
    --  while (fgets (buf, (int)(sizeof buf), fp) == buf) {
    -+  while (fgets(buf, (int)(sizeof(buf)), fp) != NULL) {
    +-  while (fgets(buf, sizeof(buf), fp) == buf) {
    ++  while (fgets(buf, sizeof(buf), fp) != NULL) {
                if (stpsep(buf, "\n") == NULL)
                        break;
      
    @@ lib/ttytype.c: void ttytype (const char *line)
                        perror (typefile);
                return;
        }
    --  while (fgets (buf, sizeof buf, fp) == buf) {
    +-  while (fgets(buf, sizeof(buf), fp) == buf) {
     +  while (fgets(buf, sizeof(buf), fp) != NULL) {
                if (buf[0] == '#') {
                        continue;
                }
     
    + ## lib/user_busy.c ##
    +@@
    + #ident "$Id: $"
    + 
    + #include <assert.h>
    ++#include <stddef.h>
    + #include <stdio.h>
    + #include <sys/types.h>
    + #include <dirent.h>
    +@@ lib/user_busy.c: static int check_status (const char *name, const char *sname, uid_t uid)
    +   if (NULL == sfile) {
    +           return 0;
    +   }
    +-  while (fgets(line, sizeof(line), sfile) == line) {
    ++  while (fgets(line, sizeof(line), sfile) != NULL) {
    +           if (strncmp (line, "Uid:\t", 5) == 0) {
    +                   unsigned long ruid, euid, suid;
    + 
    +
      ## src/login_nopam.c ##
     @@ src/login_nopam.c: login_access(const char *user, const char *from)
        if (NULL != fp) {
                int lineno = 0; /* for diagnostics */
                while (   !match
    --                 && (fgets (line, sizeof (line), fp) == line))
    +-                 && (fgets(line, sizeof(line), fp) == line))
     +                 && (fgets(line, sizeof(line), fp) != NULL))
                {
                        char  *p;
    @@ src/useradd.c: get_defaults(void)
         * Read the file a line at a time. Only the lines that have relevant
         * values are used, everything else can be ignored.
         */
    --  while (fgets (buf, sizeof buf, fp) == buf) {
    +-  while (fgets(buf, sizeof(buf), fp) == buf) {
     +  while (fgets(buf, sizeof(buf), fp) != NULL) {
                stpsep(buf, "\n");
      
    @@ src/useradd.c: set_defaults(void)
                goto skip;
        }
      
    --  while (fgets (buf, sizeof buf, ifp) == buf) {
    +-  while (fgets(buf, sizeof(buf), ifp) == buf) {
     +  while (fgets(buf, sizeof(buf), ifp) != NULL) {
                char  *val;
      
4:  cd64d530 ! 5:  c1ccbb9a lib/, po/: Remove fgetsx() and fputsx()
    @@ lib/commonio.c: int commonio_open (struct commonio_db *db, int mode)
                                goto cleanup_errno;
      
                        len = strlen (buf);
    --                  if (db->ops->fgets(buf + len, buflen - len, db->fp) == NULL)
    +-                  if (db->ops->fgets(buf + len, buflen - len, db->fp) == NULL) {
     +                  if (fgets(buf + len, buflen - len, db->fp) == NULL)
                                goto cleanup_buf;
    +-                  }
                }
                stpsep(buf, "\n");
    + 
     @@ lib/commonio.c: static int write_all (const struct commonio_db *db)
                                return -1;
                        }
                } else if (NULL != p->line) {
     -                  if (db->ops->fputs (p->line, db->fp) == EOF) {
    -+                  if (fputs(p->line, db->fp) == EOF) {
    ++                  if (fputs(p->line, db->fp) == EOF)
    +                           return -1;
    +-                  }
    ++
    +                   if (putc ('\n', db->fp) == EOF) {
                                return -1;
                        }
    -                   if (putc ('\n', db->fp) == EOF) {
     
      ## lib/commonio.h ##
     @@ lib/commonio.h: struct commonio_ops {
5:  decf456e = 6:  9991189d lib/: Use getline(3) instead of its pattern
6:  0936efac = 7:  51005793 lib/gshadow.c: fgetsgent(): Don't use static variables
v4b
  • Rebase
$ git range-diff d0cdc9c8f683^..gh/fgets string..fgets 
1:  d0cdc9c8 = 1:  8dbc8149 lib/gshadow.c: endsgent(): Invert logic to reduce indentation
2:  8f77030f ! 2:  ac57816a contrib/, lib/, src/: Consistently use sizeof() as if it were a function
    @@ Commit message
         Signed-off-by: Alejandro Colomar <[email protected]>
     
      ## contrib/adduser.c ##
    -@@ contrib/adduser.c: main(void)
    +@@ contrib/adduser.c: main (void)
          printf ("\nLogin to add (^C to quit): ");
          fflush (stdout);
      
    @@ contrib/adduser.c: main(void)
      
          if (!strlen (usrname))
            {
    -@@ contrib/adduser.c: main(void)
    +@@ contrib/adduser.c: main (void)
      
            printf ("\nFull Name [%s]: ", usrname);
            fflush (stdout);
    @@ contrib/adduser.c: main(void)
          strcpy (person, usrname);
        };
      
    -@@ contrib/adduser.c: main(void)
    +@@ contrib/adduser.c: main (void)
              bad = 0;
              printf ("GID [%d]: ", DEFAULT_GROUP);
              fflush (stdout);
    @@ contrib/adduser.c: main(void)
              if (!strlen (foo))
                group = DEFAULT_GROUP;
              else if (isdigit (*foo))
    -@@ contrib/adduser.c: main(void)
    +@@ contrib/adduser.c: main (void)
          printf ("\nIf home dir ends with a / then '%s' will be appended to it\n", usrname);
          printf ("Home Directory [%s/%s]: ", DEFAULT_HOME, usrname);
          fflush (stdout);
    @@ contrib/adduser.c: main(void)
          if (!strlen(dir))  /* hit return */
            sprintf(dir, "%s/%s", DEFAULT_HOME, usrname);
          else if (dir[strlen (dir) - 1] == '/')
    -@@ contrib/adduser.c: main(void)
    +@@ contrib/adduser.c: main (void)
      
            printf ("\nShell [%s]: ", DEFAULT_SHELL);
            fflush (stdout);
    @@ contrib/adduser.c: main(void)
            if (!strlen (shell))
        strcpy(shell, DEFAULT_SHELL);
            else
    -@@ contrib/adduser.c: main(void)
    +@@ contrib/adduser.c: main (void)
      #endif
          printf ("\nMin. Password Change Days [%d]: ", DEFAULT_MIN_PASS);
          fflush (stdout);
    @@ contrib/adduser.c: main(void)
          if (strlen (foo) > 1)
            min_pass = DEFAULT_MIN_PASS;
          else
    -@@ contrib/adduser.c: main(void)
    +@@ contrib/adduser.c: main (void)
      
          printf ("Max. Password Change Days [%d]: ", DEFAULT_MAX_PASS);
          fflush (stdout);
    @@ contrib/adduser.c: main(void)
          if (strlen (foo) > 1)
            max_pass = atoi (foo);
          else
    -@@ contrib/adduser.c: main(void)
    +@@ contrib/adduser.c: main (void)
      
          printf ("Password Warning Days [%d]: ", DEFAULT_WARN_PASS);
          fflush (stdout);
    @@ contrib/adduser.c: main(void)
          warn_pass = atoi (foo);
          if (warn_pass == 0)
      
    -@@ contrib/adduser.c: main(void)
    +@@ contrib/adduser.c: main (void)
      
          printf ("Days after Password Expiry for Account Locking [%d]: ", DEFAULT_USER_DIE);
          fflush (stdout);
    @@ contrib/adduser.c: main(void)
          user_die = atoi (foo);
          if (user_die == 0)
            user_die = DEFAULT_USER_DIE;
    -@@ contrib/adduser.c: main(void)
    +@@ contrib/adduser.c: main (void)
              min_pass, max_pass, warn_pass, user_die);
            printf ("\nIs this correct? [y/N]: ");
            fflush (stdout);
     -      safeget (foo, sizeof (foo));
     +      safeget(foo, sizeof(foo));
      
    -       done = bad = correct = !!strchr("yY", foo[0]);
    +       done = bad = correct = (foo[0] == 'y' || foo[0] == 'Y');
      
    -@@ contrib/adduser.c: main(void)
    +@@ contrib/adduser.c: main (void)
      
        *environ = NULL;
      
    @@ contrib/adduser.c: main(void)
        sprintf (cmd, "%s -g %d -d %s -s %s -c \"%s\" -m -k /etc/skel %s",
           USERADD_PATH, group, dir, shell, person, usrname);
        printf ("Calling useradd to add new user:\n%s\n", cmd);
    -@@ contrib/adduser.c: main(void)
    +@@ contrib/adduser.c: main (void)
                         */
        setuid (0);
      
    @@ contrib/adduser.c: main(void)
      
        /* Chage runs suid root. => we need ruid root to run it with
         * anything other than chage -l
    -@@ contrib/adduser.c: main(void)
    +@@ contrib/adduser.c: main (void)
        /* I want to add a user completely with one easy command --chris */
      
      #ifdef HAVE_QUOTAS
    @@ contrib/adduser.c: main(void)
        sprintf (cmd, "%s -p %s -u %s", EDQUOTA_PATH, QUOTA_DEFAULT, usrname);
        printf ("%s\n", cmd);
        if (system (cmd))
    -@@ contrib/adduser.c: main(void)
    +@@ contrib/adduser.c: main (void)
          printf ("\nDefault quota set.\n");
      #endif /* HAVE_QUOTAS */
      
    @@ contrib/adduser.c: main(void)
        sprintf (cmd, "%s %s", PASSWD_PATH, usrname);
        if (system (cmd))
          {
    -@@ contrib/adduser.c: main(void)
    +@@ contrib/adduser.c: main (void)
      #endif
          }
      #ifdef IMMEDIATE_CHANGE
    @@ src/lastlog.c: static void update_one (/*@null@*/const struct passwd *pw)
                                 Prog, (unsigned long)pw->pw_uid);
     
      ## src/login.c ##
    -@@ src/login.c: main(int argc, char **argv)
    +@@ src/login.c: int main (int argc, char **argv)
                unsigned int  failcount = 0;
      
                /* Make the login prompt look like we want it */
    @@ src/login.c: main(int argc, char **argv)
                        SNPRINTF(loginprompt, _("%s login: "), hostn);
                } else {
                        STRTCPY(loginprompt, _("login: "));
    -@@ src/login.c: main(int argc, char **argv)
    +@@ src/login.c: int main (int argc, char **argv)
      #ifdef HAVE_LL_HOST               /* __linux__ || SUN4 */
                        if ('\0' != ll.ll_host[0]) {
                                printf (_(" from %.*s"),
3:  b2b9bbb3 = 3:  9fdffc48 lib/, src/: Remove useless casts in fgets(3)
4:  00db7341 = 4:  d46fd02e lib/, src/: Consistently use NULL with fgets(3)
5:  c1ccbb9a = 5:  1721920a lib/, po/: Remove fgetsx() and fputsx()
6:  9991189d = 6:  664817b3 lib/: Use getline(3) instead of its pattern
7:  51005793 = 7:  a71fc6f3 lib/gshadow.c: fgetsgent(): Don't use static variables
v4c
  • Rebase
$ git range-diff gh/string..gh/fgets string..fgets 
1:  8dbc8149 = 1:  8af482a6 lib/gshadow.c: endsgent(): Invert logic to reduce indentation
2:  ac57816a = 2:  7cae4284 contrib/, lib/, src/: Consistently use sizeof() as if it were a function
3:  9fdffc48 = 3:  410f2492 lib/, src/: Remove useless casts in fgets(3)
4:  d46fd02e = 4:  a0953493 lib/, src/: Consistently use NULL with fgets(3)
5:  1721920a = 5:  9abcea85 lib/, po/: Remove fgetsx() and fputsx()
6:  664817b3 = 6:  dc3819ff lib/: Use getline(3) instead of its pattern
7:  a71fc6f3 = 7:  e49bcf8b lib/gshadow.c: fgetsgent(): Don't use static variables
v4d
  • Rebase
$ git range-diff gh/string..gh/fgets string..fgets 
1:  8af482a6 = 1:  b4a37bc9 lib/gshadow.c: endsgent(): Invert logic to reduce indentation
2:  7cae4284 = 2:  d1abe1ac contrib/, lib/, src/: Consistently use sizeof() as if it were a function
3:  410f2492 = 3:  f388b921 lib/, src/: Remove useless casts in fgets(3)
4:  a0953493 = 4:  31c6c72f lib/, src/: Consistently use NULL with fgets(3)
5:  9abcea85 = 5:  bf0a81e6 lib/, po/: Remove fgetsx() and fputsx()
6:  dc3819ff = 6:  bbbae6af lib/: Use getline(3) instead of its pattern
7:  e49bcf8b = 7:  f7d5cc12 lib/gshadow.c: fgetsgent(): Don't use static variables
v4e
  • Rebase
$ git range-diff gh/string..gh/fgets string..fgets 
1:  b4a37bc9 = 1:  be73a591 lib/gshadow.c: endsgent(): Invert logic to reduce indentation
2:  d1abe1ac = 2:  219af975 contrib/, lib/, src/: Consistently use sizeof() as if it were a function
3:  f388b921 = 3:  691673bc lib/, src/: Remove useless casts in fgets(3)
4:  31c6c72f = 4:  7cb79af6 lib/, src/: Consistently use NULL with fgets(3)
5:  bf0a81e6 = 5:  364b354d lib/, po/: Remove fgetsx() and fputsx()
6:  bbbae6af = 6:  3f398748 lib/: Use getline(3) instead of its pattern
7:  f7d5cc12 = 7:  ef91817e lib/gshadow.c: fgetsgent(): Don't use static variables
v4f
  • Rebase
$ git range-diff gh/string..gh/fgets string..fgets 
1:  be73a591 = 1:  5684988b lib/gshadow.c: endsgent(): Invert logic to reduce indentation
2:  219af975 = 2:  022f2da0 contrib/, lib/, src/: Consistently use sizeof() as if it were a function
3:  691673bc = 3:  05fe7f89 lib/, src/: Remove useless casts in fgets(3)
4:  7cb79af6 = 4:  5991bd9c lib/, src/: Consistently use NULL with fgets(3)
5:  364b354d = 5:  5cf10040 lib/, po/: Remove fgetsx() and fputsx()
6:  3f398748 = 6:  7e3d5d58 lib/: Use getline(3) instead of its pattern
7:  ef91817e = 7:  27dd9f5c lib/gshadow.c: fgetsgent(): Don't use static variables
v4g
  • Rebase
$ git range-diff 5684988b^..gh/fgets string..fgets 
1:  5684988b = 1:  77e6a686 lib/gshadow.c: endsgent(): Invert logic to reduce indentation
2:  022f2da0 = 2:  c42d9568 contrib/, lib/, src/: Consistently use sizeof() as if it were a function
3:  05fe7f89 = 3:  b67527a6 lib/, src/: Remove useless casts in fgets(3)
4:  5991bd9c = 4:  87af89d8 lib/, src/: Consistently use NULL with fgets(3)
5:  5cf10040 = 5:  375d57a0 lib/, po/: Remove fgetsx() and fputsx()
6:  7e3d5d58 = 6:  d094dc5d lib/: Use getline(3) instead of its pattern
7:  27dd9f5c = 7:  8ef8fc73 lib/gshadow.c: fgetsgent(): Don't use static variables
v4h
  • Rebase
$ git range-diff gh/string..gh/fgets string..fgets 
1:  77e6a686 = 1:  8a8c6635 lib/gshadow.c: endsgent(): Invert logic to reduce indentation
2:  c42d9568 ! 2:  da61e23a contrib/, lib/, src/: Consistently use sizeof() as if it were a function
    @@ lib/tz.c
        if (   (NULL == fp)
     -      || (fgets (tzbuf, sizeof (tzbuf), fp) == NULL)) {
     +      || (fgets(tzbuf, sizeof(tzbuf), fp) == NULL)) {
    -           def_tz = getdef_str ("ENV_TZ");
    -           if ((NULL == def_tz) || ('/' == def_tz[0])) {
    -                   def_tz = "TZ=CST6CDT";
    +           result = "TZ=CST6CDT";
    +   } else {
    +           stpsep(tzbuf, "\n");
     
      ## lib/user_busy.c ##
     @@ lib/user_busy.c: user_busy_utmp(const char *name)
    @@ src/useradd.c: static void lastlog_reset (uid_t uid)
                return;
        }
        if (   (lseek (fd, offset_uid, SEEK_SET) != offset_uid)
    --      || (write_full (fd, &ll, sizeof (ll)) != (ssize_t) sizeof (ll))
    -+      || (write_full(fd, &ll, sizeof(ll)) != (ssize_t) sizeof(ll))
    +-      || (write_full (fd, &ll, sizeof (ll)) == -1)
    ++      || (write_full(fd, &ll, sizeof(ll)) == -1)
            || (fsync (fd) != 0)) {
                fprintf (stderr,
                         _("%s: failed to reset the lastlog entry of UID %lu: %s\n"),
3:  b67527a6 = 3:  9f934b2a lib/, src/: Remove useless casts in fgets(3)
4:  87af89d8 = 4:  8a8620eb lib/, src/: Consistently use NULL with fgets(3)
5:  375d57a0 = 5:  2e696e77 lib/, po/: Remove fgetsx() and fputsx()
6:  d094dc5d = 6:  2375cbfc lib/: Use getline(3) instead of its pattern
7:  8ef8fc73 = 7:  7d2a356c lib/gshadow.c: fgetsgent(): Don't use static variables
v4i
  • Rebase
$ git range-diff gh/string..gh/fgets string..fgets 
1:  8a8c6635 = 1:  c6dabf04 lib/gshadow.c: endsgent(): Invert logic to reduce indentation
2:  da61e23a = 2:  6d57727a contrib/, lib/, src/: Consistently use sizeof() as if it were a function
3:  9f934b2a = 3:  857da077 lib/, src/: Remove useless casts in fgets(3)
4:  8a8620eb = 4:  db2b027d lib/, src/: Consistently use NULL with fgets(3)
5:  2e696e77 = 5:  c8645b33 lib/, po/: Remove fgetsx() and fputsx()
6:  2375cbfc = 6:  8d9b55dd lib/: Use getline(3) instead of its pattern
7:  7d2a356c = 7:  b5663560 lib/gshadow.c: fgetsgent(): Don't use static variables
v4j
  • Rebase
$ git range-diff gh/string..gh/fgets string..fgets 
1:  c6dabf04 = 1:  2ff6e318 lib/gshadow.c: endsgent(): Invert logic to reduce indentation
2:  6d57727a = 2:  6faa0944 contrib/, lib/, src/: Consistently use sizeof() as if it were a function
3:  857da077 = 3:  ee315ddc lib/, src/: Remove useless casts in fgets(3)
4:  db2b027d = 4:  876c36d1 lib/, src/: Consistently use NULL with fgets(3)
5:  c8645b33 = 5:  5fc868e2 lib/, po/: Remove fgetsx() and fputsx()
6:  8d9b55dd = 6:  f7ac2b0a lib/: Use getline(3) instead of its pattern
7:  b5663560 = 7:  9fd4a0b3 lib/gshadow.c: fgetsgent(): Don't use static variables
v4k
  • Rebase
$ git range-diff gh/string..gh/fgets string..fgets 
1:  2ff6e318 = 1:  2b6a1413 lib/gshadow.c: endsgent(): Invert logic to reduce indentation
2:  6faa0944 ! 2:  61bc9a04 contrib/, lib/, src/: Consistently use sizeof() as if it were a function
    @@ lib/log.c: void dolastlog (
      
     
      ## lib/loginprompt.c ##
    -@@ lib/loginprompt.c: login_prompt(char *name, int namesize)
    +@@ lib/loginprompt.c: void login_prompt (char *name, int namesize)
                        (void) fclose (fp);
                }
        }
    @@ lib/loginprompt.c: login_prompt(char *name, int namesize)
        printf (_("\n%s login: "), buf);
        (void) fflush (stdout);
      
    -@@ lib/loginprompt.c: login_prompt(char *name, int namesize)
    +@@ lib/loginprompt.c: void login_prompt (char *name, int namesize)
         */
      
        MEMZERO(buf);
3:  ee315ddc = 3:  ca165ccf lib/, src/: Remove useless casts in fgets(3)
4:  876c36d1 ! 4:  8929e11e lib/, src/: Consistently use NULL with fgets(3)
    @@ lib/loginprompt.c
      
      #include "attr.h"
      #include "defines.h"
    -@@ lib/loginprompt.c: login_prompt(char *name, int namesize)
    +@@ lib/loginprompt.c: void login_prompt (char *name, int namesize)
         */
      
        MEMZERO(buf);
5:  5fc868e2 = 5:  fee111ca lib/, po/: Remove fgetsx() and fputsx()
6:  f7ac2b0a = 6:  08d1534f lib/: Use getline(3) instead of its pattern
7:  9fd4a0b3 = 7:  b6b6a6b5 lib/gshadow.c: fgetsgent(): Don't use static variables
v4l
  • Rebase
$ git range-diff gh/string..gh/fgets string..fgets 
1:  2b6a1413 = 1:  ea9f29ec lib/gshadow.c: endsgent(): Invert logic to reduce indentation
2:  61bc9a04 = 2:  e628440c contrib/, lib/, src/: Consistently use sizeof() as if it were a function
3:  ca165ccf = 3:  dec51b42 lib/, src/: Remove useless casts in fgets(3)
4:  8929e11e = 4:  e63fef58 lib/, src/: Consistently use NULL with fgets(3)
5:  fee111ca = 5:  5fe14748 lib/, po/: Remove fgetsx() and fputsx()
6:  08d1534f = 6:  0dc3bf45 lib/: Use getline(3) instead of its pattern
7:  b6b6a6b5 = 7:  d3278c53 lib/gshadow.c: fgetsgent(): Don't use static variables
v5
  • Several rebases
$ git range-diff string..fgets gh/string..gh/fgets 
1:  ea9f29ec = 1:  bbde7826 lib/gshadow.c: endsgent(): Invert logic to reduce indentation
2:  e628440c ! 2:  e1d0706a contrib/, lib/, src/: Consistently use sizeof() as if it were a function
    @@ lib/getdef.c: struct itemdef {
      static struct itemdef def_table[] = {
        {"CHFN_RESTRICT", NULL},
        {"CONSOLE_GROUPS", NULL},
    -@@ lib/getdef.c: static struct itemdef def_table[] = {
    -   {NULL, NULL}
    - };
    - 
    --#define NUMKNOWNDEFS      (sizeof(knowndef_table)/sizeof(knowndef_table[0]))
    -+#define NUMKNOWNDEFS  (sizeof(knowndef_table) / sizeof(knowndef_table[0]))
    - static struct itemdef knowndef_table[] = {
    - #ifdef USE_PAM
    -   PAMDEFS
     @@ lib/getdef.c: static void def_load (void)
        /*
         * Go through all of the lines in the file.
    @@ lib/log.c: void dolastlog (
      
     
      ## lib/loginprompt.c ##
    -@@ lib/loginprompt.c: void login_prompt (char *name, int namesize)
    +@@ lib/loginprompt.c: login_prompt(char *name, int namesize)
                        (void) fclose (fp);
                }
        }
    @@ lib/loginprompt.c: void login_prompt (char *name, int namesize)
        printf (_("\n%s login: "), buf);
        (void) fflush (stdout);
      
    -@@ lib/loginprompt.c: void login_prompt (char *name, int namesize)
    +@@ lib/loginprompt.c: login_prompt(char *name, int namesize)
         */
      
        MEMZERO(buf);
    @@ lib/subordinateio.c: subordinate_parse(const char *line)
        strcpy (rangebuf, line);
      
     
    - ## lib/tcbfuncs.c ##
    -@@ lib/tcbfuncs.c: static /*@null@*/ char *shadowtcb_path_rel_existing (const char *name)
    -           free (path);
    -           return NULL;
    -   }
    --  ret = readlink (path, link, sizeof (link) - 1);
    -+  ret = readlink(path, link, sizeof(link) - 1);
    -   if (-1 == ret) {
    -           fprintf (shadow_logfd,
    -                    _("%s: Cannot read symbolic link %s: %s\n"),
    -
      ## lib/ttytype.c ##
     @@ lib/ttytype.c: void ttytype (const char *line)
                        perror (typefile);
    @@ lib/user_busy.c: user_busy_utmp(const char *name)
                        continue;
                }
                if (kill (utent->ut_pid, 0) != 0) {
    -@@ lib/user_busy.c: static int different_namespace (const char *sname)
    - 
    -   SNPRINTF(path, "/proc/%s/ns/user", sname);
    - 
    --  if ((llen1 = readlink (path, buf, sizeof(buf))) == -1)
    -+  if ((llen1 = readlink(path, buf, sizeof(buf))) == -1)
    -           return 0;
    - 
    --  if ((llen2 = readlink ("/proc/self/ns/user", buf2, sizeof(buf2))) == -1)
    -+  if ((llen2 = readlink("/proc/self/ns/user", buf2, sizeof(buf2))) == -1)
    -           return 0;
    - 
    -   if (llen1 == llen2 && memcmp (buf, buf2, llen1) == 0)
     @@ lib/user_busy.c: static int check_status (const char *name, const char *sname, uid_t uid)
        if (NULL == sfile) {
                return 0;
3:  dec51b42 = 3:  1cf6b14d lib/, src/: Remove useless casts in fgets(3)
4:  e63fef58 ! 4:  3fc6e9ed lib/, src/: Consistently use NULL with fgets(3)
    @@ lib/loginprompt.c
      
      #include "attr.h"
      #include "defines.h"
    -@@ lib/loginprompt.c: void login_prompt (char *name, int namesize)
    +@@ lib/loginprompt.c: login_prompt(char *name, int namesize)
         */
      
        MEMZERO(buf);
5:  5fe14748 ! 5:  79adfd9d lib/, po/: Remove fgetsx() and fputsx()
    @@ lib/Makefile.am: libshadow_la_SOURCES = \
        find_new_sub_gids.c \
        find_new_sub_uids.c \
     -  fputsx.c \
    -   get_pid.c \
    -   getdate.h \
    -   getdate.y \
    +   fs/readlink/areadlink.c \
    +   fs/readlink/areadlink.h \
    +   fs/readlink/readlinknul.c \
     
      ## lib/commonio.c ##
     @@ lib/commonio.c: int commonio_open (struct commonio_db *db, int mode)
6:  0dc3bf45 = 6:  5bac295b lib/: Use getline(3) instead of its pattern
7:  d3278c53 = 7:  b3acc480 lib/gshadow.c: fgetsgent(): Don't use static variables
v5b
  • Rebase
$ git range-diff gh/string..gh/fgets string..fgets 
1:  bbde7826 < -:  -------- lib/gshadow.c: endsgent(): Invert logic to reduce indentation
2:  e1d0706a = 1:  045fcee5 contrib/, lib/, src/: Consistently use sizeof() as if it were a function
3:  1cf6b14d = 2:  fafa51f2 lib/, src/: Remove useless casts in fgets(3)
4:  3fc6e9ed = 3:  cddf585c lib/, src/: Consistently use NULL with fgets(3)
5:  79adfd9d = 4:  ff64b68b lib/, po/: Remove fgetsx() and fputsx()
6:  5bac295b = 5:  7bd6a873 lib/: Use getline(3) instead of its pattern
7:  b3acc480 = 6:  0ea5edc8 lib/gshadow.c: fgetsgent(): Don't use static variables
v5c
  • Rebase
$ git range-diff gh/string..gh/fgets string..fgets 
1:  045fcee5 ! 1:  8f180904 contrib/, lib/, src/: Consistently use sizeof() as if it were a function
    @@ lib/sgetspent.c: sgetspent(const char *string)
                         shadow_progname);
     
      ## lib/shadow.c ##
    -@@ lib/shadow.c: my_sgetspent(const char *string)
    -    * have to do that to our private copy.
    -    */
    - 
    --  if (strlen (string) >= sizeof spwbuf)
    -+  if (strlen(string) >= sizeof(spwbuf))
    -           return 0;
    -   strcpy (spwbuf, string);
    -   stpsep(spwbuf, "\n");
     @@ lib/shadow.c: struct spwd *fgetspent (FILE * fp)
                return (0);
        }
    @@ lib/shadow.c: struct spwd *fgetspent (FILE * fp)
     +  if (fgets(buf, sizeof(buf), fp) != NULL)
        {
                stpsep(buf, "\n");
    -           return my_sgetspent (buf);
    +           return sgetspent(buf);
     
      ## lib/subordinateio.c ##
     @@ lib/subordinateio.c: subordinate_parse(const char *line)
    @@ src/groupmod.c: grp_update(void)
     
      ## src/grpconv.c ##
     @@ src/grpconv.c: int main (int argc, char **argv)
    -                   static char *empty = 0;
    +                   static char *empty = NULL;
      
                        /* add new shadow group entry */
     -                  bzero(&sgent, sizeof sgent);
2:  fafa51f2 = 2:  afb1c131 lib/, src/: Remove useless casts in fgets(3)
3:  cddf585c ! 3:  188be985 lib/, src/: Consistently use NULL with fgets(3)
    @@ lib/fputsx.c: fgetsx(/*@returned@*/char *restrict buf, int cnt, FILE *restrict f
     -          if (fgets (cp, cnt, f) != cp) {
     +          if (fgets(cp, cnt, f) == NULL) {
                        if (cp == buf) {
    --                          return 0;
    -+                          return NULL;
    +                           return NULL;
                        } else {
    -                           break;
    -                   }
     
      ## lib/getdate.y ##
     @@
4:  ff64b68b = 4:  85fe221b lib/, po/: Remove fgetsx() and fputsx()
5:  7bd6a873 = 5:  917c4cbd lib/: Use getline(3) instead of its pattern
6:  0ea5edc8 = 6:  4997bf3c lib/gshadow.c: fgetsgent(): Don't use static variables
v5d
  • Rebase
  • $ git range-diff 4443b615..gh/fgets string..fgets 
    1:  8f180904 ! 1:  b218e332 contrib/, lib/, src/: Consistently use sizeof() as if it were a function
        @@ lib/console.c: is_listed(const char *cfgin, const char *tty, bool def)
         -  while (fgets (buf, sizeof (buf), fp) != NULL) {
         +  while (fgets(buf, sizeof(buf), fp) != NULL) {
                    stpsep(buf, "\n");
        -           if (strcmp (buf, tty) == 0) {
        +           if (streq(buf, tty)) {
                            (void) fclose (fp);
         
          ## lib/copydir.c ##
        @@ lib/hushed.c: bool hushed (const char *username)
         -  for (found = false; !found && (fgets (buf, sizeof buf, fp) == buf);) {
         +  for (found = false; !found && (fgets(buf, sizeof(buf), fp) == buf);) {
                    stpsep(buf, "\n");
        -           found = (strcmp (buf, pw->pw_shell) == 0) ||
        -                   (strcmp (buf, pw->pw_name) == 0);
        +           found = streq(buf, pw->pw_shell) ||
        +                   streq(buf, pw->pw_name);
         
          ## lib/log.c ##
         @@ lib/log.c: void dolastlog (
        @@ src/chage.c: static int new_fields (void)
         -  change_field (buf, sizeof buf, _("Last Password Change (YYYY-MM-DD)"));
         +  change_field(buf, sizeof(buf), _("Last Password Change (YYYY-MM-DD)"));
          
        -   if (strcmp (buf, "-1") == 0) {
        +   if (streq(buf, "-1")) {
                    lstchgdate = -1;
         @@ src/chage.c: static int new_fields (void)
            }
        @@ src/chage.c: static int new_fields (void)
         +  change_field(buf, sizeof(buf),
                          _("Account Expiration Date (YYYY-MM-DD)"));
          
        -   if (strcmp (buf, "-1") == 0) {
        +   if (streq(buf, "-1")) {
         @@ src/chage.c: static void update_age (/*@null@*/const struct spwd *sp,
            if (NULL == sp) {
                    struct passwd pwent = *pw;
    2:  afb1c131 = 2:  5747fddc lib/, src/: Remove useless casts in fgets(3)
    3:  188be985 ! 3:  76ad76fd lib/, src/: Consistently use NULL with fgets(3)
        @@ lib/hushed.c: bool hushed (const char *username)
         -  for (found = false; !found && (fgets(buf, sizeof(buf), fp) == buf);) {
         +  for (found = false; !found && (fgets(buf, sizeof(buf), fp) != NULL);) {
                    stpsep(buf, "\n");
        -           found = (strcmp (buf, pw->pw_shell) == 0) ||
        -                   (strcmp (buf, pw->pw_name) == 0);
        +           found = streq(buf, pw->pw_shell) ||
        +                   streq(buf, pw->pw_name);
         
          ## lib/loginprompt.c ##
         @@
    4:  85fe221b = 4:  2b584c1d lib/, po/: Remove fgetsx() and fputsx()
    5:  917c4cbd = 5:  2b0dced9 lib/: Use getline(3) instead of its pattern
    6:  4997bf3c = 6:  decea534 lib/gshadow.c: fgetsgent(): Don't use static variables
    
    v5e
    • Rebase
    $ git range-diff gh/string..gh/fgets string..fgets 
    1:  b218e332 = 1:  d735f06d contrib/, lib/, src/: Consistently use sizeof() as if it were a function
    2:  5747fddc = 2:  bc48d436 lib/, src/: Remove useless casts in fgets(3)
    3:  76ad76fd = 3:  de5d37f4 lib/, src/: Consistently use NULL with fgets(3)
    4:  2b584c1d = 4:  433653dc lib/, po/: Remove fgetsx() and fputsx()
    5:  2b0dced9 = 5:  b7014a18 lib/: Use getline(3) instead of its pattern
    6:  decea534 = 6:  55705d75 lib/gshadow.c: fgetsgent(): Don't use static variables
    
    v5f
    • Rebase
    $ git range-diff d735f06df02a^..gh/fgets string..fgets 
    1:  d735f06d = 1:  10a97f1a contrib/, lib/, src/: Consistently use sizeof() as if it were a function
    2:  bc48d436 = 2:  2edf4077 lib/, src/: Remove useless casts in fgets(3)
    3:  de5d37f4 = 3:  2e7b5948 lib/, src/: Consistently use NULL with fgets(3)
    4:  433653dc = 4:  88978371 lib/, po/: Remove fgetsx() and fputsx()
    5:  b7014a18 = 5:  9ba864e1 lib/: Use getline(3) instead of its pattern
    6:  55705d75 = 6:  00a84c7c lib/gshadow.c: fgetsgent(): Don't use static variables
    
    v5g
    • Rebase
    $ git range-diff gh/string..gh/fgets string..fgets  
    1:  10a97f1a = 1:  6b1f4504 contrib/, lib/, src/: Consistently use sizeof() as if it were a function
    2:  2edf4077 = 2:  e019f028 lib/, src/: Remove useless casts in fgets(3)
    3:  2e7b5948 = 3:  bb286988 lib/, src/: Consistently use NULL with fgets(3)
    4:  88978371 = 4:  df5e91b2 lib/, po/: Remove fgetsx() and fputsx()
    5:  9ba864e1 = 5:  8319879d lib/: Use getline(3) instead of its pattern
    6:  00a84c7c = 6:  8533575c lib/gshadow.c: fgetsgent(): Don't use static variables
    
    v5h
    • Rebase
    $ git range-diff gh/string..gh/fgets string..fgets 
    1:  6b1f4504 = 1:  c5662ba2 contrib/, lib/, src/: Consistently use sizeof() as if it were a function
    2:  e019f028 = 2:  c98032d3 lib/, src/: Remove useless casts in fgets(3)
    3:  bb286988 = 3:  8bd9acd7 lib/, src/: Consistently use NULL with fgets(3)
    4:  df5e91b2 = 4:  1df2aa5a lib/, po/: Remove fgetsx() and fputsx()
    5:  8319879d = 5:  964e080e lib/: Use getline(3) instead of its pattern
    6:  8533575c = 6:  5a9bf7fe lib/gshadow.c: fgetsgent(): Don't use static variables
    
    v5i
    • Rebase
    $ git range-diff gh/string..gh/fgets string..fgets 
    1:  c5662ba2 ! 1:  65450ddd contrib/, lib/, src/: Consistently use sizeof() as if it were a function
        @@ src/login_nopam.c: login_access(const char *user, const char *from)
         @@ src/login_nopam.c: myhostname(void)
            static char name[MAXHOSTNAMELEN + 1] = "";
          
        -   if (strcmp(name, "") == 0) {
        +   if (streq(name, "")) {
         -          gethostname (name, sizeof (name));
         +          gethostname(name, sizeof(name));
                    stpcpy(&name[MAXHOSTNAMELEN], "");
    2:  c98032d3 = 2:  e7a79bec lib/, src/: Remove useless casts in fgets(3)
    3:  8bd9acd7 = 3:  8f8351b5 lib/, src/: Consistently use NULL with fgets(3)
    4:  1df2aa5a = 4:  bf670236 lib/, po/: Remove fgetsx() and fputsx()
    5:  964e080e = 5:  7d38ceda lib/: Use getline(3) instead of its pattern
    6:  5a9bf7fe = 6:  4c8d340c lib/gshadow.c: fgetsgent(): Don't use static variables
    
    v5j
    • Rebase
    $ git range-diff gh/string..gh/fgets string..fgets 
    1:  65450ddd = 1:  551780b3 contrib/, lib/, src/: Consistently use sizeof() as if it were a function
    2:  e7a79bec = 2:  00e3d101 lib/, src/: Remove useless casts in fgets(3)
    3:  8f8351b5 ! 3:  def7bd46 lib/, src/: Consistently use NULL with fgets(3)
        @@ lib/loginprompt.c: login_prompt(char *name, int namesize)
         
          ## lib/setupenv.c ##
         @@
        + #ident "$Id$"
          
          #include <assert.h>
        - #include <ctype.h>
         +#include <stddef.h>
        - #include <stdio.h>
        - #include <string.h>
          #include <sys/types.h>
        + #include <sys/stat.h>
        + #include <stdio.h>
         @@ lib/setupenv.c: static void read_env_file (const char *filename)
            if (NULL == fp) {
                    return;
    4:  bf670236 = 4:  361e2d27 lib/, po/: Remove fgetsx() and fputsx()
    5:  7d38ceda = 5:  4b73c980 lib/: Use getline(3) instead of its pattern
    6:  4c8d340c = 6:  29f75cf2 lib/gshadow.c: fgetsgent(): Don't use static variables
    
    v5k
    • Rebase
    $ git range-diff gh/string..gh/fgets string..fgets 
    1:  551780b3 ! 1:  9595d531 contrib/, lib/, src/: Consistently use sizeof() as if it were a function
        @@ src/login_nopam.c: login_access(const char *user, const char *from)
                    {
                            char  *p;
          
        -@@ src/login_nopam.c: myhostname(void)
        +@@ src/login_nopam.c: static char *myhostname (void)
            static char name[MAXHOSTNAMELEN + 1] = "";
          
            if (streq(name, "")) {
    2:  00e3d101 = 2:  39b4a028 lib/, src/: Remove useless casts in fgets(3)
    3:  def7bd46 = 3:  52aee4d3 lib/, src/: Consistently use NULL with fgets(3)
    4:  361e2d27 = 4:  b219136c lib/, po/: Remove fgetsx() and fputsx()
    5:  4b73c980 = 5:  df79b8fc lib/: Use getline(3) instead of its pattern
    6:  29f75cf2 = 6:  a371b78b lib/gshadow.c: fgetsgent(): Don't use static variables
    
    v5l
    • Rebase
    $ git range-diff gh/string..gh/fgets string..fgets 
    1:  9595d531 = 1:  8be05fda contrib/, lib/, src/: Consistently use sizeof() as if it were a function
    2:  39b4a028 = 2:  3620b3d5 lib/, src/: Remove useless casts in fgets(3)
    3:  52aee4d3 = 3:  d5f7872a lib/, src/: Consistently use NULL with fgets(3)
    4:  b219136c = 4:  779f70be lib/, po/: Remove fgetsx() and fputsx()
    5:  df79b8fc = 5:  240124a5 lib/: Use getline(3) instead of its pattern
    6:  a371b78b = 6:  714a2b14 lib/gshadow.c: fgetsgent(): Don't use static variables
    
    v5m
    • Rebase
    $ git range-diff gh/string..gh/fgets string..fgets 
    1:  8be05fda = 1:  e07132f5 contrib/, lib/, src/: Consistently use sizeof() as if it were a function
    2:  3620b3d5 = 2:  93f18f76 lib/, src/: Remove useless casts in fgets(3)
    3:  d5f7872a = 3:  dc657761 lib/, src/: Consistently use NULL with fgets(3)
    4:  779f70be ! 4:  3aa23780 lib/, po/: Remove fgetsx() and fputsx()
        @@ lib/fputsx.c (deleted)
         -
         -#include "defines.h"
         -#include "prototypes.h"
        --
        --#ident "$Id$"
        +-#include "string/strcmp/streq.h"
         -
         -
         -/*@null@*/char *
        @@ lib/fputsx.c (deleted)
         -{
         -  int i;
         -
        --  for (i = 0; '\0' != *s; i++, s++) {
        +-  for (i = 0; !streq(s, ""); i++, s++) {
         -          if (putc (*s, stream) == EOF) {
         -                  return EOF;
         -          }
    5:  240124a5 = 5:  67f45381 lib/: Use getline(3) instead of its pattern
    6:  714a2b14 = 6:  8b45ec41 lib/gshadow.c: fgetsgent(): Don't use static variables
    
    v5n
    • Rebase
    $ git range-diff gh/string..gh/fgets string..fgets 
    1:  e07132f5 = 1:  80694cff contrib/, lib/, src/: Consistently use sizeof() as if it were a function
    2:  93f18f76 ! 2:  30f2f88d lib/, src/: Remove useless casts in fgets(3)
        @@ lib/commonio.c: int commonio_open (struct commonio_db *db, int mode)
                    }
         
          ## lib/gshadow.c ##
        -@@ lib/gshadow.c: void endsgent (void)
        +@@ lib/gshadow.c: sgetsgent(const char *string)
                    buflen *= 2;
          
                    len = strlen (buf);
    3:  dc657761 ! 3:  3ac49d36 lib/, src/: Consistently use NULL with fgets(3)
        @@ lib/getdate.y: main(void)
                if (d == -1)
         
          ## lib/gshadow.c ##
        -@@ lib/gshadow.c: void endsgent (void)
        +@@ lib/gshadow.c: sgetsgent(const char *string)
                    buflen *= 2;
          
                    len = strlen (buf);
    4:  3aa23780 ! 4:  6c058335 lib/, po/: Remove fgetsx() and fputsx()
        @@ lib/groupio.c: static struct commonio_ops group_ops = {
          };
         
          ## lib/gshadow.c ##
        -@@ lib/gshadow.c: void endsgent (void)
        +@@ lib/gshadow.c: sgetsgent(const char *string)
                    return NULL;
            }
          
        @@ lib/gshadow.c: void endsgent (void)
                    return NULL;
          
            while (   (strrchr(buf, '\n') == NULL)
        -@@ lib/gshadow.c: void endsgent (void)
        +@@ lib/gshadow.c: sgetsgent(const char *string)
                    buflen *= 2;
          
                    len = strlen (buf);
    5:  67f45381 ! 5:  377e0abd lib/: Use getline(3) instead of its pattern
        @@ lib/commonio.c: int commonio_open (struct commonio_db *db, int mode)
           */
         
          ## lib/gshadow.c ##
        -@@ lib/gshadow.c: void endsgent (void)
        +@@ lib/gshadow.c: sgetsgent(const char *string)
            return &sgroup;
          }
          
        @@ lib/gshadow.c: void endsgent (void)
          /*
           * fgetsgent - convert next line in stream to (struct sgrp)
           *
        -@@ lib/gshadow.c: void endsgent (void)
        +@@ lib/gshadow.c: sgetsgent(const char *string)
           * converts it to a (struct sgrp).  NULL is returned on EOF.
           */
          
    6:  8b45ec41 ! 6:  b9658b23 lib/gshadow.c: fgetsgent(): Don't use static variables
        @@ Commit message
             Signed-off-by: Alejandro Colomar <[email protected]>
         
          ## lib/gshadow.c ##
        -@@ lib/gshadow.c: void endsgent (void)
        +@@ lib/gshadow.c: sgetsgent(const char *string)
          /*@observer@*//*@null@*/struct sgrp *
          fgetsgent(/*@null@*/FILE *fp)
          {
    
    v5o
    • Rebase
    $ git range-diff 80694cff^..gh/fgets string..fgets 
    1:  80694cff ! 1:  90aa5f8b contrib/, lib/, src/: Consistently use sizeof() as if it were a function
        @@ lib/user_busy.c: static int check_status (const char *name, const char *sname, u
            }
         -  while (fgets (line, sizeof (line), sfile) == line) {
         +  while (fgets(line, sizeof(line), sfile) == line) {
        -           if (strncmp (line, "Uid:\t", 5) == 0) {
        +           if (strprefix(line, "Uid:\t")) {
                            unsigned long ruid, euid, suid;
          
         
    2:  30f2f88d = 2:  33373c47 lib/, src/: Remove useless casts in fgets(3)
    3:  3ac49d36 ! 3:  7d30f553 lib/, src/: Consistently use NULL with fgets(3)
        @@ lib/user_busy.c: static int check_status (const char *name, const char *sname, u
            }
         -  while (fgets(line, sizeof(line), sfile) == line) {
         +  while (fgets(line, sizeof(line), sfile) != NULL) {
        -           if (strncmp (line, "Uid:\t", 5) == 0) {
        +           if (strprefix(line, "Uid:\t")) {
                            unsigned long ruid, euid, suid;
          
         
    4:  6c058335 = 4:  3894a987 lib/, po/: Remove fgetsx() and fputsx()
    5:  377e0abd = 5:  62fbb8e1 lib/: Use getline(3) instead of its pattern
    6:  b9658b23 = 6:  1e3d7afa lib/gshadow.c: fgetsgent(): Don't use static variables
    
    v5p
    • Rebase
    $ git range-diff gh/string..gh/fgets string..fgets 
    1:  90aa5f8b ! 1:  e2f46820 contrib/, lib/, src/: Consistently use sizeof() as if it were a function
        @@ contrib/adduser.c: main (void)
         -      safeget (foo, sizeof (foo));
         +      safeget(foo, sizeof(foo));
          
        -       done = bad = correct = (foo[0] == 'y' || foo[0] == 'Y');
        +       done = bad = correct = (strprefix(foo, "y") || strprefix(foo, "Y"));
          
         @@ contrib/adduser.c: main (void)
          
        @@ lib/ttytype.c: void ttytype (const char *line)
            }
         -  while (fgets (buf, sizeof buf, fp) == buf) {
         +  while (fgets(buf, sizeof(buf), fp) == buf) {
        -           if (buf[0] == '#') {
        +           if (strprefix(buf, "#")) {
                            continue;
                    }
         
    2:  33373c47 = 2:  12cf176f lib/, src/: Remove useless casts in fgets(3)
    3:  7d30f553 ! 3:  0320b6ea lib/, src/: Consistently use NULL with fgets(3)
        @@ lib/ttytype.c: void ttytype (const char *line)
            }
         -  while (fgets(buf, sizeof(buf), fp) == buf) {
         +  while (fgets(buf, sizeof(buf), fp) != NULL) {
        -           if (buf[0] == '#') {
        +           if (strprefix(buf, "#")) {
                            continue;
                    }
         
    4:  3894a987 = 4:  fd585453 lib/, po/: Remove fgetsx() and fputsx()
    5:  62fbb8e1 = 5:  93239c4a lib/: Use getline(3) instead of its pattern
    6:  1e3d7afa = 6:  3261e283 lib/gshadow.c: fgetsgent(): Don't use static variables
    
    v5q
    • Rebase
    $ git range-diff gh/string..gh/fgets string..fgets 
    1:  e2f46820 = 1:  5f807312 contrib/, lib/, src/: Consistently use sizeof() as if it were a function
    2:  12cf176f = 2:  d008c70a lib/, src/: Remove useless casts in fgets(3)
    3:  0320b6ea = 3:  78e34e84 lib/, src/: Consistently use NULL with fgets(3)
    4:  fd585453 = 4:  7c492df2 lib/, po/: Remove fgetsx() and fputsx()
    5:  93239c4a = 5:  22a830bc lib/: Use getline(3) instead of its pattern
    6:  3261e283 = 6:  8d1c561a lib/gshadow.c: fgetsgent(): Don't use static variables
    
    v5r
    • Rebase
    $ git range-diff gh/string..gh/fgets string..fgets 
    1:  5f807312 = 1:  bdec46cf contrib/, lib/, src/: Consistently use sizeof() as if it were a function
    2:  d008c70a = 2:  af0903a9 lib/, src/: Remove useless casts in fgets(3)
    3:  78e34e84 = 3:  ce5cea23 lib/, src/: Consistently use NULL with fgets(3)
    4:  7c492df2 = 4:  cab93702 lib/, po/: Remove fgetsx() and fputsx()
    5:  22a830bc = 5:  3293e367 lib/: Use getline(3) instead of its pattern
    6:  8d1c561a = 6:  f0b6756c lib/gshadow.c: fgetsgent(): Don't use static variables
    
    v5s
    • Rebase
    $ git range-diff gh/string..gh/fgets string..fgets 
    1:  bdec46cf ! 1:  f8d0c008 contrib/, lib/, src/: Consistently use sizeof() as if it were a function
        @@ src/chgpasswd.c: int main (int argc, char **argv)
                            fprintf (stderr, _("%s: line %d: line too long\n"),
         
          ## src/chpasswd.c ##
        -@@ src/chpasswd.c: main(int argc, char **argv)
        +@@ src/chpasswd.c: int main (int argc, char **argv)
             * last change date is set in the age only if aging information is
             * present.
             */
        @@ src/chpasswd.c: main(int argc, char **argv)
                                    // Drop all remaining characters on this line.
         -                          while (fgets (buf, sizeof buf, stdin) != NULL) {
         +                          while (fgets(buf, sizeof(buf), stdin) != NULL) {
        -                                   if (!!strchr(buf, '\n'))
        +                                   if (strchr(buf, '\n'))
                                                    break;
                                    }
         
    2:  af0903a9 = 2:  8e9867a3 lib/, src/: Remove useless casts in fgets(3)
    3:  ce5cea23 = 3:  218faac9 lib/, src/: Consistently use NULL with fgets(3)
    4:  cab93702 = 4:  45ce40e0 lib/, po/: Remove fgetsx() and fputsx()
    5:  3293e367 = 5:  1f221414 lib/: Use getline(3) instead of its pattern
    6:  f0b6756c = 6:  38b17e29 lib/gshadow.c: fgetsgent(): Don't use static variables
    
    v5t
    • Rebase
    $ git range-diff gh/string..gh/fgets string..fgets 
    1:  f8d0c008 = 1:  a320dadc contrib/, lib/, src/: Consistently use sizeof() as if it were a function
    2:  8e9867a3 = 2:  23a841d9 lib/, src/: Remove useless casts in fgets(3)
    3:  218faac9 = 3:  cbc5d2e2 lib/, src/: Consistently use NULL with fgets(3)
    4:  45ce40e0 = 4:  453d6fde lib/, po/: Remove fgetsx() and fputsx()
    5:  1f221414 = 5:  f3ea5c75 lib/: Use getline(3) instead of its pattern
    6:  38b17e29 = 6:  08d68d10 lib/gshadow.c: fgetsgent(): Don't use static variables
    
    v5u
    • Rebase
    $ git range-diff gh/string..gh/fgets string..fgets 
    1:  a320dadc ! 1:  4b9d2f28 contrib/, lib/, src/: Consistently use sizeof() as if it were a function
        @@ src/chgpasswd.c: int main (int argc, char **argv)
         +  while (fgets(buf, (int) sizeof(buf), stdin) != NULL) {
                    line++;
                    if (stpsep(buf, "\n") == NULL) {
        -                   fprintf (stderr, _("%s: line %d: line too long\n"),
        +                   fprintf (stderr, _("%s: line %jd: line too long\n"),
         
          ## src/chpasswd.c ##
         @@ src/chpasswd.c: int main (int argc, char **argv)
        @@ src/login.c: int main (int argc, char **argv)
          ## src/login_nopam.c ##
         @@ src/login_nopam.c: login_access(const char *user, const char *from)
            if (NULL != fp) {
        -           int lineno = 0; /* for diagnostics */
        +           intmax_t lineno = 0;    /* for diagnostics */
                    while (   !match
         -                 && (fgets (line, sizeof (line), fp) == line))
         +                 && (fgets(line, sizeof(line), fp) == line))
        @@ src/newusers.c: int main (int argc, char **argv)
         +  while (fgets(buf, sizeof(buf), stdin) != NULL) {
                    line++;
                    if (stpsep(buf, "\n") == NULL && feof(stdin) == 0) {
        -                   fprintf (stderr, _("%s: line %d: line too long\n"),
        +                   fprintf (stderr, _("%s: line %jd: line too long\n"),
         
          ## src/pwconv.c ##
         @@ src/pwconv.c: int main (int argc, char **argv)
    2:  23a841d9 ! 2:  8579d59f lib/, src/: Remove useless casts in fgets(3)
        @@ src/chgpasswd.c: int main (int argc, char **argv)
         +  while (fgets(buf, sizeof(buf), stdin) != NULL) {
                    line++;
                    if (stpsep(buf, "\n") == NULL) {
        -                   fprintf (stderr, _("%s: line %d: line too long\n"),
        +                   fprintf (stderr, _("%s: line %jd: line too long\n"),
    3:  cbc5d2e2 ! 3:  7912afb8 lib/, src/: Consistently use NULL with fgets(3)
        @@ lib/user_busy.c: static int check_status (const char *name, const char *sname, u
          ## src/login_nopam.c ##
         @@ src/login_nopam.c: login_access(const char *user, const char *from)
            if (NULL != fp) {
        -           int lineno = 0; /* for diagnostics */
        +           intmax_t lineno = 0;    /* for diagnostics */
                    while (   !match
         -                 && (fgets(line, sizeof(line), fp) == line))
         +                 && (fgets(line, sizeof(line), fp) != NULL))
    4:  453d6fde = 4:  02cdc1c8 lib/, po/: Remove fgetsx() and fputsx()
    5:  f3ea5c75 = 5:  cff254db lib/: Use getline(3) instead of its pattern
    6:  08d68d10 = 6:  4cbd4be7 lib/gshadow.c: fgetsgent(): Don't use static variables
    
    v5v
    • Rebase
    $ git range-diff gh/string..gh/fgets string..fgets 
    1:  4b9d2f28 ! 1:  da3cf2fd contrib/, lib/, src/: Consistently use sizeof() as if it were a function
        @@ contrib/adduser.c: main (void)
            if (system (cmd))
              {
         
        - ## lib/addgrps.c ##
        -@@ lib/addgrps.c: add_groups(const char *list)
        -   int ret;
        -   FILE *shadow_logfd = log_get_logfd();
        - 
        --  if (strlen (list) >= sizeof (buf)) {
        -+  if (strlen(list) >= sizeof(buf)) {
        -           errno = EINVAL;
        -           return -1;
        -   }
        -
          ## lib/commonio.c ##
         @@ lib/commonio.c: static int do_lock_file (const char *file, const char *lock, bool log)
                    errno = EINVAL;
        @@ src/groupadd.c: static void new_grent (struct group *grent)
          {
         -  memzero (sgent, sizeof *sgent);
         +  memzero(sgent, sizeof(*sgent));
        -   sgent->sg_name = group_name;
        +   sgent->sg_namp = group_name;
            if (pflg) {
                    sgent->sg_passwd = group_passwd;
         
        @@ src/groupmod.c: grp_update(void)
                             */
         -                  bzero(&sgrp, sizeof sgrp);
         +                  bzero(&sgrp, sizeof(sgrp));
        -                   sgrp.sg_name   = xstrdup (grp.gr_name);
        +                   sgrp.sg_namp   = xstrdup (grp.gr_name);
                            sgrp.sg_passwd = xstrdup (grp.gr_passwd);
                            sgrp.sg_adm    = &empty;
         
        @@ src/grpconv.c: int main (int argc, char **argv)
                            /* add new shadow group entry */
         -                  bzero(&sgent, sizeof sgent);
         +                  bzero(&sgent, sizeof(sgent));
        -                   sgent.sg_name = gr->gr_name;
        +                   sgent.sg_namp = gr->gr_name;
                            sgent.sg_passwd = gr->gr_passwd;
                            sgent.sg_adm = &empty;
         
        @@ src/useradd.c: static void new_grent (struct group *grent)
          {
         -  memzero (sgent, sizeof *sgent);
         +  memzero(sgent, sizeof(*sgent));
        -   sgent->sg_name = (char *) user_name;
        +   sgent->sg_namp = (char *) user_name;
            sgent->sg_passwd = "!"; /* XXX warning: const */
            sgent->sg_adm = &empty_list;
         @@ src/useradd.c: static void faillog_reset (uid_t uid)
    2:  8579d59f = 2:  4415eb17 lib/, src/: Remove useless casts in fgets(3)
    3:  7912afb8 = 3:  6d066eb8 lib/, src/: Consistently use NULL with fgets(3)
    4:  02cdc1c8 = 4:  53879694 lib/, po/: Remove fgetsx() and fputsx()
    5:  cff254db = 5:  65e79372 lib/: Use getline(3) instead of its pattern
    6:  4cbd4be7 = 6:  6c307387 lib/gshadow.c: fgetsgent(): Don't use static variables
    
    v5w
    • Rebase
    $ git range-diff gh/string..gh/fgets string..fgets 
    1:  da3cf2fd = 1:  86571932 contrib/, lib/, src/: Consistently use sizeof() as if it were a function
    2:  4415eb17 = 2:  c8c777b6 lib/, src/: Remove useless casts in fgets(3)
    3:  6d066eb8 = 3:  eccf4267 lib/, src/: Consistently use NULL with fgets(3)
    4:  53879694 = 4:  debf7e3c lib/, po/: Remove fgetsx() and fputsx()
    5:  65e79372 = 5:  fb154cca lib/: Use getline(3) instead of its pattern
    6:  6c307387 = 6:  62af4606 lib/gshadow.c: fgetsgent(): Don't use static variables
    
    v5x
    • Rebase
    $ git range-diff gh/string..gh/fgets string..fgets 
    1:  86571932 = 1:  21ce510b contrib/, lib/, src/: Consistently use sizeof() as if it were a function
    2:  c8c777b6 = 2:  3ea6d3ec lib/, src/: Remove useless casts in fgets(3)
    3:  eccf4267 = 3:  f0951cd4 lib/, src/: Consistently use NULL with fgets(3)
    4:  debf7e3c = 4:  bb13c9ab lib/, po/: Remove fgetsx() and fputsx()
    5:  fb154cca = 5:  9ed7d343 lib/: Use getline(3) instead of its pattern
    6:  62af4606 = 6:  690185d4 lib/gshadow.c: fgetsgent(): Don't use static variables
    
    v5y
    • Rebase
    $ git range-diff 21ce510b1d2f^..gh/fgets string..fgets 
    1:  21ce510b = 1:  2f6a4452 contrib/, lib/, src/: Consistently use sizeof() as if it were a function
    2:  3ea6d3ec = 2:  374f771f lib/, src/: Remove useless casts in fgets(3)
    3:  f0951cd4 = 3:  b36c0cfa lib/, src/: Consistently use NULL with fgets(3)
    4:  bb13c9ab = 4:  2aec821f lib/, po/: Remove fgetsx() and fputsx()
    5:  9ed7d343 = 5:  bd5f6e16 lib/: Use getline(3) instead of its pattern
    6:  690185d4 = 6:  479883fe lib/gshadow.c: fgetsgent(): Don't use static variables
    
    v5z
    • Rebase
    $ git range-diff gh/string..gh/fgets string..fgets 
    1:  2f6a4452 = 1:  4ca804e0 contrib/, lib/, src/: Consistently use sizeof() as if it were a function
    2:  374f771f = 2:  35c4fcef lib/, src/: Remove useless casts in fgets(3)
    3:  b36c0cfa = 3:  70c17ee5 lib/, src/: Consistently use NULL with fgets(3)
    4:  2aec821f = 4:  6e1a991c lib/, po/: Remove fgetsx() and fputsx()
    5:  bd5f6e16 = 5:  3905cec1 lib/: Use getline(3) instead of its pattern
    6:  479883fe = 6:  3bd2d9ac lib/gshadow.c: fgetsgent(): Don't use static variables
    
    v6
    • Remember to free(3) after getline(3) (even on error!).
    $ git range-diff --creation-factor=99 string gh/fgets fgets 
    1:  4ca804e0 = 1:  4ca804e0 contrib/, lib/, src/: Consistently use sizeof() as if it were a function
    2:  35c4fcef = 2:  35c4fcef lib/, src/: Remove useless casts in fgets(3)
    3:  70c17ee5 = 3:  70c17ee5 lib/, src/: Consistently use NULL with fgets(3)
    4:  6e1a991c = 4:  6e1a991c lib/, po/: Remove fgetsx() and fputsx()
    5:  3905cec1 = 5:  3905cec1 lib/: Use getline(3) instead of its pattern
    6:  3bd2d9ac ! 6:  f463ab52 lib/gshadow.c: fgetsgent(): Don't use static variables
        @@ Metadata
          ## Commit message ##
             lib/gshadow.c: fgetsgent(): Don't use static variables
         
        +    BTW, getline(3) says we must free(3) the buffer on error.
        +
             Reported-by: Chris Hofstaedtler <[email protected]>
             Signed-off-by: Alejandro Colomar <[email protected]>
         
        @@ lib/gshadow.c: sgetsgent(const char *string)
          {
         -  static size_t buflen = 0;
         -  static char *buf = NULL;
        -+  char         *buf = NULL;
        -+  size_t       buflen = 0;
        ++  char         *buf;
        ++  size_t       buflen;
         +  struct sgrp  *sg;
          
            if (NULL == fp) {
                    return NULL;
        -@@ lib/gshadow.c: fgetsgent(/*@null@*/FILE *fp)
        +   }
        + 
        ++  buf = NULL;
        ++  buflen = 0;
        +   if (getline(&buf, &buflen, fp) == -1)
        +-          return NULL;
        ++          goto fail;
            if (stpsep(buf, "\n") == NULL)
        -           return NULL;
        +-          return NULL;
        ++          goto fail;
          
         -  return (sgetsgent (buf));
         +  sg = sgetsgent(buf);
         +
         +  free(buf);
        -+
         +  return sg;
        ++fail:
        ++  free(buf);
        ++  return NULL;
          }
          
          
    
    v6b
    • Rebase
    $ git range-diff gh/string..gh/fgets string..fgets 
    1:  4ca804e0 = 1:  d4e03537 contrib/, lib/, src/: Consistently use sizeof() as if it were a function
    2:  35c4fcef = 2:  49b6fee7 lib/, src/: Remove useless casts in fgets(3)
    3:  70c17ee5 ! 3:  c097c72a lib/, src/: Consistently use NULL with fgets(3)
        @@ lib/fields.c
         +#include <string.h>
          
          #include "prototypes.h"
        - #include "string/strchr/stpspn.h"
        + #include "string/strcmp/streq.h"
         @@ lib/fields.c: change_field(char *buf, size_t maxsize, const char *prompt)
          
            printf ("\t%s [%s]: ", prompt, buf);
    4:  6e1a991c = 4:  9e00e098 lib/, po/: Remove fgetsx() and fputsx()
    5:  3905cec1 = 5:  67ac895f lib/: Use getline(3) instead of its pattern
    6:  f463ab52 = 6:  c1d8d494 lib/gshadow.c: fgetsgent(): Don't use static variables
    
    v6c
    • Rebase
    $ git range-diff gh/string..gh/fgets string..fgets 
    1:  d4e03537 = 1:  0632c003 contrib/, lib/, src/: Consistently use sizeof() as if it were a function
    2:  49b6fee7 = 2:  7567966f lib/, src/: Remove useless casts in fgets(3)
    3:  c097c72a = 3:  b347ac57 lib/, src/: Consistently use NULL with fgets(3)
    4:  9e00e098 = 4:  9aaf55fb lib/, po/: Remove fgetsx() and fputsx()
    5:  67ac895f = 5:  65a4a01d lib/: Use getline(3) instead of its pattern
    6:  c1d8d494 = 6:  30929142 lib/gshadow.c: fgetsgent(): Don't use static variables
    
    v6d
    • Rebase
    $ git range-diff master..gh/fgets shadow/master..fgets 
     1:  99c3517e =  1:  35198af4 lib/, src/: Reduce scope of local variables
     2:  1ce95714 =  2:  2f2a4269 lib/string/strcmp/: strprefix(): Add API
     3:  b103ceb8 =  3:  61e5ef83 lib/, src/: Use s=strprefix(s,p)?:s instead of its pattern
     4:  1ac57a50 =  4:  fc8fb2b4 lib/, src/: Use strprefix() instead of its pattern
     5:  b095b42c =  5:  1490df3d lib/env.c: sanitize_env(): Use !strprefix() instead of its pattern
     6:  88100802 =  6:  b7cf26d0 lib/: Use strprefix() instead of its pattern
     7:  ac0458ed =  7:  45f32bd8 lib/: Use !strprefix() instead of its pattern
     8:  dee9e425 =  8:  a3e23f24 src/check_subid_range.c: main(): Remove local variable
     9:  222f5a59 =  9:  8f71db6d lib/, src/: Use strprefix() instead of its pattern
    10:  4aedf986 = 10:  68c3f50e lib/, src/: Use str[n]cmp(3) instead of explicit byte comparisons
    11:  e7b24218 = 11:  888cf1d9 contrib/, lib/, src/: Use consistent style using strchr(3) in conditionals
    12:  0632c003 ! 12:  85f9d558 contrib/, lib/, src/: Consistently use sizeof() as if it were a function
        @@ src/faillog.c: static void set_locktime (long locktime)
                            }
         
          ## src/groupadd.c ##
        -@@ src/groupadd.c: usage (int status)
        +@@ src/groupadd.c: static void fail_exit(int status)
           */
          static void new_grent (struct group *grent)
          {
        @@ src/grpconv.c: int main (int argc, char **argv)
                            sgent.sg_adm = &empty;
         
          ## src/lastlog.c ##
        -@@ src/lastlog.c: static void print_one (/*@null@*/const struct passwd *pw)
        -   }
        - 
        - 
        --  offset = (off_t) pw->pw_uid * sizeof (ll);
        --  if (offset + sizeof (ll) <= statbuf.st_size) {
        -+  offset = (off_t) pw->pw_uid * sizeof(ll);
        -+  if (offset + sizeof(ll) <= statbuf.st_size) {
        -           /* fseeko errors are not really relevant for us. */
        -           int err = fseeko (lastlogfile, offset, SEEK_SET);
        -           assert (0 == err);
         @@ src/lastlog.c: static void print_one (/*@null@*/const struct passwd *pw)
                     * entered for this user, which should be able to get the
                     * empty entry in this case.
    13:  7567966f = 13:  41ee625f lib/, src/: Remove useless casts in fgets(3)
    14:  b347ac57 = 14:  ffd89bb7 lib/, src/: Consistently use NULL with fgets(3)
    15:  9aaf55fb = 15:  c198da9a lib/, po/: Remove fgetsx() and fputsx()
    16:  65a4a01d = 16:  98ba953e lib/: Use getline(3) instead of its pattern
    17:  30929142 = 17:  59885bda lib/gshadow.c: fgetsgent(): Don't use static variables
    
    v6e
    • Rebase
    $ git range-diff gh/string..gh/fgets string..fgets 
    1:  85f9d558 = 1:  c7a5832f contrib/, lib/, src/: Consistently use sizeof() as if it were a function
    2:  41ee625f = 2:  033f2fcb lib/, src/: Remove useless casts in fgets(3)
    3:  ffd89bb7 = 3:  14c6b9c7 lib/, src/: Consistently use NULL with fgets(3)
    4:  c198da9a = 4:  144630e6 lib/, po/: Remove fgetsx() and fputsx()
    5:  98ba953e = 5:  69714884 lib/: Use getline(3) instead of its pattern
    6:  59885bda = 6:  6fc14cf5 lib/gshadow.c: fgetsgent(): Don't use static variables
    
    v6f
    • Rebase
    $ git range-diff gh/string..gh/fgets string..fgets 
    1:  c7a5832f ! 1:  4a2d5ba9 contrib/, lib/, src/: Consistently use sizeof() as if it were a function
        @@ lib/fields.c: change_field(char *buf, size_t maxsize, const char *prompt)
          
            printf ("\t%s [%s]: ", prompt, buf);
         
        - ## lib/getdate.y ##
        -@@ lib/getdate.y: yylex (void)
        -       if (isalpha (c))
        -   {
        -     for (p = buff; (c = *yyInput++, isalpha (c)) || c == '.';)
        --      if (p < &buff[sizeof buff - 1])
        -+      if (p < &buff[sizeof(buff) - 1])
        -         *p++ = c;
        -           stpcpy(p, "");
        -     yyInput--;
        -
          ## lib/getdef.c ##
         @@ lib/getdef.c: struct itemdef {
            {"MOTD_FIRSTONLY", NULL},               \
    2:  033f2fcb = 2:  4cc803fb lib/, src/: Remove useless casts in fgets(3)
    3:  14c6b9c7 = 3:  99ccfd6c lib/, src/: Consistently use NULL with fgets(3)
    4:  144630e6 = 4:  81b31630 lib/, po/: Remove fgetsx() and fputsx()
    5:  69714884 = 5:  6f208e92 lib/: Use getline(3) instead of its pattern
    6:  6fc14cf5 = 6:  25c1f5ce lib/gshadow.c: fgetsgent(): Don't use static variables
    
    v6g
    • Rebase
    $ git range-diff gh/string..gh/fgets string..fgets 
    1:  4a2d5ba9 = 1:  7f21723c contrib/, lib/, src/: Consistently use sizeof() as if it were a function
    2:  4cc803fb = 2:  83949b63 lib/, src/: Remove useless casts in fgets(3)
    3:  99ccfd6c = 3:  eed73722 lib/, src/: Consistently use NULL with fgets(3)
    4:  81b31630 = 4:  7b9df691 lib/, po/: Remove fgetsx() and fputsx()
    5:  6f208e92 = 5:  bc999bb2 lib/: Use getline(3) instead of its pattern
    6:  25c1f5ce = 6:  db8c1145 lib/gshadow.c: fgetsgent(): Don't use static variables
    
    v6h
    • Rebase
    $ git range-diff gh/string..gh/fgets string..fgets 
    1:  7f21723c = 1:  a9671f15 contrib/, lib/, src/: Consistently use sizeof() as if it were a function
    2:  83949b63 = 2:  f6d82734 lib/, src/: Remove useless casts in fgets(3)
    3:  eed73722 = 3:  36e83138 lib/, src/: Consistently use NULL with fgets(3)
    4:  7b9df691 = 4:  01aa14ab lib/, po/: Remove fgetsx() and fputsx()
    5:  bc999bb2 = 5:  1d766a1d lib/: Use getline(3) instead of its pattern
    6:  db8c1145 = 6:  c9dd7307 lib/gshadow.c: fgetsgent(): Don't use static variables
    
    v6i
    • Rebase
    $ git range-diff gh/string..gh/fgets string..fgets 
    1:  a9671f15 ! 1:  d96ea13a contrib/, lib/, src/: Consistently use sizeof() as if it were a function
        @@ lib/sgetspent.c: sgetspent(const char *string)
                             "%s: Too long passwd entry encountered, file corruption?\n",
                             shadow_progname);
         
        - ## lib/shadow.c ##
        -@@ lib/shadow.c: struct spwd *fgetspent (FILE * fp)
        -           return (0);
        -   }
        - 
        --  if (fgets (buf, sizeof buf, fp) != NULL)
        -+  if (fgets(buf, sizeof(buf), fp) != NULL)
        -   {
        -           stpsep(buf, "\n");
        -           return sgetspent(buf);
        -
          ## lib/subordinateio.c ##
         @@ lib/subordinateio.c: subordinate_parse(const char *line)
             * Copy the string to a temporary buffer so the substrings can
    2:  f6d82734 = 2:  94c0534b lib/, src/: Remove useless casts in fgets(3)
    3:  36e83138 = 3:  abfd98d5 lib/, src/: Consistently use NULL with fgets(3)
    4:  01aa14ab = 4:  aa42c669 lib/, po/: Remove fgetsx() and fputsx()
    5:  1d766a1d = 5:  fa234d92 lib/: Use getline(3) instead of its pattern
    6:  c9dd7307 = 6:  5178549c lib/gshadow.c: fgetsgent(): Don't use static variables
    
    v6j
    • Rebase
    $ git range-diff gh/string..gh/fgets string..fgets 
    1:  d96ea13a ! 1:  e3824160 contrib/, lib/, src/: Consistently use sizeof() as if it were a function
        @@ lib/setupenv.c: static void read_env_file (const char *filename)
                            break;
          
         
        - ## lib/sgetpwent.c ##
        -@@ lib/sgetpwent.c: sgetpwent(const char *buf)
        -    * the password structure remain valid.
        -    */
        - 
        --  if (strlen (buf) >= sizeof pwdbuf) {
        -+  if (strlen(buf) >= sizeof(pwdbuf)) {
        -           fprintf (shadow_logfd,
        -                    "%s: Too long passwd entry encountered, file corruption?\n",
        -                    shadow_progname);
        -
        - ## lib/sgetspent.c ##
        -@@ lib/sgetspent.c: sgetspent(const char *string)
        -    * have to do that to our private copy.
        -    */
        - 
        --  if (strlen (string) >= sizeof spwbuf) {
        -+  if (strlen(string) >= sizeof(spwbuf)) {
        -           fprintf (shadow_logfd,
        -                    "%s: Too long passwd entry encountered, file corruption?\n",
        -                    shadow_progname);
        -
          ## lib/subordinateio.c ##
         @@ lib/subordinateio.c: subordinate_parse(const char *line)
             * Copy the string to a temporary buffer so the substrings can
    2:  94c0534b ! 2:  327aeffa lib/, src/: Remove useless casts in fgets(3)
        @@ lib/commonio.c: int commonio_open (struct commonio_db *db, int mode)
                    }
         
          ## lib/gshadow.c ##
        -@@ lib/gshadow.c: sgetsgent(const char *string)
        +@@ lib/gshadow.c: sgetsgent(const char *s)
                    buflen *= 2;
          
                    len = strlen (buf);
    3:  abfd98d5 ! 3:  569753c5 lib/, src/: Consistently use NULL with fgets(3)
        @@ lib/getdate.y: main(void)
                if (d == -1)
         
          ## lib/gshadow.c ##
        -@@ lib/gshadow.c: sgetsgent(const char *string)
        +@@ lib/gshadow.c: sgetsgent(const char *s)
                    buflen *= 2;
          
                    len = strlen (buf);
    4:  aa42c669 ! 4:  4644e511 lib/, po/: Remove fgetsx() and fputsx()
        @@ lib/groupio.c: static struct commonio_ops group_ops = {
          };
         
          ## lib/gshadow.c ##
        -@@ lib/gshadow.c: sgetsgent(const char *string)
        +@@ lib/gshadow.c: sgetsgent(const char *s)
                    return NULL;
            }
          
        @@ lib/gshadow.c: sgetsgent(const char *string)
                    return NULL;
          
            while (   (strrchr(buf, '\n') == NULL)
        -@@ lib/gshadow.c: sgetsgent(const char *string)
        +@@ lib/gshadow.c: sgetsgent(const char *s)
                    buflen *= 2;
          
                    len = strlen (buf);
    5:  fa234d92 ! 5:  cefc100b lib/: Use getline(3) instead of its pattern
        @@ lib/commonio.c: int commonio_open (struct commonio_db *db, int mode)
           */
         
          ## lib/gshadow.c ##
        -@@ lib/gshadow.c: sgetsgent(const char *string)
        +@@ lib/gshadow.c: sgetsgent(const char *s)
            return &sgroup;
          }
          
        @@ lib/gshadow.c: sgetsgent(const char *string)
          /*
           * fgetsgent - convert next line in stream to (struct sgrp)
           *
        -@@ lib/gshadow.c: sgetsgent(const char *string)
        +@@ lib/gshadow.c: sgetsgent(const char *s)
           * converts it to a (struct sgrp).  NULL is returned on EOF.
           */
          
    6:  5178549c ! 6:  c046c0ed lib/gshadow.c: fgetsgent(): Don't use static variables
        @@ Commit message
             Signed-off-by: Alejandro Colomar <[email protected]>
         
          ## lib/gshadow.c ##
        -@@ lib/gshadow.c: sgetsgent(const char *string)
        +@@ lib/gshadow.c: sgetsgent(const char *s)
          /*@observer@*//*@null@*/struct sgrp *
          fgetsgent(/*@null@*/FILE *fp)
          {
    
    v6k
    • Rebase
    $ git range-diff gh/string..gh/fgets string..fgets 
    1:  e3824160 = 1:  e2555392 contrib/, lib/, src/: Consistently use sizeof() as if it were a function
    2:  327aeffa = 2:  348486c2 lib/, src/: Remove useless casts in fgets(3)
    3:  569753c5 ! 3:  7891956a lib/, src/: Consistently use NULL with fgets(3)
        @@ lib/fputsx.c: fgetsx(/*@returned@*/char *restrict buf, int cnt, FILE *restrict f
                                    return NULL;
                            } else {
         
        - ## lib/getdate.y ##
        -@@
        - #endif
        - 
        - #include <ctype.h>
        -+#include <stddef.h>
        - #include <stdio.h>
        - #include <string.h>
        - #include <time.h>
        -@@ lib/getdate.y: main(void)
        -   (void) fflush (stdout);
        - 
        -   buff[MAX_BUFF_LEN] = 0;
        --  while (fgets (buff, MAX_BUFF_LEN, stdin) && buff[0])
        -+  while (fgets(buff, MAX_BUFF_LEN, stdin) != NULL && buff[0])
        -     {
        -       d = get_date(buff, NULL);
        -       if (d == -1)
        -
          ## lib/gshadow.c ##
         @@ lib/gshadow.c: sgetsgent(const char *s)
                    buflen *= 2;
    4:  4644e511 = 4:  41dee385 lib/, po/: Remove fgetsx() and fputsx()
    5:  cefc100b = 5:  25aa344a lib/: Use getline(3) instead of its pattern
    6:  c046c0ed = 6:  2d640f69 lib/gshadow.c: fgetsgent(): Don't use static variables
    
    v6l
    • Rebase
    $ git range-diff gh/string..gh/fgets string..fgets 
    1:  e2555392 ! 1:  a462d33c contrib/, lib/, src/: Consistently use sizeof() as if it were a function
        @@ contrib/adduser.c: main (void)
         -      safeget (foo, sizeof (foo));
         +      safeget(foo, sizeof(foo));
          
        -       done = bad = correct = (strprefix(foo, "y") || strprefix(foo, "Y"));
        +       done = bad = correct = strcaseprefix(foo, "y");
          
         @@ contrib/adduser.c: main (void)
          
    2:  348486c2 = 2:  86e8c887 lib/, src/: Remove useless casts in fgets(3)
    3:  7891956a = 3:  45858d68 lib/, src/: Consistently use NULL with fgets(3)
    4:  41dee385 = 4:  0c001bc4 lib/, po/: Remove fgetsx() and fputsx()
    5:  25aa344a = 5:  0b02ab1d lib/: Use getline(3) instead of its pattern
    6:  2d640f69 = 6:  aa2463d9 lib/gshadow.c: fgetsgent(): Don't use static variables
    
    v6m
    • Rebase
    $ git range-diff gh/string..gh/fgets string..fgets 
    1:  a462d33c ! 1:  70501f3b contrib/, lib/, src/: Consistently use sizeof() as if it were a function
        @@ lib/fields.c: change_field(char *buf, size_t maxsize, const char *prompt)
            printf ("\t%s [%s]: ", prompt, buf);
         
          ## lib/getdef.c ##
        -@@ lib/getdef.c: struct itemdef {
        -   {"MOTD_FIRSTONLY", NULL},               \
        - 
        - 
        --#define NUMDEFS   (sizeof(def_table)/sizeof(def_table[0]))
        -+#define NUMDEFS  (sizeof(def_table) / sizeof(def_table[0]))
        - static struct itemdef def_table[] = {
        -   {"CHFN_RESTRICT", NULL},
        -   {"CONSOLE_GROUPS", NULL},
         @@ lib/getdef.c: static void def_load (void)
            /*
             * Go through all of the lines in the file.
    2:  86e8c887 = 2:  23d7b16b lib/, src/: Remove useless casts in fgets(3)
    3:  45858d68 ! 3:  78bf46fc lib/, src/: Consistently use NULL with fgets(3)
        @@ lib/commonio.c: int commonio_open (struct commonio_db *db, int mode)
         
          ## lib/fields.c ##
         @@
        - #ident "$Id$"
        + #include "fields.h"
          
          #include <ctype.h>
         -#include <string.h>
        @@ lib/fields.c
         +#include <string.h>
          
          #include "prototypes.h"
        - #include "string/strcmp/streq.h"
        + #include "string/ctype/strisascii/strisprint.h"
         @@ lib/fields.c: change_field(char *buf, size_t maxsize, const char *prompt)
          
            printf ("\t%s [%s]: ", prompt, buf);
    4:  0c001bc4 ! 4:  56a61625 lib/, po/: Remove fgetsx() and fputsx()
        @@ lib/Makefile.am: libshadow_la_SOURCES = \
            find_new_sub_gids.c \
            find_new_sub_uids.c \
         -  fputsx.c \
        -   fs/readlink/areadlink.c \
        -   fs/readlink/areadlink.h \
        -   fs/readlink/readlinknul.c \
        +   fs/mkstemp/fmkomstemp.c \
        +   fs/mkstemp/fmkomstemp.h \
        +   fs/mkstemp/mkomstemp.c \
         
          ## lib/commonio.c ##
         @@ lib/commonio.c: int commonio_open (struct commonio_db *db, int mode)
    5:  0b02ab1d = 5:  f20dea73 lib/: Use getline(3) instead of its pattern
    6:  aa2463d9 = 6:  665787ae lib/gshadow.c: fgetsgent(): Don't use static variables
    
    v6n
    • Rebase
    $ git range-diff gh/string..gh/fgets string..fgets 
    1:  70501f3b = 1:  aa941f27 contrib/, lib/, src/: Consistently use sizeof() as if it were a function
    2:  23d7b16b = 2:  90be577a lib/, src/: Remove useless casts in fgets(3)
    3:  78bf46fc = 3:  0696dced lib/, src/: Consistently use NULL with fgets(3)
    4:  56a61625 = 4:  a9174275 lib/, po/: Remove fgetsx() and fputsx()
    5:  f20dea73 = 5:  b12ac1a2 lib/: Use getline(3) instead of its pattern
    6:  665787ae = 6:  134a6408 lib/gshadow.c: fgetsgent(): Don't use static variables
    
    v6o
    • Rebase
    $ git range-diff gh/string..gh/fgets string..fgets 
    1:  aa941f27 = 1:  78771cb3 contrib/, lib/, src/: Consistently use sizeof() as if it were a function
    2:  90be577a = 2:  26d8e767 lib/, src/: Remove useless casts in fgets(3)
    3:  0696dced = 3:  ab82626f lib/, src/: Consistently use NULL with fgets(3)
    4:  a9174275 = 4:  d491f57c lib/, po/: Remove fgetsx() and fputsx()
    5:  b12ac1a2 = 5:  4f8cb8cf lib/: Use getline(3) instead of its pattern
    6:  134a6408 = 6:  9d98c22f lib/gshadow.c: fgetsgent(): Don't use static variables
    
    v6p
    • Rebase
    $ git range-diff gh/string..gh/fgets string..fgets 
    1:  78771cb3 = 1:  c93723c2 contrib/, lib/, src/: Consistently use sizeof() as if it were a function
    2:  26d8e767 = 2:  945379e8 lib/, src/: Remove useless casts in fgets(3)
    3:  ab82626f = 3:  bd74c85e lib/, src/: Consistently use NULL with fgets(3)
    4:  d491f57c = 4:  1b29b5b6 lib/, po/: Remove fgetsx() and fputsx()
    5:  4f8cb8cf = 5:  dd38fdbd lib/: Use getline(3) instead of its pattern
    6:  9d98c22f = 6:  1d942f61 lib/gshadow.c: fgetsgent(): Don't use static variables
    
    v6q
    • Rebase
    $ git range-diff gh/string..gh/fgets string..fgets 
    1:  c93723c2 ! 1:  821ee57c contrib/, lib/, src/: Consistently use sizeof() as if it were a function
        @@ Metadata
         Author: Alejandro Colomar <[email protected]>
         
          ## Commit message ##
        -    contrib/, lib/, src/: Consistently use sizeof() as if it were a function
        +    lib/, src/: Consistently use sizeof() as if it were a function
         
             sizeof(foo)
         
        @@ Commit message
             Link: <https://lkml.org/lkml/2012/7/11/103>
             Signed-off-by: Alejandro Colomar <[email protected]>
         
        - ## contrib/adduser.c ##
        -@@ contrib/adduser.c: main (void)
        -     printf ("\nLogin to add (^C to quit): ");
        -     fflush (stdout);
        - 
        --    safeget (usrname, sizeof (usrname));
        -+    safeget(usrname, sizeof(usrname));
        - 
        -     if (!strlen (usrname))
        -       {
        -@@ contrib/adduser.c: main (void)
        - 
        -       printf ("\nFull Name [%s]: ", usrname);
        -       fflush (stdout);
        --      safeget (person, sizeof (person));
        -+      safeget(person, sizeof(person));
        -       if (!strlen (person))
        -   {
        --    bzero (person, sizeof (person));
        -+    bzero(person, sizeof(person));
        -     strcpy (person, usrname);
        -   };
        - 
        -@@ contrib/adduser.c: main (void)
        -         bad = 0;
        -         printf ("GID [%d]: ", DEFAULT_GROUP);
        -         fflush (stdout);
        --        safeget (foo, sizeof (foo));
        -+        safeget(foo, sizeof(foo));
        -         if (!strlen (foo))
        -           group = DEFAULT_GROUP;
        -         else if (isdigit (*foo))
        -@@ contrib/adduser.c: main (void)
        -     printf ("\nIf home dir ends with a / then '%s' will be appended to it\n", usrname);
        -     printf ("Home Directory [%s/%s]: ", DEFAULT_HOME, usrname);
        -     fflush (stdout);
        --    safeget (dir, sizeof (dir));
        -+    safeget(dir, sizeof(dir));
        -     if (!strlen(dir))  /* hit return */
        -       sprintf(dir, "%s/%s", DEFAULT_HOME, usrname);
        -     else if (dir[strlen (dir) - 1] == '/')
        -@@ contrib/adduser.c: main (void)
        - 
        -       printf ("\nShell [%s]: ", DEFAULT_SHELL);
        -       fflush (stdout);
        --      safeget (shell, sizeof (shell));
        -+      safeget(shell, sizeof(shell));
        -       if (!strlen (shell))
        -   strcpy(shell, DEFAULT_SHELL);
        -       else
        -@@ contrib/adduser.c: main (void)
        - #endif
        -     printf ("\nMin. Password Change Days [%d]: ", DEFAULT_MIN_PASS);
        -     fflush (stdout);
        --    safeget (foo, sizeof (foo));
        -+    safeget(foo, sizeof(foo));
        -     if (strlen (foo) > 1)
        -       min_pass = DEFAULT_MIN_PASS;
        -     else
        -@@ contrib/adduser.c: main (void)
        - 
        -     printf ("Max. Password Change Days [%d]: ", DEFAULT_MAX_PASS);
        -     fflush (stdout);
        --    safeget (foo, sizeof (foo));
        -+    safeget(foo, sizeof(foo));
        -     if (strlen (foo) > 1)
        -       max_pass = atoi (foo);
        -     else
        -@@ contrib/adduser.c: main (void)
        - 
        -     printf ("Password Warning Days [%d]: ", DEFAULT_WARN_PASS);
        -     fflush (stdout);
        --    safeget (foo, sizeof (foo));
        -+    safeget(foo, sizeof(foo));
        -     warn_pass = atoi (foo);
        -     if (warn_pass == 0)
        - 
        -@@ contrib/adduser.c: main (void)
        - 
        -     printf ("Days after Password Expiry for Account Locking [%d]: ", DEFAULT_USER_DIE);
        -     fflush (stdout);
        --    safeget (foo, sizeof (foo));
        -+    safeget(foo, sizeof(foo));
        -     user_die = atoi (foo);
        -     if (user_die == 0)
        -       user_die = DEFAULT_USER_DIE;
        -@@ contrib/adduser.c: main (void)
        -         min_pass, max_pass, warn_pass, user_die);
        -       printf ("\nIs this correct? [y/N]: ");
        -       fflush (stdout);
        --      safeget (foo, sizeof (foo));
        -+      safeget(foo, sizeof(foo));
        - 
        -       done = bad = correct = strcaseprefix(foo, "y");
        - 
        -@@ contrib/adduser.c: main (void)
        - 
        -   *environ = NULL;
        - 
        --  bzero (cmd, sizeof (cmd));
        -+  bzero(cmd, sizeof(cmd));
        -   sprintf (cmd, "%s -g %d -d %s -s %s -c \"%s\" -m -k /etc/skel %s",
        -      USERADD_PATH, group, dir, shell, person, usrname);
        -   printf ("Calling useradd to add new user:\n%s\n", cmd);
        -@@ contrib/adduser.c: main (void)
        -                    */
        -   setuid (0);
        - 
        --  bzero (cmd, sizeof (cmd));
        -+  bzero(cmd, sizeof(cmd));
        - 
        -   /* Chage runs suid root. => we need ruid root to run it with
        -    * anything other than chage -l
        -@@ contrib/adduser.c: main (void)
        -   /* I want to add a user completely with one easy command --chris */
        - 
        - #ifdef HAVE_QUOTAS
        --  bzero (cmd, sizeof (cmd));
        -+  bzero(cmd, sizeof(cmd));
        -   sprintf (cmd, "%s -p %s -u %s", EDQUOTA_PATH, QUOTA_DEFAULT, usrname);
        -   printf ("%s\n", cmd);
        -   if (system (cmd))
        -@@ contrib/adduser.c: main (void)
        -     printf ("\nDefault quota set.\n");
        - #endif /* HAVE_QUOTAS */
        - 
        --  bzero (cmd, sizeof (cmd));
        -+  bzero(cmd, sizeof(cmd));
        -   sprintf (cmd, "%s %s", PASSWD_PATH, usrname);
        -   if (system (cmd))
        -     {
        -@@ contrib/adduser.c: main (void)
        - #endif
        -     }
        - #ifdef IMMEDIATE_CHANGE
        --  bzero (cmd, sizeof (cmd));
        -+  bzero(cmd, sizeof(cmd));
        -   sprintf (cmd, "%s -e %s", PASSWD_PATH, usrname);
        -   if (system (cmd))
        -     {
        -
          ## lib/commonio.c ##
         @@ lib/commonio.c: static int do_lock_file (const char *file, const char *lock, bool log)
                    errno = EINVAL;
    2:  945379e8 = 2:  0bacfef5 lib/, src/: Remove useless casts in fgets(3)
    3:  bd74c85e = 3:  8659380e lib/, src/: Consistently use NULL with fgets(3)
    4:  1b29b5b6 = 4:  e4a23020 lib/, po/: Remove fgetsx() and fputsx()
    5:  dd38fdbd = 5:  f04a6520 lib/: Use getline(3) instead of its pattern
    6:  1d942f61 = 6:  af556bc5 lib/gshadow.c: fgetsgent(): Don't use static variables
    

    @alejandro-colomar alejandro-colomar marked this pull request as ready for review July 21, 2024 17:01
    @alejandro-colomar alejandro-colomar marked this pull request as draft July 21, 2024 17:01
    lib/gshadow.c Outdated
    Comment on lines 158 to 177
    if (fgetsx(buf, buflen, fp) == buf) {
    while ( ((cp = strrchr (buf, '\n')) == NULL)
    && (feof (fp) == 0)) {
    size_t len;

    cp = REALLOC(buf, buflen * 2, char);
    if (NULL == cp) {
    return NULL;
    }
    buf = cp;
    buflen *= 2;

    len = strlen (buf);
    if (fgetsx (&buf[len],
    (int) (buflen - len),
    fp) != &buf[len]) {
    return NULL;
    }
    if (fgets(buf, buflen, fp) == NULL)
    return NULL;

    while ( (strrchr(buf, '\n') == NULL)
    && (feof (fp) == 0)) {
    size_t len;

    cp = REALLOC(buf, buflen * 2, char);
    if (NULL == cp) {
    return NULL;
    }
    stpsep(buf, "\n");
    return (sgetsgent (buf));
    buf = cp;
    buflen *= 2;

    len = strlen (buf);
    if (fgets(&buf[len], buflen - len, fp) == NULL)
    return NULL;
    }
    return NULL;
    stpsep(buf, "\n");
    return (sgetsgent (buf));
    Copy link
    Collaborator Author

    @alejandro-colomar alejandro-colomar Jul 22, 2024

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    @thesamesam

    Hi Sam,

    It might be worth commenting this here.

    Here's an overview of the branch:

    $ git log --oneline master..fgets 
    cd64d530 (HEAD -> fgets, gh/fgets) lib/, po/: Remove fgetsx() and fputsx()
    941c951c lib/, src/: Remove useless casts in fgets(3)
    4d66df60 lib/, src/: Consistently use NULL with fgets(3)
    d0cdc9c8 lib/gshadow.c: endsgent(): Invert logic to reduce indentation
    a719bc39 (gh/string, string) lib/fields.c: Remove dead code
    b71d2236 contrib/, lib/, src/: Use consistent style using strchr(3) in conditionals
    44df1083 lib/, src/: Use str[n]cmp(3) instead of explicit byte comparisons
    d3350b67 contrib/, lib/, src/: Use strchr(3) to compact comparisons
    9a6e3284 lib/loginprompt.c: login_prompt(): Use strtcpy() instead of its pattern
    db93a222 lib/, src/: Use strsep(3) instead of strtok(3)
    376e4166 src/suauth.c: check_su_auth(): Use pointers to simplify
    ae1c284e src/suauth.c: check_su_auth(): Use strspn(3) instead of its pattern
    93362cc3 lib/gshadow.c: endsgent(): Remove dead assignment
    5a46723a lib/port.c: portcmp(): Use strcmp(3) instead of its pattern
    7442a127 lib/, src/: Use stpspn() instead of its pattern
    

    This fgets branch is really only

    $ git log --oneline string..fgets 
    cd64d530 (HEAD -> fgets, gh/fgets) lib/, po/: Remove fgetsx() and fputsx()
    941c951c lib/, src/: Remove useless casts in fgets(3)
    4d66df60 lib/, src/: Consistently use NULL with fgets(3)
    d0cdc9c8 lib/gshadow.c: endsgent(): Invert logic to reduce indentation
    

    but I based it on string, which corresponds to PR #1048.

    Here's why. Basically, according to the bug report that it closes, the PR is about replacing fgetsx => fgets. Here are two of the calls that we replace:

    $ grep -rnC4 fgetsx lib/gshadow.c
    154-	if (NULL == fp) {
    155-		return NULL;
    156-	}
    157-
    158:	if (fgetsx(buf, buflen, fp) == buf) {
    159-		while (   ((cp = strrchr (buf, '\n')) == NULL)
    160-		       && (feof (fp) == 0)) {
    161-			size_t len;
    162-
    --
    167-			buf = cp;
    168-			buflen *= 2;
    169-
    170-			len = strlen (buf);
    171:			if (fgetsx (&buf[len],
    172-			            (int) (buflen - len),
    173-			            fp) != &buf[len]) {
    174-				return NULL;
    175-			}

    I want to fully understand what the code is doing before doing the change, which makes me more confident that the change is correct. To that end, I need to reduce superfluous complexity.

    In the code above, you may notice a dead assignment:

    159-		while (   ((cp = strrchr (buf, '\n')) == NULL)

    I already had removed that dead assignment in #1048 in commit 93362cc. That's the only reason why I decided to base it on that PR.

    Now let's see why this PR has 4 new commits, instead of 1.

    Line

    158:	if (fgetsx(buf, buflen, fp) == buf) {

    Has a conditional that spans the entire rest of the function. Commit 1 turns this into the usual thing, which is an early return on error.

    Then we get to

    171:			if (fgetsx (&buf[len],
    172-			            (int) (buflen - len),
    173-			            fp) != &buf[len]) {

    Why do we have that cast? It's nonsense. I'll remove it.
    And also &buf[len] is very brittle, and a small typo could add a bug here. Let's use NULL there.

    While doing those two changes, I'll check any other places that do similarly bad stuff, and replace it in the entire code base. Then commit 4 does what we originally wanted.

    I don't reason too much the first 3 commits, which you might find frustrating while reviewing the changes a posteriori. I didn't because they're not the main purpose of the PR; they're just trivial cosmetic changes in preparation for the PR. And it's usual to apply cosmetic patches as the first patches in a patch set, to prepare for the important ones.

    Do you have any suggestions for making it easier for you to review the changes later?

    Maybe I could add an explicit [cosmetic] in the second line of the commit message, to mark those as unimportant commits.

    Still, I need to apply those cosmetic changes, or it would be much more difficult to me to reason about the important changes of the PR.

    Copy link
    Collaborator Author

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    And these cosmetic patches combined with the change fgetsx=>fgets have allowed me to see a transformation fgets=>getline too. I probably wouldn't have been able to see it without the cosmetic changes.

    Copy link
    Contributor

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    Did you consider my coccinelle suggestion?

    Copy link
    Collaborator Author

    @alejandro-colomar alejandro-colomar Jul 22, 2024

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    I don't know how to use it. If you point me to some docs and/or show me a small shell example session showing how it's useful (the example will help more than the docs, TBH), I'll be happy to try it.

    Copy link
    Collaborator Author

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    Hmmm. https://coccinelle.gitlabpages.inria.fr/website/sp.html. Sounds like it could be interesting.

    Copy link
    Contributor

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    That's why I mentioned it before ;)

    I think it's both a good fit for the work you're interested in and eases review of it.

    Copy link
    Collaborator Author

    @alejandro-colomar alejandro-colomar Jul 23, 2024

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    I'm trying to develop a coccinelle script that would do something similar to 941c951

    So far, I've written

    $ cat fgets_cast.sp 
    @@
    expression a, b, c;
    type t;
    
    @@
    
    - fgets(a, (t) (b), c)
    + fgets(a, b, c)
    
    @@
    expression a, b, c;
    type t;
    
    @@
    
    - fgets(a, (t) b, c)
    + fgets(a, b, c)
    
    @@
    expression a, b, c;
    type t;
    @@
    
    - fgetsx(a, (t) (b), c)
    + fgetsx(a, b, c)
    
    @@
    expression a, b, c;
    type t;
    @@
    
    - fgetsx(a, (t) b, c)
    + fgetsx(a, b, c)
    
    @@
    expression a, b, c, p;
    type t;
    @@
    
    - p->fgets(a, (t) (b), c)
    + p->fgets(a, b, c)
    
    @@
    expression a, b, c, p;
    type t;
    @@
    
    - p->fgets(a, (t) b, c)
    + p->fgets(a, b, c)

    and I'm running it as

    $ find lib* src/ -type f \
    | xargs spatch --sp-file ~/tmp/spatch/fgets_cast.sp --in-place;

    but it results in false positives, such as

    diff --git i/lib/shadow.c w/lib/shadow.c
    index 44436836..5759f259 100644
    --- i/lib/shadow.c
    +++ w/lib/shadow.c
    @@ -202,7 +202,7 @@ struct spwd *fgetspent (FILE * fp)
                    return (0);
            }
     
    -       if (fgets (buf, sizeof buf, fp) != NULL)
    +       if (fgets(buf, sizeof buf, fp) != NULL)
            {
                    stpsep(buf, "\n");
                    return my_sgetspent (buf);

    How is that matching (t), if there are no casts?

    @@ -81,9 +84,8 @@ void login_prompt (char *name, int namesize)
    */

    MEMZERO(buf);
    if (fgets (buf, sizeof buf, stdin) != buf) {
    if (fgets(buf, sizeof(buf), stdin) == NULL)
    Copy link
    Contributor

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    It would be helpful if formatting changes weren't mixed in.

    Copy link
    Collaborator Author

    @alejandro-colomar alejandro-colomar Jul 22, 2024

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    I try to keep those to a minimum: only whitespace and (sometimes) parentheses. And only on hunks where it (subjectively, admittedly) doesn't hurt too much readability (i.e., if I'm doing some huge transformations where I need your attention somewhere, I'll try to not do it there.

    I'll keep in mind your concern.

    /*
    * fgetsgent - convert next line in stream to (struct sgrp)
    *
    * fgetsgent() reads the next line from the provided stream and
    * converts it to a (struct sgrp). NULL is returned on EOF.
    */

    /*@observer@*//*@null@*/struct sgrp *fgetsgent (/*@null@*/FILE * fp)
    /*@observer@*//*@null@*/struct sgrp *
    fgetsgent(/*@null@*/FILE *fp)
    Copy link
    Contributor

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    Is this null stuff really needed? Can't we use the attribute for it?

    Copy link
    Collaborator Author

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    I added some patches for reducing those comments some time ago, and replaced some of them by attributes and qualifiers

    I should have another look at those at some point, and send another round of patches.

    lib/fields.c Outdated
    @@ -66,7 +68,8 @@ int valid_field (const char *field, const char *illegal)
    * prompt the user with the name of the field being changed and the
    * current value.
    */
    void change_field (char *buf, size_t maxsize, const char *prompt)
    void
    Copy link
    Contributor

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    Really, if you must do this, can't you just do a huge clang-format pass?

    Copy link
    Collaborator Author

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    Hmm, I'll have a look at using it. Thanks for the suggestion.

    @thesamesam
    Copy link
    Contributor

    I really feel this PR is still pretty noisy.

    @alejandro-colomar alejandro-colomar force-pushed the fgets branch 2 times, most recently from 0936efa to 5100579 Compare July 23, 2024 21:32
    Comment on lines 401 to 403
    bzero (cmd, sizeof (cmd));
    bzero(cmd, sizeof(cmd));
    Copy link
    Collaborator Author

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    @thesamesam

    If you apply the semantic patch accompanied with the corresponding commit message, and then git diff -w against the actual commit, you should be able to ignore these unrelated whitespace changes. I've written recommendations for how to better review each commit.

    I hope that helps reviewing, while at the same time allowing me to apply some house style while doing the changes.

    This is simpler to read, IMO.
    
    Signed-off-by: Alejandro Colomar <[email protected]>
    While the return value is a pointer, it can be interpreted as a boolean
    value meaning "found".  In general, we use explicit comparisons of
    pointers to NULL, but in this specific case, let's use that
    interpretation, and make an exception, using an implicit conversion to
    boolean.
    
    For negative matches, use
    	if (!strchr(...))
    
    For positive matches, use
    	if (strchr(...))
    
    For positive matches, when a variable is also set, use
    	while (NULL != (p = strchr(...)))
    
    Signed-off-by: Alejandro Colomar <[email protected]>
    sizeof(foo)
    
    -  No spaces.
    	Not:  sizeof (foo)
    -  Parentheses.
    	Not:  sizeof foo
    -  No parentheses wrapping sizeof itself
    	Not:  (sizeof foo)
    
    This patch can be approximated with the following semantic patch:
    
    	$ cat ~/tmp/spatch/sizeof.sp
    	@@
    	identifier a, b;
    	@@
    
    	- sizeof a->b
    	+ sizeof(a->b)
    
    	@@
    	identifier a, b;
    	@@
    
    	- sizeof a.b
    	+ sizeof(a.b)
    
    	@@
    	identifier x;
    	@@
    
    	- sizeof x
    	+ sizeof(x)
    
    	@@
    	identifier x;
    	@@
    
    	- sizeof *x
    	+ sizeof(*x)
    
    	@@
    	identifier x;
    	@@
    
    	- (sizeof(x))
    	+ sizeof(x)
    
    	@@
    	identifier x;
    	@@
    
    	- (sizeof(*x))
    	+ sizeof(*x)
    
    Applied as
    
    	$ find contrib/ lib* src/ -type f \
    	| xargs spatch --sp-file ~/tmp/spatch/sizeof.sp --in-place;
    
    The differences between the actual patch and the approximation via the
    semantic patch from above are whitespace only.  When reviewing, it'll
    be useful to diff with '-w'.
    
    Link: <https://lkml.org/lkml/2012/7/11/103>
    Signed-off-by: Alejandro Colomar <[email protected]>
    This patch can be replicated with the following semantic patch:
    
    	$ cat fgets_cast.sp
    	@@
    	expression a, b, c;
    	@@
    
    	- fgets(a, (int) (b), c)
    	+ fgets(a, b, c)
    
    	@@
    	expression a, b, c;
    	@@
    
    	- fgets(a, (int) b, c)
    	+ fgets(a, b, c)
    
    	@@
    	expression a, b, c;
    	@@
    
    	- fgetsx(a, (int) (b), c)
    	+ fgetsx(a, b, c)
    
    	@@
    	expression a, b, c;
    	@@
    
    	- fgetsx(a, (int) b, c)
    	+ fgetsx(a, b, c)
    
    	@@
    	expression a, b, c, p;
    	@@
    
    	- p->fgets(a, (int) (b), c)
    	+ p->fgets(a, b, c)
    
    	@@
    	expression a, b, c, p;
    	@@
    
    	- p->fgets(a, (int) b, c)
    	+ p->fgets(a, b, c)
    
    which is applied as:
    
    	$ find lib* src/ -type f \
    	| xargs spatch --sp-file ~/tmp/spatch/fgets_cast.sp --in-place;
    
    Signed-off-by: Alejandro Colomar <[email protected]>
    fgets(3) returns either NULL or the input pointer.  Checking for NULL is
    more explicit, and simpler.
    
    <stddef.h> is the header that provides NULL; add it where appropriate.
    
    The meat of this patch can be approximated with the following semantic
    patch:
    
    	$ cat ~/tmp/spatch/fgets_null.sp
    	@@
    	expression a, b, c;
    	@@
    
    	- fgets(a, b, c) == a
    	+ fgets(a, b, c) != NULL
    
    	@@
    	expression a, b, c;
    	@@
    
    	- fgetsx(a, b, c) == a
    	+ fgetsx(a, b, c) != NULL
    
    	@@
    	expression a, b, c, p;
    	@@
    
    	- p->fgets(a, b, c) == a
    	+ p->fgets(a, b, c) != NULL
    
    	@@
    	expression a, b, c;
    	@@
    
    	- fgets(a, b, c) != a
    	+ fgets(a, b, c) == NULL
    
    	@@
    	expression a, b, c;
    	@@
    
    	- fgetsx(a, b, c) != a
    	+ fgetsx(a, b, c) == NULL
    
    	@@
    	expression a, b, c, p;
    	@@
    
    	- p->fgets(a, b, c) != a
    	+ p->fgets(a, b, c) == NUL
    
    Applied as
    
    	$ find contrib/ lib* src/ -type f \
    	| xargs spatch --sp-file ~/tmp/spatch/fgets_null.sp --in-place;
    
    The differences between the actual patch and the approximation via the
    semantic patch from above are includes, whitespace, braces, and a case
    where there was an implicit pointer-to-bool comparison which I made
    explicit.  When reviewing, it'll be useful to use git-diff(1) with '-w'
    and '--color-words=.'.
    
    Signed-off-by: Alejandro Colomar <[email protected]>
    It seems they never worked correctly.  Let's keep it simple and remove
    support for escaped newlines.
    
    Closes: <shadow-maint#1055>
    Reported-by: Chris Hofstaedtler <[email protected]>
    Signed-off-by: Alejandro Colomar <[email protected]>
    BTW, getline(3) says we must free(3) the buffer on error.
    
    Reported-by: Chris Hofstaedtler <[email protected]>
    Signed-off-by: Alejandro Colomar <[email protected]>
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    None yet
    Projects
    None yet
    Development

    Successfully merging this pull request may close these issues.

    fputsx is not round-trip safe with backslash-ending usernames
    4 participants