aboutsummaryrefslogtreecommitdiff
path: root/libsm
diff options
context:
space:
mode:
Diffstat (limited to 'libsm')
-rw-r--r--libsm/Makefile.m41
-rw-r--r--libsm/README4
-rw-r--r--libsm/b-strl.c2
-rw-r--r--libsm/exc.html2
-rw-r--r--libsm/heap.c2
-rw-r--r--libsm/io.html14
-rw-r--r--libsm/ldap.c110
-rw-r--r--libsm/lowercase.c35
-rw-r--r--libsm/mpeix.c2
-rw-r--r--libsm/notify.c68
-rw-r--r--libsm/notify.h111
-rw-r--r--libsm/rewind.c2
-rw-r--r--libsm/setvbuf.c3
-rw-r--r--libsm/stdio.c2
-rw-r--r--libsm/strcaseeq.c12
-rw-r--r--libsm/t-ixlen.c56
-rw-r--r--libsm/t-notify.c141
-rw-r--r--libsm/t-qic.c16
-rw-r--r--libsm/t-streq.c42
-rwxr-xr-xlibsm/t-streq.sh19
-rw-r--r--libsm/test.c2
-rw-r--r--libsm/util.c10
-rw-r--r--libsm/vfprintf.c16
-rw-r--r--libsm/vfscanf.c2
24 files changed, 526 insertions, 148 deletions
diff --git a/libsm/Makefile.m4 b/libsm/Makefile.m4
index 173427970f62..a7c624068c0f 100644
--- a/libsm/Makefile.m4
+++ b/libsm/Makefile.m4
@@ -45,7 +45,6 @@ dnl ? smcheck(`t-isprint', `compile-run')
smcheck(`t-ixlen', `compile')
smcheck(`t-ixlen.sh', `run')
smcheck(`t-streq', `compile')
-smcheck(`t-utf8_valid', `compile')
smcheck(`t-streq.sh', `run')
divert(bldTARGETS_SECTION)
divert(0)
diff --git a/libsm/README b/libsm/README
index 37345e05b111..7a1bfba181e7 100644
--- a/libsm/README
+++ b/libsm/README
@@ -34,6 +34,7 @@ The programs are:
b-strcmp.c tests strcasecmp().
+
+----------------------+
| CONFIGURATION MACROS |
+----------------------+
@@ -106,9 +107,6 @@ SM_CONF_SEM
SM_CONF_BROKEN_STRTOD
Set to 1 if your strtod() does not work properly.
-SM_CONF_GETOPT
- Set to 1 if your operating system does not include getopt(3).
-
SM_CONF_LDAP_INITIALIZE
Set to 1 if your LDAP client libraries include ldap_initialize(3).
diff --git a/libsm/b-strl.c b/libsm/b-strl.c
index 1e0e770cf62b..b70b28245759 100644
--- a/libsm/b-strl.c
+++ b/libsm/b-strl.c
@@ -101,7 +101,7 @@ main(argc, argv)
** the copy.
*/
(void) strlcpy(source,
- " This is the longer string that will be used for catenation and copying for the the performace testing. The longer the string being catenated or copied the greater the difference in measureable performance\n",
+ " This is the longer string that will be used for catenation and copying for the the performance testing. The longer the string being catenated or copied the greater the difference in measureable performance\n",
SRC_SIZE - 1);
/* Run-time comments to the user */
diff --git a/libsm/exc.html b/libsm/exc.html
index d9b7941f65c5..45253928faa2 100644
--- a/libsm/exc.html
+++ b/libsm/exc.html
@@ -350,7 +350,7 @@ of type SM_EXC_TYPE_T, which has the following members:
<dt><tt>"E"</tt>
<dd>The function could not complete its task because an error occurred.
(It might be useful to define subclasses of this category,
- in which case our taxonony becomes a tree, and 'F' becomes
+ in which case our taxonomy becomes a tree, and 'F' becomes
a subclass of 'E'.)
<dt><tt>"J"</tt>
diff --git a/libsm/heap.c b/libsm/heap.c
index 330739acef22..1192c461308a 100644
--- a/libsm/heap.c
+++ b/libsm/heap.c
@@ -242,7 +242,7 @@ size_t SmHeapMaxTotal = 0;
*/
SM_DEBUG_T SmHeapLimit = SM_DEBUG_INITIALIZER("sm_heap_limit",
- "@(#)$Debug: sm_heap_limit - max # of bytes permitted in heap $");
+ "@(#)$Debug: sm_heap_limit - max # of bytes permitted in heap $");
/*
** This is the data structure that keeps track of all currently
diff --git a/libsm/io.html b/libsm/io.html
index 3efdfebb58c7..97b7cbf37787 100644
--- a/libsm/io.html
+++ b/libsm/io.html
@@ -481,7 +481,7 @@ close file descriptors 0, 1 and 2).
Thus <tt>sm_io_open()</tt> should
never be called: the named file pointers should be used directly.
Calls to <b>stdio</b> are safe to make when using these three<b>sm_io</b>
-file pointers though no code is shared between the two libaries.
+file pointers though no code is shared between the two libraries.
However, the input and output between <i>sm_io</i> and <i>stdio</i> is
coordinated for these three file pointers: <i>smiostdin</i>,
<i>smiostdout</i> and <i>smiostderr</i> are layered on-top-of
@@ -574,10 +574,12 @@ SM_FILE_T. The file pointer content (internal structure members) of an active
file should only be set and observed with the "info" functions.
The two exceptions to the above statement are the structure members
<i>cookie</i> and <i>ival</i>. <i>Cookie</i> is of type <tt>void *</tt>
-while <i>ival</i> is of type <tt>int</tt>. These two structure members exist
-specificly for your created file type to use. The <i>sm_io</i> functions
-will not change or set these two structure members; only specific file type
-will change or set these variables.
+while <i>ival</i> is of type <tt>int</tt>.
+These two structure members exist specifically
+for your created file type to use.
+The <i>sm_io</i> functions
+will not change or set these two structure members;
+only specific file type will change or set these variables.
</p>
<p>
For maintaining information privately about status for a file type the
@@ -598,7 +600,7 @@ For the <i>cookie</i> to be passed to all members of a function type
cleanly the location of the cookie must assigned during
the call to open. The file type functions should not attempt to
maintain the <i>cookie</i> internally since the file type may have
-serveral instances (file pointers).
+several instances (file pointers).
</p>
<p>
The SM_FILE_T's member <i>ival</i> may be used in a manner similar to
diff --git a/libsm/ldap.c b/libsm/ldap.c
index a78ab4daa567..cf5aa18ab9d7 100644
--- a/libsm/ldap.c
+++ b/libsm/ldap.c
@@ -36,6 +36,8 @@ SM_DEBUG_T SmLDAPTrace = SM_DEBUG_INITIALIZER("sm_trace_ldap",
static bool sm_ldap_has_objectclass __P((SM_LDAP_STRUCT *, LDAPMessage *, char *));
static SM_LDAP_RECURSE_ENTRY *sm_ldap_add_recurse __P((SM_LDAP_RECURSE_LIST **, char *, int, SM_RPOOL_T *));
+static char *sm_ldap_geterror __P((LDAP *));
+
/*
** SM_LDAP_CLEAR -- set default values for SM_LDAP_STRUCT
**
@@ -49,10 +51,10 @@ static SM_LDAP_RECURSE_ENTRY *sm_ldap_add_recurse __P((SM_LDAP_RECURSE_LIST **,
# if _FFR_LDAP_VERSION
# if defined(LDAP_VERSION_MAX) && _FFR_LDAP_VERSION > LDAP_VERSION_MAX
-# ERROR "_FFR_LDAP_VERSION > LDAP_VERSION_MAX"
+# error "_FFR_LDAP_VERSION > LDAP_VERSION_MAX"
# endif
# if defined(LDAP_VERSION_MIN) && _FFR_LDAP_VERSION < LDAP_VERSION_MIN
-# ERROR "_FFR_LDAP_VERSION < LDAP_VERSION_MAX"
+# error "_FFR_LDAP_VERSION < LDAP_VERSION_MAX"
# endif
# define SM_LDAP_VERSION_DEFAULT _FFR_LDAP_VERSION
# else /* _FFR_LDAP_VERSION */
@@ -79,6 +81,9 @@ sm_ldap_clear(lmap)
lmap->ldap_options = 0;
# endif
lmap->ldap_attrsep = '\0';
+# if LDAP_NETWORK_TIMEOUT
+ lmap->ldap_networktmo = 0;
+# endif
lmap->ldap_binddn = NULL;
lmap->ldap_secret = NULL;
lmap->ldap_method = LDAP_AUTH_SIMPLE;
@@ -229,6 +234,23 @@ sm_ldap_setopts(ld, lmap)
# ifdef LDAP_OPT_RESTART
ldap_set_option(ld, LDAP_OPT_RESTART, LDAP_OPT_ON);
# endif
+# if _FFR_TESTS
+ if (sm_debug_active(&SmLDAPTrace, 101))
+ {
+ char *cert;
+ char buf[PATH_MAX];
+
+ cert = getcwd(buf, sizeof(buf));
+ if (NULL != cert)
+ {
+ int r;
+
+ (void) sm_strlcat(buf, "/ldaps.pem", sizeof(buf));
+ r = ldap_set_option(ld, LDAP_OPT_X_TLS_CACERTFILE, cert);
+ sm_dprintf("LDAP_OPT_X_TLS_CACERTFILE(%s)=%d\n", cert, r);
+ }
+ }
+# endif /* _FFR_TESTS */
# else /* USE_LDAP_SET_OPTION */
/* From here on in we can use ldap internal timelimits */
@@ -305,6 +327,7 @@ sm_ldap_start(name, lmap)
{
int save_errno = 0;
char *id;
+ char *errmsg;
# if !USE_LDAP_INIT || !LDAP_NETWORK_TIMEOUT
SM_EVENT *ev = NULL;
# endif
@@ -312,6 +335,7 @@ sm_ldap_start(name, lmap)
struct timeval tmo;
int msgid, err, r;
+ errmsg = NULL;
if (sm_debug_active(&SmLDAPTrace, 2))
sm_dprintf("ldapmap_start(%s)\n", name == NULL ? "" : name);
@@ -439,37 +463,66 @@ sm_ldap_start(name, lmap)
lmap->ldap_method);
save_errno = errno;
if (sm_debug_active(&SmLDAPTrace, 9))
- sm_dprintf("ldap_bind(%s)=%d, errno=%d, tmo=%ld\n",
+ {
+ errmsg = sm_ldap_geterror(ld);
+ sm_dprintf("ldap_bind(%s)=%d, errno=%d, ldaperr=%d, ld_error=%s, tmo=%lld\n",
lmap->ldap_uri, msgid, save_errno,
- (long) tmo.tv_sec);
+ sm_ldap_geterrno(ld), errmsg, (long long) tmo.tv_sec);
+ if (NULL != errmsg)
+ {
+ ldap_memfree(errmsg);
+ errmsg = NULL;
+ }
+ }
if (-1 == msgid)
{
r = -1;
+ err = sm_ldap_geterrno(ld);
+ if (LDAP_SUCCESS != err)
+ save_errno = err + E_LDAPBASE;
goto fail;
}
errno = 0;
r = ldap_result(ld, msgid, LDAP_MSG_ALL,
tmo.tv_sec == 0 ? NULL : &(tmo), &(lmap->ldap_res));
+ save_errno = errno;
if (sm_debug_active(&SmLDAPTrace, 9))
- sm_dprintf("ldap_result(%s)=%d, errno=%d\n", lmap->ldap_uri, r, errno);
+ {
+ errmsg = sm_ldap_geterror(ld);
+ sm_dprintf("ldap_result(%s)=%d, errno=%d, ldaperr=%d, ld_error=%s\n",
+ lmap->ldap_uri, r, errno,
+ sm_ldap_geterrno(ld), errmsg);
+ if (NULL != errmsg)
+ {
+ ldap_memfree(errmsg);
+ errmsg = NULL;
+ }
+ }
if (-1 == r)
+ {
+ err = sm_ldap_geterrno(ld);
+ if (LDAP_SUCCESS != err)
+ save_errno = err + E_LDAPBASE;
goto fail;
+ }
if (0 == r)
{
save_errno = ETIMEDOUT;
r = -1;
goto fail;
}
- r = ldap_parse_result(ld, lmap->ldap_res, &err, NULL, NULL, NULL, NULL,
- 1);
+ r = ldap_parse_result(ld, lmap->ldap_res, &err, NULL, &errmsg, NULL,
+ NULL, 1);
+ save_errno = errno;
if (sm_debug_active(&SmLDAPTrace, 9))
- sm_dprintf("ldap_parse_result(%s)=%d, err=%d\n", lmap->ldap_uri, r, err);
+ sm_dprintf("ldap_parse_result(%s)=%d, err=%d, errmsg=%s\n",
+ lmap->ldap_uri, r, err, errmsg);
if (r != LDAP_SUCCESS)
goto fail;
if (err != LDAP_SUCCESS)
{
- r = -1;
+ r = err;
goto fail;
}
@@ -487,12 +540,22 @@ sm_ldap_start(name, lmap)
errno = save_errno;
else
errno = r + E_LDAPBASE;
+ if (NULL != errmsg)
+ {
+ ldap_memfree(errmsg);
+ errmsg = NULL;
+ }
return false;
}
/* Save PID to make sure only this PID closes the LDAP connection */
lmap->ldap_pid = getpid();
lmap->ldap_ld = ld;
+ if (NULL != errmsg)
+ {
+ ldap_memfree(errmsg);
+ errmsg = NULL;
+ }
return true;
}
@@ -536,7 +599,7 @@ sm_ldap_search_m(lmap, argv)
if (lmap->ldap_multi_args)
{
# if SM_LDAP_ARGS < 10
-# ERROR _SM_LDAP_ARGS must be 10
+# error _SM_LDAP_ARGS must be 10
# endif
if (q[1] == 's')
key = argv[0];
@@ -1559,7 +1622,6 @@ sm_ldap_results(lmap, msgid, flags, delim, rpool, result,
**
** Returns:
** None.
-**
*/
void
@@ -1574,6 +1636,7 @@ sm_ldap_close(lmap)
lmap->ldap_ld = NULL;
lmap->ldap_pid = 0;
}
+
/*
** SM_LDAP_GETERRNO -- get ldap errno value
**
@@ -1582,7 +1645,6 @@ sm_ldap_close(lmap)
**
** Returns:
** LDAP errno.
-**
*/
int
@@ -1614,4 +1676,28 @@ sm_ldap_geterrno(ld)
# endif /* defined(LDAP_VERSION_MAX) && LDAP_VERSION_MAX >= 3 */
return err;
}
+
+/*
+** SM_LDAP_GETERROR -- get ldap error value
+**
+** Parameters:
+** ld -- LDAP session handle
+**
+** Returns:
+** LDAP error
+*/
+
+static char *
+sm_ldap_geterror(ld)
+ LDAP *ld;
+{
+ char *error = NULL;
+
+# if defined(LDAP_OPT_DIAGNOSTIC_MESSAGE)
+ (void) ldap_get_option(ld, LDAP_OPT_DIAGNOSTIC_MESSAGE, &error);
+# endif
+ return error;
+}
+
+
#endif /* LDAPMAP */
diff --git a/libsm/lowercase.c b/libsm/lowercase.c
index 8448eee5ad40..430d2ac79039 100644
--- a/libsm/lowercase.c
+++ b/libsm/lowercase.c
@@ -15,10 +15,11 @@
#include <sm/string.h>
#include <sm/heap.h>
#if USE_EAI
-# include <sm/ixlen.h>
+# include <sm/limits.h>
# include <unicode/ucasemap.h>
# include <unicode/ustring.h>
# include <unicode/uchar.h>
+# include <sm/ixlen.h>
/*
** ASCIISTR -- check whether a string is printable ASCII
@@ -42,6 +43,38 @@ asciistr(str)
str++;
return ch == '\0';
}
+
+/*
+** ASCIINSTR -- check whether a string is printable ASCII up to len
+**
+** Parameters:
+** str -- string
+** len -- length to check
+**
+** Returns:
+** TRUE iff printable ASCII
+*/
+
+bool
+asciinstr(str, len)
+ const char *str;
+ size_t len;
+{
+ unsigned char ch;
+ int n;
+
+ if (str == NULL)
+ return true;
+ SM_REQUIRE(len < INT_MAX);
+ n = 0;
+ while (n < len && (ch = (unsigned char)*str) != '\0'
+ && ch >= 32 && ch < 127)
+ {
+ n++;
+ str++;
+ }
+ return n == len || ch == '\0';
+}
#endif /* USE_EAI */
/*
diff --git a/libsm/mpeix.c b/libsm/mpeix.c
index 3fe361709f69..e80f23d510a7 100644
--- a/libsm/mpeix.c
+++ b/libsm/mpeix.c
@@ -314,7 +314,7 @@ sendmail_mpe_getpwnam(name)
/*
** SENDMAIL_MPE_GETPWUID -- shadow function for getpwuid()
**
-** Initializes the uninitalized fields in the passwd struct.
+** Initializes the uninitialized fields in the passwd struct.
**
** Parameters:
** uid -- uid to obtain passwd data for
diff --git a/libsm/notify.c b/libsm/notify.c
index 4ed3fd7f2bd1..8b35d9e3839a 100644
--- a/libsm/notify.c
+++ b/libsm/notify.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016 Proofpoint, Inc. and its suppliers.
+ * Copyright (c) 2020 Proofpoint, Inc. and its suppliers.
* All rights reserved.
*
* By using this file, you agree to the terms and conditions set
@@ -10,11 +10,12 @@
#include <sm/gen.h>
-#if _FFR_DMTRIGGER
+#if _FFR_DMTRIGGER && _FFR_NOTIFY < 2
#include <sm/conf.h> /* FDSET_CAST */
#include <sm/fdset.h>
#include <sm/assert.h>
#include <sm/notify.h>
+#include "notify.h"
#include <sm/time.h>
#include <sm/string.h>
@@ -28,12 +29,6 @@
#include <fcntl.h>
#include <string.h> /* for memset() */
-#if SM_NOTIFY_DEBUG
-#define SM_DBG(p) fprintf p
-#else
-#define SM_DBG(p)
-#endif
-
static int Notifypipe[2];
#define NotifyRDpipe Notifypipe[0]
#define NotifyWRpipe Notifypipe[1]
@@ -129,9 +124,6 @@ sm_notify_stop(owner, flags)
** <0: -errno
*/
-#define MAX_NETSTR 1024
-#define NETSTRPRE 5
-
int
sm_notify_snd(buf, buflen)
char *buf;
@@ -152,7 +144,7 @@ sm_notify_snd(buf, buflen)
len = sm_snprintf(netstr, sizeof(netstr), "%04d:%s,", (int)buflen, buf);
r = write(NotifyWRpipe, netstr, len);
save_errno = errno;
- SM_DBG((stderr, "write=%d, fd=%d, e=%d\n", r, NotifyWRpipe, save_errno));
+ SM_DBG((stderr, "pid=%ld, write=%d, fd=%d, e=%d\n", (long)getpid(), r, NotifyWRpipe, save_errno));
return r >= 0 ? 0 : -save_errno;
}
@@ -165,7 +157,8 @@ sm_notify_snd(buf, buflen)
** tmo -- timeout (micro seconds)
**
** Returns:
-** 0: success
+** 0: EOF (XXX need to provide info about client)
+** >0: length of received data
** <0: -errno
*/
@@ -186,55 +179,14 @@ sm_notify_rcv(buf, buflen, tmo)
return -EINVAL;
FD_ZERO(&readfds);
SM_FD_SET(NotifyRDpipe, &readfds);
- if (tmo < 0)
- tval = NULL;
- else
- {
- timeout.tv_sec = (long) (tmo / SM_MICROS);
- timeout.tv_usec = tmo % SM_MICROS;
- tval = &timeout;
- }
+ SM_MICROS2TVAL(tmo, tval, timeout);
do {
r = select(NotifyRDpipe + 1, FDSET_CAST &readfds, NULL, NULL, tval);
save_errno = errno;
- SM_DBG((stderr, "select=%d, fd=%d, e=%d\n", r, NotifyRDpipe, save_errno));
+ SM_DBG((stderr, "pid=%ld, select=%d, fd=%d, e=%d\n", (long)getpid(), r, NotifyRDpipe, save_errno));
} while (r < 0 && save_errno == EINTR);
- if (r <= 0)
- {
- SM_DBG((stderr, "select=%d, e=%d\n", r, save_errno));
- return -ETIMEDOUT;
- }
-
- /* bogus... need to check again? */
- if (!FD_ISSET(NotifyRDpipe, &readfds))
- return -ETIMEDOUT;
-
- r = read(NotifyRDpipe, buf, NETSTRPRE);
- if (NETSTRPRE != r)
- return -1; /* ??? */
-
- if (sm_io_sscanf(buf, "%4u:", &len) != 1)
- return -EINVAL; /* ??? */
- if (len >= MAX_NETSTR)
- return -E2BIG; /* ??? */
- if (len >= buflen - 1)
- return -E2BIG; /* ??? */
- if (len <= 0)
- return -EINVAL; /* ??? */
- r = read(NotifyRDpipe, buf, len + 1);
- save_errno = errno;
- SM_DBG((stderr, "read=%d, e=%d\n", r, save_errno));
- if (r == 0)
- return -1; /* ??? */
- if (r < 0)
- return -save_errno;
- if (len + 1 != r)
- return -1; /* ??? */
- if (buf[len] != ',')
- return -EINVAL; /* ??? */
- buf[len] = '\0';
- return r;
+ RDNETSTR(r, NotifyRDpipe, (void)0);
}
-#endif /* _FFR_DMTRIGGER */
+#endif /* _FFR_DMTRIGGER && _FFR_NOTIFY < 2 */
diff --git a/libsm/notify.h b/libsm/notify.h
new file mode 100644
index 000000000000..a314e75a4bb2
--- /dev/null
+++ b/libsm/notify.h
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2021 Proofpoint, Inc. and its suppliers.
+ * All rights reserved.
+ *
+ * By using this file, you agree to the terms and conditions set
+ * forth in the LICENSE file which can be found at the top level of
+ * the sendmail distribution.
+ */
+
+#ifndef LIBSM_NOTIFY_H
+#define LIBSM_NOTIFY_H
+
+#if SM_NOTIFY_DEBUG
+#define SM_DBG(p) fprintf p
+#else
+#define SM_DBG(p)
+#endif
+
+/* microseconds */
+#define SM_MICROS 1000000L
+
+#define SM_MICROS2TVAL(tmo, tval, timeout) \
+ do \
+ { \
+ if (tmo < 0) \
+ tval = NULL; \
+ else \
+ { \
+ timeout.tv_sec = (long) (tmo / SM_MICROS); \
+ timeout.tv_usec = tmo % SM_MICROS; \
+ tval = &timeout; \
+ } \
+ } while (0)
+
+#define MAX_NETSTR 1024
+#define NETSTRPRE 5
+
+/* flow through code, be careful how to use! */
+#define RDNETSTR(rc, fd, SM_NOTIFY_EOF) \
+ if ((rc) <= 0) \
+ { \
+ SM_DBG((stderr, "pid=%ld, select=%d, e=%d\n", (long)getpid(), (rc), save_errno)); \
+ return -ETIMEDOUT; \
+ } \
+ \
+ /* bogus... need to check again? */ \
+ if (!FD_ISSET(fd, &readfds)) \
+ { \
+ SM_DBG((stderr, "pid=%ld, fd=%d, isset=false\n", (long)getpid(), fd)); \
+ return -ETIMEDOUT; \
+ } \
+ r = read(fd, buf, NETSTRPRE); \
+ if (0 == r) \
+ { \
+ SM_DBG((stderr, "pid=%ld, fd=%d, read1=EOF, e=%d\n", (long)getpid(), fd, errno)); \
+ SM_NOTIFY_EOF; \
+ return r; \
+ } \
+ if (NETSTRPRE != r) \
+ { \
+ SM_DBG((stderr, "pid=%ld, fd=%d, read1=%d, e=%d\n", (long)getpid(), fd, r, errno)); \
+ return -1; /* ??? */ \
+ } \
+ \
+ if (sm_io_sscanf(buf, "%4u:", &len) != 1) \
+ { \
+ SM_DBG((stderr, "pid=%ld, scanf, e=%d\n", (long)getpid(), errno)); \
+ return -EINVAL; /* ??? */ \
+ } \
+ if (len >= MAX_NETSTR) \
+ { \
+ SM_DBG((stderr, "pid=%ld, 1: len=%d\n", (long)getpid(), len)); \
+ return -E2BIG; /* ??? */ \
+ } \
+ if (len >= buflen - 1) \
+ { \
+ SM_DBG((stderr, "pid=%ld, 2: len=%d\n", (long)getpid(), len)); \
+ return -E2BIG; /* ??? */ \
+ } \
+ if (len <= 0) \
+ { \
+ SM_DBG((stderr, "pid=%ld, 3: len=%d\n", (long)getpid(), len)); \
+ return -EINVAL; /* ??? */ \
+ } \
+ r = read(fd, buf, len + 1); \
+ save_errno = errno; \
+ SM_DBG((stderr, "pid=%ld, fd=%d, read=%d, len=%d, e=%d\n", (long)getpid(), fd, r, len+1, save_errno)); \
+ if (r == 0) \
+ { \
+ SM_DBG((stderr, "pid=%ld, fd=%d, read2=%d, e=%d\n", (long)getpid(), fd, r, save_errno)); \
+ return -1; /* ??? */ \
+ } \
+ if (r < 0) \
+ { \
+ SM_DBG((stderr, "pid=%ld, fd=%d, read3=%d, e=%d\n", (long)getpid(), fd, r, save_errno)); \
+ return -save_errno; \
+ } \
+ if (len + 1 != r) \
+ { \
+ SM_DBG((stderr, "pid=%ld, fd=%d, read4=%d, len=%d\n", (long)getpid(), fd, r, len)); \
+ return -1; /* ??? */ \
+ } \
+ if (buf[len] != ',') \
+ { \
+ SM_DBG((stderr, "pid=%ld, fd=%d, read5=%d, f=%d\n", (long)getpid(), fd, r, buf[len])); \
+ return -EINVAL; /* ??? */ \
+ } \
+ buf[len] = '\0'; \
+ return r
+
+#endif /* ! LIBSM_MSG_H */
diff --git a/libsm/rewind.c b/libsm/rewind.c
index 2bbb26d2a9a9..bfbbbab4dd80 100644
--- a/libsm/rewind.c
+++ b/libsm/rewind.c
@@ -25,7 +25,7 @@ SM_RCSID("@(#)$Id: rewind.c,v 1.19 2013-11-22 20:51:43 ca Exp $")
** Seeks the file to the beginning and clears any outstanding errors.
**
** Parameters:
-** fp -- the flie pointer for rewind
+** fp -- the file pointer for rewind
** timeout -- time to complete the rewind
**
** Returns:
diff --git a/libsm/setvbuf.c b/libsm/setvbuf.c
index 85b178b60c85..092a1fc93fb0 100644
--- a/libsm/setvbuf.c
+++ b/libsm/setvbuf.c
@@ -17,6 +17,7 @@ SM_RCSID("@(#)$Id: setvbuf.c,v 1.33 2013-11-22 20:51:43 ca Exp $")
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
+#include <sm/limits.h>
#include <sm/io.h>
#include <sm/heap.h>
#include <sm/assert.h>
@@ -67,7 +68,7 @@ sm_io_setvbuf(fp, timeout, buf, mode, size)
if (mode != SM_IO_NBF)
if ((mode != SM_IO_FBF && mode != SM_IO_LBF &&
- mode != SM_IO_NOW) || (int) size < 0)
+ mode != SM_IO_NOW) || size > INT_MAX)
return SM_IO_EOF;
/*
diff --git a/libsm/stdio.c b/libsm/stdio.c
index 7e045fa56fec..2cdb0dfedbcf 100644
--- a/libsm/stdio.c
+++ b/libsm/stdio.c
@@ -162,7 +162,7 @@ sm_stdwrite(fp, buf, n)
/*
** SM_STDSEEK -- set the file offset position
**
-** Parmeters:
+** Parameters:
** fp -- file pointer to position
** offset -- how far to position from "base" (set by 'whence')
** whence -- indicates where the "base" of the 'offset' to start
diff --git a/libsm/strcaseeq.c b/libsm/strcaseeq.c
index c252d85e53e0..ec1a942e3c65 100644
--- a/libsm/strcaseeq.c
+++ b/libsm/strcaseeq.c
@@ -17,7 +17,7 @@
#include <sm/ixlen.h>
/*
-** SM_STRCASEEQ -- are two strings equal (case-insenstive)?
+** SM_STRCASEEQ -- are two strings equal (case-insensitive)?
**
** Parameters:
** s1 -- string
@@ -63,7 +63,7 @@ sm_strcaseeq(s1, s2)
}
/*
-** SM_STRNCASEEQ -- are two strings (up to a length) equal (case-insenstive)?
+** SM_STRNCASEEQ -- are two strings (up to a length) equal (case-insensitive)?
**
** Parameters:
** s1 -- string
@@ -86,13 +86,13 @@ sm_strncaseeq(s1, s2, n)
if (0 == n)
return true;
- if (asciistr(s1))
+ if (asciinstr(s1, n))
{
- if (!asciistr(s2))
+ if (!asciinstr(s2, n))
return false;
return (sm_strncasecmp(s1, s2, n) == 0);
}
- if (asciistr(s2))
+ if (asciinstr(s2, n))
return false;
l1 = sm_lowercase(s1);
if (l1 != s1)
@@ -104,7 +104,7 @@ sm_strncaseeq(s1, s2, n)
f1 = NULL;
l2 = sm_lowercase(s2);
- while (*l1 == *l2 && '\0' != *l1 && n-- > 0)
+ while (*l1 == *l2 && '\0' != *l1 && --n > 0)
l1++, l2++;
same = *l1 == *l2;
diff --git a/libsm/t-ixlen.c b/libsm/t-ixlen.c
index cc29431725a8..cdf96f04c4ad 100644
--- a/libsm/t-ixlen.c
+++ b/libsm/t-ixlen.c
@@ -19,6 +19,7 @@ SM_IDSTR(id, "@(#)$Id: t-qic.c,v 1.10 2013-11-22 20:51:43 ca Exp $")
#if _FFR_8BITENVADDR
extern bool SmTestVerbose;
+static int Verbose = 0;
static void
chkilenx(str, len)
@@ -30,11 +31,42 @@ chkilenx(str, len)
xlen = ilenx(str);
SM_TEST(len == xlen);
if (len != xlen)
- fprintf(stderr, "str=\"%s\", len=%d, excpected=%d\n",
+ fprintf(stderr, "str=\"%s\", len=%d, expected=%d\n",
str, xlen, len);
}
static void
+chkilen(str)
+ char *str;
+{
+ char *obp;
+ int outlen, leni, lenx, ilen;
+ char line_in[1024];
+ XLENDECL
+
+ lenx = strlen(str);
+ sm_strlcpy(line_in, str, sizeof(line_in));
+ obp = quote_internal_chars(str, NULL, &outlen, NULL);
+ leni = strlen(obp);
+
+ for (ilen = 0; *obp != '\0'; obp++, ilen++)
+ {
+ XLEN(*obp);
+ }
+ if (Verbose)
+ fprintf(stderr, "str=\"%s\", ilen=%d, xlen=%d\n",
+ str, ilen, xlen);
+ SM_TEST(ilen == leni);
+ if (ilen != leni)
+ fprintf(stderr, "str=\"%s\", ilen=%d, leni=%d\n",
+ str, ilen, leni);
+ SM_TEST(xlen == lenx);
+ if (xlen != lenx)
+ fprintf(stderr, "str=\"%s\", xlen=%d, lenx=%d\n",
+ str, xlen, lenx);
+}
+
+static void
chkxleni(str, len)
const char *str;
int len;
@@ -44,7 +76,7 @@ chkxleni(str, len)
ilen = xleni(str);
SM_TEST(len == ilen);
if (len != ilen)
- fprintf(stderr, "str=\"%s\", len=%d, excpected=%d\n",
+ fprintf(stderr, "str=\"%s\", len=%d, expected=%d\n",
str, ilen, len);
}
@@ -64,18 +96,26 @@ main(argc, argv)
char *argv[];
{
int o, len;
- bool x;
+ bool x, both;
char line[1024];
- x = false;
- while ((o = getopt(argc, argv, "x")) != -1)
+ x = both = false;
+ while ((o = getopt(argc, argv, "bxV")) != -1)
{
switch ((char) o)
{
+ case 'b':
+ both = true;
+ break;
+
case 'x':
x = true;
break;
+ case 'V':
+ Verbose++;
+ break;
+
default:
usage(argv[0]);
exit(1);
@@ -84,6 +124,12 @@ main(argc, argv)
sm_test_begin(argc, argv, "test ilenx");
+ if (both)
+ {
+ while (fscanf(stdin, "%s\n", line) == 1)
+ chkilen(line);
+ return sm_test_end();
+ }
while (fscanf(stdin, "%d:%s\n", &len, line) == 2)
{
if (x)
diff --git a/libsm/t-notify.c b/libsm/t-notify.c
index f8da3a2fb9bc..c0a090470dc3 100644
--- a/libsm/t-notify.c
+++ b/libsm/t-notify.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016 Proofpoint, Inc. and its suppliers.
+ * Copyright (c) 2020 Proofpoint, Inc. and its suppliers.
* All rights reserved.
*
* By using this file, you agree to the terms and conditions set
@@ -8,7 +8,6 @@
*/
#include <sm/gen.h>
-
#include <stdio.h>
#if _FFR_DMTRIGGER || _FFR_NOTIFY
@@ -20,23 +19,32 @@
# include <sm/test.h>
# include <sm/notify.h>
# include <sm/conf.h>
+# include "notify.h"
+
+static int Verbose = 0;
+#define MAX_CHILDREN 256
+#define MAX_MSGS 1024
+static pid_t pids[MAX_CHILDREN];
+static char msgs[MAX_CHILDREN][MAX_MSGS];
/*
-** NOTIFY_WR -- test of notify feature
+** NOTIFY_WR -- test of notify write feature
**
** Parameters:
** pid -- pid of process
+** nmsgs -- number of messages to write
**
** Returns:
-** 0 on success
+** >=0 on success
** < 0 on failure
*/
static int
-notify_wr(pid)
+notify_wr(pid, nmsgs)
pid_t pid;
+ int nmsgs;
{
- int r;
+ int r, i;
size_t len;
char buf[64];
#define TSTSTR "qf0001"
@@ -48,16 +56,38 @@ notify_wr(pid)
return -1;
}
- len = sm_snprintf(buf, sizeof(buf), "%s-%ld", TSTSTR, (long) pid);
- r = sm_notify_snd(buf, len);
- SM_TEST(r >= 0);
+ for (i = 0; i < nmsgs; i++)
+ {
+ len = sm_snprintf(buf, sizeof(buf), "%s-%ld_%d", TSTSTR,
+ (long) pid, i);
+ r = sm_notify_snd(buf, len);
+ SM_TEST(r >= 0);
+ }
return r;
}
+static int
+validpid(nproc, cpid)
+ int nproc;
+ pid_t cpid;
+{
+ int i;
+
+ for (i = 0; i < nproc; i++)
+ if (cpid == pids[i])
+ return i;
+ if (Verbose > 0)
+ fprintf(stderr, "pid=%ld not found, nproc=%d\n",
+ (long) cpid, nproc);
+ return -1;
+}
+
/*
-** NOTIFY_RD -- test of notify feature
+** NOTIFY_RD -- test of notify read feature
**
** Parameters:
+** nproc -- number of processes started
+** nmsgs -- number of messages to read for each process
**
** Returns:
** 0 on success
@@ -65,11 +95,13 @@ notify_wr(pid)
*/
static int
-notify_rd(nproc)
+notify_rd(nproc, nmsgs)
int nproc;
+ int nmsgs;
{
- int r, i;
- char buf[64];
+ int r, i, pidx;
+ long cpid;
+ char buf[64], *p;
#define TSTSTR "qf0001"
r = sm_notify_start(true, 0);
@@ -79,21 +111,52 @@ notify_rd(nproc)
return -1;
}
- for (i = 0; i < nproc; i++)
+ for (i = 0; i < nmsgs * nproc; i++)
{
- r = sm_notify_rcv(buf, sizeof(buf), 5 * SM_MICROS);
- SM_TEST(r >= 0);
+ do
+ {
+ r = sm_notify_rcv(buf, sizeof(buf), 5 * SM_MICROS);
+ SM_TEST(r >= 0);
+ } while (0 == r);
if (r < 0)
{
- fprintf(stderr, "rcv=%d\n", r);
+ fprintf(stderr, "pid=%ld, rcv=%d, i=%d\n",
+ (long)getpid(), r, i);
return r;
}
if (r > 0 && r < sizeof(buf))
buf[r] = '\0';
buf[sizeof(buf) - 1] = '\0';
+
+ if (Verbose > 0)
+ fprintf(stderr, "pid=%ld, buf=\"%s\", i=%d\n",
+ (long)getpid(), buf, i);
+
SM_TEST(strncmp(buf, TSTSTR, sizeof(TSTSTR) - 1) == 0);
SM_TEST(r > sizeof(TSTSTR));
- fprintf(stderr, "buf=\"%s\"\n", buf);
+
+ r = sscanf(buf + sizeof(TSTSTR), "%ld", &cpid);
+ SM_TEST(1 == r);
+ pidx = validpid(nproc, (pid_t)cpid);
+ SM_TEST(pidx >= 0);
+ SM_TEST(pidx < nproc);
+
+ p = strchr(buf, '_');
+ SM_TEST(NULL != p);
+ if (NULL != p && pidx < nproc && pidx >= 0)
+ {
+ int n;
+
+ r = sscanf(p + 1, "%d", &n);
+ SM_TEST(1 == r);
+ SM_TEST(n >= 0);
+ SM_TEST(n < nmsgs);
+ if (1 == r && n < nmsgs && n >= 0)
+ {
+ SM_TEST('\0' == msgs[pidx][n]);
+ msgs[pidx][n] = 'f';
+ }
+ }
}
return 0;
}
@@ -106,27 +169,53 @@ main(argc, argv)
int i;
int r = 0;
int nproc = 1;
+ int nmsgs = 1;
pid_t pid;
-# define OPTIONS "p:"
+# define OPTIONS "n:p:V"
while ((i = getopt(argc, argv, OPTIONS)) != -1)
{
switch ((char) i)
{
+ case 'n':
+ nmsgs = atoi(optarg);
+ if (nmsgs < 1)
+ {
+ errno = EINVAL;
+ fprintf(stderr, "-%c: must be >0\n", (char) i);
+ return 1;
+ }
+ if (nmsgs >= MAX_MSGS)
+ {
+ errno = EINVAL;
+ fprintf(stderr, "-%c: must be <%d\n", (char) i, MAX_MSGS);
+ return 1;
+ }
+ break;
case 'p':
nproc = atoi(optarg);
if (nproc < 1)
{
errno = EINVAL;
- perror("-p: must be >0\n");
- return r;
+ fprintf(stderr, "-%c: must be >0\n", (char) i);
+ return 1;
}
+ if (nproc >= MAX_CHILDREN)
+ {
+ errno = EINVAL;
+ fprintf(stderr, "-%c: must be <%d\n", (char) i, MAX_CHILDREN);
+ return 1;
+ }
+ break;
+ case 'V':
+ ++Verbose;
break;
default:
break;
}
}
+ memset(msgs, '\0', sizeof(msgs));
sm_test_begin(argc, argv, "test notify");
r = sm_notify_init(0);
SM_TEST(r >= 0);
@@ -149,12 +238,14 @@ main(argc, argv)
{
/* give the parent the chance to set up data */
sleep(1);
- r = notify_wr(getpid());
+ r = notify_wr(getpid(), nmsgs);
break;
}
+ if (pid > 0)
+ pids[i] = pid;
}
if (pid > 0)
- r = notify_rd(nproc);
+ r = notify_rd(nproc, nmsgs);
SM_TEST(r >= 0);
return sm_test_end();
}
@@ -164,7 +255,7 @@ main(argc, argv)
int argc;
char *argv[];
{
- printf("SKIPPED: no _FFR_DMTRIGGER\n");
+ printf("SKIPPED: no _FFR_DMTRIGGER || _FFR_NOTIFY\n");
return 0;
}
-#endif /* _FFR_DMTRIGGER */
+#endif /* _FFR_DMTRIGGER || _FFR_NOTIFY */
diff --git a/libsm/t-qic.c b/libsm/t-qic.c
index fea88c95b43d..d2b73a5cb3d6 100644
--- a/libsm/t-qic.c
+++ b/libsm/t-qic.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006 Proofpoint, Inc. and its suppliers.
+ * Copyright (c) 2006, 2023 Proofpoint, Inc. and its suppliers.
* All rights reserved.
*
* By using this file, you agree to the terms and conditions set
@@ -19,7 +19,6 @@ SM_IDSTR(id, "@(#)$Id: t-qic.c,v 1.10 2013-11-22 20:51:43 ca Exp $")
extern bool SmTestVerbose;
-
void
show_diff(s1, s2)
const char *s1;
@@ -107,6 +106,8 @@ main(argc, argv)
int i, los, cmp, mode;
sm_qic_T inout[] = {
{ "", "", 0 }
+ , { "\t", "\t", 0 }
+ , { "\tuser", "\tuser", 0 }
, { "abcdef", "abcdef", 0 }
, { "01234567890123456789", "01234567890123456789", 0 }
, { "\\", "\\", 0 }
@@ -242,5 +243,16 @@ main(argc, argv)
}
}
+ los = -1;
+ obp = quote_internal_chars(NULL, NULL, &los, NULL);
+ SM_TEST(NULL == obp);
+ SM_TEST(-1 == los);
+
+ sm_strlcpy(line_in, "nothing", sizeof(line_in));
+ los = -123;
+ obp = quote_internal_chars(line_in, NULL, &los, NULL);
+ SM_TEST(NULL != obp);
+ SM_TEST(los > 0);
+
return sm_test_end();
}
diff --git a/libsm/t-streq.c b/libsm/t-streq.c
index a193eca5f02d..c6f369be0945 100644
--- a/libsm/t-streq.c
+++ b/libsm/t-streq.c
@@ -17,7 +17,6 @@ SM_IDSTR(id, "@(#)$Id: t-qic.c,v 1.10 2013-11-22 20:51:43 ca Exp $")
#include <sm/ixlen.h>
#include <sm/test.h>
-#if _FFR_8BITENVADDR
extern bool SmTestVerbose;
static int
@@ -37,6 +36,32 @@ usage(prg)
fprintf(stderr, "options:\n");
}
+static void
+hack(str)
+ char *str;
+{
+ char c;
+
+ /* replace just one \x char */
+ while ((c = *str++) != '\0')
+ {
+ if (c != '\\')
+ continue;
+ c = *str;
+ switch (c)
+ {
+ case 'n': c ='\n'; break;
+ case 't': c ='\t'; break;
+ case 'r': c ='\r'; break;
+ /* case 'X': c ='\X'; break; */
+ default: c ='\0'; break;
+ }
+ *(str - 1) = c;
+ *str = '\0';
+ break;
+ }
+}
+
int
main(argc, argv)
int argc;
@@ -61,17 +86,14 @@ main(argc, argv)
while (fscanf(stdin, "%d:%s\n", &len, s1) == 2 &&
fscanf(stdin, "%d:%s\n", &o,s2) == 2)
{
+ int r;
+
+ hack(s1);
+ hack(s2);
SM_TEST(tstrncaseeq(s1, s2, len) == o);
+ if ((r = tstrncaseeq(s1, s2, len)) != o)
+ fprintf(stderr, "\"%s\"\n\"%s\"\n%d!=%d\n", s1, s2, o, r);
}
return sm_test_end();
}
-#else /* _FFR_8BITENVADDR */
-int
-main(argc, argv)
- int argc;
- char *argv[];
-{
- return 0;
-}
-#endif /* _FFR_8BITENVADDR */
diff --git a/libsm/t-streq.sh b/libsm/t-streq.sh
index 7797e3f848f0..d798cf315010 100755
--- a/libsm/t-streq.sh
+++ b/libsm/t-streq.sh
@@ -12,6 +12,13 @@
PRG=./t-streq
R=0
+# format:
+# two lines:
+# len:string1
+# result:string2
+# result:
+# 1: equal
+# 0: not equal
${PRG} <<EOF
0:a
1:X
@@ -23,6 +30,18 @@ ${PRG} <<EOF
1:AC
2:aB
0:AC
+2:aB\n
+1:AB
+20:xabcez@uabcey.por.az\n
+1:xabcez@uabcey.por.az
+7:ünchen\n
+1:ünchen
+7:ünchen\n
+0:üncheX
+22:iseadmin@somest.sld.br>\n
+1:iseadmin@somest.sld.br
+22:iseadmin@somest.sld.br
+1:iseadmin@somest.sld.br>\n
EOF
R=$?
diff --git a/libsm/test.c b/libsm/test.c
index 0aee5ae4aa6b..d955909c101f 100644
--- a/libsm/test.c
+++ b/libsm/test.c
@@ -96,7 +96,7 @@ sm_test_begin(argc, argv, testname)
** SM_TEST -- single test.
**
** Parameters:
-** success -- did test succeeed?
+** success -- did test succeed?
** expr -- expression that has been evaluated.
** filename -- guess...
** lineno -- line number.
diff --git a/libsm/util.c b/libsm/util.c
index dd8bf88f79e5..2610a3dfe553 100644
--- a/libsm/util.c
+++ b/libsm/util.c
@@ -132,10 +132,11 @@ str2prt(s)
** ibp -- a pointer to the string to translate [x]
** obp -- a pointer to an output buffer [i][m:A]
** bsp -- pointer to the length of the output buffer
+** rpool -- rpool for allocations
**
** Returns:
-** A possibly new bp (if the buffer needed to grow); if
-** it is different, *bsp will updated to the size of
+** A possibly new obp (if the buffer needed to grow);
+** if it is different, *bsp will updated to the size of
** the new buffer and the caller is responsible for
** freeing the memory.
*/
@@ -171,7 +172,12 @@ quote_internal_chars
int bufused, olen;
bool buffer_same, needs_quoting;
+ if (NULL == ibp)
+ return NULL;
buffer_same = ibp == obp;
+ SM_REQUIRE(NULL != bsp);
+ if (NULL == obp)
+ *bsp = 0;
needs_quoting = false;
/* determine length of output string (starts at 1 for trailing '\0') */
diff --git a/libsm/vfprintf.c b/libsm/vfprintf.c
index e4e69edbe419..b335c4b795ed 100644
--- a/libsm/vfprintf.c
+++ b/libsm/vfprintf.c
@@ -74,7 +74,7 @@ sm_print(fp, timeout, uio)
}
/*
-** SM_BPRINTF -- allow formating to an unbuffered file.
+** SM_BPRINTF -- allow formatting to an unbuffered file.
**
** Helper function for `fprintf to unbuffered unix file': creates a
** temporary buffer (via a "fake" file pointer).
@@ -84,11 +84,11 @@ sm_print(fp, timeout, uio)
** Parameters:
** fp -- the file to send the o/p to
** fmt -- format instructions for the o/p
-** ap -- vectors of data units used for formating
+** ap -- vectors of data units used for formatting
**
** Results:
** Failure: SM_IO_EOF and errno set
-** Success: number of data units used in the formating
+** Success: number of data units used in the formatting
**
** Side effects:
** formatted o/p can be SM_IO_BUFSIZ length maximum
@@ -156,13 +156,13 @@ sm_bprintf(fp, fmt, ap)
#define FPT 0x100 /* Floating point number */
/*
-** SM_IO_VFPRINTF -- performs actual formating for o/p
+** SM_IO_VFPRINTF -- performs actual formatting for o/p
**
** Parameters:
** fp -- file pointer for o/p
** timeout -- time to complete the print
-** fmt0 -- formating directives
-** ap -- vectors with data units for formating
+** fmt0 -- formatting directives
+** ap -- vectors with data units for formatting
**
** Results:
** Success: number of data units used for formatting
@@ -816,8 +816,8 @@ error:
** It will be replaced with a malloc-ed one if it overflows.
**
** Parameters:
-** fmt0 -- formating directives
-** ap -- vector list of data unit for formating consumption
+** fmt0 -- formatting directives
+** ap -- vector list of data unit for formatting consumption
** argtable -- an indexable table (returned) of 'ap'
**
** Results:
diff --git a/libsm/vfscanf.c b/libsm/vfscanf.c
index c367f7682e37..e1b7830b49d5 100644
--- a/libsm/vfscanf.c
+++ b/libsm/vfscanf.c
@@ -655,7 +655,7 @@ literal:
c = *fp->f_p;
/*
- ** This code mimicks the integer conversion
+ ** This code mimics the integer conversion
** code, but is much simpler.
*/