Skip to content
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

Simplify a lot of NIH stuff, and fix several bugs #991

Open
wants to merge 30 commits into
base: master
Choose a base branch
from

Conversation

alejandro-colomar
Copy link
Collaborator

@alejandro-colomar alejandro-colomar commented May 12, 2024

I was looking at some code about REALLOC(), due to my recent implementation of these macros in neomutt(1), just to do some sanity checks.

While doing that, I found that a few cases were still open-coding the REALLOCF() variant, so I changed that. Then I found nearby some other nasty open-coded versions of strcspn(3) and strsep(3), which I also adapted (in several steps). Then I found another case of REALLOCF().

And finally, while doing some of those simplifications, they made obvious that there was a forever loop in a mis-handled error from REALLOC().

Sorry for the churn, but it helped find a bug (edit: two bugs (edit: three bugs)), so I guess it's worth it.
I hope I didn't do any mistakes in the simplifications... :-)


Revisions:

v2
  • Found and fixed another bug, just a few lines above the other one; and this one was my fault. :)
$ git range-diff master gh/reduce reduce 
 1:  68483d8a =  1:  68483d8a lib/: Use REALLOCF() instead of its pattern
 2:  9fc5e5c7 =  2:  9fc5e5c7 lib/commonio.c: commonio_open(): MALLOC() and REALLOCF() already set ENOMEM
 3:  485e1546 =  3:  485e1546 lib/commonio.c: commonio_open(): Reduce scope of local variables
 4:  546ce642 =  4:  546ce642 lib/, src/: Use strchrnul(3) to remove conditionals
 5:  54785cb1 =  5:  54785cb1 lib/, src/: Use strcspn(3) to simplify removal of '\n'
 6:  fd4d9e4e =  6:  fd4d9e4e src/useradd.c: tallylog_reset(): Use Basename() instead of its pattern
 7:  8ec8a50a =  7:  8ec8a50a lib/sgetspent.c: sgetspent(): Use strsep(3) instead of its pattern
 8:  d6aba479 =  8:  d6aba479 src/: Use strsep(3) instead of its pattern
 9:  557d3455 =  9:  557d3455 lib/gshadow.c: build_list(): Fix forever loop on ENOMEM
 -:  -------- > 10:  964e70b9 lib/gshadow.c: build_list(): Fix REALLOC() nmemb calculation
v3
  • Add ZUSTR2STR(), and use it to implement XSTRNDUP()
  • Add XSTRNDUP()
  • Use XSTRNDUP() instead of its pattern
  • Use xasprintf() and xstrdup() instead of their patterns
  • Fix off-by-one bug in allocation size (buffer overrun)
  • And other minor churny changes.
$ git range-diff master gh/reduce reduce 
 1:  68483d8a =  1:  68483d8a lib/: Use REALLOCF() instead of its pattern
 2:  9fc5e5c7 =  2:  9fc5e5c7 lib/commonio.c: commonio_open(): MALLOC() and REALLOCF() already set ENOMEM
 3:  485e1546 =  3:  485e1546 lib/commonio.c: commonio_open(): Reduce scope of local variables
 4:  546ce642 =  4:  546ce642 lib/, src/: Use strchrnul(3) to remove conditionals
 5:  54785cb1 =  5:  54785cb1 lib/, src/: Use strcspn(3) to simplify removal of '\n'
 6:  fd4d9e4e =  6:  fd4d9e4e src/useradd.c: tallylog_reset(): Use Basename() instead of its pattern
 7:  8ec8a50a =  7:  8ec8a50a lib/sgetspent.c: sgetspent(): Use strsep(3) instead of its pattern
 8:  d6aba479 =  8:  d6aba479 src/: Use strsep(3) instead of its pattern
 9:  557d3455 =  9:  557d3455 lib/gshadow.c: build_list(): Fix forever loop on ENOMEM
10:  964e70b9 = 10:  964e70b9 lib/gshadow.c: build_list(): Fix REALLOC() nmemb calculation
 -:  -------- > 11:  6c58629d src/login.c: main(): Remove dead code
 -:  -------- > 12:  b76b8844 src/groupmems.c: Fix number of elements in allocation
 -:  -------- > 13:  ee2dc886 src/: Use xasprintf() instead of its pattern
 -:  -------- > 14:  719c2c4d lib/Makefile.am: Add missing file
 -:  -------- > 15:  39846f56 lib/string/zustr2stp.h: ZUSTR2STR(): Add macro
 -:  -------- > 16:  165d8e2a lib/string/strndup.[ch]: XSTRNDUP(): Add macro
 -:  -------- > 17:  64a9dbc6 lib/utmp.c: Use XSTRNDUP() instead of its pattern
 -:  -------- > 18:  511b5977 lib/utmp.c: prepare_utmp(): Use xstrdup() instead of its pattern
 -:  -------- > 19:  42a9c332 lib/utmp.c: prepare_utmp(): Reduce braces
v3b
  • Fix includes
$ git range-diff master gh/reduce reduce 
 1:  68483d8a =  1:  68483d8a lib/: Use REALLOCF() instead of its pattern
 2:  9fc5e5c7 =  2:  9fc5e5c7 lib/commonio.c: commonio_open(): MALLOC() and REALLOCF() already set ENOMEM
 3:  485e1546 =  3:  485e1546 lib/commonio.c: commonio_open(): Reduce scope of local variables
 4:  546ce642 =  4:  546ce642 lib/, src/: Use strchrnul(3) to remove conditionals
 5:  54785cb1 =  5:  54785cb1 lib/, src/: Use strcspn(3) to simplify removal of '\n'
 6:  fd4d9e4e =  6:  fd4d9e4e src/useradd.c: tallylog_reset(): Use Basename() instead of its pattern
 7:  8ec8a50a =  7:  8ec8a50a lib/sgetspent.c: sgetspent(): Use strsep(3) instead of its pattern
 8:  d6aba479 =  8:  d6aba479 src/: Use strsep(3) instead of its pattern
 9:  557d3455 =  9:  557d3455 lib/gshadow.c: build_list(): Fix forever loop on ENOMEM
10:  964e70b9 = 10:  964e70b9 lib/gshadow.c: build_list(): Fix REALLOC() nmemb calculation
11:  6c58629d = 11:  6c58629d src/login.c: main(): Remove dead code
12:  b76b8844 = 12:  b76b8844 src/groupmems.c: Fix number of elements in allocation
13:  ee2dc886 = 13:  ee2dc886 src/: Use xasprintf() instead of its pattern
14:  719c2c4d = 14:  719c2c4d lib/Makefile.am: Add missing file
15:  39846f56 = 15:  39846f56 lib/string/zustr2stp.h: ZUSTR2STR(): Add macro
16:  165d8e2a ! 16:  137dc501 lib/string/strndup.[ch]: XSTRNDUP(): Add macro
    @@ Commit message
     
      ## lib/Makefile.am ##
     @@ lib/Makefile.am: libshadow_la_SOURCES = \
    +   string/strftime.c \
    +   string/strftime.h \
        string/strncpy.h \
    ++  string/strndup.c \
    ++  string/strndup.h \
        string/strtcpy.c \
        string/strtcpy.h \
    -+  string/xstrndup.c \
    -+  string/xstrndup.h \
        string/zustr2stp.c \
    -   string/zustr2stp.h \
    -   strtoday.c \
     
      ## lib/string/strndup.c (new) ##
     @@
    @@ lib/string/strndup.c (new)
     +
     +#include <config.h>
     +
    -+#include "string/xstrndup.h"
    ++#include "string/strndup.h"
     
      ## lib/string/strndup.h (new) ##
     @@
17:  64a9dbc6 = 17:  c38cc491 lib/utmp.c: Use XSTRNDUP() instead of its pattern
18:  511b5977 = 18:  3410dd99 lib/utmp.c: prepare_utmp(): Use xstrdup() instead of its pattern
19:  42a9c332 = 19:  56fceba6 lib/utmp.c: prepare_utmp(): Reduce braces
 -:  -------- > 20:  a7887298 lib/, src/: Add missing include
v4
  • Remove unused variable
  • Reduce scope of variables
$ git range-diff master gh/reduce reduce 
 1:  68483d8a =  1:  68483d8a lib/: Use REALLOCF() instead of its pattern
 2:  9fc5e5c7 =  2:  9fc5e5c7 lib/commonio.c: commonio_open(): MALLOC() and REALLOCF() already set ENOMEM
 3:  485e1546 =  3:  485e1546 lib/commonio.c: commonio_open(): Reduce scope of local variables
 4:  546ce642 =  4:  546ce642 lib/, src/: Use strchrnul(3) to remove conditionals
 5:  54785cb1 =  5:  54785cb1 lib/, src/: Use strcspn(3) to simplify removal of '\n'
 6:  fd4d9e4e =  6:  fd4d9e4e src/useradd.c: tallylog_reset(): Use Basename() instead of its pattern
 7:  8ec8a50a =  7:  8ec8a50a lib/sgetspent.c: sgetspent(): Use strsep(3) instead of its pattern
 8:  d6aba479 =  8:  d6aba479 src/: Use strsep(3) instead of its pattern
 9:  557d3455 =  9:  557d3455 lib/gshadow.c: build_list(): Fix forever loop on ENOMEM
10:  964e70b9 = 10:  964e70b9 lib/gshadow.c: build_list(): Fix REALLOC() nmemb calculation
11:  6c58629d = 11:  6c58629d src/login.c: main(): Remove dead code
12:  b76b8844 = 12:  b76b8844 src/groupmems.c: Fix number of elements in allocation
13:  ee2dc886 = 13:  ee2dc886 src/: Use xasprintf() instead of its pattern
14:  719c2c4d = 14:  719c2c4d lib/Makefile.am: Add missing file
15:  39846f56 = 15:  39846f56 lib/string/zustr2stp.h: ZUSTR2STR(): Add macro
16:  137dc501 = 16:  137dc501 lib/string/strndup.[ch]: XSTRNDUP(): Add macro
17:  c38cc491 = 17:  c38cc491 lib/utmp.c: Use XSTRNDUP() instead of its pattern
18:  3410dd99 = 18:  3410dd99 lib/utmp.c: prepare_utmp(): Use xstrdup() instead of its pattern
19:  56fceba6 = 19:  56fceba6 lib/utmp.c: prepare_utmp(): Reduce braces
20:  a7887298 = 20:  a7887298 lib/, src/: Add missing include
 -:  -------- > 21:  a549fafb src/logoutd.c: main(): Remove unused variable
 -:  -------- > 22:  3b786e56 src/logoutd.c: main(): Reduce scope of local variables
v5
  • Remove uses of ZUSTR2STP(), and replace them by XSTRNDUP()
  • Remove tests of ZUSTR2STP(), and replace them by tests of XSTRNDUP()
$ git range-diff master gh/reduce reduce 
 1:  68483d8a =  1:  68483d8a lib/: Use REALLOCF() instead of its pattern
 2:  9fc5e5c7 =  2:  9fc5e5c7 lib/commonio.c: commonio_open(): MALLOC() and REALLOCF() already set ENOMEM
 3:  485e1546 =  3:  485e1546 lib/commonio.c: commonio_open(): Reduce scope of local variables
 4:  546ce642 =  4:  546ce642 lib/, src/: Use strchrnul(3) to remove conditionals
 5:  54785cb1 =  5:  54785cb1 lib/, src/: Use strcspn(3) to simplify removal of '\n'
 6:  fd4d9e4e =  6:  fd4d9e4e src/useradd.c: tallylog_reset(): Use Basename() instead of its pattern
 7:  8ec8a50a =  7:  8ec8a50a lib/sgetspent.c: sgetspent(): Use strsep(3) instead of its pattern
 8:  d6aba479 =  8:  d6aba479 src/: Use strsep(3) instead of its pattern
 9:  557d3455 =  9:  557d3455 lib/gshadow.c: build_list(): Fix forever loop on ENOMEM
10:  964e70b9 = 10:  964e70b9 lib/gshadow.c: build_list(): Fix REALLOC() nmemb calculation
11:  6c58629d = 11:  6c58629d src/login.c: main(): Remove dead code
12:  b76b8844 = 12:  b76b8844 src/groupmems.c: Fix number of elements in allocation
13:  ee2dc886 = 13:  ee2dc886 src/: Use xasprintf() instead of its pattern
14:  719c2c4d = 14:  719c2c4d lib/Makefile.am: Add missing file
15:  39846f56 = 15:  39846f56 lib/string/zustr2stp.h: ZUSTR2STR(): Add macro
16:  137dc501 = 16:  137dc501 lib/string/strndup.[ch]: XSTRNDUP(): Add macro
17:  c38cc491 = 17:  c38cc491 lib/utmp.c: Use XSTRNDUP() instead of its pattern
18:  3410dd99 = 18:  3410dd99 lib/utmp.c: prepare_utmp(): Use xstrdup() instead of its pattern
19:  56fceba6 = 19:  56fceba6 lib/utmp.c: prepare_utmp(): Reduce braces
20:  a7887298 = 20:  a7887298 lib/, src/: Add missing include
21:  a549fafb = 21:  a549fafb src/logoutd.c: main(): Remove unused variable
22:  3b786e56 = 22:  3b786e56 src/logoutd.c: main(): Reduce scope of local variables
 -:  -------- > 23:  df290b1c src/logoutd.c: Replace ZUSTR2STP() calls by XSTRNDUP()
 -:  -------- > 24:  08242fd0 lib/string/zustr2stp.h: Simplify ZUSTR2STP() and its documentation
 -:  -------- > 25:  e5447128 tests/unit/test_zustr2stp.c: Repurpose ZUSTR2STP() tests for ZUSTR2STR()
 -:  -------- > 26:  be2f424b tests/unit/: Repurpose ZUSTR2STR() tests for XSTRNDUP()
