Skip to content

Use liba2i #1049

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 2 commits into
base: master
Choose a base branch
from
Draft

Conversation

alejandro-colomar
Copy link
Collaborator

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

A lot needs to happen before we can merge this, but let's have it here as a draft. Most likely, won't happen before 2025.

Distros should package liba2i before this happens.

https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1076091


Revisions:

v1b
  • Rebase
$ git range-diff gh/master..gh/liba2i shadow/master..liba2i 
1:  cc974c31 = 1:  85174e72 Depend on liba2i
2:  379cdd67 = 2:  a13ba662 Add liba2i to the build system
v1c
  • Rebase
$ git range-diff master..gh/liba2i shadow/master..liba2i 
1:  85174e72 ! 1:  b309d24b Depend on liba2i
    @@ lib/limits.c
     +#include <a2i/str2i/str2s.h>
     +#include <a2i/str2i/str2u.h>
     +
    - #include "memzero.h"
    + #include "string/memset/memzero.h"
      #include "typetraits.h"
      
     
    @@ src/chage.c
     +#include <a2i/a2i/a2s.h>
     +
      #include "defines.h"
    - #include "memzero.h"
      #include "prototypes.h"
    + #include "pwio.h"
     
      ## src/check_subid_range.c ##
     @@
    @@ src/faillog.c
     +
      #include "defines.h"
      #include "faillog.h"
    - #include "memzero.h"
    + #include "prototypes.h"
     
      ## src/free_subid_range.c ##
     @@
    @@ src/passwd.c
     -#include "atoi/a2i/a2s.h"
      #include "defines.h"
      #include "getdef.h"
    - #include "memzero.h"
    + #include "nscd.h"
     
      ## src/useradd.c ##
     @@
2:  a13ba662 = 2:  6dcf69be Add liba2i to the build system
v1d
  • Rebase
$ git range-diff gh/master..gh/liba2i shadow/master..liba2i 
1:  b309d24b = 1:  2a8356f3 Depend on liba2i
2:  6dcf69be = 2:  bbf5f6b6 Add liba2i to the build system
v1e
  • Rebase
$ git range-diff gh/master..gh/liba2i master..liba2i 
1:  2a8356f3 ! 1:  a22fdc3d Depend on liba2i
    @@ lib/limits.c
     +#include <a2i/str2i/str2u.h>
     +
      #include "string/memset/memzero.h"
    + #include "string/strchr/stpspn.h"
      #include "typetraits.h"
    - 
     
      ## lib/sgetspent.c ##
     @@
    @@ lib/strtoday.c
     -#include "atoi/str2i/str2s.h"
     +#include <a2i/str2i/str2s.h>
     +
    - #include "prototypes.h"
      #include "getdate.h"
    - 
    + #include "prototypes.h"
    + #include "string/strchr/stpspn.h"
     
      ## lib/subordinateio.c ##
     @@
2:  bbf5f6b6 = 2:  a8561202 Add liba2i to the build system
v1f
  • Rebase
$ git range-diff master..gh/liba2i shadow/master..liba2i 
1:  a22fdc3d = 1:  3cc9507f Depend on liba2i
2:  a8561202 = 2:  3c81aca6 Add liba2i to the build system
v1g
  • Rebase
$ git range-diff alx/master..gh/liba2i master..liba2i 
1:  3cc9507f = 1:  c770266c Depend on liba2i
2:  3c81aca6 = 2:  fcd4e55b Add liba2i to the build system
v1h
  • Rebase
$ git range-diff alx/master..gh/liba2i shadow/master..liba2i 
1:  c770266c = 1:  0951743b Depend on liba2i
2:  fcd4e55b = 2:  0a0fb508 Add liba2i to the build system
v1i
  • Rebase
$ git range-diff master..gh/liba2i shadow/master..liba2i 
1:  0951743b ! 1:  e640d35b Depend on liba2i
    @@ lib/gettime.c
     
      ## lib/idmapping.c ##
     @@
    + #include <stdlib.h>
      #include <stdio.h>
      #include <strings.h>
    - 
    ++
     +#include <a2i/a2i/a2u.h>
     +
    - #include "alloc/calloc.h"
    - #include "alloc/x/xmalloc.h"
    --#include "atoi/a2i/a2u.h"
    - #include "prototypes.h"
    - #include "string/sprintf/stpeprintf.h"
    - #include "idmapping.h"
    + #if HAVE_SYS_CAPABILITY_H
    + #include <sys/prctl.h>
    + #include <sys/capability.h>
     
      ## lib/limits.c ##
     @@
    @@ lib/limits.c
     +
      #include "string/memset/memzero.h"
      #include "string/strchr/stpspn.h"
    - #include "typetraits.h"
    + #include "string/strcmp/streq.h"
     
      ## lib/sgetspent.c ##
     @@
    @@ lib/shadow.c
     +
      #include "defines.h"
      #include "prototypes.h"
    - #include "string/strtok/stpsep.h"
    + #include "string/strcmp/streq.h"
     
      ## lib/strtoday.c ##
     @@
    @@ lib/subordinateio.c
      #include "alloc/reallocf.h"
     -#include "atoi/str2i/str2u.h"
      #include "string/sprintf/snprintf.h"
    - 
    + #include "string/strcmp/streq.h"
      
     
      ## src/chage.c ##
    @@ src/passwd.c
     +#include <a2i/a2i/a2s.h>
     +
      #include "agetpass.h"
    --#include "atoi/a2i/a2s.h"
    - #include "defines.h"
    - #include "getdef.h"
    - #include "nscd.h"
    + #include "atoi/a2i/a2s.h"
    + #include "chkname.h"
     
      ## src/useradd.c ##
     @@
2:  0a0fb508 = 2:  bf2bd3b7 Add liba2i to the build system
v1j
  • Rebase
$ git range-diff master..gh/liba2i shadow/master..liba2i 
1:  e640d35b = 1:  bdd3f026 Depend on liba2i
2:  bf2bd3b7 = 2:  101ccdcf Add liba2i to the build system
v1k
  • Rebase
$ git range-diff master..gh/liba2i shadow/master..liba2i 
1:  bdd3f026 = 1:  d062c80f Depend on liba2i
2:  101ccdcf = 2:  a640728f Add liba2i to the build system
v1l
  • Rebase
$ git range-diff master..gh/liba2i shadow/master..liba2i 
1:  d062c80f = 1:  00d94f37 Depend on liba2i
2:  a640728f = 2:  81d85e4c Add liba2i to the build system
v1m
  • Rebase
$ git range-diff master..gh/liba2i shadow/master..liba2i 
1:  00d94f37 ! 1:  6c54b752 Depend on liba2i
    @@ lib/getrange.c
     +
      #include "defines.h"
      #include "prototypes.h"
    - 
    + #include "string/strcmp/streq.h"
     
      ## lib/gettime.c ##
     @@
    @@ lib/shadow.c
      ## lib/strtoday.c ##
     @@
      
    - #ident "$Id$"
    + #include <ctype.h>
      
     -#include "atoi/str2i/str2s.h"
     +#include <a2i/str2i/str2s.h>
2:  81d85e4c = 2:  55ba0e01 Add liba2i to the build system
v1n
  • Rebase
$ git range-diff alx/master..gh/liba2i master..liba2i 
1:  6c54b752 = 1:  fabc9a63 Depend on liba2i
2:  55ba0e01 = 2:  7b7e71fc Add liba2i to the build system
v1o
  • Rebase
