Coverage Report

Created: 2024-05-04 12:45

/proc/self/cwd/external/curl/lib/fopen.c
Line
Count
Source (jump to first uncovered line)
1
/***************************************************************************
2
 *                                  _   _ ____  _
3
 *  Project                     ___| | | |  _ \| |
4
 *                             / __| | | | |_) | |
5
 *                            | (__| |_| |  _ <| |___
6
 *                             \___|\___/|_| \_\_____|
7
 *
8
 * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
9
 *
10
 * This software is licensed as described in the file COPYING, which
11
 * you should have received as part of this distribution. The terms
12
 * are also available at https://curl.se/docs/copyright.html.
13
 *
14
 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15
 * copies of the Software, and permit persons to whom the Software is
16
 * furnished to do so, under the terms of the COPYING file.
17
 *
18
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19
 * KIND, either express or implied.
20
 *
21
 * SPDX-License-Identifier: curl
22
 *
23
 ***************************************************************************/
24
25
#include "curl_setup.h"
26
27
#if !defined(CURL_DISABLE_COOKIES) || !defined(CURL_DISABLE_ALTSVC) ||  \
28
  !defined(CURL_DISABLE_HSTS)
29
30
#ifdef HAVE_FCNTL_H
31
#include <fcntl.h>
32
#endif
33
34
#include "urldata.h"
35
#include "rand.h"
36
#include "fopen.h"
37
/* The last 3 #include files should be in this order */
38
#include "curl_printf.h"
39
#include "curl_memory.h"
40
#include "memdebug.h"
41
42
/*
43
 * Curl_fopen() opens a file for writing with a temp name, to be renamed
44
 * to the final name when completed. If there is an existing file using this
45
 * name at the time of the open, this function will clone the mode from that
46
 * file.  if 'tempname' is non-NULL, it needs a rename after the file is
47
 * written.
48
 */
49
CURLcode Curl_fopen(struct Curl_easy *data, const char *filename,
50
                    FILE **fh, char **tempname)
51
0
{
52
0
  CURLcode result = CURLE_WRITE_ERROR;
53
0
  unsigned char randsuffix[9];
54
0
  char *tempstore = NULL;
55
0
  struct_stat sb;
56
0
  int fd = -1;
57
0
  *tempname = NULL;
58
59
0
  *fh = fopen(filename, FOPEN_WRITETEXT);
60
0
  if(!*fh)
61
0
    goto fail;
62
0
  if(fstat(fileno(*fh), &sb) == -1 || !S_ISREG(sb.st_mode))
63
0
    return CURLE_OK;
64
0
  fclose(*fh);
65
0
  *fh = NULL;
66
67
0
  result = Curl_rand_alnum(data, randsuffix, sizeof(randsuffix));
68
0
  if(result)
69
0
    goto fail;
70
71
0
  tempstore = aprintf("%s.%s.tmp", filename, randsuffix);
72
0
  if(!tempstore) {
73
0
    result = CURLE_OUT_OF_MEMORY;
74
0
    goto fail;
75
0
  }
76
77
0
  result = CURLE_WRITE_ERROR;
78
0
  fd = open(tempstore, O_WRONLY | O_CREAT | O_EXCL, 0600);
79
0
  if(fd == -1)
80
0
    goto fail;
81
82
#ifdef HAVE_FCHMOD
83
  {
84
    struct_stat nsb;
85
    if((fstat(fd, &nsb) != -1) &&
86
       (nsb.st_uid == sb.st_uid) && (nsb.st_gid == sb.st_gid)) {
87
      /* if the user and group are the same, clone the original mode */
88
      if(fchmod(fd, (mode_t)sb.st_mode) == -1)
89
        goto fail;
90
    }
91
  }
92
#endif
93
94
0
  *fh = fdopen(fd, FOPEN_WRITETEXT);
95
0
  if(!*fh)
96
0
    goto fail;
97
98
0
  *tempname = tempstore;
99
0
  return CURLE_OK;
100
101
0
fail:
102
0
  if(fd != -1) {
103
0
    close(fd);
104
0
    unlink(tempstore);
105
0
  }
106
107
0
  free(tempstore);
108
109
0
  return result;
110
0
}
111
112
#endif /* ! disabled */