From 13d882686343bf9a76ffdfa83854043d808703dd Mon Sep 17 00:00:00 2001 From: Gregory Neil Shapiro Date: Tue, 7 Jun 2005 04:14:59 +0000 Subject: Import sendmail 8.13.4 --- contrib/sendmail/libsm/Makefile.m4 | 8 +- contrib/sendmail/libsm/ldap.c | 30 ++-- contrib/sendmail/libsm/sem.c | 201 ++++++++++++++++++++++ contrib/sendmail/libsm/shm.c | 38 +++- contrib/sendmail/libsm/t-sem.c | 344 +++++++++++++++++++++++++++++++++++++ contrib/sendmail/libsm/t-shm.c | 10 +- 6 files changed, 609 insertions(+), 22 deletions(-) create mode 100644 contrib/sendmail/libsm/sem.c create mode 100644 contrib/sendmail/libsm/t-sem.c (limited to 'contrib/sendmail/libsm') diff --git a/contrib/sendmail/libsm/Makefile.m4 b/contrib/sendmail/libsm/Makefile.m4 index 8896a1e9cf35..a77afeae26af 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 5e6557ddd58b..3af7ffab01cd 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_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 @@ -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 000000000000..a429cf4a2ed2 --- /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_RCSID("@(#)$Id: sem.c,v 1.12 2005/03/25 21:27:02 ca Exp $") + +#if SM_CONF_SEM +# include +# include +# include +# include + +/* +** 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 4cef8929e283..b68f7c689d5e 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_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 @@ -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 000000000000..3964327017e3 --- /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_RCSID("@(#)$Id: t-sem.c,v 1.14 2005/03/25 21:27:41 ca Exp $") + +#include + +#if SM_CONF_SEM +# include +# include +# include +# include +# include +# include +# include +# include + +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 16ea131c2274..ba0bc6c3ab91 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_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 @@ -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); -- cgit v1.2.3