$ git range-diff alx/master..gh/liba2i master..liba2i 
1:  fabc9a63 ! 1:  03f5546d Depend on liba2i
    @@ lib/subordinateio.c
     
      ## src/chage.c ##
     @@
    - #endif                            /* ACCT_TOOLS_SETUID */
    + #include <time.h>
      #include <pwd.h>
      
     -#include "atoi/a2i/a2s.h"
    @@ src/new_subid_range.c
     
      ## src/newusers.c ##
     @@
    - #include <errno.h>
    + #include <stdint.h>
      #include <string.h>
      
     +#include <a2i/str2i/str2s.h>
2:  7b7e71fc = 2:  0bb56421 Add liba2i to the build system
v1p
  • Rebase
$ git range-diff master..gh/liba2i shadow/master..liba2i 
1:  03f5546d = 1:  84c34e7d Depend on liba2i
2:  0bb56421 = 2:  5db22521 Add liba2i to the build system
v1q
  • Rebase
$ git range-diff master..gh/liba2i shadow/master..liba2i 
1:  84c34e7d ! 1:  136fb802 Depend on liba2i
    @@ lib/gettime.c
     
      ## lib/idmapping.c ##
     @@
    - #include <stdlib.h>
    - #include <stdio.h>
    - #include <strings.h>
    -+
    + # include <sys/capability.h>
    + #endif
    + 
     +#include <a2i/a2i/a2u.h>
     +
    - #if HAVE_SYS_CAPABILITY_H
    - #include <sys/prctl.h>
    - #include <sys/capability.h>
    + #include "alloc/calloc.h"
    + #include "alloc/x/xmalloc.h"
    + #include "atoi/a2i/a2u.h"
     
      ## lib/limits.c ##
     @@
2:  5db22521 = 2:  1d4f9623 Add liba2i to the build system
v1r
  • Rebase
$ git range-diff master..gh/liba2i shadow/master..liba2i 
1:  136fb802 = 1:  9e4f8d3d Depend on liba2i
2:  1d4f9623 = 2:  608e9738 Add liba2i to the build system
v1s
  • Rebase
$ git range-diff master..gh/liba2i shadow/master..liba2i 
1:  9e4f8d3d ! 1:  18751e92 Depend on liba2i
    @@ lib/limits.c
     +#include <a2i/str2i/str2u.h>
     +
      #include "string/memset/memzero.h"
    - #include "string/strchr/stpspn.h"
      #include "string/strcmp/streq.h"
    + #include "string/strspn/stpspn.h"
     
      ## lib/sgetspent.c ##
     @@
    @@ lib/strtoday.c
     +
      #include "getdate.h"
      #include "prototypes.h"
    - #include "string/strchr/stpspn.h"
    + #include "string/strcmp/streq.h"
     
      ## lib/subordinateio.c ##
     @@
2:  608e9738 = 2:  2f9a41ce Add liba2i to the build system
v1t
  • Rebase
$ git range-diff master..gh/liba2i shadow/master..liba2i 
1:  18751e92 ! 1:  0a0230dd Depend on liba2i
    @@ lib/strtoday.c
     +
      #include "getdate.h"
      #include "prototypes.h"
    - #include "string/strcmp/streq.h"
    + #include "string/ctype/strisascii/strisdigit.h"
     
      ## lib/subordinateio.c ##
     @@
    @@ lib/subordinateio.c
      #include "alloc/realloc.h"
      #include "alloc/reallocf.h"
     -#include "atoi/str2i/str2u.h"
    + #include "string/ctype/strisascii/strisdigit.h"
      #include "string/sprintf/snprintf.h"
      #include "string/strcmp/streq.h"
    - 
     
      ## src/chage.c ##
     @@
2:  2f9a41ce = 2:  29f23765 Add liba2i to the build system
v1u
  • Rebase
$ git range-diff master..gh/liba2i shadow/master..liba2i 
1:  0a0230dd = 1:  e08013df Depend on liba2i
2:  29f23765 = 2:  f9eeb978 Add liba2i to the build system
v1v
  • Rebase
$ git rd
1:  e08013df = 1:  3e441062 Depend on liba2i
2:  f9eeb978 = 2:  ab03d243 Add liba2i to the build system
v1w
  • Rebase
$ git rd
1:  3e441062 = 1:  ef565dad Depend on liba2i
2:  ab03d243 = 2:  e520ffcc Add liba2i to the build system
v1x
  • Rebase
$ git rd 
1:  ef565dad ! 1:  9219d227 Depend on liba2i
    @@ lib/limits.c
     +
      #include "string/memset/memzero.h"
      #include "string/strcmp/streq.h"
    - #include "string/strspn/stpspn.h"
    + #include "string/strcmp/strprefix.h"
     
      ## lib/sgetspent.c ##
     @@
    @@ src/check_subid_range.c
      #include "atoi/getnum.h"
     -#include "atoi/str2i/str2u.h"
      #include "defines.h"
    + #include "idmapping.h"
      #include "prototypes.h"
    - #include "subordinateio.h"
     
      ## src/chgpasswd.c ##
     @@
2:  e520ffcc = 2:  1a8ff94f Add liba2i to the build system
v1y
  • Rebase
$ git rd
1:  9219d227 ! 1:  4c8f590f Depend on liba2i
    @@ lib/sgetspent.c
      #include "prototypes.h"
      #include "shadowlog_internal.h"
     
    - ## lib/shadow.c ##
    -@@
    - #include <string.h>
    - #include <sys/types.h>
    - 
    --#include "atoi/a2i/a2s.h"
    --#include "atoi/str2i/str2u.h"
    -+#include <a2i/a2i/a2s.h>
    -+#include <a2i/str2i/str2u.h>
    -+
    - #include "defines.h"
    - #include "prototypes.h"
    - #include "string/strcmp/streq.h"
    -
      ## lib/strtoday.c ##
     @@
      
2:  1a8ff94f = 2:  794617dd Add liba2i to the build system
v2
  • Rebase