v6
  • Remove unnecessary casts
  • Fix calls to time(2)
$ git range-diff master gh/reduce reduce 
 1:  68483d8a =  1:  68483d8a lib/: Use REALLOCF() instead of its pattern
 2:  9fc5e5c7 =  2:  9fc5e5c7 lib/commonio.c: commonio_open(): MALLOC() and REALLOCF() already set ENOMEM
 3:  485e1546 =  3:  485e1546 lib/commonio.c: commonio_open(): Reduce scope of local variables
 4:  546ce642 =  4:  546ce642 lib/, src/: Use strchrnul(3) to remove conditionals
 5:  54785cb1 =  5:  54785cb1 lib/, src/: Use strcspn(3) to simplify removal of '\n'
 6:  fd4d9e4e =  6:  fd4d9e4e src/useradd.c: tallylog_reset(): Use Basename() instead of its pattern
 7:  8ec8a50a =  7:  8ec8a50a lib/sgetspent.c: sgetspent(): Use strsep(3) instead of its pattern
 8:  d6aba479 =  8:  d6aba479 src/: Use strsep(3) instead of its pattern
 9:  557d3455 =  9:  557d3455 lib/gshadow.c: build_list(): Fix forever loop on ENOMEM
10:  964e70b9 = 10:  964e70b9 lib/gshadow.c: build_list(): Fix REALLOC() nmemb calculation
11:  6c58629d = 11:  6c58629d src/login.c: main(): Remove dead code
12:  b76b8844 = 12:  b76b8844 src/groupmems.c: Fix number of elements in allocation
13:  ee2dc886 = 13:  ee2dc886 src/: Use xasprintf() instead of its pattern
14:  719c2c4d = 14:  719c2c4d lib/Makefile.am: Add missing file
15:  39846f56 = 15:  39846f56 lib/string/zustr2stp.h: ZUSTR2STR(): Add macro
16:  137dc501 = 16:  137dc501 lib/string/strndup.[ch]: XSTRNDUP(): Add macro
17:  c38cc491 = 17:  c38cc491 lib/utmp.c: Use XSTRNDUP() instead of its pattern
18:  3410dd99 = 18:  3410dd99 lib/utmp.c: prepare_utmp(): Use xstrdup() instead of its pattern
19:  56fceba6 = 19:  56fceba6 lib/utmp.c: prepare_utmp(): Reduce braces
20:  a7887298 = 20:  a7887298 lib/, src/: Add missing include
21:  a549fafb = 21:  a549fafb src/logoutd.c: main(): Remove unused variable
22:  3b786e56 = 22:  3b786e56 src/logoutd.c: main(): Reduce scope of local variables
23:  df290b1c = 23:  df290b1c src/logoutd.c: Replace ZUSTR2STP() calls by XSTRNDUP()
24:  08242fd0 = 24:  08242fd0 lib/string/zustr2stp.h: Simplify ZUSTR2STP() and its documentation
25:  e5447128 = 25:  e5447128 tests/unit/test_zustr2stp.c: Repurpose ZUSTR2STP() tests for ZUSTR2STR()
26:  be2f424b = 26:  be2f424b tests/unit/: Repurpose ZUSTR2STR() tests for XSTRNDUP()
 -:  -------- > 27:  8b595ff4 lib/getdate.y: NULL doesn't need a cast
 -:  -------- > 28:  47a6170b lib/, src/: Always pass NULL to time(2)
v6b
  • Add fixes tag
$ git range-diff master gh/reduce reduce 
 1:  68483d8a =  1:  68483d8a lib/: Use REALLOCF() instead of its pattern
 2:  9fc5e5c7 =  2:  9fc5e5c7 lib/commonio.c: commonio_open(): MALLOC() and REALLOCF() already set ENOMEM
 3:  485e1546 =  3:  485e1546 lib/commonio.c: commonio_open(): Reduce scope of local variables
 4:  546ce642 =  4:  546ce642 lib/, src/: Use strchrnul(3) to remove conditionals
 5:  54785cb1 =  5:  54785cb1 lib/, src/: Use strcspn(3) to simplify removal of '\n'
 6:  fd4d9e4e =  6:  fd4d9e4e src/useradd.c: tallylog_reset(): Use Basename() instead of its pattern
 7:  8ec8a50a =  7:  8ec8a50a lib/sgetspent.c: sgetspent(): Use strsep(3) instead of its pattern
 8:  d6aba479 =  8:  d6aba479 src/: Use strsep(3) instead of its pattern
 9:  557d3455 =  9:  557d3455 lib/gshadow.c: build_list(): Fix forever loop on ENOMEM
10:  964e70b9 = 10:  964e70b9 lib/gshadow.c: build_list(): Fix REALLOC() nmemb calculation
11:  6c58629d = 11:  6c58629d src/login.c: main(): Remove dead code
12:  b76b8844 = 12:  b76b8844 src/groupmems.c: Fix number of elements in allocation
13:  ee2dc886 = 13:  ee2dc886 src/: Use xasprintf() instead of its pattern
14:  719c2c4d = 14:  719c2c4d lib/Makefile.am: Add missing file
15:  39846f56 = 15:  39846f56 lib/string/zustr2stp.h: ZUSTR2STR(): Add macro
16:  137dc501 = 16:  137dc501 lib/string/strndup.[ch]: XSTRNDUP(): Add macro
17:  c38cc491 = 17:  c38cc491 lib/utmp.c: Use XSTRNDUP() instead of its pattern
18:  3410dd99 = 18:  3410dd99 lib/utmp.c: prepare_utmp(): Use xstrdup() instead of its pattern
19:  56fceba6 = 19:  56fceba6 lib/utmp.c: prepare_utmp(): Reduce braces
20:  a7887298 = 20:  a7887298 lib/, src/: Add missing include
21:  a549fafb = 21:  a549fafb src/logoutd.c: main(): Remove unused variable
22:  3b786e56 = 22:  3b786e56 src/logoutd.c: main(): Reduce scope of local variables
23:  df290b1c = 23:  df290b1c src/logoutd.c: Replace ZUSTR2STP() calls by XSTRNDUP()
24:  08242fd0 = 24:  08242fd0 lib/string/zustr2stp.h: Simplify ZUSTR2STP() and its documentation
25:  e5447128 = 25:  e5447128 tests/unit/test_zustr2stp.c: Repurpose ZUSTR2STP() tests for ZUSTR2STR()
26:  be2f424b = 26:  be2f424b tests/unit/: Repurpose ZUSTR2STR() tests for XSTRNDUP()
27:  8b595ff4 = 27:  8b595ff4 lib/getdate.y: NULL doesn't need a cast
28:  47a6170b ! 28:  f07e5d38 lib/, src/: Always pass NULL to time(2)
    @@ Commit message
              The tloc argument is obsolescent and should always be NULL in  new
              code.  When tloc is NULL, the call cannot fail.
     
    +    Fixes: 45c6603cc86c ("[svn-upgrade] Integrating new upstream version, shadow (19990709)")
         Signed-off-by: Alejandro Colomar <alx@kernel.org>
     
      ## lib/failure.c ##
v7
  • Replace one strdup(3) by xstrdup(3)
$ git range-diff master gh/reduce reduce 
 1:  68483d8a =  1:  68483d8a lib/: Use REALLOCF() instead of its pattern
 2:  9fc5e5c7 =  2:  9fc5e5c7 lib/commonio.c: commonio_open(): MALLOC() and REALLOCF() already set ENOMEM
 3:  485e1546 =  3:  485e1546 lib/commonio.c: commonio_open(): Reduce scope of local variables
 4:  546ce642 =  4:  546ce642 lib/, src/: Use strchrnul(3) to remove conditionals
 5:  54785cb1 =  5:  54785cb1 lib/, src/: Use strcspn(3) to simplify removal of '\n'
 6:  fd4d9e4e =  6:  fd4d9e4e src/useradd.c: tallylog_reset(): Use Basename() instead of its pattern
 7:  8ec8a50a =  7:  8ec8a50a lib/sgetspent.c: sgetspent(): Use strsep(3) instead of its pattern
 8:  d6aba479 =  8:  d6aba479 src/: Use strsep(3) instead of its pattern
 9:  557d3455 =  9:  557d3455 lib/gshadow.c: build_list(): Fix forever loop on ENOMEM
10:  964e70b9 = 10:  964e70b9 lib/gshadow.c: build_list(): Fix REALLOC() nmemb calculation
11:  6c58629d = 11:  6c58629d src/login.c: main(): Remove dead code
12:  b76b8844 = 12:  b76b8844 src/groupmems.c: Fix number of elements in allocation
13:  ee2dc886 = 13:  ee2dc886 src/: Use xasprintf() instead of its pattern
14:  719c2c4d = 14:  719c2c4d lib/Makefile.am: Add missing file
15:  39846f56 = 15:  39846f56 lib/string/zustr2stp.h: ZUSTR2STR(): Add macro
16:  137dc501 = 16:  137dc501 lib/string/strndup.[ch]: XSTRNDUP(): Add macro
17:  c38cc491 = 17:  c38cc491 lib/utmp.c: Use XSTRNDUP() instead of its pattern
18:  3410dd99 = 18:  3410dd99 lib/utmp.c: prepare_utmp(): Use xstrdup() instead of its pattern
19:  56fceba6 = 19:  56fceba6 lib/utmp.c: prepare_utmp(): Reduce braces
20:  a7887298 = 20:  a7887298 lib/, src/: Add missing include
21:  a549fafb = 21:  a549fafb src/logoutd.c: main(): Remove unused variable
22:  3b786e56 = 22:  3b786e56 src/logoutd.c: main(): Reduce scope of local variables
23:  df290b1c = 23:  df290b1c src/logoutd.c: Replace ZUSTR2STP() calls by XSTRNDUP()
24:  08242fd0 = 24:  08242fd0 lib/string/zustr2stp.h: Simplify ZUSTR2STP() and its documentation
25:  e5447128 = 25:  e5447128 tests/unit/test_zustr2stp.c: Repurpose ZUSTR2STP() tests for ZUSTR2STR()
26:  be2f424b = 26:  be2f424b tests/unit/: Repurpose ZUSTR2STR() tests for XSTRNDUP()
27:  8b595ff4 = 27:  8b595ff4 lib/getdate.y: NULL doesn't need a cast
28:  f07e5d38 = 28:  f07e5d38 lib/, src/: Always pass NULL to time(2)
 -:  -------- > 29:  4faf560a src/newusers.c: main(): Exit on ENOMEM, by calling xstrdup() instead of strdup(3)
v7b
  • Rebase
