"Fossies" - the Fresh Open Source Software Archive

Member "src/Common/libzip/mkstemp.c" (10 Oct 2018, 3949 Bytes) of package /windows/misc/VeraCrypt_1.23-Hotfix-2_Source.zip:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "mkstemp.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 1.21_Source_vs_1.22_Source.

    1 /* Adapted from NetBSB libc by Dieter Baron */
    2 
    3 /*  NetBSD: gettemp.c,v 1.13 2003/12/05 00:57:36 uebayasi Exp   */
    4 
    5 /*
    6  * Copyright (c) 1987, 1993
    7  *  The Regents of the University of California.  All rights reserved.
    8  *
    9  * Redistribution and use in source and binary forms, with or without
   10  * modification, are permitted provided that the following conditions
   11  * are met:
   12  * 1. Redistributions of source code must retain the above copyright
   13  *    notice, this list of conditions and the following disclaimer.
   14  * 2. Redistributions in binary form must reproduce the above copyright
   15  *    notice, this list of conditions and the following disclaimer in the
   16  *    documentation and/or other materials provided with the distribution.
   17  * 3. Neither the name of the University nor the names of its contributors
   18  *    may be used to endorse or promote products derived from this software
   19  *    without specific prior written permission.
   20  *
   21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   31  * SUCH DAMAGE.
   32  */
   33 
   34 #include <sys/stat.h>
   35 #include <sys/types.h>
   36 
   37 #include <assert.h>
   38 #include <ctype.h>
   39 #include <errno.h>
   40 #include <fcntl.h>
   41 #ifdef _WIN32
   42 #include <io.h>
   43 #include <process.h>
   44 #else
   45 #include <unistd.h>
   46 #endif
   47 #include <stdio.h>
   48 #include <stdlib.h>
   49 
   50 #ifndef O_BINARY
   51 #define O_BINARY 0
   52 #endif
   53 
   54 
   55 int
   56 _zip_mkstemp(char *path) {
   57 #ifdef _WIN32
   58     int ret;
   59     ret = _creat(_mktemp(path), _S_IREAD | _S_IWRITE);
   60     if (ret == -1) {
   61     return 0;
   62     }
   63     else {
   64     return ret;
   65     }
   66 #else
   67     int fd;
   68     char *start, *trv;
   69     struct stat sbuf;
   70     pid_t pid;
   71 
   72     /* To guarantee multiple calls generate unique names even if
   73        the file is not created. 676 different possibilities with 7
   74        or more X's, 26 with 6 or less. */
   75     static char xtra[2] = "aa";
   76     int xcnt = 0;
   77 
   78     pid = getpid();
   79 
   80     /* Move to end of path and count trailing X's. */
   81     for (trv = path; *trv; ++trv)
   82     if (*trv == 'X')
   83         xcnt++;
   84     else
   85         xcnt = 0;
   86 
   87     /* Use at least one from xtra.  Use 2 if more than 6 X's. */
   88     if (*(trv - 1) == 'X')
   89     *--trv = xtra[0];
   90     if (xcnt > 6 && *(trv - 1) == 'X')
   91     *--trv = xtra[1];
   92 
   93     /* Set remaining X's to pid digits with 0's to the left. */
   94     while (*--trv == 'X') {
   95     *trv = (pid % 10) + '0';
   96     pid /= 10;
   97     }
   98 
   99     /* update xtra for next call. */
  100     if (xtra[0] != 'z')
  101     xtra[0]++;
  102     else {
  103     xtra[0] = 'a';
  104     if (xtra[1] != 'z')
  105         xtra[1]++;
  106     else
  107         xtra[1] = 'a';
  108     }
  109 
  110     /*
  111      * check the target directory; if you have six X's and it
  112      * doesn't exist this runs for a *very* long time.
  113      */
  114     for (start = trv + 1;; --trv) {
  115     if (trv <= path)
  116         break;
  117     if (*trv == '/') {
  118         *trv = '\0';
  119         if (stat(path, &sbuf))
  120         return (0);
  121         if (!S_ISDIR(sbuf.st_mode)) {
  122         errno = ENOTDIR;
  123         return (0);
  124         }
  125         *trv = '/';
  126         break;
  127     }
  128     }
  129 
  130     for (;;) {
  131     if ((fd = open(path, O_CREAT | O_EXCL | O_RDWR | O_BINARY, 0600)) >= 0)
  132         return (fd);
  133     if (errno != EEXIST)
  134         return (0);
  135 
  136     /* tricky little algorithm for backward compatibility */
  137     for (trv = start;;) {
  138         if (!*trv)
  139         return (0);
  140         if (*trv == 'z')
  141         *trv++ = 'a';
  142         else {
  143         if (isdigit((unsigned char)*trv))
  144             *trv = 'a';
  145         else
  146             ++*trv;
  147         break;
  148         }
  149     }
  150     }
  151     /*NOTREACHED*/
  152 #endif
  153 }