$ git rd
1:  4c8f590f ! 1:  5b254775 Depend on liba2i
    @@ lib/Makefile.am: libshadow_la_SOURCES = \
     -  atoi/a2i/a2u_nc.h \
        atoi/getnum.c \
        atoi/getnum.h \
    --  atoi/str2i/str2i.c \
    --  atoi/str2i/str2i.h \
    --  atoi/str2i/str2s.c \
    --  atoi/str2i/str2s.h \
    --  atoi/str2i/str2u.c \
    --  atoi/str2i/str2u.h \
    +-  atoi/str2i.c \
    +-  atoi/str2i.h \
     -  atoi/strtoi/strtoi.c \
     -  atoi/strtoi/strtoi.h \
     -  atoi/strtoi/strtou.c \
    @@ lib/atoi/a2i/a2s.h (deleted)
     -
     -#include <config.h>
     -
    --#include "atoi/a2i/a2s_c.h"
    --#include "atoi/a2i/a2s_nc.h"
    +-#include "atoi/a2i/a2i.h"
     -
     -
    --#define a2sh(n, s, ...)                                                       \
    --(                                                                             \
    --  _Generic(s,                                                           \
    --          const char *:  a2sh_c,                                        \
    --          const void *:  a2sh_c,                                        \
    --          char *:        a2sh_nc,                                       \
    --          void *:        a2sh_nc                                        \
    --  )(n, s, __VA_ARGS__)                                                  \
    --)
    --
    --#define a2si(n, s, ...)                                                       \
    --(                                                                             \
    --  _Generic(s,                                                           \
    --          const char *:  a2si_c,                                        \
    --          const void *:  a2si_c,                                        \
    --          char *:        a2si_nc,                                       \
    --          void *:        a2si_nc                                        \
    --  )(n, s, __VA_ARGS__)                                                  \
    --)
    --
    --#define a2sl(n, s, ...)                                                       \
    --(                                                                             \
    --  _Generic(s,                                                           \
    --          const char *:  a2sl_c,                                        \
    --          const void *:  a2sl_c,                                        \
    --          char *:        a2sl_nc,                                       \
    --          void *:        a2sl_nc                                        \
    --  )(n, s, __VA_ARGS__)                                                  \
    --)
    --
    --#define a2sll(n, s, ...)                                                      \
    --(                                                                             \
    --  _Generic(s,                                                           \
    --          const char *:  a2sll_c,                                       \
    --          const void *:  a2sll_c,                                       \
    --          char *:        a2sll_nc,                                      \
    --          void *:        a2sll_nc                                       \
    --  )(n, s, __VA_ARGS__)                                                  \
    --)
    +-#define a2sh(...)   a2i(short, __VA_ARGS__)
    +-#define a2si(...)   a2i(int, __VA_ARGS__)
    +-#define a2sl(...)   a2i(long, __VA_ARGS__)
    +-#define a2sll(...)  a2i(long long, __VA_ARGS__)
     -
     -
     -#endif  // include guard
    @@ lib/atoi/a2i/a2u.h (deleted)
     -
     -#include <config.h>
     -
    --#include "atoi/a2i/a2u_c.h"
    --#include "atoi/a2i/a2u_nc.h"
    +-#include "atoi/a2i/a2i.h"
     -
     -
    --#define a2uh(n, s, ...)                                                       \
    --(                                                                             \
    --  _Generic(s,                                                           \
    --          const char *:  a2uh_c,                                        \
    --          const void *:  a2uh_c,                                        \
    --          char *:        a2uh_nc,                                       \
    --          void *:        a2uh_nc                                        \
    --  )(n, s, __VA_ARGS__)                                                  \
    --)
    --
    --#define a2ui(n, s, ...)                                                       \
    --(                                                                             \
    --  _Generic(s,                                                           \
    --          const char *:  a2ui_c,                                        \
    --          const void *:  a2ui_c,                                        \
    --          char *:        a2ui_nc,                                       \
    --          void *:        a2ui_nc                                        \
    --  )(n, s, __VA_ARGS__)                                                  \
    --)
    --
    --#define a2ul(n, s, ...)                                                       \
    --(                                                                             \
    --  _Generic(s,                                                           \
    --          const char *:  a2ul_c,                                        \
    --          const void *:  a2ul_c,                                        \
    --          char *:        a2ul_nc,                                       \
    --          void *:        a2ul_nc                                        \
    --  )(n, s, __VA_ARGS__)                                                  \
    --)
    --
    --#define a2ull(n, s, ...)                                                      \
    --(                                                                             \
    --  _Generic(s,                                                           \
    --          const char *:  a2ull_c,                                       \
    --          const void *:  a2ull_c,                                       \
    --          char *:        a2ull_nc,                                      \
    --          void *:        a2ull_nc                                       \
    --  )(n, s, __VA_ARGS__)                                                  \
    --)
    +-#define a2uh(...)   a2i(unsigned short, __VA_ARGS__)
    +-#define a2ui(...)   a2i(unsigned int, __VA_ARGS__)
    +-#define a2ul(...)   a2i(unsigned long, __VA_ARGS__)
    +-#define a2ull(...)  a2i(unsigned long long, __VA_ARGS__)
     -
     -
     -#endif  // include guard
    @@ lib/atoi/getnum.h
      #include "typetraits.h"
      
     
    - ## lib/atoi/str2i/str2i.c (deleted) ##
    + ## lib/atoi/str2i.c (deleted) ##
     @@
     -// SPDX-FileCopyrightText: 2007-2009, Nicolas François
    --// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <[email protected]>
    +-// SPDX-FileCopyrightText: 2023-2025, Alejandro Colomar <[email protected]>
     -// SPDX-License-Identifier: BSD-3-Clause
     -
     -
     -#include <config.h>
     -
    --#include "atoi/str2i/str2i.h"
    +-#include "atoi/str2i.h"
     
    - ## lib/atoi/str2i/str2i.h (deleted) ##
    + ## lib/atoi/str2i.h (deleted) ##
     @@
     -// SPDX-FileCopyrightText: 2007-2009, Nicolas François
    --// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <[email protected]>
    +-// SPDX-FileCopyrightText: 2023-2025, Alejandro Colomar <[email protected]>
     -// SPDX-License-Identifier: BSD-3-Clause
     -
     -
    --#ifndef SHADOW_INCLUDE_LIB_ATOI_STR2I_STR2I_H_
    --#define SHADOW_INCLUDE_LIB_ATOI_STR2I_STR2I_H_
    +-#ifndef SHADOW_INCLUDE_LIB_ATOI_STR2I_H_
    +-#define SHADOW_INCLUDE_LIB_ATOI_STR2I_H_
     -
     -
     -#include <config.h>
     -
    --#include "atoi/str2i/str2s.h"
    --#include "atoi/str2i/str2u.h"
    --
    --
    --#define str2i(TYPE, ...)                                                      \
    --(                                                                             \
    --  _Generic((TYPE) 0,                                                    \
    --          short:              str2sh,                                   \
    --          int:                str2si,                                   \
    --          long:               str2sl,                                   \
    --          long long:          str2sll,                                  \
    --          unsigned short:     str2uh,                                   \
    --          unsigned int:       str2ui,                                   \
    --          unsigned long:      str2ul,                                   \
    --          unsigned long long: str2ull                                   \
    --  )(__VA_ARGS__)                                                        \
    --)
    --
    --
    --#endif  // include guard
    -
    - ## lib/atoi/str2i/str2s.c (deleted) ##
    -@@
    --// SPDX-FileCopyrightText: 2007-2009, Nicolas François
    --// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <[email protected]>
    --// SPDX-License-Identifier: BSD-3-Clause
    --
    --
    --#include <config.h>
    --
    --#include "atoi/str2i/str2s.h"
    --
    --
    --extern inline int str2sh(short *restrict n, const char *restrict s);
    --extern inline int str2si(int *restrict n, const char *restrict s);
    --extern inline int str2sl(long *restrict n, const char *restrict s);
    --extern inline int str2sll(long long *restrict n, const char *restrict s);
    -
    - ## lib/atoi/str2i/str2s.h (deleted) ##
    -@@
    --// SPDX-FileCopyrightText: 2007-2009, Nicolas François
    --// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <[email protected]>
    --// SPDX-License-Identifier: BSD-3-Clause
    --
    --
    --#ifndef SHADOW_INCLUDE_LIB_ATOI_STR2I_STR2S_H_
    --#define SHADOW_INCLUDE_LIB_ATOI_STR2I_STR2S_H_
    --
    --
    --#include <config.h>
    --
    --#include <limits.h>
     -#include <stddef.h>
     -
    --#include "atoi/a2i/a2s.h"
    --#include "attr.h"
    +-#include "atoi/a2i/a2i.h"
    +-#include "typetraits.h"
     -
     -
    --ATTR_STRING(2) ATTR_ACCESS(write_only, 1)
    --inline int str2sh(short *restrict n, const char *restrict s);
    --ATTR_STRING(2) ATTR_ACCESS(write_only, 1)
    --inline int str2si(int *restrict n, const char *restrict s);
    --ATTR_STRING(2) ATTR_ACCESS(write_only, 1)
    --inline int str2sl(long *restrict n, const char *restrict s);
    --ATTR_STRING(2) ATTR_ACCESS(write_only, 1)
    --inline int str2sll(long long *restrict n, const char *restrict s);
    +-#define str2i(T, ...)  a2i(T, __VA_ARGS__, NULL, 0, type_min(T), type_max(T))
     -
    +-#define str2sh(...)    str2i(short, __VA_ARGS__)
    +-#define str2si(...)    str2i(int, __VA_ARGS__)
    +-#define str2sl(...)    str2i(long, __VA_ARGS__)
    +-#define str2sll(...)   str2i(long long, __VA_ARGS__)
     -
    --inline int
    --str2sh(short *restrict n, const char *restrict s)
    --{
    --  return a2sh(n, s, NULL, 0, SHRT_MIN, SHRT_MAX);
    --}
    --
    --
    --inline int
    --str2si(int *restrict n, const char *restrict s)
    --{
    --  return a2si(n, s, NULL, 0, INT_MIN, INT_MAX);
    --}
    --
    --
    --inline int
    --str2sl(long *restrict n, const char *restrict s)
    --{
    --  return a2sl(n, s, NULL, 0, LONG_MIN, LONG_MAX);
    --}
    --
    --
    --inline int
    --str2sll(long long *restrict n, const char *restrict s)
    --{
    --  return a2sll(n, s, NULL, 0, LLONG_MIN, LLONG_MAX);
    --}
    --
    --
    --#endif  // include guard
    -
    - ## lib/atoi/str2i/str2u.c (deleted) ##
    -@@
    --// SPDX-FileCopyrightText: 2007-2009, Nicolas François
    --// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <[email protected]>
    --// SPDX-License-Identifier: BSD-3-Clause
    --
    --
    --#include <config.h>
    --
    --#include "atoi/str2i/str2u.h"
    --
    --
    --extern inline int str2uh(unsigned short *restrict n, const char *restrict s);
    --extern inline int str2ui(unsigned int *restrict n, const char *restrict s);
    --extern inline int str2ul(unsigned long *restrict n, const char *restrict s);
    --extern inline int str2ull(unsigned long long *restrict n, const char *restrict s);
    -
    - ## lib/atoi/str2i/str2u.h (deleted) ##
    -@@
    --// SPDX-FileCopyrightText: 2007-2009, Nicolas François
    --// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <[email protected]>
    --// SPDX-License-Identifier: BSD-3-Clause
    --
    --
    --#ifndef SHADOW_INCLUDE_LIB_ATOI_STR2I_STR2U_H_
    --#define SHADOW_INCLUDE_LIB_ATOI_STR2I_STR2U_H_
    --
    --
    --#include <config.h>
    --
    --#include <limits.h>
    --#include <stddef.h>
    --
    --#include "atoi/a2i/a2u.h"
    --#include "attr.h"
    --
    --
    --ATTR_STRING(2) ATTR_ACCESS(write_only, 1)
    --inline int str2uh(unsigned short *restrict n, const char *restrict s);
    --ATTR_STRING(2) ATTR_ACCESS(write_only, 1)
    --inline int str2ui(unsigned int *restrict n, const char *restrict s);
    --ATTR_STRING(2) ATTR_ACCESS(write_only, 1)
    --inline int str2ul(unsigned long *restrict n, const char *restrict s);
    --ATTR_STRING(2) ATTR_ACCESS(write_only, 1)
    --inline int str2ull(unsigned long long *restrict n, const char *restrict s);
    --
    --
    --inline int
    --str2uh(unsigned short *restrict n, const char *restrict s)
    --{
    --  return a2uh(n, s, NULL, 0, 0, USHRT_MAX);
    --}
    --
    --
    --inline int
    --str2ui(unsigned int *restrict n, const char *restrict s)
    --{
    --  return a2ui(n, s, NULL, 0, 0, UINT_MAX);
    --}
    --
    --
    --inline int
    --str2ul(unsigned long *restrict n, const char *restrict s)
    --{
    --  return a2ul(n, s, NULL, 0, 0, ULONG_MAX);
    --}
    --
    --
    --inline int
    --str2ull(unsigned long long *restrict n, const char *restrict s)
    --{
    --  return a2ull(n, s, NULL, 0, 0, ULLONG_MAX);
    --}
    +-#define str2uh(...)    str2i(unsigned short, __VA_ARGS__)
    +-#define str2ui(...)    str2i(unsigned int, __VA_ARGS__)
    +-#define str2ul(...)    str2i(unsigned long, __VA_ARGS__)
    +-#define str2ull(...)   str2i(unsigned long long, __VA_ARGS__)
     -
     -
     -#endif  // include guard
    @@ lib/getdef.c
      
     -#include "atoi/a2i/a2s.h"
     -#include "atoi/a2i/a2u.h"
    --#include "atoi/str2i/str2u.h"
    +-#include "atoi/str2i.h"
     +#include <a2i/a2i/a2s.h>
     +#include <a2i/a2i/a2u.h>
    -+#include <a2i/str2i/str2u.h>
    ++#include <a2i/str2i.h>
     +
      #include "defines.h"
      #include "getdef.h"
    @@ lib/limits.c
      
     -#include "atoi/a2i/a2i.h"
     -#include "atoi/a2i/a2s.h"
    --#include "atoi/str2i/str2i.h"
    --#include "atoi/str2i/str2s.h"
    --#include "atoi/str2i/str2u.h"
    +-#include "atoi/str2i.h"
     +#include <a2i/a2i/a2i.h>
     +#include <a2i/a2i/a2s.h>
    -+#include <a2i/str2i/str2i.h>
    -+#include <a2i/str2i/str2s.h>
    -+#include <a2i/str2i/str2u.h>
    ++#include <a2i/str2i.h>
     +
      #include "string/memset/memzero.h"
      #include "string/strcmp/streq.h"
    @@ lib/sgetspent.c
      #include <string.h>
      
     -#include "atoi/a2i/a2s.h"
    --#include "atoi/str2i/str2u.h"
    +-#include "atoi/str2i.h"
     +#include <a2i/a2i/a2s.h>
    -+#include <a2i/str2i/str2u.h>
    ++#include <a2i/str2i.h>
     +
      #include "defines.h"
      #include "prototypes.h"
    @@ lib/strtoday.c
      
      #include <ctype.h>
      
    --#include "atoi/str2i/str2s.h"
    -+#include <a2i/str2i/str2s.h>
    +-#include "atoi/str2i.h"
    ++#include <a2i/str2i.h>
     +
      #include "getdate.h"
      #include "prototypes.h"
    @@ lib/subordinateio.c
      #include <fcntl.h>
      #include <string.h>
      
    -+#include <a2i/str2i/str2u.h>
    ++#include <a2i/str2i.h>
     +
      #include "alloc/malloc.h"
      #include "alloc/realloc.h"
      #include "alloc/reallocf.h"
    --#include "atoi/str2i/str2u.h"
    +-#include "atoi/str2i.h"
      #include "string/ctype/strisascii/strisdigit.h"
      #include "string/sprintf/snprintf.h"
      #include "string/strcmp/streq.h"
    @@ src/check_subid_range.c
      #include <sys/stat.h>
      #include <fcntl.h>
      
    -+#include <a2i/str2i/str2u.h>
    ++#include <a2i/str2i.h>
     +
      #include "atoi/getnum.h"
    --#include "atoi/str2i/str2u.h"
    +-#include "atoi/str2i.h"
      #include "defines.h"
      #include "idmapping.h"
      #include "prototypes.h"
    @@ src/chgpasswd.c
      #include <stdio.h>
      #include <stdlib.h>
      
    -+#include <a2i/str2i/str2s.h>
    ++#include <a2i/str2i.h>
     +
      #ifdef ACCT_TOOLS_SETUID
      #ifdef USE_PAM
      #include "pam_defs.h"
      #endif                            /* USE_PAM */
      #endif                            /* ACCT_TOOLS_SETUID */
    --#include "atoi/str2i/str2s.h"
    +-#include "atoi/str2i.h"
      #include "defines.h"
      #include "nscd.h"
      #include "sssd.h"
    @@ src/chpasswd.c
      #include <stdio.h>
      #include <stdlib.h>
      
    -+#include <a2i/str2i/str2s.h>
    ++#include <a2i/str2i.h>
     +
      #ifdef USE_PAM
      #include "pam_defs.h"
      #endif                            /* USE_PAM */
    --#include "atoi/str2i/str2s.h"
    +-#include "atoi/str2i.h"
      #include "defines.h"
      #include "nscd.h"
      #include "sssd.h"
    @@ src/faillog.c
      #include <time.h>
      #include <assert.h>
      
    --#include "atoi/str2i/str2s.h"
    -+#include <a2i/str2i/str2s.h>
    +-#include "atoi/str2i.h"
    ++#include <a2i/str2i.h>
     +
      #include "defines.h"
      #include "faillog.h"
    @@ src/free_subid_range.c
      #include <stdio.h>
      #include <unistd.h>
      
    --#include "atoi/str2i/str2u.h"
    -+#include <a2i/str2i/str2u.h>
    +-#include "atoi/str2i.h"
    ++#include <a2i/str2i.h>
     +
      #include "subid.h"
      #include "stdlib.h"
    @@ src/lastlog.c
      #include <net/if.h>
      #endif
      
    --#include "atoi/str2i/str2u.h"
    -+#include <a2i/str2i/str2u.h>
    +-#include "atoi/str2i.h"
    ++#include <a2i/str2i.h>
     +
      #include "defines.h"
      #include "prototypes.h"
    @@ src/new_subid_range.c
      #include <stdio.h>
      #include <unistd.h>
      
    --#include "atoi/str2i/str2u.h"
    -+#include <a2i/str2i/str2u.h>
    +-#include "atoi/str2i.h"
    ++#include <a2i/str2i.h>
     +
      #include "subid.h"
      #include "stdlib.h"
    @@ src/newusers.c
      #include <stdint.h>
      #include <string.h>
      
    -+#include <a2i/str2i/str2s.h>
    ++#include <a2i/str2i.h>
     +
      #include "alloc/reallocf.h"
      #include "atoi/getnum.h"
    --#include "atoi/str2i/str2s.h"
    +-#include "atoi/str2i.h"
      #ifdef ACCT_TOOLS_SETUID
      #ifdef USE_PAM
      #include "pam_defs.h"
