Add mkstemp replacement function. --HG-- branch : HEAD
diff --git a/configure.ac b/configure.ac index d60ed9e..5eb6bbd 100644 --- a/configure.ac +++ b/configure.ac
@@ -43,6 +43,8 @@ AM_PROG_LIBTOOL +AC_CHECK_FUNCS([mkstemp], [], [AC_LIBOBJ(mkstemp)]) + case $host_os in *bsd*) MANFMT=mdoc;;
diff --git a/lib/Makefile.am b/lib/Makefile.am index 2c0922f..8f5aa7a 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am
@@ -3,6 +3,7 @@ include_HEADERS = zip.h libzip_la_LDFLAGS=-version-info 0:5 +libzip_la_LIBADD=@LIBOBJS@ libzip_la_SOURCES=\ zip_add.c \
diff --git a/lib/mkstemp.c b/lib/mkstemp.c new file mode 100644 index 0000000..c926a99 --- /dev/null +++ b/lib/mkstemp.c
@@ -0,0 +1,136 @@ +/* $NiH$ */ + +/* Adapted from NetBSB libc by Dieter Baron */ + +/* NetBSD: gettemp.c,v 1.13 2003/12/05 00:57:36 uebayasi Exp */ + +/* + * Copyright (c) 1987, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/types.h> +#include <sys/stat.h> + +#include <assert.h> +#include <ctype.h> +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + + +int +_zip_mkstemp(char *path) +{ + int fd; + char *start, *trv; + struct stat sbuf; + u_int pid; + + /* To guarantee multiple calls generate unique names even if + the file is not created. 676 different possibilities with 7 + or more X's, 26 with 6 or less. */ + static char xtra[2] = "aa"; + int xcnt = 0; + + pid = getpid(); + + /* Move to end of path and count trailing X's. */ + for (trv = path; *trv; ++trv) + if (*trv == 'X') + xcnt++; + else + xcnt = 0; + + /* Use at least one from xtra. Use 2 if more than 6 X's. */ + if (*(trv - 1) == 'X') + *--trv = xtra[0]; + if (xcnt > 6 && *(trv - 1) == 'X') + *--trv = xtra[1]; + + /* Set remaining X's to pid digits with 0's to the left. */ + while (*--trv == 'X') { + *trv = (pid % 10) + '0'; + pid /= 10; + } + + /* update xtra for next call. */ + if (xtra[0] != 'z') + xtra[0]++; + else { + xtra[0] = 'a'; + if (xtra[1] != 'z') + xtra[1]++; + else + xtra[1] = 'a'; + } + + /* + * check the target directory; if you have six X's and it + * doesn't exist this runs for a *very* long time. + */ + for (start = trv + 1;; --trv) { + if (trv <= path) + break; + if (*trv == '/') { + *trv = '\0'; + if (stat(path, &sbuf)) + return (0); + if (!S_ISDIR(sbuf.st_mode)) { + errno = ENOTDIR; + return (0); + } + *trv = '/'; + break; + } + } + + for (;;) { + if ((fd = open(path, O_CREAT | O_EXCL | O_RDWR, 0600)) >= 0) + return (1); + if (errno != EEXIST) + return (0); + + /* tricky little algorithm for backward compatibility */ + for (trv = start;;) { + if (!*trv) + return (0); + if (*trv == 'z') + *trv++ = 'a'; + else { + if (isdigit((unsigned char)*trv)) + *trv = 'a'; + else + ++*trv; + break; + } + } + } + /*NOTREACHED*/ +}
diff --git a/lib/zipint.h b/lib/zipint.h index 367ae8f..e6658fd 100644 --- a/lib/zipint.h +++ b/lib/zipint.h
@@ -2,10 +2,10 @@ #define _HAD_ZIPINT_H /* - $NiH: zipint.h,v 1.42 2005/09/06 23:44:25 wiz Exp $ + $NiH: zipint.h,v 1.43 2006/02/21 09:41:00 dillo Exp $ zipint.h -- internal declarations. - Copyright (C) 1999, 2003, 2004, 2005 Dieter Baron and Thomas Klausner + Copyright (C) 1999, 2003, 2004, 2005, 2006 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <nih@giga.or.at> @@ -39,6 +39,12 @@ #include <zlib.h> #include "zip.h" +#include "config.h" + +#ifndef HAVE_MKSTEMP +int _zip_mkstemp(char *); +#define mkstemp _zip_mkstemp +#endif