$ git range-diff gh/master..gh/reduce shadow/master..reduce 
 1:  68483d8a =  1:  2f872500 lib/: Use REALLOCF() instead of its pattern
 2:  9fc5e5c7 =  2:  22982691 lib/commonio.c: commonio_open(): MALLOC() and REALLOCF() already set ENOMEM
 3:  485e1546 =  3:  c2709bb4 lib/commonio.c: commonio_open(): Reduce scope of local variables
 4:  546ce642 =  4:  dfc4d9a6 lib/, src/: Use strchrnul(3) to remove conditionals
 5:  54785cb1 =  5:  d3c4b810 lib/, src/: Use strcspn(3) to simplify removal of '\n'
 6:  fd4d9e4e =  6:  cb35cb7e src/useradd.c: tallylog_reset(): Use Basename() instead of its pattern
 7:  8ec8a50a =  7:  cd15d3dc lib/sgetspent.c: sgetspent(): Use strsep(3) instead of its pattern
 8:  d6aba479 !  8:  e45dc97a src/: Use strsep(3) instead of its pattern
    @@ src/newusers.c: int main (int argc, char **argv)
                        fprintf (stderr, _("%s: line %d: invalid line\n"),
     
      ## src/useradd.c ##
    -@@ src/useradd.c: static int set_defaults (void)
    +@@ src/useradd.c: err_free_new:
       */
      static int get_groups (char *list)
      {
 9:  557d3455 =  9:  5fb874b4 lib/gshadow.c: build_list(): Fix forever loop on ENOMEM
10:  964e70b9 = 10:  39b898da lib/gshadow.c: build_list(): Fix REALLOC() nmemb calculation
11:  6c58629d = 11:  11368257 src/login.c: main(): Remove dead code
12:  b76b8844 = 12:  33f82d7b src/groupmems.c: Fix number of elements in allocation
13:  ee2dc886 = 13:  0c41cce0 src/: Use xasprintf() instead of its pattern
14:  719c2c4d = 14:  622c1090 lib/Makefile.am: Add missing file
15:  39846f56 = 15:  988466e5 lib/string/zustr2stp.h: ZUSTR2STR(): Add macro
16:  137dc501 = 16:  4fb48700 lib/string/strndup.[ch]: XSTRNDUP(): Add macro
17:  c38cc491 = 17:  3e674707 lib/utmp.c: Use XSTRNDUP() instead of its pattern
18:  3410dd99 = 18:  586d1fba lib/utmp.c: prepare_utmp(): Use xstrdup() instead of its pattern
19:  56fceba6 = 19:  efa2cc09 lib/utmp.c: prepare_utmp(): Reduce braces
20:  a7887298 = 20:  41891dec lib/, src/: Add missing include
21:  a549fafb = 21:  81588919 src/logoutd.c: main(): Remove unused variable
22:  3b786e56 = 22:  16cd03b1 src/logoutd.c: main(): Reduce scope of local variables
23:  df290b1c = 23:  112ad4c8 src/logoutd.c: Replace ZUSTR2STP() calls by XSTRNDUP()
24:  08242fd0 = 24:  49e1823f lib/string/zustr2stp.h: Simplify ZUSTR2STP() and its documentation
25:  e5447128 = 25:  e504d79a tests/unit/test_zustr2stp.c: Repurpose ZUSTR2STP() tests for ZUSTR2STR()
26:  be2f424b = 26:  e5a9b104 tests/unit/: Repurpose ZUSTR2STR() tests for XSTRNDUP()
27:  8b595ff4 = 27:  3f1086cb lib/getdate.y: NULL doesn't need a cast
28:  f07e5d38 = 28:  2a05b32c lib/, src/: Always pass NULL to time(2)
29:  4faf560a = 29:  9a071756 src/newusers.c: main(): Exit on ENOMEM, by calling xstrdup() instead of strdup(3)
v7c
  • Rebase
$ git range-diff master..gh/reduce shadow/master..reduce 
 1:  2f872500 =  1:  97f0ab70 lib/: Use REALLOCF() instead of its pattern
 2:  22982691 =  2:  3d94f64a lib/commonio.c: commonio_open(): MALLOC() and REALLOCF() already set ENOMEM
 3:  c2709bb4 =  3:  e18338a0 lib/commonio.c: commonio_open(): Reduce scope of local variables
 4:  dfc4d9a6 =  4:  cf1e02a4 lib/, src/: Use strchrnul(3) to remove conditionals
 5:  d3c4b810 =  5:  00023ee1 lib/, src/: Use strcspn(3) to simplify removal of '\n'
 6:  cb35cb7e =  6:  2bc9d12b src/useradd.c: tallylog_reset(): Use Basename() instead of its pattern
 7:  cd15d3dc =  7:  829d778c lib/sgetspent.c: sgetspent(): Use strsep(3) instead of its pattern
 8:  e45dc97a =  8:  38d02d93 src/: Use strsep(3) instead of its pattern
 9:  5fb874b4 =  9:  92f7830c lib/gshadow.c: build_list(): Fix forever loop on ENOMEM
10:  39b898da = 10:  5fc6945d lib/gshadow.c: build_list(): Fix REALLOC() nmemb calculation
11:  11368257 = 11:  f962a79b src/login.c: main(): Remove dead code
12:  33f82d7b = 12:  acc6b9e8 src/groupmems.c: Fix number of elements in allocation
13:  0c41cce0 = 13:  6c46d747 src/: Use xasprintf() instead of its pattern
14:  622c1090 = 14:  1080768f lib/Makefile.am: Add missing file
15:  988466e5 = 15:  3d0fb0ec lib/string/zustr2stp.h: ZUSTR2STR(): Add macro
16:  4fb48700 = 16:  de6dee6a lib/string/strndup.[ch]: XSTRNDUP(): Add macro
17:  3e674707 = 17:  9aa6b8d0 lib/utmp.c: Use XSTRNDUP() instead of its pattern
18:  586d1fba = 18:  2fc1d558 lib/utmp.c: prepare_utmp(): Use xstrdup() instead of its pattern
19:  efa2cc09 = 19:  4f1a6ecb lib/utmp.c: prepare_utmp(): Reduce braces
20:  41891dec = 20:  9492b749 lib/, src/: Add missing include
21:  81588919 = 21:  bc621dc3 src/logoutd.c: main(): Remove unused variable
22:  16cd03b1 = 22:  51e6e60b src/logoutd.c: main(): Reduce scope of local variables
23:  112ad4c8 = 23:  3740360b src/logoutd.c: Replace ZUSTR2STP() calls by XSTRNDUP()
24:  49e1823f = 24:  4b674d8a lib/string/zustr2stp.h: Simplify ZUSTR2STP() and its documentation
25:  e504d79a = 25:  51b3663e tests/unit/test_zustr2stp.c: Repurpose ZUSTR2STP() tests for ZUSTR2STR()
26:  e5a9b104 = 26:  4be8c568 tests/unit/: Repurpose ZUSTR2STR() tests for XSTRNDUP()
27:  3f1086cb = 27:  b2487b84 lib/getdate.y: NULL doesn't need a cast
28:  2a05b32c = 28:  0b90d8d5 lib/, src/: Always pass NULL to time(2)
29:  9a071756 = 29:  0d38af22 src/newusers.c: main(): Exit on ENOMEM, by calling xstrdup() instead of strdup(3)
v8
  • strchrnul(3) results in simpler code than strcspn(3)
$ git range-diff --creation-factor=99 shadow/master gh/reduce reduce 
 1:  97f0ab70 =  1:  97f0ab70 lib/: Use REALLOCF() instead of its pattern
 2:  3d94f64a =  2:  3d94f64a lib/commonio.c: commonio_open(): MALLOC() and REALLOCF() already set ENOMEM
 3:  e18338a0 =  3:  e18338a0 lib/commonio.c: commonio_open(): Reduce scope of local variables
 4:  cf1e02a4 <  -:  -------- lib/, src/: Use strchrnul(3) to remove conditionals
 5:  00023ee1 !  4:  d955aaed lib/, src/: Use strcspn(3) to simplify removal of '\n'
    @@ Metadata
     Author: Alejandro Colomar <alx@kernel.org>
     
      ## Commit message ##
    -    lib/, src/: Use strcspn(3) to simplify removal of '\n'
    +    lib/, src/: Use strchrnul(3) instead of its pattern
     
    -    Link: <https://stackoverflow.com/a/28462221/6872717>
         Signed-off-by: Alejandro Colomar <alx@kernel.org>
     
      ## lib/commonio.c ##
    @@ lib/commonio.c: int commonio_open (struct commonio_db *db, int mode)
                                goto cleanup_buf;
                        }
                }
    --          cp = strchrnul(buf, '\n');
    --          *cp = '\0';
    -+          buf[strcspn(buf, "\n")] = '\0';
    +-          cp = strrchr (buf, '\n');
    +-          if (NULL != cp) {
    +-                  *cp = '\0';
    +-          }
    ++          *strchrnul(buf, '\n') = '\0';
      
                line = strdup (buf);
                if (NULL == line) {
     
    + ## lib/console.c ##
    +@@ lib/console.c: static bool is_listed (const char *cfgin, const char *tty, bool def)
    +    */
    + 
    +   while (fgets (buf, sizeof (buf), fp) != NULL) {
    +-          /* Remove optional trailing '\n'. */
    +-          buf[strcspn (buf, "\n")] = '\0';
    ++          *strchrnul(buf, '\n') = '\0';
    +           if (strcmp (buf, tty) == 0) {
    +                   (void) fclose (fp);
    +                   return true;
    +
    + ## lib/getdef.c ##
    +@@ lib/getdef.c: static void def_load (void)
    + 
    +           *s++ = '\0';
    +           value = s + strspn (s, " \"\t");        /* next nonwhite */
    +-          *(value + strcspn (value, "\"")) = '\0';
    ++          *strchrnul(value, '"') = '\0';
    + 
    +           /*
    +            * Store the value in def_table.
    +
      ## lib/gshadow.c ##
     @@ lib/gshadow.c: void endsgent (void)
    +   }
      
        strcpy (sgrbuf, string);
    - 
    --  cp = strchrnul(sgrbuf, '\n');
    --  *cp = '\0';
    -+  sgrbuf[strcspn(sgrbuf, "\n")] = '\0';
    +-
    +-  cp = strrchr (sgrbuf, '\n');
    +-  if (NULL != cp) {
    +-          *cp = '\0';
    +-  }
    ++  *strchrnul(sgrbuf, '\n') = '\0';
      
        /*
         * There should be exactly 4 colon separated fields.  Find
    @@ lib/gshadow.c: void endsgent (void)
                                return NULL;
                        }
                }
    --          cp = strchrnul(buf, '\n');
    --          *cp = '\0';
    -+          buf[strcspn(buf, "\n")] = '\0';
    +-          cp = strrchr (buf, '\n');
    +-          if (NULL != cp) {
    +-                  *cp = '\0';
    +-          }
    ++          *strchrnul(buf, '\n') = '\0';
                return (sgetsgent (buf));
        }
        return NULL;
     
    + ## lib/hushed.c ##
    +@@ lib/hushed.c: bool hushed (const char *username)
    +           return false;
    +   }
    +   for (found = false; !found && (fgets (buf, sizeof buf, fp) == buf);) {
    +-          buf[strcspn (buf, "\n")] = '\0';
    ++          *strchrnul(buf, '\n') = '\0';
    +           found = (strcmp (buf, pw->pw_shell) == 0) ||
    +                   (strcmp (buf, pw->pw_name) == 0);
    +   }
    +
    + ## lib/port.c ##
    +@@ lib/port.c: again:
    +    * TTY devices.
    +    */
    + 
    +-  buf[strcspn (buf, "\n")] = 0;
    ++  *strchrnul(buf, '\n') = '\0';
    + 
    +   port.pt_names = ttys;
    +   for (cp = buf, j = 0; j < PORT_TTY; j++) {
    +
      ## lib/sgetgrent.c ##
     @@ lib/sgetgrent.c: struct group *sgetgrent (const char *buf)
    +           }
        }
        strcpy (grpbuf, buf);
    - 
    --  cp = strchrnul(grpbuf, '\n');
    --  *cp = '\0';
    -+  grpbuf[strcspn(grpbuf, "\n")] = '\0';
    +-
    +-  cp = strrchr (grpbuf, '\n');
    +-  if (NULL != cp) {
    +-          *cp = '\0';
    +-  }
    ++  *strchrnul(grpbuf, '\n') = '\0';
      
        for (cp = grpbuf, i = 0; (i < NFIELDS) && (NULL != cp); i++)
                grpfields[i] = strsep(&cp, ":");
     
      ## lib/sgetspent.c ##
     @@ lib/sgetspent.c: sgetspent(const char *string)
    +           return NULL;    /* fail if too long */
        }
        strcpy (spwbuf, string);
    - 
    --  cp = strchrnul(spwbuf, '\n');
    --  *cp = '\0';
    -+  spwbuf[strcspn(spwbuf, "\n")] = '\0';
    +-
    +-  cp = strrchr (spwbuf, '\n');
    +-  if (NULL != cp) {
    +-          *cp = '\0';
    +-  }
    ++  *strchrnul(spwbuf, '\n') = '\0';
      
        /*
         * Tokenize the string into colon separated fields.  Allow up to
     
      ## lib/shadow.c ##
     @@ lib/shadow.c: static struct spwd *my_sgetspent (const char *string)
    +   if (strlen (string) >= sizeof spwbuf)
                return 0;
        strcpy (spwbuf, string);
    - 
    --  cp = strchrnul(spwbuf, '\n');
    --  *cp = '\0';
    -+  spwbuf[strcspn(spwbuf, "\n")] = '\0';
    +-
    +-  cp = strrchr (spwbuf, '\n');
    +-  if (NULL != cp)
    +-          *cp = '\0';
    ++  *strchrnul(spwbuf, '\n') = '\0';
      
        /*
         * Tokenize the string into colon separated fields.  Allow up to
     @@ lib/shadow.c: static struct spwd *my_sgetspent (const char *string)
    + 
      struct spwd *fgetspent (FILE * fp)
      {
    -   char buf[BUFSIZ];
    +-  char buf[BUFSIZ];
     -  char *cp;
    ++  char  buf[BUFSIZ];
      
        if (NULL == fp) {
                return (0);
    @@ lib/shadow.c: struct spwd *fgetspent (FILE * fp)
      
        if (fgets (buf, sizeof buf, fp) != NULL)
        {
    --          cp = strchrnul(buf, '\n');
    --          *cp = '\0';
    -+          buf[strcspn(buf, "\n")] = '\0';
    +-          cp = strchr (buf, '\n');
    +-          if (NULL != cp) {
    +-                  *cp = '\0';
    +-          }
    ++          *strchrnul(buf, '\n') = '\0';
                return my_sgetspent (buf);
        }
        return 0;
    @@ lib/ttytype.c: void ttytype (const char *line)
                        continue;
                }
      
    --          cp = strchrnul(buf, '\n');
    --          *cp = '\0';
    -+          buf[strcspn(buf, "\n")] = '\0';
    +-          cp = strchr (buf, '\n');
    +-          if (NULL != cp) {
    +-                  *cp = '\0';
    +-          }
    ++          *strchrnul(buf, '\n') = '\0';
      
                if (   (sscanf (buf, "%1023s %1023s", type, port) == 2)
                    && (strcmp (line, port) == 0)) {
     
    + ## lib/tz.c ##
    +@@
    + 
    +           strcpy (tzbuf, def_tz);
    +   } else {
    +-          /* Remove optional trailing '\n'. */
    +-          tzbuf[strcspn (tzbuf, "\n")] = '\0';
    ++          *strchrnul(tzbuf, '\n') = '\0';
    +   }
    + 
    +   if (NULL != fp) {
    +
      ## src/useradd.c ##
     @@ src/useradd.c: static void get_defaults (void)
         * values are used, everything else can be ignored.
         */
        while (fgets (buf, sizeof buf, fp) == buf) {
    --          cp = strchrnul(buf, '\n');
    --          *cp = '\0';
    -+          buf[strcspn(buf, "\n")] = '\0';
    +-          cp = strrchr (buf, '\n');
    +-          if (NULL != cp) {
    +-                  *cp = '\0';
    +-          }
    ++          *strchrnul(buf, '\n') = '\0';
      
                cp = strchr (buf, '=');
                if (NULL == cp) {
 6:  2bc9d12b =  5:  724f4232 src/useradd.c: tallylog_reset(): Use Basename() instead of its pattern
 7:  829d778c =  6:  e9d7b6d9 lib/sgetspent.c: sgetspent(): Use strsep(3) instead of its pattern
 8:  38d02d93 =  7:  7ef764e5 src/: Use strsep(3) instead of its pattern
 9:  92f7830c =  8:  61b11a6c lib/gshadow.c: build_list(): Fix forever loop on ENOMEM
10:  5fc6945d =  9:  24dfb87c lib/gshadow.c: build_list(): Fix REALLOC() nmemb calculation
11:  f962a79b = 10:  a4b843dc src/login.c: main(): Remove dead code
12:  acc6b9e8 = 11:  bde12417 src/groupmems.c: Fix number of elements in allocation
13:  6c46d747 = 12:  4536ac00 src/: Use xasprintf() instead of its pattern
14:  1080768f = 13:  37d750b3 lib/Makefile.am: Add missing file
15:  3d0fb0ec = 14:  d6688781 lib/string/zustr2stp.h: ZUSTR2STR(): Add macro
16:  de6dee6a = 15:  39aad7d5 lib/string/strndup.[ch]: XSTRNDUP(): Add macro
17:  9aa6b8d0 = 16:  976b9fea lib/utmp.c: Use XSTRNDUP() instead of its pattern
18:  2fc1d558 = 17:  ec4ba6fb lib/utmp.c: prepare_utmp(): Use xstrdup() instead of its pattern
19:  4f1a6ecb = 18:  655bd437 lib/utmp.c: prepare_utmp(): Reduce braces
20:  9492b749 = 19:  4041520c lib/, src/: Add missing include
21:  bc621dc3 = 20:  e4a1cf49 src/logoutd.c: main(): Remove unused variable
22:  51e6e60b = 21:  28725036 src/logoutd.c: main(): Reduce scope of local variables
23:  3740360b = 22:  3323147b src/logoutd.c: Replace ZUSTR2STP() calls by XSTRNDUP()
24:  4b674d8a = 23:  6494b12c lib/string/zustr2stp.h: Simplify ZUSTR2STP() and its documentation
25:  51b3663e = 24:  c7c66b8e tests/unit/test_zustr2stp.c: Repurpose ZUSTR2STP() tests for ZUSTR2STR()
26:  4be8c568 = 25:  02d11dd2 tests/unit/: Repurpose ZUSTR2STR() tests for XSTRNDUP()
27:  b2487b84 = 26:  36730752 lib/getdate.y: NULL doesn't need a cast
28:  0b90d8d5 = 27:  bfc28317 lib/, src/: Always pass NULL to time(2)
29:  0d38af22 = 28:  5f580662 src/newusers.c: main(): Exit on ENOMEM, by calling xstrdup() instead of strdup(3)
v9
  • Use strchrnul(3) in another place
  • Add missing <string.h> includes
  • Sort includes
$ git range-diff shadow/master gh/reduce reduce 
 1:  97f0ab70 =  1:  97f0ab70 lib/: Use REALLOCF() instead of its pattern
 2:  3d94f64a =  2:  3d94f64a lib/commonio.c: commonio_open(): MALLOC() and REALLOCF() already set ENOMEM
 3:  e18338a0 =  3:  e18338a0 lib/commonio.c: commonio_open(): Reduce scope of local variables
 4:  d955aaed !  4:  0c31a685 lib/, src/: Use strchrnul(3) instead of its pattern
    @@ Metadata
      ## Commit message ##
         lib/, src/: Use strchrnul(3) instead of its pattern
     
    +    In the files where #include <string.h> is missing, add it, and sort the
    +    includes.
    +
         Signed-off-by: Alejandro Colomar <alx@kernel.org>
     
      ## lib/commonio.c ##
    +@@
    + 
    + #ident "$Id$"
    + 
    +-#include "defines.h"
    + #include <assert.h>
    ++#include <errno.h>
    ++#include <fcntl.h>
    ++#include <limits.h>
    ++#include <signal.h>
    ++#include <stdio.h>
    ++#include <string.h>
    + #include <sys/stat.h>
    + #include <stdlib.h>
    +-#include <limits.h>
    + #include <utime.h>
    +-#include <fcntl.h>
    +-#include <errno.h>
    +-#include <stdio.h>
    +-#include <signal.h>
    + 
    + #include "alloc.h"
    ++#include "commonio.h"
    ++#include "defines.h"
    + #include "memzero.h"
    + #include "nscd.h"
    +-#include "sssd.h"
    + #ifdef WITH_TCB
    + #include <tcb.h>
    + #endif                            /* WITH_TCB */
    + #include "prototypes.h"
    +-#include "commonio.h"
    + #include "shadowlog_internal.h"
    ++#include "sssd.h"
    + #include "string/sprintf.h"
    + 
    + 
     @@ lib/commonio.c: int commonio_open (struct commonio_db *db, int mode)
                goto cleanup_errno;
      
    @@ lib/commonio.c: int commonio_open (struct commonio_db *db, int mode)
                if (NULL == line) {
     
      ## lib/console.c ##
    +@@
    +  */
    + 
    + #include <config.h>
    +-#include "defines.h"
    ++
    + #include <stdio.h>
    ++#include <string.h>
    ++
    ++#include "defines.h"
    + #include "getdef.h"
    + #include "prototypes.h"
    + #include "string/strtcpy.h"
    + 
    + #ident "$Id$"
    + 
    ++
    + /*
    +  * This is now rather generic function which decides if "tty" is listed
    +  * under "cfgin" in config (directly or indirectly). Fallback to default if
     @@ lib/console.c: static bool is_listed (const char *cfgin, const char *tty, bool def)
         */
      
    @@ lib/console.c: static bool is_listed (const char *cfgin, const char *tty, bool d
                        return true;
     
      ## lib/getdef.c ##
    +@@
    + 
    + #ident "$Id$"
    + 
    +-#include "prototypes.h"
    +-#include "defines.h"
    ++#include <ctype.h>
    ++#include <errno.h>
    + #include <stddef.h>
    + #include <stdio.h>
    + #include <stdlib.h>
    +-#include <ctype.h>
    +-#include <errno.h>
    ++#include <string.h>
    ++
    + #ifdef USE_ECONF
    + #include <libeconf.h>
    + #endif
    + 
    + #include "alloc.h"
    + #include "atoi/str2i.h"
    ++#include "defines.h"
    + #include "getdef.h"
    ++#include "prototypes.h"
    + #include "shadowlog_internal.h"
    + #include "string/sprintf.h"
    + 
     @@ lib/getdef.c: static void def_load (void)
      
                *s++ = '\0';
    @@ lib/gshadow.c: void endsgent (void)
        return NULL;
     
      ## lib/hushed.c ##
    +@@
    + 
    + #ident "$Id$"
    + 
    +-#include <sys/types.h>
    +-#include <stdio.h>
    + #include <pwd.h>
    ++#include <stdio.h>
    ++#include <string.h>
    ++#include <sys/types.h>
    ++
    + #include "defines.h"
    +-#include "prototypes.h"
    + #include "getdef.h"
    ++#include "prototypes.h"
    + #include "string/sprintf.h"
    + 
    + 
     @@ lib/hushed.c: bool hushed (const char *username)
                return false;
        }
    @@ lib/hushed.c: bool hushed (const char *username)
        }
     
      ## lib/port.c ##
    +@@
    + 
    + #ident "$Id$"
    + 
    +-#include <stdio.h>
    + #include <ctype.h>
    + #include <errno.h>
    ++#include <stdio.h>
    ++#include <string.h>
    ++
    + #include "defines.h"
    +-#include "prototypes.h"
    + #include "port.h"
    ++#include "prototypes.h"
    ++
    + 
    + static FILE *ports;
    + 
     @@ lib/port.c: again:
         * TTY devices.
         */
    @@ lib/sgetspent.c: sgetspent(const char *string)
         * Tokenize the string into colon separated fields.  Allow up to
     
      ## lib/shadow.c ##
    +@@
    + 
    + #ident "$Id$"
    + 
    +-#include <sys/types.h>
    +-#include "prototypes.h"
    +-#include "defines.h"
    + #include <stdio.h>
    ++#include <string.h>
    ++#include <sys/types.h>
    + 
    + #include "atoi/str2i.h"
    ++#include "defines.h"
    ++#include "prototypes.h"
    + 
    + 
    + static FILE *shadow;
     @@ lib/shadow.c: static struct spwd *my_sgetspent (const char *string)
        if (strlen (string) >= sizeof spwbuf)
                return 0;
    @@ lib/shadow.c: static struct spwd *my_sgetspent (const char *string)
         * Tokenize the string into colon separated fields.  Allow up to
     @@ lib/shadow.c: static struct spwd *my_sgetspent (const char *string)
      
    +   for (cp = spwbuf, i = 0; *cp && i < FIELDS; i++) {
    +           fields[i] = cp;
    +-          while (*cp && *cp != ':')
    +-                  cp++;
    +-
    ++          cp = strchrnul(cp, ':');
    +           if (*cp)
    +                   *cp++ = '\0';
    +   }
    +@@ lib/shadow.c: static struct spwd *my_sgetspent (const char *string)
    + 
      struct spwd *fgetspent (FILE * fp)
      {
     -  char buf[BUFSIZ];
    @@ lib/shadow.c: struct spwd *fgetspent (FILE * fp)
        return 0;
     
      ## lib/ttytype.c ##
    +@@
    + #ident "$Id$"
    + 
    + #include <stdio.h>
    +-#include "prototypes.h"
    ++#include <string.h>
    ++
    + #include "defines.h"
    + #include "getdef.h"
    ++#include "prototypes.h"
    ++
    ++
    + /*
    +  * ttytype - set ttytype from port to terminal type mapping database
    +  */
     @@ lib/ttytype.c: void ttytype (const char *line)
        FILE *fp;
        char buf[BUFSIZ];
 5:  724f4232 =  5:  90b3abef src/useradd.c: tallylog_reset(): Use Basename() instead of its pattern
 6:  e9d7b6d9 =  6:  a517b951 lib/sgetspent.c: sgetspent(): Use strsep(3) instead of its pattern
 7:  7ef764e5 =  7:  ba6fd2c0 src/: Use strsep(3) instead of its pattern
 8:  61b11a6c =  8:  c5cfdbb3 lib/gshadow.c: build_list(): Fix forever loop on ENOMEM
 9:  24dfb87c =  9:  59e08dd5 lib/gshadow.c: build_list(): Fix REALLOC() nmemb calculation
10:  a4b843dc = 10:  6e54a748 src/login.c: main(): Remove dead code
11:  bde12417 = 11:  bf0262af src/groupmems.c: Fix number of elements in allocation
12:  4536ac00 = 12:  1e3b0330 src/: Use xasprintf() instead of its pattern
13:  37d750b3 = 13:  2322ac1a lib/Makefile.am: Add missing file
14:  d6688781 = 14:  a8b76305 lib/string/zustr2stp.h: ZUSTR2STR(): Add macro
15:  39aad7d5 = 15:  f3524346 lib/string/strndup.[ch]: XSTRNDUP(): Add macro
16:  976b9fea = 16:  bbd4a756 lib/utmp.c: Use XSTRNDUP() instead of its pattern
17:  ec4ba6fb = 17:  183086f0 lib/utmp.c: prepare_utmp(): Use xstrdup() instead of its pattern
18:  655bd437 = 18:  94827f3c lib/utmp.c: prepare_utmp(): Reduce braces
19:  4041520c = 19:  aab6c4ef lib/, src/: Add missing include
20:  e4a1cf49 = 20:  7e67714b src/logoutd.c: main(): Remove unused variable
21:  28725036 = 21:  03aa161f src/logoutd.c: main(): Reduce scope of local variables
22:  3323147b = 22:  468027d9 src/logoutd.c: Replace ZUSTR2STP() calls by XSTRNDUP()
23:  6494b12c = 23:  8e9806ae lib/string/zustr2stp.h: Simplify ZUSTR2STP() and its documentation
24:  c7c66b8e = 24:  2bc3b98b tests/unit/test_zustr2stp.c: Repurpose ZUSTR2STP() tests for ZUSTR2STR()
25:  02d11dd2 = 25:  02916dcf tests/unit/: Repurpose ZUSTR2STR() tests for XSTRNDUP()
26:  36730752 = 26:  7df491c5 lib/getdate.y: NULL doesn't need a cast
27:  bfc28317 = 27:  b79ad6a6 lib/, src/: Always pass NULL to time(2)
28:  5f580662 = 28:  f1d03318 src/newusers.c: main(): Exit on ENOMEM, by calling xstrdup() instead of strdup(3)
v10
  • Use strsep(3) in another place
  • Squash two commits
  • Clarify an assignment of an empty string
$ git range-diff shadow/master gh/reduce reduce 
 1:  97f0ab70 =  1:  97f0ab70 lib/: Use REALLOCF() instead of its pattern
 2:  3d94f64a =  2:  3d94f64a lib/commonio.c: commonio_open(): MALLOC() and REALLOCF() already set ENOMEM
 3:  e18338a0 =  3:  e18338a0 lib/commonio.c: commonio_open(): Reduce scope of local variables
 4:  0c31a685 =  4:  0c31a685 lib/, src/: Use strchrnul(3) instead of its pattern
 5:  90b3abef =  5:  90b3abef src/useradd.c: tallylog_reset(): Use Basename() instead of its pattern
 6:  a517b951 <  -:  -------- lib/sgetspent.c: sgetspent(): Use strsep(3) instead of its pattern
 -:  -------- >  6:  41227e4f lib/shadow.c: my_sgetspent(): Clarify that we're assigning an empty string
 7:  ba6fd2c0 !  7:  2b592b8e src/: Use strsep(3) instead of its pattern
    @@ Metadata
     Author: Alejandro Colomar <alx@kernel.org>
     
      ## Commit message ##
    -    src/: Use strsep(3) instead of its pattern
    +    lib/, src/: Use strsep(3) instead of its pattern
     
         Signed-off-by: Alejandro Colomar <alx@kernel.org>
     
    + ## lib/sgetspent.c ##
    +@@ lib/sgetspent.c: sgetspent(const char *string)
    +    * FIELDS different fields.
    +    */
    + 
    +-  for (cp = spwbuf, i = 0; ('\0' != *cp) && (i < FIELDS); i++) {
    +-          fields[i] = cp;
    +-          cp = strchrnul(cp, ':');
    +-
    +-          if ('\0' != *cp) {
    +-                  *cp = '\0';
    +-                  cp++;
    +-          }
    +-  }
    ++  for (cp = spwbuf, i = 0; cp != NULL && i < FIELDS; i++)
    ++          fields[i] = strsep(&cp, ":");
    + 
    +   if (i == (FIELDS - 1))
    +           fields[i++] = "";
    + 
    +-  if ( ((NULL != cp) && ('\0' != *cp)) ||
    +-       ((i != FIELDS) && (i != OFIELDS)) ) {
    ++  if (cp != NULL || (i != FIELDS && i != OFIELDS))
    +           return NULL;
    +-  }
    + 
    +   /*
    +    * Start populating the structure.  The fields are all in
    +
    + ## lib/shadow.c ##
    +@@ lib/shadow.c: static struct spwd *my_sgetspent (const char *string)
    +    * FIELDS different fields.
    +    */
    + 
    +-  for (cp = spwbuf, i = 0; *cp && i < FIELDS; i++) {
    +-          fields[i] = cp;
    +-          cp = strchrnul(cp, ':');
    +-          if (*cp)
    +-                  *cp++ = '\0';
    +-  }
    ++  for (cp = spwbuf, i = 0; cp != NULL && i < FIELDS; i++)
    ++          fields[i] = strsep(&cp, ":");
    + 
    +   if (i == (FIELDS - 1))
    +           fields[i++] = empty;
    + 
    +-  if ((cp && *cp) || (i != FIELDS && i != OFIELDS))
    ++  if (cp != NULL || (i != FIELDS && i != OFIELDS))
    +           return 0;
    + 
    +   /*
    +
      ## src/chfn.c ##
     @@ src/chfn.c: static void new_fields (void)
       */
 8:  c5cfdbb3 =  8:  c1d531fc lib/gshadow.c: build_list(): Fix forever loop on ENOMEM
 9:  59e08dd5 =  9:  d1ca750a lib/gshadow.c: build_list(): Fix REALLOC() nmemb calculation
10:  6e54a748 = 10:  e94200ed src/login.c: main(): Remove dead code
11:  bf0262af = 11:  6f1be2f8 src/groupmems.c: Fix number of elements in allocation
12:  1e3b0330 = 12:  1753a19f src/: Use xasprintf() instead of its pattern
13:  2322ac1a = 13:  295a8819 lib/Makefile.am: Add missing file
14:  a8b76305 = 14:  285fb712 lib/string/zustr2stp.h: ZUSTR2STR(): Add macro
15:  f3524346 = 15:  bcfcd4b3 lib/string/strndup.[ch]: XSTRNDUP(): Add macro
16:  bbd4a756 = 16:  36b4b1a3 lib/utmp.c: Use XSTRNDUP() instead of its pattern
17:  183086f0 = 17:  07a8c91f lib/utmp.c: prepare_utmp(): Use xstrdup() instead of its pattern
18:  94827f3c = 18:  8c228cd8 lib/utmp.c: prepare_utmp(): Reduce braces
19:  aab6c4ef = 19:  6f061c8e lib/, src/: Add missing include
20:  7e67714b = 20:  af18b4d8 src/logoutd.c: main(): Remove unused variable
21:  03aa161f = 21:  e762b825 src/logoutd.c: main(): Reduce scope of local variables
22:  468027d9 = 22:  19ab12f3 src/logoutd.c: Replace ZUSTR2STP() calls by XSTRNDUP()
23:  8e9806ae = 23:  8aa9ce50 lib/string/zustr2stp.h: Simplify ZUSTR2STP() and its documentation
24:  2bc3b98b = 24:  d7aad83b tests/unit/test_zustr2stp.c: Repurpose ZUSTR2STP() tests for ZUSTR2STR()
25:  02916dcf = 25:  93e67309 tests/unit/: Repurpose ZUSTR2STR() tests for XSTRNDUP()
26:  7df491c5 = 26:  89866841 lib/getdate.y: NULL doesn't need a cast
27:  b79ad6a6 = 27:  b1def328 lib/, src/: Always pass NULL to time(2)
28:  f1d03318 = 28:  ae0cc49d src/newusers.c: main(): Exit on ENOMEM, by calling xstrdup() instead of strdup(3)
v11
  • Remove dead code
$ git range-diff shadow/master gh/reduce reduce 
 1:  97f0ab70 !  1:  aa006a86 lib/: Use REALLOCF() instead of its pattern
    @@ lib/commonio.c: int commonio_open (struct commonio_db *db, int mode)
                                            (int) (buflen - len),
     
      ## lib/subordinateio.c ##
    +@@ lib/subordinateio.c: static bool all_digits(const char *str)
    + 
    + static int append_uids(uid_t **uids, const char *owner, int n)
    + {
    +-  uid_t owner_uid;
    +-  uid_t *ret;
    +-  int i;
    ++  int    i;
    ++  uid_t  owner_uid;
    + 
    +   if (all_digits(owner)) {
    +           i = sscanf(owner, "%d", &owner_uid);
     @@ lib/subordinateio.c: static int append_uids(uid_t **uids, const char *owner, int n)
                        return n;
        }
 2:  3d94f64a =  2:  a4a67952 lib/commonio.c: commonio_open(): MALLOC() and REALLOCF() already set ENOMEM
 3:  e18338a0 =  3:  9f7e3f3f lib/commonio.c: commonio_open(): Reduce scope of local variables
 4:  0c31a685 =  4:  29fe6822 lib/, src/: Use strchrnul(3) instead of its pattern
 5:  90b3abef =  5:  22ab9ccf src/useradd.c: tallylog_reset(): Use Basename() instead of its pattern
 6:  41227e4f =  6:  59ba2329 lib/shadow.c: my_sgetspent(): Clarify that we're assigning an empty string
 7:  2b592b8e =  7:  ea204ae3 lib/, src/: Use strsep(3) instead of its pattern
 8:  c1d531fc =  8:  e9c5f0ab lib/gshadow.c: build_list(): Fix forever loop on ENOMEM
 9:  d1ca750a =  9:  1bb39ddc lib/gshadow.c: build_list(): Fix REALLOC() nmemb calculation
10:  e94200ed = 10:  f19ea03f src/login.c: main(): Remove dead code
11:  6f1be2f8 = 11:  71cafac4 src/groupmems.c: Fix number of elements in allocation
12:  1753a19f = 12:  187356c6 src/: Use xasprintf() instead of its pattern
13:  295a8819 = 13:  30457378 lib/Makefile.am: Add missing file
14:  285fb712 = 14:  3334781c lib/string/zustr2stp.h: ZUSTR2STR(): Add macro
15:  bcfcd4b3 = 15:  54bd1b7c lib/string/strndup.[ch]: XSTRNDUP(): Add macro
16:  36b4b1a3 = 16:  ae742cf2 lib/utmp.c: Use XSTRNDUP() instead of its pattern
17:  07a8c91f = 17:  aca896b8 lib/utmp.c: prepare_utmp(): Use xstrdup() instead of its pattern
18:  8c228cd8 = 18:  8faf4207 lib/utmp.c: prepare_utmp(): Reduce braces
19:  6f061c8e = 19:  81e53195 lib/, src/: Add missing include
20:  af18b4d8 = 20:  264d4f3c src/logoutd.c: main(): Remove unused variable
21:  e762b825 = 21:  c7bf7001 src/logoutd.c: main(): Reduce scope of local variables
22:  19ab12f3 = 22:  0767270f src/logoutd.c: Replace ZUSTR2STP() calls by XSTRNDUP()
23:  8aa9ce50 = 23:  e2ab6d4f lib/string/zustr2stp.h: Simplify ZUSTR2STP() and its documentation
24:  d7aad83b = 24:  1901ab33 tests/unit/test_zustr2stp.c: Repurpose ZUSTR2STP() tests for ZUSTR2STR()
25:  93e67309 = 25:  becd83d7 tests/unit/: Repurpose ZUSTR2STR() tests for XSTRNDUP()
26:  89866841 = 26:  9a75e0c7 lib/getdate.y: NULL doesn't need a cast
 -:  -------- > 27:  26cd6e87 lib/failure.c: failprint(): Remove dead code
27:  b1def328 ! 28:  5c6e6b1b lib/, src/: Always pass NULL to time(2)
    @@ lib/failure.c: static bool too_many_failures (const struct faillog *fl)
        if ((fl->fail_time + fl->fail_locktime) < now) {
                return false;   /* enough time since last failure */
        }
    -@@ lib/failure.c: void failprint (const struct faillog *fail)
    -   }
    - 
    -   tp = localtime (&(fail->fail_time));
    --  (void) time (&NOW);
    -+  NOW = time(NULL);
    - 
    -   /*
    -    * Print all information we have.
     
      ## lib/log.c ##
     @@ lib/log.c: void dolastlog (
28:  ae0cc49d = 29:  fef8a6c8 src/newusers.c: main(): Exit on ENOMEM, by calling xstrdup() instead of strdup(3)
 -:  -------- > 30:  75341447 src/su.c: save_caller_context(): Remove unused parameter
v12
  • Add missing file to Makefile sources for a test
$ git range-diff shadow/master gh/reduce reduce 
 1:  aa006a86 =  1:  aa006a86 lib/: Use REALLOCF() instead of its pattern
 2:  a4a67952 =  2:  a4a67952 lib/commonio.c: commonio_open(): MALLOC() and REALLOCF() already set ENOMEM
 3:  9f7e3f3f =  3:  9f7e3f3f lib/commonio.c: commonio_open(): Reduce scope of local variables
 4:  29fe6822 =  4:  29fe6822 lib/, src/: Use strchrnul(3) instead of its pattern
 5:  22ab9ccf =  5:  22ab9ccf src/useradd.c: tallylog_reset(): Use Basename() instead of its pattern
 6:  59ba2329 =  6:  59ba2329 lib/shadow.c: my_sgetspent(): Clarify that we're assigning an empty string
 7:  ea204ae3 =  7:  ea204ae3 lib/, src/: Use strsep(3) instead of its pattern
 8:  e9c5f0ab =  8:  e9c5f0ab lib/gshadow.c: build_list(): Fix forever loop on ENOMEM
 9:  1bb39ddc =  9:  1bb39ddc lib/gshadow.c: build_list(): Fix REALLOC() nmemb calculation
10:  f19ea03f = 10:  f19ea03f src/login.c: main(): Remove dead code
11:  71cafac4 = 11:  71cafac4 src/groupmems.c: Fix number of elements in allocation
12:  187356c6 = 12:  187356c6 src/: Use xasprintf() instead of its pattern
13:  30457378 = 13:  30457378 lib/Makefile.am: Add missing file
14:  3334781c = 14:  3334781c lib/string/zustr2stp.h: ZUSTR2STR(): Add macro
15:  54bd1b7c = 15:  54bd1b7c lib/string/strndup.[ch]: XSTRNDUP(): Add macro
16:  ae742cf2 = 16:  ae742cf2 lib/utmp.c: Use XSTRNDUP() instead of its pattern
17:  aca896b8 = 17:  aca896b8 lib/utmp.c: prepare_utmp(): Use xstrdup() instead of its pattern
18:  8faf4207 = 18:  8faf4207 lib/utmp.c: prepare_utmp(): Reduce braces
19:  81e53195 = 19:  81e53195 lib/, src/: Add missing include
20:  264d4f3c = 20:  264d4f3c src/logoutd.c: main(): Remove unused variable
21:  c7bf7001 = 21:  c7bf7001 src/logoutd.c: main(): Reduce scope of local variables
22:  0767270f = 22:  0767270f src/logoutd.c: Replace ZUSTR2STP() calls by XSTRNDUP()
23:  e2ab6d4f = 23:  e2ab6d4f lib/string/zustr2stp.h: Simplify ZUSTR2STP() and its documentation
24:  1901ab33 = 24:  1901ab33 tests/unit/test_zustr2stp.c: Repurpose ZUSTR2STP() tests for ZUSTR2STR()
25:  becd83d7 ! 25:  1b94784c tests/unit/: Repurpose ZUSTR2STR() tests for XSTRNDUP()
    @@ tests/unit/Makefile.am: test_strncpy_LDADD = \
          $(NULL)
      
     +test_strndup_SOURCES = \
    ++    ../../lib/alloc.c \
     +    test_strndup.c \
     +    $(NULL)
     +test_strndup_CFLAGS = \
26:  9a75e0c7 = 26:  e187e2bd lib/getdate.y: NULL doesn't need a cast
27:  26cd6e87 = 27:  bf2a2f7a lib/failure.c: failprint(): Remove dead code
28:  5c6e6b1b = 28:  dceb2a80 lib/, src/: Always pass NULL to time(2)
29:  fef8a6c8 = 29:  6111435c src/newusers.c: main(): Exit on ENOMEM, by calling xstrdup() instead of strdup(3)
30:  75341447 = 30:  df886067 src/su.c: save_caller_context(): Remove unused parameter
v13
  • Don't test XSTRNDUP(). Anything that depends on alloc functions pulls in so many dependencies to test.
$ git range-diff shadow/master gh/reduce reduce 
 1:  aa006a86 =  1:  aa006a86 lib/: Use REALLOCF() instead of its pattern
 2:  a4a67952 =  2:  a4a67952 lib/commonio.c: commonio_open(): MALLOC() and REALLOCF() already set ENOMEM
 3:  9f7e3f3f =  3:  9f7e3f3f lib/commonio.c: commonio_open(): Reduce scope of local variables
 4:  29fe6822 =  4:  29fe6822 lib/, src/: Use strchrnul(3) instead of its pattern
 5:  22ab9ccf =  5:  22ab9ccf src/useradd.c: tallylog_reset(): Use Basename() instead of its pattern
 6:  59ba2329 =  6:  59ba2329 lib/shadow.c: my_sgetspent(): Clarify that we're assigning an empty string
 7:  ea204ae3 =  7:  ea204ae3 lib/, src/: Use strsep(3) instead of its pattern
 8:  e9c5f0ab =  8:  e9c5f0ab lib/gshadow.c: build_list(): Fix forever loop on ENOMEM
 9:  1bb39ddc =  9:  1bb39ddc lib/gshadow.c: build_list(): Fix REALLOC() nmemb calculation
10:  f19ea03f = 10:  f19ea03f src/login.c: main(): Remove dead code
11:  71cafac4 = 11:  71cafac4 src/groupmems.c: Fix number of elements in allocation
12:  187356c6 = 12:  187356c6 src/: Use xasprintf() instead of its pattern
13:  30457378 = 13:  30457378 lib/Makefile.am: Add missing file
14:  3334781c = 14:  3334781c lib/string/zustr2stp.h: ZUSTR2STR(): Add macro
15:  54bd1b7c = 15:  54bd1b7c lib/string/strndup.[ch]: XSTRNDUP(): Add macro
16:  ae742cf2 = 16:  ae742cf2 lib/utmp.c: Use XSTRNDUP() instead of its pattern
17:  aca896b8 = 17:  aca896b8 lib/utmp.c: prepare_utmp(): Use xstrdup() instead of its pattern
18:  8faf4207 = 18:  8faf4207 lib/utmp.c: prepare_utmp(): Reduce braces
19:  81e53195 = 19:  81e53195 lib/, src/: Add missing include
20:  264d4f3c = 20:  264d4f3c src/logoutd.c: main(): Remove unused variable
21:  c7bf7001 = 21:  c7bf7001 src/logoutd.c: main(): Reduce scope of local variables
22:  0767270f = 22:  0767270f src/logoutd.c: Replace ZUSTR2STP() calls by XSTRNDUP()
23:  e2ab6d4f = 23:  e2ab6d4f lib/string/zustr2stp.h: Simplify ZUSTR2STP() and its documentation
24:  1901ab33 = 24:  1901ab33 tests/unit/test_zustr2stp.c: Repurpose ZUSTR2STP() tests for ZUSTR2STR()
25:  1b94784c <  -:  -------- tests/unit/: Repurpose ZUSTR2STR() tests for XSTRNDUP()
26:  e187e2bd = 25:  a73c45e8 lib/getdate.y: NULL doesn't need a cast
27:  bf2a2f7a = 26:  c99404fe lib/failure.c: failprint(): Remove dead code
28:  dceb2a80 = 27:  6fe06842 lib/, src/: Always pass NULL to time(2)
29:  6111435c = 28:  1142d6bd src/newusers.c: main(): Exit on ENOMEM, by calling xstrdup() instead of strdup(3)
30:  df886067 = 29:  291b3e3a src/su.c: save_caller_context(): Remove unused parameter
v13b
  • Squash some commits
  • Reorder commits
  • Simplify some commit messages
$ git range-diff --creation-factor=99 shadow/master gh/reduce reduce 29:  291b3e3a =  1:  dac868b2 src/su.c: save_caller_context(): Remove unused parameter
20:  264d4f3c !  2:  84611483 src/logoutd.c: main(): Remove unused variable
    @@ Metadata
     Author: Alejandro Colomar <alx@kernel.org>
     
      ## Commit message ##
    -    src/logoutd.c: main(): Remove unused variable
    +    src/logoutd.c: Remove unused variable
     
         wait(2) accepts NULL if the status won't be read.  Simplify.
     
10:  f19ea03f !  3:  c659e125 src/login.c: main(): Remove dead code
    @@ Metadata
     Author: Alejandro Colomar <alx@kernel.org>
     
      ## Commit message ##
    -    src/login.c: main(): Remove dead code
    +    src/login.c: Remove dead code
     
         The functions that set these strings --do_rlogin() and login_prompt()--
         make sure to terminate them with a NUL.
21:  c7bf7001 !  4:  90d7f3bf src/logoutd.c: main(): Reduce scope of local variables
    @@ Metadata
     Author: Alejandro Colomar <alx@kernel.org>
     
      ## Commit message ##
    -    src/logoutd.c: main(): Reduce scope of local variables
    +    lib/, src/: Reduce scope of local variables
     
         Signed-off-by: Alejandro Colomar <alx@kernel.org>
     
    + ## lib/commonio.c ##
    +@@ lib/commonio.c: static void add_one_entry_nis (struct commonio_db *db,
    + int commonio_open (struct commonio_db *db, int mode)
    + {
    +   char *buf;
    +-  char *cp;
    +   char *line;
    +-  struct commonio_entry *p;
    +   void *eptr = NULL;
    +   int flags = mode;
    +   size_t buflen;
    +@@ lib/commonio.c: int commonio_open (struct commonio_db *db, int mode)
    +   }
    + 
    +   while (db->ops->fgets (buf, buflen, db->fp) == buf) {
    ++          char                   *cp;
    ++          struct commonio_entry  *p;
    ++
    +           while (   (strrchr (buf, '\n') == NULL)
    +                  && (feof (db->fp) == 0)) {
    +                   size_t len;
    +
      ## src/logoutd.c ##
     @@ src/logoutd.c: static void send_mesg_to_tty (int tty_fd)
      int
 6:  59ba2329 =  5:  05a0c1bc lib/shadow.c: my_sgetspent(): Clarify that we're assigning an empty string
25:  a73c45e8 =  6:  861e3c89 lib/getdate.y: NULL doesn't need a cast
27:  6fe06842 !  7:  8e10fdca lib/, src/: Always pass NULL to time(2)
    @@ src/faillog.c: static void print_one (/*@null@*/const struct passwd *pw, bool fo
     
      ## src/logoutd.c ##
     @@ src/logoutd.c: check_login(const struct utmpx *ut)
    -   user = XSTRNDUP(ut->ut_user);
    -   line = XSTRNDUP(ut->ut_line);
    +   ZUSTR2STP(user, ut->ut_user);
    +   ZUSTR2STP(line, ut->ut_line);
      
     -  (void) time (&now);
     +  now = time(NULL);
      
    -   allowed_now = isttytime(user, line, now);
    - 
    +   /*
    +    * Check if they are allowed to be logged in right now.
26:  c99404fe =  8:  83bb6e13 lib/failure.c: failprint(): Remove dead code
13:  30457378 =  9:  c50f671d lib/Makefile.am: Add missing file
19:  81e53195 ! 10:  f290e305 lib/, src/: Add missing include
    @@ Commit message
     
         Signed-off-by: Alejandro Colomar <alx@kernel.org>
     
    - ## lib/obscure.c ##
    -@@
    - #include <ctype.h>
    - #include <stdio.h>
    - 
    -+#include "alloc.h"
    - #include "attr.h"
    - #include "memzero.h"
    - #include "prototypes.h"
    -
      ## src/passwd.c ##
     @@
      #include <sys/types.h>
    @@ src/passwd.c
      
     +#include "alloc.h"
      #include "agetpass.h"
    + #include "alloc.h"
      #include "atoi/str2i.h"
    - #include "defines.h"
 1:  aa006a86 = 11:  f206979e lib/: Use REALLOCF() instead of its pattern
 2:  a4a67952 ! 12:  7b7271c2 lib/commonio.c: commonio_open(): MALLOC() and REALLOCF() already set ENOMEM
    @@ lib/commonio.c: int commonio_open (struct commonio_db *db, int mode)
     +          goto cleanup_errno;
      
        while (db->ops->fgets (buf, buflen, db->fp) == buf) {
    -           while (   (strrchr (buf, '\n') == NULL)
    +           char                   *cp;
     @@ lib/commonio.c: int commonio_open (struct commonio_db *db, int mode)
      
                        buflen += BUFLEN;
 3:  9f7e3f3f <  -:  -------- lib/commonio.c: commonio_open(): Reduce scope of local variables
 4:  29fe6822 = 13:  bbcbd7bd lib/, src/: Use strchrnul(3) instead of its pattern
 5:  22ab9ccf = 14:  42b086b5 src/useradd.c: tallylog_reset(): Use Basename() instead of its pattern
 7:  ea204ae3 = 15:  3f75d467 lib/, src/: Use strsep(3) instead of its pattern
 8:  e9c5f0ab = 16:  80183769 lib/gshadow.c: build_list(): Fix forever loop on ENOMEM
 9:  1bb39ddc = 17:  ea22f334 lib/gshadow.c: build_list(): Fix REALLOC() nmemb calculation
11:  71cafac4 = 18:  ad3fbd48 src/groupmems.c: Fix number of elements in allocation
12:  187356c6 ! 19:  6dbab221 src/: Use xasprintf() instead of its pattern
    @@ lib/obscure.c: static /*@observer@*//*@null@*/const char *password_check (
     
      ## src/passwd.c ##
     @@
    - #include <time.h>
      
    + #include "alloc.h"
      #include "agetpass.h"
     -#include "alloc.h"
      #include "atoi/str2i.h"
14:  3334781c = 20:  ce49758f lib/string/zustr2stp.h: ZUSTR2STR(): Add macro
15:  54bd1b7c = 21:  32a42b6f lib/string/strndup.[ch]: XSTRNDUP(): Add macro
16:  ae742cf2 = 22:  b0491978 lib/utmp.c: Use XSTRNDUP() instead of its pattern
17:  aca896b8 <  -:  -------- lib/utmp.c: prepare_utmp(): Use xstrdup() instead of its pattern
18:  8faf4207 ! 23:  7eec456e lib/utmp.c: prepare_utmp(): Reduce braces
    @@ Metadata
     Author: Alejandro Colomar <alx@kernel.org>
     
      ## Commit message ##
    -    lib/utmp.c: prepare_utmp(): Reduce braces
    +    lib/utmp.c: prepare_utmp(): Use xstrdup() instead of its pattern
     
         Signed-off-by: Alejandro Colomar <alx@kernel.org>
     
    @@ lib/utmp.c: prepare_utmp(const char *name, const char *line, const char *host,
      
      
     -  if (   (NULL != host)
    --      && ('\0' != host[0]))
    --  {
    +-      && ('\0' != host[0])) {
    +-          hostname = XMALLOC(strlen(host) + 1, char);
    +-          strcpy (hostname, host);
     +  if (NULL != host && '\0' != host[0])
    -           hostname = xstrdup(host);
    ++          hostname = xstrdup(host);
      #if defined(HAVE_STRUCT_UTMPX_UT_HOST)
     -  } else if (   (NULL != ut)
     -             && ('\0' != ut->ut_host[0])) {
22:  0767270f ! 24:  0316f71c src/logoutd.c: Replace ZUSTR2STP() calls by XSTRNDUP()
    @@ src/logoutd.c: static void send_mesg_to_tty (int tty_fd);
     +  user = XSTRNDUP(ut->ut_user);
     +  line = XSTRNDUP(ut->ut_line);
      
    -   (void) time (&now);
    +   now = time(NULL);
      
     -  /*
     -   * Check if they are allowed to be logged in right now.
23:  e2ab6d4f = 25:  b1069168 lib/string/zustr2stp.h: Simplify ZUSTR2STP() and its documentation
24:  1901ab33 = 26:  9b90ee45 tests/unit/test_zustr2stp.c: Repurpose ZUSTR2STP() tests for ZUSTR2STR()
28:  1142d6bd ! 27:  6480408f src/newusers.c: main(): Exit on ENOMEM, by calling xstrdup() instead of strdup(3)
    @@ Metadata
     Author: Alejandro Colomar <alx@kernel.org>
     
      ## Commit message ##
    -    src/newusers.c: main(): Exit on ENOMEM, by calling xstrdup() instead of strdup(3)
    +    src/newusers.c: Exit on ENOMEM, by calling xstrdup() instead of strdup(3)
     
         The program was happily passing the result of strdup(3) to functions
         that don't accept NULL --such as crypt(3), via add_passwd()--.
v13c
  • Fix includes
$ git range-diff shadow/master gh/reduce reduce 
 1:  dac868b2 =  1:  dac868b2 src/su.c: save_caller_context(): Remove unused parameter
 2:  84611483 =  2:  84611483 src/logoutd.c: Remove unused variable
 3:  c659e125 =  3:  c659e125 src/login.c: Remove dead code
 4:  90d7f3bf =  4:  90d7f3bf lib/, src/: Reduce scope of local variables
 5:  05a0c1bc =  5:  05a0c1bc lib/shadow.c: my_sgetspent(): Clarify that we're assigning an empty string
 6:  861e3c89 =  6:  861e3c89 lib/getdate.y: NULL doesn't need a cast
 7:  8e10fdca =  7:  8e10fdca lib/, src/: Always pass NULL to time(2)
 8:  83bb6e13 =  8:  83bb6e13 lib/failure.c: failprint(): Remove dead code
 9:  c50f671d =  9:  c50f671d lib/Makefile.am: Add missing file
10:  f290e305 = 10:  f290e305 lib/, src/: Add missing include
11:  f206979e = 11:  f206979e lib/: Use REALLOCF() instead of its pattern
12:  7b7271c2 = 12:  7b7271c2 lib/commonio.c: commonio_open(): MALLOC() and REALLOCF() already set ENOMEM
13:  bbcbd7bd = 13:  bbcbd7bd lib/, src/: Use strchrnul(3) instead of its pattern
14:  42b086b5 = 14:  42b086b5 src/useradd.c: tallylog_reset(): Use Basename() instead of its pattern
15:  3f75d467 = 15:  3f75d467 lib/, src/: Use strsep(3) instead of its pattern
16:  80183769 = 16:  80183769 lib/gshadow.c: build_list(): Fix forever loop on ENOMEM
17:  ea22f334 = 17:  ea22f334 lib/gshadow.c: build_list(): Fix REALLOC() nmemb calculation
18:  ad3fbd48 = 18:  ad3fbd48 src/groupmems.c: Fix number of elements in allocation
19:  6dbab221 ! 19:  2bed0218 src/: Use xasprintf() instead of its pattern
    @@ Commit message
     
      ## lib/obscure.c ##
     @@
    - #include <ctype.h>
    - #include <stdio.h>
    - 
    --#include "alloc.h"
    - #include "attr.h"
    - #include "memzero.h"
      #include "prototypes.h"
      #include "defines.h"
      #include "getdef.h"
20:  ce49758f = 20:  d4167425 lib/string/zustr2stp.h: ZUSTR2STR(): Add macro
21:  32a42b6f = 21:  b889fb88 lib/string/strndup.[ch]: XSTRNDUP(): Add macro
22:  b0491978 = 22:  71db0210 lib/utmp.c: Use XSTRNDUP() instead of its pattern
23:  7eec456e = 23:  942b5949 lib/utmp.c: prepare_utmp(): Use xstrdup() instead of its pattern
24:  0316f71c = 24:  009a1093 src/logoutd.c: Replace ZUSTR2STP() calls by XSTRNDUP()
25:  b1069168 = 25:  fc49ee04 lib/string/zustr2stp.h: Simplify ZUSTR2STP() and its documentation
26:  9b90ee45 = 26:  363a72c5 tests/unit/test_zustr2stp.c: Repurpose ZUSTR2STP() tests for ZUSTR2STR()
27:  6480408f = 27:  6889478c src/newusers.c: Exit on ENOMEM, by calling xstrdup() instead of strdup(3)
v14
  • Add STRNCAT()
  • Remove ZUSTR2STP()
  • Reimplement ZUSTR2STR()
$ git range-diff shadow/master gh/reduce reduce 
 1:  dac868b2 =  1:  dac868b2 src/su.c: save_caller_context(): Remove unused parameter
 2:  84611483 =  2:  84611483 src/logoutd.c: Remove unused variable
 3:  c659e125 =  3:  c659e125 src/login.c: Remove dead code
 4:  90d7f3bf =  4:  90d7f3bf lib/, src/: Reduce scope of local variables
 5:  05a0c1bc =  5:  05a0c1bc lib/shadow.c: my_sgetspent(): Clarify that we're assigning an empty string
 6:  861e3c89 =  6:  861e3c89 lib/getdate.y: NULL doesn't need a cast
 7:  8e10fdca =  7:  8e10fdca lib/, src/: Always pass NULL to time(2)
 8:  83bb6e13 =  8:  83bb6e13 lib/failure.c: failprint(): Remove dead code
 9:  c50f671d =  9:  c50f671d lib/Makefile.am: Add missing file
10:  f290e305 = 10:  f290e305 lib/, src/: Add missing include
11:  f206979e = 11:  f206979e lib/: Use REALLOCF() instead of its pattern
12:  7b7271c2 = 12:  7b7271c2 lib/commonio.c: commonio_open(): MALLOC() and REALLOCF() already set ENOMEM
13:  bbcbd7bd = 13:  79e8208f lib/, src/: Use strchrnul(3) instead of its pattern
14:  42b086b5 = 14:  d8c17e5c src/useradd.c: tallylog_reset(): Use Basename() instead of its pattern
15:  3f75d467 = 15:  058435e3 lib/, src/: Use strsep(3) instead of its pattern
16:  80183769 = 16:  893f35f2 lib/gshadow.c: build_list(): Fix forever loop on ENOMEM
17:  ea22f334 = 17:  465e9753 lib/gshadow.c: build_list(): Fix REALLOC() nmemb calculation
18:  ad3fbd48 = 18:  dbc294f1 src/groupmems.c: Fix number of elements in allocation
19:  2bed0218 = 19:  d2f82dc7 src/: Use xasprintf() instead of its pattern
20:  d4167425 = 20:  e0087179 lib/string/zustr2stp.h: ZUSTR2STR(): Add macro
21:  b889fb88 = 21:  39345d8e lib/string/strndup.[ch]: XSTRNDUP(): Add macro
22:  71db0210 = 22:  a42aa280 lib/utmp.c: Use XSTRNDUP() instead of its pattern
23:  942b5949 = 23:  32caf54b lib/utmp.c: prepare_utmp(): Use xstrdup() instead of its pattern
24:  009a1093 = 24:  b11b542d src/logoutd.c: Replace ZUSTR2STP() calls by XSTRNDUP()
25:  fc49ee04 <  -:  -------- lib/string/zustr2stp.h: Simplify ZUSTR2STP() and its documentation
26:  363a72c5 ! 25:  0fc70484 tests/unit/test_zustr2stp.c: Repurpose ZUSTR2STP() tests for ZUSTR2STR()
    @@ Metadata
     Author: Alejandro Colomar <alx@kernel.org>
     
      ## Commit message ##
    -    tests/unit/test_zustr2stp.c: Repurpose ZUSTR2STP() tests for ZUSTR2STR()
    -
    -    Instead of testing ZUSTR2STP(), we can test its only caller: ZUSTR2STR().
    +    tests/unit/test_zustr2str.c: Repurpose ZUSTR2STP() tests for ZUSTR2STR()
     
         Signed-off-by: Alejandro Colomar <alx@kernel.org>
     
    - ## tests/unit/test_zustr2stp.c ##
    + ## tests/unit/Makefile.am ##
    +@@ tests/unit/Makefile.am: check_PROGRAMS = \
    +     test_strncpy \
    +     test_strtcpy \
    +     test_xasprintf \
    +-    test_zustr2stp
    ++    test_zustr2str
    + 
    + if ENABLE_LOGIND
    + check_PROGRAMS += \
    +@@ tests/unit/Makefile.am: test_xasprintf_LDADD = \
    +     $(CMOCKA_LIBS) \
    +     $(NULL)
    + 
    +-test_zustr2stp_SOURCES = \
    +-    test_zustr2stp.c \
    ++test_zustr2str_SOURCES = \
    ++    test_zustr2str.c \
    +     $(NULL)
    +-test_zustr2stp_CFLAGS = \
    ++test_zustr2str_CFLAGS = \
    +     $(AM_CFLAGS) \
    +     $(NULL)
    +-test_zustr2stp_LDFLAGS = \
    ++test_zustr2str_LDFLAGS = \
    +     $(NULL)
    +-test_zustr2stp_LDADD = \
    ++test_zustr2str_LDADD = \
    +     $(CMOCKA_LIBS) \
    +     $(NULL)
    + 
    +
    + ## tests/unit/test_zustr2stp.c => tests/unit/test_zustr2str.c ##
     @@
      #include "string/zustr2stp.h"
      
    @@ tests/unit/test_zustr2stp.c
          };
      
          return cmocka_run_group_tests(tests, NULL, NULL);
    -@@ tests/unit/test_zustr2stp.c: main(void)
    +@@ tests/unit/test_zustr2str.c: main(void)
      
      
      static void
 -:  -------- > 26:  cd5903c5 lib/string/strncat.[ch]: STRNCAT(): Add macro
 -:  -------- > 27:  a7f17b13 lib/string/: Remove ZUSTR2STP, and reimplement ZUSTR2STR()
27:  6889478c = 28:  7e87bccb src/newusers.c: Exit on ENOMEM, by calling xstrdup() instead of strdup(3)
 -:  -------- > 29:  a81ac44d src/logoutd.c: Use STRNCAT() instead of its pattern
v14b
  • Rebase
$ git range-diff master..gh/reduce shadow/master..reduce 
 1:  dac868b2 =  1:  39fcc072 src/su.c: save_caller_context(): Remove unused parameter
 2:  84611483 =  2:  ffd280ac src/logoutd.c: Remove unused variable
 3:  c659e125 !  3:  69c7f0d1 src/login.c: Remove dead code
    @@ Commit message
     
      ## src/login.c ##
     @@ src/login.c: int main (int argc, char **argv)
    - 
    +           max_size = login_name_max_size();
                assert (NULL == username);
                username = XMALLOC(max_size, char);
     -          username[max_size - 1] = '\0';
 4:  90d7f3bf =  4:  168d9fce lib/, src/: Reduce scope of local variables
 5:  05a0c1bc =  5:  97cb8a87 lib/shadow.c: my_sgetspent(): Clarify that we're assigning an empty string
 6:  861e3c89 =  6:  7b5345dc lib/getdate.y: NULL doesn't need a cast
 7:  8e10fdca =  7:  cd1ed7ad lib/, src/: Always pass NULL to time(2)
 8:  83bb6e13 =  8:  92ffd93c lib/failure.c: failprint(): Remove dead code
 9:  c50f671d =  9:  a77f8284 lib/Makefile.am: Add missing file
10:  f290e305 = 10:  264c36ad lib/, src/: Add missing include
11:  f206979e = 11:  9b3cc4d9 lib/: Use REALLOCF() instead of its pattern
12:  7b7271c2 = 12:  d1ddac40 lib/commonio.c: commonio_open(): MALLOC() and REALLOCF() already set ENOMEM
13:  79e8208f = 13:  b438cd0f lib/, src/: Use strchrnul(3) instead of its pattern
14:  d8c17e5c = 14:  4ff6b399 src/useradd.c: tallylog_reset(): Use Basename() instead of its pattern
15:  058435e3 = 15:  975aee74 lib/, src/: Use strsep(3) instead of its pattern
16:  893f35f2 = 16:  1e28b7af lib/gshadow.c: build_list(): Fix forever loop on ENOMEM
17:  465e9753 = 17:  6e26f5f2 lib/gshadow.c: build_list(): Fix REALLOC() nmemb calculation
18:  dbc294f1 = 18:  b0f601e5 src/groupmems.c: Fix number of elements in allocation
19:  d2f82dc7 = 19:  6bc75bd1 src/: Use xasprintf() instead of its pattern
20:  e0087179 = 20:  8131b8d6 lib/string/zustr2stp.h: ZUSTR2STR(): Add macro
21:  39345d8e = 21:  93991ac8 lib/string/strndup.[ch]: XSTRNDUP(): Add macro
22:  a42aa280 = 22:  197e174c lib/utmp.c: Use XSTRNDUP() instead of its pattern
23:  32caf54b = 23:  756e2885 lib/utmp.c: prepare_utmp(): Use xstrdup() instead of its pattern
24:  b11b542d = 24:  918df02e src/logoutd.c: Replace ZUSTR2STP() calls by XSTRNDUP()
25:  0fc70484 = 25:  7ff4c250 tests/unit/test_zustr2str.c: Repurpose ZUSTR2STP() tests for ZUSTR2STR()
26:  cd5903c5 = 26:  7fe6504d lib/string/strncat.[ch]: STRNCAT(): Add macro
27:  a7f17b13 = 27:  2072bba3 lib/string/: Remove ZUSTR2STP, and reimplement ZUSTR2STR()
28:  7e87bccb = 28:  40ef9e1e src/newusers.c: Exit on ENOMEM, by calling xstrdup() instead of strdup(3)
29:  a81ac44d = 29:  55119d1e src/logoutd.c: Use STRNCAT() instead of its pattern
v15
  • Fix test
$ git range-diff shadow/master gh/reduce reduce 
 1:  39fcc072 =  1:  39fcc072 src/su.c: save_caller_context(): Remove unused parameter
 2:  ffd280ac =  2:  ffd280ac src/logoutd.c: Remove unused variable
 3:  69c7f0d1 =  3:  69c7f0d1 src/login.c: Remove dead code
 4:  168d9fce =  4:  168d9fce lib/, src/: Reduce scope of local variables
 5:  97cb8a87 =  5:  97cb8a87 lib/shadow.c: my_sgetspent(): Clarify that we're assigning an empty string
 6:  7b5345dc =  6:  7b5345dc lib/getdate.y: NULL doesn't need a cast
 7:  cd1ed7ad =  7:  cd1ed7ad lib/, src/: Always pass NULL to time(2)
 8:  92ffd93c =  8:  92ffd93c lib/failure.c: failprint(): Remove dead code
 9:  a77f8284 =  9:  a77f8284 lib/Makefile.am: Add missing file
10:  264c36ad = 10:  264c36ad lib/, src/: Add missing include
11:  9b3cc4d9 = 11:  9b3cc4d9 lib/: Use REALLOCF() instead of its pattern
12:  d1ddac40 = 12:  d1ddac40 lib/commonio.c: commonio_open(): MALLOC() and REALLOCF() already set ENOMEM
13:  b438cd0f = 13:  b438cd0f lib/, src/: Use strchrnul(3) instead of its pattern
14:  4ff6b399 = 14:  4ff6b399 src/useradd.c: tallylog_reset(): Use Basename() instead of its pattern
15:  975aee74 = 15:  975aee74 lib/, src/: Use strsep(3) instead of its pattern
16:  1e28b7af = 16:  1e28b7af lib/gshadow.c: build_list(): Fix forever loop on ENOMEM
17:  6e26f5f2 = 17:  6e26f5f2 lib/gshadow.c: build_list(): Fix REALLOC() nmemb calculation
18:  b0f601e5 = 18:  b0f601e5 src/groupmems.c: Fix number of elements in allocation
19:  6bc75bd1 = 19:  6bc75bd1 src/: Use xasprintf() instead of its pattern
20:  8131b8d6 = 20:  8131b8d6 lib/string/zustr2stp.h: ZUSTR2STR(): Add macro
21:  93991ac8 = 21:  93991ac8 lib/string/strndup.[ch]: XSTRNDUP(): Add macro
22:  197e174c = 22:  197e174c lib/utmp.c: Use XSTRNDUP() instead of its pattern
23:  756e2885 = 23:  756e2885 lib/utmp.c: prepare_utmp(): Use xstrdup() instead of its pattern
24:  918df02e = 24:  918df02e src/logoutd.c: Replace ZUSTR2STP() calls by XSTRNDUP()
25:  7ff4c250 = 25:  7ff4c250 tests/unit/test_zustr2str.c: Repurpose ZUSTR2STP() tests for ZUSTR2STR()
26:  7fe6504d = 26:  7fe6504d lib/string/strncat.[ch]: STRNCAT(): Add macro
27:  2072bba3 = 27:  2072bba3 lib/string/: Remove ZUSTR2STP, and reimplement ZUSTR2STR()
28:  40ef9e1e = 28:  40ef9e1e src/newusers.c: Exit on ENOMEM, by calling xstrdup() instead of strdup(3)
29:  55119d1e = 29:  55119d1e src/logoutd.c: Use STRNCAT() instead of its pattern
 -:  -------- > 30:  0f43c3ac tests/unit/test_zustr2str.c: Remove incorrect use of address-of operator

src/chfn.c Fixed Show resolved Hide resolved
lib/subordinateio.c Dismissed Show resolved Hide resolved
src/chfn.c Dismissed Show resolved Hide resolved
@alejandro-colomar alejandro-colomar marked this pull request as ready for review May 12, 2024 23:56
@alejandro-colomar alejandro-colomar changed the title Simplify a lot of open-coded stuff, and fix a forever loop Simplify a lot of NIH stuff, and fix a forever loop May 13, 2024
@alejandro-colomar alejandro-colomar changed the title Simplify a lot of NIH stuff, and fix a forever loop Simplify a lot of NIH stuff, and fix several bugs May 13, 2024
@alejandro-colomar
Copy link
Collaborator Author

I've also documented strndup(3) within string_copying(7) as a function that duplicates an input null-padded character sequence into an output newly allocated string:

commit 6af636f134d82b8d3838074fa6e0dce5efc356a4 (HEAD -> contrib, alx/contrib)
Author: Alejandro Colomar <alx@kernel.org>
Date:   Tue May 14 19:36:53 2024 +0200

    string_copying.7: Document strndup(3)
    
    Signed-off-by: Alejandro Colomar <alx@kernel.org>

diff --git a/man/man7/string_copying.7 b/man/man7/string_copying.7
index 281fff8be..0be53d1cf 100644
--- a/man/man7/string_copying.7
+++ b/man/man7/string_copying.7
@@ -61,6 +61,9 @@ .SS Null-padded character sequences
 // Catenate a null-padded character sequence into a string.
 .BI "char *strncat(char *restrict " dst ", const char " src "[restrict ." ssize ],
 .BI "               size_t " ssize );
+.P
+// Duplicate a null-padded character sequence into a string.
+.BI "char *strndup(const char " src [. ssize "], size_t " ssize );
 .fi
 .\" ----- SYNOPSIS :: Known-length character sequences --------------------/
 .SS Known-length character sequences
@@ -154,6 +157,11 @@ .SS Terms (and abbreviations)
 (or one after the last character in a character sequence)
 after the call,
 so that the programmer can use it to chain such calls.
+.\" ----- DESCRIPTION :: Terms (and abbreviations) :: duplicate -------/
+.TP
+.I duplicate
+Allocate a new buffer
+where a copy is placed.
 .\" ----- DESCRIPTION :: Copy, catenate, and chain-copy ---------------/
 .SS Copy, catenate, and chain-copy
 Originally,
@@ -252,6 +260,8 @@ .SS Null-padded character sequences
 and then you can treat it as a known-length character sequence;
 or use
 .BR strncat (3)
+or
+.BR strndup (3)
 directly.
 .\" ----- DESCRIPTION :: Known-length character sequences -----------------/
 .SS Known-length character sequences
@@ -342,7 +352,11 @@ .SS String vs character sequence
 has an even more misleading name than the functions above.
 List of functions:
 .IP \[bu] 3
+.PD 0
 .BR strncat (3)
+.IP \[bu]
+.BR strndup (3)
+.PD
 .P
 Other functions operate on an input character sequence
 to create an output character sequence.
@@ -453,6 +467,15 @@ .SS Functions
 .IP
 .I \%stpcpy(mempcpy(dst,\ src,\ strnlen(src,\ NITEMS(src))),\ \[dq]\[dq])
 is a faster alternative to this function.
+.\" ----- DESCRIPTION :: Functions :: strndup(3) ----------------------/
+.TP
+.BR strndup (3)
+Duplicate the input character sequence,
+contained in a null-padded fixed-size buffer,
+into a newly allocated destination string.
+.IP
+The string must be freed with
+.BR free (3).
 .\" ----- DESCRIPTION :: Functions :: mempcpy(3) ----------------------/
 .TP
 .BR mempcpy (3)
@@ -508,6 +531,9 @@ .SH RETURN VALUE
 .I dst
 pointer,
 which is useless.
+.TP
+.BR strndup (3)
+The newly allocated string.
 .\" ----- ERRORS ------------------------------------------------------/
 .SH ERRORS
 Most of these functions don't set
@@ -526,6 +552,13 @@ .SH ERRORS
 .B E2BIG
 The string has been truncated.
 .RE
+.TP
+.BR strndup (3)
+.RS
+.TP
+.B ENOMEM
+Insufficient memory available to allocate duplicate string.
+.RE
 .\" ----- NOTES :: strscpy(9) -----------------------------------------/
 .SH NOTES
 The Linux kernel has an internal function for copying strings,
@@ -689,6 +722,15 @@ .SH EXAMPLES
 len = strlen(buf);
 puts(buf);
 .EE
+.\" ----- EXAMPLES :: strndup(3) --------------------------------------/
+.TP
+.BR strndup (3)
+.EX
+buf = strndup(u->ut_user, NITEMS(u->ut_user));
+len = strlen(buf);
+puts(buf);
+free(buf);
+.EE
 .\" ----- EXAMPLES :: mempcpy(3) --------------------------------------/
 .TP
 .BR mempcpy (3)

@alejandro-colomar
Copy link
Collaborator Author

@ikerexxe , if you want me to divide this into smaller PRs, let me know more or less the size you want to handle in each. ;)

@alejandro-colomar
Copy link
Collaborator Author

@ikerexxe The codeq failure is spurious (see the resolved reports above). Feel free to review and merge when you find some time.

Fixes: e6c2e43 ("Hardcoding Prog to known value")
Signed-off-by: Alejandro Colomar <alx@kernel.org>
wait(2) accepts NULL if the status won't be read.  Simplify.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
The functions that set these strings --do_rlogin() and login_prompt()--
make sure to terminate them with a NUL.

Fixes: 3704745 ("* lib/defines.h: Define USER_NAME_MAX_LENGTH, based on utmp and [...]")
Signed-off-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
…tring

Signed-off-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
See time(2):

BUGS
     Error returns from this system  call  are  indistinguishable  from
     successful  reports  that  the  time  is  a few seconds before the
     Epoch, so the C library wrapper function never sets errno as a re‐
     sult of this call.

     The tloc argument is obsolescent and should always be NULL in  new
     code.  When tloc is NULL, the call cannot fail.

Fixes: 45c6603 ("[svn-upgrade] Integrating new upstream version, shadow (19990709)")
Signed-off-by: Alejandro Colomar <alx@kernel.org>
This should have gone into the #else'd branch in 8451bed, and
should have been removed in 3e602b5.

Fixes: 8451bed ("[svn-upgrade] Integrating new upstream version, shadow (4.0.13)")
Fixes: 3e602b5 ("Remove HAVE_STRFTIME ifdefs")
Signed-off-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
…ENOMEM

We don't need to set ENOMEM on failure of those functions.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
In the files where #include <string.h> is missing, add it, and sort the
includes.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
Before this patch, the function looped while (s != NULL && *s != '\0').
However, nothing was modifying that string if REALLOC() failed, so the
loop was forever.

Fixes: 8e167d2 ("[svn-upgrade] Integrating new upstream version, shadow (4.0.8)")
Signed-off-by: Alejandro Colomar <alx@kernel.org>
Fixes: efbbcad ("Use safer allocation macros")
Signed-off-by: Alejandro Colomar <alx@kernel.org>
We are setting `sgrent.sg_adm[1] = NULL;`, so we need 2 elements.

Fixes: 87b56b1 ("* NEWS, src/groupmems.c, man/groupmems.8.xml: Added support for [...]")
Signed-off-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
This is like ZUSTR2STP(), but returns dst instead of dst + strlen(dst).

Signed-off-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
XSTRNDUP() is similar to ZUSTR2STP() but allocating the destination
buffer.

This means that we must change the buffers to be allocated in the call
instead of automatic storage, which itself means we must free(3) the
memory after using.

The benefits of this refactor are:

-  The allocation size is always correct, and needs no comments, since
   it's now automatically calculated by the macro.

-  XSTRNDUP() is probably more familiar, since
   -  strndup(3) is a standard libc function,
   -  XSTRNDUP() is the obvious wrapper that
      -  exit()s on ENOMEM,
      -  calculates the size based on the input array.

-  We can remove ZUSTR2STP().  Or actually, we can use it internally
   just for implementing XSTRNDUP(), but stop using it in other code.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
ZUSTR2STR() is now only used by XSTRNDUP(), where 'dst' is a recently
allocated buffer (so, not an array).  Thus, we can remove the
static_assert(3), which is now useless.  ZUSTR2STP() is unused.

ZUSTR2STR() is much simpler by implementing it as a STRNCAT() wrapper.

Also, this macro can be documented by comparing them to strndup(3) and
strncat(3).  That's much easier to understand than a fully descriptive
manual page.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
…p(3)

The program was happily passing the result of strdup(3) to functions
that don't accept NULL --such as crypt(3), via add_passwd()--.

Fixes: 7f9e196 ("* NEWS, src/newusers.c, src/Makefile.am: Added support for")
Signed-off-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
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.

None yet

1 participant