2:  794617dd = 2:  ebccd917 Add liba2i to the build system
v2b
  • Rebase
$ git rd
1:  5b254775 ! 1:  e40a8e81 Depend on liba2i
    @@ lib/sgetspent.c
     
      ## lib/strtoday.c ##
     @@
    - 
    - #include <ctype.h>
    + #include <stddef.h>
    + #include <time.h>
      
     -#include "atoi/str2i.h"
     +#include <a2i/str2i.h>
     +
    - #include "getdate.h"
    + #include "defines.h"
      #include "prototypes.h"
    - #include "string/ctype/strisascii/strisdigit.h"
    + #include "string/strcmp/streq.h"
     
      ## lib/subordinateio.c ##
     @@
2:  ebccd917 = 2:  f4b2328f Add liba2i to the build system
v2c
  • Rebase
$ git rd
1:  e40a8e81 = 1:  3f996496 Depend on liba2i
2:  f4b2328f = 2:  4dd52989 Add liba2i to the build system
v2d
  • Rebase
$ git rd 
1:  3f996496 ! 1:  0d4b4426 Depend on liba2i
    @@ src/chage.c
     +#include <a2i/a2i/a2s.h>
     +
      #include "defines.h"
    + #include "fields.h"
      #include "prototypes.h"
    - #include "pwio.h"
     
      ## src/check_subid_range.c ##
     @@
