summaryrefslogtreecommitdiffstats
path: root/contrib/sendmail/libsm
diff options
context:
space:
mode:
authorgshapiro <gshapiro@FreeBSD.org>2005-06-07 04:14:59 +0000
committergshapiro <gshapiro@FreeBSD.org>2005-06-07 04:14:59 +0000
commit125167ce170bc64dfd57dd664a3bdde3580230c7 (patch)
tree2c6b97c0946a681c9c1031038e89d298a645c754 /contrib/sendmail/libsm
parent476228659f3f241ba8be1db8703b14c5f443082a (diff)
downloadFreeBSD-src-125167ce170bc64dfd57dd664a3bdde3580230c7.zip
FreeBSD-src-125167ce170bc64dfd57dd664a3bdde3580230c7.tar.gz
Import sendmail 8.13.4
Diffstat (limited to 'contrib/sendmail/libsm')
-rw-r--r--contrib/sendmail/libsm/Makefile.m48
-rw-r--r--contrib/sendmail/libsm/ldap.c30
-rw-r--r--contrib/sendmail/libsm/sem.c201
-rw-r--r--contrib/sendmail/libsm/shm.c38
-rw-r--r--contrib/sendmail/libsm/t-sem.c344
-rw-r--r--contrib/sendmail/libsm/t-shm.c10
6 files changed, 609 insertions, 22 deletions
diff --git a/contrib/sendmail/libsm/Makefile.m4 b/contrib/sendmail/libsm/Makefile.m4
index 8896a1e..a77afea 100644
--- a/contrib/sendmail/libsm/Makefile.m4
+++ b/contrib/sendmail/libsm/Makefile.m4
@@ -1,13 +1,13 @@
-dnl $Id: Makefile.m4,v 1.67 2004/08/20 20:42:14 ca Exp $
+dnl $Id: Makefile.m4,v 1.68 2005/02/17 23:34:25 ca Exp $
define(`confREQUIRE_LIBUNIX')
include(confBUILDTOOLSDIR`/M4/switch.m4')
define(`confREQUIRE_LIBSM', `true')
PREPENDDEF(`confENVDEF', `confMAPDEF')
bldPRODUCT_START(`library', `libsm')
-define(`bldSOURCES', ` assert.c debug.c errstring.c exc.c heap.c match.c rpool.c strdup.c strerror.c strl.c clrerr.c fclose.c feof.c ferror.c fflush.c fget.c fpos.c findfp.c flags.c fopen.c fprintf.c fpurge.c fput.c fread.c fscanf.c fseek.c fvwrite.c fwalk.c fwrite.c get.c makebuf.c put.c refill.c rewind.c setvbuf.c smstdio.c snprintf.c sscanf.c stdio.c strio.c ungetc.c vasprintf.c vfprintf.c vfscanf.c vprintf.c vsnprintf.c wbuf.c wsetup.c string.c stringf.c xtrap.c strto.c test.c path.c strcasecmp.c strrevcmp.c signal.c clock.c config.c shm.c mbdb.c strexit.c cf.c ldap.c niprop.c mpeix.c ')
+define(`bldSOURCES', ` assert.c debug.c errstring.c exc.c heap.c match.c rpool.c strdup.c strerror.c strl.c clrerr.c fclose.c feof.c ferror.c fflush.c fget.c fpos.c findfp.c flags.c fopen.c fprintf.c fpurge.c fput.c fread.c fscanf.c fseek.c fvwrite.c fwalk.c fwrite.c get.c makebuf.c put.c refill.c rewind.c setvbuf.c smstdio.c snprintf.c sscanf.c stdio.c strio.c ungetc.c vasprintf.c vfprintf.c vfscanf.c vprintf.c vsnprintf.c wbuf.c wsetup.c string.c stringf.c xtrap.c strto.c test.c path.c strcasecmp.c strrevcmp.c signal.c clock.c config.c shm.c sem.c mbdb.c strexit.c cf.c ldap.c niprop.c mpeix.c ')
bldPRODUCT_END
-dnl sem.c msg.c
+dnl msg.c
dnl syslogio.c
include(confBUILDTOOLSDIR`/M4/'bldM4_TYPE_DIR`/sm-test.m4')
@@ -27,7 +27,7 @@ smtest(`t-path', `run')
smtest(`t-float', `run')
smtest(`t-scanf', `run')
smtest(`t-shm', `run')
-dnl smtest(`t-sem', `run')
+smtest(`t-sem', `run')
dnl smtest(`t-msg', `run')
smtest(`t-cf')
smtest(`b-strcmp')
diff --git a/contrib/sendmail/libsm/ldap.c b/contrib/sendmail/libsm/ldap.c
index 5e6557d..3af7ffa 100644
--- a/contrib/sendmail/libsm/ldap.c
+++ b/contrib/sendmail/libsm/ldap.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001-2004 Sendmail, Inc. and its suppliers.
+ * Copyright (c) 2001-2005 Sendmail, Inc. and its suppliers.
* All rights reserved.
*
* By using this file, you agree to the terms and conditions set
@@ -8,7 +8,7 @@
*/
#include <sm/gen.h>
-SM_RCSID("@(#)$Id: ldap.c,v 1.60 2004/08/03 20:42:21 ca Exp $")
+SM_RCSID("@(#)$Id: ldap.c,v 1.62 2005/02/24 00:30:01 ca Exp $")
#if LDAPMAP
# include <sys/types.h>
@@ -589,7 +589,9 @@ sm_ldap_results(lmap, msgid, flags, delim, rpool, result,
LDAPMessage *entry;
/* If we don't want multiple values and we have one, break */
- if ((char) delim == '\0' && *result != NULL)
+ if ((char) delim == '\0' &&
+ !bitset(SM_LDAP_SINGLEMATCH, flags) &&
+ *result != NULL)
break;
/* Cycle through all entries */
@@ -767,19 +769,17 @@ sm_ldap_results(lmap, msgid, flags, delim, rpool, result,
if (*result != NULL)
{
/* already have a value */
+ if (bitset(SM_LDAP_SINGLEMATCH,
+ flags))
+ {
+ /* only wanted one match */
+ SM_LDAP_ERROR_CLEANUP();
+ errno = ENOENT;
+ return EX_NOTFOUND;
+ }
break;
}
- if (bitset(SM_LDAP_SINGLEMATCH,
- flags) &&
- *result != NULL)
- {
- /* only wanted one match */
- SM_LDAP_ERROR_CLEANUP();
- errno = ENOENT;
- return EX_NOTFOUND;
- }
-
if (lmap->ldap_attrsonly == LDAPMAP_TRUE)
{
*result = sm_rpool_strdup_x(rpool,
@@ -990,7 +990,9 @@ sm_ldap_results(lmap, msgid, flags, delim, rpool, result,
}
/* We don't want multiple values and we have one */
- if ((char) delim == '\0' && *result != NULL)
+ if ((char) delim == '\0' &&
+ !bitset(SM_LDAP_SINGLEMATCH, flags) &&
+ *result != NULL)
break;
}
save_errno = sm_ldap_geterrno(lmap->ldap_ld);
diff --git a/contrib/sendmail/libsm/sem.c b/contrib/sendmail/libsm/sem.c
new file mode 100644
index 0000000..a429cf4
--- /dev/null
+++ b/contrib/sendmail/libsm/sem.c
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 2000-2001, 2005 Sendmail, 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.
+ */
+
+#include <sm/gen.h>
+SM_RCSID("@(#)$Id: sem.c,v 1.12 2005/03/25 21:27:02 ca Exp $")
+
+#if SM_CONF_SEM
+# include <stdlib.h>
+# include <unistd.h>
+# include <sm/sem.h>
+# include <sm/heap.h>
+
+/*
+** SM_SEM_START -- initialize semaphores
+**
+** Parameters:
+** key -- key for semaphores.
+** nsem -- number of semaphores.
+** semflg -- flag for semget(), if 0, use a default.
+** owner -- create semaphores.
+**
+** Returns:
+** id for semaphores.
+** < 0 on failure.
+*/
+
+int
+sm_sem_start(key, nsem, semflg, owner)
+ key_t key;
+ int nsem;
+ int semflg;
+ bool owner;
+{
+ int semid, i;
+ unsigned short *semvals;
+
+ semvals = NULL;
+ if (semflg == 0)
+ semflg = (SEM_A|SEM_R)|((SEM_A|SEM_R) >> 3);
+ if (owner)
+ semflg |= IPC_CREAT|IPC_EXCL;
+ semid = semget(key, nsem, semflg);
+ if (semid < 0)
+ goto error;
+
+ if (owner)
+ {
+ union semun semarg;
+
+ semvals = (unsigned short *) sm_malloc(nsem * sizeof semvals);
+ if (semvals == NULL)
+ goto error;
+ semarg.array = semvals;
+
+ /* initialize semaphore values to be available */
+ for (i = 0; i < nsem; i++)
+ semvals[i] = 1;
+ if (semctl(semid, 0, SETALL, semarg) < 0)
+ goto error;
+ }
+ return semid;
+
+error:
+ if (semvals != NULL)
+ sm_free(semvals);
+ if (semid >= 0)
+ sm_sem_stop(semid);
+ return -1;
+}
+
+/*
+** SM_SEM_STOP -- stop using semaphores.
+**
+** Parameters:
+** semid -- id for semaphores.
+**
+** Returns:
+** 0 on success.
+** < 0 on failure.
+*/
+
+int
+sm_sem_stop(semid)
+ int semid;
+{
+ return semctl(semid, 0, IPC_RMID, NULL);
+}
+
+/*
+** SM_SEM_ACQ -- acquire semaphore.
+**
+** Parameters:
+** semid -- id for semaphores.
+** semnum -- number of semaphore.
+** timeout -- how long to wait for operation to succeed.
+**
+** Returns:
+** 0 on success.
+** < 0 on failure.
+*/
+
+int
+sm_sem_acq(semid, semnum, timeout)
+ int semid;
+ int semnum;
+ int timeout;
+{
+ int r;
+ struct sembuf semops[1];
+
+ semops[0].sem_num = semnum;
+ semops[0].sem_op = -1;
+ semops[0].sem_flg = SEM_UNDO |
+ (timeout != SM_TIME_FOREVER ? 0 : IPC_NOWAIT);
+ if (timeout == SM_TIME_IMMEDIATE || timeout == SM_TIME_FOREVER)
+ return semop(semid, semops, 1);
+ do
+ {
+ r = semop(semid, semops, 1);
+ if (r == 0)
+ return r;
+ sleep(1);
+ --timeout;
+ } while (timeout > 0);
+ return r;
+}
+
+/*
+** SM_SEM_REL -- release semaphore.
+**
+** Parameters:
+** semid -- id for semaphores.
+** semnum -- number of semaphore.
+** timeout -- how long to wait for operation to succeed.
+**
+** Returns:
+** 0 on success.
+** < 0 on failure.
+*/
+
+int
+sm_sem_rel(semid, semnum, timeout)
+ int semid;
+ int semnum;
+ int timeout;
+{
+ int r;
+ struct sembuf semops[1];
+
+#if PARANOID
+ /* XXX should we check whether the value is already 0 ? */
+ SM_REQUIRE(sm_get_sem(semid, semnum) > 0);
+#endif /* PARANOID */
+
+ semops[0].sem_num = semnum;
+ semops[0].sem_op = 1;
+ semops[0].sem_flg = SEM_UNDO |
+ (timeout != SM_TIME_FOREVER ? 0 : IPC_NOWAIT);
+ if (timeout == SM_TIME_IMMEDIATE || timeout == SM_TIME_FOREVER)
+ return semop(semid, semops, 1);
+ do
+ {
+ r = semop(semid, semops, 1);
+ if (r == 0)
+ return r;
+ sleep(1);
+ --timeout;
+ } while (timeout > 0);
+ return r;
+}
+
+/*
+** SM_SEM_GET -- get semaphore value.
+**
+** Parameters:
+** semid -- id for semaphores.
+** semnum -- number of semaphore.
+**
+** Returns:
+** value of semaphore on success.
+** < 0 on failure.
+*/
+
+int
+sm_sem_get(semid, semnum)
+ int semid;
+ int semnum;
+{
+ int semval;
+
+ if ((semval = semctl(semid, semnum, GETVAL, NULL)) < 0)
+ return -1;
+ return semval;
+}
+#endif /* SM_CONF_SEM */
diff --git a/contrib/sendmail/libsm/shm.c b/contrib/sendmail/libsm/shm.c
index 4cef892..b68f7c6 100644
--- a/contrib/sendmail/libsm/shm.c
+++ b/contrib/sendmail/libsm/shm.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000-2001, 2003 Sendmail, Inc. and its suppliers.
+ * Copyright (c) 2000-2001, 2003, 2005 Sendmail, Inc. and its suppliers.
* All rights reserved.
*
* By using this file, you agree to the terms and conditions set
@@ -8,7 +8,7 @@
*/
#include <sm/gen.h>
-SM_RCSID("@(#)$Id: shm.c,v 1.16 2003/06/13 21:18:08 ca Exp $")
+SM_RCSID("@(#)$Id: shm.c,v 1.18 2005/02/09 01:54:51 ca Exp $")
#if SM_CONF_SHM
# include <stdlib.h>
@@ -104,4 +104,38 @@ sm_shmstop(shm, shmid, owner)
}
+/*
+** SM_SHMSETOWNER -- set owner/group/mode of shared memory segment.
+**
+** Parameters:
+** shmid -- id.
+** uid -- uid to use
+** gid -- gid to use
+** mode -- mode to use
+**
+** Returns:
+** 0 on success.
+** < 0 on failure.
+*/
+
+int
+sm_shmsetowner(shmid, uid, gid, mode)
+ int shmid;
+ uid_t uid;
+ gid_t gid;
+ mode_t mode;
+{
+ int r;
+ struct shmid_ds shmid_ds;
+
+ memset(&shmid_ds, 0, sizeof(shmid_ds));
+ if ((r = shmctl(shmid, IPC_STAT, &shmid_ds)) < 0)
+ return r;
+ shmid_ds.shm_perm.uid = uid;
+ shmid_ds.shm_perm.gid = gid;
+ shmid_ds.shm_perm.mode = mode;
+ if ((r = shmctl(shmid, IPC_SET, &shmid_ds)) < 0)
+ return r;
+ return 0;
+}
#endif /* SM_CONF_SHM */
diff --git a/contrib/sendmail/libsm/t-sem.c b/contrib/sendmail/libsm/t-sem.c
new file mode 100644
index 0000000..3964327
--- /dev/null
+++ b/contrib/sendmail/libsm/t-sem.c
@@ -0,0 +1,344 @@
+/*
+ * Copyright (c) 2000-2001 Sendmail, 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.
+ */
+
+#include <sm/gen.h>
+SM_RCSID("@(#)$Id: t-sem.c,v 1.14 2005/03/25 21:27:41 ca Exp $")
+
+#include <stdio.h>
+
+#if SM_CONF_SEM
+# include <stdlib.h>
+# include <unistd.h>
+# include <sysexits.h>
+# include <sm/heap.h>
+# include <sm/string.h>
+# include <sm/signal.h>
+# include <sm/test.h>
+# include <sm/sem.h>
+
+static void
+delay(t, s)
+ int t;
+ char *s;
+{
+ if (t > 0)
+ {
+#if DEBUG
+ fprintf(stderr, "sleep(%d) before %s\n", t, s);
+#endif /* DEBUG */
+ sleep(t);
+ }
+#if DEBUG
+ fprintf(stderr, "%s\n", s);
+#endif /* DEBUG */
+}
+
+
+/*
+** SEMINTER -- interactive testing of semaphores.
+**
+** Parameters:
+** owner -- create semaphores.
+**
+** Returns:
+** 0 on success
+** < 0 on failure.
+*/
+
+static int
+seminter(owner)
+ bool owner;
+{
+ int semid;
+ int t;
+
+ semid = sm_sem_start(SM_SEM_KEY, SM_NSEM, 0, owner);
+ if (semid < 0)
+ {
+ perror("sm_sem_start failed");
+ return 1;
+ }
+
+ while ((t = getchar()) != EOF)
+ {
+ switch (t)
+ {
+ case 'a':
+ delay(0, "try to acq");
+ if (sm_sem_acq(semid, 0, 2) < 0)
+ {
+ perror("sm_sem_acq failed");
+ return 1;
+ }
+ delay(0, "acquired");
+ break;
+
+ case 'r':
+ delay(0, "try to rel");
+ if (sm_sem_rel(semid, 0, 2) < 0)
+ {
+ perror("sm_sem_rel failed");
+ return 1;
+ }
+ delay(0, "released");
+ break;
+
+ case 'v':
+ if ((t = sm_sem_get(semid, 0)) < 0)
+ {
+ perror("get_sem failed");
+ return 1;
+ }
+ printf("semval: %d\n", t);
+ break;
+
+ }
+ }
+ if (owner)
+ return sm_sem_stop(semid);
+ return 0;
+}
+
+/*
+** SEM_CLEANUP -- cleanup if something breaks
+**
+** Parameters:
+** sig -- signal.
+**
+** Returns:
+** none.
+*/
+
+static int semid_c = -1;
+void
+sem_cleanup(sig)
+ int sig;
+{
+ if (semid_c >= 0)
+ (void) sm_sem_stop(semid_c);
+ exit(EX_UNAVAILABLE);
+}
+
+/*
+** SEMTEST -- test of semaphores
+**
+** Parameters:
+** owner -- create semaphores.
+**
+** Returns:
+** 0 on success
+** < 0 on failure.
+*/
+
+# define MAX_CNT 10
+
+static int
+semtest(owner)
+ int owner;
+{
+ int semid, r;
+ int cnt = 0;
+
+ semid = sm_sem_start(SM_SEM_KEY, 1, 0, owner);
+ if (semid < 0)
+ {
+ perror("sm_sem_start failed");
+ return -1;
+ }
+
+ if (owner)
+ {
+ /* just in case someone kills the program... */
+ semid_c = semid;
+ (void) sm_signal(SIGHUP, sem_cleanup);
+ (void) sm_signal(SIGINT, sem_cleanup);
+ (void) sm_signal(SIGTERM, sem_cleanup);
+
+ delay(1, "parent: acquire 1");
+ cnt = 0;
+ do
+ {
+ r = sm_sem_acq(semid, 0, 0);
+ if (r < 0)
+ {
+ sleep(1);
+ ++cnt;
+ }
+ } while (r < 0 && cnt <= MAX_CNT);
+ SM_TEST(r >= 0);
+ if (r < 0)
+ return r;
+
+ delay(3, "parent: release 1");
+ cnt = 0;
+ do
+ {
+ r = sm_sem_rel(semid, 0, 0);
+ if (r < 0)
+ {
+ sleep(1);
+ ++cnt;
+ }
+ } while (r < 0 && cnt <= MAX_CNT);
+ SM_TEST(r >= 0);
+ if (r < 0)
+ return r;
+
+ delay(1, "parent: getval");
+ cnt = 0;
+ do
+ {
+ r = sm_sem_get(semid, 0);
+ if (r <= 0)
+ {
+ sleep(1);
+ ++cnt;
+ }
+ } while (r <= 0 && cnt <= MAX_CNT);
+ SM_TEST(r > 0);
+ if (r <= 0)
+ return r;
+
+ delay(1, "parent: acquire 2");
+ cnt = 0;
+ do
+ {
+ r = sm_sem_acq(semid, 0, 0);
+ if (r < 0)
+ {
+ sleep(1);
+ ++cnt;
+ }
+ } while (r < 0 && cnt <= MAX_CNT);
+ SM_TEST(r >= 0);
+ if (r < 0)
+ return r;
+
+ cnt = 0;
+ do
+ {
+ r = sm_sem_rel(semid, 0, 0);
+ if (r < 0)
+ {
+ sleep(1);
+ ++cnt;
+ }
+ } while (r < 0 && cnt <= MAX_CNT);
+ SM_TEST(r >= 0);
+ if (r < 0)
+ return r;
+ }
+ else
+ {
+ delay(1, "child: acquire 1");
+ cnt = 0;
+ do
+ {
+ r = sm_sem_acq(semid, 0, 0);
+ if (r < 0)
+ {
+ sleep(1);
+ ++cnt;
+ }
+ } while (r < 0 && cnt <= MAX_CNT);
+ SM_TEST(r >= 0);
+ if (r < 0)
+ return r;
+
+ delay(1, "child: release 1");
+ cnt = 0;
+ do
+ {
+ r = sm_sem_rel(semid, 0, 0);
+ if (r < 0)
+ {
+ sleep(1);
+ ++cnt;
+ }
+ } while (r < 0 && cnt <= MAX_CNT);
+ SM_TEST(r >= 0);
+ if (r < 0)
+ return r;
+
+ }
+ if (owner)
+ return sm_sem_stop(semid);
+ return 0;
+}
+
+int
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ bool interactive = false;
+ bool owner = false;
+ int ch;
+ int r = 0;
+
+# define OPTIONS "io"
+ while ((ch = getopt(argc, argv, OPTIONS)) != -1)
+ {
+ switch ((char) ch)
+ {
+ case 'i':
+ interactive = true;
+ break;
+
+ case 'o':
+ owner = true;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if (interactive)
+ r = seminter(owner);
+ else
+ {
+ pid_t pid;
+
+ printf("This test takes about 8 seconds.\n");
+ printf("If it takes longer than 30 second, please interrupt it\n");
+ printf("and compile again without semaphore support, i.e.,");
+ printf("-DSM_CONF_SEM=0\n");
+ if ((pid = fork()) < 0)
+ {
+ perror("fork failed\n");
+ return -1;
+ }
+
+ sm_test_begin(argc, argv, "test semaphores");
+ if (pid == 0)
+ {
+ /* give the parent the chance to setup data */
+ sleep(1);
+ r = semtest(false);
+ }
+ else
+ {
+ r = semtest(true);
+ }
+ SM_TEST(r == 0);
+ return sm_test_end();
+ }
+ return r;
+}
+#else /* SM_CONF_SEM */
+int
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ printf("No support for semaphores configured on this machine\n");
+ return 0;
+}
+#endif /* SM_CONF_SEM */
diff --git a/contrib/sendmail/libsm/t-shm.c b/contrib/sendmail/libsm/t-shm.c
index 16ea131..ba0bc6c 100644
--- a/contrib/sendmail/libsm/t-shm.c
+++ b/contrib/sendmail/libsm/t-shm.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000-2002, 2004 Sendmail, Inc. and its suppliers.
+ * Copyright (c) 2000-2002, 2004, 2005 Sendmail, Inc. and its suppliers.
* All rights reserved.
*
* By using this file, you agree to the terms and conditions set
@@ -8,7 +8,7 @@
*/
#include <sm/gen.h>
-SM_RCSID("@(#)$Id: t-shm.c,v 1.20 2004/08/03 20:51:36 ca Exp $")
+SM_RCSID("@(#)$Id: t-shm.c,v 1.22 2005/01/14 02:14:10 ca Exp $")
#include <stdio.h>
@@ -83,6 +83,10 @@ shminter(owner)
case 'v':
printf("shmval: %d\n", *shm);
break;
+ case 'S':
+ i = sm_shmsetowner(shmid, getuid(), getgid(), 0644);
+ printf("sm_shmsetowner=%d\n", i);
+ break;
}
}
return sm_shmstop((void *) shm, shmid, owner);
@@ -165,6 +169,8 @@ shmtest(owner)
{
int r;
+ r = sm_shmsetowner(shmid, getuid(), getgid(), 0660);
+ SM_TEST(r == 0);
*shm = 1;
while (*shm == 1 && cnt++ < MAX_CNT)
sleep(1);
OpenPOWER on IntegriCloud