2:  4dd52989 = 2:  3afa8280 Add liba2i to the build system
v2d
  • Rebase
$ git rd 
1:  0d4b4426 = 1:  55cd35af Depend on liba2i
2:  3afa8280 = 2:  9c7ced1c Add liba2i to the build system
v2e
  • Rebase
$ git rd 
1:  55cd35af = 1:  e20e8309 Depend on liba2i
2:  9c7ced1c = 2:  fd1e38a9 Add liba2i to the build system
v2f
  • Rebase
$ git rd 
1:  e20e8309 = 1:  53579f0e Depend on liba2i
2:  fd1e38a9 = 2:  415c95f8 Add liba2i to the build system

@ikerexxe
Copy link
Collaborator

Adding this dependency as optional would probably help to merge the changes more quickly. I say this mostly because this project is used in many distributions, and getting all of them to include this new dependency library is going to take a while.

@alejandro-colomar
Copy link
Collaborator Author

alejandro-colomar commented Jul 15, 2024

Adding this dependency as optional would probably help to merge the changes more quickly. I say this mostly because this project is used in many distributions, and getting all of them to include this new dependency library is going to take a while.

Hmmm, interesting. I'll consider changing it to be optional. Maybe we could have it optional for a few releases, and after that make it unconditional.

BTW, would you mind doing the packaging for Fedora/RHEL? :-)

@jubalh
Copy link
Member

jubalh commented Jul 15, 2024

I'll package it for openSUSE.
http://www.alejandro-colomar.es/src/alx/alx/lib/liba2i.git/ is the upstream repo, correct?

Do you publish a release tarball somewhere?
Is there a way to get notified about new tags/releases?

@alejandro-colomar
Copy link
Collaborator Author

alejandro-colomar commented Jul 15, 2024

I'll package it for openSUSE.

Lovely; thanks!! :-)

http://www.alejandro-colomar.es/src/alx/alx/lib/liba2i.git/ is the upstream repo, correct?

That's correct, although you will probably prefer to use https://git.kernel.org/pub/scm/libs/liba2i/liba2i.git/.

Both are supported, as far as I'm concerned, but <kernel.org> is more trusted by random users (and probably slightly more stable), I guess.

Do you publish a release tarball somewhere?

I do publish release tarballs here:
https://www.alejandro-colomar.es/share/dist/liba2i/

Since the current versions are 0.x, you'll find them under the 0/ subdir:
https://www.alejandro-colomar.es/share/dist/liba2i/0/

And have requested the creation of a liba2i/ subdir under
https://kernel.org/pub/linux/libs/,
but am still waiting for that. I guess now in the summer it may go slower, but probably in a month or so we'll have that site.

Is there a way to get notified about new tags/releases?

If you have a script that can watch a git repository for tags, look for tags of the form liba2i-*.

There's a mailing list:
[email protected]

I send an email to the list in every release. You could subscribe to it if you want. (But maybe it gets noisier, so you may want to not subscribe to yet another list.)

I can also CC you in those emails. I plan to write a file in the repository with a list of known downstream packages and their websites and maintainers, and CC everyone in that list (unless someone doesn't want to get notified) on every release.

Current links:

Website | Documentation | Contact | Archives | Bugs | Releases | Git | Contributing

@ikerexxe
Copy link
Collaborator

BTW, would you mind doing the packaging for Fedora/RHEL? :-)

Yes, I'll take care of it for Fedora, but it'll take me some time because the holiday period is approaching and I am closing a few things before I leave.

@alejandro-colomar
Copy link
Collaborator Author

BTW, would you mind doing the packaging for Fedora/RHEL? :-)

Yes, I'll take care of it for Fedora, but it'll take me some time because the holiday period is approaching and I am closing a few things before I leave.

Sure; no problem. I expect to need to fix a few things once some distros give feedback, so you'll have 0.11 when you come back, more polished.

@jubalh
Copy link
Member

jubalh commented Jul 15, 2024

I do publish release tarballs here: https://www.alejandro-colomar.es/share/dist/liba2i/

Don' you have LetsEncrypt or something? :)

@jubalh
Copy link
Member

jubalh commented Jul 15, 2024

Maybe we could have it optional for a few releases, and after that make it unconditional.

Not sure if some distros would want to add a new dependency to their ring0/base systems though.

@alejandro-colomar
Copy link
Collaborator Author

I do publish release tarballs here: https://www.alejandro-colomar.es/share/dist/liba2i/

Don' you have LetsEncrypt or something? :)

Nope, and don't want to: https://www.alejandro-colomar.es/ssl :)

You can access it via http, though.

@alejandro-colomar
Copy link
Collaborator Author

alejandro-colomar commented Jul 15, 2024

Maybe we could have it optional for a few releases, and after that make it unconditional.

Not sure if some distros would want to add a new dependency to their ring0/base systems though.

It's a quite small lib. I hope they don't mind so much. I was talking to Void Linux, and they were receptive. Let's see how others receive it.

@alejandro-colomar
Copy link
Collaborator Author

@jubalh

Currently, the build system of liba2i behaves like this:

make CFLAGS=...  # override default CFLAGS
make EXTRA_CFLAGS=...  # append to default CFLAGS

Is that behavior ok? Should I change that? What do downstream distros expect? How does one normally append to the default CFLAGS, and how does one normally overwrite the default CFLAGS?

@thesamesam
Copy link
Contributor

thesamesam commented Jul 17, 2024

Adding this dependency as optional would probably help to merge the changes more quickly. I say this mostly because this project is used in many distributions, and getting all of them to include this new dependency library is going to take a while.

I gave extensive feedback on it via email several months ago and I don't feel it was fully reflected upon. All the little things like not being able to use HTTPS and these silly quirks do not help. If it's on git.kernel.org, that helps now, I guess, although using it to "launder trust" is a bit meh.

I don't really want to see shadow adopt another library, especially one which has received little review. I also think the bar should be particularly high for a critical package like shadow. I don't see what arguments have been made in favour of the move, let alone strong ones.

I already think there's been an uncomfortably-large amount of churn in the input handling in shadow, often inventing new functions which.. are now being moved out into an external library anyway? Not only does this introduce opportunities for bugs to creep in, it makes it challenging for others to interact with the shadow codebase. In other communities, this is called NIH syndrome. There is an implicit cost to inventing your own functions, wrappers, and then a whole library.

Further, when looking at the implementations in liba2i, there's a not-insignificant amount of indirection which makes reading it challenging.

I don't have a vote, but if I did, I'd cast it against at present.

EDIT: And the various preliminary concerns I've had to point out again in void-linux/void-packages#51261 are not helping.

@jubalh
Copy link
Member

jubalh commented Jul 17, 2024

Nope, and don't want to: https://www.alejandro-colomar.es/ssl :)

That's unsual ;)

I gave a quick go at packaging and noticed that the build isn't straight forward. I wonder why no standard build system and default installation way was chosen.

It would be good to keep the "unusualness" to a minimum.

@alejandro-colomar
Copy link
Collaborator Author

alejandro-colomar commented Jul 17, 2024

@thesamesam

Hi Sam,

I gave extensive feedback on it via email several months ago and I don't feel it was fully reflected upon.

I have reflected upon what I've been able to.

Of course, the larger request of "please drop your entire build system and use my favourite one^W^W^W autotools", I haven't been able to address, because I do not know how to use autotools.

Even if you were so kind of providing patches for doing that change, I doubt I would be able to maintain my own project if the build system is autotools-based, so we'd have an important problem.

All the little things like not being able to use HTTPS and these silly quirks do not help.

It's my server; my rules. I'm sorry if we disagree on how my server should work.

If it's on git.kernel.org, that helps now, I guess,

Since we clearly have a disagreement on my server, I provide an impartial server for commodity.

I don't like github, nor any other paid services (github is paid; if we account for the data they steal from you legally, including source code to train their AI; it's more expensive that a paid git server (if those exist at all), actually).

I wouldn't mind using sourcehut, but I find cgit more comfortable.

Since I have a kernel.org account, and they allow me to do this, I provide it there.

although using it to "launder trust" is a bit meh.

I know you're worried after the XZ events. I don't know how I can make you trust me, since of course a malicious actor would also try the same goal. Also, since Jia Tan introduced his stuff via a build system, and I'm also doing unusual stuff with build systems, I guess it makes sense to be suspicious.

You can trace back all of my programming history back to when I was learning to program in StackOverflow. This is my account, if you want to investigate: https://stackoverflow.com/users/6872717/alx-recommends-codidact

That's my first online pressence programming, so if you search there for my questions in chronological order, it will hopefully make sense to you and be consistent.

I also have no problem to give you personal information about which school I went to in Spain, or where I live, if you want to do a full background check. If you need anything, please ask in private.

Also regarding trust:

I think my transparency in patches is actually unprecedented. I provide range diffs from the first iteration of a patch until it's merged, to let anyone reviewing see that I didn't introduce any sneaky changes during revision. Anyone is free to audit any of my PRs to find out any problems.

I also sign all of my commits, so that I can stand by them when I see them. That also adds some other feature: I can't repudiate a commit of mine (unless I repudiate my own signing key, via a revocation certificate, but that'd need to be justified). My reputation depends on my contributions, so I sign them (commits, and emails).

And after your feedback about it, I have increased my transparency even further, as you can see in the commit logs, when cherry-picking commits between projects. If you find anything I do to not be transparent enough, please let me know, and I'll try to improve it.

I don't really want to see shadow adopt another library, especially one which has received little review.

Feel free to review it as much as you want. I can wait 5 years if that's what you need. But you ghosted me some months ago, which I think is a bit rude from you.

I still understand it in context, because I could have just been the next Jia Tan trying to convince you of something, so I understand you not wanting to talk too much with someone asking for feedback about packaging his stuff in the middle of the XZ aftermath. But it still sucks.

Please let me know what problems you find in the project, and I will kindly try to solve them, if I can (this excludes, at the moment, switching to autotools, but I can try to make my GNUmakefile-based build system behave very much like any other standard build system).

Regarding the library, I provide a comprehensive set of tests, so if you try those tests, or can think of anything I'm missing in my tests, please say so.

I also think the bar should be particularly high for a critical package like shadow.

Agree.

I don't see what arguments have been made in favour of the move, let alone strong ones.

  • Comprehensive set of tests for the API (unlike in shadow, where I only added some basic tests; I don't feel like adding 10k lines of tests to shadow just for a small set of functions; and even then, I'm not sure how I could test some things with the current build system of shadow.git).
alx@debian:~/src/alx/liba2i/master$ find share/tests/ -type f | xargs wc -l | tail -n1
  9638 total
  • I've found bugs in other projects that would be fixed by using the same interfaces.
    This point, admittedly, is only justification for adding the library to distros for using in other projects, but not shadow, so we could keep shadow with its own implementation, and use liba2i for other projects. But doing so would have its own problems:

    • We'd need to backport any bug fixes applied to liba2i to shadow.
  • Once you finish auditing the liba2i project, you'll be able to use it in other projects.

So, I think it makes sense to add the dependency. I'm ready to wait as long as you need to audit the project.

I already think there's been an uncomfortably-large amount of churn in the input handling in shadow, often inventing new functions

That churn has found and fixed many bugs. Not only in shadow, BTW. I even found and fixed a bug in the design of strtoi(3) in NetBSD (and consequently in libbsd too) while designing and testing these APIs, which has fixed uncountable bugs in NetBSD and Debian, and probably also in other OSes.

I agree churn can be a bad thing, but in this case I think it's quite justified.

Moreover, in some cases I've taken almost a year, not just some months, to discuss and iterate over some of the changes. That has helped make them quite good before merging.

It's not at all like one has used sed(1) to do a global churny change possibly introducing several bugs in the process.

which.. are now being moved out into an external library anyway?

That sets in stone those APIs, which reduces the maintenance of that part. It means no more churn to those APIs, which should be a good thing?

Not only does this introduce opportunities for bugs to creep in,

Sure; but I have a comprehensive set of tests in that library, so it would be harder to introduce bugs there than in shadow. In fact, I had a bug in the shadow version, which had already been fixed in liba2i (see 63297e8).

it makes it challenging for others to interact with the shadow codebase.

Really? Do you find it easier to interact with strtol(3)? I don't even know how to use it correctly.

And clearly, the authors of shadow didn't either, from what we've seen.

I understand some friction when using a new API, because
you need to learn it, but in fact, shadow already had APIs like the ones provided in liba2i. For example, str2sl(3) is the same exact function that shadow has had for a very long time: it was called getlong() in shadow (with a trivial difference: getlong() reported errors with false, while str2sl(3) reports them with -1). I have only standardized the functions, gave them a consistent and unique name, and added macros that allowed to use these APIs with typedefs.

In other communities, this is called NIH syndrome.

I know that syndrome. But it is only a valid term when the API (or some usable replacement) is actually invented.

In this case, it was actually Not Invented Anywhere.

Let me list the invented list:

  • atol(3)
    UB Russian Roulette (this is actually fault of ISO C, not the API itself). I guess we can skip it.

  • strtol(3)
    It is unusable (directly). If you want an example, just look at shadow a few versions ago before I removed all of its uses. It had plenty of mishandled errors. The same in groff, where I've fixed plenty of mishandled errors (and I stopped fixing more in groff because it was a never-ending job; CC: @g-branden-robinson). I'm not the first one claiming that, and proof is that several projects came with their own "better" APIs wrapping strtol(3) (I'm referring to the BSDs).

  • OpenBSD's strtonum(3)
    It is a specialized function that is not a replacement for all strtol(3) uses; only some. We can discard it.

  • NetBSD's strtoi(3)
    This is actually a good interface. It fixes most of the problems in strtol(3). However, it's not good for typedefs, so I had to develop my own wrapper around it. a2i(3) is only a thin wrapper around strtoi(3). (I had to also provide strtoi(3) in my library, to not have libbsd as a dependency of liba2i.)

The fact that I provide strtoi(3) in my library (as a2i_strtoi()), is not a chance for adding bugs, but actually a bug fix. By writing that function, and developing comprehensive tests for it, and running those tests against both my implementation and libbsd's one, I found the design issue in NetBSD's strtoi(3).

alx@debian:~/src/bsd/netbsd/trunk$ git show f1987b28c87ee37690268b93ba1b11ed8d571305
commit f1987b28c87ee37690268b93ba1b11ed8d571305
Author: christos <[email protected]>
Date:   Sat Jan 20 16:13:39 2024 +0000

    PR/57828: Alejandro Colomar: Prioritize test for ERANGE before testing for
    fully consuming the string. Adjust strtonum(3) to behave as before. Document
    the order of the tests and sync the man pages (I should really autogenerate
    one of the two man pages...)

https://gnats.netbsd.org/cgi-bin/query-pr-single.pl?number=57828

There is an implicit cost to inventing your own functions,
wrappers,

And a reward. Do you suggest to continue using strtol(3)? If so, I'll let you suggest how it should be used correctly in shadow. I don't, myself.

and then a whole library.

I think the library is the smallest change. Yeah, it has the build system, and packaging cost, but then you get the reward in the form of being allowed to call those APIs from any other projects. Since the only dependency of liba2i is libc, it should be usable almost everywhere.

The library has the lowest cost, and the highest reward.

It was indeed when writing my library that the strtoi(3) bug was found. If I had kept it just as a shadow internal library, we would have never found that, and you could be arguing that it was indeed a NIH syndrome by not using libbsd's strtoi(3). Now we know that libbsd's strtoi(3) wasn't as good as it sounded (and anyway, it's not good for typedefs).

Further, when looking at the implementations in liba2i, there's a not-insignificant amount of indirection which makes reading it challenging.

I have significantly reduced that since you last looked at it, I think.

$ grepc a2s include/
include/a2i/a2i/a2s.h:#define a2s(TYPE, n, s, ...)                                                  \
(                                                                             \
	_Generic((void (*)(TYPE, typeof(s))) 0,                               \
		void (*)(signed char,        const char *):  a2shh_c,         \
		void (*)(signed char,        const void *):  a2shh_c,         \
		void (*)(signed char,        char *):        a2shh_nc,        \
		void (*)(signed char,        void *):        a2shh_nc,        \
		void (*)(short,              const char *):  a2sh_c,          \
		void (*)(short,              const void *):  a2sh_c,          \
		void (*)(short,              char *):        a2sh_nc,         \
		void (*)(short,              void *):        a2sh_nc,         \
		void (*)(int,                const char *):  a2si_c,          \
		void (*)(int,                const void *):  a2si_c,          \
		void (*)(int,                char *):        a2si_nc,         \
		void (*)(int,                void *):        a2si_nc,         \
		void (*)(long,               const char *):  a2sl_c,          \
		void (*)(long,               const void *):  a2sl_c,          \
		void (*)(long,               char *):        a2sl_nc,         \
		void (*)(long,               void *):        a2sl_nc,         \
		void (*)(long long,          const char *):  a2sll_c,         \
		void (*)(long long,          const void *):  a2sll_c,         \
		void (*)(long long,          char *):        a2sll_nc,        \
		void (*)(long long,          void *):        a2sll_nc         \
	)(n, s, __VA_ARGS__)                                                  \
)
$ grepc -B1 a2shh_c lib/src/
lib/src/a2i/a2i/a2s_.c-A2I_ATTR_ALIAS("a2shh_nc")
lib/src/a2i/a2i/a2s_.c:int a2shh_c(signed char *restrict n, const char *s,
    const char **a2i_nullable restrict endp, int base,
    signed char min, signed char max);
$ grepc -tfd a2shh_nc lib/src/
lib/src/a2i/a2i/a2s_.h:inline int
a2shh_nc(signed char *restrict n, char *s,
    char **a2i_nullable restrict endp, int base,
    signed char min, signed char max)
{
	int  status;

	*n = a2i_strtoi(s, endp, base, min, max, &status);
	if (status != 0)
		errno = status;

	return -!!status;
}

And then you could stop there, since a2i_strtoi() is exactly strtoi(3), which is a relatively well-known API. But if you want to check it in my own implementation:

$ grepc -tfd a2i_strtoi lib/src/
lib/src/a2i/strtoi/strtoi/strtoi.h:inline intmax_t
a2i_strtoi(char *s,
    char **a2i_nullable restrict endp, int base,
    intmax_t min, intmax_t max, int *a2i_nullable restrict status)
{
	int        errno_saved, st;
	char       *e;
	intmax_t   n;

	if (endp == NULL)
		endp = &e;
	if (status == NULL)
		status = &st;

	if (base != 0 && (base < 2 || base > 36)) {
		*status = EINVAL;
		return MAX(min, MIN(max, 0));
	}

	errno_saved = errno;
	errno = 0;

	n = strtoimax(s, endp, base);

	if (*endp == s)
		*status = ECANCELED;
	else if (errno == ERANGE || n < min || n > max)
		*status = ERANGE;
	else if (**endp != '\0')
		*status = ENOTSUP;
	else
		*status = 0;

	errno = errno_saved;

	return MAX(min, MIN(max, n));
}

I don't have a vote, but if I did, I'd cast it against at present.

Understood. If you are interested in making an effort in auditing and packaging liba2i, I'll respect that vote and wait for you to be happy with the library.

EDIT: And the various preliminary concerns I've had to point out again in void-linux/void-packages#51261 are not helping.

I'll try to reply to those there.

And some last words: after the XZ events, I've noticed a difference in your attitude to me, which I understand, but doesn't feel nice. I'd like to ask you to please be nice with me, as I never did anything to you (or if I did, I dind't notice, I'm sorry if I did). If you're skeptic about trusting me, that's ok, but please be nice, and let me know if there anything I can improve.

I'm certainly not going to be an expert in autotools tomorrow, though, so please don't ask me to be one.

Have a lovely day!
Alex

@alejandro-colomar
Copy link
Collaborator Author

Nope, and don't want to: https://www.alejandro-colomar.es/ssl :)

That's unsual ;)

I gave a quick go at packaging and noticed that the build isn't straight forward. I wonder why no standard build system and default installation way was chosen.

I just don't know what's "usual" behavior, especially, since it's not something written in any standard. When I learned to write Makefiles, I learned from the GNU make documentation. If something is not written there, I didn't learn it.

I'm now learning what distros expect, after talking to some packagers that gave me feedback about the library. I'm trying to adjust the build system to that feedback.

It would be good to keep the "unusualness" to a minimum.

That's my intention. In 1.0-rc2, liba2i is significantly more "usual". There are still a few bits that I haven't been able to fix, but now it should be more usable.

@hallyn
Copy link
Member

hallyn commented Jul 17, 2024

Do I understand correctly that liba2i is only licensed under LGPG 3.0-or-later ? I see the exception, but I'm not quite clear on whether that limits the license that can be applied to binaries and libraries using shadow.

@alejandro-colomar
Copy link
Collaborator Author

alejandro-colomar commented Jul 17, 2024

Do I understand correctly that liba2i is only licensed under LGPG 3.0-or-later ? I see the exception, but I'm not quite clear on whether that limits the license that can be applied to binaries and libraries using shadow.

The source code and build system is LGPL-3.0-only WITH LGPL-3.0-linking-exception:

alx@debian:~/src/alx/liba2i/contrib$ grep -rh SPDX-License include/ | sort | uniq -c
     11 // SPDX-License-Identifier: LGPL-3.0-only WITH LGPL-3.0-linking-exception
alx@debian:~/src/alx/liba2i/contrib$ grep -rh SPDX-License lib/src/ | sort | uniq -c
     28 // SPDX-License-Identifier: LGPL-3.0-only WITH LGPL-3.0-linking-exception
alx@debian:~/src/alx/liba2i/contrib$ grep -rh SPDX-License share/mk/ | sort | uniq -c
    154 # SPDX-License-Identifier: LGPL-3.0-only WITH LGPL-3.0-linking-exception

For some reason, I accidentally slipped a different license version in the tests (the -or-later one). I'll make that consistent.

alx@debian:~/src/alx/liba2i/contrib$ grep -rh SPDX-License share/tests/ | sort | uniq -c
     26 # SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception
     26 // SPDX-License-Identifier: LGPL-3.0-only WITH LGPL-3.0-linking-exception

And the man pages have the Linux-man-pages-copyleft license:

alx@debian:~/src/alx/liba2i/contrib$ grep -rh SPDX-License man/ | sort | uniq -c
      6 .\" SPDX-License-Identifier: Linux-man-pages-copyleft

So, you shouldn't have any license problems linking to it:

$ cat LICENSES/LGPL-3.0-linking-exception.txt 
As a special exception to the GNU Lesser General Public License version 3
("LGPL3"), the copyright holders of this Library give you permission to
convey to a third party a Combined Work that links statically or dynamically
to this Library without providing any Minimal Corresponding Source or
Minimal Application Code as set out in 4d or providing the installation
information set out in section 4e, provided that you comply with the other
provisions of LGPL3 and provided that you meet, for the Application the
terms and conditions of the license(s) which apply to the Application.

Except as stated in this special exception, the provisions of LGPL3 will
continue to comply in full to this Library. If you modify this Library, you
may apply this exception to your version of this Library, but you are not
obliged to do so. If you do not wish to do so, delete this exception
statement from your version. This exception does not (and cannot) modify any
license terms which apply to the Application, with which you must still
comply.

AFAIU, that exception means that you can link to it, and the LGPL won't eat your project. But IANAL.

@alejandro-colomar
Copy link
Collaborator Author

If anyone else can clarify if that license allows linking in shadow, please manifest yourselves. Cc: @g-branden-robinson

@hallyn
Copy link
Member

hallyn commented Jul 17, 2024 via email

@alejandro-colomar
Copy link
Collaborator Author

alejandro-colomar commented Jul 17, 2024

$ cat LICENSES/LGPL-3.0-linking-exception.txt As a special exception to the GNU Lesser General Public License version 3 ("LGPL3"), the copyright holders of this Library give you permission to convey to a third party a Combined Work that links statically or dynamically to this Library without providing any Minimal Corresponding Source or Minimal Application Code as set out in 4d or providing the installation information set out in section 4e, provided that you comply with the other provisions of LGPL3 and provided that you meet, for the Application the terms and conditions of the license(s) which apply to the Application.
What about 4a, c and d?

4a) I consider the relevant entry in the build system to be "prominent notice". Maybe we can have a one-or-two-liner comment above it to be more prominent, and more of a notice.

4c) It starts saying For a Combined Work that displays copyright notices during execution, . AFAIK, shadow utils don't display copyright notices during execution, so it wouldn't apply.

4d is explicitly excluded in the exception.

@alejandro-colomar
Copy link
Collaborator Author

4a) I consider the relevant entry in the build system to be "prominent notice". Maybe we can have a one-or-two-liner comment above it to be more prominent, and more of a notice.

And maybe add a one-liner to COPYING.

@alejandro-colomar
Copy link
Collaborator Author

alejandro-colomar commented Jul 17, 2024

$ cat LICENSES/LGPL-3.0-linking-exception.txt As a special exception to the GNU Lesser General Public License version 3 ("LGPL3"), the copyright holders of this Library give you permission to convey to a third party a Combined Work that links statically or dynamically to this Library without providing any Minimal Corresponding Source or Minimal Application Code as set out in 4d or providing the installation information set out in section 4e, provided that you comply with the other provisions of LGPL3 and provided that you meet, for the Application the terms and conditions of the license(s) which apply to the Application.
What about 4a, c and d?

For example, glibc is LGPL-2.1, which also has similar text in 6 (2nd paragraph). If shadow can link to glibc, it should be able to link to liba2i.

@hallyn
Copy link
Member

hallyn commented Jul 17, 2024 via email

@sgn
Copy link

sgn commented Jul 18, 2024

It's a quite small lib. I hope they don't mind so much. I was talking to Void Linux, and they were receptive. Let's see how others receive it.

I only tried to see how to build it, no where I said receptive or not :)

@alejandro-colomar alejandro-colomar force-pushed the liba2i branch 2 times, most recently from a856120 to 3c81aca Compare October 15, 2024 09:16
@alejandro-colomar alejandro-colomar force-pushed the liba2i branch 4 times, most recently from a640728 to 81d85e4 Compare December 6, 2024 11:58
@alejandro-colomar alejandro-colomar force-pushed the liba2i branch 2 times, most recently from 0bb5642 to 5db2252 Compare January 24, 2025 15:23
@alejandro-colomar alejandro-colomar force-pushed the liba2i branch 3 times, most recently from 2f9a41c to 29f2376 Compare February 16, 2025 22:56
@alejandro-colomar alejandro-colomar force-pushed the liba2i branch 4 times, most recently from ebccd91 to f4b2328 Compare June 2, 2025 09:10
@alejandro-colomar alejandro-colomar force-pushed the liba2i branch 4 times, most recently from 9c7ced1 to fd1e38a Compare June 7, 2025 17:46
Signed-off-by: Alejandro Colomar <[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.

6 participants